]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: rework how carrier bindings are serialized
authorLennart Poettering <lennart@poettering.net>
Fri, 19 Feb 2016 19:43:03 +0000 (20:43 +0100)
committerLennart Poettering <lennart@poettering.net>
Sun, 21 Feb 2016 19:40:57 +0000 (20:40 +0100)
Instead of serializing the interface name, expose the interface index, since
that's the only stable identifier.

src/libsystemd/sd-network/sd-network.c
src/network/networkctl.c
src/network/networkd-link.c
src/systemd/sd-network.h

index 26b283f60ddd3ce29cc1feacb47bf953b2ebd56c..037ffb6e751d099b7b64463a310ce52e9c216e1a 100644 (file)
@@ -207,12 +207,66 @@ _public_ int sd_network_link_get_route_domains(int ifindex, char ***ret) {
         return network_link_get_strv(ifindex, "ROUTE_DOMAINS", ret);
 }
 
-_public_ int sd_network_link_get_carrier_bound_to(int ifindex, char ***ret) {
-        return network_link_get_strv(ifindex, "CARRIER_BOUND_TO", ret);
+static int network_link_get_ifindexes(int ifindex, const char *key, int **ret) {
+        _cleanup_free_ char *p = NULL, *s = NULL;
+        _cleanup_strv_free_ char **a = NULL;
+        _cleanup_free_ int *ifis = NULL;
+        size_t allocated = 0, c = 0;
+        const char *x;
+        int r;
+
+        assert_return(ifindex > 0, -EINVAL);
+        assert_return(ret, -EINVAL);
+
+        if (asprintf(&p, "/run/systemd/netif/links/%d", ifindex) < 0)
+                return -ENOMEM;
+
+        r = parse_env_file(p, NEWLINE, key, &s, NULL);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+        if (isempty(s)) {
+                *ret = NULL;
+                return 0;
+        }
+
+        x = s;
+        for (;;) {
+                _cleanup_free_ char *word = NULL;
+
+                r = extract_first_word(&x, &word, NULL, 0);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        break;
+
+                r = parse_ifindex(word, &ifindex);
+                if (r < 0)
+                        return r;
+
+                if (!GREEDY_REALLOC(ifis, allocated, c + 1))
+                        return -ENOMEM;
+
+                ifis[c++] = ifindex;
+        }
+
+        if (!GREEDY_REALLOC(ifis, allocated, c + 1))
+                return -ENOMEM;
+        ifis[c] = 0; /* Let's add a 0 ifindex to the end, to be nice*/
+
+        *ret = ifis;
+        ifis = NULL;
+
+        return c;
+}
+
+_public_ int sd_network_link_get_carrier_bound_to(int ifindex, int **ret) {
+        return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_TO", ret);
 }
 
-_public_ int sd_network_link_get_carrier_bound_by(int ifindex, char ***ret) {
-        return network_link_get_strv(ifindex, "CARRIER_BOUND_BY", ret);
+_public_ int sd_network_link_get_carrier_bound_by(int ifindex, int **ret) {
+        return network_link_get_ifindexes(ifindex, "CARRIER_BOUND_BY", ret);
 }
 
 static inline int MONITOR_TO_FD(sd_network_monitor *m) {
index c5da24e75bc0f158cb970e61841d40f0da4ad6ea..8abb1eff9a61b32c0ec3e404a92e8dbea1a150bb 100644 (file)
@@ -662,6 +662,30 @@ static int dump_lldp_neighbors(const char *prefix, int ifindex) {
         return c;
 }
 
+static void dump_ifindexes(const char *prefix, const int *ifindexes) {
+        unsigned c;
+
+        assert(prefix);
+
+        if (!ifindexes || ifindexes[0] <= 0)
+                return;
+
+        for (c = 0; ifindexes[c] > 0; c++) {
+                char name[IF_NAMESIZE+1];
+
+                printf("%*s",
+                       (int) strlen(prefix),
+                       c == 0 ? prefix : "");
+
+                if (if_indextoname(ifindexes[c], name))
+                        fputs(name, stdout);
+                else
+                        printf("%i", ifindexes[c]);
+
+                fputc('\n', stdout);
+        }
+}
+
 static void dump_list(const char *prefix, char **l) {
         char **i;
 
@@ -689,8 +713,7 @@ static int link_status_one(
         const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
         const char *on_color_operational, *off_color_operational,
                    *on_color_setup, *off_color_setup;
-        _cleanup_strv_free_ char **carrier_bound_to = NULL;
-        _cleanup_strv_free_ char **carrier_bound_by = NULL;
+        _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
         int r;
 
         assert(rtnl);
@@ -777,8 +800,8 @@ static int link_status_one(
 
         dump_list("             NTP: ", ntp);
 
-        dump_list("Carrier Bound To: ", carrier_bound_to);
-        dump_list("Carrier Bound By: ", carrier_bound_by);
+        dump_ifindexes("Carrier Bound To: ", carrier_bound_to);
+        dump_ifindexes("Carrier Bound By: ", carrier_bound_by);
 
         (void) sd_network_link_get_timezone(info->ifindex, &tz);
         if (tz)
index 02fb04e0cb61995cfe9a5ce24f2de69458faf8c5..32437d21959d82787c3954b32b8151162b3c286e 100644 (file)
@@ -1622,7 +1622,7 @@ static int link_new_bound_by_list(Link *link) {
 
         m = link->manager;
 
-        HASHMAP_FOREACH (carrier, m->links, i) {
+        HASHMAP_FOREACH(carrier, m->links, i) {
                 if (!carrier->network)
                         continue;
 
@@ -1641,7 +1641,7 @@ static int link_new_bound_by_list(Link *link) {
         if (list_updated)
                 link_dirty(link);
 
-        HASHMAP_FOREACH (carrier, link->bound_by_links, i) {
+        HASHMAP_FOREACH(carrier, link->bound_by_links, i) {
                 r = link_put_carrier(carrier, link, &carrier->bound_to_links);
                 if (r < 0)
                         return r;
@@ -2631,7 +2631,6 @@ int link_carrier_reset(Link *link) {
         return 0;
 }
 
-
 int link_update(Link *link, sd_netlink_message *m) {
         struct ether_addr mac;
         const char *ifname;
@@ -2752,12 +2751,34 @@ int link_update(Link *link, sd_netlink_message *m) {
                 r = link_carrier_lost(link);
                 if (r < 0)
                         return r;
-
         }
 
         return 0;
 }
 
+static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
+        bool space = false;
+        Iterator i;
+        Link *link;
+
+        assert(f);
+        assert(prefix);
+
+        if (hashmap_isempty(h))
+                return;
+
+        fputs(prefix, f);
+        HASHMAP_FOREACH(link, h, i) {
+                if (space)
+                        fputc(' ', f);
+
+                fprintf(f, "%i", link->ifindex);
+                space = true;
+        }
+
+        fputc('\n', f);
+}
+
 int link_save(Link *link) {
         _cleanup_free_ char *temp_path = NULL;
         _cleanup_fclose_ FILE *f = NULL;
@@ -2958,27 +2979,8 @@ int link_save(Link *link) {
                 fputc('\n', f);
         }
 
-        if (!hashmap_isempty(link->bound_to_links)) {
-                Link *carrier;
-                bool space = false;
-
-                fputs("CARRIER_BOUND_TO=", f);
-                HASHMAP_FOREACH(carrier, link->bound_to_links, i)
-                        fputs_with_space(f, carrier->ifname, NULL, &space);
-
-                fputc('\n', f);
-        }
-
-        if (!hashmap_isempty(link->bound_by_links)) {
-                Link *carrier;
-                bool space = false;
-
-                fputs("CARRIER_BOUND_BY=", f);
-                HASHMAP_FOREACH(carrier, link->bound_by_links, i)
-                        fputs_with_space(f, carrier->ifname, NULL, &space);
-
-                fputc('\n', f);
-        }
+        print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
+        print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);
 
         if (link->dhcp_lease) {
                 struct in_addr address;
index 56986c984d153ec245cbdeea7ac6ae9043adc5e4..0f13e2bae78bbf7fcae8981acf6187fab2014671 100644 (file)
@@ -99,11 +99,11 @@ int sd_network_link_get_network_file(int ifindex, char **filename);
 
 /* Get DNS entries for a given link. These are string representations of
  * IP addresses */
-int sd_network_link_get_dns(int ifindex, char ***addr);
+int sd_network_link_get_dns(int ifindex, char ***ret);
 
 /* Get NTP entries for a given link. These are domain names or string
  * representations of IP addresses */
-int sd_network_link_get_ntp(int ifindex, char ***addr);
+int sd_network_link_get_ntp(int ifindex, char ***ret);
 
 /* Indicates whether or not LLMNR should be enabled for the link
  * Possible levels of support: yes, no, resolve
@@ -139,11 +139,11 @@ int sd_network_link_get_search_domains(int ifindex, char ***domains);
 /* Get the route DNS domain names for a given link. */
 int sd_network_link_get_route_domains(int ifindex, char ***domains);
 
-/* Get the CARRIERS to which current link is bound to. */
-int sd_network_link_get_carrier_bound_to(int ifindex, char ***carriers);
+/* Get the carrier interface indexes to which current link is bound to. */
+int sd_network_link_get_carrier_bound_to(int ifindex, int **ifindexes);
 
 /* Get the CARRIERS that are bound to current link. */
-int sd_network_link_get_carrier_bound_by(int ifindex, char ***carriers);
+int sd_network_link_get_carrier_bound_by(int ifindex, int **ifindexes);
 
 /* Get the timezone that was learnt on a specific link. */
 int sd_network_link_get_timezone(int ifindex, char **timezone);