]> git.proxmox.com Git - pve-network.git/commitdiff
make Vxlanplugin generic for multicast/unicast/frr
authorAlexandre Derumier <aderumier@odiso.com>
Thu, 29 Aug 2019 10:32:46 +0000 (12:32 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 3 Sep 2019 06:22:56 +0000 (08:22 +0200)
if no multicast or unicast address is defined, default to frr

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
PVE/API2/Network/SDN.pm
PVE/Network/SDN.pm
PVE/Network/SDN/Makefile
PVE/Network/SDN/Plugin.pm
PVE/Network/SDN/VxlanMulticastPlugin.pm [deleted file]
PVE/Network/SDN/VxlanPlugin.pm [new file with mode: 0644]

index 7baf7eea86801d4867308520305dc259068f3b2b..22b26f85be387e21b83d7400d1187f5ef56b7470 100644 (file)
@@ -9,7 +9,7 @@ use PVE::Cluster qw(cfs_read_file cfs_write_file);
 use PVE::Network::SDN;
 use PVE::Network::SDN::Plugin;
 use PVE::Network::SDN::VlanPlugin;
-use PVE::Network::SDN::VxlanMulticastPlugin;
+use PVE::Network::SDN::VxlanPlugin;
 use PVE::Network::SDN::VnetPlugin;
 use Storable qw(dclone);
 use PVE::JSONSchema qw(get_standard_option);
index 1b1529b0c1f538eee94ff1090a4aba53fb4a5ae2..1b060e7dc7b47376b729388deec43d6fcb1eb2a3 100644 (file)
@@ -11,11 +11,11 @@ use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::Network::SDN::Plugin;
 use PVE::Network::SDN::VnetPlugin;
 use PVE::Network::SDN::VlanPlugin;
-use PVE::Network::SDN::VxlanMulticastPlugin;
+use PVE::Network::SDN::VxlanPlugin;
 
 PVE::Network::SDN::VnetPlugin->register();
 PVE::Network::SDN::VlanPlugin->register();
-PVE::Network::SDN::VxlanMulticastPlugin->register();
+PVE::Network::SDN::VxlanPlugin->register();
 PVE::Network::SDN::Plugin->init();
 
 
index 194a7089ab9cd0b96bc37a5b2483b9028bc72aa6..19a8e35869d62be59c52201800e81313f4594de9 100644 (file)
@@ -1,4 +1,4 @@
-SOURCES=Plugin.pm VnetPlugin.pm VlanPlugin.pm  VxlanMulticastPlugin.pm
+SOURCES=Plugin.pm VnetPlugin.pm VlanPlugin.pm  VxlanPlugin.pm
 
 
 PERL5DIR=${DESTDIR}/usr/share/perl5
index a76442b26d122ef4b3b8e6bf96af7260c33016ea..36efbe17f8514c5e852a572a41080908d11e3512 100644 (file)
@@ -121,4 +121,26 @@ sub parse_tag_number_or_range {
     return (scalar(@elements) > 1);
 }
 
+#to be move to Network.pm helper
+sub get_first_local_ipv4_from_interface {
+    my ($interface) = @_;
+
+    my $cmd = ['/sbin/ip', 'address', 'show', 'dev', $interface];
+
+    my $IP = "";
+
+    my $code = sub {
+       my $line = shift;
+
+       if ($line =~ m!^\s*inet\s+($PVE::Tools::IPRE)(?:/\d+|\s+peer\s+)!) {
+           $IP = $1;
+           return;
+       }
+    };
+
+    PVE::Tools::run_command($cmd, outfunc => $code);
+
+    return $IP;
+}
+
 1;
diff --git a/PVE/Network/SDN/VxlanMulticastPlugin.pm b/PVE/Network/SDN/VxlanMulticastPlugin.pm
deleted file mode 100644 (file)
index ac60734..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-package PVE::Network::SDN::VxlanMulticastPlugin;
-
-use strict;
-use warnings;
-use PVE::Network::SDN::Plugin;
-
-use base('PVE::Network::SDN::Plugin');
-
-PVE::JSONSchema::register_format('pve-sdn-vxlanrange', \&pve_verify_sdn_vxlanrange);
-sub pve_verify_sdn_vxlanrange {
-   my ($vxlanstr) = @_;
-
-   PVE::Network::SDN::Plugin::parse_tag_number_or_range($vxlanstr, '16777216');
-
-   return $vxlanstr;
-}
-
-sub type {
-    return 'vxlanmulticast';
-}
-
-sub properties {
-    return {
-        'vxlan-allowed' => {
-            type => 'string', format => 'pve-sdn-vxlanrange',
-            description => "Allowed vlan range",
-        },
-        'multicast-address' => {
-            description => "Multicast address.",
-            type => 'string',  #fixme: format 
-        },
-
-    };
-}
-
-sub options {
-
-    return {
-       'uplink-id' => { optional => 0 },
-        'multicast-address' => { optional => 0 },
-        'vxlan-allowed' => { optional => 1 },
-    };
-}
-
-# Plugin implementation
-sub generate_sdn_config {
-    my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks) = @_;
-
-    my $tag = $vnet->{tag};
-    my $alias = $vnet->{alias};
-    my $multicastaddress = $plugin_config->{'multicast-address'};
-    my $uplink = $plugin_config->{'uplink-id'};
-    my $vxlanallowed = $plugin_config->{'vxlan-allowed'};
-
-    die "missing vxlan tag" if !$tag;
-    my $iface = $uplinks->{$uplink}->{name} ? $uplinks->{$uplink}->{name} : "uplink$uplink";
-
-    my $mtu = 1450;
-    $mtu = $uplinks->{$uplink}->{mtu} - 50 if $uplinks->{$uplink}->{mtu};
-    $mtu = $vnet->{mtu} if $vnet->{mtu};
-
-    my $config = "\n";
-    $config .= "auto vxlan$vnetid\n";
-    $config .= "iface vxlan$vnetid inet manual\n";
-    $config .= "       vxlan-id $tag\n";
-    $config .= "       vxlan-svcnodeip $multicastaddress\n" if $multicastaddress;
-    $config .= "       vxlan-physdev $iface\n" if $iface;
-    $config .= "       mtu $mtu\n" if $mtu;
-    $config .= "\n";
-    $config .= "auto $vnetid\n";
-    $config .= "iface $vnetid inet manual\n";
-    $config .= "        bridge_ports vxlan$vnetid\n";
-    $config .= "        bridge_stp off\n";
-    $config .= "        bridge_fd 0\n";
-    $config .= "        mtu $mtu\n" if $mtu;
-    $config .= "        alias $alias\n" if $alias;
-
-    return $config;
-}
-
-sub on_delete_hook {
-    my ($class, $transportid, $sdn_cfg) = @_;
-
-    # verify that no vnet are associated to this transport
-    foreach my $id (keys %{$sdn_cfg->{ids}}) {
-       my $sdn = $sdn_cfg->{ids}->{$id};
-       die "transport $transportid is used by vnet $id" 
-           if ($sdn->{type} eq 'vnet' && defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid);
-    }
-}
-
-sub on_update_hook {
-    my ($class, $transportid, $sdn_cfg) = @_;
-
-    my $transport = $sdn_cfg->{ids}->{$transportid};
-
-    # verify that vxlan-allowed don't conflict with another vxlan-allowed transport
-
-    # verify that vxlan-allowed is matching currently vnet tag in this transport  
-    my $vxlanallowed = $transport->{'vxlan-allowed'};
-    if ($vxlanallowed) {
-       foreach my $id (keys %{$sdn_cfg->{ids}}) {
-           my $sdn = $sdn_cfg->{ids}->{$id};
-           if ($sdn->{type} eq 'vnet' && defined($sdn->{tag})) {
-               if(defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid) {
-                   my $tag = $sdn->{tag};
-                   eval {
-                       PVE::Network::SDN::Plugin::parse_tag_number_or_range($vxlanallowed, '16777216', $tag);
-                   };
-                   if($@) {
-                       die "vnet $id - vlan $tag is not allowed in transport $transportid";
-                   }
-               }
-           }
-       }
-    }
-}
-
-1;
-
-
diff --git a/PVE/Network/SDN/VxlanPlugin.pm b/PVE/Network/SDN/VxlanPlugin.pm
new file mode 100644 (file)
index 0000000..ae1f86a
--- /dev/null
@@ -0,0 +1,150 @@
+package PVE::Network::SDN::VxlanPlugin;
+
+use strict;
+use warnings;
+use PVE::Network::SDN::Plugin;
+use PVE::Tools;
+
+use base('PVE::Network::SDN::Plugin');
+
+PVE::JSONSchema::register_format('pve-sdn-vxlanrange', \&pve_verify_sdn_vxlanrange);
+sub pve_verify_sdn_vxlanrange {
+   my ($vxlanstr) = @_;
+
+   PVE::Network::SDN::Plugin::parse_tag_number_or_range($vxlanstr, '16777216');
+
+   return $vxlanstr;
+}
+
+sub type {
+    return 'vxlan';
+}
+
+sub properties {
+    return {
+        'vxlan-allowed' => {
+            type => 'string', format => 'pve-sdn-vxlanrange',
+            description => "Allowed vlan range",
+        },
+        'multicast-address' => {
+            description => "Multicast address.",
+            type => 'string',  #fixme: format 
+        },
+       'unicast-address' => {
+           description => "Unicast peers address ip list.",
+           type => 'string',  #fixme: format 
+       },
+    };
+}
+
+sub options {
+
+    return {
+       'uplink-id' => { optional => 0 },
+        'multicast-address' => { optional => 1 },
+        'unicast-address' => { optional => 1 },
+        'vxlan-allowed' => { optional => 1 },
+    };
+}
+
+# Plugin implementation
+sub generate_sdn_config {
+    my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks) = @_;
+
+    my $tag = $vnet->{tag};
+    my $alias = $vnet->{alias};
+    my $multicastaddress = $plugin_config->{'multicast-address'};
+    my @unicastaddress = split(',', $plugin_config->{'unicast-address'}) if $plugin_config->{'unicast-address'};
+
+    my $uplink = $plugin_config->{'uplink-id'};
+    my $vxlanallowed = $plugin_config->{'vxlan-allowed'};
+
+    die "missing vxlan tag" if !$tag;
+    my $iface = "uplink$uplink";
+    my $ifaceip = "";
+
+    if($uplinks->{$uplink}->{name}) {
+       $iface = $uplinks->{$uplink}->{name};
+       $ifaceip = PVE::Network::SDN::Plugin::get_first_local_ipv4_from_interface($iface);
+    }
+
+    my $mtu = 1450;
+    $mtu = $uplinks->{$uplink}->{mtu} - 50 if $uplinks->{$uplink}->{mtu};
+    $mtu = $vnet->{mtu} if $vnet->{mtu};
+
+    my $config = "\n";
+    $config .= "auto vxlan$vnetid\n";
+    $config .= "iface vxlan$vnetid inet manual\n";
+    $config .= "       vxlan-id $tag\n";
+
+    if($multicastaddress) {
+       $config .= "       vxlan-svcnodeip $multicastaddress\n";
+       $config .= "       vxlan-physdev $iface\n";
+    } elsif (@unicastaddress) {
+
+       foreach my $address (@unicastaddress) {
+           next if $address eq $ifaceip;
+           $config .= "       vxlan_remoteip $address\n";
+       }
+    } else {
+       $config .= "       vxlan-local-tunnelip $ifaceip\n" if $ifaceip;
+       $config .= "       bridge-learning off\n";
+       $config .= "       bridge-arp-nd-suppress on\n";
+       $config .= "       bridge-unicast-flood off\n";
+       $config .= "       bridge-multicast-flood off\n";
+    }
+
+    $config .= "       mtu $mtu\n" if $mtu;
+    $config .= "\n";
+    $config .= "auto $vnetid\n";
+    $config .= "iface $vnetid inet manual\n";
+    $config .= "       bridge_ports vxlan$vnetid\n";
+    $config .= "       bridge_stp off\n";
+    $config .= "       bridge_fd 0\n";
+    $config .= "       mtu $mtu\n" if $mtu;
+    $config .= "       alias $alias\n" if $alias;
+
+    return $config;
+}
+
+sub on_delete_hook {
+    my ($class, $transportid, $sdn_cfg) = @_;
+
+    # verify that no vnet are associated to this transport
+    foreach my $id (keys %{$sdn_cfg->{ids}}) {
+       my $sdn = $sdn_cfg->{ids}->{$id};
+       die "transport $transportid is used by vnet $id" 
+           if ($sdn->{type} eq 'vnet' && defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid);
+    }
+}
+
+sub on_update_hook {
+    my ($class, $transportid, $sdn_cfg) = @_;
+
+    my $transport = $sdn_cfg->{ids}->{$transportid};
+
+    # verify that vxlan-allowed don't conflict with another vxlan-allowed transport
+
+    # verify that vxlan-allowed is matching currently vnet tag in this transport  
+    my $vxlanallowed = $transport->{'vxlan-allowed'};
+    if ($vxlanallowed) {
+       foreach my $id (keys %{$sdn_cfg->{ids}}) {
+           my $sdn = $sdn_cfg->{ids}->{$id};
+           if ($sdn->{type} eq 'vnet' && defined($sdn->{tag})) {
+               if(defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid) {
+                   my $tag = $sdn->{tag};
+                   eval {
+                       PVE::Network::SDN::Plugin::parse_tag_number_or_range($vxlanallowed, '16777216', $tag);
+                   };
+                   if($@) {
+                       die "vnet $id - vlan $tag is not allowed in transport $transportid";
+                   }
+               }
+           }
+       }
+    }
+}
+
+1;
+
+