summaryrefslogtreecommitdiff
path: root/datapath-windows
diff options
context:
space:
mode:
authorAnkur Sharma <ankursharma@vmware.com>2014-09-26 17:33:08 -0700
committerBen Pfaff <blp@nicira.com>2014-09-29 09:03:42 -0700
commit8a79c2d43150e9ae3fd88370a64458a9c423cf91 (patch)
tree800b38bb242ca504b08bbd5ff745ef1457fb5373 /datapath-windows
parent0d9bd68b7b30a83d601cca2040702894a95b2b5a (diff)
downloadopenvswitch-8a79c2d43150e9ae3fd88370a64458a9c423cf91.tar.gz
datapath-windows/Flow.c: FLOW_NEW command handler.
This patch covers the changes needed to support FLOW_NEW command. API _OvsFlowMapNlToFlowPutFlags has a bug, which will be fixed with the patches for FLOW_DEL. Signed-off-by: Ankur Sharma <ankursharma@vmware.com> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Acked-by: Eitan Eliahu <eliahue@vmware.com> Acked-by: Nithin Raju <nithin@vmware.com> Acked-by: Samuel Ghinet <sghinet@cloudbasesolutions.com> Tested-by: Ankur Sharma <ankursharma@vmware.com> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'datapath-windows')
-rw-r--r--datapath-windows/include/OvsPub.h2
-rw-r--r--datapath-windows/ovsext/Datapath.c2
-rw-r--r--datapath-windows/ovsext/Flow.c441
-rw-r--r--datapath-windows/ovsext/Flow.h6
4 files changed, 424 insertions, 27 deletions
diff --git a/datapath-windows/include/OvsPub.h b/datapath-windows/include/OvsPub.h
index ff0e8ce20..a8516b6d2 100644
--- a/datapath-windows/include/OvsPub.h
+++ b/datapath-windows/include/OvsPub.h
@@ -405,7 +405,7 @@ typedef struct OvsFlowPut {
uint32_t actionsLen;
OvsFlowKey key;
uint32_t flags;
- NL_ATTR actions[0]; /* Variable length indicated by actionsLen. */
+ PNL_ATTR actions;
} OvsFlowPut;
#define OVS_MIN_PACKET_SIZE 60
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 6174a85d8..9fe6fa5fb 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -157,7 +157,7 @@ NETLINK_CMD nlDatapathFamilyCmdOps[] = {
.handler = OvsGetDpCmdHandler,
.supportedDevOp = OVS_WRITE_DEV_OP | OVS_READ_DEV_OP |
OVS_TRANSACTION_DEV_OP,
- .validateDpIndex = FALSE
+ .validateDpIndex = FALSE
},
{ .cmd = OVS_DP_CMD_SET,
.handler = OvsSetDpCmdHandler,
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index fb408dae6..f68db19fd 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -46,6 +46,20 @@ static VOID DeleteAllFlows(OVS_DATAPATH *datapath);
static NTSTATUS AddFlow(OVS_DATAPATH *datapath, OvsFlow *flow);
static VOID FreeFlow(OvsFlow *flow);
static VOID __inline *GetStartAddrNBL(const NET_BUFFER_LIST *_pNB);
+static NTSTATUS _MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr,
+ PNL_ATTR actionAttr,
+ PNL_ATTR flowAttrClear,
+ OvsFlowPut *mappedFlow);
+static VOID _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
+ PNL_ATTR *tunnelAttrs,
+ OvsFlowPut *mappedFlow);
+
+static VOID _MapTunAttrToFlowPut(PNL_ATTR *keyAttrs,
+ PNL_ATTR *tunnelAttrs,
+ OvsFlowKey *destKey);
+static VOID _MapNlToFlowPutFlags(PGENL_MSG_HDR genlMsgHdr,
+ PNL_ATTR flowAttrClear,
+ OvsFlowPut *mappedFlow);
#define OVS_FLOW_TABLE_SIZE 2048
#define OVS_FLOW_TABLE_MASK (OVS_FLOW_TABLE_SIZE -1)
@@ -194,20 +208,422 @@ static const NL_POLICY nlFlowActionPolicy[] = {
* Netlink interface for flow commands.
*----------------------------------------------------------------------------
*/
+
+/*
+ *----------------------------------------------------------------------------
+ * OvsFlowNlNewCmdHandler --
+ * Handler for OVS_FLOW_CMD_NEW command.
+ *----------------------------------------------------------------------------
+ */
NTSTATUS
OvsFlowNlNewCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
UINT32 *replyLen)
{
NTSTATUS rc = STATUS_SUCCESS;
+ POVS_MESSAGE msgIn = (POVS_MESSAGE)usrParamsCtx->inputBuffer;
+ POVS_MESSAGE msgOut = (POVS_MESSAGE)usrParamsCtx->outputBuffer;
+ PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg);
+ PGENL_MSG_HDR genlMsgHdr = &(msgIn->genlMsg);
+ POVS_HDR ovsHdr = &(msgIn->ovsHdr);
+ PNL_ATTR nlAttrs[__OVS_FLOW_ATTR_MAX];
+ UINT32 attrOffset = NLMSG_HDRLEN + GENL_HDRLEN + OVS_HDRLEN;
+ OvsFlowPut mappedFlow;
+ OvsFlowStats stats;
+ struct ovs_flow_stats replyStats;
+
+ NL_BUFFER nlBuf;
+
+ RtlZeroMemory(&mappedFlow, sizeof(OvsFlowPut));
+ RtlZeroMemory(&stats, sizeof(stats));
+ RtlZeroMemory(&replyStats, sizeof(replyStats));
+
+ *replyLen = 0;
+
+ /* Get all the top level Flow attributes */
+ if ((NlAttrParse(nlMsgHdr, attrOffset, NlMsgAttrsLen(nlMsgHdr),
+ nlFlowPolicy, nlAttrs, ARRAY_SIZE(nlAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ rc = STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if ((_MapNlToFlowPut(msgIn, nlAttrs[OVS_FLOW_ATTR_KEY],
+ nlAttrs[OVS_FLOW_ATTR_ACTIONS], nlAttrs[OVS_FLOW_ATTR_CLEAR],
+ &mappedFlow))
+ != STATUS_SUCCESS) {
+ OVS_LOG_ERROR("Conversion to OvsFlowPut failed");
+ goto done;
+ }
+
+ rc = OvsPutFlowIoctl(&mappedFlow, sizeof (struct OvsFlowPut),
+ &stats);
+ if (rc != STATUS_SUCCESS) {
+ OVS_LOG_ERROR("OvsFlowPut failed.");
+ goto done;
+ }
+
+ if (!(usrParamsCtx->outputBuffer)) {
+ /* No output buffer */
+ OVS_LOG_ERROR("outputBuffer NULL.");
+ goto done;
+ }
+
+ replyStats.n_packets = stats.packetCount;
+ replyStats.n_bytes = stats.byteCount;
+
+ /* So far so good. Prepare the reply for userspace */
+ NlBufInit(&nlBuf, usrParamsCtx->outputBuffer,
+ usrParamsCtx->outputLength);
+
+ /* Prepare nl Msg headers */
+ rc = NlFillOvsMsg(&nlBuf, nlMsgHdr->nlmsgType, 0,
+ nlMsgHdr->nlmsgSeq, nlMsgHdr->nlmsgPid,
+ genlMsgHdr->cmd, OVS_FLOW_VERSION,
+ ovsHdr->dp_ifindex);
+ ASSERT(rc);
+
+ /* Append OVS_FLOW_ATTR_STATS attribute */
+ if (!NlMsgPutTailUnspec(&nlBuf, OVS_FLOW_ATTR_STATS,
+ (PCHAR)(&replyStats), sizeof(replyStats))) {
+ OVS_LOG_ERROR("Adding OVS_FLOW_ATTR_STATS attribute failed.");
+ rc = STATUS_UNSUCCESSFUL;
+ }
- UNREFERENCED_PARAMETER(usrParamsCtx);
- UNREFERENCED_PARAMETER(replyLen);
+ *replyLen = msgOut->nlMsg.nlmsgLen;
+done:
return rc;
}
/*
*----------------------------------------------------------------------------
+ * _MapNlToFlowPut --
+ * Maps input netlink message to OvsFlowPut.
+ *----------------------------------------------------------------------------
+ */
+static NTSTATUS
+_MapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr,
+ PNL_ATTR actionAttr, PNL_ATTR flowAttrClear,
+ OvsFlowPut *mappedFlow)
+{
+ NTSTATUS rc = STATUS_SUCCESS;
+ PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg);
+ PGENL_MSG_HDR genlMsgHdr = &(msgIn->genlMsg);
+ POVS_HDR ovsHdr = &(msgIn->ovsHdr);
+
+ UINT32 keyAttrOffset = (UINT32)((PCHAR)keyAttr - (PCHAR)nlMsgHdr);
+ UINT32 tunnelKeyAttrOffset;
+
+ PNL_ATTR keyAttrs[__OVS_KEY_ATTR_MAX] = {NULL};
+ PNL_ATTR tunnelAttrs[__OVS_TUNNEL_KEY_ATTR_MAX] = {NULL};
+
+ /* Get flow keys attributes */
+ if ((NlAttrParseNested(nlMsgHdr, keyAttrOffset, NlAttrLen(keyAttr),
+ nlFlowKeyPolicy, keyAttrs, ARRAY_SIZE(keyAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Key Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ rc = STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (keyAttrs[OVS_KEY_ATTR_TUNNEL]) {
+ tunnelKeyAttrOffset = (UINT32)((PCHAR)
+ (keyAttrs[OVS_KEY_ATTR_TUNNEL])
+ - (PCHAR)nlMsgHdr);
+
+ OVS_LOG_ERROR("Parse Flow Tunnel Key Policy");
+
+ /* Get tunnel keys attributes */
+ if ((NlAttrParseNested(nlMsgHdr, tunnelKeyAttrOffset,
+ NlAttrLen(keyAttr), nlFlowTunnelKeyPolicy,
+ tunnelAttrs, ARRAY_SIZE(tunnelAttrs)))
+ != TRUE) {
+ OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p",
+ nlMsgHdr);
+ rc = STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+ }
+
+ _MapKeyAttrToFlowPut(keyAttrs, tunnelAttrs,
+ mappedFlow);
+
+ /* Map the action */
+ mappedFlow->actionsLen = NlAttrGetSize(actionAttr);
+ mappedFlow->actions = NlAttrGet(actionAttr);
+ mappedFlow->dpNo = ovsHdr->dp_ifindex;
+
+ _MapNlToFlowPutFlags(genlMsgHdr, flowAttrClear,
+ mappedFlow);
+
+done:
+ return rc;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * _MapNlToFlowPutFlags --
+ * Maps netlink message to OvsFlowPut->flags.
+ *----------------------------------------------------------------------------
+ */
+static VOID
+_MapNlToFlowPutFlags(PGENL_MSG_HDR genlMsgHdr,
+ PNL_ATTR flowAttrClear, OvsFlowPut *mappedFlow)
+{
+ uint32_t flags = 0;
+
+ switch (genlMsgHdr->cmd) {
+ case OVS_FLOW_CMD_NEW:
+ flags |= OVSWIN_FLOW_PUT_CREATE;
+ break;
+ case OVS_FLOW_CMD_DEL:
+ flags |= OVSWIN_FLOW_PUT_DELETE;
+ break;
+ case OVS_FLOW_CMD_SET:
+ flags |= OVSWIN_FLOW_PUT_MODIFY;
+ break;
+ default:
+ ASSERT(0);
+ }
+
+ if (flowAttrClear) {
+ flags |= OVSWIN_FLOW_PUT_CLEAR;
+ }
+
+ mappedFlow->flags = flags;
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * _MapKeyAttrToFlowPut --
+ * Converts FLOW_KEY attribute to OvsFlowPut->key.
+ *----------------------------------------------------------------------------
+ */
+static VOID
+_MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
+ PNL_ATTR *tunnelAttrs,
+ OvsFlowPut *mappedFlow)
+{
+ const struct ovs_key_ethernet *eth_key;
+ OvsFlowKey *destKey = &(mappedFlow->key);
+
+ _MapTunAttrToFlowPut(keyAttrs, tunnelAttrs, destKey);
+
+ /* ===== L2 headers ===== */
+ destKey->l2.inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
+ eth_key = NlAttrGet(keyAttrs[OVS_KEY_ATTR_ETHERNET]);
+ RtlCopyMemory(destKey->l2.dlSrc, eth_key->eth_src, ETH_ADDR_LEN);
+ RtlCopyMemory(destKey->l2.dlDst, eth_key->eth_dst, ETH_ADDR_LEN);
+
+ destKey->l2.dlType = ntohs((NlAttrGetU16(keyAttrs
+ [OVS_KEY_ATTR_ETHERTYPE])));
+
+ if (keyAttrs[OVS_KEY_ATTR_VLAN]) {
+ destKey->l2.vlanTci = NlAttrGetU16(keyAttrs
+ [OVS_KEY_ATTR_VLAN]);
+ }
+
+ /* ==== L3 + L4. ==== */
+ destKey->l2.keyLen = OVS_WIN_TUNNEL_KEY_SIZE + OVS_L2_KEY_SIZE
+ - destKey->l2.offset;
+
+ switch (destKey->l2.dlType) {
+ case ETH_TYPE_IPV4: {
+
+ if (keyAttrs[OVS_KEY_ATTR_IPV4]) {
+ const struct ovs_key_ipv4 *ipv4Key;
+
+ ipv4Key = NlAttrGet(keyAttrs[OVS_KEY_ATTR_IPV4]);
+ IpKey *ipv4FlowPutKey = &(destKey->ipKey);
+ ipv4FlowPutKey->nwSrc = ipv4Key->ipv4_src;
+ ipv4FlowPutKey->nwDst = ipv4Key->ipv4_dst;
+ ipv4FlowPutKey->nwProto = ipv4Key->ipv4_proto;
+ ipv4FlowPutKey->nwTos = ipv4Key->ipv4_tos;
+ ipv4FlowPutKey->nwTtl = ipv4Key->ipv4_ttl;
+ ipv4FlowPutKey->nwFrag = ipv4Key->ipv4_frag;
+
+ if (keyAttrs[OVS_KEY_ATTR_TCP]) {
+ const struct ovs_key_tcp *tcpKey;
+ tcpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_TCP]);
+ ipv4FlowPutKey->l4.tpSrc = tcpKey->tcp_src;
+ ipv4FlowPutKey->l4.tpDst = tcpKey->tcp_dst;
+ }
+
+ if (keyAttrs[OVS_KEY_ATTR_UDP]) {
+ const struct ovs_key_udp *udpKey;
+ udpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_UDP]);
+ ipv4FlowPutKey->l4.tpSrc = udpKey->udp_src;
+ ipv4FlowPutKey->l4.tpDst = udpKey->udp_dst;
+ }
+
+ if (keyAttrs[OVS_KEY_ATTR_SCTP]) {
+ const struct ovs_key_sctp *sctpKey;
+ sctpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_SCTP]);
+ ipv4FlowPutKey->l4.tpSrc = sctpKey->sctp_src;
+ ipv4FlowPutKey->l4.tpDst = sctpKey->sctp_dst;
+ }
+
+ destKey->l2.keyLen += OVS_IP_KEY_SIZE;
+ }
+ break;
+ }
+ case ETH_TYPE_IPV6: {
+
+ if (keyAttrs[OVS_KEY_ATTR_IPV6]) {
+ const struct ovs_key_ipv6 *ipv6Key;
+
+ ipv6Key = NlAttrGet(keyAttrs[OVS_KEY_ATTR_IPV6]);
+ Ipv6Key *ipv6FlowPutKey = &(destKey->ipv6Key);
+
+ RtlCopyMemory(&ipv6FlowPutKey->ipv6Src, ipv6Key->ipv6_src,
+ sizeof ipv6Key->ipv6_src);
+ RtlCopyMemory(&ipv6FlowPutKey->ipv6Dst, ipv6Key->ipv6_dst,
+ sizeof ipv6Key->ipv6_dst);
+
+ ipv6FlowPutKey->ipv6Label = ipv6Key->ipv6_label;
+ ipv6FlowPutKey->nwProto = ipv6Key->ipv6_proto;
+ ipv6FlowPutKey->nwTos = ipv6Key->ipv6_tclass;
+ ipv6FlowPutKey->nwTtl = ipv6Key->ipv6_hlimit;
+ ipv6FlowPutKey->nwFrag = ipv6Key->ipv6_frag;
+
+ if (keyAttrs[OVS_KEY_ATTR_TCP]) {
+ const struct ovs_key_tcp *tcpKey;
+ tcpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_TCP]);
+ ipv6FlowPutKey->l4.tpSrc = tcpKey->tcp_src;
+ ipv6FlowPutKey->l4.tpDst = tcpKey->tcp_dst;
+ }
+
+ if (keyAttrs[OVS_KEY_ATTR_UDP]) {
+ const struct ovs_key_udp *udpKey;
+ udpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_UDP]);
+ ipv6FlowPutKey->l4.tpSrc = udpKey->udp_src;
+ ipv6FlowPutKey->l4.tpDst = udpKey->udp_dst;
+ }
+
+ if (keyAttrs[OVS_KEY_ATTR_SCTP]) {
+ const struct ovs_key_sctp *sctpKey;
+ sctpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_SCTP]);
+ ipv6FlowPutKey->l4.tpSrc = sctpKey->sctp_src;
+ ipv6FlowPutKey->l4.tpDst = sctpKey->sctp_dst;
+ }
+
+ if (keyAttrs[OVS_KEY_ATTR_ICMPV6]) {
+ const struct ovs_key_icmpv6 *icmpv6Key;
+
+ Icmp6Key *icmp6FlowPutKey= &(destKey->icmp6Key);
+
+ icmpv6Key = NlAttrGet(keyAttrs[OVS_KEY_ATTR_ICMPV6]);
+
+ icmp6FlowPutKey->l4.tpSrc = icmpv6Key->icmpv6_type;
+ icmp6FlowPutKey->l4.tpDst = icmpv6Key->icmpv6_code;
+
+ if (keyAttrs[OVS_KEY_ATTR_ND]) {
+ const struct ovs_key_nd *ndKey;
+
+ ndKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_ND]);
+ RtlCopyMemory(&icmp6FlowPutKey->ndTarget,
+ ndKey->nd_target, sizeof (icmp6FlowPutKey->ndTarget));
+ RtlCopyMemory(icmp6FlowPutKey->arpSha,
+ ndKey->nd_sll, ETH_ADDR_LEN);
+ RtlCopyMemory(icmp6FlowPutKey->arpTha,
+ ndKey->nd_tll, ETH_ADDR_LEN);
+ }
+
+ destKey->l2.keyLen += OVS_ICMPV6_KEY_SIZE;
+
+ } else {
+
+ destKey->l2.keyLen += OVS_IPV6_KEY_SIZE;
+ }
+
+ ipv6FlowPutKey->pad = 0;
+ }
+ break;
+ }
+ case ETH_TYPE_ARP:
+ case ETH_TYPE_RARP: {
+ ArpKey *arpFlowPutKey = &destKey->arpKey;
+ const struct ovs_key_arp *arpKey;
+
+ arpKey = NlAttrGet(keyAttrs[OVS_KEY_ATTR_ARP]);
+
+ arpFlowPutKey->nwSrc = arpKey->arp_sip;
+ arpFlowPutKey->nwDst = arpKey->arp_tip;
+
+ RtlCopyMemory(arpFlowPutKey->arpSha, arpKey->arp_sha, ETH_ADDR_LEN);
+ RtlCopyMemory(arpFlowPutKey->arpTha, arpKey->arp_tha, ETH_ADDR_LEN);
+ arpFlowPutKey->nwProto = (UINT8)(arpKey->arp_op);
+ arpFlowPutKey->pad[0] = 0;
+ arpFlowPutKey->pad[1] = 0;
+ arpFlowPutKey->pad[2] = 0;
+ destKey->l2.keyLen += OVS_ARP_KEY_SIZE;
+ break;
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
+ * _MapTunAttrToFlowPut --
+ * Converts FLOW_TUNNEL_KEY attribute to OvsFlowKey->tunKey.
+ *----------------------------------------------------------------------------
+ */
+static VOID
+_MapTunAttrToFlowPut(PNL_ATTR *keyAttrs,
+ PNL_ATTR *tunAttrs,
+ OvsFlowKey *destKey)
+{
+ if (keyAttrs[OVS_KEY_ATTR_TUNNEL]) {
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_ID]) {
+ destKey->tunKey.tunnelId = NlAttrGetU64
+ (tunAttrs[OVS_TUNNEL_KEY_ATTR_ID]);
+ destKey->tunKey.flags |= OVS_TNL_F_KEY;
+ }
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_DST]) {
+ destKey->tunKey.dst = NlAttrGetU32
+ (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_DST]);
+ }
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_SRC]) {
+ destKey->tunKey.src = NlAttrGetU32
+ (tunAttrs[OVS_TUNNEL_KEY_ATTR_IPV4_SRC]);
+ }
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT]) {
+ destKey->tunKey.flags |= OVS_TNL_F_DONT_FRAGMENT;
+ }
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_CSUM]) {
+ destKey->tunKey.flags |= OVS_TNL_F_CSUM;
+ }
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_TOS]) {
+ destKey->tunKey.tos = NlAttrGetU8
+ (tunAttrs[OVS_TUNNEL_KEY_ATTR_TOS]);
+ }
+
+ if (tunAttrs[OVS_TUNNEL_KEY_ATTR_TTL]) {
+ destKey->tunKey.ttl = NlAttrGetU8
+ (tunAttrs[OVS_TUNNEL_KEY_ATTR_TTL]);
+ }
+
+ destKey->tunKey.pad = 0;
+ destKey->l2.offset = 0;
+ } else {
+ destKey->tunKey.attr[0] = 0;
+ destKey->tunKey.attr[1] = 0;
+ destKey->tunKey.attr[2] = 0;
+ destKey->l2.offset = sizeof destKey->tunKey;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------------
* OvsDeleteFlowTable --
* Results:
* NDIS_STATUS_SUCCESS always.
@@ -840,13 +1256,10 @@ ReportFlowInfo(OvsFlow *flow,
NTSTATUS
OvsPutFlowIoctl(PVOID inputBuffer,
UINT32 inputLength,
- PVOID outputBuffer,
- UINT32 outputLength,
- UINT32 *replyLen)
+ struct OvsFlowStats *stats)
{
NTSTATUS status = STATUS_SUCCESS;
OVS_DATAPATH *datapath = NULL;
- struct OvsFlowStats stats;
ULONG actionsLen;
OvsFlowPut *put;
UINT32 dpNo;
@@ -856,19 +1269,12 @@ OvsPutFlowIoctl(PVOID inputBuffer,
return STATUS_INFO_LENGTH_MISMATCH;
}
- if ((outputLength != sizeof(stats)) || (outputBuffer == NULL)) {
- return STATUS_INFO_LENGTH_MISMATCH;
- }
-
put = (OvsFlowPut *)inputBuffer;
if (put->actionsLen > 0) {
actionsLen = put->actionsLen;
} else {
actionsLen = 0;
}
- if (inputLength != actionsLen + sizeof(*put)) {
- return STATUS_INFO_LENGTH_MISMATCH;
- }
dpNo = put->dpNo;
NdisAcquireSpinLock(gOvsCtrlLock);
@@ -880,17 +1286,10 @@ OvsPutFlowIoctl(PVOID inputBuffer,
datapath = &gOvsSwitchContext->datapath;
ASSERT(datapath);
- RtlZeroMemory(&stats, sizeof(stats));
OvsAcquireDatapathWrite(datapath, &dpLockState, FALSE);
- status = HandleFlowPut(put, datapath, &stats);
+ status = HandleFlowPut(put, datapath, stats);
OvsReleaseDatapath(datapath, &dpLockState);
- if (status == STATUS_SUCCESS) {
- // Copy stats to User mode app
- NdisMoveMemory(outputBuffer, (PVOID)&stats, sizeof(stats));
- *replyLen = sizeof stats;
- }
-
unlock:
NdisReleaseSpinLock(gOvsCtrlLock);
return status;
diff --git a/datapath-windows/ovsext/Flow.h b/datapath-windows/ovsext/Flow.h
index 602e56705..e62ba409b 100644
--- a/datapath-windows/ovsext/Flow.h
+++ b/datapath-windows/ovsext/Flow.h
@@ -64,16 +64,14 @@ NTSTATUS OvsDumpFlowIoctl(PVOID inputBuffer, UINT32 inputLength,
PVOID outputBuffer, UINT32 outputLength,
UINT32 *replyLen);
NTSTATUS OvsPutFlowIoctl(PVOID inputBuffer, UINT32 inputLength,
- PVOID outputBuffer, UINT32 outputLength,
- UINT32 *replyLen);
+ struct OvsFlowStats *stats);
NTSTATUS OvsGetFlowIoctl(PVOID inputBuffer, UINT32 inputLength,
PVOID outputBuffer, UINT32 outputLength,
UINT32 *replyLen);
NTSTATUS OvsFlushFlowIoctl(PVOID inputBuffer, UINT32 inputLength);
NTSTATUS OvsFlowNlNewCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
- UINT32 *replyLen);
-
+ UINT32 *replyLen);
/* Flags for tunneling */
#define OVS_TNL_F_DONT_FRAGMENT (1 << 0)