[pve-devel] [PATCH pve-network 1/2] generate_frr_config: cleanup hash and ordering
Alexandre Derumier
aderumier at odiso.com
Fri Sep 6 15:14:31 CEST 2019
Signed-off-by: Alexandre Derumier <aderumier at 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
More information about the pve-devel
mailing list