diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-10-03 04:54:20 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-10-03 19:52:46 +0200 |
commit | af2aea8bb64b0dc42ecbe5549216eb567681a803 (patch) | |
tree | 642e29825207ed394c71bb1129beec805c96b7c6 /src/network | |
parent | network: make sec_to_usec() map 0sec -> 0usec (diff) | |
download | systemd-af2aea8bb64b0dc42ecbe5549216eb567681a803.tar.xz systemd-af2aea8bb64b0dc42ecbe5549216eb567681a803.zip |
network: ndisc: drop addresses and friends when RA with zero lifetime is received
Routers may send options with zero lifetime if previously announced
information is outdated. Hence, if we receive such messages, then we
need to drop relevant addresses or friends.
See e.g. https://www.rfc-editor.org/rfc/rfc4861#section-12.
Follow-up for 2ccada8dc4a3571468a335808fd6fe49b8c6c6dd.
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/networkd-address.c | 10 | ||||
-rw-r--r-- | src/network/networkd-ndisc.c | 34 | ||||
-rw-r--r-- | src/network/networkd-route.c | 10 |
3 files changed, 30 insertions, 24 deletions
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 60d3c6286e..259cd312c9 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1154,7 +1154,7 @@ int link_request_address( address_netlink_handler_t netlink_handler, Request **ret) { - Address *acquired, *existing; + Address *acquired, *existing = NULL; int r; assert(link); @@ -1187,7 +1187,13 @@ int link_request_address( address_set_broadcast(address, link); } - if (address_get(link, address, &existing) < 0) { + (void) address_get(link, address, &existing); + + if (address->lifetime_valid_usec == 0) + /* The requested address is outdated. Let's remove it. */ + return address_remove_and_drop(existing); + + if (!existing) { _cleanup_(address_freep) Address *tmp = NULL; if (consume_object) diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 124c777105..f2057a2d98 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -235,9 +235,6 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { if (r < 0) return log_link_error_errno(link, r, "Failed to get gateway lifetime from RA: %m"); - if (lifetime_sec == 0) /* not a default router */ - return 0; - r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, ×tamp_usec); if (r < 0) return log_link_error_errno(link, r, "Failed to get RA timestamp: %m"); @@ -351,11 +348,6 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r if (r < 0) return log_link_error_errno(link, r, "Failed to get prefix valid lifetime: %m"); - if (lifetime_valid_sec == 0) { - log_link_debug(link, "Ignoring prefix as its valid lifetime is zero."); - return 0; - } - r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred_sec); if (r < 0) return log_link_error_errno(link, r, "Failed to get prefix preferred lifetime: %m"); @@ -412,9 +404,6 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) { if (r < 0) return log_link_error_errno(link, r, "Failed to get prefix lifetime: %m"); - if (lifetime_sec == 0) - return 0; - r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, ×tamp_usec); if (r < 0) return log_link_error_errno(link, r, "Failed to get RA timestamp: %m"); @@ -515,9 +504,6 @@ 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 route lifetime from RA: %m"); - if (lifetime_sec == 0) - return 0; - r = sd_ndisc_router_route_get_address(rt, &dst); if (r < 0) return log_link_error_errno(link, r, "Failed to get route destination address: %m"); @@ -623,9 +609,6 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { if (r < 0) return log_link_error_errno(link, r, "Failed to get RDNSS lifetime: %m"); - if (lifetime_sec == 0) - return 0; - lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec); n = sd_ndisc_router_rdnss_get_addresses(rt, &a); @@ -643,6 +626,13 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) { .address = a[j], }; + if (lifetime_usec == 0) { + /* The entry is outdated. */ + free(set_remove(link->ndisc_rdnss, &d)); + updated = true; + continue; + } + rdnss = set_get(link->ndisc_rdnss, &d); if (rdnss) { rdnss->router = router; @@ -716,9 +706,6 @@ static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) { if (r < 0) return log_link_error_errno(link, r, "Failed to get DNSSL lifetime: %m"); - if (lifetime_sec == 0) - return 0; - lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec); r = sd_ndisc_router_dnssl_get_domains(rt, &l); @@ -741,6 +728,13 @@ static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) { strcpy(NDISC_DNSSL_DOMAIN(s), *j); + if (lifetime_usec == 0) { + /* The entry is outdated. */ + free(set_remove(link->ndisc_dnssl, s)); + updated = true; + continue; + } + dnssl = set_get(link->ndisc_dnssl, s); if (dnssl) { dnssl->router = router; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 2b17959ca2..514845f7c5 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1426,7 +1426,7 @@ int link_request_route( route_netlink_handler_t netlink_handler, Request **ret) { - Route *existing; + Route *existing = NULL; int r; assert(link); @@ -1435,7 +1435,13 @@ int link_request_route( assert(route->source != NETWORK_CONFIG_SOURCE_FOREIGN); assert(!route_needs_convert(route)); - if (route_get(link->manager, link, route, &existing) < 0) { + (void) route_get(link->manager, link, route, &existing); + + if (route->lifetime_usec == 0) + /* The requested route is outdated. Let's remove it. */ + return route_remove_and_drop(existing); + + if (!existing) { _cleanup_(route_freep) Route *tmp = NULL; if (consume_object) |