]> git.puffer.fish Git - mirror/pve-network.git/commitdiff
fix #4389: evpn: exit nodes: null routes subnets from other zones
authorAlexandre Derumier <aderumier@odiso.com>
Thu, 20 Apr 2023 21:36:20 +0000 (23:36 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 6 Jun 2023 08:23:57 +0000 (10:23 +0200)
We don't want to routes subnets between different zones when same
exit node is used.

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
src/PVE/Network/SDN/Controllers/EvpnPlugin.pm
src/PVE/Network/SDN/Vnets.pm
src/test/zones/evpn/exitnodenullroute/expected_controller_config [new file with mode: 0644]
src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces [new file with mode: 0644]
src/test/zones/evpn/exitnodenullroute/interfaces [new file with mode: 0644]
src/test/zones/evpn/exitnodenullroute/sdn_config [new file with mode: 0644]

index 19441782500c639d3e641418f64cd72e85d7c58a..b1eb845a7fbe0405dc3af979ac3c905f7f51345f 100644 (file)
@@ -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) {
index 0b32c58c5c7ea5b15f597bd30720ec0af700c2f6..1106c9f6d72894ec875810557839fd5504393e96 100644 (file)
@@ -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/src/test/zones/evpn/exitnodenullroute/expected_controller_config b/src/test/zones/evpn/exitnodenullroute/expected_controller_config
new file mode 100644 (file)
index 0000000..f461f1e
--- /dev/null
@@ -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/src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces b/src/test/zones/evpn/exitnodenullroute/expected_sdn_interfaces
new file mode 100644 (file)
index 0000000..b6d9c13
--- /dev/null
@@ -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/src/test/zones/evpn/exitnodenullroute/interfaces b/src/test/zones/evpn/exitnodenullroute/interfaces
new file mode 100644 (file)
index 0000000..66bb826
--- /dev/null
@@ -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/src/test/zones/evpn/exitnodenullroute/sdn_config b/src/test/zones/evpn/exitnodenullroute/sdn_config
new file mode 100644 (file)
index 0000000..1060f83
--- /dev/null
@@ -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',
+                       },
+               }
+  }
+
+}
+
+