Merge pull request #31730 from yuwata/network-dhcp-server-lease-file-follow-ups

network: several follow-ups for DHCP server lease file
This commit is contained in:
Luca Boccassi 2024-03-25 14:32:05 +00:00 committed by GitHub
commit 650421fb8e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 76 additions and 1 deletions

View file

@ -1495,6 +1495,10 @@ static int address_acquire(Link *link, const Address *address, union in_addr_uni
assert(address);
assert(ret);
r = address_acquire_from_dhcp_server_leases_file(link, address, ret);
if (r != -ENOENT)
return r;
r = address_pool_acquire(link->manager, address->family, address->prefixlen, &a);
if (r < 0)
return r;

View file

@ -57,6 +57,7 @@ struct Address {
bool scope_set:1;
bool ip_masquerade_done:1;
bool requested_as_null:1;
bool used_by_dhcp_server:1;
/* duplicate_address_detection is only used by static or IPv4 dynamic addresses.
* To control DAD for IPv6 dynamic addresses, set IFA_F_NODAD to flags. */

View file

@ -7,6 +7,7 @@
#include "sd-dhcp-server.h"
#include "dhcp-protocol.h"
#include "dhcp-server-lease-internal.h"
#include "fd-util.h"
#include "fileio.h"
#include "network-common.h"
@ -82,6 +83,7 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
/* TODO: check if the prefix length is small enough for the pool. */
network->dhcp_server_address = address;
address->used_by_dhcp_server = true;
break;
}
if (!network->dhcp_server_address) {
@ -128,6 +130,7 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
a->prefixlen = network->dhcp_server_address_prefixlen;
a->in_addr.in = network->dhcp_server_address_in_addr;
a->requested_as_null = !in4_addr_is_set(&network->dhcp_server_address_in_addr);
a->used_by_dhcp_server = true;
r = address_section_verify(a);
if (r < 0)
@ -144,6 +147,49 @@ int network_adjust_dhcp_server(Network *network, Set **addresses) {
return 0;
}
int address_acquire_from_dhcp_server_leases_file(Link *link, const Address *address, union in_addr_union *ret) {
struct in_addr a;
uint8_t prefixlen;
int r;
assert(link);
assert(link->manager);
assert(address);
assert(ret);
/* If the DHCP server address is configured as a null address, reuse the server address of the
* previous instance. */
if (address->family != AF_INET)
return -ENOENT;
if (!address->used_by_dhcp_server)
return -ENOENT;
if (!link_dhcp4_server_enabled(link))
return -ENOENT;
if (link->manager->persistent_storage_fd < 0)
return -EBUSY; /* The persistent storage is not ready, try later again. */
_cleanup_free_ char *lease_file = path_join("dhcp-server-lease", link->ifname);
if (!lease_file)
return -ENOMEM;
r = dhcp_server_leases_file_get_server_address(
link->manager->persistent_storage_fd,
lease_file,
&a,
&prefixlen);
if (r < 0)
return r;
if (prefixlen != address->prefixlen)
return -ENOENT;
ret->in = a;
return 0;
}
int link_start_dhcp4_server(Link *link) {
int r;

View file

@ -2,14 +2,16 @@
#pragma once
#include "conf-parser.h"
#include "in-addr-util.h"
#include "set.h"
typedef struct Address Address;
typedef struct Link Link;
typedef struct Manager Manager;
typedef struct Network Network;
int network_adjust_dhcp_server(Network *network, Set **addresses);
int address_acquire_from_dhcp_server_leases_file(Link *link, const Address *address, union in_addr_union *ret);
int link_request_dhcp_server(Link *link);
int link_start_dhcp4_server(Link *link);

View file

@ -5771,6 +5771,28 @@ class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
output = networkctl_status('veth-peer')
self.assertIn(f'Offered DHCP leases: {client_address}', output)
# Check if the same addresses are used even if the service is restarted.
restart_networkd()
self.wait_online('veth99:routable', 'veth-peer:routable')
output = check_output('ip -4 address show dev veth-peer')
print(output)
self.assertIn(f'{server_address}', output)
output = check_output('ip -4 address show dev veth99')
print(output)
self.assertIn(f'{client_address}', output)
output = networkctl_status('veth99')
print(output)
self.assertRegex(output, rf'Address: {client_address} \(DHCP4 via {server_address}\)')
self.assertIn(f'Gateway: {server_address}', output)
self.assertIn(f'DNS: {server_address}', output)
self.assertIn(f'NTP: {server_address}', output)
output = networkctl_status('veth-peer')
self.assertIn(f'Offered DHCP leases: {client_address}', output)
def test_dhcp_server_with_uplink(self):
copy_network_unit('25-veth.netdev', '25-dhcp-client.network', '25-dhcp-server-downstream.network',
'12-dummy.netdev', '25-dhcp-server-uplink.network')