mirror of
https://github.com/systemd/systemd.git
synced 2024-12-11 11:13:58 +08:00
Merge pull request #6116 from richardmaw-codethink/networkd-carrier-fixes
Networkd fixes related to carrier status
This commit is contained in:
commit
b1d25c25e1
@ -34,6 +34,14 @@
|
||||
#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
|
||||
#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
|
||||
|
||||
static void dhcp_lease_free(DHCPLease *lease) {
|
||||
if (!lease)
|
||||
return;
|
||||
|
||||
free(lease->client_id.data);
|
||||
free(lease);
|
||||
}
|
||||
|
||||
/* configures the server's address and subnet, and optionally the pool's size and offset into the subnet
|
||||
* the whole pool must fit into the subnet, and may not contain the first (any) nor last (broadcast) address
|
||||
* moreover, the server's own address may be in the pool, and is in that case reserved in order not to
|
||||
@ -47,7 +55,6 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
|
||||
assert_return(address, -EINVAL);
|
||||
assert_return(address->s_addr != INADDR_ANY, -EINVAL);
|
||||
assert_return(prefixlen <= 32, -ERANGE);
|
||||
assert_return(server->address == INADDR_ANY, -EBUSY);
|
||||
|
||||
assert_se(in_addr_prefixlen_to_netmask(&netmask_addr, prefixlen));
|
||||
netmask = netmask_addr.s_addr;
|
||||
@ -78,19 +85,28 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
|
||||
else
|
||||
size = size_max;
|
||||
|
||||
server->bound_leases = new0(DHCPLease*, size);
|
||||
if (!server->bound_leases)
|
||||
return -ENOMEM;
|
||||
if (server->address != address->s_addr || server->netmask != netmask || server->pool_size != size || server->pool_offset != offset) {
|
||||
DHCPLease *lease;
|
||||
|
||||
server->pool_offset = offset;
|
||||
server->pool_size = size;
|
||||
free(server->bound_leases);
|
||||
server->bound_leases = new0(DHCPLease*, size);
|
||||
if (!server->bound_leases)
|
||||
return -ENOMEM;
|
||||
|
||||
server->address = address->s_addr;
|
||||
server->netmask = netmask;
|
||||
server->subnet = address->s_addr & netmask;
|
||||
server->pool_offset = offset;
|
||||
server->pool_size = size;
|
||||
|
||||
if (server_off >= offset && server_off - offset < size)
|
||||
server->bound_leases[server_off - offset] = &server->invalid_lease;
|
||||
server->address = address->s_addr;
|
||||
server->netmask = netmask;
|
||||
server->subnet = address->s_addr & netmask;
|
||||
|
||||
if (server_off >= offset && server_off - offset < size)
|
||||
server->bound_leases[server_off - offset] = &server->invalid_lease;
|
||||
|
||||
/* Drop any leases associated with the old address range */
|
||||
while ((lease = hashmap_steal_first(server->leases_by_client_id)))
|
||||
dhcp_lease_free(lease);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -143,14 +159,6 @@ static const struct hash_ops client_id_hash_ops = {
|
||||
.compare = client_id_compare_func
|
||||
};
|
||||
|
||||
static void dhcp_lease_free(DHCPLease *lease) {
|
||||
if (!lease)
|
||||
return;
|
||||
|
||||
free(lease->client_id.data);
|
||||
free(lease);
|
||||
}
|
||||
|
||||
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
|
||||
DHCPLease *lease;
|
||||
|
||||
|
@ -63,7 +63,7 @@ static int test_basic(sd_event *event) {
|
||||
assert_se(sd_dhcp_server_configure_pool(server, &address_any, 28, 0, 0) == -EINVAL);
|
||||
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 38, 0, 0) == -ERANGE);
|
||||
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
|
||||
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) == -EBUSY);
|
||||
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
|
||||
|
||||
test_pool(&address_any, 1, -EINVAL);
|
||||
test_pool(&address_lo, 1, 0);
|
||||
|
@ -2135,6 +2135,12 @@ static int link_joined(Link *link) {
|
||||
log_link_error_errno(link, r, "Could not set bridge vlan: %m");
|
||||
}
|
||||
|
||||
/* Skip setting up addresses until it gets carrier,
|
||||
or it would try to set addresses twice,
|
||||
which is bad for non-idempotent steps. */
|
||||
if (!link_has_carrier(link))
|
||||
return 0;
|
||||
|
||||
return link_enter_set_addresses(link);
|
||||
}
|
||||
|
||||
@ -2443,7 +2449,7 @@ static int link_drop_foreign_config(Link *link) {
|
||||
}
|
||||
|
||||
static int link_drop_config(Link *link) {
|
||||
Address *address;
|
||||
Address *address, *pool_address;
|
||||
Route *route;
|
||||
Iterator i;
|
||||
int r;
|
||||
@ -2456,6 +2462,15 @@ static int link_drop_config(Link *link) {
|
||||
r = address_remove(address, link, link_address_remove_handler);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* If this address came from an address pool, clean up the pool */
|
||||
LIST_FOREACH(addresses, pool_address, link->pool_addresses) {
|
||||
if (address_equal(address, pool_address)) {
|
||||
LIST_REMOVE(addresses, link->pool_addresses, pool_address);
|
||||
address_free(pool_address);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SET_FOREACH(route, link->routes, i) {
|
||||
@ -3045,6 +3060,8 @@ static int link_carrier_lost(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
(void) sd_dhcp_server_stop(link->dhcp_server);
|
||||
|
||||
r = link_drop_config(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
Loading…
Reference in New Issue
Block a user