From 344b3cff36ecb9b30c56cc924d14676952660664 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 11 Nov 2021 13:16:46 +0900 Subject: [PATCH] network: split networkd-route.[ch] --- src/network/meson.build | 2 + src/network/networkd-dhcp-server.c | 2 +- src/network/networkd-gperf.gperf | 2 +- src/network/networkd-nexthop.c | 2 +- src/network/networkd-radv.c | 2 +- src/network/networkd-route-util.c | 393 +++++++++++++++++++++ src/network/networkd-route-util.h | 32 ++ src/network/networkd-route.c | 383 +------------------- src/network/networkd-route.h | 6 - src/network/networkd-routing-policy-rule.c | 2 +- src/network/test-network.c | 2 +- 11 files changed, 434 insertions(+), 394 deletions(-) create mode 100644 src/network/networkd-route-util.c create mode 100644 src/network/networkd-route-util.h diff --git a/src/network/meson.build b/src/network/meson.build index dedfc90f4d..9247734c75 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -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 diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 9fa0c4233c..9acfd17d49 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -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" diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf index 20c33e8c80..8ed90f0e4b 100644 --- a/src/network/networkd-gperf.gperf +++ b/src/network/networkd-gperf.gperf @@ -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 diff --git a/src/network/networkd-nexthop.c b/src/network/networkd-nexthop.c index 7ae43a00bd..f043754ea1 100644 --- a/src/network/networkd-nexthop.c +++ b/src/network/networkd-nexthop.c @@ -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" diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index 7b98251570..c98528aee9 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -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 index 0000000000..77e8c2bfb9 --- /dev/null +++ b/src/network/networkd-route-util.c @@ -0,0 +1,393 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include + +#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 index 0000000000..4b1f778d93 --- /dev/null +++ b/src/network/networkd-route-util.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include +#include + +#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); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index ed8c113a54..946c69621f 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -13,166 +13,13 @@ #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; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index f6066d9601..6bc19fd7d8 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -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); diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 35808b10f7..08126ed3e7 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -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" diff --git a/src/network/test-network.c b/src/network/test-network.c index 479675722b..9026207265 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -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" -- 2.25.1