[pve-devel] [PATCH pve-network] fix #4662 : frr: fix config generation ordering

Alexandre Derumier aderumier at odiso.com
Wed Apr 12 10:41:41 CEST 2023


vrf and router bgp vrf need to be ordered by vrf name

ip protocol need to be at the end

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/Network/SDN/Controllers/BgpPlugin.pm      |  2 +-
 PVE/Network/SDN/Controllers/EvpnPlugin.pm     | 67 ++++++++-------
 .../ebgp_loopback/expected_controller_config  |  3 +-
 .../expected_controller_config                |  3 +-
 .../multiplezones/expected_controller_config  | 49 +++++++++++
 .../multiplezones/expected_sdn_interfaces     | 81 +++++++++++++++++++
 test/zones/evpn/multiplezones/interfaces      |  7 ++
 test/zones/evpn/multiplezones/sdn_config      | 37 +++++++++
 8 files changed, 217 insertions(+), 32 deletions(-)
 create mode 100644 test/zones/evpn/multiplezones/expected_controller_config
 create mode 100644 test/zones/evpn/multiplezones/expected_sdn_interfaces
 create mode 100644 test/zones/evpn/multiplezones/interfaces
 create mode 100644 test/zones/evpn/multiplezones/sdn_config

diff --git a/PVE/Network/SDN/Controllers/BgpPlugin.pm b/PVE/Network/SDN/Controllers/BgpPlugin.pm
index 0b8cf1a..e001faa 100644
--- a/PVE/Network/SDN/Controllers/BgpPlugin.pm
+++ b/PVE/Network/SDN/Controllers/BgpPlugin.pm
@@ -119,7 +119,7 @@ sub generate_controller_config {
 
     if ($loopback) {
 	$config->{frr_prefix_list}->{loopbacks_ips}->{10} = "permit 0.0.0.0/0 le 32";
-	push(@{$config->{frr}->{''}}, "ip protocol bgp route-map correct_src");
+	push(@{$config->{frr_ip_protocol}}, "ip protocol bgp route-map correct_src");
 
 	my $routemap_config = ();
 	push @{$routemap_config}, "match ip address prefix-list loopbacks_ips";
diff --git a/PVE/Network/SDN/Controllers/EvpnPlugin.pm b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
index 9d39b9b..1944178 100644
--- a/PVE/Network/SDN/Controllers/EvpnPlugin.pm
+++ b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
@@ -247,7 +247,7 @@ sub generate_controller_vnet_config {
 	my $cidr = $subnet->{cidr};
 	push @controller_config, "ip route $cidr 10.255.255.2 xvrf_$zoneid";
     }
-    push(@{$config->{frr}->{''}}, @controller_config);
+    push(@{$config->{frr_ip_protocol}}, @controller_config);
 }
 
 sub on_delete_hook {
@@ -291,41 +291,14 @@ sub find_bgp_controller {
 }
 
 
-sub sort_frr_config {
-    my $order = {};
-    $order->{''} = 0;
-    $order->{'vrf'} = 1;
-    $order->{'ipv4 unicast'} = 1;
-    $order->{'ipv6 unicast'} = 2;
-    $order->{'l2vpn evpn'} = 3;
-
-    my $a_val = 100;
-    my $b_val = 100;
-
-    $a_val = $order->{$a} if defined($order->{$a});
-    $b_val = $order->{$b} if defined($order->{$b});
-
-    if ($a =~ /bgp (\d+)$/) {
-	$a_val = 2;
-    }
-
-    if ($b =~ /bgp (\d+)$/) {
-	$b_val = 2;
-    }
-
-    return $a_val <=> $b_val;
-}
-
 sub generate_frr_recurse{
    my ($final_config, $content, $parentkey, $level) = @_;
 
    my $keylist = {};
-   $keylist->{vrf} = 1;
    $keylist->{'address-family'} = 1;
    $keylist->{router} = 1;
 
    my $exitkeylist = {};
-   $exitkeylist->{vrf} = 1;
    $exitkeylist->{'address-family'} = 1;
 
    my $simple_exitkeylist = {};
@@ -343,7 +316,8 @@ sub generate_frr_recurse{
    $padding = ' ' x ($paddinglevel) if $paddinglevel;
 
    if (ref $content eq  'HASH') {
-	foreach my $key (sort sort_frr_config keys %$content) {
+	foreach my $key (sort keys %$content) {
+	    next if $key eq 'vrf';
 	    if ($parentkey && defined($keylist->{$parentkey})) {
 		push @{$final_config}, $padding."!";
 		push @{$final_config}, $padding."$parentkey $key";
@@ -364,6 +338,39 @@ sub generate_frr_recurse{
     }
 }
 
+sub generate_frr_vrf {
+   my ($final_config, $vrfs) = @_;
+
+   return if !$vrfs;
+
+   my @config = ();
+
+   foreach my $id (sort keys %$vrfs) {
+	my $vrf = $vrfs->{$id};
+	push @config, "!";
+	push @config, "vrf $id";
+	foreach my $rule (@$vrf) {
+	    push @config, " $rule";
+
+	}
+	push @config, "exit-vrf";
+    }
+
+    push @{$final_config}, @config;
+}
+
+sub generate_frr_ip_protocol {
+   my ($final_config, $ips) = @_;
+
+   return if !$ips;
+
+   my @config = ();
+   push @{$final_config}, "!";
+   foreach my $rule (sort @$ips) {
+	push @{$final_config}, $rule;
+   }
+}
+
 sub generate_frr_routemap {
    my ($final_config, $routemaps) = @_;
 
@@ -422,10 +429,12 @@ sub generate_controller_rawconfig {
 	parse_merge_frr_local_config($config, $local_conf);
     }
 
+    generate_frr_vrf($final_config, $config->{frr}->{vrf});
     generate_frr_recurse($final_config, $config->{frr}, undef, 0);
     generate_frr_list($final_config, $config->{frr_access_list}, "access-list");
     generate_frr_list($final_config, $config->{frr_prefix_list}, "ip prefix-list");
     generate_frr_routemap($final_config, $config->{frr_routemap});
+    generate_frr_ip_protocol($final_config, $config->{frr_ip_protocol});
 
     push @{$final_config}, "!";
     push @{$final_config}, "line vty";
diff --git a/test/zones/evpn/ebgp_loopback/expected_controller_config b/test/zones/evpn/ebgp_loopback/expected_controller_config
index 548d532..47836f8 100644
--- a/test/zones/evpn/ebgp_loopback/expected_controller_config
+++ b/test/zones/evpn/ebgp_loopback/expected_controller_config
@@ -4,7 +4,6 @@ hostname localhost
 log syslog informational
 service integrated-vtysh-config
 !
-ip protocol bgp route-map correct_src
 !
 vrf vrf_myzone
  vni 1000
@@ -65,5 +64,7 @@ route-map correct_src permit 1
  set src 192.168.0.1
 exit
 !
+ip protocol bgp route-map correct_src
+!
 line vty
 !
\ No newline at end of file
diff --git a/test/zones/evpn/exitnode_local_routing/expected_controller_config b/test/zones/evpn/exitnode_local_routing/expected_controller_config
index c557a7e..ef3948d 100644
--- a/test/zones/evpn/exitnode_local_routing/expected_controller_config
+++ b/test/zones/evpn/exitnode_local_routing/expected_controller_config
@@ -4,7 +4,6 @@ hostname localhost
 log syslog informational
 service integrated-vtysh-config
 !
-ip route 10.0.0.0/24 10.255.255.2 xvrf_myzone
 !
 vrf vrf_myzone
  vni 1000
@@ -48,5 +47,7 @@ exit
 route-map MAP_VTEP_OUT permit 1
 exit
 !
+ip route 10.0.0.0/24 10.255.255.2 xvrf_myzone
+!
 line vty
 !
\ No newline at end of file
diff --git a/test/zones/evpn/multiplezones/expected_controller_config b/test/zones/evpn/multiplezones/expected_controller_config
new file mode 100644
index 0000000..d6dfa73
--- /dev/null
+++ b/test/zones/evpn/multiplezones/expected_controller_config
@@ -0,0 +1,49 @@
+frr version 8.2.2
+frr defaults datacenter
+hostname localhost
+log syslog informational
+service integrated-vtysh-config
+!
+!
+vrf vrf_myzone
+ vni 1000
+exit-vrf
+!
+vrf vrf_myzone2
+ vni 1001
+exit-vrf
+!
+router bgp 65000
+ bgp router-id 192.168.0.1
+ no bgp default ipv4-unicast
+ coalesce-time 1000
+ neighbor VTEP peer-group
+ neighbor VTEP remote-as 65000
+ neighbor VTEP bfd
+ neighbor 192.168.0.2 peer-group VTEP
+ neighbor 192.168.0.3 peer-group VTEP
+ !
+ address-family l2vpn evpn
+  neighbor VTEP route-map MAP_VTEP_IN in
+  neighbor VTEP route-map MAP_VTEP_OUT out
+  neighbor VTEP activate
+  advertise-all-vni
+ exit-address-family
+exit
+!
+router bgp 65000 vrf vrf_myzone
+ bgp router-id 192.168.0.1
+exit
+!
+router bgp 65000 vrf vrf_myzone2
+ bgp router-id 192.168.0.1
+exit
+!
+route-map MAP_VTEP_IN permit 1
+exit
+!
+route-map MAP_VTEP_OUT permit 1
+exit
+!
+line vty
+!
\ No newline at end of file
diff --git a/test/zones/evpn/multiplezones/expected_sdn_interfaces b/test/zones/evpn/multiplezones/expected_sdn_interfaces
new file mode 100644
index 0000000..e279b0a
--- /dev/null
+++ b/test/zones/evpn/multiplezones/expected_sdn_interfaces
@@ -0,0 +1,81 @@
+#version:1
+
+auto myvnet
+iface myvnet
+	address 10.0.0.1/24
+	bridge_ports vxlan_myvnet
+	bridge_stp off
+	bridge_fd 0
+	mtu 1450
+	ip-forward on
+	arp-accept on
+	vrf vrf_myzone
+
+auto myvnet2
+iface myvnet2
+	address 172.16.0.1/24
+	bridge_ports vxlan_myvnet2
+	bridge_stp off
+	bridge_fd 0
+	mtu 1450
+	ip-forward on
+	arp-accept on
+	vrf vrf_myzone2
+
+auto vrf_myzone
+iface vrf_myzone
+	vrf-table auto
+	post-up ip route add vrf vrf_myzone unreachable default metric 4278198272
+
+auto vrf_myzone2
+iface vrf_myzone2
+	vrf-table auto
+	post-up ip route add vrf vrf_myzone2 unreachable default metric 4278198272
+
+auto vrfbr_myzone
+iface vrfbr_myzone
+	bridge-ports vrfvx_myzone
+	bridge_stp off
+	bridge_fd 0
+	mtu 1450
+	vrf vrf_myzone
+
+auto vrfbr_myzone2
+iface vrfbr_myzone2
+	bridge-ports vrfvx_myzone2
+	bridge_stp off
+	bridge_fd 0
+	mtu 1450
+	vrf vrf_myzone2
+
+auto vrfvx_myzone
+iface vrfvx_myzone
+	vxlan-id 1000
+	vxlan-local-tunnelip 192.168.0.1
+	bridge-learning off
+	bridge-arp-nd-suppress on
+	mtu 1450
+
+auto vrfvx_myzone2
+iface vrfvx_myzone2
+	vxlan-id 1001
+	vxlan-local-tunnelip 192.168.0.1
+	bridge-learning off
+	bridge-arp-nd-suppress on
+	mtu 1450
+
+auto vxlan_myvnet
+iface vxlan_myvnet
+	vxlan-id 100
+	vxlan-local-tunnelip 192.168.0.1
+	bridge-learning off
+	bridge-arp-nd-suppress on
+	mtu 1450
+
+auto vxlan_myvnet2
+iface vxlan_myvnet2
+	vxlan-id 101
+	vxlan-local-tunnelip 192.168.0.1
+	bridge-learning off
+	bridge-arp-nd-suppress on
+	mtu 1450
diff --git a/test/zones/evpn/multiplezones/interfaces b/test/zones/evpn/multiplezones/interfaces
new file mode 100644
index 0000000..66bb826
--- /dev/null
+++ b/test/zones/evpn/multiplezones/interfaces
@@ -0,0 +1,7 @@
+auto vmbr0
+iface vmbr0 inet static
+	address 192.168.0.1/24
+	gateway 192.168.0.254
+        bridge-ports eth0
+        bridge-stp off
+        bridge-fd 0
diff --git a/test/zones/evpn/multiplezones/sdn_config b/test/zones/evpn/multiplezones/sdn_config
new file mode 100644
index 0000000..6ffdfb9
--- /dev/null
+++ b/test/zones/evpn/multiplezones/sdn_config
@@ -0,0 +1,37 @@
+{
+  version => 1,
+  vnets   => {
+               ids => {
+                        myvnet => { tag => "100", type => "vnet", zone => "myzone" },
+                        myvnet2 => { tag => "101", type => "vnet", zone => "myzone2" },
+                      },
+             },
+
+  zones   => {
+		ids => { 
+			myzone => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1000 },
+			myzone2 => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1001 },
+		}
+             },
+  controllers  => {
+               ids => { evpnctl => { type => "evpn", 'peers' => '192.168.0.1,192.168.0.2,192.168.0.3', asn => "65000" } },
+             },
+
+  subnets => {
+		ids => { 
+			'myzone-10.0.0.0-24' => {
+			    'type' => 'subnet',
+			    'vnet' => 'myvnet',
+			    'gateway' => '10.0.0.1',
+			},
+			'myzone2-172.16.0.0-24' => {
+			    'type' => 'subnet',
+			    'vnet' => 'myvnet2',
+			    'gateway' => '172.16.0.1',
+			},
+		}
+  }
+
+}
+
+
-- 
2.30.2





More information about the pve-devel mailing list