Skip to content

Commit

Permalink
netlink-socket: Add packet subscribe functionality on Windows.
Browse files Browse the repository at this point in the history
In this patch, we add support in userspace for packet subscribe API
similar to the join/leave MC group API that is used for port events.
The kernel code has already been commited.

Signed-off-by: Nithin Raju <[email protected]>
Acked-by: Alin Gabriel Serdean <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
nithinrajub authored and blp committed Oct 23, 2014
1 parent b7cefbf commit 36791e2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 0 deletions.
62 changes: 62 additions & 0 deletions lib/netlink-socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,68 @@ nl_sock_join_mcgroup(struct nl_sock *sock, unsigned int multicast_group)
return 0;
}

#ifdef _WIN32
int
nl_sock_subscribe_packets(struct nl_sock *sock)
{
int error;

if (sock->read_ioctl != OVS_IOCTL_READ) {
return EINVAL;
}

error = nl_sock_subscribe_packet__(sock, true);
if (error) {
VLOG_WARN("could not unsubscribe packets (%s)",
ovs_strerror(errno));
return error;
}
sock->read_ioctl = OVS_IOCTL_READ_PACKET;

return 0;
}

int
nl_sock_unsubscribe_packets(struct nl_sock *sock)
{
ovs_assert(sock->read_ioctl == OVS_IOCTL_READ_PACKET);

int error = nl_sock_subscribe_packet__(sock, false);
if (error) {
VLOG_WARN("could not subscribe to packets (%s)",
ovs_strerror(errno));
return error;
}

sock->read_ioctl = OVS_IOCTL_READ;
return 0;
}

int
nl_sock_subscribe_packet__(struct nl_sock *sock, bool subscribe)
{
struct ofpbuf request;
uint64_t request_stub[128];
struct ovs_header *ovs_header;
struct nlmsghdr *nlmsg;
int error;

ofpbuf_use_stub(&request, request_stub, sizeof request_stub);
nl_msg_put_genlmsghdr(&request, 0, OVS_WIN_NL_CTRL_FAMILY_ID, 0,
OVS_CTRL_CMD_PACKET_SUBSCRIBE_REQ,
OVS_WIN_CONTROL_VERSION);

ovs_header = ofpbuf_put_uninit(&request, sizeof *ovs_header);
ovs_header->dp_ifindex = 0;
nl_msg_put_u8(&request, OVS_NL_ATTR_PACKET_SUBSCRIBE, subscribe ? 1 : 0);
nl_msg_put_u32(&request, OVS_NL_ATTR_PACKET_PID, sock->pid);

error = nl_sock_send(sock, &request, true);
ofpbuf_uninit(&request);
return error;
}
#endif

/* Tries to make 'sock' stop listening to 'multicast_group'. Returns 0 if
* successful, otherwise a positive errno value.
*
Expand Down
13 changes: 13 additions & 0 deletions lib/netlink-socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@
*
* nl_sock_recv() reads notifications sent this way.
*
* Specifically on Windows platform, the datapath needs to allocate a
* queue for packets, and it does so only when userspace "subscribe"'s to
* packets on that netlink socket. Before closing the netlink socket,
* userspace needs to "unsubscribe" packets on that netlink socket.
*
* nl_sock_subscribe_packets() and nl_sock_unsubscribe_packets() are
* Windows specific.
*
* Messages received this way can overflow, just like multicast
* subscription messages, and they are reported the same way. Because
* packet notification messages do not report the state of a table, there
Expand Down Expand Up @@ -205,6 +213,11 @@ void nl_sock_destroy(struct nl_sock *);
int nl_sock_join_mcgroup(struct nl_sock *, unsigned int multicast_group);
int nl_sock_leave_mcgroup(struct nl_sock *, unsigned int multicast_group);

#ifdef _WIN32
int nl_sock_subscribe_packets(struct nl_sock *sock);
int nl_sock_unsubscribe_packets(struct nl_sock *sock);
#endif

int nl_sock_send(struct nl_sock *, const struct ofpbuf *, bool wait);
int nl_sock_send_seq(struct nl_sock *, const struct ofpbuf *,
uint32_t nlmsg_seq, bool wait);
Expand Down

0 comments on commit 36791e2

Please sign in to comment.