tcp: add more connection stats
[vpp.git] / src / vnet / tcp / tcp_output.c
1 /*
2  * Copyright (c) 2016-2019 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 <vnet/tcp/tcp.h>
17 #include <math.h>
18
19 typedef enum _tcp_output_next
20 {
21   TCP_OUTPUT_NEXT_DROP,
22   TCP_OUTPUT_NEXT_IP_LOOKUP,
23   TCP_OUTPUT_NEXT_IP_REWRITE,
24   TCP_OUTPUT_NEXT_IP_ARP,
25   TCP_OUTPUT_N_NEXT
26 } tcp_output_next_t;
27
28 #define foreach_tcp4_output_next                \
29   _ (DROP, "error-drop")                        \
30   _ (IP_LOOKUP, "ip4-lookup")                   \
31   _ (IP_REWRITE, "ip4-rewrite")                 \
32   _ (IP_ARP, "ip4-arp")
33
34 #define foreach_tcp6_output_next                \
35   _ (DROP, "error-drop")                        \
36   _ (IP_LOOKUP, "ip6-lookup")                   \
37   _ (IP_REWRITE, "ip6-rewrite")                 \
38   _ (IP_ARP, "ip6-discover-neighbor")
39
40 static char *tcp_error_strings[] = {
41 #define tcp_error(n,s) s,
42 #include <vnet/tcp/tcp_error.def>
43 #undef tcp_error
44 };
45
46 typedef struct
47 {
48   tcp_header_t tcp_header;
49   tcp_connection_t tcp_connection;
50 } tcp_tx_trace_t;
51
52 static u8 *
53 format_tcp_tx_trace (u8 * s, va_list * args)
54 {
55   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
56   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
57   tcp_tx_trace_t *t = va_arg (*args, tcp_tx_trace_t *);
58   u32 indent = format_get_indent (s);
59
60   s = format (s, "%U\n%U%U",
61               format_tcp_header, &t->tcp_header, 128,
62               format_white_space, indent,
63               format_tcp_connection, &t->tcp_connection, 1);
64
65   return s;
66 }
67
68 #ifndef CLIB_MARCH_VARIANT
69 static u8
70 tcp_window_compute_scale (u32 window)
71 {
72   u8 wnd_scale = 0;
73   while (wnd_scale < TCP_MAX_WND_SCALE && (window >> wnd_scale) > TCP_WND_MAX)
74     wnd_scale++;
75   return wnd_scale;
76 }
77
78 /**
79  * Update max segment size we're able to process.
80  *
81  * The value is constrained by our interface's MTU and IP options. It is
82  * also what we advertise to our peer.
83  */
84 void
85 tcp_update_rcv_mss (tcp_connection_t * tc)
86 {
87   /* TODO find our iface MTU */
88   tc->mss = tcp_main.default_mtu - sizeof (tcp_header_t);
89 }
90
91 /**
92  * TCP's initial window
93  */
94 always_inline u32
95 tcp_initial_wnd_unscaled (tcp_connection_t * tc)
96 {
97   /* RFC 6928 recommends the value lower. However at the time our connections
98    * are initialized, fifos may not be allocated. Therefore, advertise the
99    * smallest possible unscaled window size and update once fifos are
100    * assigned to the session.
101    */
102   /*
103      tcp_update_rcv_mss (tc);
104      TCP_IW_N_SEGMENTS * tc->mss;
105    */
106   return TCP_MIN_RX_FIFO_SIZE;
107 }
108
109 /**
110  * Compute initial window and scale factor. As per RFC1323, window field in
111  * SYN and SYN-ACK segments is never scaled.
112  */
113 u32
114 tcp_initial_window_to_advertise (tcp_connection_t * tc)
115 {
116   tcp_main_t *tm = &tcp_main;
117   u32 max_fifo;
118
119   /* Initial wnd for SYN. Fifos are not allocated yet.
120    * Use some predefined value. For SYN-ACK we still want the
121    * scale to be computed in the same way */
122   max_fifo = tm->max_rx_fifo ? tm->max_rx_fifo : TCP_MAX_RX_FIFO_SIZE;
123
124   /* Compute rcv wscale only if peer advertised support for it */
125   if (tc->state != TCP_STATE_SYN_RCVD || tcp_opts_wscale (&tc->rcv_opts))
126     tc->rcv_wscale = tcp_window_compute_scale (max_fifo);
127
128   tc->rcv_wnd = tcp_initial_wnd_unscaled (tc);
129
130   return clib_min (tc->rcv_wnd, TCP_WND_MAX);
131 }
132
133 static inline void
134 tcp_update_rcv_wnd (tcp_connection_t * tc)
135 {
136   u32 available_space, wnd;
137   i32 observed_wnd;
138
139   ASSERT (tc->rcv_opts.mss < transport_rx_fifo_size (&tc->connection));
140
141   /*
142    * Figure out how much space we have available
143    */
144   available_space = transport_max_rx_enqueue (&tc->connection);
145   if (PREDICT_FALSE (available_space < tc->rcv_opts.mss))
146     available_space = 0;
147
148   /*
149    * Use the above and what we know about what we've previously advertised
150    * to compute the new window
151    */
152   observed_wnd = (i32) tc->rcv_wnd - (tc->rcv_nxt - tc->rcv_las);
153
154   /* Bad. Thou shalt not shrink */
155   if (PREDICT_FALSE ((i32) available_space < observed_wnd))
156     {
157       wnd = clib_max (observed_wnd, 0);
158       TCP_EVT_DBG (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space);
159     }
160   else
161     {
162       wnd = available_space;
163     }
164
165   /* Make sure we have a multiple of rcv_wscale */
166   if (wnd && tc->rcv_wscale)
167     {
168       wnd &= ~((1 << tc->rcv_wscale) - 1);
169       if (wnd == 0)
170         wnd = 1 << tc->rcv_wscale;
171     }
172
173   tc->rcv_wnd = clib_min (wnd, TCP_WND_MAX << tc->rcv_wscale);
174 }
175
176 /**
177  * Compute and return window to advertise, scaled as per RFC1323
178  */
179 static inline u32
180 tcp_window_to_advertise (tcp_connection_t * tc, tcp_state_t state)
181 {
182   if (state < TCP_STATE_ESTABLISHED)
183     return tcp_initial_window_to_advertise (tc);
184
185   tcp_update_rcv_wnd (tc);
186   return tc->rcv_wnd >> tc->rcv_wscale;
187 }
188
189 /**
190  * Write TCP options to segment.
191  */
192 static u32
193 tcp_options_write (u8 * data, tcp_options_t * opts)
194 {
195   u32 opts_len = 0;
196   u32 buf, seq_len = 4;
197
198   if (tcp_opts_mss (opts))
199     {
200       *data++ = TCP_OPTION_MSS;
201       *data++ = TCP_OPTION_LEN_MSS;
202       buf = clib_host_to_net_u16 (opts->mss);
203       clib_memcpy_fast (data, &buf, sizeof (opts->mss));
204       data += sizeof (opts->mss);
205       opts_len += TCP_OPTION_LEN_MSS;
206     }
207
208   if (tcp_opts_wscale (opts))
209     {
210       *data++ = TCP_OPTION_WINDOW_SCALE;
211       *data++ = TCP_OPTION_LEN_WINDOW_SCALE;
212       *data++ = opts->wscale;
213       opts_len += TCP_OPTION_LEN_WINDOW_SCALE;
214     }
215
216   if (tcp_opts_sack_permitted (opts))
217     {
218       *data++ = TCP_OPTION_SACK_PERMITTED;
219       *data++ = TCP_OPTION_LEN_SACK_PERMITTED;
220       opts_len += TCP_OPTION_LEN_SACK_PERMITTED;
221     }
222
223   if (tcp_opts_tstamp (opts))
224     {
225       *data++ = TCP_OPTION_TIMESTAMP;
226       *data++ = TCP_OPTION_LEN_TIMESTAMP;
227       buf = clib_host_to_net_u32 (opts->tsval);
228       clib_memcpy_fast (data, &buf, sizeof (opts->tsval));
229       data += sizeof (opts->tsval);
230       buf = clib_host_to_net_u32 (opts->tsecr);
231       clib_memcpy_fast (data, &buf, sizeof (opts->tsecr));
232       data += sizeof (opts->tsecr);
233       opts_len += TCP_OPTION_LEN_TIMESTAMP;
234     }
235
236   if (tcp_opts_sack (opts))
237     {
238       int i;
239
240       if (opts->n_sack_blocks != 0)
241         {
242           *data++ = TCP_OPTION_SACK_BLOCK;
243           *data++ = 2 + opts->n_sack_blocks * TCP_OPTION_LEN_SACK_BLOCK;
244           for (i = 0; i < opts->n_sack_blocks; i++)
245             {
246               buf = clib_host_to_net_u32 (opts->sacks[i].start);
247               clib_memcpy_fast (data, &buf, seq_len);
248               data += seq_len;
249               buf = clib_host_to_net_u32 (opts->sacks[i].end);
250               clib_memcpy_fast (data, &buf, seq_len);
251               data += seq_len;
252             }
253           opts_len += 2 + opts->n_sack_blocks * TCP_OPTION_LEN_SACK_BLOCK;
254         }
255     }
256
257   /* Terminate TCP options */
258   if (opts_len % 4)
259     {
260       *data++ = TCP_OPTION_EOL;
261       opts_len += TCP_OPTION_LEN_EOL;
262     }
263
264   /* Pad with zeroes to a u32 boundary */
265   while (opts_len % 4)
266     {
267       *data++ = TCP_OPTION_NOOP;
268       opts_len += TCP_OPTION_LEN_NOOP;
269     }
270   return opts_len;
271 }
272
273 static int
274 tcp_make_syn_options (tcp_options_t * opts, u8 wnd_scale)
275 {
276   u8 len = 0;
277
278   opts->flags |= TCP_OPTS_FLAG_MSS;
279   opts->mss = tcp_main.default_mtu;     /*XXX discover that */
280   len += TCP_OPTION_LEN_MSS;
281
282   opts->flags |= TCP_OPTS_FLAG_WSCALE;
283   opts->wscale = wnd_scale;
284   len += TCP_OPTION_LEN_WINDOW_SCALE;
285
286   opts->flags |= TCP_OPTS_FLAG_TSTAMP;
287   opts->tsval = tcp_time_now ();
288   opts->tsecr = 0;
289   len += TCP_OPTION_LEN_TIMESTAMP;
290
291   if (TCP_USE_SACKS)
292     {
293       opts->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
294       len += TCP_OPTION_LEN_SACK_PERMITTED;
295     }
296
297   /* Align to needed boundary */
298   len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
299   return len;
300 }
301
302 static int
303 tcp_make_synack_options (tcp_connection_t * tc, tcp_options_t * opts)
304 {
305   u8 len = 0;
306
307   opts->flags |= TCP_OPTS_FLAG_MSS;
308   opts->mss = tc->mss;
309   len += TCP_OPTION_LEN_MSS;
310
311   if (tcp_opts_wscale (&tc->rcv_opts))
312     {
313       opts->flags |= TCP_OPTS_FLAG_WSCALE;
314       opts->wscale = tc->rcv_wscale;
315       len += TCP_OPTION_LEN_WINDOW_SCALE;
316     }
317
318   if (tcp_opts_tstamp (&tc->rcv_opts))
319     {
320       opts->flags |= TCP_OPTS_FLAG_TSTAMP;
321       opts->tsval = tcp_time_now ();
322       opts->tsecr = tc->tsval_recent;
323       len += TCP_OPTION_LEN_TIMESTAMP;
324     }
325
326   if (tcp_opts_sack_permitted (&tc->rcv_opts))
327     {
328       opts->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
329       len += TCP_OPTION_LEN_SACK_PERMITTED;
330     }
331
332   /* Align to needed boundary */
333   len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
334   return len;
335 }
336
337 static int
338 tcp_make_established_options (tcp_connection_t * tc, tcp_options_t * opts)
339 {
340   u8 len = 0;
341
342   opts->flags = 0;
343
344   if (tcp_opts_tstamp (&tc->rcv_opts))
345     {
346       opts->flags |= TCP_OPTS_FLAG_TSTAMP;
347       opts->tsval = tcp_tstamp (tc);
348       opts->tsecr = tc->tsval_recent;
349       len += TCP_OPTION_LEN_TIMESTAMP;
350     }
351   if (tcp_opts_sack_permitted (&tc->rcv_opts))
352     {
353       if (vec_len (tc->snd_sacks))
354         {
355           opts->flags |= TCP_OPTS_FLAG_SACK;
356           if (tc->snd_sack_pos >= vec_len (tc->snd_sacks))
357             tc->snd_sack_pos = 0;
358           opts->sacks = &tc->snd_sacks[tc->snd_sack_pos];
359           opts->n_sack_blocks = vec_len (tc->snd_sacks) - tc->snd_sack_pos;
360           opts->n_sack_blocks = clib_min (opts->n_sack_blocks,
361                                           TCP_OPTS_MAX_SACK_BLOCKS);
362           tc->snd_sack_pos += opts->n_sack_blocks;
363           len += 2 + TCP_OPTION_LEN_SACK_BLOCK * opts->n_sack_blocks;
364         }
365     }
366
367   /* Align to needed boundary */
368   len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
369   return len;
370 }
371
372 always_inline int
373 tcp_make_options (tcp_connection_t * tc, tcp_options_t * opts,
374                   tcp_state_t state)
375 {
376   switch (state)
377     {
378     case TCP_STATE_ESTABLISHED:
379     case TCP_STATE_CLOSE_WAIT:
380     case TCP_STATE_FIN_WAIT_1:
381     case TCP_STATE_LAST_ACK:
382     case TCP_STATE_CLOSING:
383     case TCP_STATE_FIN_WAIT_2:
384     case TCP_STATE_TIME_WAIT:
385     case TCP_STATE_CLOSED:
386       return tcp_make_established_options (tc, opts);
387     case TCP_STATE_SYN_RCVD:
388       return tcp_make_synack_options (tc, opts);
389     case TCP_STATE_SYN_SENT:
390       return tcp_make_syn_options (opts, tc->rcv_wscale);
391     default:
392       clib_warning ("State not handled! %d", state);
393       return 0;
394     }
395 }
396
397 /**
398  * Update burst send vars
399  *
400  * - Updates snd_mss to reflect the effective segment size that we can send
401  * by taking into account all TCP options, including SACKs.
402  * - Cache 'on the wire' options for reuse
403  * - Updates receive window which can be reused for a burst.
404  *
405  * This should *only* be called when doing bursts
406  */
407 void
408 tcp_update_burst_snd_vars (tcp_connection_t * tc)
409 {
410   tcp_main_t *tm = &tcp_main;
411
412   /* Compute options to be used for connection. These may be reused when
413    * sending data or to compute the effective mss (snd_mss) */
414   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts,
415                                        TCP_STATE_ESTABLISHED);
416
417   /* XXX check if MTU has been updated */
418   tc->snd_mss = clib_min (tc->mss, tc->rcv_opts.mss) - tc->snd_opts_len;
419   ASSERT (tc->snd_mss > 0);
420
421   tcp_options_write (tm->wrk_ctx[tc->c_thread_index].cached_opts,
422                      &tc->snd_opts);
423
424   tcp_update_rcv_wnd (tc);
425
426   if (tc->flags & TCP_CONN_RATE_SAMPLE)
427     tc->flags |= TCP_CONN_TRACK_BURST;
428
429   if (tc->snd_una == tc->snd_nxt)
430     tcp_cc_event (tc, TCP_CC_EVT_START_TX);
431 }
432
433 void
434 tcp_init_mss (tcp_connection_t * tc)
435 {
436   u16 default_min_mss = 536;
437   tcp_update_rcv_mss (tc);
438
439   /* TODO cache mss and consider PMTU discovery */
440   tc->snd_mss = clib_min (tc->rcv_opts.mss, tc->mss);
441
442   if (tc->snd_mss < 45)
443     {
444       /* Assume that at least the min default mss works */
445       tc->snd_mss = default_min_mss;
446       tc->rcv_opts.mss = default_min_mss;
447     }
448
449   /* We should have enough space for 40 bytes of options */
450   ASSERT (tc->snd_mss > 45);
451
452   /* If we use timestamp option, account for it */
453   if (tcp_opts_tstamp (&tc->rcv_opts))
454     tc->snd_mss -= TCP_OPTION_LEN_TIMESTAMP;
455 }
456 #endif /* CLIB_MARCH_VARIANT */
457
458 static void *
459 tcp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b)
460 {
461   if (b->flags & VLIB_BUFFER_NEXT_PRESENT)
462     vlib_buffer_free_one (vm, b->next_buffer);
463   /* Zero all flags but free list index and trace flag */
464   b->flags &= VLIB_BUFFER_NEXT_PRESENT - 1;
465   b->current_data = 0;
466   b->current_length = 0;
467   b->total_length_not_including_first_buffer = 0;
468   vnet_buffer (b)->tcp.flags = 0;
469
470   /* Leave enough space for headers */
471   return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
472 }
473
474 #ifndef CLIB_MARCH_VARIANT
475 static void *
476 tcp_init_buffer (vlib_main_t * vm, vlib_buffer_t * b)
477 {
478   ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0);
479   b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
480   b->total_length_not_including_first_buffer = 0;
481   b->current_data = 0;
482   vnet_buffer (b)->tcp.flags = 0;
483   VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
484   /* Leave enough space for headers */
485   return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
486 }
487
488 /**
489  * Prepare ACK
490  */
491 static inline void
492 tcp_make_ack_i (tcp_connection_t * tc, vlib_buffer_t * b, tcp_state_t state,
493                 u8 flags)
494 {
495   tcp_options_t _snd_opts, *snd_opts = &_snd_opts;
496   u8 tcp_opts_len, tcp_hdr_opts_len;
497   tcp_header_t *th;
498   u16 wnd;
499
500   wnd = tcp_window_to_advertise (tc, state);
501
502   /* Make and write options */
503   tcp_opts_len = tcp_make_established_options (tc, snd_opts);
504   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
505
506   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
507                              tc->rcv_nxt, tcp_hdr_opts_len, flags, wnd);
508
509   tcp_options_write ((u8 *) (th + 1), snd_opts);
510   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
511
512   if (wnd == 0)
513     tcp_zero_rwnd_sent_on (tc);
514   else
515     tcp_zero_rwnd_sent_off (tc);
516 }
517
518 /**
519  * Convert buffer to ACK
520  */
521 static inline void
522 tcp_make_ack (tcp_connection_t * tc, vlib_buffer_t * b)
523 {
524   tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, TCP_FLAG_ACK);
525   TCP_EVT_DBG (TCP_EVT_ACK_SENT, tc);
526   tc->rcv_las = tc->rcv_nxt;
527 }
528
529 /**
530  * Convert buffer to FIN-ACK
531  */
532 void
533 tcp_make_fin (tcp_connection_t * tc, vlib_buffer_t * b)
534 {
535   tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, TCP_FLAG_FIN | TCP_FLAG_ACK);
536 }
537
538 /**
539  * Convert buffer to SYN
540  */
541 void
542 tcp_make_syn (tcp_connection_t * tc, vlib_buffer_t * b)
543 {
544   u8 tcp_hdr_opts_len, tcp_opts_len;
545   tcp_header_t *th;
546   u16 initial_wnd;
547   tcp_options_t snd_opts;
548
549   initial_wnd = tcp_initial_window_to_advertise (tc);
550
551   /* Make and write options */
552   clib_memset (&snd_opts, 0, sizeof (snd_opts));
553   tcp_opts_len = tcp_make_syn_options (&snd_opts, tc->rcv_wscale);
554   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
555
556   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
557                              tc->rcv_nxt, tcp_hdr_opts_len, TCP_FLAG_SYN,
558                              initial_wnd);
559   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
560   tcp_options_write ((u8 *) (th + 1), &snd_opts);
561 }
562
563 /**
564  * Convert buffer to SYN-ACK
565  */
566 void
567 tcp_make_synack (tcp_connection_t * tc, vlib_buffer_t * b)
568 {
569   tcp_options_t _snd_opts, *snd_opts = &_snd_opts;
570   u8 tcp_opts_len, tcp_hdr_opts_len;
571   tcp_header_t *th;
572   u16 initial_wnd;
573
574   clib_memset (snd_opts, 0, sizeof (*snd_opts));
575   initial_wnd = tcp_initial_window_to_advertise (tc);
576   tcp_opts_len = tcp_make_synack_options (tc, snd_opts);
577   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
578
579   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
580                              tc->rcv_nxt, tcp_hdr_opts_len,
581                              TCP_FLAG_SYN | TCP_FLAG_ACK, initial_wnd);
582   tcp_options_write ((u8 *) (th + 1), snd_opts);
583
584   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
585 }
586
587 always_inline void
588 tcp_enqueue_to_ip_lookup_i (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
589                             u8 is_ip4, u32 fib_index, u8 flush)
590 {
591   vlib_main_t *vm = wrk->vm;
592   u32 *to_next, next_index;
593   vlib_frame_t *f;
594
595   b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
596   b->error = 0;
597
598   vnet_buffer (b)->sw_if_index[VLIB_TX] = fib_index;
599   vnet_buffer (b)->sw_if_index[VLIB_RX] = 0;
600
601   /* Send to IP lookup */
602   next_index = is_ip4 ? ip4_lookup_node.index : ip6_lookup_node.index;
603   tcp_trajectory_add_start (b, 1);
604
605   f = wrk->ip_lookup_tx_frames[!is_ip4];
606   if (!f)
607     {
608       f = vlib_get_frame_to_node (vm, next_index);
609       ASSERT (f);
610       wrk->ip_lookup_tx_frames[!is_ip4] = f;
611     }
612
613   to_next = vlib_frame_vector_args (f);
614   to_next[f->n_vectors] = bi;
615   f->n_vectors += 1;
616   if (flush || f->n_vectors == VLIB_FRAME_SIZE)
617     {
618       vlib_put_frame_to_node (vm, next_index, f);
619       wrk->ip_lookup_tx_frames[!is_ip4] = 0;
620     }
621 }
622
623 static void
624 tcp_enqueue_to_ip_lookup_now (tcp_worker_ctx_t * wrk, vlib_buffer_t * b,
625                               u32 bi, u8 is_ip4, u32 fib_index)
626 {
627   tcp_enqueue_to_ip_lookup_i (wrk, b, bi, is_ip4, fib_index, 1);
628 }
629
630 static void
631 tcp_enqueue_to_ip_lookup (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
632                           u8 is_ip4, u32 fib_index)
633 {
634   tcp_enqueue_to_ip_lookup_i (wrk, b, bi, is_ip4, fib_index, 0);
635   if (wrk->vm->thread_index == 0 && vlib_num_workers ())
636     session_flush_frames_main_thread (wrk->vm);
637 }
638
639 always_inline void
640 tcp_enqueue_to_output_i (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
641                          u8 is_ip4, u8 flush)
642 {
643   u32 *to_next, next_index;
644   vlib_frame_t *f;
645
646   b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
647   b->error = 0;
648
649   /* Decide where to send the packet */
650   next_index = is_ip4 ? tcp4_output_node.index : tcp6_output_node.index;
651   tcp_trajectory_add_start (b, 2);
652
653   /* Get frame to v4/6 output node */
654   f = wrk->tx_frames[!is_ip4];
655   if (!f)
656     {
657       f = vlib_get_frame_to_node (wrk->vm, next_index);
658       ASSERT (f);
659       wrk->tx_frames[!is_ip4] = f;
660     }
661   to_next = vlib_frame_vector_args (f);
662   to_next[f->n_vectors] = bi;
663   f->n_vectors += 1;
664   if (flush || f->n_vectors == VLIB_FRAME_SIZE)
665     {
666       vlib_put_frame_to_node (wrk->vm, next_index, f);
667       wrk->tx_frames[!is_ip4] = 0;
668     }
669 }
670
671 static void
672 tcp_enqueue_to_output (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
673                        u8 is_ip4)
674 {
675   tcp_enqueue_to_output_i (wrk, b, bi, is_ip4, 0);
676 }
677
678 static void
679 tcp_enqueue_to_output_now (tcp_worker_ctx_t * wrk, vlib_buffer_t * b, u32 bi,
680                            u8 is_ip4)
681 {
682   tcp_enqueue_to_output_i (wrk, b, bi, is_ip4, 1);
683 }
684 #endif /* CLIB_MARCH_VARIANT */
685
686 static int
687 tcp_make_reset_in_place (vlib_main_t * vm, vlib_buffer_t * b0,
688                          tcp_state_t state, u8 thread_index, u8 is_ip4)
689 {
690   ip4_header_t *ih4;
691   ip6_header_t *ih6;
692   tcp_header_t *th0;
693   ip4_address_t src_ip40, dst_ip40;
694   ip6_address_t src_ip60, dst_ip60;
695   u16 src_port, dst_port;
696   u32 tmp;
697   u32 seq, ack;
698   u8 flags;
699
700   /* Find IP and TCP headers */
701   th0 = tcp_buffer_hdr (b0);
702
703   /* Save src and dst ip */
704   if (is_ip4)
705     {
706       ih4 = vlib_buffer_get_current (b0);
707       ASSERT ((ih4->ip_version_and_header_length & 0xF0) == 0x40);
708       src_ip40.as_u32 = ih4->src_address.as_u32;
709       dst_ip40.as_u32 = ih4->dst_address.as_u32;
710     }
711   else
712     {
713       ih6 = vlib_buffer_get_current (b0);
714       ASSERT ((ih6->ip_version_traffic_class_and_flow_label & 0xF0) == 0x60);
715       clib_memcpy_fast (&src_ip60, &ih6->src_address, sizeof (ip6_address_t));
716       clib_memcpy_fast (&dst_ip60, &ih6->dst_address, sizeof (ip6_address_t));
717     }
718
719   src_port = th0->src_port;
720   dst_port = th0->dst_port;
721
722   /* Try to determine what/why we're actually resetting */
723   if (state == TCP_STATE_CLOSED)
724     {
725       if (!tcp_syn (th0))
726         return -1;
727
728       tmp = clib_net_to_host_u32 (th0->seq_number);
729
730       /* Got a SYN for no listener. */
731       flags = TCP_FLAG_RST | TCP_FLAG_ACK;
732       ack = clib_host_to_net_u32 (tmp + 1);
733       seq = 0;
734     }
735   else
736     {
737       flags = TCP_FLAG_RST;
738       seq = th0->ack_number;
739       ack = 0;
740     }
741
742   tcp_reuse_buffer (vm, b0);
743   tcp_trajectory_add_start (b0, 4);
744   th0 = vlib_buffer_push_tcp_net_order (b0, dst_port, src_port, seq, ack,
745                                         sizeof (tcp_header_t), flags, 0);
746
747   if (is_ip4)
748     {
749       ih4 = vlib_buffer_push_ip4 (vm, b0, &dst_ip40, &src_ip40,
750                                   IP_PROTOCOL_TCP, 1);
751       th0->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ih4);
752     }
753   else
754     {
755       int bogus = ~0;
756       ih6 = vlib_buffer_push_ip6 (vm, b0, &dst_ip60, &src_ip60,
757                                   IP_PROTOCOL_TCP);
758       th0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ih6, &bogus);
759       ASSERT (!bogus);
760     }
761
762   return 0;
763 }
764
765 #ifndef CLIB_MARCH_VARIANT
766 /**
767  *  Send reset without reusing existing buffer
768  *
769  *  It extracts connection info out of original packet
770  */
771 void
772 tcp_send_reset_w_pkt (tcp_connection_t * tc, vlib_buffer_t * pkt,
773                       u32 thread_index, u8 is_ip4)
774 {
775   tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
776   vlib_main_t *vm = wrk->vm;
777   vlib_buffer_t *b;
778   u32 bi, sw_if_index, fib_index;
779   u8 tcp_hdr_len, flags = 0;
780   tcp_header_t *th, *pkt_th;
781   u32 seq, ack;
782   ip4_header_t *ih4, *pkt_ih4;
783   ip6_header_t *ih6, *pkt_ih6;
784   fib_protocol_t fib_proto;
785
786   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
787     return;
788
789   b = vlib_get_buffer (vm, bi);
790   sw_if_index = vnet_buffer (pkt)->sw_if_index[VLIB_RX];
791   fib_proto = is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
792   fib_index = fib_table_get_index_for_sw_if_index (fib_proto, sw_if_index);
793   tcp_init_buffer (vm, b);
794
795   /* Make and write options */
796   tcp_hdr_len = sizeof (tcp_header_t);
797
798   if (is_ip4)
799     {
800       pkt_ih4 = vlib_buffer_get_current (pkt);
801       pkt_th = ip4_next_header (pkt_ih4);
802     }
803   else
804     {
805       pkt_ih6 = vlib_buffer_get_current (pkt);
806       pkt_th = ip6_next_header (pkt_ih6);
807     }
808
809   if (tcp_ack (pkt_th))
810     {
811       flags = TCP_FLAG_RST;
812       seq = pkt_th->ack_number;
813       ack = (tc->state >= TCP_STATE_SYN_RCVD) ? tc->rcv_nxt : 0;
814     }
815   else
816     {
817       flags = TCP_FLAG_RST | TCP_FLAG_ACK;
818       seq = 0;
819       ack = clib_host_to_net_u32 (vnet_buffer (pkt)->tcp.seq_end);
820     }
821
822   th = vlib_buffer_push_tcp_net_order (b, pkt_th->dst_port, pkt_th->src_port,
823                                        seq, ack, tcp_hdr_len, flags, 0);
824
825   /* Swap src and dst ip */
826   if (is_ip4)
827     {
828       ASSERT ((pkt_ih4->ip_version_and_header_length & 0xF0) == 0x40);
829       ih4 = vlib_buffer_push_ip4 (vm, b, &pkt_ih4->dst_address,
830                                   &pkt_ih4->src_address, IP_PROTOCOL_TCP, 1);
831       th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih4);
832     }
833   else
834     {
835       int bogus = ~0;
836       ASSERT ((pkt_ih6->ip_version_traffic_class_and_flow_label & 0xF0) ==
837               0x60);
838       ih6 = vlib_buffer_push_ip6 (vm, b, &pkt_ih6->dst_address,
839                                   &pkt_ih6->src_address, IP_PROTOCOL_TCP);
840       th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih6, &bogus);
841       ASSERT (!bogus);
842     }
843
844   tcp_enqueue_to_ip_lookup_now (wrk, b, bi, is_ip4, fib_index);
845   TCP_EVT_DBG (TCP_EVT_RST_SENT, tc);
846   vlib_node_increment_counter (vm, tcp_node_index (output, tc->c_is_ip4),
847                                TCP_ERROR_RST_SENT, 1);
848 }
849
850 /**
851  * Build and set reset packet for connection
852  */
853 void
854 tcp_send_reset (tcp_connection_t * tc)
855 {
856   tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
857   vlib_main_t *vm = wrk->vm;
858   vlib_buffer_t *b;
859   u32 bi;
860   tcp_header_t *th;
861   u16 tcp_hdr_opts_len, advertise_wnd, opts_write_len;
862   u8 flags;
863
864   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
865     return;
866   b = vlib_get_buffer (vm, bi);
867   tcp_init_buffer (vm, b);
868
869   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
870   tcp_hdr_opts_len = tc->snd_opts_len + sizeof (tcp_header_t);
871   advertise_wnd = tcp_window_to_advertise (tc, TCP_STATE_ESTABLISHED);
872   flags = TCP_FLAG_RST;
873   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
874                              tc->rcv_nxt, tcp_hdr_opts_len, flags,
875                              advertise_wnd);
876   opts_write_len = tcp_options_write ((u8 *) (th + 1), &tc->snd_opts);
877   ASSERT (opts_write_len == tc->snd_opts_len);
878   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
879   if (tc->c_is_ip4)
880     {
881       ip4_header_t *ih4;
882       ih4 = vlib_buffer_push_ip4 (vm, b, &tc->c_lcl_ip.ip4,
883                                   &tc->c_rmt_ip.ip4, IP_PROTOCOL_TCP, 0);
884       th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih4);
885     }
886   else
887     {
888       int bogus = ~0;
889       ip6_header_t *ih6;
890       ih6 = vlib_buffer_push_ip6 (vm, b, &tc->c_lcl_ip.ip6,
891                                   &tc->c_rmt_ip.ip6, IP_PROTOCOL_TCP);
892       th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih6, &bogus);
893       ASSERT (!bogus);
894     }
895   tcp_enqueue_to_ip_lookup_now (wrk, b, bi, tc->c_is_ip4, tc->c_fib_index);
896   TCP_EVT_DBG (TCP_EVT_RST_SENT, tc);
897   vlib_node_increment_counter (vm, tcp_node_index (output, tc->c_is_ip4),
898                                TCP_ERROR_RST_SENT, 1);
899 }
900
901 static void
902 tcp_push_ip_hdr (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
903                  vlib_buffer_t * b)
904 {
905   tcp_header_t *th = vlib_buffer_get_current (b);
906   vlib_main_t *vm = wrk->vm;
907   if (tc->c_is_ip4)
908     {
909       ip4_header_t *ih;
910       ih = vlib_buffer_push_ip4 (vm, b, &tc->c_lcl_ip4,
911                                  &tc->c_rmt_ip4, IP_PROTOCOL_TCP, 1);
912       th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih);
913     }
914   else
915     {
916       ip6_header_t *ih;
917       int bogus = ~0;
918
919       ih = vlib_buffer_push_ip6 (vm, b, &tc->c_lcl_ip6,
920                                  &tc->c_rmt_ip6, IP_PROTOCOL_TCP);
921       th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih, &bogus);
922       ASSERT (!bogus);
923     }
924 }
925
926 /**
927  *  Send SYN
928  *
929  *  Builds a SYN packet for a half-open connection and sends it to ipx_lookup.
930  *  The packet is not forwarded through tcpx_output to avoid doing lookups
931  *  in the half_open pool.
932  */
933 void
934 tcp_send_syn (tcp_connection_t * tc)
935 {
936   tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
937   vlib_main_t *vm = wrk->vm;
938   vlib_buffer_t *b;
939   u32 bi;
940
941   /*
942    * Setup retransmit and establish timers before requesting buffer
943    * such that we can return if we've ran out.
944    */
945   tcp_timer_set (tc, TCP_TIMER_ESTABLISH_AO, TCP_ESTABLISH_TIME);
946   tcp_timer_update (tc, TCP_TIMER_RETRANSMIT_SYN,
947                     tc->rto * TCP_TO_TIMER_TICK);
948
949   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
950     {
951       tcp_timer_update (tc, TCP_TIMER_RETRANSMIT_SYN, 1);
952       return;
953     }
954
955   b = vlib_get_buffer (vm, bi);
956   tcp_init_buffer (vm, b);
957   tcp_make_syn (tc, b);
958
959   /* Measure RTT with this */
960   tc->rtt_ts = tcp_time_now_us (vlib_num_workers ()? 1 : 0);
961   tc->rtt_seq = tc->snd_nxt;
962   tc->rto_boff = 0;
963
964   tcp_push_ip_hdr (wrk, tc, b);
965   tcp_enqueue_to_ip_lookup (wrk, b, bi, tc->c_is_ip4, tc->c_fib_index);
966   TCP_EVT_DBG (TCP_EVT_SYN_SENT, tc);
967 }
968
969 void
970 tcp_send_synack (tcp_connection_t * tc)
971 {
972   tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
973   vlib_main_t *vm = wrk->vm;
974   vlib_buffer_t *b;
975   u32 bi;
976
977   tcp_retransmit_timer_force_update (tc);
978
979   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
980     {
981       tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
982       return;
983     }
984
985   tc->rtt_ts = tcp_time_now_us (tc->c_thread_index);
986   b = vlib_get_buffer (vm, bi);
987   tcp_init_buffer (vm, b);
988   tcp_make_synack (tc, b);
989   tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
990   TCP_EVT_DBG (TCP_EVT_SYNACK_SENT, tc);
991 }
992
993 /**
994  * Flush tx frame populated by retransmits and timer pops
995  */
996 void
997 tcp_flush_frame_to_output (tcp_worker_ctx_t * wrk, u8 is_ip4)
998 {
999   if (wrk->tx_frames[!is_ip4])
1000     {
1001       u32 next_index;
1002       next_index = is_ip4 ? tcp4_output_node.index : tcp6_output_node.index;
1003       vlib_put_frame_to_node (wrk->vm, next_index, wrk->tx_frames[!is_ip4]);
1004       wrk->tx_frames[!is_ip4] = 0;
1005     }
1006 }
1007
1008 /**
1009  * Flush ip lookup tx frames populated by timer pops
1010  */
1011 static void
1012 tcp_flush_frame_to_ip_lookup (tcp_worker_ctx_t * wrk, u8 is_ip4)
1013 {
1014   if (wrk->ip_lookup_tx_frames[!is_ip4])
1015     {
1016       u32 next_index;
1017       next_index = is_ip4 ? ip4_lookup_node.index : ip6_lookup_node.index;
1018       vlib_put_frame_to_node (wrk->vm, next_index,
1019                               wrk->ip_lookup_tx_frames[!is_ip4]);
1020       wrk->ip_lookup_tx_frames[!is_ip4] = 0;
1021     }
1022 }
1023
1024 /**
1025  * Flush v4 and v6 tcp and ip-lookup tx frames for thread index
1026  */
1027 void
1028 tcp_flush_frames_to_output (tcp_worker_ctx_t * wrk)
1029 {
1030   tcp_flush_frame_to_output (wrk, 1);
1031   tcp_flush_frame_to_output (wrk, 0);
1032   tcp_flush_frame_to_ip_lookup (wrk, 1);
1033   tcp_flush_frame_to_ip_lookup (wrk, 0);
1034 }
1035
1036 /**
1037  *  Send FIN
1038  */
1039 void
1040 tcp_send_fin (tcp_connection_t * tc)
1041 {
1042   tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
1043   vlib_main_t *vm = wrk->vm;
1044   vlib_buffer_t *b;
1045   u32 bi;
1046   u8 fin_snt = 0;
1047
1048   fin_snt = tc->flags & TCP_CONN_FINSNT;
1049   if (fin_snt)
1050     tc->snd_nxt -= 1;
1051
1052   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
1053     {
1054       /* Out of buffers so program fin retransmit ASAP */
1055       tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
1056       if (fin_snt)
1057         tc->snd_nxt += 1;
1058       else
1059         /* Make sure retransmit retries a fin not data */
1060         tc->flags |= TCP_CONN_FINSNT;
1061       return;
1062     }
1063
1064   tcp_retransmit_timer_force_update (tc);
1065   b = vlib_get_buffer (vm, bi);
1066   tcp_init_buffer (vm, b);
1067   tcp_make_fin (tc, b);
1068   tcp_enqueue_to_output_now (wrk, b, bi, tc->c_is_ip4);
1069   TCP_EVT_DBG (TCP_EVT_FIN_SENT, tc);
1070   /* Account for the FIN */
1071   tc->snd_nxt += 1;
1072   if (!fin_snt)
1073     {
1074       tc->flags |= TCP_CONN_FINSNT;
1075       tc->flags &= ~TCP_CONN_FINPNDG;
1076       tc->snd_una_max = seq_max (tc->snd_una_max, tc->snd_nxt);
1077     }
1078 }
1079
1080 /**
1081  * Push TCP header and update connection variables. Should only be called
1082  * for segments with data, not for 'control' packets.
1083  */
1084 always_inline void
1085 tcp_push_hdr_i (tcp_connection_t * tc, vlib_buffer_t * b, u32 snd_nxt,
1086                 u8 compute_opts, u8 maybe_burst, u8 update_snd_nxt)
1087 {
1088   u8 tcp_hdr_opts_len, flags = TCP_FLAG_ACK;
1089   u32 advertise_wnd, data_len;
1090   tcp_main_t *tm = &tcp_main;
1091   tcp_header_t *th;
1092
1093   data_len = b->current_length;
1094   if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
1095     data_len += b->total_length_not_including_first_buffer;
1096
1097   vnet_buffer (b)->tcp.flags = 0;
1098   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
1099
1100   if (compute_opts)
1101     tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1102
1103   tcp_hdr_opts_len = tc->snd_opts_len + sizeof (tcp_header_t);
1104
1105   if (maybe_burst)
1106     advertise_wnd = tc->rcv_wnd >> tc->rcv_wscale;
1107   else
1108     advertise_wnd = tcp_window_to_advertise (tc, TCP_STATE_ESTABLISHED);
1109
1110   if (PREDICT_FALSE (tc->flags & TCP_CONN_PSH_PENDING))
1111     {
1112       if (seq_geq (tc->psh_seq, snd_nxt)
1113           && seq_lt (tc->psh_seq, snd_nxt + data_len))
1114         flags |= TCP_FLAG_PSH;
1115     }
1116   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, snd_nxt,
1117                              tc->rcv_nxt, tcp_hdr_opts_len, flags,
1118                              advertise_wnd);
1119
1120   if (maybe_burst)
1121     {
1122       clib_memcpy_fast ((u8 *) (th + 1),
1123                         tm->wrk_ctx[tc->c_thread_index].cached_opts,
1124                         tc->snd_opts_len);
1125     }
1126   else
1127     {
1128       u8 len = tcp_options_write ((u8 *) (th + 1), &tc->snd_opts);
1129       ASSERT (len == tc->snd_opts_len);
1130     }
1131
1132   /*
1133    * Update connection variables
1134    */
1135
1136   if (update_snd_nxt)
1137     tc->snd_nxt += data_len;
1138   tc->rcv_las = tc->rcv_nxt;
1139
1140   tc->bytes_out += data_len;
1141   tc->data_segs_out += 1;
1142
1143   TCP_EVT_DBG (TCP_EVT_PKTIZE, tc);
1144 }
1145
1146 u32
1147 tcp_session_push_header (transport_connection_t * tconn, vlib_buffer_t * b)
1148 {
1149   tcp_connection_t *tc = (tcp_connection_t *) tconn;
1150
1151   if (tc->flags & TCP_CONN_TRACK_BURST)
1152     {
1153       tcp_bt_check_app_limited (tc);
1154       tcp_bt_track_tx (tc);
1155       tc->flags &= ~TCP_CONN_TRACK_BURST;
1156     }
1157
1158   tcp_push_hdr_i (tc, b, tc->snd_nxt, /* compute opts */ 0, /* burst */ 1,
1159                   /* update_snd_nxt */ 1);
1160
1161   tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
1162   tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
1163   /* If not tracking an ACK, start tracking */
1164   if (tc->rtt_ts == 0 && !tcp_in_cong_recovery (tc))
1165     {
1166       tc->rtt_ts = tcp_time_now_us (tc->c_thread_index);
1167       tc->rtt_seq = tc->snd_nxt;
1168     }
1169   if (PREDICT_FALSE (!tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)))
1170     {
1171       tcp_retransmit_timer_set (tc);
1172       tc->rto_boff = 0;
1173     }
1174   tcp_trajectory_add_start (b, 3);
1175   return 0;
1176 }
1177
1178 void
1179 tcp_send_ack (tcp_connection_t * tc)
1180 {
1181   tcp_worker_ctx_t *wrk = tcp_get_worker (tc->c_thread_index);
1182   vlib_main_t *vm = wrk->vm;
1183   vlib_buffer_t *b;
1184   u32 bi;
1185
1186   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
1187     {
1188       tcp_update_rcv_wnd (tc);
1189       return;
1190     }
1191   b = vlib_get_buffer (vm, bi);
1192   tcp_init_buffer (vm, b);
1193   tcp_make_ack (tc, b);
1194   tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1195 }
1196
1197 void
1198 tcp_program_ack (tcp_connection_t * tc)
1199 {
1200   if (!(tc->flags & TCP_CONN_SNDACK))
1201     {
1202       session_add_self_custom_tx_evt (&tc->connection, 1);
1203       tc->flags |= TCP_CONN_SNDACK;
1204     }
1205 }
1206
1207 void
1208 tcp_program_dupack (tcp_connection_t * tc)
1209 {
1210   if (!(tc->flags & TCP_CONN_SNDACK))
1211     {
1212       session_add_self_custom_tx_evt (&tc->connection, 1);
1213       tc->flags |= TCP_CONN_SNDACK;
1214     }
1215   if (tc->pending_dupacks < 255)
1216     tc->pending_dupacks += 1;
1217 }
1218
1219 void
1220 tcp_program_fastretransmit (tcp_connection_t * tc)
1221 {
1222   if (!(tc->flags & TCP_CONN_FRXT_PENDING))
1223     {
1224       session_add_self_custom_tx_evt (&tc->connection, 0);
1225       tc->flags |= TCP_CONN_FRXT_PENDING;
1226     }
1227 }
1228
1229 /**
1230  * Delayed ack timer handler
1231  *
1232  * Sends delayed ACK when timer expires
1233  */
1234 void
1235 tcp_timer_delack_handler (u32 index)
1236 {
1237   u32 thread_index = vlib_get_thread_index ();
1238   tcp_connection_t *tc;
1239
1240   tc = tcp_connection_get (index, thread_index);
1241   tc->timers[TCP_TIMER_DELACK] = TCP_TIMER_HANDLE_INVALID;
1242   tcp_send_ack (tc);
1243 }
1244
1245 /**
1246  * Send Window Update ACK,
1247  * ensuring that it will be sent once, if RWND became non-zero,
1248  * after zero RWND has been advertised in ACK before
1249  */
1250 void
1251 tcp_send_window_update_ack (tcp_connection_t * tc)
1252 {
1253   u32 win;
1254
1255   if (tcp_zero_rwnd_sent (tc))
1256     {
1257       win = tcp_window_to_advertise (tc, tc->state);
1258       if (win > 0)
1259         {
1260           tcp_zero_rwnd_sent_off (tc);
1261           tcp_program_ack (tc);
1262         }
1263     }
1264 }
1265
1266 /**
1267  * Allocate a new buffer and build a new tcp segment
1268  *
1269  * @param wrk           tcp worker
1270  * @param tc            connection for which the segment will be allocated
1271  * @param offset        offset of the first byte in the tx fifo
1272  * @param max_deq_byte  segment size
1273  * @param[out] b        pointer to buffer allocated
1274  *
1275  * @return      the number of bytes in the segment or 0 if buffer cannot be
1276  *              allocated or no data available
1277  */
1278 static int
1279 tcp_prepare_segment (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
1280                      u32 offset, u32 max_deq_bytes, vlib_buffer_t ** b)
1281 {
1282   u32 bytes_per_buffer = vnet_get_tcp_main ()->bytes_per_buffer;
1283   vlib_main_t *vm = wrk->vm;
1284   u32 bi, seg_size;
1285   int n_bytes = 0;
1286   u8 *data;
1287
1288   seg_size = max_deq_bytes + TRANSPORT_MAX_HDRS_LEN;
1289
1290   /*
1291    * Prepare options
1292    */
1293   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1294
1295   /*
1296    * Allocate and fill in buffer(s)
1297    */
1298
1299   /* Easy case, buffer size greater than mss */
1300   if (PREDICT_TRUE (seg_size <= bytes_per_buffer))
1301     {
1302       if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
1303         return 0;
1304       *b = vlib_get_buffer (vm, bi);
1305       data = tcp_init_buffer (vm, *b);
1306       n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
1307                                             max_deq_bytes);
1308       ASSERT (n_bytes == max_deq_bytes);
1309       b[0]->current_length = n_bytes;
1310       tcp_push_hdr_i (tc, *b, tc->snd_una + offset, /* compute opts */ 0,
1311                       /* burst */ 0, /* update_snd_nxt */ 0);
1312     }
1313   /* Split mss into multiple buffers */
1314   else
1315     {
1316       u32 chain_bi = ~0, n_bufs_per_seg, n_bufs;
1317       u16 n_peeked, len_to_deq;
1318       vlib_buffer_t *chain_b, *prev_b;
1319       int i;
1320
1321       /* Make sure we have enough buffers */
1322       n_bufs_per_seg = ceil ((double) seg_size / bytes_per_buffer);
1323       vec_validate_aligned (wrk->tx_buffers, n_bufs_per_seg - 1,
1324                             CLIB_CACHE_LINE_BYTES);
1325       n_bufs = vlib_buffer_alloc (vm, wrk->tx_buffers, n_bufs_per_seg);
1326       if (PREDICT_FALSE (n_bufs != n_bufs_per_seg))
1327         {
1328           if (n_bufs)
1329             vlib_buffer_free (vm, wrk->tx_buffers, n_bufs);
1330           return 0;
1331         }
1332
1333       *b = vlib_get_buffer (vm, wrk->tx_buffers[--n_bufs]);
1334       data = tcp_init_buffer (vm, *b);
1335       n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
1336                                             bytes_per_buffer -
1337                                             TRANSPORT_MAX_HDRS_LEN);
1338       b[0]->current_length = n_bytes;
1339       b[0]->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;
1340       b[0]->total_length_not_including_first_buffer = 0;
1341       max_deq_bytes -= n_bytes;
1342
1343       chain_b = *b;
1344       for (i = 1; i < n_bufs_per_seg; i++)
1345         {
1346           prev_b = chain_b;
1347           len_to_deq = clib_min (max_deq_bytes, bytes_per_buffer);
1348           chain_bi = wrk->tx_buffers[--n_bufs];
1349           chain_b = vlib_get_buffer (vm, chain_bi);
1350           chain_b->current_data = 0;
1351           data = vlib_buffer_get_current (chain_b);
1352           n_peeked = session_tx_fifo_peek_bytes (&tc->connection, data,
1353                                                  offset + n_bytes,
1354                                                  len_to_deq);
1355           ASSERT (n_peeked == len_to_deq);
1356           n_bytes += n_peeked;
1357           chain_b->current_length = n_peeked;
1358           chain_b->next_buffer = 0;
1359
1360           /* update previous buffer */
1361           prev_b->next_buffer = chain_bi;
1362           prev_b->flags |= VLIB_BUFFER_NEXT_PRESENT;
1363
1364           max_deq_bytes -= n_peeked;
1365           b[0]->total_length_not_including_first_buffer += n_peeked;
1366         }
1367
1368       tcp_push_hdr_i (tc, *b, tc->snd_una + offset, /* compute opts */ 0,
1369                       /* burst */ 0, /* update_snd_nxt */ 0);
1370
1371       if (PREDICT_FALSE (n_bufs))
1372         {
1373           clib_warning ("not all buffers consumed");
1374           vlib_buffer_free (vm, wrk->tx_buffers, n_bufs);
1375         }
1376     }
1377
1378   ASSERT (n_bytes > 0);
1379   ASSERT (((*b)->current_data + (*b)->current_length) <= bytes_per_buffer);
1380
1381   return n_bytes;
1382 }
1383
1384 /**
1385  * Build a retransmit segment
1386  *
1387  * @return the number of bytes in the segment or 0 if there's nothing to
1388  *         retransmit
1389  */
1390 static u32
1391 tcp_prepare_retransmit_segment (tcp_worker_ctx_t * wrk,
1392                                 tcp_connection_t * tc, u32 offset,
1393                                 u32 max_deq_bytes, vlib_buffer_t ** b)
1394 {
1395   u32 start, available_bytes;
1396   int n_bytes = 0;
1397
1398   ASSERT (tc->state >= TCP_STATE_ESTABLISHED);
1399   ASSERT (max_deq_bytes != 0);
1400
1401   /*
1402    * Make sure we can retransmit something
1403    */
1404   available_bytes = transport_max_tx_dequeue (&tc->connection);
1405   ASSERT (available_bytes >= offset);
1406   available_bytes -= offset;
1407   if (!available_bytes)
1408     return 0;
1409
1410   max_deq_bytes = clib_min (tc->snd_mss, max_deq_bytes);
1411   max_deq_bytes = clib_min (available_bytes, max_deq_bytes);
1412
1413   /* Start is beyond snd_congestion */
1414   start = tc->snd_una + offset;
1415   if (seq_geq (start, tc->snd_congestion))
1416     return 0;
1417
1418   /* Don't overshoot snd_congestion */
1419   if (seq_gt (start + max_deq_bytes, tc->snd_congestion))
1420     {
1421       max_deq_bytes = tc->snd_congestion - start;
1422       if (max_deq_bytes == 0)
1423         return 0;
1424     }
1425
1426   n_bytes = tcp_prepare_segment (wrk, tc, offset, max_deq_bytes, b);
1427   if (!n_bytes)
1428     return 0;
1429
1430   if (tcp_in_fastrecovery (tc))
1431     {
1432       tc->snd_rxt_bytes += n_bytes;
1433       if (tc->flags & TCP_CONN_RATE_SAMPLE)
1434         tcp_bt_track_rxt (tc, start, start + n_bytes);
1435     }
1436
1437   tc->bytes_retrans += n_bytes;
1438   tc->segs_retrans += 1;
1439   TCP_EVT_DBG (TCP_EVT_CC_RTX, tc, offset, n_bytes);
1440   return n_bytes;
1441 }
1442
1443 /**
1444  * Reset congestion control, switch cwnd to loss window and try again.
1445  */
1446 static void
1447 tcp_cc_init_rxt_timeout (tcp_connection_t * tc)
1448 {
1449   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 6);
1450   tc->prev_ssthresh = tc->ssthresh;
1451   tc->prev_cwnd = tc->cwnd;
1452
1453   /* Clear fast recovery state if needed */
1454   if (tcp_in_fastrecovery (tc))
1455     tcp_cc_fastrecovery_clear (tc);
1456
1457   /* Let cc algo decide loss cwnd and ssthresh */
1458   tcp_cc_loss (tc);
1459
1460   /* Start again from the beginning */
1461   tc->snd_congestion = tc->snd_nxt;
1462   tc->rcv_dupacks = 0;
1463   tc->rtt_ts = 0;
1464   tc->cwnd_acc_bytes = 0;
1465   tc->tr_occurences += 1;
1466   tcp_connection_tx_pacer_reset (tc, tc->cwnd, 2 * tc->snd_mss);
1467   tcp_recovery_on (tc);
1468 }
1469
1470 static inline void
1471 tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
1472 {
1473   u32 thread_index = vlib_get_thread_index ();
1474   tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
1475   vlib_main_t *vm = wrk->vm;
1476   tcp_connection_t *tc;
1477   vlib_buffer_t *b = 0;
1478   u32 bi, n_bytes;
1479
1480   if (is_syn)
1481     {
1482       tc = tcp_half_open_connection_get (index);
1483       /* Note: the connection may have transitioned to ESTABLISHED... */
1484       if (PREDICT_FALSE (tc == 0 || tc->state != TCP_STATE_SYN_SENT))
1485         return;
1486       tc->timers[TCP_TIMER_RETRANSMIT_SYN] = TCP_TIMER_HANDLE_INVALID;
1487     }
1488   else
1489     {
1490       tc = tcp_connection_get (index, thread_index);
1491       /* Note: the connection may have been closed and pool_put */
1492       if (PREDICT_FALSE (tc == 0 || tc->state == TCP_STATE_SYN_SENT))
1493         return;
1494       tc->timers[TCP_TIMER_RETRANSMIT] = TCP_TIMER_HANDLE_INVALID;
1495       /* Wait-close and retransmit could pop at the same time */
1496       if (tc->state == TCP_STATE_CLOSED)
1497         return;
1498     }
1499
1500   if (tc->state >= TCP_STATE_ESTABLISHED)
1501     {
1502       TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 2);
1503
1504       /* Lost FIN, retransmit and return */
1505       if (tc->flags & TCP_CONN_FINSNT)
1506         {
1507           tcp_send_fin (tc);
1508           tc->rto_boff += 1;
1509           tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1510           return;
1511         }
1512
1513       /* Shouldn't be here. This condition is tricky because it has to take
1514        * into account boff > 0 due to persist timeout. */
1515       if ((tc->rto_boff == 0 && tc->snd_una == tc->snd_nxt)
1516           || (tc->rto_boff > 0 && seq_geq (tc->snd_una, tc->snd_congestion)
1517               && !tcp_flight_size (tc)))
1518         {
1519           ASSERT (!tcp_in_recovery (tc));
1520           tc->rto_boff = 0;
1521           return;
1522         }
1523
1524       /* We're not in recovery so make sure rto_boff is 0. Can be non 0 due
1525        * to persist timer timeout */
1526       if (!tcp_in_recovery (tc) && tc->rto_boff > 0)
1527         {
1528           tc->rto_boff = 0;
1529           tcp_update_rto (tc);
1530         }
1531
1532       /* Peer is dead or network connectivity is lost. Close connection.
1533        * RFC 1122 section 4.2.3.5 recommends a value of at least 100s. For
1534        * a min rto of 0.2s we need to retry about 8 times. */
1535       if (tc->rto_boff >= TCP_RTO_BOFF_MAX)
1536         {
1537           tcp_send_reset (tc);
1538           tcp_connection_set_state (tc, TCP_STATE_CLOSED);
1539           session_transport_closing_notify (&tc->connection);
1540           tcp_connection_timers_reset (tc);
1541           tcp_timer_update (tc, TCP_TIMER_WAITCLOSE, TCP_CLOSEWAIT_TIME);
1542           return;
1543         }
1544
1545       /* Increment RTO backoff (also equal to number of retries) and go back
1546        * to first un-acked byte  */
1547       tc->rto_boff += 1;
1548
1549       /* TODO be less aggressive about clearing scoreboard */
1550       scoreboard_clear (&tc->sack_sb);
1551
1552       /* First retransmit timeout */
1553       if (tc->rto_boff == 1)
1554         tcp_cc_init_rxt_timeout (tc);
1555
1556       if (tc->flags & TCP_CONN_RATE_SAMPLE)
1557         tcp_bt_flush_samples (tc);
1558
1559       /* If we've sent beyond snd_congestion, update it */
1560       tc->snd_congestion = seq_max (tc->snd_nxt, tc->snd_congestion);
1561
1562       tc->snd_nxt = tc->snd_una;
1563       tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1564
1565       /* Send one segment. Note that n_bytes may be zero due to buffer
1566        * shortfall */
1567       n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, tc->snd_mss, &b);
1568       if (!n_bytes)
1569         {
1570           tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
1571           return;
1572         }
1573
1574       bi = vlib_get_buffer_index (vm, b);
1575
1576       /* For first retransmit, record timestamp (Eifel detection RFC3522) */
1577       if (tc->rto_boff == 1)
1578         tc->snd_rxt_ts = tcp_tstamp (tc);
1579
1580       tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1581       tcp_retransmit_timer_force_update (tc);
1582     }
1583   /* Retransmit for SYN */
1584   else if (tc->state == TCP_STATE_SYN_SENT)
1585     {
1586       /* Half-open connection actually moved to established but we were
1587        * waiting for syn retransmit to pop to call cleanup from the right
1588        * thread. */
1589       if (tc->flags & TCP_CONN_HALF_OPEN_DONE)
1590         {
1591           if (tcp_half_open_connection_cleanup (tc))
1592             TCP_DBG ("could not remove half-open connection");
1593           return;
1594         }
1595
1596       TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 2);
1597
1598       /* Try without increasing RTO a number of times. If this fails,
1599        * start growing RTO exponentially */
1600       tc->rto_boff += 1;
1601       if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
1602         tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1603
1604       tcp_timer_update (tc, TCP_TIMER_RETRANSMIT_SYN,
1605                         tc->rto * TCP_TO_TIMER_TICK);
1606
1607       if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
1608         {
1609           tcp_timer_update (tc, TCP_TIMER_RETRANSMIT_SYN, 1);
1610           return;
1611         }
1612
1613       b = vlib_get_buffer (vm, bi);
1614       tcp_init_buffer (vm, b);
1615       tcp_make_syn (tc, b);
1616
1617       tc->rtt_ts = 0;
1618       TCP_EVT_DBG (TCP_EVT_SYN_RXT, tc, 0);
1619
1620       /* This goes straight to ipx_lookup. Retransmit timer set already */
1621       tcp_push_ip_hdr (wrk, tc, b);
1622       tcp_enqueue_to_ip_lookup (wrk, b, bi, tc->c_is_ip4, tc->c_fib_index);
1623     }
1624   /* Retransmit SYN-ACK */
1625   else if (tc->state == TCP_STATE_SYN_RCVD)
1626     {
1627       TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 2);
1628
1629       tc->rto_boff += 1;
1630       if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
1631         tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1632       tc->rtt_ts = 0;
1633
1634       tcp_retransmit_timer_force_update (tc);
1635
1636       if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
1637         {
1638           tcp_timer_update (tc, TCP_TIMER_RETRANSMIT, 1);
1639           return;
1640         }
1641
1642       b = vlib_get_buffer (vm, bi);
1643       tcp_init_buffer (vm, b);
1644       tcp_make_synack (tc, b);
1645       TCP_EVT_DBG (TCP_EVT_SYN_RXT, tc, 1);
1646
1647       /* Retransmit timer already updated, just enqueue to output */
1648       tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1649     }
1650   else
1651     {
1652       ASSERT (tc->state == TCP_STATE_CLOSED);
1653       return;
1654     }
1655 }
1656
1657 void
1658 tcp_timer_retransmit_handler (u32 index)
1659 {
1660   tcp_timer_retransmit_handler_i (index, 0);
1661 }
1662
1663 void
1664 tcp_timer_retransmit_syn_handler (u32 index)
1665 {
1666   tcp_timer_retransmit_handler_i (index, 1);
1667 }
1668
1669 /**
1670  * Got 0 snd_wnd from peer, try to do something about it.
1671  *
1672  */
1673 void
1674 tcp_timer_persist_handler (u32 index)
1675 {
1676   u32 thread_index = vlib_get_thread_index ();
1677   tcp_worker_ctx_t *wrk = tcp_get_worker (thread_index);
1678   u32 bi, max_snd_bytes, available_bytes, offset;
1679   tcp_main_t *tm = vnet_get_tcp_main ();
1680   vlib_main_t *vm = wrk->vm;
1681   tcp_connection_t *tc;
1682   vlib_buffer_t *b;
1683   int n_bytes = 0;
1684   u8 *data;
1685
1686   tc = tcp_connection_get_if_valid (index, thread_index);
1687   if (!tc)
1688     return;
1689
1690   /* Make sure timer handle is set to invalid */
1691   tc->timers[TCP_TIMER_PERSIST] = TCP_TIMER_HANDLE_INVALID;
1692
1693   /* Problem already solved or worse */
1694   if (tc->state == TCP_STATE_CLOSED || tc->snd_wnd > tc->snd_mss
1695       || (tc->flags & TCP_CONN_FINSNT))
1696     return;
1697
1698   available_bytes = transport_max_tx_dequeue (&tc->connection);
1699   offset = tc->snd_nxt - tc->snd_una;
1700
1701   /* Reprogram persist if no new bytes available to send. We may have data
1702    * next time */
1703   if (!available_bytes)
1704     {
1705       tcp_persist_timer_set (tc);
1706       return;
1707     }
1708
1709   if (available_bytes <= offset)
1710     {
1711       ASSERT (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT));
1712       return;
1713     }
1714
1715   /* Increment RTO backoff */
1716   tc->rto_boff += 1;
1717   tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1718
1719   /*
1720    * Try to force the first unsent segment (or buffer)
1721    */
1722   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
1723     {
1724       tcp_persist_timer_set (tc);
1725       return;
1726     }
1727   b = vlib_get_buffer (vm, bi);
1728   data = tcp_init_buffer (vm, b);
1729
1730   tcp_validate_txf_size (tc, offset);
1731   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1732   max_snd_bytes = clib_min (tc->snd_mss,
1733                             tm->bytes_per_buffer - TRANSPORT_MAX_HDRS_LEN);
1734   n_bytes = session_tx_fifo_peek_bytes (&tc->connection, data, offset,
1735                                         max_snd_bytes);
1736   b->current_length = n_bytes;
1737   ASSERT (n_bytes != 0 && (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)
1738                            || tc->snd_nxt == tc->snd_una_max
1739                            || tc->rto_boff > 1));
1740
1741   tcp_push_hdr_i (tc, b, tc->snd_nxt, /* compute opts */ 0,
1742                   /* burst */ 0, /* update_snd_nxt */ 1);
1743   tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
1744   tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
1745   tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1746
1747   /* Just sent new data, enable retransmit */
1748   tcp_retransmit_timer_update (tc);
1749 }
1750
1751 /**
1752  * Retransmit first unacked segment
1753  */
1754 int
1755 tcp_retransmit_first_unacked (tcp_worker_ctx_t * wrk, tcp_connection_t * tc)
1756 {
1757   vlib_main_t *vm = wrk->vm;
1758   vlib_buffer_t *b;
1759   u32 bi, n_bytes;
1760
1761   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 1);
1762
1763   n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, tc->snd_mss, &b);
1764   if (!n_bytes)
1765     return -1;
1766
1767   bi = vlib_get_buffer_index (vm, b);
1768   tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1769
1770   return 0;
1771 }
1772
1773 static int
1774 tcp_fast_retransmit_unsent (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
1775                             u32 burst_size)
1776 {
1777   u32 offset, n_segs = 0, n_written, bi, available_wnd;
1778   vlib_main_t *vm = wrk->vm;
1779   vlib_buffer_t *b = 0;
1780
1781   offset = tc->snd_nxt - tc->snd_una;
1782   available_wnd = tc->snd_wnd - offset;
1783   burst_size = clib_min (burst_size, available_wnd / tc->snd_mss);
1784
1785   while (n_segs < burst_size)
1786     {
1787       n_written = tcp_prepare_segment (wrk, tc, offset, tc->snd_mss, &b);
1788       if (!n_written)
1789         goto done;
1790
1791       bi = vlib_get_buffer_index (vm, b);
1792       tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1793       offset += n_written;
1794       n_segs += 1;
1795
1796       tc->snd_nxt += n_written;
1797       tc->snd_una_max = seq_max (tc->snd_nxt, tc->snd_una_max);
1798     }
1799
1800 done:
1801   return n_segs;
1802 }
1803
1804 #define scoreboard_rescue_rxt_valid(_sb, _tc)                   \
1805     (seq_geq (_sb->rescue_rxt, _tc->snd_una)                    \
1806         && seq_leq (_sb->rescue_rxt, _tc->snd_congestion))
1807
1808 /**
1809  * Do fast retransmit with SACKs
1810  */
1811 int
1812 tcp_fast_retransmit_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
1813                           u32 burst_size)
1814 {
1815   u32 n_written = 0, offset, max_bytes, n_segs = 0, n_segs_now;
1816   sack_scoreboard_hole_t *hole;
1817   vlib_main_t *vm = wrk->vm;
1818   vlib_buffer_t *b = 0;
1819   sack_scoreboard_t *sb;
1820   u32 bi, max_deq;
1821   int snd_space;
1822   u8 snd_limited = 0, can_rescue = 0;
1823
1824   ASSERT (tcp_in_fastrecovery (tc));
1825
1826   snd_space = tcp_available_cc_snd_space (tc);
1827   if (snd_space < tc->snd_mss)
1828     {
1829       tcp_program_fastretransmit (tc);
1830       return 0;
1831     }
1832
1833   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1834   sb = &tc->sack_sb;
1835   hole = scoreboard_get_hole (sb, sb->cur_rxt_hole);
1836
1837   max_deq = transport_max_tx_dequeue (&tc->connection);
1838   max_deq -= tc->snd_nxt - tc->snd_una;
1839
1840   while (snd_space > 0 && n_segs < burst_size)
1841     {
1842       hole = scoreboard_next_rxt_hole (sb, hole, max_deq, &can_rescue,
1843                                        &snd_limited);
1844       if (!hole)
1845         {
1846           if (max_deq)
1847             {
1848               snd_space = clib_min (max_deq, snd_space);
1849               burst_size = clib_min (burst_size - n_segs,
1850                                      snd_space / tc->snd_mss);
1851               n_segs_now = tcp_fast_retransmit_unsent (wrk, tc, burst_size);
1852               if (max_deq > n_segs_now * tc->snd_mss)
1853                 tcp_program_fastretransmit (tc);
1854               n_segs += n_segs_now;
1855               goto done;
1856             }
1857
1858           if (!can_rescue || scoreboard_rescue_rxt_valid (sb, tc))
1859             break;
1860
1861           /* If rescue rxt undefined or less than snd_una then one segment of
1862            * up to SMSS octets that MUST include the highest outstanding
1863            * unSACKed sequence number SHOULD be returned, and RescueRxt set to
1864            * RecoveryPoint. HighRxt MUST NOT be updated.
1865            */
1866           max_bytes = clib_min (tc->snd_mss,
1867                                 tc->snd_congestion - tc->snd_una);
1868           max_bytes = clib_min (max_bytes, snd_space);
1869           offset = tc->snd_congestion - tc->snd_una - max_bytes;
1870           sb->rescue_rxt = tc->snd_congestion;
1871           n_written = tcp_prepare_retransmit_segment (wrk, tc, offset,
1872                                                       max_bytes, &b);
1873           if (!n_written)
1874             goto done;
1875
1876           bi = vlib_get_buffer_index (vm, b);
1877           tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1878           n_segs += 1;
1879           break;
1880         }
1881
1882       max_bytes = clib_min (hole->end - sb->high_rxt, snd_space);
1883       max_bytes = snd_limited ? clib_min (max_bytes, tc->snd_mss) : max_bytes;
1884       if (max_bytes == 0)
1885         break;
1886
1887       offset = sb->high_rxt - tc->snd_una;
1888       n_written = tcp_prepare_retransmit_segment (wrk, tc, offset, max_bytes,
1889                                                   &b);
1890       ASSERT (n_written <= snd_space);
1891
1892       /* Nothing left to retransmit */
1893       if (n_written == 0)
1894         break;
1895
1896       bi = vlib_get_buffer_index (vm, b);
1897       tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1898
1899       sb->high_rxt += n_written;
1900       snd_space -= n_written;
1901       n_segs += 1;
1902     }
1903
1904   if (hole)
1905     tcp_program_fastretransmit (tc);
1906
1907 done:
1908   return n_segs;
1909 }
1910
1911 /**
1912  * Fast retransmit without SACK info
1913  */
1914 int
1915 tcp_fast_retransmit_no_sack (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
1916                              u32 burst_size)
1917 {
1918   u32 n_written = 0, offset = 0, bi, max_deq, n_segs_now;
1919   vlib_main_t *vm = wrk->vm;
1920   int snd_space, n_segs = 0;
1921   vlib_buffer_t *b;
1922
1923   ASSERT (tcp_in_fastrecovery (tc));
1924   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1925
1926   snd_space = tcp_available_cc_snd_space (tc);
1927
1928   if (!tcp_fastrecovery_first (tc))
1929     goto send_unsent;
1930
1931   /* RFC 6582: [If a partial ack], retransmit the first unacknowledged
1932    * segment. */
1933   while (snd_space > 0 && n_segs < burst_size)
1934     {
1935       n_written = tcp_prepare_retransmit_segment (wrk, tc, offset,
1936                                                   tc->snd_mss, &b);
1937
1938       /* Nothing left to retransmit */
1939       if (n_written == 0)
1940         break;
1941
1942       bi = vlib_get_buffer_index (vm, b);
1943       tcp_enqueue_to_output (wrk, b, bi, tc->c_is_ip4);
1944       snd_space -= n_written;
1945       offset += n_written;
1946       n_segs += 1;
1947     }
1948
1949   if (n_segs == burst_size)
1950     goto done;
1951
1952 send_unsent:
1953
1954   /* RFC 6582: Send a new segment if permitted by the new value of cwnd. */
1955   if (snd_space < tc->snd_mss || tc->snd_mss == 0)
1956     goto done;
1957
1958   max_deq = transport_max_tx_dequeue (&tc->connection);
1959   max_deq -= tc->snd_nxt - tc->snd_una;
1960   if (max_deq)
1961     {
1962       snd_space = clib_min (max_deq, snd_space);
1963       burst_size = clib_min (burst_size - n_segs, snd_space / tc->snd_mss);
1964       n_segs_now = tcp_fast_retransmit_unsent (wrk, tc, burst_size);
1965       if (max_deq > n_segs_now * tc->snd_mss)
1966         tcp_program_fastretransmit (tc);
1967       n_segs += n_segs_now;
1968     }
1969
1970 done:
1971   tcp_fastrecovery_first_off (tc);
1972   return n_segs;
1973 }
1974
1975 /**
1976  * Do fast retransmit
1977  */
1978 int
1979 tcp_fast_retransmit (tcp_worker_ctx_t * wrk, tcp_connection_t * tc,
1980                      u32 burst_size)
1981 {
1982   if (tcp_opts_sack_permitted (&tc->rcv_opts))
1983     return tcp_fast_retransmit_sack (wrk, tc, burst_size);
1984   else
1985     return tcp_fast_retransmit_no_sack (wrk, tc, burst_size);
1986 }
1987
1988 static int
1989 tcp_send_acks (tcp_connection_t * tc, u32 max_burst_size)
1990 {
1991   int j, n_acks;
1992
1993   if (!tc->pending_dupacks)
1994     {
1995       tcp_send_ack (tc);
1996       return 1;
1997     }
1998
1999   /* If we're supposed to send dupacks but have no ooo data
2000    * send only one ack */
2001   if (!vec_len (tc->snd_sacks))
2002     {
2003       tcp_send_ack (tc);
2004       return 1;
2005     }
2006
2007   /* Start with first sack block */
2008   tc->snd_sack_pos = 0;
2009
2010   /* Generate enough dupacks to cover all sack blocks. Do not generate
2011    * more sacks than the number of packets received. But do generate at
2012    * least 3, i.e., the number needed to signal congestion, if needed. */
2013   n_acks = vec_len (tc->snd_sacks) / TCP_OPTS_MAX_SACK_BLOCKS;
2014   n_acks = clib_min (n_acks, tc->pending_dupacks);
2015   n_acks = clib_max (n_acks, clib_min (tc->pending_dupacks, 3));
2016   for (j = 0; j < clib_min (n_acks, max_burst_size); j++)
2017     tcp_send_ack (tc);
2018
2019   if (n_acks < max_burst_size)
2020     {
2021       tc->pending_dupacks = 0;
2022       tc->snd_sack_pos = 0;
2023       tc->dupacks_out += n_acks;
2024       return n_acks;
2025     }
2026   else
2027     {
2028       TCP_DBG ("constrained by burst size");
2029       tc->pending_dupacks = n_acks - max_burst_size;
2030       tc->dupacks_out += max_burst_size;
2031       tcp_program_dupack (tc);
2032       return max_burst_size;
2033     }
2034 }
2035
2036 static int
2037 tcp_do_fastretransmit (tcp_connection_t * tc, u32 max_burst_size)
2038 {
2039   u32 n_segs = 0, burst_size, sent_bytes, burst_bytes;
2040   tcp_worker_ctx_t *wrk;
2041
2042   wrk = tcp_get_worker (tc->c_thread_index);
2043   burst_bytes = transport_connection_tx_pacer_burst (&tc->connection,
2044                                                      wrk->vm->
2045                                                      clib_time.last_cpu_time);
2046   burst_size = clib_min (max_burst_size, burst_bytes / tc->snd_mss);
2047   if (!burst_size)
2048     {
2049       tcp_program_fastretransmit (tc);
2050       return 0;
2051     }
2052
2053   n_segs = tcp_fast_retransmit (wrk, tc, burst_size);
2054   sent_bytes = clib_min (n_segs * tc->snd_mss, burst_bytes);
2055   transport_connection_tx_pacer_update_bytes (&tc->connection, sent_bytes);
2056   return n_segs;
2057 }
2058
2059 int
2060 tcp_session_custom_tx (void *conn, u32 max_burst_size)
2061 {
2062   tcp_connection_t *tc = (tcp_connection_t *) conn;
2063   u32 n_segs = 0;
2064
2065   if (tcp_in_fastrecovery (tc) && (tc->flags & TCP_CONN_FRXT_PENDING))
2066     {
2067       tc->flags &= ~TCP_CONN_FRXT_PENDING;
2068       n_segs = tcp_do_fastretransmit (tc, max_burst_size);
2069       max_burst_size -= n_segs;
2070     }
2071
2072   if (!(tc->flags & TCP_CONN_SNDACK))
2073     return n_segs;
2074
2075   tc->flags &= ~TCP_CONN_SNDACK;
2076
2077   /* We have retransmitted packets and no dupack */
2078   if (n_segs && !tc->pending_dupacks)
2079     return n_segs;
2080
2081   if (!max_burst_size)
2082     {
2083       tcp_program_ack (tc);
2084       return max_burst_size;
2085     }
2086
2087   n_segs += tcp_send_acks (tc, max_burst_size);
2088
2089   return n_segs;
2090 }
2091 #endif /* CLIB_MARCH_VARIANT */
2092
2093 static void
2094 tcp_output_handle_link_local (tcp_connection_t * tc0, vlib_buffer_t * b0,
2095                               u16 * next0, u32 * error0)
2096 {
2097   ip_adjacency_t *adj;
2098   adj_index_t ai;
2099
2100   /* Not thread safe but as long as the connection exists the adj should
2101    * not be removed */
2102   ai = adj_nbr_find (FIB_PROTOCOL_IP6, VNET_LINK_IP6, &tc0->c_rmt_ip,
2103                      tc0->sw_if_index);
2104   if (ai == ADJ_INDEX_INVALID)
2105     {
2106       vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
2107       *next0 = TCP_OUTPUT_NEXT_DROP;
2108       *error0 = TCP_ERROR_LINK_LOCAL_RW;
2109       return;
2110     }
2111
2112   adj = adj_get (ai);
2113   if (PREDICT_TRUE (adj->lookup_next_index == IP_LOOKUP_NEXT_REWRITE))
2114     *next0 = TCP_OUTPUT_NEXT_IP_REWRITE;
2115   else if (adj->lookup_next_index == IP_LOOKUP_NEXT_ARP)
2116     *next0 = TCP_OUTPUT_NEXT_IP_ARP;
2117   else
2118     {
2119       *next0 = TCP_OUTPUT_NEXT_DROP;
2120       *error0 = TCP_ERROR_LINK_LOCAL_RW;
2121     }
2122   vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ai;
2123 }
2124
2125 static void
2126 tcp46_output_trace_frame (vlib_main_t * vm, vlib_node_runtime_t * node,
2127                           u32 * to_next, u32 n_bufs)
2128 {
2129   u32 n_trace = vlib_get_trace_count (vm, node);
2130   tcp_connection_t *tc;
2131   tcp_tx_trace_t *t;
2132   vlib_buffer_t *b;
2133   tcp_header_t *th;
2134   int i;
2135
2136   for (i = 0; i < clib_min (n_trace, n_bufs); i++)
2137     {
2138       b = vlib_get_buffer (vm, to_next[i]);
2139       th = vlib_buffer_get_current (b);
2140       tc = tcp_connection_get (vnet_buffer (b)->tcp.connection_index,
2141                                vm->thread_index);
2142       t = vlib_add_trace (vm, node, b, sizeof (*t));
2143       clib_memcpy_fast (&t->tcp_header, th, sizeof (t->tcp_header));
2144       clib_memcpy_fast (&t->tcp_connection, tc, sizeof (t->tcp_connection));
2145     }
2146 }
2147
2148 always_inline void
2149 tcp_output_push_ip (vlib_main_t * vm, vlib_buffer_t * b0,
2150                     tcp_connection_t * tc0, u8 is_ip4)
2151 {
2152   tcp_header_t *th0 = 0;
2153
2154   th0 = vlib_buffer_get_current (b0);
2155   TCP_EVT_DBG (TCP_EVT_OUTPUT, tc0, th0->flags, b0->current_length);
2156   if (is_ip4)
2157     {
2158       vlib_buffer_push_ip4 (vm, b0, &tc0->c_lcl_ip4, &tc0->c_rmt_ip4,
2159                             IP_PROTOCOL_TCP, 1);
2160       b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
2161       vnet_buffer (b0)->l4_hdr_offset = (u8 *) th0 - b0->data;
2162       th0->checksum = 0;
2163     }
2164   else
2165     {
2166       ip6_header_t *ih0;
2167       ih0 = vlib_buffer_push_ip6 (vm, b0, &tc0->c_lcl_ip6,
2168                                   &tc0->c_rmt_ip6, IP_PROTOCOL_TCP);
2169       b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
2170       vnet_buffer (b0)->l3_hdr_offset = (u8 *) ih0 - b0->data;
2171       vnet_buffer (b0)->l4_hdr_offset = (u8 *) th0 - b0->data;
2172       th0->checksum = 0;
2173     }
2174 }
2175
2176 always_inline void
2177 tcp_output_handle_packet (tcp_connection_t * tc0, vlib_buffer_t * b0,
2178                           u32 * error0, u16 * next0, u8 is_ip4)
2179 {
2180
2181   if (PREDICT_FALSE (tc0->state == TCP_STATE_CLOSED))
2182     {
2183       *error0 = TCP_ERROR_INVALID_CONNECTION;
2184       *next0 = TCP_OUTPUT_NEXT_DROP;
2185       return;
2186     }
2187
2188   /* If next_index is not drop use it */
2189   if (tc0->next_node_index)
2190     {
2191       *next0 = tc0->next_node_index;
2192       vnet_buffer (b0)->tcp.next_node_opaque = tc0->next_node_opaque;
2193     }
2194
2195   vnet_buffer (b0)->sw_if_index[VLIB_TX] = tc0->c_fib_index;
2196   vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
2197
2198   if (!is_ip4)
2199     {
2200       if (PREDICT_FALSE (ip6_address_is_link_local_unicast (&tc0->c_rmt_ip6)))
2201         tcp_output_handle_link_local (tc0, b0, next0, error0);
2202     }
2203
2204   if (!TCP_ALWAYS_ACK)
2205     tcp_timer_reset (tc0, TCP_TIMER_DELACK);
2206
2207   tc0->segs_out += 1;
2208 }
2209
2210 always_inline uword
2211 tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2212                      vlib_frame_t * frame, int is_ip4)
2213 {
2214   u32 n_left_from, *from, thread_index = vm->thread_index;
2215   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
2216   u16 nexts[VLIB_FRAME_SIZE], *next;
2217
2218   from = vlib_frame_vector_args (frame);
2219   n_left_from = frame->n_vectors;
2220   tcp_set_time_now (tcp_get_worker (thread_index));
2221
2222   if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
2223     tcp46_output_trace_frame (vm, node, from, n_left_from);
2224
2225   vlib_get_buffers (vm, from, bufs, n_left_from);
2226   b = bufs;
2227   next = nexts;
2228
2229   while (n_left_from >= 4)
2230     {
2231       u32 error0 = TCP_ERROR_PKTS_SENT, error1 = TCP_ERROR_PKTS_SENT;
2232       tcp_connection_t *tc0, *tc1;
2233
2234       {
2235         vlib_prefetch_buffer_header (b[2], STORE);
2236         CLIB_PREFETCH (b[2]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
2237
2238         vlib_prefetch_buffer_header (b[3], STORE);
2239         CLIB_PREFETCH (b[3]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
2240       }
2241
2242       next[0] = next[1] = TCP_OUTPUT_NEXT_IP_LOOKUP;
2243
2244       tc0 = tcp_connection_get (vnet_buffer (b[0])->tcp.connection_index,
2245                                 thread_index);
2246       tc1 = tcp_connection_get (vnet_buffer (b[1])->tcp.connection_index,
2247                                 thread_index);
2248
2249       tcp_output_push_ip (vm, b[0], tc0, is_ip4);
2250       tcp_output_push_ip (vm, b[1], tc1, is_ip4);
2251
2252       tcp_output_handle_packet (tc0, b[0], &error0, &next[0], is_ip4);
2253       tcp_output_handle_packet (tc1, b[1], &error1, &next[1], is_ip4);
2254
2255       b += 2;
2256       next += 2;
2257       n_left_from -= 2;
2258     }
2259   while (n_left_from > 0)
2260     {
2261       u32 error0 = TCP_ERROR_PKTS_SENT;
2262       tcp_connection_t *tc0;
2263
2264       if (n_left_from > 1)
2265         {
2266           vlib_prefetch_buffer_header (b[1], STORE);
2267           CLIB_PREFETCH (b[1]->data, 2 * CLIB_CACHE_LINE_BYTES, STORE);
2268         }
2269
2270       next[0] = TCP_OUTPUT_NEXT_IP_LOOKUP;
2271       tc0 = tcp_connection_get (vnet_buffer (b[0])->tcp.connection_index,
2272                                 thread_index);
2273
2274       tcp_output_push_ip (vm, b[0], tc0, is_ip4);
2275       tcp_output_handle_packet (tc0, b[0], &error0, &next[0], is_ip4);
2276
2277       b += 1;
2278       next += 1;
2279       n_left_from -= 1;
2280     }
2281
2282   vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
2283   return frame->n_vectors;
2284 }
2285
2286 VLIB_NODE_FN (tcp4_output_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
2287                                  vlib_frame_t * from_frame)
2288 {
2289   return tcp46_output_inline (vm, node, from_frame, 1 /* is_ip4 */ );
2290 }
2291
2292 VLIB_NODE_FN (tcp6_output_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
2293                                  vlib_frame_t * from_frame)
2294 {
2295   return tcp46_output_inline (vm, node, from_frame, 0 /* is_ip4 */ );
2296 }
2297
2298 /* *INDENT-OFF* */
2299 VLIB_REGISTER_NODE (tcp4_output_node) =
2300 {
2301   .name = "tcp4-output",
2302   /* Takes a vector of packets. */
2303   .vector_size = sizeof (u32),
2304   .n_errors = TCP_N_ERROR,
2305   .protocol_hint = VLIB_NODE_PROTO_HINT_TCP,
2306   .error_strings = tcp_error_strings,
2307   .n_next_nodes = TCP_OUTPUT_N_NEXT,
2308   .next_nodes = {
2309 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
2310     foreach_tcp4_output_next
2311 #undef _
2312   },
2313   .format_buffer = format_tcp_header,
2314   .format_trace = format_tcp_tx_trace,
2315 };
2316 /* *INDENT-ON* */
2317
2318 /* *INDENT-OFF* */
2319 VLIB_REGISTER_NODE (tcp6_output_node) =
2320 {
2321   .name = "tcp6-output",
2322     /* Takes a vector of packets. */
2323   .vector_size = sizeof (u32),
2324   .n_errors = TCP_N_ERROR,
2325   .protocol_hint = VLIB_NODE_PROTO_HINT_TCP,
2326   .error_strings = tcp_error_strings,
2327   .n_next_nodes = TCP_OUTPUT_N_NEXT,
2328   .next_nodes = {
2329 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
2330     foreach_tcp6_output_next
2331 #undef _
2332   },
2333   .format_buffer = format_tcp_header,
2334   .format_trace = format_tcp_tx_trace,
2335 };
2336 /* *INDENT-ON* */
2337
2338 typedef enum _tcp_reset_next
2339 {
2340   TCP_RESET_NEXT_DROP,
2341   TCP_RESET_NEXT_IP_LOOKUP,
2342   TCP_RESET_N_NEXT
2343 } tcp_reset_next_t;
2344
2345 #define foreach_tcp4_reset_next         \
2346   _(DROP, "error-drop")                 \
2347   _(IP_LOOKUP, "ip4-lookup")
2348
2349 #define foreach_tcp6_reset_next         \
2350   _(DROP, "error-drop")                 \
2351   _(IP_LOOKUP, "ip6-lookup")
2352
2353 static uword
2354 tcp46_send_reset_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
2355                          vlib_frame_t * from_frame, u8 is_ip4)
2356 {
2357   u32 n_left_from, next_index, *from, *to_next;
2358   u32 my_thread_index = vm->thread_index;
2359
2360   from = vlib_frame_vector_args (from_frame);
2361   n_left_from = from_frame->n_vectors;
2362
2363   next_index = node->cached_next_index;
2364
2365   while (n_left_from > 0)
2366     {
2367       u32 n_left_to_next;
2368
2369       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2370
2371       while (n_left_from > 0 && n_left_to_next > 0)
2372         {
2373           u32 bi0;
2374           vlib_buffer_t *b0;
2375           tcp_tx_trace_t *t0;
2376           tcp_header_t *th0;
2377           u32 error0 = TCP_ERROR_RST_SENT, next0 = TCP_RESET_NEXT_IP_LOOKUP;
2378
2379           bi0 = from[0];
2380           to_next[0] = bi0;
2381           from += 1;
2382           to_next += 1;
2383           n_left_from -= 1;
2384           n_left_to_next -= 1;
2385
2386           b0 = vlib_get_buffer (vm, bi0);
2387
2388           if (tcp_make_reset_in_place (vm, b0, vnet_buffer (b0)->tcp.flags,
2389                                        my_thread_index, is_ip4))
2390             {
2391               error0 = TCP_ERROR_LOOKUP_DROPS;
2392               next0 = TCP_RESET_NEXT_DROP;
2393               goto done;
2394             }
2395
2396           /* Prepare to send to IP lookup */
2397           vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
2398           next0 = TCP_RESET_NEXT_IP_LOOKUP;
2399
2400         done:
2401           b0->error = node->errors[error0];
2402           b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
2403           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2404             {
2405               th0 = vlib_buffer_get_current (b0);
2406               if (is_ip4)
2407                 th0 = ip4_next_header ((ip4_header_t *) th0);
2408               else
2409                 th0 = ip6_next_header ((ip6_header_t *) th0);
2410               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
2411               clib_memcpy_fast (&t0->tcp_header, th0,
2412                                 sizeof (t0->tcp_header));
2413             }
2414
2415           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2416                                            n_left_to_next, bi0, next0);
2417         }
2418       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2419     }
2420   return from_frame->n_vectors;
2421 }
2422
2423 VLIB_NODE_FN (tcp4_reset_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
2424                                 vlib_frame_t * from_frame)
2425 {
2426   return tcp46_send_reset_inline (vm, node, from_frame, 1);
2427 }
2428
2429 VLIB_NODE_FN (tcp6_reset_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
2430                                 vlib_frame_t * from_frame)
2431 {
2432   return tcp46_send_reset_inline (vm, node, from_frame, 0);
2433 }
2434
2435 /* *INDENT-OFF* */
2436 VLIB_REGISTER_NODE (tcp4_reset_node) = {
2437   .name = "tcp4-reset",
2438   .vector_size = sizeof (u32),
2439   .n_errors = TCP_N_ERROR,
2440   .error_strings = tcp_error_strings,
2441   .n_next_nodes = TCP_RESET_N_NEXT,
2442   .next_nodes = {
2443 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
2444     foreach_tcp4_reset_next
2445 #undef _
2446   },
2447   .format_trace = format_tcp_tx_trace,
2448 };
2449 /* *INDENT-ON* */
2450
2451 /* *INDENT-OFF* */
2452 VLIB_REGISTER_NODE (tcp6_reset_node) = {
2453   .name = "tcp6-reset",
2454   .vector_size = sizeof (u32),
2455   .n_errors = TCP_N_ERROR,
2456   .error_strings = tcp_error_strings,
2457   .n_next_nodes = TCP_RESET_N_NEXT,
2458   .next_nodes = {
2459 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
2460     foreach_tcp6_reset_next
2461 #undef _
2462   },
2463   .format_trace = format_tcp_tx_trace,
2464 };
2465 /* *INDENT-ON* */
2466
2467 /*
2468  * fd.io coding-style-patch-verification: ON
2469  *
2470  * Local Variables:
2471  * eval: (c-set-style "gnu")
2472  * End:
2473  */