Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #11

Merged
merged 9 commits into from Oct 22, 2012
8 changes: 4 additions & 4 deletions lib/genl/family.c
Expand Up @@ -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)
Expand Down
119 changes: 81 additions & 38 deletions lib/nl.c
Expand Up @@ -405,9 +405,9 @@ int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
/**
* 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
Expand All @@ -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;
Expand All @@ -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 (!iov.iov_base) {
retval = -NLE_NOMEM;
goto abort;
}

if (sk->s_flags & NL_SOCK_PASSCRED) {
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");
}
if (errno == EAGAIN || errno == EWOULDBLOCK) {
NL_DBG(3, "recvmsg() returned EAGAIN||EWOULDBLOCK, aborting\n");
retval = 0;
goto abort;
} else {
free(msg.msg_control);
free(*buf);
return -nl_syserr2nlerr(errno);
}
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 */
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/route/classid.c
Expand Up @@ -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;
Expand Down
8 changes: 7 additions & 1 deletion lib/route/cls/ematch/container.c
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion lib/route/pktloc.c
Expand Up @@ -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;
Expand Down
8 changes: 4 additions & 4 deletions lib/route/qdisc/htb.c
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lib/route/route_obj.c
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/nf-log.c
Expand Up @@ -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)
Expand Down