summaryrefslogtreecommitdiff
path: root/src/network/networkd-ndisc.c
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-10-28 12:55:59 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-10-28 15:48:28 +0900
commit6f812d289946a3e0e386378263b40d09e125752e (patch)
tree0d617bec9c7a5791cae07285fa4179dbda6c4eac /src/network/networkd-ndisc.c
parent6fadf01cf3cdd98f78b7829f4c6c892306958394 (diff)
downloadsystemd-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.c25
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;