chiark / gitweb /
resolved: add daemon to manage resolv.conf
[elogind.git] / src / network / networkd-link.c
index 8dd742a3faeee867653b97329afdc9f9ddffed8e..5a7472ba24a09dcdb2337fbf4f8b2d37de0cb493 100644 (file)
@@ -96,11 +96,18 @@ static int link_new(Manager *manager, sd_rtnl_message *message, Link **ret) {
 }
 
 static void link_free(Link *link) {
+        Address *address;
+
         if (!link)
                 return;
 
         assert(link->manager);
 
+        while ((address = link->addresses)) {
+                LIST_REMOVE(addresses, link->addresses, address);
+                address_free(address);
+        }
+
         sd_dhcp_client_unref(link->dhcp_client);
         sd_dhcp_lease_unref(link->dhcp_lease);
 
@@ -291,7 +298,7 @@ static int link_enter_set_routes(Link *link) {
 
         log_debug_link(link, "setting routes");
 
-        LIST_FOREACH(static_routes, rt, link->network->static_routes) {
+        LIST_FOREACH(routes, rt, link->network->static_routes) {
                 r = route_configure(rt, link, &route_handler);
                 if (r < 0) {
                         log_warning_link(link,
@@ -487,7 +494,7 @@ static int link_enter_set_addresses(Link *link) {
 
         log_debug_link(link, "setting addresses");
 
-        LIST_FOREACH(static_addresses, ad, link->network->static_addresses) {
+        LIST_FOREACH(addresses, ad, link->network->static_addresses) {
                 r = address_configure(ad, link, &address_handler);
                 if (r < 0) {
                         log_warning_link(link,
@@ -847,8 +854,6 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
         struct in_addr netmask;
         struct in_addr gateway;
         unsigned prefixlen;
-        struct in_addr *nameservers;
-        size_t nameservers_size;
         int r;
 
         assert(client);
@@ -913,15 +918,6 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
 
         link->dhcp_lease = lease;
 
-        if (link->network->dhcp_dns) {
-                r = sd_dhcp_lease_get_dns(lease, &nameservers, &nameservers_size);
-                if (r >= 0) {
-                        r = manager_update_resolv_conf(link->manager);
-                        if (r < 0)
-                                log_error_link(link, "Failed to update resolv.conf");
-                }
-        }
-
         if (link->network->dhcp_mtu) {
                 uint16_t mtu;
 
@@ -1690,7 +1686,7 @@ int link_initialized(Link *link, struct udev_device *device) {
         if (device)
                 link->udev_device = udev_device_ref(device);
 
-        log_debug_link(link, "link initialized");
+        log_debug_link(link, "udev initialized link");
 
         r = network_get(link->manager, device, link->ifname, &link->mac, &network);
         if (r == -ENOENT) {
@@ -1715,7 +1711,9 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
         Link *link = NULL;
         uint16_t type;
         _cleanup_address_free_ Address *address = NULL;
+        Address *ad;
         char buf[INET6_ADDRSTRLEN];
+        bool address_dropped = false;
         int r, ifindex;
 
         assert(rtnl);
@@ -1784,15 +1782,33 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message, void *use
                 return 0;
         }
 
+        LIST_FOREACH(addresses, ad, link->addresses) {
+                if (address_equal(ad, address)) {
+                        LIST_REMOVE(addresses, link->addresses, ad);
+
+                        address_free(ad);
+
+                        address_dropped = true;
+
+                        break;
+                }
+        }
+
         switch (type) {
         case RTM_NEWADDR:
-                log_info_link(link, "added address: %s/%u", buf,
-                              address->prefixlen);
-                break;
+                if (!address_dropped)
+                        log_debug_link(link, "added address: %s/%u", buf,
+                                      address->prefixlen);
 
+                LIST_PREPEND(addresses, link->addresses, address);
+                address = NULL;
+
+                break;
         case RTM_DELADDR:
-                log_info_link(link, "removed address: %s/%u", buf,
-                              address->prefixlen);
+                if (address_dropped)
+                        log_debug_link(link, "removed address: %s/%u", buf,
+                                      address->prefixlen);
+
                 break;
         default:
                 assert_not_reached("Received invalid RTNL message type");
@@ -1861,9 +1877,11 @@ int link_add(Manager *m, sd_rtnl_message *message, Link **ret) {
                         return -errno;
                 }
 
-                if (udev_device_get_is_initialized(device) <= 0)
+                if (udev_device_get_is_initialized(device) <= 0) {
                         /* not yet ready */
+                        log_debug_link(link, "udev initializing link...");
                         return 0;
+                }
         }
 
         r = link_initialized(link, device);
@@ -1947,6 +1965,27 @@ int link_update(Link *link, sd_rtnl_message *m) {
         return link_update_flags(link, m);
 }
 
+static void serialize_addresses(FILE *f, const char *key, Address *address) {
+        Address *ad;
+
+        assert(f);
+        assert(key);
+
+        if (!address)
+                return;
+
+        fprintf(f, "%s=", key);
+
+        LIST_FOREACH(addresses, ad, address) {
+                char buf[INET6_ADDRSTRLEN];
+
+                if (inet_ntop(address->family, &address->in_addr, buf, INET6_ADDRSTRLEN))
+                        fprintf(f, "%s%s", buf, (ad->addresses_next) ? " ": "");
+        }
+
+        fputs("\n", f);
+}
+
 int link_save(Link *link) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -1988,12 +2027,18 @@ int link_save(Link *link) {
                 "FLAGS=%u\n",
                 admin_state, oper_state, link->flags);
 
+        if (link->network)
+                serialize_addresses(f, "DNS", link->network->dns);
+
         if (link->dhcp_lease) {
                 r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
                 if (r < 0)
                         goto finish;
 
-                fprintf(f, "DHCP_LEASE=%s\n", link->lease_file);
+                fprintf(f,
+                        "DHCP_LEASE=%s\n"
+                        "DHCP_USE_DNS=%s\n",
+                        link->lease_file, yes_no(link->network->dhcp_dns));
         } else
                 unlink(link->lease_file);