summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-11-30 11:10:21 +0900
committerLuca Boccassi <luca.boccassi@gmail.com>2022-12-01 23:15:09 +0100
commitd9a95033bf3a2a8cb886847dd7404a53336ac090 (patch)
tree3983b027646b43eacd335bee8597de797a9eae13 /src/network
parentf7031144da4d6fd8a765f6e5d27748fae4fe9a2e (diff)
downloadsystemd-d9a95033bf3a2a8cb886847dd7404a53336ac090.tar.gz
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.c24
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) {