diff options
author | Michal Kubecek <mkubecek@suse.cz> | 2020-03-30 09:28:44 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2020-05-13 16:05:04 -0400 |
commit | 684f3e6c31bd096ef50725267957e0423b7932c6 (patch) | |
tree | 0610c6734b4043ea5431638fde803ecc5a6bfae7 | |
parent | e59fdcd23b27dd13d2d70c3e6e44dca80bdf5b12 (diff) | |
download | ethtool-684f3e6c31bd096ef50725267957e0423b7932c6.tar.gz |
netlink: show netlink error even without extack
Even if the NLMSG_ERROR message has no extack (NLM_F_ACK_TLVS not set, i.e.
no error/warning message and bad attribute offset), we still want to
display the error code (unless suppressed) and, if pretty printing is
enabled, the embedded client message (if present).
Fixes: 50efb3cdd2bb ("netlink: netlink socket wrapper and helpers")
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | netlink/nlsock.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/netlink/nlsock.c b/netlink/nlsock.c index 22abb68..2c760b7 100644 --- a/netlink/nlsock.c +++ b/netlink/nlsock.c @@ -173,25 +173,25 @@ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, { const struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; DECLARE_ATTR_TB_INFO(tb); + unsigned int err_offset = 0; unsigned int tlv_offset; struct nlmsgerr *nlerr; bool silent; - if (len < NLMSG_HDRLEN + sizeof(*nlerr)) + if ((len < NLMSG_HDRLEN + sizeof(*nlerr)) || (len < nlhdr->nlmsg_len)) return -EFAULT; nlerr = mnl_nlmsg_get_payload(nlhdr); - silent = (!(nlhdr->nlmsg_flags & NLM_F_ACK_TLVS) || - suppress_nlerr >= 2 || - (suppress_nlerr && nlerr->error == -EOPNOTSUPP)); - if (silent) - goto out; + silent = suppress_nlerr >= 2 || + (suppress_nlerr && nlerr->error == -EOPNOTSUPP); + if (silent || !(nlhdr->nlmsg_flags & NLM_F_ACK_TLVS)) + goto tlv_done; tlv_offset = sizeof(*nlerr); if (!(nlhdr->nlmsg_flags & NLM_F_CAPPED)) tlv_offset += MNL_ALIGN(mnl_nlmsg_get_payload_len(&nlerr->msg)); - if (mnl_attr_parse(nlhdr, tlv_offset, attr_cb, &tb_info) < 0) - goto out; + goto tlv_done; + if (tb[NLMSGERR_ATTR_MSG]) { const char *msg = mnl_attr_get_str(tb[NLMSGERR_ATTR_MSG]); @@ -202,24 +202,21 @@ static int nlsock_process_ack(struct nlmsghdr *nlhdr, ssize_t len, mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS])); fputc('\n', stderr); } + if (tb[NLMSGERR_ATTR_OFFS]) + err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); - if (nlerr->error && pretty) { - unsigned int err_offset = 0; - - if (tb[NLMSGERR_ATTR_OFFS]) - err_offset = mnl_attr_get_u32(tb[NLMSGERR_ATTR_OFFS]); +tlv_done: + if (nlerr->error && !silent) { + errno = -nlerr->error; + perror("netlink error"); + } + if (pretty && !(nlhdr->nlmsg_flags & NLM_F_CAPPED) && + nlhdr->nlmsg_len >= NLMSG_HDRLEN + nlerr->msg.nlmsg_len) { 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; - if (!silent) - perror("netlink error"); - } return nlerr->error; } |