47c94e6dacaf0edf273e71db317cbee29e7b1a15
[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   tcp_recovery_on (tc);
1056 }
1057
1058 static void
1059 tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
1060 {
1061   tcp_main_t *tm = vnet_get_tcp_main ();
1062   vlib_main_t *vm = vlib_get_main ();
1063   u32 thread_index = vlib_get_thread_index ();
1064   tcp_connection_t *tc;
1065   vlib_buffer_t *b;
1066   u32 bi, n_bytes;
1067
1068   if (is_syn)
1069     {
1070       tc = tcp_half_open_connection_get (index);
1071     }
1072   else
1073     {
1074       tc = tcp_connection_get (index, thread_index);
1075     }
1076
1077   /* Make sure timer handle is set to invalid */
1078   tc->timers[TCP_TIMER_RETRANSMIT] = TCP_TIMER_HANDLE_INVALID;
1079
1080   if (!tcp_in_recovery (tc) && tc->rto_boff > 0
1081       && tc->state >= TCP_STATE_ESTABLISHED)
1082     {
1083       tc->rto_boff = 0;
1084       tcp_update_rto (tc);
1085     }
1086
1087   /* Increment RTO backoff (also equal to number of retries) */
1088   tc->rto_boff += 1;
1089
1090   /* Go back to first un-acked byte */
1091   tc->snd_nxt = tc->snd_una;
1092
1093   tcp_get_free_buffer_index (tm, &bi);
1094   b = vlib_get_buffer (vm, bi);
1095
1096   if (tc->state >= TCP_STATE_ESTABLISHED)
1097     {
1098       /* Lost FIN, retransmit and return */
1099       if (tc->flags & TCP_CONN_FINSNT)
1100         {
1101           tcp_send_fin (tc);
1102           return;
1103         }
1104
1105       /* First retransmit timeout */
1106       if (tc->rto_boff == 1)
1107         tcp_rtx_timeout_cc (tc);
1108
1109       /* Exponential backoff */
1110       tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1111
1112       TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 1);
1113
1114       /* Send one segment */
1115       n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
1116       /* TODO be less aggressive about this */
1117       scoreboard_clear (&tc->sack_sb);
1118
1119       if (n_bytes == 0)
1120         {
1121           clib_warning ("could not retransmit anything");
1122           clib_warning ("%U", format_tcp_connection, tc, 2);
1123
1124           /* Try again eventually */
1125           tcp_retransmit_timer_set (tc);
1126           ASSERT (0 || (tc->rto_boff > 1
1127                         && tc->snd_una == tc->snd_congestion));
1128           return;
1129         }
1130
1131       /* For first retransmit, record timestamp (Eifel detection RFC3522) */
1132       if (tc->rto_boff == 1)
1133         tc->snd_rxt_ts = tcp_time_now ();
1134     }
1135   /* Retransmit for SYN/SYNACK */
1136   else if (tc->state == TCP_STATE_SYN_RCVD || tc->state == TCP_STATE_SYN_SENT)
1137     {
1138       /* Try without increasing RTO a number of times. If this fails,
1139        * start growing RTO exponentially */
1140       if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
1141         tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1142
1143       vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
1144
1145       tcp_push_hdr_i (tc, b, tc->state, 1);
1146
1147       /* Account for the SYN */
1148       tc->snd_nxt += 1;
1149     }
1150   else
1151     {
1152       ASSERT (tc->state == TCP_STATE_CLOSED);
1153       clib_warning ("connection closed ...");
1154       return;
1155     }
1156
1157   if (!is_syn)
1158     {
1159       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1160
1161       /* Re-enable retransmit timer */
1162       tcp_retransmit_timer_set (tc);
1163     }
1164   else
1165     {
1166       ASSERT (tc->state == TCP_STATE_SYN_SENT);
1167
1168       TCP_EVT_DBG (TCP_EVT_SYN_RTX, tc);
1169
1170       /* This goes straight to ipx_lookup */
1171       tcp_push_ip_hdr (tm, tc, b);
1172       tcp_enqueue_to_ip_lookup (vm, b, bi, tc->c_is_ip4);
1173
1174       /* Re-enable retransmit timer */
1175       tcp_timer_set (tc, TCP_TIMER_RETRANSMIT_SYN,
1176                      tc->rto * TCP_TO_TIMER_TICK);
1177     }
1178 }
1179
1180 void
1181 tcp_timer_retransmit_handler (u32 index)
1182 {
1183   tcp_timer_retransmit_handler_i (index, 0);
1184 }
1185
1186 void
1187 tcp_timer_retransmit_syn_handler (u32 index)
1188 {
1189   tcp_timer_retransmit_handler_i (index, 1);
1190 }
1191
1192 /**
1193  * Got 0 snd_wnd from peer, try to do something about it.
1194  *
1195  */
1196 void
1197 tcp_timer_persist_handler (u32 index)
1198 {
1199   tcp_main_t *tm = vnet_get_tcp_main ();
1200   vlib_main_t *vm = vlib_get_main ();
1201   u32 thread_index = vlib_get_thread_index ();
1202   tcp_connection_t *tc;
1203   vlib_buffer_t *b;
1204   u32 bi, old_snd_nxt;
1205   int n_bytes = 0;
1206
1207   tc = tcp_connection_get_if_valid (index, thread_index);
1208
1209   if (!tc)
1210     return;
1211
1212   /* Make sure timer handle is set to invalid */
1213   tc->timers[TCP_TIMER_PERSIST] = TCP_TIMER_HANDLE_INVALID;
1214
1215   /* Problem already solved or worse */
1216   if (tc->state == TCP_STATE_CLOSED
1217       || tc->snd_wnd > tc->snd_mss || tcp_in_recovery (tc))
1218     return;
1219
1220   /* Increment RTO backoff */
1221   tc->rto_boff += 1;
1222   tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1223
1224   /* Try to force the first unsent segment  */
1225   tcp_get_free_buffer_index (tm, &bi);
1226   b = vlib_get_buffer (vm, bi);
1227
1228   tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
1229   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1230   n_bytes = stream_session_peek_bytes (&tc->connection,
1231                                        vlib_buffer_get_current (b),
1232                                        tc->snd_una_max - tc->snd_una,
1233                                        tc->snd_mss);
1234   /* Nothing to send */
1235   if (n_bytes <= 0)
1236     {
1237       clib_warning ("persist found nothing to send");
1238       tcp_return_buffer (tm);
1239       return;
1240     }
1241
1242   b->current_length = n_bytes;
1243   ASSERT (tc->snd_nxt == tc->snd_una_max || tc->rto_boff > 1
1244           || tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT));
1245
1246   /* Allow updating of snd_una_max but don't update snd_nxt */
1247   old_snd_nxt = tc->snd_nxt;
1248   tcp_push_hdr_i (tc, b, tc->state, 0);
1249   tc->snd_nxt = old_snd_nxt;
1250   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1251
1252   /* Re-enable persist timer */
1253   tcp_persist_timer_set (tc);
1254 }
1255
1256 /**
1257  * Retransmit first unacked segment
1258  */
1259 void
1260 tcp_retransmit_first_unacked (tcp_connection_t * tc)
1261 {
1262   tcp_main_t *tm = vnet_get_tcp_main ();
1263   vlib_main_t *vm = vlib_get_main ();
1264   vlib_buffer_t *b;
1265   u32 bi, n_bytes, old_snd_nxt;
1266
1267   old_snd_nxt = tc->snd_nxt;
1268   tc->snd_nxt = tc->snd_una;
1269
1270   /* Get buffer */
1271   tcp_get_free_buffer_index (tm, &bi);
1272   b = vlib_get_buffer (vm, bi);
1273
1274   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 2);
1275
1276   n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
1277   if (n_bytes == 0)
1278     {
1279       tcp_return_buffer (tm);
1280       goto done;
1281     }
1282
1283   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1284
1285 done:
1286   tc->snd_nxt = old_snd_nxt;
1287 }
1288
1289 /**
1290  * Do fast retransmit with SACKs
1291  */
1292 void
1293 tcp_fast_retransmit_sack (tcp_connection_t * tc)
1294 {
1295   tcp_main_t *tm = vnet_get_tcp_main ();
1296   vlib_main_t *vm = vlib_get_main ();
1297   u32 n_written = 0, offset = 0, max_bytes;
1298   vlib_buffer_t *b;
1299   sack_scoreboard_hole_t *hole;
1300   sack_scoreboard_t *sb;
1301   u32 bi, old_snd_nxt;
1302   int snd_space;
1303   u8 snd_limited = 0, can_rescue = 0;
1304
1305   ASSERT (tcp_in_fastrecovery (tc));
1306   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1307
1308   old_snd_nxt = tc->snd_nxt;
1309   sb = &tc->sack_sb;
1310   snd_space = tcp_available_snd_space (tc);
1311
1312   hole = scoreboard_get_hole (sb, sb->cur_rxt_hole);
1313   while (hole && snd_space > 0)
1314     {
1315       tcp_get_free_buffer_index (tm, &bi);
1316       b = vlib_get_buffer (vm, bi);
1317
1318       hole = scoreboard_next_rxt_hole (sb, hole,
1319                                        tcp_fastrecovery_sent_1_smss (tc),
1320                                        &can_rescue, &snd_limited);
1321       if (!hole)
1322         {
1323           if (!can_rescue || !(seq_lt (sb->rescue_rxt, tc->snd_una)
1324                                || seq_gt (sb->rescue_rxt,
1325                                           tc->snd_congestion)))
1326             break;
1327
1328           /* If rescue rxt undefined or less than snd_una then one segment of
1329            * up to SMSS octets that MUST include the highest outstanding
1330            * unSACKed sequence number SHOULD be returned, and RescueRxt set to
1331            * RecoveryPoint. HighRxt MUST NOT be updated.
1332            */
1333           max_bytes = clib_min (tc->snd_mss, snd_space);
1334           offset = tc->snd_congestion - tc->snd_una - max_bytes;
1335           sb->rescue_rxt = tc->snd_congestion;
1336           tc->snd_nxt = tc->snd_una + offset;
1337           tcp_prepare_retransmit_segment (tc, b, offset, max_bytes);
1338           tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1339           break;
1340         }
1341
1342       max_bytes = snd_limited ? tc->snd_mss : hole->end - sb->high_rxt;
1343       offset = sb->high_rxt - tc->snd_una;
1344       tc->snd_nxt = tc->snd_una + offset;
1345       n_written = tcp_prepare_retransmit_segment (tc, b, offset, max_bytes);
1346
1347       /* Nothing left to retransmit */
1348       if (n_written == 0)
1349         {
1350           tcp_return_buffer (tm);
1351           break;
1352         }
1353
1354       sb->high_rxt += n_written;
1355       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1356       snd_space -= n_written;
1357     }
1358
1359   /* If window allows, send 1 SMSS of new data */
1360   tc->snd_nxt = old_snd_nxt;
1361 }
1362
1363 /**
1364  * Fast retransmit without SACK info
1365  */
1366 void
1367 tcp_fast_retransmit_no_sack (tcp_connection_t * tc)
1368 {
1369   tcp_main_t *tm = vnet_get_tcp_main ();
1370   vlib_main_t *vm = vlib_get_main ();
1371   u32 n_written = 0, offset = 0, bi, old_snd_nxt;
1372   int snd_space;
1373   vlib_buffer_t *b;
1374
1375   ASSERT (tcp_in_fastrecovery (tc));
1376   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1377
1378   /* Start resending from first un-acked segment */
1379   old_snd_nxt = tc->snd_nxt;
1380   tc->snd_nxt = tc->snd_una;
1381   snd_space = tcp_available_snd_space (tc);
1382
1383   while (snd_space > 0)
1384     {
1385       tcp_get_free_buffer_index (tm, &bi);
1386       b = vlib_get_buffer (vm, bi);
1387
1388       offset += n_written;
1389       n_written = tcp_prepare_retransmit_segment (tc, b, offset, snd_space);
1390
1391       /* Nothing left to retransmit */
1392       if (n_written == 0)
1393         {
1394           tcp_return_buffer (tm);
1395           break;
1396         }
1397
1398       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1399       snd_space -= n_written;
1400     }
1401
1402   /* Restore snd_nxt. If window allows, send 1 SMSS of new data */
1403   tc->snd_nxt = old_snd_nxt;
1404 }
1405
1406 /**
1407  * Do fast retransmit
1408  */
1409 void
1410 tcp_fast_retransmit (tcp_connection_t * tc)
1411 {
1412   if (tcp_opts_sack_permitted (&tc->rcv_opts)
1413       && scoreboard_first_hole (&tc->sack_sb))
1414     tcp_fast_retransmit_sack (tc);
1415   else
1416     tcp_fast_retransmit_no_sack (tc);
1417 }
1418
1419 always_inline u32
1420 tcp_session_has_ooo_data (tcp_connection_t * tc)
1421 {
1422   stream_session_t *s =
1423     stream_session_get (tc->c_s_index, tc->c_thread_index);
1424   return svm_fifo_has_ooo_data (s->server_rx_fifo);
1425 }
1426
1427 always_inline uword
1428 tcp46_output_inline (vlib_main_t * vm,
1429                      vlib_node_runtime_t * node,
1430                      vlib_frame_t * from_frame, int is_ip4)
1431 {
1432   u32 n_left_from, next_index, *from, *to_next;
1433   u32 my_thread_index = vm->thread_index;
1434
1435   from = vlib_frame_vector_args (from_frame);
1436   n_left_from = from_frame->n_vectors;
1437
1438   next_index = node->cached_next_index;
1439
1440   while (n_left_from > 0)
1441     {
1442       u32 n_left_to_next;
1443
1444       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1445
1446       while (n_left_from > 0 && n_left_to_next > 0)
1447         {
1448           u32 bi0;
1449           vlib_buffer_t *b0;
1450           tcp_connection_t *tc0;
1451           tcp_tx_trace_t *t0;
1452           tcp_header_t *th0 = 0;
1453           u32 error0 = TCP_ERROR_PKTS_SENT, next0 = TCP_OUTPUT_NEXT_IP_LOOKUP;
1454
1455           bi0 = from[0];
1456           to_next[0] = bi0;
1457           from += 1;
1458           to_next += 1;
1459           n_left_from -= 1;
1460           n_left_to_next -= 1;
1461
1462           b0 = vlib_get_buffer (vm, bi0);
1463           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
1464                                     my_thread_index);
1465           if (PREDICT_FALSE (tc0 == 0 || tc0->state == TCP_STATE_CLOSED))
1466             {
1467               error0 = TCP_ERROR_INVALID_CONNECTION;
1468               next0 = TCP_OUTPUT_NEXT_DROP;
1469               goto done;
1470             }
1471
1472           th0 = vlib_buffer_get_current (b0);
1473           TCP_EVT_DBG (TCP_EVT_OUTPUT, tc0, th0->flags, b0->current_length);
1474
1475           if (is_ip4)
1476             {
1477               ip4_header_t *ih0;
1478               ih0 = vlib_buffer_push_ip4 (vm, b0, &tc0->c_lcl_ip4,
1479                                           &tc0->c_rmt_ip4, IP_PROTOCOL_TCP);
1480               th0->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ih0);
1481             }
1482           else
1483             {
1484               ip6_header_t *ih0;
1485               int bogus = ~0;
1486
1487               ih0 = vlib_buffer_push_ip6 (vm, b0, &tc0->c_lcl_ip6,
1488                                           &tc0->c_rmt_ip6, IP_PROTOCOL_TCP);
1489               th0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ih0,
1490                                                                  &bogus);
1491               ASSERT (!bogus);
1492             }
1493
1494           /* Filter out DUPACKs if there are no OOO segments left */
1495           if (PREDICT_FALSE
1496               (vnet_buffer (b0)->tcp.flags & TCP_BUF_FLAG_DUPACK))
1497             {
1498               if (!tcp_session_has_ooo_data (tc0))
1499                 {
1500                   error0 = TCP_ERROR_FILTERED_DUPACKS;
1501                   next0 = TCP_OUTPUT_NEXT_DROP;
1502                   goto done;
1503                 }
1504             }
1505
1506           /* Stop DELACK timer and fix flags */
1507           tc0->flags &= ~(TCP_CONN_SNDACK);
1508           if (tcp_timer_is_active (tc0, TCP_TIMER_DELACK))
1509             {
1510               tcp_timer_reset (tc0, TCP_TIMER_DELACK);
1511             }
1512
1513           /* If not retransmitting
1514            * 1) update snd_una_max (SYN, SYNACK, FIN)
1515            * 2) If we're not tracking an ACK, start tracking */
1516           if (seq_lt (tc0->snd_una_max, tc0->snd_nxt))
1517             {
1518               tc0->snd_una_max = tc0->snd_nxt;
1519               if (tc0->rtt_ts == 0)
1520                 {
1521                   tc0->rtt_ts = tcp_time_now ();
1522                   tc0->rtt_seq = tc0->snd_nxt;
1523                 }
1524             }
1525
1526           /* Set the retransmit timer if not set already and not
1527            * doing a pure ACK */
1528           if (!tcp_timer_is_active (tc0, TCP_TIMER_RETRANSMIT)
1529               && tc0->snd_nxt != tc0->snd_una)
1530             {
1531               tcp_retransmit_timer_set (tc0);
1532               tc0->rto_boff = 0;
1533             }
1534
1535           /* set fib index to default and lookup node */
1536           /* XXX network virtualization (vrf/vni) */
1537           vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
1538           vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
1539
1540           b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
1541         done:
1542           b0->error = node->errors[error0];
1543           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1544             {
1545               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1546               if (th0)
1547                 {
1548                   clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1549                 }
1550               else
1551                 {
1552                   memset (&t0->tcp_header, 0, sizeof (t0->tcp_header));
1553                 }
1554               clib_memcpy (&t0->tcp_connection, tc0,
1555                            sizeof (t0->tcp_connection));
1556             }
1557
1558           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1559                                            n_left_to_next, bi0, next0);
1560         }
1561
1562       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1563     }
1564
1565   return from_frame->n_vectors;
1566 }
1567
1568 static uword
1569 tcp4_output (vlib_main_t * vm, vlib_node_runtime_t * node,
1570              vlib_frame_t * from_frame)
1571 {
1572   return tcp46_output_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1573 }
1574
1575 static uword
1576 tcp6_output (vlib_main_t * vm, vlib_node_runtime_t * node,
1577              vlib_frame_t * from_frame)
1578 {
1579   return tcp46_output_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1580 }
1581
1582 /* *INDENT-OFF* */
1583 VLIB_REGISTER_NODE (tcp4_output_node) =
1584 {
1585   .function = tcp4_output,.name = "tcp4-output",
1586     /* Takes a vector of packets. */
1587     .vector_size = sizeof (u32),
1588     .n_errors = TCP_N_ERROR,
1589     .error_strings = tcp_error_strings,
1590     .n_next_nodes = TCP_OUTPUT_N_NEXT,
1591     .next_nodes = {
1592 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
1593     foreach_tcp4_output_next
1594 #undef _
1595     },
1596     .format_buffer = format_tcp_header,
1597     .format_trace = format_tcp_tx_trace,
1598 };
1599 /* *INDENT-ON* */
1600
1601 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_output_node, tcp4_output);
1602
1603 /* *INDENT-OFF* */
1604 VLIB_REGISTER_NODE (tcp6_output_node) =
1605 {
1606   .function = tcp6_output,
1607   .name = "tcp6-output",
1608     /* Takes a vector of packets. */
1609   .vector_size = sizeof (u32),
1610   .n_errors = TCP_N_ERROR,
1611   .error_strings = tcp_error_strings,
1612   .n_next_nodes = TCP_OUTPUT_N_NEXT,
1613   .next_nodes = {
1614 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
1615     foreach_tcp6_output_next
1616 #undef _
1617   },
1618   .format_buffer = format_tcp_header,
1619   .format_trace = format_tcp_tx_trace,
1620 };
1621 /* *INDENT-ON* */
1622
1623 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_output_node, tcp6_output);
1624
1625 u32
1626 tcp_push_header (transport_connection_t * tconn, vlib_buffer_t * b)
1627 {
1628   tcp_connection_t *tc;
1629
1630   tc = (tcp_connection_t *) tconn;
1631   tcp_push_hdr_i (tc, b, TCP_STATE_ESTABLISHED, 0);
1632
1633   if (tc->rtt_ts == 0)
1634     {
1635       tc->rtt_ts = tcp_time_now ();
1636       tc->rtt_seq = tc->snd_nxt;
1637     }
1638   return 0;
1639 }
1640
1641 typedef enum _tcp_reset_next
1642 {
1643   TCP_RESET_NEXT_DROP,
1644   TCP_RESET_NEXT_IP_LOOKUP,
1645   TCP_RESET_N_NEXT
1646 } tcp_reset_next_t;
1647
1648 #define foreach_tcp4_reset_next         \
1649   _(DROP, "error-drop")                 \
1650   _(IP_LOOKUP, "ip4-lookup")
1651
1652 #define foreach_tcp6_reset_next         \
1653   _(DROP, "error-drop")                 \
1654   _(IP_LOOKUP, "ip6-lookup")
1655
1656 static uword
1657 tcp46_send_reset_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1658                          vlib_frame_t * from_frame, u8 is_ip4)
1659 {
1660   u32 n_left_from, next_index, *from, *to_next;
1661   u32 my_thread_index = vm->thread_index;
1662
1663   from = vlib_frame_vector_args (from_frame);
1664   n_left_from = from_frame->n_vectors;
1665
1666   next_index = node->cached_next_index;
1667
1668   while (n_left_from > 0)
1669     {
1670       u32 n_left_to_next;
1671
1672       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1673
1674       while (n_left_from > 0 && n_left_to_next > 0)
1675         {
1676           u32 bi0;
1677           vlib_buffer_t *b0;
1678           tcp_tx_trace_t *t0;
1679           tcp_header_t *th0;
1680           u32 error0 = TCP_ERROR_RST_SENT, next0 = TCP_RESET_NEXT_IP_LOOKUP;
1681
1682           bi0 = from[0];
1683           to_next[0] = bi0;
1684           from += 1;
1685           to_next += 1;
1686           n_left_from -= 1;
1687           n_left_to_next -= 1;
1688
1689           b0 = vlib_get_buffer (vm, bi0);
1690
1691           if (tcp_make_reset_in_place (vm, b0, vnet_buffer (b0)->tcp.flags,
1692                                        my_thread_index, is_ip4))
1693             {
1694               error0 = TCP_ERROR_LOOKUP_DROPS;
1695               next0 = TCP_RESET_NEXT_DROP;
1696               goto done;
1697             }
1698
1699           /* Prepare to send to IP lookup */
1700           vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
1701           next0 = TCP_RESET_NEXT_IP_LOOKUP;
1702
1703         done:
1704           b0->error = node->errors[error0];
1705           b0->flags |= VNET_BUFFER_LOCALLY_ORIGINATED;
1706           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1707             {
1708               th0 = vlib_buffer_get_current (b0);
1709               if (is_ip4)
1710                 th0 = ip4_next_header ((ip4_header_t *) th0);
1711               else
1712                 th0 = ip6_next_header ((ip6_header_t *) th0);
1713               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1714               clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1715             }
1716
1717           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1718                                            n_left_to_next, bi0, next0);
1719         }
1720       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1721     }
1722   return from_frame->n_vectors;
1723 }
1724
1725 static uword
1726 tcp4_send_reset (vlib_main_t * vm, vlib_node_runtime_t * node,
1727                  vlib_frame_t * from_frame)
1728 {
1729   return tcp46_send_reset_inline (vm, node, from_frame, 1);
1730 }
1731
1732 static uword
1733 tcp6_send_reset (vlib_main_t * vm, vlib_node_runtime_t * node,
1734                  vlib_frame_t * from_frame)
1735 {
1736   return tcp46_send_reset_inline (vm, node, from_frame, 0);
1737 }
1738
1739 /* *INDENT-OFF* */
1740 VLIB_REGISTER_NODE (tcp4_reset_node) = {
1741   .function = tcp4_send_reset,
1742   .name = "tcp4-reset",
1743   .vector_size = sizeof (u32),
1744   .n_errors = TCP_N_ERROR,
1745   .error_strings = tcp_error_strings,
1746   .n_next_nodes = TCP_RESET_N_NEXT,
1747   .next_nodes = {
1748 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
1749     foreach_tcp4_reset_next
1750 #undef _
1751   },
1752   .format_trace = format_tcp_tx_trace,
1753 };
1754 /* *INDENT-ON* */
1755
1756 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_reset_node, tcp4_send_reset);
1757
1758 /* *INDENT-OFF* */
1759 VLIB_REGISTER_NODE (tcp6_reset_node) = {
1760   .function = tcp6_send_reset,
1761   .name = "tcp6-reset",
1762   .vector_size = sizeof (u32),
1763   .n_errors = TCP_N_ERROR,
1764   .error_strings = tcp_error_strings,
1765   .n_next_nodes = TCP_RESET_N_NEXT,
1766   .next_nodes = {
1767 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
1768     foreach_tcp6_reset_next
1769 #undef _
1770   },
1771   .format_trace = format_tcp_tx_trace,
1772 };
1773 /* *INDENT-ON* */
1774
1775 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_reset_node, tcp6_send_reset);
1776
1777 /*
1778  * fd.io coding-style-patch-verification: ON
1779  *
1780  * Local Variables:
1781  * eval: (c-set-style "gnu")
1782  * End:
1783  */