chiark / gitweb /
networkd-wait-online: track links
[elogind.git] / src / network / networkd-address.c
index ce015004de7e6209ca25f1cbcf2606d12dce26a9..8c4ef9964ba822424cafe18811a2b94a436cb466 100644 (file)
@@ -144,6 +144,8 @@ int address_drop(Address *address, Link *link,
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
@@ -225,13 +227,15 @@ int address_update(Address *address, Link *link,
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
 static int address_acquire(Link *link, Address *original, Address **ret) {
         union in_addr_union in_addr = {};
         struct in_addr broadcast = {};
-        Address *na = NULL;
+        _cleanup_address_free_ Address *na = NULL;
         int r;
 
         assert(link);
@@ -274,11 +278,8 @@ static int address_acquire(Link *link, Address *original, Address **ret) {
 
         if (original->label) {
                 na->label = strdup(original->label);
-
-                if (!na->label) {
-                        free(na);
+                if (!na->label)
                         return -ENOMEM;
-                }
         }
 
         na->broadcast = broadcast;
@@ -287,6 +288,8 @@ static int address_acquire(Link *link, Address *original, Address **ret) {
         LIST_PREPEND(addresses, link->pool_addresses, na);
 
         *ret = na;
+        na = NULL;
+
         return 0;
 }
 
@@ -342,13 +345,25 @@ int address_configure(Address *address, Link *link,
                 return r;
         }
 
-        if (address->family == AF_INET) {
-                r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
+        if (!in_addr_null(address->family, &address->in_addr_peer)) {
+                if (address->family == AF_INET)
+                        r = sd_rtnl_message_append_in_addr(req, IFA_ADDRESS, &address->in_addr_peer.in);
+                else if (address->family == AF_INET6)
+                        r = sd_rtnl_message_append_in6_addr(req, IFA_ADDRESS, &address->in_addr_peer.in6);
                 if (r < 0) {
-                        log_error("Could not append IFA_BROADCAST attribute: %s",
+                        log_error("Could not append IFA_ADDRESS attribute: %s",
                                   strerror(-r));
                         return r;
                 }
+        } else {
+                if (address->family == AF_INET) {
+                        r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
+                        if (r < 0) {
+                                log_error("Could not append IFA_BROADCAST attribute: %s",
+                                          strerror(-r));
+                                return r;
+                        }
+                }
         }
 
         if (address->label) {
@@ -360,12 +375,22 @@ int address_configure(Address *address, Link *link,
                 }
         }
 
+        r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO,
+                                              &address->cinfo);
+        if (r < 0) {
+                log_error("Could not append IFA_CACHEINFO attribute: %s",
+                          strerror(-r));
+                return r;
+        }
+
         r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
         if (r < 0) {
                 log_error("Could not send rtnetlink message: %s", strerror(-r));
                 return r;
         }
 
+        link_ref(link);
+
         return 0;
 }
 
@@ -475,6 +500,7 @@ int config_parse_address(const char *unit,
         Network *network = userdata;
         _cleanup_address_free_ Address *n = NULL;
         _cleanup_free_ char *address = NULL;
+        union in_addr_union *addr;
         const char *e;
         int r;
 
@@ -494,6 +520,11 @@ int config_parse_address(const char *unit,
         if (r < 0)
                 return r;
 
+        if (streq(lvalue, "Address"))
+                addr = &n->in_addr;
+        else
+                addr = &n->in_addr_peer;
+
         /* Address=address/prefixlen */
 
         /* prefixlen */
@@ -519,7 +550,7 @@ int config_parse_address(const char *unit,
                         return log_oom();
         }
 
-        r = net_parse_inaddr(address, &n->family, &n->in_addr);
+        r = net_parse_inaddr(address, &n->family, addr);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                            "Address is invalid, ignoring assignment: %s", address);