diff options
-rw-r--r-- | man/systemd.network.xml | 11 | ||||
-rw-r--r-- | src/libsystemd-network/sd-dhcp-client.c | 18 | ||||
-rw-r--r-- | src/network/networkd-link.c | 4 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 1 | ||||
-rw-r--r-- | src/network/networkd.h | 1 | ||||
-rw-r--r-- | src/systemd/sd-dhcp-client.h | 1 |
6 files changed, 33 insertions, 3 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 3c4fdd20c8..7c5f69895a 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -446,12 +446,21 @@ if, say, the root filesystem relies on this connection. Defaults to false.</para> </listitem> </varlistentry> - <varlistentry> + <varlistentry> <term><varname>VendorClassIdentifier=</varname></term> <listitem> <para>The vendor class identifier used to identify vendor type and configuration.</para> </listitem> </varlistentry> + <varlistentry> + <term><varname>RequestBroadcast=</varname></term> + <listitem> + <para>Request the server to use broadcast messages before the IP address has been + configured. This is necessary for devices that cannot receive RAW packets, or that + cannot receive packets at all before an IP address has been configured. On the other + hand, this must not be enabled on networks where broadcasts are filtered out.</para> + </listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 3c389931cd..f7a4018540 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -48,6 +48,7 @@ struct sd_dhcp_client { int fd; union sockaddr_union link; sd_event_source *receive_message; + bool request_broadcast; uint8_t *req_opts; size_t req_opts_allocated; size_t req_opts_size; @@ -96,6 +97,14 @@ int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb, return 0; } +int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast) { + assert_return(client, -EINVAL); + + client->request_broadcast = !!broadcast; + + return 0; +} + int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) { size_t i; @@ -322,8 +331,13 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret, BROADCAST bit in the 'flags' field to 1 in any DHCPDISCOVER or DHCPREQUEST messages that client sends. The BROADCAST bit will provide a hint to the DHCP server and BOOTP relay agent to broadcast - any messages to the client on the client's subnet. */ - packet->dhcp.flags = htobe16(0x8000); + any messages to the client on the client's subnet. + + Note: some interfaces needs this to be enabled, but some networks + needs this to be disabled as broadcasts are filteretd, so this + needs to be configurable */ + if (client->request_broadcast) + packet->dhcp.flags = htobe16(0x8000); /* RFC2132 section 4.1.1: The client MUST include its hardware address in the ’chaddr’ field, if diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 877b7a9be2..0fb323b9a5 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1998,6 +1998,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); + if (r < 0) + return r; + if (link->network->dhcp_mtu) { r = sd_dhcp_client_set_request_option(link->dhcp_client, 26); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 61dd8ef5f6..f5156b43b2 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -51,6 +51,7 @@ DHCP.UseHostname, config_parse_bool, 0, DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domainname) DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) +DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) /* backwards compatibility: do not add new entries to this section */ diff --git a/src/network/networkd.h b/src/network/networkd.h index 3f0ef5d0ec..9abc0d46ec 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -92,6 +92,7 @@ struct Network { bool dhcp_hostname; bool dhcp_domainname; bool dhcp_sendhost; + bool dhcp_broadcast; bool dhcp_critical; bool dhcp_routes; bool ipv4ll; diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h index 9ab6105e5b..08aa0dca69 100644 --- a/src/systemd/sd-dhcp-client.h +++ b/src/systemd/sd-dhcp-client.h @@ -48,6 +48,7 @@ int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb, int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option); int sd_dhcp_client_set_request_address(sd_dhcp_client *client, const struct in_addr *last_address); +int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast); int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index); int sd_dhcp_client_set_mac(sd_dhcp_client *client, const struct ether_addr *addr); |