From 731ff05b3218aa7dce03bf53ff1be41e56212b5b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Oct 2020 09:52:07 +0900 Subject: [PATCH] network: introduce link_deserialize_routes() --- src/network/networkd-link.c | 62 ++------------------------------- src/network/networkd-route.c | 66 ++++++++++++++++++++++++++++++++++++ src/network/networkd-route.h | 1 + 3 files changed, 70 insertions(+), 59 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index dea1e723c3..0217300be6 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3391,65 +3391,9 @@ network_file_fail: return log_link_error_errno(link, r, "Failed to add address: %m"); } - for (const char *p = routes; p; ) { - _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL; - _cleanup_(route_freep) Route *tmp = NULL; - _cleanup_free_ char *route_str = NULL; - char *prefixlen_str; - Route *route; - - r = extract_first_word(&p, &route_str, NULL, 0); - if (r < 0) - log_link_debug_errno(link, r, "failed to parse ROUTES: %m"); - if (r <= 0) - break; - - prefixlen_str = strchr(route_str, '/'); - if (!prefixlen_str) { - log_link_debug(link, "Failed to parse route %s", route_str); - continue; - } - *prefixlen_str++ = '\0'; - - r = route_new(&tmp); - if (r < 0) - return log_oom(); - - r = sscanf(prefixlen_str, - "%hhu/%hhu/%"SCNu32"/%"PRIu32"/"USEC_FMT, - &tmp->dst_prefixlen, - &tmp->tos, - &tmp->priority, - &tmp->table, - &tmp->lifetime); - if (r != 5) { - log_link_debug(link, - "Failed to parse destination prefix length, tos, priority, table or expiration %s", - prefixlen_str); - continue; - } - - r = in_addr_from_string_auto(route_str, &tmp->family, &tmp->dst); - if (r < 0) { - log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str); - continue; - } - - r = route_add(link, tmp, &route); - if (r < 0) - return log_link_error_errno(link, r, "Failed to add route: %m"); - - if (route->lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) { - r = sd_event_add_time(link->manager->event, &expire, - clock_boottime_or_monotonic(), - route->lifetime, 0, route_expire_handler, route); - if (r < 0) - log_link_warning_errno(link, r, "Could not arm route expiration handler: %m"); - } - - sd_event_source_unref(route->expire); - route->expire = TAKE_PTR(expire); - } + r = link_deserialize_routes(link, routes); + if (r < 0) + log_link_warning_errno(link, r, "Failed to load routes from %s, ignoring: %m", link->state_file); if (dhcp4_address) { r = in_addr_from_string(AF_INET, dhcp4_address, &address); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 87006a6c44..0ac6ccd794 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1234,6 +1234,72 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma return 1; } +int link_deserialize_routes(Link *link, const char *routes) { + int r; + + assert(link); + + for (const char *p = routes;; ) { + _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL; + _cleanup_(route_freep) Route *tmp = NULL; + _cleanup_free_ char *route_str = NULL; + char *prefixlen_str; + Route *route; + + r = extract_first_word(&p, &route_str, NULL, 0); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to parse ROUTES=: %m"); + if (r == 0) + return 0; + + prefixlen_str = strchr(route_str, '/'); + if (!prefixlen_str) { + log_link_debug(link, "Failed to parse route, ignoring: %s", route_str); + continue; + } + *prefixlen_str++ = '\0'; + + r = route_new(&tmp); + if (r < 0) + return log_oom(); + + r = sscanf(prefixlen_str, + "%hhu/%hhu/%"SCNu32"/%"PRIu32"/"USEC_FMT, + &tmp->dst_prefixlen, + &tmp->tos, + &tmp->priority, + &tmp->table, + &tmp->lifetime); + if (r != 5) { + log_link_debug(link, + "Failed to parse destination prefix length, tos, priority, table or expiration: %s", + prefixlen_str); + continue; + } + + r = in_addr_from_string_auto(route_str, &tmp->family, &tmp->dst); + if (r < 0) { + log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str); + continue; + } + + r = route_add(link, tmp, &route); + if (r < 0) + return log_link_debug_errno(link, r, "Failed to add route: %m"); + + if (route->lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) { + r = sd_event_add_time(link->manager->event, &expire, + clock_boottime_or_monotonic(), + route->lifetime, 0, route_expire_handler, route); + if (r < 0) + log_link_debug_errno(link, r, "Could not arm route expiration handler: %m"); + } + + sd_event_source_unref(route->expire); + route->expire = TAKE_PTR(expire); + } +} + int network_add_ipv4ll_route(Network *network) { _cleanup_(route_free_or_set_invalidp) Route *n = NULL; int r; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index d5760a96a6..02b7c1b3ad 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -74,6 +74,7 @@ int route_remove(Route *route, Link *link, link_netlink_message_handler_t callba int link_set_routes(Link *link); int link_drop_routes(Link *link); int link_drop_foreign_routes(Link *link); +int link_deserialize_routes(Link *link, const char *routes); int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);