From b8f958eaf355c48aaa659b50d5f39d7f0f509436 Mon Sep 17 00:00:00 2001 From: Eitan Eliahu Date: Thu, 11 Sep 2014 10:01:02 -0700 Subject: [PATCH] Netlink_socket.c Join/Unjoin an MC group for event subscription Use a specific out of band device control to subscribe/unsubscribe a socket to the driver event queue for notification. Signed-off-by: Eitan Eliahu Acked-by: Nithin Raju Acked-by: Saurabh Shah Acked-by: Ankur Sharma Acked-by: Alin Gabriel Serdean Signed-off-by: Ben Pfaff --- datapath-windows/include/OvsDpInterfaceExt.h | 9 ++- lib/netlink-socket.c | 82 ++++++++++---------- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/datapath-windows/include/OvsDpInterfaceExt.h b/datapath-windows/include/OvsDpInterfaceExt.h index ab2088ad5..877b2adee 100644 --- a/datapath-windows/include/OvsDpInterfaceExt.h +++ b/datapath-windows/include/OvsDpInterfaceExt.h @@ -70,7 +70,14 @@ /* Commands available under the OVS_WIN_CONTROL_FAMILY. */ enum ovs_win_control_cmd { OVS_CTRL_CMD_WIN_GET_PID, - OVS_CTRL_CMD_WIN_PEND_REQ + OVS_CTRL_CMD_WIN_PEND_REQ, + OVS_CTRL_CMD_MC_SUBSCRIBE_REQ, +}; + +/* NL Attributes for joining/unjoining an MC group */ +enum ovs_nl_mcast_attr { + OVS_NL_ATTR_MCAST_GRP, /* (UINT32) Join an MC group */ + OVS_NL_ATTR_MCAST_JOIN, /* (UINT8) 1/0 - Join/Unjoin */ }; #endif /* __OVS_DP_INTERFACE_EXT_H_ */ diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c index 7ac97c669..1dd7a2423 100644 --- a/lib/netlink-socket.c +++ b/lib/netlink-socket.c @@ -332,6 +332,33 @@ done: } #endif /* _WIN32 */ +#ifdef _WIN32 +static int __inline +nl_sock_mcgroup(struct nl_sock *sock, unsigned int multicast_group, bool join) +{ + 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_MC_SUBSCRIBE_REQ, + OVS_WIN_CONTROL_VERSION); + + ovs_header = ofpbuf_put_uninit(&request, sizeof *ovs_header); + ovs_header->dp_ifindex = 0; + + nl_msg_put_u32(&request, OVS_NL_ATTR_MCAST_GRP, multicast_group); + nl_msg_put_u8(&request, OVS_NL_ATTR_MCAST_JOIN, join ? 1 : 0); + + error = nl_sock_send(sock, &request, true); + ofpbuf_uninit(&request); + return error; +} +#endif /* Tries to add 'sock' as a listener for 'multicast_group'. Returns 0 if * successful, otherwise a positive errno value. * @@ -347,31 +374,12 @@ int nl_sock_join_mcgroup(struct nl_sock *sock, unsigned int multicast_group) { #ifdef _WIN32 -#define OVS_VPORT_MCGROUP_FALLBACK_ID 33 - struct ofpbuf msg_buf; - struct message_multicast - { - struct nlmsghdr; - /* if true, join; if else, leave */ - unsigned char join; - unsigned int groupId; - }; - - struct message_multicast msg = { 0 }; - - msg.nlmsg_len = sizeof(struct message_multicast); - msg.nlmsg_type = OVS_VPORT_MCGROUP_FALLBACK_ID; - msg.nlmsg_flags = 0; - msg.nlmsg_seq = 0; - msg.nlmsg_pid = sock->pid; - - msg.join = 1; - msg.groupId = multicast_group; - msg_buf.base_ = &msg; - msg_buf.data_ = &msg; - msg_buf.size_ = msg.nlmsg_len; - - nl_sock_send__(sock, &msg_buf, msg.nlmsg_seq, 0); + int error = nl_sock_mcgroup(sock, multicast_group, true); + if (error) { + VLOG_WARN("could not join multicast group %u (%s)", + multicast_group, ovs_strerror(errno)); + return errno; + } #else if (setsockopt(sock->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &multicast_group, sizeof multicast_group) < 0) { @@ -397,24 +405,12 @@ int nl_sock_leave_mcgroup(struct nl_sock *sock, unsigned int multicast_group) { #ifdef _WIN32 - struct ofpbuf msg_buf; - struct message_multicast - { - struct nlmsghdr; - /* if true, join; if else, leave*/ - unsigned char join; - }; - - struct message_multicast msg = { 0 }; - nl_msg_put_nlmsghdr(&msg, sizeof(struct message_multicast), - multicast_group, 0); - msg.join = 0; - - msg_buf.base_ = &msg; - msg_buf.data_ = &msg; - msg_buf.size_ = msg.nlmsg_len; - - nl_sock_send__(sock, &msg_buf, msg.nlmsg_seq, 0); + int error = nl_sock_mcgroup(sock, multicast_group, false); + if (error) { + VLOG_WARN("could not leave multicast group %u (%s)", + multicast_group, ovs_strerror(errno)); + return errno; + } #else if (setsockopt(sock->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, &multicast_group, sizeof multicast_group) < 0) { -- 2.20.1