Re: [PATCH iproute2 V3 3/4] rdma: Add link object

2017-07-11 Thread Leon Romanovsky
On Mon, Jul 10, 2017 at 08:28:28PM +0200, Jiri Pirko wrote:
> Mon, Jul 10, 2017 at 06:22:23PM CEST, l...@kernel.org wrote:
> >On Mon, Jul 10, 2017 at 10:13:07AM +0200, Jiri Pirko wrote:
> >> Tue, Jul 04, 2017 at 09:55:40AM CEST, l...@kernel.org wrote:
> >> >From: Leon Romanovsky 
> >> >
> >> >Link (port) object represent struct ib_port to the user space.
> >> >
> >> >Link properties:
> >> > * Port capabilities
> >> > * IB subnet prefix
> >> > * LID, SM_LID and LMC
> >> > * Port state
> >> > * Physical state
> >> >
> >> >Signed-off-by: Leon Romanovsky 
> >> >---
> >> > rdma/Makefile |   2 +-
> >> > rdma/link.c   | 280 
> >> > ++
> >> > rdma/rdma.c   |   3 +-
> >> > rdma/utils.c  |   5 ++
> >> > 4 files changed, 288 insertions(+), 2 deletions(-)
> >> > create mode 100644 rdma/link.c
> >> >
> >> >diff --git a/rdma/Makefile b/rdma/Makefile
> >> >index 123d7ac5..1a9e4b1a 100644
> >> >--- a/rdma/Makefile
> >> >+++ b/rdma/Makefile
> >> >@@ -2,7 +2,7 @@ include ../Config
> >> >
> >> > ifeq ($(HAVE_MNL),y)
> >> >
> >> >-RDMA_OBJ = rdma.o utils.o dev.o
> >> >+RDMA_OBJ = rdma.o utils.o dev.o link.o
> >> >
> >> > TARGETS=rdma
> >> > CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
> >> >diff --git a/rdma/link.c b/rdma/link.c
> >> >new file mode 100644
> >> >index ..f92b4cef
> >> >--- /dev/null
> >> >+++ b/rdma/link.c
> >> >@@ -0,0 +1,280 @@
> >> >+/*
> >> >+ * link.cRDMA tool
> >> >+ *
> >> >+ *  This program is free software; you can redistribute it 
> >> >and/or
> >> >+ *  modify it under the terms of the GNU General Public 
> >> >License
> >> >+ *  as published by the Free Software Foundation; either 
> >> >version
> >> >+ *  2 of the License, or (at your option) any later version.
> >> >+ *
> >> >+ * Authors: Leon Romanovsky 
> >> >+ */
> >> >+
> >> >+#include "rdma.h"
> >> >+
> >> >+static int link_help(struct rdma *rd)
> >> >+{
> >> >+ pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
> >> >+ return 0;
> >> >+}
> >> >+
> >> >+static void link_print_caps(struct nlattr **tb)
> >> >+{
> >> >+ uint64_t caps;
> >> >+ uint32_t idx;
> >> >+
> >> >+ /*
> >> >+  * FIXME: move to indexes when kernel will start exporting them.
> >>
> >> Not exported yet?
> >
> >Not yet, I want to minimize the UAPI export from kernel before user-space
> >part is accepted.
>
> I don't get it. If you need it in userspace, you should expose it. Why
> to wait? What am I missing?

Mainly my attempt to avoid constant rebasing for four series at the
same time. One for rdmatool, one for RDMA netlink, one for RDMA UAPI changes
and one for rdma-core [1] which should reuse those exported structures too.

[1] http://github.com/linux-rdma/rdma-core

Thanks


signature.asc
Description: PGP signature


Re: [PATCH iproute2 V3 3/4] rdma: Add link object

2017-07-10 Thread Jiri Pirko
Mon, Jul 10, 2017 at 06:22:23PM CEST, l...@kernel.org wrote:
>On Mon, Jul 10, 2017 at 10:13:07AM +0200, Jiri Pirko wrote:
>> Tue, Jul 04, 2017 at 09:55:40AM CEST, l...@kernel.org wrote:
>> >From: Leon Romanovsky 
>> >
>> >Link (port) object represent struct ib_port to the user space.
>> >
>> >Link properties:
>> > * Port capabilities
>> > * IB subnet prefix
>> > * LID, SM_LID and LMC
>> > * Port state
>> > * Physical state
>> >
>> >Signed-off-by: Leon Romanovsky 
>> >---
>> > rdma/Makefile |   2 +-
>> > rdma/link.c   | 280 
>> > ++
>> > rdma/rdma.c   |   3 +-
>> > rdma/utils.c  |   5 ++
>> > 4 files changed, 288 insertions(+), 2 deletions(-)
>> > create mode 100644 rdma/link.c
>> >
>> >diff --git a/rdma/Makefile b/rdma/Makefile
>> >index 123d7ac5..1a9e4b1a 100644
>> >--- a/rdma/Makefile
>> >+++ b/rdma/Makefile
>> >@@ -2,7 +2,7 @@ include ../Config
>> >
>> > ifeq ($(HAVE_MNL),y)
>> >
>> >-RDMA_OBJ = rdma.o utils.o dev.o
>> >+RDMA_OBJ = rdma.o utils.o dev.o link.o
>> >
>> > TARGETS=rdma
>> > CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
>> >diff --git a/rdma/link.c b/rdma/link.c
>> >new file mode 100644
>> >index ..f92b4cef
>> >--- /dev/null
>> >+++ b/rdma/link.c
>> >@@ -0,0 +1,280 @@
>> >+/*
>> >+ * link.c  RDMA tool
>> >+ *
>> >+ *  This program is free software; you can redistribute it 
>> >and/or
>> >+ *  modify it under the terms of the GNU General Public License
>> >+ *  as published by the Free Software Foundation; either 
>> >version
>> >+ *  2 of the License, or (at your option) any later version.
>> >+ *
>> >+ * Authors: Leon Romanovsky 
>> >+ */
>> >+
>> >+#include "rdma.h"
>> >+
>> >+static int link_help(struct rdma *rd)
>> >+{
>> >+   pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
>> >+   return 0;
>> >+}
>> >+
>> >+static void link_print_caps(struct nlattr **tb)
>> >+{
>> >+   uint64_t caps;
>> >+   uint32_t idx;
>> >+
>> >+   /*
>> >+* FIXME: move to indexes when kernel will start exporting them.
>>
>> Not exported yet?
>
>Not yet, I want to minimize the UAPI export from kernel before user-space
>part is accepted.

I don't get it. If you need it in userspace, you should expose it. Why
to wait? What am I missing?

[...]


>> >+   rd->port_idx = port ? :1;
>>
>> "port ? : 1"
>
>Yeah, legal C, the same as (port) ? port : 1
>ihttps://en.wikipedia.org/wiki/%3F:#C


I was referring to the missing " ". I'm a nitpicker :)



Re: [PATCH iproute2 V3 3/4] rdma: Add link object

2017-07-10 Thread Leon Romanovsky
On Mon, Jul 10, 2017 at 10:13:07AM +0200, Jiri Pirko wrote:
> Tue, Jul 04, 2017 at 09:55:40AM CEST, l...@kernel.org wrote:
> >From: Leon Romanovsky 
> >
> >Link (port) object represent struct ib_port to the user space.
> >
> >Link properties:
> > * Port capabilities
> > * IB subnet prefix
> > * LID, SM_LID and LMC
> > * Port state
> > * Physical state
> >
> >Signed-off-by: Leon Romanovsky 
> >---
> > rdma/Makefile |   2 +-
> > rdma/link.c   | 280 
> > ++
> > rdma/rdma.c   |   3 +-
> > rdma/utils.c  |   5 ++
> > 4 files changed, 288 insertions(+), 2 deletions(-)
> > create mode 100644 rdma/link.c
> >
> >diff --git a/rdma/Makefile b/rdma/Makefile
> >index 123d7ac5..1a9e4b1a 100644
> >--- a/rdma/Makefile
> >+++ b/rdma/Makefile
> >@@ -2,7 +2,7 @@ include ../Config
> >
> > ifeq ($(HAVE_MNL),y)
> >
> >-RDMA_OBJ = rdma.o utils.o dev.o
> >+RDMA_OBJ = rdma.o utils.o dev.o link.o
> >
> > TARGETS=rdma
> > CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
> >diff --git a/rdma/link.c b/rdma/link.c
> >new file mode 100644
> >index ..f92b4cef
> >--- /dev/null
> >+++ b/rdma/link.c
> >@@ -0,0 +1,280 @@
> >+/*
> >+ * link.c   RDMA tool
> >+ *
> >+ *  This program is free software; you can redistribute it 
> >and/or
> >+ *  modify it under the terms of the GNU General Public License
> >+ *  as published by the Free Software Foundation; either version
> >+ *  2 of the License, or (at your option) any later version.
> >+ *
> >+ * Authors: Leon Romanovsky 
> >+ */
> >+
> >+#include "rdma.h"
> >+
> >+static int link_help(struct rdma *rd)
> >+{
> >+pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
> >+return 0;
> >+}
> >+
> >+static void link_print_caps(struct nlattr **tb)
> >+{
> >+uint64_t caps;
> >+uint32_t idx;
> >+
> >+/*
> >+ * FIXME: move to indexes when kernel will start exporting them.
>
> Not exported yet?

Not yet, I want to minimize the UAPI export from kernel before user-space
part is accepted.

>
>
>
> >+ */
> >+static const char *link_caps[64] = {
>
> []

It will require from me to fill all 64 fields.
In current version, I'm leveraging the fact that static is initialized
to zero (NULL).

>
>
> >+"UNKNOWN",
> >+"SM",
> >+"NOTICE",
> >+"TRAP",
> >+"OPT_IPD",
> >+"AUTO_MIGR",
> >+"SL_MAP",
> >+"MKEY_NVRAM",
> >+"PKEY_NVRAM",
> >+"LED_INFO",
> >+"SM_DISABLED",
> >+"SYS_IMAGE_GUID",
> >+"PKEY_SW_EXT_PORT_TRAP",
> >+"UNKNOWN",
> >+"EXTENDED_SPEEDS",
> >+"UNKNOWN",
> >+"CM",
> >+"SNMP_TUNNEL",
> >+"REINIT",
> >+"DEVICE_MGMT",
> >+"VENDOR_CLASS",
> >+"DR_NOTICE",
> >+"CAP_MASK_NOTICE",
> >+"BOOT_MGMT",
> >+"LINK_LATENCY",
> >+"CLIENT_REG",
> >+"IP_BASED_GIDS",
> >+};
> >+
> >+if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
> >+return;
> >+
> >+caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
> >+
> >+pr_out("\ncaps: <");
> >+for (idx = 0; idx < 64; idx++) {
> >+if (caps & 0x1) {
> >+pr_out("%s", link_caps[idx]?link_caps[idx]:"UNKNONW");
>
> "link_caps[idx] ? link_caps[idx] : "UNKNOWN""
>
> note the s/UNKNONW/UNKNOWN/

Right

>
>
> >+if (caps >> 0x1)
> >+pr_out(", ");
> >+}
> >+caps >>= 0x1;
>
> Interesting.
>
>
> >+}
> >+
> >+pr_out(">");
> >+}
> >+
> >+static void link_print_subnet_prefix(struct nlattr **tb)
> >+{
> >+uint64_t subnet_prefix;
> >+uint16_t sp[4];
> >+
> >+if (!tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX])
> >+return;
> >+
> >+subnet_prefix = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]);
> >+memcpy(sp, _prefix, sizeof(uint64_t));
> >+pr_out("subnet_prefix %04x:%04x:%04x:%04x ", sp[3], sp[2], sp[1], 
> >sp[0]);
>
> You have similar pr_out helper in the previous patch. Perhaps you can
> re-use it?

