From 75d26411900d3276edf536009dcc2bbd4766d43c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 24 Dec 2020 14:27:25 +0900 Subject: [PATCH] network: introduce RouterAllowList= and RouterDenyList= in [IPv6AcceptRA] --- man/systemd.network.xml | 17 ++++++++++ src/network/networkd-ndisc.c | 34 ++++++++++++++----- src/network/networkd-network-gperf.gperf | 2 ++ src/network/networkd-network.c | 2 ++ src/network/networkd-network.h | 2 ++ .../fuzz-network-parser/directives.network | 2 ++ 6 files changed, 51 insertions(+), 8 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 903ffd88de..7baf1a9df0 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2092,6 +2092,23 @@ IPv6Token=prefixstable:2002:da8:1:: + + RouterDenyList= + + A whitespace-separated list of IPv6 router addresses. Any information advertised by + the listed router is ignored. + + + + + RouterAllowList= + + A whitespace-separated list of IPv6 router addresses. Only information advertised by + the listed router is accepted. Note that if RouterAllowList= is + configured then RouterDenyList= is ignored. + + + PrefixDenyList= diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 59ab8a7843..3f1837f591 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -70,7 +70,10 @@ void network_adjust_ipv6_accept_ra(Network *network) { /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */ network->ipv6_accept_ra = !FLAGS_SET(network->ip_forward, ADDRESS_FAMILY_IPV6); - /* When PrefixAllowList= or RouteAllowList= are specified, then PrefixDenyList= or RouteDenyList= are ignored. */ + /* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then + * RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */ + if (!set_isempty(network->ndisc_allow_listed_router)) + network->ndisc_deny_listed_router = set_free_free(network->ndisc_deny_listed_router); if (!set_isempty(network->ndisc_allow_listed_prefix)) network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix); if (!set_isempty(network->ndisc_allow_listed_route_prefix)) @@ -1168,7 +1171,7 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) { } static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { - struct in6_addr router; + union in_addr_union router; uint64_t flags; NDiscAddress *na; NDiscRoute *nr; @@ -1179,21 +1182,36 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) { assert(link->manager); assert(rt); + r = sd_ndisc_router_get_address(rt, &router.in6); + if (r < 0) + return log_link_error_errno(link, r, "Failed to get router address from RA: %m"); + + if ((!set_isempty(link->network->ndisc_allow_listed_router) && + !set_contains(link->network->ndisc_allow_listed_router, &router.in6)) || + set_contains(link->network->ndisc_deny_listed_router, &router.in6)) { + if (DEBUG_LOGGING) { + _cleanup_free_ char *buf = NULL; + + (void) in_addr_to_string(AF_INET6, &router, &buf); + if (!set_isempty(link->network->ndisc_allow_listed_router)) + log_link_debug(link, "Router '%s' is not in allow list, ignoring", strna(buf)); + else + log_link_debug(link, "Router '%s' is in deny list, ignoring", strna(buf)); + } + return 0; + } + link->ndisc_addresses_configured = false; link->ndisc_routes_configured = false; link_dirty(link); - r = sd_ndisc_router_get_address(rt, &router); - if (r < 0) - return log_link_error_errno(link, r, "Failed to get router address from RA: %m"); - SET_FOREACH(na, link->ndisc_addresses) - if (IN6_ARE_ADDR_EQUAL(&na->router, &router)) + if (IN6_ARE_ADDR_EQUAL(&na->router, &router.in6)) na->marked = true; SET_FOREACH(nr, link->ndisc_routes) - if (IN6_ARE_ADDR_EQUAL(&nr->router, &router)) + if (IN6_ARE_ADDR_EQUAL(&nr->router, &router.in6)) nr->marked = true; r = sd_ndisc_router_get_flags(rt, &flags); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 6c999e4363..2a6cb6deae 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -237,6 +237,8 @@ IPv6AcceptRA.UseDNS, config_parse_bool, IPv6AcceptRA.UseDomains, config_parse_dhcp_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) 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.RouterAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_router) +IPv6AcceptRA.RouterDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_router) IPv6AcceptRA.PrefixAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_prefix) IPv6AcceptRA.PrefixDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix) IPv6AcceptRA.RouteAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_route_prefix) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 89a1f8acba..daece28dbb 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -606,6 +606,8 @@ static Network *network_free(Network *network) { ordered_set_free(network->router_search_domains); free(network->router_dns); + set_free_free(network->ndisc_deny_listed_router); + set_free_free(network->ndisc_allow_listed_router); set_free_free(network->ndisc_deny_listed_prefix); set_free_free(network->ndisc_allow_listed_prefix); set_free_free(network->ndisc_deny_listed_route_prefix); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 835e7299ea..32f5ae8d72 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -256,6 +256,8 @@ struct Network { DHCPUseDomains ipv6_accept_ra_use_domains; IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client; uint32_t ipv6_accept_ra_route_table; + Set *ndisc_deny_listed_router; + Set *ndisc_allow_listed_router; Set *ndisc_deny_listed_prefix; Set *ndisc_allow_listed_prefix; Set *ndisc_deny_listed_route_prefix; diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index f1f7ad0cb8..f57f0cd561 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -310,6 +310,8 @@ UseDNS= DHCPv6Client= UseAutonomousPrefix= UseOnLinkPrefix= +RouterAllowList= +RouterDenyList= PrefixAllowList= PrefixDenyList= RouteAllowList=