]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/VxlanPlugin.pm
generate network config in a hash
[pve-network.git] / PVE / Network / SDN / VxlanPlugin.pm
1 package PVE::Network::SDN::VxlanPlugin;
2
3 use strict;
4 use warnings;
5 use PVE::Network::SDN::Plugin;
6 use PVE::Tools;
7
8 use base('PVE::Network::SDN::Plugin');
9
10 PVE::JSONSchema::register_format('pve-sdn-vxlanrange', \&pve_verify_sdn_vxlanrange);
11 sub pve_verify_sdn_vxlanrange {
12 my ($vxlanstr) = @_;
13
14 PVE::Network::SDN::Plugin::parse_tag_number_or_range($vxlanstr, '16777216');
15
16 return $vxlanstr;
17 }
18
19 sub type {
20 return 'vxlan';
21 }
22
23 sub properties {
24 return {
25 'vxlan-allowed' => {
26 type => 'string', format => 'pve-sdn-vxlanrange',
27 description => "Allowed vlan range",
28 },
29 'multicast-address' => {
30 description => "Multicast address.",
31 type => 'string', #fixme: format
32 },
33 'unicast-address' => {
34 description => "Unicast peers address ip list.",
35 type => 'string', #fixme: format
36 },
37 'vrf' => {
38 description => "vrf name.",
39 type => 'string', #fixme: format
40 },
41 'vrf-vxlan' => {
42 type => 'integer',
43 description => "l3vni.",
44 },
45 };
46 }
47
48 sub options {
49
50 return {
51 'uplink-id' => { optional => 0 },
52 'multicast-address' => { optional => 1 },
53 'unicast-address' => { optional => 1 },
54 'vxlan-allowed' => { optional => 1 },
55 'vrf' => { optional => 1 },
56 'vrf-vxlan' => { optional => 1 },
57 };
58 }
59
60 # Plugin implementation
61 sub generate_sdn_config {
62 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
63
64 my $tag = $vnet->{tag};
65 my $alias = $vnet->{alias};
66 my $ipv4 = $vnet->{ipv4};
67 my $ipv6 = $vnet->{ipv6};
68 my $mac = $vnet->{mac};
69 my $multicastaddress = $plugin_config->{'multicast-address'};
70 my @unicastaddress = split(',', $plugin_config->{'unicast-address'}) if $plugin_config->{'unicast-address'};
71
72 my $uplink = $plugin_config->{'uplink-id'};
73 my $vxlanallowed = $plugin_config->{'vxlan-allowed'};
74 my $vrf = $plugin_config->{'vrf'};
75 my $vrfvxlan = $plugin_config->{'vrf-vxlan'};
76
77 die "missing vxlan tag" if !$tag;
78 my $iface = "uplink$uplink";
79 my $ifaceip = "";
80
81 if($uplinks->{$uplink}->{name}) {
82 $iface = $uplinks->{$uplink}->{name};
83 $ifaceip = PVE::Network::SDN::Plugin::get_first_local_ipv4_from_interface($iface);
84 }
85
86 my $mtu = 1450;
87 $mtu = $uplinks->{$uplink}->{mtu} - 50 if $uplinks->{$uplink}->{mtu};
88 $mtu = $vnet->{mtu} if $vnet->{mtu};
89
90 #vxlan interface
91 my @iface_config = ();
92 push @iface_config, "vxlan-id $tag";
93
94 if($multicastaddress) {
95 push @iface_config, "vxlan-svcnodeip $multicastaddress";
96 push @iface_config, "vxlan-physdev $iface";
97 } elsif (@unicastaddress) {
98
99 foreach my $address (@unicastaddress) {
100 next if $address eq $ifaceip;
101 push @iface_config, "vxlan_remoteip $address";
102 }
103 } else {
104 push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
105 push @iface_config, "bridge-learning off";
106 push @iface_config, "bridge-arp-nd-suppress on";
107 }
108
109 push @iface_config, "mtu $mtu" if $mtu;
110 push(@{$config->{network}->{"vxlan$vnetid"}}, @iface_config) if !$config->{network}->{"vxlan$vnetid"};
111
112 #vnet bridge
113 @iface_config = ();
114 push @iface_config, "address $ipv4" if $ipv4;
115 push @iface_config, "address $ipv6" if $ipv6;
116 push @iface_config, "hwaddress $mac" if $mac;
117 push @iface_config, "bridge_ports vxlan$vnetid";
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, "alias $alias" if $alias;
122 push @iface_config, "vrf $vrf" if $vrf;
123 push(@{$config->{network}->{$vnetid}}, @iface_config) if !$config->{network}->{$vnetid};
124
125 if ($vrf) {
126 #vrf intreface
127 @iface_config = ();
128 push @iface_config, "vrf-table auto";
129 push(@{$config->{network}->{$vrf}}, @iface_config) if !$config->{network}->{$vrf};
130
131 if ($vrfvxlan) {
132 #l3vni vxlan interface
133 my $iface_vxlan = "vxlan$vrf";
134 @iface_config = ();
135 push @iface_config, "vxlan-id $vrfvxlan";
136 push @iface_config, "vxlan-local-tunnelip $ifaceip" if $ifaceip;
137 push @iface_config, "bridge-learning off";
138 push @iface_config, "bridge-arp-nd-suppress on";
139 push @iface_config, "mtu $mtu" if $mtu;
140 push(@{$config->{network}->{$iface_vxlan}}, @iface_config) if !$config->{network}->{$iface_vxlan};
141
142 #l3vni bridge
143 my $brvrf = "br$vrf";
144 @iface_config = ();
145 push @iface_config, "bridge-ports $iface_vxlan";
146 push @iface_config, "bridge_stp off";
147 push @iface_config, "bridge_fd 0";
148 push @iface_config, "mtu $mtu" if $mtu;
149 push @iface_config, "vrf $vrf";
150 push(@{$config->{network}->{$brvrf}}, @iface_config) if !$config->{network}->{$brvrf};
151 }
152 }
153
154 return $config;
155 }
156
157 sub on_delete_hook {
158 my ($class, $transportid, $sdn_cfg) = @_;
159
160 # verify that no vnet are associated to this transport
161 foreach my $id (keys %{$sdn_cfg->{ids}}) {
162 my $sdn = $sdn_cfg->{ids}->{$id};
163 die "transport $transportid is used by vnet $id"
164 if ($sdn->{type} eq 'vnet' && defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid);
165 }
166 }
167
168 sub on_update_hook {
169 my ($class, $transportid, $sdn_cfg) = @_;
170
171 my $transport = $sdn_cfg->{ids}->{$transportid};
172
173 # verify that vxlan-allowed don't conflict with another vxlan-allowed transport
174
175 # verify that vxlan-allowed is matching currently vnet tag in this transport
176 my $vxlanallowed = $transport->{'vxlan-allowed'};
177 if ($vxlanallowed) {
178 foreach my $id (keys %{$sdn_cfg->{ids}}) {
179 my $sdn = $sdn_cfg->{ids}->{$id};
180 if ($sdn->{type} eq 'vnet' && defined($sdn->{tag})) {
181 if(defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid) {
182 my $tag = $sdn->{tag};
183 eval {
184 PVE::Network::SDN::Plugin::parse_tag_number_or_range($vxlanallowed, '16777216', $tag);
185 };
186 if($@) {
187 die "vnet $id - vlan $tag is not allowed in transport $transportid";
188 }
189 }
190 }
191 }
192 }
193 }
194
195 1;
196
197