From: David Ahern Date: Thu, 4 Oct 2018 21:07:15 +0000 (-0700) Subject: libnetlink: dump extack string in done message X-Git-Tag: v5.0.0~36^2~5^2~11 X-Git-Url: https://git.proxmox.com/?p=mirror_iproute2.git;a=commitdiff_plain;h=2750252d7e850793a7d50987abb974141eb8525e libnetlink: dump extack string in done message Print any extack message that has been appended to a NLMSG_DONE message. To avoid duplication, move the existing print code to a new helper. Signed-off-by: David Ahern --- diff --git a/lib/libnetlink.c b/lib/libnetlink.c index 95457109..e28e1ab6 100644 --- a/lib/libnetlink.c +++ b/lib/libnetlink.c @@ -67,6 +67,14 @@ static int err_attr_cb(const struct nlattr *attr, void *data) return MNL_CB_OK; } +static void print_ext_ack_msg(bool is_err, const char *msg) +{ + fprintf(stderr, "%s: %s", is_err ? "Error" : "Warning", msg); + if (msg[strlen(msg) - 1] != '.') + fprintf(stderr, "."); + fprintf(stderr, "\n"); +} + /* dump netlink extended ack error message */ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) { @@ -108,12 +116,29 @@ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) if (msg && *msg != '\0') { bool is_err = !!err->error; - fprintf(stderr, "%s: %s", - is_err ? "Error" : "Warning", msg); - if (msg[strlen(msg) - 1] != '.') - fprintf(stderr, "."); - fprintf(stderr, "\n"); + print_ext_ack_msg(is_err, msg); + return is_err ? 1 : 0; + } + return 0; +} + +static int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error) +{ + struct nlattr *tb[NLMSGERR_ATTR_MAX + 1] = {}; + unsigned int hlen = sizeof(int); + const char *msg = NULL; + + if (mnl_attr_parse(nlh, hlen, err_attr_cb, tb) != MNL_CB_OK) + return 0; + + if (tb[NLMSGERR_ATTR_MSG]) + msg = mnl_attr_get_str(tb[NLMSGERR_ATTR_MSG]); + + if (msg && *msg != '\0') { + bool is_err = !!error; + + print_ext_ack_msg(is_err, msg); return is_err ? 1 : 0; } @@ -127,6 +152,11 @@ int nl_dump_ext_ack(const struct nlmsghdr *nlh, nl_ext_ack_fn_t errfn) { return 0; } + +static int nl_dump_ext_ack_done(const struct nlmsghdr *nlh, int error) +{ + return 0; +} #endif void rtnl_close(struct rtnl_handle *rth) @@ -512,6 +542,10 @@ static int rtnl_dump_done(struct nlmsghdr *h) } if (len < 0) { + /* check for any messages returned from kernel */ + if (nl_dump_ext_ack_done(h, len)) + return len; + errno = -len; switch (errno) { case ENOENT: