]> git.proxmox.com Git - pve-network.git/commitdiff
generate_frr_config: cleanup hash and ordering
authorAlexandre Derumier <aderumier@odiso.com>
Mon, 9 Sep 2019 06:45:50 +0000 (08:45 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Mon, 9 Sep 2019 14:36:43 +0000 (16:36 +0200)
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
PVE/Network/SDN.pm
PVE/Network/SDN/FrrPlugin.pm
PVE/Network/SDN/VxlanPlugin.pm

index 1d84a32e9f1a8d9090715170d99ff86ebe0a08d8..d72b94aa8cf46a2ef6d07d8d59e0a6df5c119265 100644 (file)
@@ -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) = @_;
 
index 2559b105ce01346c1fe83d20ca27a588b019b017..772d7d24c77aa260ce2e1947739d9b9fddc31696 100644 (file)
@@ -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;
 }
index 733412e71003ee23b6fbdffef02e14124cee48dc..9ab0adef456730a9cf650b125ad16519cd8c9999 100644 (file)
@@ -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;