lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 6 Mar 2020 18:06:05 +0100 (CET) From: Michal Kubecek <mkubecek@...e.cz> To: John Linville <linville@...driver.com>, netdev@...r.kernel.org Cc: Andrew Lunn <andrew@...n.ch>, Florian Fainelli <f.fainelli@...il.com> Subject: [PATCH ethtool v3 25/25] netlink: use pretty printing for ethtool netlink messages Introduce new debugging flag DEBUG_NL_PRETTY_MSG (0x10) which has two effects: - show request messages embedded in extack error messages in human readable form; if failing attribute offset is provided, highlight the attribute - if DEBUG_NL_MSGS is also set, show structure of all outgoing and incoming ethtool netlink messages in addition to their summary Signed-off-by: Michal Kubecek <mkubecek@...e.cz> --- internal.h | 1 + netlink/nlsock.c | 71 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 56 insertions(+), 16 deletions(-) diff --git a/internal.h b/internal.h index a518bfa99380..edb07bddd073 100644 --- a/internal.h +++ b/internal.h @@ -122,6 +122,7 @@ enum { DEBUG_NL_MSGS, /* incoming/outgoing netlink messages */ DEBUG_NL_DUMP_SND, /* dump outgoing netlink messages */ DEBUG_NL_DUMP_RCV, /* dump incoming netlink messages */ + DEBUG_NL_PRETTY_MSG, /* pretty print of messages and errors */ }; static inline bool debug_on(unsigned long debug, unsigned int bit) diff --git a/netlink/nlsock.c b/netlink/nlsock.c index 4366c52ce390..22abb68b6646 100644 --- a/netlink/nlsock.c +++ b/netlink/nlsock.c @@ -10,6 +10,7 @@ #include "../internal.h" #include "nlsock.h" #include "netlink.h" +#include "prettymsg.h" #define NLSOCK_RECV_BUFFSIZE 65536 @@ -43,10 +44,12 @@ static void ctrl_msg_summary(const struct nlmsghdr *nlhdr) } static void genl_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam, - bool outgoing) + bool outgoing, bool pretty) { if (nlhdr->nlmsg_type == ethnl_fam) { + const struct pretty_nlmsg_desc *msg_desc; const struct genlmsghdr *ghdr; + unsigned int n_desc; printf(" ethool"); if (nlhdr->nlmsg_len < NLMSG_HDRLEN + GENL_HDRLEN) { @@ -55,27 +58,46 @@ static void genl_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam, } ghdr = mnl_nlmsg_get_payload(nlhdr); - printf(" cmd %u", ghdr->cmd); + msg_desc = outgoing ? ethnl_umsg_desc : ethnl_kmsg_desc; + n_desc = outgoing ? ethnl_umsg_n_desc : ethnl_kmsg_n_desc; + if (ghdr->cmd < n_desc && msg_desc[ghdr->cmd].name) + printf(" %s", msg_desc[ghdr->cmd].name); + else + printf(" cmd %u", ghdr->cmd); fputc('\n', stdout); + if (pretty) + pretty_print_genlmsg(nlhdr, msg_desc, n_desc, 0); return; } - if (nlhdr->nlmsg_type == GENL_ID_CTRL) + if (nlhdr->nlmsg_type == GENL_ID_CTRL) { printf(" genl-ctrl\n"); - else + if (pretty) + pretty_print_genlmsg(nlhdr, genlctrl_msg_desc, + genlctrl_msg_n_desc, 0); + } else { fputc('\n', stdout); + if (pretty) + pretty_print_genlmsg(nlhdr, NULL, 0, 0); + } } -static void rtnl_msg_summary(const struct nlmsghdr *nlhdr) +static void rtnl_msg_summary(const struct nlmsghdr *nlhdr, bool pretty) { unsigned int type = nlhdr->nlmsg_type; - printf(" type %u\n", type); + if (type < rtnl_msg_n_desc && rtnl_msg_desc[type].name) + printf(" %s\n", rtnl_msg_desc[type].name); + else + printf(" type %u\n", type); + + if (pretty) + pretty_print_rtnlmsg(nlhdr, 0); } static void debug_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam, - int nl_fam, bool outgoing) + int nl_fam, bool outgoing, bool pretty) { printf(" msg length %u", nlhdr->nlmsg_len); @@ -86,10 +108,10 @@ static void debug_msg_summary(const struct nlmsghdr *nlhdr, int ethnl_fam, switch(nl_fam) { case NETLINK_GENERIC: - genl_msg_summary(nlhdr, ethnl_fam, outgoing); + genl_msg_summary(nlhdr, ethnl_fam, outgoing, pretty); break; case NETLINK_ROUTE: - rtnl_msg_summary(nlhdr); + rtnl_msg_summary(nlhdr, pretty); break; default: fputc('\n', stdout); @@ -103,13 +125,14 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len, const char *dirlabel = outgoing ? "sending" : "received"; uint32_t debug = nlsk->nlctx->ctx->debug; const struct nlmsghdr *nlhdr = msg; - bool summary, dump; + bool summary, dump, pretty; const char *nl_fam_label; int left = len; summary = debug_on(debug, DEBUG_NL_MSGS); dump = debug_on(debug, outgoing ? DEBUG_NL_DUMP_SND : DEBUG_NL_DUMP_RCV); + pretty = debug_on(debug, DEBUG_NL_PRETTY_MSG); if (!summary && !dump) return; switch(nlsk->nl_fam) { @@ -128,7 +151,7 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len, while (nlhdr && left > 0 && mnl_nlmsg_ok(nlhdr, left)) { if (summary) debug_msg_summary(nlhdr, nlsk->nlctx->ethnl_fam, - nlsk->nl_fam, outgoing); + nlsk->nl_fam, outgoing, pretty); if (dump) mnl_nlmsg_fprintf(stdout, nlhdr, nlhdr->nlmsg_len, GENL_HDRLEN); @@ -146,7 +169,7 @@ static void debug_msg(struct nl_socket *nlsk, const void *msg, unsigned int len, * Return: error code extracted from the message */ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, - unsigned int suppress_nlerr) + unsigned int suppress_nlerr, bool pretty) { const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; DECLARE_ATTR_TB_INFO(tb); @@ -174,12 +197,23 @@ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, fprintf(stderr, "netlink %s: %s", nlerr->error ? "error" : "warning", msg); - if (tb[NLMSGERR_ATTR_OFFS]) + if (!pretty && tb[NLMSGERR_ATTR_OFFS]) fprintf(stderr, " (offset %u)", mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS])); fputc('\n', stderr); } + if (nlerr->error && pretty) { + unsigned int err_offset = 0; + + if (tb[NLMSGERR_ATTR_OFFS]) + err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); + fprintf(stderr, "offending message%s:\n", + err_offset ? " and attribute" : ""); + pretty_print_genlmsg(&nlerr->msg, ethnl_umsg_desc, + ethnl_umsg_n_desc, err_offset); + } + out: if (nlerr->error) { errno = -nlerr->error; @@ -223,9 +257,14 @@ int nlsock_process_reply(struct nl_socket *nlsk, mnl_cb_t reply_cb, void *data) return -EFAULT; nlhdr = (struct nlmsghdr *)buff; - if (nlhdr->nlmsg_type == NLMSG_ERROR) - return nlsock_process_ack(nlhdr, len, - nlsk->nlctx->suppress_nlerr); + if (nlhdr->nlmsg_type == NLMSG_ERROR) { + bool silent = nlsk->nlctx->suppress_nlerr; + bool pretty; + + pretty = debug_on(nlsk->nlctx->ctx->debug, + DEBUG_NL_PRETTY_MSG); + return nlsock_process_ack(nlhdr, len, silent, pretty); + } msgbuff->nlhdr = nlhdr; msgbuff->genlhdr = mnl_nlmsg_get_payload(nlhdr); -- 2.25.1
Powered by blists - more mailing lists