From: Yu Watanabe Date: Fri, 5 Jan 2024 20:08:40 +0000 (+0900) Subject: network/route: move several conf parsers to networkd-route-metric.c and networkd... X-Git-Tag: v256-rc1~1247^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=df8767fc8d8824ffc0a6858de7647b3cc8ee5fa0;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/network/meson.build b/src/network/meson.build index 5f06948752b..2708b3a5bf4 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 ab11047f7e8..455ca8ee226 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 00000000000..194e53be397 --- /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 00000000000..a6ae425013d --- /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 00000000000..fbb8ee2d68d --- /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 00000000000..ae07696e5a7 --- /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 7c8461abb73..b8f1041dbdd 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 2e7f6290630..50753989679 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);