diff --git a/man/systemd.network.xml b/man/systemd.network.xml index f7c4e3e49e..49814a05eb 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2482,12 +2482,16 @@ Token=prefixstable:2002:da8:1:: EmitRouter= + Router= - Similar to the EmitDNS= - 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 - EmitDNS=. + The EmitRouter= setting takes a boolean value, and configures + whether the DHCP lease should contain the router option. The Router= setting + takes an IPv4 address, and configures the router address to be emitted. When the + Router= setting is not specified, then the server address will be used for + the router option. When the EmitRouter= setting is disabled, the + Router= setting will be ignored. The EmitRouter= setting + defaults to true, and the Router= setting defaults to unset. + diff --git a/src/libsystemd-network/dhcp-server-internal.h b/src/libsystemd-network/dhcp-server-internal.h index 3b87a4c066..13d8cd77b4 100644 --- a/src/libsystemd-network/dhcp-server-internal.h +++ b/src/libsystemd-network/dhcp-server-internal.h @@ -68,6 +68,7 @@ struct sd_dhcp_server { OrderedSet *vendor_options; bool emit_router; + struct in_addr router_address; Hashmap *bound_leases_by_client_id; Hashmap *bound_leases_by_address; diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 604c34fe15..261818b46a 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -533,7 +533,10 @@ static int server_send_offer_or_ack( if (server->emit_router) { r = dhcp_option_append(&packet->dhcp, req->max_optlen, &offset, 0, - SD_DHCP_OPTION_ROUTER, 4, &server->address); + SD_DHCP_OPTION_ROUTER, 4, + in4_addr_is_set(&server->router_address) ? + &server->router_address.s_addr : + &server->address); if (r < 0) return r; } @@ -1418,15 +1421,18 @@ int sd_dhcp_server_set_lpr(sd_dhcp_server *server, const struct in_addr lpr[], s return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_LPR, lpr, n); } -int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) { +int sd_dhcp_server_set_router(sd_dhcp_server *server, const struct in_addr *router) { assert_return(server, -EINVAL); - if (enabled == server->emit_router) - return 0; + /* router is NULL: router option will not be appended. + * router is null address (0.0.0.0): the server address will be used as the router address. + * otherwise: the specified address will be used as the router address.*/ - server->emit_router = enabled; + server->emit_router = router; + if (router) + server->router_address = *router; - return 1; + return 0; } int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v) { diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 45ef1b4903..9fa0c4233c 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -448,9 +448,11 @@ static int dhcp4_server_configure(Link *link) { dhcp_lease_server_type_to_string(type)); } - r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router); - if (r < 0) - return log_link_error_errno(link, r, "Failed to set router emission for DHCP server: %m"); + if (link->network->dhcp_server_emit_router) { + r = sd_dhcp_server_set_router(link->dhcp_server, &link->network->dhcp_server_router); + if (r < 0) + return log_link_error_errno(link, r, "Failed to set router address for DHCP server: %m"); + } r = sd_dhcp_server_set_relay_target(link->dhcp_server, &link->network->dhcp_server_relay_target); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 595dd36121..1f0a625183 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -290,6 +290,7 @@ DHCPServer.SMTP, config_parse_dhcp_server_emit, DHCPServer.EmitLPR, config_parse_bool, 0, offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_LPR].emit) DHCPServer.LPR, config_parse_dhcp_server_emit, 0, offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_LPR]) DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router) +DHCPServer.Router, config_parse_in_addr_non_null, AF_INET, offsetof(Network, dhcp_server_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) diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 91553265da..f5258c9fcd 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -202,6 +202,7 @@ struct Network { char *dhcp_server_relay_agent_remote_id; NetworkDHCPServerEmitAddress dhcp_server_emit[_SD_DHCP_LEASE_SERVER_TYPE_MAX]; bool dhcp_server_emit_router; + struct in_addr dhcp_server_router; bool dhcp_server_emit_timezone; char *dhcp_server_timezone; usec_t dhcp_server_default_lease_time_usec, dhcp_server_max_lease_time_usec; diff --git a/src/systemd/sd-dhcp-server.h b/src/systemd/sd-dhcp-server.h index 149a14fdc6..59ef27e1dc 100644 --- a/src/systemd/sd-dhcp-server.h +++ b/src/systemd/sd-dhcp-server.h @@ -60,7 +60,7 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, const struct in_addr * int sd_dhcp_server_set_bind_to_interface(sd_dhcp_server *server, int enabled); int sd_dhcp_server_set_timezone(sd_dhcp_server *server, const char *timezone); -int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled); +int sd_dhcp_server_set_router(sd_dhcp_server *server, const struct in_addr *address); int sd_dhcp_server_set_servers( sd_dhcp_server *server, diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 985c2fc0d3..2ff20e0f08 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -379,6 +379,7 @@ SMTP= EmitLPR= LPR= EmitRouter= +Router= MaxLeaseTimeSec= DefaultLeaseTimeSec= EmitTimezone=