netlink: Treat send() or recv() errors as fatal

Errors on send() or recv() calls on a netlink socket don't indicate errors
with the netlink operations we're attempting, but rather that something's
gone wrong with the mechanics of netlink itself.  We don't really expect
this to ever happen, and if it does, it's not clear what we could to to
recover.

So, treat errors from these calls as fatal, rather than returning the error
up the stack.  This makes handling failures in the callers of nl_req()
simpler.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2023-08-03 17:19:47 +10:00 committed by Stefano Brivio
parent 0a568c847d
commit f62600b2df

View file

@ -103,9 +103,9 @@ fail:
* @req: Request with netlink header * @req: Request with netlink header
* @len: Request length * @len: Request length
* *
* Return: received length on success, negative error code on failure * Return: received length on success, terminates on error
*/ */
static int nl_req(int s, char *buf, const void *req, ssize_t len) static ssize_t nl_req(int s, char *buf, const void *req, ssize_t len)
{ {
char flush[NLBUFSIZ]; char flush[NLBUFSIZ];
int done = 0; int done = 0;
@ -124,11 +124,17 @@ static int nl_req(int s, char *buf, const void *req, ssize_t len)
} }
} }
if ((send(s, req, len, 0) < len) || n = send(s, req, len, 0);
(len = recv(s, buf, NLBUFSIZ, 0)) < 0) if (n < 0)
return -errno; die("netlink: Failed to send(): %s", strerror(errno));
else if (n < len)
die("netlink: Short send (%lu of %lu bytes)", n, len);
return len; n = recv(s, buf, NLBUFSIZ, 0);
if (n < 0)
die("netlink: Failed to recv(): %s", strerror(errno));
return n;
} }
/** /**
@ -158,8 +164,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af)
ssize_t n; ssize_t n;
size_t na; size_t na;
if ((n = nl_req(s, buf, &req, sizeof(req))) < 0) n = nl_req(s, buf, &req, sizeof(req));
return 0;
nh = (struct nlmsghdr *)buf; nh = (struct nlmsghdr *)buf;
@ -218,8 +223,7 @@ void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw)
char buf[NLBUFSIZ]; char buf[NLBUFSIZ];
ssize_t n; ssize_t n;
if ((n = nl_req(s, buf, &req, req.nlh.nlmsg_len)) < 0) n = nl_req(s, buf, &req, req.nlh.nlmsg_len);
return;
for (nh = (struct nlmsghdr *)buf; for (nh = (struct nlmsghdr *)buf;
NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE; NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE;
@ -357,8 +361,7 @@ void nl_route_dup(int s_src, unsigned int ifi_src,
char buf[NLBUFSIZ]; char buf[NLBUFSIZ];
unsigned i; unsigned i;
if ((nlmsgs_size = nl_req(s_src, buf, &req, req.nlh.nlmsg_len)) < 0) nlmsgs_size = nl_req(s_src, buf, &req, req.nlh.nlmsg_len);
return;
for (nh = (struct nlmsghdr *)buf, n = nlmsgs_size; for (nh = (struct nlmsghdr *)buf, n = nlmsgs_size;
NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE; NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE;
@ -433,8 +436,7 @@ void nl_addr_get(int s, unsigned int ifi, sa_family_t af,
char buf[NLBUFSIZ]; char buf[NLBUFSIZ];
ssize_t n; ssize_t n;
if ((n = nl_req(s, buf, &req, req.nlh.nlmsg_len)) < 0) n = nl_req(s, buf, &req, req.nlh.nlmsg_len);
return;
for (nh = (struct nlmsghdr *)buf; for (nh = (struct nlmsghdr *)buf;
NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE; NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE;
@ -570,8 +572,7 @@ void nl_addr_dup(int s_src, unsigned int ifi_src,
struct nlmsghdr *nh; struct nlmsghdr *nh;
ssize_t n; ssize_t n;
if ((n = nl_req(s_src, buf, &req, sizeof(req))) < 0) n = nl_req(s_src, buf, &req, sizeof(req));
return;
for (nh = (struct nlmsghdr *)buf; for (nh = (struct nlmsghdr *)buf;
NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE; NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE;
@ -631,9 +632,6 @@ void nl_link_get_mac(int s, unsigned int ifi, void *mac)
ssize_t n; ssize_t n;
n = nl_req(s, buf, &req, sizeof(req)); n = nl_req(s, buf, &req, sizeof(req));
if (n < 0)
return;
for (nh = (struct nlmsghdr *)buf; for (nh = (struct nlmsghdr *)buf;
NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE; NLMSG_OK(nh, n) && nh->nlmsg_type != NLMSG_DONE;
nh = NLMSG_NEXT(nh, n)) { nh = NLMSG_NEXT(nh, n)) {