public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Alexandre Derumier <aderumier@odiso.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH pve-network 2/3] frr: add a local config parser and merge with generated config
Date: Wed, 24 Aug 2022 10:56:45 +0200	[thread overview]
Message-ID: <20220824085646.561337-3-aderumier@odiso.com> (raw)
In-Reply-To: <20220824085646.561337-1-aderumier@odiso.com>

some users with very specific config want to be able to add
custom local config and merge it with generated config

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
---
 PVE/Network/SDN/Controllers/EvpnPlugin.pm | 95 ++++++++++++++++++++---
 1 file changed, 86 insertions(+), 9 deletions(-)

diff --git a/PVE/Network/SDN/Controllers/EvpnPlugin.pm b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
index 15b268b..2bc10f5 100644
--- a/PVE/Network/SDN/Controllers/EvpnPlugin.pm
+++ b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
@@ -376,6 +376,28 @@ sub generate_frr_routemap {
 	}
    }
 }
+
+sub generate_frr_accesslist {
+    my ($final_config, $accesslists) = @_;
+
+    my @config = ();
+
+    for my $id (sort keys %$accesslists) {
+
+	my $accesslist = $accesslists->{$id};
+
+	for my $seq (sort keys %$accesslist) {
+	    my $rule = $accesslist->{$seq};
+	    push @config, "access-list $id seq $seq $rule";
+	}
+    }
+
+    if(@config > 0) {
+	push @{$final_config}, "!";
+	push @{$final_config}, @config;
+    }
+}
+
 sub generate_controller_rawconfig {
     my ($class, $plugin_config, $config) = @_;
 
@@ -390,18 +412,14 @@ sub generate_controller_rawconfig {
     push @{$final_config}, "!";
 
     if (-e "/etc/frr/frr.conf.local") {
-	generate_frr_recurse($final_config, $config->{frr}->{vrf}, "vrf", 1);
-	generate_frr_routemap($final_config, $config->{frr_routemap});
-	push @{$final_config}, "!";
-
 	my $local_conf = file_get_contents("/etc/frr/frr.conf.local");
-	chomp ($local_conf);
-	push @{$final_config}, $local_conf;
-    } else {
-	generate_frr_recurse($final_config, $config->{frr}, undef, 0);
-	generate_frr_routemap($final_config, $config->{frr_routemap});
+	parse_merge_frr_local_config($config, $local_conf);
     }
 
+    generate_frr_recurse($final_config, $config->{frr}, undef, 0);
+    generate_frr_accesslist($final_config, $config->{frr_access_list});
+    generate_frr_routemap($final_config, $config->{frr_routemap});
+
     push @{$final_config}, "!";
     push @{$final_config}, "line vty";
     push @{$final_config}, "!";
@@ -412,6 +430,65 @@ sub generate_controller_rawconfig {
     return $rawconfig;
 }
 
+sub parse_merge_frr_local_config {
+    my ($config, $local_conf) = @_;
+
+    my $section = \$config->{""};
+    my $router = undef;
+    my $routemap = undef;
+    my $routemap_config = ();
+    my $routemap_action = undef;
+
+    while ($local_conf =~ /^\s*(.+?)\s*$/gm) {
+        my $line = $1;
+	$line =~ s/^\s+|\s+$//g;
+
+	if ($line =~ m/^router (.+)$/) {
+	    $router = $1;
+	    $section = \$config->{'frr'}->{'router'}->{$router}->{""};
+	    next;
+	} elsif ($line =~ m/^vrf (.+)$/) {
+	    $section = \$config->{'frr'}->{'vrf'}->{$1};
+	    next;
+	} elsif ($line =~ m/address-family (.+)$/) {
+	    $section = \$config->{'frr'}->{'router'}->{$router}->{'address-family'}->{$1};
+	    next;
+	} elsif ($line =~ m/^route-map (.+) (permit|deny) (\d+)/) {
+	    $routemap = $1;
+	    $routemap_config = ();
+	    $routemap_action = $2;
+	    $section = \$config->{'frr_routemap'}->{$routemap};
+	    next;
+	} elsif ($line =~ m/^access-list (.+) seq (\d+) (.+)$/) {
+	    $config->{'frr_access_list'}->{$1}->{$2} = $3;
+	    next;
+	} elsif($line =~ m/^exit-address-family$/) {
+	    next;
+	} elsif($line =~ m/^exit$/) {
+	    if($router) {
+		$section = \$config->{''};
+		$router = undef;
+	    } elsif($routemap) {
+		push(@{$$section}, { rule => $routemap_config, action => $routemap_action });
+		$section = \$config->{''};
+		$routemap = undef;
+		$routemap_action = undef;
+		$routemap_config = ();
+	    }
+	    next;
+	} elsif($line =~ m/!/) {
+	    next;
+	}
+
+	next if !$section;
+	if($routemap) {
+	    push(@{$routemap_config}, $line);
+	} else {
+	    push(@{$$section}, $line);
+	}
+    }
+}
+
 sub write_controller_config {
     my ($class, $plugin_config, $config) = @_;
 
-- 
2.30.2




  parent reply	other threads:[~2022-08-24  8:56 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-24  8:56 [pve-devel] [PATCH pve-network 0/3] evpn improvment Alexandre Derumier
2022-08-24  8:56 ` [pve-devel] [PATCH pve-network 1/3] frr: update config frrversion to 8.2.2 Alexandre Derumier
2022-08-24  8:56 ` Alexandre Derumier [this message]
2022-08-24  8:56 ` [pve-devel] [PATCH pve-network 3/3] frr: config : add exit on router && routemaps Alexandre Derumier
2022-08-31  9:49 ` [pve-devel] applied-series: [PATCH pve-network 0/3] evpn improvment Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220824085646.561337-3-aderumier@odiso.com \
    --to=aderumier@odiso.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal