]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: address - properly take over a foreign address
authorTom Gundersen <teg@jklm.no>
Mon, 26 Oct 2015 10:40:02 +0000 (11:40 +0100)
committerTom Gundersen <teg@jklm.no>
Fri, 30 Oct 2015 11:32:48 +0000 (12:32 +0100)
src/network/networkd-address.c

index 0338fe9393389f53ebc5b2ad5ea150aa390400cf..5b5492e02ee1b88485e977e4f611cafcf2fb6206 100644 (file)
@@ -272,14 +272,34 @@ int address_add_foreign(Link *link, int family, const union in_addr_union *in_ad
 }
 
 static int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
+        Address *address;
         int r;
 
-        r = address_add_internal(link, &link->addresses, family, in_addr, prefixlen, ret);
-        if (r < 0)
+        r = address_get(link, family, in_addr, prefixlen, &address);
+        if (r == -ENOENT) {
+                /* Address does not exist, create a new one */
+                r = address_add_internal(link, &link->addresses, family, in_addr, prefixlen, &address);
+                if (r < 0)
+                        return r;
+        } else if (r == 0) {
+                /* Take over a foreign address */
+                r = set_ensure_allocated(&link->addresses, &address_hash_ops);
+                if (r < 0)
+                        return r;
+
+                r = set_put(link->addresses, address);
+                if (r < 0)
+                        return r;
+
+                set_remove(link->addresses_foreign, address);
+        } else if (r == 1) {
+                /* Already exists, do nothing */
+                ;
+        } else
                 return r;
 
-        link_update_operstate(link);
-        link_dirty(link);
+        if (ret)
+                *ret = address;
 
         return 0;
 }
@@ -360,7 +380,11 @@ int address_get(Link *link, int family, const union in_addr_union *in_addr, unsi
         address.prefixlen = prefixlen;
 
         existing = set_get(link->addresses, &address);
-        if (!existing) {
+        if (existing) {
+                *ret = existing;
+
+                return 1;
+        } else {
                 existing = set_get(link->addresses_foreign, &address);
                 if (!existing)
                         return -ENOENT;