diff mbox series

[ovs-dev,v1,1/1] datapath-windows: Update layers for multiple tunnels processing

Message ID 20220602064404.73085-1-svc.ovs-community@vmware.com
State Accepted
Headers show
Series [ovs-dev,v1,1/1] datapath-windows: Update layers for multiple tunnels processing | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test fail github build: failed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Wilson Peng June 2, 2022, 6:44 a.m. UTC
From: Wilson Peng <pweisong@vmware.com>

While testing OVS-windows for multiple IPV6 Geneve tunnels on Windows2019VM,
for the broadcast/mutlicast packets, it needs to flood out via configured
multiple Geneve tunnels. Then in some  flow pipeline processing, it may have
at least two tunnel processing in OVS_ACTION_ATTR_SET action. When processing
the second tunnel setting it may need flush out the packet out via tunnel before
setting new tunnel parameter in tunKey.  We found in this case, after flushing out
the packet out via tunnel, the related layers pointer does not update. In our
test setup on Windows2019VM, it will cause BSOD which is triggered in other Windows
 processes. We suspect it may be related to memory overwriting. When we apply the
fix in the patch, no BSOD is observed on the same VM and same packet/tunnel settting.

Another thing needs to be mentioned is for multiple Geneve IPv4 tunnels, the same
kind broadcase/multicast packet will not cause BSOD.

Signed-off-by: Wilson Peng <pweisong@vmware.com>
---
 datapath-windows/ovsext/Actions.c | 21 ++++++++++++++++++++-
 datapath-windows/ovsext/Flow.c    |  2 +-
 datapath-windows/ovsext/Flow.h    |  2 ++
 3 files changed, 23 insertions(+), 2 deletions(-)

Comments

Alin-Gabriel Serdean June 21, 2022, 11:33 p.m. UTC | #1
Applied on master! Thank you!

Alin.

-----Original Message-----
From: dev <ovs-dev-bounces@openvswitch.org> On Behalf Of Wilson Peng via dev
Sent: Thursday, June 2, 2022 9:44 AM
To: dev@openvswitch.org
Subject: [ovs-dev] [PATCH v1 1/1] datapath-windows: Update layers for
multiple tunnels processing

From: Wilson Peng <pweisong@vmware.com>

While testing OVS-windows for multiple IPV6 Geneve tunnels on Windows2019VM,
for the broadcast/mutlicast packets, it needs to flood out via configured
multiple Geneve tunnels. Then in some  flow pipeline processing, it may have
at least two tunnel processing in OVS_ACTION_ATTR_SET action. When
processing the second tunnel setting it may need flush out the packet out
via tunnel before setting new tunnel parameter in tunKey.  We found in this
case, after flushing out the packet out via tunnel, the related layers
pointer does not update. In our test setup on Windows2019VM, it will cause
BSOD which is triggered in other Windows  processes. We suspect it may be
related to memory overwriting. When we apply the fix in the patch, no BSOD
is observed on the same VM and same packet/tunnel settting.

Another thing needs to be mentioned is for multiple Geneve IPv4 tunnels, the
same kind broadcase/multicast packet will not cause BSOD.

Signed-off-by: Wilson Peng <pweisong@vmware.com>
---
 datapath-windows/ovsext/Actions.c | 21 ++++++++++++++++++++-
 datapath-windows/ovsext/Flow.c    |  2 +-
 datapath-windows/ovsext/Flow.h    |  2 ++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/datapath-windows/ovsext/Actions.c
b/datapath-windows/ovsext/Actions.c
index 0f7f78932..20de4db4c 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -2465,6 +2465,7 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
         }
         case OVS_ACTION_ATTR_SET:
         {
+            OvsIPTunnelKey pre_tunKey = { 0 };
             if (ovsFwdCtx.destPortsSizeOut > 0 || ovsFwdCtx.tunnelTxNic !=
NULL
                 || ovsFwdCtx.tunnelRxNic != NULL) {
                 status = OvsOutputBeforeSetAction(&ovsFwdCtx);
@@ -2473,7 +2474,7 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
                     goto dropit;
                 }
             }
-
+            RtlCopyMemory(&pre_tunKey, &key->tunKey, sizeof 
+ key->tunKey);
             status = OvsExecuteSetAction(&ovsFwdCtx, key, hash,
                                          (const PNL_ATTR)NlAttrGet
                                          ((const PNL_ATTR)a)); @@ -2481,6
+2482,24 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
                 dropReason = L"OVS-set action failed";
                 goto dropit;
             }
+
+            if (!OvsIphIsZero(&(key->tunKey.dst)) &&
+                 key->l2.offset != OvsGetFlowIPL2Offset(&key->tunKey)) {
+                 key->l2.offset = OvsGetFlowIPL2Offset(&ovsFwdCtx.tunKey);
+            }
+            if (!OvsIphIsZero(&(pre_tunKey.dst))) {
+                 /*if pre_tunkey dst is not null in multiple IPV6 Geneve
tunnels case,
+                  * for broadcast and multicast packet the flow pipeline
will set different
+                  * tunnel setting on one flow. In such case, it needs to
do layers update.
+                  * Elsewise it will meet BSOD issue but in IPV4 tunnel the
BSOD will not
+                  * have construct case to make it happen.
+                  */
+                 status = OvsExtractLayers(ovsFwdCtx.curNbl,
&ovsFwdCtx.layers);
+                 if (status != NDIS_STATUS_SUCCESS) {
+                     dropReason = L"OVS-set action ExtractLayers failed";
+                     goto dropit;
+                 }
+            }
             break;
         }
         case OVS_ACTION_ATTR_SAMPLE:
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index 08fba4c4d..86e809fc1 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -88,7 +88,7 @@ static NTSTATUS OvsDoDumpFlows(OvsFlowDumpInput
*dumpInput,
                                UINT32 *replyLen);  static NTSTATUS
