]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Zones/VlanPlugin.pm
rename transportzone option to zone
[pve-network.git] / PVE / Network / SDN / Zones / VlanPlugin.pm
1 package PVE::Network::SDN::Zones::VlanPlugin;
2
3 use strict;
4 use warnings;
5 use PVE::Network::SDN::Zones::Plugin;
6
7 use base('PVE::Network::SDN::Zones::Plugin');
8
9 sub type {
10 return 'vlan';
11 }
12
13 PVE::JSONSchema::register_format('pve-sdn-vlanrange', \&pve_verify_sdn_vlanrange);
14 sub pve_verify_sdn_vlanrange {
15 my ($vlanstr) = @_;
16
17 PVE::Network::SDN::Zones::Plugin::parse_tag_number_or_range($vlanstr, '4096');
18
19 return $vlanstr;
20 }
21
22 sub properties {
23 return {
24 'uplink-id' => {
25 type => 'integer',
26 minimum => 1, maximum => 4096,
27 description => 'Uplink interface',
28 },
29 'vlan-allowed' => {
30 type => 'string', format => 'pve-sdn-vlanrange',
31 description => "Allowed vlan range",
32 },
33 };
34 }
35
36 sub options {
37
38 return {
39 'uplink-id' => { optional => 0 },
40 'vlan-allowed' => { optional => 1 },
41 };
42 }
43
44 # Plugin implementation
45 sub generate_sdn_config {
46 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $uplinks, $config) = @_;
47
48 my $tag = $vnet->{tag};
49 my $mtu = $vnet->{mtu};
50 my $alias = $vnet->{alias};
51 my $uplink = $plugin_config->{'uplink-id'};
52
53 die "missing vlan tag" if !$tag;
54
55 my $iface = $uplinks->{$uplink}->{name};
56 $iface = "uplink${uplink}" if !$iface;
57 $iface .= ".$tag";
58
59 #tagged interface
60 my @iface_config = ();
61 push @iface_config, "mtu $mtu" if $mtu;
62 push(@{$config->{$iface}}, @iface_config) if !$config->{$iface};
63
64 #vnet bridge
65 @iface_config = ();
66 push @iface_config, "bridge_ports $iface";
67 push @iface_config, "bridge_stp off";
68 push @iface_config, "bridge_fd 0";
69 push @iface_config, "mtu $mtu" if $mtu;
70 push @iface_config, "alias $alias" if $alias;
71 push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
72
73 return $config;
74 }
75
76 sub on_delete_hook {
77 my ($class, $transportid, $sdn_cfg) = @_;
78
79 # verify that no vnet are associated to this transport
80 foreach my $id (keys %{$sdn_cfg->{ids}}) {
81 my $sdn = $sdn_cfg->{ids}->{$id};
82 die "transport $transportid is used by vnet $id"
83 if ($sdn->{type} eq 'vnet' && defined($sdn->{zone}) && $sdn->{zone} eq $transportid);
84 }
85 }
86
87 sub on_update_hook {
88 my ($class, $transportid, $sdn_cfg) = @_;
89
90 my $transport = $sdn_cfg->{ids}->{$transportid};
91
92 # verify that vlan-allowed don't conflict with another vlan-allowed transport
93
94 # verify that vlan-allowed is matching currently vnet tag in this transport
95 my $vlanallowed = $transport->{'vlan-allowed'};
96 if ($vlanallowed) {
97 foreach my $id (keys %{$sdn_cfg->{ids}}) {
98 my $sdn = $sdn_cfg->{ids}->{$id};
99 if ($sdn->{type} eq 'vnet' && defined($sdn->{tag})) {
100 if(defined($sdn->{zone}) && $sdn->{zone} eq $transportid) {
101 my $tag = $sdn->{tag};
102 eval {
103 PVE::Network::SDN::Zones::Plugin::parse_tag_number_or_range($vlanallowed, '4096', $tag);
104 };
105 if($@) {
106 die "vlan $tag is not allowed in transport $transportid";
107 }
108 }
109 }
110 }
111 }
112 }
113
114 1;
115
116