]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
wireguard: verify routes configured in .netdev file 30916/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 9 Jan 2024 02:45:37 +0000 (11:45 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 13 Jan 2024 01:10:32 +0000 (10:10 +0900)
Then, scope and friends are correctly adjusted, and the behavior should
be matched when the same route is configured in .network file.

src/network/netdev/wireguard.c
src/network/networkd-route-nexthop.c
src/network/networkd-route.c
src/network/networkd-route.h
test/test-network/systemd-networkd-tests.py

index 57c3923c1b1764b755ba77c8ce64f010fe8be59c..0195dce1bf04c6654623661621e869dcb4b541ca 100644 (file)
@@ -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);
                 }
         }
 
index 4dc86d3b76dbf7a6859d2e6680216384d4037571..a8fddeb6c0462c072cc7fd4600e86ef98af1467b 100644 (file)
 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. "
index 04b6380513755e3d1fc7f4b75645112f361e3522..dfbbefdbd668acab3d1b801f989a78943b68abf2 100644 (file)
@@ -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;
         }
index 140980ca05b35e87775f79aaaeaff7ccabd79e74..5c041953ab40d6f78a8bc4858a4faebd345f43c5 100644 (file)
@@ -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);
index dfa74c203df45ed1595f77bf58c06bef9583bc69..16103210531271964f9c974648630b9f89475b7b 100755 (executable)
@@ -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)