]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Zones/VxlanPlugin.pm
956c950c40e6fc7686611ea2293aabe32f98ccbc
[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
9 use base('PVE::Network::SDN::Zones::Plugin');
10
11 PVE::JSONSchema::register_format('pve-sdn-vxlanrange', \&pve_verify_sdn_vxlanrange);
12 sub pve_verify_sdn_vxlanrange {
13 my ($vxlanstr) = @_;
14
15 PVE::Network::SDN::Zones::Plugin::parse_tag_number_or_range($vxlanstr, '16777216');
16
17 return $vxlanstr;
18 }
19
20 PVE::JSONSchema::register_format('ipv4-multicast', \&parse_ipv4_multicast);
21 sub parse_ipv4_multicast {
22 my ($ipv4, $noerr) = @_;
23
24 if ($ipv4 !~ m/^(?:$IPV4RE)$/) {
25 return undef if $noerr;
26 die "value does not look like a valid multicast IPv4 address\n";
27 }
28
29 if ($ipv4 =~ m/^(\d+)\.\d+.\d+.\d+/) {
30 if($1 < 224 || $1 > 239) {
31 return undef if $noerr;
32 die "value does not look like a valid multicast IPv4 address\n";
33 }
34 }
35
36 return $ipv4;
37 }
38
39 sub type {
40 return 'vxlan';
41 }
42
43 sub properties {
44 return {
45 'multicast-address' => {
46 description => "Multicast address.",
47 type => 'string', format => 'ipv4-multicast'
48 },
49 'unicast-address' => {
50 description => "Unicast peers address ip list.",
51 type => 'string', format => 'ip-list'
52 },
53 };
54 }
55
56 sub options {
57
58 return {
59 nodes => { optional => 1},
60 'uplink-id' => { optional => 0 },
61 'multicast-address' => { optional => 1 },
62 'unicast-address' => { optional => 1 },
63 };
64 }
65
66 # Plugin implementation
67 sub generate_sdn_config {
68 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
69
70 my $tag = $vnet->{tag};
71 my $alias = $vnet->{alias};
72 my $ipv4 = $vnet->{ipv4};
73 my $ipv6 = $vnet->{ipv6};
74 my $mac = $vnet->{mac};
75 my $multicastaddress = $plugin_config->{'multicast-address'};
76 my @unicastaddress = split(',', $plugin_config->{'unicast-address'}) if $plugin_config->{'unicast-address'};
77
78 my $uplink = $plugin_config->{'uplink-id'};
79
80 die "missing vxlan tag" if !$tag;
81 my $iface = "uplink$uplink";
82 my $ifaceip = "";
83
84 if($uplinks->{$uplink}->{name}) {
85 $iface = $uplinks->{$uplink}->{name};
86 $ifaceip = PVE::Network::SDN::Zones::Plugin::get_first_local_ipv4_from_interface($iface);
87 }
88
89 my $mtu = 1450;
90 $mtu = $uplinks->{$uplink}->{mtu} - 50 if $uplinks->{$uplink}->{mtu};
91 $mtu = $vnet->{mtu} if $vnet->{mtu};
92
93 #vxlan interface
94 my @iface_config = ();
95 push @iface_config, "vxlan-id $tag";
96
97 if($multicastaddress) {
98 push @iface_config, "vxlan-svcnodeip $multicastaddress";
99 push @iface_config, "vxlan-physdev $iface";
100 } elsif (@unicastaddress) {
101
102 foreach my $address (@unicastaddress) {
103 next if $address eq $ifaceip;
104 push @iface_config, "vxlan_remoteip $address";
105 }
106 }
107
108 push @iface_config, "mtu $mtu" if $mtu;
109 push(@{$config->{"vxlan$vnetid"}}, @iface_config) if !$config->{"vxlan$vnetid"};
110
111 #vnet bridge
112 @iface_config = ();
113 push @iface_config, "address $ipv4" if $ipv4;
114 push @iface_config, "address $ipv6" if $ipv6;
115 push @iface_config, "hwaddress $mac" if $mac;
116 push @iface_config, "bridge_ports vxlan$vnetid";
117 push @iface_config, "bridge_stp off";
118 push @iface_config, "bridge_fd 0";
119 push @iface_config, "mtu $mtu" if $mtu;
120 push @iface_config, "alias $alias" if $alias;
121 push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
122
123 return $config;
124 }
125
126 1;
127
128