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