From: Alexandre Derumier Date: Thu, 28 Nov 2019 08:40:24 +0000 (+0100) Subject: evpn: remove uplink-id X-Git-Url: https://git.proxmox.com/?p=pve-network.git;a=commitdiff_plain;h=4405f2ded1411401b3199298059db95aeef926b9 evpn: remove uplink-id instead, auto find interfaces Signed-off-by: Alexandre Derumier --- diff --git a/PVE/Network/SDN/Controllers/EvpnPlugin.pm b/PVE/Network/SDN/Controllers/EvpnPlugin.pm index 0693e21..66b4568 100644 --- a/PVE/Network/SDN/Controllers/EvpnPlugin.pm +++ b/PVE/Network/SDN/Controllers/EvpnPlugin.pm @@ -3,7 +3,7 @@ package PVE::Network::SDN::Controllers::EvpnPlugin; use strict; use warnings; use PVE::Network::SDN::Controllers::Plugin; -use PVE::Tools; +use PVE::Tools qw(run_command); use PVE::INotify; use PVE::JSONSchema qw(get_standard_option); @@ -15,11 +15,6 @@ sub type { sub properties { return { - 'uplink-id' => { - type => 'integer', - minimum => 1, maximum => 4096, - description => 'Uplink interface', - }, 'asn' => { type => 'integer', description => "autonomous system number", @@ -39,7 +34,6 @@ sub properties { sub options { return { - 'uplink-id' => { optional => 0 }, 'asn' => { optional => 0 }, 'peers' => { optional => 0 }, 'gateway-nodes' => { optional => 1 }, @@ -47,6 +41,46 @@ sub options { }; } +sub get_local_route_ip { + my ($targetip) = @_; + + my $ip = undef; + my $interface = undef; + + run_command(['/sbin/ip', 'route', 'get', $targetip], outfunc => sub { + if ($_[0] =~ m/src ($PVE::Tools::IPRE)/) { + $ip = $1; + } + if ($_[0] =~ m/dev (\S+)/) { + $interface = $1; + } + + }); + return ($ip, $interface); +} + +sub find_local_ip_interface { + my ($peers) = @_; + + my $network_config = PVE::INotify::read_file('interfaces'); + my $ifaces = $network_config->{ifaces}; + #is a local ip member of peers list ? + foreach my $address (@{$peers}) { + while (my $interface = each %$ifaces) { + my $ip = $ifaces->{$interface}->{address}; + if ($ip && $ip eq $address) { + return ($ip, $interface); + } + } + } + + #if peer is remote, find source with ip route + foreach my $address (@{$peers}) { + my ($ip, $interface) = get_local_route_ip($address); + return ($ip, $interface); + } +} + # Plugin implementation sub generate_controller_config { my ($class, $plugin_config, $controller, $id, $uplinks, $config) = @_; @@ -54,19 +88,12 @@ sub generate_controller_config { my @peers = split(',', $plugin_config->{'peers'}) if $plugin_config->{'peers'}; my $asn = $plugin_config->{asn}; - my $uplink = $plugin_config->{'uplink-id'}; my $gatewaynodes = $plugin_config->{'gateway-nodes'}; my @gatewaypeers = split(',', $plugin_config->{'gateway-external-peers'}) if $plugin_config->{'gateway-external-peers'}; return if !$asn; - my $iface = "uplink$uplink"; - my $ifaceip = ""; - - if($uplinks->{$uplink}->{name}) { - $iface = $uplinks->{$uplink}->{name}; - $ifaceip = PVE::Network::SDN::Controllers::Plugin::get_first_local_ipv4_from_interface($iface); - } + my ($ifaceip, $interface) = find_local_ip_interface(\@peers); my $is_gateway = undef; my $local_node = PVE::INotify::nodename(); diff --git a/PVE/Network/SDN/Controllers/Plugin.pm b/PVE/Network/SDN/Controllers/Plugin.pm index ce35574..04eddca 100644 --- a/PVE/Network/SDN/Controllers/Plugin.pm +++ b/PVE/Network/SDN/Controllers/Plugin.pm @@ -107,28 +107,4 @@ sub on_update_hook { # do nothing by default } -#helpers - -#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/Zones.pm b/PVE/Network/SDN/Zones.pm index 84ce60c..022d061 100644 --- a/PVE/Network/SDN/Zones.pm +++ b/PVE/Network/SDN/Zones.pm @@ -76,6 +76,7 @@ sub generate_etc_network_config { my $vnet_cfg = PVE::Cluster::cfs_read_file('sdn/vnets.cfg'); my $zone_cfg = PVE::Cluster::cfs_read_file('sdn/zones.cfg'); + my $controller_cfg = PVE::Cluster::cfs_read_file('sdn/controllers.cfg'); return if !$vnet_cfg && !$zone_cfg; #read main config for physical interfaces @@ -117,8 +118,14 @@ sub generate_etc_network_config { next if defined($plugin_config->{nodes}) && !$plugin_config->{nodes}->{$nodename}; + my $controller = undef; + if($plugin_config->{controller}) { + my $controllerid = $plugin_config->{controller}; + $controller = $controller_cfg->{ids}->{$controllerid}; + } + my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type}); - $plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $uplinks, $config); + $plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $uplinks, $controller, $config); } my $raw_network_config = ""; diff --git a/PVE/Network/SDN/Zones/EvpnPlugin.pm b/PVE/Network/SDN/Zones/EvpnPlugin.pm index 62382fb..c80408a 100644 --- a/PVE/Network/SDN/Zones/EvpnPlugin.pm +++ b/PVE/Network/SDN/Zones/EvpnPlugin.pm @@ -5,6 +5,7 @@ use warnings; use PVE::Network::SDN::Zones::VxlanPlugin; use PVE::Tools qw($IPV4RE); use PVE::INotify; +use PVE::Network::SDN::Controllers::EvpnPlugin; use base('PVE::Network::SDN::Zones::VxlanPlugin'); @@ -29,7 +30,6 @@ sub options { return { nodes => { optional => 1}, - 'uplink-id' => { optional => 0 }, 'vrf-vxlan' => { optional => 0 }, 'controller' => { optional => 0 }, }; @@ -37,7 +37,7 @@ sub options { # Plugin implementation sub generate_sdn_config { - my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_; + my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; my $tag = $vnet->{tag}; my $alias = $vnet->{alias}; @@ -45,21 +45,16 @@ sub generate_sdn_config { my $ipv6 = $vnet->{ipv6}; my $mac = $vnet->{mac}; - my $uplink = $plugin_config->{'uplink-id'}; my $vrf = $zoneid; my $vrfvxlan = $plugin_config->{'vrf-vxlan'}; die "missing vxlan tag" if !$tag; - my $iface = "uplink$uplink"; - my $ifaceip = ""; - if($uplinks->{$uplink}->{name}) { - $iface = $uplinks->{$uplink}->{name}; - $ifaceip = PVE::Network::SDN::Zones::Plugin::get_first_local_ipv4_from_interface($iface); - } + my @peers = split(',', $controller->{'peers'}); + my ($ifaceip, $iface) = PVE::Network::SDN::Controllers::EvpnPlugin::find_local_ip_interface(\@peers); my $mtu = 1450; - $mtu = $uplinks->{$uplink}->{mtu} - 50 if $uplinks->{$uplink}->{mtu}; + $mtu = $uplinks->{$iface}->{mtu} - 50 if $uplinks->{$iface}->{mtu}; $mtu = $vnet->{mtu} if $vnet->{mtu}; #vxlan interface diff --git a/PVE/Network/SDN/Zones/FaucetPlugin.pm b/PVE/Network/SDN/Zones/FaucetPlugin.pm index bece4e4..6093723 100644 --- a/PVE/Network/SDN/Zones/FaucetPlugin.pm +++ b/PVE/Network/SDN/Zones/FaucetPlugin.pm @@ -31,7 +31,7 @@ sub options { # Plugin implementation sub generate_sdn_config { - my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_; + my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; my $mtu = $vnet->{mtu}; my $uplink = $plugin_config->{'uplink-id'}; diff --git a/PVE/Network/SDN/Zones/Plugin.pm b/PVE/Network/SDN/Zones/Plugin.pm index 5d9aeff..7dd66e2 100644 --- a/PVE/Network/SDN/Zones/Plugin.pm +++ b/PVE/Network/SDN/Zones/Plugin.pm @@ -96,7 +96,7 @@ sub parse_section_header { } sub generate_sdn_config { - my ($class, $plugin_config, $node, $data, $ctime) = @_; + my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; die "please implement inside plugin"; } diff --git a/PVE/Network/SDN/Zones/QinQPlugin.pm b/PVE/Network/SDN/Zones/QinQPlugin.pm index 2036620..42b0dec 100644 --- a/PVE/Network/SDN/Zones/QinQPlugin.pm +++ b/PVE/Network/SDN/Zones/QinQPlugin.pm @@ -38,7 +38,7 @@ sub options { # Plugin implementation sub generate_sdn_config { - my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_; + my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; my $tag = $vnet->{tag}; my $zone_tag = $plugin_config->{tag}; diff --git a/PVE/Network/SDN/Zones/VlanPlugin.pm b/PVE/Network/SDN/Zones/VlanPlugin.pm index 8f957f3..8951e9b 100644 --- a/PVE/Network/SDN/Zones/VlanPlugin.pm +++ b/PVE/Network/SDN/Zones/VlanPlugin.pm @@ -39,7 +39,7 @@ sub options { # Plugin implementation sub generate_sdn_config { - my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_; + my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; my $tag = $vnet->{tag}; my $mtu = $vnet->{mtu}; diff --git a/PVE/Network/SDN/Zones/VxlanPlugin.pm b/PVE/Network/SDN/Zones/VxlanPlugin.pm index 956c950..a95d794 100644 --- a/PVE/Network/SDN/Zones/VxlanPlugin.pm +++ b/PVE/Network/SDN/Zones/VxlanPlugin.pm @@ -65,7 +65,7 @@ sub options { # Plugin implementation sub generate_sdn_config { - my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_; + my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $controller, $config) = @_; my $tag = $vnet->{tag}; my $alias = $vnet->{alias}; diff --git a/test/documentation.txt b/test/documentation.txt index 82e7e14..575027b 100644 --- a/test/documentation.txt +++ b/test/documentation.txt @@ -12,13 +12,13 @@ pvesh create /cluster/sdn/zones/ --zone vxlanmulticastzone --type vxlan --uplink pvesh create /cluster/sdn/zones/ --zone vxlanunicastzone --type vxlan --uplink-id 1 --unicast-address 192.168.0.1,192.168.0.2,192.168.0.3 #create an controller -pvesh create /cluster/sdn/controllers/ --controller frrrouter1 --type evpn --uplink-id 1 --peers 192.168.0.1,192.168.0.2,192.168.0.3 --asn 1234 --gateway-nodes pxnode1,pxnode2 --gateway-external-peers 192.168.0.253,192.168.0.254 +pvesh create /cluster/sdn/controllers/ --controller frrrouter1 --type evpn --peers 192.168.0.1,192.168.0.2,192.168.0.3 --asn 1234 --gateway-nodes pxnode1,pxnode2 --gateway-external-peers 192.168.0.253,192.168.0.254 #create a layer2 vxlan bgpevpn transportzone -pvesh create /cluster/sdn/zones/ --zone layer2evpnzone --type evpn --uplink-id 1 --controller frrrouter1 +pvesh create /cluster/sdn/zones/ --zone layer2evpnzone --type evpn --controller frrrouter1 #create a layer3 routable vxlan bgpevpn transportzone -pvesh create /cluster/sdn/zones/ --zone layer3evpnzone --type evpn --uplink-id 1 --controller frrrouter1 --vrf-vxlan 4000 +pvesh create /cluster/sdn/zones/ --zone layer3evpnzone --type evpn --controller frrrouter1 --vrf-vxlan 4000 #create a vnet in the transportzone