]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: dhcp6: logs about delegated prefixes
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Apr 2021 01:50:36 +0000 (10:50 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 21 Apr 2021 05:04:33 +0000 (14:04 +0900)
Closes #19354.

src/network/networkd-dhcp6.c
src/network/networkd-link.c
src/network/networkd-link.h

index f5e66b945758481feb4ae8737d868a3e2378f399..73987600d2db0b732f14f0d85d649ae468c9f430 100644 (file)
@@ -652,6 +652,8 @@ static void dhcp6_pd_prefix_lost(Link *dhcp6_link) {
                 if (r < 0)
                         link_enter_failed(link);
         }
+
+        set_clear(dhcp6_link->dhcp6_pd_prefixes);
 }
 
 static int dhcp6_remove_old(Link *link, bool force);
@@ -794,20 +796,12 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
 
         (void) in_addr_prefix_to_string(AF_INET6, addr, prefixlen, &buf);
 
-        if (prefixlen > 64) {
-                log_link_debug(link, "PD Prefix length > 64, ignoring prefix %s", strna(buf));
-                return 0;
-        }
-
         if (prefixlen == 64) {
                 log_link_debug(link, "Not adding a blocking route for DHCPv6 delegated subnet %s since distributed prefix is 64",
                                strna(buf));
-                return 1;
+                return 0;
         }
 
-        if (prefixlen < 48)
-                log_link_warning(link, "PD Prefix length < 48, looks unusual: %s", strna(buf));
-
         r = route_new(&route);
         if (r < 0)
                 return log_oom();
@@ -835,7 +829,45 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
 
         (void) set_remove(link->dhcp6_routes_old, ret);
 
-        return 1;
+        return 0;
+}
+
+static int dhcp6_pd_prefix_add(Link *link, const union in_addr_union *prefix, uint8_t prefixlen) {
+        _cleanup_free_ struct in_addr_prefix *p = NULL;
+        _cleanup_free_ char *buf = NULL;
+        int r;
+
+        assert(link);
+        assert(prefix);
+
+        p = new(struct in_addr_prefix, 1);
+        if (!p)
+                return log_oom();
+
+        *p = (struct in_addr_prefix) {
+                .family = AF_INET6,
+                .prefixlen = prefixlen,
+                .address = *prefix,
+        };
+
+        (void) in_addr_prefix_to_string(p->family, &p->address, p->prefixlen, &buf);
+
+        log_link_full(link,
+                      set_contains(link->dhcp6_pd_prefixes, p) ? LOG_DEBUG :
+                      prefixlen > 64 || prefixlen < 48 ? LOG_WARNING : LOG_INFO,
+                      "DHCP6: received PD Prefix %s%s",
+                      strna(buf),
+                      prefixlen > 64 ? " with prefix length > 64, ignoring." :
+                      prefixlen < 48 ? " with prefix lenght < 48, looks unusual.": "");
+
+        /* Store PD prefix even if prefixlen > 64, not to make logged at warning level so frequently. */
+        r = set_ensure_put(&link->dhcp6_pd_prefixes, &in_addr_prefix_hash_ops_free, p);
+        if (r < 0)
+                return log_link_error_errno(link, r, "Failed to store DHCP6 PD prefix %s: %m", strna(buf));
+        if (r > 0)
+                TAKE_PTR(p);
+
+        return prefixlen <= 64;
 }
 
 static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
@@ -864,12 +896,16 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
                 if (r < 0)
                         break;
 
-                r = dhcp6_set_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len);
+                r = dhcp6_pd_prefix_add(dhcp6_link, &pd_prefix, pd_prefix_len);
                 if (r < 0)
                         return r;
                 if (r == 0)
                         continue;
 
+                r = dhcp6_set_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len);
+                if (r < 0)
+                        return r;
+
                 /* We are doing prefix allocation in two steps:
                  * 1. all those links that have a preferred subnet id will be assigned their subnet
                  * 2. all those links that remain will receive prefixes in sequential order. Prefixes
index 5143502745291ccea66766c928666be1cf259600..127780ec60675da28206739612294c54ab97b1c6 100644 (file)
@@ -573,6 +573,8 @@ static Link *link_free(Link *link) {
         link->dhcp6_pd_addresses_old = set_free(link->dhcp6_pd_addresses_old);
         link->ndisc_addresses = set_free(link->ndisc_addresses);
 
+        link->dhcp6_pd_prefixes = set_free(link->dhcp6_pd_prefixes);
+
         link_free_engines(link);
 
         free(link->ifname);
index a8bdd971f5fd5bd6fcdcfeac5d4b87abc3408579..a9f6cf61eb6bbf84a740f9ef11db28e7560cfaf6 100644 (file)
@@ -151,6 +151,7 @@ typedef struct Link {
         sd_dhcp6_lease *dhcp6_lease;
         Set *dhcp6_addresses, *dhcp6_addresses_old;
         Set *dhcp6_routes, *dhcp6_routes_old;
+        Set *dhcp6_pd_prefixes;
         Set *dhcp6_pd_addresses, *dhcp6_pd_addresses_old;
         Set *dhcp6_pd_routes, *dhcp6_pd_routes_old;
         unsigned dhcp6_address_messages;