dhcp: set request_broadcast for devices that set udev ID_NET_DHCP_BROADCAST

For infiniband, request_broadcast is automatically (and always) enabled.
Otherwise, we usually don't enable it, and (unlike systemd-networkd),
there is currently no configuration option to enable it.

Still honor the new udev property that can indicate to enable the flag
per device.

See-also: https://github.com/systemd/systemd/pull/ ### 19346
This commit is contained in:
Thomas Haller 2021-04-23 10:47:12 +02:00
parent 4acbb0fdc9
commit 2ae5e7aa26
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
6 changed files with 58 additions and 26 deletions

View file

@ -9447,6 +9447,8 @@ dhcp4_start(NMDevice *self)
GError * error = NULL;
const NMPlatformLink * pllink;
const char *const * reject_servers;
gboolean request_broadcast;
const char * str;
connection = nm_device_get_applied_connection(self);
g_return_val_if_fail(connection, FALSE);
@ -9460,10 +9462,22 @@ dhcp4_start(NMDevice *self)
nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config);
priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET);
request_broadcast = FALSE;
pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self));
if (pllink) {
hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address);
bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast);
str = nmp_object_link_udev_device_get_property_value(NMP_OBJECT_UP_CAST(pllink),
"ID_NET_DHCP_BROADCAST");
if (str && _nm_utils_ascii_str_to_bool(str, FALSE)) {
/* Use the device property ID_NET_DHCP_BROADCAST setting, which may be set for interfaces
* requiring that the DHCPOFFER message is being broadcast because they can't handle unicast
* messages while not fully configured.
*/
request_broadcast = TRUE;
}
}
client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr);
@ -9472,29 +9486,29 @@ dhcp4_start(NMDevice *self)
reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip4, NULL);
g_warn_if_fail(priv->dhcp_data_4.client == NULL);
priv->dhcp_data_4.client =
nm_dhcp_manager_start_ip4(nm_dhcp_manager_get(),
nm_netns_get_multi_idx(nm_device_get_netns(self)),
nm_device_get_ip_iface(self),
nm_device_get_ip_ifindex(self),
hwaddr,
bcast_hwaddr,
nm_connection_get_uuid(connection),
nm_device_get_route_table(self, AF_INET),
nm_device_get_route_metric(self, AF_INET),
NM_DHCP_CLIENT_FLAGS_NONE,
nm_setting_ip_config_get_dhcp_send_hostname(s_ip4),
nm_setting_ip_config_get_dhcp_hostname(s_ip4),
nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)),
_prop_get_ipvx_dhcp_hostname_flags(self, AF_INET),
_prop_get_connection_mud_url(self, s_con, &mud_url_free),
client_id,
_prop_get_ipvx_dhcp_timeout(self, AF_INET),
priv->dhcp_anycast_address,
NULL,
vendor_class_identifier,
reject_servers,
&error);
priv->dhcp_data_4.client = nm_dhcp_manager_start_ip4(
nm_dhcp_manager_get(),
nm_netns_get_multi_idx(nm_device_get_netns(self)),
nm_device_get_ip_iface(self),
nm_device_get_ip_ifindex(self),
hwaddr,
bcast_hwaddr,
nm_connection_get_uuid(connection),
nm_device_get_route_table(self, AF_INET),
nm_device_get_route_metric(self, AF_INET),
request_broadcast ? NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST : NM_DHCP_CLIENT_FLAGS_NONE,
nm_setting_ip_config_get_dhcp_send_hostname(s_ip4),
nm_setting_ip_config_get_dhcp_hostname(s_ip4),
nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)),
_prop_get_ipvx_dhcp_hostname_flags(self, AF_INET),
_prop_get_connection_mud_url(self, s_con, &mud_url_free),
client_id,
_prop_get_ipvx_dhcp_timeout(self, AF_INET),
priv->dhcp_anycast_address,
NULL,
vendor_class_identifier,
reject_servers,
&error);
if (!priv->dhcp_data_4.client) {
_LOGW(LOGD_DHCP4, "failure to start DHCP: %s", error->message);
g_clear_error(&error);

View file

@ -1152,8 +1152,10 @@ constructed(GObject *object)
* for that. */
if (NM_IS_IPv4(priv->addr_family))
nm_assert(!NM_FLAGS_ANY(priv->client_flags, NM_DHCP_CLIENT_FLAGS_INFO_ONLY));
else
else {
nm_assert(NM_FLAGS_HAS(priv->client_flags, NM_DHCP_CLIENT_FLAGS_USE_FQDN));
nm_assert(!NM_FLAGS_ANY(priv->client_flags, NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST));
}
G_OBJECT_CLASS(nm_dhcp_client_parent_class)->constructed(object);
}

View file

@ -71,8 +71,9 @@ typedef struct {
typedef enum _nm_packed {
NM_DHCP_CLIENT_FLAGS_NONE = 0,
NM_DHCP_CLIENT_FLAGS_INFO_ONLY = (1LL << 0),
NM_DHCP_CLIENT_FLAGS_USE_FQDN = (1LL << 1),
NM_DHCP_CLIENT_FLAGS_INFO_ONLY = (1LL << 0),
NM_DHCP_CLIENT_FLAGS_USE_FQDN = (1LL << 1),
NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST = (1LL << 2),
_NM_DHCP_CLIENT_FLAGS_LAST,
NM_DHCP_CLIENT_FLAGS_ALL = ((_NM_DHCP_CLIENT_FLAGS_LAST - 1) << 1) - 1,

View file

@ -435,6 +435,12 @@ dhclient_start(NMDhcpClient *client,
if (release)
g_ptr_array_add(argv, (gpointer) "-r");
if (!release
&& NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)),
NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST)) {
g_ptr_array_add(argv, (gpointer) "-B");
}
if (addr_family == AF_INET6) {
g_ptr_array_add(argv, (gpointer) "-6");

View file

@ -938,6 +938,10 @@ nettools_create(NMDhcpNettools *self, const char *dhcp_anycast_addr, GError **er
n_dhcp4_client_config_set_transport(config, transport);
n_dhcp4_client_config_set_mac(config, hwaddr_arr, hwaddr_len);
n_dhcp4_client_config_set_broadcast_mac(config, bcast_hwaddr_arr, bcast_hwaddr_len);
n_dhcp4_client_config_set_request_broadcast(
config,
NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(NM_DHCP_CLIENT(self)),
NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST));
r = n_dhcp4_client_config_set_client_id(config,
client_id_arr,
NM_MIN(client_id_len, 1 + _NM_SD_MAX_CLIENT_ID_LEN));

View file

@ -632,6 +632,11 @@ ip4_start(NMDhcpClient *client,
sd_dhcp_lease_get_address(lease, &last_addr);
}
r = sd_dhcp_client_set_request_broadcast(sd_client,
NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(client),
NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST));
nm_assert(r >= 0);
if (last_addr.s_addr) {
r = sd_dhcp_client_set_request_address(sd_client, &last_addr);
if (r < 0) {