X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fnetlink-socket.c;h=e6b10a184c07551cf188684ae19ddaeb6764aa71;hb=e018053f14beb09ac7f634687c48ac2a214208f2;hp=713049aab0ed2367b472eb646830002700d7b8ce;hpb=e0edde6fee279cdbbf3c179f5f50adaf0c7c7f1e;p=sliver-openvswitch.git diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c index 713049aab..e6b10a184 100644 --- a/lib/netlink-socket.c +++ b/lib/netlink-socket.c @@ -16,7 +16,6 @@ #include #include "netlink-socket.h" -#include #include #include #include @@ -129,8 +128,12 @@ nl_sock_create(int protocol, struct nl_sock **sockp) rcvbuf = 1024 * 1024; if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUFFORCE, &rcvbuf, sizeof rcvbuf)) { - VLOG_WARN_RL(&rl, "setting %d-byte socket receive buffer failed (%s)", - rcvbuf, strerror(errno)); + /* Only root can use SO_RCVBUFFORCE. Everyone else gets EPERM. + * Warn only if the failure is therefore unexpected. */ + if (errno != EPERM || !getuid()) { + VLOG_WARN_RL(&rl, "setting %d-byte socket receive buffer failed " + "(%s)", rcvbuf, strerror(errno)); + } } retval = get_socket_rcvbuf(sock->fd); @@ -242,7 +245,7 @@ nl_sock_join_mcgroup(struct nl_sock *sock, unsigned int multicast_group) int nl_sock_leave_mcgroup(struct nl_sock *sock, unsigned int multicast_group) { - assert(!sock->dump); + ovs_assert(!sock->dump); if (setsockopt(sock->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &multicast_group, sizeof multicast_group) < 0) { VLOG_WARN("could not leave multicast group %u (%s)", @@ -253,13 +256,14 @@ nl_sock_leave_mcgroup(struct nl_sock *sock, unsigned int multicast_group) } static int -nl_sock_send__(struct nl_sock *sock, const struct ofpbuf *msg, bool wait) +nl_sock_send__(struct nl_sock *sock, const struct ofpbuf *msg, + uint32_t nlmsg_seq, bool wait) { struct nlmsghdr *nlmsg = nl_msg_nlmsghdr(msg); int error; nlmsg->nlmsg_len = msg->size; - nlmsg->nlmsg_seq = nl_sock_allocate_seq(sock, 1); + nlmsg->nlmsg_seq = nlmsg_seq; nlmsg->nlmsg_pid = sock->pid; do { int retval; @@ -274,20 +278,39 @@ nl_sock_send__(struct nl_sock *sock, const struct ofpbuf *msg, bool wait) } /* Tries to send 'msg', which must contain a Netlink message, to the kernel on - * 'sock'. nlmsg_len in 'msg' will be finalized to match msg->size, and - * nlmsg_pid will be set to 'sock''s pid, before the message is sent. + * 'sock'. nlmsg_len in 'msg' will be finalized to match msg->size, nlmsg_pid + * will be set to 'sock''s pid, and nlmsg_seq will be initialized to a fresh + * sequence number, before the message is sent. * * Returns 0 if successful, otherwise a positive errno value. If * 'wait' is true, then the send will wait until buffer space is ready; * otherwise, returns EAGAIN if the 'sock' send buffer is full. */ int nl_sock_send(struct nl_sock *sock, const struct ofpbuf *msg, bool wait) +{ + return nl_sock_send_seq(sock, msg, nl_sock_allocate_seq(sock, 1), wait); +} + +/* Tries to send 'msg', which must contain a Netlink message, to the kernel on + * 'sock'. nlmsg_len in 'msg' will be finalized to match msg->size, nlmsg_pid + * will be set to 'sock''s pid, and nlmsg_seq will be initialized to + * 'nlmsg_seq', before the message is sent. + * + * Returns 0 if successful, otherwise a positive errno value. If + * 'wait' is true, then the send will wait until buffer space is ready; + * otherwise, returns EAGAIN if the 'sock' send buffer is full. + * + * This function is suitable for sending a reply to a request that was received + * with sequence number 'nlmsg_seq'. Otherwise, use nl_sock_send() instead. */ +int +nl_sock_send_seq(struct nl_sock *sock, const struct ofpbuf *msg, + uint32_t nlmsg_seq, bool wait) { int error = nl_sock_cow__(sock); if (error) { return error; } - return nl_sock_send__(sock, msg, wait); + return nl_sock_send__(sock, msg, nlmsg_seq, wait); } /* This stress option is useful for testing that OVS properly tolerates @@ -313,7 +336,7 @@ nl_sock_recv__(struct nl_sock *sock, struct ofpbuf *buf, bool wait) struct msghdr msg; ssize_t retval; - assert(buf->allocated >= sizeof *nlmsghdr); + ovs_assert(buf->allocated >= sizeof *nlmsghdr); ofpbuf_clear(buf); iov[0].iov_base = buf->base; @@ -663,7 +686,7 @@ nl_sock_transact(struct nl_sock *sock, const struct ofpbuf *request, struct nl_transaction *transactionp; struct nl_transaction transaction; - transaction.request = (struct ofpbuf *) request; + transaction.request = CONST_CAST(struct ofpbuf *, request); transaction.reply = replyp ? ofpbuf_new(1024) : NULL; transactionp = &transaction; @@ -770,7 +793,8 @@ nl_dump_start(struct nl_dump *dump, } nl_msg_nlmsghdr(request)->nlmsg_flags |= NLM_F_DUMP | NLM_F_ACK; - dump->status = nl_sock_send__(sock, request, true); + dump->status = nl_sock_send__(sock, request, nl_sock_allocate_seq(sock, 1), + true); dump->seq = nl_msg_nlmsghdr(request)->nlmsg_seq; } @@ -860,7 +884,7 @@ nl_dump_done(struct nl_dump *dump) while (!dump->status) { struct ofpbuf reply; if (!nl_dump_next(dump, &reply)) { - assert(dump->status); + ovs_assert(dump->status); } } @@ -1079,7 +1103,7 @@ nl_lookup_genl_family(const char *name, int *number) } ofpbuf_delete(reply); - assert(*number != 0); + ovs_assert(*number != 0); } return *number > 0 ? 0 : -*number; }