2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

Windows: Add support for handling protocol (netlink family)

Windows datapath currently has no notion of netlink family.
It assumes all netlink messages to belong to NETLINK_GENERIC family.
This patch adds support for handling other protocols if the userspace sends it down to kernel.

This patch introduces a new NETLINK_CMD - OVS_CTRL_CMD_SOCK_PROP to manage
all properties associated with a socket. The properties are passed down as
netlink message attributes. This makes it easier to introduce other
properties in the future.

Signed-off-by: Sairam Venugopal <vsairam@vmware.com>
Acked-by: Nithin Raju <nithin@vmware.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
This commit is contained in:
Sairam Venugopal
2016-07-11 14:59:49 -07:00
committed by Gurucharan Shetty
parent 1e25f5caef
commit e70f55edbc
4 changed files with 194 additions and 3 deletions

View File

@@ -59,6 +59,7 @@ static void log_nlmsg(const char *function, int error,
const void *message, size_t size, int protocol);
#ifdef _WIN32
static int get_sock_pid_from_kernel(struct nl_sock *sock);
static int set_sock_property(struct nl_sock *sock);
#endif
/* Netlink sockets. */
@@ -165,6 +166,10 @@ nl_sock_create(int protocol, struct nl_sock **sockp)
if (retval != 0) {
goto error;
}
retval = set_sock_property(sock);
if (retval != 0) {
goto error;
}
#else
if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUFFORCE,
&rcvbuf, sizeof rcvbuf)) {
@@ -284,6 +289,76 @@ get_sock_pid_from_kernel(struct nl_sock *sock)
return retval;
}
/* Used for setting and managing socket properties in userspace and kernel.
* Currently two attributes are tracked - pid and protocol
* protocol - supplied by userspace based on the netlink family. Windows uses
* this property to set the value in kernel datapath.
* eg: (NETLINK_GENERIC/ NETLINK_NETFILTER)
* pid - generated by windows kernel and set in userspace. The property
* is not modified.
* Also verify if Protocol and PID in Kernel reflects the values in userspace
* */
static int
set_sock_property(struct nl_sock *sock)
{
static const struct nl_policy ovs_socket_policy[] = {
[OVS_NL_ATTR_SOCK_PROTO] = { .type = NL_A_BE32, .optional = true },
[OVS_NL_ATTR_SOCK_PID] = { .type = NL_A_BE32, .optional = true }
};
struct ofpbuf request, *reply;
struct ovs_header *ovs_header;
struct nlattr *attrs[ARRAY_SIZE(ovs_socket_policy)];
int retval = 0;
int error;
ofpbuf_init(&request, 0);
nl_msg_put_genlmsghdr(&request, 0, OVS_WIN_NL_CTRL_FAMILY_ID, 0,
OVS_CTRL_CMD_SOCK_PROP, OVS_WIN_CONTROL_VERSION);
ovs_header = ofpbuf_put_uninit(&request, sizeof *ovs_header);
ovs_header->dp_ifindex = 0;
nl_msg_put_be32(&request, OVS_NL_ATTR_SOCK_PROTO, sock->protocol);
/* pid is already set as part of get_sock_pid_from_kernel()
* This is added to maintain consistency
*/
nl_msg_put_be32(&request, OVS_NL_ATTR_SOCK_PID, sock->pid);
error = nl_sock_transact(sock, &request, &reply);
ofpbuf_uninit(&request);
if (error) {
retval = EINVAL;
}
if (!nl_policy_parse(reply,
NLMSG_HDRLEN + GENL_HDRLEN + sizeof *ovs_header,
ovs_socket_policy, attrs,
ARRAY_SIZE(ovs_socket_policy))) {
ofpbuf_delete(reply);
retval = EINVAL;
}
/* Verify if the properties are setup properly */
if (attrs[OVS_NL_ATTR_SOCK_PROTO]) {
int protocol = nl_attr_get_be32(attrs[OVS_NL_ATTR_SOCK_PROTO]);
if (protocol != sock->protocol) {
VLOG_ERR("Invalid protocol returned:%d expected:%d",
protocol, sock->protocol);
retval = EINVAL;
}
}
if (attrs[OVS_NL_ATTR_SOCK_PID]) {
int pid = nl_attr_get_be32(attrs[OVS_NL_ATTR_SOCK_PID]);
if (pid != sock->pid) {
VLOG_ERR("Invalid pid returned:%d expected:%d",
pid, sock->pid);
retval = EINVAL;
}
}
return retval;
}
#endif /* _WIN32 */
#ifdef _WIN32