]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Zones/VxlanPlugin.pm
vnets: allow duplicate tags in differents zones
[pve-network.git] / PVE / Network / SDN / Zones / VxlanPlugin.pm
1 package PVE::Network::SDN::Zones::VxlanPlugin;
2
3 use strict;
4 use warnings;
5 use PVE::Network::SDN::Zones::Plugin;
6 use PVE::Tools qw($IPV4RE);
7 use PVE::INotify;
8 use PVE::Network::SDN::Controllers::EvpnPlugin;
9 use PVE::Exception qw(raise raise_param_exc);
10
11 use base('PVE::Network::SDN::Zones::Plugin');
12
13 PVE::JSONSchema::register_format('pve-sdn-vxlanrange', \&pve_verify_sdn_vxlanrange);
14 sub pve_verify_sdn_vxlanrange {
15 my ($vxlanstr) = @_;
16
17 PVE::Network::SDN::Zones::Plugin::parse_tag_number_or_range($vxlanstr, '16777216');
18
19 return $vxlanstr;
20 }
21
22 sub type {
23 return 'vxlan';
24 }
25
26 sub properties {
27 return {
28 'peers' => {
29 description => "peers address list.",
30 type => 'string', format => 'ip-list'
31 },
32 };
33 }
34
35 sub options {
36
37 return {
38 nodes => { optional => 1},
39 peers => { optional => 0 },
40 mtu => { optional => 1 },
41 dns => { optional => 1 },
42 reversedns => { optional => 1 },
43 dnszone => { optional => 1 },
44 ipam => { optional => 0 },
45 };
46 }
47
48 # Plugin implementation
49 sub generate_sdn_config {
50 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $controller, $subnet_cfg, $interfaces_config, $config) = @_;
51
52 my $tag = $vnet->{tag};
53 my $alias = $vnet->{alias};
54 my $multicastaddress = $plugin_config->{'multicast-address'};
55 my @peers;
56 @peers = PVE::Tools::split_list($plugin_config->{'peers'}) if $plugin_config->{'peers'};
57 my $vxlan_iface = "vxlan_$vnetid";
58
59 die "missing vxlan tag" if !$tag;
60
61 my ($ifaceip, $iface) = PVE::Network::SDN::Zones::Plugin::find_local_ip_interface_peers(\@peers);
62
63 my $mtu = 1450;
64 $mtu = $interfaces_config->{$iface}->{mtu} - 50 if $interfaces_config->{$iface}->{mtu};
65 $mtu = $plugin_config->{mtu} if $plugin_config->{mtu};
66
67 #vxlan interface
68 my @iface_config = ();
69 push @iface_config, "vxlan-id $tag";
70
71 foreach my $address (@peers) {
72 next if $address eq $ifaceip;
73 push @iface_config, "vxlan_remoteip $address";
74 }
75
76
77 push @iface_config, "mtu $mtu" if $mtu;
78 push(@{$config->{$vxlan_iface}}, @iface_config) if !$config->{$vxlan_iface};
79
80 #vnet bridge
81 @iface_config = ();
82 push @iface_config, "bridge_ports $vxlan_iface";
83 push @iface_config, "bridge_stp off";
84 push @iface_config, "bridge_fd 0";
85 if($vnet->{vlanaware}) {
86 push @iface_config, "bridge-vlan-aware yes";
87 push @iface_config, "bridge-vids 2-4094";
88 }
89 push @iface_config, "mtu $mtu" if $mtu;
90 push @iface_config, "alias $alias" if $alias;
91 push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
92
93 return $config;
94 }
95
96 sub vnet_update_hook {
97 my ($class, $vnet_cfg, $vnetid, $zone_cfg) = @_;
98
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 }
115 }
116
117 1;
118
119