Sure

>
>
> >+}
> >+
> >+static void link_print_lid(struct nlattr **tb)
> >+{
> >+if (!tb[RDMA_NLDEV_ATTR_LID])
> >+return;
> >+
> >+pr_out("lid %u ",
> >+   mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_LID]));
> >+}
> >+
> >+static void link_print_sm_lid(struct nlattr **tb)
> >+{
> >+
>
> Avoid the extra empty line.
>

Will remove

>
> >+if (!tb[RDMA_NLDEV_ATTR_SM_LID])
> >+return;
> >+
> >+pr_out("sm_lid %u ",
> >+   mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_SM_LID]));
> >+}
> >+
> >+static void link_print_lmc(struct nlattr **tb)
> >+{
> >+if (!tb[RDMA_NLDEV_ATTR_LMC])
> >+return;
> >+
> >+pr_out("lmc %u ", 

Re: [PATCH iproute2 V3 3/4] rdma: Add link object

2017-07-10 Thread Jiri Pirko
Tue, Jul 04, 2017 at 09:55:40AM CEST, l...@kernel.org wrote:
>From: Leon Romanovsky 
>
>Link (port) object represent struct ib_port to the user space.
>
>Link properties:
> * Port capabilities
> * IB subnet prefix
> * LID, SM_LID and LMC
> * Port state
> * Physical state
>
>Signed-off-by: Leon Romanovsky 
>---
> rdma/Makefile |   2 +-
> rdma/link.c   | 280 ++
> rdma/rdma.c   |   3 +-
> rdma/utils.c  |   5 ++
> 4 files changed, 288 insertions(+), 2 deletions(-)
> create mode 100644 rdma/link.c
>
>diff --git a/rdma/Makefile b/rdma/Makefile
>index 123d7ac5..1a9e4b1a 100644
>--- a/rdma/Makefile
>+++ b/rdma/Makefile
>@@ -2,7 +2,7 @@ include ../Config
>
> ifeq ($(HAVE_MNL),y)
>
>-RDMA_OBJ = rdma.o utils.o dev.o
>+RDMA_OBJ = rdma.o utils.o dev.o link.o
>
> TARGETS=rdma
> CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
>diff --git a/rdma/link.c b/rdma/link.c
>new file mode 100644
>index ..f92b4cef
>--- /dev/null
>+++ b/rdma/link.c
>@@ -0,0 +1,280 @@
>+/*
>+ * link.c RDMA tool
>+ *
>+ *  This program is free software; you can redistribute it and/or
>+ *  modify it under the terms of the GNU General Public License
>+ *  as published by the Free Software Foundation; either version
>+ *  2 of the License, or (at your option) any later version.
>+ *
>+ * Authors: Leon Romanovsky 
>+ */
>+
>+#include "rdma.h"
>+
>+static int link_help(struct rdma *rd)
>+{
>+  pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
>+  return 0;
>+}
>+
>+static void link_print_caps(struct nlattr **tb)
>+{
>+  uint64_t caps;
>+  uint32_t idx;
>+
>+  /*
>+   * FIXME: move to indexes when kernel will start exporting them.

Not exported yet?



>+   */
>+  static const char *link_caps[64] = {

[]


>+  "UNKNOWN",
>+  "SM",
>+  "NOTICE",
>+  "TRAP",
>+  "OPT_IPD",
>+  "AUTO_MIGR",
>+  "SL_MAP",
>+  "MKEY_NVRAM",
>+  "PKEY_NVRAM",
>+  "LED_INFO",
>+  "SM_DISABLED",
>+  "SYS_IMAGE_GUID",
>+  "PKEY_SW_EXT_PORT_TRAP",
>+  "UNKNOWN",
>+  "EXTENDED_SPEEDS",
>+  "UNKNOWN",
>+  "CM",
>+  "SNMP_TUNNEL",
>+  "REINIT",
>+  "DEVICE_MGMT",
>+  "VENDOR_CLASS",
>+  "DR_NOTICE",
>+  "CAP_MASK_NOTICE",
>+  "BOOT_MGMT",
>+  "LINK_LATENCY",
>+  "CLIENT_REG",
>+  "IP_BASED_GIDS",
>+  };
>+
>+  if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
>+  return;
>+
>+  caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
>+
>+  pr_out("\ncaps: <");
>+  for (idx = 0; idx < 64; idx++) {
>+  if (caps & 0x1) {
>+  pr_out("%s", link_caps[idx]?link_caps[idx]:"UNKNONW");

"link_caps[idx] ? link_caps[idx] : "UNKNOWN""

note the s/UNKNONW/UNKNOWN/


>+  if (caps >> 0x1)
>+  pr_out(", ");
>+  }
>+  caps >>= 0x1;

Interesting. 


>+  }
>+
>+  pr_out(">");
>+}
>+
>+static void link_print_subnet_prefix(struct nlattr **tb)
>+{
>+  uint64_t subnet_prefix;
>+  uint16_t sp[4];
>+
>+  if (!tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX])
>+  return;
>+
>+  subnet_prefix = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]);
>+  memcpy(sp, _prefix, sizeof(uint64_t));
>+  pr_out("subnet_prefix %04x:%04x:%04x:%04x ", sp[3], sp[2], sp[1], 
>sp[0]);

