]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: add RouteDenyList
authorDevon Pringle <devon.pringle@opengear.com>
Mon, 14 Dec 2020 06:23:17 +0000 (16:23 +1000)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 18 Dec 2020 12:44:32 +0000 (21:44 +0900)
Allow configuration for IPv6 discovered routes to be ignored instead of
adding them as a route. This can be used to block unwanted routes, for
example, you may wish to not receive some set of routes on an interface
if they are causing issues.

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 e46f506f0f0c26334346a7ef319e0cc273b40731..7a330c12fae84a6077dc898df0262f160bf6a107 100644 (file)
@@ -2095,7 +2095,16 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
         <varlistentry>
           <term><varname>DenyList=</varname></term>
           <listitem>
-            <para>A whitespace-separated list of IPv6 prefixes. IPv6 prefixes supplied via router advertisements in the list are ignored.</para>
+            <para>A whitespace-separated list of IPv6 prefixes. IPv6 prefixes supplied via router
+            advertisements in the list are ignored.</para>
+          </listitem>
+        </varlistentry>
+
+        <varlistentry>
+          <term><varname>RouteDenyList=</varname></term>
+          <listitem>
+            <para>A whitespace-separated list of IPv6 route prefixes. IPv6 route prefixes supplied via
+            router advertisements in the list are ignored.</para>
           </listitem>
         </varlistentry>
 
index 0d21089d5cc5bc4a101f6cfa38b67c7b3a601cf5..61d3c987952d019f3ced24892d2943105913c9db 100644 (file)
@@ -839,6 +839,16 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
 
