[pve-devel] [PATCH pve-network 4/6] fix #4389 : evpn: exit nodes : null routes subnets from other zones

Alexandre Derumier aderumier at odiso.com
Thu Apr 20 23:36:20 CEST 2023


We don't want to routes subnets betwen differents when same exit
node is used

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/Network/SDN/Controllers/EvpnPlugin.pm     | 15 ++-
 PVE/Network/SDN/Vnets.pm                      |  4 +-
 .../expected_controller_config                | 98 +++++++++++++++++++
 .../exitnodenullroute/expected_sdn_interfaces | 81 +++++++++++++++
 test/zones/evpn/exitnodenullroute/interfaces  |  7 ++
 test/zones/evpn/exitnodenullroute/sdn_config  | 42 ++++++++
 6 files changed, 242 insertions(+), 5 deletions(-)
 create mode 100644 test/zones/evpn/exitnodenullroute/expected_controller_config
 create mode 100644 test/zones/evpn/exitnodenullroute/expected_sdn_interfaces
 create mode 100644 test/zones/evpn/exitnodenullroute/interfaces
 create mode 100644 test/zones/evpn/exitnodenullroute/sdn_config

diff --git a/PVE/Network/SDN/Controllers/EvpnPlugin.pm b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
index 1944178..b1eb845 100644
--- a/PVE/Network/SDN/Controllers/EvpnPlugin.pm
+++ b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
@@ -144,10 +144,23 @@ sub generate_controller_zone_config {
     return if !$vrf || !$vrfvxlan || !$asn;
 
     my ($ifaceip, $interface) = PVE::Network::SDN::Zones::Plugin::find_local_ip_interface_peers(\@peers, $loopback);
+    my $is_gateway = $exitnodes->{$local_node};
 
     # vrf
     my @controller_config = ();
     push @controller_config, "vni $vrfvxlan";
+    #avoid to routes between nodes through the exit nodes
+    #null routes subnets of other zones
+    if ($is_gateway) {
+	my $subnets = PVE::Network::SDN::Vnets::get_subnets();
+	foreach my $subnetid (sort keys %{$subnets}) {
+	    my $subnet = $subnets->{$subnetid};
+	    my $cidr = $subnet->{cidr};
+	    my $zone = $subnet->{zone};
+	    push @controller_config, "ip route $cidr null0" if $zone ne $id;
+	}
+    }
+
     push(@{$config->{frr}->{vrf}->{"$vrf"}}, @controller_config);
 
     #main vrf router
@@ -161,8 +174,6 @@ sub generate_controller_zone_config {
 	push(@{$config->{frr}->{router}->{"bgp $asn vrf $vrf"}->{"address-family"}->{"l2vpn evpn"}}, "route-target export $autortas:$vrfvxlan");
     }
 
-    my $is_gateway = $exitnodes->{$local_node};
-
     if ($is_gateway) {
 
 	if (!$exitnodes_primary || $exitnodes_primary eq $local_node) {
diff --git a/PVE/Network/SDN/Vnets.pm b/PVE/Network/SDN/Vnets.pm
index 0b32c58..1106c9f 100644
--- a/PVE/Network/SDN/Vnets.pm
+++ b/PVE/Network/SDN/Vnets.pm
@@ -70,13 +70,11 @@ sub get_vnet {
 sub get_subnets {
     my ($vnetid) = @_;
 
-    return if !$vnetid;
-
     my $subnets = undef;
     my $subnets_cfg = PVE::Network::SDN::Subnets::config();
     foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
 	my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($subnets_cfg, $subnetid);
-	next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid;
+	next if !$subnet->{vnet} || ($vnetid && $subnet->{vnet} ne $vnetid);
 	$subnets->{$subnetid} = $subnet;
     }
     return $subnets;
diff --git a/test/zones/evpn/exitnodenullroute/expected_controller_config b/test/zones/evpn/exitnodenullroute/expected_controller_config
new file mode 100644
index 0000000..f461f1e
--- /dev/null
+++ b/test/zones/evpn/exitnodenullroute/expected_controller_config
@@ -0,0 +1,98 @@
+frr version 8.2.2
+frr defaults datacenter
+hostname localhost
+log syslog informational
+service integrated-vtysh-config
+!
+!
+vrf vrf_myzone
+ vni 1000
+ ip route 172.16.0.0/24 null0
+ ip route 172.16.1.0/24 null0
+exit-vrf
+!
+vrf vrf_myzone2
+ vni 1001
+ ip route 10.0.0.0/24 null0
+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 ipv4 unicast
+  import vrf vrf_myzone
+  import vrf vrf_myzone2
+ exit-address-family
+ !
+ address-family ipv6 unicast
+  import vrf vrf_myzone
+  import vrf vrf_myzone2
+ exit-address-family
+ !
+ 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
+ !
+ address-family ipv4 unicast
+  redistribute connected
+ exit-address-family
+ !
+ address-family ipv6 unicast
+  redistribute connected
+ exit-address-family
+ !
+ address-family l2vpn evpn
+  default-originate ipv4
+  default-originate ipv6
+ exit-address-family
+exit
+!
+router bgp 65000 vrf vrf_myzone2
+ bgp router-id 192.168.0.1
+ !
+ address-family ipv4 unicast
+  redistribute connected
+ exit-address-family
+ !
+ address-family ipv6 unicast
+  redistribute connected
+ exit-address-family
+ !
+ address-family l2vpn evpn
+  default-originate ipv4
+  default-originate ipv6
+ exit-address-family
+exit
+!
+route-map MAP_VTEP_IN deny 1
+ match evpn vni 1001
+ match evpn route-type prefix
+exit
+!
+route-map MAP_VTEP_IN deny 2
+ match evpn vni 1000
+ match evpn route-type prefix
+exit
+!
+route-map MAP_VTEP_IN permit 3
+exit
+!
+route-map MAP_VTEP_OUT permit 1
+exit
+!
+line vty
+!
\ No newline at end of file
diff --git a/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces b/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces
new file mode 100644
index 0000000..b6d9c13
--- /dev/null
+++ b/test/zones/evpn/exitnodenullroute/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 del vrf vrf_myzone unreachable default metric 4278198272
+
+auto vrf_myzone2
+iface vrf_myzone2
+	vrf-table auto
+	post-up ip route del 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/exitnodenullroute/interfaces b/test/zones/evpn/exitnodenullroute/interfaces
new file mode 100644
index 0000000..66bb826
--- /dev/null
+++ b/test/zones/evpn/exitnodenullroute/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/exitnodenullroute/sdn_config b/test/zones/evpn/exitnodenullroute/sdn_config
new file mode 100644
index 0000000..1060f83
--- /dev/null
+++ b/test/zones/evpn/exitnodenullroute/sdn_config
@@ -0,0 +1,42 @@
+{
+  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, exitnodes => { 'localhost' => 1 } },
+			myzone2 => { ipam => "pve", type => "evpn", controller => "evpnctl", 'vrf-vxlan' => 1001, exitnodes => { 'localhost' => 1 } },
+		}
+             },
+  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',
+			},
+			'myzone2-172.16.1.0-24' => {
+			    'type' => 'subnet',
+			    'vnet' => 'myvnet2',
+			    'gateway' => '172.16.0.1',
+			},
+		}
+  }
+
+}
+
+
-- 
2.30.2





More information about the pve-devel mailing list