]> git.proxmox.com Git - pve-network.git/blame - PVE/Network/SDN/Zones/VxlanPlugin.pm
vnets: allow duplicate tags in differents zones
[pve-network.git] / PVE / Network / SDN / Zones / VxlanPlugin.pm
CommitLineData
f5eabba0 1package PVE::Network::SDN::Zones::VxlanPlugin;
7e720d4d
AD
2
3use strict;
4use warnings;
f5eabba0 5use PVE::Network::SDN::Zones::Plugin;
c692cbfa 6use PVE::Tools qw($IPV4RE);
e3dca233 7use PVE::INotify;
ba7ac021 8use PVE::Network::SDN::Controllers::EvpnPlugin;
1d44ce70 9use PVE::Exception qw(raise raise_param_exc);
7e720d4d 10
f5eabba0 11use base('PVE::Network::SDN::Zones::Plugin');
7e720d4d 12
6bffe819
AD
13PVE::JSONSchema::register_format('pve-sdn-vxlanrange', \&pve_verify_sdn_vxlanrange);
14sub pve_verify_sdn_vxlanrange {
7e720d4d
AD
15 my ($vxlanstr) = @_;
16
f5eabba0 17 PVE::Network::SDN::Zones::Plugin::parse_tag_number_or_range($vxlanstr, '16777216');
7e720d4d
AD
18
19 return $vxlanstr;
20}
21
22sub type {
3ee45e4c 23 return 'vxlan';
7e720d4d
AD
24}
25
26sub properties {
27 return {
ba7ac021
AD
28 'peers' => {
29 description => "peers address list.",
30 type => 'string', format => 'ip-list'
7e720d4d 31 },
7e720d4d
AD
32 };
33}
34
35sub options {
36
37 return {
c2b9c173 38 nodes => { optional => 1},
ba7ac021 39 peers => { optional => 0 },
823f2e2a 40 mtu => { optional => 1 },
4ad78442
AD
41 dns => { optional => 1 },
42 reversedns => { optional => 1 },
43 dnszone => { optional => 1 },
331e2330 44 ipam => { optional => 0 },
7e720d4d
AD
45 };
46}
47
48# Plugin implementation
6bffe819 49sub generate_sdn_config {
7024ec2b 50 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $controller, $subnet_cfg, $interfaces_config, $config) = @_;
7e720d4d
AD
51
52 my $tag = $vnet->{tag};
dc7e431e 53 my $alias = $vnet->{alias};
7e720d4d 54 my $multicastaddress = $plugin_config->{'multicast-address'};
3caa7687
FG
55 my @peers;
56 @peers = PVE::Tools::split_list($plugin_config->{'peers'}) if $plugin_config->{'peers'};
ff3088cb 57 my $vxlan_iface = "vxlan_$vnetid";
7e720d4d
AD
58
59 die "missing vxlan tag" if !$tag;
3ee45e4c 60
1f543c5f 61 my ($ifaceip, $iface) = PVE::Network::SDN::Zones::Plugin::find_local_ip_interface_peers(\@peers);
c1ae8486
AD
62
63 my $mtu = 1450;
ba7ac021 64 $mtu = $interfaces_config->{$iface}->{mtu} - 50 if $interfaces_config->{$iface}->{mtu};
0251ed2f 65 $mtu = $plugin_config->{mtu} if $plugin_config->{mtu};
7e720d4d 66
93dea3aa
AD
67 #vxlan interface
68 my @iface_config = ();
69 push @iface_config, "vxlan-id $tag";
3ee45e4c 70
ba7ac021
AD
71 foreach my $address (@peers) {
72 next if $address eq $ifaceip;
73 push @iface_config, "vxlan_remoteip $address";
3ee45e4c
AD
74 }
75
ff3088cb 76
93dea3aa 77 push @iface_config, "mtu $mtu" if $mtu;
ff3088cb 78 push(@{$config->{$vxlan_iface}}, @iface_config) if !$config->{$vxlan_iface};
93dea3aa
AD
79
80 #vnet bridge
81 @iface_config = ();
ff3088cb 82 push @iface_config, "bridge_ports $vxlan_iface";
93dea3aa
AD
83 push @iface_config, "bridge_stp off";
84 push @iface_config, "bridge_fd 0";
912fb443
AD
85 if($vnet->{vlanaware}) {
86 push @iface_config, "bridge-vlan-aware yes";
87 push @iface_config, "bridge-vids 2-4094";
88 }
93dea3aa
AD
89 push @iface_config, "mtu $mtu" if $mtu;
90 push @iface_config, "alias $alias" if $alias;
87d8b623 91 push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
126fc68c 92
7e720d4d
AD
93 return $config;
94}
95
5ca07ed9 96sub vnet_update_hook {
88d9562b 97 my ($class, $vnet_cfg, $vnetid, $zone_cfg) = @_;
1d44ce70 98
88d9562b
AD
99 my $vnet = $vnet_cfg->{ids}->{$vnetid};
100 my $tag = $vnet->{tag};
101
102 raise_param_exc({ tag => "missing vxlan tag"}) if !defined($tag);
103 raise_param_exc({ tag => "vxlan tag max value is 16777216"}) if $tag > 16777216;
104
105 # verify that tag is not already defined globally (vxlan-id are unique)
106 foreach my $id (keys %{$vnet_cfg->{ids}}) {
107 next if $id eq $vnetid;
108 my $othervnet = $vnet_cfg->{ids}->{$id};
109 my $other_tag = $othervnet->{tag};
110 my $other_zoneid = $othervnet->{zone};
111 my $other_zone = $zone_cfg->{ids}->{$other_zoneid};
112 next if $other_zone->{type} ne 'vxlan' && $other_zone->{type} ne 'evpn';
113 raise_param_exc({ tag => "vxlan tag $tag already exist in vnet $id in zone $other_zoneid "}) if $other_tag && $tag eq $other_tag;
114 }
1d44ce70
AD
115}
116
7e720d4d
AD
1171;
118
119