]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkctl: display address labels
authorSusant Sahani <susant@redhat.com>
Mon, 26 Jun 2017 17:58:10 +0000 (23:28 +0530)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 27 Jun 2017 14:15:27 +0000 (10:15 -0400)
```
 ./networkctl label

    Prefix/Prefixlen                          Label
        ::/0                                  1
    fc00::/7                                  5
    fec0::/10                                11
    2002::/16                                 2
    3ffe::/16                                12
 2001:10::/28                                 7
    2001::/32                                 6
::ffff:0.0.0.0/96                                 4
        ::/96                                 3
       ::1/128                                0

```

src/libsystemd/sd-netlink/netlink-message.c
src/libsystemd/sd-netlink/rtnl-message.c
src/network/networkctl.c
src/systemd/sd-netlink.h

index 654a22fe3b5c74e1418747930f41def282809a2e..e8c8abac2ae352efe29623c0610a5e56686943a7 100644 (file)
@@ -104,7 +104,8 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
         assert_return(m->hdr->nlmsg_type == RTM_GETLINK  ||
                       m->hdr->nlmsg_type == RTM_GETADDR  ||
                       m->hdr->nlmsg_type == RTM_GETROUTE ||
-                      m->hdr->nlmsg_type == RTM_GETNEIGH,
+                      m->hdr->nlmsg_type == RTM_GETNEIGH ||
+                      m->hdr->nlmsg_type == RTM_GETADDRLABEL ,
                       -EINVAL);
 
         SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
index d5f8b7d15eb04a77e0fc2db8e4e261134881201c..12c51ffe2e6728a5126a25fa75b7f9b847701ee8 100644 (file)
@@ -740,3 +740,17 @@ int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char
 
         return 0;
 }
+
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
+        struct ifaddrlblmsg *addrlabel;
+
+        assert_return(m, -EINVAL);
+        assert_return(m->hdr, -EINVAL);
+        assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
+
+        addrlabel = NLMSG_DATA(m->hdr);
+
+        *prefixlen = addrlabel->ifal_prefixlen;
+
+        return 0;
+}
index 6f7f41bf7d2c5e8f98249b013308e92936e39662..54d54c8fd5939263dbe367e777bc7e9b3a14fca5 100644 (file)
@@ -18,6 +18,7 @@
 ***/
 
 #include <getopt.h>
+#include <linux/if_addrlabel.h>
 #include <net/if.h>
 #include <stdbool.h>
 
@@ -35,6 +36,7 @@
 #include "hwdb-util.h"
 #include "local-addresses.h"
 #include "locale-util.h"
+#include "macro.h"
 #include "netlink-util.h"
 #include "pager.h"
 #include "parse-util.h"
@@ -569,6 +571,76 @@ static int dump_addresses(
         return 0;
 }
 
+static int dump_address_labels(sd_netlink *rtnl) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
+        sd_netlink_message *m;
+        int r;
+
+        assert(rtnl);
+
+        r = sd_rtnl_message_new_addrlabel(rtnl, &req, RTM_GETADDRLABEL, 0, AF_INET6);
+        if (r < 0)
+                return log_error_errno(r, "Could not allocate RTM_GETADDRLABEL message: %m");
+
+        r = sd_netlink_message_request_dump(req, true);
+        if (r < 0)
+                return r;
+
+        r = sd_netlink_call(rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        printf("%10s/%s %30s\n", "Prefix", "Prefixlen", "Label");
+
+        for (m = reply; m; m = sd_netlink_message_next(m)) {
+                _cleanup_free_ char *pretty = NULL;
+                union in_addr_union prefix = {};
+                uint8_t prefixlen;
+                uint32_t label;
+
+                r = sd_netlink_message_get_errno(m);
+                if (r < 0) {
+                        log_error_errno(r, "got error: %m");
+                        continue;
+                }
+
+                r = sd_netlink_message_read_u32(m, IFAL_LABEL, &label);
+                if (r < 0 && r != -ENODATA) {
+                        log_error_errno(r, "Could not read IFAL_LABEL, ignoring: %m");
+                        continue;
+                }
+
+                r = sd_netlink_message_read_in6_addr(m, IFAL_ADDRESS, &prefix.in6);
+                if (r < 0)
+                        continue;
+
+                r = in_addr_to_string(AF_INET6, &prefix, &pretty);
+                if (r < 0)
+                        continue;
+
+                r = sd_rtnl_message_addrlabel_get_prefixlen(m, &prefixlen);
+                if (r < 0)
+                        continue;
+
+                printf("%10s/%-5u %30u\n", pretty, prefixlen, label);
+        }
+
+        return 0;
+}
+
+static int list_address_labels(int argc, char *argv[], void *userdata) {
+        _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+        int r;
+
+        r = sd_netlink_open(&rtnl);
+        if (r < 0)
+                return log_error_errno(r, "Failed to connect to netlink: %m");
+
+        dump_address_labels(rtnl);
+
+        return 0;
+}
+
 static int open_lldp_neighbors(int ifindex, FILE **ret) {
         _cleanup_free_ char *p = NULL;
         FILE *f;
@@ -1043,6 +1115,7 @@ static void help(void) {
                "  list [LINK...]        List links\n"
                "  status [LINK...]      Show link status\n"
                "  lldp [LINK...]        Show LLDP neighbors\n"
+               "  label                 Show current address label entries in the kernel\n"
                , program_invocation_short_name);
 }
 
@@ -1107,6 +1180,7 @@ static int networkctl_main(int argc, char *argv[]) {
                 { "list",   VERB_ANY, VERB_ANY, VERB_DEFAULT, list_links       },
                 { "status", VERB_ANY, VERB_ANY, 0,            link_status      },
                 { "lldp",   VERB_ANY, VERB_ANY, 0,            link_lldp_status },
+                { "label",  VERB_ANY, VERB_ANY, 0,            list_address_labels},
                 {}
         };
 
index aa39e0a0db8e1f7cf63ed55e729bd3f1ed1645aa..3f5a6673cf54fe41087c7f32cc05c32c3db0b698 100644 (file)
@@ -157,6 +157,7 @@ int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags);
 
 int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family);
 int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen);
 
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref);