mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
Merge pull request #25142 from yuwata/network-fix-race-in-device-renaming-vs-dhcp
network,dhcp: fix theoretical race in device renaming
This commit is contained in:
commit
7319adcd1b
@ -4,15 +4,11 @@
|
|||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
|
|
||||||
#include "sd-device.h"
|
|
||||||
#include "sd-id128.h"
|
|
||||||
|
|
||||||
#include "dhcp-identifier.h"
|
#include "dhcp-identifier.h"
|
||||||
#include "netif-util.h"
|
#include "netif-util.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
#include "sparse-endian.h"
|
#include "sparse-endian.h"
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
#include "udev-util.h"
|
|
||||||
|
|
||||||
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
|
#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
|
||||||
#define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
|
#define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
|
||||||
@ -207,48 +203,20 @@ int dhcp_identifier_set_duid(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dhcp_identifier_set_iaid(
|
int dhcp_identifier_set_iaid(
|
||||||
int ifindex,
|
sd_device *dev,
|
||||||
const struct hw_addr_data *hw_addr,
|
const struct hw_addr_data *hw_addr,
|
||||||
bool legacy_unstable_byteorder,
|
bool legacy_unstable_byteorder,
|
||||||
bool use_mac,
|
|
||||||
void *ret) {
|
void *ret) {
|
||||||
|
|
||||||
/* name is a pointer to memory in the sd_device struct, so must
|
|
||||||
* have the same scope */
|
|
||||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
uint32_t id32;
|
uint32_t id32;
|
||||||
uint64_t id;
|
uint64_t id;
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(ifindex > 0);
|
|
||||||
assert(hw_addr);
|
assert(hw_addr);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
if (udev_available() && !use_mac) {
|
if (dev)
|
||||||
/* udev should be around */
|
name = net_get_persistent_name(dev);
|
||||||
|
|
||||||
r = sd_device_new_from_ifindex(&device, ifindex);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = sd_device_get_is_initialized(device);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
if (r == 0)
|
|
||||||
/* not yet ready */
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
r = device_is_renaming(device);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
if (r > 0)
|
|
||||||
/* device is under renaming */
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
name = net_get_persistent_name(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
id = siphash24(name, strlen(name), HASH_KEY.bytes);
|
id = siphash24(name, strlen(name), HASH_KEY.bytes);
|
||||||
else
|
else
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "sd-device.h"
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
#include "ether-addr-util.h"
|
#include "ether-addr-util.h"
|
||||||
@ -66,10 +67,9 @@ int dhcp_identifier_set_duid(
|
|||||||
struct duid *ret_duid,
|
struct duid *ret_duid,
|
||||||
size_t *ret_len);
|
size_t *ret_len);
|
||||||
int dhcp_identifier_set_iaid(
|
int dhcp_identifier_set_iaid(
|
||||||
int ifindex,
|
sd_device *dev,
|
||||||
const struct hw_addr_data *hw_addr,
|
const struct hw_addr_data *hw_addr,
|
||||||
bool legacy_unstable_byteorder,
|
bool legacy_unstable_byteorder,
|
||||||
bool use_mac,
|
|
||||||
void *ret);
|
void *ret);
|
||||||
|
|
||||||
const char *duid_type_to_string(DUIDType t) _const_;
|
const char *duid_type_to_string(DUIDType t) _const_;
|
||||||
|
@ -48,6 +48,8 @@ struct sd_dhcp6_client {
|
|||||||
int event_priority;
|
int event_priority;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
sd_device *dev;
|
||||||
|
|
||||||
DHCP6State state;
|
DHCP6State state;
|
||||||
bool information_request;
|
bool information_request;
|
||||||
usec_t information_request_time_usec;
|
usec_t information_request_time_usec;
|
||||||
@ -78,7 +80,7 @@ struct sd_dhcp6_client {
|
|||||||
sd_dhcp6_client_callback_t callback;
|
sd_dhcp6_client_callback_t callback;
|
||||||
void *userdata;
|
void *userdata;
|
||||||
|
|
||||||
/* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
|
/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
|
||||||
bool test_mode;
|
bool test_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "sd-dhcp-client.h"
|
#include "sd-dhcp-client.h"
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
|
#include "device-util.h"
|
||||||
#include "dhcp-identifier.h"
|
#include "dhcp-identifier.h"
|
||||||
#include "dhcp-internal.h"
|
#include "dhcp-internal.h"
|
||||||
#include "dhcp-lease-internal.h"
|
#include "dhcp-lease-internal.h"
|
||||||
@ -77,8 +78,12 @@ struct sd_dhcp_client {
|
|||||||
sd_event *event;
|
sd_event *event;
|
||||||
int event_priority;
|
int event_priority;
|
||||||
sd_event_source *timeout_resend;
|
sd_event_source *timeout_resend;
|
||||||
|
|
||||||
int ifindex;
|
int ifindex;
|
||||||
char *ifname;
|
char *ifname;
|
||||||
|
|
||||||
|
sd_device *dev;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
union sockaddr_union link;
|
union sockaddr_union link;
|
||||||
@ -117,7 +122,7 @@ struct sd_dhcp_client {
|
|||||||
usec_t start_delay;
|
usec_t start_delay;
|
||||||
int ip_service_type;
|
int ip_service_type;
|
||||||
|
|
||||||
/* Ignore ifindex when generating iaid. See dhcp_identifier_set_iaid(). */
|
/* Ignore machine-ID when generating DUID. See dhcp_identifier_set_duid_en(). */
|
||||||
bool test_mode;
|
bool test_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -420,9 +425,8 @@ static int dhcp_client_set_iaid_duid_internal(
|
|||||||
if (iaid_set)
|
if (iaid_set)
|
||||||
client->client_id.ns.iaid = htobe32(iaid);
|
client->client_id.ns.iaid = htobe32(iaid);
|
||||||
else {
|
else {
|
||||||
r = dhcp_identifier_set_iaid(client->ifindex, &client->hw_addr,
|
r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
|
||||||
/* legacy_unstable_byteorder = */ true,
|
/* legacy_unstable_byteorder = */ true,
|
||||||
/* use_mac = */ client->test_mode,
|
|
||||||
&client->client_id.ns.iaid);
|
&client->client_id.ns.iaid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_dhcp_client_errno(client, r, "Failed to set IAID: %m");
|
return log_dhcp_client_errno(client, r, "Failed to set IAID: %m");
|
||||||
@ -799,9 +803,8 @@ static int client_message_init(
|
|||||||
|
|
||||||
client->client_id.type = 255;
|
client->client_id.type = 255;
|
||||||
|
|
||||||
r = dhcp_identifier_set_iaid(client->ifindex, &client->hw_addr,
|
r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
|
||||||
/* legacy_unstable_byteorder = */ true,
|
/* legacy_unstable_byteorder = */ true,
|
||||||
/* use_mac = */ client->test_mode,
|
|
||||||
&client->client_id.ns.iaid);
|
&client->client_id.ns.iaid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -2153,6 +2156,12 @@ sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client) {
|
|||||||
return client->event;
|
return client->event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp_client_attach_device(sd_dhcp_client *client, sd_device *dev) {
|
||||||
|
assert_return(client, -EINVAL);
|
||||||
|
|
||||||
|
return device_unref_and_replace(client->dev, dev);
|
||||||
|
}
|
||||||
|
|
||||||
static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
|
static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
|
||||||
if (!client)
|
if (!client)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2168,6 +2177,8 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
|
|||||||
|
|
||||||
sd_dhcp_client_detach_event(client);
|
sd_dhcp_client_detach_event(client);
|
||||||
|
|
||||||
|
sd_device_unref(client->dev);
|
||||||
|
|
||||||
set_free(client->req_opts);
|
set_free(client->req_opts);
|
||||||
free(client->hostname);
|
free(client->hostname);
|
||||||
free(client->vendor_class_identifier);
|
free(client->vendor_class_identifier);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "sd-dhcp6-client.h"
|
#include "sd-dhcp6-client.h"
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
|
#include "device-util.h"
|
||||||
#include "dhcp-identifier.h"
|
#include "dhcp-identifier.h"
|
||||||
#include "dhcp6-internal.h"
|
#include "dhcp6-internal.h"
|
||||||
#include "dhcp6-lease-internal.h"
|
#include "dhcp6-lease-internal.h"
|
||||||
@ -299,9 +300,8 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
|
|||||||
if (client->iaid_set)
|
if (client->iaid_set)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = dhcp_identifier_set_iaid(client->ifindex, &client->hw_addr,
|
r = dhcp_identifier_set_iaid(client->dev, &client->hw_addr,
|
||||||
/* legacy_unstable_byteorder = */ true,
|
/* legacy_unstable_byteorder = */ true,
|
||||||
/* use_mac = */ client->test_mode,
|
|
||||||
&iaid);
|
&iaid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1446,6 +1446,12 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) {
|
|||||||
return client->event;
|
return client->event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sd_dhcp6_client_attach_device(sd_dhcp6_client *client, sd_device *dev) {
|
||||||
|
assert_return(client, -EINVAL);
|
||||||
|
|
||||||
|
return device_unref_and_replace(client->dev, dev);
|
||||||
|
}
|
||||||
|
|
||||||
static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
|
static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
|
||||||
if (!client)
|
if (!client)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1461,6 +1467,8 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
|
|||||||
|
|
||||||
client->fd = safe_close(client->fd);
|
client->fd = safe_close(client->fd);
|
||||||
|
|
||||||
|
sd_device_unref(client->dev);
|
||||||
|
|
||||||
free(client->req_opts);
|
free(client->req_opts);
|
||||||
free(client->fqdn);
|
free(client->fqdn);
|
||||||
free(client->mudurl);
|
free(client->mudurl);
|
||||||
|
@ -144,10 +144,8 @@ static void test_dhcp_identifier_set_iaid(void) {
|
|||||||
uint32_t iaid_legacy;
|
uint32_t iaid_legacy;
|
||||||
be32_t iaid;
|
be32_t iaid;
|
||||||
|
|
||||||
assert_se(dhcp_identifier_set_iaid(42, &hw_addr, /* legacy = */ true,
|
assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ true, &iaid_legacy) >= 0);
|
||||||
/* use_mac = */ true, &iaid_legacy) >= 0);
|
assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ false, &iaid) >= 0);
|
||||||
assert_se(dhcp_identifier_set_iaid(42, &hw_addr, /* legacy = */ false,
|
|
||||||
/* use_mac = */ true, &iaid) >= 0);
|
|
||||||
|
|
||||||
/* we expect, that the MAC address was hashed. The legacy value is in native
|
/* we expect, that the MAC address was hashed. The legacy value is in native
|
||||||
* endianness. */
|
* endianness. */
|
||||||
@ -169,7 +167,7 @@ static int check_options(uint8_t code, uint8_t len, const void *option, void *us
|
|||||||
size_t duid_len;
|
size_t duid_len;
|
||||||
|
|
||||||
assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid, &duid_len) >= 0);
|
assert_se(dhcp_identifier_set_duid_en(/* test_mode = */ true, &duid, &duid_len) >= 0);
|
||||||
assert_se(dhcp_identifier_set_iaid(42, &hw_addr, /* legacy = */ true, /* use_mac = */ true, &iaid) >= 0);
|
assert_se(dhcp_identifier_set_iaid(NULL, &hw_addr, /* legacy = */ true, &iaid) >= 0);
|
||||||
|
|
||||||
assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
|
assert_se(len == sizeof(uint8_t) + sizeof(uint32_t) + duid_len);
|
||||||
assert_se(len == 19);
|
assert_se(len == 19);
|
||||||
|
@ -1357,6 +1357,10 @@ static int dhcp4_configure(Link *link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to attach event to DHCPv4 client: %m");
|
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to attach event to DHCPv4 client: %m");
|
||||||
|
|
||||||
|
r = sd_dhcp_client_attach_device(link->dhcp_client, link->dev);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_debug_errno(link, r, "DHCPv4 CLIENT: Failed to attach device: %m");
|
||||||
|
|
||||||
r = sd_dhcp_client_set_mac(link->dhcp_client,
|
r = sd_dhcp_client_set_mac(link->dhcp_client,
|
||||||
link->hw_addr.bytes,
|
link->hw_addr.bytes,
|
||||||
link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
|
link->bcast_addr.length > 0 ? link->bcast_addr.bytes : NULL,
|
||||||
|
@ -594,6 +594,10 @@ static int dhcp6_configure(Link *link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to attach event: %m");
|
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to attach event: %m");
|
||||||
|
|
||||||
|
r = sd_dhcp6_client_attach_device(client, link->dev);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to attach device: %m");
|
||||||
|
|
||||||
r = dhcp6_set_identifier(link, client);
|
r = dhcp6_set_identifier(link, client);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set identifier: %m");
|
return log_link_debug_errno(link, r, "DHCPv6 CLIENT: Failed to set identifier: %m");
|
||||||
|
@ -1410,6 +1410,18 @@ static int link_initialized(Link *link, sd_device *device) {
|
|||||||
* or sysattrs) may be outdated. */
|
* or sysattrs) may be outdated. */
|
||||||
device_unref_and_replace(link->dev, device);
|
device_unref_and_replace(link->dev, device);
|
||||||
|
|
||||||
|
if (link->dhcp_client) {
|
||||||
|
r = sd_dhcp_client_attach_device(link->dhcp_client, link->dev);
|
||||||
|
if (r < 0)
|
||||||
|
log_link_warning_errno(link, r, "Failed to attach device to DHCPv4 client, ignoring: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->dhcp6_client) {
|
||||||
|
r = sd_dhcp6_client_attach_device(link->dhcp6_client, link->dev);
|
||||||
|
if (r < 0)
|
||||||
|
log_link_warning_errno(link, r, "Failed to attach device to DHCPv6 client, ignoring: %m");
|
||||||
|
}
|
||||||
|
|
||||||
r = link_set_sr_iov_ifindices(link);
|
r = link_set_sr_iov_ifindices(link);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_warning_errno(link, r, "Failed to manage SR-IOV PF and VF ports, ignoring: %m");
|
log_link_warning_errno(link, r, "Failed to manage SR-IOV PF and VF ports, ignoring: %m");
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "sd-device.h"
|
||||||
#include "sd-dhcp-lease.h"
|
#include "sd-dhcp-lease.h"
|
||||||
#include "sd-dhcp-option.h"
|
#include "sd-dhcp-option.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
@ -337,6 +338,7 @@ int sd_dhcp_client_attach_event(
|
|||||||
int64_t priority);
|
int64_t priority);
|
||||||
int sd_dhcp_client_detach_event(sd_dhcp_client *client);
|
int sd_dhcp_client_detach_event(sd_dhcp_client *client);
|
||||||
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
|
sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
|
||||||
|
int sd_dhcp_client_attach_device(sd_dhcp_client *client, sd_device *dev);
|
||||||
|
|
||||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref);
|
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_client, sd_dhcp_client_unref);
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "sd-device.h"
|
||||||
#include "sd-dhcp6-lease.h"
|
#include "sd-dhcp6-lease.h"
|
||||||
#include "sd-dhcp6-option.h"
|
#include "sd-dhcp6-option.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
@ -279,6 +280,7 @@ int sd_dhcp6_client_attach_event(
|
|||||||
int64_t priority);
|
int64_t priority);
|
||||||
int sd_dhcp6_client_detach_event(sd_dhcp6_client *client);
|
int sd_dhcp6_client_detach_event(sd_dhcp6_client *client);
|
||||||
sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client);
|
sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client);
|
||||||
|
int sd_dhcp6_client_attach_device(sd_dhcp6_client *client, sd_device *dev);
|
||||||
sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client);
|
sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client);
|
||||||
sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client);
|
sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client);
|
||||||
int sd_dhcp6_client_new(sd_dhcp6_client **ret);
|
int sd_dhcp6_client_new(sd_dhcp6_client **ret);
|
||||||
|
Loading…
Reference in New Issue
Block a user