]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: copy multipath route element earlier
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Oct 2020 06:26:51 +0000 (15:26 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Oct 2020 06:32:55 +0000 (15:32 +0900)
`route_get()` compares input with existing routes, however previously,
the input may did not have information about gateway. So, the
comparison result might be incorrect, and the foregoing set_put() might
return -EEXIST.

src/network/networkd-route.c

index 4ad9adc920262737761986e5311fe08662d32510..34ede604056c68ed09409c03743add52db5df70b 100644 (file)
@@ -487,20 +487,19 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m) {
         }
 }
 
-static int route_add_internal(Manager *manager, Link *link, Set **routes, const Route *in, const MultipathRoute *m, Route **ret) {
+static int route_add_internal(Manager *manager, Link *link, Set **routes, const Route *in, Route **ret) {
         _cleanup_(route_freep) Route *route = NULL;
         int r;
 
         assert(manager || link);
         assert(routes);
         assert(in);
-        assert(!m || (link && (m->ifindex == 0 || m->ifindex == link->ifindex)));
 
         r = route_new(&route);
         if (r < 0)
                 return r;
 
-        route_copy(route, in, m);
+        route_copy(route, in, NULL);
 
         r = set_ensure_put(routes, &route_hash_ops, route);
         if (r < 0)
@@ -521,20 +520,32 @@ static int route_add_internal(Manager *manager, Link *link, Set **routes, const
 
 static int route_add_foreign(Manager *manager, Link *link, const Route *in, Route **ret) {
         assert(manager || link);
-        return route_add_internal(manager, link, link ? &link->routes_foreign : &manager->routes_foreign, in, NULL, ret);
+        return route_add_internal(manager, link, link ? &link->routes_foreign : &manager->routes_foreign, in, ret);
 }
 
 static int route_add(Manager *manager, Link *link, const Route *in, const MultipathRoute *m, Route **ret) {
+        _cleanup_(route_freep) Route *tmp = NULL;
         Route *route;
         int r;
 
         assert(manager || link);
         assert(in);
 
+        if (m) {
+                assert(link && (m->ifindex == 0 || m->ifindex == link->ifindex));
+
+                r = route_new(&tmp);
+                if (r < 0)
+                        return r;
+
+                route_copy(tmp, in, m);
+                in = tmp;
+        }
+
         r = route_get(manager, link, in, &route);
         if (r == -ENOENT) {
                 /* Route does not exist, create a new one */
-                r = route_add_internal(manager, link, link ? &link->routes : &manager->routes, in, m, &route);
+                r = route_add_internal(manager, link, link ? &link->routes : &manager->routes, in, &route);
                 if (r < 0)
                         return r;
         } else if (r == 0) {