[ovs-dev] [PATCH] datapath-windows: Support for IPv6 in TCP segmentation.

Alin Serdean aserdean at cloudbasesolutions.com
Mon Feb 29 17:38:30 UTC 2016


You are right Sai, the flags need to be set before the checksum is computed.

I acked you patch.

Alin.

> -----Mesaj original-----
> De la: Sairam Venugopal [mailto:vsairam at vmware.com]
> Trimis: Friday, February 26, 2016 12:56 AM
> Către: Sorin Vinturis <svinturis at cloudbasesolutions.com>;
> dev at openvswitch.org
> Cc: Alin Serdean <aserdean at cloudbasesolutions.com>
> Subiect: Re: [ovs-dev] [PATCH] datapath-windows: Support for IPv6 in TCP
> segmentation.
> 
> Hi Sorin/Alin,
> 
> I tested out the patch and it seems to break existing checksum calculation. I
> will send out a patch with changes that I did on top of Sorin¹s. I tested it out
> and could send TCP packets using IPv4 and IPv6.
> 
> I believe this patch is in regards to the issue I reported earlier -
> https://github.com/openvswitch/ovs-issues/issues/105
> 
> Thanks,
> Sairam
> 
> On 2/18/16, 3:08 AM, "Sorin Vinturis" <svinturis at cloudbasesolutions.com>
> wrote:
> 
> >When a packet which needs segmentation is received, the header for each
> >segment is being calculated, i.e. IP length, checksum, TCP seq, TCP
> >checksum.
> >
> >The problem with the current code is that it wrongly assumes that the
> >Ethernet frame payload is always an IPv4 packet.
> >
> >This patch checks the EtherType field of the Ethernet frame to see
> >which protocol is encapsulated in its payload, IPv4 or IPv6, and
> >calculates accordingly the segment's header.
> >
> >Signed-off-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>
> >---
> > datapath-windows/ovsext/BufferMgmt.c | 91
> >++++++++++++++++++++++++------------
> > 1 file changed, 62 insertions(+), 29 deletions(-)
> >
> >diff --git a/datapath-windows/ovsext/BufferMgmt.c
> >b/datapath-windows/ovsext/BufferMgmt.c
> >index 3189e9b..085a551 100644
> >--- a/datapath-windows/ovsext/BufferMgmt.c
> >+++ b/datapath-windows/ovsext/BufferMgmt.c
> >@@ -1122,11 +1122,10 @@ static NDIS_STATUS
> >FixSegmentHeader(PNET_BUFFER nb, UINT16 segmentSize, UINT32
> seqNumber,
> >                  BOOLEAN lastPacket, UINT16 packetCounter)  {
> >-    EthHdr *dstEth;
> >-    IPHdr *dstIP;
> >-    TCPHdr *dstTCP;
> >-    PMDL mdl;
> >-    PUINT8 bufferStart;
> >+    EthHdr *dstEth = NULL;
> >+    TCPHdr *dstTCP = NULL;
> >+    PMDL mdl = NULL;
> >+    PUINT8 bufferStart = NULL;
> >
> >     mdl = NET_BUFFER_FIRST_MDL(nb);
> >
> >@@ -1135,21 +1134,64 @@ FixSegmentHeader(PNET_BUFFER nb, UINT16
> >segmentSize, UINT32 seqNumber,
> >         return NDIS_STATUS_RESOURCES;
> >     }
> >     dstEth = (EthHdr *)(bufferStart +
> NET_BUFFER_CURRENT_MDL_OFFSET(nb));
> >-    ASSERT((INT)MmGetMdlByteCount(mdl) -
> >NET_BUFFER_CURRENT_MDL_OFFSET(nb)
> >-            >= sizeof(EthHdr) + sizeof(IPHdr) + sizeof(TCPHdr));
> >-    dstIP = (IPHdr *)((PCHAR)dstEth + sizeof *dstEth);
> >-    dstTCP = (TCPHdr *)((PCHAR)dstIP + dstIP->ihl * 4);
> >-    ASSERT((INT)MmGetMdlByteCount(mdl) -
> >NET_BUFFER_CURRENT_MDL_OFFSET(nb)
> >-            >= sizeof(EthHdr) + dstIP->ihl * 4 + TCP_HDR_LEN(dstTCP));
> >-
> >-    /* Fix IP length and checksum */
> >-    ASSERT(dstIP->protocol == IPPROTO_TCP);
> >-    dstIP->tot_len = htons(segmentSize + dstIP->ihl * 4 +
> >TCP_HDR_LEN(dstTCP));
> >-    dstIP->id += packetCounter;
> >-    dstIP->check = 0;
> >-    dstIP->check = IPChecksum((UINT8 *)dstIP, dstIP->ihl * 4, 0);
> >-
> >-    /* Fix TCP checksum */
> >+
> >+    switch (dstEth->Type) {
> >+    case ETH_TYPE_IPV4_NBO:
> >+    {
> >+        IPHdr *dstIP = NULL;
> >+
> >+        ASSERT((INT)MmGetMdlByteCount(mdl) -
> >NET_BUFFER_CURRENT_MDL_OFFSET(nb)
> >+                >= sizeof(EthHdr) + sizeof(IPHdr) + sizeof(TCPHdr));
> >+        dstIP = (IPHdr *)((PCHAR)dstEth + sizeof(*dstEth));
> >+        dstTCP = (TCPHdr *)((PCHAR)dstIP + dstIP->ihl * 4);
> >+        ASSERT((INT)MmGetMdlByteCount(mdl) -
> >NET_BUFFER_CURRENT_MDL_OFFSET(nb)
> >+                >= sizeof(EthHdr) + dstIP->ihl * 4 +
> >TCP_HDR_LEN(dstTCP));
> >+
> >+        /* Fix IP length and checksum */
> >+        ASSERT(dstIP->protocol == IPPROTO_TCP);
> >+        dstIP->tot_len = htons(segmentSize + dstIP->ihl * 4 +
> >TCP_HDR_LEN(dstTCP));
> >+        dstIP->id += packetCounter;
> >+        dstIP->check = IPChecksum((UINT8 *)dstIP, dstIP->ihl * 4, 0);
> >+
> >+        /* Fix TCP checksum */
> >+        UINT16 csumLength = segmentSize + TCP_HDR_LEN(dstTCP);
> >+        dstTCP->check = IPPseudoChecksum(&dstIP->saddr,
> >+                                         &dstIP->daddr,
> >+                                         IPPROTO_TCP,
> >+                                         csumLength);
> >+        dstTCP->check = CalculateChecksumNB(nb,
> >+                                            csumLength,
> >+                                            sizeof(*dstEth) +
> >+ dstIP->ihl
> >* 4);
> >+        break;
> >+    }
> >+    case ETH_TYPE_IPV6_NBO:
> >+    {
> >+        IPv6Hdr *dstIP = NULL;
> >+
> >+        ASSERT((INT)MmGetMdlByteCount(mdl) -
> >NET_BUFFER_CURRENT_MDL_OFFSET(nb)
> >+            >= sizeof(EthHdr) + sizeof(IPv6Hdr) + sizeof(TCPHdr));
> >+        dstIP = (IPv6Hdr *)((PCHAR)dstEth + sizeof(*dstEth));
> >+        dstTCP = (TCPHdr *)((PCHAR)dstIP + sizeof(IPv6Hdr));
> >+        ASSERT((INT)MmGetMdlByteCount(mdl) -
> >NET_BUFFER_CURRENT_MDL_OFFSET(nb)
> >+            >= sizeof(EthHdr) + sizeof(IPv6Hdr) +
> >+ TCP_HDR_LEN(dstTCP));
> >+
> >+        /* Fix IP length */
> >+        ASSERT(dstIP->nexthdr == IPPROTO_TCP);
> >+        dstIP->payload_len = htons(segmentSize + sizeof(IPv6Hdr) +
> >TCP_HDR_LEN(dstTCP));
> >+
> >+        /* Fix TCP checksum */
> >+        UINT16 csumLength = segmentSize + TCP_HDR_LEN(dstTCP);
> >+        dstTCP->check = IPv6PseudoChecksum((UINT32*)&dstIP->saddr,
> >+                                           (UINT32*)&dstIP->daddr,
> >+                                           IPPROTO_TCP,
> >+                                           csumLength);
> >+        dstTCP->check = CalculateChecksumNB(nb,
> >+                                            csumLength,
> >+                                            sizeof(*dstEth) +
> >sizeof(IPv6Hdr));
> >+        break;
> >+    }
> >+    }
> >+
> >     dstTCP->seq = htonl(seqNumber);
> >
> >     /*
> >@@ -1164,15 +1206,6 @@ FixSegmentHeader(PNET_BUFFER nb, UINT16
> >segmentSize, UINT32 seqNumber,
> >         dstTCP->psh = lastPacket;
> >     }
> >
> >-    UINT16 csumLength = segmentSize + TCP_HDR_LEN(dstTCP);
> >-    dstTCP->check = IPPseudoChecksum(&dstIP->saddr,
> >-                                     &dstIP->daddr,
> >-                                     IPPROTO_TCP,
> >-                                     csumLength);
> >-    dstTCP->check = CalculateChecksumNB(nb,
> >-                                        csumLength,
> >-                                        sizeof *dstEth + dstIP->ihl * 4);
> >-
> >     return STATUS_SUCCESS;
> > }
> >
> >--
> >1.9.0.msysgit.0
> >_______________________________________________
> >dev mailing list
> >dev at openvswitch.org
> >https://urldefense.proofpoint.com/v2/url?u=http-
> 3A__openvswitch.org_mai
> >lma
> >n_listinfo_dev&d=BQIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-
> YihVMNtXt-uEs&r
> >=Dc
> >ruz40PROJ40ROzSpxyQSLw6fcrOWpJgEcEmNR3JEQ&m=E9U6eKBsuYHgHjK7
> -hEEVbGHhT1
> >gD6 -
> FaMMkV95KXMw&s=NXpotbyxWn81PBmzYgR9N9Q8itBskCUcrItdbSB0MUs
> &e=




More information about the dev mailing list