]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce RouterAllowList= and RouterDenyList= in [IPv6AcceptRA]
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Dec 2020 05:27:25 +0000 (14:27 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Dec 2020 08:16:15 +0000 (17:16 +0900)
man/systemd.network.xml
src/network/networkd-ndisc.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index 903ffd88de556b338c537b80e780fc9073cf724b..7baf1a9df01e08d115148ce4872859830ec9f09a 100644 (file)
@@ -2092,6 +2092,23 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>RouterDenyList=</varname></term>
+          <listitem>
+            <para>A whitespace-separated list of IPv6 router addresses. Any information advertised by
+            the listed router is ignored.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><varname>RouterAllowList=</varname></term>
+          <listitem>
+            <para>A whitespace-separated list of IPv6 router addresses. Only information advertised by
+            the listed router is accepted. Note that if <varname>RouterAllowList=</varname> is
+            configured then <varname>RouterDenyList=</varname> is ignored.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>PrefixDenyList=</varname></term>
           <listitem>
index 59ab8a7843430c13fbf5db3ccc52e3b4e3819930..3f1837f5911ece029d11f47d81badf552fc17dc5 100644 (file)
@@ -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);
index 6c999e43636d68b5678aba0cd6315b1353de7844..2a6cb6deaeb90dd4f8fc675f7b708f0c3a3266c0 100644 (file)
@@ -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)
index 89a1f8acba18cb144b241823e918485e211c54ad..daece28dbbe6905dbc258aa03ac5bd8ac1f8cb2d 100644 (file)
@@ -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);
index 835e7299ead40ae6b9711969247ed01d83421bc4..32f5ae8d72a84eae5ca164b3a56030de9107bfbf 100644 (file)
@@ -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;
index f1f7ad0cb87188809b98624aa38cb3b438ea8071..f57f0cd561138d81910fd445394bd0982cc9ca4a 100644 (file)
@@ -310,6 +310,8 @@ UseDNS=
 DHCPv6Client=
 UseAutonomousPrefix=
 UseOnLinkPrefix=
+RouterAllowList=
+RouterDenyList=
 PrefixAllowList=
 PrefixDenyList=
 RouteAllowList=