From 413ea20ab3d86b5bccf775da21a945327b3880c9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 14 Jan 2024 13:49:30 +0900 Subject: [PATCH] network/route-nexthop: introduce route_nexthops_copy() This also introduce an extra argument for route_dup(), but it is currently unused, will be used later. No functional change, just preparation for later commits. --- src/network/networkd-dhcp4.c | 2 +- src/network/networkd-ndisc.c | 2 +- src/network/networkd-route-nexthop.c | 30 ++++++++++++++++++++++++++++ src/network/networkd-route-nexthop.h | 4 ++++ src/network/networkd-route.c | 19 ++++++++++-------- src/network/networkd-route.h | 2 +- 6 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index b56106867bd..d07b56142ca 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -659,7 +659,7 @@ static int dhcp4_request_semi_static_routes(Link *link) { if (r < 0) return r; - r = route_dup(rt, &route); + r = route_dup(rt, NULL, &route); if (r < 0) return r; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 33d11509d37..0b033c70b6e 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -340,7 +340,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) { if (route_gw->nexthop.family != AF_INET6) continue; - r = route_dup(route_gw, &route); + r = route_dup(route_gw, NULL, &route); if (r < 0) return r; diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c index 9f08938dfc3..6ea68afdc8a 100644 --- a/src/network/networkd-route-nexthop.c +++ b/src/network/networkd-route-nexthop.c @@ -170,6 +170,36 @@ int route_nexthops_compare_func(const Route *a, const Route *b) { }} } +static int route_nexthop_copy(const RouteNextHop *src, RouteNextHop *dest) { + assert(src); + assert(dest); + + *dest = *src; + + /* unset pointer copied in the above. */ + dest->ifname = NULL; + + return strdup_or_null(src->ifindex == 0 ? NULL : src->ifname, &dest->ifname); +} + +int route_nexthops_copy(const Route *src, const RouteNextHop *nh, Route *dest) { + assert(src); + assert(dest); + + if (src->nexthop_id != 0 || route_type_is_reject(src)) + return 0; + + if (nh) + return route_nexthop_copy(nh, &dest->nexthop); + + if (ordered_set_isempty(src->nexthops)) + return route_nexthop_copy(&src->nexthop, &dest->nexthop); + + /* Currently, this does not copy multipath routes. */ + + return 0; +} + int route_nexthop_get_link(Manager *manager, Link *link, const RouteNextHop *nh, Link **ret) { assert(manager); assert(nh); diff --git a/src/network/networkd-route-nexthop.h b/src/network/networkd-route-nexthop.h index f06a2c49ff1..0d305c7231c 100644 --- a/src/network/networkd-route-nexthop.h +++ b/src/network/networkd-route-nexthop.h @@ -24,6 +24,8 @@ typedef struct RouteNextHop { /* unsupported attributes: RTA_FLOW (IPv4 only), RTA_ENCAP_TYPE, RTA_ENCAP. */ } RouteNextHop; +#define ROUTE_NEXTHOP_NULL ((const RouteNextHop) {}) + RouteNextHop* route_nexthop_free(RouteNextHop *nh); DEFINE_TRIVIAL_CLEANUP_FUNC(RouteNextHop*, route_nexthop_free); @@ -32,6 +34,8 @@ void route_nexthops_done(Route *route); void route_nexthops_hash_func(const Route *route, struct siphash *state); int route_nexthops_compare_func(const Route *a, const Route *b); +int route_nexthops_copy(const Route *src, const RouteNextHop *nh, Route *dest); + int route_nexthop_get_link(Manager *manager, Link *link, const RouteNextHop *nh, Link **ret); int route_nexthops_is_ready_to_configure(const Route *route, Link *link); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 06a114b5a06..0fbe99f06a2 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -336,12 +336,10 @@ static int route_get_link(Manager *manager, const Route *route, Link **ret) { return route_nexthop_get_link(manager, NULL, &route->nexthop, ret); } -int route_dup(const Route *src, Route **ret) { +int route_dup(const Route *src, const RouteNextHop *nh, Route **ret) { _cleanup_(route_freep) Route *dest = NULL; int r; - /* This does not copy mulipath routes. */ - assert(src); assert(ret); @@ -355,10 +353,15 @@ int route_dup(const Route *src, Route **ret) { dest->wireguard = NULL; dest->section = NULL; dest->link = NULL; + dest->nexthop = ROUTE_NEXTHOP_NULL; dest->nexthops = NULL; dest->metric = ROUTE_METRIC_NULL; dest->expire = NULL; + r = route_nexthops_copy(src, nh, dest); + if (r < 0) + return r; + r = route_metric_copy(&src->metric, &dest->metric); if (r < 0) return r; @@ -476,7 +479,7 @@ static int route_convert(Manager *manager, Link *link, const Route *route, Conve if (r < 0) return r; - r = route_dup(route, &c->routes[0]); + r = route_dup(route, NULL, &c->routes[0]); if (r < 0) return r; @@ -499,7 +502,7 @@ static int route_convert(Manager *manager, Link *link, const Route *route, Conve if (r < 0) return r; - r = route_dup(route, &c->routes[i]); + r = route_dup(route, NULL, &c->routes[i]); if (r < 0) return r; @@ -523,7 +526,7 @@ static int route_convert(Manager *manager, Link *link, const Route *route, Conve size_t i = 0; RouteNextHop *nh; ORDERED_SET_FOREACH(nh, route->nexthops) { - r = route_dup(route, &c->routes[i]); + r = route_dup(route, NULL, &c->routes[i]); if (r < 0) return r; @@ -1129,7 +1132,7 @@ static int route_process_request(Request *req, Link *link, Route *route) { if (route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) < 0) { _cleanup_(route_freep) Route *tmp = NULL; - r = route_dup(converted->routes[i], &tmp); + r = route_dup(converted->routes[i], NULL, &tmp); if (r < 0) return log_oom(); @@ -1215,7 +1218,7 @@ int link_request_route( if (consume_object) tmp = route; else { - r = route_dup(route, &tmp); + r = route_dup(route, NULL, &tmp); if (r < 0) return r; } diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 8d55a6ac001..49e78e9777e 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -86,7 +86,7 @@ DEFINE_SECTION_CLEANUP_FUNCTIONS(Route, route_free); int route_new(Route **ret); int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret); -int route_dup(const Route *src, Route **ret); +int route_dup(const Route *src, const RouteNextHop *nh, Route **ret); int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, Route *route, const char *error_msg); int route_remove(Route *route); -- 2.39.5