]> git.proxmox.com Git - mirror_ovs.git/blobdiff - datapath-windows/ovsext/User.c
datapath-windows: Fix conntrack event handler
[mirror_ovs.git] / datapath-windows / ovsext / User.c
index f2e3c17914f95c42e976173198433dd29188347b..c7ac28456983de7438023b467fd38d721ff3b20a 100644 (file)
@@ -46,10 +46,13 @@ extern PNDIS_SPIN_LOCK gOvsCtrlLock;
 extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
 OVS_USER_STATS ovsUserStats;
 
-static VOID _MapNlAttrToOvsPktExec(PNL_ATTR *nlAttrs, PNL_ATTR *keyAttrs,
-                                   OvsPacketExecute  *execute);
+static VOID _MapNlAttrToOvsPktExec(PNL_MSG_HDR nlMsgHdr, PNL_ATTR *nlAttrs,
+                                   PNL_ATTR *keyAttrs,
+                                   OvsPacketExecute *execute);
 extern NL_POLICY nlFlowKeyPolicy[];
 extern UINT32 nlFlowKeyPolicyLen;
+extern NL_POLICY nlFlowTunnelKeyPolicy[];
+extern UINT32 nlFlowTunnelKeyPolicyLen;
 
 static __inline VOID
 OvsAcquirePidHashLock()
@@ -311,7 +314,7 @@ OvsNlExecuteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
 
     execute.dpNo = ovsHdr->dp_ifindex;
 
-    _MapNlAttrToOvsPktExec(nlAttrs, keyAttrs, &execute);
+    _MapNlAttrToOvsPktExec(nlMsgHdr, nlAttrs, keyAttrs, &execute);
 
     status = OvsExecuteDpIoctl(&execute);
 
@@ -345,9 +348,9 @@ OvsNlExecuteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
 
             POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR)
                                            usrParamsCtx->outputBuffer;
-            UINT32 msgErrorLen = usrParamsCtx->outputLength;
 
-            NlBuildErrorMsg(msgIn, msgError, msgErrorLen, nlError, replyLen);
+            ASSERT(msgError);
+            NlBuildErrorMsg(msgIn, msgError, nlError, replyLen);
             status = STATUS_SUCCESS;
             goto done;
         }
@@ -364,15 +367,18 @@ done:
  *----------------------------------------------------------------------------
  */
 static VOID
