mirror of
https://github.com/systemd/systemd
synced 2024-07-21 10:17:21 +00:00
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:
commit
650421fb8e
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in a new issue