]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/route-metric: introduce RouteMetric
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 7 Jan 2024 01:35:07 +0000 (10:35 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 7 Jan 2024 05:04:00 +0000 (14:04 +0900)
Then, split out route metric handling from networkd-route.c to
networkd-route-metric.c.

No functional change, just refactoring and preparation for later
commits.

src/network/networkd-dhcp4.c
src/network/networkd-json.c
src/network/networkd-ndisc.c
src/network/networkd-route-metric.c
src/network/networkd-route-metric.h
src/network/networkd-route.c
src/network/networkd-route.h

index 8aee30e7266435f7f9ec4b7bfc41945caa28a739..4fada25a9c2bbabde3fda4e047ac9943068f62b0 100644 (file)
@@ -380,14 +380,14 @@ static int dhcp4_request_route(Route *in, Link *link) {
                 route->priority = link->network->dhcp_route_metric;
         if (!route->table_set)
                 route->table = link_get_dhcp4_route_table(link);
-        if (route->mtu == 0)
-                route->mtu = link->network->dhcp_route_mtu;
-        if (route->quickack < 0)
-                route->quickack = link->network->dhcp_quickack;
-        if (route->initcwnd == 0)
-                route->initcwnd = link->network->dhcp_initial_congestion_window;
-        if (route->initrwnd == 0)
-                route->initrwnd = link->network->dhcp_advertised_receive_window;
+        if (route->metric.mtu == 0)
+                route->metric.mtu = link->network->dhcp_route_mtu;
+        if (route->metric.quickack < 0)
+                route->metric.quickack = link->network->dhcp_quickack;
+        if (route->metric.initcwnd == 0)
+                route->metric.initcwnd = link->network->dhcp_initial_congestion_window;
+        if (route->metric.initrwnd == 0)
+                route->metric.initrwnd = link->network->dhcp_advertised_receive_window;
 
         if (route_get(NULL, link, route, &existing) < 0) /* This is a new route. */
                 link->dhcp4_configured = false;
index d972588b3ea0d5017ad8d93634ebb4699da7da0b..7b703bdfef39a9d9569a4736dede6f24fd286f40 100644 (file)
@@ -251,7 +251,7 @@ static int route_append_json(Route *route, JsonVariant **array) {
                                 JSON_BUILD_PAIR_UNSIGNED("Priority", route->priority),
                                 JSON_BUILD_PAIR_UNSIGNED("Table", route->table),
                                 JSON_BUILD_PAIR_STRING("TableString", table),
-                                JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("MTU", route->mtu),
+                                JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("MTU", route->metric.mtu),
                                 JSON_BUILD_PAIR_UNSIGNED("Preference", route->pref),
                                 JSON_BUILD_PAIR_UNSIGNED("Flags", route->flags),
                                 JSON_BUILD_PAIR_STRING("FlagsString", strempty(flags)),
index 369e205a99a229b49c346772c1ac8a1dac761bf3..ee9e2448f35aa6cdd9f3e87efdd90e02515ae6ec 100644 (file)
@@ -208,12 +208,12 @@ static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
         ndisc_set_route_priority(link, route);
         if (!route->protocol_set)
                 route->protocol = RTPROT_RA;
-        if (route->quickack < 0)
-                route->quickack = link->network->ipv6_accept_ra_quickack;
-        if (route->mtu == 0)
-                route->mtu = mtu;
-        if (route->hop_limit == 0)
-                route->hop_limit = hop_limit;
+        if (route->metric.quickack < 0)
+                route->metric.quickack = link->network->ipv6_accept_ra_quickack;
+        if (route->metric.mtu == 0)
+                route->metric.mtu = mtu;
+        if (route->metric.hop_limit == 0)
+                route->metric.hop_limit = hop_limit;
 
         is_new = route_get(NULL, link, route, NULL) < 0;
 
index a0fb40fd26d8a969b60110091da85b900e9cdd37..4c74a5d792b9a7c6fab6fed96bf5957e75e37f2c 100644 (file)
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include "alloc-util.h"
+#include "netlink-util.h"
 #include "networkd-route.h"
 #include "networkd-route-metric.h"
 #include "parse-util.h"
 #include "string-util.h"
 
+void route_metric_done(RouteMetric *metric) {
+        assert(metric);
+
+        free(metric->tcp_congestion_control_algo);
+}
+
+int route_metric_copy(const RouteMetric *src, RouteMetric *dest) {
+        assert(src);
+        assert(dest);
+
+        dest->quickack = src->quickack;
+        dest->fast_open_no_cookie = src->fast_open_no_cookie;
+        dest->mtu = src->mtu;
+        dest->initcwnd = src->initcwnd;
+        dest->initrwnd = src->initrwnd;
+        dest->advmss = src->advmss;
+        dest->hop_limit = src->hop_limit;
+        dest->tcp_rto_usec = src->tcp_rto_usec;
+
+        return free_and_strdup(&dest->tcp_congestion_control_algo, src->tcp_congestion_control_algo);
+}
+
+void route_metric_hash_func(const RouteMetric *metric, struct siphash *state) {
+        assert(metric);
+
+        siphash24_compress_typesafe(metric->initcwnd, state);
+        siphash24_compress_typesafe(metric->initrwnd, state);
+        siphash24_compress_typesafe(metric->advmss, state);
+}
+
+int route_metric_compare_func(const RouteMetric *a, const RouteMetric *b) {
+        int r;
+
+        assert(a);
+        assert(b);
+
+        r = CMP(a->initcwnd, b->initcwnd);
+        if (r != 0)
+                return r;
+
+        r = CMP(a->initrwnd, b->initrwnd);
+        if (r != 0)
+                return r;
+
+        return CMP(a->advmss, b->advmss);
+}
+
+int route_metric_set_netlink_message(const RouteMetric *metric, sd_netlink_message *m) {
+        int r;
+
+        assert(metric);
+        assert(m);
+
+        r = sd_netlink_message_open_container(m, RTA_METRICS);
+        if (r < 0)
+                return r;
+
+        if (metric->mtu > 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_MTU, metric->mtu);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->initcwnd > 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_INITCWND, metric->initcwnd);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->initrwnd > 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_INITRWND, metric->initrwnd);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->quickack >= 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_QUICKACK, metric->quickack);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->fast_open_no_cookie >= 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_FASTOPEN_NO_COOKIE, metric->fast_open_no_cookie);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->advmss > 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_ADVMSS, metric->advmss);
+                if (r < 0)
+                        return r;
+        }
+
+        if (!isempty(metric->tcp_congestion_control_algo)) {
+                r = sd_netlink_message_append_string(m, RTAX_CC_ALGO, metric->tcp_congestion_control_algo);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->hop_limit > 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_HOPLIMIT, metric->hop_limit);
+                if (r < 0)
+                        return r;
+        }
+
+        if (metric->tcp_rto_usec > 0) {
+                r = sd_netlink_message_append_u32(m, RTAX_RTO_MIN, DIV_ROUND_UP(metric->tcp_rto_usec, USEC_PER_MSEC));
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_netlink_message_close_container(m);
+        if (r < 0)
+                return r;
+
+        return 0;
+}
+
+int route_metric_read_netlink_message(RouteMetric *metric, sd_netlink_message *m) {
+        int r;
+
+        assert(metric);
+        assert(m);
+
+        r = sd_netlink_message_enter_container(m, RTA_METRICS);
+        if (r == -ENODATA)
+                return 0;
+        if (r < 0)
+                return log_warning_errno(r, "rtnl: Could not enter RTA_METRICS container, ignoring: %m");
+
+        r = sd_netlink_message_read_u32(m, RTAX_INITCWND, &metric->initcwnd);
+        if (r < 0 && r != -ENODATA)
+                return log_warning_errno(r, "rtnl: received route message with invalid initcwnd, ignoring: %m");
+
+        r = sd_netlink_message_read_u32(m, RTAX_INITRWND, &metric->initrwnd);
+        if (r < 0 && r != -ENODATA)
+                return log_warning_errno(r, "rtnl: received route message with invalid initrwnd, ignoring: %m");
+
+        r = sd_netlink_message_read_u32(m, RTAX_ADVMSS, &metric->advmss);
+        if (r < 0 && r != -ENODATA)
+                return log_warning_errno(r, "rtnl: received route message with invalid advmss, ignoring: %m");
+
+        r = sd_netlink_message_exit_container(m);
+        if (r < 0)
+                return log_warning_errno(r, "rtnl: Could not exit from RTA_METRICS container, ignoring: %m");
+
+        return 0;
+}
+
 int config_parse_route_metric_mtu(
                 const char *unit,
                 const char *filename,
@@ -36,7 +187,7 @@ int config_parse_route_metric_mtu(
                 return 0;
         }
 
-        r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, AF_UNSPEC, rvalue, &route->mtu, userdata);
+        r = config_parse_mtu(unit, filename, line, section, section_line, lvalue, AF_UNSPEC, rvalue, &route->metric.mtu, userdata);
         if (r <= 0)
                 return r;
 
