sdn: add generate_frr_config

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
This commit is contained in:
Alexandre Derumier 2019-08-29 12:32:51 +02:00 committed by Thomas Lamprecht
parent 93dea3aad0
commit 87d8b62369
5 changed files with 146 additions and 29 deletions

View File

@ -149,27 +149,103 @@ sub generate_etc_network_config {
$plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $uplinks, $config);
}
my $network_config = $config->{network};
my $raw_network_config = "";
foreach my $iface (keys %$network_config) {
foreach my $iface (keys %$config) {
$raw_network_config .= "\n";
$raw_network_config .= "auto $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";
}
}
my $frr_config = $config->{frr};
my $raw_frr_config = "";
foreach my $asn (keys %$frr_config) {
$raw_frr_config .= "router bgp $asn";
foreach my $option (@{$frr_config->{$asn}}) {
$raw_frr_config .= " $option\n";
return $raw_network_config;
}
sub generate_frr_config {
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 {

View File

@ -34,27 +34,23 @@ sub options {
}
# Plugin implementation
sub generate_sdn_config {
my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
sub generate_frr_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 $uplink = $plugin_config->{'uplink-id'};
die "missing peers" if !$plugin_config->{'peers'};
my $iface = "uplink$uplink";
my $ifaceip = "";
if($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 = ();
push @router_config, "router bgp $asn";
push @router_config, "bgp router-id $ifaceip";
push @router_config, "coalesce-time 1000";
@ -70,11 +66,8 @@ sub generate_sdn_config {
}
push @router_config, " advertise-all-vni";
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;
}

View File

@ -77,7 +77,7 @@ sub generate_sdn_config {
my @iface_config = ();
push @iface_config, "vlan-protocol $vlanprotocol" if $vlanprotocol;
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
@iface_config = ();
@ -87,7 +87,7 @@ sub generate_sdn_config {
push @iface_config, "bridge-vlan-aware yes" if $vlanaware;
push @iface_config, "mtu $mtu" if $mtu;
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;
}

View File

@ -42,6 +42,10 @@ sub properties {
type => 'integer',
description => "l3vni.",
},
'router' => {
type => 'string',
description => "Frr router name",
},
};
}
@ -54,6 +58,7 @@ sub options {
'vxlan-allowed' => { optional => 1 },
'vrf' => { 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(@{$config->{network}->{"vxlan$vnetid"}}, @iface_config) if !$config->{network}->{"vxlan$vnetid"};
push(@{$config->{"vxlan$vnetid"}}, @iface_config) if !$config->{"vxlan$vnetid"};
#vnet bridge
@iface_config = ();
@ -120,13 +125,13 @@ sub generate_sdn_config {
push @iface_config, "mtu $mtu" if $mtu;
push @iface_config, "alias $alias" if $alias;
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) {
#vrf intreface
@iface_config = ();
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) {
#l3vni vxlan interface
@ -137,7 +142,7 @@ sub generate_sdn_config {
push @iface_config, "bridge-learning off";
push @iface_config, "bridge-arp-nd-suppress on";
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
my $brvrf = "br$vrf";
@ -147,13 +152,53 @@ sub generate_sdn_config {
push @iface_config, "bridge_fd 0";
push @iface_config, "mtu $mtu" if $mtu;
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;
}
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 {
my ($class, $transportid, $sdn_cfg) = @_;

View File

@ -6,7 +6,10 @@ use PVE::Cluster qw(cfs_read_file);
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);
print $network_config;
my $frr_config = PVE::Network::SDN::generate_frr_config();
print $frr_config;