Merge "conntrack: timer reset in reply traffic causes performance impact"
[samplevnf.git] / common / VIL / conntrack / rte_ct_tcp.c
1 /*
2 // Copyright (c) 2017 Intel Corporation
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 #include <stdlib.h>
18 #include <string.h>
19 #include <immintrin.h>
20 #include <inttypes.h>
21 #include "rte_ct_tcp.h"
22 #include "rte_cnxn_tracking.h"
23
24 /* uint32_t CT_DEBUG = 1; */ /* Can be used to conditionally turn of debug */
25 #define CT_DEBUG 0
26 #define STATE_TRACKING 0
27 #define RTE_CT_ASSERT 0
28
29 /* constants for mbuff manipulation */
30 #define META_DATA_OFFSET 128
31 #define RTE_PKTMBUF_HEADROOM 128        /* where is this defined ? */
32 #define ETHERNET_START (META_DATA_OFFSET + RTE_PKTMBUF_HEADROOM)
33 #define ETH_HDR_SIZE 14
34 #define IP_START (ETHERNET_START + ETH_HDR_SIZE)
35
36 #define IPv4_HEADER_SIZE 20
37 #define IPv6_HEADER_SIZE 40
38
39 #define IP_VERSION_4 4
40 #define IP_VERSION_6 6
41
42 #define rte_after(seq2, seq1) rte_before(seq1, seq2)
43 static inline uint8_t rte_before(uint32_t seq1, uint32_t seq2)
44 {
45         return (int32_t) (seq1 - seq2) < 0;
46 }
47
48 /* short state names for defining state table */
49
50 #define ctNO RTE_CT_TCP_NONE
51 #define ctSS RTE_CT_TCP_SYN_SENT
52 #define ctSR RTE_CT_TCP_SYN_RECV
53 #define ctES RTE_CT_TCP_ESTABLISHED
54 #define ctFW RTE_CT_TCP_FIN_WAIT
55 #define ctCW RTE_CT_TCP_CLOSE_WAIT
56 #define ctLA RTE_CT_TCP_LAST_ACK
57 #define ctTW RTE_CT_TCP_TIME_WAIT
58 #define ctCL RTE_CT_TCP_CLOSE
59 #define ctS2 RTE_CT_TCP_SYN_SENT_2
60 #define ctIV RTE_CT_TCP_MAX
61 #define ctIG RTE_CT_TCP_IGNORE
62
63 static const uint8_t rte_ct_tcp_state_table[2][6][RTE_CT_TCP_MAX] = {
64         {                       /* "client" direction, i.e. first SYN sent */
65          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
66          /* syn */ {ctSS, ctSS, ctIG, ctIG, ctIG, ctIG, ctIG, ctSS, ctSS,
67                                 ctS2},
68
69          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
70          /* synack */ {ctIV, ctIV, ctSR, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV,
71                                          ctSR},
72
73          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
74          /* fin */ {ctIV, ctIV, ctFW, ctFW, ctLA, ctLA, ctLA, ctTW, ctCL,
75                                 ctIV},
76          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
77          /* ack */ {ctES, ctIV, ctES, ctES, ctCW, ctCW, ctTW, ctTW, ctCL,
78                                 ctIV},
79
80          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
81          /* rst */ {ctIV, ctCL, ctCL, ctCL, ctCL, ctCL, ctCL, ctCL, ctCL,
82                                 ctCL},
83          /* ill */ {ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV}
84          },
85
86         {                       /* "server" direction */
87          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
88          /* syn */ {ctIV, ctS2, ctIV, ctIV, ctIV, ctIV, ctIV, ctSS, ctIV,
89                                 ctS2},
90
91          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
92          /* synack */ {ctIV, ctSR, ctIG, ctIG, ctIG, ctIG, ctIG, ctIG, ctIG,
93                                          ctSR},
94
95          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
96          /* fin */ {ctIV, ctIV, ctFW, ctFW, ctLA, ctLA, ctLA, ctTW, ctCL,
97                                 ctIV},
98
99          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
100          /* ack */ {ctIV, ctIG, ctSR, ctES, ctCW, ctCW, ctTW, ctTW, ctCL,
101                                 ctIG},
102
103          /* ctNO, ctSS, ctSR, ctES, ctFW, ctCW, ctLA, ctTW, ctCL, ctS2 */
104          /* rst */ {ctIV, ctCL, ctCL, ctCL, ctCL, ctCL, ctCL, ctCL, ctCL,
105                                 ctCL},
106          /* ill */ {ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV, ctIV}
107          }
108 };
109
110 /* What TCP flags are set from RST/SYN/FIN/ACK. */
111 enum rte_tcp_flag {
112         RTE_CT_TCP_SYN_FLAG,
113         RTE_CT_TCP_SAK_FLAG,    /* SYN ACK */
114         RTE_CT_TCP_FIN_FLAG,
115         RTE_CT_TCP_ACK_FLAG,
116         RTE_CT_TCP_RST_FLAG,
117         RTE_CT_TCP_ILL_FLAG,
118 };
119
120 static uint8_t rte_ct_tcp_flags_to_state_table_index[16] = {
121         /* A R S F */
122         RTE_CT_TCP_ILL_FLAG,    /* 0 0 0 0 */
123         RTE_CT_TCP_FIN_FLAG,    /* 0 0 0 1 */
124         RTE_CT_TCP_SYN_FLAG,    /* 0 0 1 0 */
125         RTE_CT_TCP_ILL_FLAG,    /* 0 0 1 1 */
126         RTE_CT_TCP_RST_FLAG,    /* 0 1 0 0 */
127         RTE_CT_TCP_RST_FLAG,    /* 0 1 0 1 */
128         RTE_CT_TCP_RST_FLAG,    /* 0 1 1 0 */
129         RTE_CT_TCP_ILL_FLAG,    /* 0 1 1 1 */
130
131         RTE_CT_TCP_ACK_FLAG,    /* 1 0 0 0 */
132         RTE_CT_TCP_FIN_FLAG,    /* 1 0 0 1 */
133         RTE_CT_TCP_SAK_FLAG,    /* 1 0 1 0 */
134         RTE_CT_TCP_ILL_FLAG,    /* 1 0 1 1 */
135         RTE_CT_TCP_RST_FLAG,    /* 1 1 0 0 */
136         RTE_CT_TCP_ILL_FLAG,    /* 1 1 0 1 */
137         RTE_CT_TCP_RST_FLAG,    /* 1 1 1 0 */
138         RTE_CT_TCP_ILL_FLAG,    /* 1 1 1 1 */
139 };
140
141 static inline uint8_t
142 rte_ct_get_index(uint8_t tcp_flags)
143 {
144         uint8_t important_flags;
145
146         tcp_flags &= 0x3f;      /* clear off optional flags */
147         important_flags = ((tcp_flags & 0x10) >> 1) | (tcp_flags & 7);
148         /* should be _pext_u32(tcp_flags, 0x17) */
149
150         if (unlikely((tcp_flags == 0) || (tcp_flags == 0x3f)))
151                 /* these known as null and christmas tree respectively */
152                 return RTE_CT_TCP_ILL_FLAG;
153
154         return rte_ct_tcp_flags_to_state_table_index[important_flags];
155
156 }
157
158 static inline int
159 rte_ct_either_direction_has_flags(struct rte_ct_cnxn_data *cd, uint8_t flags)
160 {
161         return ((cd->ct_protocol.tcp_ct_data.seen[0].flags | cd->
162                  ct_protocol.tcp_ct_data.seen[1].flags) & flags) != 0;
163 }
164
165 static inline uint32_t rte_ct_seq_plus_length(struct rte_mbuf *pkt,
166                 uint8_t ip_hdr_size)
167 {
168         uint16_t pkt_length = 0;
169         struct tcp_hdr *tcpheader =
170                         (struct tcp_hdr *)RTE_MBUF_METADATA_UINT32_PTR(pkt,
171                                                                  (IP_START +
172                                                                         ip_hdr_size));
173         uint32_t tcp_hdr_size = (tcpheader->data_off & 0xf0) >> 2;
174
175         void *ip_hdr = RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
176
177         if (ip_hdr_size == IPv4_HEADER_SIZE) {
178                 struct ipv4_hdr *ihdr = (struct ipv4_hdr *)ip_hdr;
179
180                 pkt_length = rte_bswap16(ihdr->total_length);
181         }
182         if (ip_hdr_size == IPv6_HEADER_SIZE) {
183                 struct ipv6_hdr *ihdr = (struct ipv6_hdr *)ip_hdr;
184
185                 pkt_length = rte_bswap16(ihdr->payload_len) + IPv6_HEADER_SIZE;
186         }
187
188         /*
189          * Return sequence number plus the length of TCP segment (payload).
190          * SYN & FIN are each considered one byte, but it is illegal
191          * to have them together in one header (checked elsewhere)
192         */
193
194
195         return rte_bswap32(tcpheader->sent_seq) +
196                         pkt_length - ip_hdr_size - tcp_hdr_size +
197                         ((tcpheader->tcp_flags & (RTE_CT_TCPHDR_SYN | RTE_CT_TCPHDR_FIN)) !=
198                          0 ? 1 : 0);
199
200 }
201
202 static void
203 rte_ct_check_for_scaling_and_sack_perm(
204         struct rte_mbuf *pkt,
205         struct rte_ct_tcp_state *state,
206         uint8_t ip_hdr_size)
207 {
208
209         struct tcp_hdr *tcpheader =
210                         (struct tcp_hdr *)RTE_MBUF_METADATA_UINT32_PTR(pkt,
211                                                                  (IP_START +
212                                                                         ip_hdr_size));
213         uint32_t dataoff_in_bytes = (tcpheader->data_off & 0xf0) >> 2;
214         uint32_t length = dataoff_in_bytes - sizeof(struct tcp_hdr);
215
216         state->scale = 0;
217         state->flags = 0;
218
219         if (length == 0)
220                 /* no header options */
221                 return;
222         uint8_t *options_ptr =
223                         RTE_MBUF_METADATA_UINT8_PTR(pkt,
224                                         (IP_START + ip_hdr_size +
225                                          sizeof(struct tcp_hdr)));
226
227         while (length > 0) {
228                 uint8_t option = *options_ptr;
229                 uint8_t opsize = options_ptr[1];
230                 /* opsize reset for NOPs below */
231
232                 switch (option) {
233
234                 case RTE_CT_TCPOPT_EOL:
235                         /* end of options */
236                         return;
237
238                 case RTE_CT_TCPOPT_NOP:
239                         options_ptr++;
240                         length--;
241                         continue;
242
243                 case RTE_CT_TCPOPT_SACK_PERM:
244                         if (opsize == RTE_CT_TCPOLEN_SACK_PERM)
245                                 state->flags |= RTE_CT_TCP_FLAG_SACK_PERM;
246                         break;
247
248                 case RTE_CT_TCPOPT_WINDOW:
249                         if (opsize == RTE_CT_TCPOLEN_WINDOW) {
250                                 state->scale =
251                                                 RTE_MIN(options_ptr[2],
252                                                         RTE_CT_MAX_TCP_WINDOW_SCALE);
253                                 state->flags |= RTE_CT_TCP_FLAG_WINDOW_SCALE;
254                         }
255                         break;
256
257                 default:
258                         break;
259
260                 }
261
262                 if ((opsize < 2) || (opsize > length)) {
263                         /* something wrong */
264                         printf("scaling_and_sack_perm:something wrong\n");
265                         return;
266                 }
267                 options_ptr += opsize;
268                 length -= opsize;
269
270         }
271 }
272
273 static void
274 rte_ct_tcpdisplay_hdr(struct tcp_hdr *tcpheader)
275 {
276         printf("Tcp header: src_port=%d", rte_bswap16(tcpheader->src_port));
277         printf(", dst_port=%d", rte_bswap16(tcpheader->dst_port));
278         printf(", sent_seq=%u", rte_bswap32(tcpheader->sent_seq));
279         printf(", recv_ack=%u", rte_bswap32(tcpheader->recv_ack));
280         printf(",data_off=%d", tcpheader->data_off / 16);
281         printf(",tcp_flags=%02x", tcpheader->tcp_flags);
282         printf(", rx_win=%d\n", rte_bswap16(tcpheader->rx_win));
283
284 }
285
286 static inline void
287 rte_ct_clear_cnxn_data(__rte_unused struct rte_ct_cnxn_tracker *ct,
288                 struct rte_ct_cnxn_data *cd,
289                 __rte_unused struct rte_mbuf *pkt)
290 {
291         /* clear all tcp connection data, then set up individual fields */
292
293         memset(&cd->ct_protocol.tcp_ct_data, 0,
294                                  sizeof(cd->ct_protocol.tcp_ct_data));
295         cd->ct_protocol.tcp_ct_data.last_index = RTE_CT_TCP_ILL_FLAG;
296
297 }
298
299 enum rte_ct_packet_action
300 rte_ct_tcp_new_connection(
301         struct rte_ct_cnxn_tracker *ct,
302         struct rte_ct_cnxn_data *cd,
303         struct rte_mbuf *pkt,
304         int     use_synproxy,
305         uint8_t ip_hdr_size)
306 {
307         struct tcp_hdr *tcpheader =
308                 (struct tcp_hdr *)RTE_MBUF_METADATA_UINT32_PTR(pkt,
309                                 (IP_START + ip_hdr_size));
310
311         enum rte_ct_tcp_states new_state;
312         uint8_t index;
313         struct rte_ct_tcp_state *sender =
314                 &cd->ct_protocol.tcp_ct_data.seen[RTE_CT_DIR_ORIGINAL];
315         struct rte_ct_tcp_state *receiver =
316                 &cd->ct_protocol.tcp_ct_data.seen[RTE_CT_DIR_REPLY];
317         uint16_t win;
318
319          if (CT_DEBUG)
320                 rte_ct_tcpdisplay_hdr(tcpheader);
321
322         index = rte_ct_get_index(tcpheader->tcp_flags);
323         new_state = rte_ct_tcp_state_table[0][index][RTE_CT_TCP_NONE];
324
325         if (unlikely(new_state >= RTE_CT_TCP_MAX)) {
326                 if (CT_DEBUG)
327                         printf("invalid new state with flags %02x\n",
328                                         tcpheader->tcp_flags);
329                 return RTE_CT_DROP_PACKET;
330         }
331         /*
332          * A normal connection starts with a SYN packet. However, it is possible
333          * that an onginging connection has been routed here somehow. Support
334          * for these connections is optional.
335          */
336
337         if (unlikely((new_state != RTE_CT_TCP_SYN_SENT
338                                         && ct->misc_options.tcp_loose == 0))) {
339                 /* Not a standard connection start and not supporting
340                  * onging connections. */
341                 return RTE_CT_DROP_PACKET;
342         }
343
344         if (CT_DEBUG)
345                 printf(" new connection with state %s\n",
346                                          rte_ct_tcp_names[new_state]);
347
348         /* clear all tcp connection data, then set up individual fields */
349         rte_ct_clear_cnxn_data(ct, cd, pkt);
350         cd->ct_protocol.tcp_ct_data.state = new_state;
351
352         sender->end = sender->maxend = rte_ct_seq_plus_length(pkt, ip_hdr_size);
353         win = rte_bswap16(tcpheader->rx_win);
354         sender->maxwin = RTE_MAX(win, (uint32_t)1);
355
356         if (likely(new_state == RTE_CT_TCP_SYN_SENT)) {
357                 /* check for window scaling and selective ACK */
358                 rte_ct_check_for_scaling_and_sack_perm(pkt, sender,
359                                 ip_hdr_size);
360
361                 cd->ct_protocol.synproxy_data.synproxied = use_synproxy;
362
363                 if (use_synproxy) {
364                         /*
365                          * new connection from client using synproxy. The proxy
366                          * must send back a SYN-ACK
367                          */
368
369
370                         if (CT_DEBUG > 2)
371                                 printf("synproxy sending SYN-ACK to client\n");
372
373                         return RTE_CT_SEND_CLIENT_SYNACK;
374                 }
375         } else {
376                 /*
377                  * An ongoing connection. Make a very liberal connection since
378                  * all the original set up data is lost. Assume SACK and
379                  * liberal window checking to handle unknown window scaling.
380                  */
381
382                 sender->maxend += sender->maxwin;
383                 sender->flags = receiver->flags =
384                                 (RTE_CT_TCP_FLAG_SACK_PERM | RTE_CT_TCP_FLAG_BE_LIBERAL);
385         }
386
387         if (CT_DEBUG > 0) {
388                 printf("tcp_new: sender end=%u maxend=%u maxwin=%u scale=%i",
389                                 sender->end, sender->maxend, sender->maxwin,
390                                 sender->scale);
391                 printf(" receiver end=%u maxend=%u maxwin=%u scale=%i\n",
392                                 receiver->end, receiver->maxend,
393                                 receiver->maxwin,
394                                 receiver->scale);
395         }
396
397         return RTE_CT_OPEN_CONNECTION;
398 }
399
400 static uint32_t
401 rte_ct_tcp_sack(struct rte_mbuf *pkt, uint8_t ip_hdr_size)
402 {
403         struct tcp_hdr *tcpheader =
404                 (struct tcp_hdr *)RTE_MBUF_METADATA_UINT32_PTR(pkt,
405                                 (IP_START +
406                                  ip_hdr_size));
407         uint16_t dataoff_in_bytes = (tcpheader->data_off & 0xf0) >> 2;
408         uint16_t length = dataoff_in_bytes - sizeof(struct tcp_hdr);
409         uint32_t sack = rte_bswap32(tcpheader->recv_ack);
410
411         if (unlikely(!length))
412                 return sack;
413
414         uint8_t *options_ptr = RTE_MBUF_METADATA_UINT8_PTR(pkt,
415                         (IP_START + ip_hdr_size + sizeof(struct tcp_hdr)));
416
417         while (length > 0) {
418                 uint8_t opcode = *options_ptr;
419                 uint8_t opsize = options_ptr[1];
420                 int i;
421                 uint32_t *sack_ptr;
422
423                 switch (opcode) {
424                 case RTE_CT_TCPOPT_TIMESTAMP:
425                         /* common "solo" option, check first */
426                         break;
427
428                 case RTE_CT_TCPOPT_EOL:
429                         return sack;    /* end of options */
430
431                 case RTE_CT_TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
432                         length--;
433                         options_ptr++;
434                         continue;
435
436                 case RTE_CT_TCPOPT_SACK:
437                         /*
438                          * SACK (selective ACK) contains a block of
439                          * 1 to 4 entries of 8 bytes each.
440                          *  Each entry is a pair of 32 bit numbers.
441                          * This block follows the usual 2
442                          * bytes for opcode and opsize. Thus,
443                          * the entire SACK option must be 10, 18,
444                          * 26 or 34 bytes long.
445                          */
446                         if ((opsize >= (RTE_CT_TCPOLEN_PER_SACK_ENTRY + 2)) &&
447                                         ((opsize - 2) %
448                                          RTE_CT_TCPOLEN_PER_SACK_ENTRY) == 0) {
449                                 /* skip over opcode and size, and point to
450                                  * 2nd 32 bits in entry */
451                                 options_ptr += 6;
452                                 for (i = 0; i < (opsize - 2); i +=
453                                                 RTE_CT_TCPOLEN_PER_SACK_ENTRY) {
454                                         sack_ptr =
455                                                 (uint32_t *) &options_ptr[i];
456                                         uint32_t ack = rte_bswap32(*sack_ptr);
457
458                                         if (rte_after(ack, sack))
459                                                 sack = ack;
460                                 }
461                                 return sack;
462                         }
463                         break;
464                 default:
465                         break;
466                 }
467                 if ((opsize < 2) || (opsize > length)) {
468                         printf("rte_ct_tcp_sack: something wrong, opsize %i,",
469                                         opsize);
470                         printf(" length %i\n", length);
471                         return sack;
472                 }
473                 options_ptr += opsize;
474                 length -= opsize;
475         }
476         return sack;
477 }
478
479 /*
480  * if this is a retransmission of last packet, increment retransmission count,
481  * otherwise record this as last packet.
482  */
483 static inline void
484 rte_ct_check_for_retransmissions(
485         struct rte_ct_tcp *state,
486         uint8_t dir,
487         uint32_t seq,
488         uint32_t ack,
489         uint32_t end,
490         uint16_t win)
491 {
492         if (state->last_dir == dir
493                         && state->last_seq == seq
494                         && state->last_ack == ack
495                         && state->last_end == end && state->last_win == win)
496                 state->retrans++;
497         else {
498                 state->last_dir = dir;
499                 state->last_seq = seq;
500                 state->last_ack = ack;
501                 state->last_end = end;
502                 state->last_win = win;
503                 state->retrans = 0;
504         }
505 }
506
507 /*
508  * Verify that the sequence number in the given packet is within the valid
509  * range at this point in the connection
510  */
511 static uint8_t
512 rte_ct_tcp_in_window(
513         struct rte_ct_cnxn_data *cd,
514         struct rte_ct_cnxn_tracker *ct,
515         struct rte_ct_tcp *state,
516         enum rte_ct_pkt_direction dir,
517         uint8_t index,
518         struct rte_mbuf *pkt,
519         uint8_t ip_hdr_size)
520 {
521         struct rte_ct_tcp_state *sender = &state->seen[dir];
522         struct rte_ct_tcp_state *receiver = &state->seen[!dir];
523         uint32_t seq, ack, sack, end, win, swin;
524         uint8_t in_recv_win, tcp_flags;
525         enum rte_ct_packet_action res;
526
527         void *iphdr = RTE_MBUF_METADATA_UINT32_PTR(pkt, IP_START);
528         struct tcp_hdr *tcpheader =
529                 (struct tcp_hdr *)RTE_MBUF_METADATA_UINT32_PTR(pkt,
530                                 (IP_START + ip_hdr_size));
531
532         if (cd->ct_protocol.synproxy_data.synproxied)
533                 rte_sp_adjust_client_ack_before_window_check(cd, iphdr,
534                                 tcpheader, dir);
535
536
537         seq = rte_bswap32(tcpheader->sent_seq);
538         ack = sack = rte_bswap32(tcpheader->recv_ack);
539         win = rte_bswap16(tcpheader->rx_win);
540         end = rte_ct_seq_plus_length(pkt, ip_hdr_size);
541         tcp_flags = tcpheader->tcp_flags;
542
543         if (receiver->flags & RTE_CT_TCP_FLAG_SACK_PERM)
544                 sack = rte_ct_tcp_sack(pkt, ip_hdr_size);
545
546         if (unlikely(sender->maxwin == 0)) {
547                 /* First packet for sender, initialize data.  */
548                 if (tcp_flags & RTE_CT_TCPHDR_SYN) {
549                         /*
550                          * SYN-ACK in reply to a SYN
551                          * or SYN from reply direction in simultaneous open.
552                          */
553                         sender->end = sender->maxend = end;
554                         sender->maxwin = RTE_MAX(win, (uint32_t)1);
555
556                         rte_ct_check_for_scaling_and_sack_perm(pkt, sender,
557                                         ip_hdr_size);
558
559                         /*
560                          * RFC 1323: Both sides must send Window Scale option
561                          * to enable scaling in either direction.
562                          */
563                         if ((sender->
564                                          flags & receiver->flags &
565                                          RTE_CT_TCP_FLAG_WINDOW_SCALE) == 0)
566                                 sender->scale = receiver->scale = 0;
567
568                         if (!(tcp_flags & RTE_CT_TCPHDR_ACK))
569                                 /* Simultaneous open */
570                                 return 1;
571                 } else {
572                         /*
573                          * In the middle of a connection with no setup data.
574                          * Use available data from the packet.
575                          */
576                         sender->end = end;
577                         swin = win << sender->scale;
578                         sender->maxwin = (swin == 0 ? 1 : swin);
579                         sender->maxend = end + sender->maxwin;
580                         /*
581                          * We haven't seen traffic in the other direction yet
582                          * but we have to tweak window tracking to pass III
583                          * and IV until that happens.
584                          */
585                         if (receiver->maxwin == 0)
586                                 receiver->end = receiver->maxend = sack;
587                 }
588         }
589         /* if sender unititialized */
590         else if (((cd->ct_protocol.tcp_ct_data.state == RTE_CT_TCP_SYN_SENT &&
591                          dir == RTE_CT_DIR_ORIGINAL) ||
592                         (cd->ct_protocol.tcp_ct_data.state == RTE_CT_TCP_SYN_RECV &&
593                          dir == RTE_CT_DIR_REPLY)) && rte_after(end, sender->end)) {
594                 /*
595                  * RFC 793: "if a TCP is reinitialized ... then it need
596                  * not wait at all; it must only be sure to use sequence
597                  * numbers larger than those recently used."
598                  */
599                 sender->end = sender->maxend = end;
600                 sender->maxwin = RTE_MAX(win, (uint32_t)1);
601
602                 rte_ct_check_for_scaling_and_sack_perm(pkt, sender,
603                                 ip_hdr_size);
604         }
605         /* If no ACK, just pretend there was.  */
606         if (!(tcp_flags & RTE_CT_TCPHDR_ACK) ||
607                         (((tcp_flags & RTE_CT_TCPHDR_RST_ACK) ==
608                                 RTE_CT_TCPHDR_RST_ACK) && (ack == 0))) {
609                 /* Bad TCP Stacks */
610                 ack = sack = receiver->end;
611         }
612
613         if ((tcp_flags & RTE_CT_TCPHDR_RST) && seq == 0 &&
614                         cd->ct_protocol.tcp_ct_data.state == RTE_CT_TCP_SYN_SENT)
615                 /* RST sent answering SYN. */
616                 seq = end = sender->end;
617
618         /* Is the ending sequence in the receive window (if available)? */
619         in_recv_win = !receiver->maxwin ||
620                         rte_after(end, sender->end - receiver->maxwin - 1);
621
622         if (rte_before(seq, sender->maxend + 1) && in_recv_win &&
623                         rte_before(sack, receiver->end + 1) &&
624                         rte_after(sack,
625                                 receiver->end - RTE_MAX(sender->maxwin,
626                                         (uint32_t)RTE_MAX_ACKWIN_CONST) - 1)) {
627                 /*
628                  * Apply window scaling (RFC 1323). Only valid if both
629                  * directions sent this option in a SYN packet,
630                  * so ignore until not a SYN packet. Scale will be
631                  * set to zero if connection set up but no valid scale is there.
632                  */
633                 if (!(tcp_flags & RTE_CT_TCPHDR_SYN))
634                         win <<= sender->scale;
635
636                 /* Update sender data. */
637                 swin = win + (sack - ack);
638                 sender->maxwin = RTE_MAX(sender->maxwin, swin);
639
640                 if (rte_after(end, sender->end)) {
641                         sender->end = end;
642                         sender->flags |= RTE_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
643                 }
644
645                 if (tcp_flags & RTE_CT_TCPHDR_ACK) {
646                         if (!(sender->flags & RTE_CT_TCP_FLAG_MAXACK_SET)) {
647                                 sender->maxack = ack;
648                                 sender->flags |= RTE_CT_TCP_FLAG_MAXACK_SET;
649                         } else if (rte_after(ack, sender->maxack))
650                                 sender->maxack = ack;
651                 }
652
653                 /* Update receiver data. */
654                 if (receiver->maxwin != 0 && rte_after(end, sender->maxend))
655                         receiver->maxwin += end - sender->maxend;
656
657                 if (rte_after(sack + win, receiver->maxend - 1))
658                         receiver->maxend = sack + RTE_MAX(win, (uint32_t)1);
659
660                 if (ack == receiver->end)
661                         receiver->flags &= ~RTE_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
662
663                 /* If this packet has an ACK, it may be a retransmission.  */
664                 if (index == RTE_CT_TCP_ACK_FLAG)
665                         rte_ct_check_for_retransmissions(state, dir, seq, ack,
666                                                          end, win);
667                 res = 1;
668         } else {
669                 res = (sender->flags & RTE_CT_TCP_FLAG_BE_LIBERAL ||
670                                          ct->misc_options.tcp_be_liberal);
671         }
672
673         if (CT_DEBUG) {
674                 if (!res) {
675                         /* CT_DEBUG = 0; */
676                         printf("tcp_in_window FAILED for %p\n", cd);
677                         printf("rte_before(%u, %u + 1) is %d\n",
678                                                  seq, sender->maxend + 1,
679                                                  rte_before(seq, sender->maxend + 1));
680                         printf("!%u ||  rte_after(%u, %u - %u - 1) is %d\n",
681                                                  receiver->maxwin, end, sender->end,
682                                                  receiver->maxwin, in_recv_win);
683                         printf("rte_before(%u, %u + 1) is %d\n", sack,
684                                                  receiver->end, rte_before(sack,
685                                                          receiver->end + 1));
686                         printf
687                                         ("rte_after(%u,(%u - RTE_MAX(%u, %u) - 1))) is%d\n",
688                                          sack, receiver->end, sender->maxwin,
689                                          RTE_MAX_ACKWIN_CONST, rte_after(sack,
690                                                  receiver->end - RTE_MAX(sender->maxwin,
691                                                          (uint32_t)RTE_MAX_ACKWIN_CONST)
692                                                  - 1));
693
694                 }
695         }
696         if (cd->ct_protocol.synproxy_data.synproxied)
697                 rte_sp_adjust_server_seq_after_window_check(cd, iphdr,
698                                 tcpheader, dir);
699         return res;
700 }
701
702 /*for the given two FSM states,return the one with the smallest timeout value*/
703 static inline uint8_t
704 rte_ct_choose_min_timeout_state(
705         struct rte_ct_cnxn_tracker *ct,
706         uint8_t state1,
707         uint8_t state2)
708 {
709         if (ct->ct_timeout.tcptimeout.tcp_timeouts[state1] <
710                         ct->ct_timeout.tcptimeout.tcp_timeouts[state2])
711                 return state1;
712         else
713                 return state2;
714 }
715
716
717 /* Returns verdict for packet */
718 enum rte_ct_packet_action
719 rte_ct_verify_tcp_packet(
720         struct rte_ct_cnxn_tracker *ct,
721         struct rte_ct_cnxn_data *cd,
722         struct rte_mbuf *pkt,
723         uint8_t key_was_flipped,
724         uint8_t ip_hdr_size)
725 {
726         struct tcp_hdr *tcpheader = (struct tcp_hdr *)
727                         RTE_MBUF_METADATA_UINT32_PTR(pkt, (IP_START + ip_hdr_size));
728
729         enum rte_ct_tcp_states new_state, old_state;
730         enum rte_ct_pkt_direction dir;
731         uint8_t index;
732
733         /* state whose timeout value will be used. In odd cases,
734          * not always current state */
735         uint8_t timeout_state;
736
737         dir = (cd->key_is_client_order == !key_was_flipped);
738
739         if (cd->ct_protocol.synproxy_data.synproxied &&
740                 cd->ct_protocol.synproxy_data.half_established &&
741                 !cd->ct_protocol.synproxy_data.cnxn_established &&
742                 dir == RTE_CT_DIR_ORIGINAL) {
743                 /*
744                  * Packet from client, but only client side of this connection
745                  * has been set up. Buffer packet until server side of
746                  * connection complete.
747                  */
748                 rte_ct_buffer_packet(ct, cd, pkt);
749                 return RTE_CT_HIJACK;
750         }
751
752         uint32_t recv_ack = rte_bswap32(tcpheader->recv_ack);
753         uint32_t sent_seq = rte_bswap32(tcpheader->sent_seq);
754
755         int check_window = 1;
756         enum rte_ct_packet_action return_action = RTE_CT_FORWARD_PACKET;
757
758         /*  rte_ct_tcpdisplay_hdr(tcpheader); */
759
760         old_state = cd->ct_protocol.tcp_ct_data.state;
761         index = rte_ct_get_index(tcpheader->tcp_flags);
762         new_state = rte_ct_tcp_state_table[dir][index][old_state];
763
764         if (new_state == RTE_CT_TCP_MAX) {
765                 if (CT_DEBUG) {
766                         printf("!!!!invalid state transition from %s ",
767                                         rte_ct_tcp_names[old_state]);
768                         printf("with flags 0x%02x\n",
769                                         tcpheader->tcp_flags);
770                 }
771
772                 ct->counters->pkts_drop_invalid_state++;
773                 return RTE_CT_DROP_PACKET;
774         }
775
776         if (STATE_TRACKING && new_state != old_state)
777                 printf(" new state %s\n", rte_ct_tcp_names[new_state]);
778
779         switch (new_state) {
780
781         case RTE_CT_TCP_ESTABLISHED:
782
783                 if (cd->ct_protocol.synproxy_data.synproxied &&
784                                 !cd->ct_protocol.synproxy_data.half_established &&
785                                 (old_state == RTE_CT_TCP_SYN_RECV)) {
786                         /*
787                          * During synproxy setup, ESTABLISHED state entered by
788                          * ACK arriving from client. The proxy must now send a
789                          * spoofed SYN to the server.
790                          * Reset the state to RTE_CT_TCP_SYN_SENT.
791                          */
792
793                         if (STATE_TRACKING) {
794                                 printf(" synproxy first half-cnxn complete,");
795                                 printf(" new state %s\n",
796                                         rte_ct_tcp_names[RTE_CT_TCP_SYN_SENT]);
797                         }
798                         cd->ct_protocol.synproxy_data.half_established = true;
799
800                         rte_sp_cvt_to_spoofed_server_syn(cd, pkt);
801                         rte_ct_clear_cnxn_data(ct, cd, pkt);
802                         cd->ct_protocol.tcp_ct_data.state = RTE_CT_TCP_SYN_SENT;
803
804                         struct rte_ct_tcp_state *sender =
805                                 &cd->ct_protocol.tcp_ct_data.
806                                 seen[RTE_CT_DIR_ORIGINAL];
807                         uint16_t win = rte_bswap16(tcpheader->rx_win);
808
809                         sender->end = sender->maxend =
810                                 rte_ct_seq_plus_length(pkt, ip_hdr_size);
811                         sender->maxwin = RTE_MAX(win, (uint32_t)1);
812                         rte_ct_check_for_scaling_and_sack_perm(pkt, sender,
813                                         ip_hdr_size);
814                         /* TODO seq number code */
815                         rte_ct_set_cnxn_timer_for_tcp(ct, cd,
816                                         RTE_CT_TCP_SYN_SENT);
817                         return RTE_CT_SEND_SERVER_SYN;
818                 }
819
820
821         case RTE_CT_TCP_SYN_RECV:
822
823                 if (cd->ct_protocol.synproxy_data.synproxied &&
824                                 cd->ct_protocol.synproxy_data.half_established &&
825                                 !cd->ct_protocol.synproxy_data.cnxn_established) {
826                         /*
827                          * The reply SYN/ACK has been received from the server.
828                          * The connection can now be considered established,
829                          * even though an ACK stills needs to be sent to
830                          * the server.
831                          */
832
833                         if (!rte_ct_tcp_in_window(cd, ct,
834                                                 &cd->ct_protocol.tcp_ct_data,
835                                                 dir, index, pkt, ip_hdr_size)) {
836                                 ct->counters->pkts_drop_outof_window++;
837                                 return RTE_CT_DROP_PACKET;
838                         }
839
840                         if (STATE_TRACKING) {
841                                 printf("synproxy full cnxn complete,");
842                                 printf(" new state %s\n", rte_ct_tcp_names
843                                                 [RTE_CT_TCP_ESTABLISHED]);
844                         }
845
846                         /*
847                          * Convert the packet to an ack to return to the server.
848                          * This routine also saves the real sequence number
849                          * from the server.
850                          */
851
852                         rte_sp_cvt_to_spoofed_server_ack(cd, pkt);
853
854                         index = rte_ct_get_index(tcpheader->tcp_flags);
855
856                         if (!rte_ct_tcp_in_window(cd, ct,
857                                         &cd->ct_protocol.tcp_ct_data,
858                                         !dir, index, pkt, ip_hdr_size)) {
859                                 ct->counters->pkts_drop_outof_window++;
860                                 return RTE_CT_DROP_PACKET;
861                         }
862
863                         /* good packets, OK to update state */
864
865                         cd->ct_protocol.tcp_ct_data.state =
866                                 RTE_CT_TCP_ESTABLISHED;
867                         ct->counters->sessions_established++;
868                         cd->ct_protocol.synproxy_data.cnxn_established = true;
869                         cd->ct_protocol.tcp_ct_data.last_index = index;
870                         cd->ct_protocol.tcp_ct_data.last_dir = !dir;
871
872                         rte_ct_set_cnxn_timer_for_tcp(ct, cd,
873                                         RTE_CT_TCP_ESTABLISHED);
874                         rte_ct_release_buffered_packets(ct, cd);
875
876                         return RTE_CT_SEND_SERVER_ACK;
877                 }
878
879         case RTE_CT_TCP_SYN_SENT:
880
881                 /*
882                  * A connection that is actively closed goes to TIME-WAIT state.
883                  * It can be re-opened (before it times out) by a SYN packet.
884                  */
885
886                 if (old_state < RTE_CT_TCP_TIME_WAIT)
887                         break;
888                 /*
889                  * Due to previous check and state machine transitions,
890                  * old state must be RTE_CT_TCP_TIME_WAIT or RTE_CT_TCP_CLOSE .
891                  * Need to re-open connection.
892                  */
893
894                 return RTE_CT_REOPEN_CNXN_AND_FORWARD_PACKET;
895
896         case RTE_CT_TCP_IGNORE:
897
898                 /*
899                  * Ignored packets usually mean the connection data is
900                  * out of sync with client/server. Ignore, but forward
901                  * these packets since they may be valid for the connection.
902                  * If the ignored packet is invalid, the receiver will send
903                  * an RST which should get the connection entry back in sync.
904                  */
905
906                 /*
907                  * However, if connection is running synproxy and the full
908                  * connection is not yet established, there is no where
909                  * for test packets to go so drop these packets.
910                  */
911
912                 if (cd->ct_protocol.synproxy_data.synproxied &&
913                                 !cd->ct_protocol.synproxy_data.cnxn_established)
914                         return RTE_CT_DROP_PACKET;
915
916                 if (index == RTE_CT_TCP_SAK_FLAG &&
917                                 cd->ct_protocol.tcp_ct_data.last_index ==
918                                 RTE_CT_TCP_SYN_FLAG
919                                 && cd->ct_protocol.tcp_ct_data.last_dir != dir
920                                 && recv_ack == cd->ct_protocol.tcp_ct_data.last_end) {
921                         /*
922                          * SYN/ACK in reply direction acknowledging a SYN
923                          * earlier ignored as invalid.Client and server in sync,
924                          * but connection tracker is not. Use previous values
925                          * to get back in sync.
926                          */
927
928                         struct rte_ct_tcp_state *last_seen =
929                                         &cd->ct_protocol.tcp_ct_data.seen[cd->ct_protocol.
930                                                                                 tcp_ct_data.
931                                                                                 last_dir];
932
933                         /* reset new and old states to what they should
934                          * have been */
935                         old_state = RTE_CT_TCP_SYN_SENT;
936                         new_state = RTE_CT_TCP_SYN_RECV;
937
938                         last_seen->end = cd->ct_protocol.tcp_ct_data.last_end;
939                         last_seen->maxend =
940                                         cd->ct_protocol.tcp_ct_data.last_end;
941                         last_seen->maxwin =
942                                 RTE_MAX(cd->ct_protocol.tcp_ct_data.last_win,
943                                                 (uint32_t)1);
944                         last_seen->scale =
945                                         cd->ct_protocol.tcp_ct_data.last_wscale;
946                         cd->ct_protocol.tcp_ct_data.last_flags &=
947                                         ~RTE_CT_EXP_CHALLENGE_ACK;
948                         last_seen->flags =
949                                         cd->ct_protocol.tcp_ct_data.last_flags;
950                         memset(&cd->ct_protocol.tcp_ct_data.seen[dir], 0,
951                                                  sizeof(struct rte_ct_tcp_state));
952                         break;
953                 }
954
955                 cd->ct_protocol.tcp_ct_data.last_index = index;
956                 cd->ct_protocol.tcp_ct_data.last_dir = dir;
957                 cd->ct_protocol.tcp_ct_data.last_seq = sent_seq;
958                 cd->ct_protocol.tcp_ct_data.last_end =
959                         rte_ct_seq_plus_length(pkt, ip_hdr_size);
960                 cd->ct_protocol.tcp_ct_data.last_win =
961                         rte_bswap16(tcpheader->rx_win);
962
963                 /*
964                  * An orinal SYN. Client and the server may be in sync, but
965                  * the tracker is not . Annotate
966                  * the TCP options and let the packet go through. If it is a
967                  * valid SYN packet, the server will reply with a SYN/ACK, and
968                  * then we'll get in sync. Otherwise, the server potentially
969                  * responds with a challenge ACK if implementing RFC5961.
970                  */
971                 if (index == RTE_CT_TCP_SYN_FLAG &&
972                                 dir == RTE_CT_DIR_ORIGINAL) {
973                         struct rte_ct_tcp_state seen;
974
975                         /* call following to set "flag" and "scale" fields */
976                         rte_ct_check_for_scaling_and_sack_perm(pkt, &seen,
977                                         ip_hdr_size);
978
979                         /* only possible flags set for scling and sack */
980                         cd->ct_protocol.tcp_ct_data.last_flags = seen.flags;
981                         cd->ct_protocol.tcp_ct_data.last_wscale =
982                         (seen.flags & RTE_CT_TCP_FLAG_WINDOW_SCALE) == 0 ?
983                                         0 : seen.scale;
984
985                         /*
986                          * Mark the potential for RFC5961 challenge ACK,
987                          * this pose a special problem for LAST_ACK state
988                          * as ACK is intrepretated as ACKing last FIN.
989                          */
990                         if (old_state == RTE_CT_TCP_LAST_ACK)
991                                 cd->ct_protocol.tcp_ct_data.last_flags |=
992                                         RTE_CT_EXP_CHALLENGE_ACK;
993                 }
994                 return RTE_CT_FORWARD_PACKET;
995
996         case RTE_CT_TCP_TIME_WAIT:
997                 /*
998                  * RFC5961 compliance cause stack to send "challenge-ACK" in
999                  * response to unneeded SYNs. Do not treat this as acking
1000                  * last FIN.
1001                  */
1002                 if (old_state == RTE_CT_TCP_LAST_ACK &&
1003                                 index == RTE_CT_TCP_ACK_FLAG &&
1004                                 cd->ct_protocol.tcp_ct_data.last_dir != dir &&
1005                                 cd->ct_protocol.tcp_ct_data.last_index ==
1006                                 RTE_CT_TCP_SYN_FLAG
1007                                 && (cd->ct_protocol.tcp_ct_data.
1008                         last_flags & RTE_CT_EXP_CHALLENGE_ACK)) {
1009                         /* Detected RFC5961 challenge ACK */
1010                         cd->ct_protocol.tcp_ct_data.last_flags &=
1011                                 ~RTE_CT_EXP_CHALLENGE_ACK;
1012                         return RTE_CT_FORWARD_PACKET;   /* Don't change state */
1013                 }
1014                 break;
1015
1016         case RTE_CT_TCP_CLOSE:
1017
1018                 if (index == RTE_CT_TCP_RST_FLAG) {
1019                         /*
1020                          * Can only transition to CLOSE state with an RST,
1021                          * but can remain in
1022                          * CLOSE state with ACK, FIN, or RST. Do special checks.
1023                          */
1024
1025                         if ((cd->ct_protocol.tcp_ct_data.seen[!dir].flags &
1026                                                 RTE_CT_TCP_FLAG_MAXACK_SET) &&
1027                                         rte_before(sent_seq, cd->ct_protocol.
1028                                         tcp_ct_data.seen[!dir].maxack)) {
1029
1030                                 ct->counters->pkts_drop_invalid_rst++;
1031                                 /* Invalid RST  */
1032                                 return RTE_CT_DROP_PACKET;
1033                         }
1034
1035                         if (((cd->connstatus == RTE_SEEN_REPLY_CONN &&
1036                                                 cd->ct_protocol.tcp_ct_data.last_index ==
1037                                                         RTE_CT_TCP_SYN_FLAG) ||
1038                                 (cd->connstatus != RTE_ASSURED_CONN &&
1039                                 cd->ct_protocol.tcp_ct_data.last_index ==
1040                                                         RTE_CT_TCP_ACK_FLAG)) &&
1041                                 recv_ack ==
1042                                         cd->ct_protocol.tcp_ct_data.last_end) {
1043                                 /* RST sent to invalid SYN or ACK previously
1044                                  * let through */
1045                                 check_window = 0;
1046                         }
1047                 }
1048                 break;
1049
1050         default:
1051                 break;
1052         }
1053
1054         if (likely(check_window)) {
1055                 if (unlikely(!rte_ct_tcp_in_window(cd, ct,
1056                                                 &cd->ct_protocol.tcp_ct_data,
1057                                                 dir, index,
1058                                                 pkt, ip_hdr_size))) {
1059                         ct->counters->pkts_drop_outof_window++;
1060                         return RTE_CT_DROP_PACKET;
1061                 }
1062         }
1063
1064         if (new_state == RTE_CT_TCP_ESTABLISHED &&
1065                         old_state != RTE_CT_TCP_ESTABLISHED)
1066                 /* only increment for first state transition to established */
1067                 /* synproxy established count handled elswhere */
1068                 ct->counters->sessions_established++;
1069         /* From this point on, all packets are in-window */
1070         cd->ct_protocol.tcp_ct_data.last_index = index;
1071         cd->ct_protocol.tcp_ct_data.last_dir = dir;
1072
1073         if (index == RTE_CT_TCP_SAK_FLAG)
1074                 cd->connstatus = RTE_SEEN_REPLY_CONN;
1075
1076         timeout_state = new_state;
1077
1078         if (cd->ct_protocol.tcp_ct_data.retrans >=
1079                         ct->misc_options.tcp_max_retrans)
1080                 timeout_state =
1081                         rte_ct_choose_min_timeout_state(ct, timeout_state,
1082                                         RTE_CT_TCP_RETRANS);
1083         else if (rte_ct_either_direction_has_flags(cd,
1084                                 RTE_CT_TCP_FLAG_DATA_UNACKNOWLEDGED))
1085                 timeout_state =
1086                         rte_ct_choose_min_timeout_state(ct, timeout_state,
1087                                         RTE_CT_TCP_UNACK);
1088
1089         if (cd->connstatus != RTE_SEEN_REPLY_CONN) {
1090                 if (tcpheader->tcp_flags & RTE_CT_TCPHDR_RST) {
1091                         /*
1092                          * if only reply seen is RST, there is not an
1093                          * established connection, so just destroy
1094                          * connection now.
1095                          */
1096
1097                         return RTE_CT_DESTROY_CNXN_AND_FORWARD_PACKET;
1098                 }
1099                 /* ESTABLISHED without SEEN_REPLY, i.e. mid-connection
1100                          pickup with loose=1. Avoid large ESTABLISHED timeout. */
1101                 if (new_state == RTE_CT_TCP_ESTABLISHED)
1102                         timeout_state = rte_ct_choose_min_timeout_state(ct,
1103                                         timeout_state,
1104                                         RTE_CT_TCP_UNACK);
1105
1106         } else if (cd->connstatus != RTE_ASSURED_CONN &&
1107                          (old_state == RTE_CT_TCP_SYN_RECV
1108                                 || old_state == RTE_CT_TCP_ESTABLISHED)
1109                          && new_state == RTE_CT_TCP_ESTABLISHED)
1110                 cd->connstatus = RTE_ASSURED_CONN;
1111
1112         cd->ct_protocol.tcp_ct_data.state = new_state;
1113         rte_ct_set_cnxn_timer_for_tcp(ct, cd, timeout_state);
1114
1115         return return_action;
1116 }