OvsProbeSupportedFeature(POVS_MESSAGE msgIn,
                                          PNL_ATTR keyAttr); -static UINT16
OvsGetFlowIPL2Offset(const OvsIPTunnelKey *tunKey);
+UINT16 OvsGetFlowIPL2Offset(const OvsIPTunnelKey *tunKey);
 
 #define OVS_FLOW_TABLE_SIZE 2048
 #define OVS_FLOW_TABLE_MASK (OVS_FLOW_TABLE_SIZE -1) diff --git
a/datapath-windows/ovsext/Flow.h b/datapath-windows/ovsext/Flow.h index
8f7214124..ea3396f08 100644
--- a/datapath-windows/ovsext/Flow.h
+++ b/datapath-windows/ovsext/Flow.h
@@ -89,6 +89,8 @@ UINT32 OvsTunKeyAttrSize(void);  NTSTATUS
OvsTunnelAttrToIPTunnelKey(PNL_ATTR attr, OvsIPTunnelKey *tunKey);
 
+UINT16 OvsGetFlowIPL2Offset(const OvsIPTunnelKey *tunKey);
+
 /* Flags for tunneling */
 #define OVS_TNL_F_DONT_FRAGMENT         (1 << 0)
 #define OVS_TNL_F_CSUM                  (1 << 1)
--
2.24.3 (Apple Git-128)
diff mbox series

Patch

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 0f7f78932..20de4db4c 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -2465,6 +2465,7 @@  OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
         }
         case OVS_ACTION_ATTR_SET:
         {
+            OvsIPTunnelKey pre_tunKey = { 0 };
             if (ovsFwdCtx.destPortsSizeOut > 0 || ovsFwdCtx.tunnelTxNic != NULL
                 || ovsFwdCtx.tunnelRxNic != NULL) {
                 status = OvsOutputBeforeSetAction(&ovsFwdCtx);
@@ -2473,7 +2474,7 @@  OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
                     goto dropit;
                 }
             }
-
+            RtlCopyMemory(&pre_tunKey, &key->tunKey, sizeof key->tunKey);
             status = OvsExecuteSetAction(&ovsFwdCtx, key, hash,
                                          (const PNL_ATTR)NlAttrGet
                                          ((const PNL_ATTR)a));
@@ -2481,6 +2482,24 @@  OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
                 dropReason = L"OVS-set action failed";
                 goto dropit;
             }
+
+            if (!OvsIphIsZero(&(key->tunKey.dst)) &&
+                 key->l2.offset != OvsGetFlowIPL2Offset(&key->tunKey)) {
+                 key->l2.offset = OvsGetFlowIPL2Offset(&ovsFwdCtx.tunKey);
+            }
+            if (!OvsIphIsZero(&(pre_tunKey.dst))) {
+                 /*if pre_tunkey dst is not null in multiple IPV6 Geneve tunnels case,
+                  * for broadcast and multicast packet the flow pipeline will set different
+                  * tunnel setting on one flow. In such case, it needs to do layers update.
+                  * Elsewise it will meet BSOD issue but in IPV4 tunnel the BSOD will not
+                  * have construct case to make it happen.
+                  */
+                 status = OvsExtractLayers(ovsFwdCtx.curNbl, &ovsFwdCtx.layers);
+                 if (status != NDIS_STATUS_SUCCESS) {
+                     dropReason = L"OVS-set action ExtractLayers failed";
+                     goto dropit;
+                 }
+            }
             break;
         }
         case OVS_ACTION_ATTR_SAMPLE:
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index 08fba4c4d..86e809fc1 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -88,7 +88,7 @@  static NTSTATUS OvsDoDumpFlows(OvsFlowDumpInput *dumpInput,
                                UINT32 *replyLen);
 static NTSTATUS OvsProbeSupportedFeature(POVS_MESSAGE msgIn,
                                          PNL_ATTR keyAttr);
-static UINT16 OvsGetFlowIPL2Offset(const OvsIPTunnelKey *tunKey);
+UINT16 OvsGetFlowIPL2Offset(const OvsIPTunnelKey *tunKey);
 
 #define OVS_FLOW_TABLE_SIZE 2048
 #define OVS_FLOW_TABLE_MASK (OVS_FLOW_TABLE_SIZE -1)
diff --git a/datapath-windows/ovsext/Flow.h b/datapath-windows/ovsext/Flow.h
index 8f7214124..ea3396f08 100644
--- a/datapath-windows/ovsext/Flow.h
+++ b/datapath-windows/ovsext/Flow.h
@@ -89,6 +89,8 @@  UINT32 OvsTunKeyAttrSize(void);
 NTSTATUS
 OvsTunnelAttrToIPTunnelKey(PNL_ATTR attr, OvsIPTunnelKey *tunKey);
 
+UINT16 OvsGetFlowIPL2Offset(const OvsIPTunnelKey *tunKey);
+
 /* Flags for tunneling */
 #define OVS_TNL_F_DONT_FRAGMENT         (1 << 0)
 #define OVS_TNL_F_CSUM                  (1 << 1)