diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-11-30 03:10:21 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2022-12-01 23:15:09 +0100 |
commit | d9a95033bf3a2a8cb886847dd7404a53336ac090 (patch) | |
tree | 3983b027646b43eacd335bee8597de797a9eae13 /src/network | |
parent | Merge pull request #25568 from yuwata/network-tiny-cleanups (diff) | |
download | systemd-d9a95033bf3a2a8cb886847dd7404a53336ac090.tar.xz systemd-d9a95033bf3a2a8cb886847dd7404a53336ac090.zip |
network: unset Link.ndisc_configured only when a new address or route is requested
This fixes an issue introduced by af2aea8bb64b0dc42ecbe5549216eb567681a803.
When an outdated address or route is passed to link_request_address()/route(),
then they return 0 and the address or route will not be assigned. Such
situation can happen when we receive RA with zero lifetime. In that
case, we should not unset Link.ndisc_configured flag, otherwise even
no new address nor route will assigned, the interface will enter to the
configuring state, and unnecessary DBus property change is emit and the state
file will be updated. That makes resolved or timesyncd triggered to
reconfigure the interface.
Fixes #25456.
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/networkd-ndisc.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 6ee098a015..c7ed5fcfe1 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -168,6 +168,7 @@ static void ndisc_set_route_priority(Link *link, Route *route) { static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) { _cleanup_(route_freep) Route *route = in; struct in6_addr router; + bool is_new; int r; assert(route); @@ -186,11 +187,16 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) { if (!route->protocol_set) route->protocol = RTPROT_RA; - if (route_get(NULL, link, route, NULL) < 0) + is_new = route_get(NULL, link, route, NULL) < 0; + + r = link_request_route(link, TAKE_PTR(route), true, &link->ndisc_messages, + ndisc_route_handler, NULL); + if (r < 0) + return r; + if (r > 0 && is_new) link->ndisc_configured = false; - return link_request_route(link, TAKE_PTR(route), true, &link->ndisc_messages, - ndisc_route_handler, NULL); + return 0; } static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) { @@ -212,6 +218,7 @@ static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Reques static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) { _cleanup_(address_freep) Address *address = in; struct in6_addr router; + bool is_new; int r; assert(address); @@ -229,11 +236,16 @@ static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) { if (r < 0) return r; - if (address_get(link, address, NULL) < 0) + is_new = address_get(link, address, NULL) < 0; + + r = link_request_address(link, TAKE_PTR(address), true, &link->ndisc_messages, + ndisc_address_handler, NULL); + if (r < 0) + return r; + if (r > 0 && is_new) link->ndisc_configured = false; - return link_request_address(link, TAKE_PTR(address), true, &link->ndisc_messages, - ndisc_address_handler, NULL); + return 0; } static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { |