5
0
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:
Alexandre Derumier 2023-09-13 13:38:45 +02:00 committed by Fabian Grünbichler
parent ced9392063
commit 9ce18f80bc
13 changed files with 476 additions and 6 deletions

View File

@ -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();

View File

@ -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) = @_;

View 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;

View File

@ -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

View File

@ -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'};

View 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
!

View 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

View 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

View 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',
},
},
},
}

View 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
!

View 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

View 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

View 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',
},
},
},
}