]> git.proxmox.com Git - pve-network.git/blob - PVE/Network/SDN/Vnets.pm
Fix vnet gateway for routed setup + /32 pointopoint subnet
[pve-network.git] / PVE / Network / SDN / Vnets.pm
1 package PVE::Network::SDN::Vnets;
2
3 use strict;
4 use warnings;
5
6 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
7 use Net::IP;
8 use PVE::Network::SDN::Subnets;
9
10 use PVE::Network::SDN::VnetPlugin;
11 PVE::Network::SDN::VnetPlugin->register();
12 PVE::Network::SDN::VnetPlugin->init();
13
14 sub sdn_vnets_config {
15 my ($cfg, $id, $noerr) = @_;
16
17 die "no sdn vnet ID specified\n" if !$id;
18
19 my $scfg = $cfg->{ids}->{$id};
20 die "sdn vnet '$id' does not exist\n" if (!$noerr && !$scfg);
21
22 return $scfg;
23 }
24
25 sub config {
26 return cfs_read_file("sdn/vnets.cfg");
27 }
28
29 sub write_config {
30 my ($cfg) = @_;
31
32 cfs_write_file("sdn/vnets.cfg", $cfg);
33 }
34
35 sub sdn_vnets_ids {
36 my ($cfg) = @_;
37
38 return keys %{$cfg->{ids}};
39 }
40
41 sub complete_sdn_vnet {
42 my ($cmdname, $pname, $cvalue) = @_;
43
44 my $cfg = PVE::Network::SDN::Vnets::config();
45
46 return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::Vnets::sdn_vnet_ids($cfg) ];
47 }
48
49 sub get_vnet {
50 my ($vnetid) = @_;
51
52 my $cfg = PVE::Network::SDN::Vnets::config();
53 my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($cfg, $vnetid, 1);
54 return $vnet;
55 }
56
57 sub get_subnets {
58 my ($vnetid) = @_;
59
60 my $subnets = {};
61 my $subnets_cfg = PVE::Network::SDN::Subnets::config();
62 foreach my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
63 my $subnet = $subnets_cfg->{ids}->{$subnetid};
64 next if !$subnet->{vnet} || $subnet->{vnet} ne $vnetid;
65 $subnets->{$subnetid} = $subnet;
66 }
67 return $subnets;
68
69 }
70
71 sub get_next_free_ip {
72 my ($vnetid, $hostname, $ipversion) = @_;
73
74 $ipversion = 4 if !$ipversion;
75 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
76 my $ip = undef;
77 my $subnetcount = 0;
78
79 foreach my $subnetid (sort keys %{$subnets}) {
80 my $subnet = $subnets->{$subnetid};
81 my ($network, $mask) = split(/-/, $subnetid);
82
83 next if $ipversion != Net::IP::ip_get_version($network);
84 $subnetcount++;
85 if ($subnet->{ipam}) {
86 eval {
87 $ip = PVE::Network::SDN::Subnets::next_free_ip($subnetid, $subnet, $hostname);
88 };
89 warn $@ if $@;
90 }
91 last if $ip;
92 }
93 die "can't find any free ip" if !$ip && $subnetcount > 0;
94
95 return $ip;
96 }
97
98 sub add_ip {
99 my ($vnetid, $cidr, $hostname) = @_;
100
101 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
102
103 my ($ip, $mask) = split(/\//, $cidr);
104 my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
105
106 PVE::Network::SDN::Subnets::add_ip($subnetid, $subnet, $ip, $hostname);
107 }
108
109 sub del_ip {
110 my ($vnetid, $cidr, $hostname) = @_;
111
112 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
113
114 my ($ip, $mask) = split(/\//, $cidr);
115 my ($subnetid, $subnet) = PVE::Network::SDN::Subnets::find_ip_subnet($ip, $subnets);
116
117 PVE::Network::SDN::Subnets::del_ip($subnetid, $subnet, $ip, $hostname);
118 }
119
120 1;