]> git.proxmox.com Git - pve-network.git/blob - src/PVE/Network/SDN/Dhcp.pm
dhcp dnsmasq: guard die with zone having enabled dhcp
[pve-network.git] / src / PVE / Network / SDN / Dhcp.pm
1 package PVE::Network::SDN::Dhcp;
2
3 use strict;
4 use warnings;
5
6 use PVE::Cluster qw(cfs_read_file);
7
8 use PVE::Network::SDN;
9 use PVE::Network::SDN::SubnetPlugin;
10 use PVE::Network::SDN::Dhcp qw(config);
11 use PVE::Network::SDN::Ipams;
12 use PVE::Network::SDN::Subnets qw(sdn_subnets_config config get_dhcp_ranges);
13 use PVE::Network::SDN::Dhcp::Plugin;
14 use PVE::Network::SDN::Dhcp::Dnsmasq;
15
16 use PVE::INotify qw(nodename);
17
18 PVE::Network::SDN::Dhcp::Plugin->init();
19
20 PVE::Network::SDN::Dhcp::Dnsmasq->register();
21 PVE::Network::SDN::Dhcp::Dnsmasq->init();
22
23 sub add_mapping {
24 my ($vnetid, $mac, $ip4, $ip6) = @_;
25
26 my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
27 return if !$vnet;
28
29 my $zoneid = $vnet->{zone};
30 my $zone = PVE::Network::SDN::Zones::get_zone($zoneid);
31
32 return if !$zone->{ipam} || !$zone->{dhcp};
33
34 my $dhcptype = $zone->{dhcp};
35
36 my $macdb = PVE::Network::SDN::Ipams::read_macdb();
37 my $dhcp_plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcptype);
38 $dhcp_plugin->add_ip_mapping($zoneid, $macdb, $mac, $ip4, $ip6)
39 }
40
41 sub remove_mapping {
42 my ($vnetid, $mac) = @_;
43
44 my $vnet = PVE::Network::SDN::Vnets::get_vnet($vnetid);
45 return if !$vnet;
46
47 my $zoneid = $vnet->{zone};
48 my $zone = PVE::Network::SDN::Zones::get_zone($zoneid);
49
50 return if !$zone->{ipam} || !$zone->{dhcp};
51
52 my $dhcp_plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($zone->{dhcp});
53 $dhcp_plugin->del_ip_mapping($zoneid, $mac);
54 }
55
56 sub regenerate_config {
57 my ($reload) = @_;
58
59 my $cfg = PVE::Network::SDN::running_config();
60
61 my $zone_cfg = $cfg->{zones};
62 my $vnet_cfg = $cfg->{vnets};
63 my $subnet_cfg = $cfg->{subnets};
64 return if !$zone_cfg && !$subnet_cfg;
65
66 my $nodename = PVE::INotify::nodename();
67
68 my $plugins = PVE::Network::SDN::Dhcp::Plugin->lookup_types();
69
70 my $any_zone_needs_dhcp = grep { $_->{dhcp} } values $zone_cfg->{ids}->%*;
71
72 foreach my $plugin_name (@$plugins) {
73 my $plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($plugin_name);
74 eval { $plugin->before_regenerate(!$any_zone_needs_dhcp) };
75 die "Could not run before_regenerate for DHCP plugin $plugin_name $@\n" if $@;
76 }
77
78 foreach my $zoneid (sort keys %{$zone_cfg->{ids}}) {
79 my $zone = $zone_cfg->{ids}->{$zoneid};
80 next if !$zone->{dhcp};
81
82 my $dhcp_plugin_name = $zone->{dhcp};
83 my $dhcp_plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($dhcp_plugin_name);
84
85 die "Could not find DHCP plugin: $dhcp_plugin_name" if !$dhcp_plugin;
86
87 eval { $dhcp_plugin->before_configure($zoneid) };
88 die "Could not run before_configure for DHCP server $zoneid $@\n" if $@;
89
90 for my $vnetid (sort keys %{$vnet_cfg->{ids}}) {
91 my $vnet = $vnet_cfg->{ids}->{$vnetid};
92 next if $vnet->{zone} ne $zoneid;
93
94 my $config = [];
95 my $subnets = PVE::Network::SDN::Vnets::get_subnets($vnetid);
96
97 foreach my $subnet_id (sort keys %{$subnets}) {
98 my $subnet_config = $subnets->{$subnet_id};
99 my $dhcp_ranges = PVE::Network::SDN::Subnets::get_dhcp_ranges($subnet_config);
100
101 my ($zone, $subnet_network, $subnet_mask) = split(/-/, $subnet_id);
102 next if $zone ne $zoneid;
103 next if !$dhcp_ranges;
104
105 eval { $dhcp_plugin->configure_subnet($config, $zoneid, $vnetid, $subnet_config) };
106 warn "Could not configure subnet $subnet_id: $@\n" if $@;
107
108 foreach my $dhcp_range (@$dhcp_ranges) {
109 eval { $dhcp_plugin->configure_range($config, $zoneid, $vnetid, $subnet_config, $dhcp_range) };
110 warn "Could not configure DHCP range for $subnet_id: $@\n" if $@;
111 }
112 }
113
114 eval { $dhcp_plugin->configure_vnet($config, $zoneid, $vnetid, $vnet) };
115 warn "Could not configure vnet $vnetid: $@\n" if $@;
116 }
117
118 eval { $dhcp_plugin->after_configure($zoneid, !$any_zone_needs_dhcp) };
119 warn "Could not run after_configure for DHCP server $zoneid $@\n" if $@;
120
121 }
122
123 foreach my $plugin_name (@$plugins) {
124 my $plugin = PVE::Network::SDN::Dhcp::Plugin->lookup($plugin_name);
125
126 eval { $plugin->after_regenerate() };
127 warn "Could not run after_regenerate for DHCP plugin $plugin_name $@\n" if $@;
128 }
129 }
130
131 1;