]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkctl: rework interface data acquisition
authorLennart Poettering <lennart@poettering.net>
Fri, 19 Feb 2016 18:18:12 +0000 (19:18 +0100)
committerLennart Poettering <lennart@poettering.net>
Sun, 21 Feb 2016 19:40:57 +0000 (20:40 +0100)
Let's always use the same calls to acquire interface data. Specifically port
"networkctl status" to use acquire_link_info_strv() and acquire_link_info_all()
like the other calls.

src/network/networkctl.c

index d19bf131cdab7400c8c0ffc88d6be9153f58a4eb..144e52cbfa37bc98066bae6a054b57c1f7e8eb8c 100644 (file)
@@ -110,6 +110,11 @@ typedef struct LinkInfo {
         char name[IFNAMSIZ+1];
         int ifindex;
         unsigned short iftype;
+        struct ether_addr mac_address;
+        uint32_t mtu;
+
+        bool has_mac_address:1;
+        bool has_mtu:1;
 } LinkInfo;
 
 static int link_info_compare(const void *a, const void *b) {
@@ -119,10 +124,10 @@ static int link_info_compare(const void *a, const void *b) {
 }
 
 static int decode_link_one(sd_netlink_message *m, LinkInfo *info) {
+        static const struct ether_addr null_address = {};
         const char *name;
-        unsigned short iftype;
         uint16_t type;
-        int ifindex, r;
+        int r;
 
         assert(m);
         assert(info);
@@ -134,7 +139,7 @@ static int decode_link_one(sd_netlink_message *m, LinkInfo *info) {
         if (type != RTM_NEWLINK)
                 return 0;
 
-        r = sd_rtnl_message_link_get_ifindex(m, &ifindex);
+        r = sd_rtnl_message_link_get_ifindex(m, &info->ifindex);
         if (r < 0)
                 return r;
 
@@ -142,13 +147,19 @@ static int decode_link_one(sd_netlink_message *m, LinkInfo *info) {
         if (r < 0)
                 return r;
 
-        r = sd_rtnl_message_link_get_type(m, &iftype);
+        r = sd_rtnl_message_link_get_type(m, &info->iftype);
         if (r < 0)
                 return r;
 
         strncpy(info->name, name, sizeof(info->name));
-        info->ifindex = ifindex;
-        info->iftype = iftype;
+
+        info->has_mac_address =
+                sd_netlink_message_read_ether_addr(m, IFLA_ADDRESS, &info->mac_address) >= 0 &&
+                memcmp(&info->mac_address, &null_address, sizeof(struct ether_addr)) != 0;
+
+        info->has_mtu =
+                sd_netlink_message_read_u32(m, IFLA_MTU, &info->mtu) &&
+                info->mtu > 0;
 
         return 1;
 }
@@ -209,23 +220,19 @@ static void setup_state_to_color(const char *state, const char **on, const char
                 *on = *off = "";
 }
 
-static int acquire_link_info_strv(char **l, LinkInfo **ret) {
+static int acquire_link_info_strv(sd_netlink *rtnl, char **l, LinkInfo **ret) {
         _cleanup_free_ LinkInfo *links = NULL;
-        _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         char **i;
         size_t c = 0;
         int r;
 
+        assert(rtnl);
         assert(ret);
 
         links = new(LinkInfo, strv_length(l));
         if (!links)
                 return log_oom();
 
-        r = sd_netlink_open(&rtnl);
-        if (r < 0)
-                return log_error_errno(r, "Failed to connect to netlink: %m");
-
         STRV_FOREACH(i, l) {
                 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
                 int ifindex;
@@ -261,18 +268,13 @@ static int acquire_link_info_strv(char **l, LinkInfo **ret) {
         return (int) c;
 }
 
-static int acquire_link_info_all(LinkInfo **ret) {
+static int acquire_link_info_all(sd_netlink *rtnl, LinkInfo **ret) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
-
         int r;
 
+        assert(rtnl);
         assert(ret);
 
-        r = sd_netlink_open(&rtnl);
-        if (r < 0)
-                return log_error_errno(r, "Failed to connect to netlink: %m");
-
         r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
         if (r < 0)
                 return rtnl_log_create_error(r);
@@ -293,13 +295,18 @@ static int acquire_link_info_all(LinkInfo **ret) {
 }
 
 static int list_links(int argc, char *argv[], void *userdata) {
+        _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         _cleanup_free_ LinkInfo *links = NULL;
-        int c, i;
+        int c, i, r;
+
+        r = sd_netlink_open(&rtnl);
+        if (r < 0)
+                return log_error_errno(r, "Failed to connect to netlink: %m");
 
         if (argc > 1)
-                c = acquire_link_info_strv(argv + 1, &links);
+                c = acquire_link_info_strv(rtnl, argv + 1, &links);
         else
-                c = acquire_link_info_all(&links);
+                c = acquire_link_info_all(rtnl, &links);
         if (c < 0)
                 return c;
 
@@ -345,7 +352,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
 }
 
 /* IEEE Organizationally Unique Identifier vendor string */
-static int ieee_oui(sd_hwdb *hwdb, struct ether_addr *mac, char **ret) {
+static int ieee_oui(sd_hwdb *hwdb, const struct ether_addr *mac, char **ret) {
         const char *description;
         char modalias[strlen("OUI:XXYYXXYYXXYY") + 1], *desc;
         int r;
@@ -590,10 +597,10 @@ static void dump_list(const char *prefix, char **l) {
 static int link_status_one(
                 sd_netlink *rtnl,
                 sd_hwdb *hwdb,
-                const char *name) {
+                const LinkInfo *info) {
+
         _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
         _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
         _cleanup_(sd_device_unrefp) sd_device *d = NULL;
         char devid[2 + DECIMAL_STR_MAX(int)];
         _cleanup_free_ char *t = NULL, *network = NULL;
@@ -602,72 +609,23 @@ static int link_status_one(
                    *on_color_setup, *off_color_setup;
         _cleanup_strv_free_ char **carrier_bound_to = NULL;
         _cleanup_strv_free_ char **carrier_bound_by = NULL;
-        struct ether_addr e;
-        unsigned short iftype;
-        int r, ifindex;
-        bool have_mac;
-        uint32_t mtu;
+        int r;
 
         assert(rtnl);
-        assert(name);
-
-        if (parse_ifindex(name, &ifindex) >= 0)
-                r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, ifindex);
-        else {
-                r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
-                if (r < 0)
-                        return rtnl_log_create_error(r);
-
-                r = sd_netlink_message_append_string(req, IFLA_IFNAME, name);
-        }
-        if (r < 0)
-                return rtnl_log_create_error(r);
-
-        r = sd_netlink_call(rtnl, req, 0, &reply);
-        if (r < 0)
-                return log_error_errno(r, "Failed to query link: %m");
-
-        r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
-        if (r < 0)
-                return rtnl_log_parse_error(r);
-
-        r = sd_netlink_message_read_string(reply, IFLA_IFNAME, &name);
-        if (r < 0)
-                return rtnl_log_parse_error(r);
-
-        r = sd_rtnl_message_link_get_type(reply, &iftype);
-        if (r < 0)
-                return rtnl_log_parse_error(r);
-
-        have_mac = sd_netlink_message_read_ether_addr(reply, IFLA_ADDRESS, &e) >= 0;
-        if (have_mac) {
-                const uint8_t *p;
-                bool all_zeroes = true;
-
-                for (p = (uint8_t*) &e; p < (uint8_t*) &e + sizeof(e); p++)
-                        if (*p != 0) {
-                                all_zeroes = false;
-                                break;
-                        }
-
-                if (all_zeroes)
-                        have_mac = false;
-        }
-
-        (void) sd_netlink_message_read_u32(reply, IFLA_MTU, &mtu);
+        assert(info);
 
-        (void) sd_network_link_get_operational_state(ifindex, &operational_state);
+        (void) sd_network_link_get_operational_state(info->ifindex, &operational_state);
         operational_state_to_color(operational_state, &on_color_operational, &off_color_operational);
 
-        (void) sd_network_link_get_setup_state(ifindex, &setup_state);
+        (void) sd_network_link_get_setup_state(info->ifindex, &setup_state);
         setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
 
-        (void) sd_network_link_get_dns(ifindex, &dns);
-        (void) sd_network_link_get_search_domains(ifindex, &search_domains);
-        (void) sd_network_link_get_route_domains(ifindex, &route_domains);
-        (void) sd_network_link_get_ntp(ifindex, &ntp);
+        (void) sd_network_link_get_dns(info->ifindex, &dns);
+        (void) sd_network_link_get_search_domains(info->ifindex, &search_domains);
+        (void) sd_network_link_get_route_domains(info->ifindex, &route_domains);
+        (void) sd_network_link_get_ntp(info->ifindex, &ntp);
 
-        sprintf(devid, "n%i", ifindex);
+        sprintf(devid, "n%i", info->ifindex);
 
         (void) sd_device_new_from_device_id(&d, devid);
 
@@ -685,14 +643,14 @@ static int link_status_one(
                         (void) sd_device_get_property_value(d, "ID_MODEL", &model);
         }
 
-        link_get_type_string(iftype, d, &t);
+        link_get_type_string(info->iftype, d, &t);
 
-        sd_network_link_get_network_file(ifindex, &network);
+        sd_network_link_get_network_file(info->ifindex, &network);
 
-        sd_network_link_get_carrier_bound_to(ifindex, &carrier_bound_to);
-        sd_network_link_get_carrier_bound_by(ifindex, &carrier_bound_by);
+        sd_network_link_get_carrier_bound_to(info->ifindex, &carrier_bound_to);
+        sd_network_link_get_carrier_bound_by(info->ifindex, &carrier_bound_by);
 
-        printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, ifindex, name);
+        printf("%s%s%s %i: %s\n", on_color_operational, draw_special_char(DRAW_BLACK_CIRCLE), off_color_operational, info->ifindex, info->name);
 
         printf("       Link File: %s\n"
                "    Network File: %s\n"
@@ -713,23 +671,23 @@ static int link_status_one(
         if (model)
                 printf("           Model: %s\n", model);
 
-        if (have_mac) {
+        if (info->has_mac_address) {
                 _cleanup_free_ char *description = NULL;
                 char ea[ETHER_ADDR_TO_STRING_MAX];
 
-                ieee_oui(hwdb, &e, &description);
+                ieee_oui(hwdb, &info->mac_address, &description);
 
                 if (description)
-                        printf("      HW Address: %s (%s)\n", ether_addr_to_string(&e, ea), description);
+                        printf("      HW Address: %s (%s)\n", ether_addr_to_string(&info->mac_address, ea), description);
                 else
-                        printf("      HW Address: %s\n", ether_addr_to_string(&e, ea));
+                        printf("      HW Address: %s\n", ether_addr_to_string(&info->mac_address, ea));
         }
 
-        if (mtu > 0)
-                printf("             MTU: %u\n", mtu);
+        if (info->has_mtu)
+                printf("             MTU: %u\n", info->mtu);
 
-        dump_addresses(rtnl, "         Address: ", ifindex);
-        dump_gateways(rtnl, hwdb, "         Gateway: ", ifindex);
+        dump_addresses(rtnl, "         Address: ", info->ifindex);
+        dump_gateways(rtnl, hwdb, "         Gateway: ", info->ifindex);
 
         dump_list("             DNS: ", dns);
         dump_list("  Search Domains: ", search_domains);
@@ -740,7 +698,7 @@ static int link_status_one(
         dump_list("Carrier Bound To: ", carrier_bound_to);
         dump_list("Carrier Bound By: ", carrier_bound_by);
 
-        (void) sd_network_link_get_timezone(ifindex, &tz);
+        (void) sd_network_link_get_timezone(info->ifindex, &tz);
         if (tz)
                 printf("       Time Zone: %s", tz);
 
@@ -780,10 +738,10 @@ static int system_status(sd_netlink *rtnl, sd_hwdb *hwdb) {
 }
 
 static int link_status(int argc, char *argv[], void *userdata) {
-        _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
-        char **name;
-        int r;
+        _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
+        _cleanup_free_ LinkInfo *links = NULL;
+        int r, c, i;
 
         pager_open_if_enabled();
 
@@ -795,43 +753,20 @@ static int link_status(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 log_debug_errno(r, "Failed to open hardware database: %m");
 
-        if (argc <= 1 && !arg_all)
+        if (arg_all)
+                c = acquire_link_info_all(rtnl, &links);
+        else if (argc <= 1)
                 return system_status(rtnl, hwdb);
+        else
+                c = acquire_link_info_strv(rtnl, argv + 1, &links);
+        if (c < 0)
+                return c;
 
-        if (arg_all) {
-                _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-                _cleanup_free_ LinkInfo *links = NULL;
-                int c, i;
-
-                r = sd_rtnl_message_new_link(rtnl, &req, RTM_GETLINK, 0);
-                if (r < 0)
-                        return rtnl_log_create_error(r);
-
-                r = sd_netlink_message_request_dump(req, true);
-                if (r < 0)
-                        return rtnl_log_create_error(r);
-
-                r = sd_netlink_call(rtnl, req, 0, &reply);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to enumerate links: %m");
-
-                c = decode_and_sort_links(reply, &links);
-                if (c < 0)
-                        return rtnl_log_parse_error(c);
-
-                for (i = 0; i < c; i++) {
-                        if (i > 0)
-                                fputc('\n', stdout);
-
-                        link_status_one(rtnl, hwdb, links[i].name);
-                }
-        } else {
-                STRV_FOREACH(name, argv + 1) {
-                        if (name != argv + 1)
-                                fputc('\n', stdout);
+        for (i = 0; i < c; i++) {
+                if (i > 0)
+                        fputc('\n', stdout);
 
-                        link_status_one(rtnl, hwdb, *name);
-                }
+                link_status_one(rtnl, hwdb, links + i);
         }
 
         return 0;
@@ -856,13 +791,18 @@ static char *lldp_capabilities_to_string(uint16_t x) {
 }
 
 static int link_lldp_status(int argc, char *argv[], void *userdata) {
+        _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         _cleanup_free_ LinkInfo *links = NULL;
-        int i, r, c, j;
+        int i, r, c, m = 0;
+
+        r = sd_netlink_open(&rtnl);
+        if (r < 0)
+                return log_error_errno(r, "Failed to connect to netlink: %m");
 
         if (argc > 1)
-                c = acquire_link_info_strv(argv + 1, &links);
+                c = acquire_link_info_strv(rtnl, argv + 1, &links);
         else
-                c = acquire_link_info_all(&links);
+                c = acquire_link_info_all(rtnl, &links);
         if (c < 0)
                 return c;
 
@@ -877,7 +817,7 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
                        "PORT ID",
                        "PORT DESCRIPTION");
 
-        for (i = j = 0; i < c; i++) {
+        for (i = 0; i < c; i++) {
                 _cleanup_fclose_ FILE *f = NULL;
                 _cleanup_free_ char *p = NULL;
 
@@ -939,6 +879,8 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
                                strna(capabilities),
                                strna(port_id),
                                strna(port_description));
+
+                        m++;
                 }
         }
 
@@ -947,7 +889,7 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) {
                        "o - Other; p - Repeater;  b - Bridge; w - WLAN Access Point; r - Router;\n"
                        "t - Telephone; d - DOCSIS cable device; a - Station; c - Customer VLAN;\n"
                        "s - Service VLAN, m - Two-port MAC Relay (TPMR)\n\n"
-                       "%i neighbors listed.\n", j);
+                       "%i neighbors listed.\n", m);
 
         return 0;
 }