@@ -77,7 +228,7 @@ int config_parse_route_metric_advmss(
         }
 
         if (isempty(rvalue)) {
-                route->advmss = 0;
+                route->metric.advmss = 0;
                 TAKE_PTR(route);
                 return 0;
         }
@@ -95,7 +246,7 @@ int config_parse_route_metric_advmss(
                 return 0;
         }
 
-        route->advmss = u;
+        route->metric.advmss = u;
 
         TAKE_PTR(route);
         return 0;
@@ -134,7 +285,7 @@ int config_parse_route_metric_hop_limit(
         }
 
         if (isempty(rvalue)) {
-                route->hop_limit = 0;
+                route->metric.hop_limit = 0;
                 TAKE_PTR(route);
                 return 0;
         }
@@ -151,7 +302,7 @@ int config_parse_route_metric_hop_limit(
                 return 0;
         }
 
-        route->hop_limit = k;
+        route->metric.hop_limit = k;
 
         TAKE_PTR(route);
         return 0;
@@ -228,9 +379,9 @@ int config_parse_route_metric_tcp_window(
         }
 
         if (streq(lvalue, "InitialCongestionWindow"))
-                d = &route->initcwnd;
+                d = &route->metric.initcwnd;
         else if (streq(lvalue, "InitialAdvertisedReceiveWindow"))
-                d = &route->initrwnd;
+                d = &route->metric.initrwnd;
         else
                 assert_not_reached();
 
@@ -288,7 +439,7 @@ int config_parse_route_metric_tcp_rto(
                 return 0;
         }
 
-        route->tcp_rto_usec = usec;
+        route->metric.tcp_rto_usec = usec;
 
         TAKE_PTR(route);
         return 0;
@@ -333,9 +484,9 @@ int config_parse_route_metric_boolean(
         }
 
         if (streq(lvalue, "QuickAck"))
-                route->quickack = r;
+                route->metric.quickack = r;
         else if (streq(lvalue, "FastOpenNoCookie"))
-                route->fast_open_no_cookie = r;
+                route->metric.fast_open_no_cookie = r;
         else
                 assert_not_reached();
 
@@ -375,7 +526,7 @@ int config_parse_route_metric_tcp_congestion(
         }
 
         r = config_parse_string(unit, filename, line, section, section_line, lvalue, 0,
-                                rvalue, &route->tcp_congestion_control_algo, userdata);
+                                rvalue, &route->metric.tcp_congestion_control_algo, userdata);
         if (r < 0)
                 return r;
 
index ba8b7bb6c8dfce49a433736110bbc278452dae18..8f447f6e811e92cdbc89b84d6e41c63181693468 100644 (file)
@@ -1,7 +1,40 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "sd-netlink.h"
+
 #include "conf-parser.h"
+#include "hash-funcs.h"
+
+typedef struct RouteMetric {
+        int quickack;
+        int fast_open_no_cookie;
+        uint32_t mtu;
+        uint32_t initcwnd;
+        uint32_t initrwnd;
+        uint32_t advmss;
+        uint32_t hop_limit;
+        char *tcp_congestion_control_algo;
+        usec_t tcp_rto_usec;
+} RouteMetric;
+
+#define ROUTE_METRIC_NULL                       \
+        ((const RouteMetric) {                  \
+                .quickack = -1,                 \
+                .fast_open_no_cookie = -1,      \
+        })
+
+void route_metric_done(RouteMetric *metric);
+int route_metric_copy(const RouteMetric *src, RouteMetric *dest);
+
+void route_metric_hash_func(const RouteMetric *metric, struct siphash *state);
+int route_metric_compare_func(const RouteMetric *a, const RouteMetric *b);
+
+int route_metric_set_netlink_message(const RouteMetric *metric, sd_netlink_message *m);
+int route_metric_read_netlink_message(RouteMetric *metric, sd_netlink_message *message);
 
 CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_mtu);
 CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_advmss);
index b8f1041dbdd409a635232cec09f5a2f77058b655..4fe2bd49bd71d8a6196995e5c86e19dc1ce203de 100644 (file)
@@ -35,8 +35,7 @@ int route_new(Route **ret) {
                 .type = RTN_UNICAST,
                 .table = RT_TABLE_MAIN,
                 .lifetime_usec = USEC_INFINITY,
-                .quickack = -1,
-                .fast_open_no_cookie = -1,
+                .metric = ROUTE_METRIC_NULL,
                 .gateway_onlink = -1,
         };
 
@@ -103,11 +102,9 @@ Route *route_free(Route *route) {
                 set_remove(route->manager->routes, route);
 
         ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free);
-
+        route_metric_done(&route->metric);
         sd_event_source_disable_unref(route->expire);
 
-        free(route->tcp_congestion_control_algo);
-
         return mfree(route);
 }
 
@@ -139,11 +136,7 @@ static void route_hash_func(const Route *route, struct siphash *state) {
                 siphash24_compress_typesafe(route->protocol, state);
                 siphash24_compress_typesafe(route->scope, state);
                 siphash24_compress_typesafe(route->type, state);
-
-                siphash24_compress_typesafe(route->initcwnd, state);
-                siphash24_compress_typesafe(route->initrwnd, state);
-
-                siphash24_compress_typesafe(route->advmss, state);
+                route_metric_hash_func(&route->metric, state);
                 siphash24_compress_typesafe(route->nexthop_id, state);
 
                 break;
@@ -221,15 +214,7 @@ static int route_compare_func(const Route *a, const Route *b) {
                 if (r != 0)
                         return r;
 
-                r = CMP(a->initcwnd, b->initcwnd);
-                if (r != 0)
-                        return r;
-
-                r = CMP(a->initrwnd, b->initrwnd);
-                if (r != 0)
-                        return r;
-
-                r = CMP(a->advmss, b->advmss);
+                r = route_metric_compare_func(&a->metric, &b->metric);
                 if (r != 0)
                         return r;
 
@@ -337,10 +322,10 @@ int route_dup(const Route *src, Route **ret) {
         dest->link = NULL;
         dest->manager = NULL;
         dest->multipath_routes = NULL;
+        dest->metric = ROUTE_METRIC_NULL;
         dest->expire = NULL;
-        dest->tcp_congestion_control_algo = NULL;
 
-        r = free_and_strdup(&dest->tcp_congestion_control_algo, src->tcp_congestion_control_algo);
+        r = route_metric_copy(&src->metric, &dest->metric);
         if (r < 0)
                 return r;
 
@@ -1187,65 +1172,8 @@ static int route_configure(const Route *route, uint32_t lifetime_sec, Link *link
                         return r;
         }
 
-        r = sd_netlink_message_open_container(m, RTA_METRICS);
-        if (r < 0)
-                return r;
-
-        if (route->mtu > 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_MTU, route->mtu);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->initcwnd > 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_INITCWND, route->initcwnd);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->initrwnd > 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_INITRWND, route->initrwnd);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->quickack >= 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_QUICKACK, route->quickack);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->fast_open_no_cookie >= 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_FASTOPEN_NO_COOKIE, route->fast_open_no_cookie);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->advmss > 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_ADVMSS, route->advmss);
-                if (r < 0)
-                        return r;
-        }
-
-        if (!isempty(route->tcp_congestion_control_algo)) {
-                r = sd_netlink_message_append_string(m, RTAX_CC_ALGO, route->tcp_congestion_control_algo);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->hop_limit > 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_HOPLIMIT, route->hop_limit);
-                if (r < 0)
-                        return r;
-        }
-
-        if (route->tcp_rto_usec > 0) {
-                r = sd_netlink_message_append_u32(m, RTAX_RTO_MIN, DIV_ROUND_UP(route->tcp_rto_usec, USEC_PER_MSEC));
-                if (r < 0)
-                        return r;
-        }
-
-        r = sd_netlink_message_close_container(m);
+        /* metrics */
+        r = route_metric_set_netlink_message(&route->metric, m);
         if (r < 0)
                 return r;
 
@@ -1851,36 +1779,9 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma
                 return 0;
         }
 
-        r = sd_netlink_message_enter_container(message, RTA_METRICS);
-        if (r < 0 && r != -ENODATA) {
-                log_link_error_errno(link, r, "rtnl: Could not enter RTA_METRICS container, ignoring: %m");
+        /* metrics */
+        if (route_metric_read_netlink_message(&tmp->metric, message) < 0)
                 return 0;
-        }
-        if (r >= 0) {
-                r = sd_netlink_message_read_u32(message, RTAX_INITCWND, &tmp->initcwnd);
-                if (r < 0 && r != -ENODATA) {
-                        log_link_warning_errno(link, r, "rtnl: received route message with invalid initcwnd, ignoring: %m");
-                        return 0;
-                }
-
-                r = sd_netlink_message_read_u32(message, RTAX_INITRWND, &tmp->initrwnd);
-                if (r < 0 && r != -ENODATA) {
-                        log_link_warning_errno(link, r, "rtnl: received route message with invalid initrwnd, ignoring: %m");
-                        return 0;
-                }
-
-                r = sd_netlink_message_read_u32(message, RTAX_ADVMSS, &tmp->advmss);
-                if (r < 0 && r != -ENODATA) {
-                        log_link_warning_errno(link, r, "rtnl: received route message with invalid advmss, ignoring: %m");
-                        return 0;
-                }
-
-                r = sd_netlink_message_exit_container(message);
-                if (r < 0) {
-                        log_link_error_errno(link, r, "rtnl: Could not exit from RTA_METRICS container, ignoring: %m");
-                        return 0;
-                }
-        }
 
         r = sd_netlink_message_read_data(message, RTA_MULTIPATH, &rta_len, &rta_multipath);
         if (r < 0 && r != -ENODATA) {
index 5075398967954e60c57f2f523be1cadd18b0c28e..33d1e643cc49e92ae6cf36045d8bbedf028a44d7 100644 (file)
@@ -36,8 +36,6 @@ struct Route {
         int family;
         int gw_family;
         uint32_t gw_weight;
-        int quickack;
-        int fast_open_no_cookie;
 
         unsigned char dst_prefixlen;
         unsigned char src_prefixlen;
@@ -47,17 +45,13 @@ struct Route {
         unsigned char tos;
         uint32_t priority; /* note that ip(8) calls this 'metric' */
         uint32_t table;
-        uint32_t mtu;
-        uint32_t initcwnd;
-        uint32_t initrwnd;
-        uint32_t advmss;
-        uint32_t hop_limit;
-        char *tcp_congestion_control_algo;
         unsigned char pref;
         unsigned flags;
         int gateway_onlink; /* Only used in conf parser and route_section_verify(). */
         uint32_t nexthop_id;
-        usec_t tcp_rto_usec;
+
+        /* metrics (RTA_METRICS) */
+        RouteMetric metric;
 
         bool scope_set:1;
         bool table_set:1;