d268251cb38babf289052b6cd2ccd5c5d9f4f24c
[vpp.git] / src / vnet / tcp / tcp_input.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vppinfra/sparse_vec.h>
17 #include <vnet/tcp/tcp_packet.h>
18 #include <vnet/tcp/tcp.h>
19 #include <vnet/session/session.h>
20 #include <math.h>
21
22 static char *tcp_error_strings[] = {
23 #define tcp_error(n,s) s,
24 #include <vnet/tcp/tcp_error.def>
25 #undef tcp_error
26 };
27
28 /* All TCP nodes have the same outgoing arcs */
29 #define foreach_tcp_state_next                  \
30   _ (DROP, "error-drop")                        \
31   _ (TCP4_OUTPUT, "tcp4-output")                \
32   _ (TCP6_OUTPUT, "tcp6-output")
33
34 typedef enum _tcp_established_next
35 {
36 #define _(s,n) TCP_ESTABLISHED_NEXT_##s,
37   foreach_tcp_state_next
38 #undef _
39     TCP_ESTABLISHED_N_NEXT,
40 } tcp_established_next_t;
41
42 typedef enum _tcp_rcv_process_next
43 {
44 #define _(s,n) TCP_RCV_PROCESS_NEXT_##s,
45   foreach_tcp_state_next
46 #undef _
47     TCP_RCV_PROCESS_N_NEXT,
48 } tcp_rcv_process_next_t;
49
50 typedef enum _tcp_syn_sent_next
51 {
52 #define _(s,n) TCP_SYN_SENT_NEXT_##s,
53   foreach_tcp_state_next
54 #undef _
55     TCP_SYN_SENT_N_NEXT,
56 } tcp_syn_sent_next_t;
57
58 typedef enum _tcp_listen_next
59 {
60 #define _(s,n) TCP_LISTEN_NEXT_##s,
61   foreach_tcp_state_next
62 #undef _
63     TCP_LISTEN_N_NEXT,
64 } tcp_listen_next_t;
65
66 /* Generic, state independent indices */
67 typedef enum _tcp_state_next
68 {
69 #define _(s,n) TCP_NEXT_##s,
70   foreach_tcp_state_next
71 #undef _
72     TCP_STATE_N_NEXT,
73 } tcp_state_next_t;
74
75 #define tcp_next_output(is_ip4) (is_ip4 ? TCP_NEXT_TCP4_OUTPUT          \
76                                         : TCP_NEXT_TCP6_OUTPUT)
77
78 vlib_node_registration_t tcp4_established_node;
79 vlib_node_registration_t tcp6_established_node;
80
81 /**
82  * Validate segment sequence number. As per RFC793:
83  *
84  * Segment Receive Test
85  *      Length  Window
86  *      ------- -------  -------------------------------------------
87  *      0       0       SEG.SEQ = RCV.NXT
88  *      0       >0      RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
89  *      >0      0       not acceptable
90  *      >0      >0      RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
91  *                      or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
92  *
93  * This ultimately consists in checking if segment falls within the window.
94  * The one important difference compared to RFC793 is that we use rcv_las,
95  * or the rcv_nxt at last ack sent instead of rcv_nxt since that's the
96  * peer's reference when computing our receive window.
97  *
98  * This:
99  *  seq_leq (end_seq, tc->rcv_las + tc->rcv_wnd) && seq_geq (seq, tc->rcv_las)
100  * however, is too strict when we have retransmits. Instead we just check that
101  * the seq is not beyond the right edge and that the end of the segment is not
102  * less than the left edge.
103  *
104  * N.B. rcv_nxt and rcv_wnd are both updated in this node if acks are sent, so
105  * use rcv_nxt in the right edge window test instead of rcv_las.
106  *
107  */
108 always_inline u8
109 tcp_segment_in_rcv_wnd (tcp_connection_t * tc, u32 seq, u32 end_seq)
110 {
111   return (seq_geq (end_seq, tc->rcv_las)
112           && seq_leq (seq, tc->rcv_nxt + tc->rcv_wnd));
113 }
114
115 void
116 tcp_options_parse (tcp_header_t * th, tcp_options_t * to)
117 {
118   const u8 *data;
119   u8 opt_len, opts_len, kind;
120   int j;
121   sack_block_t b;
122
123   opts_len = (tcp_doff (th) << 2) - sizeof (tcp_header_t);
124   data = (const u8 *) (th + 1);
125
126   /* Zero out all flags but those set in SYN */
127   to->flags &= (TCP_OPTS_FLAG_SACK_PERMITTED | TCP_OPTS_FLAG_WSCALE);
128
129   for (; opts_len > 0; opts_len -= opt_len, data += opt_len)
130     {
131       kind = data[0];
132
133       /* Get options length */
134       if (kind == TCP_OPTION_EOL)
135         break;
136       else if (kind == TCP_OPTION_NOOP)
137         opt_len = 1;
138       else
139         {
140           /* broken options */
141           if (opts_len < 2)
142             break;
143           opt_len = data[1];
144
145           /* weird option length */
146           if (opt_len < 2 || opt_len > opts_len)
147             break;
148         }
149
150       /* Parse options */
151       switch (kind)
152         {
153         case TCP_OPTION_MSS:
154           if ((opt_len == TCP_OPTION_LEN_MSS) && tcp_syn (th))
155             {
156               to->flags |= TCP_OPTS_FLAG_MSS;
157               to->mss = clib_net_to_host_u16 (*(u16 *) (data + 2));
158             }
159           break;
160         case TCP_OPTION_WINDOW_SCALE:
161           if ((opt_len == TCP_OPTION_LEN_WINDOW_SCALE) && tcp_syn (th))
162             {
163               to->flags |= TCP_OPTS_FLAG_WSCALE;
164               to->wscale = data[2];
165               if (to->wscale > TCP_MAX_WND_SCALE)
166                 {
167                   clib_warning ("Illegal window scaling value: %d",
168                                 to->wscale);
169                   to->wscale = TCP_MAX_WND_SCALE;
170                 }
171             }
172           break;
173         case TCP_OPTION_TIMESTAMP:
174           if (opt_len == TCP_OPTION_LEN_TIMESTAMP)
175             {
176               to->flags |= TCP_OPTS_FLAG_TSTAMP;
177               to->tsval = clib_net_to_host_u32 (*(u32 *) (data + 2));
178               to->tsecr = clib_net_to_host_u32 (*(u32 *) (data + 6));
179             }
180           break;
181         case TCP_OPTION_SACK_PERMITTED:
182           if (opt_len == TCP_OPTION_LEN_SACK_PERMITTED && tcp_syn (th))
183             to->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
184           break;
185         case TCP_OPTION_SACK_BLOCK:
186           /* If SACK permitted was not advertised or a SYN, break */
187           if ((to->flags & TCP_OPTS_FLAG_SACK_PERMITTED) == 0 || tcp_syn (th))
188             break;
189
190           /* If too short or not correctly formatted, break */
191           if (opt_len < 10 || ((opt_len - 2) % TCP_OPTION_LEN_SACK_BLOCK))
192             break;
193
194           to->flags |= TCP_OPTS_FLAG_SACK;
195           to->n_sack_blocks = (opt_len - 2) / TCP_OPTION_LEN_SACK_BLOCK;
196           vec_reset_length (to->sacks);
197           for (j = 0; j < to->n_sack_blocks; j++)
198             {
199               b.start = clib_net_to_host_u32 (*(u32 *) (data + 2 + 4 * j));
200               b.end = clib_net_to_host_u32 (*(u32 *) (data + 6 + 4 * j));
201               vec_add1 (to->sacks, b);
202             }
203           break;
204         default:
205           /* Nothing to see here */
206           continue;
207         }
208     }
209 }
210
211 /**
212  * RFC1323: Check against wrapped sequence numbers (PAWS). If we have
213  * timestamp to echo and it's less than tsval_recent, drop segment
214  * but still send an ACK in order to retain TCP's mechanism for detecting
215  * and recovering from half-open connections
216  *
217  * Or at least that's what the theory says. It seems that this might not work
218  * very well with packet reordering and fast retransmit. XXX
219  */
220 always_inline int
221 tcp_segment_check_paws (tcp_connection_t * tc)
222 {
223   return tcp_opts_tstamp (&tc->opt) && tc->tsval_recent
224     && timestamp_lt (tc->opt.tsval, tc->tsval_recent);
225 }
226
227 /**
228  * Update tsval recent
229  */
230 always_inline void
231 tcp_update_timestamp (tcp_connection_t * tc, u32 seq, u32 seq_end)
232 {
233   /*
234    * RFC1323: If Last.ACK.sent falls within the range of sequence numbers
235    * of an incoming segment:
236    *    SEG.SEQ <= Last.ACK.sent < SEG.SEQ + SEG.LEN
237    * then the TSval from the segment is copied to TS.Recent;
238    * otherwise, the TSval is ignored.
239    */
240   if (tcp_opts_tstamp (&tc->opt) && tc->tsval_recent
241       && seq_leq (seq, tc->rcv_las) && seq_leq (tc->rcv_las, seq_end))
242     {
243       tc->tsval_recent = tc->opt.tsval;
244       tc->tsval_recent_age = tcp_time_now ();
245     }
246 }
247
248 /**
249  * Validate incoming segment as per RFC793 p. 69 and RFC1323 p. 19
250  *
251  * It first verifies if segment has a wrapped sequence number (PAWS) and then
252  * does the processing associated to the first four steps (ignoring security
253  * and precedence): sequence number, rst bit and syn bit checks.
254  *
255  * @return 0 if segments passes validation.
256  */
257 static int
258 tcp_segment_validate (vlib_main_t * vm, tcp_connection_t * tc0,
259                       vlib_buffer_t * b0, tcp_header_t * th0, u32 * next0)
260 {
261   if (PREDICT_FALSE (!tcp_ack (th0) && !tcp_rst (th0) && !tcp_syn (th0)))
262     return -1;
263
264   tcp_options_parse (th0, &tc0->opt);
265
266   if (tcp_segment_check_paws (tc0))
267     {
268       clib_warning ("paws failed");
269       TCP_EVT_DBG (TCP_EVT_PAWS_FAIL, tc0, vnet_buffer (b0)->tcp.seq_number,
270                    vnet_buffer (b0)->tcp.seq_end);
271
272       /* If it just so happens that a segment updates tsval_recent for a
273        * segment over 24 days old, invalidate tsval_recent. */
274       if (timestamp_lt (tc0->tsval_recent_age + TCP_PAWS_IDLE,
275                         tcp_time_now ()))
276         {
277           /* Age isn't reset until we get a valid tsval (bsd inspired) */
278           tc0->tsval_recent = 0;
279           clib_warning ("paws failed - really old segment. REALLY?");
280         }
281       else
282         {
283           /* Drop after ack if not rst */
284           if (!tcp_rst (th0))
285             {
286               tcp_make_ack (tc0, b0);
287               *next0 = tcp_next_output (tc0->c_is_ip4);
288               TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc0);
289               return -1;
290             }
291         }
292     }
293
294   /* 1st: check sequence number */
295   if (!tcp_segment_in_rcv_wnd (tc0, vnet_buffer (b0)->tcp.seq_number,
296                                vnet_buffer (b0)->tcp.seq_end))
297     {
298       /* If our window is 0 and the packet is in sequence, let it pass
299        * through for ack processing. It should be dropped later.*/
300       if (tc0->rcv_wnd == 0
301           && tc0->rcv_nxt == vnet_buffer (b0)->tcp.seq_number)
302         {
303           /* TODO Should segment be tagged?  */
304         }
305       else
306         {
307           /* If not RST, send dup ack */
308           if (!tcp_rst (th0))
309             {
310               tcp_make_ack (tc0, b0);
311               *next0 = tcp_next_output (tc0->c_is_ip4);
312               TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc0);
313             }
314           return -1;
315         }
316     }
317
318   /* 2nd: check the RST bit */
319   if (tcp_rst (th0))
320     {
321       tcp_connection_reset (tc0);
322       return -1;
323     }
324
325   /* 3rd: check security and precedence (skip) */
326
327   /* 4th: check the SYN bit */
328   if (tcp_syn (th0))
329     {
330       tcp_send_reset (b0, tc0->c_is_ip4);
331       return -1;
332     }
333
334   /* If segment in window, save timestamp */
335   tcp_update_timestamp (tc0, vnet_buffer (b0)->tcp.seq_number,
336                         vnet_buffer (b0)->tcp.seq_end);
337
338   return 0;
339 }
340
341 always_inline int
342 tcp_rcv_ack_is_acceptable (tcp_connection_t * tc0, vlib_buffer_t * tb0)
343 {
344   /* SND.UNA =< SEG.ACK =< SND.NXT */
345   return (seq_leq (tc0->snd_una, vnet_buffer (tb0)->tcp.ack_number)
346           && seq_leq (vnet_buffer (tb0)->tcp.ack_number, tc0->snd_nxt));
347 }
348
349 /**
350  * Compute smoothed RTT as per VJ's '88 SIGCOMM and RFC6298
351  *
352  * Note that although the original article, srtt and rttvar are scaled
353  * to minimize round-off errors, here we don't. Instead, we rely on
354  * better precision time measurements.
355  *
356  * TODO support us rtt resolution
357  */
358 static void
359 tcp_estimate_rtt (tcp_connection_t * tc, u32 mrtt)
360 {
361   int err;
362
363   if (tc->srtt != 0)
364     {
365       err = mrtt - tc->srtt;
366       tc->srtt += err >> 3;
367
368       /* XXX Drop in RTT results in RTTVAR increase and bigger RTO.
369        * The increase should be bound */
370       tc->rttvar += ((int) clib_abs (err) - (int) tc->rttvar) >> 2;
371     }
372   else
373     {
374       /* First measurement. */
375       tc->srtt = mrtt;
376       tc->rttvar = mrtt >> 1;
377     }
378 }
379
380 /** Update RTT estimate and RTO timer
381  *
382  * Measure RTT: We have two sources of RTT measurements: TSOPT and ACK
383  * timing. Middle boxes are known to fiddle with TCP options so we
384  * should give higher priority to ACK timing.
385  *
386  * return 1 if valid rtt 0 otherwise
387  */
388 static int
389 tcp_update_rtt (tcp_connection_t * tc, u32 ack)
390 {
391   u32 mrtt = 0;
392   u8 rtx_acked;
393
394   /* Determine if only rtx bytes are acked. TODO fast retransmit */
395   rtx_acked = tc->rto_boff && (tc->bytes_acked <= tc->snd_mss);
396
397   /* Karn's rule, part 1. Don't use retransmitted segments to estimate
398    * RTT because they're ambiguous. */
399   if (tc->rtt_ts && seq_geq (ack, tc->rtt_seq) && !rtx_acked)
400     {
401       mrtt = tcp_time_now () - tc->rtt_ts;
402     }
403   /* As per RFC7323 TSecr can be used for RTTM only if the segment advances
404    * snd_una, i.e., the left side of the send window:
405    * seq_lt (tc->snd_una, ack). Note: last condition could be dropped, we don't
406    * try to update rtt for dupacks */
407   else if (tcp_opts_tstamp (&tc->opt) && tc->opt.tsecr && tc->bytes_acked)
408     {
409       mrtt = tcp_time_now () - tc->opt.tsecr;
410     }
411
412   /* Allow measuring of a new RTT */
413   tc->rtt_ts = 0;
414
415   /* If ACK moves left side of the wnd make sure boff is 0, even if mrtt is
416    * not valid */
417   if (tc->bytes_acked)
418     tc->rto_boff = 0;
419
420   /* Ignore dubious measurements */
421   if (mrtt == 0 || mrtt > TCP_RTT_MAX)
422     return 0;
423
424   tcp_estimate_rtt (tc, mrtt);
425   tc->rto = clib_min (tc->srtt + (tc->rttvar << 2), TCP_RTO_MAX);
426
427   return 0;
428 }
429
430 /**
431  * Dequeue bytes that have been acked and while at it update RTT estimates.
432  */
433 static void
434 tcp_dequeue_acked (tcp_connection_t * tc, u32 ack)
435 {
436   /* Dequeue the newly ACKed bytes */
437   stream_session_dequeue_drop (&tc->connection, tc->bytes_acked);
438
439   /* Update rtt and rto */
440   tcp_update_rtt (tc, ack);
441 }
442
443 /**
444  * Check if dupack as per RFC5681 Sec. 2
445  *
446  * This works only if called before updating snd_wnd.
447  * */
448 always_inline u8
449 tcp_ack_is_dupack (tcp_connection_t * tc, vlib_buffer_t * b, u32 new_snd_wnd)
450 {
451   return ((vnet_buffer (b)->tcp.ack_number == tc->snd_una)
452           && seq_gt (tc->snd_una_max, tc->snd_una)
453           && (vnet_buffer (b)->tcp.seq_end == vnet_buffer (b)->tcp.seq_number)
454           && (new_snd_wnd == tc->snd_wnd));
455 }
456
457 void
458 scoreboard_remove_hole (sack_scoreboard_t * sb, sack_scoreboard_hole_t * hole)
459 {
460   sack_scoreboard_hole_t *next, *prev;
461
462   if (hole->next != TCP_INVALID_SACK_HOLE_INDEX)
463     {
464       next = pool_elt_at_index (sb->holes, hole->next);
465       next->prev = hole->prev;
466     }
467
468   if (hole->prev != TCP_INVALID_SACK_HOLE_INDEX)
469     {
470       prev = pool_elt_at_index (sb->holes, hole->prev);
471       prev->next = hole->next;
472     }
473   else
474     {
475       sb->head = hole->next;
476     }
477
478   pool_put (sb->holes, hole);
479 }
480
481 sack_scoreboard_hole_t *
482 scoreboard_insert_hole (sack_scoreboard_t * sb, u32 prev_index,
483                         u32 start, u32 end)
484 {
485   sack_scoreboard_hole_t *hole, *next, *prev;
486   u32 hole_index;
487
488   pool_get (sb->holes, hole);
489   memset (hole, 0, sizeof (*hole));
490
491   hole->start = start;
492   hole->end = end;
493   hole_index = hole - sb->holes;
494
495   prev = scoreboard_get_hole (sb, prev_index);
496   if (prev)
497     {
498       hole->prev = prev - sb->holes;
499       hole->next = prev->next;
500
501       if ((next = scoreboard_next_hole (sb, hole)))
502         next->prev = hole_index;
503
504       prev->next = hole_index;
505     }
506   else
507     {
508       sb->head = hole_index;
509       hole->prev = TCP_INVALID_SACK_HOLE_INDEX;
510       hole->next = TCP_INVALID_SACK_HOLE_INDEX;
511     }
512
513   return hole;
514 }
515
516 void
517 tcp_rcv_sacks (tcp_connection_t * tc, u32 ack)
518 {
519   sack_scoreboard_t *sb = &tc->sack_sb;
520   sack_block_t *blk, tmp;
521   sack_scoreboard_hole_t *hole, *next_hole, *last_hole, *new_hole;
522   u32 blk_index = 0, old_sacked_bytes, hole_index;
523   int i, j;
524
525   sb->last_sacked_bytes = 0;
526   sb->snd_una_adv = 0;
527   old_sacked_bytes = sb->sacked_bytes;
528
529   if (!tcp_opts_sack (&tc->opt) && sb->head == TCP_INVALID_SACK_HOLE_INDEX)
530     return;
531
532   /* Remove invalid blocks */
533   blk = tc->opt.sacks;
534   while (blk < vec_end (tc->opt.sacks))
535     {
536       if (seq_lt (blk->start, blk->end)
537           && seq_gt (blk->start, tc->snd_una)
538           && seq_gt (blk->start, ack) && seq_leq (blk->end, tc->snd_nxt))
539         {
540           blk++;
541           continue;
542         }
543       vec_del1 (tc->opt.sacks, blk - tc->opt.sacks);
544     }
545
546   /* Add block for cumulative ack */
547   if (seq_gt (ack, tc->snd_una))
548     {
549       tmp.start = tc->snd_una;
550       tmp.end = ack;
551       vec_add1 (tc->opt.sacks, tmp);
552     }
553
554   if (vec_len (tc->opt.sacks) == 0)
555     return;
556
557   /* Make sure blocks are ordered */
558   for (i = 0; i < vec_len (tc->opt.sacks); i++)
559     for (j = i + 1; j < vec_len (tc->opt.sacks); j++)
560       if (seq_lt (tc->opt.sacks[j].start, tc->opt.sacks[i].start))
561         {
562           tmp = tc->opt.sacks[i];
563           tc->opt.sacks[i] = tc->opt.sacks[j];
564           tc->opt.sacks[j] = tmp;
565         }
566
567   if (sb->head == TCP_INVALID_SACK_HOLE_INDEX)
568     {
569       /* If no holes, insert the first that covers all outstanding bytes */
570       last_hole = scoreboard_insert_hole (sb, TCP_INVALID_SACK_HOLE_INDEX,
571                                           tc->snd_una, tc->snd_una_max);
572       sb->tail = scoreboard_hole_index (sb, last_hole);
573     }
574   else
575     {
576       /* If we have holes but snd_una_max is beyond the last hole, update
577        * last hole end */
578       tmp = tc->opt.sacks[vec_len (tc->opt.sacks) - 1];
579       last_hole = scoreboard_last_hole (sb);
580       if (seq_gt (tc->snd_una_max, sb->max_byte_sacked)
581           && seq_gt (tc->snd_una_max, last_hole->end))
582         last_hole->end = tc->snd_una_max;
583     }
584
585   /* Walk the holes with the SACK blocks */
586   hole = pool_elt_at_index (sb->holes, sb->head);
587   while (hole && blk_index < vec_len (tc->opt.sacks))
588     {
589       blk = &tc->opt.sacks[blk_index];
590
591       if (seq_leq (blk->start, hole->start))
592         {
593           /* Block covers hole. Remove hole */
594           if (seq_geq (blk->end, hole->end))
595             {
596               next_hole = scoreboard_next_hole (sb, hole);
597
598               /* Byte accounting */
599               if (seq_leq (hole->end, ack))
600                 {
601                   /* Bytes lost because snd_wnd left edge advances */
602                   if (next_hole && seq_leq (next_hole->start, ack))
603                     sb->sacked_bytes -= next_hole->start - hole->end;
604                   else
605                     sb->sacked_bytes -= ack - hole->end;
606                 }
607               else
608                 {
609                   sb->sacked_bytes += scoreboard_hole_bytes (hole);
610                 }
611
612               /* snd_una needs to be advanced */
613               if (seq_geq (ack, hole->end))
614                 {
615                   if (next_hole && seq_lt (ack, next_hole->start))
616                     sb->snd_una_adv = next_hole->start - ack;
617                   else
618                     sb->snd_una_adv = sb->max_byte_sacked - ack;
619
620                   /* all these can be delivered */
621                   sb->sacked_bytes -= sb->snd_una_adv;
622                 }
623
624               /* About to remove last hole */
625               if (hole == last_hole)
626                 {
627                   sb->tail = hole->prev;
628                   last_hole = scoreboard_last_hole (sb);
629                   /* keep track of max byte sacked in case the last hole
630                    * is acked */
631                   if (seq_gt (hole->end, sb->max_byte_sacked))
632                     sb->max_byte_sacked = hole->end;
633                 }
634               scoreboard_remove_hole (sb, hole);
635               hole = next_hole;
636             }
637           /* Partial 'head' overlap */
638           else
639             {
640               if (seq_gt (blk->end, hole->start))
641                 {
642                   sb->sacked_bytes += blk->end - hole->start;
643                   hole->start = blk->end;
644                 }
645               blk_index++;
646             }
647         }
648       else
649         {
650           /* Hole must be split */
651           if (seq_lt (blk->end, hole->end))
652             {
653               sb->sacked_bytes += blk->end - blk->start;
654               hole_index = scoreboard_hole_index (sb, hole);
655               new_hole = scoreboard_insert_hole (sb, hole_index, blk->end,
656                                                  hole->end);
657
658               /* Pool might've moved */
659               hole = scoreboard_get_hole (sb, hole_index);
660               hole->end = blk->start;
661
662               /* New or split of tail */
663               if ((last_hole->end == new_hole->end)
664                   || seq_lt (last_hole->end, new_hole->start))
665                 {
666                   last_hole = new_hole;
667                   sb->tail = scoreboard_hole_index (sb, new_hole);
668                 }
669
670               blk_index++;
671               hole = scoreboard_next_hole (sb, hole);
672             }
673           else
674             {
675               sb->sacked_bytes += hole->end - blk->start;
676               hole->end = blk->start;
677               hole = scoreboard_next_hole (sb, hole);
678             }
679         }
680     }
681
682   sb->last_sacked_bytes = sb->sacked_bytes + sb->snd_una_adv
683     - old_sacked_bytes;
684 }
685
686 /** Update snd_wnd
687  *
688  * If (SND.WL1 < SEG.SEQ or (SND.WL1 = SEG.SEQ and SND.WL2 =< SEG.ACK)), set
689  * SND.WND <- SEG.WND, set SND.WL1 <- SEG.SEQ, and set SND.WL2 <- SEG.ACK */
690 static void
691 tcp_update_snd_wnd (tcp_connection_t * tc, u32 seq, u32 ack, u32 snd_wnd)
692 {
693   if (seq_lt (tc->snd_wl1, seq)
694       || (tc->snd_wl1 == seq && seq_leq (tc->snd_wl2, ack)))
695     {
696       tc->snd_wnd = snd_wnd;
697       tc->snd_wl1 = seq;
698       tc->snd_wl2 = ack;
699       TCP_EVT_DBG (TCP_EVT_SND_WND, tc);
700
701       /* Set probe timer if we just got 0 wnd */
702       if (tc->snd_wnd < tc->snd_mss
703           && !tcp_timer_is_active (tc, TCP_TIMER_PERSIST))
704         tcp_persist_timer_set (tc);
705       else
706         tcp_persist_timer_reset (tc);
707     }
708 }
709
710 void
711 tcp_cc_congestion (tcp_connection_t * tc)
712 {
713   tc->snd_congestion = tc->snd_nxt;
714   tc->cc_algo->congestion (tc);
715   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 4);
716 }
717
718 void
719 tcp_cc_recover (tcp_connection_t * tc)
720 {
721   /* TODO: check if time to recover was small. It might be that RTO popped
722    * too soon.
723    */
724
725   tc->cc_algo->recovered (tc);
726
727   tc->rtx_bytes = 0;
728   tc->rcv_dupacks = 0;
729   tc->snd_nxt = tc->snd_una;
730
731   tc->cc_algo->rcv_ack (tc);
732   tc->tsecr_last_ack = tc->opt.tsecr;
733
734   tcp_cong_recovery_off (tc);
735
736   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 3);
737 }
738
739 static void
740 tcp_cc_rcv_ack (tcp_connection_t * tc, vlib_buffer_t * b)
741 {
742   u8 partial_ack;
743
744   if (tcp_in_fastrecovery (tc))
745     {
746       partial_ack = seq_lt (tc->snd_una, tc->snd_congestion);
747       if (!partial_ack)
748         {
749           /* Clear retransmitted bytes. */
750           tcp_cc_recover (tc);
751         }
752       else
753         {
754           TCP_EVT_DBG (TCP_EVT_CC_PACK, tc);
755
756           /* Clear retransmitted bytes. XXX should we clear all? */
757           tc->rtx_bytes = 0;
758
759           tc->cc_algo->rcv_cong_ack (tc, TCP_CC_PARTIALACK);
760
761           /* In case snd_nxt is still in the past and output tries to
762            * shove some new bytes */
763           tc->snd_nxt = tc->snd_una_max;
764
765           /* XXX need proper RFC6675 support */
766           if (tc->sack_sb.last_sacked_bytes && !tcp_in_recovery (tc))
767             {
768               tcp_fast_retransmit (tc);
769             }
770           else
771             {
772               /* Retransmit first unacked segment */
773               tcp_retransmit_first_unacked (tc);
774             }
775         }
776     }
777   else
778     {
779       tc->cc_algo->rcv_ack (tc);
780       tc->tsecr_last_ack = tc->opt.tsecr;
781       tc->rcv_dupacks = 0;
782       if (tcp_in_recovery (tc))
783         {
784           tc->rtx_bytes -= clib_min (tc->bytes_acked, tc->rtx_bytes);
785           tc->rto = clib_min (tc->srtt + (tc->rttvar << 2), TCP_RTO_MAX);
786           if (seq_geq (tc->snd_una, tc->snd_congestion))
787             tcp_recovery_off (tc);
788         }
789     }
790 }
791
792 static void
793 tcp_cc_rcv_dupack (tcp_connection_t * tc, u32 ack)
794 {
795 //  ASSERT (seq_geq(tc->snd_una, ack));
796
797   tc->rcv_dupacks++;
798   if (tc->rcv_dupacks == TCP_DUPACK_THRESHOLD)
799     {
800       /* RFC6582 NewReno heuristic to avoid multiple fast retransmits */
801       if (tc->opt.tsecr != tc->tsecr_last_ack)
802         {
803           tc->rcv_dupacks = 0;
804           return;
805         }
806
807       tcp_fastrecovery_on (tc);
808
809       /* Handle congestion and dupack */
810       tcp_cc_congestion (tc);
811       tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
812
813       tcp_fast_retransmit (tc);
814
815       /* Post retransmit update cwnd to ssthresh and account for the
816        * three segments that have left the network and should've been
817        * buffered at the receiver */
818       tc->cwnd = tc->ssthresh + TCP_DUPACK_THRESHOLD * tc->snd_mss;
819     }
820   else if (tc->rcv_dupacks > TCP_DUPACK_THRESHOLD)
821     {
822       ASSERT (tcp_in_fastrecovery (tc));
823
824       tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
825     }
826 }
827
828 void
829 tcp_cc_init (tcp_connection_t * tc)
830 {
831   tc->cc_algo = tcp_cc_algo_get (TCP_CC_NEWRENO);
832   tc->cc_algo->init (tc);
833 }
834
835 static int
836 tcp_rcv_ack (tcp_connection_t * tc, vlib_buffer_t * b,
837              tcp_header_t * th, u32 * next, u32 * error)
838 {
839   u32 new_snd_wnd;
840
841   /* If the ACK acks something not yet sent (SEG.ACK > SND.NXT) */
842   if (seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt))
843     {
844       /* If we have outstanding data and this is within the window, accept it,
845        * probably retransmit has timed out. Otherwise ACK segment and then
846        * drop it */
847       if (seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_una_max))
848         {
849           tcp_make_ack (tc, b);
850           *next = tcp_next_output (tc->c_is_ip4);
851           *error = TCP_ERROR_ACK_INVALID;
852           TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 0,
853                        vnet_buffer (b)->tcp.ack_number);
854           return -1;
855         }
856
857       TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 2,
858                    vnet_buffer (b)->tcp.ack_number);
859
860       tc->snd_nxt = vnet_buffer (b)->tcp.ack_number;
861       *error = TCP_ERROR_ACK_FUTURE;
862     }
863
864   /* If old ACK, probably it's an old dupack */
865   if (seq_lt (vnet_buffer (b)->tcp.ack_number, tc->snd_una))
866     {
867       *error = TCP_ERROR_ACK_OLD;
868       TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 1,
869                    vnet_buffer (b)->tcp.ack_number);
870       if (tcp_in_fastrecovery (tc) && tc->rcv_dupacks == TCP_DUPACK_THRESHOLD)
871         {
872           TCP_EVT_DBG (TCP_EVT_DUPACK_RCVD, tc);
873           tcp_cc_rcv_dupack (tc, vnet_buffer (b)->tcp.ack_number);
874         }
875       /* Don't drop yet */
876       return 0;
877     }
878
879   if (tcp_opts_sack_permitted (&tc->opt))
880     tcp_rcv_sacks (tc, vnet_buffer (b)->tcp.ack_number);
881
882   new_snd_wnd = clib_net_to_host_u16 (th->window) << tc->snd_wscale;
883
884   if (tcp_ack_is_dupack (tc, b, new_snd_wnd))
885     {
886       TCP_EVT_DBG (TCP_EVT_DUPACK_RCVD, tc, 1);
887       tcp_cc_rcv_dupack (tc, vnet_buffer (b)->tcp.ack_number);
888       *error = TCP_ERROR_ACK_DUP;
889       return -1;
890     }
891
892   /*
893    * Valid ACK
894    */
895
896   tc->bytes_acked = vnet_buffer (b)->tcp.ack_number - tc->snd_una;
897   tc->snd_una = vnet_buffer (b)->tcp.ack_number + tc->sack_sb.snd_una_adv;
898
899   /* Dequeue ACKed data and update RTT */
900   tcp_dequeue_acked (tc, vnet_buffer (b)->tcp.ack_number);
901   tcp_update_snd_wnd (tc, vnet_buffer (b)->tcp.seq_number,
902                       vnet_buffer (b)->tcp.ack_number, new_snd_wnd);
903
904   /* If some of our sent bytes have been acked, update cc and retransmit
905    * timer. */
906   if (tc->bytes_acked)
907     {
908       TCP_EVT_DBG (TCP_EVT_ACK_RCVD, tc);
909
910       /* Updates congestion control (slow start/congestion avoidance) */
911       tcp_cc_rcv_ack (tc, b);
912
913       /* If everything has been acked, stop retransmit timer
914        * otherwise update. */
915       if (tc->snd_una == tc->snd_una_max)
916         tcp_retransmit_timer_reset (tc);
917       else
918         tcp_retransmit_timer_update (tc);
919     }
920
921   return 0;
922 }
923
924 /**
925  * Build SACK list as per RFC2018.
926  *
927  * Makes sure the first block contains the segment that generated the current
928  * ACK and the following ones are the ones most recently reported in SACK
929  * blocks.
930  *
931  * @param tc TCP connection for which the SACK list is updated
932  * @param start Start sequence number of the newest SACK block
933  * @param end End sequence of the newest SACK block
934  */
935 void
936 tcp_update_sack_list (tcp_connection_t * tc, u32 start, u32 end)
937 {
938   sack_block_t *new_list = 0, *block = 0;
939   int i;
940
941   /* If the first segment is ooo add it to the list. Last write might've moved
942    * rcv_nxt over the first segment. */
943   if (seq_lt (tc->rcv_nxt, start))
944     {
945       vec_add2 (new_list, block, 1);
946       block->start = start;
947       block->end = end;
948     }
949
950   /* Find the blocks still worth keeping. */
951   for (i = 0; i < vec_len (tc->snd_sacks); i++)
952     {
953       /* Discard if rcv_nxt advanced beyond current block */
954       if (seq_leq (tc->snd_sacks[i].start, tc->rcv_nxt))
955         continue;
956
957       /* Merge or drop if segment overlapped by the new segment */
958       if (block && (seq_geq (tc->snd_sacks[i].end, new_list[0].start)
959                     && seq_leq (tc->snd_sacks[i].start, new_list[0].end)))
960         {
961           if (seq_lt (tc->snd_sacks[i].start, new_list[0].start))
962             new_list[0].start = tc->snd_sacks[i].start;
963           if (seq_lt (new_list[0].end, tc->snd_sacks[i].end))
964             new_list[0].end = tc->snd_sacks[i].end;
965           continue;
966         }
967
968       /* Save to new SACK list if we have space. */
969       if (vec_len (new_list) < TCP_MAX_SACK_BLOCKS)
970         {
971           vec_add1 (new_list, tc->snd_sacks[i]);
972         }
973     }
974
975   ASSERT (vec_len (new_list) <= TCP_MAX_SACK_BLOCKS);
976
977   /* Replace old vector with new one */
978   vec_free (tc->snd_sacks);
979   tc->snd_sacks = new_list;
980 }
981
982 /** Enqueue data for delivery to application */
983 always_inline int
984 tcp_session_enqueue_data (tcp_connection_t * tc, vlib_buffer_t * b,
985                           u16 data_len)
986 {
987   int written;
988
989   /* Pure ACK. Update rcv_nxt and be done. */
990   if (PREDICT_FALSE (data_len == 0))
991     {
992       tc->rcv_nxt = vnet_buffer (b)->tcp.seq_end;
993       return TCP_ERROR_PURE_ACK;
994     }
995
996   written = stream_session_enqueue_data (&tc->connection,
997                                          vlib_buffer_get_current (b),
998                                          data_len, 1 /* queue event */ );
999
1000   TCP_EVT_DBG (TCP_EVT_INPUT, tc, 0, data_len, written);
1001
1002   /* Update rcv_nxt */
1003   if (PREDICT_TRUE (written == data_len))
1004     {
1005       tc->rcv_nxt = vnet_buffer (b)->tcp.seq_end;
1006     }
1007   /* If more data written than expected, account for out-of-order bytes. */
1008   else if (written > data_len)
1009     {
1010       tc->rcv_nxt = vnet_buffer (b)->tcp.seq_end + written - data_len;
1011
1012       /* Send ACK confirming the update */
1013       tc->flags |= TCP_CONN_SNDACK;
1014     }
1015   else if (written > 0)
1016     {
1017       /* We've written something but FIFO is probably full now */
1018       tc->rcv_nxt += written;
1019
1020       /* Depending on how fast the app is, all remaining buffers in burst will
1021        * not be enqueued. Inform peer */
1022       tc->flags |= TCP_CONN_SNDACK;
1023
1024       return TCP_ERROR_PARTIALLY_ENQUEUED;
1025     }
1026   else
1027     {
1028       tc->flags |= TCP_CONN_SNDACK;
1029       return TCP_ERROR_FIFO_FULL;
1030     }
1031
1032   /* Update SACK list if need be */
1033   if (tcp_opts_sack_permitted (&tc->opt))
1034     {
1035       /* Remove SACK blocks that have been delivered */
1036       tcp_update_sack_list (tc, tc->rcv_nxt, tc->rcv_nxt);
1037     }
1038
1039   return TCP_ERROR_ENQUEUED;
1040 }
1041
1042 /** Enqueue out-of-order data */
1043 always_inline int
1044 tcp_session_enqueue_ooo (tcp_connection_t * tc, vlib_buffer_t * b,
1045                          u16 data_len)
1046 {
1047   stream_session_t *s0;
1048   int rv;
1049
1050   /* Pure ACK. Do nothing */
1051   if (PREDICT_FALSE (data_len == 0))
1052     {
1053       return TCP_ERROR_PURE_ACK;
1054     }
1055
1056   s0 = stream_session_get (tc->c_s_index, tc->c_thread_index);
1057
1058   /* Enqueue out-of-order data with absolute offset */
1059   rv = svm_fifo_enqueue_with_offset (s0->server_rx_fifo,
1060                                      vnet_buffer (b)->tcp.seq_number,
1061                                      data_len, vlib_buffer_get_current (b));
1062
1063   /* Nothing written */
1064   if (rv)
1065     {
1066       TCP_EVT_DBG (TCP_EVT_INPUT, tc, 1, data_len, 0);
1067       return TCP_ERROR_FIFO_FULL;
1068     }
1069
1070   TCP_EVT_DBG (TCP_EVT_INPUT, tc, 1, data_len, data_len);
1071
1072   /* Update SACK list if in use */
1073   if (tcp_opts_sack_permitted (&tc->opt))
1074     {
1075       ooo_segment_t *newest;
1076       u32 start, end;
1077
1078       /* Get the newest segment from the fifo */
1079       newest = svm_fifo_newest_ooo_segment (s0->server_rx_fifo);
1080       start = ooo_segment_offset (s0->server_rx_fifo, newest);
1081       end = ooo_segment_end_offset (s0->server_rx_fifo, newest);
1082
1083       tcp_update_sack_list (tc, start, end);
1084     }
1085
1086   return TCP_ERROR_ENQUEUED;
1087 }
1088
1089 /**
1090  * Check if ACK could be delayed. If ack can be delayed, it should return
1091  * true for a full frame. If we're always acking return 0.
1092  */
1093 always_inline int
1094 tcp_can_delack (tcp_connection_t * tc)
1095 {
1096   /* Send ack if ... */
1097   if (TCP_ALWAYS_ACK
1098       /* just sent a rcv wnd 0 */
1099       || (tc->flags & TCP_CONN_SENT_RCV_WND0) != 0
1100       /* constrained to send ack */
1101       || (tc->flags & TCP_CONN_SNDACK) != 0
1102       /* we're almost out of tx wnd */
1103       || tcp_available_snd_space (tc) < 2 * tc->snd_mss)
1104     return 0;
1105
1106   return 1;
1107 }
1108
1109 static int
1110 tcp_segment_rcv (tcp_main_t * tm, tcp_connection_t * tc, vlib_buffer_t * b,
1111                  u16 n_data_bytes, u32 * next0)
1112 {
1113   u32 error = 0;
1114
1115   /* Handle out-of-order data */
1116   if (PREDICT_FALSE (vnet_buffer (b)->tcp.seq_number != tc->rcv_nxt))
1117     {
1118       /* Old sequence numbers allowed through because they overlapped
1119        * the rx window */
1120
1121       if (seq_lt (vnet_buffer (b)->tcp.seq_number, tc->rcv_nxt))
1122         {
1123           error = TCP_ERROR_SEGMENT_OLD;
1124           *next0 = TCP_NEXT_DROP;
1125           goto done;
1126         }
1127
1128       error = tcp_session_enqueue_ooo (tc, b, n_data_bytes);
1129
1130       /* N.B. Should not filter burst of dupacks. Two issues 1) dupacks open
1131        * cwnd on remote peer when congested 2) acks leaving should have the
1132        * latest rcv_wnd since the burst may eaten up all of it, so only the
1133        * old ones could be filtered.
1134        */
1135
1136       /* RFC2581: Send DUPACK for fast retransmit */
1137       tcp_make_ack (tc, b);
1138       *next0 = tcp_next_output (tc->c_is_ip4);
1139
1140       /* Mark as DUPACK. We may filter these in output if
1141        * the burst fills the holes. */
1142       if (n_data_bytes)
1143         vnet_buffer (b)->tcp.flags = TCP_BUF_FLAG_DUPACK;
1144
1145       TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc);
1146       goto done;
1147     }
1148
1149   /* In order data, enqueue. Fifo figures out by itself if any out-of-order
1150    * segments can be enqueued after fifo tail offset changes. */
1151   error = tcp_session_enqueue_data (tc, b, n_data_bytes);
1152
1153   if (n_data_bytes == 0)
1154     {
1155       *next0 = TCP_NEXT_DROP;
1156       goto done;
1157     }
1158
1159   /* Check if ACK can be delayed */
1160   if (tcp_can_delack (tc))
1161     {
1162       if (!tcp_timer_is_active (tc, TCP_TIMER_DELACK))
1163         tcp_timer_set (tc, TCP_TIMER_DELACK, TCP_DELACK_TIME);
1164       goto done;
1165     }
1166
1167   *next0 = tcp_next_output (tc->c_is_ip4);
1168   tcp_make_ack (tc, b);
1169
1170 done:
1171   return error;
1172 }
1173
1174 typedef struct
1175 {
1176   tcp_header_t tcp_header;
1177   tcp_connection_t tcp_connection;
1178 } tcp_rx_trace_t;
1179
1180 u8 *
1181 format_tcp_rx_trace (u8 * s, va_list * args)
1182 {
1183   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1184   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1185   tcp_rx_trace_t *t = va_arg (*args, tcp_rx_trace_t *);
1186   uword indent = format_get_indent (s);
1187
1188   s = format (s, "%U\n%U%U",
1189               format_tcp_header, &t->tcp_header, 128,
1190               format_white_space, indent,
1191               format_tcp_connection_verbose, &t->tcp_connection);
1192
1193   return s;
1194 }
1195
1196 u8 *
1197 format_tcp_rx_trace_short (u8 * s, va_list * args)
1198 {
1199   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1200   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1201   tcp_rx_trace_t *t = va_arg (*args, tcp_rx_trace_t *);
1202
1203   s = format (s, "%d -> %d (%U)",
1204               clib_net_to_host_u16 (t->tcp_header.src_port),
1205               clib_net_to_host_u16 (t->tcp_header.dst_port), format_tcp_state,
1206               &t->tcp_connection.state);
1207
1208   return s;
1209 }
1210
1211 void
1212 tcp_set_rx_trace_data (tcp_rx_trace_t * t0, tcp_connection_t * tc0,
1213                        tcp_header_t * th0, vlib_buffer_t * b0, u8 is_ip4)
1214 {
1215   if (tc0)
1216     {
1217       clib_memcpy (&t0->tcp_connection, tc0, sizeof (t0->tcp_connection));
1218     }
1219   else
1220     {
1221       th0 = tcp_buffer_hdr (b0);
1222     }
1223   clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1224 }
1225
1226 always_inline void
1227 tcp_established_inc_counter (vlib_main_t * vm, u8 is_ip4, u8 evt, u8 val)
1228 {
1229   if (PREDICT_TRUE (!val))
1230     return;
1231
1232   if (is_ip4)
1233     vlib_node_increment_counter (vm, tcp4_established_node.index, evt, val);
1234   else
1235     vlib_node_increment_counter (vm, tcp6_established_node.index, evt, val);
1236 }
1237
1238 always_inline uword
1239 tcp46_established_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1240                           vlib_frame_t * from_frame, int is_ip4)
1241 {
1242   u32 n_left_from, next_index, *from, *to_next;
1243   u32 my_thread_index = vm->thread_index, errors = 0;
1244   tcp_main_t *tm = vnet_get_tcp_main ();
1245   u8 is_fin = 0;
1246
1247   from = vlib_frame_vector_args (from_frame);
1248   n_left_from = from_frame->n_vectors;
1249
1250   next_index = node->cached_next_index;
1251
1252   while (n_left_from > 0)
1253     {
1254       u32 n_left_to_next;
1255
1256       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1257
1258       while (n_left_from > 0 && n_left_to_next > 0)
1259         {
1260           u32 bi0;
1261           vlib_buffer_t *b0;
1262           tcp_header_t *th0 = 0;
1263           tcp_connection_t *tc0;
1264           u32 next0 = TCP_ESTABLISHED_NEXT_DROP, error0 = TCP_ERROR_ENQUEUED;
1265
1266           bi0 = from[0];
1267           to_next[0] = bi0;
1268           from += 1;
1269           to_next += 1;
1270           n_left_from -= 1;
1271           n_left_to_next -= 1;
1272
1273           b0 = vlib_get_buffer (vm, bi0);
1274           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
1275                                     my_thread_index);
1276
1277           if (PREDICT_FALSE (tc0 == 0))
1278             {
1279               error0 = TCP_ERROR_INVALID_CONNECTION;
1280               goto done;
1281             }
1282
1283           th0 = tcp_buffer_hdr (b0);
1284
1285           is_fin = (th0->flags & TCP_FLAG_FIN) != 0;
1286
1287           /* SYNs, FINs and data consume sequence numbers */
1288           vnet_buffer (b0)->tcp.seq_end = vnet_buffer (b0)->tcp.seq_number
1289             + tcp_is_syn (th0) + is_fin + vnet_buffer (b0)->tcp.data_len;
1290
1291           /* TODO header prediction fast path */
1292
1293           /* 1-4: check SEQ, RST, SYN */
1294           if (PREDICT_FALSE (tcp_segment_validate (vm, tc0, b0, th0, &next0)))
1295             {
1296               error0 = TCP_ERROR_SEGMENT_INVALID;
1297               TCP_EVT_DBG (TCP_EVT_SEG_INVALID, tc0,
1298                            vnet_buffer (b0)->tcp.seq_number,
1299                            vnet_buffer (b0)->tcp.seq_end);
1300               goto done;
1301             }
1302
1303           /* 5: check the ACK field  */
1304           if (tcp_rcv_ack (tc0, b0, th0, &next0, &error0))
1305             {
1306               goto done;
1307             }
1308
1309           /* 6: check the URG bit TODO */
1310
1311           /* 7: process the segment text */
1312
1313           vlib_buffer_advance (b0, vnet_buffer (b0)->tcp.data_offset);
1314           error0 = tcp_segment_rcv (tm, tc0, b0,
1315                                     vnet_buffer (b0)->tcp.data_len, &next0);
1316
1317           /* N.B. buffer is rewritten if segment is ooo. Thus, th0 becomes a
1318            * dangling reference. */
1319
1320           /* 8: check the FIN bit */
1321           if (is_fin)
1322             {
1323               /* Enter CLOSE-WAIT and notify session. Don't send ACK, instead
1324                * wait for session to call close. To avoid lingering
1325                * in CLOSE-WAIT, set timer (reuse WAITCLOSE). */
1326               tc0->state = TCP_STATE_CLOSE_WAIT;
1327               TCP_EVT_DBG (TCP_EVT_FIN_RCVD, tc0);
1328               stream_session_disconnect_notify (&tc0->connection);
1329               tcp_timer_set (tc0, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
1330             }
1331
1332         done:
1333           b0->error = node->errors[error0];
1334           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1335             {
1336               tcp_rx_trace_t *t0 =
1337                 vlib_add_trace (vm, node, b0, sizeof (*t0));
1338               tcp_set_rx_trace_data (t0, tc0, th0, b0, is_ip4);
1339             }
1340
1341           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1342                                            n_left_to_next, bi0, next0);
1343         }
1344
1345       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1346     }
1347
1348   errors = session_manager_flush_enqueue_events (my_thread_index);
1349   tcp_established_inc_counter (vm, is_ip4, TCP_ERROR_EVENT_FIFO_FULL, errors);
1350
1351   return from_frame->n_vectors;
1352 }
1353
1354 static uword
1355 tcp4_established (vlib_main_t * vm, vlib_node_runtime_t * node,
1356                   vlib_frame_t * from_frame)
1357 {
1358   return tcp46_established_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1359 }
1360
1361 static uword
1362 tcp6_established (vlib_main_t * vm, vlib_node_runtime_t * node,
1363                   vlib_frame_t * from_frame)
1364 {
1365   return tcp46_established_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1366 }
1367
1368 /* *INDENT-OFF* */
1369 VLIB_REGISTER_NODE (tcp4_established_node) =
1370 {
1371   .function = tcp4_established,
1372   .name = "tcp4-established",
1373   /* Takes a vector of packets. */
1374   .vector_size = sizeof (u32),
1375   .n_errors = TCP_N_ERROR,
1376   .error_strings = tcp_error_strings,
1377   .n_next_nodes = TCP_ESTABLISHED_N_NEXT,
1378   .next_nodes =
1379   {
1380 #define _(s,n) [TCP_ESTABLISHED_NEXT_##s] = n,
1381     foreach_tcp_state_next
1382 #undef _
1383   },
1384   .format_trace = format_tcp_rx_trace_short,
1385 };
1386 /* *INDENT-ON* */
1387
1388 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_established_node, tcp4_established);
1389
1390 /* *INDENT-OFF* */
1391 VLIB_REGISTER_NODE (tcp6_established_node) =
1392 {
1393   .function = tcp6_established,
1394   .name = "tcp6-established",
1395   /* Takes a vector of packets. */
1396   .vector_size = sizeof (u32),
1397   .n_errors = TCP_N_ERROR,
1398   .error_strings = tcp_error_strings,
1399   .n_next_nodes = TCP_ESTABLISHED_N_NEXT,
1400   .next_nodes =
1401   {
1402 #define _(s,n) [TCP_ESTABLISHED_NEXT_##s] = n,
1403     foreach_tcp_state_next
1404 #undef _
1405   },
1406   .format_trace = format_tcp_rx_trace_short,
1407 };
1408 /* *INDENT-ON* */
1409
1410
1411 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_established_node, tcp6_established);
1412
1413 vlib_node_registration_t tcp4_syn_sent_node;
1414 vlib_node_registration_t tcp6_syn_sent_node;
1415
1416 always_inline uword
1417 tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1418                        vlib_frame_t * from_frame, int is_ip4)
1419 {
1420   tcp_main_t *tm = vnet_get_tcp_main ();
1421   u32 n_left_from, next_index, *from, *to_next;
1422   u32 my_thread_index = vm->thread_index, errors = 0;
1423   u8 sst = is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP;
1424
1425   from = vlib_frame_vector_args (from_frame);
1426   n_left_from = from_frame->n_vectors;
1427
1428   next_index = node->cached_next_index;
1429
1430   while (n_left_from > 0)
1431     {
1432       u32 n_left_to_next;
1433
1434       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1435
1436       while (n_left_from > 0 && n_left_to_next > 0)
1437         {
1438           u32 bi0, ack0, seq0;
1439           vlib_buffer_t *b0;
1440           tcp_rx_trace_t *t0;
1441           tcp_header_t *tcp0 = 0;
1442           tcp_connection_t *tc0;
1443           tcp_connection_t *new_tc0;
1444           u32 next0 = TCP_SYN_SENT_NEXT_DROP, error0 = TCP_ERROR_ENQUEUED;
1445
1446           bi0 = from[0];
1447           to_next[0] = bi0;
1448           from += 1;
1449           to_next += 1;
1450           n_left_from -= 1;
1451           n_left_to_next -= 1;
1452
1453           b0 = vlib_get_buffer (vm, bi0);
1454           tc0 =
1455             tcp_half_open_connection_get (vnet_buffer (b0)->
1456                                           tcp.connection_index);
1457
1458           ack0 = vnet_buffer (b0)->tcp.ack_number;
1459           seq0 = vnet_buffer (b0)->tcp.seq_number;
1460           tcp0 = tcp_buffer_hdr (b0);
1461
1462           if (PREDICT_FALSE
1463               (!tcp_ack (tcp0) && !tcp_rst (tcp0) && !tcp_syn (tcp0)))
1464             goto drop;
1465
1466           /* SYNs, FINs and data consume sequence numbers */
1467           vnet_buffer (b0)->tcp.seq_end = seq0 + tcp_is_syn (tcp0)
1468             + tcp_is_fin (tcp0) + vnet_buffer (b0)->tcp.data_len;
1469
1470           /*
1471            *  1. check the ACK bit
1472            */
1473
1474           /*
1475            *   If the ACK bit is set
1476            *     If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send a reset (unless
1477            *     the RST bit is set, if so drop the segment and return)
1478            *       <SEQ=SEG.ACK><CTL=RST>
1479            *     and discard the segment.  Return.
1480            *     If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable.
1481            */
1482           if (tcp_ack (tcp0))
1483             {
1484               if (ack0 <= tc0->iss || ack0 > tc0->snd_nxt)
1485                 {
1486                   if (!tcp_rst (tcp0))
1487                     tcp_send_reset (b0, is_ip4);
1488
1489                   goto drop;
1490                 }
1491
1492               /* Make sure ACK is valid */
1493               if (tc0->snd_una > ack0)
1494                 goto drop;
1495             }
1496
1497           /*
1498            * 2. check the RST bit
1499            */
1500
1501           if (tcp_rst (tcp0))
1502             {
1503               /* If ACK is acceptable, signal client that peer is not
1504                * willing to accept connection and drop connection*/
1505               if (tcp_ack (tcp0))
1506                 {
1507                   stream_session_connect_notify (&tc0->connection, sst,
1508                                                  1 /* fail */ );
1509                   tcp_connection_cleanup (tc0);
1510                 }
1511               goto drop;
1512             }
1513
1514           /*
1515            * 3. check the security and precedence (skipped)
1516            */
1517
1518           /*
1519            * 4. check the SYN bit
1520            */
1521
1522           /* No SYN flag. Drop. */
1523           if (!tcp_syn (tcp0))
1524             goto drop;
1525
1526           /* Stop connection establishment and retransmit timers */
1527           tcp_timer_reset (tc0, TCP_TIMER_ESTABLISH);
1528           tcp_timer_reset (tc0, TCP_TIMER_RETRANSMIT_SYN);
1529
1530           /* Valid SYN or SYN-ACK. Move connection from half-open pool to
1531            * current thread pool. */
1532           pool_get (tm->connections[my_thread_index], new_tc0);
1533           clib_memcpy (new_tc0, tc0, sizeof (*new_tc0));
1534
1535           new_tc0->c_thread_index = my_thread_index;
1536
1537           /* Cleanup half-open connection XXX lock */
1538           pool_put (tm->half_open_connections, tc0);
1539
1540           new_tc0->rcv_nxt = vnet_buffer (b0)->tcp.seq_end;
1541           new_tc0->irs = seq0;
1542
1543           /* Parse options */
1544           tcp_options_parse (tcp0, &new_tc0->opt);
1545
1546           if (tcp_opts_tstamp (&new_tc0->opt))
1547             {
1548               new_tc0->tsval_recent = new_tc0->opt.tsval;
1549               new_tc0->tsval_recent_age = tcp_time_now ();
1550             }
1551
1552           if (tcp_opts_wscale (&new_tc0->opt))
1553             new_tc0->snd_wscale = new_tc0->opt.wscale;
1554
1555           /* No scaling */
1556           new_tc0->snd_wnd = clib_net_to_host_u16 (tcp0->window);
1557           new_tc0->snd_wl1 = seq0;
1558           new_tc0->snd_wl2 = ack0;
1559
1560           tcp_connection_init_vars (new_tc0);
1561
1562           /* SYN-ACK: See if we can switch to ESTABLISHED state */
1563           if (tcp_ack (tcp0))
1564             {
1565               /* Our SYN is ACKed: we have iss < ack = snd_una */
1566
1567               /* TODO Dequeue acknowledged segments if we support Fast Open */
1568               new_tc0->snd_una = ack0;
1569               new_tc0->state = TCP_STATE_ESTABLISHED;
1570
1571               /* Make sure las is initialized for the wnd computation */
1572               new_tc0->rcv_las = new_tc0->rcv_nxt;
1573
1574               /* Notify app that we have connection */
1575               stream_session_connect_notify (&new_tc0->connection, sst, 0);
1576
1577               stream_session_init_fifos_pointers (&new_tc0->connection,
1578                                                   new_tc0->irs + 1,
1579                                                   new_tc0->iss + 1);
1580               /* Make sure after data segment processing ACK is sent */
1581               new_tc0->flags |= TCP_CONN_SNDACK;
1582             }
1583           /* SYN: Simultaneous open. Change state to SYN-RCVD and send SYN-ACK */
1584           else
1585             {
1586               new_tc0->state = TCP_STATE_SYN_RCVD;
1587
1588               /* Notify app that we have connection */
1589               stream_session_connect_notify (&new_tc0->connection, sst, 0);
1590               stream_session_init_fifos_pointers (&new_tc0->connection,
1591                                                   new_tc0->irs + 1,
1592                                                   new_tc0->iss + 1);
1593               tcp_make_synack (new_tc0, b0);
1594               next0 = tcp_next_output (is_ip4);
1595
1596               goto drop;
1597             }
1598
1599           /* Read data, if any */
1600           if (vnet_buffer (b0)->tcp.data_len)
1601             {
1602               vlib_buffer_advance (b0, vnet_buffer (b0)->tcp.data_offset);
1603               error0 = tcp_segment_rcv (tm, new_tc0, b0,
1604                                         vnet_buffer (b0)->tcp.data_len,
1605                                         &next0);
1606               if (error0 == TCP_ERROR_PURE_ACK)
1607                 error0 = TCP_ERROR_SYN_ACKS_RCVD;
1608             }
1609           else
1610             {
1611               tcp_make_ack (new_tc0, b0);
1612               next0 = tcp_next_output (new_tc0->c_is_ip4);
1613             }
1614
1615         drop:
1616
1617           b0->error = error0 ? node->errors[error0] : 0;
1618           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1619             {
1620               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1621               clib_memcpy (&t0->tcp_header, tcp0, sizeof (t0->tcp_header));
1622               clib_memcpy (&t0->tcp_connection, tc0,
1623                            sizeof (t0->tcp_connection));
1624             }
1625
1626           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1627                                            n_left_to_next, bi0, next0);
1628         }
1629
1630       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1631     }
1632
1633   errors = session_manager_flush_enqueue_events (my_thread_index);
1634   if (errors)
1635     {
1636       if (is_ip4)
1637         vlib_node_increment_counter (vm, tcp4_established_node.index,
1638                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
1639       else
1640         vlib_node_increment_counter (vm, tcp6_established_node.index,
1641                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
1642     }
1643
1644   return from_frame->n_vectors;
1645 }
1646
1647 static uword
1648 tcp4_syn_sent (vlib_main_t * vm, vlib_node_runtime_t * node,
1649                vlib_frame_t * from_frame)
1650 {
1651   return tcp46_syn_sent_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1652 }
1653
1654 static uword
1655 tcp6_syn_sent_rcv (vlib_main_t * vm, vlib_node_runtime_t * node,
1656                    vlib_frame_t * from_frame)
1657 {
1658   return tcp46_syn_sent_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1659 }
1660
1661 /* *INDENT-OFF* */
1662 VLIB_REGISTER_NODE (tcp4_syn_sent_node) =
1663 {
1664   .function = tcp4_syn_sent,
1665   .name = "tcp4-syn-sent",
1666   /* Takes a vector of packets. */
1667   .vector_size = sizeof (u32),
1668   .n_errors = TCP_N_ERROR,
1669   .error_strings = tcp_error_strings,
1670   .n_next_nodes = TCP_SYN_SENT_N_NEXT,
1671   .next_nodes =
1672   {
1673 #define _(s,n) [TCP_SYN_SENT_NEXT_##s] = n,
1674     foreach_tcp_state_next
1675 #undef _
1676   },
1677   .format_trace = format_tcp_rx_trace_short,
1678 };
1679 /* *INDENT-ON* */
1680
1681 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_syn_sent_node, tcp4_syn_sent);
1682
1683 /* *INDENT-OFF* */
1684 VLIB_REGISTER_NODE (tcp6_syn_sent_node) =
1685 {
1686   .function = tcp6_syn_sent_rcv,
1687   .name = "tcp6-syn-sent",
1688   /* Takes a vector of packets. */
1689   .vector_size = sizeof (u32),
1690   .n_errors = TCP_N_ERROR,
1691   .error_strings = tcp_error_strings,
1692   .n_next_nodes = TCP_SYN_SENT_N_NEXT,
1693   .next_nodes =
1694   {
1695 #define _(s,n) [TCP_SYN_SENT_NEXT_##s] = n,
1696     foreach_tcp_state_next
1697 #undef _
1698   },
1699   .format_trace = format_tcp_rx_trace_short,
1700 };
1701 /* *INDENT-ON* */
1702
1703 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_syn_sent_node, tcp6_syn_sent_rcv);
1704 /**
1705  * Handles reception for all states except LISTEN, SYN-SENT and ESTABLISHED
1706  * as per RFC793 p. 64
1707  */
1708 always_inline uword
1709 tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1710                           vlib_frame_t * from_frame, int is_ip4)
1711 {
1712   tcp_main_t *tm = vnet_get_tcp_main ();
1713   u32 n_left_from, next_index, *from, *to_next;
1714   u32 my_thread_index = vm->thread_index, errors = 0;
1715
1716   from = vlib_frame_vector_args (from_frame);
1717   n_left_from = from_frame->n_vectors;
1718
1719   next_index = node->cached_next_index;
1720
1721   while (n_left_from > 0)
1722     {
1723       u32 n_left_to_next;
1724
1725       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1726
1727       while (n_left_from > 0 && n_left_to_next > 0)
1728         {
1729           u32 bi0;
1730           vlib_buffer_t *b0;
1731           tcp_header_t *tcp0 = 0;
1732           tcp_connection_t *tc0;
1733           u32 next0 = TCP_RCV_PROCESS_NEXT_DROP, error0 = TCP_ERROR_ENQUEUED;
1734
1735           bi0 = from[0];
1736           to_next[0] = bi0;
1737           from += 1;
1738           to_next += 1;
1739           n_left_from -= 1;
1740           n_left_to_next -= 1;
1741
1742           b0 = vlib_get_buffer (vm, bi0);
1743           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
1744                                     my_thread_index);
1745           if (PREDICT_FALSE (tc0 == 0))
1746             {
1747               error0 = TCP_ERROR_INVALID_CONNECTION;
1748               goto drop;
1749             }
1750
1751           tcp0 = tcp_buffer_hdr (b0);
1752
1753           /* SYNs, FINs and data consume sequence numbers */
1754           vnet_buffer (b0)->tcp.seq_end = vnet_buffer (b0)->tcp.seq_number
1755             + tcp_is_syn (tcp0) + tcp_is_fin (tcp0)
1756             + vnet_buffer (b0)->tcp.data_len;
1757
1758           /*
1759            * Special treatment for CLOSED
1760            */
1761           switch (tc0->state)
1762             {
1763             case TCP_STATE_CLOSED:
1764               goto drop;
1765               break;
1766             }
1767
1768           /*
1769            * For all other states (except LISTEN)
1770            */
1771
1772           /* 1-4: check SEQ, RST, SYN */
1773           if (PREDICT_FALSE
1774               (tcp_segment_validate (vm, tc0, b0, tcp0, &next0)))
1775             {
1776               error0 = TCP_ERROR_SEGMENT_INVALID;
1777               goto drop;
1778             }
1779
1780           /* 5: check the ACK field  */
1781           switch (tc0->state)
1782             {
1783             case TCP_STATE_SYN_RCVD:
1784               /*
1785                * If the segment acknowledgment is not acceptable, form a
1786                * reset segment,
1787                *  <SEQ=SEG.ACK><CTL=RST>
1788                * and send it.
1789                */
1790               if (!tcp_rcv_ack_is_acceptable (tc0, b0))
1791                 {
1792                   tcp_send_reset (b0, is_ip4);
1793                   goto drop;
1794                 }
1795
1796               /* Update rtt and rto */
1797               tc0->bytes_acked = 1;
1798               tcp_update_rtt (tc0, vnet_buffer (b0)->tcp.ack_number);
1799
1800               /* Switch state to ESTABLISHED */
1801               tc0->state = TCP_STATE_ESTABLISHED;
1802
1803               /* Initialize session variables */
1804               tc0->snd_una = vnet_buffer (b0)->tcp.ack_number;
1805               tc0->snd_wnd = clib_net_to_host_u16 (tcp0->window)
1806                 << tc0->opt.wscale;
1807               tc0->snd_wl1 = vnet_buffer (b0)->tcp.seq_number;
1808               tc0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
1809
1810               /* Shoulder tap the server */
1811               stream_session_accept_notify (&tc0->connection);
1812
1813               /* Reset SYN-ACK retransmit timer */
1814               tcp_retransmit_timer_reset (tc0);
1815               break;
1816             case TCP_STATE_ESTABLISHED:
1817               /* We can get packets in established state here because they
1818                * were enqueued before state change */
1819               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
1820                 goto drop;
1821
1822               break;
1823             case TCP_STATE_FIN_WAIT_1:
1824               /* In addition to the processing for the ESTABLISHED state, if
1825                * our FIN is now acknowledged then enter FIN-WAIT-2 and
1826                * continue processing in that state. */
1827               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
1828                 goto drop;
1829
1830               /* If FIN is ACKed */
1831               if (tc0->snd_una == tc0->snd_una_max)
1832                 {
1833                   tc0->state = TCP_STATE_FIN_WAIT_2;
1834                   /* Stop all timers, 2MSL will be set lower */
1835                   tcp_connection_timers_reset (tc0);
1836                 }
1837               break;
1838             case TCP_STATE_FIN_WAIT_2:
1839               /* In addition to the processing for the ESTABLISHED state, if
1840                * the retransmission queue is empty, the user's CLOSE can be
1841                * acknowledged ("ok") but do not delete the TCB. */
1842               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
1843                 goto drop;
1844               /* check if rtx queue is empty and ack CLOSE TODO */
1845               break;
1846             case TCP_STATE_CLOSE_WAIT:
1847               /* Do the same processing as for the ESTABLISHED state. */
1848               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
1849                 goto drop;
1850               break;
1851             case TCP_STATE_CLOSING:
1852               /* In addition to the processing for the ESTABLISHED state, if
1853                * the ACK acknowledges our FIN then enter the TIME-WAIT state,
1854                * otherwise ignore the segment. */
1855               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
1856                 goto drop;
1857
1858               /* XXX test that send queue empty */
1859               tc0->state = TCP_STATE_TIME_WAIT;
1860               goto drop;
1861
1862               break;
1863             case TCP_STATE_LAST_ACK:
1864               /* The only thing that can arrive in this state is an
1865                * acknowledgment of our FIN. If our FIN is now acknowledged,
1866                * delete the TCB, enter the CLOSED state, and return. */
1867
1868               if (!tcp_rcv_ack_is_acceptable (tc0, b0))
1869                 goto drop;
1870
1871               tc0->state = TCP_STATE_CLOSED;
1872
1873               /* Don't delete the connection/session yet. Instead, wait a
1874                * reasonable amount of time until the pipes are cleared. In
1875                * particular, this makes sure that we won't have dead sessions
1876                * when processing events on the tx path */
1877               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_CLEANUP_TIME);
1878
1879               /* Stop retransmit */
1880               tcp_retransmit_timer_reset (tc0);
1881
1882               goto drop;
1883
1884               break;
1885             case TCP_STATE_TIME_WAIT:
1886               /* The only thing that can arrive in this state is a
1887                * retransmission of the remote FIN. Acknowledge it, and restart
1888                * the 2 MSL timeout. */
1889
1890               /* TODO */
1891               goto drop;
1892               break;
1893             default:
1894               ASSERT (0);
1895             }
1896
1897           /* 6: check the URG bit TODO */
1898
1899           /* 7: process the segment text */
1900           switch (tc0->state)
1901             {
1902             case TCP_STATE_ESTABLISHED:
1903             case TCP_STATE_FIN_WAIT_1:
1904             case TCP_STATE_FIN_WAIT_2:
1905               vlib_buffer_advance (b0, vnet_buffer (b0)->tcp.data_offset);
1906               error0 = tcp_segment_rcv (tm, tc0, b0,
1907                                         vnet_buffer (b0)->tcp.data_len,
1908                                         &next0);
1909               break;
1910             case TCP_STATE_CLOSE_WAIT:
1911             case TCP_STATE_CLOSING:
1912             case TCP_STATE_LAST_ACK:
1913             case TCP_STATE_TIME_WAIT:
1914               /* This should not occur, since a FIN has been received from the
1915                * remote side.  Ignore the segment text. */
1916               break;
1917             }
1918
1919           /* 8: check the FIN bit */
1920           if (!tcp_fin (tcp0))
1921             goto drop;
1922
1923           switch (tc0->state)
1924             {
1925             case TCP_STATE_ESTABLISHED:
1926             case TCP_STATE_SYN_RCVD:
1927               /* Send FIN-ACK notify app and enter CLOSE-WAIT */
1928               tcp_connection_timers_reset (tc0);
1929               tcp_make_fin (tc0, b0);
1930               next0 = tcp_next_output (tc0->c_is_ip4);
1931               stream_session_disconnect_notify (&tc0->connection);
1932               tc0->state = TCP_STATE_CLOSE_WAIT;
1933               break;
1934             case TCP_STATE_CLOSE_WAIT:
1935             case TCP_STATE_CLOSING:
1936             case TCP_STATE_LAST_ACK:
1937               /* move along .. */
1938               break;
1939             case TCP_STATE_FIN_WAIT_1:
1940               tc0->state = TCP_STATE_TIME_WAIT;
1941               tcp_connection_timers_reset (tc0);
1942               tcp_timer_set (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
1943               break;
1944             case TCP_STATE_FIN_WAIT_2:
1945               /* Got FIN, send ACK! */
1946               tc0->state = TCP_STATE_TIME_WAIT;
1947               tcp_timer_set (tc0, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
1948               tcp_make_ack (tc0, b0);
1949               next0 = tcp_next_output (is_ip4);
1950               break;
1951             case TCP_STATE_TIME_WAIT:
1952               /* Remain in the TIME-WAIT state. Restart the 2 MSL time-wait
1953                * timeout.
1954                */
1955               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
1956               break;
1957             }
1958           TCP_EVT_DBG (TCP_EVT_FIN_RCVD, tc0);
1959
1960         drop:
1961           b0->error = error0 ? node->errors[error0] : 0;
1962
1963           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1964             {
1965               tcp_rx_trace_t *t0 =
1966                 vlib_add_trace (vm, node, b0, sizeof (*t0));
1967               tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4);
1968             }
1969
1970           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1971                                            n_left_to_next, bi0, next0);
1972         }
1973
1974       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1975     }
1976
1977   errors = session_manager_flush_enqueue_events (my_thread_index);
1978   if (errors)
1979     {
1980       if (is_ip4)
1981         vlib_node_increment_counter (vm, tcp4_established_node.index,
1982                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
1983       else
1984         vlib_node_increment_counter (vm, tcp6_established_node.index,
1985                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
1986     }
1987
1988   return from_frame->n_vectors;
1989 }
1990
1991 static uword
1992 tcp4_rcv_process (vlib_main_t * vm, vlib_node_runtime_t * node,
1993                   vlib_frame_t * from_frame)
1994 {
1995   return tcp46_rcv_process_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1996 }
1997
1998 static uword
1999 tcp6_rcv_process (vlib_main_t * vm, vlib_node_runtime_t * node,
2000                   vlib_frame_t * from_frame)
2001 {
2002   return tcp46_rcv_process_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2003 }
2004
2005 /* *INDENT-OFF* */
2006 VLIB_REGISTER_NODE (tcp4_rcv_process_node) =
2007 {
2008   .function = tcp4_rcv_process,
2009   .name = "tcp4-rcv-process",
2010   /* Takes a vector of packets. */
2011   .vector_size = sizeof (u32),
2012   .n_errors = TCP_N_ERROR,
2013   .error_strings = tcp_error_strings,
2014   .n_next_nodes = TCP_RCV_PROCESS_N_NEXT,
2015   .next_nodes =
2016   {
2017 #define _(s,n) [TCP_RCV_PROCESS_NEXT_##s] = n,
2018     foreach_tcp_state_next
2019 #undef _
2020   },
2021   .format_trace = format_tcp_rx_trace_short,
2022 };
2023 /* *INDENT-ON* */
2024
2025 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_rcv_process_node, tcp4_rcv_process);
2026
2027 /* *INDENT-OFF* */
2028 VLIB_REGISTER_NODE (tcp6_rcv_process_node) =
2029 {
2030   .function = tcp6_rcv_process,
2031   .name = "tcp6-rcv-process",
2032   /* Takes a vector of packets. */
2033   .vector_size = sizeof (u32),
2034   .n_errors = TCP_N_ERROR,
2035   .error_strings = tcp_error_strings,
2036   .n_next_nodes = TCP_RCV_PROCESS_N_NEXT,
2037   .next_nodes =
2038   {
2039 #define _(s,n) [TCP_RCV_PROCESS_NEXT_##s] = n,
2040     foreach_tcp_state_next
2041 #undef _
2042   },
2043   .format_trace = format_tcp_rx_trace_short,
2044 };
2045 /* *INDENT-ON* */
2046
2047 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_rcv_process_node, tcp6_rcv_process);
2048
2049 vlib_node_registration_t tcp4_listen_node;
2050 vlib_node_registration_t tcp6_listen_node;
2051
2052 /**
2053  * LISTEN state processing as per RFC 793 p. 65
2054  */
2055 always_inline uword
2056 tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2057                      vlib_frame_t * from_frame, int is_ip4)
2058 {
2059   u32 n_left_from, next_index, *from, *to_next;
2060   u32 my_thread_index = vm->thread_index;
2061   tcp_main_t *tm = vnet_get_tcp_main ();
2062   u8 sst = is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP;
2063
2064   from = vlib_frame_vector_args (from_frame);
2065   n_left_from = from_frame->n_vectors;
2066
2067   next_index = node->cached_next_index;
2068
2069   while (n_left_from > 0)
2070     {
2071       u32 n_left_to_next;
2072
2073       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2074
2075       while (n_left_from > 0 && n_left_to_next > 0)
2076         {
2077           u32 bi0;
2078           vlib_buffer_t *b0;
2079           tcp_rx_trace_t *t0;
2080           tcp_header_t *th0 = 0;
2081           tcp_connection_t *lc0;
2082           ip4_header_t *ip40;
2083           ip6_header_t *ip60;
2084           tcp_connection_t *child0;
2085           u32 error0 = TCP_ERROR_SYNS_RCVD, next0 = TCP_LISTEN_NEXT_DROP;
2086
2087           bi0 = from[0];
2088           to_next[0] = bi0;
2089           from += 1;
2090           to_next += 1;
2091           n_left_from -= 1;
2092           n_left_to_next -= 1;
2093
2094           b0 = vlib_get_buffer (vm, bi0);
2095           lc0 = tcp_listener_get (vnet_buffer (b0)->tcp.connection_index);
2096
2097           if (is_ip4)
2098             {
2099               ip40 = vlib_buffer_get_current (b0);
2100               th0 = ip4_next_header (ip40);
2101             }
2102           else
2103             {
2104               ip60 = vlib_buffer_get_current (b0);
2105               th0 = ip6_next_header (ip60);
2106             }
2107
2108           /* Create child session. For syn-flood protection use filter */
2109
2110           /* 1. first check for an RST */
2111           if (tcp_rst (th0))
2112             goto drop;
2113
2114           /* 2. second check for an ACK */
2115           if (tcp_ack (th0))
2116             {
2117               tcp_send_reset (b0, is_ip4);
2118               goto drop;
2119             }
2120
2121           /* 3. check for a SYN (did that already) */
2122
2123           /* Create child session and send SYN-ACK */
2124           pool_get (tm->connections[my_thread_index], child0);
2125           memset (child0, 0, sizeof (*child0));
2126
2127           child0->c_c_index = child0 - tm->connections[my_thread_index];
2128           child0->c_lcl_port = lc0->c_lcl_port;
2129           child0->c_rmt_port = th0->src_port;
2130           child0->c_is_ip4 = is_ip4;
2131           child0->c_thread_index = my_thread_index;
2132
2133           if (is_ip4)
2134             {
2135               child0->c_lcl_ip4.as_u32 = ip40->dst_address.as_u32;
2136               child0->c_rmt_ip4.as_u32 = ip40->src_address.as_u32;
2137             }
2138           else
2139             {
2140               clib_memcpy (&child0->c_lcl_ip6, &ip60->dst_address,
2141                            sizeof (ip6_address_t));
2142               clib_memcpy (&child0->c_rmt_ip6, &ip60->src_address,
2143                            sizeof (ip6_address_t));
2144             }
2145
2146           if (stream_session_accept (&child0->connection, lc0->c_s_index, sst,
2147                                      0 /* notify */ ))
2148             {
2149               error0 = TCP_ERROR_CREATE_SESSION_FAIL;
2150               goto drop;
2151             }
2152
2153           tcp_options_parse (th0, &child0->opt);
2154
2155           child0->irs = vnet_buffer (b0)->tcp.seq_number;
2156           child0->rcv_nxt = vnet_buffer (b0)->tcp.seq_number + 1;
2157           child0->rcv_las = child0->rcv_nxt;
2158           child0->state = TCP_STATE_SYN_RCVD;
2159
2160           /* RFC1323: TSval timestamps sent on {SYN} and {SYN,ACK}
2161            * segments are used to initialize PAWS. */
2162           if (tcp_opts_tstamp (&child0->opt))
2163             {
2164               child0->tsval_recent = child0->opt.tsval;
2165               child0->tsval_recent_age = tcp_time_now ();
2166             }
2167
2168           if (tcp_opts_wscale (&child0->opt))
2169             child0->snd_wscale = child0->opt.wscale;
2170
2171           /* No scaling */
2172           child0->snd_wnd = clib_net_to_host_u16 (th0->window);
2173           child0->snd_wl1 = vnet_buffer (b0)->tcp.seq_number;
2174           child0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
2175
2176           tcp_connection_init_vars (child0);
2177
2178           TCP_EVT_DBG (TCP_EVT_SYN_RCVD, child0);
2179
2180           /* Reuse buffer to make syn-ack and send */
2181           tcp_make_synack (child0, b0);
2182           next0 = tcp_next_output (is_ip4);
2183
2184           /* Init fifo pointers after we have iss */
2185           stream_session_init_fifos_pointers (&child0->connection,
2186                                               child0->irs + 1,
2187                                               child0->iss + 1);
2188         drop:
2189           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2190             {
2191               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
2192               clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
2193               clib_memcpy (&t0->tcp_connection, lc0,
2194                            sizeof (t0->tcp_connection));
2195             }
2196
2197           b0->error = node->errors[error0];
2198
2199           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2200                                            n_left_to_next, bi0, next0);
2201         }
2202
2203       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2204     }
2205   return from_frame->n_vectors;
2206 }
2207
2208 static uword
2209 tcp4_listen (vlib_main_t * vm, vlib_node_runtime_t * node,
2210              vlib_frame_t * from_frame)
2211 {
2212   return tcp46_listen_inline (vm, node, from_frame, 1 /* is_ip4 */ );
2213 }
2214
2215 static uword
2216 tcp6_listen (vlib_main_t * vm, vlib_node_runtime_t * node,
2217              vlib_frame_t * from_frame)
2218 {
2219   return tcp46_listen_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2220 }
2221
2222 /* *INDENT-OFF* */
2223 VLIB_REGISTER_NODE (tcp4_listen_node) =
2224 {
2225   .function = tcp4_listen,
2226   .name = "tcp4-listen",
2227   /* Takes a vector of packets. */
2228   .vector_size = sizeof (u32),
2229   .n_errors = TCP_N_ERROR,
2230   .error_strings = tcp_error_strings,
2231   .n_next_nodes = TCP_LISTEN_N_NEXT,
2232   .next_nodes =
2233   {
2234 #define _(s,n) [TCP_LISTEN_NEXT_##s] = n,
2235     foreach_tcp_state_next
2236 #undef _
2237   },
2238   .format_trace = format_tcp_rx_trace_short,
2239 };
2240 /* *INDENT-ON* */
2241
2242 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_listen_node, tcp4_listen);
2243
2244 /* *INDENT-OFF* */
2245 VLIB_REGISTER_NODE (tcp6_listen_node) =
2246 {
2247   .function = tcp6_listen,
2248   .name = "tcp6-listen",
2249   /* Takes a vector of packets. */
2250   .vector_size = sizeof (u32),
2251   .n_errors = TCP_N_ERROR,
2252   .error_strings = tcp_error_strings,
2253   .n_next_nodes = TCP_LISTEN_N_NEXT,
2254   .next_nodes =
2255   {
2256 #define _(s,n) [TCP_LISTEN_NEXT_##s] = n,
2257     foreach_tcp_state_next
2258 #undef _
2259   },
2260   .format_trace = format_tcp_rx_trace_short,
2261 };
2262 /* *INDENT-ON* */
2263
2264 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_listen_node, tcp6_listen);
2265
2266 vlib_node_registration_t tcp4_input_node;
2267 vlib_node_registration_t tcp6_input_node;
2268
2269 typedef enum _tcp_input_next
2270 {
2271   TCP_INPUT_NEXT_DROP,
2272   TCP_INPUT_NEXT_LISTEN,
2273   TCP_INPUT_NEXT_RCV_PROCESS,
2274   TCP_INPUT_NEXT_SYN_SENT,
2275   TCP_INPUT_NEXT_ESTABLISHED,
2276   TCP_INPUT_NEXT_RESET,
2277   TCP_INPUT_N_NEXT
2278 } tcp_input_next_t;
2279
2280 #define foreach_tcp4_input_next                 \
2281   _ (DROP, "error-drop")                        \
2282   _ (LISTEN, "tcp4-listen")                     \
2283   _ (RCV_PROCESS, "tcp4-rcv-process")           \
2284   _ (SYN_SENT, "tcp4-syn-sent")                 \
2285   _ (ESTABLISHED, "tcp4-established")           \
2286   _ (RESET, "tcp4-reset")
2287
2288 #define foreach_tcp6_input_next                 \
2289   _ (DROP, "error-drop")                        \
2290   _ (LISTEN, "tcp6-listen")                     \
2291   _ (RCV_PROCESS, "tcp6-rcv-process")           \
2292   _ (SYN_SENT, "tcp6-syn-sent")                 \
2293   _ (ESTABLISHED, "tcp6-established")           \
2294   _ (RESET, "tcp6-reset")
2295
2296 #define filter_flags (TCP_FLAG_SYN|TCP_FLAG_ACK|TCP_FLAG_RST|TCP_FLAG_FIN)
2297
2298 always_inline uword
2299 tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2300                     vlib_frame_t * from_frame, int is_ip4)
2301 {
2302   u32 n_left_from, next_index, *from, *to_next;
2303   u32 my_thread_index = vm->thread_index;
2304   tcp_main_t *tm = vnet_get_tcp_main ();
2305
2306   from = vlib_frame_vector_args (from_frame);
2307   n_left_from = from_frame->n_vectors;
2308
2309   next_index = node->cached_next_index;
2310
2311   while (n_left_from > 0)
2312     {
2313       u32 n_left_to_next;
2314
2315       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2316
2317       while (n_left_from > 0 && n_left_to_next > 0)
2318         {
2319           int n_advance_bytes0, n_data_bytes0;
2320           u32 bi0;
2321           vlib_buffer_t *b0;
2322           tcp_header_t *tcp0 = 0;
2323           tcp_connection_t *tc0;
2324           ip4_header_t *ip40;
2325           ip6_header_t *ip60;
2326           u32 error0 = TCP_ERROR_NO_LISTENER, next0 = TCP_INPUT_NEXT_DROP;
2327           u8 flags0;
2328
2329           bi0 = from[0];
2330           to_next[0] = bi0;
2331           from += 1;
2332           to_next += 1;
2333           n_left_from -= 1;
2334           n_left_to_next -= 1;
2335
2336           b0 = vlib_get_buffer (vm, bi0);
2337           vnet_buffer (b0)->tcp.flags = 0;
2338
2339           /* Checksum computed by ipx_local no need to compute again */
2340
2341           if (is_ip4)
2342             {
2343               ip40 = vlib_buffer_get_current (b0);
2344               tcp0 = ip4_next_header (ip40);
2345               n_advance_bytes0 = (ip4_header_bytes (ip40)
2346                                   + tcp_header_bytes (tcp0));
2347               n_data_bytes0 = clib_net_to_host_u16 (ip40->length)
2348                 - n_advance_bytes0;
2349
2350               /* lookup session */
2351               tc0 =
2352                 (tcp_connection_t *)
2353                 stream_session_lookup_transport4 (&ip40->dst_address,
2354                                                   &ip40->src_address,
2355                                                   tcp0->dst_port,
2356                                                   tcp0->src_port,
2357                                                   SESSION_TYPE_IP4_TCP,
2358                                                   my_thread_index);
2359             }
2360           else
2361             {
2362               ip60 = vlib_buffer_get_current (b0);
2363               tcp0 = ip6_next_header (ip60);
2364               n_advance_bytes0 = tcp_header_bytes (tcp0);
2365               n_data_bytes0 = clib_net_to_host_u16 (ip60->payload_length)
2366                 - n_advance_bytes0;
2367               n_advance_bytes0 += sizeof (ip60[0]);
2368
2369               tc0 =
2370                 (tcp_connection_t *)
2371                 stream_session_lookup_transport6 (&ip60->src_address,
2372                                                   &ip60->dst_address,
2373                                                   tcp0->src_port,
2374                                                   tcp0->dst_port,
2375                                                   SESSION_TYPE_IP6_TCP,
2376                                                   my_thread_index);
2377             }
2378
2379           /* Length check */
2380           if (PREDICT_FALSE (n_advance_bytes0 < 0))
2381             {
2382               error0 = TCP_ERROR_LENGTH;
2383               goto done;
2384             }
2385
2386           /* Session exists */
2387           if (PREDICT_TRUE (0 != tc0))
2388             {
2389               /* Save connection index */
2390               vnet_buffer (b0)->tcp.connection_index = tc0->c_c_index;
2391               vnet_buffer (b0)->tcp.seq_number =
2392                 clib_net_to_host_u32 (tcp0->seq_number);
2393               vnet_buffer (b0)->tcp.ack_number =
2394                 clib_net_to_host_u32 (tcp0->ack_number);
2395
2396               vnet_buffer (b0)->tcp.hdr_offset = (u8 *) tcp0
2397                 - (u8 *) vlib_buffer_get_current (b0);
2398               vnet_buffer (b0)->tcp.data_offset = n_advance_bytes0;
2399               vnet_buffer (b0)->tcp.data_len = n_data_bytes0;
2400
2401               flags0 = tcp0->flags & filter_flags;
2402               next0 = tm->dispatch_table[tc0->state][flags0].next;
2403               error0 = tm->dispatch_table[tc0->state][flags0].error;
2404
2405               if (PREDICT_FALSE (error0 == TCP_ERROR_DISPATCH))
2406                 {
2407                   tcp_state_t state0 = tc0->state;
2408                   /* Overload tcp flags to store state */
2409                   vnet_buffer (b0)->tcp.flags = tc0->state;
2410                   clib_warning ("disp error state %U flags %U",
2411                                 format_tcp_state, &state0,
2412                                 format_tcp_flags, (int) flags0);
2413                 }
2414             }
2415           else
2416             {
2417               /* Send reset */
2418               next0 = TCP_INPUT_NEXT_RESET;
2419               error0 = TCP_ERROR_NO_LISTENER;
2420             }
2421
2422         done:
2423           b0->error = error0 ? node->errors[error0] : 0;
2424
2425           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2426             {
2427               tcp_rx_trace_t *t0 =
2428                 vlib_add_trace (vm, node, b0, sizeof (*t0));
2429               tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4);
2430             }
2431
2432           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2433                                            n_left_to_next, bi0, next0);
2434         }
2435
2436       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2437     }
2438
2439   return from_frame->n_vectors;
2440 }
2441
2442 static uword
2443 tcp4_input (vlib_main_t * vm, vlib_node_runtime_t * node,
2444             vlib_frame_t * from_frame)
2445 {
2446   return tcp46_input_inline (vm, node, from_frame, 1 /* is_ip4 */ );
2447 }
2448
2449 static uword
2450 tcp6_input (vlib_main_t * vm, vlib_node_runtime_t * node,
2451             vlib_frame_t * from_frame)
2452 {
2453   return tcp46_input_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2454 }
2455
2456 /* *INDENT-OFF* */
2457 VLIB_REGISTER_NODE (tcp4_input_node) =
2458 {
2459   .function = tcp4_input,
2460   .name = "tcp4-input",
2461   /* Takes a vector of packets. */
2462   .vector_size = sizeof (u32),
2463   .n_errors = TCP_N_ERROR,
2464   .error_strings = tcp_error_strings,
2465   .n_next_nodes = TCP_INPUT_N_NEXT,
2466   .next_nodes =
2467   {
2468 #define _(s,n) [TCP_INPUT_NEXT_##s] = n,
2469     foreach_tcp4_input_next
2470 #undef _
2471   },
2472   .format_buffer = format_tcp_header,
2473   .format_trace = format_tcp_rx_trace,
2474 };
2475 /* *INDENT-ON* */
2476
2477 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_input_node, tcp4_input);
2478
2479 /* *INDENT-OFF* */
2480 VLIB_REGISTER_NODE (tcp6_input_node) =
2481 {
2482   .function = tcp6_input,
2483   .name = "tcp6-input",
2484   /* Takes a vector of packets. */
2485   .vector_size = sizeof (u32),
2486   .n_errors = TCP_N_ERROR,
2487   .error_strings = tcp_error_strings,
2488   .n_next_nodes = TCP_INPUT_N_NEXT,
2489   .next_nodes =
2490   {
2491 #define _(s,n) [TCP_INPUT_NEXT_##s] = n,
2492     foreach_tcp6_input_next
2493 #undef _
2494   },
2495   .format_buffer = format_tcp_header,
2496   .format_trace = format_tcp_rx_trace,
2497 };
2498 /* *INDENT-ON* */
2499
2500 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_input_node, tcp6_input);
2501
2502 static void
2503 tcp_dispatch_table_init (tcp_main_t * tm)
2504 {
2505   int i, j;
2506   for (i = 0; i < ARRAY_LEN (tm->dispatch_table); i++)
2507     for (j = 0; j < ARRAY_LEN (tm->dispatch_table[i]); j++)
2508       {
2509         tm->dispatch_table[i][j].next = TCP_INPUT_NEXT_DROP;
2510         tm->dispatch_table[i][j].error = TCP_ERROR_DISPATCH;
2511       }
2512
2513 #define _(t,f,n,e)                                              \
2514 do {                                                            \
2515     tm->dispatch_table[TCP_STATE_##t][f].next = (n);            \
2516     tm->dispatch_table[TCP_STATE_##t][f].error = (e);           \
2517 } while (0)
2518
2519   /* SYNs for new connections -> tcp-listen. */
2520   _(LISTEN, TCP_FLAG_SYN, TCP_INPUT_NEXT_LISTEN, TCP_ERROR_NONE);
2521   /* ACK for for a SYN-ACK -> tcp-rcv-process. */
2522   _(SYN_RCVD, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
2523   _(SYN_RCVD, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
2524   /* SYN-ACK for a SYN */
2525   _(SYN_SENT, TCP_FLAG_SYN | TCP_FLAG_ACK, TCP_INPUT_NEXT_SYN_SENT,
2526     TCP_ERROR_NONE);
2527   _(SYN_SENT, TCP_FLAG_ACK, TCP_INPUT_NEXT_SYN_SENT, TCP_ERROR_NONE);
2528   _(SYN_SENT, TCP_FLAG_RST, TCP_INPUT_NEXT_SYN_SENT, TCP_ERROR_NONE);
2529   _(SYN_SENT, TCP_FLAG_RST | TCP_FLAG_ACK, TCP_INPUT_NEXT_SYN_SENT,
2530     TCP_ERROR_NONE);
2531   /* ACK for for established connection -> tcp-established. */
2532   _(ESTABLISHED, TCP_FLAG_ACK, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
2533   /* FIN for for established connection -> tcp-established. */
2534   _(ESTABLISHED, TCP_FLAG_FIN, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
2535   _(ESTABLISHED, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_ESTABLISHED,
2536     TCP_ERROR_NONE);
2537   _(ESTABLISHED, TCP_FLAG_RST, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
2538   /* ACK or FIN-ACK to our FIN */
2539   _(FIN_WAIT_1, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
2540   _(FIN_WAIT_1, TCP_FLAG_ACK | TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS,
2541     TCP_ERROR_NONE);
2542   /* FIN in reply to our FIN from the other side */
2543   _(FIN_WAIT_1, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
2544   /* FIN confirming that the peer (app) has closed */
2545   _(FIN_WAIT_2, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
2546   _(FIN_WAIT_2, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS,
2547     TCP_ERROR_NONE);
2548   _(LAST_ACK, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
2549   _(CLOSED, TCP_FLAG_ACK, TCP_INPUT_NEXT_DROP, TCP_ERROR_CONNECTION_CLOSED);
2550 #undef _
2551 }
2552
2553 clib_error_t *
2554 tcp_input_init (vlib_main_t * vm)
2555 {
2556   clib_error_t *error = 0;
2557   tcp_main_t *tm = vnet_get_tcp_main ();
2558
2559   if ((error = vlib_call_init_function (vm, tcp_init)))
2560     return error;
2561
2562   /* Initialize dispatch table. */
2563   tcp_dispatch_table_init (tm);
2564
2565   return error;
2566 }
2567
2568 VLIB_INIT_FUNCTION (tcp_input_init);
2569
2570 /*
2571  * fd.io coding-style-patch-verification: ON
2572  *
2573  * Local Variables:
2574  * eval: (c-set-style "gnu")
2575  * End:
2576  */