]> git.proxmox.com Git - pve-network.git/blame - PVE/Network/Network/VnetPlugin.pm
vnet: update_hook: verify if tag already exist in another vnet
[pve-network.git] / PVE / Network / Network / VnetPlugin.pm
CommitLineData
6bad73d0 1package PVE::Network::Network::VnetPlugin;
e7939454
AD
2
3use strict;
4use warnings;
6bad73d0 5use PVE::Network::Network::Plugin;
e7939454 6
6bad73d0 7use base('PVE::Network::Network::Plugin');
e7939454 8
aa38ba46 9use PVE::Cluster;
46cd4e06
AD
10
11# dynamically include PVE::QemuServer and PVE::LXC
12# to avoid dependency problems
13my $have_qemu_server;
14eval {
15 require PVE::QemuServer;
16 require PVE::QemuConfig;
17 $have_qemu_server = 1;
18};
19
20my $have_lxc;
21eval {
22 require PVE::LXC;
23 require PVE::LXC::Config;
24
25 $have_lxc = 1;
26};
aa38ba46 27
6bad73d0
AD
28sub type {
29 return 'vnet';
30}
e7939454 31
e7939454
AD
32
33
6bad73d0 34sub properties {
e7939454 35 return {
e7939454
AD
36 transportzone => {
37 type => 'string',
38 description => "transportzone id",
e7939454
AD
39 },
40 tag => {
41 type => 'integer',
42 description => "vlan or vxlan id",
e7939454 43 },
dc7e431e 44 alias => {
e7939454 45 type => 'string',
dc7e431e 46 description => "alias name of the vnet",
e7939454
AD
47 optional => 1,
48 },
49 mtu => {
50 type => 'integer',
51 description => "mtu",
52 optional => 1,
53 },
54 ipv4 => {
55 description => "Anycast router ipv4 address.",
56 type => 'string', format => 'ipv4',
57 optional => 1,
58 },
59 ipv6 => {
60 description => "Anycast router ipv6 address.",
61 type => 'string', format => 'ipv6',
62 optional => 1,
63 },
64 mac => {
65 type => 'boolean',
66 description => "Anycast router mac address",
67 optional => 1,
68 }
6bad73d0 69 };
e7939454
AD
70}
71
6bad73d0
AD
72sub options {
73 return {
205e9166
AD
74 transportzone => { optional => 0},
75 tag => { optional => 0},
dc7e431e 76 alias => { optional => 1 },
6bad73d0
AD
77 ipv4 => { optional => 1 },
78 ipv6 => { optional => 1 },
6bad73d0
AD
79 mtu => { optional => 1 },
80 };
e7939454
AD
81}
82
fe0c6b9e
AD
83sub on_delete_hook {
84 my ($class, $networkid, $scfg) = @_;
85
86 # verify than no vm or ct have interfaces in this bridge
b1791012 87 my $vmdata = read_cluster_vm_config();
aa38ba46
AD
88
89 foreach my $vmid (sort keys %{$vmdata->{qemu}}) {
90 my $conf = $vmdata->{qemu}->{$vmid};
91 foreach my $netid (sort keys %$conf) {
92 next if $netid !~ m/^net(\d+)$/;
93 my $net = PVE::QemuServer::parse_net($conf->{$netid});
94 die "vnet $networkid is used by vm $vmid" if $net->{bridge} eq $networkid;
95 }
96 }
97
98 foreach my $vmid (sort keys %{$vmdata->{lxc}}) {
99 my $conf = $vmdata->{lxc}->{$vmid};
100 foreach my $netid (sort keys %$conf) {
101 next if $netid !~ m/^net(\d+)$/;
102 my $net = PVE::LXC::Config->parse_lxc_network($conf->{$netid});
103 die "vnet $networkid is used by ct $vmid" if $net->{bridge} eq $networkid;
104 }
105 }
106
fe0c6b9e
AD
107}
108
e8d5906e 109sub on_update_hook {
6a2db30a 110 my ($class, $networkid, $network_cfg) = @_;
e8d5906e 111 # verify that tag is not already defined in another vnet
6a2db30a
AD
112 if (defined($network_cfg->{ids}->{$networkid}->{tag})) {
113 my $tag = $network_cfg->{ids}->{$networkid}->{tag};
114 foreach my $id (keys %{$network_cfg->{ids}}) {
115 next if $id eq $networkid;
116 my $network = $network_cfg->{ids}->{$id};
117 if ($network->{type} eq 'vnet' && defined($network->{tag})) {
118 die "tag $tag already exist in vnet $id" if $tag eq $network->{tag};
119 }
120 }
121 }
e8d5906e 122}
e7939454 123
b1791012 124sub read_cluster_vm_config {
aa38ba46
AD
125
126 my $qemu = {};
127 my $lxc = {};
128
129 my $vmdata = { qemu => $qemu, lxc => $lxc };
130
131 my $vmlist = PVE::Cluster::get_vmlist();
132 return $vmdata if !$vmlist || !$vmlist->{ids};
133 my $ids = $vmlist->{ids};
134
135 foreach my $vmid (keys %$ids) {
136 next if !$vmid;
137 my $d = $ids->{$vmid};
aa38ba46 138 next if !$d->{type};
46cd4e06 139 if ($d->{type} eq 'qemu' && $have_qemu_server) {
aa38ba46
AD
140 my $cfspath = PVE::QemuConfig->cfs_config_path($vmid);
141 if (my $conf = PVE::Cluster::cfs_read_file($cfspath)) {
142 $qemu->{$vmid} = $conf;
143 }
46cd4e06 144 } elsif ($d->{type} eq 'lxc' && $have_lxc) {
aa38ba46
AD
145 my $cfspath = PVE::LXC::Config->cfs_config_path($vmid);
146 if (my $conf = PVE::Cluster::cfs_read_file($cfspath)) {
147 $lxc->{$vmid} = $conf;
148 }
149 }
150 }
151
152 return $vmdata;
153};
154
e7939454 1551;