diff options
author | Sairam Venugopal <vsairam@vmware.com> | 2016-07-11 14:59:49 -0700 |
---|---|---|
committer | Gurucharan Shetty <guru@ovn.org> | 2016-07-13 15:04:52 -0700 |
commit | e70f55edbc47e99432da7c868594d7f9d9589eca (patch) | |
tree | 8100196ba5ffe31aeaa504d1f58a20a9ef841e99 /datapath-windows/ovsext | |
parent | 1e25f5caef5c1b6378bfee3f6ed0d1cb04e61e0c (diff) | |
download | openvswitch-e70f55edbc47e99432da7c868594d7f9d9589eca.tar.gz |
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>
Diffstat (limited to 'datapath-windows/ovsext')
-rw-r--r-- | datapath-windows/ovsext/Datapath.c | 104 | ||||
-rw-r--r-- | datapath-windows/ovsext/Datapath.h | 1 |
2 files changed, 104 insertions, 1 deletions
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c index 16d58ef6e..4f47be575 100644 --- a/datapath-windows/ovsext/Datapath.c +++ b/datapath-windows/ovsext/Datapath.c @@ -87,7 +87,8 @@ static NetlinkCmdHandler OvsPendEventCmdHandler, OvsReadEventCmdHandler, OvsNewDpCmdHandler, OvsGetDpCmdHandler, - OvsSetDpCmdHandler; + OvsSetDpCmdHandler, + OvsSockPropCmdHandler; NetlinkCmdHandler OvsGetNetdevCmdHandler, OvsGetVportCmdHandler, @@ -147,6 +148,11 @@ NETLINK_CMD nlControlFamilyCmdOps[] = { .handler = OvsReadPacketCmdHandler, .supportedDevOp = OVS_READ_DEV_OP, .validateDpIndex = FALSE, + }, + { .cmd = OVS_CTRL_CMD_SOCK_PROP, + .handler = OvsSockPropCmdHandler, + .supportedDevOp = OVS_TRANSACTION_DEV_OP, + .validateDpIndex = FALSE, } }; @@ -1685,3 +1691,99 @@ OvsReadEventCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, cleanup: return status; } + +/* + * -------------------------------------------------------------------------- + * Command Handler for 'OVS_CTRL_CMD_SOCK_PROP'. + * + * Handler to set and verify socket properties between userspace and kernel. + * + * Protocol is passed down by the userspace. It refers to the NETLINK family + * and could be of different types (NETLINK_GENERIC/NETLINK_NETFILTER etc.,) + * This function parses out the protocol and adds it to the open instance. + * + * PID is generated by the kernel and is set in userspace after querying the + * kernel for it. This function does not modify PID set in the kernel, + * instead it verifies if it was sent down correctly. + * + * XXX -This method can be modified to handle all Socket properties thereby + * eliminating the use of OVS_IOCTL_GET_PID + * + * -------------------------------------------------------------------------- + */ +static NTSTATUS +OvsSockPropCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, + UINT32 *replyLen) +{ + static const NL_POLICY ovsSocketPolicy[] = { + [OVS_NL_ATTR_SOCK_PROTO] = { .type = NL_A_U32, .optional = TRUE }, + [OVS_NL_ATTR_SOCK_PID] = { .type = NL_A_U32, .optional = TRUE } + }; + PNL_ATTR attrs[ARRAY_SIZE(ovsSocketPolicy)]; + + if (usrParamsCtx->outputLength < sizeof(OVS_MESSAGE)) { + return STATUS_NDIS_INVALID_LENGTH; + } + + NL_BUFFER nlBuf; + POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer; + POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer; + POVS_OPEN_INSTANCE instance = (POVS_OPEN_INSTANCE)usrParamsCtx->ovsInstance; + UINT32 protocol; + PNL_MSG_HDR nlMsg; + UINT32 pid; + + /* Parse the input */ + if (!NlAttrParse((PNL_MSG_HDR)msgIn, + NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN, + NlMsgAttrsLen((PNL_MSG_HDR)msgIn), + ovsSocketPolicy, + ARRAY_SIZE(ovsSocketPolicy), + attrs, + ARRAY_SIZE(attrs))) { + return STATUS_INVALID_PARAMETER; + } + + /* Set the Protocol if it was passed down */ + if (attrs[OVS_NL_ATTR_SOCK_PROTO]) { + protocol = NlAttrGetU32(attrs[OVS_NL_ATTR_SOCK_PROTO]); + if (protocol) { + instance->protocol = protocol; + } + } + + /* Verify if the PID sent down matches the kernel */ + if (attrs[OVS_NL_ATTR_SOCK_PID]) { + pid = NlAttrGetU32(attrs[OVS_NL_ATTR_SOCK_PID]); + if (pid != instance->pid) { + OVS_LOG_ERROR("Received invalid pid:%d expected:%d", + pid, instance->pid); + return STATUS_INVALID_PARAMETER; + } + } + + /* Prepare the output */ + NlBufInit(&nlBuf, usrParamsCtx->outputBuffer, usrParamsCtx->outputLength); + if(!NlFillOvsMsg(&nlBuf, msgIn->nlMsg.nlmsgType, NLM_F_MULTI, + msgIn->nlMsg.nlmsgSeq, msgIn->nlMsg.nlmsgPid, + msgIn->genlMsg.cmd, msgIn->genlMsg.version, + gOvsSwitchContext->dpNo)){ + return STATUS_INVALID_BUFFER_SIZE; + } + + if (!NlMsgPutTailU32(&nlBuf, OVS_NL_ATTR_SOCK_PID, + instance->pid)) { + return STATUS_INVALID_BUFFER_SIZE; + } + + if (!NlMsgPutTailU32(&nlBuf, OVS_NL_ATTR_SOCK_PROTO, + instance->protocol)) { + return STATUS_INVALID_BUFFER_SIZE; + } + + nlMsg = (PNL_MSG_HDR)NlBufAt(&nlBuf, 0, 0); + nlMsg->nlmsgLen = NlBufSize(&nlBuf); + *replyLen = msgOut->nlMsg.nlmsgLen; + + return STATUS_SUCCESS; +} diff --git a/datapath-windows/ovsext/Datapath.h b/datapath-windows/ovsext/Datapath.h index 09e233fd3..2b41d82ac 100644 --- a/datapath-windows/ovsext/Datapath.h +++ b/datapath-windows/ovsext/Datapath.h @@ -51,6 +51,7 @@ typedef struct _OVS_OPEN_INSTANCE { PVOID eventQueue; POVS_USER_PACKET_QUEUE packetQueue; UINT32 pid; + UINT32 protocol; /* Refers to NETLINK Family (eg. NETLINK_GENERIC)*/ struct { POVS_MESSAGE ovsMsg; /* OVS message passed during dump start. */ |