summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml11
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c18
-rw-r--r--src/network/networkd-link.c4
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd.h1
-rw-r--r--src/systemd/sd-dhcp-client.h1
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);