aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Kubecek <mkubecek@suse.cz>2020-03-06 18:06:00 +0100
committerJohn W. Linville <linville@tuxdriver.com>2020-03-13 15:10:51 -0400
commitbdfffab54933d8880a5a7a5b874ab0a89b398ecd (patch)
treecf8abd36cf923594763c636716b47abf715a8e62
parent8a7a417a40b8335c803f9fe274cdb1231d543092 (diff)
downloadethtool-bdfffab54933d8880a5a7a5b874ab0a89b398ecd.tar.gz
netlink: message format descriptions for rtnetlink
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--Makefile.am1
-rw-r--r--netlink/desc-rtnl.c96
-rw-r--r--netlink/prettymsg.c44
-rw-r--r--netlink/prettymsg.h6
4 files changed, 147 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 8d99315..0f8465f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
diff --git a/netlink/desc-rtnl.c b/netlink/desc-rtnl.c
new file mode 100644
index 0000000..e15e6f0
--- /dev/null
+++ b/netlink/desc-rtnl.c
@@ -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);
diff --git a/netlink/prettymsg.c b/netlink/prettymsg.c
index 74fe6f2..9e62beb 100644
--- a/netlink/prettymsg.c
+++ b/netlink/prettymsg.c
@@ -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);
+}
diff --git a/netlink/prettymsg.h b/netlink/prettymsg.h
index 50d0bbf..b5e5f73 100644
--- a/netlink/prettymsg.h
+++ b/netlink/prettymsg.h
@@ -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__ */