+        if (set_contains(link->network->ndisc_deny_listed_route_prefix, &gateway.in6)) {
+                if (DEBUG_LOGGING) {
+                        _cleanup_free_ char *buf = NULL;
+
+                        (void) in_addr_to_string(AF_INET6, &gateway, &buf);
+                        log_link_debug(link, "Route Prefix '%s' is deny-listed, ignoring", strnull(buf));
+                }
+                return 0;
+        }
+
         if (link_has_ipv6_address(link, &gateway.in6) == 0) {
                 if (DEBUG_LOGGING) {
                         _cleanup_free_ char *buf = NULL;
@@ -1378,8 +1388,8 @@ int config_parse_ndisc_deny_listed_prefix(
                 void *data,
                 void *userdata) {
 
-        Network *network = data;
-        const char *p;
+        Set **list = data;
+        bool is_route;
         int r;
 
         assert(filename);
@@ -1388,11 +1398,13 @@ int config_parse_ndisc_deny_listed_prefix(
         assert(data);
 
         if (isempty(rvalue)) {
-                network->ndisc_deny_listed_prefix = set_free_free(network->ndisc_deny_listed_prefix);
+                *list = set_free_free(*list);
                 return 0;
         }
 
-        for (p = rvalue;;) {
+        is_route = streq_ptr(lvalue, "RouteDenyList");
+
+        for (const char *p = rvalue;;) {
                 _cleanup_free_ char *n = NULL;
                 _cleanup_free_ struct in6_addr *a = NULL;
                 union in_addr_union ip;
@@ -1402,8 +1414,8 @@ int config_parse_ndisc_deny_listed_prefix(
                         return log_oom();
                 if (r < 0) {
                         log_syntax(unit, LOG_WARNING, filename, line, r,
-                                   "Failed to parse NDisc deny-listed prefix, ignoring assignment: %s",
-                                   rvalue);
+                                   "Failed to parse NDisc deny-listed %sprefix, ignoring assignment: %s",
+                                   is_route ? "route " : "", rvalue);
                         return 0;
                 }
                 if (r == 0)
@@ -1412,20 +1424,24 @@ int config_parse_ndisc_deny_listed_prefix(
                 r = in_addr_from_string(AF_INET6, n, &ip);
                 if (r < 0) {
                         log_syntax(unit, LOG_WARNING, filename, line, r,
-                                   "NDisc deny-listed prefix is invalid, ignoring assignment: %s", n);
+                                   "NDisc deny-listed %sprefix is invalid, ignoring assignment: %s",
+                                   is_route ? "route " : "", n);
                         continue;
                 }
 
-                if (set_contains(network->ndisc_deny_listed_prefix, &ip.in6))
-                        continue;
-
                 a = newdup(struct in6_addr, &ip.in6, 1);
                 if (!a)
                         return log_oom();
 
-                r = set_ensure_consume(&network->ndisc_deny_listed_prefix, &in6_addr_hash_ops, TAKE_PTR(a));
+                r = set_ensure_consume(list, &in6_addr_hash_ops, TAKE_PTR(a));
                 if (r < 0)
                         return log_oom();
+                if (r == 0)
+                        log_syntax(unit, LOG_WARNING, filename, line, 0,
+                                   "NDisc deny-listed %sprefix entry %s is duplicated, ignoring assignment.",
+                                   is_route ? "route " : "", n);
+                if (r > 0)
+                        TAKE_PTR(a);
         }
 }
 
index ccf7867d4f64acdb62cd5c51afaff17a78da35e9..b082ffe6e877c2f14d407f34e6f07dfeb4757894 100644 (file)
@@ -237,8 +237,9 @@ 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.DenyList,                       config_parse_ndisc_deny_listed_prefix,                    0,                             0
-IPv6AcceptRA.BlackList,                      config_parse_ndisc_deny_listed_prefix,                    0,                             0
+IPv6AcceptRA.DenyList,                       config_parse_ndisc_deny_listed_prefix,                    0,                             offsetof(Network, ndisc_deny_listed_prefix)
+IPv6AcceptRA.BlackList,                      config_parse_ndisc_deny_listed_prefix,                    0,                             offsetof(Network, ndisc_deny_listed_prefix)
+IPv6AcceptRA.RouteDenyList,                  config_parse_ndisc_deny_listed_prefix,                    0,                             offsetof(Network, ndisc_deny_listed_route_prefix)
 DHCPServer.MaxLeaseTimeSec,                  config_parse_sec,                                         0,                             offsetof(Network, dhcp_server_max_lease_time_usec)
 DHCPServer.DefaultLeaseTimeSec,              config_parse_sec,                                         0,                             offsetof(Network, dhcp_server_default_lease_time_usec)
 DHCPServer.EmitDNS,                          config_parse_bool,                                        0,                             offsetof(Network, dhcp_server_emit[SD_DHCP_LEASE_DNS].emit)
index a5440a83c795c25efa90fccc9ee7d03c72b08cdb..c037904cdd1c1f025be8c20e69761e56ff844cda 100644 (file)
@@ -607,6 +607,7 @@ static Network *network_free(Network *network) {
         ordered_set_free(network->router_search_domains);
         free(network->router_dns);
         set_free_free(network->ndisc_deny_listed_prefix);
+        set_free_free(network->ndisc_deny_listed_route_prefix);
 
         free(network->bridge_name);
         free(network->bond_name);
index a23de93126dbb47be6447d0d903e355f25daceda..feda19bbc1fe257bb267a618afa279222968326d 100644 (file)
@@ -257,6 +257,7 @@ struct Network {
         IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client;
         uint32_t ipv6_accept_ra_route_table;
         Set *ndisc_deny_listed_prefix;
+        Set *ndisc_deny_listed_route_prefix;
         OrderedSet *ipv6_tokens;
 
         /* LLDP support */
index a4da64bd0085b4c77660e45164013a278a4a7cba..6b7cbb355930674c1bab52c373e5b37c0011bb48 100644 (file)
@@ -312,6 +312,7 @@ UseAutonomousPrefix=
 UseOnLinkPrefix=
 DenyList=
 BlackList=
+RouteDenyList=
 [DHCPServer]
 EmitNTP=
 PoolSize=