summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2024-04-12 08:46:34 +0200
committerGitHub <noreply@github.com>2024-04-12 08:46:34 +0200
commitdd63f00c6471971e96e4f71f186979230ddaf3d1 (patch)
tree388c14fa00191416f91ae70d38d75cdd24231d67
parentresolved: use NULL to represent an empty answer (diff)
parentnetwork/ndisc: drop onlink prefix when valid lifetime is zero (diff)
downloadsystemd-dd63f00c6471971e96e4f71f186979230ddaf3d1.tar.xz
systemd-dd63f00c6471971e96e4f71f186979230ddaf3d1.zip
Merge pull request #32240 from yuwata/network-ndisc-fix-on-link-prefix
network/ndisc: fixlets for on-link prefix
-rw-r--r--src/network/networkd-ndisc.c79
1 files changed, 21 insertions, 58 deletions
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 7f5577f6ae..5d1c895f0d 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -1224,59 +1224,23 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
route->pref = preference;
route->lifetime_usec = lifetime_usec;
- r = ndisc_request_router_route(route, link, rt);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not request prefix route: %m");
-
- return 0;
-}
-
-static int ndisc_router_drop_onlink_prefix(Link *link, sd_ndisc_router *rt) {
- _cleanup_(route_unrefp) Route *route = NULL;
- uint8_t prefixlen;
- struct in6_addr prefix;
- usec_t lifetime_usec;
- int r;
-
- assert(link);
- assert(link->network);
- assert(rt);
-
- /* RFC 4861 section 6.3.4.
- * Note, however, that a Prefix Information option with the on-link flag set to zero conveys no
- * information concerning on-link determination and MUST NOT be interpreted to mean that addresses
- * covered by the prefix are off-link. The only way to cancel a previous on-link indication is to
- * advertise that prefix with the L-bit set and the Lifetime set to zero. */
-
- if (!link->network->ndisc_use_onlink_prefix)
- return 0;
-
- r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_usec);
- if (r < 0)
- return log_link_warning_errno(link, r, "Failed to get prefix lifetime: %m");
-
- if (lifetime_usec != 0)
- return 0;
-
- r = sd_ndisc_router_prefix_get_address(rt, &prefix);
- if (r < 0)
- return log_link_warning_errno(link, r, "Failed to get prefix address: %m");
-
- r = sd_ndisc_router_prefix_get_prefixlen(rt, &prefixlen);
- if (r < 0)
- return log_link_warning_errno(link, r, "Failed to get prefix length: %m");
-
- r = route_new(&route);
- if (r < 0)
- return log_oom();
-
- route->family = AF_INET6;
- route->dst.in6 = prefix;
- route->dst_prefixlen = prefixlen;
-
- r = ndisc_remove_route(route, link);
- if (r < 0)
- return log_link_warning_errno(link, r, "Could not remove prefix route: %m");
+ /* RFC 4861 section 6.3.4:
+ * - If the prefix is not already present in the Prefix List, and the Prefix Information option's
+ * Valid Lifetime field is non-zero, create a new entry for the prefix and initialize its
+ * invalidation timer to the Valid Lifetime value in the Prefix Information option.
+ *
+ * - If the prefix is already present in the host's Prefix List as the result of a previously
+ * received advertisement, reset its invalidation timer to the Valid Lifetime value in the Prefix
+ * Information option. If the new Lifetime value is zero, time-out the prefix immediately. */
+ if (lifetime_usec == 0) {
+ r = ndisc_remove_route(route, link);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to remove prefix route: %m");
+ } else {
+ r = ndisc_request_router_route(route, link, rt);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to request prefix route: %m");
+ }
return 0;
}
@@ -1319,12 +1283,11 @@ static int ndisc_router_process_prefix(Link *link, sd_ndisc_router *rt) {
if (r < 0)
return log_link_warning_errno(link, r, "Failed to get RA prefix flags: %m");
- if (FLAGS_SET(flags, ND_OPT_PI_FLAG_ONLINK))
+ if (FLAGS_SET(flags, ND_OPT_PI_FLAG_ONLINK)) {
r = ndisc_router_process_onlink_prefix(link, rt);
- else
- r = ndisc_router_drop_onlink_prefix(link, rt);
- if (r < 0)
- return r;
+ if (r < 0)
+ return r;
+ }
if (FLAGS_SET(flags, ND_OPT_PI_FLAG_AUTO)) {
r = ndisc_router_process_autonomous_prefix(link, rt);