summaryrefslogtreecommitdiff
path: root/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
diff options
context:
space:
mode:
authorStefan Hanreich <s.hanreich@proxmox.com>2025-07-16 15:08:13 +0200
committerThomas Lamprecht <t.lamprecht@proxmox.com>2025-07-17 00:10:47 +0200
commit9794f3a7de8863d182f24b5fa676b8ad376cc26d (patch)
treedf70046c05769a627589484e12c5cd925aca37b7 /src/PVE/Network/SDN/Zones/EvpnPlugin.pm
parentf9c774e8b1a2ebde0207bfb826ee9c7afa47b2be (diff)
controller: evpn: add fabrics integration
Provide a new option to the EVPN controller, fabric, that can be used to define a fabric as the underlay network for the EVPN controller. When applying the configuration, the EVPN controller then automatically generates the peer list and from the fabric configuration, rather than users having to specify all IP addresses manually. This also means that the peer list automatically updates when changing the fabric. An EVPN controller can only either define a peer list or a fabric, but not both. This requires the 'peers' property to now be optional, but the existence of either fabric / peers is now validated in the on_update_hook now instead. MTU is set automatically to 1450 (because of VXLAN overhead) when fabrics are used, unless otherwise specified in the EVPN zone configuration, since there is currently now way of reliably accessing the MTU of the interfaces of the fabric. This means users have to manually specify the MTU for the EVPN controller when using fabrics. This could be particularly relevant in the future, when Wireguard is introduced as a fabric, which incurs an overhead of 80 bytes, requiring users to manually set the MTU to 1370. Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com> Link: https://lore.proxmox.com/20250716130837.585796-53-g.goller@proxmox.com
Diffstat (limited to 'src/PVE/Network/SDN/Zones/EvpnPlugin.pm')
-rw-r--r--src/PVE/Network/SDN/Zones/EvpnPlugin.pm65
1 files changed, 50 insertions, 15 deletions
diff --git a/src/PVE/Network/SDN/Zones/EvpnPlugin.pm b/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
index 7d26e1b..0153364 100644
--- a/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
+++ b/src/PVE/Network/SDN/Zones/EvpnPlugin.pm
@@ -135,28 +135,63 @@ sub generate_sdn_config {
die "missing vxlan tag" if !$tag;
die "missing controller" if !$controller;
- my @peers = PVE::Tools::split_list($controller->{'peers'});
-
+ my @peers;
my $loopback = undef;
- my $bgprouter = PVE::Network::SDN::Controllers::EvpnPlugin::find_bgp_controller(
- $local_node, $controller_cfg,
- );
- 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 = undef;
+ my $iface = undef;
+ my $routerid = undef;
+
+ if ($controller->{peers}) {
+ @peers = PVE::Tools::split_list($controller->{'peers'});
+
+ my $bgprouter = PVE::Network::SDN::Controllers::EvpnPlugin::find_bgp_controller(
+ $local_node, $controller_cfg,
+ );
+ 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};
+ }
+
+ ($ifaceip, $iface) =
+ PVE::Network::SDN::Zones::Plugin::find_local_ip_interface_peers(\@peers, $loopback);
+ } elsif ($controller->{fabric}) {
+ my $config = PVE::Network::SDN::Fabrics::config(1);
+
+ my $fabric = eval { $config->get_fabric($controller->{fabric}) };
+ die "could not configure EVPN zone $plugin_config->{id}: $@" if $@;
+
+ my $nodes = $config->list_nodes_fabric($controller->{fabric});
+
+ my $current_node = eval { $config->get_node($controller->{fabric}, $local_node) };
+ die "could not configure EVPN zone $plugin_config->{id}: $@" if $@;
+
+ die "Node $local_node requires an IP in the fabric $fabric->{id} to configure the EVPN zone"
+ if !$current_node->{ip};
+
+ for my $node (values %$nodes) {
+ push @peers, $node->{ip} if $node->{ip};
+ }
+
+ $loopback = "dummy_$fabric->{id}";
+
+ $ifaceip = $current_node->{ip};
+ $routerid = $current_node->{ip};
+ } else {
+ die "neither fabric nor peers configured for EVPN controller $controller->{id}";
}
- 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'};
my $mtu = 1450;
- $mtu = $interfaces_config->{$iface}->{mtu} - 50 if $interfaces_config->{$iface}->{mtu};
+ if ($iface) {
+ $mtu = $interfaces_config->{$iface}->{mtu} - 50 if $interfaces_config->{$iface}->{mtu};
+ }
$mtu = $plugin_config->{mtu} if $plugin_config->{mtu};
#vxlan interface