]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: link - deserialize
authorTom Gundersen <teg@jklm.no>
Thu, 1 Oct 2015 19:14:06 +0000 (21:14 +0200)
committerTom Gundersen <teg@jklm.no>
Fri, 30 Oct 2015 11:32:49 +0000 (12:32 +0100)
For now only deserialize some basic state and the applied addresses.

When a link is added, try to deserialize it's state from /run. This
is relevant only when networkd is restarted at runtime.

src/network/networkd-address.c
src/network/networkd-address.h
src/network/networkd-link.c
src/network/networkd-network.c

index 5b5492e02ee1b88485e977e4f611cafcf2fb6206..8b6acf2e1d7eee47803c0aff51fb335ab45dc04e 100644 (file)
@@ -271,7 +271,7 @@ int address_add_foreign(Link *link, int family, const union in_addr_union *in_ad
         return address_add_internal(link, &link->addresses_foreign, family, in_addr, prefixlen, ret);
 }
 
-static int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
+int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret) {
         Address *address;
         int r;
 
index fd309bebb69c2495ba52d10bf064374e8f60684b..0b1f3b688bcb6cf91ef59c13987b11a6fe6299da 100644 (file)
@@ -62,6 +62,7 @@ int address_new_static(Network *network, unsigned section, Address **ret);
 int address_new(Address **ret);
 void address_free(Address *address);
 int address_add_foreign(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret);
+int address_add(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret);
 int address_get(Link *link, int family, const union in_addr_union *in_addr, unsigned char prefixlen, Address **ret);
 int address_update(Address *address, unsigned char flags, unsigned char scope, struct ifa_cacheinfo *cinfo);
 int address_drop(Address *address);
index c5be599ecdc93847eb8f429995aa2c626dcb2cac..4243f8cba9b5478e00ee6ea9c10ac4d81727049a 100644 (file)
@@ -2057,28 +2057,30 @@ static int link_initialized_and_synced(sd_netlink *rtnl, sd_netlink_message *m,
         if (r < 0)
                 return r;
 
-        r = network_get(link->manager, link->udev_device, link->ifname,
-                        &link->mac, &network);
-        if (r == -ENOENT) {
-                link_enter_unmanaged(link);
-                return 1;
-        } else if (r < 0)
-                return r;
+        if (!link->network) {
+                r = network_get(link->manager, link->udev_device, link->ifname,
+                                &link->mac, &network);
+                if (r == -ENOENT) {
+                        link_enter_unmanaged(link);
+                        return 1;
+                } else if (r < 0)
+                        return r;
 
-        if (link->flags & IFF_LOOPBACK) {
-                if (network->link_local != ADDRESS_FAMILY_NO)
-                        log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
+                if (link->flags & IFF_LOOPBACK) {
+                        if (network->link_local != ADDRESS_FAMILY_NO)
+                                log_link_debug(link, "Ignoring link-local autoconfiguration for loopback link");
 
-                if (network->dhcp != ADDRESS_FAMILY_NO)
-                        log_link_debug(link, "Ignoring DHCP clients for loopback link");
+                        if (network->dhcp != ADDRESS_FAMILY_NO)
+                                log_link_debug(link, "Ignoring DHCP clients for loopback link");
 
-                if (network->dhcp_server)
-                        log_link_debug(link, "Ignoring DHCP server for loopback link");
-        }
+                        if (network->dhcp_server)
+                                log_link_debug(link, "Ignoring DHCP server for loopback link");
+                }
 
-        r = network_apply(link->manager, network, link);
-        if (r < 0)
-                return r;
+                r = network_apply(link->manager, network, link);
+                if (r < 0)
+                        return r;
+        }
 
         r = link_new_bound_to_list(link);
         if (r < 0)
@@ -2130,6 +2132,87 @@ int link_initialized(Link *link, struct udev_device *device) {
         return 0;
 }
 
+static int link_load(Link *link) {
+        _cleanup_free_ char *network_file = NULL, *addresses = NULL;
+        int r;
+
+        assert(link);
+
+        r = parse_env_file(link->state_file, NEWLINE,
+                           "NETWORK_FILE", &network_file,
+                           "ADDRESSES", &addresses,
+                           NULL);
+        if (r < 0 && r != -ENOENT)
+                return log_link_error_errno(link, r, "Failed to read %s: %m", link->state_file);
+
+        if (network_file) {
+                Network *network;
+                char *suffix;
+
+                /* drop suffix */
+                suffix = strrchr(network_file, '.');
+                if (!suffix) {
+                        log_link_debug(link, "Failed to get network name from %s", network_file);
+                        goto network_file_fail;
+                }
+                *suffix = '\0';
+
+                r = network_get_by_name(link->manager, basename(network_file), &network);
+                if (r < 0) {
+                        log_link_debug_errno(link, r, "Failed to get network %s: %m", basename(network_file));
+                        goto network_file_fail;
+                }
+
+                r = network_apply(link->manager, network, link);
+                if (r < 0)
+                        return log_link_error_errno(link, r, "Failed to apply network %s: %m", basename(network_file));
+        }
+
+network_file_fail:
+
+        if (addresses) {
+                _cleanup_strv_free_ char **addresses_strv = NULL;
+                char **address_str;
+
+                addresses_strv = strv_split(addresses, " ");
+                if (!addresses_strv)
+                        return log_oom();
+
+                STRV_FOREACH(address_str, addresses_strv) {
+                        char *prefixlen_str;
+                        int family;
+                        unsigned char prefixlen;
+                        union in_addr_union address;
+
+                        prefixlen_str = strchr(*address_str, '/');
+                        if (!prefixlen_str) {
+                                log_link_debug(link, "Failed to parse address and prefix length %s", *address_str);
+                                continue;
+                        }
+
+                        *prefixlen_str ++ = '\0';
+
+                        r = sscanf(prefixlen_str, "%hhu", &prefixlen);
+                        if (r != 1) {
+                                log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
+                                continue;
+                        }
+
+                        r = in_addr_from_string_auto(*address_str, &family, &address);
+                        if (r < 0) {
+                                log_link_debug_errno(link, r, "Failed to parse address %s: %m", *address_str);
+                                continue;
+                        }
+
+                        r = address_add(link, family, &address, prefixlen, NULL);
+                        if (r < 0)
+                                return log_link_error_errno(link, r, "Failed to add address: %m");
+                }
+        }
+
+        return 0;
+}
+
 int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
         Link *link;
         _cleanup_udev_device_unref_ struct udev_device *device = NULL;
@@ -2149,6 +2232,10 @@ int link_add(Manager *m, sd_netlink_message *message, Link **ret) {
 
         log_link_debug(link, "Link %d added", link->ifindex);
 
+        r = link_load(link);
+        if (r < 0)
+                return r;
+
         if (detect_container() <= 0) {
                 /* not in a container, udev will be around */
                 sprintf(ifindex_str, "n%d", link->ifindex);
index 14c201e9a55ec6ba36f526422ddf718c65c3b932..0188cb6fe5fb6cfe27aa3f4cb0ff5216e9ed8e1d 100644 (file)
@@ -352,6 +352,10 @@ int network_get(Manager *manager, struct udev_device *device,
 int network_apply(Manager *manager, Network *network, Link *link) {
         int r;
 
+        assert(manager);
+        assert(network);
+        assert(link);
+
         link->network = network;
 
         if (network->ipv4ll_route) {