mirror of
git://git.proxmox.com/git/pve-network.git
synced 2025-01-09 01:18:06 +03:00
controllers: add isis router plugin
This commit is contained in:
parent
ced9392063
commit
9ce18f80bc
@ -14,10 +14,12 @@ use PVE::Network::SDN::Zones;
|
||||
|
||||
use PVE::Network::SDN::Controllers::EvpnPlugin;
|
||||
use PVE::Network::SDN::Controllers::BgpPlugin;
|
||||
use PVE::Network::SDN::Controllers::IsisPlugin;
|
||||
use PVE::Network::SDN::Controllers::FaucetPlugin;
|
||||
use PVE::Network::SDN::Controllers::Plugin;
|
||||
PVE::Network::SDN::Controllers::EvpnPlugin->register();
|
||||
PVE::Network::SDN::Controllers::BgpPlugin->register();
|
||||
PVE::Network::SDN::Controllers::IsisPlugin->register();
|
||||
PVE::Network::SDN::Controllers::FaucetPlugin->register();
|
||||
PVE::Network::SDN::Controllers::Plugin->init();
|
||||
|
||||
|
@ -53,11 +53,15 @@ sub generate_controller_config {
|
||||
my $loopback = undef;
|
||||
my $autortas = undef;
|
||||
my $bgprouter = find_bgp_controller($local_node, $controller_cfg);
|
||||
my $isisrouter = find_isis_controller($local_node, $controller_cfg);
|
||||
|
||||
if ($bgprouter) {
|
||||
$ebgp = 1 if $plugin_config->{'asn'} ne $bgprouter->{asn};
|
||||
$loopback = $bgprouter->{loopback} if $bgprouter->{loopback};
|
||||
$asn = $bgprouter->{asn} if $bgprouter->{asn};
|
||||
$autortas = $plugin_config->{'asn'} if $ebgp;
|
||||
} elsif ($isisrouter) {
|
||||
$loopback = $isisrouter->{loopback} if $isisrouter->{loopback};
|
||||
}
|
||||
|
||||
return if !$asn;
|
||||
@ -86,10 +90,8 @@ sub generate_controller_config {
|
||||
push @controller_config, "neighbor VTEP remote-as $remoteas";
|
||||
push @controller_config, "neighbor VTEP bfd";
|
||||
|
||||
if($ebgp && $loopback) {
|
||||
push @controller_config, "neighbor VTEP ebgp-multihop 10";
|
||||
push @controller_config, "neighbor VTEP update-source $loopback";
|
||||
}
|
||||
push @controller_config, "neighbor VTEP ebgp-multihop 10" if $ebgp && $loopback;
|
||||
push @controller_config, "neighbor VTEP update-source $loopback" if $loopback;
|
||||
|
||||
# VTEP peers
|
||||
foreach my $address (@peers) {
|
||||
@ -136,11 +138,15 @@ sub generate_controller_zone_config {
|
||||
my $loopback = undef;
|
||||
my $autortas = undef;
|
||||
my $bgprouter = find_bgp_controller($local_node, $controller_cfg);
|
||||
my $isisrouter = find_isis_controller($local_node, $controller_cfg);
|
||||
|
||||
if($bgprouter) {
|
||||
$ebgp = 1 if $controller->{'asn'} ne $bgprouter->{asn};
|
||||
$loopback = $bgprouter->{loopback} if $bgprouter->{loopback};
|
||||
$asn = $bgprouter->{asn} if $bgprouter->{asn};
|
||||
$autortas = $controller->{'asn'} if $ebgp;
|
||||
} elsif ($isisrouter) {
|
||||
$loopback = $isisrouter->{loopback} if $isisrouter->{loopback};
|
||||
}
|
||||
|
||||
return if !$vrf || !$vrfvxlan || !$asn;
|
||||
@ -306,6 +312,20 @@ sub find_bgp_controller {
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub find_isis_controller {
|
||||
my ($nodename, $controller_cfg) = @_;
|
||||
|
||||
my $res = undef;
|
||||
foreach my $id (keys %{$controller_cfg->{ids}}) {
|
||||
my $controller = $controller_cfg->{ids}->{$id};
|
||||
next if $controller->{type} ne 'isis';
|
||||
next if $controller->{node} ne $nodename;
|
||||
$res = $controller;
|
||||
last;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
sub generate_frr_recurse{
|
||||
my ($final_config, $content, $parentkey, $level) = @_;
|
||||
|
||||
|
123
src/PVE/Network/SDN/Controllers/IsisPlugin.pm
Normal file
123
src/PVE/Network/SDN/Controllers/IsisPlugin.pm
Normal file
@ -0,0 +1,123 @@
|
||||
package PVE::Network::SDN::Controllers::IsisPlugin;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use PVE::INotify;
|
||||
use PVE::JSONSchema qw(get_standard_option);
|
||||
use PVE::Tools qw(run_command file_set_contents file_get_contents);
|
||||
|
||||
use PVE::Network::SDN::Controllers::Plugin;
|
||||
use PVE::Network::SDN::Zones::Plugin;
|
||||
use Net::IP;
|
||||
|
||||
use base('PVE::Network::SDN::Controllers::Plugin');
|
||||
|
||||
sub type {
|
||||
return 'isis';
|
||||
}
|
||||
|
||||
sub properties {
|
||||
return {
|
||||
'isis-domain' => {
|
||||
description => "ISIS domain.",
|
||||
type => 'string'
|
||||
},
|
||||
'isis-ifaces' => {
|
||||
description => "ISIS interface.",
|
||||
type => 'string', format => 'pve-iface-list',
|
||||
},
|
||||
'isis-net' => {
|
||||
description => "ISIS network entity title.",
|
||||
type => 'string'
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
sub options {
|
||||
return {
|
||||
'isis-domain' => { optional => 0 },
|
||||
'isis-net' => { optional => 0 },
|
||||
'isis-ifaces' => { optional => 0 },
|
||||
'node' => { optional => 0 },
|
||||
'loopback' => { optional => 1 },
|
||||
};
|
||||
}
|
||||
|
||||
# Plugin implementation
|
||||
sub generate_controller_config {
|
||||
my ($class, $plugin_config, $controller, $id, $uplinks, $config) = @_;
|
||||
|
||||
my $isis_ifaces = $plugin_config->{'isis-ifaces'};
|
||||
my $isis_net = $plugin_config->{'isis-net'};
|
||||
my $isis_domain = $plugin_config->{'isis-domain'};
|
||||
my $local_node = PVE::INotify::nodename();
|
||||
|
||||
return if !$isis_ifaces || !$isis_net || !$isis_domain;
|
||||
return if $local_node ne $plugin_config->{node};
|
||||
|
||||
my @router_config = (
|
||||
"net $isis_net",
|
||||
"redistribute ipv4 connected level-1",
|
||||
"redistribute ipv6 connected level-1",
|
||||
"log-adjacency-changes",
|
||||
);
|
||||
|
||||
push(@{$config->{frr}->{router}->{"isis $isis_domain"}}, @router_config);
|
||||
|
||||
my @iface_config = (
|
||||
"ip router isis $isis_domain"
|
||||
);
|
||||
|
||||
my @ifaces = PVE::Tools::split_list($isis_ifaces);
|
||||
for my $iface (sort @ifaces) {
|
||||
push(@{$config->{frr_interfaces}->{$iface}}, @iface_config);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
sub generate_controller_zone_config {
|
||||
my ($class, $plugin_config, $controller, $controller_cfg, $id, $uplinks, $config) = @_;
|
||||
|
||||
}
|
||||
|
||||
sub on_delete_hook {
|
||||
my ($class, $controllerid, $zone_cfg) = @_;
|
||||
|
||||
}
|
||||
|
||||
sub on_update_hook {
|
||||
my ($class, $controllerid, $controller_cfg) = @_;
|
||||
|
||||
# we can only have 1 bgp controller by node
|
||||
my $local_node = PVE::INotify::nodename();
|
||||
my $controllernb = 0;
|
||||
foreach my $id (keys %{$controller_cfg->{ids}}) {
|
||||
next if $id eq $controllerid;
|
||||
my $controller = $controller_cfg->{ids}->{$id};
|
||||
next if $controller->{type} ne "isis";
|
||||
next if $controller->{node} ne $local_node;
|
||||
$controllernb++;
|
||||
die "only 1 bgp or isis controller can be defined" if $controllernb > 1;
|
||||
}
|
||||
}
|
||||
|
||||
sub generate_controller_rawconfig {
|
||||
my ($class, $plugin_config, $config) = @_;
|
||||
return "";
|
||||
}
|
||||
|
||||
sub write_controller_config {
|
||||
my ($class, $plugin_config, $config) = @_;
|
||||
return;
|
||||
}
|
||||
|
||||
sub reload_controller {
|
||||
my ($class) = @_;
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
SOURCES=Plugin.pm FaucetPlugin.pm EvpnPlugin.pm BgpPlugin.pm
|
||||
SOURCES=Plugin.pm FaucetPlugin.pm EvpnPlugin.pm BgpPlugin.pm IsisPlugin.pm
|
||||
|
||||
|
||||
PERL5DIR=${DESTDIR}/usr/share/perl5
|
||||
|
@ -120,8 +120,16 @@ sub generate_sdn_config {
|
||||
warn "vlan-aware vnet can't be enabled with evpn plugin" if $vnet->{vlanaware};
|
||||
|
||||
my @peers = PVE::Tools::split_list($controller->{'peers'});
|
||||
|
||||
my $loopback = undef;
|
||||
my $bgprouter = PVE::Network::SDN::Controllers::EvpnPlugin::find_bgp_controller($local_node, $controller_cfg);
|
||||
my $loopback = $bgprouter->{loopback} if $bgprouter->{loopback};
|
||||
my $isisrouter = PVE::Network::SDN::Controllers::EvpnPlugin::find_isis_controller($local_node, $controller_cfg);
|
||||
if ($bgprouter->{loopback}) {
|
||||
$loopback = $bgprouter->{loopback};
|
||||
} elsif ($isisrouter->{loopback}) {
|
||||
$loopback = $isisrouter->{loopback};
|
||||
}
|
||||
|
||||
my ($ifaceip, $iface) = PVE::Network::SDN::Zones::Plugin::find_local_ip_interface_peers(\@peers, $loopback);
|
||||
my $is_evpn_gateway = $plugin_config->{'exitnodes'}->{$local_node};
|
||||
my $exitnodes_local_routing = $plugin_config->{'exitnodes-local-routing'};
|
||||
|
58
src/test/zones/evpn/isis/expected_controller_config
Normal file
58
src/test/zones/evpn/isis/expected_controller_config
Normal file
@ -0,0 +1,58 @@
|
||||
frr version 8.5.1
|
||||
frr defaults datacenter
|
||||
hostname localhost
|
||||
log syslog informational
|
||||
service integrated-vtysh-config
|
||||
!
|
||||
!
|
||||
vrf vrf_myzone
|
||||
vni 1000
|
||||
exit-vrf
|
||||
!
|
||||
interface eth0
|
||||
ip router isis isis1
|
||||
!
|
||||
interface eth1
|
||||
ip router isis isis1
|
||||
!
|
||||
router bgp 65000
|
||||
bgp router-id 192.168.0.1
|
||||
no bgp hard-administrative-reset
|
||||
no bgp graceful-restart notification
|
||||
no bgp default ipv4-unicast
|
||||
coalesce-time 1000
|
||||
neighbor VTEP peer-group
|
||||
neighbor VTEP remote-as 65000
|
||||
neighbor VTEP bfd
|
||||
neighbor 192.168.0.2 peer-group VTEP
|
||||
neighbor 192.168.0.3 peer-group VTEP
|
||||
!
|
||||
address-family l2vpn evpn
|
||||
neighbor VTEP route-map MAP_VTEP_IN in
|
||||
neighbor VTEP route-map MAP_VTEP_OUT out
|
||||
neighbor VTEP activate
|
||||
advertise-all-vni
|
||||
exit-address-family
|
||||
exit
|
||||
!
|
||||
router bgp 65000 vrf vrf_myzone
|
||||
bgp router-id 192.168.0.1
|
||||
no bgp hard-administrative-reset
|
||||
no bgp graceful-restart notification
|
||||
exit
|
||||
!
|
||||
router isis isis1
|
||||
net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00
|
||||
redistribute ipv4 connected level-1
|
||||
redistribute ipv6 connected level-1
|
||||
log-adjacency-changes
|
||||
exit
|
||||
!
|
||||
route-map MAP_VTEP_IN permit 1
|
||||
exit
|
||||
!
|
||||
route-map MAP_VTEP_OUT permit 1
|
||||
exit
|
||||
!
|
||||
line vty
|
||||
!
|
41
src/test/zones/evpn/isis/expected_sdn_interfaces
Normal file
41
src/test/zones/evpn/isis/expected_sdn_interfaces
Normal file
@ -0,0 +1,41 @@
|
||||
#version:1
|
||||
|
||||
auto myvnet
|
||||
iface myvnet
|
||||
address 10.0.0.1/24
|
||||
bridge_ports vxlan_myvnet
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
mtu 1450
|
||||
ip-forward on
|
||||
arp-accept on
|
||||
vrf vrf_myzone
|
||||
|
||||
auto vrf_myzone
|
||||
iface vrf_myzone
|
||||
vrf-table auto
|
||||
post-up ip route add vrf vrf_myzone unreachable default metric 4278198272
|
||||
|
||||
auto vrfbr_myzone
|
||||
iface vrfbr_myzone
|
||||
bridge-ports vrfvx_myzone
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
mtu 1450
|
||||
vrf vrf_myzone
|
||||
|
||||
auto vrfvx_myzone
|
||||
iface vrfvx_myzone
|
||||
vxlan-id 1000
|
||||
vxlan-local-tunnelip 192.168.0.1
|
||||
bridge-learning off
|
||||
bridge-arp-nd-suppress on
|
||||
mtu 1450
|
||||
|
||||
auto vxlan_myvnet
|
||||
iface vxlan_myvnet
|
||||
vxlan-id 100
|
||||
vxlan-local-tunnelip 192.168.0.1
|
||||
bridge-learning off
|
||||
bridge-arp-nd-suppress on
|
||||
mtu 1450
|
7
src/test/zones/evpn/isis/interfaces
Normal file
7
src/test/zones/evpn/isis/interfaces
Normal file
@ -0,0 +1,7 @@
|
||||
auto vmbr0
|
||||
iface vmbr0 inet static
|
||||
address 192.168.0.1/24
|
||||
gateway 192.168.0.254
|
||||
bridge-ports eth0
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
49
src/test/zones/evpn/isis/sdn_config
Normal file
49
src/test/zones/evpn/isis/sdn_config
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
version => 1,
|
||||
vnets => {
|
||||
ids => {
|
||||
myvnet => {
|
||||
tag => "100",
|
||||
type => "vnet",
|
||||
zone => "myzone",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
zones => {
|
||||
ids => {
|
||||
myzone => {
|
||||
ipam => "pve",
|
||||
type => "evpn",
|
||||
controller => "evpnctl",
|
||||
'vrf-vxlan' => 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
controllers => {
|
||||
ids => {
|
||||
evpnctl => {
|
||||
type => "evpn",
|
||||
'peers' => '192.168.0.1,192.168.0.2,192.168.0.3',
|
||||
asn => "65000",
|
||||
},
|
||||
localhost => {
|
||||
type => "isis",
|
||||
'isis-domain' => 'isis1',
|
||||
'isis-ifaces' => 'eth1,eth0',
|
||||
'isis-net' => "47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00",
|
||||
node => "localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
subnets => {
|
||||
ids => {
|
||||
'myzone-10.0.0.0-24' => {
|
||||
'type' => 'subnet',
|
||||
'vnet' => 'myvnet',
|
||||
'gateway' => '10.0.0.1',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
59
src/test/zones/evpn/isis_loopback/expected_controller_config
Normal file
59
src/test/zones/evpn/isis_loopback/expected_controller_config
Normal file
@ -0,0 +1,59 @@
|
||||
frr version 8.5.1
|
||||
frr defaults datacenter
|
||||
hostname localhost
|
||||
log syslog informational
|
||||
service integrated-vtysh-config
|
||||
!
|
||||
!
|
||||
vrf vrf_myzone
|
||||
vni 1000
|
||||
exit-vrf
|
||||
!
|
||||
interface eth0
|
||||
ip router isis isis1
|
||||
!
|
||||
interface eth1
|
||||
ip router isis isis1
|
||||
!
|
||||
router bgp 65000
|
||||
bgp router-id 10.0.0.1
|
||||
no bgp hard-administrative-reset
|
||||
no bgp graceful-restart notification
|
||||
no bgp default ipv4-unicast
|
||||
coalesce-time 1000
|
||||
neighbor VTEP peer-group
|
||||
neighbor VTEP remote-as 65000
|
||||
neighbor VTEP bfd
|
||||
neighbor VTEP update-source dummy1
|
||||
neighbor 10.0.0.2 peer-group VTEP
|
||||
neighbor 10.0.0.3 peer-group VTEP
|
||||
!
|
||||
address-family l2vpn evpn
|
||||
neighbor VTEP route-map MAP_VTEP_IN in
|
||||
neighbor VTEP route-map MAP_VTEP_OUT out
|
||||
neighbor VTEP activate
|
||||
advertise-all-vni
|
||||
exit-address-family
|
||||
exit
|
||||
!
|
||||
router bgp 65000 vrf vrf_myzone
|
||||
bgp router-id 10.0.0.1
|
||||
no bgp hard-administrative-reset
|
||||
no bgp graceful-restart notification
|
||||
exit
|
||||
!
|
||||
router isis isis1
|
||||
net 47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00
|
||||
redistribute ipv4 connected level-1
|
||||
redistribute ipv6 connected level-1
|
||||
log-adjacency-changes
|
||||
exit
|
||||
!
|
||||
route-map MAP_VTEP_IN permit 1
|
||||
exit
|
||||
!
|
||||
route-map MAP_VTEP_OUT permit 1
|
||||
exit
|
||||
!
|
||||
line vty
|
||||
!
|
41
src/test/zones/evpn/isis_loopback/expected_sdn_interfaces
Normal file
41
src/test/zones/evpn/isis_loopback/expected_sdn_interfaces
Normal file
@ -0,0 +1,41 @@
|
||||
#version:1
|
||||
|
||||
auto myvnet
|
||||
iface myvnet
|
||||
address 10.0.0.1/24
|
||||
bridge_ports vxlan_myvnet
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
mtu 1450
|
||||
ip-forward on
|
||||
arp-accept on
|
||||
vrf vrf_myzone
|
||||
|
||||
auto vrf_myzone
|
||||
iface vrf_myzone
|
||||
vrf-table auto
|
||||
post-up ip route add vrf vrf_myzone unreachable default metric 4278198272
|
||||
|
||||
auto vrfbr_myzone
|
||||
iface vrfbr_myzone
|
||||
bridge-ports vrfvx_myzone
|
||||
bridge_stp off
|
||||
bridge_fd 0
|
||||
mtu 1450
|
||||
vrf vrf_myzone
|
||||
|
||||
auto vrfvx_myzone
|
||||
iface vrfvx_myzone
|
||||
vxlan-id 1000
|
||||
vxlan-local-tunnelip 10.0.0.1
|
||||
bridge-learning off
|
||||
bridge-arp-nd-suppress on
|
||||
mtu 1450
|
||||
|
||||
auto vxlan_myvnet
|
||||
iface vxlan_myvnet
|
||||
vxlan-id 100
|
||||
vxlan-local-tunnelip 10.0.0.1
|
||||
bridge-learning off
|
||||
bridge-arp-nd-suppress on
|
||||
mtu 1450
|
12
src/test/zones/evpn/isis_loopback/interfaces
Normal file
12
src/test/zones/evpn/isis_loopback/interfaces
Normal file
@ -0,0 +1,12 @@
|
||||
auto vmbr0
|
||||
iface vmbr0 inet static
|
||||
address 192.168.0.1/24
|
||||
gateway 192.168.0.254
|
||||
bridge-ports eth0
|
||||
bridge-stp off
|
||||
bridge-fd 0
|
||||
|
||||
auto dummy1
|
||||
iface dummy1 inet static
|
||||
address 10.0.0.1/32
|
||||
link-type dummy
|
50
src/test/zones/evpn/isis_loopback/sdn_config
Normal file
50
src/test/zones/evpn/isis_loopback/sdn_config
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
version => 1,
|
||||
vnets => {
|
||||
ids => {
|
||||
myvnet => {
|
||||
tag => "100",
|
||||
type => "vnet",
|
||||
zone => "myzone",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
zones => {
|
||||
ids => {
|
||||
myzone => {
|
||||
ipam => "pve",
|
||||
type => "evpn",
|
||||
controller => "evpnctl",
|
||||
'vrf-vxlan' => 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
controllers => {
|
||||
ids => {
|
||||
evpnctl => {
|
||||
type => "evpn",
|
||||
'peers' => '10.0.0.1,10.0.0.2,10.0.0.3',
|
||||
asn => "65000",
|
||||
},
|
||||
localhost => {
|
||||
type => "isis",
|
||||
'isis-domain' => 'isis1',
|
||||
'isis-ifaces' => 'eth1,eth0',
|
||||
'isis-net' => "47.0023.0000.0000.0000.0000.0000.0000.1900.0004.00",
|
||||
loopback => 'dummy1',
|
||||
node => "localhost",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
subnets => {
|
||||
ids => {
|
||||
'myzone-10.0.0.0-24' => {
|
||||
'type' => 'subnet',
|
||||
'vnet' => 'myvnet',
|
||||
'gateway' => '10.0.0.1',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
Loading…
Reference in New Issue
Block a user