841e72a503e3e14cb9de76a9ffc003c9a5697171
[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 /**
116  * Parse TCP header options.
117  *
118  * @param th TCP header
119  * @param to TCP options data structure to be populated
120  * @return -1 if parsing failed
121  */
122 int
123 tcp_options_parse (tcp_header_t * th, tcp_options_t * to)
124 {
125   const u8 *data;
126   u8 opt_len, opts_len, kind;
127   int j;
128   sack_block_t b;
129
130   opts_len = (tcp_doff (th) << 2) - sizeof (tcp_header_t);
131   data = (const u8 *) (th + 1);
132
133   /* Zero out all flags but those set in SYN */
134   to->flags &= (TCP_OPTS_FLAG_SACK_PERMITTED | TCP_OPTS_FLAG_WSCALE);
135
136   for (; opts_len > 0; opts_len -= opt_len, data += opt_len)
137     {
138       kind = data[0];
139
140       /* Get options length */
141       if (kind == TCP_OPTION_EOL)
142         break;
143       else if (kind == TCP_OPTION_NOOP)
144         {
145           opt_len = 1;
146           continue;
147         }
148       else
149         {
150           /* broken options */
151           if (opts_len < 2)
152             return -1;
153           opt_len = data[1];
154
155           /* weird option length */
156           if (opt_len < 2 || opt_len > opts_len)
157             return -1;
158         }
159
160       /* Parse options */
161       switch (kind)
162         {
163         case TCP_OPTION_MSS:
164           if ((opt_len == TCP_OPTION_LEN_MSS) && tcp_syn (th))
165             {
166               to->flags |= TCP_OPTS_FLAG_MSS;
167               to->mss = clib_net_to_host_u16 (*(u16 *) (data + 2));
168             }
169           break;
170         case TCP_OPTION_WINDOW_SCALE:
171           if ((opt_len == TCP_OPTION_LEN_WINDOW_SCALE) && tcp_syn (th))
172             {
173               to->flags |= TCP_OPTS_FLAG_WSCALE;
174               to->wscale = data[2];
175               if (to->wscale > TCP_MAX_WND_SCALE)
176                 {
177                   clib_warning ("Illegal window scaling value: %d",
178                                 to->wscale);
179                   to->wscale = TCP_MAX_WND_SCALE;
180                 }
181             }
182           break;
183         case TCP_OPTION_TIMESTAMP:
184           if (opt_len == TCP_OPTION_LEN_TIMESTAMP)
185             {
186               to->flags |= TCP_OPTS_FLAG_TSTAMP;
187               to->tsval = clib_net_to_host_u32 (*(u32 *) (data + 2));
188               to->tsecr = clib_net_to_host_u32 (*(u32 *) (data + 6));
189             }
190           break;
191         case TCP_OPTION_SACK_PERMITTED:
192           if (opt_len == TCP_OPTION_LEN_SACK_PERMITTED && tcp_syn (th))
193             to->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
194           break;
195         case TCP_OPTION_SACK_BLOCK:
196           /* If SACK permitted was not advertised or a SYN, break */
197           if ((to->flags & TCP_OPTS_FLAG_SACK_PERMITTED) == 0 || tcp_syn (th))
198             break;
199
200           /* If too short or not correctly formatted, break */
201           if (opt_len < 10 || ((opt_len - 2) % TCP_OPTION_LEN_SACK_BLOCK))
202             break;
203
204           to->flags |= TCP_OPTS_FLAG_SACK;
205           to->n_sack_blocks = (opt_len - 2) / TCP_OPTION_LEN_SACK_BLOCK;
206           vec_reset_length (to->sacks);
207           for (j = 0; j < to->n_sack_blocks; j++)
208             {
209               b.start = clib_net_to_host_u32 (*(u32 *) (data + 2 + 8 * j));
210               b.end = clib_net_to_host_u32 (*(u32 *) (data + 6 + 8 * j));
211               vec_add1 (to->sacks, b);
212             }
213           break;
214         default:
215           /* Nothing to see here */
216           continue;
217         }
218     }
219   return 0;
220 }
221
222 /**
223  * RFC1323: Check against wrapped sequence numbers (PAWS). If we have
224  * timestamp to echo and it's less than tsval_recent, drop segment
225  * but still send an ACK in order to retain TCP's mechanism for detecting
226  * and recovering from half-open connections
227  *
228  * Or at least that's what the theory says. It seems that this might not work
229  * very well with packet reordering and fast retransmit. XXX
230  */
231 always_inline int
232 tcp_segment_check_paws (tcp_connection_t * tc)
233 {
234   return tcp_opts_tstamp (&tc->rcv_opts) && tc->tsval_recent
235     && timestamp_lt (tc->rcv_opts.tsval, tc->tsval_recent);
236 }
237
238 /**
239  * Update tsval recent
240  */
241 always_inline void
242 tcp_update_timestamp (tcp_connection_t * tc, u32 seq, u32 seq_end)
243 {
244   /*
245    * RFC1323: If Last.ACK.sent falls within the range of sequence numbers
246    * of an incoming segment:
247    *    SEG.SEQ <= Last.ACK.sent < SEG.SEQ + SEG.LEN
248    * then the TSval from the segment is copied to TS.Recent;
249    * otherwise, the TSval is ignored.
250    */
251   if (tcp_opts_tstamp (&tc->rcv_opts) && tc->tsval_recent
252       && seq_leq (seq, tc->rcv_las) && seq_leq (tc->rcv_las, seq_end))
253     {
254       ASSERT (timestamp_leq (tc->tsval_recent, tc->rcv_opts.tsval));
255       tc->tsval_recent = tc->rcv_opts.tsval;
256       tc->tsval_recent_age = tcp_time_now ();
257     }
258 }
259
260 /**
261  * Validate incoming segment as per RFC793 p. 69 and RFC1323 p. 19
262  *
263  * It first verifies if segment has a wrapped sequence number (PAWS) and then
264  * does the processing associated to the first four steps (ignoring security
265  * and precedence): sequence number, rst bit and syn bit checks.
266  *
267  * @return 0 if segments passes validation.
268  */
269 static int
270 tcp_segment_validate (vlib_main_t * vm, tcp_connection_t * tc0,
271                       vlib_buffer_t * b0, tcp_header_t * th0, u32 * next0)
272 {
273   if (PREDICT_FALSE (!tcp_ack (th0) && !tcp_rst (th0) && !tcp_syn (th0)))
274     return -1;
275
276   if (PREDICT_FALSE (tcp_options_parse (th0, &tc0->rcv_opts)))
277     {
278       clib_warning ("options parse error");
279       return -1;
280     }
281
282   if (tcp_segment_check_paws (tc0))
283     {
284       if (CLIB_DEBUG > 2)
285         {
286           clib_warning ("paws failed\n%U", format_tcp_connection, tc0, 2);
287           clib_warning ("seq %u seq_end %u ack %u",
288                         vnet_buffer (b0)->tcp.seq_number - tc0->irs,
289                         vnet_buffer (b0)->tcp.seq_end - tc0->irs,
290                         vnet_buffer (b0)->tcp.ack_number - tc0->iss);
291         }
292       TCP_EVT_DBG (TCP_EVT_PAWS_FAIL, tc0, vnet_buffer (b0)->tcp.seq_number,
293                    vnet_buffer (b0)->tcp.seq_end);
294
295       /* If it just so happens that a segment updates tsval_recent for a
296        * segment over 24 days old, invalidate tsval_recent. */
297       if (timestamp_lt (tc0->tsval_recent_age + TCP_PAWS_IDLE,
298                         tcp_time_now ()))
299         {
300           /* Age isn't reset until we get a valid tsval (bsd inspired) */
301           tc0->tsval_recent = 0;
302           clib_warning ("paws failed - really old segment. REALLY?");
303         }
304       else
305         {
306           /* Drop after ack if not rst */
307           if (!tcp_rst (th0))
308             {
309               tcp_make_ack (tc0, b0);
310               *next0 = tcp_next_output (tc0->c_is_ip4);
311               TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc0);
312               return -1;
313             }
314         }
315     }
316
317   /* 1st: check sequence number */
318   if (!tcp_segment_in_rcv_wnd (tc0, vnet_buffer (b0)->tcp.seq_number,
319                                vnet_buffer (b0)->tcp.seq_end))
320     {
321       /* If our window is 0 and the packet is in sequence, let it pass
322        * through for ack processing. It should be dropped later.*/
323       if (tc0->rcv_wnd == 0
324           && tc0->rcv_nxt == vnet_buffer (b0)->tcp.seq_number)
325         {
326           /* TODO Should segment be tagged?  */
327         }
328       else
329         {
330           /* If not RST, send dup ack */
331           if (!tcp_rst (th0))
332             {
333               tcp_make_ack (tc0, b0);
334               *next0 = tcp_next_output (tc0->c_is_ip4);
335               TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc0);
336             }
337           return -1;
338         }
339     }
340
341   /* 2nd: check the RST bit */
342   if (tcp_rst (th0))
343     {
344       tcp_connection_reset (tc0);
345       return -1;
346     }
347
348   /* 3rd: check security and precedence (skip) */
349
350   /* 4th: check the SYN bit */
351   if (tcp_syn (th0))
352     {
353       /* TODO implement RFC 5961 */
354       if (tc0->state != TCP_STATE_SYN_RCVD)
355         tcp_make_ack (tc0, b0);
356       else
357         tcp_make_synack (tc0, b0);
358       *next0 = tcp_next_output (tc0->c_is_ip4);
359       TCP_EVT_DBG (TCP_EVT_SYN_RCVD, tc0, 0);
360       return -1;
361     }
362
363   /* If segment in window, save timestamp */
364   tcp_update_timestamp (tc0, vnet_buffer (b0)->tcp.seq_number,
365                         vnet_buffer (b0)->tcp.seq_end);
366   return 0;
367 }
368
369 always_inline int
370 tcp_rcv_ack_is_acceptable (tcp_connection_t * tc0, vlib_buffer_t * tb0)
371 {
372   /* SND.UNA =< SEG.ACK =< SND.NXT */
373   return (seq_leq (tc0->snd_una, vnet_buffer (tb0)->tcp.ack_number)
374           && seq_leq (vnet_buffer (tb0)->tcp.ack_number, tc0->snd_nxt));
375 }
376
377 /**
378  * Compute smoothed RTT as per VJ's '88 SIGCOMM and RFC6298
379  *
380  * Note that although the original article, srtt and rttvar are scaled
381  * to minimize round-off errors, here we don't. Instead, we rely on
382  * better precision time measurements.
383  *
384  * TODO support us rtt resolution
385  */
386 static void
387 tcp_estimate_rtt (tcp_connection_t * tc, u32 mrtt)
388 {
389   int err, diff;
390
391   if (tc->srtt != 0)
392     {
393       err = mrtt - tc->srtt;
394
395       /* XXX Drop in RTT results in RTTVAR increase and bigger RTO.
396        * The increase should be bound */
397       tc->srtt = clib_max ((int) tc->srtt + (err >> 3), 1);
398       diff = (clib_abs (err) - (int) tc->rttvar) >> 2;
399       tc->rttvar = clib_max ((int) tc->rttvar + diff, 1);
400     }
401   else
402     {
403       /* First measurement. */
404       tc->srtt = mrtt;
405       tc->rttvar = mrtt >> 1;
406     }
407 }
408
409 void
410 tcp_update_rto (tcp_connection_t * tc)
411 {
412   tc->rto = clib_min (tc->srtt + (tc->rttvar << 2), TCP_RTO_MAX);
413   tc->rto = clib_max (tc->rto, TCP_RTO_MIN);
414 }
415
416 /** Update RTT estimate and RTO timer
417  *
418  * Measure RTT: We have two sources of RTT measurements: TSOPT and ACK
419  * timing. Middle boxes are known to fiddle with TCP options so we
420  * should give higher priority to ACK timing.
421  *
422  * return 1 if valid rtt 0 otherwise
423  */
424 static int
425 tcp_update_rtt (tcp_connection_t * tc, u32 ack)
426 {
427   u32 mrtt = 0;
428   u8 rtx_acked;
429
430   /* Determine if only rtx bytes are acked. */
431   rtx_acked = tcp_in_cong_recovery (tc) || !tc->bytes_acked;
432
433   /* Karn's rule, part 1. Don't use retransmitted segments to estimate
434    * RTT because they're ambiguous. */
435   if (tc->rtt_ts && seq_geq (ack, tc->rtt_seq) && !rtx_acked)
436     {
437       mrtt = tcp_time_now () - tc->rtt_ts;
438     }
439   /* As per RFC7323 TSecr can be used for RTTM only if the segment advances
440    * snd_una, i.e., the left side of the send window:
441    * seq_lt (tc->snd_una, ack). */
442   else if (tcp_opts_tstamp (&tc->rcv_opts) && tc->rcv_opts.tsecr
443            && tc->bytes_acked)
444     {
445       mrtt = tcp_time_now () - tc->rcv_opts.tsecr;
446     }
447
448   /* Allow measuring of a new RTT */
449   tc->rtt_ts = 0;
450
451   /* If ACK moves left side of the wnd make sure boff is 0, even if mrtt is
452    * not valid */
453   if (tc->bytes_acked)
454     tc->rto_boff = 0;
455
456   /* Ignore dubious measurements */
457   if (mrtt == 0 || mrtt > TCP_RTT_MAX)
458     return 0;
459
460   tcp_estimate_rtt (tc, mrtt);
461   tcp_update_rto (tc);
462
463   return 0;
464 }
465
466 /**
467  * Dequeue bytes that have been acked and while at it update RTT estimates.
468  */
469 static void
470 tcp_dequeue_acked (tcp_connection_t * tc, u32 ack)
471 {
472   /* Dequeue the newly ACKed add SACKed bytes */
473   stream_session_dequeue_drop (&tc->connection,
474                                tc->bytes_acked + tc->sack_sb.snd_una_adv);
475
476   tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
477
478   /* Update rtt and rto */
479   tcp_update_rtt (tc, ack);
480
481   /* If everything has been acked, stop retransmit timer
482    * otherwise update. */
483   tcp_retransmit_timer_update (tc);
484 }
485
486 /**
487  * Check if duplicate ack as per RFC5681 Sec. 2
488  */
489 static u8
490 tcp_ack_is_dupack (tcp_connection_t * tc, vlib_buffer_t * b, u32 prev_snd_wnd,
491                    u32 prev_snd_una)
492 {
493   return ((vnet_buffer (b)->tcp.ack_number == prev_snd_una)
494           && seq_gt (tc->snd_una_max, tc->snd_una)
495           && (vnet_buffer (b)->tcp.seq_end == vnet_buffer (b)->tcp.seq_number)
496           && (prev_snd_wnd == tc->snd_wnd));
497 }
498
499 /**
500  * Checks if ack is a congestion control event.
501  */
502 static u8
503 tcp_ack_is_cc_event (tcp_connection_t * tc, vlib_buffer_t * b,
504                      u32 prev_snd_wnd, u32 prev_snd_una, u8 * is_dack)
505 {
506   /* Check if ack is duplicate. Per RFC 6675, ACKs that SACK new data are
507    * defined to be 'duplicate' */
508   *is_dack = tc->sack_sb.last_sacked_bytes
509     || tcp_ack_is_dupack (tc, b, prev_snd_wnd, prev_snd_una);
510
511   return ((*is_dack || tcp_in_cong_recovery (tc)) && !tcp_is_lost_fin (tc));
512 }
513
514 void
515 scoreboard_remove_hole (sack_scoreboard_t * sb, sack_scoreboard_hole_t * hole)
516 {
517   sack_scoreboard_hole_t *next, *prev;
518
519   if (hole->next != TCP_INVALID_SACK_HOLE_INDEX)
520     {
521       next = pool_elt_at_index (sb->holes, hole->next);
522       next->prev = hole->prev;
523     }
524   else
525     {
526       sb->tail = hole->prev;
527     }
528
529   if (hole->prev != TCP_INVALID_SACK_HOLE_INDEX)
530     {
531       prev = pool_elt_at_index (sb->holes, hole->prev);
532       prev->next = hole->next;
533     }
534   else
535     {
536       sb->head = hole->next;
537     }
538
539   if (scoreboard_hole_index (sb, hole) == sb->cur_rxt_hole)
540     sb->cur_rxt_hole = TCP_INVALID_SACK_HOLE_INDEX;
541
542   /* Poison the entry */
543   if (CLIB_DEBUG > 0)
544     memset (hole, 0xfe, sizeof (*hole));
545
546   pool_put (sb->holes, hole);
547 }
548
549 sack_scoreboard_hole_t *
550 scoreboard_insert_hole (sack_scoreboard_t * sb, u32 prev_index,
551                         u32 start, u32 end)
552 {
553   sack_scoreboard_hole_t *hole, *next, *prev;
554   u32 hole_index;
555
556   pool_get (sb->holes, hole);
557   memset (hole, 0, sizeof (*hole));
558
559   hole->start = start;
560   hole->end = end;
561   hole_index = scoreboard_hole_index (sb, hole);
562
563   prev = scoreboard_get_hole (sb, prev_index);
564   if (prev)
565     {
566       hole->prev = prev_index;
567       hole->next = prev->next;
568
569       if ((next = scoreboard_next_hole (sb, hole)))
570         next->prev = hole_index;
571       else
572         sb->tail = hole_index;
573
574       prev->next = hole_index;
575     }
576   else
577     {
578       sb->head = hole_index;
579       hole->prev = TCP_INVALID_SACK_HOLE_INDEX;
580       hole->next = TCP_INVALID_SACK_HOLE_INDEX;
581     }
582
583   return hole;
584 }
585
586 void
587 scoreboard_update_bytes (tcp_connection_t * tc, sack_scoreboard_t * sb)
588 {
589   sack_scoreboard_hole_t *hole, *prev;
590   u32 bytes = 0, blks = 0;
591
592   sb->lost_bytes = 0;
593   sb->sacked_bytes = 0;
594   hole = scoreboard_last_hole (sb);
595   if (!hole)
596     return;
597
598   if (seq_gt (sb->high_sacked, hole->end))
599     {
600       bytes = sb->high_sacked - hole->end;
601       blks = 1;
602     }
603
604   while ((prev = scoreboard_prev_hole (sb, hole))
605          && (bytes < (TCP_DUPACK_THRESHOLD - 1) * tc->snd_mss
606              && blks < TCP_DUPACK_THRESHOLD))
607     {
608       bytes += hole->start - prev->end;
609       blks++;
610       hole = prev;
611     }
612
613   while (hole)
614     {
615       sb->lost_bytes += scoreboard_hole_bytes (hole);
616       hole->is_lost = 1;
617       prev = hole;
618       hole = scoreboard_prev_hole (sb, hole);
619       if (hole)
620         bytes += prev->start - hole->end;
621     }
622   sb->sacked_bytes = bytes;
623 }
624
625 /**
626  * Figure out the next hole to retransmit
627  *
628  * Follows logic proposed in RFC6675 Sec. 4, NextSeg()
629  */
630 sack_scoreboard_hole_t *
631 scoreboard_next_rxt_hole (sack_scoreboard_t * sb,
632                           sack_scoreboard_hole_t * start,
633                           u8 have_sent_1_smss,
634                           u8 * can_rescue, u8 * snd_limited)
635 {
636   sack_scoreboard_hole_t *hole = 0;
637
638   hole = start ? start : scoreboard_first_hole (sb);
639   while (hole && seq_leq (hole->end, sb->high_rxt) && hole->is_lost)
640     hole = scoreboard_next_hole (sb, hole);
641
642   /* Nothing, return */
643   if (!hole)
644     {
645       sb->cur_rxt_hole = TCP_INVALID_SACK_HOLE_INDEX;
646       return 0;
647     }
648
649   /* Rule (1): if higher than rxt, less than high_sacked and lost */
650   if (hole->is_lost && seq_lt (hole->start, sb->high_sacked))
651     {
652       sb->cur_rxt_hole = scoreboard_hole_index (sb, hole);
653     }
654   else
655     {
656       /* Rule (2): output takes care of transmitting new data */
657       if (!have_sent_1_smss)
658         {
659           hole = 0;
660           sb->cur_rxt_hole = TCP_INVALID_SACK_HOLE_INDEX;
661         }
662       /* Rule (3): if hole not lost */
663       else if (seq_lt (hole->start, sb->high_sacked))
664         {
665           *snd_limited = 1;
666           sb->cur_rxt_hole = scoreboard_hole_index (sb, hole);
667         }
668       /* Rule (4): if hole beyond high_sacked */
669       else
670         {
671           ASSERT (seq_geq (hole->start, sb->high_sacked));
672           *snd_limited = 1;
673           *can_rescue = 1;
674           /* HighRxt MUST NOT be updated */
675           return 0;
676         }
677     }
678
679   if (hole && seq_lt (sb->high_rxt, hole->start))
680     sb->high_rxt = hole->start;
681
682   return hole;
683 }
684
685 void
686 scoreboard_init_high_rxt (sack_scoreboard_t * sb, u32 seq)
687 {
688   sack_scoreboard_hole_t *hole;
689   hole = scoreboard_first_hole (sb);
690   if (hole)
691     {
692       seq = seq_gt (seq, hole->start) ? seq : hole->start;
693       sb->cur_rxt_hole = sb->head;
694     }
695   sb->high_rxt = seq;
696 }
697
698 /**
699  * Test that scoreboard is sane after recovery
700  *
701  * Returns 1 if scoreboard is empty or if first hole beyond
702  * snd_una.
703  */
704 u8
705 tcp_scoreboard_is_sane_post_recovery (tcp_connection_t * tc)
706 {
707   sack_scoreboard_hole_t *hole;
708   hole = scoreboard_first_hole (&tc->sack_sb);
709   return (!hole || seq_geq (hole->start, tc->snd_una));
710 }
711
712 void
713 tcp_rcv_sacks (tcp_connection_t * tc, u32 ack)
714 {
715   sack_scoreboard_t *sb = &tc->sack_sb;
716   sack_block_t *blk, tmp;
717   sack_scoreboard_hole_t *hole, *next_hole, *last_hole;
718   u32 blk_index = 0, old_sacked_bytes, hole_index;
719   int i, j;
720
721   sb->last_sacked_bytes = 0;
722   sb->snd_una_adv = 0;
723   old_sacked_bytes = sb->sacked_bytes;
724   sb->last_bytes_delivered = 0;
725
726   if (!tcp_opts_sack (&tc->rcv_opts)
727       && sb->head == TCP_INVALID_SACK_HOLE_INDEX)
728     return;
729
730   /* Remove invalid blocks */
731   blk = tc->rcv_opts.sacks;
732   while (blk < vec_end (tc->rcv_opts.sacks))
733     {
734       if (seq_lt (blk->start, blk->end)
735           && seq_gt (blk->start, tc->snd_una)
736           && seq_gt (blk->start, ack) && seq_leq (blk->end, tc->snd_una_max))
737         {
738           blk++;
739           continue;
740         }
741       vec_del1 (tc->rcv_opts.sacks, blk - tc->rcv_opts.sacks);
742     }
743
744   /* Add block for cumulative ack */
745   if (seq_gt (ack, tc->snd_una))
746     {
747       tmp.start = tc->snd_una;
748       tmp.end = ack;
749       vec_add1 (tc->rcv_opts.sacks, tmp);
750     }
751
752   if (vec_len (tc->rcv_opts.sacks) == 0)
753     return;
754
755   tcp_scoreboard_trace_add (tc, ack);
756
757   /* Make sure blocks are ordered */
758   for (i = 0; i < vec_len (tc->rcv_opts.sacks); i++)
759     for (j = i + 1; j < vec_len (tc->rcv_opts.sacks); j++)
760       if (seq_lt (tc->rcv_opts.sacks[j].start, tc->rcv_opts.sacks[i].start))
761         {
762           tmp = tc->rcv_opts.sacks[i];
763           tc->rcv_opts.sacks[i] = tc->rcv_opts.sacks[j];
764           tc->rcv_opts.sacks[j] = tmp;
765         }
766
767   if (sb->head == TCP_INVALID_SACK_HOLE_INDEX)
768     {
769       /* If no holes, insert the first that covers all outstanding bytes */
770       last_hole = scoreboard_insert_hole (sb, TCP_INVALID_SACK_HOLE_INDEX,
771                                           tc->snd_una, tc->snd_una_max);
772       sb->tail = scoreboard_hole_index (sb, last_hole);
773       tmp = tc->rcv_opts.sacks[vec_len (tc->rcv_opts.sacks) - 1];
774       sb->high_sacked = tmp.end;
775     }
776   else
777     {
778       /* If we have holes but snd_una_max is beyond the last hole, update
779        * last hole end */
780       tmp = tc->rcv_opts.sacks[vec_len (tc->rcv_opts.sacks) - 1];
781       last_hole = scoreboard_last_hole (sb);
782       if (seq_gt (tc->snd_una_max, last_hole->end))
783         {
784           if (seq_geq (last_hole->start, sb->high_sacked))
785             {
786               last_hole->end = tc->snd_una_max;
787             }
788           /* New hole after high sacked block */
789           else if (seq_lt (sb->high_sacked, tc->snd_una_max))
790             {
791               scoreboard_insert_hole (sb, sb->tail, sb->high_sacked,
792                                       tc->snd_una_max);
793             }
794         }
795       /* Keep track of max byte sacked for when the last hole
796        * is acked */
797       if (seq_gt (tmp.end, sb->high_sacked))
798         sb->high_sacked = tmp.end;
799     }
800
801   /* Walk the holes with the SACK blocks */
802   hole = pool_elt_at_index (sb->holes, sb->head);
803   while (hole && blk_index < vec_len (tc->rcv_opts.sacks))
804     {
805       blk = &tc->rcv_opts.sacks[blk_index];
806       if (seq_leq (blk->start, hole->start))
807         {
808           /* Block covers hole. Remove hole */
809           if (seq_geq (blk->end, hole->end))
810             {
811               next_hole = scoreboard_next_hole (sb, hole);
812
813               /* Byte accounting: snd_una needs to be advanced */
814               if (blk->end == ack)
815                 {
816                   if (next_hole)
817                     {
818                       if (seq_lt (ack, next_hole->start))
819                         sb->snd_una_adv = next_hole->start - ack;
820                       sb->last_bytes_delivered +=
821                         next_hole->start - hole->end;
822                     }
823                   else
824                     {
825                       ASSERT (seq_geq (sb->high_sacked, ack));
826                       sb->snd_una_adv = sb->high_sacked - ack;
827                       sb->last_bytes_delivered += sb->high_sacked - hole->end;
828                     }
829                 }
830
831               scoreboard_remove_hole (sb, hole);
832               hole = next_hole;
833             }
834           /* Partial 'head' overlap */
835           else
836             {
837               if (seq_gt (blk->end, hole->start))
838                 {
839                   hole->start = blk->end;
840                 }
841               blk_index++;
842             }
843         }
844       else
845         {
846           /* Hole must be split */
847           if (seq_lt (blk->end, hole->end))
848             {
849               hole_index = scoreboard_hole_index (sb, hole);
850               next_hole = scoreboard_insert_hole (sb, hole_index, blk->end,
851                                                   hole->end);
852
853               /* Pool might've moved */
854               hole = scoreboard_get_hole (sb, hole_index);
855               hole->end = blk->start;
856               blk_index++;
857               ASSERT (hole->next == scoreboard_hole_index (sb, next_hole));
858             }
859           else if (seq_lt (blk->start, hole->end))
860             {
861               hole->end = blk->start;
862             }
863           hole = scoreboard_next_hole (sb, hole);
864         }
865     }
866
867   scoreboard_update_bytes (tc, sb);
868   sb->last_sacked_bytes = sb->sacked_bytes
869     - (old_sacked_bytes - sb->last_bytes_delivered);
870   ASSERT (sb->last_sacked_bytes <= sb->sacked_bytes);
871   ASSERT (sb->sacked_bytes == 0
872           || sb->sacked_bytes < tc->snd_una_max - seq_max (tc->snd_una, ack));
873   ASSERT (sb->last_sacked_bytes + sb->lost_bytes <= tc->snd_una_max
874           - seq_max (tc->snd_una, ack));
875   ASSERT (sb->head == TCP_INVALID_SACK_HOLE_INDEX || tcp_in_recovery (tc)
876           || sb->holes[sb->head].start == ack + sb->snd_una_adv);
877 }
878
879 /**
880  * Try to update snd_wnd based on feedback received from peer.
881  *
882  * If successful, and new window is 'effectively' 0, activate persist
883  * timer.
884  */
885 static void
886 tcp_update_snd_wnd (tcp_connection_t * tc, u32 seq, u32 ack, u32 snd_wnd)
887 {
888   /* If (SND.WL1 < SEG.SEQ or (SND.WL1 = SEG.SEQ and SND.WL2 =< SEG.ACK)), set
889    * SND.WND <- SEG.WND, set SND.WL1 <- SEG.SEQ, and set SND.WL2 <- SEG.ACK */
890   if (seq_lt (tc->snd_wl1, seq)
891       || (tc->snd_wl1 == seq && seq_leq (tc->snd_wl2, ack)))
892     {
893       tc->snd_wnd = snd_wnd;
894       tc->snd_wl1 = seq;
895       tc->snd_wl2 = ack;
896       TCP_EVT_DBG (TCP_EVT_SND_WND, tc);
897
898       if (tc->snd_wnd < tc->snd_mss)
899         {
900           /* Set persist timer if not set and we just got 0 wnd */
901           if (!tcp_timer_is_active (tc, TCP_TIMER_PERSIST)
902               && !tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT))
903             tcp_persist_timer_set (tc);
904         }
905       else
906         {
907           tcp_persist_timer_reset (tc);
908           if (!tcp_in_recovery (tc) && tc->rto_boff > 0)
909             {
910               tc->rto_boff = 0;
911               tcp_update_rto (tc);
912             }
913         }
914     }
915 }
916
917 void
918 tcp_cc_init_congestion (tcp_connection_t * tc)
919 {
920   tcp_fastrecovery_on (tc);
921   tc->snd_congestion = tc->snd_una_max;
922   tc->cc_algo->congestion (tc);
923   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 4);
924 }
925
926 static void
927 tcp_cc_recovery_exit (tcp_connection_t * tc)
928 {
929   /* Deflate rto */
930   tcp_update_rto (tc);
931   tc->rto_boff = 0;
932   tc->snd_rxt_ts = 0;
933   tcp_recovery_off (tc);
934 }
935
936 void
937 tcp_cc_fastrecovery_exit (tcp_connection_t * tc)
938 {
939   tc->cc_algo->recovered (tc);
940   tc->snd_rxt_bytes = 0;
941   tc->rcv_dupacks = 0;
942   tcp_fastrecovery_off (tc);
943   tcp_fastrecovery_1_smss_off (tc);
944 }
945
946 static void
947 tcp_cc_congestion_undo (tcp_connection_t * tc)
948 {
949   tc->cwnd = tc->prev_cwnd;
950   tc->ssthresh = tc->prev_ssthresh;
951   tc->snd_nxt = tc->snd_una_max;
952   tc->rcv_dupacks = 0;
953   if (tcp_in_recovery (tc))
954     tcp_cc_recovery_exit (tc);
955   ASSERT (tc->rto_boff == 0);
956   /* TODO extend for fastrecovery */
957 }
958
959 static u8
960 tcp_cc_is_spurious_retransmit (tcp_connection_t * tc)
961 {
962   return (tcp_in_recovery (tc)
963           && tc->snd_rxt_ts
964           && tcp_opts_tstamp (&tc->rcv_opts)
965           && timestamp_lt (tc->rcv_opts.tsecr, tc->snd_rxt_ts));
966 }
967
968 int
969 tcp_cc_recover (tcp_connection_t * tc)
970 {
971   ASSERT (tcp_in_cong_recovery (tc));
972   if (tcp_cc_is_spurious_retransmit (tc))
973     {
974       tcp_cc_congestion_undo (tc);
975       return 1;
976     }
977
978   if (tcp_in_recovery (tc))
979     tcp_cc_recovery_exit (tc);
980   else if (tcp_in_fastrecovery (tc))
981     tcp_cc_fastrecovery_exit (tc);
982
983   ASSERT (tc->rto_boff == 0);
984   ASSERT (!tcp_in_cong_recovery (tc));
985   ASSERT (tcp_scoreboard_is_sane_post_recovery (tc));
986   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 3);
987   return 0;
988 }
989
990 static void
991 tcp_cc_update (tcp_connection_t * tc, vlib_buffer_t * b)
992 {
993   ASSERT (!tcp_in_cong_recovery (tc) || tcp_is_lost_fin (tc));
994
995   /* Congestion avoidance */
996   tc->cc_algo->rcv_ack (tc);
997   tc->tsecr_last_ack = tc->rcv_opts.tsecr;
998
999   /* If a cumulative ack, make sure dupacks is 0 */
1000   tc->rcv_dupacks = 0;
1001
1002   /* When dupacks hits the threshold we only enter fast retransmit if
1003    * cumulative ack covers more than snd_congestion. Should snd_una
1004    * wrap this test may fail under otherwise valid circumstances.
1005    * Therefore, proactively update snd_congestion when wrap detected. */
1006   if (PREDICT_FALSE
1007       (seq_leq (tc->snd_congestion, tc->snd_una - tc->bytes_acked)
1008        && seq_gt (tc->snd_congestion, tc->snd_una)))
1009     tc->snd_congestion = tc->snd_una - 1;
1010 }
1011
1012 static u8
1013 tcp_should_fastrecover_sack (tcp_connection_t * tc)
1014 {
1015   return (TCP_DUPACK_THRESHOLD - 1) * tc->snd_mss < tc->sack_sb.sacked_bytes;
1016 }
1017
1018 static u8
1019 tcp_should_fastrecover (tcp_connection_t * tc)
1020 {
1021   return (tc->rcv_dupacks == TCP_DUPACK_THRESHOLD
1022           || tcp_should_fastrecover_sack (tc));
1023 }
1024
1025 /**
1026  * One function to rule them all ... and in the darkness bind them
1027  */
1028 static void
1029 tcp_cc_handle_event (tcp_connection_t * tc, u32 is_dack)
1030 {
1031   u32 rxt_delivered;
1032
1033   /*
1034    * Duplicate ACK. Check if we should enter fast recovery, or if already in
1035    * it account for the bytes that left the network.
1036    */
1037   if (is_dack)
1038     {
1039       ASSERT (tc->snd_una != tc->snd_una_max
1040               || tc->sack_sb.last_sacked_bytes);
1041
1042       tc->rcv_dupacks++;
1043
1044       if (tc->rcv_dupacks > TCP_DUPACK_THRESHOLD && !tc->bytes_acked)
1045         {
1046           ASSERT (tcp_in_fastrecovery (tc));
1047           /* Pure duplicate ack. If some data got acked, it's handled lower */
1048           tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
1049           return;
1050         }
1051       else if (tcp_should_fastrecover (tc))
1052         {
1053           /* Things are already bad */
1054           if (tcp_in_cong_recovery (tc))
1055             {
1056               tc->rcv_dupacks = 0;
1057               goto partial_ack_test;
1058             }
1059
1060           /* If of of the two conditions lower hold, reset dupacks because
1061            * we're probably after timeout (RFC6582 heuristics).
1062            * If Cumulative ack does not cover more than congestion threshold,
1063            * and:
1064            * 1) The following doesn't hold: The congestion window is greater
1065            *    than SMSS bytes and the difference between highest_ack
1066            *    and prev_highest_ack is at most 4*SMSS bytes
1067            * 2) Echoed timestamp in the last non-dup ack does not equal the
1068            *    stored timestamp
1069            */
1070           if (seq_leq (tc->snd_una, tc->snd_congestion)
1071               && ((!(tc->cwnd > tc->snd_mss
1072                      && tc->bytes_acked <= 4 * tc->snd_mss))
1073                   || (tc->rcv_opts.tsecr != tc->tsecr_last_ack)))
1074             {
1075               tc->rcv_dupacks = 0;
1076               return;
1077             }
1078
1079           tcp_cc_init_congestion (tc);
1080           tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
1081
1082           /* The first segment MUST be retransmitted */
1083           tcp_retransmit_first_unacked (tc);
1084
1085           /* Post retransmit update cwnd to ssthresh and account for the
1086            * three segments that have left the network and should've been
1087            * buffered at the receiver XXX */
1088           tc->cwnd = tc->ssthresh + tc->rcv_dupacks * tc->snd_mss;
1089           ASSERT (tc->cwnd >= tc->snd_mss);
1090
1091           /* If cwnd allows, send more data */
1092           if (tcp_opts_sack_permitted (&tc->rcv_opts))
1093             {
1094               scoreboard_init_high_rxt (&tc->sack_sb,
1095                                         tc->snd_una + tc->snd_mss);
1096               tcp_fast_retransmit_sack (tc);
1097             }
1098           else
1099             {
1100               tcp_fast_retransmit_no_sack (tc);
1101             }
1102
1103           return;
1104         }
1105       else if (!tc->bytes_acked
1106                || (tc->bytes_acked && !tcp_in_cong_recovery (tc)))
1107         {
1108           tc->cc_algo->rcv_cong_ack (tc, TCP_CC_DUPACK);
1109           return;
1110         }
1111       else
1112         goto partial_ack;
1113     }
1114
1115 partial_ack_test:
1116
1117   if (!tc->bytes_acked)
1118     return;
1119
1120 partial_ack:
1121   /*
1122    * Legitimate ACK. 1) See if we can exit recovery
1123    */
1124   /* XXX limit this only to first partial ack? */
1125   tcp_retransmit_timer_update (tc);
1126
1127   if (seq_geq (tc->snd_una, tc->snd_congestion))
1128     {
1129       /* If spurious return, we've already updated everything */
1130       if (tcp_cc_recover (tc))
1131         {
1132           tc->tsecr_last_ack = tc->rcv_opts.tsecr;
1133           return;
1134         }
1135
1136       tc->snd_nxt = tc->snd_una_max;
1137
1138       /* Treat as congestion avoidance ack */
1139       tc->cc_algo->rcv_ack (tc);
1140       tc->tsecr_last_ack = tc->rcv_opts.tsecr;
1141       return;
1142     }
1143
1144   /*
1145    * Legitimate ACK. 2) If PARTIAL ACK try to retransmit
1146    */
1147   TCP_EVT_DBG (TCP_EVT_CC_PACK, tc);
1148
1149   /* RFC6675: If the incoming ACK is a cumulative acknowledgment,
1150    * reset dupacks to 0 */
1151   tc->rcv_dupacks = 0;
1152
1153   tcp_retransmit_first_unacked (tc);
1154
1155   /* Post RTO timeout don't try anything fancy */
1156   if (tcp_in_recovery (tc))
1157     return;
1158
1159   /* Remove retransmitted bytes that have been delivered */
1160   ASSERT (tc->bytes_acked + tc->sack_sb.snd_una_adv
1161           >= tc->sack_sb.last_bytes_delivered
1162           || (tc->flags & TCP_CONN_FINSNT));
1163
1164   if (seq_lt (tc->snd_una, tc->sack_sb.high_rxt))
1165     {
1166       /* If we have sacks and we haven't gotten an ack beyond high_rxt,
1167        * remove sacked bytes delivered */
1168       rxt_delivered = tc->bytes_acked + tc->sack_sb.snd_una_adv
1169         - tc->sack_sb.last_bytes_delivered;
1170       ASSERT (tc->snd_rxt_bytes >= rxt_delivered);
1171       tc->snd_rxt_bytes -= rxt_delivered;
1172     }
1173   else
1174     {
1175       /* Either all retransmitted holes have been acked, or we're
1176        * "in the blind" and retransmitting segment by segment */
1177       tc->snd_rxt_bytes = 0;
1178     }
1179
1180   tc->cc_algo->rcv_cong_ack (tc, TCP_CC_PARTIALACK);
1181
1182   /*
1183    * Since this was a partial ack, try to retransmit some more data
1184    */
1185   tcp_fast_retransmit (tc);
1186 }
1187
1188 void
1189 tcp_cc_init (tcp_connection_t * tc)
1190 {
1191   tc->cc_algo = tcp_cc_algo_get (TCP_CC_NEWRENO);
1192   tc->cc_algo->init (tc);
1193 }
1194
1195 /**
1196  * Process incoming ACK
1197  */
1198 static int
1199 tcp_rcv_ack (tcp_connection_t * tc, vlib_buffer_t * b,
1200              tcp_header_t * th, u32 * next, u32 * error)
1201 {
1202   u32 prev_snd_wnd, prev_snd_una;
1203   u8 is_dack;
1204
1205   TCP_EVT_DBG (TCP_EVT_CC_STAT, tc);
1206
1207   /* If the ACK acks something not yet sent (SEG.ACK > SND.NXT) */
1208   if (PREDICT_FALSE (seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_nxt)))
1209     {
1210       /* If we have outstanding data and this is within the window, accept it,
1211        * probably retransmit has timed out. Otherwise ACK segment and then
1212        * drop it */
1213       if (seq_gt (vnet_buffer (b)->tcp.ack_number, tc->snd_una_max))
1214         {
1215           tcp_make_ack (tc, b);
1216           *next = tcp_next_output (tc->c_is_ip4);
1217           *error = TCP_ERROR_ACK_INVALID;
1218           TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 0,
1219                        vnet_buffer (b)->tcp.ack_number);
1220           return -1;
1221         }
1222
1223       TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 2,
1224                    vnet_buffer (b)->tcp.ack_number);
1225
1226       tc->snd_nxt = vnet_buffer (b)->tcp.ack_number;
1227       *error = TCP_ERROR_ACK_FUTURE;
1228     }
1229
1230   /* If old ACK, probably it's an old dupack */
1231   if (PREDICT_FALSE (seq_lt (vnet_buffer (b)->tcp.ack_number, tc->snd_una)))
1232     {
1233       *error = TCP_ERROR_ACK_OLD;
1234       TCP_EVT_DBG (TCP_EVT_ACK_RCV_ERR, tc, 1,
1235                    vnet_buffer (b)->tcp.ack_number);
1236       if (tcp_in_fastrecovery (tc) && tc->rcv_dupacks == TCP_DUPACK_THRESHOLD)
1237         {
1238           TCP_EVT_DBG (TCP_EVT_DUPACK_RCVD, tc);
1239           tcp_cc_handle_event (tc, 1);
1240         }
1241       /* Don't drop yet */
1242       return 0;
1243     }
1244
1245   /*
1246    * Looks okay, process feedback
1247    */
1248
1249   if (tcp_opts_sack_permitted (&tc->rcv_opts))
1250     tcp_rcv_sacks (tc, vnet_buffer (b)->tcp.ack_number);
1251
1252   prev_snd_wnd = tc->snd_wnd;
1253   prev_snd_una = tc->snd_una;
1254   tcp_update_snd_wnd (tc, vnet_buffer (b)->tcp.seq_number,
1255                       vnet_buffer (b)->tcp.ack_number,
1256                       clib_net_to_host_u16 (th->window) << tc->snd_wscale);
1257   tc->bytes_acked = vnet_buffer (b)->tcp.ack_number - tc->snd_una;
1258   tc->snd_una = vnet_buffer (b)->tcp.ack_number + tc->sack_sb.snd_una_adv;
1259   tcp_validate_txf_size (tc, tc->bytes_acked);
1260
1261   if (tc->bytes_acked)
1262     tcp_dequeue_acked (tc, vnet_buffer (b)->tcp.ack_number);
1263
1264   TCP_EVT_DBG (TCP_EVT_ACK_RCVD, tc);
1265
1266   /*
1267    * Check if we have congestion event
1268    */
1269
1270   if (tcp_ack_is_cc_event (tc, b, prev_snd_wnd, prev_snd_una, &is_dack))
1271     {
1272       tcp_cc_handle_event (tc, is_dack);
1273       if (!tcp_in_cong_recovery (tc))
1274         return 0;
1275       *error = TCP_ERROR_ACK_DUP;
1276       TCP_EVT_DBG (TCP_EVT_DUPACK_RCVD, tc, 1);
1277       return vnet_buffer (b)->tcp.data_len ? 0 : -1;
1278     }
1279
1280   /*
1281    * Update congestion control (slow start/congestion avoidance)
1282    */
1283   tcp_cc_update (tc, b);
1284
1285   return 0;
1286 }
1287
1288 static u8
1289 tcp_sack_vector_is_sane (sack_block_t * sacks)
1290 {
1291   int i;
1292   for (i = 1; i < vec_len (sacks); i++)
1293     {
1294       if (sacks[i - 1].end == sacks[i].start)
1295         return 0;
1296     }
1297   return 1;
1298 }
1299
1300 /**
1301  * Build SACK list as per RFC2018.
1302  *
1303  * Makes sure the first block contains the segment that generated the current
1304  * ACK and the following ones are the ones most recently reported in SACK
1305  * blocks.
1306  *
1307  * @param tc TCP connection for which the SACK list is updated
1308  * @param start Start sequence number of the newest SACK block
1309  * @param end End sequence of the newest SACK block
1310  */
1311 void
1312 tcp_update_sack_list (tcp_connection_t * tc, u32 start, u32 end)
1313 {
1314   sack_block_t *new_list = 0, *block = 0;
1315   int i;
1316
1317   /* If the first segment is ooo add it to the list. Last write might've moved
1318    * rcv_nxt over the first segment. */
1319   if (seq_lt (tc->rcv_nxt, start))
1320     {
1321       vec_add2 (new_list, block, 1);
1322       block->start = start;
1323       block->end = end;
1324     }
1325
1326   /* Find the blocks still worth keeping. */
1327   for (i = 0; i < vec_len (tc->snd_sacks); i++)
1328     {
1329       /* Discard if rcv_nxt advanced beyond current block */
1330       if (seq_leq (tc->snd_sacks[i].start, tc->rcv_nxt))
1331         continue;
1332
1333       /* Merge or drop if segment overlapped by the new segment */
1334       if (block && (seq_geq (tc->snd_sacks[i].end, new_list[0].start)
1335                     && seq_leq (tc->snd_sacks[i].start, new_list[0].end)))
1336         {
1337           if (seq_lt (tc->snd_sacks[i].start, new_list[0].start))
1338             new_list[0].start = tc->snd_sacks[i].start;
1339           if (seq_lt (new_list[0].end, tc->snd_sacks[i].end))
1340             new_list[0].end = tc->snd_sacks[i].end;
1341           continue;
1342         }
1343
1344       /* Save to new SACK list if we have space. */
1345       if (vec_len (new_list) < TCP_MAX_SACK_BLOCKS)
1346         {
1347           vec_add1 (new_list, tc->snd_sacks[i]);
1348         }
1349       else
1350         {
1351           clib_warning ("sack discarded");
1352         }
1353     }
1354
1355   ASSERT (vec_len (new_list) <= TCP_MAX_SACK_BLOCKS);
1356
1357   /* Replace old vector with new one */
1358   vec_free (tc->snd_sacks);
1359   tc->snd_sacks = new_list;
1360
1361   /* Segments should not 'touch' */
1362   ASSERT (tcp_sack_vector_is_sane (tc->snd_sacks));
1363 }
1364
1365 /** Enqueue data for delivery to application */
1366 always_inline int
1367 tcp_session_enqueue_data (tcp_connection_t * tc, vlib_buffer_t * b,
1368                           u16 data_len)
1369 {
1370   int written, error = TCP_ERROR_ENQUEUED;
1371
1372   ASSERT (seq_geq (vnet_buffer (b)->tcp.seq_number, tc->rcv_nxt));
1373
1374   /* Pure ACK. Update rcv_nxt and be done. */
1375   if (PREDICT_FALSE (data_len == 0))
1376     {
1377       return TCP_ERROR_PURE_ACK;
1378     }
1379
1380   written = stream_session_enqueue_data (&tc->connection, b, 0,
1381                                          1 /* queue event */ , 1);
1382
1383   TCP_EVT_DBG (TCP_EVT_INPUT, tc, 0, data_len, written);
1384
1385   /* Update rcv_nxt */
1386   if (PREDICT_TRUE (written == data_len))
1387     {
1388       tc->rcv_nxt += written;
1389     }
1390   /* If more data written than expected, account for out-of-order bytes. */
1391   else if (written > data_len)
1392     {
1393       tc->rcv_nxt += written;
1394
1395       /* Send ACK confirming the update */
1396       tc->flags |= TCP_CONN_SNDACK;
1397     }
1398   else if (written > 0)
1399     {
1400       /* We've written something but FIFO is probably full now */
1401       tc->rcv_nxt += written;
1402
1403       /* Depending on how fast the app is, all remaining buffers in burst will
1404        * not be enqueued. Inform peer */
1405       tc->flags |= TCP_CONN_SNDACK;
1406
1407       error = TCP_ERROR_PARTIALLY_ENQUEUED;
1408     }
1409   else
1410     {
1411       tc->flags |= TCP_CONN_SNDACK;
1412       return TCP_ERROR_FIFO_FULL;
1413     }
1414
1415   /* Update SACK list if need be */
1416   if (tcp_opts_sack_permitted (&tc->rcv_opts))
1417     {
1418       /* Remove SACK blocks that have been delivered */
1419       tcp_update_sack_list (tc, tc->rcv_nxt, tc->rcv_nxt);
1420     }
1421
1422   return error;
1423 }
1424
1425 /** Enqueue out-of-order data */
1426 always_inline int
1427 tcp_session_enqueue_ooo (tcp_connection_t * tc, vlib_buffer_t * b,
1428                          u16 data_len)
1429 {
1430   stream_session_t *s0;
1431   int rv, offset;
1432
1433   ASSERT (seq_gt (vnet_buffer (b)->tcp.seq_number, tc->rcv_nxt));
1434
1435   /* Pure ACK. Do nothing */
1436   if (PREDICT_FALSE (data_len == 0))
1437     {
1438       return TCP_ERROR_PURE_ACK;
1439     }
1440
1441   /* Enqueue out-of-order data with relative offset */
1442   rv = stream_session_enqueue_data (&tc->connection, b,
1443                                     vnet_buffer (b)->tcp.seq_number -
1444                                     tc->rcv_nxt, 0 /* queue event */ , 0);
1445
1446   /* Nothing written */
1447   if (rv)
1448     {
1449       TCP_EVT_DBG (TCP_EVT_INPUT, tc, 1, data_len, 0);
1450       return TCP_ERROR_FIFO_FULL;
1451     }
1452
1453   TCP_EVT_DBG (TCP_EVT_INPUT, tc, 1, data_len, data_len);
1454
1455   /* Update SACK list if in use */
1456   if (tcp_opts_sack_permitted (&tc->rcv_opts))
1457     {
1458       ooo_segment_t *newest;
1459       u32 start, end;
1460
1461       s0 = stream_session_get (tc->c_s_index, tc->c_thread_index);
1462
1463       /* Get the newest segment from the fifo */
1464       newest = svm_fifo_newest_ooo_segment (s0->server_rx_fifo);
1465       if (newest)
1466         {
1467           offset = ooo_segment_offset (s0->server_rx_fifo, newest);
1468           ASSERT (offset <= vnet_buffer (b)->tcp.seq_number - tc->rcv_nxt);
1469           start = tc->rcv_nxt + offset;
1470           end = start + ooo_segment_length (s0->server_rx_fifo, newest);
1471           tcp_update_sack_list (tc, start, end);
1472           svm_fifo_newest_ooo_segment_reset (s0->server_rx_fifo);
1473         }
1474     }
1475
1476   return TCP_ERROR_ENQUEUED;
1477 }
1478
1479 /**
1480  * Check if ACK could be delayed. If ack can be delayed, it should return
1481  * true for a full frame. If we're always acking return 0.
1482  */
1483 always_inline int
1484 tcp_can_delack (tcp_connection_t * tc)
1485 {
1486   /* Send ack if ... */
1487   if (TCP_ALWAYS_ACK
1488       /* just sent a rcv wnd 0 */
1489       || (tc->flags & TCP_CONN_SENT_RCV_WND0) != 0
1490       /* constrained to send ack */
1491       || (tc->flags & TCP_CONN_SNDACK) != 0
1492       /* we're almost out of tx wnd */
1493       || tcp_available_snd_space (tc) < 4 * tc->snd_mss)
1494     return 0;
1495
1496   return 1;
1497 }
1498
1499 static int
1500 tcp_buffer_discard_bytes (vlib_buffer_t * b, u32 n_bytes_to_drop)
1501 {
1502   u32 discard, first = b->current_length;
1503   vlib_main_t *vm = vlib_get_main ();
1504
1505   /* Handle multi-buffer segments */
1506   if (n_bytes_to_drop > b->current_length)
1507     {
1508       if (!(b->flags & VLIB_BUFFER_NEXT_PRESENT))
1509         return -1;
1510       do
1511         {
1512           discard = clib_min (n_bytes_to_drop, b->current_length);
1513           vlib_buffer_advance (b, discard);
1514           b = vlib_get_buffer (vm, b->next_buffer);
1515           n_bytes_to_drop -= discard;
1516         }
1517       while (n_bytes_to_drop);
1518       if (n_bytes_to_drop > first)
1519         b->total_length_not_including_first_buffer -= n_bytes_to_drop - first;
1520     }
1521   else
1522     vlib_buffer_advance (b, n_bytes_to_drop);
1523   vnet_buffer (b)->tcp.data_len -= n_bytes_to_drop;
1524   return 0;
1525 }
1526
1527 static int
1528 tcp_segment_rcv (tcp_main_t * tm, tcp_connection_t * tc, vlib_buffer_t * b,
1529                  u32 * next0)
1530 {
1531   u32 error = 0, n_bytes_to_drop, n_data_bytes;
1532
1533   vlib_buffer_advance (b, vnet_buffer (b)->tcp.data_offset);
1534   n_data_bytes = vnet_buffer (b)->tcp.data_len;
1535   ASSERT (n_data_bytes);
1536
1537   /* Handle out-of-order data */
1538   if (PREDICT_FALSE (vnet_buffer (b)->tcp.seq_number != tc->rcv_nxt))
1539     {
1540       /* Old sequence numbers allowed through because they overlapped
1541        * the rx window */
1542       if (seq_lt (vnet_buffer (b)->tcp.seq_number, tc->rcv_nxt))
1543         {
1544           error = TCP_ERROR_SEGMENT_OLD;
1545           *next0 = TCP_NEXT_DROP;
1546
1547           /* Completely in the past (possible retransmit) */
1548           if (seq_leq (vnet_buffer (b)->tcp.seq_end, tc->rcv_nxt))
1549             {
1550               /* Ack retransmissions since we may not have any data to send */
1551               tcp_make_ack (tc, b);
1552               *next0 = tcp_next_output (tc->c_is_ip4);
1553               goto done;
1554             }
1555
1556           /* Chop off the bytes in the past */
1557           n_bytes_to_drop = tc->rcv_nxt - vnet_buffer (b)->tcp.seq_number;
1558           n_data_bytes -= n_bytes_to_drop;
1559           vnet_buffer (b)->tcp.seq_number = tc->rcv_nxt;
1560           if (tcp_buffer_discard_bytes (b, n_bytes_to_drop))
1561             goto done;
1562
1563           goto in_order;
1564         }
1565
1566       error = tcp_session_enqueue_ooo (tc, b, n_data_bytes);
1567
1568       /* N.B. Should not filter burst of dupacks. Two issues 1) dupacks open
1569        * cwnd on remote peer when congested 2) acks leaving should have the
1570        * latest rcv_wnd since the burst may eaten up all of it, so only the
1571        * old ones could be filtered.
1572        */
1573
1574       /* RFC2581: Send DUPACK for fast retransmit */
1575       tcp_make_ack (tc, b);
1576       *next0 = tcp_next_output (tc->c_is_ip4);
1577
1578       /* Mark as DUPACK. We may filter these in output if
1579        * the burst fills the holes. */
1580       if (n_data_bytes)
1581         vnet_buffer (b)->tcp.flags = TCP_BUF_FLAG_DUPACK;
1582
1583       TCP_EVT_DBG (TCP_EVT_DUPACK_SENT, tc);
1584       goto done;
1585     }
1586
1587 in_order:
1588
1589   /* In order data, enqueue. Fifo figures out by itself if any out-of-order
1590    * segments can be enqueued after fifo tail offset changes. */
1591   error = tcp_session_enqueue_data (tc, b, n_data_bytes);
1592
1593   /* Check if ACK can be delayed */
1594   if (tcp_can_delack (tc))
1595     {
1596       if (!tcp_timer_is_active (tc, TCP_TIMER_DELACK))
1597         tcp_timer_set (tc, TCP_TIMER_DELACK, TCP_DELACK_TIME);
1598       goto done;
1599     }
1600
1601   *next0 = tcp_next_output (tc->c_is_ip4);
1602   tcp_make_ack (tc, b);
1603
1604 done:
1605   return error;
1606 }
1607
1608 typedef struct
1609 {
1610   tcp_header_t tcp_header;
1611   tcp_connection_t tcp_connection;
1612 } tcp_rx_trace_t;
1613
1614 u8 *
1615 format_tcp_rx_trace (u8 * s, va_list * args)
1616 {
1617   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1618   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1619   tcp_rx_trace_t *t = va_arg (*args, tcp_rx_trace_t *);
1620   uword indent = format_get_indent (s);
1621
1622   s = format (s, "%U\n%U%U",
1623               format_tcp_header, &t->tcp_header, 128,
1624               format_white_space, indent,
1625               format_tcp_connection, &t->tcp_connection, 1);
1626
1627   return s;
1628 }
1629
1630 u8 *
1631 format_tcp_rx_trace_short (u8 * s, va_list * args)
1632 {
1633   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1634   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1635   tcp_rx_trace_t *t = va_arg (*args, tcp_rx_trace_t *);
1636
1637   s = format (s, "%d -> %d (%U)",
1638               clib_net_to_host_u16 (t->tcp_header.src_port),
1639               clib_net_to_host_u16 (t->tcp_header.dst_port), format_tcp_state,
1640               t->tcp_connection.state);
1641
1642   return s;
1643 }
1644
1645 void
1646 tcp_set_rx_trace_data (tcp_rx_trace_t * t0, tcp_connection_t * tc0,
1647                        tcp_header_t * th0, vlib_buffer_t * b0, u8 is_ip4)
1648 {
1649   if (tc0)
1650     {
1651       clib_memcpy (&t0->tcp_connection, tc0, sizeof (t0->tcp_connection));
1652     }
1653   else
1654     {
1655       th0 = tcp_buffer_hdr (b0);
1656     }
1657   clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1658 }
1659
1660 always_inline void
1661 tcp_established_inc_counter (vlib_main_t * vm, u8 is_ip4, u8 evt, u8 val)
1662 {
1663   if (PREDICT_TRUE (!val))
1664     return;
1665
1666   if (is_ip4)
1667     vlib_node_increment_counter (vm, tcp4_established_node.index, evt, val);
1668   else
1669     vlib_node_increment_counter (vm, tcp6_established_node.index, evt, val);
1670 }
1671
1672 always_inline uword
1673 tcp46_established_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1674                           vlib_frame_t * from_frame, int is_ip4)
1675 {
1676   u32 n_left_from, next_index, *from, *to_next;
1677   u32 my_thread_index = vm->thread_index, errors = 0;
1678   tcp_main_t *tm = vnet_get_tcp_main ();
1679   u8 is_fin = 0;
1680
1681   from = vlib_frame_vector_args (from_frame);
1682   n_left_from = from_frame->n_vectors;
1683
1684   next_index = node->cached_next_index;
1685
1686   while (n_left_from > 0)
1687     {
1688       u32 n_left_to_next;
1689
1690       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1691       while (n_left_from > 0 && n_left_to_next > 0)
1692         {
1693           u32 bi0;
1694           vlib_buffer_t *b0;
1695           tcp_header_t *th0 = 0;
1696           tcp_connection_t *tc0;
1697           u32 next0 = TCP_ESTABLISHED_NEXT_DROP, error0 = TCP_ERROR_ENQUEUED;
1698
1699           bi0 = from[0];
1700           to_next[0] = bi0;
1701           from += 1;
1702           to_next += 1;
1703           n_left_from -= 1;
1704           n_left_to_next -= 1;
1705
1706           b0 = vlib_get_buffer (vm, bi0);
1707           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
1708                                     my_thread_index);
1709
1710           if (PREDICT_FALSE (tc0 == 0))
1711             {
1712               error0 = TCP_ERROR_INVALID_CONNECTION;
1713               goto done;
1714             }
1715
1716           th0 = tcp_buffer_hdr (b0);
1717           /* N.B. buffer is rewritten if segment is ooo. Thus, th0 becomes a
1718            * dangling reference. */
1719           is_fin = tcp_is_fin (th0);
1720
1721           /* SYNs, FINs and data consume sequence numbers */
1722           vnet_buffer (b0)->tcp.seq_end = vnet_buffer (b0)->tcp.seq_number
1723             + tcp_is_syn (th0) + is_fin + vnet_buffer (b0)->tcp.data_len;
1724
1725           /* TODO header prediction fast path */
1726
1727           /* 1-4: check SEQ, RST, SYN */
1728           if (PREDICT_FALSE (tcp_segment_validate (vm, tc0, b0, th0, &next0)))
1729             {
1730               error0 = TCP_ERROR_SEGMENT_INVALID;
1731               TCP_EVT_DBG (TCP_EVT_SEG_INVALID, tc0,
1732                            vnet_buffer (b0)->tcp.seq_number,
1733                            vnet_buffer (b0)->tcp.seq_end);
1734               goto done;
1735             }
1736
1737           /* 5: check the ACK field  */
1738           if (tcp_rcv_ack (tc0, b0, th0, &next0, &error0))
1739             goto done;
1740
1741           /* 6: check the URG bit TODO */
1742
1743           /* 7: process the segment text */
1744           if (vnet_buffer (b0)->tcp.data_len)
1745             error0 = tcp_segment_rcv (tm, tc0, b0, &next0);
1746
1747           /* 8: check the FIN bit */
1748           if (PREDICT_FALSE (is_fin))
1749             {
1750               /* Enter CLOSE-WAIT and notify session. Don't send ACK, instead
1751                * wait for session to call close. To avoid lingering
1752                * in CLOSE-WAIT, set timer (reuse WAITCLOSE). */
1753               tc0->state = TCP_STATE_CLOSE_WAIT;
1754               TCP_EVT_DBG (TCP_EVT_FIN_RCVD, tc0);
1755               if (vnet_buffer (b0)->tcp.data_len == 0)
1756                 {
1757                   tc0->rcv_nxt += 1;
1758                   next0 = TCP_ESTABLISHED_NEXT_DROP;
1759                 }
1760               stream_session_disconnect_notify (&tc0->connection);
1761               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
1762             }
1763
1764         done:
1765           b0->error = node->errors[error0];
1766           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1767             {
1768               tcp_rx_trace_t *t0 =
1769                 vlib_add_trace (vm, node, b0, sizeof (*t0));
1770               tcp_set_rx_trace_data (t0, tc0, th0, b0, is_ip4);
1771             }
1772
1773           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1774                                            n_left_to_next, bi0, next0);
1775         }
1776
1777       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1778     }
1779
1780   errors = session_manager_flush_enqueue_events (my_thread_index);
1781   tcp_established_inc_counter (vm, is_ip4, TCP_ERROR_EVENT_FIFO_FULL, errors);
1782   tcp_flush_frame_to_output (vm, my_thread_index, is_ip4);
1783
1784   return from_frame->n_vectors;
1785 }
1786
1787 static uword
1788 tcp4_established (vlib_main_t * vm, vlib_node_runtime_t * node,
1789                   vlib_frame_t * from_frame)
1790 {
1791   return tcp46_established_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1792 }
1793
1794 static uword
1795 tcp6_established (vlib_main_t * vm, vlib_node_runtime_t * node,
1796                   vlib_frame_t * from_frame)
1797 {
1798   return tcp46_established_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1799 }
1800
1801 /* *INDENT-OFF* */
1802 VLIB_REGISTER_NODE (tcp4_established_node) =
1803 {
1804   .function = tcp4_established,
1805   .name = "tcp4-established",
1806   /* Takes a vector of packets. */
1807   .vector_size = sizeof (u32),
1808   .n_errors = TCP_N_ERROR,
1809   .error_strings = tcp_error_strings,
1810   .n_next_nodes = TCP_ESTABLISHED_N_NEXT,
1811   .next_nodes =
1812   {
1813 #define _(s,n) [TCP_ESTABLISHED_NEXT_##s] = n,
1814     foreach_tcp_state_next
1815 #undef _
1816   },
1817   .format_trace = format_tcp_rx_trace_short,
1818 };
1819 /* *INDENT-ON* */
1820
1821 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_established_node, tcp4_established);
1822
1823 /* *INDENT-OFF* */
1824 VLIB_REGISTER_NODE (tcp6_established_node) =
1825 {
1826   .function = tcp6_established,
1827   .name = "tcp6-established",
1828   /* Takes a vector of packets. */
1829   .vector_size = sizeof (u32),
1830   .n_errors = TCP_N_ERROR,
1831   .error_strings = tcp_error_strings,
1832   .n_next_nodes = TCP_ESTABLISHED_N_NEXT,
1833   .next_nodes =
1834   {
1835 #define _(s,n) [TCP_ESTABLISHED_NEXT_##s] = n,
1836     foreach_tcp_state_next
1837 #undef _
1838   },
1839   .format_trace = format_tcp_rx_trace_short,
1840 };
1841 /* *INDENT-ON* */
1842
1843
1844 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_established_node, tcp6_established);
1845
1846 vlib_node_registration_t tcp4_syn_sent_node;
1847 vlib_node_registration_t tcp6_syn_sent_node;
1848
1849 static u8
1850 tcp_lookup_is_valid (tcp_connection_t * tc, tcp_header_t * hdr)
1851 {
1852   transport_connection_t *tmp;
1853   if (!tc)
1854     return 1;
1855
1856   u8 is_valid = (tc->c_lcl_port == hdr->dst_port
1857                  && (tc->state == TCP_STATE_LISTEN
1858                      || tc->c_rmt_port == hdr->src_port));
1859
1860   if (!is_valid)
1861     {
1862       if ((tmp =
1863            stream_session_half_open_lookup (&tc->c_lcl_ip, &tc->c_rmt_ip,
1864                                             tc->c_lcl_port, tc->c_rmt_port,
1865                                             tc->c_transport_proto)))
1866         {
1867           if (tmp->lcl_port == hdr->dst_port
1868               && tmp->rmt_port == hdr->src_port)
1869             {
1870               clib_warning ("half-open is valid!");
1871             }
1872         }
1873     }
1874   return is_valid;
1875 }
1876
1877 /**
1878  * Lookup transport connection
1879  */
1880 static tcp_connection_t *
1881 tcp_lookup_connection (vlib_buffer_t * b, u8 thread_index, u8 is_ip4)
1882 {
1883   tcp_header_t *tcp;
1884   transport_connection_t *tconn;
1885   tcp_connection_t *tc;
1886   if (is_ip4)
1887     {
1888       ip4_header_t *ip4;
1889       ip4 = vlib_buffer_get_current (b);
1890       tcp = ip4_next_header (ip4);
1891       tconn = stream_session_lookup_transport_wt4 (&ip4->dst_address,
1892                                                    &ip4->src_address,
1893                                                    tcp->dst_port,
1894                                                    tcp->src_port,
1895                                                    SESSION_TYPE_IP4_TCP,
1896                                                    thread_index);
1897       tc = tcp_get_connection_from_transport (tconn);
1898       ASSERT (tcp_lookup_is_valid (tc, tcp));
1899     }
1900   else
1901     {
1902       ip6_header_t *ip6;
1903       ip6 = vlib_buffer_get_current (b);
1904       tcp = ip6_next_header (ip6);
1905       tconn = stream_session_lookup_transport_wt6 (&ip6->dst_address,
1906                                                    &ip6->src_address,
1907                                                    tcp->dst_port,
1908                                                    tcp->src_port,
1909                                                    SESSION_TYPE_IP6_TCP,
1910                                                    thread_index);
1911       tc = tcp_get_connection_from_transport (tconn);
1912       ASSERT (tcp_lookup_is_valid (tc, tcp));
1913     }
1914   return tc;
1915 }
1916
1917 always_inline uword
1918 tcp46_syn_sent_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1919                        vlib_frame_t * from_frame, int is_ip4)
1920 {
1921   tcp_main_t *tm = vnet_get_tcp_main ();
1922   u32 n_left_from, next_index, *from, *to_next;
1923   u32 my_thread_index = vm->thread_index, errors = 0;
1924
1925   from = vlib_frame_vector_args (from_frame);
1926   n_left_from = from_frame->n_vectors;
1927
1928   next_index = node->cached_next_index;
1929
1930   while (n_left_from > 0)
1931     {
1932       u32 n_left_to_next;
1933
1934       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1935
1936       while (n_left_from > 0 && n_left_to_next > 0)
1937         {
1938           u32 bi0, ack0, seq0;
1939           vlib_buffer_t *b0;
1940           tcp_rx_trace_t *t0;
1941           tcp_header_t *tcp0 = 0;
1942           tcp_connection_t *tc0;
1943           tcp_connection_t *new_tc0;
1944           u32 next0 = TCP_SYN_SENT_NEXT_DROP, error0 = TCP_ERROR_ENQUEUED;
1945
1946           bi0 = from[0];
1947           to_next[0] = bi0;
1948           from += 1;
1949           to_next += 1;
1950           n_left_from -= 1;
1951           n_left_to_next -= 1;
1952
1953           b0 = vlib_get_buffer (vm, bi0);
1954           tc0 =
1955             tcp_half_open_connection_get (vnet_buffer (b0)->
1956                                           tcp.connection_index);
1957           if (PREDICT_FALSE (tc0 == 0))
1958             {
1959               error0 = TCP_ERROR_INVALID_CONNECTION;
1960               goto drop;
1961             }
1962
1963           /* Half-open completed recently but the connection was't removed
1964            * yet by the owning thread */
1965           if (PREDICT_FALSE (tc0->flags & TCP_CONN_HALF_OPEN_DONE))
1966             {
1967               /* Make sure the connection actually exists */
1968               ASSERT (tcp_lookup_connection (b0, my_thread_index, is_ip4));
1969               goto drop;
1970             }
1971
1972           ack0 = vnet_buffer (b0)->tcp.ack_number;
1973           seq0 = vnet_buffer (b0)->tcp.seq_number;
1974           tcp0 = tcp_buffer_hdr (b0);
1975
1976           if (PREDICT_FALSE
1977               (!tcp_ack (tcp0) && !tcp_rst (tcp0) && !tcp_syn (tcp0)))
1978             goto drop;
1979
1980           /* SYNs, FINs and data consume sequence numbers */
1981           vnet_buffer (b0)->tcp.seq_end = seq0 + tcp_is_syn (tcp0)
1982             + tcp_is_fin (tcp0) + vnet_buffer (b0)->tcp.data_len;
1983
1984           /*
1985            *  1. check the ACK bit
1986            */
1987
1988           /*
1989            *   If the ACK bit is set
1990            *     If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, send a reset (unless
1991            *     the RST bit is set, if so drop the segment and return)
1992            *       <SEQ=SEG.ACK><CTL=RST>
1993            *     and discard the segment.  Return.
1994            *     If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable.
1995            */
1996           if (tcp_ack (tcp0))
1997             {
1998               if (seq_leq (ack0, tc0->iss) || seq_gt (ack0, tc0->snd_nxt))
1999                 {
2000                   clib_warning ("ack not in rcv wnd");
2001                   if (!tcp_rst (tcp0))
2002                     tcp_send_reset_w_pkt (tc0, b0, is_ip4);
2003                   goto drop;
2004                 }
2005
2006               /* Make sure ACK is valid */
2007               if (seq_gt (tc0->snd_una, ack0))
2008                 {
2009                   clib_warning ("ack invalid");
2010                   goto drop;
2011                 }
2012             }
2013
2014           /*
2015            * 2. check the RST bit
2016            */
2017
2018           if (tcp_rst (tcp0))
2019             {
2020               /* If ACK is acceptable, signal client that peer is not
2021                * willing to accept connection and drop connection*/
2022               if (tcp_ack (tcp0))
2023                 tcp_connection_reset (tc0);
2024               goto drop;
2025             }
2026
2027           /*
2028            * 3. check the security and precedence (skipped)
2029            */
2030
2031           /*
2032            * 4. check the SYN bit
2033            */
2034
2035           /* No SYN flag. Drop. */
2036           if (!tcp_syn (tcp0))
2037             {
2038               clib_warning ("not synack");
2039               goto drop;
2040             }
2041
2042           /* Parse options */
2043           if (tcp_options_parse (tcp0, &tc0->rcv_opts))
2044             {
2045               clib_warning ("options parse fail");
2046               goto drop;
2047             }
2048
2049           /* Valid SYN or SYN-ACK. Move connection from half-open pool to
2050            * current thread pool. */
2051           pool_get (tm->connections[my_thread_index], new_tc0);
2052           clib_memcpy (new_tc0, tc0, sizeof (*new_tc0));
2053           new_tc0->c_c_index = new_tc0 - tm->connections[my_thread_index];
2054           new_tc0->c_thread_index = my_thread_index;
2055           new_tc0->rcv_nxt = vnet_buffer (b0)->tcp.seq_end;
2056           new_tc0->irs = seq0;
2057           new_tc0->timers[TCP_TIMER_ESTABLISH] = TCP_TIMER_HANDLE_INVALID;
2058           new_tc0->timers[TCP_TIMER_RETRANSMIT_SYN] =
2059             TCP_TIMER_HANDLE_INVALID;
2060
2061           /* If this is not the owning thread, wait for syn retransmit to
2062            * expire and cleanup then */
2063           if (tcp_half_open_connection_cleanup (tc0))
2064             tc0->flags |= TCP_CONN_HALF_OPEN_DONE;
2065
2066           if (tcp_opts_tstamp (&new_tc0->rcv_opts))
2067             {
2068               new_tc0->tsval_recent = new_tc0->rcv_opts.tsval;
2069               new_tc0->tsval_recent_age = tcp_time_now ();
2070             }
2071
2072           if (tcp_opts_wscale (&new_tc0->rcv_opts))
2073             new_tc0->snd_wscale = new_tc0->rcv_opts.wscale;
2074
2075           /* RFC1323: SYN and SYN-ACK wnd not scaled */
2076           new_tc0->snd_wnd = clib_net_to_host_u16 (tcp0->window);
2077           new_tc0->snd_wl1 = seq0;
2078           new_tc0->snd_wl2 = ack0;
2079
2080           tcp_connection_init_vars (new_tc0);
2081
2082           /* SYN-ACK: See if we can switch to ESTABLISHED state */
2083           if (PREDICT_TRUE (tcp_ack (tcp0)))
2084             {
2085               /* Our SYN is ACKed: we have iss < ack = snd_una */
2086
2087               /* TODO Dequeue acknowledged segments if we support Fast Open */
2088               new_tc0->snd_una = ack0;
2089               new_tc0->state = TCP_STATE_ESTABLISHED;
2090
2091               /* Make sure las is initialized for the wnd computation */
2092               new_tc0->rcv_las = new_tc0->rcv_nxt;
2093
2094               /* Notify app that we have connection. If session layer can't
2095                * allocate session send reset */
2096               if (stream_session_connect_notify (&new_tc0->connection, 0))
2097                 {
2098                   clib_warning ("connect notify fail");
2099                   tcp_send_reset_w_pkt (new_tc0, b0, is_ip4);
2100                   tcp_connection_cleanup (new_tc0);
2101                   goto drop;
2102                 }
2103
2104               /* Make sure after data segment processing ACK is sent */
2105               new_tc0->flags |= TCP_CONN_SNDACK;
2106
2107               /* Update rtt with the syn-ack sample */
2108               new_tc0->bytes_acked = 1;
2109               tcp_update_rtt (new_tc0, vnet_buffer (b0)->tcp.ack_number);
2110               TCP_EVT_DBG (TCP_EVT_SYNACK_RCVD, new_tc0);
2111             }
2112           /* SYN: Simultaneous open. Change state to SYN-RCVD and send SYN-ACK */
2113           else
2114             {
2115               new_tc0->state = TCP_STATE_SYN_RCVD;
2116
2117               /* Notify app that we have connection */
2118               if (stream_session_connect_notify (&new_tc0->connection, 0))
2119                 {
2120                   tcp_connection_cleanup (new_tc0);
2121                   tcp_send_reset_w_pkt (tc0, b0, is_ip4);
2122                   TCP_EVT_DBG (TCP_EVT_RST_SENT, tc0);
2123                   goto drop;
2124                 }
2125
2126               tc0->rtt_ts = 0;
2127               tcp_init_snd_vars (tc0);
2128               tcp_make_synack (new_tc0, b0);
2129               next0 = tcp_next_output (is_ip4);
2130
2131               goto drop;
2132             }
2133
2134           /* Read data, if any */
2135           if (PREDICT_FALSE (vnet_buffer (b0)->tcp.data_len))
2136             {
2137               ASSERT (0);
2138               error0 = tcp_segment_rcv (tm, new_tc0, b0, &next0);
2139               if (error0 == TCP_ERROR_PURE_ACK)
2140                 error0 = TCP_ERROR_SYN_ACKS_RCVD;
2141             }
2142           else
2143             {
2144               tcp_make_ack (new_tc0, b0);
2145               next0 = tcp_next_output (new_tc0->c_is_ip4);
2146             }
2147
2148         drop:
2149
2150           b0->error = error0 ? node->errors[error0] : 0;
2151           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2152             {
2153               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
2154               clib_memcpy (&t0->tcp_header, tcp0, sizeof (t0->tcp_header));
2155               clib_memcpy (&t0->tcp_connection, tc0,
2156                            sizeof (t0->tcp_connection));
2157             }
2158
2159           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2160                                            n_left_to_next, bi0, next0);
2161         }
2162
2163       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2164     }
2165
2166   errors = session_manager_flush_enqueue_events (my_thread_index);
2167   if (errors)
2168     {
2169       if (is_ip4)
2170         vlib_node_increment_counter (vm, tcp4_established_node.index,
2171                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
2172       else
2173         vlib_node_increment_counter (vm, tcp6_established_node.index,
2174                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
2175     }
2176
2177   return from_frame->n_vectors;
2178 }
2179
2180 static uword
2181 tcp4_syn_sent (vlib_main_t * vm, vlib_node_runtime_t * node,
2182                vlib_frame_t * from_frame)
2183 {
2184   return tcp46_syn_sent_inline (vm, node, from_frame, 1 /* is_ip4 */ );
2185 }
2186
2187 static uword
2188 tcp6_syn_sent_rcv (vlib_main_t * vm, vlib_node_runtime_t * node,
2189                    vlib_frame_t * from_frame)
2190 {
2191   return tcp46_syn_sent_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2192 }
2193
2194 /* *INDENT-OFF* */
2195 VLIB_REGISTER_NODE (tcp4_syn_sent_node) =
2196 {
2197   .function = tcp4_syn_sent,
2198   .name = "tcp4-syn-sent",
2199   /* Takes a vector of packets. */
2200   .vector_size = sizeof (u32),
2201   .n_errors = TCP_N_ERROR,
2202   .error_strings = tcp_error_strings,
2203   .n_next_nodes = TCP_SYN_SENT_N_NEXT,
2204   .next_nodes =
2205   {
2206 #define _(s,n) [TCP_SYN_SENT_NEXT_##s] = n,
2207     foreach_tcp_state_next
2208 #undef _
2209   },
2210   .format_trace = format_tcp_rx_trace_short,
2211 };
2212 /* *INDENT-ON* */
2213
2214 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_syn_sent_node, tcp4_syn_sent);
2215
2216 /* *INDENT-OFF* */
2217 VLIB_REGISTER_NODE (tcp6_syn_sent_node) =
2218 {
2219   .function = tcp6_syn_sent_rcv,
2220   .name = "tcp6-syn-sent",
2221   /* Takes a vector of packets. */
2222   .vector_size = sizeof (u32),
2223   .n_errors = TCP_N_ERROR,
2224   .error_strings = tcp_error_strings,
2225   .n_next_nodes = TCP_SYN_SENT_N_NEXT,
2226   .next_nodes =
2227   {
2228 #define _(s,n) [TCP_SYN_SENT_NEXT_##s] = n,
2229     foreach_tcp_state_next
2230 #undef _
2231   },
2232   .format_trace = format_tcp_rx_trace_short,
2233 };
2234 /* *INDENT-ON* */
2235
2236 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_syn_sent_node, tcp6_syn_sent_rcv);
2237
2238 /**
2239  * Handles reception for all states except LISTEN, SYN-SENT and ESTABLISHED
2240  * as per RFC793 p. 64
2241  */
2242 always_inline uword
2243 tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2244                           vlib_frame_t * from_frame, int is_ip4)
2245 {
2246   tcp_main_t *tm = vnet_get_tcp_main ();
2247   u32 n_left_from, next_index, *from, *to_next;
2248   u32 my_thread_index = vm->thread_index, errors = 0;
2249
2250   from = vlib_frame_vector_args (from_frame);
2251   n_left_from = from_frame->n_vectors;
2252
2253   next_index = node->cached_next_index;
2254
2255   while (n_left_from > 0)
2256     {
2257       u32 n_left_to_next;
2258
2259       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2260
2261       while (n_left_from > 0 && n_left_to_next > 0)
2262         {
2263           u32 bi0;
2264           vlib_buffer_t *b0;
2265           tcp_header_t *tcp0 = 0;
2266           tcp_connection_t *tc0;
2267           u32 next0 = TCP_RCV_PROCESS_NEXT_DROP, error0 = TCP_ERROR_ENQUEUED;
2268
2269           bi0 = from[0];
2270           to_next[0] = bi0;
2271           from += 1;
2272           to_next += 1;
2273           n_left_from -= 1;
2274           n_left_to_next -= 1;
2275
2276           b0 = vlib_get_buffer (vm, bi0);
2277           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
2278                                     my_thread_index);
2279           if (PREDICT_FALSE (tc0 == 0))
2280             {
2281               error0 = TCP_ERROR_INVALID_CONNECTION;
2282               goto drop;
2283             }
2284
2285           tcp0 = tcp_buffer_hdr (b0);
2286
2287           /* SYNs, FINs and data consume sequence numbers */
2288           vnet_buffer (b0)->tcp.seq_end = vnet_buffer (b0)->tcp.seq_number
2289             + tcp_is_syn (tcp0) + tcp_is_fin (tcp0)
2290             + vnet_buffer (b0)->tcp.data_len;
2291
2292           if (CLIB_DEBUG)
2293             {
2294               tcp_connection_t *tmp;
2295               tmp = tcp_lookup_connection (b0, my_thread_index, is_ip4);
2296               if (tmp->state != tc0->state)
2297                 {
2298                   clib_warning ("state changed");
2299                   ASSERT (0);
2300                   goto drop;
2301                 }
2302             }
2303
2304           /*
2305            * Special treatment for CLOSED
2306            */
2307           switch (tc0->state)
2308             {
2309             case TCP_STATE_CLOSED:
2310               goto drop;
2311               break;
2312             }
2313
2314           /*
2315            * For all other states (except LISTEN)
2316            */
2317
2318           /* 1-4: check SEQ, RST, SYN */
2319           if (PREDICT_FALSE (tcp_segment_validate (vm, tc0, b0, tcp0,
2320                                                    &next0)))
2321             {
2322               error0 = TCP_ERROR_SEGMENT_INVALID;
2323               goto drop;
2324             }
2325
2326           /* 5: check the ACK field  */
2327           switch (tc0->state)
2328             {
2329             case TCP_STATE_SYN_RCVD:
2330               /*
2331                * If the segment acknowledgment is not acceptable, form a
2332                * reset segment,
2333                *  <SEQ=SEG.ACK><CTL=RST>
2334                * and send it.
2335                */
2336               if (!tcp_rcv_ack_is_acceptable (tc0, b0))
2337                 {
2338                   clib_warning ("connection not accepted");
2339                   tcp_send_reset_w_pkt (tc0, b0, is_ip4);
2340                   goto drop;
2341                 }
2342
2343               /* Update rtt and rto */
2344               tc0->bytes_acked = 1;
2345               tcp_update_rtt (tc0, vnet_buffer (b0)->tcp.ack_number);
2346
2347               /* Switch state to ESTABLISHED */
2348               tc0->state = TCP_STATE_ESTABLISHED;
2349
2350               /* Initialize session variables */
2351               tc0->snd_una = vnet_buffer (b0)->tcp.ack_number;
2352               tc0->snd_wnd = clib_net_to_host_u16 (tcp0->window)
2353                 << tc0->rcv_opts.wscale;
2354               tc0->snd_wl1 = vnet_buffer (b0)->tcp.seq_number;
2355               tc0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
2356               stream_session_accept_notify (&tc0->connection);
2357
2358               /* Reset SYN-ACK retransmit and SYN_RCV establish timers */
2359               tcp_retransmit_timer_reset (tc0);
2360               tcp_timer_reset (tc0, TCP_TIMER_ESTABLISH);
2361               TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2362               break;
2363             case TCP_STATE_ESTABLISHED:
2364               /* We can get packets in established state here because they
2365                * were enqueued before state change */
2366               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
2367                 goto drop;
2368
2369               break;
2370             case TCP_STATE_FIN_WAIT_1:
2371               /* In addition to the processing for the ESTABLISHED state, if
2372                * our FIN is now acknowledged then enter FIN-WAIT-2 and
2373                * continue processing in that state. */
2374               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
2375                 goto drop;
2376
2377               /* Still have to send the FIN */
2378               if (tc0->flags & TCP_CONN_FINPNDG)
2379                 {
2380                   /* TX fifo finally drained */
2381                   if (!stream_session_tx_fifo_max_dequeue (&tc0->connection))
2382                     tcp_send_fin (tc0);
2383                 }
2384               /* If FIN is ACKed */
2385               else if (tc0->snd_una == tc0->snd_una_max)
2386                 {
2387                   tc0->rcv_nxt += 1;
2388                   tc0->state = TCP_STATE_FIN_WAIT_2;
2389                   TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2390
2391                   if (tcp_fin (tcp0))
2392                     {
2393                       /* Stop all timers, 2MSL will be set lower */
2394                       tcp_connection_timers_reset (tc0);
2395                     }
2396                   else
2397                     {
2398                       /* Wait for peer to finish sending its data */
2399                       tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE,
2400                                         TCP_2MSL_TIME);
2401                     }
2402                 }
2403               break;
2404             case TCP_STATE_FIN_WAIT_2:
2405               /* In addition to the processing for the ESTABLISHED state, if
2406                * the retransmission queue is empty, the user's CLOSE can be
2407                * acknowledged ("ok") but do not delete the TCB. */
2408               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
2409                 goto drop;
2410               break;
2411             case TCP_STATE_CLOSE_WAIT:
2412               /* Do the same processing as for the ESTABLISHED state. */
2413               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
2414                 goto drop;
2415               break;
2416             case TCP_STATE_CLOSING:
2417               /* In addition to the processing for the ESTABLISHED state, if
2418                * the ACK acknowledges our FIN then enter the TIME-WAIT state,
2419                * otherwise ignore the segment. */
2420               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
2421                 goto drop;
2422
2423               tc0->state = TCP_STATE_TIME_WAIT;
2424               TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2425               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
2426               goto drop;
2427
2428               break;
2429             case TCP_STATE_LAST_ACK:
2430               /* The only thing that [should] arrive in this state is an
2431                * acknowledgment of our FIN. If our FIN is now acknowledged,
2432                * delete the TCB, enter the CLOSED state, and return. */
2433
2434               if (!tcp_rcv_ack_is_acceptable (tc0, b0))
2435                 goto drop;
2436
2437               /* Apparently our FIN was lost */
2438               if (tcp_fin (tcp0))
2439                 {
2440                   /* Don't "make" fin since that increments snd_nxt */
2441                   tcp_send_fin (tc0);
2442                   goto drop;
2443                 }
2444
2445               tc0->state = TCP_STATE_CLOSED;
2446               TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2447
2448               /* Don't delete the connection/session yet. Instead, wait a
2449                * reasonable amount of time until the pipes are cleared. In
2450                * particular, this makes sure that we won't have dead sessions
2451                * when processing events on the tx path */
2452               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_CLEANUP_TIME);
2453
2454               /* Stop retransmit */
2455               tcp_retransmit_timer_reset (tc0);
2456
2457               goto drop;
2458
2459               break;
2460             case TCP_STATE_TIME_WAIT:
2461               /* The only thing that can arrive in this state is a
2462                * retransmission of the remote FIN. Acknowledge it, and restart
2463                * the 2 MSL timeout. */
2464
2465               if (tcp_rcv_ack (tc0, b0, tcp0, &next0, &error0))
2466                 goto drop;
2467
2468               tcp_make_ack (tc0, b0);
2469               tcp_timer_reset (tc0, TCP_TIMER_WAITCLOSE);
2470               tcp_timer_set (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
2471
2472               goto drop;
2473
2474               break;
2475             default:
2476               ASSERT (0);
2477             }
2478
2479           /* 6: check the URG bit TODO */
2480
2481           /* 7: process the segment text */
2482           switch (tc0->state)
2483             {
2484             case TCP_STATE_ESTABLISHED:
2485             case TCP_STATE_FIN_WAIT_1:
2486             case TCP_STATE_FIN_WAIT_2:
2487               if (vnet_buffer (b0)->tcp.data_len)
2488                 error0 = tcp_segment_rcv (tm, tc0, b0, &next0);
2489               break;
2490             case TCP_STATE_CLOSE_WAIT:
2491             case TCP_STATE_CLOSING:
2492             case TCP_STATE_LAST_ACK:
2493             case TCP_STATE_TIME_WAIT:
2494               /* This should not occur, since a FIN has been received from the
2495                * remote side.  Ignore the segment text. */
2496               break;
2497             }
2498
2499           /* 8: check the FIN bit */
2500           if (!tcp_fin (tcp0))
2501             goto drop;
2502
2503           switch (tc0->state)
2504             {
2505             case TCP_STATE_ESTABLISHED:
2506             case TCP_STATE_SYN_RCVD:
2507               /* Send FIN-ACK notify app and enter CLOSE-WAIT */
2508               tcp_connection_timers_reset (tc0);
2509               tcp_make_fin (tc0, b0);
2510               tc0->snd_nxt += 1;
2511               next0 = tcp_next_output (tc0->c_is_ip4);
2512               stream_session_disconnect_notify (&tc0->connection);
2513               tc0->state = TCP_STATE_CLOSE_WAIT;
2514               TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2515               break;
2516             case TCP_STATE_CLOSE_WAIT:
2517             case TCP_STATE_CLOSING:
2518             case TCP_STATE_LAST_ACK:
2519               /* move along .. */
2520               break;
2521             case TCP_STATE_FIN_WAIT_1:
2522               tc0->state = TCP_STATE_CLOSING;
2523               tcp_make_ack (tc0, b0);
2524               next0 = tcp_next_output (is_ip4);
2525               TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2526               /* Wait for ACK but not forever */
2527               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
2528               break;
2529             case TCP_STATE_FIN_WAIT_2:
2530               /* Got FIN, send ACK! */
2531               tc0->state = TCP_STATE_TIME_WAIT;
2532               tcp_connection_timers_reset (tc0);
2533               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
2534               tcp_make_ack (tc0, b0);
2535               next0 = tcp_next_output (is_ip4);
2536               TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0);
2537               break;
2538             case TCP_STATE_TIME_WAIT:
2539               /* Remain in the TIME-WAIT state. Restart the 2 MSL time-wait
2540                * timeout.
2541                */
2542               tcp_timer_update (tc0, TCP_TIMER_WAITCLOSE, TCP_2MSL_TIME);
2543               break;
2544             }
2545           TCP_EVT_DBG (TCP_EVT_FIN_RCVD, tc0);
2546
2547         drop:
2548           b0->error = error0 ? node->errors[error0] : 0;
2549
2550           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2551             {
2552               tcp_rx_trace_t *t0 =
2553                 vlib_add_trace (vm, node, b0, sizeof (*t0));
2554               tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4);
2555             }
2556
2557           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2558                                            n_left_to_next, bi0, next0);
2559         }
2560
2561       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2562     }
2563
2564   errors = session_manager_flush_enqueue_events (my_thread_index);
2565   if (errors)
2566     {
2567       if (is_ip4)
2568         vlib_node_increment_counter (vm, tcp4_established_node.index,
2569                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
2570       else
2571         vlib_node_increment_counter (vm, tcp6_established_node.index,
2572                                      TCP_ERROR_EVENT_FIFO_FULL, errors);
2573     }
2574
2575   return from_frame->n_vectors;
2576 }
2577
2578 static uword
2579 tcp4_rcv_process (vlib_main_t * vm, vlib_node_runtime_t * node,
2580                   vlib_frame_t * from_frame)
2581 {
2582   return tcp46_rcv_process_inline (vm, node, from_frame, 1 /* is_ip4 */ );
2583 }
2584
2585 static uword
2586 tcp6_rcv_process (vlib_main_t * vm, vlib_node_runtime_t * node,
2587                   vlib_frame_t * from_frame)
2588 {
2589   return tcp46_rcv_process_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2590 }
2591
2592 /* *INDENT-OFF* */
2593 VLIB_REGISTER_NODE (tcp4_rcv_process_node) =
2594 {
2595   .function = tcp4_rcv_process,
2596   .name = "tcp4-rcv-process",
2597   /* Takes a vector of packets. */
2598   .vector_size = sizeof (u32),
2599   .n_errors = TCP_N_ERROR,
2600   .error_strings = tcp_error_strings,
2601   .n_next_nodes = TCP_RCV_PROCESS_N_NEXT,
2602   .next_nodes =
2603   {
2604 #define _(s,n) [TCP_RCV_PROCESS_NEXT_##s] = n,
2605     foreach_tcp_state_next
2606 #undef _
2607   },
2608   .format_trace = format_tcp_rx_trace_short,
2609 };
2610 /* *INDENT-ON* */
2611
2612 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_rcv_process_node, tcp4_rcv_process);
2613
2614 /* *INDENT-OFF* */
2615 VLIB_REGISTER_NODE (tcp6_rcv_process_node) =
2616 {
2617   .function = tcp6_rcv_process,
2618   .name = "tcp6-rcv-process",
2619   /* Takes a vector of packets. */
2620   .vector_size = sizeof (u32),
2621   .n_errors = TCP_N_ERROR,
2622   .error_strings = tcp_error_strings,
2623   .n_next_nodes = TCP_RCV_PROCESS_N_NEXT,
2624   .next_nodes =
2625   {
2626 #define _(s,n) [TCP_RCV_PROCESS_NEXT_##s] = n,
2627     foreach_tcp_state_next
2628 #undef _
2629   },
2630   .format_trace = format_tcp_rx_trace_short,
2631 };
2632 /* *INDENT-ON* */
2633
2634 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_rcv_process_node, tcp6_rcv_process);
2635
2636 vlib_node_registration_t tcp4_listen_node;
2637 vlib_node_registration_t tcp6_listen_node;
2638
2639 /**
2640  * LISTEN state processing as per RFC 793 p. 65
2641  */
2642 always_inline uword
2643 tcp46_listen_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2644                      vlib_frame_t * from_frame, int is_ip4)
2645 {
2646   u32 n_left_from, next_index, *from, *to_next;
2647   u32 my_thread_index = vm->thread_index;
2648   u8 sst = is_ip4 ? SESSION_TYPE_IP4_TCP : SESSION_TYPE_IP6_TCP;
2649
2650   from = vlib_frame_vector_args (from_frame);
2651   n_left_from = from_frame->n_vectors;
2652
2653   next_index = node->cached_next_index;
2654
2655   while (n_left_from > 0)
2656     {
2657       u32 n_left_to_next;
2658
2659       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2660
2661       while (n_left_from > 0 && n_left_to_next > 0)
2662         {
2663           u32 bi0;
2664           vlib_buffer_t *b0;
2665           tcp_rx_trace_t *t0;
2666           tcp_header_t *th0 = 0;
2667           tcp_connection_t *lc0;
2668           ip4_header_t *ip40;
2669           ip6_header_t *ip60;
2670           tcp_connection_t *child0;
2671           u32 error0 = TCP_ERROR_SYNS_RCVD, next0 = TCP_LISTEN_NEXT_DROP;
2672
2673           bi0 = from[0];
2674           to_next[0] = bi0;
2675           from += 1;
2676           to_next += 1;
2677           n_left_from -= 1;
2678           n_left_to_next -= 1;
2679
2680           b0 = vlib_get_buffer (vm, bi0);
2681           lc0 = tcp_listener_get (vnet_buffer (b0)->tcp.connection_index);
2682
2683           if (is_ip4)
2684             {
2685               ip40 = vlib_buffer_get_current (b0);
2686               th0 = ip4_next_header (ip40);
2687             }
2688           else
2689             {
2690               ip60 = vlib_buffer_get_current (b0);
2691               th0 = ip6_next_header (ip60);
2692             }
2693
2694           /* Create child session. For syn-flood protection use filter */
2695
2696           /* 1. first check for an RST: handled in dispatch */
2697           /* if (tcp_rst (th0))
2698              goto drop; */
2699
2700           /* 2. second check for an ACK: handled in dispatch */
2701           /* if (tcp_ack (th0))
2702              {
2703              tcp_send_reset (b0, is_ip4);
2704              goto drop;
2705              } */
2706
2707           /* 3. check for a SYN (did that already) */
2708
2709           /* Make sure connection wasn't just created */
2710           child0 = tcp_lookup_connection (b0, my_thread_index, is_ip4);
2711           if (PREDICT_FALSE (child0->state != TCP_STATE_LISTEN))
2712             {
2713               error0 = TCP_ERROR_CREATE_EXISTS;
2714               goto drop;
2715             }
2716
2717           /* Create child session and send SYN-ACK */
2718           child0 = tcp_connection_new (my_thread_index);
2719           child0->c_lcl_port = lc0->c_lcl_port;
2720           child0->c_rmt_port = th0->src_port;
2721           child0->c_is_ip4 = is_ip4;
2722           child0->state = TCP_STATE_SYN_RCVD;
2723
2724           if (is_ip4)
2725             {
2726               child0->c_lcl_ip4.as_u32 = ip40->dst_address.as_u32;
2727               child0->c_rmt_ip4.as_u32 = ip40->src_address.as_u32;
2728             }
2729           else
2730             {
2731               clib_memcpy (&child0->c_lcl_ip6, &ip60->dst_address,
2732                            sizeof (ip6_address_t));
2733               clib_memcpy (&child0->c_rmt_ip6, &ip60->src_address,
2734                            sizeof (ip6_address_t));
2735             }
2736
2737           if (stream_session_accept (&child0->connection, lc0->c_s_index, sst,
2738                                      0 /* notify */ ))
2739             {
2740               clib_warning ("session accept fail");
2741               tcp_connection_cleanup (child0);
2742               error0 = TCP_ERROR_CREATE_SESSION_FAIL;
2743               goto drop;
2744             }
2745
2746           if (tcp_options_parse (th0, &child0->rcv_opts))
2747             {
2748               clib_warning ("options parse fail");
2749               goto drop;
2750             }
2751
2752           child0->irs = vnet_buffer (b0)->tcp.seq_number;
2753           child0->rcv_nxt = vnet_buffer (b0)->tcp.seq_number + 1;
2754           child0->rcv_las = child0->rcv_nxt;
2755
2756           /* RFC1323: TSval timestamps sent on {SYN} and {SYN,ACK}
2757            * segments are used to initialize PAWS. */
2758           if (tcp_opts_tstamp (&child0->rcv_opts))
2759             {
2760               child0->tsval_recent = child0->rcv_opts.tsval;
2761               child0->tsval_recent_age = tcp_time_now ();
2762             }
2763
2764           if (tcp_opts_wscale (&child0->rcv_opts))
2765             child0->snd_wscale = child0->rcv_opts.wscale;
2766
2767           child0->snd_wnd = clib_net_to_host_u16 (th0->window)
2768             << child0->snd_wscale;
2769           child0->snd_wl1 = vnet_buffer (b0)->tcp.seq_number;
2770           child0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number;
2771
2772           tcp_connection_init_vars (child0);
2773           TCP_EVT_DBG (TCP_EVT_SYN_RCVD, child0, 1);
2774
2775           /* Reuse buffer to make syn-ack and send */
2776           tcp_make_synack (child0, b0);
2777           next0 = tcp_next_output (is_ip4);
2778           tcp_timer_set (child0, TCP_TIMER_ESTABLISH, TCP_SYN_RCVD_TIME);
2779
2780         drop:
2781           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2782             {
2783               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
2784               clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
2785               clib_memcpy (&t0->tcp_connection, lc0,
2786                            sizeof (t0->tcp_connection));
2787             }
2788
2789           b0->error = node->errors[error0];
2790
2791           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2792                                            n_left_to_next, bi0, next0);
2793         }
2794
2795       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2796     }
2797   return from_frame->n_vectors;
2798 }
2799
2800 static uword
2801 tcp4_listen (vlib_main_t * vm, vlib_node_runtime_t * node,
2802              vlib_frame_t * from_frame)
2803 {
2804   return tcp46_listen_inline (vm, node, from_frame, 1 /* is_ip4 */ );
2805 }
2806
2807 static uword
2808 tcp6_listen (vlib_main_t * vm, vlib_node_runtime_t * node,
2809              vlib_frame_t * from_frame)
2810 {
2811   return tcp46_listen_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2812 }
2813
2814 /* *INDENT-OFF* */
2815 VLIB_REGISTER_NODE (tcp4_listen_node) =
2816 {
2817   .function = tcp4_listen,
2818   .name = "tcp4-listen",
2819   /* Takes a vector of packets. */
2820   .vector_size = sizeof (u32),
2821   .n_errors = TCP_N_ERROR,
2822   .error_strings = tcp_error_strings,
2823   .n_next_nodes = TCP_LISTEN_N_NEXT,
2824   .next_nodes =
2825   {
2826 #define _(s,n) [TCP_LISTEN_NEXT_##s] = n,
2827     foreach_tcp_state_next
2828 #undef _
2829   },
2830   .format_trace = format_tcp_rx_trace_short,
2831 };
2832 /* *INDENT-ON* */
2833
2834 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_listen_node, tcp4_listen);
2835
2836 /* *INDENT-OFF* */
2837 VLIB_REGISTER_NODE (tcp6_listen_node) =
2838 {
2839   .function = tcp6_listen,
2840   .name = "tcp6-listen",
2841   /* Takes a vector of packets. */
2842   .vector_size = sizeof (u32),
2843   .n_errors = TCP_N_ERROR,
2844   .error_strings = tcp_error_strings,
2845   .n_next_nodes = TCP_LISTEN_N_NEXT,
2846   .next_nodes =
2847   {
2848 #define _(s,n) [TCP_LISTEN_NEXT_##s] = n,
2849     foreach_tcp_state_next
2850 #undef _
2851   },
2852   .format_trace = format_tcp_rx_trace_short,
2853 };
2854 /* *INDENT-ON* */
2855
2856 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_listen_node, tcp6_listen);
2857
2858 vlib_node_registration_t tcp4_input_node;
2859 vlib_node_registration_t tcp6_input_node;
2860
2861 typedef enum _tcp_input_next
2862 {
2863   TCP_INPUT_NEXT_DROP,
2864   TCP_INPUT_NEXT_LISTEN,
2865   TCP_INPUT_NEXT_RCV_PROCESS,
2866   TCP_INPUT_NEXT_SYN_SENT,
2867   TCP_INPUT_NEXT_ESTABLISHED,
2868   TCP_INPUT_NEXT_RESET,
2869   TCP_INPUT_N_NEXT
2870 } tcp_input_next_t;
2871
2872 #define foreach_tcp4_input_next                 \
2873   _ (DROP, "error-drop")                        \
2874   _ (LISTEN, "tcp4-listen")                     \
2875   _ (RCV_PROCESS, "tcp4-rcv-process")           \
2876   _ (SYN_SENT, "tcp4-syn-sent")                 \
2877   _ (ESTABLISHED, "tcp4-established")           \
2878   _ (RESET, "tcp4-reset")
2879
2880 #define foreach_tcp6_input_next                 \
2881   _ (DROP, "error-drop")                        \
2882   _ (LISTEN, "tcp6-listen")                     \
2883   _ (RCV_PROCESS, "tcp6-rcv-process")           \
2884   _ (SYN_SENT, "tcp6-syn-sent")                 \
2885   _ (ESTABLISHED, "tcp6-established")           \
2886   _ (RESET, "tcp6-reset")
2887
2888 #define filter_flags (TCP_FLAG_SYN|TCP_FLAG_ACK|TCP_FLAG_RST|TCP_FLAG_FIN)
2889
2890 always_inline uword
2891 tcp46_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2892                     vlib_frame_t * from_frame, int is_ip4)
2893 {
2894   u32 n_left_from, next_index, *from, *to_next;
2895   u32 my_thread_index = vm->thread_index;
2896   tcp_main_t *tm = vnet_get_tcp_main ();
2897
2898   from = vlib_frame_vector_args (from_frame);
2899   n_left_from = from_frame->n_vectors;
2900   next_index = node->cached_next_index;
2901   tcp_set_time_now (my_thread_index);
2902
2903   while (n_left_from > 0)
2904     {
2905       u32 n_left_to_next;
2906
2907       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2908
2909       while (n_left_from > 0 && n_left_to_next > 0)
2910         {
2911           int n_advance_bytes0, n_data_bytes0;
2912           u32 bi0;
2913           vlib_buffer_t *b0;
2914           tcp_header_t *tcp0 = 0;
2915           tcp_connection_t *tc0;
2916           transport_connection_t *tconn;
2917           ip4_header_t *ip40;
2918           ip6_header_t *ip60;
2919           u32 error0 = TCP_ERROR_NO_LISTENER, next0 = TCP_INPUT_NEXT_DROP;
2920           u8 flags0;
2921
2922           bi0 = from[0];
2923           to_next[0] = bi0;
2924           from += 1;
2925           to_next += 1;
2926           n_left_from -= 1;
2927           n_left_to_next -= 1;
2928
2929           b0 = vlib_get_buffer (vm, bi0);
2930           vnet_buffer (b0)->tcp.flags = 0;
2931
2932           /* Checksum computed by ipx_local no need to compute again */
2933
2934           if (is_ip4)
2935             {
2936               ip40 = vlib_buffer_get_current (b0);
2937               tcp0 = ip4_next_header (ip40);
2938               n_advance_bytes0 = (ip4_header_bytes (ip40)
2939                                   + tcp_header_bytes (tcp0));
2940               n_data_bytes0 = clib_net_to_host_u16 (ip40->length)
2941                 - n_advance_bytes0;
2942               tconn = stream_session_lookup_transport_wt4 (&ip40->dst_address,
2943                                                            &ip40->src_address,
2944                                                            tcp0->dst_port,
2945                                                            tcp0->src_port,
2946                                                            SESSION_TYPE_IP4_TCP,
2947                                                            my_thread_index);
2948               tc0 = tcp_get_connection_from_transport (tconn);
2949               ASSERT (tcp_lookup_is_valid (tc0, tcp0));
2950             }
2951           else
2952             {
2953               ip60 = vlib_buffer_get_current (b0);
2954               tcp0 = ip6_next_header (ip60);
2955               n_advance_bytes0 = tcp_header_bytes (tcp0);
2956               n_data_bytes0 = clib_net_to_host_u16 (ip60->payload_length)
2957                 - n_advance_bytes0;
2958               n_advance_bytes0 += sizeof (ip60[0]);
2959               tconn = stream_session_lookup_transport_wt6 (&ip60->dst_address,
2960                                                            &ip60->src_address,
2961                                                            tcp0->dst_port,
2962                                                            tcp0->src_port,
2963                                                            SESSION_TYPE_IP6_TCP,
2964                                                            my_thread_index);
2965               tc0 = tcp_get_connection_from_transport (tconn);
2966               ASSERT (tcp_lookup_is_valid (tc0, tcp0));
2967             }
2968
2969           /* Length check */
2970           if (PREDICT_FALSE (n_advance_bytes0 < 0))
2971             {
2972               error0 = TCP_ERROR_LENGTH;
2973               goto done;
2974             }
2975
2976           /* Session exists */
2977           if (PREDICT_TRUE (0 != tc0))
2978             {
2979               /* Save connection index */
2980               vnet_buffer (b0)->tcp.connection_index = tc0->c_c_index;
2981               vnet_buffer (b0)->tcp.seq_number =
2982                 clib_net_to_host_u32 (tcp0->seq_number);
2983               vnet_buffer (b0)->tcp.ack_number =
2984                 clib_net_to_host_u32 (tcp0->ack_number);
2985
2986               vnet_buffer (b0)->tcp.hdr_offset = (u8 *) tcp0
2987                 - (u8 *) vlib_buffer_get_current (b0);
2988               vnet_buffer (b0)->tcp.data_offset = n_advance_bytes0;
2989               vnet_buffer (b0)->tcp.data_len = n_data_bytes0;
2990
2991               flags0 = tcp0->flags & filter_flags;
2992               next0 = tm->dispatch_table[tc0->state][flags0].next;
2993               error0 = tm->dispatch_table[tc0->state][flags0].error;
2994
2995               if (PREDICT_FALSE (error0 == TCP_ERROR_DISPATCH
2996                                  || next0 == TCP_INPUT_NEXT_RESET))
2997                 {
2998                   /* Overload tcp flags to store state */
2999                   tcp_state_t state0 = tc0->state;
3000                   vnet_buffer (b0)->tcp.flags = tc0->state;
3001
3002                   if (error0 == TCP_ERROR_DISPATCH)
3003                     clib_warning ("disp error state %U flags %U",
3004                                   format_tcp_state, state0, format_tcp_flags,
3005                                   (int) flags0);
3006                 }
3007             }
3008           else
3009             {
3010               /* Send reset */
3011               next0 = TCP_INPUT_NEXT_RESET;
3012               error0 = TCP_ERROR_NO_LISTENER;
3013             }
3014
3015         done:
3016           b0->error = error0 ? node->errors[error0] : 0;
3017
3018           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
3019             {
3020               tcp_rx_trace_t *t0 =
3021                 vlib_add_trace (vm, node, b0, sizeof (*t0));
3022               tcp_set_rx_trace_data (t0, tc0, tcp0, b0, is_ip4);
3023             }
3024           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
3025                                            n_left_to_next, bi0, next0);
3026         }
3027
3028       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
3029     }
3030
3031   return from_frame->n_vectors;
3032 }
3033
3034 static uword
3035 tcp4_input (vlib_main_t * vm, vlib_node_runtime_t * node,
3036             vlib_frame_t * from_frame)
3037 {
3038   return tcp46_input_inline (vm, node, from_frame, 1 /* is_ip4 */ );
3039 }
3040
3041 static uword
3042 tcp6_input (vlib_main_t * vm, vlib_node_runtime_t * node,
3043             vlib_frame_t * from_frame)
3044 {
3045   return tcp46_input_inline (vm, node, from_frame, 0 /* is_ip4 */ );
3046 }
3047
3048 /* *INDENT-OFF* */
3049 VLIB_REGISTER_NODE (tcp4_input_node) =
3050 {
3051   .function = tcp4_input,
3052   .name = "tcp4-input",
3053   /* Takes a vector of packets. */
3054   .vector_size = sizeof (u32),
3055   .n_errors = TCP_N_ERROR,
3056   .error_strings = tcp_error_strings,
3057   .n_next_nodes = TCP_INPUT_N_NEXT,
3058   .next_nodes =
3059   {
3060 #define _(s,n) [TCP_INPUT_NEXT_##s] = n,
3061     foreach_tcp4_input_next
3062 #undef _
3063   },
3064   .format_buffer = format_tcp_header,
3065   .format_trace = format_tcp_rx_trace,
3066 };
3067 /* *INDENT-ON* */
3068
3069 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_input_node, tcp4_input);
3070
3071 /* *INDENT-OFF* */
3072 VLIB_REGISTER_NODE (tcp6_input_node) =
3073 {
3074   .function = tcp6_input,
3075   .name = "tcp6-input",
3076   /* Takes a vector of packets. */
3077   .vector_size = sizeof (u32),
3078   .n_errors = TCP_N_ERROR,
3079   .error_strings = tcp_error_strings,
3080   .n_next_nodes = TCP_INPUT_N_NEXT,
3081   .next_nodes =
3082   {
3083 #define _(s,n) [TCP_INPUT_NEXT_##s] = n,
3084     foreach_tcp6_input_next
3085 #undef _
3086   },
3087   .format_buffer = format_tcp_header,
3088   .format_trace = format_tcp_rx_trace,
3089 };
3090 /* *INDENT-ON* */
3091
3092 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_input_node, tcp6_input);
3093
3094 static void
3095 tcp_dispatch_table_init (tcp_main_t * tm)
3096 {
3097   int i, j;
3098   for (i = 0; i < ARRAY_LEN (tm->dispatch_table); i++)
3099     for (j = 0; j < ARRAY_LEN (tm->dispatch_table[i]); j++)
3100       {
3101         tm->dispatch_table[i][j].next = TCP_INPUT_NEXT_DROP;
3102         tm->dispatch_table[i][j].error = TCP_ERROR_DISPATCH;
3103       }
3104
3105 #define _(t,f,n,e)                                              \
3106 do {                                                            \
3107     tm->dispatch_table[TCP_STATE_##t][f].next = (n);            \
3108     tm->dispatch_table[TCP_STATE_##t][f].error = (e);           \
3109 } while (0)
3110
3111   /* SYNs for new connections -> tcp-listen. */
3112   _(LISTEN, TCP_FLAG_SYN, TCP_INPUT_NEXT_LISTEN, TCP_ERROR_NONE);
3113   _(LISTEN, TCP_FLAG_ACK, TCP_INPUT_NEXT_RESET, TCP_ERROR_NONE);
3114   _(LISTEN, TCP_FLAG_RST, TCP_INPUT_NEXT_DROP, TCP_ERROR_NONE);
3115   _(LISTEN, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RESET,
3116     TCP_ERROR_NONE);
3117   /* ACK for for a SYN-ACK -> tcp-rcv-process. */
3118   _(SYN_RCVD, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3119   _(SYN_RCVD, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3120   _(SYN_RCVD, TCP_FLAG_SYN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3121   /* SYN-ACK for a SYN */
3122   _(SYN_SENT, TCP_FLAG_SYN | TCP_FLAG_ACK, TCP_INPUT_NEXT_SYN_SENT,
3123     TCP_ERROR_NONE);
3124   _(SYN_SENT, TCP_FLAG_ACK, TCP_INPUT_NEXT_SYN_SENT, TCP_ERROR_NONE);
3125   _(SYN_SENT, TCP_FLAG_RST, TCP_INPUT_NEXT_SYN_SENT, TCP_ERROR_NONE);
3126   _(SYN_SENT, TCP_FLAG_RST | TCP_FLAG_ACK, TCP_INPUT_NEXT_SYN_SENT,
3127     TCP_ERROR_NONE);
3128   /* ACK for for established connection -> tcp-established. */
3129   _(ESTABLISHED, TCP_FLAG_ACK, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
3130   /* FIN for for established connection -> tcp-established. */
3131   _(ESTABLISHED, TCP_FLAG_FIN, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
3132   _(ESTABLISHED, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_ESTABLISHED,
3133     TCP_ERROR_NONE);
3134   _(ESTABLISHED, TCP_FLAG_RST, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
3135   _(ESTABLISHED, TCP_FLAG_RST | TCP_FLAG_ACK, TCP_INPUT_NEXT_ESTABLISHED,
3136     TCP_ERROR_NONE);
3137   _(ESTABLISHED, TCP_FLAG_SYN, TCP_INPUT_NEXT_ESTABLISHED, TCP_ERROR_NONE);
3138   _(ESTABLISHED, TCP_FLAG_SYN | TCP_FLAG_ACK, TCP_INPUT_NEXT_ESTABLISHED,
3139     TCP_ERROR_NONE);
3140   /* ACK or FIN-ACK to our FIN */
3141   _(FIN_WAIT_1, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3142   _(FIN_WAIT_1, TCP_FLAG_ACK | TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS,
3143     TCP_ERROR_NONE);
3144   /* FIN in reply to our FIN from the other side */
3145   _(FIN_WAIT_1, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3146   _(FIN_WAIT_1, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3147   /* FIN confirming that the peer (app) has closed */
3148   _(FIN_WAIT_2, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3149   _(FIN_WAIT_2, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3150   _(FIN_WAIT_2, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS,
3151     TCP_ERROR_NONE);
3152   _(CLOSE_WAIT, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3153   _(CLOSE_WAIT, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS,
3154     TCP_ERROR_NONE);
3155   _(LAST_ACK, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3156   _(LAST_ACK, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3157   _(LAST_ACK, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS,
3158     TCP_ERROR_NONE);
3159   _(LAST_ACK, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3160   _(TIME_WAIT, TCP_FLAG_FIN, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3161   _(TIME_WAIT, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS,
3162     TCP_ERROR_NONE);
3163   _(TIME_WAIT, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3164   _(TIME_WAIT, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE);
3165   _(CLOSED, TCP_FLAG_ACK, TCP_INPUT_NEXT_RESET, TCP_ERROR_CONNECTION_CLOSED);
3166   _(CLOSED, TCP_FLAG_RST, TCP_INPUT_NEXT_DROP, TCP_ERROR_CONNECTION_CLOSED);
3167   _(CLOSED, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RESET,
3168     TCP_ERROR_CONNECTION_CLOSED);
3169 #undef _
3170 }
3171
3172 clib_error_t *
3173 tcp_input_init (vlib_main_t * vm)
3174 {
3175   clib_error_t *error = 0;
3176   tcp_main_t *tm = vnet_get_tcp_main ();
3177
3178   if ((error = vlib_call_init_function (vm, tcp_init)))
3179     return error;
3180
3181   /* Initialize dispatch table. */
3182   tcp_dispatch_table_init (tm);
3183
3184   return error;
3185 }
3186
3187 VLIB_INIT_FUNCTION (tcp_input_init);
3188
3189 /*
3190  * fd.io coding-style-patch-verification: ON
3191  *
3192  * Local Variables:
3193  * eval: (c-set-style "gnu")
3194  * End:
3195  */