@@ -32,6 +32,7 @@ ethtool_SOURCES += \
netlink/settings.c netlink/parser.c netlink/parser.h \
netlink/permaddr.c netlink/prettymsg.c netlink/prettymsg.h \
netlink/desc-ethtool.c netlink/desc-genlctrl.c \
+ netlink/desc-rtnl.c \
uapi/linux/ethtool_netlink.h \
uapi/linux/netlink.h uapi/linux/genetlink.h \
uapi/linux/rtnetlink.h uapi/linux/if_link.h
new file mode 100644
@@ -0,0 +1,96 @@
+/*
+ * desc-rtnl.c - rtnetlink message descriptions
+ *
+ * Descriptions of rtnetlink messages and attributes for pretty print.
+ */
+
+#include <linux/rtnetlink.h>
+
+#include "../internal.h"
+#include "prettymsg.h"
+
+static const struct pretty_nla_desc __link_desc[] = {
+ NLATTR_DESC_INVALID(IFLA_UNSPEC),
+ NLATTR_DESC_BINARY(IFLA_ADDRESS),
+ NLATTR_DESC_BINARY(IFLA_BROADCAST),
+ NLATTR_DESC_STRING(IFLA_IFNAME),
+ NLATTR_DESC_U32(IFLA_MTU),
+ NLATTR_DESC_U32(IFLA_LINK),
+ NLATTR_DESC_STRING(IFLA_QDISC),
+ NLATTR_DESC_BINARY(IFLA_STATS),
+ NLATTR_DESC_INVALID(IFLA_COST),
+ NLATTR_DESC_INVALID(IFLA_PRIORITY),
+ NLATTR_DESC_U32(IFLA_MASTER),
+ NLATTR_DESC_BINARY(IFLA_WIRELESS),
+ NLATTR_DESC_NESTED_NODESC(IFLA_PROTINFO),
+ NLATTR_DESC_U32(IFLA_TXQLEN),
+ NLATTR_DESC_BINARY(IFLA_MAP),
+ NLATTR_DESC_U32(IFLA_WEIGHT),
+ NLATTR_DESC_U8(IFLA_OPERSTATE),
+ NLATTR_DESC_U8(IFLA_LINKMODE),
+ NLATTR_DESC_NESTED_NODESC(IFLA_LINKINFO),
+ NLATTR_DESC_U32(IFLA_NET_NS_PID),
+ NLATTR_DESC_STRING(IFLA_IFALIAS),
+ NLATTR_DESC_U32(IFLA_NUM_VF),
+ NLATTR_DESC_NESTED_NODESC(IFLA_VFINFO_LIST),
+ NLATTR_DESC_BINARY(IFLA_STATS64),
+ NLATTR_DESC_NESTED_NODESC(IFLA_VF_PORTS),
+ NLATTR_DESC_NESTED_NODESC(IFLA_PORT_SELF),
+ NLATTR_DESC_NESTED_NODESC(IFLA_AF_SPEC),
+ NLATTR_DESC_U32(IFLA_GROUP),
+ NLATTR_DESC_U32(IFLA_NET_NS_FD),
+ NLATTR_DESC_U32(IFLA_EXT_MASK),
+ NLATTR_DESC_U32(IFLA_PROMISCUITY),
+ NLATTR_DESC_U32(IFLA_NUM_TX_QUEUES),
+ NLATTR_DESC_U32(IFLA_NUM_RX_QUEUES),
+ NLATTR_DESC_U8(IFLA_CARRIER),
+ NLATTR_DESC_BINARY(IFLA_PHYS_PORT_ID),
+ NLATTR_DESC_U32(IFLA_CARRIER_CHANGES),
+ NLATTR_DESC_BINARY(IFLA_PHYS_SWITCH_ID),
+ NLATTR_DESC_S32(IFLA_LINK_NETNSID),
+ NLATTR_DESC_STRING(IFLA_PHYS_PORT_NAME),
+ NLATTR_DESC_U8(IFLA_PROTO_DOWN),
+ NLATTR_DESC_U32(IFLA_GSO_MAX_SEGS),
+ NLATTR_DESC_U32(IFLA_GSO_MAX_SIZE),
+ NLATTR_DESC_BINARY(IFLA_PAD),
+ NLATTR_DESC_U32(IFLA_XDP),
+ NLATTR_DESC_U32(IFLA_EVENT),
+ NLATTR_DESC_S32(IFLA_NEW_NETNSID),
+ NLATTR_DESC_S32(IFLA_IF_NETNSID),
+ NLATTR_DESC_U32(IFLA_CARRIER_UP_COUNT),
+ NLATTR_DESC_U32(IFLA_CARRIER_DOWN_COUNT),
+ NLATTR_DESC_S32(IFLA_NEW_IFINDEX),
+ NLATTR_DESC_U32(IFLA_MIN_MTU),
+ NLATTR_DESC_U32(IFLA_MAX_MTU),
+ NLATTR_DESC_NESTED_NODESC(IFLA_PROP_LIST),
+ NLATTR_DESC_STRING(IFLA_ALT_IFNAME),
+ NLATTR_DESC_BINARY(IFLA_PERM_ADDRESS),
+};
+
+const struct pretty_nlmsg_desc rtnl_msg_desc[] = {
+ NLMSG_DESC(RTM_NEWLINK, link),
+ NLMSG_DESC(RTM_DELLINK, link),
+ NLMSG_DESC(RTM_GETLINK, link),
+ NLMSG_DESC(RTM_SETLINK, link),
+};
+
+const unsigned int rtnl_msg_n_desc = ARRAY_SIZE(rtnl_msg_desc);
+
+#define RTNL_MSGHDR_LEN(_name, _struct) \
+ [((RTM_ ## _name) - RTM_BASE) / 4] = sizeof(struct _struct)
+#define RTNL_MSGHDR_NOLEN(_name) \
+ [((RTM_ ## _name) - RTM_BASE) / 4] = USHRT_MAX
+
+const unsigned short rtnl_msghdr_lengths[] = {
+ RTNL_MSGHDR_LEN(NEWLINK, ifinfomsg),
+ RTNL_MSGHDR_LEN(NEWADDR, ifaddrmsg),
+ RTNL_MSGHDR_LEN(NEWROUTE, rtmsg),
+ RTNL_MSGHDR_LEN(NEWNEIGH, ndmsg),
+ RTNL_MSGHDR_LEN(NEWRULE, rtmsg),
+ RTNL_MSGHDR_LEN(NEWQDISC, tcmsg),
+ RTNL_MSGHDR_LEN(NEWTCLASS, tcmsg),
+ RTNL_MSGHDR_LEN(NEWTFILTER, tcmsg),
+ RTNL_MSGHDR_LEN(NEWACTION, tcamsg),
+};
+
+const unsigned int rtnl_msghdr_n_len = ARRAY_SIZE(rtnl_msghdr_lengths);
@@ -191,3 +191,47 @@ int pretty_print_genlmsg(const struct nlmsghdr *nlhdr,
msg_desc ? msg_desc->attrs : NULL,
msg_desc ? msg_desc->n_attrs : 0, err_offset);
}
+
+static void rtm_link_summary(const struct ifinfomsg *ifinfo)
+{
+ if (ifinfo->ifi_family)
+ printf(" family=%u", ifinfo->ifi_family);
+ if (ifinfo->ifi_type)
+ printf(" type=0x%04x", ifinfo->ifi_type);
+ if (ifinfo->ifi_index)
+ printf(" ifindex=%d", ifinfo->ifi_index);
+ if (ifinfo->ifi_flags)
+ printf(" flags=0x%x", ifinfo->ifi_flags);
+ if (ifinfo->ifi_flags)
+ printf(" change=0x%x", ifinfo->ifi_change);
+}
+
+int pretty_print_rtnlmsg(const struct nlmsghdr *nlhdr, unsigned int err_offset)
+{
+ const unsigned int idx = (nlhdr->nlmsg_type - RTM_BASE) / 4;
+ const struct pretty_nlmsg_desc *msg_desc = NULL;
+ unsigned int hdrlen = USHRT_MAX;
+
+ if (nlhdr->nlmsg_type < rtnl_msg_n_desc)
+ msg_desc = &rtnl_msg_desc[nlhdr->nlmsg_type];
+ if (idx < rtnl_msghdr_n_len)
+ hdrlen = rtnl_msghdr_lengths[idx];
+ if (hdrlen < USHRT_MAX && mnl_nlmsg_get_payload_len(nlhdr) < hdrlen) {
+ fprintf(stderr, "ethtool: message too short (%u bytes)\n",
+ nlhdr->nlmsg_len);
+ return -EINVAL;
+ }
+ if (msg_desc && msg_desc->name)
+ printf(" %s", msg_desc->name);
+ else
+ printf(" [%u]", nlhdr->nlmsg_type);
+ if (idx == (RTM_NEWLINK - RTM_BASE) / 4)
+ rtm_link_summary(mnl_nlmsg_get_payload(nlhdr));
+ putchar('\n');
+ if (hdrlen == USHRT_MAX)
+ return 0;
+
+ return pretty_print_nlmsg(nlhdr, hdrlen,
+ msg_desc ? msg_desc->attrs : NULL,
+ msg_desc ? msg_desc->n_attrs : 0, err_offset);
+}
@@ -98,6 +98,7 @@ struct pretty_nlmsg_desc {
int pretty_print_genlmsg(const struct nlmsghdr *nlhdr,
const struct pretty_nlmsg_desc *desc,
unsigned int ndesc, unsigned int err_offset);
+int pretty_print_rtnlmsg(const struct nlmsghdr *nlhdr, unsigned int err_offset);
/* message descriptions */
@@ -109,4 +110,9 @@ extern const unsigned int ethnl_kmsg_n_desc;
extern const struct pretty_nlmsg_desc genlctrl_msg_desc[];
extern const unsigned int genlctrl_msg_n_desc;
+extern const struct pretty_nlmsg_desc rtnl_msg_desc[];
+extern const unsigned int rtnl_msg_n_desc;
+extern const unsigned short rtnl_msghdr_lengths[];
+extern const unsigned int rtnl_msghdr_n_len;
+
#endif /* ETHTOOL_NETLINK_PRETTYMSG_H__ */
Add description of rtnetlink message formats to be used for pretty printing infrastructure and helper function to pretty print rtnetlink messages. As rtnetlink is quite complex and only RTM_GETLINK and RTM_NEWLINK messages are interesting for ethtool at the moment, this commit provides only names of a limited subset of rtnetlink messages and names and formats of top level attributes used in RTM_{NEW,DEL,GET,SET}LINK messages. Signed-off-by: Michal Kubecek <mkubecek@suse.cz> --- Makefile.am | 1 + netlink/desc-rtnl.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ netlink/prettymsg.c | 44 +++++++++++++++++++++ netlink/prettymsg.h | 6 +++ 4 files changed, 147 insertions(+) create mode 100644 netlink/desc-rtnl.c