diff options
author | ldejing <ldejing@vmware.com> | 2022-08-16 19:14:32 +0800 |
---|---|---|
committer | Alin-Gabriel Serdean <alin.serdean@canonical.com> | 2022-09-20 02:40:03 +0300 |
commit | 7af5c33c1629b309cbcbe3b6c9c3bd6d3b4c0abf (patch) | |
tree | 445f0e0379b0134bf1bbde32811b05ee59586014 /datapath-windows/ovsext/Ip6Fragment.h | |
parent | 54a618f0bd83431a18307a312e5b41e401538bbc (diff) | |
download | openvswitch-7af5c33c1629b309cbcbe3b6c9c3bd6d3b4c0abf.tar.gz |
datapath-windows: Add IPv6 conntrack ip fragment support on windows
Implementation on Windows:
IPv6 conntrack ip fragment feature use a link list to store ip
fragment. When ipv6 fragment module receives a fragment packet,
it will store length of the fragment, until to the received length
equal to the packet length before fragmented, it will reassemble
fragment packet to a complete packet and send the complete packet
to conntrack module. After conntrack processed the packet, fragment
module will divide the complete packet into small fragment and send
it to destination. Currently, ipv6 was implemented in a indenpent
module, for the reason it can reduce the risk of introduce bug to
ipv4 fragmenb module.
Testing Topology:
On the Windows VM runs on the ESXi host, two hyper-v ports attached
to the ovs bridge; one hyper-v port worked as client and the
other port worked as server.
Testing Case:
1.UdpV6
a) UdpV6 fragment with multiple ipv6 extension fields.
b) UdpV6 fragment in normal scenario.
c) UdpV6 fragment in nat scenario.
2.IcmpV6
a) IcmpV6 fragment in normal scenario.
b) IcmpV6 fragment in nat scenario.
Signed-off-by: ldejing <ldejing@vmware.com>
Signed-off-by: Alin-Gabriel Serdean <aserdean@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Ip6Fragment.h')
-rw-r--r-- | datapath-windows/ovsext/Ip6Fragment.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/datapath-windows/ovsext/Ip6Fragment.h b/datapath-windows/ovsext/Ip6Fragment.h new file mode 100644 index 000000000..f978bf5c3 --- /dev/null +++ b/datapath-windows/ovsext/Ip6Fragment.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2022 VMware, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __IP6FRAGMENT_H_ +#define __IP6FRAGMENT_H_ 1 +#include "PacketIO.h" + +typedef struct _OVS_FRAGMENT6_LIST { + CHAR *pbuff; + UINT16 len; /* Fragment data length. */ + UINT16 offset; /* Fragment data offset. */ + struct _OVS_FRAGMENT6_LIST *next; +} OVS_FRAGMENT6_LIST, *POVS_FRAGMENT6_LIST; + +typedef struct _OVS_IP6FRAG_KEY { + UINT8 protocol; + UINT8 pad_1[3]; /* Align the structure to address boundaries.*/ + UINT32 id; + struct in6_addr sAddr; + struct in6_addr dAddr; + ovs_be64 tunnelId; +} OVS_IP6FRAG_KEY, *POVS_IP6FRAG_KEY; + +typedef struct _OVS_IP6FRAG_ENTRY { + NDIS_SPIN_LOCK lockObj; /* To access the entry. */ + BOOLEAN markedForDelete; + UINT8 numFragments; + UINT16 totalLen; /* The packet data total length(not + * include ipv6 header and opt header length) before + * fragment */ + UINT16 recvdLen; /* Total data length packet contains has received */ + UINT16 mru; /* Max receive unit(it's the whole ethernet frame + * packet length), it will be used in sent out before forward */ + UINT64 expiration; + /* refer https://www.rfc-editor.org/rfc/rfc8200.html */ + PCHAR beforeFragHdrBuf;/* ipv6 extension header buf before fragment field */ + UINT16 beforeFragHdrLen; + UINT16 priorFragEleOffset;/* The last element before fragment field offset */ + PCHAR fragHdrBuf; + UINT16 fragHdrLen; + PCHAR behindFragHdrBuf;/* ipv6 extension header buf behind fragment field */ + UINT16 behindFragHdrLen; + OVS_IP6FRAG_KEY fragKey; + POVS_FRAGMENT6_LIST head; + POVS_FRAGMENT6_LIST tail; + LIST_ENTRY link; +} OVS_IP6FRAG_ENTRY, *POVS_IP6FRAG_ENTRY; + +typedef struct _IP6_PktExtHeader_Meta { + UINT8 firstHdr; + UINT8 protocol; + UINT16 beforeFragExtHdrLen; + UINT16 fragExtHdrLen; + UINT16 behindFragExtHdrLen; + UINT16 extHdrTotalLen; + UINT16 dataPayloadLen;/* Ipv6 data length, not include extension header */ + UINT16 fragOffset; + UINT16 priorFragEleOffset; + UINT16 flags; + UINT16 pktMru; + UINT32 ident; + PCHAR beforeFragElePtr; + IPv6ExtHdr *firstHdrPtr; +} IP6_PktExtHeader_Meta, *PIP6_PktExtHeader_Meta; + +typedef struct _OVS_IP6FRAG_THREAD_CTX { + KEVENT event; + PVOID threadObject; + UINT32 exit; +} OVS_IP6FRAG_THREAD_CTX, *POVS_IP6FRAG_THREAD_CTX; + +#define IP6_FRAG_HASH_TABLE_SIZE ((UINT32)1 << 10) +#define IP6_FRAG_HASH_TABLE_MASK (IP6_FRAG_HASH_TABLE_SIZE - 1) + +#define IP6FRAG_ENTRY_TIMEOUT 300000000LL +#define IP6FRAG_CLEANUP_INTERVAL IP6FRAG_ENTRY_TIMEOUT * 2 /*1m.*/ + +NDIS_STATUS OvsProcessIpv6Fragment(POVS_SWITCH_CONTEXT switchContext, + PNET_BUFFER_LIST *curNbl, + OvsCompletionList *completionList, + NDIS_SWITCH_PORT_ID sourcePort, + POVS_PACKET_HDR_INFO layers, + ovs_be64 tunnelId, OvsFlowKey *key); +NDIS_STATUS OvsStorageIpv6ExtHeader(POVS_IP6FRAG_ENTRY entry, + UINT16 beforeFragHdrLen, + UINT16 fragHdrLen, + UINT16 behindFragHdrLen, + UINT16 priorFragEleOffset, + CHAR *pktBuf, + POVS_PACKET_HDR_INFO layers); +NDIS_STATUS OvsInitIp6Fragment(POVS_SWITCH_CONTEXT context); +VOID OvsCleanupIp6Fragment(VOID); +NDIS_STATUS OvsGetPacketMeta(PIP6_PktExtHeader_Meta pktMeta, EthHdr *eth, + OvsFlowKey *key, POVS_PACKET_HDR_INFO layers); +PCHAR OvsBuildNewIpv6Hdr(EthHdr *eth, POVS_IP6FRAG_ENTRY entry, + POVS_PACKET_HDR_INFO layers, UINT32 *pktLen); + +#endif //_IP6FRAGMENT_H_ |