f34eb797c77fab3ecc935da13ea13d90024967b3
[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_next
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        vlib_get_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_F_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   vlib_main_t *vm = vlib_get_main ();
764   if (tc->c_is_ip4)
765     {
766       ip4_header_t *ih;
767       ih = vlib_buffer_push_ip4 (vm, b, &tc->c_lcl_ip4,
768                                  &tc->c_rmt_ip4, IP_PROTOCOL_TCP);
769       th->checksum = ip4_tcp_udp_compute_checksum (vm, b, ih);
770     }
771   else
772     {
773       ip6_header_t *ih;
774       int bogus = ~0;
775
776       ih = vlib_buffer_push_ip6 (vm, b, &tc->c_lcl_ip6,
777                                  &tc->c_rmt_ip6, IP_PROTOCOL_TCP);
778       th->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b, ih, &bogus);
779       ASSERT (!bogus);
780     }
781 }
782
783 /**
784  *  Send SYN
785  *
786  *  Builds a SYN packet for a half-open connection and sends it to ipx_lookup.
787  *  The packet is not forwarded through tcpx_output to avoid doing lookups
788  *  in the half_open pool.
789  */
790 void
791 tcp_send_syn (tcp_connection_t * tc)
792 {
793   vlib_buffer_t *b;
794   u32 bi;
795   tcp_main_t *tm = vnet_get_tcp_main ();
796   vlib_main_t *vm = vlib_get_main ();
797   u8 tcp_hdr_opts_len, tcp_opts_len;
798   tcp_header_t *th;
799   u32 time_now;
800   u16 initial_wnd;
801   tcp_options_t snd_opts;
802
803   tcp_get_free_buffer_index (tm, &bi);
804   b = vlib_get_buffer (vm, bi);
805
806   /* Leave enough space for headers */
807   vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
808
809   /* Set random initial sequence */
810   time_now = tcp_time_now ();
811
812   tc->iss = random_u32 (&time_now);
813   tc->snd_una = tc->iss;
814   tc->snd_una_max = tc->snd_nxt = tc->iss + 1;
815
816   initial_wnd = tcp_initial_window_to_advertise (tc);
817
818   /* Make and write options */
819   memset (&snd_opts, 0, sizeof (snd_opts));
820   tcp_opts_len = tcp_make_syn_options (&snd_opts, tc->rcv_wscale);
821   tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
822
823   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,
824                              tc->rcv_nxt, tcp_hdr_opts_len, TCP_FLAG_SYN,
825                              initial_wnd);
826
827   tcp_options_write ((u8 *) (th + 1), &snd_opts);
828
829   /* Measure RTT with this */
830   tc->rtt_ts = tcp_time_now ();
831   tc->rtt_seq = tc->snd_nxt;
832
833   /* Start retransmit trimer  */
834   tcp_timer_set (tc, TCP_TIMER_RETRANSMIT_SYN, tc->rto * TCP_TO_TIMER_TICK);
835   tc->rto_boff = 0;
836
837   /* Set the connection establishment timer */
838   tcp_timer_set (tc, TCP_TIMER_ESTABLISH, TCP_ESTABLISH_TIME);
839
840   tcp_push_ip_hdr (tm, tc, b);
841   tcp_enqueue_to_ip_lookup (vm, b, bi, tc->c_is_ip4);
842 }
843
844 always_inline void
845 tcp_enqueue_to_output (vlib_main_t * vm, vlib_buffer_t * b, u32 bi, u8 is_ip4)
846 {
847   u32 *to_next, next_index;
848   vlib_frame_t *f;
849
850   b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
851   b->error = 0;
852
853   /* Decide where to send the packet */
854   next_index = is_ip4 ? tcp4_output_node.index : tcp6_output_node.index;
855
856   /* Initialize the trajectory trace, if configured */
857   if (VLIB_BUFFER_TRACE_TRAJECTORY > 0)
858     {
859       b->pre_data[0] = 1;
860       b->pre_data[1] = next_index;
861     }
862
863   /* Enqueue the packet */
864   f = vlib_get_frame_to_node (vm, next_index);
865   to_next = vlib_frame_vector_args (f);
866   to_next[0] = bi;
867   f->n_vectors = 1;
868   vlib_put_frame_to_node (vm, next_index, f);
869 }
870
871 /**
872  *  Send FIN
873  */
874 void
875 tcp_send_fin (tcp_connection_t * tc)
876 {
877   vlib_buffer_t *b;
878   u32 bi;
879   tcp_main_t *tm = vnet_get_tcp_main ();
880   vlib_main_t *vm = vlib_get_main ();
881
882   tcp_get_free_buffer_index (tm, &bi);
883   b = vlib_get_buffer (vm, bi);
884
885   /* Leave enough space for headers */
886   vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
887
888   tcp_make_fin (tc, b);
889   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
890   tc->flags |= TCP_CONN_FINSNT;
891   tcp_retransmit_timer_force_update (tc);
892   TCP_EVT_DBG (TCP_EVT_FIN_SENT, tc);
893 }
894
895 always_inline u8
896 tcp_make_state_flags (tcp_state_t next_state)
897 {
898   switch (next_state)
899     {
900     case TCP_STATE_ESTABLISHED:
901       return TCP_FLAG_ACK;
902     case TCP_STATE_SYN_RCVD:
903       return TCP_FLAG_SYN | TCP_FLAG_ACK;
904     case TCP_STATE_SYN_SENT:
905       return TCP_FLAG_SYN;
906     case TCP_STATE_LAST_ACK:
907     case TCP_STATE_FIN_WAIT_1:
908       return TCP_FLAG_FIN;
909     default:
910       clib_warning ("Shouldn't be here!");
911     }
912   return 0;
913 }
914
915 /**
916  * Push TCP header and update connection variables
917  */
918 static void
919 tcp_push_hdr_i (tcp_connection_t * tc, vlib_buffer_t * b,
920                 tcp_state_t next_state, u8 compute_opts)
921 {
922   u32 advertise_wnd, data_len;
923   u8 tcp_hdr_opts_len, opts_write_len, flags;
924   tcp_header_t *th;
925
926   data_len = b->current_length + b->total_length_not_including_first_buffer;
927   vnet_buffer (b)->tcp.flags = 0;
928
929   if (compute_opts)
930     tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
931
932   tcp_hdr_opts_len = tc->snd_opts_len + sizeof (tcp_header_t);
933   advertise_wnd = tcp_window_to_advertise (tc, next_state);
934   flags = tcp_make_state_flags (next_state);
935
936   /* Push header and options */
937   th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->snd_nxt,
938                              tc->rcv_nxt, tcp_hdr_opts_len, flags,
939                              advertise_wnd);
940   opts_write_len = tcp_options_write ((u8 *) (th + 1), &tc->snd_opts);
941
942   ASSERT (opts_write_len == tc->snd_opts_len);
943   vnet_buffer (b)->tcp.connection_index = tc->c_c_index;
944
945   /*
946    * Update connection variables
947    */
948
949   tc->snd_nxt += data_len;
950   tc->rcv_las = tc->rcv_nxt;
951
952   /* TODO this is updated in output as well ... */
953   if (seq_gt (tc->snd_nxt, tc->snd_una_max))
954     {
955       tc->snd_una_max = tc->snd_nxt;
956       tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
957     }
958
959   TCP_EVT_DBG (TCP_EVT_PKTIZE, tc);
960 }
961
962 void
963 tcp_send_ack (tcp_connection_t * tc)
964 {
965   tcp_main_t *tm = vnet_get_tcp_main ();
966   vlib_main_t *vm = vlib_get_main ();
967
968   vlib_buffer_t *b;
969   u32 bi;
970
971   /* Get buffer */
972   tcp_get_free_buffer_index (tm, &bi);
973   b = vlib_get_buffer (vm, bi);
974
975   /* Fill in the ACK */
976   tcp_make_ack (tc, b);
977   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
978 }
979
980 /* Send delayed ACK when timer expires */
981 void
982 tcp_timer_delack_handler (u32 index)
983 {
984   u32 thread_index = vlib_get_thread_index ();
985   tcp_connection_t *tc;
986
987   tc = tcp_connection_get (index, thread_index);
988   tc->timers[TCP_TIMER_DELACK] = TCP_TIMER_HANDLE_INVALID;
989   tcp_send_ack (tc);
990 }
991
992 /** Build a retransmit segment
993  *
994  * @return the number of bytes in the segment or 0 if there's nothing to
995  *         retransmit
996  */
997 u32
998 tcp_prepare_retransmit_segment (tcp_connection_t * tc, vlib_buffer_t * b,
999                                 u32 offset, u32 max_bytes)
1000 {
1001   vlib_main_t *vm = vlib_get_main ();
1002   int n_bytes = 0;
1003   u32 start;
1004
1005   tcp_reuse_buffer (vm, b);
1006
1007   ASSERT (tc->state >= TCP_STATE_ESTABLISHED);
1008   ASSERT (max_bytes != 0);
1009
1010   max_bytes = clib_min (tc->snd_mss, max_bytes);
1011   start = tc->snd_una + offset;
1012
1013   /* Start is beyond snd_congestion */
1014   if (seq_geq (start, tc->snd_congestion))
1015     goto done;
1016
1017   /* Don't overshoot snd_congestion */
1018   if (seq_gt (start + max_bytes, tc->snd_congestion))
1019     {
1020       max_bytes = tc->snd_congestion - start;
1021       if (max_bytes == 0)
1022         goto done;
1023     }
1024
1025   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1026
1027   ASSERT (max_bytes <= tc->snd_mss);
1028
1029   n_bytes = stream_session_peek_bytes (&tc->connection,
1030                                        vlib_buffer_get_current (b), offset,
1031                                        max_bytes);
1032   ASSERT (n_bytes > 0);
1033   b->current_length = n_bytes;
1034   tcp_push_hdr_i (tc, b, tc->state, 0);
1035
1036   if (tcp_in_fastrecovery (tc))
1037     tc->snd_rxt_bytes += n_bytes;
1038
1039 done:
1040   TCP_EVT_DBG (TCP_EVT_CC_RTX, tc, offset, n_bytes);
1041   return n_bytes;
1042 }
1043
1044 /**
1045  * Reset congestion control, switch cwnd to loss window and try again.
1046  */
1047 static void
1048 tcp_rtx_timeout_cc (tcp_connection_t * tc)
1049 {
1050   tc->prev_ssthresh = tc->ssthresh;
1051   tc->prev_cwnd = tc->cwnd;
1052
1053   /* Cleanly recover cc (also clears up fast retransmit) */
1054   if (tcp_in_fastrecovery (tc))
1055     tcp_cc_fastrecovery_exit (tc);
1056
1057   /* Start again from the beginning */
1058   tc->ssthresh = clib_max (tcp_flight_size (tc) / 2, 2 * tc->snd_mss);
1059   tc->cwnd = tcp_loss_wnd (tc);
1060   tc->snd_congestion = tc->snd_una_max;
1061
1062   tcp_recovery_on (tc);
1063 }
1064
1065 static void
1066 tcp_timer_retransmit_handler_i (u32 index, u8 is_syn)
1067 {
1068   tcp_main_t *tm = vnet_get_tcp_main ();
1069   vlib_main_t *vm = vlib_get_main ();
1070   u32 thread_index = vlib_get_thread_index ();
1071   tcp_connection_t *tc;
1072   vlib_buffer_t *b;
1073   u32 bi, n_bytes;
1074
1075   if (is_syn)
1076     {
1077       tc = tcp_half_open_connection_get (index);
1078     }
1079   else
1080     {
1081       tc = tcp_connection_get (index, thread_index);
1082     }
1083
1084   /* Make sure timer handle is set to invalid */
1085   tc->timers[TCP_TIMER_RETRANSMIT] = TCP_TIMER_HANDLE_INVALID;
1086
1087   if (!tcp_in_recovery (tc) && tc->rto_boff > 0
1088       && tc->state >= TCP_STATE_ESTABLISHED)
1089     {
1090       tc->rto_boff = 0;
1091       tcp_update_rto (tc);
1092     }
1093
1094   /* Increment RTO backoff (also equal to number of retries) */
1095   tc->rto_boff += 1;
1096
1097   /* Go back to first un-acked byte */
1098   tc->snd_nxt = tc->snd_una;
1099
1100   tcp_get_free_buffer_index (tm, &bi);
1101   b = vlib_get_buffer (vm, bi);
1102
1103   if (tc->state >= TCP_STATE_ESTABLISHED)
1104     {
1105       /* Lost FIN, retransmit and return */
1106       if (tc->flags & TCP_CONN_FINSNT)
1107         {
1108           tcp_send_fin (tc);
1109           return;
1110         }
1111
1112       /* First retransmit timeout */
1113       if (tc->rto_boff == 1)
1114         tcp_rtx_timeout_cc (tc);
1115
1116       /* Exponential backoff */
1117       tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1118
1119       TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 1);
1120
1121       /* Send one segment */
1122       n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
1123       /* TODO be less aggressive about this */
1124       scoreboard_clear (&tc->sack_sb);
1125
1126       if (n_bytes == 0)
1127         {
1128           clib_warning ("could not retransmit anything");
1129           clib_warning ("%U", format_tcp_connection, tc, 2);
1130
1131           /* Try again eventually */
1132           tcp_retransmit_timer_set (tc);
1133           ASSERT (0 || (tc->rto_boff > 1
1134                         && tc->snd_una == tc->snd_congestion));
1135           return;
1136         }
1137
1138       /* For first retransmit, record timestamp (Eifel detection RFC3522) */
1139       if (tc->rto_boff == 1)
1140         tc->snd_rxt_ts = tcp_time_now ();
1141     }
1142   /* Retransmit for SYN/SYNACK */
1143   else if (tc->state == TCP_STATE_SYN_RCVD || tc->state == TCP_STATE_SYN_SENT)
1144     {
1145       /* Try without increasing RTO a number of times. If this fails,
1146        * start growing RTO exponentially */
1147       if (tc->rto_boff > TCP_RTO_SYN_RETRIES)
1148         tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1149
1150       vlib_buffer_make_headroom (b, MAX_HDRS_LEN);
1151
1152       tcp_push_hdr_i (tc, b, tc->state, 1);
1153
1154       /* Account for the SYN */
1155       tc->snd_nxt += 1;
1156       tc->rtt_ts = 0;
1157     }
1158   else
1159     {
1160       ASSERT (tc->state == TCP_STATE_CLOSED);
1161       clib_warning ("connection closed ...");
1162       return;
1163     }
1164
1165   if (!is_syn)
1166     {
1167       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1168
1169       /* Re-enable retransmit timer */
1170       tcp_retransmit_timer_set (tc);
1171     }
1172   else
1173     {
1174       ASSERT (tc->state == TCP_STATE_SYN_SENT);
1175
1176       TCP_EVT_DBG (TCP_EVT_SYN_RTX, tc);
1177
1178       /* This goes straight to ipx_lookup */
1179       tcp_push_ip_hdr (tm, tc, b);
1180       tcp_enqueue_to_ip_lookup (vm, b, bi, tc->c_is_ip4);
1181
1182       /* Re-enable retransmit timer */
1183       tcp_timer_set (tc, TCP_TIMER_RETRANSMIT_SYN,
1184                      tc->rto * TCP_TO_TIMER_TICK);
1185     }
1186 }
1187
1188 void
1189 tcp_timer_retransmit_handler (u32 index)
1190 {
1191   tcp_timer_retransmit_handler_i (index, 0);
1192 }
1193
1194 void
1195 tcp_timer_retransmit_syn_handler (u32 index)
1196 {
1197   tcp_timer_retransmit_handler_i (index, 1);
1198 }
1199
1200 /**
1201  * Got 0 snd_wnd from peer, try to do something about it.
1202  *
1203  */
1204 void
1205 tcp_timer_persist_handler (u32 index)
1206 {
1207   tcp_main_t *tm = vnet_get_tcp_main ();
1208   vlib_main_t *vm = vlib_get_main ();
1209   u32 thread_index = vlib_get_thread_index ();
1210   tcp_connection_t *tc;
1211   vlib_buffer_t *b;
1212   u32 bi, old_snd_nxt;
1213   int n_bytes = 0;
1214
1215   tc = tcp_connection_get_if_valid (index, thread_index);
1216
1217   if (!tc)
1218     return;
1219
1220   /* Make sure timer handle is set to invalid */
1221   tc->timers[TCP_TIMER_PERSIST] = TCP_TIMER_HANDLE_INVALID;
1222
1223   /* Problem already solved or worse */
1224   if (tc->state == TCP_STATE_CLOSED || tc->state > TCP_STATE_ESTABLISHED
1225       || tc->snd_wnd > tc->snd_mss || tcp_in_recovery (tc))
1226     return;
1227
1228   /* Increment RTO backoff */
1229   tc->rto_boff += 1;
1230   tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX);
1231
1232   /* Try to force the first unsent segment  */
1233   tcp_get_free_buffer_index (tm, &bi);
1234   b = vlib_get_buffer (vm, bi);
1235
1236   tcp_validate_txf_size (tc, tc->snd_una_max - tc->snd_una);
1237   tc->snd_opts_len = tcp_make_options (tc, &tc->snd_opts, tc->state);
1238   n_bytes = stream_session_peek_bytes (&tc->connection,
1239                                        vlib_buffer_get_current (b),
1240                                        tc->snd_una_max - tc->snd_una,
1241                                        tc->snd_mss);
1242   /* Nothing to send */
1243   if (n_bytes <= 0)
1244     {
1245       // clib_warning ("persist found nothing to send");
1246       tcp_return_buffer (tm);
1247       return;
1248     }
1249
1250   b->current_length = n_bytes;
1251   ASSERT (tc->snd_nxt == tc->snd_una_max || tc->rto_boff > 1
1252           || tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT));
1253
1254   /* Allow updating of snd_una_max but don't update snd_nxt */
1255   old_snd_nxt = tc->snd_nxt;
1256   tcp_push_hdr_i (tc, b, tc->state, 0);
1257   tc->snd_nxt = old_snd_nxt;
1258   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1259
1260   /* Re-enable persist timer */
1261   tcp_persist_timer_set (tc);
1262 }
1263
1264 /**
1265  * Retransmit first unacked segment
1266  */
1267 void
1268 tcp_retransmit_first_unacked (tcp_connection_t * tc)
1269 {
1270   tcp_main_t *tm = vnet_get_tcp_main ();
1271   vlib_main_t *vm = vlib_get_main ();
1272   vlib_buffer_t *b;
1273   u32 bi, n_bytes, old_snd_nxt;
1274
1275   old_snd_nxt = tc->snd_nxt;
1276   tc->snd_nxt = tc->snd_una;
1277
1278   /* Get buffer */
1279   tcp_get_free_buffer_index (tm, &bi);
1280   b = vlib_get_buffer (vm, bi);
1281
1282   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 2);
1283
1284   n_bytes = tcp_prepare_retransmit_segment (tc, b, 0, tc->snd_mss);
1285   if (n_bytes == 0)
1286     {
1287       tcp_return_buffer (tm);
1288       goto done;
1289     }
1290
1291   tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1292
1293 done:
1294   tc->snd_nxt = old_snd_nxt;
1295 }
1296
1297 /**
1298  * Do fast retransmit with SACKs
1299  */
1300 void
1301 tcp_fast_retransmit_sack (tcp_connection_t * tc)
1302 {
1303   tcp_main_t *tm = vnet_get_tcp_main ();
1304   vlib_main_t *vm = vlib_get_main ();
1305   u32 n_written = 0, offset = 0, max_bytes;
1306   vlib_buffer_t *b;
1307   sack_scoreboard_hole_t *hole;
1308   sack_scoreboard_t *sb;
1309   u32 bi, old_snd_nxt;
1310   int snd_space;
1311   u8 snd_limited = 0, can_rescue = 0;
1312
1313   ASSERT (tcp_in_fastrecovery (tc));
1314   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1315
1316   old_snd_nxt = tc->snd_nxt;
1317   sb = &tc->sack_sb;
1318   snd_space = tcp_available_snd_space (tc);
1319
1320   hole = scoreboard_get_hole (sb, sb->cur_rxt_hole);
1321   while (hole && snd_space > 0)
1322     {
1323       tcp_get_free_buffer_index (tm, &bi);
1324       b = vlib_get_buffer (vm, bi);
1325
1326       hole = scoreboard_next_rxt_hole (sb, hole,
1327                                        tcp_fastrecovery_sent_1_smss (tc),
1328                                        &can_rescue, &snd_limited);
1329       if (!hole)
1330         {
1331           if (!can_rescue || !(seq_lt (sb->rescue_rxt, tc->snd_una)
1332                                || seq_gt (sb->rescue_rxt,
1333                                           tc->snd_congestion)))
1334             break;
1335
1336           /* If rescue rxt undefined or less than snd_una then one segment of
1337            * up to SMSS octets that MUST include the highest outstanding
1338            * unSACKed sequence number SHOULD be returned, and RescueRxt set to
1339            * RecoveryPoint. HighRxt MUST NOT be updated.
1340            */
1341           max_bytes = clib_min (tc->snd_mss, snd_space);
1342           offset = tc->snd_congestion - tc->snd_una - max_bytes;
1343           sb->rescue_rxt = tc->snd_congestion;
1344           tc->snd_nxt = tc->snd_una + offset;
1345           tcp_prepare_retransmit_segment (tc, b, offset, max_bytes);
1346           tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1347           break;
1348         }
1349
1350       max_bytes = snd_limited ? tc->snd_mss : hole->end - sb->high_rxt;
1351       offset = sb->high_rxt - tc->snd_una;
1352       tc->snd_nxt = tc->snd_una + offset;
1353       n_written = tcp_prepare_retransmit_segment (tc, b, offset, max_bytes);
1354
1355       /* Nothing left to retransmit */
1356       if (n_written == 0)
1357         {
1358           tcp_return_buffer (tm);
1359           break;
1360         }
1361
1362       sb->high_rxt += n_written;
1363       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1364       snd_space -= n_written;
1365     }
1366
1367   /* If window allows, send 1 SMSS of new data */
1368   tc->snd_nxt = old_snd_nxt;
1369 }
1370
1371 /**
1372  * Fast retransmit without SACK info
1373  */
1374 void
1375 tcp_fast_retransmit_no_sack (tcp_connection_t * tc)
1376 {
1377   tcp_main_t *tm = vnet_get_tcp_main ();
1378   vlib_main_t *vm = vlib_get_main ();
1379   u32 n_written = 0, offset = 0, bi, old_snd_nxt;
1380   int snd_space;
1381   vlib_buffer_t *b;
1382
1383   ASSERT (tcp_in_fastrecovery (tc));
1384   TCP_EVT_DBG (TCP_EVT_CC_EVT, tc, 0);
1385
1386   /* Start resending from first un-acked segment */
1387   old_snd_nxt = tc->snd_nxt;
1388   tc->snd_nxt = tc->snd_una;
1389   snd_space = tcp_available_snd_space (tc);
1390
1391   while (snd_space > 0)
1392     {
1393       tcp_get_free_buffer_index (tm, &bi);
1394       b = vlib_get_buffer (vm, bi);
1395
1396       offset += n_written;
1397       n_written = tcp_prepare_retransmit_segment (tc, b, offset, snd_space);
1398
1399       /* Nothing left to retransmit */
1400       if (n_written == 0)
1401         {
1402           tcp_return_buffer (tm);
1403           break;
1404         }
1405
1406       tcp_enqueue_to_output (vm, b, bi, tc->c_is_ip4);
1407       snd_space -= n_written;
1408     }
1409
1410   /* Restore snd_nxt. If window allows, send 1 SMSS of new data */
1411   tc->snd_nxt = old_snd_nxt;
1412 }
1413
1414 /**
1415  * Do fast retransmit
1416  */
1417 void
1418 tcp_fast_retransmit (tcp_connection_t * tc)
1419 {
1420   if (tcp_opts_sack_permitted (&tc->rcv_opts)
1421       && scoreboard_first_hole (&tc->sack_sb))
1422     tcp_fast_retransmit_sack (tc);
1423   else
1424     tcp_fast_retransmit_no_sack (tc);
1425 }
1426
1427 always_inline u32
1428 tcp_session_has_ooo_data (tcp_connection_t * tc)
1429 {
1430   stream_session_t *s =
1431     stream_session_get (tc->c_s_index, tc->c_thread_index);
1432   return svm_fifo_has_ooo_data (s->server_rx_fifo);
1433 }
1434
1435 always_inline uword
1436 tcp46_output_inline (vlib_main_t * vm,
1437                      vlib_node_runtime_t * node,
1438                      vlib_frame_t * from_frame, int is_ip4)
1439 {
1440   u32 n_left_from, next_index, *from, *to_next;
1441   u32 my_thread_index = vm->thread_index;
1442
1443   from = vlib_frame_vector_args (from_frame);
1444   n_left_from = from_frame->n_vectors;
1445
1446   next_index = node->cached_next_index;
1447
1448   while (n_left_from > 0)
1449     {
1450       u32 n_left_to_next;
1451
1452       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1453
1454       while (n_left_from > 0 && n_left_to_next > 0)
1455         {
1456           u32 bi0;
1457           vlib_buffer_t *b0;
1458           tcp_connection_t *tc0;
1459           tcp_tx_trace_t *t0;
1460           tcp_header_t *th0 = 0;
1461           u32 error0 = TCP_ERROR_PKTS_SENT, next0 = TCP_OUTPUT_NEXT_IP_LOOKUP;
1462
1463           bi0 = from[0];
1464           to_next[0] = bi0;
1465           from += 1;
1466           to_next += 1;
1467           n_left_from -= 1;
1468           n_left_to_next -= 1;
1469
1470           b0 = vlib_get_buffer (vm, bi0);
1471           tc0 = tcp_connection_get (vnet_buffer (b0)->tcp.connection_index,
1472                                     my_thread_index);
1473           if (PREDICT_FALSE (tc0 == 0 || tc0->state == TCP_STATE_CLOSED))
1474             {
1475               error0 = TCP_ERROR_INVALID_CONNECTION;
1476               next0 = TCP_OUTPUT_NEXT_DROP;
1477               goto done;
1478             }
1479
1480           th0 = vlib_buffer_get_current (b0);
1481           TCP_EVT_DBG (TCP_EVT_OUTPUT, tc0, th0->flags, b0->current_length);
1482
1483           if (is_ip4)
1484             {
1485               ip4_header_t *ih0;
1486               ih0 = vlib_buffer_push_ip4 (vm, b0, &tc0->c_lcl_ip4,
1487                                           &tc0->c_rmt_ip4, IP_PROTOCOL_TCP);
1488               th0->checksum = ip4_tcp_udp_compute_checksum (vm, b0, ih0);
1489             }
1490           else
1491             {
1492               ip6_header_t *ih0;
1493               int bogus = ~0;
1494
1495               ih0 = vlib_buffer_push_ip6 (vm, b0, &tc0->c_lcl_ip6,
1496                                           &tc0->c_rmt_ip6, IP_PROTOCOL_TCP);
1497               th0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ih0,
1498                                                                  &bogus);
1499               ASSERT (!bogus);
1500             }
1501
1502           /* Filter out DUPACKs if there are no OOO segments left */
1503           if (PREDICT_FALSE
1504               (vnet_buffer (b0)->tcp.flags & TCP_BUF_FLAG_DUPACK))
1505             {
1506               if (!tcp_session_has_ooo_data (tc0))
1507                 {
1508                   error0 = TCP_ERROR_FILTERED_DUPACKS;
1509                   next0 = TCP_OUTPUT_NEXT_DROP;
1510                   goto done;
1511                 }
1512             }
1513
1514           /* Stop DELACK timer and fix flags */
1515           tc0->flags &= ~(TCP_CONN_SNDACK);
1516           tcp_timer_reset (tc0, TCP_TIMER_DELACK);
1517
1518           /* If not retransmitting
1519            * 1) update snd_una_max (SYN, SYNACK, FIN)
1520            * 2) If we're not tracking an ACK, start tracking */
1521           if (seq_lt (tc0->snd_una_max, tc0->snd_nxt))
1522             {
1523               tc0->snd_una_max = tc0->snd_nxt;
1524               if (tc0->rtt_ts == 0)
1525                 {
1526                   tc0->rtt_ts = tcp_time_now ();
1527                   tc0->rtt_seq = tc0->snd_nxt;
1528                 }
1529             }
1530
1531           /* Set the retransmit timer if not set already and not
1532            * doing a pure ACK */
1533           if (!tcp_timer_is_active (tc0, TCP_TIMER_RETRANSMIT)
1534               && tc0->snd_nxt != tc0->snd_una)
1535             {
1536               tcp_retransmit_timer_set (tc0);
1537               tc0->rto_boff = 0;
1538             }
1539
1540 #if 0
1541           /* Make sure we haven't lost route to our peer */
1542           if (PREDICT_FALSE (tc0->last_fib_check
1543                              < tc0->snd_opts.tsval + TCP_FIB_RECHECK_PERIOD))
1544             {
1545               if (PREDICT_TRUE
1546                   (tc0->c_rmt_fei == tcp_lookup_rmt_in_fib (tc0)))
1547                 {
1548                   tc0->last_fib_check = tc0->snd_opts.tsval;
1549                 }
1550               else
1551                 {
1552                   clib_warning ("lost connection to peer");
1553                   tcp_connection_reset (tc0);
1554                   goto done;
1555                 }
1556             }
1557
1558           /* Use pre-computed dpo to set next node */
1559           next0 = tc0->c_rmt_dpo.dpoi_next_node;
1560           vnet_buffer (b0)->ip.adj_index[VLIB_TX] = tc0->c_rmt_dpo.dpoi_index;
1561 #endif
1562
1563           vnet_buffer (b0)->sw_if_index[VLIB_RX] = 0;
1564           vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0;
1565
1566           b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
1567         done:
1568           b0->error = node->errors[error0];
1569           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1570             {
1571               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1572               if (th0)
1573                 {
1574                   clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1575                 }
1576               else
1577                 {
1578                   memset (&t0->tcp_header, 0, sizeof (t0->tcp_header));
1579                 }
1580               clib_memcpy (&t0->tcp_connection, tc0,
1581                            sizeof (t0->tcp_connection));
1582             }
1583
1584           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1585                                            n_left_to_next, bi0, next0);
1586         }
1587
1588       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1589     }
1590
1591   return from_frame->n_vectors;
1592 }
1593
1594 static uword
1595 tcp4_output (vlib_main_t * vm, vlib_node_runtime_t * node,
1596              vlib_frame_t * from_frame)
1597 {
1598   return tcp46_output_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1599 }
1600
1601 static uword
1602 tcp6_output (vlib_main_t * vm, vlib_node_runtime_t * node,
1603              vlib_frame_t * from_frame)
1604 {
1605   return tcp46_output_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1606 }
1607
1608 /* *INDENT-OFF* */
1609 VLIB_REGISTER_NODE (tcp4_output_node) =
1610 {
1611   .function = tcp4_output,.name = "tcp4-output",
1612     /* Takes a vector of packets. */
1613     .vector_size = sizeof (u32),
1614     .n_errors = TCP_N_ERROR,
1615     .error_strings = tcp_error_strings,
1616     .n_next_nodes = TCP_OUTPUT_N_NEXT,
1617     .next_nodes = {
1618 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
1619     foreach_tcp4_output_next
1620 #undef _
1621     },
1622     .format_buffer = format_tcp_header,
1623     .format_trace = format_tcp_tx_trace,
1624 };
1625 /* *INDENT-ON* */
1626
1627 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_output_node, tcp4_output);
1628
1629 /* *INDENT-OFF* */
1630 VLIB_REGISTER_NODE (tcp6_output_node) =
1631 {
1632   .function = tcp6_output,
1633   .name = "tcp6-output",
1634     /* Takes a vector of packets. */
1635   .vector_size = sizeof (u32),
1636   .n_errors = TCP_N_ERROR,
1637   .error_strings = tcp_error_strings,
1638   .n_next_nodes = TCP_OUTPUT_N_NEXT,
1639   .next_nodes = {
1640 #define _(s,n) [TCP_OUTPUT_NEXT_##s] = n,
1641     foreach_tcp6_output_next
1642 #undef _
1643   },
1644   .format_buffer = format_tcp_header,
1645   .format_trace = format_tcp_tx_trace,
1646 };
1647 /* *INDENT-ON* */
1648
1649 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_output_node, tcp6_output);
1650
1651 u32
1652 tcp_push_header (transport_connection_t * tconn, vlib_buffer_t * b)
1653 {
1654   tcp_connection_t *tc;
1655
1656   tc = (tcp_connection_t *) tconn;
1657   tcp_push_hdr_i (tc, b, TCP_STATE_ESTABLISHED, 0);
1658
1659   if (tc->rtt_ts == 0 && !tcp_in_cong_recovery (tc))
1660     {
1661       tc->rtt_ts = tcp_time_now ();
1662       tc->rtt_seq = tc->snd_nxt;
1663     }
1664   return 0;
1665 }
1666
1667 typedef enum _tcp_reset_next
1668 {
1669   TCP_RESET_NEXT_DROP,
1670   TCP_RESET_NEXT_IP_LOOKUP,
1671   TCP_RESET_N_NEXT
1672 } tcp_reset_next_t;
1673
1674 #define foreach_tcp4_reset_next         \
1675   _(DROP, "error-drop")                 \
1676   _(IP_LOOKUP, "ip4-lookup")
1677
1678 #define foreach_tcp6_reset_next         \
1679   _(DROP, "error-drop")                 \
1680   _(IP_LOOKUP, "ip6-lookup")
1681
1682 static uword
1683 tcp46_send_reset_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
1684                          vlib_frame_t * from_frame, u8 is_ip4)
1685 {
1686   u32 n_left_from, next_index, *from, *to_next;
1687   u32 my_thread_index = vm->thread_index;
1688
1689   from = vlib_frame_vector_args (from_frame);
1690   n_left_from = from_frame->n_vectors;
1691
1692   next_index = node->cached_next_index;
1693
1694   while (n_left_from > 0)
1695     {
1696       u32 n_left_to_next;
1697
1698       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1699
1700       while (n_left_from > 0 && n_left_to_next > 0)
1701         {
1702           u32 bi0;
1703           vlib_buffer_t *b0;
1704           tcp_tx_trace_t *t0;
1705           tcp_header_t *th0;
1706           u32 error0 = TCP_ERROR_RST_SENT, next0 = TCP_RESET_NEXT_IP_LOOKUP;
1707
1708           bi0 = from[0];
1709           to_next[0] = bi0;
1710           from += 1;
1711           to_next += 1;
1712           n_left_from -= 1;
1713           n_left_to_next -= 1;
1714
1715           b0 = vlib_get_buffer (vm, bi0);
1716
1717           if (tcp_make_reset_in_place (vm, b0, vnet_buffer (b0)->tcp.flags,
1718                                        my_thread_index, is_ip4))
1719             {
1720               error0 = TCP_ERROR_LOOKUP_DROPS;
1721               next0 = TCP_RESET_NEXT_DROP;
1722               goto done;
1723             }
1724
1725           /* Prepare to send to IP lookup */
1726           vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
1727           next0 = TCP_RESET_NEXT_IP_LOOKUP;
1728
1729         done:
1730           b0->error = node->errors[error0];
1731           b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
1732           if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1733             {
1734               th0 = vlib_buffer_get_current (b0);
1735               if (is_ip4)
1736                 th0 = ip4_next_header ((ip4_header_t *) th0);
1737               else
1738                 th0 = ip6_next_header ((ip6_header_t *) th0);
1739               t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
1740               clib_memcpy (&t0->tcp_header, th0, sizeof (t0->tcp_header));
1741             }
1742
1743           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1744                                            n_left_to_next, bi0, next0);
1745         }
1746       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1747     }
1748   return from_frame->n_vectors;
1749 }
1750
1751 static uword
1752 tcp4_send_reset (vlib_main_t * vm, vlib_node_runtime_t * node,
1753                  vlib_frame_t * from_frame)
1754 {
1755   return tcp46_send_reset_inline (vm, node, from_frame, 1);
1756 }
1757
1758 static uword
1759 tcp6_send_reset (vlib_main_t * vm, vlib_node_runtime_t * node,
1760                  vlib_frame_t * from_frame)
1761 {
1762   return tcp46_send_reset_inline (vm, node, from_frame, 0);
1763 }
1764
1765 /* *INDENT-OFF* */
1766 VLIB_REGISTER_NODE (tcp4_reset_node) = {
1767   .function = tcp4_send_reset,
1768   .name = "tcp4-reset",
1769   .vector_size = sizeof (u32),
1770   .n_errors = TCP_N_ERROR,
1771   .error_strings = tcp_error_strings,
1772   .n_next_nodes = TCP_RESET_N_NEXT,
1773   .next_nodes = {
1774 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
1775     foreach_tcp4_reset_next
1776 #undef _
1777   },
1778   .format_trace = format_tcp_tx_trace,
1779 };
1780 /* *INDENT-ON* */
1781
1782 VLIB_NODE_FUNCTION_MULTIARCH (tcp4_reset_node, tcp4_send_reset);
1783
1784 /* *INDENT-OFF* */
1785 VLIB_REGISTER_NODE (tcp6_reset_node) = {
1786   .function = tcp6_send_reset,
1787   .name = "tcp6-reset",
1788   .vector_size = sizeof (u32),
1789   .n_errors = TCP_N_ERROR,
1790   .error_strings = tcp_error_strings,
1791   .n_next_nodes = TCP_RESET_N_NEXT,
1792   .next_nodes = {
1793 #define _(s,n) [TCP_RESET_NEXT_##s] = n,
1794     foreach_tcp6_reset_next
1795 #undef _
1796   },
1797   .format_trace = format_tcp_tx_trace,
1798 };
1799 /* *INDENT-ON* */
1800
1801 VLIB_NODE_FUNCTION_MULTIARCH (tcp6_reset_node, tcp6_send_reset);
1802
1803 /*
1804  * fd.io coding-style-patch-verification: ON
1805  *
1806  * Local Variables:
1807  * eval: (c-set-style "gnu")
1808  * End:
1809  */