forked from Mirror/pve-network
add evpnplugin (splitted from vxlanplugin)
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
This commit is contained in:
parent
ad03c54368
commit
63586d2f92
|
@ -14,6 +14,7 @@ use PVE::Network::SDN::VnetPlugin;
|
|||
use PVE::Network::SDN::FrrPlugin;
|
||||
use PVE::Network::SDN::OVSFaucetPlugin;
|
||||
use PVE::Network::SDN::FaucetPlugin;
|
||||
use PVE::Network::SDN::EvpnPlugin;
|
||||
|
||||
use Storable qw(dclone);
|
||||
use PVE::JSONSchema qw(get_standard_option);
|
||||
|
|
|
@ -15,6 +15,7 @@ use PVE::Network::SDN::VxlanPlugin;
|
|||
use PVE::Network::SDN::FrrPlugin;
|
||||
use PVE::Network::SDN::OVSFaucetPlugin;
|
||||
use PVE::Network::SDN::FaucetPlugin;
|
||||
use PVE::Network::SDN::EvpnPlugin;
|
||||
|
||||
PVE::Network::SDN::VnetPlugin->register();
|
||||
PVE::Network::SDN::VlanPlugin->register();
|
||||
|
@ -22,6 +23,7 @@ PVE::Network::SDN::VxlanPlugin->register();
|
|||
PVE::Network::SDN::FrrPlugin->register();
|
||||
PVE::Network::SDN::OVSFaucetPlugin->register();
|
||||
PVE::Network::SDN::FaucetPlugin->register();
|
||||
PVE::Network::SDN::EvpnPlugin->register();
|
||||
PVE::Network::SDN::Plugin->init();
|
||||
|
||||
|
||||
|
|
200
PVE/Network/SDN/EvpnPlugin.pm
Normal file
200
PVE/Network/SDN/EvpnPlugin.pm
Normal file
|
@ -0,0 +1,200 @@
|
|||
package PVE::Network::SDN::EvpnPlugin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use PVE::Network::SDN::Plugin;
|
||||
use PVE::Tools qw($IPV4RE);
|
||||
use PVE::INotify;
|
||||
|
||||
use base('PVE::Network::SDN::VxlanPlugin');
|
||||
|
||||
sub type {
|
||||
return 'evpn';
|
||||
}
|
||||
|
||||
sub plugindata {
|
||||
return {
|
||||
role => 'transport',
|
||||
};
|
||||
}
|
||||
|
||||
sub properties {
|
||||
return {
|
||||
'vrf' => {
|
||||
description => "vrf name.",
|
||||
type => 'string', #fixme: format
|
||||
},
|
||||
'vrf-vxlan' => {
|
||||
type => 'integer',
|
||||
description => "l3vni.",
|
||||
},
|
||||
'controller' => {
|
||||
type => 'string',
|
||||
description => "Frr router name",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
sub options {
|
||||
|
||||
return {
|
||||
'uplink-id' => { optional => 0 },
|
||||
'vxlan-allowed' => { optional => 1 },
|
||||
'vrf' => { optional => 0 },
|
||||
'vrf-vxlan' => { optional => 0 },
|
||||
'controller' => { optional => 0 },
|
||||
};
|
||||
}
|
||||
|
||||
# Plugin implementation
|
||||
sub generate_sdn_config {
|
||||
my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
|
||||
|
||||
my $tag = $vnet->{tag};
|
||||
my $alias = $vnet->{alias};
|
||||
my $ipv4 = $vnet->{ipv4};
|
||||
my $ipv6 = $vnet->{ipv6};
|
||||
my $mac = $vnet->{mac};
|
||||
|
||||
my $uplink = $plugin_config->{'uplink-id'};
|
||||
my $vxlanallowed = $plugin_config->{'vxlan-allowed'};
|
||||
my $vrf = $plugin_config->{'vrf'};
|
||||
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::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};
|
||||
|
||||
#vxlan interface
|
||||
my @iface_config = ();
|
||||
push @iface_config, "vxlan-id $tag";
|
||||
|
||||
push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
|
||||
push @iface_config, "bridge-learning off";
|
||||
push @iface_config, "bridge-arp-nd-suppress on";
|
||||
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push(@{$config->{"vxlan$vnetid"}}, @iface_config) if !$config->{"vxlan$vnetid"};
|
||||
|
||||
#vnet bridge
|
||||
@iface_config = ();
|
||||
push @iface_config, "address $ipv4" if $ipv4;
|
||||
push @iface_config, "address $ipv6" if $ipv6;
|
||||
push @iface_config, "hwaddress $mac" if $mac;
|
||||
push @iface_config, "bridge_ports vxlan$vnetid";
|
||||
push @iface_config, "bridge_stp off";
|
||||
push @iface_config, "bridge_fd 0";
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push @iface_config, "alias $alias" if $alias;
|
||||
push @iface_config, "ip-forward on" if $ipv4;
|
||||
push @iface_config, "ip6-forward on" if $ipv6;
|
||||
push @iface_config, "arp-accept on" if $ipv4||$ipv6;
|
||||
push @iface_config, "vrf $vrf" if $vrf;
|
||||
push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
|
||||
|
||||
if ($vrf) {
|
||||
#vrf interface
|
||||
@iface_config = ();
|
||||
push @iface_config, "vrf-table auto";
|
||||
push(@{$config->{$vrf}}, @iface_config) if !$config->{$vrf};
|
||||
|
||||
if ($vrfvxlan) {
|
||||
#l3vni vxlan interface
|
||||
my $iface_vxlan = "vxlan$vrf";
|
||||
@iface_config = ();
|
||||
push @iface_config, "vxlan-id $vrfvxlan";
|
||||
push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
|
||||
push @iface_config, "bridge-learning off";
|
||||
push @iface_config, "bridge-arp-nd-suppress on";
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push(@{$config->{$iface_vxlan}}, @iface_config) if !$config->{$iface_vxlan};
|
||||
|
||||
#l3vni bridge
|
||||
my $brvrf = "br$vrf";
|
||||
@iface_config = ();
|
||||
push @iface_config, "bridge-ports $iface_vxlan";
|
||||
push @iface_config, "bridge_stp off";
|
||||
push @iface_config, "bridge_fd 0";
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push @iface_config, "vrf $vrf";
|
||||
push(@{$config->{$brvrf}}, @iface_config) if !$config->{$brvrf};
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# verify that router exist
|
||||
if (defined($sdn_cfg->{ids}->{$transportid}->{router})) {
|
||||
my $router = $sdn_cfg->{ids}->{$transportid}->{router};
|
||||
if (!defined($sdn_cfg->{ids}->{$router})) {
|
||||
die "router $router don't exist";
|
||||
} else {
|
||||
die "$router is not a router type" if $sdn_cfg->{ids}->{$router}->{type} ne 'frr';
|
||||
}
|
||||
|
||||
#vrf && vrf-vxlan need to be defined with router
|
||||
my $vrf = $sdn_cfg->{ids}->{$transportid}->{vrf};
|
||||
if (!defined($vrf)) {
|
||||
die "missing vrf option";
|
||||
} else {
|
||||
# verify that vrf is not already declared in another transport
|
||||
foreach my $id (keys %{$sdn_cfg->{ids}}) {
|
||||
next if $id eq $transportid;
|
||||
die "vrf $vrf is already declared in $id"
|
||||
if (defined($sdn_cfg->{ids}->{$id}->{vrf}) && $sdn_cfg->{ids}->{$id}->{vrf} eq $vrf);
|
||||
}
|
||||
}
|
||||
|
||||
my $vrfvxlan = $sdn_cfg->{ids}->{$transportid}->{'vrf-vxlan'};
|
||||
if (!defined($vrfvxlan)) {
|
||||
die "missing vrf-vxlan option";
|
||||
} else {
|
||||
# verify that vrf-vxlan is not already declared in another transport
|
||||
foreach my $id (keys %{$sdn_cfg->{ids}}) {
|
||||
next if $id eq $transportid;
|
||||
die "vrf-vxlan $vrfvxlan is already declared in $id"
|
||||
if (defined($sdn_cfg->{ids}->{$id}->{'vrf-vxlan'}) && $sdn_cfg->{ids}->{$id}->{'vrf-vxlan'} eq $vrfvxlan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
SOURCES=Plugin.pm VnetPlugin.pm VlanPlugin.pm VxlanPlugin.pm FrrPlugin.pm FaucetPlugin.pm OVSFaucetPlugin.pm
|
||||
SOURCES=Plugin.pm VnetPlugin.pm VlanPlugin.pm VxlanPlugin.pm FrrPlugin.pm FaucetPlugin.pm OVSFaucetPlugin.pm EvpnPlugin.pm
|
||||
|
||||
|
||||
PERL5DIR=${DESTDIR}/usr/share/perl5
|
||||
|
|
|
@ -60,18 +60,6 @@ sub properties {
|
|||
description => "Unicast peers address ip list.",
|
||||
type => 'string', format => 'ip-list'
|
||||
},
|
||||
'vrf' => {
|
||||
description => "vrf name.",
|
||||
type => 'string', #fixme: format
|
||||
},
|
||||
'vrf-vxlan' => {
|
||||
type => 'integer',
|
||||
description => "l3vni.",
|
||||
},
|
||||
'controller' => {
|
||||
type => 'string',
|
||||
description => "Frr router name",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -82,9 +70,6 @@ sub options {
|
|||
'multicast-address' => { optional => 1 },
|
||||
'unicast-address' => { optional => 1 },
|
||||
'vxlan-allowed' => { optional => 1 },
|
||||
'vrf' => { optional => 1 },
|
||||
'vrf-vxlan' => { optional => 1 },
|
||||
'controller' => { optional => 1 },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -102,8 +87,6 @@ sub generate_sdn_config {
|
|||
|
||||
my $uplink = $plugin_config->{'uplink-id'};
|
||||
my $vxlanallowed = $plugin_config->{'vxlan-allowed'};
|
||||
my $vrf = $plugin_config->{'vrf'};
|
||||
my $vrfvxlan = $plugin_config->{'vrf-vxlan'};
|
||||
|
||||
die "missing vxlan tag" if !$tag;
|
||||
my $iface = "uplink$uplink";
|
||||
|
@ -131,10 +114,6 @@ sub generate_sdn_config {
|
|||
next if $address eq $ifaceip;
|
||||
push @iface_config, "vxlan_remoteip $address";
|
||||
}
|
||||
} else {
|
||||
push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
|
||||
push @iface_config, "bridge-learning off";
|
||||
push @iface_config, "bridge-arp-nd-suppress on";
|
||||
}
|
||||
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
|
@ -150,41 +129,8 @@ sub generate_sdn_config {
|
|||
push @iface_config, "bridge_fd 0";
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push @iface_config, "alias $alias" if $alias;
|
||||
push @iface_config, "ip-forward on" if $ipv4;
|
||||
push @iface_config, "ip6-forward on" if $ipv6;
|
||||
push @iface_config, "arp-accept on" if $ipv4||$ipv6;
|
||||
push @iface_config, "vrf $vrf" if $vrf;
|
||||
push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
|
||||
|
||||
if ($vrf) {
|
||||
#vrf intreface
|
||||
@iface_config = ();
|
||||
push @iface_config, "vrf-table auto";
|
||||
push(@{$config->{$vrf}}, @iface_config) if !$config->{$vrf};
|
||||
|
||||
if ($vrfvxlan) {
|
||||
#l3vni vxlan interface
|
||||
my $iface_vxlan = "vxlan$vrf";
|
||||
@iface_config = ();
|
||||
push @iface_config, "vxlan-id $vrfvxlan";
|
||||
push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
|
||||
push @iface_config, "bridge-learning off";
|
||||
push @iface_config, "bridge-arp-nd-suppress on";
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push(@{$config->{$iface_vxlan}}, @iface_config) if !$config->{$iface_vxlan};
|
||||
|
||||
#l3vni bridge
|
||||
my $brvrf = "br$vrf";
|
||||
@iface_config = ();
|
||||
push @iface_config, "bridge-ports $iface_vxlan";
|
||||
push @iface_config, "bridge_stp off";
|
||||
push @iface_config, "bridge_fd 0";
|
||||
push @iface_config, "mtu $mtu" if $mtu;
|
||||
push @iface_config, "vrf $vrf";
|
||||
push(@{$config->{$brvrf}}, @iface_config) if !$config->{$brvrf};
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,10 @@ pvesh create /cluster/sdn/ --sdn vxlanunicastzone --type vxlan --uplink-id 1 --u
|
|||
pvesh create /cluster/sdn/ --sdn frrrouter1 --type frr --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
|
||||
|
||||
#create a layer2 vxlan bgpevpn transportzone
|
||||
pvesh create /cluster/sdn/ --sdn layer2evpnzone --type vxlan --uplink-id 1 --controller frrrouter1
|
||||
pvesh create /cluster/sdn/ --sdn layer2evpnzone --type evpn --uplink-id 1 --controller frrrouter1
|
||||
|
||||
#create a layer3 routable vxlan bgpevpn transportzone
|
||||
pvesh create /cluster/sdn/ --sdn layer3evpnzone --type vxlan --uplink-id 1 --controller frrrouter1 --vrf vrf1 --vrf-vxlan 4000
|
||||
pvesh create /cluster/sdn/ --sdn layer3evpnzone --type evpn --uplink-id 1 --controller frrrouter1 --vrf vrf1 --vrf-vxlan 4000
|
||||
|
||||
|
||||
#create a vnet in the transportzone
|
||||
|
|
Loading…
Reference in a new issue