Overall tcp performance improvements (VPP-846)
[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
19 vlib_node_registration_t tcp4_output_node;
20 vlib_node_registration_t tcp6_output_node;
21
22 typedef enum _tcp_output_nect
23 {
24   TCP_OUTPUT_NEXT_DROP,
25   TCP_OUTPUT_NEXT_IP_LOOKUP,
26   TCP_OUTPUT_N_NEXT
27 } tcp_output_next_t;
28
29 #define foreach_tcp4_output_next                \
30   _ (DROP, "error-drop")                        \
31   _ (IP_LOOKUP, "ip4-lookup")
32
33 #define foreach_tcp6_output_next                \
34   _ (DROP, "error-drop")                        \
35   _ (IP_LOOKUP, "ip6-lookup")
36
37 static char *tcp_error_strings[] = {
38 #define tcp_error(n,s) s,
39 #include <vnet/tcp/tcp_error.def>
40 #undef tcp_error
41 };
42
43 typedef struct
44 {
45   tcp_header_t tcp_header;
46   tcp_connection_t tcp_connection;
47 } tcp_tx_trace_t;
48
49 u16 dummy_mtu = 1460;
50
51 u8 *
52 format_tcp_tx_trace (u8 * s, va_list * args)
53 {
54   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
55   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
56   tcp_tx_trace_t *t = va_arg (*args, tcp_tx_trace_t *);
57   uword indent = format_get_indent (s);
58
59   s = format (s, "%U\n%U%U",
60               format_tcp_header, &t->tcp_header, 128,
61               format_white_space, indent,
62               format_tcp_connection, &t->tcp_connection, 1);
63
64   return s;
65 }
66
67 static u8
68 tcp_window_compute_scale (u32 available_space)
69 {
70   u8 wnd_scale = 0;
71   while (wnd_scale < TCP_MAX_WND_SCALE
72          && (available_space >> wnd_scale) > TCP_WND_MAX)
73     wnd_scale++;
74   return wnd_scale;
75 }
76
77 /**
78  * TCP's IW as recommended by RFC6928
79  */
80 always_inline u32
81 tcp_initial_wnd_unscaled (tcp_connection_t * tc)
82 {
83   return TCP_IW_N_SEGMENTS * tc->mss;
84 }
85
86 /**
87  * Compute initial window and scale factor. As per RFC1323, window field in
88  * SYN and SYN-ACK segments is never scaled.
89  */
90 u32
91 tcp_initial_window_to_advertise (tcp_connection_t * tc)
92 {
93   u32 max_fifo;
94
95   /* Initial wnd for SYN. Fifos are not allocated yet.
96    * Use some predefined value. For SYN-ACK we still want the
97    * scale to be computed in the same way */
98   max_fifo = TCP_MAX_RX_FIFO_SIZE;
99
100   tc->rcv_wscale = tcp_window_compute_scale (max_fifo);
101   tc->rcv_wnd = tcp_initial_wnd_unscaled (tc);
102
103   return clib_min (tc->rcv_wnd, TCP_WND_MAX);
104 }
105
106 /**
107  * Compute and return window to advertise, scaled as per RFC1323
108  */
109 u32
110 tcp_window_to_advertise (tcp_connection_t * tc, tcp_state_t state)
111 {
112   if (state < TCP_STATE_ESTABLISHED)
113     return tcp_initial_window_to_advertise (tc);
114
115   tcp_update_rcv_wnd (tc);
116
117   if (tc->rcv_wnd == 0)
118     {
119       tc->flags |= TCP_CONN_SENT_RCV_WND0;
120     }
121   else
122     {
123       tc->flags &= ~TCP_CONN_SENT_RCV_WND0;
124     }
125
126   return tc->rcv_wnd >> tc->rcv_wscale;
127 }
128
129 void
130 tcp_update_rcv_wnd (tcp_connection_t * tc)
131 {
132   i32 observed_wnd;
133   u32 available_space, max_fifo, wnd;
134
135   /*
136    * Figure out how much space we have available
137    */
138   available_space = stream_session_max_rx_enqueue (&tc->connection);
139   max_fifo = stream_session_rx_fifo_size (&tc->connection);
140
141   ASSERT (tc->rcv_opts.mss < max_fifo);
142   if (available_space < tc->rcv_opts.mss && available_space < max_fifo >> 3)
143     available_space = 0;
144
145   /*
146    * Use the above and what we know about what we've previously advertised
147    * to compute the new window
148    */
149   observed_wnd = (i32) tc->rcv_wnd - (tc->rcv_nxt - tc->rcv_las);
150   if (observed_wnd < 0)
151     observed_wnd = 0;
152
153   /* Bad. Thou shalt not shrink */
154   if (available_space < observed_wnd)
155     {
156       wnd = observed_wnd;
157       TCP_EVT_DBG (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space);
158     }
159   else
160     {
161       wnd = available_space;
162     }
163
164   /* Make sure we have a multiple of rcv_wscale */
165   if (wnd && tc->rcv_wscale)
166     {
167       wnd &= ~(1 << tc->rcv_wscale);
168       if (wnd == 0)
169         wnd = 1 << tc->rcv_wscale;
170     }
171
172   tc->rcv_wnd = clib_min (wnd, TCP_WND_MAX << tc->rcv_wscale);
173 }
174
175 /**
176  * Write TCP options to segment.
177  */
178 u32
179 tcp_options_write (u8 * data, tcp_options_t * opts)
180 {
181   u32 opts_len = 0;
182   u32 buf, seq_len = 4;
183
184   if (tcp_opts_mss (opts))
185     {
186       *data++ = TCP_OPTION_MSS;
187       *data++ = TCP_OPTION_LEN_MSS;
188       buf = clib_host_to_net_u16 (opts->mss);
189       clib_memcpy (data, &buf, sizeof (opts->mss));
190       data += sizeof (opts->mss);
191       opts_len += TCP_OPTION_LEN_MSS;
192     }
193
194   if (tcp_opts_wscale (opts))
195     {
196       *data++ = TCP_OPTION_WINDOW_SCALE;
197       *data++ = TCP_OPTION_LEN_WINDOW_SCALE;
198       *data++ = opts->wscale;
199       opts_len += TCP_OPTION_LEN_WINDOW_SCALE;
200     }
201
202   if (tcp_opts_sack_permitted (opts))
203     {
204       *data++ = TCP_OPTION_SACK_PERMITTED;
205       *data++ = TCP_OPTION_LEN_SACK_PERMITTED;
206       opts_len += TCP_OPTION_LEN_SACK_PERMITTED;
207     }
208
209   if (tcp_opts_tstamp (opts))
210     {
211       *data++ = TCP_OPTION_TIMESTAMP;
212       *data++ = TCP_OPTION_LEN_TIMESTAMP;
213       buf = clib_host_to_net_u32 (opts->tsval);
214       clib_memcpy (data, &buf, sizeof (opts->tsval));
215       data += sizeof (opts->tsval);
216       buf = clib_host_to_net_u32 (opts->tsecr);
217       clib_memcpy (data, &buf, sizeof (opts->tsecr));
218       data += sizeof (opts->tsecr);
219       opts_len += TCP_OPTION_LEN_TIMESTAMP;
220     }
221
222   if (tcp_opts_sack (opts))
223     {
224       int i;
225       u32 n_sack_blocks = clib_min (vec_len (opts->sacks),
226                                     TCP_OPTS_MAX_SACK_BLOCKS);
227
228       if (n_sack_blocks != 0)
229         {
230           *data++ = TCP_OPTION_SACK_BLOCK;
231           *data++ = 2 + n_sack_blocks * TCP_OPTION_LEN_SACK_BLOCK;
232           for (i = 0; i < n_sack_blocks; i++)
233             {
234               buf = clib_host_to_net_u32 (opts->sacks[i].start);
235               clib_memcpy (data, &buf, seq_len);
236               data += seq_len;
237               buf = clib_host_to_net_u32 (opts->sacks[i].end);
238               clib_memcpy (data, &buf, seq_len);
239               data += seq_len;
240             }
241           opts_len += 2 + n_sack_blocks * TCP_OPTION_LEN_SACK_BLOCK;
242         }
243     }
244
245   /* Terminate TCP options */
246   if (opts_len % 4)
247     {
248       *data++ = TCP_OPTION_EOL;
249       opts_len += TCP_OPTION_LEN_EOL;
250     }
251
252   /* Pad with zeroes to a u32 boundary */
253   while (opts_len % 4)
254     {
255       *data++ = TCP_OPTION_NOOP;
256       opts_len += TCP_OPTION_LEN_NOOP;
257     }
258   return opts_len;
259 }
260
261 always_inline int
262 tcp_make_syn_options (tcp_options_t * opts, u8 wnd_scale)
263 {
264   u8 len = 0;
265
266   opts->flags |= TCP_OPTS_FLAG_MSS;
267   opts->mss = dummy_mtu;        /*XXX discover that */
268   len += TCP_OPTION_LEN_MSS;
269
270   opts->flags |= TCP_OPTS_FLAG_WSCALE;
271   opts->wscale = wnd_scale;
272   len += TCP_OPTION_LEN_WINDOW_SCALE;
273
274   opts->flags |= TCP_OPTS_FLAG_TSTAMP;
275   opts->tsval = tcp_time_now ();
276   opts->tsecr = 0;
277   len += TCP_OPTION_LEN_TIMESTAMP;
278
279   if (TCP_USE_SACKS)
280     {
281       opts->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
282       len += TCP_OPTION_LEN_SACK_PERMITTED;
283     }
284
285   /* Align to needed boundary */
286   len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
287   return len;
288 }
289
290 always_inline int
291 tcp_make_synack_options (tcp_connection_t * tc, tcp_options_t * opts)
292 {
293   u8 len = 0;
294
295   opts->flags |= TCP_OPTS_FLAG_MSS;
296   opts->mss = tc->mss;
297   len += TCP_OPTION_LEN_MSS;
298
299   if (tcp_opts_wscale (&tc->rcv_opts))
300     {
301       opts->flags |= TCP_OPTS_FLAG_WSCALE;
302       opts->wscale = tc->rcv_wscale;
303       len += TCP_OPTION_LEN_WINDOW_SCALE;
304     }
305
306   if (tcp_opts_tstamp (&tc->rcv_opts))
307     {
308       opts->flags |= TCP_OPTS_FLAG_TSTAMP;
309       opts->tsval = tcp_time_now ();
310       opts->tsecr = tc->tsval_recent;
311       len += TCP_OPTION_LEN_TIMESTAMP;
312     }
313
314   if (tcp_opts_sack_permitted (&tc->rcv_opts))
315     {
316       opts->flags |= TCP_OPTS_FLAG_SACK_PERMITTED;
317       len += TCP_OPTION_LEN_SACK_PERMITTED;
318     }
319
320   /* Align to needed boundary */
321   len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
322   return len;
323 }
324
325 always_inline int
326 tcp_make_established_options (tcp_connection_t * tc, tcp_options_t * opts)
327 {
328   u8 len = 0;
329
330   opts->flags = 0;
331
332   if (tcp_opts_tstamp (&tc->rcv_opts))
333     {
334       opts->flags |= TCP_OPTS_FLAG_TSTAMP;
335       opts->tsval = tcp_time_now ();
336       opts->tsecr = tc->tsval_recent;
337       len += TCP_OPTION_LEN_TIMESTAMP;
338     }
339   if (tcp_opts_sack_permitted (&tc->rcv_opts))
340     {
341       if (vec_len (tc->snd_sacks))
342         {
343           opts->flags |= TCP_OPTS_FLAG_SACK;
344           opts->sacks = tc->snd_sacks;
345           opts->n_sack_blocks = clib_min (vec_len (tc->snd_sacks),
346                                           TCP_OPTS_MAX_SACK_BLOCKS);
347           len += 2 + TCP_OPTION_LEN_SACK_BLOCK * opts->n_sack_blocks;
348         }
349     }
350
351   /* Align to needed boundary */
352   len += (TCP_OPTS_ALIGN - len % TCP_OPTS_ALIGN) % TCP_OPTS_ALIGN;
353   return len;
354 }
355
356 always_inline int
357 tcp_make_options (tcp_connection_t * tc, tcp_options_t * opts,
358                   tcp_state_t state)
359 {
360   switch (state)
361     {
362     case TCP_STATE_ESTABLISHED:
363     case TCP_STATE_FIN_WAIT_1:
364       return tcp_make_established_options (tc, opts);
365     case TCP_STATE_SYN_RCVD:
366       return tcp_make_synack_options (tc, opts);
367     case TCP_STATE_SYN_SENT:
368       return tcp_make_syn_options (opts, tc->rcv_wscale);
369     default:
370       clib_warning ("Not handled!");
371       return 0;
372     }
373 }
374
375 /**
376  * Update max segment size we're able to process.
377  *
378  * The value is constrained by our interface's MTU and IP options. It is
379  * also what we advertise to our peer.
380  */
381 void
382 tcp_update_rcv_mss (tcp_connection_t * tc)
383 {
384   /* TODO find our iface MTU */
385   tc->mss = dummy_mtu;
386 }
387
388 /**
389  * Update snd_mss to reflect the effective segment size that we can send
390  * by taking into account all TCP options, including SACKs
391  */
392 void
393 tcp_update_snd_mss (tcp_connection_t * tc)
394 {
395   /* Compute options to be used for connection. These may be reused when
396    * sending data or to compute the effective mss (snd_mss) */
397   tc->snd_opts_len =
398     tcp_make_options (tc, &tc->snd_opts, TCP_STATE_ESTABLISHED);
399
400   /* XXX check if MTU has been updated */
401   tc->snd_mss = clib_min (tc->mss, tc->rcv_opts.mss) - tc->snd_opts_len;
402   ASSERT (tc->snd_mss > 0);
403 }
404
405 void
406 tcp_init_mss (tcp_connection_t * tc)
407 {
408   u16 default_min_mss = 536;
409   tcp_update_rcv_mss (tc);
410
411   /* TODO cache mss and consider PMTU discovery */
412   tc->snd_mss = clib_min (tc->rcv_opts.mss, tc->mss);
413
414   if (tc->snd_mss < 45)
415     {
416       clib_warning ("snd mss is 0");
417       /* Assume that at least the min default mss works */
418       tc->snd_mss = default_min_mss;
419       tc->rcv_opts.mss = default_min_mss;
420     }
421
422   /* We should have enough space for 40 bytes of options */
423   ASSERT (tc->snd_mss > 45);
424
425   /* If we use timestamp option, account for it */
426   if (tcp_opts_tstamp (&tc->rcv_opts))
427     tc->snd_mss -= TCP_OPTION_LEN_TIMESTAMP;
428 }
429
430 #define tcp_get_free_buffer_index(tm, bidx)                             \
431 do {                                                                    \
432   u32 *my_tx_buffers, n_free_buffers;                                   \
433   u32 thread_index = vlib_get_thread_index();                                   \
434   my_tx_buffers = tm->tx_buffers[thread_index];                            \
435   if (PREDICT_FALSE(vec_len (my_tx_buffers) == 0))                      \
436     {                                                                   \
437       n_free_buffers = 32;      /* TODO config or macro */              \
438       vec_validate (my_tx_buffers, n_free_buffers - 1);                 \
439       _vec_len(my_tx_buffers) = vlib_buffer_alloc_from_free_list (      \
440           tm->vlib_main, my_tx_buffers, n_free_buffers,                 \
441           VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);                         \
442       tm->tx_buffers[thread_index] = my_tx_buffers;                        \
443     }                                                                   \
444   /* buffer shortage */                                                 \
445   if (PREDICT_FALSE (vec_len (my_tx_buffers) == 0))                     \
446     return;                                                             \
447   *bidx = my_tx_buffers[_vec_len (my_tx_buffers)-1];                    \
448   _vec_len (my_tx_buffers) -= 1;                                        \
449 } while (0)
450
451 #define tcp_return_buffer(tm)                                           \
452 do {                                                                    \
453   u32 *my_tx_buffers;                                                   \
454   u32 thread_index = vlib_get_thread_index();                                   \
455   my_tx_buffers = tm->tx_buffers[thread_index];                                 \
456   _vec_len (my_tx_buffers) +=1;                                         \
457 } while (0)
458
459 always_inline void
460 tcp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b)
461 {
462   vlib_buffer_t *it = b;
463   do
464     {
465       it->current_data = 0;
466       it->current_length = 0;
467       it->total_length_not_including_first_buffer = 0;
468     }
469   while ((it->flags & VLIB_BUFFER_NEXT_PRESENT)
470          && (it = vlib_get_buffer (vm, it->next_buffer)));
471
472   /* Leave enough space for headers */
473   vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
474   vnet_buffer (b)->tcp.flags = 0;
475 }
476
477 /**
478  * Prepare ACK
479  */
480 void
481 tcp_make_ack_i (tcp_connection_t * tc, vlib_buffer_t * b, tcp_state_t state,
482                 u8 flags)
483 {
484   tcp_options_t _snd_opts, *snd_opts = &_snd_opts;
485   u8 tcp_opts_len, tcp_hdr_opts_len;
486   tcp_header_t *th;
487   u16 wnd;
488
489   wnd = tcp_window_to_advertise (tc, state);
490
491   /* Make and write options */
492   tcp_opts_len = tcp_make_established_options (tc, snd_opts);
493   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
494
495   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
496                              tc->rcv_nxt, tcp_hdr_opts_len, flags, wnd);
497
498   tcp_options_write ((u8 *) (th + 1), snd_opts);
499   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
500 }
501
502 /**
503  * Convert buffer to ACK
504  */
505 void
506 tcp_make_ack (tcp_connection_t * tc, vlib_buffer_t * b)
507 {
508   vlib_main_t *vm = vlib_get_main ();
509
510   tcp_reuse_buffer (vm, b);
511   tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, TCP_FLAG_ACK);
512   TCP_EVT_DBG (TCP_EVT_ACK_SENT, tc);
513   vnet_buffer (b)->tcp.flags = TCP_BUF_FLAG_ACK;
514   tc->rcv_las = tc->rcv_nxt;
515 }
516
517 /**
518  * Convert buffer to FIN-ACK
519  */
520 void
521 tcp_make_fin (tcp_connection_t * tc, vlib_buffer_t * b)
522 {
523   vlib_main_t *vm = vlib_get_main ();
524   u8 flags = 0;
525
526   tcp_reuse_buffer (vm, b);
527
528   flags = TCP_FLAG_FIN | TCP_FLAG_ACK;
529   tcp_make_ack_i (tc, b, TCP_STATE_ESTABLISHED, flags);
530
531   /* Reset flags, make sure ack is sent */
532   vnet_buffer (b)->tcp.flags &= ~TCP_BUF_FLAG_DUPACK;
533
534   tc->snd_nxt += 1;
535 }
536
537 /**
538  * Convert buffer to SYN-ACK
539  */
540 void
541 tcp_make_synack (tcp_connection_t * tc, vlib_buffer_t * b)
542 {
543   vlib_main_t *vm = vlib_get_main ();
544   tcp_options_t _snd_opts, *snd_opts = &_snd_opts;
545   u8 tcp_opts_len, tcp_hdr_opts_len;
546   tcp_header_t *th;
547   u16 initial_wnd;
548   u32 time_now;
549
550   memset (snd_opts, 0, sizeof (*snd_opts));
551
552   tcp_reuse_buffer (vm, b);
553
554   /* Set random initial sequence */
555   time_now = tcp_time_now ();
556
557   tc->iss = random_u32 (&time_now);
558   tc->snd_una = tc->iss;
559   tc->snd_nxt = tc->iss + 1;
560   tc->snd_una_max = tc->snd_nxt;
561
562   initial_wnd = tcp_initial_window_to_advertise (tc);
563
564   /* Make and write options */
565   tcp_opts_len = tcp_make_synack_options (tc, snd_opts);
566   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
567
568   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
569                              tc->rcv_nxt, tcp_hdr_opts_len,
570                              TCP_FLAG_SYN | TCP_FLAG_ACK, initial_wnd);
571
572   tcp_options_write ((u8 *) (th + 1), snd_opts);
573
574   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
575   vnet_buffer (b)->tcp.flags = TCP_BUF_FLAG_ACK;
576
577   /* Init retransmit timer */
578   tcp_retransmit_timer_set (tc);
579 }
580
581 always_inline void
582 tcp_enqueue_to_ip_lookup (vlib_main_t * vm, vlib_buffer_t * b, u32 bi,
583                           u8 is_ip4)
584 {
585   u32 *to_next, next_index;
586   vlib_frame_t *f;
587
588   b->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
589   b->error = 0;
590
591   /* Default FIB for now */
592   vnet_buffer (b)->sw_if_index[VLIB_TX] = 0;
593
594   /* Send to IP lookup */
595   next_index = is_ip4 ? ip4_lookup_node.index : ip6_lookup_node.index;
596   f = vlib_get_frame_to_node (vm, next_index);
597
598   /* Enqueue the packet */
599   to_next = vlib_frame_vector_args (f);
600   to_next[0] = bi;
601   f->n_vectors = 1;
602   vlib_put_frame_to_node (vm, next_index, f);
603 }
604
605 int
606 tcp_make_reset_in_place (vlib_main_t * vm, vlib_buffer_t * b0,
607                          tcp_state_t state, u8 thread_index, u8 is_ip4)
608 {
609   ip4_header_t *ih4;
610   ip6_header_t *ih6;
611   tcp_header_t *th0;
612   ip4_address_t src_ip40, dst_ip40;
613   ip6_address_t src_ip60, dst_ip60;
614   u16 src_port, dst_port;
615   u32 tmp;
616   u32 seq, ack;
617   u8 flags;
618
619   /* Find IP and TCP headers */
620   th0 = tcp_buffer_hdr (b0);
621
622   /* Save src and dst ip */
623   if (is_ip4)
624     {
625       ih4 = vlib_buffer_get_current (b0);
626       ASSERT ((ih4->ip_version_and_header_length & 0xF0) == 0x40);
627       src_ip40.as_u32 = ih4->src_address.as_u32;
628       dst_ip40.as_u32 = ih4->dst_address.as_u32;
629     }
630   else
631     {
632       ih6 = vlib_buffer_get_current (b0);
633       ASSERT ((ih6->ip_version_traffic_class_and_flow_label & 0xF0) == 0x60);
634       clib_memcpy (&src_ip60, &ih6->src_address, sizeof (ip6_address_t));
635       clib_memcpy (&dst_ip60, &ih6->dst_address, sizeof (ip6_address_t));
636     }
637
638   src_port = th0->src_port;
639   dst_port = th0->dst_port;
640
641   /* Try to determine what/why we're actually resetting */
642   if (state == TCP_STATE_CLOSED)
643     {
644       if (!tcp_syn (th0))
645         return -1;
646
647       tmp = clib_net_to_host_u32 (th0->seq_number);
648
649       /* Got a SYN for no listener. */
650       flags = TCP_FLAG_RST | TCP_FLAG_ACK;
651       ack = clib_host_to_net_u32 (tmp + 1);
652       seq = 0;
653     }
654   else
655     {
656       flags = TCP_FLAG_RST;
657       seq = th0->ack_number;
658       ack = 0;
659     }
660
661   tcp_reuse_buffer (vm, b0);
662   th0 = vlib_buffer_push_tcp_net_order (b0, dst_port, src_port, seq, ack,
663                                         sizeof (tcp_header_t), flags, 0);
664
665   if (is_ip4)
666     {
667       ih4 = vlib_buffer_push_ip4 (vm, b0, &dst_ip40, &src_ip40,
668                                   IP_PROTOCOL_TCP);
669       th0->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ih4);
670     }
671   else
672     {
673       int bogus = ~0;
674       ih6 = vlib_buffer_push_ip6 (vm, b0, &dst_ip60, &src_ip60,
675                                   IP_PROTOCOL_TCP);
676       th0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ih6, &bogus);
677       ASSERT (!bogus);
678     }
679
680   return 0;
681 }
682
683 /**
684  *  Send reset without reusing existing buffer
685  */
686 void
687 tcp_send_reset (vlib_buffer_t * pkt, u8 is_ip4)
688 {
689   vlib_buffer_t *b;
690   u32 bi;
691   tcp_main_t *tm = vnet_get_tcp_main ();
692   vlib_main_t *vm = vlib_get_main ();
693   u8 tcp_hdr_len, flags = 0;
694   tcp_header_t *th, *pkt_th;
695   u32 seq, ack;
696   ip4_header_t *ih4, *pkt_ih4;
697   ip6_header_t *ih6, *pkt_ih6;
698
699   tcp_get_free_buffer_index (tm, &bi);
700   b = vlib_get_buffer (vm, bi);
701
702   /* Leave enough space for headers */
703   vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
704
705   /* Make and write options */
706   tcp_hdr_len = sizeof (tcp_header_t);
707
708   if (is_ip4)
709     {
710       pkt_ih4 = vlib_buffer_get_current (pkt);
711       pkt_th = ip4_next_header (pkt_ih4);
712     }
713   else
714     {
715       pkt_ih6 = vlib_buffer_get_current (pkt);
716       pkt_th = ip6_next_header (pkt_ih6);
717     }
718
719   if (tcp_ack (pkt_th))
720     {
721       flags = TCP_FLAG_RST;
722       seq = pkt_th->ack_number;
723       ack = 0;
724     }
725   else
726     {
727       flags = TCP_FLAG_RST | TCP_FLAG_ACK;
728       seq = 0;
729       ack = clib_host_to_net_u32 (vnet_buffer (pkt)->tcp.seq_end);
730     }
731
732   th = vlib_buffer_push_tcp_net_order (b, pkt_th->dst_port, pkt_th->src_port,
733                                        seq, ack, tcp_hdr_len, flags, 0);
734
735   /* Swap src and dst ip */
736   if (is_ip4)
737     {
738       ASSERT ((pkt_ih4->ip_version_and_header_length & 0xF0) == 0x40);
739       ih4 = vlib_buffer_push_ip4 (vm, b, &pkt_ih4->dst_address,
740                                   &pkt_ih4->src_address, IP_PROTOCOL_TCP);
741       th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih4);
742     }
743   else
744     {
745       int bogus = ~0;
746       pkt_ih6 = (ip6_header_t *) (pkt_th - 1);
747       ASSERT ((pkt_ih6->ip_version_traffic_class_and_flow_label & 0xF0) ==
748               0x60);
749       ih6 =
750         vlib_buffer_push_ip6 (vm, b, &pkt_ih6->dst_address,
751                               &pkt_ih6->src_address, IP_PROTOCOL_TCP);
752       th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih6, &bogus);
753       ASSERT (!bogus);
754     }
755
756   tcp_enqueue_to_ip_lookup (vm, b, bi, is_ip4);
757 }
758
759 void
760 tcp_push_ip_hdr (tcp_main_t * tm, tcp_connection_t * tc, vlib_buffer_t * b)
761 {
762   tcp_header_t *th = vlib_buffer_get_current (b);
763
764   if (tc->c_is_ip4)
765     {
766       ip4_header_t *ih;
767       ih = vlib_buffer_push_ip4 (tm->vlib_main, b, &tc->c_lcl_ip4,
768                                  &tc->c_rmt_ip4, IP_PROTOCOL_TCP);
769       th->checksum = ip4_tcp_udp_compute_checksum (tm->vlib_main, b, ih);
770     }
771   else
772     {
773       ip6_header_t *ih;
774       int bogus = ~0;
775
776       ih = vlib_buffer_push_ip6 (tm->vlib_main, b, &tc->c_lcl_ip6,
777                                  &tc->c_rmt_ip6, IP_PROTOCOL_TCP);
778       th->checksum = ip6_tcp_udp_icmp_compute_checksum (tm->vlib_main, b, ih,
779                                                         &bogus);
780       ASSERT (!bogus);
781     }
782 }
783
784 /**
785  *  Send SYN
786  *
787  *  Builds a SYN packet for a half-open connection and sends it to ipx_lookup.
788  *  The packet is not forwarded through tcpx_output to avoid doing lookups
789  *  in the half_open pool.
790  */
791 void
792 tcp_send_syn (tcp_connection_t * tc)
793 {
794   vlib_buffer_t *b;
795   u32 bi;
796   tcp_main_t *tm = vnet_get_tcp_main ();
797   vlib_main_t *vm = vlib_get_main ();
798   u8 tcp_hdr_opts_len, tcp_opts_len;
799   tcp_header_t *th;
800   u32 time_now;
801   u16 initial_wnd;
802   tcp_options_t snd_opts;
803
804   tcp_get_free_buffer_index (tm, &bi);
805   b = vlib_get_buffer (vm, bi);
806
807   /* Leave enough space for headers */
808   vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
809
810   /* Set random initial sequence */
811   time_now = tcp_time_now ();
812
813   tc->iss = random_u32 (&time_now);
814   tc->snd_una = tc->iss;
815   tc->snd_una_max = tc->snd_nxt = tc->iss + 1;
816
817   initial_wnd = tcp_initial_window_to_advertise (tc);
818
819   /* Make and write options */
820   memset (&snd_opts, 0, sizeof (snd_opts));
821   tcp_opts_len = tcp_make_syn_options (&snd_opts, tc->rcv_wscale);
822   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
823
824   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
825                              tc->rcv_nxt, tcp_hdr_opts_len, TCP_FLAG_SYN,
826                              initial_wnd);
827
828   tcp_options_write ((u8 *) (th + 1), &snd_opts);
829
830   /* Measure RTT with this */
831   tc->rtt_ts = tcp_time_now ();
832   tc->rtt_seq = tc->snd_nxt;
833
834   /* Start retransmit trimer  */
835   tcp_timer_set (tc, TCP_TIMER_RETRANSMIT_SYN, tc->rto * TCP_TO_TIMER_TICK);
836   tc->rto_boff = 0;
837
838   /* Set the connection establishment timer */
839   tcp_timer_set (tc, TCP_TIMER_ESTABLISH, TCP_ESTABLISH_TIME);
840
841   tcp_push_ip_hdr (tm, tc, b);
842   tcp_enqueue_to_ip_lookup (vm, b, bi, tc->c_is_ip4);
843 }
844
845 always_inline void
846 tcp_enqueue_to_output (vlib_main_t * vm, vlib_buffer_t * b, u32 bi, u8 is_ip4)
847 {
848   u32 *to_next, next_index;
849   vlib_frame_t *f;
850
851   b->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
852   b->error = 0;
853
854   /* Decide where to send the packet */
855   next_index = is_ip4 ? tcp4_output_node.index : tcp6_output_node.index;
856
857   /* Enqueue the packet */
858   f = vlib_get_frame_to_node (vm, next_index);
859   to_next = vlib_frame_vector_args (f);
860   to_next[0] = bi;
861   f->n_vectors = 1;
862   vlib_put_frame_to_node (vm, next_index, f);
863 }
864
865 /**
866  *  Send FIN
867  */
868 void
869 tcp_send_fin (tcp_connection_t * tc)
870 {
871   vlib_buffer_t *b;
872   u32 bi;
873   tcp_main_t *tm = vnet_get_tcp_main ();
874   vlib_main_t *vm = vlib_get_main ();
875
876   tcp_get_free_buffer_index (tm, &bi);
877   b = vlib_get_buffer (vm, bi);
878
879   /* Leave enough space for headers */
880   vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
881
882   tcp_make_fin (tc, b);
883   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
884   tc->flags |= TCP_CONN_FINSNT;
885   tcp_retransmit_timer_force_update (tc);
886   TCP_EVT_DBG (TCP_EVT_FIN_SENT, tc);
887 }
888
889 always_inline u8
890 tcp_make_state_flags (tcp_state_t next_state)
891 {
892   switch (next_state)
893     {
894     case TCP_STATE_ESTABLISHED:
895       return TCP_FLAG_ACK;
896     case TCP_STATE_SYN_RCVD:
897       return TCP_FLAG_SYN | TCP_FLAG_ACK;
898     case TCP_STATE_SYN_SENT:
899       return TCP_FLAG_SYN;
900     case TCP_STATE_LAST_ACK:
901     case TCP_STATE_FIN_WAIT_1:
902       return TCP_FLAG_FIN;
903     default:
904       clib_warning ("Shouldn't be here!");
905     }
906   return 0;
907 }
908
909 /**
910  * Push TCP header and update connection variables
911  */
912 static void
913 tcp_push_hdr_i (tcp_connection_t * tc, vlib_buffer_t * b,
914                 tcp_state_t next_state, u8 compute_opts)
915 {
916   u32 advertise_wnd, data_len;
917   u8 tcp_hdr_opts_len, opts_write_len, flags;
918   tcp_header_t *th;
919
920   data_len = b->current_length + b->total_length_not_including_first_buffer;
921   vnet_buffer (b)->tcp.flags = 0;
922
923   if (compute_opts)
924     tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
925
926   tcp_hdr_opts_len = tc->snd_opts_len + sizeof (tcp_header_t);
927   advertise_wnd = tcp_window_to_advertise (tc, next_state);
928   flags = tcp_make_state_flags (next_state);
929
930   /* Push header and options */
931   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
932                              tc->rcv_nxt, tcp_hdr_opts_len, flags,
933                              advertise_wnd);
934   opts_write_len = tcp_options_write ((u8 *) (th + 1), &tc->snd_opts);
935
936   ASSERT (opts_write_len == tc->snd_opts_len);
937   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
938
939   /*
940    * Update connection variables
941    */
942
943   tc->snd_nxt += data_len;
944   tc->rcv_las = tc->rcv_nxt;
945
946   /* TODO this is updated in output as well ... */
947   if (seq_gt (tc->snd_nxt, tc->snd_una_max))
948     {
949       tc->snd_una_max = tc->snd_nxt;
950       tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
951     }
952
953   TCP_EVT_DBG (TCP_EVT_PKTIZE, tc);
954 }
955
956 void
957 tcp_send_ack (tcp_connection_t * tc)
958 {
959   tcp_main_t *tm = vnet_get_tcp_main ();
960   vlib_main_t *vm = vlib_get_main ();
961
962   vlib_buffer_t *b;
963   u32 bi;
964
965   /* Get buffer */
966   tcp_get_free_buffer_index (tm, &bi);
967   b = vlib_get_buffer (vm, bi);
968
969   /* Fill in the ACK */
970   tcp_make_ack (tc, b);
971   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
972 }
973
974 /* Send delayed ACK when timer expires */
975 void
976 tcp_timer_delack_handler (u32 index)
977 {
978   u32 thread_index = vlib_get_thread_index ();
979   tcp_connection_t *tc;
980
981   tc = tcp_connection_get (index, thread_index);
982   tc->timers[TCP_TIMER_DELACK] = TCP_TIMER_HANDLE_INVALID;
983   tcp_send_ack (tc);
984 }
985
986 /** Build a retransmit segment
987  *
988  * @return the number of bytes in the segment or 0 if there's nothing to
989  *         retransmit
990  */
991 u32
992 tcp_prepare_retransmit_segment (tcp_connection_t * tc, vlib_buffer_t * b,
993                                 u32 offset, u32 max_bytes)
994 {
995   vlib_main_t *vm = vlib_get_main ();
996   int n_bytes = 0;
997   u32 start;
998
999   tcp_reuse_buffer (vm, b);
1000
1001   ASSERT (tc->state >= TCP_STATE_ESTABLISHED);
1002   ASSERT (max_bytes != 0);
1003
1004   max_bytes = clib_min (tc->snd_mss, max_bytes);
1005   start = tc->snd_una + offset;
1006
1007   /* Start is beyond snd_congestion */
1008   if (seq_geq (start, tc->snd_congestion))
1009     goto done;
1010
1011   /* Don't overshoot snd_congestion */
1012   if (seq_gt (start + max_bytes, tc->snd_congestion))
1013     {
1014       max_bytes = tc->snd_congestion - start;
1015       if (max_bytes == 0)
1016         goto done;
1017     }
1018
1019   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1020
1021   ASSERT (max_bytes <= tc->snd_mss);
1022
1023   n_bytes = stream_session_peek_bytes (&tc->connection,
1024                                        vlib_buffer_get_current (b), offset,
1025                                        max_bytes);
1026   ASSERT (n_bytes > 0);
1027   b->current_length = n_bytes;
1028   tcp_push_hdr_i (tc, b, tc->state, 0);
1029
1030   if (tcp_in_fastrecovery (tc))
1031     tc->snd_rxt_bytes += n_bytes;
1032
1033 done:
1034   TCP_EVT_DBG (TCP_EVT_CC_RTX, tc, offset, n_bytes);
1035   return n_bytes;
1036 }
1037
1038 /**
1039  * Reset congestion control, switch cwnd to loss window and try again.
1040  */
1041 static void
1042 tcp_rtx_timeout_cc (tcp_connection_t * tc)
1043 {
1044   tc->prev_ssthresh = tc->ssthresh;
1045   tc->prev_cwnd = tc->cwnd;
1046
1047   /* Cleanly recover cc (also clears up fast retransmit) */
1048   if (tcp_in_fastrecovery (tc))
1049     tcp_cc_fastrecovery_exit (tc);
1050
1051   /* Start again from the beginning */
1052   tc->ssthresh = clib_max (tcp_flight_size (tc) / 2, 2 * tc->snd_mss);
1053   tc->cwnd = tcp_loss_wnd (tc);
1054   tc->snd_congestion = tc->snd_una_max;
1055
1056   tcp_recovery_on (tc);
1057 }
1058
1059 static void
1060 tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
1061 {
1062   tcp_main_t *tm = vnet_get_tcp_main ();
1063   vlib_main_t *vm = vlib_get_main ();
1064   u32 thread_index = vlib_get_thread_index ();
1065   tcp_connection_t *tc;
1066   vlib_buffer_t *b;
1067   u32 bi, n_bytes;
1068
1069   if (is_syn)
1070     {
1071       tc = tcp_half_open_connection_get (index);
1072     }
1073   else
1074     {
1075       tc = tcp_connection_get (index, thread_index);
1076     }
1077
1078   /* Make sure timer handle is set to invalid */
1079   tc->timers[TCP_TIMER_RETRANSMIT] = TCP_TIMER_HANDLE_INVALID;
1080
1081   if (!tcp_in_recovery (tc) && tc->rto_boff > 0
1082       && tc->state >= TCP_STATE_ESTABLISHED)
1083     {
1084       tc->rto_boff = 0;
1085       tcp_update_rto (tc);
1086     }
1087
1088   /* Increment RTO backoff (also equal to number of retries) */
1089   tc->rto_boff += 1;
1090
1091   /* Go back to first un-acked byte */
1092   tc->snd_nxt = tc->snd_una;
1093
1094   tcp_get_free_buffer_index (tm, &bi);
1095   b = vlib_get_buffer (vm, bi);
1096
1097   if (tc->state >= TCP_STATE_ESTABLISHED)
1098     {
1099       /* Lost FIN, retransmit and return */
1100       if (tc->flags & TCP_CONN_FINSNT)
1101         {
1102           tcp_send_fin (tc);
1103           return;
1104         }
1105
1106       /* First retransmit timeout */
1107       if (tc->rto_boff == 1)
1108         tcp_rtx_timeout_cc (tc);
1109
1110       /* Exponential backoff */
1111       tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1112
1113       TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 1);
1114
1115       /* Send one segment */
1116       n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
1117       /* TODO be less aggressive about this */
1118       scoreboard_clear (&tc->sack_sb);
1119
1120       if (n_bytes == 0)
1121         {
1122           clib_warning ("could not retransmit anything");
1123           clib_warning ("%U", format_tcp_connection, tc, 2);
1124
1125           /* Try again eventually */
1126           tcp_retransmit_timer_set (tc);
1127           ASSERT (0 || (tc->rto_boff > 1
1128                         && tc->snd_una == tc->snd_congestion));
1129           return;
1130         }
1131
1132       /* For first retransmit, record timestamp (Eifel detection RFC3522) */
1133       if (tc->rto_boff == 1)
1134         tc->snd_rxt_ts = tcp_time_now ();
1135     }
1136   /* Retransmit for SYN/SYNACK */
1137   else if (tc->state == TCP_STATE_SYN_RCVD || tc->state == TCP_STATE_SYN_SENT)
1138     {
1139       /* Try without increasing RTO a number of times. If this fails,
1140        * start growing RTO exponentially */
1141       if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
1142         tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1143
1144       vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
1145
1146       tcp_push_hdr_i (tc, b, tc->state, 1);
1147
1148       /* Account for the SYN */
1149       tc->snd_nxt += 1;
1150     }
1151   else
1152     {
1153       ASSERT (tc->state == TCP_STATE_CLOSED);
1154       clib_warning ("connection closed ...");
1155       return;
1156     }
1157
1158   if (!is_syn)
1159     {
1160       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1161
1162       /* Re-enable retransmit timer */
1163       tcp_retransmit_timer_set (tc);
1164     }
1165   else
1166     {
1167       ASSERT (tc->state == TCP_STATE_SYN_SENT);
1168
1169       TCP_EVT_DBG (TCP_EVT_SYN_RTX, tc);
1170
1171       /* This goes straight to ipx_lookup */
1172       tcp_push_ip_hdr (tm, tc, b);
1173       tcp_enqueue_to_ip_lookup (vm, b, bi, tc->c_is_ip4);
1174
1175       /* Re-enable retransmit timer */
1176       tcp_timer_set (tc, TCP_TIMER_RETRANSMIT_SYN,
1177                      tc->rto * TCP_TO_TIMER_TICK);
1178     }
1179 }
1180
1181 void
1182 tcp_timer_retransmit_handler (u32 index)
1183 {
1184   tcp_timer_retransmit_handler_i (index, 0);
1185 }
1186
1187 void
1188 tcp_timer_retransmit_syn_handler (u32 index)
1189 {
1190   tcp_timer_retransmit_handler_i (index, 1);
1191 }
1192
1193 /**
1194  * Got 0 snd_wnd from peer, try to do something about it.
1195  *
1196  */
1197 void
1198 tcp_timer_persist_handler (u32 index)
1199 {
1200   tcp_main_t *tm = vnet_get_tcp_main ();
1201   vlib_main_t *vm = vlib_get_main ();
1202   u32 thread_index = vlib_get_thread_index ();
1203   tcp_connection_t *tc;
1204   vlib_buffer_t *b;
1205   u32 bi, old_snd_nxt;
1206   int n_bytes = 0;
1207
1208   tc = tcp_connection_get_if_valid (index, thread_index);
1209
1210   if (!tc)
1211     return;
1212
1213   /* Make sure timer handle is set to invalid */
1214   tc->timers[TCP_TIMER_PERSIST] = TCP_TIMER_HANDLE_INVALID;
1215
1216   /* Problem already solved or worse */
1217   if (tc->state == TCP_STATE_CLOSED || tc->state > TCP_STATE_ESTABLISHED
1218       || tc->snd_wnd > tc->snd_mss || tcp_in_recovery (tc))
1219     return;
1220
1221   /* Increment RTO backoff */
1222   tc->rto_boff += 1;
1223   tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1224
1225   /* Try to force the first unsent segment  */
1226   tcp_get_free_buffer_index (tm, &bi);
1227   b = vlib_get_buffer (vm, bi);
1228
1229   tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
1230   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1231   n_bytes = stream_session_peek_bytes (&tc->connection,
1232                                        vlib_buffer_get_current (b),
1233                                        tc->snd_una_max - tc->snd_una,
1234                                        tc->snd_mss);
1235   /* Nothing to send */
1236   if (n_bytes <= 0)
1237     {
1238       clib_warning ("persist found nothing to send");
1239       tcp_return_buffer (tm);
1240       return;
1241     }
1242
1243   b->current_length = n_bytes;
1244   ASSERT (tc->snd_nxt == tc->snd_una_max || tc->rto_boff > 1
1245           || tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT));
1246
1247   /* Allow updating of snd_una_max but don't update snd_nxt */
1248   old_snd_nxt = tc->snd_nxt;
1249   tcp_push_hdr_i (tc, b, tc->state, 0);
1250   tc->snd_nxt = old_snd_nxt;
1251   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1252
1253   /* Re-enable persist timer */
1254   tcp_persist_timer_set (tc);
1255 }
1256
1257 /**
1258  * Retransmit first unacked segment
1259  */
1260 void
1261 tcp_retransmit_first_unacked (tcp_connection_t * tc)
1262 {
1263   tcp_main_t *tm = vnet_get_tcp_main ();
1264   vlib_main_t *vm = vlib_get_main ();
1265   vlib_buffer_t *b;
1266   u32 bi, n_bytes, old_snd_nxt;
1267
1268   old_snd_nxt = tc->snd_nxt;
1269   tc->snd_nxt = tc->snd_una;
1270
1271   /* Get buffer */
1272   tcp_get_free_buffer_index (tm, &bi);
1273   b = vlib_get_buffer (vm, bi);
1274
1275   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 2);
1276
1277   n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
1278   if (n_bytes == 0)
1279     {
1280       tcp_return_buffer (tm);
1281       goto done;
1282     }
1283
1284   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1285
1286 done:
1287   tc->snd_nxt = old_snd_nxt;
1288 }
1289
1290 /**
1291  * Do fast retransmit with SACKs
1292  */
1293 void
1294 tcp_fast_retransmit_sack (tcp_connection_t * tc)
1295 {
1296   tcp_main_t *tm = vnet_get_tcp_main ();
1297   vlib_main_t *vm = vlib_get_main ();
1298   u32 n_written = 0, offset = 0, max_bytes;
1299   vlib_buffer_t *b;
1300   sack_scoreboard_hole_t *hole;
1301   sack_scoreboard_t *sb;
1302   u32 bi, old_snd_nxt;
1303   int snd_space;
1304   u8 snd_limited = 0, can_rescue = 0;
1305
1306   ASSERT (tcp_in_fastrecovery (tc));
1307   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1308
1309   old_snd_nxt = tc->snd_nxt;
1310   sb = &tc->sack_sb;
1311   snd_space = tcp_available_snd_space (tc);
1312
1313   hole = scoreboard_get_hole (sb, sb->cur_rxt_hole);
1314   while (hole && snd_space > 0)
1315     {
1316       tcp_get_free_buffer_index (tm, &bi);
1317       b = vlib_get_buffer (vm, bi);
1318
1319       hole = scoreboard_next_rxt_hole (sb, hole,
1320                                        tcp_fastrecovery_sent_1_smss (tc),
1321                                        &can_rescue, &snd_limited);
1322       if (!hole)
1323         {
1324           if (!can_rescue || !(seq_lt (sb->rescue_rxt, tc->snd_una)
1325                                || seq_gt (sb->rescue_rxt,
1326                                           tc->snd_congestion)))
1327             break;
1328
1329           /* If rescue rxt undefined or less than snd_una then one segment of
1330            * up to SMSS octets that MUST include the highest outstanding
1331            * unSACKed sequence number SHOULD be returned, and RescueRxt set to
1332            * RecoveryPoint. HighRxt MUST NOT be updated.
1333            */
1334           max_bytes = clib_min (tc->snd_mss, snd_space);
1335           offset = tc->snd_congestion - tc->snd_una - max_bytes;
1336           sb->rescue_rxt = tc->snd_congestion;
1337           tc->snd_nxt = tc->snd_una + offset;
1338           tcp_prepare_retransmit_segment (tc, b, offset, max_bytes);
1339           tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1340           break;
1341         }
1342
1343       max_bytes = snd_limited ? tc->snd_mss : hole->end - sb->high_rxt;
1344       offset = sb->high_rxt - tc->snd_una;
1345       tc->snd_nxt = tc->snd_una + offset;
1346       n_written = tcp_prepare_retransmit_segment (tc, b, offset, max_bytes);
1347
1348       /* Nothing left to retransmit */
1349       if (n_written == 0)
1350         {
1351           tcp_return_buffer (tm);
1352           break;
1353         }
1354
1355       sb->high_rxt += n_written;
1356       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1357       snd_space -= n_written;
1358     }
1359
1360   /* If window allows, send 1 SMSS of new data */
1361   tc->snd_nxt = old_snd_nxt;
1362 }
1363
1364 /**
1365  * Fast retransmit without SACK info
1366  */
1367 void
1368 tcp_fast_retransmit_no_sack (tcp_connection_t * tc)
1369 {
1370   tcp_main_t *tm = vnet_get_tcp_main ();
1371   vlib_main_t *vm = vlib_get_main ();
1372   u32 n_written = 0, offset = 0, bi, old_snd_nxt;
1373   int snd_space;
1374   vlib_buffer_t *b;
1375
1376   ASSERT (tcp_in_fastrecovery (tc));
1377   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1378
1379   /* Start resending from first un-acked segment */
1380   old_snd_nxt = tc->snd_nxt;
1381   tc->snd_nxt = tc->snd_una;
1382   snd_space = tcp_available_snd_space (tc);
1383
1384   while (snd_space > 0)
1385     {
1386       tcp_get_free_buffer_index (tm, &bi);
1387       b = vlib_get_buffer (vm, bi);
1388
1389       offset += n_written;
1390       n_written = tcp_prepare_retransmit_segment (tc, b, offset, snd_space);
1391
1392       /* Nothing left to retransmit */
1393       if (n_written == 0)
1394         {
1395           tcp_return_buffer (tm);
1396           break;
1397         }
1398
1399       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1400       snd_space -= n_written;
1401     }
1402
1403   /* Restore snd_nxt. If window allows, send 1 SMSS of new data */
1404   tc->snd_nxt = old_snd_nxt;
1405 }
1406
1407 /**
1408  * Do fast retransmit
1409  */
1410 void
1411 tcp_fast_retransmit (tcp_connection_t * tc)
1412 {
1413   if (tcp_opts_sack_permitted (&tc->rcv_opts)
1414       && scoreboard_first_hole (&tc->sack_sb))
1415     tcp_fast_retransmit_sack (tc);
1416   else
1417     tcp_fast_retransmit_no_sack (tc);
1418 }
1419
1420 always_inline u32
1421 tcp_session_has_ooo_data (tcp_connection_t * tc)
1422 {
1423   stream_session_t *s =
1424     stream_session_get (tc->c_s_index, tc->c_thread_index);
1425   return svm_fifo_has_ooo_data (s->server_rx_fifo);
1426 }
1427
1428 always_inline uword
1429 tcp46_output_inline (vlib_main_t * vm,
1430                      vlib_node_runtime_t * node,
1431                      vlib_frame_t * from_frame, int is_ip4)
1432 {
1433   u32 n_left_from, next_index, *from, *to_next;
1434   u32 my_thread_index = vm->thread_index;
1435
1436   from = vlib_frame_vector_args (from_frame);
1437   n_left_from = from_frame->n_vectors;
1438
1439   next_index = node->cached_next_index;
1440
1441   while (n_left_from > 0)
1442     {
1443       u32 n_left_to_next;
1444
1445       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1446
1447       while (n_left_from > 0 && n_left_to_next > 0)
1448         {
1449           u32 bi0;
1450           vlib_buffer_t *b0;
1451           tcp_connection_t *tc0;
1452           tcp_tx_trace_t *t0;
1453           tcp_header_t *th0 = 0;
1454           u32 error0 = TCP_ERROR_PKTS_SENT, next0 = TCP_OUTPUT_NEXT_IP_LOOKUP;
1455
1456           bi0 = from[0];
1457           to_next[0] = bi0;
1458           from += 1;
1459           to_next += 1;
1460           n_left_from -= 1;
1461           n_left_to_next -= 1;
1462
1463           b0 = vlib_get_buffer (vm, bi0);
1464           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
1465                                     my_thread_index);
1466           if (PREDICT_FALSE (tc0 == 0 || tc0->state == TCP_STATE_CLOSED))
1467             {
1468               error0 = TCP_ERROR_INVALID_CONNECTION;
1469               next0 = TCP_OUTPUT_NEXT_DROP;
1470               goto done;
1471             }
1472
1473           th0 = vlib_buffer_get_current (b0);
1474           TCP_EVT_DBG (TCP_EVT_OUTPUT, tc0, th0->flags, b0->current_length);
1475
1476           if (is_ip4)
1477             {
1478               ip4_header_t *ih0;
1479               ih0 = vlib_buffer_push_ip4 (vm, b0, &tc0->c_lcl_ip4,
1480                                           &tc0->c_rmt_ip4, IP_PROTOCOL_TCP);
1481               th0->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ih0);
1482             }
1483           else
1484             {
1485               ip6_header_t *ih0;
1486               int bogus = ~0;
1487
1488               ih0 = vlib_buffer_push_ip6 (vm, b0, &tc0->c_lcl_ip6,
1489                                           &tc0->c_rmt_ip6, IP_PROTOCOL_TCP);
1490               th0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ih0,
1491                                                                  &bogus);
1492               ASSERT (!bogus);
1493             }
1494
1495           /* Filter out DUPACKs if there are no OOO segments left */
1496           if (PREDICT_FALSE
1497               (vnet_buffer (b0)->tcp.flags & TCP_BUF_FLAG_DUPACK))
1498             {
1499               if (!tcp_session_has_ooo_data (tc0))
1500                 {
1501                   error0 = TCP_ERROR_FILTERED_DUPACKS;
1502                   next0 = TCP_OUTPUT_NEXT_DROP;
1503                   goto done;
1504                 }
1505             }
1506
1507           /* Stop DELACK timer and fix flags */
1508           tc0->flags &= ~(TCP_CONN_SNDACK);
1509           tcp_timer_reset (tc0, TCP_TIMER_DELACK);
1510
1511           /* If not retransmitting
1512            * 1) update snd_una_max (SYN, SYNACK, FIN)
1513            * 2) If we're not tracking an ACK, start tracking */
1514           if (seq_lt (tc0->snd_una_max, tc0->snd_nxt))
1515             {
1516               tc0->snd_una_max = tc0->snd_nxt;
1517               if (tc0->rtt_ts == 0)
1518                 {
1519                   tc0->rtt_ts = tcp_time_now ();
1520                   tc0->rtt_seq = tc0->snd_nxt;
1521                 }
1522             }
1523
1524           /* Set the retransmit timer if not set already and not
1525            * doing a pure ACK */
1526           if (!tcp_timer_is_active (tc0, TCP_TIMER_RETRANSMIT)
1527               && tc0->snd_nxt != tc0->snd_una)
1528             {
1529               tcp_retransmit_timer_set (tc0);
1530               tc0->rto_boff = 0;
1531             }
1532
1533           /* set fib index to default and lookup node */
1534           /* XXX network virtualization (vrf/vni) */
1535           vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
1536           vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
1537
1538           b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
1539         done:
1540           b0->error = node->errors[error0];
1541           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1542             {
1543               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1544               if (th0)
1545                 {
1546                   clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1547                 }
1548               else
1549                 {
1550                   memset (&t0->tcp_header, 0, sizeof (t0->tcp_header));
1551                 }
1552               clib_memcpy (&t0->tcp_connection, tc0,
1553                            sizeof (t0->tcp_connection));
1554             }
1555
1556           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1557                                            n_left_to_next, bi0, next0);
1558         }
1559
1560       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1561     }
1562
1563   return from_frame->n_vectors;
1564 }
1565
1566 static uword
1567 tcp4_output (vlib_main_t * vm, vlib_node_runtime_t * node,
1568              vlib_frame_t * from_frame)
1569 {
1570   return tcp46_output_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1571 }
1572
1573 static uword
1574 tcp6_output (vlib_main_t * vm, vlib_node_runtime_t * node,
1575              vlib_frame_t * from_frame)
1576 {
1577   return tcp46_output_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1578 }
1579
1580 /* *INDENT-OFF* */
1581 VLIB_REGISTER_NODE (tcp4_output_node) =
1582 {
1583   .function = tcp4_output,.name = "tcp4-output",
1584     /* Takes a vector of packets. */
1585     .vector_size = sizeof (u32),
1586     .n_errors = TCP_N_ERROR,
1587     .error_strings = tcp_error_strings,
1588     .n_next_nodes = TCP_OUTPUT_N_NEXT,
1589     .next_nodes = {
1590 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
1591     foreach_tcp4_output_next
1592 #undef _
1593     },
1594     .format_buffer = format_tcp_header,
1595     .format_trace = format_tcp_tx_trace,
1596 };
1597 /* *INDENT-ON* */
1598
1599 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_output_node, tcp4_output);
1600
1601 /* *INDENT-OFF* */
1602 VLIB_REGISTER_NODE (tcp6_output_node) =
1603 {
1604   .function = tcp6_output,
1605   .name = "tcp6-output",
1606     /* Takes a vector of packets. */
1607   .vector_size = sizeof (u32),
1608   .n_errors = TCP_N_ERROR,
1609   .error_strings = tcp_error_strings,
1610   .n_next_nodes = TCP_OUTPUT_N_NEXT,
1611   .next_nodes = {
1612 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
1613     foreach_tcp6_output_next
1614 #undef _
1615   },
1616   .format_buffer = format_tcp_header,
1617   .format_trace = format_tcp_tx_trace,
1618 };
1619 /* *INDENT-ON* */
1620
1621 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_output_node, tcp6_output);
1622
1623 u32
1624 tcp_push_header (transport_connection_t * tconn, vlib_buffer_t * b)
1625 {
1626   tcp_connection_t *tc;
1627
1628   tc = (tcp_connection_t *) tconn;
1629   tcp_push_hdr_i (tc, b, TCP_STATE_ESTABLISHED, 0);
1630
1631   if (tc->rtt_ts == 0 && !tcp_in_cong_recovery (tc))
1632     {
1633       tc->rtt_ts = tcp_time_now ();
1634       tc->rtt_seq = tc->snd_nxt;
1635     }
1636   return 0;
1637 }
1638
1639 typedef enum _tcp_reset_next
1640 {
1641   TCP_RESET_NEXT_DROP,
1642   TCP_RESET_NEXT_IP_LOOKUP,
1643   TCP_RESET_N_NEXT
1644 } tcp_reset_next_t;
1645
1646 #define foreach_tcp4_reset_next         \
1647   _(DROP, "error-drop")                 \
1648   _(IP_LOOKUP, "ip4-lookup")
1649
1650 #define foreach_tcp6_reset_next         \
1651   _(DROP, "error-drop")                 \
1652   _(IP_LOOKUP, "ip6-lookup")
1653
1654 static uword
1655 tcp46_send_reset_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1656                          vlib_frame_t * from_frame, u8 is_ip4)
1657 {
1658   u32 n_left_from, next_index, *from, *to_next;
1659   u32 my_thread_index = vm->thread_index;
1660
1661   from = vlib_frame_vector_args (from_frame);
1662   n_left_from = from_frame->n_vectors;
1663
1664   next_index = node->cached_next_index;
1665
1666   while (n_left_from > 0)
1667     {
1668       u32 n_left_to_next;
1669
1670       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1671
1672       while (n_left_from > 0 && n_left_to_next > 0)
1673         {
1674           u32 bi0;
1675           vlib_buffer_t *b0;
1676           tcp_tx_trace_t *t0;
1677           tcp_header_t *th0;
1678           u32 error0 = TCP_ERROR_RST_SENT, next0 = TCP_RESET_NEXT_IP_LOOKUP;
1679
1680           bi0 = from[0];
1681           to_next[0] = bi0;
1682           from += 1;
1683           to_next += 1;
1684           n_left_from -= 1;
1685           n_left_to_next -= 1;
1686
1687           b0 = vlib_get_buffer (vm, bi0);
1688
1689           if (tcp_make_reset_in_place (vm, b0, vnet_buffer (b0)->tcp.flags,
1690                                        my_thread_index, is_ip4))
1691             {
1692               error0 = TCP_ERROR_LOOKUP_DROPS;
1693               next0 = TCP_RESET_NEXT_DROP;
1694               goto done;
1695             }
1696
1697           /* Prepare to send to IP lookup */
1698           vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
1699           next0 = TCP_RESET_NEXT_IP_LOOKUP;
1700
1701         done:
1702           b0->error = node->errors[error0];
1703           b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
1704           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1705             {
1706               th0 = vlib_buffer_get_current (b0);
1707               if (is_ip4)
1708                 th0 = ip4_next_header ((ip4_header_t *) th0);
1709               else
1710                 th0 = ip6_next_header ((ip6_header_t *) th0);
1711               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1712               clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1713             }
1714
1715           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1716                                            n_left_to_next, bi0, next0);
1717         }
1718       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1719     }
1720   return from_frame->n_vectors;
1721 }
1722
1723 static uword
1724 tcp4_send_reset (vlib_main_t * vm, vlib_node_runtime_t * node,
1725                  vlib_frame_t * from_frame)
1726 {
1727   return tcp46_send_reset_inline (vm, node, from_frame, 1);
1728 }
1729
1730 static uword
1731 tcp6_send_reset (vlib_main_t * vm, vlib_node_runtime_t * node,
1732                  vlib_frame_t * from_frame)
1733 {
1734   return tcp46_send_reset_inline (vm, node, from_frame, 0);
1735 }
1736
1737 /* *INDENT-OFF* */
1738 VLIB_REGISTER_NODE (tcp4_reset_node) = {
1739   .function = tcp4_send_reset,
1740   .name = "tcp4-reset",
1741   .vector_size = sizeof (u32),
1742   .n_errors = TCP_N_ERROR,
1743   .error_strings = tcp_error_strings,
1744   .n_next_nodes = TCP_RESET_N_NEXT,
1745   .next_nodes = {
1746 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
1747     foreach_tcp4_reset_next
1748 #undef _
1749   },
1750   .format_trace = format_tcp_tx_trace,
1751 };
1752 /* *INDENT-ON* */
1753
1754 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_reset_node, tcp4_send_reset);
1755
1756 /* *INDENT-OFF* */
1757 VLIB_REGISTER_NODE (tcp6_reset_node) = {
1758   .function = tcp6_send_reset,
1759   .name = "tcp6-reset",
1760   .vector_size = sizeof (u32),
1761   .n_errors = TCP_N_ERROR,
1762   .error_strings = tcp_error_strings,
1763   .n_next_nodes = TCP_RESET_N_NEXT,
1764   .next_nodes = {
1765 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
1766     foreach_tcp6_reset_next
1767 #undef _
1768   },
1769   .format_trace = format_tcp_tx_trace,
1770 };
1771 /* *INDENT-ON* */
1772
1773 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_reset_node, tcp6_send_reset);
1774
1775 /*
1776  * fd.io coding-style-patch-verification: ON
1777  *
1778  * Local Variables:
1779  * eval: (c-set-style "gnu")
1780  * End:
1781  */