-_MapNlAttrToOvsPktExec(PNL_ATTR *nlAttrs, PNL_ATTR *keyAttrs,
-                       OvsPacketExecute *execute)
+_MapNlAttrToOvsPktExec(PNL_MSG_HDR nlMsgHdr, PNL_ATTR *nlAttrs,
+                       PNL_ATTR *keyAttrs, OvsPacketExecute *execute)
 {
     execute->packetBuf = NlAttrGet(nlAttrs[OVS_PACKET_ATTR_PACKET]);
     execute->packetLen = NlAttrGetSize(nlAttrs[OVS_PACKET_ATTR_PACKET]);
 
+    execute->nlMsgHdr = nlMsgHdr;
+
     execute->actions = NlAttrGet(nlAttrs[OVS_PACKET_ATTR_ACTIONS]);
     execute->actionsLen = NlAttrGetSize(nlAttrs[OVS_PACKET_ATTR_ACTIONS]);
 
+    ASSERT(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
     execute->inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
     execute->keyAttrs = keyAttrs;
 }
@@ -389,6 +395,8 @@ OvsExecuteDpIoctl(OvsPacketExecute *execute)
     OvsFlowKey                  key = { 0 };
     OVS_PACKET_HDR_INFO         layers = { 0 };
     POVS_VPORT_ENTRY            vport = NULL;
+    PNL_ATTR tunnelAttrs[__OVS_TUNNEL_KEY_ATTR_MAX];
+    OvsFlowKey tempTunKey = {0};
 
     if (execute->packetLen == 0) {
         status = STATUS_INVALID_PARAMETER;
@@ -426,8 +434,31 @@ OvsExecuteDpIoctl(OvsPacketExecute *execute)
         goto dropit;
     }
 
-    ndisStatus = OvsExtractFlow(pNbl, fwdDetail->SourcePortId, &key, &layers,
-                                NULL);
+    if (execute->keyAttrs[OVS_KEY_ATTR_TUNNEL]) {
+        UINT32 tunnelKeyAttrOffset;
+
+        tunnelKeyAttrOffset = (UINT32)((PCHAR)
+                              (execute->keyAttrs[OVS_KEY_ATTR_TUNNEL])
+                              - (PCHAR)execute->nlMsgHdr);
+
+        /* Get tunnel keys attributes */
+        if ((NlAttrParseNested(execute->nlMsgHdr, tunnelKeyAttrOffset,
+                               NlAttrLen(execute->keyAttrs[OVS_KEY_ATTR_TUNNEL]),
+                               nlFlowTunnelKeyPolicy, nlFlowTunnelKeyPolicyLen,
+                               tunnelAttrs, ARRAY_SIZE(tunnelAttrs)))
+                               != TRUE) {
+            OVS_LOG_ERROR("Tunnel key Attr Parsing failed for msg: %p",
+                           execute->nlMsgHdr);
+            status = STATUS_INVALID_PARAMETER;
+            goto dropit;
+        }
+
+        MapTunAttrToFlowPut(execute->keyAttrs, tunnelAttrs, &tempTunKey);
+    }
+
+    ndisStatus = OvsExtractFlow(pNbl, execute->inPort, &key, &layers,
+                     tempTunKey.tunKey.dst == 0 ? NULL : &tempTunKey.tunKey);
+
     if (ndisStatus == NDIS_STATUS_SUCCESS) {
         NdisAcquireRWLockRead(gOvsSwitchContext->dispatchLock, &lockState, 0);
         ndisStatus = OvsActionsExecute(gOvsSwitchContext, NULL, pNbl,
@@ -737,7 +768,8 @@ OvsCreateAndAddPackets(PVOID userData,
         NDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO tsoInfo;
         UINT32 packetLength;
 
-        tsoInfo.Value = NET_BUFFER_LIST_INFO(nbl, TcpLargeSendNetBufferListInfo);
+        tsoInfo.Value = NET_BUFFER_LIST_INFO(nbl,
+                                             TcpLargeSendNetBufferListInfo);
         nb = NET_BUFFER_LIST_FIRST_NB(nbl);
         packetLength = NET_BUFFER_DATA_LENGTH(nb);
 
@@ -839,7 +871,8 @@ OvsCompletePacketHeader(UINT8 *packet,
                                          (UINT32 *)&ipHdr->DestinationAddress,
                                          IPPROTO_TCP, hdrInfoOut->l4PayLoad);
         } else {
-            PIPV6_HEADER ipv6Hdr = (PIPV6_HEADER)(packet + hdrInfoIn->l3Offset);
+            PIPV6_HEADER ipv6Hdr = (PIPV6_HEADER)(packet +
+                                                  hdrInfoIn->l3Offset);
             hdrInfoOut->l4PayLoad =
                 (UINT16)(ntohs(ipv6Hdr->PayloadLength) +
                 hdrInfoIn->l3Offset + sizeof(IPV6_HEADER)-
@@ -853,9 +886,9 @@ OvsCompletePacketHeader(UINT8 *packet,
         hdrInfoOut->tcpCsumNeeded = 1;
         ovsUserStats.recalTcpCsum++;
     } else if (!isRecv) {
-        if (csumInfo.Transmit.TcpChecksum) {
+        if (hdrInfoIn->isTcp && csumInfo.Transmit.TcpChecksum) {
             hdrInfoOut->tcpCsumNeeded = 1;
-        } else if (csumInfo.Transmit.UdpChecksum) {
+        } else if (hdrInfoIn->isUdp && csumInfo.Transmit.UdpChecksum) {
             hdrInfoOut->udpCsumNeeded = 1;
         }
         if (hdrInfoOut->tcpCsumNeeded || hdrInfoOut->udpCsumNeeded) {
@@ -865,7 +898,8 @@ OvsCompletePacketHeader(UINT8 *packet,
                 hdrInfoOut->tcpCsumNeeded ? IPPROTO_TCP : IPPROTO_UDP;
 #endif
             if (hdrInfoIn->isIPv4) {
-                PIPV4_HEADER ipHdr = (PIPV4_HEADER)(packet + hdrInfoIn->l3Offset);
+                PIPV4_HEADER ipHdr = (PIPV4_HEADER)(packet +
+                                                    hdrInfoIn->l3Offset);
                 hdrInfoOut->l4PayLoad = (UINT16)(ntohs(ipHdr->TotalLength) -
                     (ipHdr->HeaderLength << 2));
 #ifdef DBG
@@ -973,8 +1007,8 @@ OvsCreateQueueNlPacket(PVOID userData,
     csumInfo.Value = NET_BUFFER_LIST_INFO(nbl, TcpIpChecksumNetBufferListInfo);
 
     if (isRecv && (csumInfo.Receive.TcpChecksumFailed ||
-                  (csumInfo.Receive.UdpChecksumFailed && !hdrInfo->udpCsumZero) ||
-                  csumInfo.Receive.IpChecksumFailed)) {
+            (csumInfo.Receive.UdpChecksumFailed && !hdrInfo->udpCsumZero) ||
+            csumInfo.Receive.IpChecksumFailed)) {
         OVS_LOG_INFO("Packet dropped due to checksum failure.");
         ovsUserStats.dropDuetoChecksum++;
         return NULL;