You have similar pr_out helper in the previous patch. Perhaps you can
re-use it?


>+}
>+
>+static void link_print_lid(struct nlattr **tb)
>+{
>+  if (!tb[RDMA_NLDEV_ATTR_LID])
>+  return;
>+
>+  pr_out("lid %u ",
>+ mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_LID]));
>+}
>+
>+static void link_print_sm_lid(struct nlattr **tb)
>+{
>+

Avoid the extra empty line.


>+  if (!tb[RDMA_NLDEV_ATTR_SM_LID])
>+  return;
>+
>+  pr_out("sm_lid %u ",
>+ mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_SM_LID]));
>+}
>+
>+static void link_print_lmc(struct nlattr **tb)
>+{
>+  if (!tb[RDMA_NLDEV_ATTR_LMC])
>+  return;
>+
>+  pr_out("lmc %u ", mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_LMC]));
>+}
>+
>+static void link_print_state(struct nlattr **tb)
>+{
>+  uint8_t state;
>+  /*
>+   * FIXME: move to index exported by the kernel

Again, can't this be fixed now?


>+   */
>+  static const char *str[] = {
>+  "NOP",
>+  "DOWN",
>+  "INIT",
>+  "ARMED",
>+  "ACTIVE",
>+  "ACTIVE_DEFER",
>+  };
>+
>+  if (!tb[RDMA_NLDEV_ATTR_PORT_STATE])
>+  return;
>+
>+  state = 

[PATCH iproute2 V3 3/4] rdma: Add link object

2017-07-04 Thread Leon Romanovsky
From: Leon Romanovsky 

Link (port) object represent struct ib_port to the user space.

Link properties:
 * Port capabilities
 * IB subnet prefix
 * LID, SM_LID and LMC
 * Port state
 * Physical state

Signed-off-by: Leon Romanovsky 
---
 rdma/Makefile |   2 +-
 rdma/link.c   | 280 ++
 rdma/rdma.c   |   3 +-
 rdma/utils.c  |   5 ++
 4 files changed, 288 insertions(+), 2 deletions(-)
 create mode 100644 rdma/link.c

diff --git a/rdma/Makefile b/rdma/Makefile
index 123d7ac5..1a9e4b1a 100644
--- a/rdma/Makefile
+++ b/rdma/Makefile
@@ -2,7 +2,7 @@ include ../Config

 ifeq ($(HAVE_MNL),y)

-RDMA_OBJ = rdma.o utils.o dev.o
+RDMA_OBJ = rdma.o utils.o dev.o link.o

 TARGETS=rdma
 CFLAGS += $(shell $(PKG_CONFIG) libmnl --cflags)
diff --git a/rdma/link.c b/rdma/link.c
new file mode 100644
index ..f92b4cef
--- /dev/null
+++ b/rdma/link.c
@@ -0,0 +1,280 @@
+/*
+ * link.c  RDMA tool
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ * Authors: Leon Romanovsky 
+ */
+
+#include "rdma.h"
+
+static int link_help(struct rdma *rd)
+{
+   pr_out("Usage: %s link show [DEV/PORT_INDEX]\n", rd->filename);
+   return 0;
+}
+
+static void link_print_caps(struct nlattr **tb)
+{
+   uint64_t caps;
+   uint32_t idx;
+
+   /*
+* FIXME: move to indexes when kernel will start exporting them.
+*/
+   static const char *link_caps[64] = {
+   "UNKNOWN",
+   "SM",
+   "NOTICE",
+   "TRAP",
+   "OPT_IPD",
+   "AUTO_MIGR",
+   "SL_MAP",
+   "MKEY_NVRAM",
+   "PKEY_NVRAM",
+   "LED_INFO",
+   "SM_DISABLED",
+   "SYS_IMAGE_GUID",
+   "PKEY_SW_EXT_PORT_TRAP",
+   "UNKNOWN",
+   "EXTENDED_SPEEDS",
+   "UNKNOWN",
+   "CM",
+   "SNMP_TUNNEL",
+   "REINIT",
+   "DEVICE_MGMT",
+   "VENDOR_CLASS",
+   "DR_NOTICE",
+   "CAP_MASK_NOTICE",
+   "BOOT_MGMT",
+   "LINK_LATENCY",
+   "CLIENT_REG",
+   "IP_BASED_GIDS",
+   };
+
+   if (!tb[RDMA_NLDEV_ATTR_CAP_FLAGS])
+   return;
+
+   caps = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_CAP_FLAGS]);
+
+   pr_out("\ncaps: <");
+   for (idx = 0; idx < 64; idx++) {
+   if (caps & 0x1) {
+   pr_out("%s", link_caps[idx]?link_caps[idx]:"UNKNONW");
+   if (caps >> 0x1)
+   pr_out(", ");
+   }
+   caps >>= 0x1;
+   }
+
+   pr_out(">");
+}
+
+static void link_print_subnet_prefix(struct nlattr **tb)
+{
+   uint64_t subnet_prefix;
+   uint16_t sp[4];
+
+   if (!tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX])
+   return;
+
+   subnet_prefix = mnl_attr_get_u64(tb[RDMA_NLDEV_ATTR_SUBNET_PREFIX]);
+   memcpy(sp, _prefix, sizeof(uint64_t));
+   pr_out("subnet_prefix %04x:%04x:%04x:%04x ", sp[3], sp[2], sp[1], 
sp[0]);
+}
+
+static void link_print_lid(struct nlattr **tb)
+{
+   if (!tb[RDMA_NLDEV_ATTR_LID])
+   return;
+
+   pr_out("lid %u ",
+  mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_LID]));
+}
+
+static void link_print_sm_lid(struct nlattr **tb)
+{
+
+   if (!tb[RDMA_NLDEV_ATTR_SM_LID])
+   return;
+
+   pr_out("sm_lid %u ",
+  mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_SM_LID]));
+}
+
+static void link_print_lmc(struct nlattr **tb)
+{
+   if (!tb[RDMA_NLDEV_ATTR_LMC])
+   return;
+
+   pr_out("lmc %u ", mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_LMC]));
+}
+
+static void link_print_state(struct nlattr **tb)
+{
+   uint8_t state;
+   /*
+* FIXME: move to index exported by the kernel
+*/
+   static const char *str[] = {
+   "NOP",
+   "DOWN",
+   "INIT",
+   "ARMED",
+   "ACTIVE",
+   "ACTIVE_DEFER",
+   };
+
+   if (!tb[RDMA_NLDEV_ATTR_PORT_STATE])
+   return;
+
+   state = mnl_attr_get_u8(tb[RDMA_NLDEV_ATTR_PORT_STATE]);
+
+   if (state < 6 )
+   pr_out("state %s ", str[state]);
+   else
+   pr_out("state UNKNOWN ");
+}
+
+static void link_print_phys_state(struct nlattr **tb)
+{
+   uint8_t phys_state;
+   /*
+* FIXME: move to index exported by the kernel
+*/
+   static const char *str[] = {
+   "UNKNOWN",
+   "SLEEP",
+   "POLLING",