Commit d5369ea2 authored by Toke Høiland-Jørgensen's avatar Toke Høiland-Jørgensen Committed by Juliusz Chroboczek

Enable extended acknowledgements for netlink messages

When something goes wrong with a netlink request, the kernel may return a
human-friendly error message using the 'extack' functionality. This is
opt-in however, so this patch adds parsing and display of such error
messages to the netlink debug output.
Signed-off-by: default avatarToke Høiland-Jørgensen <toke@toke.dk>
parent 05f35886
...@@ -283,7 +283,7 @@ static int nl_setup = 0; ...@@ -283,7 +283,7 @@ static int nl_setup = 0;
static int static int
netlink_socket(struct netlink *nl, uint32_t groups) netlink_socket(struct netlink *nl, uint32_t groups)
{ {
int rc; int rc, one = 1;
int rcvsize = 512 * 1024; int rcvsize = 512 * 1024;
nl->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); nl->sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
...@@ -319,6 +319,11 @@ netlink_socket(struct netlink *nl, uint32_t groups) ...@@ -319,6 +319,11 @@ netlink_socket(struct netlink *nl, uint32_t groups)
} }
} }
rc = setsockopt(nl->sock, SOL_NETLINK, NETLINK_EXT_ACK,
&one, sizeof(one));
if(rc < 0)
perror("Warning: couldn't enable netlink extended acks");
rc = bind(nl->sock, (struct sockaddr *)&nl->sockaddr, nl->socklen); rc = bind(nl->sock, (struct sockaddr *)&nl->sockaddr, nl->socklen);
if(rc < 0) if(rc < 0)
goto fail; goto fail;
...@@ -339,6 +344,43 @@ netlink_socket(struct netlink *nl, uint32_t groups) ...@@ -339,6 +344,43 @@ netlink_socket(struct netlink *nl, uint32_t groups)
} }
} }
#define NLA_OK(nla,len) ((len) >= (int)sizeof(struct nlattr) && \
(nla)->nla_len >= sizeof(struct nlattr) && \
(nla)->nla_len <= (len))
#define NLA_NEXT(nla,attrlen) ((attrlen) -= NLA_ALIGN((nla)->nla_len), \
(struct nlattr*)(((char*)(nla)) + NLA_ALIGN((nla)->nla_len)))
#define NLA_LENGTH(len) (NLA_ALIGN(sizeof(struct nlattr)) + (len))
#define NLA_DATA(nla) ((void*)(((char*)(nla)) + NLA_LENGTH(0)))
static int netlink_get_extack(struct nlmsghdr *nh, int len, int done)
{
const char *msg = NULL;
struct nlattr *nla;
if (done) {
nla = NLMSG_DATA(nh) + sizeof(int);
len -= NLMSG_ALIGN(int);
} else {
nla = NLMSG_DATA(nh) + sizeof(struct nlmsgerr);
len -= NLMSG_ALIGN(sizeof(struct nlmsgerr));
if (!(nh->nlmsg_flags & NLM_F_ACK_TLVS))
return 0;
}
while(NLA_OK(nla, len)) {
if(nla->nla_type == NLMSGERR_ATTR_MSG)
msg = NLA_DATA(nla);
nla = NLA_NEXT(nla, len);
}
if(msg && *msg != '\0')
kdebugf(" extack: '%s' ", msg);
return 0;
}
static int static int
netlink_read(struct netlink *nl, struct netlink *nl_ignore, int answer, netlink_read(struct netlink *nl, struct netlink *nl_ignore, int answer,
struct kernel_filter *filter) struct kernel_filter *filter)
...@@ -425,11 +467,13 @@ netlink_read(struct netlink *nl, struct netlink *nl_ignore, int answer, ...@@ -425,11 +467,13 @@ netlink_read(struct netlink *nl, struct netlink *nl_ignore, int answer,
nh->nlmsg_pid, nl->sockaddr.nl_pid); nh->nlmsg_pid, nl->sockaddr.nl_pid);
continue; continue;
} else if(nh->nlmsg_type == NLMSG_DONE) { } else if(nh->nlmsg_type == NLMSG_DONE) {
netlink_get_extack(nh, len, 1);
kdebugf("(done)\n"); kdebugf("(done)\n");
done = 1; done = 1;
break; break;
} else if(nh->nlmsg_type == NLMSG_ERROR) { } else if(nh->nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nh); struct nlmsgerr *err = (struct nlmsgerr *)NLMSG_DATA(nh);
netlink_get_extack(nh, len, 0);
if(err->error == 0) { if(err->error == 0) {
kdebugf("(ACK)\n"); kdebugf("(ACK)\n");
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment