Signed-off-by: Alexandre Derumier <aderum...@odiso.com> --- PVE/Network/SDN.pm | 99 ++++++++++++++++++++++++++-------- PVE/Network/SDN/FrrPlugin.pm | 13 +++-- PVE/Network/SDN/VxlanPlugin.pm | 18 ++----- 3 files changed, 87 insertions(+), 43 deletions(-)
diff --git a/PVE/Network/SDN.pm b/PVE/Network/SDN.pm index 1d84a32..d72b94a 100644 --- a/PVE/Network/SDN.pm +++ b/PVE/Network/SDN.pm @@ -221,35 +221,88 @@ sub generate_frr_config { } } - my $raw_frr_config = "log syslog informational\n"; - $raw_frr_config .= "!\n"; - - #vrf first - my $vrfconfig = $config->{vrf}; - foreach my $vrf (sort keys %$vrfconfig) { - $raw_frr_config .= "$vrf\n"; - foreach my $option (@{$vrfconfig->{$vrf}}) { - $raw_frr_config .= " $option\n"; - } - $raw_frr_config .= "!\n"; - } + my $final_config = []; + push @{$final_config}, "log syslog informational"; - #routers - my $routerconfig = $config->{router}; - foreach my $router (sort keys %$routerconfig) { - $raw_frr_config .= "$router\n"; - foreach my $option (@{$routerconfig->{$router}}) { - $raw_frr_config .= " $option\n"; - } - $raw_frr_config .= "!\n"; - } + generate_frr_recurse($final_config, $config, undef, 0); - $raw_frr_config .= "line vty\n"; - $raw_frr_config .= "!\n"; + push @{$final_config}, "!"; + push @{$final_config}, "line vty"; + push @{$final_config}, "!"; + my $raw_frr_config = join("\n", @{$final_config}); return $raw_frr_config; } +sub sort_frr_config { + my $order = {}; + $order->{''} = 0; + $order->{'vrf'} = 1; + $order->{'ipv4 unicast'} = 1; + $order->{'l2vpn evpn'} = 2; + + 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; + + #fix me, make this generic + my $paddinglevel = undef; + if($level == 1 || $level == 2) { + $paddinglevel = $level - 1; + } elsif ($level == 3 || $level == 4) { + $paddinglevel = $level - 2; + } + + my $padding = ""; + $padding = ' ' x ($paddinglevel) if $paddinglevel; + + if (ref $content eq ref {}) { + foreach my $key (sort sort_frr_config keys %$content) { + if ($parentkey && defined($keylist->{$parentkey})) { + push @{$final_config}, $padding."!"; + push @{$final_config}, $padding."$parentkey $key"; + } else { + push @{$final_config}, $padding."$key" if $key ne '' && !defined($keylist->{$key}); + } + + my $option = $content->{$key}; + generate_frr_recurse($final_config, $option, $key, $level+1); + + push @{$final_config}, $padding."exit-$parentkey" if $parentkey && defined($exitkeylist->{$parentkey}); + } + } + + if (ref $content eq 'ARRAY') { + foreach my $value (@$content) { + push @{$final_config}, $padding."$value"; + } + } +} sub write_etc_network_config { my ($rawconfig) = @_; diff --git a/PVE/Network/SDN/FrrPlugin.pm b/PVE/Network/SDN/FrrPlugin.pm index 2559b10..772d7d2 100644 --- a/PVE/Network/SDN/FrrPlugin.pm +++ b/PVE/Network/SDN/FrrPlugin.pm @@ -49,6 +49,7 @@ sub generate_frr_config { $ifaceip = PVE::Network::SDN::Plugin::get_first_local_ipv4_from_interface($iface); } + my @router_config = (); push @router_config, "bgp router-id $ifaceip"; @@ -58,16 +59,14 @@ sub generate_frr_config { next if $address eq $ifaceip; push @router_config, "neighbor $address remote-as $asn"; } - push @router_config, "!"; - push @router_config, "address-family l2vpn evpn"; + push(@{$config->{router}->{"bgp $asn"}->{""}}, @router_config); + @router_config = (); foreach my $address (@peers) { next if $address eq $ifaceip; - push @router_config, " neighbor $address activate"; + push @router_config, "neighbor $address activate"; } - push @router_config, " advertise-all-vni"; - push @router_config, "exit-address-family"; - - push(@{$config->{router}->{"router bgp $asn"}}, @router_config); + push @router_config, "advertise-all-vni"; + push(@{$config->{router}->{"bgp $asn"}->{"address-family"}->{"l2vpn evpn"}}, @router_config); return $config; } diff --git a/PVE/Network/SDN/VxlanPlugin.pm b/PVE/Network/SDN/VxlanPlugin.pm index 733412e..9ab0ade 100644 --- a/PVE/Network/SDN/VxlanPlugin.pm +++ b/PVE/Network/SDN/VxlanPlugin.pm @@ -178,9 +178,7 @@ sub generate_frr_config { #vrf my @router_config = (); push @router_config, "vni $vrfvxlan"; - push @router_config, "exit-vrf"; - push(@{$config->{vrf}->{"vrf $vrf"}}, @router_config); - + push(@{$config->{vrf}->{"$vrf"}}, @router_config); @router_config = (); @@ -197,20 +195,14 @@ sub generate_frr_config { #import /32 routes of evpn network from vrf1 to default vrf (for packet return) #frr 7.1 tag is bugged -> works fine with 7.1 stable branch(20190829-02-g6ba76bbc1) #https://github.com/FRRouting/frr/issues/4905 - push @router_config, "!"; - push @router_config, "address-family ipv4 unicast"; - push @router_config, " import vrf $vrf"; - push @router_config, "exit-address-family"; - push(@{$config->{router}->{"router bgp $asn"}}, @router_config); + push @router_config, "import vrf $vrf"; + push(@{$config->{router}->{"bgp $asn"}->{"address-family"}->{"ipv4 unicast"}}, @router_config); @router_config = (); #add default originate to announce 0.0.0.0/0 type5 route in evpn - push @router_config, "!"; - push @router_config, "address-family l2vpn evpn"; - push @router_config, " default-originate ipv4"; - push @router_config, "exit-address-family"; - push(@{$config->{router}->{"router bgp $asn vrf $vrf"}}, @router_config); + push @router_config, "default-originate ipv4"; + push(@{$config->{router}->{"bgp $asn vrf $vrf"}->{"address-family"}->{"l2vpn evpn"}}, @router_config); } return $config; -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel