]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: split networkd-route.[ch]
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 11 Nov 2021 04:16:46 +0000 (13:16 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 14 Nov 2021 05:41:37 +0000 (14:41 +0900)
src/network/meson.build
src/network/networkd-dhcp-server.c
src/network/networkd-gperf.gperf
src/network/networkd-nexthop.c
src/network/networkd-radv.c
src/network/networkd-route-util.c [new file with mode: 0644]
src/network/networkd-route-util.h [new file with mode: 0644]
src/network/networkd-route.c
src/network/networkd-route.h
src/network/networkd-routing-policy-rule.c
src/network/test-network.c

index dedfc90f4df322bc5cafbcbfb92936c68f3e568a..9247734c75c7c7a99dbb510750f9410e7b684d44 100644 (file)
@@ -115,6 +115,8 @@ sources = files('''
         networkd-nexthop.h
         networkd-queue.c
         networkd-queue.h
+        networkd-route-util.c
+        networkd-route-util.h
         networkd-route.c
         networkd-route.h
         networkd-routing-policy-rule.c
index 9fa0c4233c5363f54e61efb50cf63d3cd11664b6..9acfd17d493da182f4833acf113015ccb83ca898 100644 (file)
@@ -16,7 +16,7 @@
 #include "networkd-manager.h"
 #include "networkd-network.h"
 #include "networkd-queue.h"
-#include "networkd-route.h"
+#include "networkd-route-util.h"
 #include "parse-util.h"
 #include "socket-netlink.h"
 #include "string-table.h"
index 20c33e8c80f176de99cfec30467bec7848105592..8ed90f0e4b84a869703acf2e01ed636615b13dc6 100644 (file)
@@ -8,7 +8,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #include "networkd-conf.h"
 #include "networkd-dhcp-common.h"
 #include "networkd-manager.h"
-#include "networkd-route.h"
+#include "networkd-route-util.h"
 %}
 struct ConfigPerfItem;
 %null_strings
index 7ae43a00bd62fdb6f90f16d8d61929a6f072b8cc..f043754ea103208771b4c2be54dd75f5bce6c571 100644 (file)
@@ -12,7 +12,7 @@
 #include "networkd-network.h"
 #include "networkd-nexthop.h"
 #include "networkd-queue.h"
-#include "networkd-route.h"
+#include "networkd-route-util.h"
 #include "parse-util.h"
 #include "set.h"
 #include "stdio-util.h"
index 7b98251570a8f934f6207d7673e6e18d219ee595..c98528aee9d92dc7ef1b16ac86baaa7547823c07 100644 (file)
@@ -15,7 +15,7 @@
 #include "networkd-network.h"
 #include "networkd-queue.h"
 #include "networkd-radv.h"
-#include "networkd-route.h"
+#include "networkd-route-util.h"
 #include "parse-util.h"
 #include "radv-internal.h"
 #include "string-util.h"
diff --git a/src/network/networkd-route-util.c b/src/network/networkd-route-util.c
new file mode 100644 (file)
index 0000000..77e8c2b
--- /dev/null
@@ -0,0 +1,393 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <linux/rtnetlink.h>
+
+#include "alloc-util.h"
+#include "networkd-address.h"
+#include "networkd-link.h"
+#include "networkd-manager.h"
+#include "networkd-route-util.h"
+#include "networkd-route.h"
+#include "parse-util.h"
+#include "string-table.h"
+#include "string-util.h"
+#include "strv.h"
+#include "sysctl-util.h"
+
+#define ROUTES_DEFAULT_MAX_PER_FAMILY 4096U
+
+unsigned routes_max(void) {
+        static thread_local unsigned cached = 0;
+        _cleanup_free_ char *s4 = NULL, *s6 = NULL;
+        unsigned val4 = ROUTES_DEFAULT_MAX_PER_FAMILY, val6 = ROUTES_DEFAULT_MAX_PER_FAMILY;
+
+        if (cached > 0)
+                return cached;
+
+        if (sysctl_read_ip_property(AF_INET, NULL, "route/max_size", &s4) >= 0)
+                if (safe_atou(s4, &val4) >= 0 && val4 == 2147483647U)
+                        /* This is the default "no limit" value in the kernel */
+                        val4 = ROUTES_DEFAULT_MAX_PER_FAMILY;
+
+        if (sysctl_read_ip_property(AF_INET6, NULL, "route/max_size", &s6) >= 0)
+                (void) safe_atou(s6, &val6);
+
+        cached = MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val4) +
+                 MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val6);
+        return cached;
+}
+
+static Route *link_find_default_gateway(Link *link, int family, Route *gw) {
+        Route *route;
+
+        assert(link);
+
+        SET_FOREACH(route, link->routes) {
+                if (!route_exists(route))
+                        continue;
+                if (family != AF_UNSPEC && route->family != family)
+                        continue;
+                if (route->dst_prefixlen != 0)
+                        continue;
+                if (route->src_prefixlen != 0)
+                        continue;
+                if (route->table != RT_TABLE_MAIN)
+                        continue;
+                if (route->type != RTN_UNICAST)
+                        continue;
+                if (route->scope != RT_SCOPE_UNIVERSE)
+                        continue;
+                if (!in_addr_is_set(route->gw_family, &route->gw))
+                        continue;
+                if (gw) {
+                        if (route->gw_weight > gw->gw_weight)
+                                continue;
+                        if (route->priority >= gw->priority)
+                                continue;
+                }
+                gw = route;
+        }
+
+        return gw;
+}
+
+int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret) {
+        Route *gw = NULL;
+        Link *link;
+
+        assert(m);
+        assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
+
+        /* Looks for a suitable "uplink", via black magic: an interface that is up and where the
+         * default route with the highest priority points to. */
+
+        HASHMAP_FOREACH(link, m->links_by_index) {
+                if (link == exclude)
+                        continue;
+
+                if (link->state != LINK_STATE_CONFIGURED)
+                        continue;
+
+                gw = link_find_default_gateway(link, family, gw);
+        }
+
+        if (!gw)
+                return -ENOENT;
+
+        if (ret) {
+                assert(gw->link);
+                *ret = gw->link;
+        }
+
+        return 0;
+}
+
+static bool link_address_is_reachable(Link *link, int family, const union in_addr_union *address) {
+        Route *route;
+        Address *a;
+
+        assert(link);
+        assert(link->manager);
+        assert(IN_SET(family, AF_INET, AF_INET6));
+        assert(address);
+
+        SET_FOREACH(route, link->routes) {
+                if (!route_exists(route))
+                        continue;
+                if (route->family != family)
+                        continue;
+                if (!in_addr_is_set(route->family, &route->dst))
+                        continue;
+                if (in_addr_prefix_covers(family, &route->dst, route->dst_prefixlen, address) > 0)
+                        return true;
+        }
+
+        if (link->manager->manage_foreign_routes)
+                return false;
+
+        /* If we do not manage foreign routes, then there may exist a prefix route we do not know,
+         * which was created on configuring an address. Hence, also check the addresses. */
+        SET_FOREACH(a, link->addresses) {
+                if (!address_is_ready(a))
+                        continue;
+                if (a->family != family)
+                        continue;
+                if (FLAGS_SET(a->flags, IFA_F_NOPREFIXROUTE))
+                        continue;
+                if (in_addr_is_set(a->family, &a->in_addr_peer))
+                        continue;
+                if (in_addr_prefix_covers(family, &a->in_addr, a->prefixlen, address) > 0)
+                        return true;
+        }
+
+        return false;
+}
+
+bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_union *gw) {
+        assert(link);
+        assert(gw);
+
+        if (onlink)
+                return true;
+
+        if (!in_addr_is_set(family, gw))
+                return true;
+
+        if (family == AF_INET6 && in6_addr_is_link_local(&gw->in6))
+                return true;
+
+        return link_address_is_reachable(link, family, gw);
+}
+
+static const char * const route_type_table[__RTN_MAX] = {
+        [RTN_UNICAST]     = "unicast",
+        [RTN_LOCAL]       = "local",
+        [RTN_BROADCAST]   = "broadcast",
+        [RTN_ANYCAST]     = "anycast",
+        [RTN_MULTICAST]   = "multicast",
+        [RTN_BLACKHOLE]   = "blackhole",
+        [RTN_UNREACHABLE] = "unreachable",
+        [RTN_PROHIBIT]    = "prohibit",
+        [RTN_THROW]       = "throw",
+        [RTN_NAT]         = "nat",
+        [RTN_XRESOLVE]    = "xresolve",
+};
+
+assert_cc(__RTN_MAX <= UCHAR_MAX);
+DEFINE_STRING_TABLE_LOOKUP(route_type, int);
+
+static const char * const route_scope_table[] = {
+        [RT_SCOPE_UNIVERSE] = "global",
+        [RT_SCOPE_SITE]     = "site",
+        [RT_SCOPE_LINK]     = "link",
+        [RT_SCOPE_HOST]     = "host",
+        [RT_SCOPE_NOWHERE]  = "nowhere",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(route_scope, int, UINT8_MAX);
+
+static const char * const route_protocol_table[] = {
+        [RTPROT_KERNEL] = "kernel",
+        [RTPROT_BOOT]   = "boot",
+        [RTPROT_STATIC] = "static",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(route_protocol, int, UINT8_MAX);
+
+static const char * const route_protocol_full_table[] = {
+        [RTPROT_REDIRECT] = "redirect",
+        [RTPROT_KERNEL]   = "kernel",
+        [RTPROT_BOOT]     = "boot",
+        [RTPROT_STATIC]   = "static",
+        [RTPROT_GATED]    = "gated",
+        [RTPROT_RA]       = "ra",
+        [RTPROT_MRT]      = "mrt",
+        [RTPROT_ZEBRA]    = "zebra",
+        [RTPROT_BIRD]     = "bird",
+        [RTPROT_DNROUTED] = "dnrouted",
+        [RTPROT_XORP]     = "xorp",
+        [RTPROT_NTK]      = "ntk",
+        [RTPROT_DHCP]     = "dhcp",
+        [RTPROT_MROUTED]  = "mrouted",
+        [RTPROT_BABEL]    = "babel",
+        [RTPROT_BGP]      = "bgp",
+        [RTPROT_ISIS]     = "isis",
+        [RTPROT_OSPF]     = "ospf",
+        [RTPROT_RIP]      = "rip",
+        [RTPROT_EIGRP]    = "eigrp",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(route_protocol_full, int, UINT8_MAX);
+
+static const char * const route_table_table[] = {
+        [RT_TABLE_DEFAULT] = "default",
+        [RT_TABLE_MAIN]    = "main",
+        [RT_TABLE_LOCAL]   = "local",
+};
+
+DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_table, int);
+
+int manager_get_route_table_from_string(const Manager *m, const char *s, uint32_t *ret) {
+        uint32_t t;
+        int r;
+
+        assert(m);
+        assert(s);
+        assert(ret);
+
+        r = route_table_from_string(s);
+        if (r >= 0) {
+                *ret = (uint32_t) r;
+                return 0;
+        }
+
+        t = PTR_TO_UINT32(hashmap_get(m->route_table_numbers_by_name, s));
+        if (t != 0) {
+                *ret = t;
+                return 0;
+        }
+
+        r = safe_atou32(s, &t);
+        if (r < 0)
+                return r;
+
+        if (t == 0)
+                return -ERANGE;
+
+        *ret = t;
+        return 0;
+}
+
+int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret) {
+        _cleanup_free_ char *str = NULL;
+        const char *s;
+        int r;
+
+        assert(m);
+        assert(ret);
+
+        if (table == 0)
+                return -EINVAL;
+
+        s = route_table_to_string(table);
+        if (!s)
+                s = hashmap_get(m->route_table_names_by_number, UINT32_TO_PTR(table));
+
+        if (s)
+                /* Currently, this is only used in debugging logs. To not confuse any bug
+                 * reports, let's include the table number. */
+                r = asprintf(&str, "%s(%" PRIu32 ")", s, table);
+        else
+                r = asprintf(&str, "%" PRIu32, table);
+        if (r < 0)
+                return -ENOMEM;
+
+        *ret = TAKE_PTR(str);
+        return 0;
+}
+
+int config_parse_route_table_names(
+                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) {
+
+        Manager *m = userdata;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(userdata);
+
+        if (isempty(rvalue)) {
+                m->route_table_names_by_number = hashmap_free(m->route_table_names_by_number);
+                m->route_table_numbers_by_name = hashmap_free(m->route_table_numbers_by_name);
+                return 0;
+        }
+
+        for (const char *p = rvalue;;) {
+                _cleanup_free_ char *name = NULL;
+                uint32_t table;
+                char *num;
+
+                r = extract_first_word(&p, &name, NULL, 0);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r,
+                                   "Invalid RouteTable=, ignoring assignment: %s", rvalue);
+                        return 0;
+                }
+                if (r == 0)
+                        return 0;
+
+                num = strchr(name, ':');
+                if (!num) {
+                        log_syntax(unit, LOG_WARNING, filename, line, 0,
+                                   "Invalid route table name and number pair, ignoring assignment: %s", name);
+                        continue;
+                }
+
+                *num++ = '\0';
+
+                if (STR_IN_SET(name, "default", "main", "local")) {
+                        log_syntax(unit, LOG_WARNING, filename, line, 0,
+                                   "Route table name %s already predefined. Ignoring assignment: %s:%s", name, name, num);
+                        continue;
+                }
+
+                r = safe_atou32(num, &table);
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r,
+                                   "Failed to parse route table number '%s', ignoring assignment: %s:%s", num, name, num);
+                        continue;
+                }
+                if (table == 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, 0,
+                                   "Invalid route table number, ignoring assignment: %s:%s", name, num);
+                        continue;
+                }
+
+                r = hashmap_ensure_put(&m->route_table_numbers_by_name, &string_hash_ops_free, name, UINT32_TO_PTR(table));
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r == -EEXIST) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r,
+                                   "Specified route table name and number pair conflicts with others, ignoring assignment: %s:%s", name, num);
+                        continue;
+                }
+                if (r < 0) {
+                        log_syntax(unit, LOG_WARNING, filename, line, r,
+                                   "Failed to store route table name and number pair, ignoring assignment: %s:%s", name, num);
+                        continue;
+                }
+                if (r == 0)
+                        /* The entry is duplicated. It should not be added to route_table_names_by_number hashmap. */
+                        continue;
+
+                r = hashmap_ensure_put(&m->route_table_names_by_number, NULL, UINT32_TO_PTR(table), name);
+                if (r < 0) {
+                        hashmap_remove(m->route_table_numbers_by_name, name);
+
+                        if (r == -ENOMEM)
+                                return log_oom();
+                        if (r == -EEXIST)
+                                log_syntax(unit, LOG_WARNING, filename, line, r,
+                                           "Specified route table name and number pair conflicts with others, ignoring assignment: %s:%s", name, num);
+                        else
+                                log_syntax(unit, LOG_WARNING, filename, line, r,
+                                           "Failed to store route table name and number pair, ignoring assignment: %s:%s", name, num);
+                        continue;
+                }
+                assert(r > 0);
+
+                TAKE_PTR(name);
+        }
+}
diff --git a/src/network/networkd-route-util.h b/src/network/networkd-route-util.h
new file mode 100644 (file)
index 0000000..4b1f778
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+#include "conf-parser.h"
+
+typedef struct Link Link;
+typedef struct Manager Manager;
+
+unsigned routes_max(void);
+
+int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret);
+
+bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_union *gw);
+
+int route_type_from_string(const char *s) _pure_;
+const char *route_type_to_string(int t) _const_;
+
+int route_scope_from_string(const char *s);
+int route_scope_to_string_alloc(int t, char **ret);
+
+int route_protocol_from_string(const char *s);
+int route_protocol_to_string_alloc(int t, char **ret);
+int route_protocol_full_from_string(const char *s);
+int route_protocol_full_to_string_alloc(int t, char **ret);
+
+int manager_get_route_table_from_string(const Manager *m, const char *table, uint32_t *ret);
+int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret);
+
+CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
index ed8c113a546d6162d8a8f888945dbf5404f752d4..946c69621fab289aeea903b0df018892bfccc216 100644 (file)
 #include "networkd-network.h"
 #include "networkd-nexthop.h"
 #include "networkd-queue.h"
+#include "networkd-route-util.h"
 #include "networkd-route.h"
 #include "parse-util.h"
-#include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
-#include "strxcpyx.h"
-#include "sysctl-util.h"
 #include "vrf.h"
 
-#define ROUTES_DEFAULT_MAX_PER_FAMILY 4096U
-
-static const char * const route_type_table[__RTN_MAX] = {
-        [RTN_UNICAST]     = "unicast",
-        [RTN_LOCAL]       = "local",
-        [RTN_BROADCAST]   = "broadcast",
-        [RTN_ANYCAST]     = "anycast",
-        [RTN_MULTICAST]   = "multicast",
-        [RTN_BLACKHOLE]   = "blackhole",
-        [RTN_UNREACHABLE] = "unreachable",
-        [RTN_PROHIBIT]    = "prohibit",
-        [RTN_THROW]       = "throw",
-        [RTN_NAT]         = "nat",
-        [RTN_XRESOLVE]    = "xresolve",
-};
-
-assert_cc(__RTN_MAX <= UCHAR_MAX);
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_type, int);
-
-static const char * const route_scope_table[] = {
-        [RT_SCOPE_UNIVERSE] = "global",
-        [RT_SCOPE_SITE]     = "site",
-        [RT_SCOPE_LINK]     = "link",
-        [RT_SCOPE_HOST]     = "host",
-        [RT_SCOPE_NOWHERE]  = "nowhere",
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(route_scope, int);
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(route_scope, int, UINT8_MAX);
-
-static const char * const route_table_table[] = {
-        [RT_TABLE_DEFAULT] = "default",
-        [RT_TABLE_MAIN]    = "main",
-        [RT_TABLE_LOCAL]   = "local",
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_table, int);
-
-int manager_get_route_table_from_string(const Manager *m, const char *s, uint32_t *ret) {
-        uint32_t t;
-        int r;
-
-        assert(m);
-        assert(s);
-        assert(ret);
-
-        r = route_table_from_string(s);
-        if (r >= 0) {
-                *ret = (uint32_t) r;
-                return 0;
-        }
-
-        t = PTR_TO_UINT32(hashmap_get(m->route_table_numbers_by_name, s));
-        if (t != 0) {
-                *ret = t;
-                return 0;
-        }
-
-        r = safe_atou32(s, &t);
-        if (r < 0)
-                return r;
-
-        if (t == 0)
-                return -ERANGE;
-
-        *ret = t;
-        return 0;
-}
-
-int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret) {
-        _cleanup_free_ char *str = NULL;
-        const char *s;
-        int r;
-
-        assert(m);
-        assert(ret);
-
-        if (table == 0)
-                return -EINVAL;
-
-        s = route_table_to_string(table);
-        if (!s)
-                s = hashmap_get(m->route_table_names_by_number, UINT32_TO_PTR(table));
-
-        if (s)
-                /* Currently, this is only used in debugging logs. To not confuse any bug
-                 * reports, let's include the table number. */
-                r = asprintf(&str, "%s(%" PRIu32 ")", s, table);
-        else
-                r = asprintf(&str, "%" PRIu32, table);
-        if (r < 0)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(str);
-        return 0;
-}
-
-static const char * const route_protocol_table[] = {
-        [RTPROT_KERNEL] = "kernel",
-        [RTPROT_BOOT]   = "boot",
-        [RTPROT_STATIC] = "static",
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_FALLBACK(route_protocol, int, UINT8_MAX);
-
-static const char * const route_protocol_full_table[] = {
-        [RTPROT_REDIRECT] = "redirect",
-        [RTPROT_KERNEL]   = "kernel",
-        [RTPROT_BOOT]     = "boot",
-        [RTPROT_STATIC]   = "static",
-        [RTPROT_GATED]    = "gated",
-        [RTPROT_RA]       = "ra",
-        [RTPROT_MRT]      = "mrt",
-        [RTPROT_ZEBRA]    = "zebra",
-        [RTPROT_BIRD]     = "bird",
-        [RTPROT_DNROUTED] = "dnrouted",
-        [RTPROT_XORP]     = "xorp",
-        [RTPROT_NTK]      = "ntk",
-        [RTPROT_DHCP]     = "dhcp",
-        [RTPROT_MROUTED]  = "mrouted",
-        [RTPROT_BABEL]    = "babel",
-        [RTPROT_BGP]      = "bgp",
-        [RTPROT_ISIS]     = "isis",
-        [RTPROT_OSPF]     = "ospf",
-        [RTPROT_RIP]      = "rip",
-        [RTPROT_EIGRP]    = "eigrp",
-};
-
-DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING_FALLBACK(route_protocol_full, int, UINT8_MAX);
-
-static unsigned routes_max(void) {
-        static thread_local unsigned cached = 0;
-        _cleanup_free_ char *s4 = NULL, *s6 = NULL;
-        unsigned val4 = ROUTES_DEFAULT_MAX_PER_FAMILY, val6 = ROUTES_DEFAULT_MAX_PER_FAMILY;
-
-        if (cached > 0)
-                return cached;
-
-        if (sysctl_read_ip_property(AF_INET, NULL, "route/max_size", &s4) >= 0)
-                if (safe_atou(s4, &val4) >= 0 && val4 == 2147483647U)
-                        /* This is the default "no limit" value in the kernel */
-                        val4 = ROUTES_DEFAULT_MAX_PER_FAMILY;
-
-        if (sysctl_read_ip_property(AF_INET6, NULL, "route/max_size", &s6) >= 0)
-                (void) safe_atou(s6, &val6);
-
-        cached = MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val4) +
-                 MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val6);
-        return cached;
-}
-
 int route_new(Route **ret) {
         _cleanup_(route_freep) Route *route = NULL;
 
@@ -695,112 +542,6 @@ void link_mark_routes(Link *link, NetworkConfigSource source, const struct in6_a
         }
 }
 
-static bool link_address_is_reachable(Link *link, int family, const union in_addr_union *address) {
-        Route *route;
-        Address *a;
-
-        assert(link);
-        assert(link->manager);
-        assert(IN_SET(family, AF_INET, AF_INET6));
-        assert(address);
-
-        SET_FOREACH(route, link->routes) {
-                if (!route_exists(route))
-                        continue;
-                if (route->family != family)
-                        continue;
-                if (!in_addr_is_set(route->family, &route->dst))
-                        continue;
-                if (in_addr_prefix_covers(family, &route->dst, route->dst_prefixlen, address) > 0)
-                        return true;
-        }
-
-        if (link->manager->manage_foreign_routes)
-                return false;
-
-        /* If we do not manage foreign routes, then there may exist a prefix route we do not know,
-         * which was created on configuring an address. Hence, also check the addresses. */
-        SET_FOREACH(a, link->addresses) {
-                if (!address_is_ready(a))
-                        continue;
-                if (a->family != family)
-                        continue;
-                if (FLAGS_SET(a->flags, IFA_F_NOPREFIXROUTE))
-                        continue;
-                if (in_addr_is_set(a->family, &a->in_addr_peer))
-                        continue;
-                if (in_addr_prefix_covers(family, &a->in_addr, a->prefixlen, address) > 0)
-                        return true;
-        }
-
-        return false;
-}
-
-static Route *link_find_default_gateway(Link *link, int family, Route *gw) {
-        Route *route;
-
-        assert(link);
-
-        SET_FOREACH(route, link->routes) {
-                if (!route_exists(route))
-                        continue;
-                if (family != AF_UNSPEC && route->family != family)
-                        continue;
-                if (route->dst_prefixlen != 0)
-                        continue;
-                if (route->src_prefixlen != 0)
-                        continue;
-                if (route->table != RT_TABLE_MAIN)
-                        continue;
-                if (route->type != RTN_UNICAST)
-                        continue;
-                if (route->scope != RT_SCOPE_UNIVERSE)
-                        continue;
-                if (!in_addr_is_set(route->gw_family, &route->gw))
-                        continue;
-                if (gw) {
-                        if (route->gw_weight > gw->gw_weight)
-                                continue;
-                        if (route->priority >= gw->priority)
-                                continue;
-                }
-                gw = route;
-        }
-
-        return gw;
-}
-
-int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret) {
-        Route *gw = NULL;
-        Link *link;
-
-        assert(m);
-        assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
-
-        /* Looks for a suitable "uplink", via black magic: an interface that is up and where the
-         * default route with the highest priority points to. */
-
-        HASHMAP_FOREACH(link, m->links_by_index) {
-                if (link == exclude)
-                        continue;
-
-                if (link->state != LINK_STATE_CONFIGURED)
-                        continue;
-
-                gw = link_find_default_gateway(link, family, gw);
-        }
-
-        if (!gw)
-                return -ENOENT;
-
-        if (ret) {
-                assert(gw->link);
-                *ret = gw->link;
-        }
-
-        return 0;
-}
-
 static void log_route_debug(const Route *route, const char *str, const Link *link, const Manager *manager) {
         _cleanup_free_ char *state = NULL, *dst = NULL, *src = NULL, *gw_alloc = NULL, *prefsrc = NULL,
                 *table = NULL, *scope = NULL, *proto = NULL;
@@ -1628,22 +1369,6 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
         return 0;
 }
 
-bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_union *gw) {
-        assert(link);
-        assert(gw);
-
-        if (onlink)
-                return true;
-
-        if (!in_addr_is_set(family, gw))
-                return true;
-
-        if (family == AF_INET6 && in6_addr_is_link_local(&gw->in6))
-                return true;
-
-        return link_address_is_reachable(link, family, gw);
-}
-
 static int route_is_ready_to_configure(const Route *route, Link *link) {
         int r;
 
@@ -2958,112 +2683,6 @@ int config_parse_multipath_route(
         return 0;
 }
 
-int config_parse_route_table_names(
-                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) {
-
-        Manager *m = userdata;
-        int r;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(userdata);
-
-        if (isempty(rvalue)) {
-                m->route_table_names_by_number = hashmap_free(m->route_table_names_by_number);
-                m->route_table_numbers_by_name = hashmap_free(m->route_table_numbers_by_name);
-                return 0;
-        }
-
-        for (const char *p = rvalue;;) {
-                _cleanup_free_ char *name = NULL;
-                uint32_t table;
-                char *num;
-
-                r = extract_first_word(&p, &name, NULL, 0);
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_WARNING, filename, line, r,
-                                   "Invalid RouteTable=, ignoring assignment: %s", rvalue);
-                        return 0;
-                }
-                if (r == 0)
-                        return 0;
-
-                num = strchr(name, ':');
-                if (!num) {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-                                   "Invalid route table name and number pair, ignoring assignment: %s", name);
-                        continue;
-                }
-
-                *num++ = '\0';
-
-                if (STR_IN_SET(name, "default", "main", "local")) {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-                                   "Route table name %s already predefined. Ignoring assignment: %s:%s", name, name, num);
-                        continue;
-                }
-
-                r = safe_atou32(num, &table);
-                if (r < 0) {
-                        log_syntax(unit, LOG_WARNING, filename, line, r,
-                                   "Failed to parse route table number '%s', ignoring assignment: %s:%s", num, name, num);
-                        continue;
-                }
-                if (table == 0) {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0,
-                                   "Invalid route table number, ignoring assignment: %s:%s", name, num);
-                        continue;
-                }
-
-                r = hashmap_ensure_put(&m->route_table_numbers_by_name, &string_hash_ops_free, name, UINT32_TO_PTR(table));
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r == -EEXIST) {
-                        log_syntax(unit, LOG_WARNING, filename, line, r,
-                                   "Specified route table name and number pair conflicts with others, ignoring assignment: %s:%s", name, num);
-                        continue;
-                }
-                if (r < 0) {
-                        log_syntax(unit, LOG_WARNING, filename, line, r,
-                                   "Failed to store route table name and number pair, ignoring assignment: %s:%s", name, num);
-                        continue;
-                }
-                if (r == 0)
-                        /* The entry is duplicated. It should not be added to route_table_names_by_number hashmap. */
-                        continue;
-
-                r = hashmap_ensure_put(&m->route_table_names_by_number, NULL, UINT32_TO_PTR(table), name);
-                if (r < 0) {
-                        hashmap_remove(m->route_table_numbers_by_name, name);
-
-                        if (r == -ENOMEM)
-                                return log_oom();
-                        if (r == -EEXIST)
-                                log_syntax(unit, LOG_WARNING, filename, line, r,
-                                           "Specified route table name and number pair conflicts with others, ignoring assignment: %s:%s", name, num);
-                        else
-                                log_syntax(unit, LOG_WARNING, filename, line, r,
-                                           "Failed to store route table name and number pair, ignoring assignment: %s:%s", name, num);
-                        continue;
-                }
-                assert(r > 0);
-
-                TAKE_PTR(name);
-        }
-}
-
 static int route_section_verify(Route *route, Network *network) {
         if (section_is_invalid(route->section))
                 return -EINVAL;
index f6066d9601af497ff6c5ab2142ab51d6f26ef2a5..6bc19fd7d88ee75bb48399ebf6a7882662cf27c9 100644 (file)
@@ -80,8 +80,6 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
 int route_remove(Route *route);
 
 int route_get(Manager *manager, Link *link, const Route *in, Route **ret);
-int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret);
-bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_union *gw);
 
 int link_drop_routes(Link *link);
 int link_drop_foreign_routes(Link *link);
@@ -104,9 +102,6 @@ int network_add_ipv4ll_route(Network *network);
 int network_add_default_route_on_device(Network *network);
 void network_drop_invalid_routes(Network *network);
 
-int manager_get_route_table_from_string(const Manager *m, const char *table, uint32_t *ret);
-int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret);
-
 DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Route, route);
 void link_mark_routes(Link *link, NetworkConfigSource source, const struct in6_addr *router);
 
@@ -124,5 +119,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
 CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu);
 CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
 CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
-CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
 CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop);
index 35808b10f72405496343747213811a5f93b42358..08126ed3e7129b9be139835356e7b6c87acb3081 100644 (file)
@@ -13,7 +13,7 @@
 #include "netlink-util.h"
 #include "networkd-manager.h"
 #include "networkd-queue.h"
-#include "networkd-route.h"
+#include "networkd-route-util.h"
 #include "networkd-routing-policy-rule.h"
 #include "networkd-util.h"
 #include "parse-util.h"
index 479675722b0ca215f14a2aa2a4cc4b8e58731c9b..9026207265862512a7a200e8b7ad175a3b18b19a 100644 (file)
@@ -12,7 +12,7 @@
 #include "network-internal.h"
 #include "networkd-address.h"
 #include "networkd-manager.h"
-#include "networkd-route.h"
+#include "networkd-route-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "tests.h"