]> git.proxmox.com Git - pve-network.git/blame - PVE/Network/SDN/Zones/QinQPlugin.pm
bump version to 0.4-5
[pve-network.git] / PVE / Network / SDN / Zones / QinQPlugin.pm
CommitLineData
f5eabba0 1package PVE::Network::SDN::Zones::QinQPlugin;
20e19696
AD
2
3use strict;
4use warnings;
3dfdc684 5use PVE::Network::SDN::Zones::Plugin;
20e19696 6
3dfdc684 7use base('PVE::Network::SDN::Zones::Plugin');
20e19696
AD
8
9sub type {
10 return 'qinq';
11}
12
20e19696
AD
13sub properties {
14 return {
f5eabba0
AD
15 tag => {
16 type => 'integer',
17 description => "vlan tag",
18 },
823f2e2a
AD
19 mtu => {
20 type => 'integer',
21 description => "mtu",
22 optional => 1,
23 },
3dfdc684
AD
24 'vlan-protocol' => {
25 type => 'string',
26 enum => ['802.1q', '802.1ad'],
27 default => '802.1q',
28 optional => 1,
29 }
20e19696
AD
30 };
31}
32
33sub options {
34
35 return {
c2b9c173 36 nodes => { optional => 1},
20e19696 37 'tag' => { optional => 0 },
938ebef7 38 'bridge' => { optional => 0 },
823f2e2a 39 'mtu' => { optional => 1 },
3dfdc684 40 'vlan-protocol' => { optional => 1 },
20e19696
AD
41 };
42}
43
44# Plugin implementation
45sub generate_sdn_config {
ba7ac021 46 my ($class, $plugin_config, $zoneid, $vnetid, $vnet, $controller, $interfaces_config, $config) = @_;
20e19696 47
3dfdc684 48 my $stag = $plugin_config->{tag};
938ebef7
AD
49 my $mtu = $plugin_config->{mtu};
50 my $bridge = $plugin_config->{'bridge'};
3dfdc684
AD
51 my $vlanprotocol = $plugin_config->{'vlan-protocol'};
52 my $ctag = $vnet->{tag};
53 my $alias = $vnet->{alias};
20e19696 54
3dfdc684
AD
55 my $vlan_aware = PVE::Tools::file_read_firstline("/sys/class/net/$bridge/bridge/vlan_filtering");
56 my $is_ovs = 1 if !-d "/sys/class/net/$bridge/brif";
20e19696 57
3dfdc684
AD
58 my @iface_config = ();
59 my $vnet_bridge_ports = "";
60
61 if($is_ovs) {
62
63 #ovs--->ovsintport(dot1q-tunnel tag)------->vlanawarebrige-----(tag)--->vnet
64
65 $vlanprotocol = "802.1q" if !$vlanprotocol;
66 my $svlan_iface = "sv_".$zoneid;
67 my $zone = "z_$zoneid";
68
69 #ovs dot1q-tunnel port
70 @iface_config = ();
71 push @iface_config, "ovs_type OVSIntPort";
72 push @iface_config, "ovs_bridge $bridge";
73 push @iface_config, "ovs_options vlan_mode=dot1q-tunnel tag=$stag other_config:qinq-ethtype=$vlanprotocol";
74 push(@{$config->{$svlan_iface}}, @iface_config) if !$config->{$svlan_iface};
75
76
77 #zone vlan aware bridge
78 @iface_config = ();
938ebef7
AD
79 push @iface_config, "mtu $mtu" if $mtu;
80 push @iface_config, "bridge-stp off";
3dfdc684 81 push @iface_config, "bridge-ports $svlan_iface";
938ebef7
AD
82 push @iface_config, "bridge-fd 0";
83 push @iface_config, "bridge-vlan-aware yes";
84 push @iface_config, "bridge-vids 2-4094";
3dfdc684
AD
85 push(@{$config->{$zone}}, @iface_config) if !$config->{$zone};
86
87 $vnet_bridge_ports = "$zone.$ctag";
88
89 } elsif ($vlan_aware) {
90
91 #vlanawarebrige-(tag)----->vlanwarebridge-(tag)----->vnet
938ebef7 92
3dfdc684
AD
93 my $zone = "z_$zoneid";
94
95 if($vlanprotocol) {
96 @iface_config = ();
97 push @iface_config, "bridge-vlan-protocol $vlanprotocol";
98 push(@{$config->{$bridge}}, @iface_config) if !$config->{$bridge};
99 }
100
101 #zone vlan bridge
938ebef7 102 @iface_config = ();
3dfdc684
AD
103 push @iface_config, "mtu $mtu" if $mtu;
104 push @iface_config, "bridge-stp off";
105 push @iface_config, "bridge-ports $bridge.$stag";
106 push @iface_config, "bridge-fd 0";
107 push @iface_config, "bridge-vlan-aware yes";
108 push @iface_config, "bridge-vids 2-4094";
109 push(@{$config->{$zone}}, @iface_config) if !$config->{$zone};
110
111 $vnet_bridge_ports = "$zone.$ctag";
112
113 } else {
114
115 #eth--->eth.x(svlan)--->eth.x.y(cvlan)---->vnet
116
117 my @bridge_ifaces = ();
118 my $dir = "/sys/class/net/$bridge/brif";
119 PVE::Tools::dir_glob_foreach($dir, '(((eth|bond)\d+|en[^.]+)(\.\d+)?)', sub {
120 push @bridge_ifaces, $_[0];
121 });
122
123 foreach my $bridge_iface (@bridge_ifaces) {
124
125 # use named vlan interface to avoid too long names
126 my $svlan_iface = "sv_$vnetid";
127 my $cvlan_iface = "cv_$vnetid";
128
129 #svlan
130 @iface_config = ();
131 push @iface_config, "vlan-raw-device $bridge_iface";
132 push @iface_config, "vlan-id $stag";
133 push @iface_config, "vlan-protocol $vlanprotocol" if $vlanprotocol;
134 push(@{$config->{$svlan_iface}}, @iface_config) if !$config->{$svlan_iface};
135
136 #cvlan
137 @iface_config = ();
138 push @iface_config, "vlan-raw-device $svlan_iface";
139 push @iface_config, "vlan-id $ctag";
140 push(@{$config->{$cvlan_iface}}, @iface_config) if !$config->{$cvlan_iface};
141
142 $vnet_bridge_ports .= " $cvlan_iface";
143 }
144 }
145
146 #vnet bridge
147 @iface_config = ();
148 push @iface_config, "bridge_ports $vnet_bridge_ports";
149 push @iface_config, "bridge_stp off";
150 push @iface_config, "bridge_fd 0";
151 push @iface_config, "mtu $mtu" if $mtu;
152 push @iface_config, "alias $alias" if $alias;
153 push(@{$config->{$vnetid}}, @iface_config) if !$config->{$vnetid};
154
20e19696
AD
155}
156
58433186
AD
157sub status {
158 my ($class, $plugin_config, $zone, $id, $vnet, $err_config, $status, $vnet_status, $zone_status) = @_;
159
160 my $bridge = $plugin_config->{bridge};
161 $vnet_status->{$id}->{zone} = $zone;
162 $zone_status->{$zone}->{status} = 'available' if !defined($zone_status->{$zone}->{status});
163
164 if($err_config) {
165 $vnet_status->{$id}->{status} = 'pending';
166 $vnet_status->{$id}->{statusmsg} = $err_config;
167 $zone_status->{$zone}->{status} = 'pending';
168 } elsif ($status->{$bridge}->{status} && $status->{$bridge}->{status} eq 'pass') {
169 $vnet_status->{$id}->{status} = 'available';
170 } else {
171 $vnet_status->{$id}->{status} = 'error';
172 $vnet_status->{$id}->{statusmsg} = 'missing bridge';
173 $zone_status->{$zone}->{status} = 'error';
174 }
175}
176
20e19696
AD
1771;
178
179