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