From: Yu Watanabe Date: Tue, 9 Jan 2024 02:45:37 +0000 (+0900) Subject: wireguard: verify routes configured in .netdev file X-Git-Tag: v256-rc1~1163^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4db8ccbb59f6825bb8eb8eed07600589fe8691c4;p=thirdparty%2Fsystemd.git wireguard: verify routes configured in .netdev file Then, scope and friends are correctly adjusted, and the behavior should be matched when the same route is configured in .network file. --- diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index 57c3923c1b1..0195dce1bf0 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -1196,20 +1196,33 @@ static int wireguard_verify(NetDev *netdev, const char *filename) { if (r < 0) return log_oom(); + /* For route_section_verify() below. */ + r = config_section_new(peer->section->filename, peer->section->line, &route->section); + if (r < 0) + return log_oom(); + + route->source = NETWORK_CONFIG_SOURCE_STATIC; route->family = ipmask->family; route->dst = ipmask->ip; route->dst_prefixlen = ipmask->cidr; - route->scope = RT_SCOPE_UNIVERSE; route->protocol = RTPROT_STATIC; + route->protocol_set = true; route->table = peer->route_table_set ? peer->route_table : w->route_table; + route->table_set = true; route->priority = peer->route_priority_set ? peer->route_priority : w->route_priority; - if (route->priority == 0 && route->family == AF_INET6) - route->priority = IP6_RT_PRIO_USER; - route->source = NETWORK_CONFIG_SOURCE_STATIC; + route->priority_set = true; - r = set_ensure_consume(&w->routes, &route_hash_ops, TAKE_PTR(route)); + if (route_section_verify(route) < 0) + continue; + + r = set_ensure_put(&w->routes, &route_hash_ops, route); if (r < 0) return log_oom(); + if (r == 0) + continue; + + route->wireguard = w; + TAKE_PTR(route); } } diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c index 4dc86d3b76d..a8fddeb6c04 100644 --- a/src/network/networkd-route-nexthop.c +++ b/src/network/networkd-route-nexthop.c @@ -15,9 +15,10 @@ int route_section_verify_nexthops(Route *route) { assert(route); assert(route->section); - assert(route->network); if (route->gateway_from_dhcp_or_ra) { + assert(route->network); + if (route->gw_family == AF_UNSPEC) /* When deprecated Gateway=_dhcp is set, then assume gateway family based on other settings. */ switch (route->family) { @@ -70,7 +71,7 @@ int route_section_verify_nexthops(Route *route) { } if (route->gateway_onlink < 0 && in_addr_is_set(route->gw_family, &route->gw) && - ordered_hashmap_isempty(route->network->addresses_by_section)) { + route->network && ordered_hashmap_isempty(route->network->addresses_by_section)) { /* If no address is configured, in most cases the gateway cannot be reachable. * TODO: we may need to improve the condition above. */ log_warning("%s: Gateway= without static address configured. " diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 04b63805137..dfbbefdbd66 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -100,6 +100,9 @@ Route *route_free(Route *route) { if (route->manager) set_remove(route->manager->routes, route); + if (route->wireguard) + set_remove(route->wireguard->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); @@ -305,6 +308,7 @@ int route_dup(const Route *src, Route **ret) { /* Unset all pointers */ dest->network = NULL; + dest->wireguard = NULL; dest->section = NULL; dest->link = NULL; dest->manager = NULL; @@ -2236,12 +2240,11 @@ int config_parse_route_type( return 0; } -static int route_section_verify(Route *route) { +int route_section_verify(Route *route) { int r; assert(route); assert(route->section); - assert(route->network); if (section_is_invalid(route->section)) return -EINVAL; @@ -2254,7 +2257,7 @@ static int route_section_verify(Route *route) { return r; /* table */ - if (!route->table_set && route->network->vrf) { + if (!route->table_set && route->network && route->network->vrf) { route->table = VRF(route->network->vrf)->table; route->table_set = true; } diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 140980ca05b..5c041953ab4 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -17,6 +17,8 @@ typedef struct Manager Manager; typedef struct Network Network; typedef struct Request Request; typedef struct Route Route; +typedef struct Wireguard Wireguard; + typedef int (*route_netlink_handler_t)( sd_netlink *rtnl, sd_netlink_message *m, @@ -28,6 +30,7 @@ struct Route { Link *link; Manager *manager; Network *network; + Wireguard *wireguard; ConfigSection *section; NetworkConfigSource source; NetworkConfigState state; @@ -108,6 +111,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma int network_add_ipv4ll_route(Network *network); int network_add_default_route_on_device(Network *network); void network_drop_invalid_routes(Network *network); +int route_section_verify(Route *route); DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Route, route); void link_mark_routes(Link *link, NetworkConfigSource source); diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index dfa74c203df..16103210531 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1823,7 +1823,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): output = check_output('ip -4 route show dev wg99 table 1234') print(output) - self.assertIn('192.168.26.0/24 proto static metric 123', output) + self.assertIn('192.168.26.0/24 proto static scope link metric 123', output) output = check_output('ip -6 route show dev wg99 table 1234') print(output)