From d2bec2426fa938fc12f8a679341cae48241ff512 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Jan 2024 05:23:06 +0900 Subject: [PATCH 1/5] network/route: do not invalidate [Route] section when an empty string is assigned to MultiPathRoute= --- src/network/networkd-route.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index abaea4e6c3..0d2765ccf8 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -2905,6 +2905,7 @@ int config_parse_multipath_route( if (isempty(rvalue)) { n->multipath_routes = ordered_set_free_with_destructor(n->multipath_routes, multipath_route_free); + TAKE_PTR(n); return 0; } From f48e52bda8eff38d5ae91168c1e02fbd4b53bd41 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Jan 2024 04:44:40 +0900 Subject: [PATCH 2/5] network/route: rename n -> route in conf parsers --- src/network/networkd-route.c | 260 +++++++++++++++++------------------ 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 0d2765ccf8..7c8461abb7 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1930,7 +1930,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma } int network_add_ipv4ll_route(Network *network) { - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; unsigned section_line; int r; @@ -1944,28 +1944,28 @@ int network_add_ipv4ll_route(Network *network) { return r; /* IPv4LLRoute= is in [Network] section. */ - r = route_new_static(network, network->filename, section_line, &n); + r = route_new_static(network, network->filename, section_line, &route); if (r < 0) return r; - r = in_addr_from_string(AF_INET, "169.254.0.0", &n->dst); + r = in_addr_from_string(AF_INET, "169.254.0.0", &route->dst); if (r < 0) return r; - n->family = AF_INET; - n->dst_prefixlen = 16; - n->scope = RT_SCOPE_LINK; - n->scope_set = true; - n->table_set = true; - n->priority = IPV4LL_ROUTE_METRIC; - n->protocol = RTPROT_STATIC; + route->family = AF_INET; + route->dst_prefixlen = 16; + route->scope = RT_SCOPE_LINK; + route->scope_set = true; + route->table_set = true; + route->priority = IPV4LL_ROUTE_METRIC; + route->protocol = RTPROT_STATIC; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } int network_add_default_route_on_device(Network *network) { - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; unsigned section_line; int r; @@ -1979,16 +1979,16 @@ int network_add_default_route_on_device(Network *network) { return r; /* DefaultRouteOnDevice= is in [Network] section. */ - r = route_new_static(network, network->filename, section_line, &n); + r = route_new_static(network, network->filename, section_line, &route); if (r < 0) return r; - n->family = AF_INET; - n->scope = RT_SCOPE_LINK; - n->scope_set = true; - n->protocol = RTPROT_STATIC; + route->family = AF_INET; + route->scope = RT_SCOPE_LINK; + route->scope_set = true; + route->protocol = RTPROT_STATIC; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2005,7 +2005,7 @@ int config_parse_gateway( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2016,7 +2016,7 @@ int config_parse_gateway( if (streq(section, "Network")) { /* we are not in an Route section, so use line number instead */ - r = route_new_static(network, filename, line, &n); + r = route_new_static(network, filename, line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2025,7 +2025,7 @@ int config_parse_gateway( return 0; } } else { - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2035,43 +2035,43 @@ int config_parse_gateway( } if (isempty(rvalue)) { - n->gateway_from_dhcp_or_ra = false; - n->gw_family = AF_UNSPEC; - n->gw = IN_ADDR_NULL; - TAKE_PTR(n); + route->gateway_from_dhcp_or_ra = false; + route->gw_family = AF_UNSPEC; + route->gw = IN_ADDR_NULL; + TAKE_PTR(route); return 0; } if (streq(rvalue, "_dhcp")) { - n->gateway_from_dhcp_or_ra = true; - TAKE_PTR(n); + route->gateway_from_dhcp_or_ra = true; + TAKE_PTR(route); return 0; } if (streq(rvalue, "_dhcp4")) { - n->gw_family = AF_INET; - n->gateway_from_dhcp_or_ra = true; - TAKE_PTR(n); + route->gw_family = AF_INET; + route->gateway_from_dhcp_or_ra = true; + TAKE_PTR(route); return 0; } if (streq(rvalue, "_ipv6ra")) { - n->gw_family = AF_INET6; - n->gateway_from_dhcp_or_ra = true; - TAKE_PTR(n); + route->gw_family = AF_INET6; + route->gateway_from_dhcp_or_ra = true; + TAKE_PTR(route); return 0; } } - r = in_addr_from_string_auto(rvalue, &n->gw_family, &n->gw); + r = in_addr_from_string_auto(rvalue, &route->gw_family, &route->gw); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue); return 0; } - n->gateway_from_dhcp_or_ra = false; - TAKE_PTR(n); + route->gateway_from_dhcp_or_ra = false; + TAKE_PTR(route); return 0; } @@ -2088,7 +2088,7 @@ int config_parse_preferred_src( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2097,7 +2097,7 @@ int config_parse_preferred_src( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2106,17 +2106,17 @@ int config_parse_preferred_src( return 0; } - if (n->family == AF_UNSPEC) - r = in_addr_from_string_auto(rvalue, &n->family, &n->prefsrc); + if (route->family == AF_UNSPEC) + r = in_addr_from_string_auto(rvalue, &route->family, &route->prefsrc); else - r = in_addr_from_string(n->family, rvalue, &n->prefsrc); + r = in_addr_from_string(route->family, rvalue, &route->prefsrc); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue); return 0; } - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2133,7 +2133,7 @@ int config_parse_destination( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; union in_addr_union *buffer; unsigned char *prefixlen; int r; @@ -2144,7 +2144,7 @@ int config_parse_destination( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2154,27 +2154,27 @@ int config_parse_destination( } if (streq(lvalue, "Destination")) { - buffer = &n->dst; - prefixlen = &n->dst_prefixlen; + buffer = &route->dst; + prefixlen = &route->dst_prefixlen; } else if (streq(lvalue, "Source")) { - buffer = &n->src; - prefixlen = &n->src_prefixlen; + buffer = &route->src; + prefixlen = &route->src_prefixlen; } else assert_not_reached(); - if (n->family == AF_UNSPEC) - r = in_addr_prefix_from_string_auto(rvalue, &n->family, buffer, prefixlen); + if (route->family == AF_UNSPEC) + r = in_addr_prefix_from_string_auto(rvalue, &route->family, buffer, prefixlen); else - r = in_addr_prefix_from_string(rvalue, n->family, buffer, prefixlen); + r = in_addr_prefix_from_string(rvalue, route->family, buffer, prefixlen); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue); return 0; } - (void) in_addr_mask(n->family, buffer, *prefixlen); + (void) in_addr_mask(route->family, buffer, *prefixlen); - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2191,7 +2191,7 @@ int config_parse_route_priority( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2200,7 +2200,7 @@ int config_parse_route_priority( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2209,15 +2209,15 @@ int config_parse_route_priority( return 0; } - r = safe_atou32(rvalue, &n->priority); + r = safe_atou32(rvalue, &route->priority); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Could not parse route priority \"%s\", ignoring assignment: %m", rvalue); return 0; } - n->priority_set = true; - TAKE_PTR(n); + route->priority_set = true; + TAKE_PTR(route); return 0; } @@ -2234,7 +2234,7 @@ int config_parse_route_scope( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2243,7 +2243,7 @@ int config_parse_route_scope( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2258,9 +2258,9 @@ int config_parse_route_scope( return 0; } - n->scope = r; - n->scope_set = true; - TAKE_PTR(n); + route->scope = r; + route->scope_set = true; + TAKE_PTR(route); return 0; } @@ -2277,7 +2277,7 @@ int config_parse_route_nexthop( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; uint32_t id; int r; @@ -2287,7 +2287,7 @@ int config_parse_route_nexthop( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2297,8 +2297,8 @@ int config_parse_route_nexthop( } if (isempty(rvalue)) { - n->nexthop_id = 0; - TAKE_PTR(n); + route->nexthop_id = 0; + TAKE_PTR(route); return 0; } @@ -2312,8 +2312,8 @@ int config_parse_route_nexthop( return 0; } - n->nexthop_id = id; - TAKE_PTR(n); + route->nexthop_id = id; + TAKE_PTR(route); return 0; } @@ -2329,7 +2329,7 @@ int config_parse_route_table( void *data, void *userdata) { - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; Network *network = userdata; int r; @@ -2339,7 +2339,7 @@ int config_parse_route_table( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2348,15 +2348,15 @@ int config_parse_route_table( return 0; } - r = manager_get_route_table_from_string(network->manager, rvalue, &n->table); + r = manager_get_route_table_from_string(network->manager, rvalue, &route->table); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Could not parse route table \"%s\", ignoring assignment: %m", rvalue); return 0; } - n->table_set = true; - TAKE_PTR(n); + route->table_set = true; + TAKE_PTR(route); return 0; } @@ -2373,7 +2373,7 @@ int config_parse_route_boolean( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2382,7 +2382,7 @@ int config_parse_route_boolean( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2399,15 +2399,15 @@ int config_parse_route_boolean( } if (STR_IN_SET(lvalue, "GatewayOnLink", "GatewayOnlink")) - n->gateway_onlink = r; + route->gateway_onlink = r; else if (streq(lvalue, "QuickAck")) - n->quickack = r; + route->quickack = r; else if (streq(lvalue, "FastOpenNoCookie")) - n->fast_open_no_cookie = r; + route->fast_open_no_cookie = r; else assert_not_reached(); - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2424,10 +2424,10 @@ int config_parse_ipv6_route_preference( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2437,18 +2437,18 @@ int config_parse_ipv6_route_preference( } if (streq(rvalue, "low")) - n->pref = ICMPV6_ROUTER_PREF_LOW; + route->pref = ICMPV6_ROUTER_PREF_LOW; else if (streq(rvalue, "medium")) - n->pref = ICMPV6_ROUTER_PREF_MEDIUM; + route->pref = ICMPV6_ROUTER_PREF_MEDIUM; else if (streq(rvalue, "high")) - n->pref = ICMPV6_ROUTER_PREF_HIGH; + route->pref = ICMPV6_ROUTER_PREF_HIGH; else { log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown route preference: %s", rvalue); return 0; } - n->pref_set = true; - TAKE_PTR(n); + route->pref_set = true; + TAKE_PTR(route); return 0; } @@ -2465,10 +2465,10 @@ int config_parse_route_protocol( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2484,9 +2484,9 @@ int config_parse_route_protocol( return 0; } - n->protocol = r; + route->protocol = r; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2503,10 +2503,10 @@ int config_parse_route_type( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int t, r; - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2522,9 +2522,9 @@ int config_parse_route_type( return 0; } - n->type = (unsigned char) t; + route->type = (unsigned char) t; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2540,7 +2540,7 @@ int config_parse_route_hop_limit( void *data, void *userdata) { - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; Network *network = userdata; uint32_t k; int r; @@ -2551,7 +2551,7 @@ int config_parse_route_hop_limit( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2561,8 +2561,8 @@ int config_parse_route_hop_limit( } if (isempty(rvalue)) { - n->hop_limit = 0; - TAKE_PTR(n); + route->hop_limit = 0; + TAKE_PTR(route); return 0; } @@ -2583,9 +2583,9 @@ int config_parse_route_hop_limit( return 0; } - n->hop_limit = k; + route->hop_limit = k; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2602,7 +2602,7 @@ int config_parse_tcp_congestion( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2611,7 +2611,7 @@ int config_parse_tcp_congestion( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2621,11 +2621,11 @@ int config_parse_tcp_congestion( } r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, - rvalue, &n->tcp_congestion_control_algo, userdata); + rvalue, &route->tcp_congestion_control_algo, userdata); if (r < 0) return r; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2641,7 +2641,7 @@ int config_parse_tcp_advmss( void *data, void *userdata) { - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; Network *network = userdata; uint64_t u; int r; @@ -2652,7 +2652,7 @@ int config_parse_tcp_advmss( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2662,8 +2662,8 @@ int config_parse_tcp_advmss( } if (isempty(rvalue)) { - n->advmss = 0; - TAKE_PTR(n); + route->advmss = 0; + TAKE_PTR(route); return 0; } @@ -2680,9 +2680,9 @@ int config_parse_tcp_advmss( return 0; } - n->advmss = u; + route->advmss = u; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2741,7 +2741,7 @@ int config_parse_route_tcp_window( void *data, void *userdata) { - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; Network *network = userdata; uint32_t *d; int r; @@ -2752,7 +2752,7 @@ int config_parse_route_tcp_window( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2762,9 +2762,9 @@ int config_parse_route_tcp_window( } if (streq(lvalue, "InitialCongestionWindow")) - d = &n->initcwnd; + d = &route->initcwnd; else if (streq(lvalue, "InitialAdvertisedReceiveWindow")) - d = &n->initrwnd; + d = &route->initrwnd; else assert_not_reached(); @@ -2772,7 +2772,7 @@ int config_parse_route_tcp_window( if (r < 0) return r; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2789,7 +2789,7 @@ int config_parse_route_mtu( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; int r; assert(filename); @@ -2798,7 +2798,7 @@ int config_parse_route_mtu( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2807,11 +2807,11 @@ int config_parse_route_mtu( return 0; } - r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &n->mtu, userdata); + r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &route->mtu, userdata); if (r <= 0) return r; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2828,7 +2828,7 @@ int config_parse_route_tcp_rto( void *userdata) { Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; usec_t usec; int r; @@ -2838,7 +2838,7 @@ int config_parse_route_tcp_rto( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2861,9 +2861,9 @@ int config_parse_route_tcp_rto( return 0; } - n->tcp_rto_usec = usec; + route->tcp_rto_usec = usec; - TAKE_PTR(n); + TAKE_PTR(route); return 0; } @@ -2880,7 +2880,7 @@ int config_parse_multipath_route( void *userdata) { _cleanup_(multipath_route_freep) MultipathRoute *m = NULL; - _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; _cleanup_free_ char *word = NULL; Network *network = userdata; union in_addr_union a; @@ -2894,7 +2894,7 @@ int config_parse_multipath_route( assert(rvalue); assert(data); - r = route_new_static(network, filename, section_line, &n); + r = route_new_static(network, filename, section_line, &route); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2904,8 +2904,8 @@ int config_parse_multipath_route( } if (isempty(rvalue)) { - n->multipath_routes = ordered_set_free_with_destructor(n->multipath_routes, multipath_route_free); - TAKE_PTR(n); + route->multipath_routes = ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free); + TAKE_PTR(route); return 0; } @@ -2971,7 +2971,7 @@ int config_parse_multipath_route( m->weight--; } - r = ordered_set_ensure_put(&n->multipath_routes, NULL, m); + r = ordered_set_ensure_put(&route->multipath_routes, NULL, m); if (r == -ENOMEM) return log_oom(); if (r < 0) { @@ -2981,7 +2981,7 @@ int config_parse_multipath_route( } TAKE_PTR(m); - TAKE_PTR(n); + TAKE_PTR(route); return 0; } From df8767fc8d8824ffc0a6858de7647b3cc8ee5fa0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Jan 2024 05:08:40 +0900 Subject: [PATCH 3/5] network/route: move several conf parsers to networkd-route-metric.c and networkd-route-nexthop.c This also split config_parse_route_boolean() into two: for GatewayOnline= and boolean route metrics. No functional change, just refactoring and preparation for later commits. --- src/network/meson.build | 4 +- src/network/networkd-network-gperf.gperf | 4 +- src/network/networkd-route-metric.c | 394 +++++++++++++++++ src/network/networkd-route-metric.h | 13 + src/network/networkd-route-nexthop.c | 182 ++++++++ src/network/networkd-route-nexthop.h | 7 + src/network/networkd-route.c | 523 +---------------------- src/network/networkd-route.h | 14 +- 8 files changed, 608 insertions(+), 533 deletions(-) create mode 100644 src/network/networkd-route-metric.c create mode 100644 src/network/networkd-route-metric.h create mode 100644 src/network/networkd-route-nexthop.c create mode 100644 src/network/networkd-route-nexthop.h diff --git a/src/network/meson.build b/src/network/meson.build index 5f06948752..2708b3a5bf 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -67,8 +67,10 @@ sources = files( 'networkd-nexthop.c', 'networkd-queue.c', 'networkd-radv.c', - 'networkd-route-util.c', 'networkd-route.c', + 'networkd-route-metric.c', + 'networkd-route-nexthop.c', + 'networkd-route-util.c', 'networkd-routing-policy-rule.c', 'networkd-setlink.c', 'networkd-speed-meter.c', diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index ab11047f7e..455ca8ee22 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -193,8 +193,8 @@ Route.Scope, config_parse_route_scope, Route.PreferredSource, config_parse_preferred_src, 0, 0 Route.Table, config_parse_route_table, 0, 0 Route.MTUBytes, config_parse_route_mtu, AF_UNSPEC, 0 -Route.GatewayOnLink, config_parse_route_boolean, 0, 0 -Route.GatewayOnlink, config_parse_route_boolean, 0, 0 +Route.GatewayOnLink, config_parse_route_gateway_onlink, 0, 0 +Route.GatewayOnlink, config_parse_route_gateway_onlink, 0, 0 Route.IPv6Preference, config_parse_ipv6_route_preference, 0, 0 Route.Protocol, config_parse_route_protocol, 0, 0 Route.Type, config_parse_route_type, 0, 0 diff --git a/src/network/networkd-route-metric.c b/src/network/networkd-route-metric.c new file mode 100644 index 0000000000..194e53be39 --- /dev/null +++ b/src/network/networkd-route-metric.c @@ -0,0 +1,394 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "networkd-route.h" +#include "networkd-route-metric.h" +#include "parse-util.h" +#include "string-util.h" + +int config_parse_route_mtu( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &route->mtu, userdata); + if (r <= 0) + return r; + + TAKE_PTR(route); + return 0; +} + +int config_parse_tcp_advmss( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + Network *network = userdata; + uint64_t u; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + if (isempty(rvalue)) { + route->advmss = 0; + TAKE_PTR(route); + return 0; + } + + r = parse_size(rvalue, 1024, &u); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Could not parse TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue); + return 0; + } + + if (u == 0 || u > UINT32_MAX) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue); + return 0; + } + + route->advmss = u; + + TAKE_PTR(route); + return 0; +} + +int config_parse_route_hop_limit( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + Network *network = userdata; + uint32_t k; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + if (isempty(rvalue)) { + route->hop_limit = 0; + TAKE_PTR(route); + return 0; + } + + r = safe_atou32(rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Could not parse per route hop limit, ignoring assignment: %s", rvalue); + return 0; + } + if (k > 255) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Specified per route hop limit \"%s\" is too large, ignoring assignment: %m", rvalue); + return 0; + } + if (k == 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid per route hop limit \"%s\", ignoring assignment: %m", rvalue); + return 0; + } + + route->hop_limit = k; + + TAKE_PTR(route); + return 0; +} + +int config_parse_tcp_window( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + uint32_t *window = ASSERT_PTR(data); + uint32_t k; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = safe_atou32(rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Could not parse TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue); + return 0; + } + if (k >= 1024) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Specified TCP %s \"%s\" is too large, ignoring assignment: %m", lvalue, rvalue); + return 0; + } + if (k == 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue); + return 0; + } + + *window = k; + return 0; +} + +int config_parse_route_tcp_window( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + Network *network = userdata; + uint32_t *d; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + if (streq(lvalue, "InitialCongestionWindow")) + d = &route->initcwnd; + else if (streq(lvalue, "InitialAdvertisedReceiveWindow")) + d = &route->initrwnd; + else + assert_not_reached(); + + r = config_parse_tcp_window(unit, filename, line, section, section_line, lvalue, ltype, rvalue, d, userdata); + if (r < 0) + return r; + + TAKE_PTR(route); + return 0; +} + +int config_parse_route_tcp_rto( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + usec_t usec; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + r = parse_sec(rvalue, &usec); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse route TCP retransmission timeout (RTO), ignoring assignment: %s", rvalue); + return 0; + } + + if (!timestamp_is_set(usec) || + DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Route TCP retransmission timeout (RTO) must be in the range 0…%"PRIu32"ms, ignoring assignment: %s", UINT32_MAX, rvalue); + return 0; + } + + route->tcp_rto_usec = usec; + + TAKE_PTR(route); + return 0; +} + +int config_parse_route_boolean( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + r = parse_boolean(rvalue); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Could not parse %s=\"%s\", ignoring assignment: %m", lvalue, rvalue); + return 0; + } + + if (streq(lvalue, "QuickAck")) + route->quickack = r; + else if (streq(lvalue, "FastOpenNoCookie")) + route->fast_open_no_cookie = r; + else + assert_not_reached(); + + TAKE_PTR(route); + return 0; +} + +int config_parse_tcp_congestion( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, + rvalue, &route->tcp_congestion_control_algo, userdata); + if (r < 0) + return r; + + TAKE_PTR(route); + return 0; +} diff --git a/src/network/networkd-route-metric.h b/src/network/networkd-route-metric.h new file mode 100644 index 0000000000..a6ae425013 --- /dev/null +++ b/src/network/networkd-route-metric.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "conf-parser.h" + +CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu); +CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss); +CONFIG_PARSER_PROTOTYPE(config_parse_route_hop_limit); +CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_window); +CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_rto); +CONFIG_PARSER_PROTOTYPE(config_parse_route_boolean); +CONFIG_PARSER_PROTOTYPE(config_parse_tcp_congestion); +CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window); diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c new file mode 100644 index 0000000000..fbb8ee2d68 --- /dev/null +++ b/src/network/networkd-route-nexthop.c @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include + +#include "alloc-util.h" +#include "extract-word.h" +#include "netlink-util.h" +#include "networkd-route.h" +#include "networkd-route-nexthop.h" +#include "parse-util.h" +#include "string-util.h" + +int config_parse_route_nexthop( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *network = userdata; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + uint32_t id; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + if (isempty(rvalue)) { + route->nexthop_id = 0; + TAKE_PTR(route); + return 0; + } + + r = safe_atou32(rvalue, &id); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse nexthop ID, ignoring assignment: %s", rvalue); + return 0; + } + if (id == 0) { + log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid nexthop ID, ignoring assignment: %s", rvalue); + return 0; + } + + route->nexthop_id = id; + TAKE_PTR(route); + return 0; +} + +int config_parse_multipath_route( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(multipath_route_freep) MultipathRoute *m = NULL; + _cleanup_(route_free_or_set_invalidp) Route *route = NULL; + _cleanup_free_ char *word = NULL; + Network *network = userdata; + union in_addr_union a; + int family, r; + const char *p; + char *dev; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = route_new_static(network, filename, section_line, &route); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to allocate route, ignoring assignment: %m"); + return 0; + } + + if (isempty(rvalue)) { + route->multipath_routes = ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free); + TAKE_PTR(route); + return 0; + } + + m = new0(MultipathRoute, 1); + if (!m) + return log_oom(); + + p = rvalue; + r = extract_first_word(&p, &word, NULL, 0); + if (r == -ENOMEM) + return log_oom(); + if (r <= 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid multipath route option, ignoring assignment: %s", rvalue); + return 0; + } + + dev = strchr(word, '@'); + if (dev) { + *dev++ = '\0'; + + r = parse_ifindex(dev); + if (r > 0) + m->ifindex = r; + else { + if (!ifname_valid_full(dev, IFNAME_VALID_ALTERNATIVE)) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid interface name '%s' in %s=, ignoring: %s", dev, lvalue, rvalue); + return 0; + } + + m->ifname = strdup(dev); + if (!m->ifname) + return log_oom(); + } + } + + r = in_addr_from_string_auto(word, &family, &a); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue); + return 0; + } + m->gateway.address = a; + m->gateway.family = family; + + if (!isempty(p)) { + r = safe_atou32(p, &m->weight); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid multipath route weight, ignoring assignment: %s", p); + return 0; + } + /* ip command takes weight in the range 1…255, while kernel takes the value in the + * range 0…254. MultiPathRoute= setting also takes weight in the same range which ip + * command uses, then networkd decreases by one and stores it to match the range which + * kernel uses. */ + if (m->weight == 0 || m->weight > 256) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid multipath route weight, ignoring assignment: %s", p); + return 0; + } + m->weight--; + } + + r = ordered_set_ensure_put(&route->multipath_routes, NULL, m); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to store multipath route, ignoring assignment: %m"); + return 0; + } + + TAKE_PTR(m); + TAKE_PTR(route); + return 0; +} diff --git a/src/network/networkd-route-nexthop.h b/src/network/networkd-route-nexthop.h new file mode 100644 index 0000000000..ae07696e5a --- /dev/null +++ b/src/network/networkd-route-nexthop.h @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "conf-parser.h" + +CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop); +CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 7c8461abb7..b8f1041dbd 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -45,7 +45,7 @@ int route_new(Route **ret) { return 0; } -static int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) { +int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) { _cleanup_(config_section_freep) ConfigSection *n = NULL; _cleanup_(route_freep) Route *route = NULL; int r; @@ -2264,59 +2264,6 @@ int config_parse_route_scope( return 0; } -int config_parse_route_nexthop( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - uint32_t id; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - if (isempty(rvalue)) { - route->nexthop_id = 0; - TAKE_PTR(route); - return 0; - } - - r = safe_atou32(rvalue, &id); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse nexthop ID, ignoring assignment: %s", rvalue); - return 0; - } - if (id == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid nexthop ID, ignoring assignment: %s", rvalue); - return 0; - } - - route->nexthop_id = id; - TAKE_PTR(route); - return 0; -} - int config_parse_route_table( const char *unit, const char *filename, @@ -2360,7 +2307,7 @@ int config_parse_route_table( return 0; } -int config_parse_route_boolean( +int config_parse_route_gateway_onlink( const char *unit, const char *filename, unsigned line, @@ -2398,14 +2345,7 @@ int config_parse_route_boolean( return 0; } - if (STR_IN_SET(lvalue, "GatewayOnLink", "GatewayOnlink")) - route->gateway_onlink = r; - else if (streq(lvalue, "QuickAck")) - route->quickack = r; - else if (streq(lvalue, "FastOpenNoCookie")) - route->fast_open_no_cookie = r; - else - assert_not_reached(); + route->gateway_onlink = r; TAKE_PTR(route); return 0; @@ -2528,463 +2468,6 @@ int config_parse_route_type( return 0; } -int config_parse_route_hop_limit( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - Network *network = userdata; - uint32_t k; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - if (isempty(rvalue)) { - route->hop_limit = 0; - TAKE_PTR(route); - return 0; - } - - r = safe_atou32(rvalue, &k); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse per route hop limit, ignoring assignment: %s", rvalue); - return 0; - } - if (k > 255) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Specified per route hop limit \"%s\" is too large, ignoring assignment: %m", rvalue); - return 0; - } - if (k == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid per route hop limit \"%s\", ignoring assignment: %m", rvalue); - return 0; - } - - route->hop_limit = k; - - TAKE_PTR(route); - return 0; -} - -int config_parse_tcp_congestion( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, - rvalue, &route->tcp_congestion_control_algo, userdata); - if (r < 0) - return r; - - TAKE_PTR(route); - return 0; -} - -int config_parse_tcp_advmss( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - Network *network = userdata; - uint64_t u; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - if (isempty(rvalue)) { - route->advmss = 0; - TAKE_PTR(route); - return 0; - } - - r = parse_size(rvalue, 1024, &u); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue); - return 0; - } - - if (u == 0 || u > UINT32_MAX) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue); - return 0; - } - - route->advmss = u; - - TAKE_PTR(route); - return 0; -} - -int config_parse_tcp_window( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - uint32_t *window = ASSERT_PTR(data); - uint32_t k; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = safe_atou32(rvalue, &k); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue); - return 0; - } - if (k >= 1024) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Specified TCP %s \"%s\" is too large, ignoring assignment: %m", lvalue, rvalue); - return 0; - } - if (k == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue); - return 0; - } - - *window = k; - return 0; -} - -int config_parse_route_tcp_window( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - Network *network = userdata; - uint32_t *d; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - if (streq(lvalue, "InitialCongestionWindow")) - d = &route->initcwnd; - else if (streq(lvalue, "InitialAdvertisedReceiveWindow")) - d = &route->initrwnd; - else - assert_not_reached(); - - r = config_parse_tcp_window(unit, filename, line, section, section_line, lvalue, ltype, rvalue, d, userdata); - if (r < 0) - return r; - - TAKE_PTR(route); - return 0; -} - -int config_parse_route_mtu( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &route->mtu, userdata); - if (r <= 0) - return r; - - TAKE_PTR(route); - return 0; -} - -int config_parse_route_tcp_rto( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - Network *network = userdata; - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - usec_t usec; - int r; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - r = parse_sec(rvalue, &usec); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to parse route TCP retransmission timeout (RTO), ignoring assignment: %s", rvalue); - return 0; - } - - if (!timestamp_is_set(usec) || - DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Route TCP retransmission timeout (RTO) must be in the range 0…%"PRIu32"ms, ignoring assignment: %s", UINT32_MAX, rvalue); - return 0; - } - - route->tcp_rto_usec = usec; - - TAKE_PTR(route); - return 0; -} - -int config_parse_multipath_route( - const char *unit, - const char *filename, - unsigned line, - const char *section, - unsigned section_line, - const char *lvalue, - int ltype, - const char *rvalue, - void *data, - void *userdata) { - - _cleanup_(multipath_route_freep) MultipathRoute *m = NULL; - _cleanup_(route_free_or_set_invalidp) Route *route = NULL; - _cleanup_free_ char *word = NULL; - Network *network = userdata; - union in_addr_union a; - int family, r; - const char *p; - char *dev; - - assert(filename); - assert(section); - assert(lvalue); - assert(rvalue); - assert(data); - - r = route_new_static(network, filename, section_line, &route); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to allocate route, ignoring assignment: %m"); - return 0; - } - - if (isempty(rvalue)) { - route->multipath_routes = ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free); - TAKE_PTR(route); - return 0; - } - - m = new0(MultipathRoute, 1); - if (!m) - return log_oom(); - - p = rvalue; - r = extract_first_word(&p, &word, NULL, 0); - if (r == -ENOMEM) - return log_oom(); - if (r <= 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid multipath route option, ignoring assignment: %s", rvalue); - return 0; - } - - dev = strchr(word, '@'); - if (dev) { - *dev++ = '\0'; - - r = parse_ifindex(dev); - if (r > 0) - m->ifindex = r; - else { - if (!ifname_valid_full(dev, IFNAME_VALID_ALTERNATIVE)) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid interface name '%s' in %s=, ignoring: %s", dev, lvalue, rvalue); - return 0; - } - - m->ifname = strdup(dev); - if (!m->ifname) - return log_oom(); - } - } - - r = in_addr_from_string_auto(word, &family, &a); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue); - return 0; - } - m->gateway.address = a; - m->gateway.family = family; - - if (!isempty(p)) { - r = safe_atou32(p, &m->weight); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid multipath route weight, ignoring assignment: %s", p); - return 0; - } - /* ip command takes weight in the range 1…255, while kernel takes the value in the - * range 0…254. MultiPathRoute= setting also takes weight in the same range which ip - * command uses, then networkd decreases by one and stores it to match the range which - * kernel uses. */ - if (m->weight == 0 || m->weight > 256) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid multipath route weight, ignoring assignment: %s", p); - return 0; - } - m->weight--; - } - - r = ordered_set_ensure_put(&route->multipath_routes, NULL, m); - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to store multipath route, ignoring assignment: %m"); - return 0; - } - - TAKE_PTR(m); - TAKE_PTR(route); - return 0; -} - static int route_section_verify(Route *route, Network *network) { if (section_is_invalid(route->section)) return -EINVAL; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 2e7f629063..5075398967 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -9,6 +9,8 @@ #include "conf-parser.h" #include "in-addr-util.h" #include "networkd-link.h" +#include "networkd-route-metric.h" +#include "networkd-route-nexthop.h" #include "networkd-util.h" typedef struct Manager Manager; @@ -80,6 +82,7 @@ struct Route { extern const struct hash_ops route_hash_ops; int route_new(Route **ret); +int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret); Route *route_free(Route *route); DEFINE_SECTION_CLEANUP_FUNCTIONS(Route, route_free); int route_dup(const Route *src, Route **ret); @@ -119,16 +122,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_destination); CONFIG_PARSER_PROTOTYPE(config_parse_route_priority); CONFIG_PARSER_PROTOTYPE(config_parse_route_scope); CONFIG_PARSER_PROTOTYPE(config_parse_route_table); -CONFIG_PARSER_PROTOTYPE(config_parse_route_boolean); +CONFIG_PARSER_PROTOTYPE(config_parse_route_gateway_onlink); CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_route_preference); CONFIG_PARSER_PROTOTYPE(config_parse_route_protocol); CONFIG_PARSER_PROTOTYPE(config_parse_route_type); -CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_window); -CONFIG_PARSER_PROTOTYPE(config_parse_route_hop_limit); -CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window); -CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_rto); -CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu); -CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route); -CONFIG_PARSER_PROTOTYPE(config_parse_tcp_congestion); -CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss); -CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop); From e2126e235e4147293d809e699ddd4d9a003e5571 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Jan 2024 13:07:11 +0900 Subject: [PATCH 4/5] network/route-metric: pass attribute type to conf parsers The passed attribute type will be used later. This also - rename conf parsers, - sort gperf entries by the attr type. No functional change, just refactoring and preparation for later commits. --- src/network/networkd-network-gperf.gperf | 20 ++++++++++---------- src/network/networkd-route-metric.c | 18 +++++++++--------- src/network/networkd-route-metric.h | 14 +++++++------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 455ca8ee22..fd1f26c798 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -192,23 +192,23 @@ Route.Metric, config_parse_route_priority, Route.Scope, config_parse_route_scope, 0, 0 Route.PreferredSource, config_parse_preferred_src, 0, 0 Route.Table, config_parse_route_table, 0, 0 -Route.MTUBytes, config_parse_route_mtu, AF_UNSPEC, 0 Route.GatewayOnLink, config_parse_route_gateway_onlink, 0, 0 Route.GatewayOnlink, config_parse_route_gateway_onlink, 0, 0 Route.IPv6Preference, config_parse_ipv6_route_preference, 0, 0 Route.Protocol, config_parse_route_protocol, 0, 0 Route.Type, config_parse_route_type, 0, 0 -Route.TCPRetransmissionTimeoutSec, config_parse_route_tcp_rto, 0, 0 -Route.HopLimit, config_parse_route_hop_limit, 0, 0 -Route.InitialCongestionWindow, config_parse_route_tcp_window, 0, 0 -Route.InitialAdvertisedReceiveWindow, config_parse_route_tcp_window, 0, 0 -Route.TCPAdvertisedMaximumSegmentSize, config_parse_tcp_advmss, 0, 0 -Route.TCPCongestionControlAlgorithm, config_parse_tcp_congestion, 0, 0 -Route.QuickAck, config_parse_route_boolean, 0, 0 -Route.FastOpenNoCookie, config_parse_route_boolean, 0, 0 -Route.TTLPropagate, config_parse_warn_compat, DISABLED_LEGACY, 0 Route.MultiPathRoute, config_parse_multipath_route, 0, 0 Route.NextHop, config_parse_route_nexthop, 0, 0 +Route.MTUBytes, config_parse_route_metric_mtu, RTAX_MTU, 0 +Route.TCPAdvertisedMaximumSegmentSize, config_parse_route_metric_advmss, RTAX_ADVMSS, 0 +Route.HopLimit, config_parse_route_metric_hop_limit, RTAX_HOPLIMIT, 0 +Route.InitialCongestionWindow, config_parse_route_metric_tcp_window, RTAX_INITCWND, 0 +Route.TCPRetransmissionTimeoutSec, config_parse_route_metric_tcp_rto, RTAX_RTO_MIN, 0 +Route.InitialAdvertisedReceiveWindow, config_parse_route_metric_tcp_window, RTAX_INITRWND, 0 +Route.QuickAck, config_parse_route_metric_boolean, RTAX_QUICKACK, 0 +Route.TCPCongestionControlAlgorithm, config_parse_route_metric_tcp_congestion, RTAX_CC_ALGO, 0 +Route.FastOpenNoCookie, config_parse_route_metric_boolean, RTAX_FASTOPEN_NO_COOKIE, 0 +Route.TTLPropagate, config_parse_warn_compat, DISABLED_LEGACY, 0 NextHop.Id, config_parse_nexthop_id, 0, 0 NextHop.Gateway, config_parse_nexthop_gateway, 0, 0 NextHop.Family, config_parse_nexthop_family, 0, 0 diff --git a/src/network/networkd-route-metric.c b/src/network/networkd-route-metric.c index 194e53be39..2319447eb7 100644 --- a/src/network/networkd-route-metric.c +++ b/src/network/networkd-route-metric.c @@ -5,7 +5,7 @@ #include "parse-util.h" #include "string-util.h" -int config_parse_route_mtu( +int config_parse_route_metric_mtu( const char *unit, const char *filename, unsigned line, @@ -36,7 +36,7 @@ int config_parse_route_mtu( return 0; } - r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &route->mtu, userdata); + r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, AF_UNSPEC, rvalue, &route->mtu, userdata); if (r <= 0) return r; @@ -44,7 +44,7 @@ int config_parse_route_mtu( return 0; } -int config_parse_tcp_advmss( +int config_parse_route_metric_advmss( const char *unit, const char *filename, unsigned line, @@ -101,7 +101,7 @@ int config_parse_tcp_advmss( return 0; } -int config_parse_route_hop_limit( +int config_parse_route_metric_hop_limit( const char *unit, const char *filename, unsigned line, @@ -205,7 +205,7 @@ int config_parse_tcp_window( return 0; } -int config_parse_route_tcp_window( +int config_parse_route_metric_tcp_window( const char *unit, const char *filename, unsigned line, @@ -252,7 +252,7 @@ int config_parse_route_tcp_window( return 0; } -int config_parse_route_tcp_rto( +int config_parse_route_metric_tcp_rto( const char *unit, const char *filename, unsigned line, @@ -304,7 +304,7 @@ int config_parse_route_tcp_rto( return 0; } -int config_parse_route_boolean( +int config_parse_route_metric_boolean( const char *unit, const char *filename, unsigned line, @@ -353,7 +353,7 @@ int config_parse_route_boolean( return 0; } -int config_parse_tcp_congestion( +int config_parse_route_metric_tcp_congestion( const char *unit, const char *filename, unsigned line, @@ -384,7 +384,7 @@ int config_parse_tcp_congestion( return 0; } - r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, + r = config_parse_string(unit, filename, line, section, section_line, lvalue, 0, rvalue, &route->tcp_congestion_control_algo, userdata); if (r < 0) return r; diff --git a/src/network/networkd-route-metric.h b/src/network/networkd-route-metric.h index a6ae425013..ba8b7bb6c8 100644 --- a/src/network/networkd-route-metric.h +++ b/src/network/networkd-route-metric.h @@ -3,11 +3,11 @@ #include "conf-parser.h" -CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu); -CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss); -CONFIG_PARSER_PROTOTYPE(config_parse_route_hop_limit); -CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_window); -CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_rto); -CONFIG_PARSER_PROTOTYPE(config_parse_route_boolean); -CONFIG_PARSER_PROTOTYPE(config_parse_tcp_congestion); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_mtu); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_advmss); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_hop_limit); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_tcp_window); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_tcp_rto); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_boolean); +CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_tcp_congestion); CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window); From 5c64017aa8ba64dede32371e068e6fac772e176b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Jan 2024 05:36:48 +0900 Subject: [PATCH 5/5] network/route-metric: unify error messages --- src/network/networkd-route-metric.c | 32 ++++++++++------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/network/networkd-route-metric.c b/src/network/networkd-route-metric.c index 2319447eb7..a0fb40fd26 100644 --- a/src/network/networkd-route-metric.c +++ b/src/network/networkd-route-metric.c @@ -85,13 +85,13 @@ int config_parse_route_metric_advmss( r = parse_size(rvalue, 1024, &u); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue); + "Could not parse %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } if (u == 0 || u > UINT32_MAX) { log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue); + "Invalid %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } @@ -142,17 +142,12 @@ int config_parse_route_metric_hop_limit( r = safe_atou32(rvalue, &k); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse per route hop limit, ignoring assignment: %s", rvalue); + "Could not parse %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } - if (k > 255) { + if (k == 0 || k > 255) { log_syntax(unit, LOG_WARNING, filename, line, 0, - "Specified per route hop limit \"%s\" is too large, ignoring assignment: %m", rvalue); - return 0; - } - if (k == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid per route hop limit \"%s\", ignoring assignment: %m", rvalue); + "Invalid %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } @@ -187,17 +182,12 @@ int config_parse_tcp_window( r = safe_atou32(rvalue, &k); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue); + "Could not parse %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } - if (k >= 1024) { + if (k == 0 || k >= 1024) { log_syntax(unit, LOG_WARNING, filename, line, 0, - "Specified TCP %s \"%s\" is too large, ignoring assignment: %m", lvalue, rvalue); - return 0; - } - if (k == 0) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue); + "Invalid %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } @@ -287,14 +277,14 @@ int config_parse_route_metric_tcp_rto( r = parse_sec(rvalue, &usec); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to parse route TCP retransmission timeout (RTO), ignoring assignment: %s", rvalue); + "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } if (!timestamp_is_set(usec) || DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) { log_syntax(unit, LOG_WARNING, filename, line, 0, - "Route TCP retransmission timeout (RTO) must be in the range 0…%"PRIu32"ms, ignoring assignment: %s", UINT32_MAX, rvalue); + "Invalid %s=, ignoring assignment: %s", lvalue, rvalue); return 0; } @@ -338,7 +328,7 @@ int config_parse_route_metric_boolean( r = parse_boolean(rvalue); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, - "Could not parse %s=\"%s\", ignoring assignment: %m", lvalue, rvalue); + "Could not parse %s=, ignoring assignment: %s", lvalue, rvalue); return 0; }