]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Vnets.pm
8c9629dc429820d961c8b4998a6925acd8e4a374
[pve-network.git] / PVE / Network / SDN / Vnets.pm
1 package PVE::Network::SDN::Vnets;
2
3 use strict;
4 use warnings;
5
6 use Net::IP;
7
8 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
9 use PVE::Network::SDN;
10 use PVE::Network::SDN::Subnets;
11 use PVE::Network::SDN::Zones;
12
13 use PVE::Network::SDN::VnetPlugin;
14 PVE::Network::SDN::VnetPlugin->register();
15 PVE::Network::SDN::VnetPlugin->init();
16
17 sub sdn_vnets_config {
18 my ($cfg, $id, $noerr) = @_;
19
20 die "no sdn vnet ID specified\n" if !$id;
21
22 my $scfg = $cfg->{ids}->{$id};
23 die "sdn vnet '$id' does not exist\n" if (!$noerr && !$scfg);
24
25 return $scfg;
26 }
27
28 sub config {
29 return cfs_read_file("sdn/vnets.cfg");
30 }
31
32 sub write_config {
33 my ($cfg) = @_;
34
35 cfs_write_file("sdn/vnets.cfg", $cfg);
36 }
37
38 sub sdn_vnets_ids {
39 my ($cfg) = @_;
40
41 return sort keys %{$cfg->{ids}};
42 }
43
44 sub complete_sdn_vnet {
45 my ($cmdname, $pname, $cvalue) = @_;
46
47 my $cfg = PVE::Network::SDN::Vnets::config();
48
49 return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::Vnets::sdn_vnet_ids($cfg) ];
50 }
51
52 sub get_vnet {
53 my ($vnetid, $running) = @_;
54
55 my $cfg = {};
56 if($running) {
57 my $cfg = PVE::Network::SDN::running_config();
58 $cfg = $cfg->{vnets};
59 } else {
60 $cfg = PVE::Network::SDN::Vnets::config();
61 }
62
63 my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($cfg, $vnetid, 1);
64
65 return $vnet;
66 }
67
68 sub get_subnets {
69 my ($vnetid) = @_;
70
71 my $subnets = undef;
72 my $subnets_cfg = PVE::Network::SDN::Subnets::config();
73 foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
74 my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($subnets_cfg, $subnetid);
75 next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid;
76 $subnets->{$subnetid} = $subnet;
77 }
78 return $subnets;
79
80 }
81
82 sub get_subnet_from_vnet_cidr {
83 my ($vnetid, $cidr) = @_;
84
85 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
86 my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
87 my $zoneid = $vnet->{zone};
88 my $zone = PVE::Network::SDN::Zones::get_zone($zoneid);
89
90 my ($ip, $mask) = split(/\//, $cidr);
91 die "ip address is not in cidr format" if !$mask;
92
93 my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $mask, $subnets);
94
95 return ($zone, $subnetid, $subnet, $ip);
96 }
97
98 sub get_next_free_cidr {
99 my ($vnetid, $hostname, $mac, $description, $ipversion) = @_;
100
101 my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
102 my $zoneid = $vnet->{zone};
103 my $zone = PVE::Network::SDN::Zones::get_zone($zoneid);
104
105 return if !$zone->{ipam};
106
107 $ipversion = 4 if !$ipversion;
108 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid, 1);
109 my $ip = undef;
110 my $subnetcount = 0;
111
112 foreach my $subnetid (sort keys %{$subnets}) {
113 my $subnet = $subnets->{$subnetid};
114 my $network = $subnet->{network};
115
116 next if $ipversion != Net::IP::ip_get_version($network);
117 $subnetcount++;
118
119 eval {
120 $ip = PVE::Network::SDN::Subnets::next_free_ip($zone, $subnetid, $subnet, $hostname, $mac, $description);
121 };
122 warn $@ if $@;
123 last if $ip;
124 }
125 die "can't find any free ip" if !$ip && $subnetcount > 0;
126
127 return $ip;
128 }
129
130 sub add_cidr {
131 my ($vnetid, $cidr, $hostname, $mac, $description) = @_;
132
133 my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
134 PVE::Network::SDN::Subnets::add_ip($zone, $subnetid, $subnet, $ip, $hostname, $mac, $description);
135 }
136
137 sub update_cidr {
138 my ($vnetid, $cidr, $hostname, $oldhostname, $mac, $description) = @_;
139
140 my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
141 PVE::Network::SDN::Subnets::update_ip($zone, $subnetid, $subnet, $ip, $hostname, $oldhostname, $mac, $description);
142 }
143
144 sub del_cidr {
145 my ($vnetid, $cidr, $hostname) = @_;
146
147 my ($zone, $subnetid, $subnet, $ip) = PVE::Network::SDN::Vnets::get_subnet_from_vnet_cidr($vnetid, $cidr);
148 PVE::Network::SDN::Subnets::del_ip($zone, $subnetid, $subnet, $ip, $hostname);
149 }
150
151
152
153 1;