]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Zones/EvpnPlugin.pm
62382fb482ddd25672d4801c9f056ce26645fff0
[pve-network.git] / PVE / Network / SDN / Zones / EvpnPlugin.pm
1 package PVE::Network::SDN::Zones::EvpnPlugin;
2
3 use strict;
4 use warnings;
5 use PVE::Network::SDN::Zones::VxlanPlugin;
6 use PVE::Tools qw($IPV4RE);
7 use PVE::INotify;
8
9 use base('PVE::Network::SDN::Zones::VxlanPlugin');
10
11 sub type {
12 return 'evpn';
13 }
14
15 sub properties {
16 return {
17 'vrf-vxlan' => {
18 type => 'integer',
19 description => "l3vni.",
20 },
21 'controller' => {
22 type => 'string',
23 description => "Frr router name",
24 },
25 };
26 }
27
28 sub options {
29
30 return {
31 nodes => { optional => 1},
32 'uplink-id' => { optional => 0 },
33 'vrf-vxlan' => { optional => 0 },
34 'controller' => { optional => 0 },
35 };
36 }
37
38 # Plugin implementation
39 sub generate_sdn_config {
40 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
41
42 my $tag = $vnet->{tag};
43 my $alias = $vnet->{alias};
44 my $ipv4 = $vnet->{ipv4};
45 my $ipv6 = $vnet->{ipv6};
46 my $mac = $vnet->{mac};
47
48 my $uplink = $plugin_config->{'uplink-id'};
49 my $vrf = $zoneid;
50 my $vrfvxlan = $plugin_config->{'vrf-vxlan'};
51
52 die "missing vxlan tag" if !$tag;
53 my $iface = "uplink$uplink";
54 my $ifaceip = "";
55
56 if($uplinks->{$uplink}->{name}) {
57 $iface = $uplinks->{$uplink}->{name};
58 $ifaceip = PVE::Network::SDN::Zones::Plugin::get_first_local_ipv4_from_interface($iface);
59 }
60
61 my $mtu = 1450;
62 $mtu = $uplinks->{$uplink}->{mtu} - 50 if $uplinks->{$uplink}->{mtu};
63 $mtu = $vnet->{mtu} if $vnet->{mtu};
64
65 #vxlan interface
66 my @iface_config = ();
67 push @iface_config, "vxlan-id $tag";
68
69 push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
70 push @iface_config, "bridge-learning off";
71 push @iface_config, "bridge-arp-nd-suppress on";
72
73 push @iface_config, "mtu $mtu" if $mtu;
74 push(@{$config->{"vxlan$vnetid"}}, @iface_config) if !$config->{"vxlan$vnetid"};
75
76 #vnet bridge
77 @iface_config = ();
78 push @iface_config, "address $ipv4" if $ipv4;
79 push @iface_config, "address $ipv6" if $ipv6;
80 push @iface_config, "hwaddress $mac" if $mac;
81 push @iface_config, "bridge_ports vxlan$vnetid";
82 push @iface_config, "bridge_stp off";
83 push @iface_config, "bridge_fd 0";
84 push @iface_config, "mtu $mtu" if $mtu;
85 push @iface_config, "alias $alias" if $alias;
86 push @iface_config, "ip-forward on" if $ipv4;
87 push @iface_config, "ip6-forward on" if $ipv6;
88 push @iface_config, "arp-accept on" if $ipv4||$ipv6;
89 push @iface_config, "vrf $vrf" if $vrf;
90 push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
91
92 if ($vrf) {
93 #vrf interface
94 @iface_config = ();
95 push @iface_config, "vrf-table auto";
96 push(@{$config->{$vrf}}, @iface_config) if !$config->{$vrf};
97
98 if ($vrfvxlan) {
99 #l3vni vxlan interface
100 my $iface_vxlan = "vxvrf$vrf";
101 @iface_config = ();
102 push @iface_config, "vxlan-id $vrfvxlan";
103 push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
104 push @iface_config, "bridge-learning off";
105 push @iface_config, "bridge-arp-nd-suppress on";
106 push @iface_config, "mtu $mtu" if $mtu;
107 push(@{$config->{$iface_vxlan}}, @iface_config) if !$config->{$iface_vxlan};
108
109 #l3vni bridge
110 my $brvrf = "br$vrf";
111 @iface_config = ();
112 push @iface_config, "bridge-ports $iface_vxlan";
113 push @iface_config, "bridge_stp off";
114 push @iface_config, "bridge_fd 0";
115 push @iface_config, "mtu $mtu" if $mtu;
116 push @iface_config, "vrf $vrf";
117 push(@{$config->{$brvrf}}, @iface_config) if !$config->{$brvrf};
118 }
119 }
120
121 return $config;
122 }
123
124 sub on_update_hook {
125 my ($class, $zoneid, $zone_cfg, $controller_cfg) = @_;
126
127 # verify that controller exist
128 my $controller = $zone_cfg->{ids}->{$zoneid}->{controller};
129 if (!defined($controller_cfg->{ids}->{$controller})) {
130 die "controller $controller don't exist";
131 } else {
132 die "$controller is not a evpn controller type" if $controller_cfg->{ids}->{$controller}->{type} ne 'evpn';
133 }
134
135 #vrf-vxlan need to be defined
136
137 my $vrfvxlan = $zone_cfg->{ids}->{$zoneid}->{'vrf-vxlan'};
138 # verify that vrf-vxlan is not already declared in another zone
139 foreach my $id (keys %{$zone_cfg->{ids}}) {
140 next if $id eq $zoneid;
141 die "vrf-vxlan $vrfvxlan is already declared in $id"
142 if (defined($zone_cfg->{ids}->{$id}->{'vrf-vxlan'}) && $zone_cfg->{ids}->{$id}->{'vrf-vxlan'} eq $vrfvxlan);
143 }
144 }
145
146 1;
147
148