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