mirror of
https://git.proxmox.com/git/pve-network
synced 2025-08-12 22:29:58 +00:00
sdn: add generate_frr_config
Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
This commit is contained in:
parent
93dea3aad0
commit
87d8b62369
@ -149,27 +149,103 @@ sub generate_etc_network_config {
|
|||||||
$plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $uplinks, $config);
|
$plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $uplinks, $config);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $network_config = $config->{network};
|
|
||||||
my $raw_network_config = "";
|
my $raw_network_config = "";
|
||||||
foreach my $iface (keys %$network_config) {
|
foreach my $iface (keys %$config) {
|
||||||
$raw_network_config .= "\n";
|
$raw_network_config .= "\n";
|
||||||
$raw_network_config .= "auto $iface\n";
|
$raw_network_config .= "auto $iface\n";
|
||||||
$raw_network_config .= "iface $iface\n";
|
$raw_network_config .= "iface $iface\n";
|
||||||
foreach my $option (@{$network_config->{$iface}}) {
|
foreach my $option (@{$config->{$iface}}) {
|
||||||
$raw_network_config .= "\t$option\n";
|
$raw_network_config .= "\t$option\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $frr_config = $config->{frr};
|
return $raw_network_config;
|
||||||
my $raw_frr_config = "";
|
}
|
||||||
foreach my $asn (keys %$frr_config) {
|
|
||||||
$raw_frr_config .= "router bgp $asn";
|
sub generate_frr_config {
|
||||||
foreach my $option (@{$frr_config->{$asn}}) {
|
|
||||||
$raw_frr_config .= " $option\n";
|
my $sdn_cfg = PVE::Cluster::cfs_read_file('sdn.cfg');
|
||||||
|
return if !$sdn_cfg;
|
||||||
|
|
||||||
|
#read main config for physical interfaces
|
||||||
|
my $current_config_file = "/etc/network/interfaces";
|
||||||
|
my $fh = IO::File->new($current_config_file);
|
||||||
|
my $interfaces_config = PVE::INotify::read_etc_network_interfaces(1,$fh);
|
||||||
|
$fh->close();
|
||||||
|
|
||||||
|
#check uplinks
|
||||||
|
my $uplinks = {};
|
||||||
|
foreach my $id (keys %{$interfaces_config->{ifaces}}) {
|
||||||
|
my $interface = $interfaces_config->{ifaces}->{$id};
|
||||||
|
if (my $uplink = $interface->{'uplink-id'}) {
|
||||||
|
die "uplink-id $uplink is already defined on $uplinks->{$uplink}" if $uplinks->{$uplink};
|
||||||
|
$interface->{name} = $id;
|
||||||
|
$uplinks->{$interface->{'uplink-id'}} = $interface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wantarray ? ($raw_network_config, $raw_frr_config) : $raw_network_config;
|
my $frr_cfg = undef;
|
||||||
|
my $transport_cfg = undef;
|
||||||
|
|
||||||
|
foreach my $id (keys %{$sdn_cfg->{ids}}) {
|
||||||
|
if ($sdn_cfg->{ids}->{$id}->{type} eq 'frr') {
|
||||||
|
$frr_cfg->{ids}->{$id} = $sdn_cfg->{ids}->{$id};
|
||||||
|
} elsif ($sdn_cfg->{ids}->{$id}->{type} ne 'vnet') {
|
||||||
|
$transport_cfg->{ids}->{$id} = $sdn_cfg->{ids}->{$id};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#generate configuration
|
||||||
|
my $config = {};
|
||||||
|
|
||||||
|
foreach my $id (keys %{$frr_cfg->{ids}}) {
|
||||||
|
my $plugin_config = $frr_cfg->{ids}->{$id};
|
||||||
|
my $asn = $plugin_config->{asn};
|
||||||
|
if ($asn) {
|
||||||
|
my $plugin = PVE::Network::SDN::Plugin->lookup($plugin_config->{type});
|
||||||
|
$plugin->generate_frr_config($plugin_config, $asn, $id, $uplinks, $config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $id (keys %{$transport_cfg->{ids}}) {
|
||||||
|
my $plugin_config = $transport_cfg->{ids}->{$id};
|
||||||
|
my $router = $plugin_config->{router};
|
||||||
|
if ($router) {
|
||||||
|
my $asn = $frr_cfg->{ids}->{$router}->{asn};
|
||||||
|
if ($asn) {
|
||||||
|
my $plugin = PVE::Network::SDN::Plugin->lookup($plugin_config->{type});
|
||||||
|
$plugin->generate_frr_config($plugin_config, $asn, $id, $uplinks, $config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $raw_frr_config = "log syslog informational\n";
|
||||||
|
$raw_frr_config .= "!\n";
|
||||||
|
|
||||||
|
#vrf first
|
||||||
|
my $vrfconfig = $config->{vrf};
|
||||||
|
foreach my $vrf (sort keys %$vrfconfig) {
|
||||||
|
$raw_frr_config .= "$vrf\n";
|
||||||
|
foreach my $option (@{$vrfconfig->{$vrf}}) {
|
||||||
|
$raw_frr_config .= " $option\n";
|
||||||
|
}
|
||||||
|
$raw_frr_config .= "!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#routers
|
||||||
|
my $routerconfig = $config->{router};
|
||||||
|
foreach my $router (sort keys %$routerconfig) {
|
||||||
|
$raw_frr_config .= "$router\n";
|
||||||
|
foreach my $option (@{$routerconfig->{$router}}) {
|
||||||
|
$raw_frr_config .= " $option\n";
|
||||||
|
}
|
||||||
|
$raw_frr_config .= "!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw_frr_config .= "line vty\n";
|
||||||
|
$raw_frr_config .= "!\n";
|
||||||
|
|
||||||
|
return $raw_frr_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub write_etc_network_config {
|
sub write_etc_network_config {
|
||||||
|
@ -34,27 +34,23 @@ sub options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Plugin implementation
|
# Plugin implementation
|
||||||
sub generate_sdn_config {
|
sub generate_frr_config {
|
||||||
my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
|
my ($class, $plugin_config, $asn, $id, $uplinks, $config) = @_;
|
||||||
|
|
||||||
my $asn = $plugin_config->{'asn'};
|
|
||||||
my @peers = split(',', $plugin_config->{'peers'}) if $plugin_config->{'peers'};
|
my @peers = split(',', $plugin_config->{'peers'}) if $plugin_config->{'peers'};
|
||||||
|
|
||||||
my $uplink = $plugin_config->{'uplink-id'};
|
my $uplink = $plugin_config->{'uplink-id'};
|
||||||
|
|
||||||
die "missing peers" if !$plugin_config->{'peers'};
|
|
||||||
|
|
||||||
my $iface = "uplink$uplink";
|
my $iface = "uplink$uplink";
|
||||||
my $ifaceip = "";
|
my $ifaceip = "";
|
||||||
|
|
||||||
if($uplinks->{$uplink}->{name}) {
|
if($uplinks->{$uplink}->{name}) {
|
||||||
$iface = $uplinks->{$uplink}->{name};
|
$iface = $uplinks->{$uplink}->{name};
|
||||||
$ifaceip = get_first_local_ipv4_from_interface($iface);
|
$ifaceip = PVE::Network::SDN::Plugin::get_first_local_ipv4_from_interface($iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
my @router_config = ();
|
my @router_config = ();
|
||||||
|
|
||||||
push @router_config, "router bgp $asn";
|
|
||||||
push @router_config, "bgp router-id $ifaceip";
|
push @router_config, "bgp router-id $ifaceip";
|
||||||
push @router_config, "coalesce-time 1000";
|
push @router_config, "coalesce-time 1000";
|
||||||
|
|
||||||
@ -70,11 +66,8 @@ sub generate_sdn_config {
|
|||||||
}
|
}
|
||||||
push @router_config, " advertise-all-vni";
|
push @router_config, " advertise-all-vni";
|
||||||
push @router_config, "exit-address-family";
|
push @router_config, "exit-address-family";
|
||||||
push @router_config, "!";
|
|
||||||
push @router_config, "line vty";
|
|
||||||
push @router_config, "!";
|
|
||||||
|
|
||||||
push(@{$config->{frr}->{$asn}}, @router_config);
|
push(@{$config->{router}->{"router bgp $asn"}}, @router_config);
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ sub generate_sdn_config {
|
|||||||
my @iface_config = ();
|
my @iface_config = ();
|
||||||
push @iface_config, "vlan-protocol $vlanprotocol" if $vlanprotocol;
|
push @iface_config, "vlan-protocol $vlanprotocol" if $vlanprotocol;
|
||||||
push @iface_config, "mtu $mtu" if $mtu;
|
push @iface_config, "mtu $mtu" if $mtu;
|
||||||
push(@{$config->{network}->{$iface}}, @iface_config) if !$config->{network}->{$iface};
|
push(@{$config->{$iface}}, @iface_config) if !$config->{$iface};
|
||||||
|
|
||||||
#vnet bridge
|
#vnet bridge
|
||||||
@iface_config = ();
|
@iface_config = ();
|
||||||
@ -87,7 +87,7 @@ sub generate_sdn_config {
|
|||||||
push @iface_config, "bridge-vlan-aware yes" if $vlanaware;
|
push @iface_config, "bridge-vlan-aware yes" if $vlanaware;
|
||||||
push @iface_config, "mtu $mtu" if $mtu;
|
push @iface_config, "mtu $mtu" if $mtu;
|
||||||
push @iface_config, "alias $alias" if $alias;
|
push @iface_config, "alias $alias" if $alias;
|
||||||
push(@{$config->{network}->{$vnetid}}, @iface_config) if !$config->{network}->{$vnetid};
|
push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,10 @@ sub properties {
|
|||||||
type => 'integer',
|
type => 'integer',
|
||||||
description => "l3vni.",
|
description => "l3vni.",
|
||||||
},
|
},
|
||||||
|
'router' => {
|
||||||
|
type => 'string',
|
||||||
|
description => "Frr router name",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +58,7 @@ sub options {
|
|||||||
'vxlan-allowed' => { optional => 1 },
|
'vxlan-allowed' => { optional => 1 },
|
||||||
'vrf' => { optional => 1 },
|
'vrf' => { optional => 1 },
|
||||||
'vrf-vxlan' => { optional => 1 },
|
'vrf-vxlan' => { optional => 1 },
|
||||||
|
'router' => { optional => 1 },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +112,7 @@ sub generate_sdn_config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push @iface_config, "mtu $mtu" if $mtu;
|
push @iface_config, "mtu $mtu" if $mtu;
|
||||||
push(@{$config->{network}->{"vxlan$vnetid"}}, @iface_config) if !$config->{network}->{"vxlan$vnetid"};
|
push(@{$config->{"vxlan$vnetid"}}, @iface_config) if !$config->{"vxlan$vnetid"};
|
||||||
|
|
||||||
#vnet bridge
|
#vnet bridge
|
||||||
@iface_config = ();
|
@iface_config = ();
|
||||||
@ -120,13 +125,13 @@ sub generate_sdn_config {
|
|||||||
push @iface_config, "mtu $mtu" if $mtu;
|
push @iface_config, "mtu $mtu" if $mtu;
|
||||||
push @iface_config, "alias $alias" if $alias;
|
push @iface_config, "alias $alias" if $alias;
|
||||||
push @iface_config, "vrf $vrf" if $vrf;
|
push @iface_config, "vrf $vrf" if $vrf;
|
||||||
push(@{$config->{network}->{$vnetid}}, @iface_config) if !$config->{network}->{$vnetid};
|
push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
|
||||||
|
|
||||||
if ($vrf) {
|
if ($vrf) {
|
||||||
#vrf intreface
|
#vrf intreface
|
||||||
@iface_config = ();
|
@iface_config = ();
|
||||||
push @iface_config, "vrf-table auto";
|
push @iface_config, "vrf-table auto";
|
||||||
push(@{$config->{network}->{$vrf}}, @iface_config) if !$config->{network}->{$vrf};
|
push(@{$config->{$vrf}}, @iface_config) if !$config->{$vrf};
|
||||||
|
|
||||||
if ($vrfvxlan) {
|
if ($vrfvxlan) {
|
||||||
#l3vni vxlan interface
|
#l3vni vxlan interface
|
||||||
@ -137,7 +142,7 @@ sub generate_sdn_config {
|
|||||||
push @iface_config, "bridge-learning off";
|
push @iface_config, "bridge-learning off";
|
||||||
push @iface_config, "bridge-arp-nd-suppress on";
|
push @iface_config, "bridge-arp-nd-suppress on";
|
||||||
push @iface_config, "mtu $mtu" if $mtu;
|
push @iface_config, "mtu $mtu" if $mtu;
|
||||||
push(@{$config->{network}->{$iface_vxlan}}, @iface_config) if !$config->{network}->{$iface_vxlan};
|
push(@{$config->{$iface_vxlan}}, @iface_config) if !$config->{$iface_vxlan};
|
||||||
|
|
||||||
#l3vni bridge
|
#l3vni bridge
|
||||||
my $brvrf = "br$vrf";
|
my $brvrf = "br$vrf";
|
||||||
@ -147,13 +152,53 @@ sub generate_sdn_config {
|
|||||||
push @iface_config, "bridge_fd 0";
|
push @iface_config, "bridge_fd 0";
|
||||||
push @iface_config, "mtu $mtu" if $mtu;
|
push @iface_config, "mtu $mtu" if $mtu;
|
||||||
push @iface_config, "vrf $vrf";
|
push @iface_config, "vrf $vrf";
|
||||||
push(@{$config->{network}->{$brvrf}}, @iface_config) if !$config->{network}->{$brvrf};
|
push(@{$config->{$brvrf}}, @iface_config) if !$config->{$brvrf};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $config;
|
return $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub generate_frr_config {
|
||||||
|
my ($class, $plugin_config, $asn, $id, $uplinks, $config) = @_;
|
||||||
|
|
||||||
|
my $vrf = $plugin_config->{'vrf'};
|
||||||
|
my $vrfvxlan = $plugin_config->{'vrf-vxlan'};
|
||||||
|
return if !$vrf || !$vrfvxlan;
|
||||||
|
|
||||||
|
my $uplink = $plugin_config->{'uplink-id'};
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#vrf
|
||||||
|
my @router_config = ();
|
||||||
|
push @router_config, "vni $vrfvxlan";
|
||||||
|
push @router_config, "exit-vrf";
|
||||||
|
push(@{$config->{vrf}->{"vrf $vrf"}}, @router_config);
|
||||||
|
|
||||||
|
|
||||||
|
#vrf router
|
||||||
|
@router_config = ();
|
||||||
|
push @router_config, "bgp router-id $ifaceip";
|
||||||
|
push @router_config, "!";
|
||||||
|
push @router_config, "address-family ipv4 unicast";
|
||||||
|
push @router_config, " redistribute connected";
|
||||||
|
push @router_config, "exit-address-family";
|
||||||
|
push @router_config, "!";
|
||||||
|
push @router_config, "address-family l2vpn evpn";
|
||||||
|
push @router_config, " advertise ipv4 unicast";
|
||||||
|
push @router_config, "exit-address-family";
|
||||||
|
push(@{$config->{router}->{"router bgp $asn vrf $vrf"}}, @router_config);
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
sub on_delete_hook {
|
sub on_delete_hook {
|
||||||
my ($class, $transportid, $sdn_cfg) = @_;
|
my ($class, $transportid, $sdn_cfg) = @_;
|
||||||
|
|
||||||
|
@ -6,7 +6,10 @@ use PVE::Cluster qw(cfs_read_file);
|
|||||||
use PVE::Network::SDN;
|
use PVE::Network::SDN;
|
||||||
|
|
||||||
|
|
||||||
my ($network_config, $frr_config) = PVE::Network::SDN::generate_etc_network_config();
|
my $network_config = PVE::Network::SDN::generate_etc_network_config();
|
||||||
PVE::Network::SDN::write_etc_network_config($network_config);
|
PVE::Network::SDN::write_etc_network_config($network_config);
|
||||||
print $network_config;
|
print $network_config;
|
||||||
|
|
||||||
|
|
||||||
|
my $frr_config = PVE::Network::SDN::generate_frr_config();
|
||||||
print $frr_config;
|
print $frr_config;
|
||||||
|
Loading…
Reference in New Issue
Block a user