]> git.proxmox.com Git - mirror_ovs.git/blame - datapath-windows/ovsext/Conntrack.h
datapath-windows: Optimize conntrack lock implementation.
[mirror_ovs.git] / datapath-windows / ovsext / Conntrack.h
CommitLineData
792d377d
SV
1/*
2 * Copyright (c) 2015, 2016 VMware, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef __OVS_CONNTRACK_H_
18#define __OVS_CONNTRACK_H_ 1
19
20#include "precomp.h"
b7a6b3a7 21#include "Actions.h"
5e422c9e 22#include "Debug.h"
b7a6b3a7 23#include "Flow.h"
ae584afe 24#include "Actions.h"
5e422c9e
SV
25#include <stddef.h>
26
27#ifdef OVS_DBG_MOD
28#undef OVS_DBG_MOD
29#endif
30#define OVS_DBG_MOD OVS_DBG_CONTRK
792d377d
SV
31
32struct ct_addr {
33 union {
34 ovs_be32 ipv4;
35 struct in6_addr ipv6;
36 uint32_t ipv4_aligned;
37 struct in6_addr ipv6_aligned;
38 };
39};
40
41struct ct_endpoint {
42 struct ct_addr addr;
6e83dfd9 43 union {
a1930487
AK
44 struct {
45 ovs_be16 port;
46 uint16 pad_port;
47 };
6e83dfd9
SV
48 struct {
49 ovs_be16 icmp_id;
50 uint8_t icmp_type;
51 uint8_t icmp_code;
52 };
53 };
792d377d
SV
54};
55
56typedef enum CT_UPDATE_RES {
57 CT_UPDATE_INVALID,
58 CT_UPDATE_VALID,
59 CT_UPDATE_NEW,
60} CT_UPDATE_RES;
61
62/* Metadata mark for masked write to conntrack mark */
63typedef struct MD_MARK {
64 UINT32 value;
65 UINT32 mask;
66} MD_MARK;
67
68/* Metadata label for masked write to conntrack label. */
69typedef struct MD_LABELS {
70 struct ovs_key_ct_labels value;
71 struct ovs_key_ct_labels mask;
72} MD_LABELS;
73
58bfaba0 74typedef enum _NAT_ACTION {
1ef6b404
AK
75 NAT_ACTION_NONE = 0,
76 NAT_ACTION_REVERSE = 1 << 0,
77 NAT_ACTION_SRC = 1 << 1,
78 NAT_ACTION_SRC_PORT = 1 << 2,
79 NAT_ACTION_DST = 1 << 3,
80 NAT_ACTION_DST_PORT = 1 << 4,
58bfaba0 81} NAT_ACTION;
1ef6b404 82
792d377d
SV
83typedef struct _OVS_CT_KEY {
84 struct ct_endpoint src;
85 struct ct_endpoint dst;
86 UINT16 dl_type;
87 UINT8 nw_proto;
88 UINT16 zone;
b50d56a7
SV
89 UINT64 packetCount;
90 UINT64 byteCount;
792d377d
SV
91} OVS_CT_KEY, *POVS_CT_KEY;
92
b7a6b3a7
YL
93typedef struct _NAT_ACTION_INFO {
94 struct ct_addr minAddr;
95 struct ct_addr maxAddr;
96 uint16_t minPort;
97 uint16_t maxPort;
98 uint16_t natAction;
99} NAT_ACTION_INFO, *PNAT_ACTION_INFO;
100
792d377d 101typedef struct OVS_CT_ENTRY {
b0b5ab8b
AK
102 /* Reference to ovsCtBucketLock of ovsConntrackTable.*/
103 PNDIS_RW_LOCK_EX bucketLockRef;
104 PNDIS_RW_LOCK_EX lock; /* Protects OVS_CT_ENTRY. */
792d377d
SV
105 OVS_CT_KEY key;
106 OVS_CT_KEY rev_key;
107 UINT64 expiration;
108 LIST_ENTRY link;
109 UINT32 mark;
b50d56a7 110 UINT64 timestampStart;
792d377d 111 struct ovs_key_ct_labels labels;
b7a6b3a7 112 NAT_ACTION_INFO natInfo;
e68988b8 113 PVOID parent; /* Points to main connection */
792d377d
SV
114} OVS_CT_ENTRY, *POVS_CT_ENTRY;
115
5e422c9e
SV
116typedef struct OVS_CT_REL_ENTRY {
117 OVS_CT_KEY key;
118 POVS_CT_ENTRY parent;
119 UINT64 expiration;
120 LIST_ENTRY link;
121} OVS_CT_REL_ENTRY, *POVS_CT_REL_ENTRY;
122
123typedef struct _OVS_CT_THREAD_CTX {
124 KEVENT event;
125 PVOID threadObject;
126 UINT32 exit;
127} OVS_CT_THREAD_CTX, *POVS_CT_THREAD_CTX;
128
792d377d
SV
129typedef struct OvsConntrackKeyLookupCtx {
130 OVS_CT_KEY key;
131 POVS_CT_ENTRY entry;
132 UINT32 hash;
133 BOOLEAN reply;
134 BOOLEAN related;
135} OvsConntrackKeyLookupCtx;
136
c3a90b46 137#define CT_MAX_ENTRIES 1 << 21
792d377d
SV
138#define CT_HASH_TABLE_SIZE ((UINT32)1 << 10)
139#define CT_HASH_TABLE_MASK (CT_HASH_TABLE_SIZE - 1)
5b37c6ae
SV
140#define CT_INTERVAL_SEC 10000000LL //1s
141#define CT_ENTRY_TIMEOUT (2 * 60 * CT_INTERVAL_SEC) // 2m
142#define CT_CLEANUP_INTERVAL (2 * 60 * CT_INTERVAL_SEC) // 2m
143
144
f6d375ea
SV
145/* Given POINTER, the address of the given MEMBER in a STRUCT object, returns
146 the STRUCT object. */
147#define CONTAINER_OF(POINTER, STRUCT, MEMBER) \
148 ((STRUCT *) (void *) ((char *) (POINTER) - \
149 offsetof (STRUCT, MEMBER)))
792d377d 150
6e83dfd9
SV
151static __inline void
152OvsConntrackUpdateExpiration(OVS_CT_ENTRY *ctEntry,
153 long long now,
154 long long interval)
155{
156 ctEntry->expiration = now + interval;
157}
158
680f666f
SV
159static __inline UINT32
160OvsGetTcpPayloadLength(PNET_BUFFER_LIST nbl)
161{
162 IPHdr *ipHdr;
263e428e
AS
163 TCPHdr *tcp;
164 char *ipBuf[sizeof(EthHdr) + sizeof(IPHdr) + sizeof(TCPHdr)];
165
166 ipHdr = NdisGetDataBuffer(NET_BUFFER_LIST_FIRST_NB(nbl), sizeof *ipBuf,
167 (PVOID)&ipBuf, 1 /*no align*/, 0);
680f666f 168 if (ipHdr == NULL) {
680f666f
SV
169 return 0;
170 }
171
263e428e
AS
172 ipHdr = (IPHdr *)((PCHAR)ipHdr + sizeof(EthHdr));
173 tcp = (TCPHdr *)((PCHAR)ipHdr + ipHdr->ihl * 4);
680f666f
SV
174
175 return (ntohs(ipHdr->tot_len) - (ipHdr->ihl * 4) - (TCP_HDR_LEN(tcp)));
176}
177
792d377d
SV
178VOID OvsCleanupConntrack(VOID);
179NTSTATUS OvsInitConntrack(POVS_SWITCH_CONTEXT context);
180
ae584afe 181NDIS_STATUS OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,
792d377d
SV
182 OvsFlowKey *key,
183 const PNL_ATTR a);
184BOOLEAN OvsConntrackValidateTcpPacket(const TCPHdr *tcp);
6e83dfd9 185BOOLEAN OvsConntrackValidateIcmpPacket(const ICMPHdr *icmp);
f6d375ea
SV
186OVS_CT_ENTRY * OvsConntrackCreateTcpEntry(const TCPHdr *tcp,
187 PNET_BUFFER_LIST nbl,
188 UINT64 now);
b50d56a7
SV
189NDIS_STATUS OvsCtMapTcpProtoInfoToNl(PNL_BUFFER nlBuf,
190 OVS_CT_ENTRY *conn_);
5b37c6ae 191OVS_CT_ENTRY * OvsConntrackCreateOtherEntry(UINT64 now);
6e83dfd9 192OVS_CT_ENTRY * OvsConntrackCreateIcmpEntry(UINT64 now);
f6d375ea 193enum CT_UPDATE_RES OvsConntrackUpdateTcpEntry(OVS_CT_ENTRY* conn_,
792d377d
SV
194 const TCPHdr *tcp,
195 PNET_BUFFER_LIST nbl,
196 BOOLEAN reply,
197 UINT64 now);
6e83dfd9 198enum CT_UPDATE_RES OvsConntrackUpdateOtherEntry(OVS_CT_ENTRY *conn_,
5b37c6ae
SV
199 BOOLEAN reply,
200 UINT64 now);
6e83dfd9
SV
201enum CT_UPDATE_RES OvsConntrackUpdateIcmpEntry(OVS_CT_ENTRY* conn_,
202 BOOLEAN reply,
203 UINT64 now);
5e422c9e
SV
204NTSTATUS OvsCreateNlMsgFromCtEntry(POVS_CT_ENTRY entry,
205 PVOID outBuffer,
206 UINT32 outBufLen,
207 UINT8 eventType,
208 UINT32 nlmsgSeq,
209 UINT32 nlmsgPid,
210 UINT8 nfGenVersion,
211 UINT32 dpIfIndex);
212
213/* Tracking related connections */
214NTSTATUS OvsInitCtRelated(POVS_SWITCH_CONTEXT context);
215VOID OvsCleanupCtRelated(VOID);
216NDIS_STATUS OvsCtRelatedEntryCreate(UINT8 ipProto,
217 UINT16 dl_type,
218 UINT32 serverIp,
219 UINT32 clientIp,
220 UINT16 serverPort,
221 UINT16 clientPort,
222 UINT64 currentTime,
223 POVS_CT_ENTRY parent);
224POVS_CT_ENTRY OvsCtRelatedLookup(OVS_CT_KEY key, UINT64 currentTime);
225
e68988b8
SV
226NDIS_STATUS OvsCtHandleFtp(PNET_BUFFER_LIST curNbl,
227 OvsFlowKey *key,
228 OVS_PACKET_HDR_INFO *layers,
229 UINT64 currentTime,
230 POVS_CT_ENTRY entry,
231 BOOLEAN request);
232
b7a6b3a7 233UINT32 OvsHashCtKey(const OVS_CT_KEY *key);
5b37c6ae 234#endif /* __OVS_CONNTRACK_H_ */