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:
committed by
Gurucharan Shetty
parent
1e25f5caef
commit
e70f55edbc
@@ -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
|
||||
|
Reference in New Issue
Block a user