Add support extack in tipc to dump the netlink extack error messages (i.e -EINVAL) sent from kernel.
Acked-by: Jon Maloy <jma...@redhat.com> Signed-off-by: Hoang Le <hoang.h...@dektech.com.au> --- tipc/msg.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/tipc/msg.c b/tipc/msg.c index dc09d05048f3..f29b2f8d35ad 100644 --- a/tipc/msg.c +++ b/tipc/msg.c @@ -18,6 +18,7 @@ #include <linux/genetlink.h> #include <libmnl/libmnl.h> +#include "libnetlink.h" #include "msg.h" int parse_attrs(const struct nlattr *attr, void *data) @@ -49,6 +50,7 @@ static struct mnl_socket *msg_send(struct nlmsghdr *nlh) { int ret; struct mnl_socket *nl; + int one = 1; nl = mnl_socket_open(NETLINK_GENERIC); if (nl == NULL) { @@ -56,6 +58,8 @@ static struct mnl_socket *msg_send(struct nlmsghdr *nlh) return NULL; } + /* support to get extended ACK */ + mnl_socket_setsockopt(nl, NETLINK_EXT_ACK, &one, sizeof(one)); ret = mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID); if (ret < 0) { perror("mnl_socket_bind"); @@ -73,21 +77,32 @@ static struct mnl_socket *msg_send(struct nlmsghdr *nlh) static int msg_recv(struct mnl_socket *nl, mnl_cb_t callback, void *data, int seq) { - int ret; unsigned int portid; char buf[MNL_SOCKET_BUFFER_SIZE]; + struct nlmsghdr *h; + size_t num_bytes; + int is_err = 0; + int ret = 0; portid = mnl_socket_get_portid(nl); - ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - while (ret > 0) { - ret = mnl_cb_run(buf, ret, seq, portid, callback, data); + num_bytes = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + while (num_bytes > 0) { + ret = mnl_cb_run(buf, num_bytes, seq, portid, callback, data); if (ret <= 0) break; - ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + num_bytes = mnl_socket_recvfrom(nl, buf, sizeof(buf)); + } + + if (ret == -1) { + if (num_bytes > 0) { + h = (struct nlmsghdr *)buf; + is_err = nl_dump_ext_ack(h, NULL); + } + + if (!is_err) + perror("error"); } - if (ret == -1) - perror("error"); mnl_socket_close(nl); -- 2.25.1