diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-10-28 12:55:59 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-10-28 15:48:28 +0900 |
commit | 6f812d289946a3e0e386378263b40d09e125752e (patch) | |
tree | 0d617bec9c7a5791cae07285fa4179dbda6c4eac /src/network/networkd-ndisc.c | |
parent | 6fadf01cf3cdd98f78b7829f4c6c892306958394 (diff) | |
download | systemd-6f812d289946a3e0e386378263b40d09e125752e.tar.gz |
network: adjust route priority based on preference
Even if different preference is specified, the kernel merges multiple
routes with the same preference. This is problematic when a network has
multiple routers.
Fixes #25138.
Diffstat (limited to 'src/network/networkd-ndisc.c')
-rw-r--r-- | src/network/networkd-ndisc.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index f31735b6ec..ce7dff222b 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -143,6 +143,28 @@ static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request return 1; } +static void ndisc_set_route_priority(Link *link, Route *route) { + assert(link); + assert(route); + + if (route->priority_set) + return; /* explicitly configured. */ + + switch (route->pref) { + case SD_NDISC_PREFERENCE_LOW: + route->priority = link->network->ipv6_accept_ra_route_metric_low; + break; + case SD_NDISC_PREFERENCE_MEDIUM: + route->priority = link->network->ipv6_accept_ra_route_metric_medium; + break; + case SD_NDISC_PREFERENCE_HIGH: + route->priority = link->network->ipv6_accept_ra_route_metric_high; + break; + default: + assert_not_reached(); + } +} + static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) { _cleanup_(route_freep) Route *route = in; struct in6_addr router; @@ -160,8 +182,7 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) { route->provider.in6 = router; if (!route->table_set) route->table = link_get_ipv6_accept_ra_route_table(link); - if (!route->priority_set) - route->priority = link->network->ipv6_accept_ra_route_metric; + ndisc_set_route_priority(link, route); if (!route->protocol_set) route->protocol = RTPROT_RA; |