]>
Commit | Line | Data |
---|---|---|
86d22462 | 1 | package PVE::Network::SDN::VlanPlugin; |
f8140d53 AD |
2 | |
3 | use strict; | |
4 | use warnings; | |
86d22462 | 5 | use PVE::Network::SDN::Plugin; |
f8140d53 | 6 | |
86d22462 | 7 | use base('PVE::Network::SDN::Plugin'); |
f8140d53 AD |
8 | |
9 | sub type { | |
10 | return 'vlan'; | |
11 | } | |
12 | ||
8fb1ee7f AD |
13 | sub plugindata { |
14 | return { | |
15 | role => 'transport', | |
16 | }; | |
17 | } | |
18 | ||
6bffe819 AD |
19 | PVE::JSONSchema::register_format('pve-sdn-vlanrange', \&pve_verify_sdn_vlanrange); |
20 | sub pve_verify_sdn_vlanrange { | |
f8140d53 AD |
21 | my ($vlanstr) = @_; |
22 | ||
86d22462 | 23 | PVE::Network::SDN::Plugin::parse_tag_number_or_range($vlanstr, '4096'); |
f8140d53 AD |
24 | |
25 | return $vlanstr; | |
26 | } | |
27 | ||
28 | sub properties { | |
29 | return { | |
eec580bf AD |
30 | 'uplink-id' => { |
31 | type => 'integer', | |
32 | minimum => 1, maximum => 4096, | |
33 | description => 'Uplink interface', | |
34 | }, | |
f8140d53 | 35 | 'vlan-allowed' => { |
6bffe819 | 36 | type => 'string', format => 'pve-sdn-vlanrange', |
f8140d53 AD |
37 | description => "Allowed vlan range", |
38 | }, | |
39 | 'vlan-aware' => { | |
40 | type => 'boolean', | |
41 | description => "enable 802.1q stacked vlan", | |
42 | }, | |
43 | 'vlan-protocol' => { | |
44 | type => 'string', | |
45 | enum => ['802.1q', '802.1ad'], | |
46 | default => '802.1q', | |
47 | optional => 1, | |
48 | description => "vlan protocol", | |
49 | } | |
50 | }; | |
51 | } | |
52 | ||
53 | sub options { | |
54 | ||
55 | return { | |
41eec961 | 56 | 'uplink-id' => { optional => 0 }, |
f8140d53 AD |
57 | 'vlan-allowed' => { optional => 1 }, |
58 | 'vlan-protocol' => { optional => 1 }, | |
59 | 'vlan-aware' => { optional => 1 }, | |
60 | ||
61 | }; | |
62 | } | |
63 | ||
64 | # Plugin implementation | |
6bffe819 | 65 | sub generate_sdn_config { |
93dea3aa | 66 | my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_; |
f8140d53 AD |
67 | |
68 | my $tag = $vnet->{tag}; | |
69 | my $mtu = $vnet->{mtu}; | |
dc7e431e | 70 | my $alias = $vnet->{alias}; |
f8140d53 AD |
71 | my $vlanaware = $plugin_config->{'vlan-aware'}; |
72 | my $vlanprotocol = $plugin_config->{'vlan-protocol'}; | |
73 | my $uplink = $plugin_config->{'uplink-id'}; | |
74 | my $vlanallowed = $plugin_config->{'vlan-allowed'}; | |
75 | ||
76 | die "missing vlan tag" if !$tag; | |
f8140d53 | 77 | |
83d209f5 TL |
78 | my $iface = $uplinks->{$uplink}->{name}; |
79 | $iface = "uplink${uplink}" if !$iface; | |
f8140d53 | 80 | $iface .= ".$tag"; |
93dea3aa AD |
81 | |
82 | #tagged interface | |
83 | my @iface_config = (); | |
84 | push @iface_config, "vlan-protocol $vlanprotocol" if $vlanprotocol; | |
85 | push @iface_config, "mtu $mtu" if $mtu; | |
87d8b623 | 86 | push(@{$config->{$iface}}, @iface_config) if !$config->{$iface}; |
93dea3aa AD |
87 | |
88 | #vnet bridge | |
89 | @iface_config = (); | |
90 | push @iface_config, "bridge_ports $iface"; | |
91 | push @iface_config, "bridge_stp off"; | |
92 | push @iface_config, "bridge_fd 0"; | |
93 | push @iface_config, "bridge-vlan-aware yes" if $vlanaware; | |
94 | push @iface_config, "mtu $mtu" if $mtu; | |
95 | push @iface_config, "alias $alias" if $alias; | |
87d8b623 | 96 | push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid}; |
f8140d53 AD |
97 | |
98 | return $config; | |
99 | } | |
100 | ||
fe0c6b9e | 101 | sub on_delete_hook { |
6bffe819 | 102 | my ($class, $transportid, $sdn_cfg) = @_; |
fe0c6b9e | 103 | |
a8ad2789 | 104 | # verify that no vnet are associated to this transport |
6bffe819 AD |
105 | foreach my $id (keys %{$sdn_cfg->{ids}}) { |
106 | my $sdn = $sdn_cfg->{ids}->{$id}; | |
a8ad2789 | 107 | die "transport $transportid is used by vnet $id" |
6bffe819 | 108 | if ($sdn->{type} eq 'vnet' && defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid); |
a8ad2789 | 109 | } |
fe0c6b9e AD |
110 | } |
111 | ||
e8d5906e | 112 | sub on_update_hook { |
6bffe819 | 113 | my ($class, $transportid, $sdn_cfg) = @_; |
da07e2b1 | 114 | |
6bffe819 | 115 | my $transport = $sdn_cfg->{ids}->{$transportid}; |
e8d5906e AD |
116 | |
117 | # verify that vlan-allowed don't conflict with another vlan-allowed transport | |
118 | ||
119 | # verify that vlan-allowed is matching currently vnet tag in this transport | |
da07e2b1 AD |
120 | my $vlanallowed = $transport->{'vlan-allowed'}; |
121 | if ($vlanallowed) { | |
6bffe819 AD |
122 | foreach my $id (keys %{$sdn_cfg->{ids}}) { |
123 | my $sdn = $sdn_cfg->{ids}->{$id}; | |
124 | if ($sdn->{type} eq 'vnet' && defined($sdn->{tag})) { | |
125 | if(defined($sdn->{transportzone}) && $sdn->{transportzone} eq $transportid) { | |
126 | my $tag = $sdn->{tag}; | |
da07e2b1 | 127 | eval { |
86d22462 | 128 | PVE::Network::SDN::Plugin::parse_tag_number_or_range($vlanallowed, '4096', $tag); |
da07e2b1 AD |
129 | }; |
130 | if($@) { | |
131 | die "vlan $tag is not allowed in transport $transportid"; | |
132 | } | |
133 | } | |
134 | } | |
135 | } | |
136 | } | |
e8d5906e AD |
137 | } |
138 | ||
f8140d53 AD |
139 | 1; |
140 | ||
141 |