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 ankursha...@vmware.com
Acked-by: Alin Gabriel Serdean aserd...@cloudbasesolutions.com
Acked-by: Eitan Eliahu elia...@vmware.com
---
datapath-windows/include/OvsPub.h | 2 +-
datapath-windows/ovsext/Flow.c| 375 +++---
datapath-windows/ovsext/Flow.h| 6 +-
3 files changed, 357 insertions(+), 26 deletions(-)
diff --git a/datapath-windows/include/OvsPub.h
b/datapath-windows/include/OvsPub.h
index 36814c4..fa1d6d4 100644
--- a/datapath-windows/include/OvsPub.h
+++ b/datapath-windows/include/OvsPub.h
@@ -420,7 +420,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/Flow.c b/datapath-windows/ovsext/Flow.c
index 25b39c1..832cf3e 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 _OvsFlowMapNlToFlowPut(POVS_MESSAGE msgIn, PNL_ATTR keyAttr,
+ PNL_ATTR actionAttr,
+ PNL_ATTR flowAttrClear,
+ OvsFlowPut *mappedFlow);
+static VOID _OvsFlowMapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
+PNL_ATTR *tunnelAttrs,
+OvsFlowPut *mappedFlow);
+
+static VOID _OvsFlowMapTunAttrToFlowPut(PNL_ATTR *keyAttrs,
+PNL_ATTR *tunnelAttrs,
+OvsFlowKey *destKey);
+static VOID _OvsFlowMapNlToFlowPutFlags(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)
@@ -191,20 +205,356 @@ 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, NlMsgAttrLen(nlMsgHdr),
+ nlFlowPolicy, nlAttrs, ARRAY_SIZE(nlAttrs)))
+ != TRUE) {
+OVS_LOG_ERROR(Attr Parsing failed for msg: %p,
+ nlMsgHdr);
+rc = STATUS_UNSUCCESSFUL;
+goto done;
+}
+
+if ((_OvsFlowMapNlToFlowPut(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;
+}
-UNREFERENCED_PARAMETER(usrParamsCtx);
-UNREFERENCED_PARAMETER(replyLen);
+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 =