sd-dhcp-client: make request broadcasts opt-in

It appears there is no good way to decide whether or not broadcasts should be enabled,
there is hardware that must have broadcast, and there are networks that only allow
unicast. So we give up and make this configurable.

By default, unicast is used, but if the kernel were to inform us abotu certain
interfaces requiring broadcast, we could change this to opt-in by default in
those cases.
This commit is contained in:
Tom Gundersen 2014-07-15 18:55:31 +02:00
parent 30632d97d9
commit f5de5b0020
6 changed files with 33 additions and 3 deletions

View File

@ -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>

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -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;

View File

@ -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);