Acked-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com>
> -----Mesaj original----- > De la: dev [mailto:dev-boun...@openvswitch.org] În numele Sairam > Venugopal > Trimis: Monday, February 29, 2016 9:42 PM > Către: dev@openvswitch.org > Subiect: [ovs-dev] [PATCH v2] datapath-windows: Support for IPv6 in TCP > segmentation > > 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 the > segment's header accordingly. > > Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> > Co-authored-by: Sairam Venugopal <vsai...@vmware.com> > Reported-by: Sairam Venugopal <vsai...@vmware.com> > Reported-at: https://github.com/openvswitch/ovs-issues/issues/105 > --- > datapath-windows/ovsext/BufferMgmt.c | 119 > +++++++++++++++++++++++------------ > 1 file changed, 80 insertions(+), 39 deletions(-) > > diff --git a/datapath-windows/ovsext/BufferMgmt.c b/datapath- > windows/ovsext/BufferMgmt.c > index 3189e9b..00db31f 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,44 +1134,86 @@ 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 */ > - dstTCP->seq = htonl(seqNumber); > > - /* > - * Set the TCP FIN and PSH bit only for the last packet > - * More information can be found under: > - * https://msdn.microsoft.com/en- > us/library/windows/hardware/ff568840%28v=vs.85%29.aspx > - */ > - if (dstTCP->fin) { > - dstTCP->fin = lastPacket; > + 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 = 0; > + dstIP->check = IPChecksum((UINT8 *)dstIP, dstIP->ihl * 4, 0); > + dstTCP->seq = htonl(seqNumber); > + > + /* > + * Set the TCP FIN and PSH bit only for the last packet > + * More information can be found under: > + * https://msdn.microsoft.com/en- > us/library/windows/hardware/ff568840%28v=vs.85%29.aspx > + */ > + if (dstTCP->fin) { > + dstTCP->fin = lastPacket; > + } > + if (dstTCP->psh) { > + 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); > + 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)); > + > + dstTCP->seq = htonl(seqNumber); > + if (dstTCP->fin) { > + dstTCP->fin = lastPacket; > + } > + if (dstTCP->psh) { > + dstTCP->psh = lastPacket; > + } > + > + 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; > } > - if (dstTCP->psh) { > - dstTCP->psh = lastPacket; > + default: > + OVS_LOG_ERROR("Invalid eth type: %d\n", dstEth->Type); > + ASSERT(! "Invalid eth type"); > } > > - 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; > } > > -- > 2.5.0.windows.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev