From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <pve-devel-bounces@lists.proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68])
	by lore.proxmox.com (Postfix) with ESMTPS id 968AF1FF17C
	for <inbox@lore.proxmox.com>; Wed,  2 Apr 2025 12:41:51 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
	by firstgate.proxmox.com (Proxmox) with ESMTP id 7838FF8D9;
	Wed,  2 Apr 2025 12:41:41 +0200 (CEST)
Date: Wed, 02 Apr 2025 12:41:35 +0200
From: Fabian =?iso-8859-1?q?Gr=FCnbichler?= <f.gruenbichler@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
References: <20250328171340.885413-1-g.goller@proxmox.com>
 <20250328171340.885413-36-g.goller@proxmox.com>
In-Reply-To: <20250328171340.885413-36-g.goller@proxmox.com>
MIME-Version: 1.0
User-Agent: astroid/0.16.0 (https://github.com/astroidmail/astroid)
Message-Id: <1743586099.02lwsh9zvu.astroid@yuna.none>
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.045 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DMARC_MISSING             0.1 Missing DMARC policy
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: Re: [pve-devel] [PATCH pve-network 08/17] sdn: frr: add daemon
 status to frr helper
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: pve-devel-bounces@lists.proxmox.com
Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com>

On March 28, 2025 6:13 pm, Gabriel Goller wrote:
> From: Stefan Hanreich <s.hanreich@proxmox.com>
> 
> Add functions that allow reading and manipulating values in the
> /etc/frr/daemons file. We need this for en/disabling daemons depending
> on which fabric types are configured. We only enable daemons which are
> required for the configured fabrics. If a daemon is enabled but a
> fabric gets deleted, we disable them.
> 
> The helper works by iterating over the lines of the daemons file from
> FRR, parsing the key and checking if the key is managed by the SDN
> configuration, then sets it. As a safeguard, keys that can be changed
> by SDN have to be explicitly configured in the respective hash of the
> Frr module.
> 
> Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
> Co-authored-by: Gabriel Goller <g.goller@proxmox.com>
> Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
> ---
>  src/PVE/Network/SDN.pm         | 15 +++++++++++
>  src/PVE/Network/SDN/Fabrics.pm | 18 +++++++++++++
>  src/PVE/Network/SDN/Frr.pm     | 49 ++++++++++++++++++++++++++++++++++
>  3 files changed, 82 insertions(+)
> 
> diff --git a/src/PVE/Network/SDN.pm b/src/PVE/Network/SDN.pm
> index b777a098a987..a0b61275e10b 100644
> --- a/src/PVE/Network/SDN.pm
> +++ b/src/PVE/Network/SDN.pm
> @@ -258,12 +258,27 @@ sub generate_frr_raw_config {
>      return $raw_config;
>  }
>  
> +=head3 get_frr_daemon_status(\%running_config, \%fabric_config)
> +
> +Returns a hash that indicates the status of the FRR daemons managed by SDN.
> +
> +=cut
> +
> +sub get_frr_daemon_status {
> +    my ($running_config, $fabric_config) = @_;
> +
> +    return PVE::Network::SDN::Fabrics::get_frr_daemon_status($fabric_config);

this takes but doesn't use the $running_config.. is this intentional?

> +}
> +
>  sub generate_frr_config {
>      my ($reload) = @_;
>  
>      my $running_config = PVE::Network::SDN::running_config();
>      my $fabric_config = PVE::Network::SDN::Fabrics::config(1);
>  
> +    my $daemon_status = PVE::Network::SDN::get_frr_daemon_status($running_config, $fabric_config);

the getter has a top-level wrapper

> +    PVE::Network::SDN::Frr::set_daemon_status($daemon_status);

but the setter doesn't? seems inconsistent ;)

> +
>      my $raw_config = PVE::Network::SDN::generate_frr_raw_config($running_config, $fabric_config);
>      PVE::Network::SDN::Frr::write_raw_config($raw_config);
>  
> diff --git a/src/PVE/Network/SDN/Fabrics.pm b/src/PVE/Network/SDN/Fabrics.pm
> index 6e3fa5234a5b..d716c68feac4 100644
> --- a/src/PVE/Network/SDN/Fabrics.pm
> +++ b/src/PVE/Network/SDN/Fabrics.pm
> @@ -69,6 +69,24 @@ sub config_for_protocol {
>      return $module->config($section_config);
>  }
>  
> +sub get_frr_daemon_status {
> +    my ($fabric_config) = @_;
> +
> +    my $daemon_status = {};
> +    my $nodename = PVE::INotify::nodename();
> +
> +    for my $protocol (sort keys %$fabric_config) {
> +	my $config = $fabric_config->{$protocol};

this could iterate over the values instead? ;)

> +	my $enabled_daemons = $config->enabled_daemons($nodename);
> +
> +	for my $daemon (@$enabled_daemons) {
> +	    $daemon_status->{$daemon} = 1;
> +	}
> +    }
> +
> +    return $daemon_status;
> +}
> +
>  sub generate_frr_raw_config {
>      my ($fabric_config) = @_;
>  
> diff --git a/src/PVE/Network/SDN/Frr.pm b/src/PVE/Network/SDN/Frr.pm
> index bb0f197d8dea..9ae302a9c25f 100644
> --- a/src/PVE/Network/SDN/Frr.pm
> +++ b/src/PVE/Network/SDN/Frr.pm
> @@ -77,6 +77,55 @@ sub reload {
>      }
>  }
>  
> +my $SDN_DAEMONS_DEFAULT = {
> +    ospfd => 0,
> +    fabricd => 0,
> +};
> +
> +=head3 set_daemon_status(\%daemons, $set_default)
> +
> +Sets the status of all daemons supplied in C<\%daemons>. This only works for
> +daemons managed by SDN, as indicated in the C<$SDN_DAEMONS_DEFAULT> constant. If
> +a daemon is supplied that isn't managed by SDN then this command will fail. If
> +C<$set_default> is set, then additionally all sdn-managed daemons that are
> +missing in C<\%daemons> are reset to their default value.
> +
> +=cut
> +
> +sub set_daemon_status {
> +    my ($daemon_status, $set_default) = @_;
> +
> +    for my $daemon (keys %$daemon_status) {
> +	die "$daemon is not SDN managed" if !defined $SDN_DAEMONS_DEFAULT->{$daemon};
> +    }
> +
> +    my $daemons_file = "/etc/frr/daemons";
> +
> +    my $old_config = PVE::Tools::file_get_contents($daemons_file);
> +    my $new_config = "";
> +
> +    my @lines = split(/\n/, $old_config);
> +
> +    for my $line (@lines) {

so we have three cases here
- line contains one of our daemons as key (=> set status)
- line contains something else as key (=> keep line as is)
- line contains no key but something else entirely (=> keep line as is)

I think this could be structured so that it is a bit more readable/easy
to follow along..

first, fill in the defaults if needed:

if ($set_default) {
  for my $daemon (keys %$SDN_DAEMONS_DEFAULT) {
    $daemon_status->{$daemon} = $SDN_DAEMONS_DEFAULT->{$daemon}
      if !defined($daemon_status->{$daemon});
  }
}

and then simply override lines as needed:

for my $line (@lines) {
	if ($line =~ m/^([a-z_]+)=/) {
	   my $key = $1;
	   my $status = $daemon_status->{$key};

	   if (defined($status)) {
        my $value = status ? "yes" : "no"; 
        $line = "$key=$value";
	   }
	}

	$new_config .= "$line\n";
}

> +	if ($line =~ m/^([a-z_]+)=/) {
> +	    my $key = $1;
> +
> +	    my $status = $daemon_status->{$key};
> +	    $status = $SDN_DAEMONS_DEFAULT->{$key} if !defined $status && $set_default;
> +
> +	    if (defined $status) {
> +		my $value = $status ? "yes" : "no";
> +		$new_config .= "$key=$value\n";
> +		next;
> +	    }
> +	}
> +
> +	$new_config .= "$line\n";
> +    }
> +
> +    PVE::Tools::file_set_contents($daemons_file, $new_config);
> +}
> +
>  =head3 to_raw_config(\%frr_config)
>  
>  Converts a given C<\%frr_config> to the raw config format.
> -- 
> 2.39.5
> 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 
> 


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel