networkd: Add EmitRouter= option for DHCP Server (#3251)

Add an option to disable appending DHCP option 3 (Router) to the DHCP
OFFER and ACK packets.
This commit adds the boolean option EmitRouter= for the [DHCPServer]
section in .network files.

Rationale: On embedded devices, it is very useful to have a DHCP server
running on an USB OTG ethernet gadget interface to avoid manual setup on
the client PCs, but it should only serve IP addresses, no route(r)s.
Otherwise, Windows clients experience network connectivity issues, due
to them using the address set in DHCP option 3 as default gateway.

Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
This commit is contained in:
Clemens Gruber 2016-05-18 01:34:25 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent a363a2e45f
commit 77ff6022fa
9 changed files with 63 additions and 22 deletions

32
NEWS
View File

@ -180,22 +180,26 @@ CHANGES WITH 230 in spe:
service. Please leave PrivateDevices= off if you run into problems
with this.
* The systemd-networkd DHCP server gained the option EmitRouter=, which
defaults to yes, to configure if the DHCP Option 3 (Router) should be
emitted.
Contributions from: Alban Crequy, Alexander Kuleshov, Alex Crawford,
Andrew Eikum, Beniamino Galvani, Benjamin Robin, Benjamin ROBIN, Biao
Lu, Bjørnar Ness, Calvin Owens, Christian Hesse, Colin Guthrie, Daniel
J Walsh, Daniel Mack, Dan Nicholson, daurnimator, David Herrmann, David
R. Hedges, Elias Probst, Emmanuel Gil Peyrot, EMOziko, Evgeny
Vereshchagin, Federico, Felipe Sateler, Filipe Brandenburger, Franck
Bui, frankheckenbach, Georgia Brikis, Harald Hoyer, Hendrik Brueckner,
Hristo Venev, Iago López Galeiras, Ian Kelling, Ismo Puustinen, Jakub
Wilk, Jaroslav Škarvada, Jeff Huang, Joel Holdsworth, kayrus, Klearchos
Chaloulos, Lennart Poettering, Lubomir Rintel, Lukas Nykryn, Lukáš
Nykrýn, Mantas Mikulėnas, Marcel Holtmann, Martin Pitt, Michael Biebl,
michaelolbrich, Michał Bartoszkiewicz, Michal Koutný, Michal Sekletar,
Mike Frysinger, Mike Gilbert, Mingcong Bai, Ming Lin, mulkieran,
muzena, Nalin Dahyabhai, Naohiro Aota, Nathan McSween, Nicolas
Braud-Santoni, Patrik Flykt, Peter Hutterer, Petr Lautrbach, Petros
Angelatos, Piotr Drąg, Rabin Vincent, Robert Węcławski, Ronny
Lu, Bjørnar Ness, Calvin Owens, Christian Hesse, Clemens Gruber, Colin
Guthrie, Daniel J Walsh, Daniel Mack, Dan Nicholson, daurnimator, David
Herrmann, David R. Hedges, Elias Probst, Emmanuel Gil Peyrot, EMOziko,
Evgeny Vereshchagin, Federico, Felipe Sateler, Filipe Brandenburger,
Franck Bui, frankheckenbach, Georgia Brikis, Harald Hoyer, Hendrik
Brueckner, Hristo Venev, Iago López Galeiras, Ian Kelling, Ismo
Puustinen, Jakub Wilk, Jaroslav Škarvada, Jeff Huang, Joel Holdsworth,
kayrus, Klearchos Chaloulos, Lennart Poettering, Lubomir Rintel, Lukas
Nykryn, Lukáš Nykrýn, Mantas Mikulėnas, Marcel Holtmann, Martin Pitt,
Michael Biebl, michaelolbrich, Michał Bartoszkiewicz, Michal Koutný,
Michal Sekletar, Mike Frysinger, Mike Gilbert, Mingcong Bai, Ming Lin,
mulkieran, muzena, Nalin Dahyabhai, Naohiro Aota, Nathan McSween,
Nicolas Braud-Santoni, Patrik Flykt, Peter Hutterer, Petr Lautrbach,
Petros Angelatos, Piotr Drąg, Rabin Vincent, Robert Węcławski, Ronny
Chevalier, Samuel Tardieu, Stefan Schallenberg, Steven Siloti, Susant
Sahani, Sylvain Plantefève, Taylor Smock, tblume, Tejun Heo, Thomas
Blume, Thomas Haller, Thomas Hindoe Paaboel Andersen, Thomas

View File

@ -981,6 +981,16 @@
<varname>DNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>EmitRouter=</varname></term>
<listitem><para>Similar to the <varname>EmitDNS=</varname>
setting described above, this setting configures whether the
DHCP lease should contain the router option. The same syntax,
propagation semantics and defaults apply as for
<varname>EmitDNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>EmitTimezone=</varname></term>
<term><varname>Timezone=</varname></term>

View File

@ -63,6 +63,8 @@ struct sd_dhcp_server {
struct in_addr *ntp, *dns;
unsigned n_ntp, n_dns;
bool emit_router;
Hashmap *leases_by_client_id;
DHCPLease **bound_leases;
DHCPLease invalid_lease;

View File

@ -468,10 +468,12 @@ static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
if (r < 0)
return r;
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_ROUTER, 4, &server->address);
if (r < 0)
return r;
if (server->emit_router) {
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_ROUTER, 4, &server->address);
if (r < 0)
return r;
}
r = dhcp_server_send_packet(server, req, packet, DHCP_OFFER, offset);
if (r < 0)
@ -505,10 +507,12 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
if (r < 0)
return r;
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_ROUTER, 4, &server->address);
if (r < 0)
return r;
if (server->emit_router) {
r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_ROUTER, 4, &server->address);
if (r < 0)
return r;
}
if (server->n_dns > 0) {
r = dhcp_option_append(
@ -1158,3 +1162,14 @@ int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], u
return 1;
}
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
assert_return(server, -EINVAL);
if (enabled == server->emit_router)
return 0;
server->emit_router = enabled;
return 1;
}

View File

@ -1020,6 +1020,12 @@ static int link_enter_set_addresses(Link *link) {
log_link_warning_errno(link, r, "Failed to set NTP server for DHCP server, ignoring: %m");
}
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
if (r < 0) {
log_link_warning_errno(link, r, "Failed to set router emission for DHCP server: %m");
return r;
}
if (link->network->dhcp_server_emit_timezone) {
_cleanup_free_ char *buffer = NULL;
const char *tz = NULL;

View File

@ -95,6 +95,7 @@ DHCPServer.EmitDNS, config_parse_bool,
DHCPServer.DNS, config_parse_dhcp_server_dns, 0, 0
DHCPServer.EmitNTP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_ntp)
DHCPServer.NTP, config_parse_dhcp_server_ntp, 0, 0
DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router)
DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)
DHCPServer.PoolOffset, config_parse_uint32, 0, offsetof(Network, dhcp_server_pool_offset)

View File

@ -113,6 +113,7 @@ static int network_load_one(Manager *manager, const char *filename) {
network->dhcp_server_emit_dns = true;
network->dhcp_server_emit_ntp = true;
network->dhcp_server_emit_router = true;
network->dhcp_server_emit_timezone = true;
network->use_bpdu = true;

View File

@ -127,6 +127,7 @@ struct Network {
bool dhcp_server_emit_ntp;
struct in_addr *dhcp_server_ntp;
unsigned n_dhcp_server_ntp;
bool dhcp_server_emit_router;
bool dhcp_server_emit_timezone;
char *dhcp_server_timezone;
usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec;

View File

@ -51,6 +51,7 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_set_max_lease_time(sd_dhcp_server *server, uint32_t t);
int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t);