Merge branch 'fixes' of https://github.com/socketpair/libnl
This commit is contained in:
commit
785f810b95
8 changed files with 101 additions and 52 deletions
|
@ -96,10 +96,10 @@ static void family_dump_line(struct nl_object *obj, struct nl_dump_params *p)
|
|||
}
|
||||
|
||||
static const struct trans_tbl ops_flags[] = {
|
||||
__ADD(GENL_ADMIN_PERM, admin-perm)
|
||||
__ADD(GENL_CMD_CAP_DO, has-doit)
|
||||
__ADD(GENL_CMD_CAP_DUMP, has-dump)
|
||||
__ADD(GENL_CMD_CAP_HASPOL, has-policy)
|
||||
__ADD(GENL_ADMIN_PERM, admin_perm)
|
||||
__ADD(GENL_CMD_CAP_DO, has_doit)
|
||||
__ADD(GENL_CMD_CAP_DUMP, has_dump)
|
||||
__ADD(GENL_CMD_CAP_HASPOL, has_policy)
|
||||
};
|
||||
|
||||
static char *ops_flags2str(int flags, char *buf, size_t len)
|
||||
|
|
121
lib/nl.c
121
lib/nl.c
|
@ -405,9 +405,9 @@ errout:
|
|||
/**
|
||||
* Receive data from netlink socket
|
||||
* @arg sk Netlink socket.
|
||||
* @arg nla Destination pointer for peer's netlink address.
|
||||
* @arg buf Destination pointer for message content.
|
||||
* @arg creds Destination pointer for credentials.
|
||||
* @arg nla Destination pointer for peer's netlink address. (required)
|
||||
* @arg buf Destination pointer for message content. (required)
|
||||
* @arg creds Destination pointer for credentials. (optional)
|
||||
*
|
||||
* Receives a netlink message, allocates a buffer in \c *buf and
|
||||
* stores the message content. The peer's netlink address is stored
|
||||
|
@ -433,13 +433,9 @@ int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
|
|||
.msg_namelen = sizeof(struct sockaddr_nl),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_control = NULL,
|
||||
.msg_controllen = 0,
|
||||
.msg_flags = 0,
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
memset(nla, 0, sizeof(*nla));
|
||||
struct ucred* tmpcreds = NULL;
|
||||
int retval = 0;
|
||||
|
||||
if (sk->s_flags & NL_MSG_PEEK)
|
||||
flags |= MSG_PEEK | MSG_TRUNC;
|
||||
|
@ -448,73 +444,114 @@ int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
|
|||
page_size = getpagesize();
|
||||
|
||||
iov.iov_len = sk->s_bufsize ? : page_size;
|
||||
iov.iov_base = *buf = malloc(iov.iov_len);
|
||||
iov.iov_base = malloc(iov.iov_len);
|
||||
|
||||
if (sk->s_flags & NL_SOCK_PASSCRED) {
|
||||
if (!iov.iov_base) {
|
||||
retval = -NLE_NOMEM;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
|
||||
msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
|
||||
msg.msg_control = calloc(1, msg.msg_controllen);
|
||||
msg.msg_control = malloc(msg.msg_controllen);
|
||||
if (!msg.msg_control) {
|
||||
retval = -NLE_NOMEM;
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
retry:
|
||||
|
||||
n = recvmsg(sk->s_fd, &msg, flags);
|
||||
if (!n)
|
||||
if (!n) {
|
||||
retval = 0;
|
||||
goto abort;
|
||||
else if (n < 0) {
|
||||
}
|
||||
if (n < 0) {
|
||||
if (errno == EINTR) {
|
||||
NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
|
||||
goto retry;
|
||||
} else if (errno == EAGAIN) {
|
||||
NL_DBG(3, "recvmsg() returned EAGAIN, aborting\n");
|
||||
goto abort;
|
||||
} else {
|
||||
free(msg.msg_control);
|
||||
free(*buf);
|
||||
return -nl_syserr2nlerr(errno);
|
||||
}
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
NL_DBG(3, "recvmsg() returned EAGAIN||EWOULDBLOCK, aborting\n");
|
||||
retval = 0;
|
||||
goto abort;
|
||||
}
|
||||
retval = -nl_syserr2nlerr(errno);
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (msg.msg_flags & MSG_CTRUNC) {
|
||||
void *tmp;
|
||||
msg.msg_controllen *= 2;
|
||||
msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
|
||||
tmp = realloc(msg.msg_control, msg.msg_controllen);
|
||||
if (!tmp) {
|
||||
retval = -NLE_NOMEM;
|
||||
goto abort;
|
||||
}
|
||||
msg.msg_control = tmp;
|
||||
goto retry;
|
||||
} else if (iov.iov_len < n || msg.msg_flags & MSG_TRUNC) {
|
||||
}
|
||||
|
||||
if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) {
|
||||
void *tmp;
|
||||
/* Provided buffer is not long enough, enlarge it
|
||||
* to size of n (which should be total length of the message)
|
||||
* and try again. */
|
||||
iov.iov_len = n;
|
||||
iov.iov_base = *buf = realloc(*buf, iov.iov_len);
|
||||
tmp = realloc(iov.iov_base, iov.iov_len);
|
||||
if (!tmp) {
|
||||
retval = -NLE_NOMEM;
|
||||
goto abort;
|
||||
}
|
||||
iov.iov_base = tmp;
|
||||
flags = 0;
|
||||
goto retry;
|
||||
} else if (flags != 0) {
|
||||
}
|
||||
|
||||
if (flags != 0) {
|
||||
/* Buffer is big enough, do the actual reading */
|
||||
flags = 0;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
|
||||
free(msg.msg_control);
|
||||
free(*buf);
|
||||
return -NLE_NOADDR;
|
||||
retval = -NLE_NOADDR;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level == SOL_SOCKET &&
|
||||
cmsg->cmsg_type == SCM_CREDENTIALS) {
|
||||
if (creds) {
|
||||
*creds = calloc(1, sizeof(struct ucred));
|
||||
memcpy(*creds, CMSG_DATA(cmsg), sizeof(struct ucred));
|
||||
if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
|
||||
struct cmsghdr *cmsg;
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
continue;
|
||||
if (cmsg->cmsg_type != SCM_CREDENTIALS)
|
||||
continue;
|
||||
tmpcreds = malloc(sizeof(*tmpcreds));
|
||||
if (!tmpcreds) {
|
||||
retval = -NLE_NOMEM;
|
||||
goto abort;
|
||||
}
|
||||
memcpy(tmpcreds, CMSG_DATA(cmsg), sizeof(*tmpcreds));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(msg.msg_control);
|
||||
return n;
|
||||
|
||||
retval = n;
|
||||
abort:
|
||||
free(msg.msg_control);
|
||||
free(*buf);
|
||||
return 0;
|
||||
|
||||
if (retval <= 0) {
|
||||
free(iov.iov_base); iov.iov_base = NULL;
|
||||
free(tmpcreds); tmpcreds = NULL;
|
||||
}
|
||||
|
||||
*buf = iov.iov_base;
|
||||
|
||||
if (creds)
|
||||
*creds = tmpcreds;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/** @cond SKIP */
|
||||
|
@ -540,6 +577,12 @@ static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
|
|||
int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
|
||||
unsigned char *buf = NULL;
|
||||
struct nlmsghdr *hdr;
|
||||
|
||||
/*
|
||||
nla is passed on to not only to nl_recv() but may also be passed
|
||||
to a function pointer provided by the caller which may or may not
|
||||
initialize the variable. Thomas Graf.
|
||||
*/
|
||||
struct sockaddr_nl nla = {0};
|
||||
struct nl_msg *msg = NULL;
|
||||
struct ucred *creds = NULL;
|
||||
|
|
|
@ -311,7 +311,7 @@ static int classid_map_add(uint32_t classid, const char *name)
|
|||
int rtnl_tc_read_classid_file(void)
|
||||
{
|
||||
static time_t last_read;
|
||||
struct stat st = {0};
|
||||
struct stat st;
|
||||
char buf[256], *path;
|
||||
FILE *fd;
|
||||
int err;
|
||||
|
|
|
@ -14,8 +14,14 @@
|
|||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/cls/ematch.h>
|
||||
|
||||
static int container_parse(struct rtnl_ematch *e, void *data, size_t len)
|
||||
static int container_parse(struct rtnl_ematch *e, void *data, size_t len __attribute__((unused)))
|
||||
{
|
||||
/*
|
||||
The kernel may provide more than 4 bytes of data in the future and we want
|
||||
older libnl versions to be ok with that. We want interfaces to be growable
|
||||
so we only ever enforce a minimum data length and copy as much as we are
|
||||
aware of. Thomas Graf.
|
||||
*/
|
||||
memcpy(e->e_data, data, sizeof(uint32_t));
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -90,7 +90,7 @@ static int read_pktlocs(void)
|
|||
YY_BUFFER_STATE buf = NULL;
|
||||
yyscan_t scanner = NULL;
|
||||
static time_t last_read;
|
||||
struct stat st = {0};
|
||||
struct stat st;
|
||||
char *path;
|
||||
int i, err;
|
||||
FILE *fd;
|
||||
|
|
|
@ -190,10 +190,10 @@ static int htb_qdisc_msg_fill(struct rtnl_tc *tc, void *data,
|
|||
struct nl_msg *msg)
|
||||
{
|
||||
struct rtnl_htb_qdisc *htb = data;
|
||||
struct tc_htb_glob opts = {0};
|
||||
|
||||
opts.version = TC_HTB_PROTOVER;
|
||||
opts.rate2quantum = 10;
|
||||
struct tc_htb_glob opts = {
|
||||
.version = TC_HTB_PROTOVER,
|
||||
.rate2quantum = 10,
|
||||
};
|
||||
|
||||
if (htb) {
|
||||
if (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM)
|
||||
|
|
|
@ -332,7 +332,7 @@ static int route_compare(struct nl_object *_a, struct nl_object *_b,
|
|||
if (a->rt_metrics_mask & (1 << i) &&
|
||||
(!(b->rt_metrics_mask & (1 << i)) ||
|
||||
a->rt_metrics[i] != b->rt_metrics[i]))
|
||||
ROUTE_DIFF(METRICS, 1);
|
||||
diff |= ROUTE_DIFF(METRICS, 1);
|
||||
}
|
||||
|
||||
diff |= ROUTE_DIFF(FLAGS,
|
||||
|
|
|
@ -96,7 +96,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
copy_range = 0xFFFF;
|
||||
if (argc > 4)
|
||||
copy_mode = atoi(argv[4]);
|
||||
copy_range = atoi(argv[4]);
|
||||
nfnl_log_set_copy_range(log, copy_range);
|
||||
|
||||
if ((err = nfnl_log_create(nf_sock, log)) < 0)
|
||||
|
|
Loading…
Add table
Reference in a new issue