From e47bcb7d0b2cb07c5c594e374baeb061bb7f88ba Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 8 Sep 2021 09:35:34 +0900 Subject: [PATCH] network: do not use RouteTable= in [DHCPv4] section for DHCPv6 routes We forgot to add RouteTable= in [DHCPv6] section when we split [DHCP] into two. --- man/systemd.network.xml | 1 + src/network/networkd-dhcp-common.c | 71 ++++++++++++++++++- src/network/networkd-dhcp-common.h | 6 +- src/network/networkd-dhcp4.c | 2 +- src/network/networkd-dhcp6.c | 2 +- src/network/networkd-network-gperf.gperf | 7 +- src/network/networkd-network.h | 6 +- src/network/networkd-route.c | 18 ----- src/network/networkd-route.h | 3 - .../fuzz-network-parser/directives.network | 1 + 10 files changed, 86 insertions(+), 31 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 48326a25c12..52043789ed9 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2111,6 +2111,7 @@ IPv6Token=prefixstable:2002:da8:1:: + RouteMetric= UseDNS= UseNTP= UseHostname= diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c index 09c242c730f..8138c4eda7d 100644 --- a/src/network/networkd-dhcp-common.c +++ b/src/network/networkd-dhcp-common.c @@ -18,6 +18,44 @@ #include "socket-util.h" #include "string-table.h" #include "strv.h" +#include "vrf.h" + +static uint32_t link_get_vrf_table(Link *link) { + assert(link); + assert(link->network); + + return link->network->vrf ? VRF(link->network->vrf)->table : RT_TABLE_MAIN; +} + +uint32_t link_get_dhcp4_route_table(Link *link) { + assert(link); + assert(link->network); + + /* When the interface is part of an VRF use the VRFs routing table, unless + * another table is explicitly specified. */ + + if (link->network->dhcp_route_table_set) + return link->network->dhcp_route_table; + return link_get_vrf_table(link); +} + +uint32_t link_get_dhcp6_route_table(Link *link) { + assert(link); + assert(link->network); + + if (link->network->dhcp6_route_table_set) + return link->network->dhcp6_route_table; + return link_get_vrf_table(link); +} + +uint32_t link_get_ipv6_accept_ra_route_table(Link *link) { + assert(link); + assert(link->network); + + if (link->network->ipv6_accept_ra_route_table_set) + return link->network->ipv6_accept_ra_route_table; + return link_get_vrf_table(link); +} bool link_dhcp_enabled(Link *link, int family) { assert(link); @@ -477,7 +515,7 @@ int config_parse_dhcp_use_ntp( return 0; } -int config_parse_section_route_table( +int config_parse_dhcp_or_ra_route_table( const char *unit, const char *filename, unsigned line, @@ -495,6 +533,11 @@ int config_parse_section_route_table( assert(filename); assert(lvalue); + assert(IN_SET(ltype, + (RTPROT_DHCP<<16) | AF_UNSPEC, + (RTPROT_DHCP<<16) | AF_INET, + (RTPROT_DHCP<<16) | AF_INET6, + (RTPROT_RA<<16) | AF_INET6)); assert(rvalue); assert(data); @@ -505,12 +548,34 @@ int config_parse_section_route_table( return 0; } - if (STRPTR_IN_SET(section, "DHCP", "DHCPv4")) { + switch(ltype) { + case (RTPROT_DHCP<<16) | AF_INET: network->dhcp_route_table = rt; network->dhcp_route_table_set = true; - } else { /* section is IPv6AcceptRA */ + network->dhcp_route_table_set_explicitly = true; + break; + case (RTPROT_DHCP<<16) | AF_INET6: + network->dhcp6_route_table = rt; + network->dhcp6_route_table_set = true; + network->dhcp6_route_table_set_explicitly = true; + break; + case (RTPROT_DHCP<<16) | AF_UNSPEC: + /* For backward compatibility. */ + if (!network->dhcp_route_table_set_explicitly) { + network->dhcp_route_table = rt; + network->dhcp_route_table_set = true; + } + if (!network->dhcp6_route_table_set_explicitly) { + network->dhcp6_route_table = rt; + network->dhcp6_route_table_set = true; + } + break; + case (RTPROT_RA<<16) | AF_INET6: network->ipv6_accept_ra_route_table = rt; network->ipv6_accept_ra_route_table_set = true; + break; + default: + assert_not_reached(); } return 0; diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h index 2bbab932c7d..faabe5430a5 100644 --- a/src/network/networkd-dhcp-common.h +++ b/src/network/networkd-dhcp-common.h @@ -44,6 +44,10 @@ typedef struct DUID { bool set; } DUID; +uint32_t link_get_dhcp4_route_table(Link *link); +uint32_t link_get_dhcp6_route_table(Link *link); +uint32_t link_get_ipv6_accept_ra_route_table(Link *link); + bool link_dhcp_enabled(Link *link, int family); static inline bool link_dhcp4_enabled(Link *link) { return link_dhcp_enabled(link, AF_INET); @@ -85,7 +89,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_dns); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_domains); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_use_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); -CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_or_ra_route_table); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_or_vendor_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index d38c429bd99..247416a750b 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -211,7 +211,7 @@ static int dhcp4_request_route(Route *in, Link *link) { if (!route->priority_set) route->priority = link->network->dhcp_route_metric; if (!route->table_set) - route->table = link_get_dhcp_route_table(link); + route->table = link_get_dhcp4_route_table(link); if (route->mtu == 0) route->mtu = link->network->dhcp_route_mtu; diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 2f755bc4ebb..824047fcc1d 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -874,7 +874,7 @@ static int dhcp6_request_unreachable_route(Link *link, const struct in6_addr *ad route->family = AF_INET6; route->dst.in6 = *addr; route->dst_prefixlen = prefixlen; - route->table = link_get_dhcp_route_table(link); + route->table = link_get_dhcp6_route_table(link); route->type = RTN_UNREACHABLE; route->protocol = RTPROT_DHCP; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 377d525e50c..b42d5ad3a48 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -223,7 +223,7 @@ DHCPv4.IAID, config_parse_iaid, DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0 DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0 DHCPv4.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET, 0 -DHCPv4.RouteTable, config_parse_section_route_table, 0, 0 +DHCPv4.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_DHCP<<16) | AF_INET, 0 DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release) @@ -253,13 +253,14 @@ DHCPv6.SendOption, config_parse_dhcp_send_option, DHCPv6.IAID, config_parse_iaid, AF_INET6, 0 DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid) DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid) +DHCPv6.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_DHCP<<16) | AF_INET6, 0 IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix) IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) IPv6AcceptRA.UseMTU, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_mtu) IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client) -IPv6AcceptRA.RouteTable, config_parse_section_route_table, 0, 0 +IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_RA<<16) | AF_INET6, 0 IPv6AcceptRA.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_INET6, 0 IPv6AcceptRA.RouterAllowList, config_parse_address_filter, AF_INET6, offsetof(Network, ndisc_allow_listed_router) IPv6AcceptRA.RouterDenyList, config_parse_address_filter, AF_INET6, offsetof(Network, ndisc_deny_listed_router) @@ -519,7 +520,7 @@ DHCP.IAID, config_parse_iaid, DHCP.DUIDType, config_parse_network_duid_type, 0, 0 DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0 DHCP.RouteMetric, config_parse_dhcp_or_ra_route_metric, AF_UNSPEC, 0 -DHCP.RouteTable, config_parse_section_route_table, 0, 0 +DHCP.RouteTable, config_parse_dhcp_or_ra_route_table, (RTPROT_DHCP<<16) | AF_UNSPEC, 0 DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_rapid_commit) diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 81d484ce535..40a52797a61 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -135,6 +135,8 @@ struct Network { uint32_t dhcp_route_metric; bool dhcp_route_metric_set; uint32_t dhcp_route_table; + bool dhcp_route_table_set; + bool dhcp_route_table_set_explicitly; uint32_t dhcp_fallback_lease_lifetime; uint32_t dhcp_route_mtu; uint16_t dhcp_client_port; @@ -155,7 +157,6 @@ struct Network { int dhcp_use_gateway; bool dhcp_use_timezone; bool dhcp_use_hostname; - bool dhcp_route_table_set; bool dhcp_send_release; bool dhcp_send_decline; DHCPUseDomains dhcp_use_domains; @@ -174,6 +175,9 @@ struct Network { bool dhcp6_use_ntp; bool dhcp6_use_ntp_set; bool dhcp6_rapid_commit; + bool dhcp6_route_table; + bool dhcp6_route_table_set; + bool dhcp6_route_table_set_explicitly; DHCPUseDomains dhcp6_use_domains; bool dhcp6_use_domains_set; uint32_t dhcp6_iaid; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index c01f1ca14ae..7c89e66ab9f 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -22,24 +22,6 @@ #define ROUTES_DEFAULT_MAX_PER_FAMILY 4096U -static uint32_t link_get_vrf_table(const Link *link) { - return link->network->vrf ? VRF(link->network->vrf)->table : RT_TABLE_MAIN; -} - -uint32_t link_get_dhcp_route_table(const Link *link) { - /* When the interface is part of an VRF use the VRFs routing table, unless - * another table is explicitly specified. */ - if (link->network->dhcp_route_table_set) - return link->network->dhcp_route_table; - return link_get_vrf_table(link); -} - -uint32_t link_get_ipv6_accept_ra_route_table(const Link *link) { - if (link->network->ipv6_accept_ra_route_table_set) - return link->network->ipv6_accept_ra_route_table; - return link_get_vrf_table(link); -} - static const char * const route_type_table[__RTN_MAX] = { [RTN_UNICAST] = "unicast", [RTN_LOCAL] = "local", diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 235a91f08d5..2e5a073a2b0 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -84,9 +84,6 @@ bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_un int link_drop_routes(Link *link); int link_drop_foreign_routes(Link *link); -uint32_t link_get_dhcp_route_table(const Link *link); -uint32_t link_get_ipv6_accept_ra_route_table(const Link *link); - int link_request_route( Link *link, Route *route, diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 71ead0df9c7..fdd7f73baee 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -148,6 +148,7 @@ RouteMetric= IAID= DUIDType= DUIDRawData= +RouteTable= [DHCPv6PrefixDelegation] SubnetId= Announce=