mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-10-17 14:25:56 +00:00
poll for errors after rtnl_send
This fixes the problem where a bulk operation (like ip flush) is performed as non-root user. The kernel will only send a response if there is an error, so check for it.
This commit is contained in:
parent
1fb0a998e1
commit
54bb35c69c
@ -114,11 +114,39 @@ int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
|
||||
int rtnl_send(struct rtnl_handle *rth, const char *buf, int len)
|
||||
{
|
||||
struct sockaddr_nl nladdr;
|
||||
struct nlmsghdr *h;
|
||||
int status;
|
||||
char resp[1024];
|
||||
|
||||
memset(&nladdr, 0, sizeof(nladdr));
|
||||
nladdr.nl_family = AF_NETLINK;
|
||||
|
||||
return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
|
||||
status = sendto(rth->fd, buf, len, 0,
|
||||
(struct sockaddr*)&nladdr, sizeof(nladdr));
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* Check for errors */
|
||||
status = recv(rth->fd, resp, sizeof(resp), MSG_DONTWAIT);
|
||||
if (status < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (h = (struct nlmsghdr *)resp; NLMSG_OK(h, status);
|
||||
h = NLMSG_NEXT(h, status)) {
|
||||
if (h->nlmsg_type == NLMSG_ERROR) {
|
||||
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
|
||||
if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
|
||||
fprintf(stderr, "ERROR truncated\n");
|
||||
else
|
||||
errno = -err->error;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
|
||||
|
Loading…
Reference in New Issue
Block a user