FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
sctp_input.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 SUSE LLC.
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 #include <vppinfra/sparse_vec.h>
16 #include <vnet/sctp/sctp.h>
17 #include <vnet/sctp/sctp_packet.h>
18 #include <vnet/sctp/sctp_debug.h>
19 #include <vnet/session/session.h>
20 #include <math.h>
21 
22 static char *sctp_error_strings[] = {
23 #define sctp_error(n,s) s,
24 #include <vnet/sctp/sctp_error.def>
25 #undef sctp_error
26 };
27 
28 /* All SCTP nodes have the same outgoing arcs */
29 #define foreach_sctp_state_next \
30  _ (DROP4, "ip4-drop") \
31  _ (DROP6, "ip6-drop") \
32  _ (SCTP4_OUTPUT, "sctp4-output") \
33  _ (SCTP6_OUTPUT, "sctp6-output")
34 
35 typedef enum _sctp_established_phase_next
36 {
37 #define _(s,n) SCTP_ESTABLISHED_PHASE_NEXT_##s,
39 #undef _
42 
43 typedef enum _sctp_rcv_phase_next
44 {
45 #define _(s,n) SCTP_RCV_PHASE_NEXT_##s,
47 #undef _
50 
51 typedef enum _sctp_listen_phase_next
52 {
53 #define _(s,n) SCTP_LISTEN_PHASE_NEXT_##s,
55 #undef _
58 
59 typedef enum _sctp_shutdown_phase_next
60 {
61 #define _(s,n) SCTP_SHUTDOWN_PHASE_NEXT_##s,
63 #undef _
66 
67 /* Generic, state independent indices */
68 typedef enum _sctp_state_next
69 {
70 #define _(s,n) SCTP_NEXT_##s,
72 #undef _
75 
76 typedef enum _sctp_input_next
77 {
86 
87 char *
89 {
90  switch (phase)
91  {
93  return "SCTP_INPUT_NEXT_DROP";
95  return "SCTP_INPUT_NEXT_LISTEN_PHASE";
97  return "SCTP_INPUT_NEXT_RCV_PHASE";
99  return "SCTP_INPUT_NEXT_ESTABLISHED_PHASE";
101  return "SCTP_INPUT_NEXT_SHUTDOWN_PHASE";
103  return "SCTP_INPUT_NEXT_PUNT_PHASE";
104  }
105  return NULL;
106 }
107 
108 #define foreach_sctp4_input_next \
109  _ (DROP, "error-drop") \
110  _ (RCV_PHASE, "sctp4-rcv") \
111  _ (LISTEN_PHASE, "sctp4-listen") \
112  _ (ESTABLISHED_PHASE, "sctp4-established") \
113  _ (SHUTDOWN_PHASE, "sctp4-shutdown") \
114  _ (PUNT_PHASE, "ip4-punt")
115 
116 
117 #define foreach_sctp6_input_next \
118  _ (DROP, "error-drop") \
119  _ (RCV_PHASE, "sctp6-rcv") \
120  _ (LISTEN_PHASE, "sctp6-listen") \
121  _ (ESTABLISHED_PHASE, "sctp6-established") \
122  _ (SHUTDOWN_PHASE, "sctp6-shutdown") \
123  _ (PUNT_PHASE, "ip6-punt")
124 
125 static u8
127  sctp_header_t * sctp_hdr)
128 {
129  sctp_connection_t *sctp_conn =
131 
132  if (!sctp_conn)
133  return 1;
134 
135  u8 is_valid = (trans_conn->lcl_port == sctp_hdr->dst_port
136  && (sctp_conn->state == SCTP_STATE_CLOSED
137  || trans_conn->rmt_port == sctp_hdr->src_port));
138 
139  return is_valid;
140 }
141 
142 /**
143  * Lookup transport connection
144  */
145 static sctp_connection_t *
146 sctp_lookup_connection (u32 fib_index, vlib_buffer_t * b, u8 thread_index,
147  u8 is_ip4)
148 {
150  sctp_header_t *sctp_hdr;
151  transport_connection_t *trans_conn;
152  sctp_connection_t *sctp_conn;
153  u8 is_filtered, i;
154  if (is_ip4)
155  {
156  ip4_header_t *ip4_hdr;
157  ip4_hdr = vlib_buffer_get_current (b);
158  sctp_hdr = ip4_next_header (ip4_hdr);
159  trans_conn = session_lookup_connection_wt4 (fib_index,
160  &ip4_hdr->dst_address,
161  &ip4_hdr->src_address,
162  sctp_hdr->dst_port,
163  sctp_hdr->src_port,
165  thread_index, &is_filtered);
166  if (trans_conn == 0) /* Not primary connection */
167  {
168  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
169  {
170  if ((tm->connections[thread_index]->sub_conn[i].
171  connection.lcl_ip.ip4.as_u32 ==
172  ip4_hdr->dst_address.as_u32)
173  && (tm->connections[thread_index]->sub_conn[i].
174  connection.rmt_ip.ip4.as_u32 ==
175  ip4_hdr->src_address.as_u32))
176  {
177  trans_conn =
178  &tm->connections[thread_index]->sub_conn[i].connection;
179  break;
180  }
181  }
182  }
183  ASSERT (trans_conn != 0);
184  ASSERT (sctp_lookup_is_valid (trans_conn, sctp_hdr));
185  }
186  else
187  {
188  ip6_header_t *ip6_hdr;
189  ip6_hdr = vlib_buffer_get_current (b);
190  sctp_hdr = ip6_next_header (ip6_hdr);
191  trans_conn = session_lookup_connection_wt6 (fib_index,
192  &ip6_hdr->dst_address,
193  &ip6_hdr->src_address,
194  sctp_hdr->dst_port,
195  sctp_hdr->src_port,
197  thread_index, &is_filtered);
198  if (trans_conn == 0) /* Not primary connection */
199  {
200  for (i = 0; i < MAX_SCTP_CONNECTIONS; i++)
201  {
202  if ((tm->connections[thread_index]->sub_conn[i].
203  connection.lcl_ip.ip6.as_u64[0] ==
204  ip6_hdr->dst_address.as_u64[0]
205  && tm->connections[thread_index]->sub_conn[i].
206  connection.lcl_ip.ip6.as_u64[1] ==
207  ip6_hdr->dst_address.as_u64[1])
208  && (tm->connections[thread_index]->sub_conn[i].
209  connection.rmt_ip.ip6.as_u64[0] ==
210  ip6_hdr->src_address.as_u64[0]
211  && tm->connections[thread_index]->
212  sub_conn[i].connection.rmt_ip.ip6.as_u64[1] ==
213  ip6_hdr->src_address.as_u64[1]))
214  {
215  trans_conn =
216  &tm->connections[thread_index]->sub_conn[i].connection;
217  break;
218  }
219  }
220  }
221  ASSERT (trans_conn != 0);
222  ASSERT (sctp_lookup_is_valid (trans_conn, sctp_hdr));
223  }
224  sctp_conn = sctp_get_connection_from_transport (trans_conn);
225  return sctp_conn;
226 }
227 
228 typedef struct
229 {
233 
234 #define sctp_next_output(is_ip4) (is_ip4 ? SCTP_NEXT_SCTP4_OUTPUT \
235  : SCTP_NEXT_SCTP6_OUTPUT)
236 
237 #define sctp_next_drop(is_ip4) (is_ip4 ? SCTP_NEXT_DROP4 \
238  : SCTP_NEXT_DROP6)
239 
240 void
242  sctp_connection_t * sctp_conn,
243  sctp_header_t * sctp_hdr, vlib_buffer_t * b0,
244  u8 is_ip4)
245 {
246  if (sctp_conn)
247  {
248  clib_memcpy (&rx_trace->sctp_connection, sctp_conn,
249  sizeof (rx_trace->sctp_connection));
250  }
251  else
252  {
253  sctp_hdr = sctp_buffer_hdr (b0);
254  }
255  clib_memcpy (&rx_trace->sctp_header, sctp_hdr,
256  sizeof (rx_trace->sctp_header));
257 }
258 
261  int is_ip4)
262 {
263  u16 sctp_implied_packet_length = 0;
264 
265  if (is_ip4)
266  sctp_implied_packet_length =
267  clib_net_to_host_u16 (ip4_hdr->length) - ip4_header_bytes (ip4_hdr);
268  else
269  sctp_implied_packet_length =
270  clib_net_to_host_u16 (ip6_hdr->payload_length) - sizeof (ip6_hdr);
271 
272  return sctp_implied_packet_length;
273 }
274 
276 sctp_is_bundling (u16 sctp_implied_length,
277  sctp_chunks_common_hdr_t * sctp_common_hdr)
278 {
279  if (sctp_implied_length !=
280  sizeof (sctp_header_t) + vnet_sctp_get_chunk_length (sctp_common_hdr))
281  return 1;
282  return 0;
283 }
284 
287  sctp_connection_t * sctp_conn, u8 idx,
288  vlib_buffer_t * b, u16 * next0)
289 {
290  sctp_operation_error_t *op_err = (sctp_operation_error_t *) sctp_hdr;
291 
292  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
293  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
294  {
295  return SCTP_ERROR_INVALID_TAG;
296  }
297 
298  if (clib_net_to_host_u16 (op_err->err_causes[0].param_hdr.type) ==
300  {
301  if (sctp_conn->state != SCTP_STATE_COOKIE_ECHOED)
302  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
303  else
304  {
305  sctp_connection_cleanup (sctp_conn);
306 
308  sub_conn[idx].connection);
309  }
310  }
311 
312  return SCTP_ERROR_NONE;
313 }
314 
317  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
318  sctp_connection_t * sctp_conn, vlib_buffer_t * b0,
319  u16 sctp_implied_length)
320 {
321  sctp_init_chunk_t *init_chunk = (sctp_init_chunk_t *) (sctp_hdr);
322  ip4_address_t ip4_addr;
323  ip6_address_t ip6_addr;
324  u8 add_ip4 = 0;
325  u8 add_ip6 = 0;
326  char hostname[FQDN_MAX_LENGTH];
327 
328  /* Check the current state of the connection
329  *
330  * The logic required by the RFC4960 Section 5.2.2 is already taken care of
331  * in the code below and by the "sctp_prepare_initack_chunk" function.
332  * However, for debugging purposes it is nice to have a message printed out
333  * for these corner-case scenarios.
334  */
335  if (sctp_conn->state != SCTP_STATE_CLOSED)
336  { /* UNEXPECTED scenario */
337  switch (sctp_conn->state)
338  {
339  case SCTP_STATE_COOKIE_WAIT:
340  SCTP_ADV_DBG ("Received INIT chunk while in COOKIE_WAIT state");
343  b0, &ip4_addr, &ip6_addr);
344  return SCTP_ERROR_NONE;
345  case SCTP_STATE_COOKIE_ECHOED:
346  case SCTP_STATE_SHUTDOWN_ACK_SENT:
347  SCTP_ADV_DBG ("Received INIT chunk while in COOKIE_ECHOED state");
348  if (sctp_conn->forming_association_changed == 0)
351  b0, &ip4_addr,
352  &ip6_addr);
353  else
356  &ip4_addr, &ip6_addr);
357  return SCTP_ERROR_NONE;
358  }
359  }
360 
361  if (sctp_hdr->verification_tag != 0x0)
362  return SCTP_ERROR_INVALID_TAG_FOR_INIT;
363 
364  /*
365  * It is not possible to bundle any other CHUNK with the INIT chunk
366  */
367  if (sctp_is_bundling (sctp_implied_length, &init_chunk->chunk_hdr))
368  return SCTP_ERROR_BUNDLING_VIOLATION;
369 
370  /* Save the INITIATE_TAG of the remote peer for this connection:
371  * it MUST be used for the VERIFICATION_TAG parameter in the SCTP HEADER */
372  sctp_conn->remote_tag = init_chunk->initiate_tag;
373  sctp_conn->remote_initial_tsn =
374  clib_net_to_host_u32 (init_chunk->initial_tsn);
375  sctp_conn->last_rcvd_tsn = sctp_conn->remote_initial_tsn;
376  sctp_conn->next_tsn_expected = sctp_conn->remote_initial_tsn + 1;
377  SCTP_CONN_TRACKING_DBG ("sctp_conn->remote_initial_tsn = %u",
378  sctp_conn->remote_initial_tsn);
379 
380  sctp_conn->peer_rwnd = clib_net_to_host_u32 (init_chunk->a_rwnd);
381  /*
382  * If the length specified in the INIT message is bigger than the size in bytes of our structure it means that
383  * optional parameters have been sent with the INIT chunk and we need to parse them.
384  */
385  u16 length = vnet_sctp_get_chunk_length (sctp_chunk_hdr);
386  if (length > sizeof (sctp_init_chunk_t))
387  {
388  /* There are optional parameters in the INIT chunk */
389  u16 pointer_offset = sizeof (sctp_init_chunk_t);
390  while (pointer_offset < length)
391  {
392  sctp_opt_params_hdr_t *opt_params_hdr =
393  (sctp_opt_params_hdr_t *) init_chunk + pointer_offset;
394 
395  switch (clib_net_to_host_u16 (opt_params_hdr->type))
396  {
398  {
399  sctp_ipv4_addr_param_t *ipv4 =
400  (sctp_ipv4_addr_param_t *) opt_params_hdr;
401  clib_memcpy (&ip4_addr, &ipv4->address,
402  sizeof (ip4_address_t));
403 
405  &sctp_conn->sub_conn
406  [SCTP_PRIMARY_PATH_IDX].connection.
407  lcl_ip.ip4,
408  &ipv4->address) ==
409  SCTP_ERROR_NONE)
410  add_ip4 = 1;
411 
412  break;
413  }
415  {
416  sctp_ipv6_addr_param_t *ipv6 =
417  (sctp_ipv6_addr_param_t *) opt_params_hdr;
418  clib_memcpy (&ip6_addr, &ipv6->address,
419  sizeof (ip6_address_t));
420 
422  &sctp_conn->sub_conn
423  [SCTP_PRIMARY_PATH_IDX].connection.
424  lcl_ip.ip6,
425  &ipv6->address) ==
426  SCTP_ERROR_NONE)
427  add_ip6 = 1;
428 
429  break;
430  }
432  {
433  sctp_cookie_preservative_param_t *cookie_pres =
434  (sctp_cookie_preservative_param_t *) opt_params_hdr;
435  sctp_conn->peer_cookie_life_span_increment =
436  cookie_pres->life_span_inc;
437  break;
438  }
440  {
441  sctp_hostname_param_t *hostname_addr =
442  (sctp_hostname_param_t *) opt_params_hdr;
443  clib_memcpy (hostname, hostname_addr->hostname,
445  break;
446  }
448  {
449  /* TODO */
450  break;
451  }
452  }
453  pointer_offset += clib_net_to_host_u16 (opt_params_hdr->length);
454  }
455  }
456 
457  /* Reuse buffer to make init-ack and send */
458  sctp_prepare_initack_chunk (sctp_conn, SCTP_PRIMARY_PATH_IDX, b0, &ip4_addr,
459  add_ip4, &ip6_addr, add_ip6);
460  return SCTP_ERROR_NONE;
461 }
462 
465  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
466  sctp_connection_t * sctp_conn, vlib_buffer_t * b0,
467  u16 sctp_implied_length)
468 {
469  sctp_init_ack_chunk_t *init_ack_chunk =
470  (sctp_init_ack_chunk_t *) (sctp_hdr);
471 
472  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
473  if (sctp_conn->local_tag != init_ack_chunk->sctp_hdr.verification_tag)
474  {
475  return SCTP_ERROR_INVALID_TAG;
476  }
477 
478  /*
479  * It is not possible to bundle any other CHUNK with the INIT_ACK chunk
480  */
481  if (sctp_is_bundling (sctp_implied_length, &init_ack_chunk->chunk_hdr))
482  return SCTP_ERROR_BUNDLING_VIOLATION;
483 
484  return SCTP_ERROR_NONE;
485 }
486 
489  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
490  sctp_connection_t * sctp_conn, u8 idx,
491  vlib_buffer_t * b0, u16 sctp_implied_length)
492 {
493  sctp_init_ack_chunk_t *init_ack_chunk =
494  (sctp_init_ack_chunk_t *) (sctp_hdr);
495 
496  char hostname[FQDN_MAX_LENGTH];
497 
498  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
499  if (sctp_conn->local_tag != init_ack_chunk->sctp_hdr.verification_tag)
500  {
501  return SCTP_ERROR_INVALID_TAG;
502  }
503 
504  /*
505  * It is not possible to bundle any other CHUNK with the INIT chunk
506  */
507  if (sctp_is_bundling (sctp_implied_length, &init_ack_chunk->chunk_hdr))
508  return SCTP_ERROR_BUNDLING_VIOLATION;
509 
510  /* Stop the T1_INIT timer */
511  sctp_timer_reset (sctp_conn, idx, SCTP_TIMER_T1_INIT);
512 
513  sctp_calculate_rto (sctp_conn, idx);
514 
515  /* remote_tag to be placed in the VERIFICATION_TAG field of the COOKIE_ECHO chunk */
516  sctp_conn->remote_tag = init_ack_chunk->initiate_tag;
517  sctp_conn->remote_initial_tsn =
518  clib_net_to_host_u32 (init_ack_chunk->initial_tsn);
519  sctp_conn->last_rcvd_tsn = sctp_conn->remote_initial_tsn;
520  sctp_conn->next_tsn_expected = sctp_conn->remote_initial_tsn + 1;
521  SCTP_CONN_TRACKING_DBG ("sctp_conn->remote_initial_tsn = %u",
522  sctp_conn->remote_initial_tsn);
523  sctp_conn->peer_rwnd = clib_net_to_host_u32 (init_ack_chunk->a_rwnd);
524 
525  u16 length = vnet_sctp_get_chunk_length (sctp_chunk_hdr);
526 
527  if (length > sizeof (sctp_init_ack_chunk_t))
528  /*
529  * There are optional parameters in the INIT ACK chunk
530  */
531  {
532  u16 pointer_offset = sizeof (sctp_init_ack_chunk_t);
533 
534  while (pointer_offset < length)
535  {
536  sctp_opt_params_hdr_t *opt_params_hdr =
537  (sctp_opt_params_hdr_t *) ((char *) init_ack_chunk +
538  pointer_offset);
539 
540  switch (clib_net_to_host_u16 (opt_params_hdr->type))
541  {
543  {
544  sctp_ipv4_addr_param_t *ipv4 =
545  (sctp_ipv4_addr_param_t *) opt_params_hdr;
546 
548  &sctp_conn->sub_conn
549  [SCTP_PRIMARY_PATH_IDX].connection.
550  lcl_ip.ip4, &ipv4->address);
551 
552  break;
553  }
555  {
556  sctp_ipv6_addr_param_t *ipv6 =
557  (sctp_ipv6_addr_param_t *) opt_params_hdr;
558 
560  &sctp_conn->sub_conn
561  [SCTP_PRIMARY_PATH_IDX].connection.
562  lcl_ip.ip6, &ipv6->address);
563 
564  break;
565  }
567  {
568  sctp_state_cookie_param_t *state_cookie_param =
569  (sctp_state_cookie_param_t *) opt_params_hdr;
570 
571  clib_memcpy (&(sctp_conn->cookie_param), state_cookie_param,
572  sizeof (sctp_state_cookie_param_t));
573 
574  break;
575  }
577  {
578  sctp_hostname_param_t *hostname_addr =
579  (sctp_hostname_param_t *) opt_params_hdr;
580  clib_memcpy (hostname, hostname_addr->hostname,
582  break;
583  }
585  {
586  break;
587  }
588  }
589  u16 increment = clib_net_to_host_u16 (opt_params_hdr->length);
590  /* This indicates something really bad happened */
591  if (increment == 0)
592  {
593  return SCTP_ERROR_INVALID_TAG;
594  }
595  pointer_offset += increment;
596  }
597  }
598 
599  sctp_prepare_cookie_echo_chunk (sctp_conn, idx, b0, 1);
600 
601  /* Start the T1_COOKIE timer */
602  sctp_timer_set (sctp_conn, idx,
603  SCTP_TIMER_T1_COOKIE, sctp_conn->sub_conn[idx].RTO);
604 
605  return SCTP_ERROR_NONE;
606 }
607 
608 /** Enqueue data out-of-order for delivery to application */
609 always_inline int
611  vlib_buffer_t * b, u16 data_len, u8 conn_idx)
612 {
613  int written, error = SCTP_ERROR_ENQUEUED;
614 
615  written =
617  sub_conn[conn_idx].connection, b, 0,
618  1 /* queue event */ ,
619  0);
620 
621  /* Update next_tsn_expected */
622  if (PREDICT_TRUE (written == data_len))
623  {
624  sctp_conn->next_tsn_expected += written;
625 
626  SCTP_ADV_DBG ("CONN = %u, WRITTEN [%u] == DATA_LEN [%d]",
627  sctp_conn->sub_conn[conn_idx].connection.c_index,
628  written, data_len);
629  }
630  /* If more data written than expected, account for out-of-order bytes. */
631  else if (written > data_len)
632  {
633  sctp_conn->next_tsn_expected += written;
634 
635  SCTP_ADV_DBG ("CONN = %u, WRITTEN [%u] > DATA_LEN [%d]",
636  sctp_conn->sub_conn[conn_idx].connection.c_index,
637  written, data_len);
638  }
639  else if (written > 0)
640  {
641  /* We've written something but FIFO is probably full now */
642  sctp_conn->next_tsn_expected += written;
643 
644  error = SCTP_ERROR_PARTIALLY_ENQUEUED;
645 
647  ("CONN = %u, WRITTEN [%u] > 0 (SCTP_ERROR_PARTIALLY_ENQUEUED)",
648  sctp_conn->sub_conn[conn_idx].connection.c_index, written);
649  }
650  else
651  {
652  SCTP_ADV_DBG ("CONN = %u, WRITTEN == 0 (SCTP_ERROR_FIFO_FULL)",
653  sctp_conn->sub_conn[conn_idx].connection.c_index);
654 
655  return SCTP_ERROR_FIFO_FULL;
656  }
657 
658  /* TODO: Update out_of_order_map & SACK list */
659 
660  return error;
661 }
662 
663 /** Enqueue data for delivery to application */
664 always_inline int
666  u16 data_len, u8 conn_idx)
667 {
668  int written, error = SCTP_ERROR_ENQUEUED;
669 
670  written =
672  sub_conn[conn_idx].connection, b, 0,
673  1 /* queue event */ ,
674  1);
675 
676  /* Update next_tsn_expected */
677  if (PREDICT_TRUE (written == data_len))
678  {
679  sctp_conn->next_tsn_expected += written;
680 
681  SCTP_ADV_DBG ("CONN = %u, WRITTEN [%u] == DATA_LEN [%d]",
682  sctp_conn->sub_conn[conn_idx].connection.c_index,
683  written, data_len);
684  }
685  /* If more data written than expected, account for out-of-order bytes. */
686  else if (written > data_len)
687  {
688  sctp_conn->next_tsn_expected += written;
689 
690  SCTP_ADV_DBG ("CONN = %u, WRITTEN [%u] > DATA_LEN [%d]",
691  sctp_conn->sub_conn[conn_idx].connection.c_index,
692  written, data_len);
693  }
694  else if (written > 0)
695  {
696  /* We've written something but FIFO is probably full now */
697  sctp_conn->next_tsn_expected += written;
698 
699  error = SCTP_ERROR_PARTIALLY_ENQUEUED;
700 
702  ("CONN = %u, WRITTEN [%u] > 0 (SCTP_ERROR_PARTIALLY_ENQUEUED)",
703  sctp_conn->sub_conn[conn_idx].connection.c_index, written);
704  }
705  else
706  {
707  SCTP_ADV_DBG ("CONN = %u, WRITTEN == 0 (SCTP_ERROR_FIFO_FULL)",
708  sctp_conn->sub_conn[conn_idx].connection.c_index);
709 
710  return SCTP_ERROR_FIFO_FULL;
711  }
712 
713  return error;
714 }
715 
717 sctp_is_sack_delayable (sctp_connection_t * sctp_conn, u8 idx, u8 is_gapping)
718 {
719  if (sctp_conn->conn_config.never_delay_sack)
720  {
721  SCTP_CONN_TRACKING_DBG ("sctp_conn->conn_config.never_delay_sack = ON");
722  return 0;
723  }
724 
725  /* Section 4.4 of the RFC4960 */
726  if (sctp_conn->state == SCTP_STATE_SHUTDOWN_SENT)
727  {
728  SCTP_CONN_TRACKING_DBG ("sctp_conn->state = %s; SACK not delayable",
729  sctp_state_to_string (sctp_conn->state));
730  return 0;
731  }
732 
733  if (is_gapping)
734  {
736  ("gapping != 0: CONN_INDEX = %u, sctp_conn->ack_state = %u",
737  sctp_conn->sub_conn[idx].connection.c_index, sctp_conn->ack_state);
738  return 0;
739  }
740 
741  sctp_conn->ack_state += 1;
742  if (sctp_conn->ack_state >= MAX_ENQUEABLE_SACKS)
743  {
745  ("sctp_conn->ack_state >= MAX_ENQUEABLE_SACKS: CONN_INDEX = %u, sctp_conn->ack_state = %u",
746  sctp_conn->sub_conn[idx].connection.c_index, sctp_conn->ack_state);
747  return 0;
748  }
749 
750  return 1;
751 }
752 
753 always_inline void
755  u8 * gapping)
756 {
757  if (sctp_conn->next_tsn_expected != tsn) // It means data transmission is GAPPING
758  {
760  ("GAPPING: CONN_INDEX = %u, sctp_conn->next_tsn_expected = %u, tsn = %u, diff = %u",
761  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.c_index,
762  sctp_conn->next_tsn_expected, tsn,
763  sctp_conn->next_tsn_expected - tsn);
764 
765  *gapping = 1;
766  }
767 }
768 
771  sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b,
772  u16 * next0)
773 {
774  u32 error = 0, n_data_bytes;
775  u8 is_gapping = 0;
776 
777  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
778  if (sctp_conn->local_tag != sctp_data_chunk->sctp_hdr.verification_tag)
779  {
780  return SCTP_ERROR_INVALID_TAG;
781  }
782 
783  vnet_buffer (b)->sctp.sid = sctp_data_chunk->stream_id;
784  vnet_buffer (b)->sctp.ssn = sctp_data_chunk->stream_seq;
785 
786  u32 tsn = clib_net_to_host_u32 (sctp_data_chunk->tsn);
787 
788  vlib_buffer_advance (b, vnet_buffer (b)->sctp.data_offset);
789  n_data_bytes = vnet_buffer (b)->sctp.data_len;
790  ASSERT (n_data_bytes);
791 
792  sctp_is_connection_gapping (sctp_conn, tsn, &is_gapping);
793 
794  sctp_conn->last_rcvd_tsn = tsn;
795 
796  SCTP_ADV_DBG ("POINTER_WITH_DATA = %p", b->data);
797 
798  u8 bbit = vnet_sctp_get_bbit (&sctp_data_chunk->chunk_hdr);
799  u8 ebit = vnet_sctp_get_ebit (&sctp_data_chunk->chunk_hdr);
800 
801  if (bbit == 1 && ebit == 1) /* Unfragmented message */
802  {
803  /* In order data, enqueue. Fifo figures out by itself if any out-of-order
804  * segments can be enqueued after fifo tail offset changes. */
805  if (PREDICT_FALSE (is_gapping == 1))
806  error =
807  sctp_session_enqueue_data_ooo (sctp_conn, b, n_data_bytes, idx);
808  else
809  error = sctp_session_enqueue_data (sctp_conn, b, n_data_bytes, idx);
810  }
811  else if (bbit == 1 && ebit == 0) /* First piece of a fragmented user message */
812  {
813  error = sctp_session_enqueue_data (sctp_conn, b, n_data_bytes, idx);
814  }
815  else if (bbit == 0 && ebit == 1) /* Last piece of a fragmented user message */
816  {
817  if (PREDICT_FALSE (is_gapping == 1))
818  error =
819  sctp_session_enqueue_data_ooo (sctp_conn, b, n_data_bytes, idx);
820  else
821  error = sctp_session_enqueue_data (sctp_conn, b, n_data_bytes, idx);
822  }
823  else /* Middle piece of a fragmented user message */
824  {
825  if (PREDICT_FALSE (is_gapping == 1))
826  error =
827  sctp_session_enqueue_data_ooo (sctp_conn, b, n_data_bytes, idx);
828  else
829  error = sctp_session_enqueue_data (sctp_conn, b, n_data_bytes, idx);
830  }
831  sctp_conn->last_rcvd_tsn = tsn;
832 
833  SCTP_ADV_DBG ("POINTER_WITH_DATA = %p", b->data);
834 
835  if (!sctp_is_sack_delayable (sctp_conn, idx, is_gapping))
836  {
837  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
838  sctp_prepare_sack_chunk (sctp_conn, idx, b);
839  }
840  else
841  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
842 
843  sctp_conn->sub_conn[idx].enqueue_state = error;
844 
845  return error;
846 }
847 
850  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
851  sctp_connection_t * sctp_conn, u8 idx,
852  vlib_buffer_t * b0, u16 * next0)
853 {
854  u32 now = sctp_time_now ();
855 
856  sctp_cookie_echo_chunk_t *cookie_echo =
857  (sctp_cookie_echo_chunk_t *) sctp_hdr;
858 
859  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
860  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
861  {
862  return SCTP_ERROR_INVALID_TAG;
863  }
864 
865  sctp_calculate_rto (sctp_conn, idx);
866 
867  u32 creation_time =
868  clib_net_to_host_u32 (cookie_echo->cookie.creation_time);
869  u32 cookie_lifespan =
870  clib_net_to_host_u32 (cookie_echo->cookie.cookie_lifespan);
871  if (now > creation_time + cookie_lifespan)
872  {
873  SCTP_DBG ("now (%u) > creation_time (%u) + cookie_lifespan (%u)",
874  now, creation_time, cookie_lifespan);
875  return SCTP_ERROR_COOKIE_ECHO_VIOLATION;
876  }
877 
878  sctp_prepare_cookie_ack_chunk (sctp_conn, idx, b0);
879 
880  /* Change state */
881  sctp_conn->state = SCTP_STATE_ESTABLISHED;
882  sctp_conn->sub_conn[idx].state = SCTP_SUBCONN_STATE_UP;
883  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
884 
885  sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT,
886  sctp_conn->sub_conn[idx].RTO);
887 
888  stream_session_accept_notify (&sctp_conn->sub_conn[idx].connection);
889 
890  return SCTP_ERROR_NONE;
891 
892 }
893 
896  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
897  sctp_connection_t * sctp_conn, u8 idx,
898  vlib_buffer_t * b0, u16 * next0)
899 {
900  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
901  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
902  {
903  return SCTP_ERROR_INVALID_TAG;
904  }
905 
906  sctp_calculate_rto (sctp_conn, idx);
907 
908  sctp_timer_reset (sctp_conn, idx, SCTP_TIMER_T1_COOKIE);
909  /* Change state */
910  sctp_conn->state = SCTP_STATE_ESTABLISHED;
911  sctp_conn->sub_conn[idx].state = SCTP_SUBCONN_STATE_UP;
912 
913  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
914 
915  sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT,
916  sctp_conn->sub_conn[idx].RTO);
917 
918  stream_session_accept_notify (&sctp_conn->sub_conn[idx].connection);
919 
920  return SCTP_ERROR_NONE;
921 
922 }
923 
926  vlib_frame_t * from_frame, int is_ip4)
927 {
929 
930  u32 n_left_from, next_index, *from, *to_next;
931  u32 my_thread_index = vm->thread_index;
932 
933  from = vlib_frame_vector_args (from_frame);
934  n_left_from = from_frame->n_vectors;
935 
936  next_index = node->cached_next_index;
937 
938  while (n_left_from > 0)
939  {
940  u32 n_left_to_next;
941 
942  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
943 
944  while (n_left_from > 0 && n_left_to_next > 0)
945  {
946  u32 bi0;
947  vlib_buffer_t *b0;
948  sctp_header_t *sctp_hdr = 0;
949  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
950  ip4_header_t *ip4_hdr = 0;
951  ip6_header_t *ip6_hdr = 0;
952  sctp_connection_t *sctp_conn, *new_sctp_conn;
953  u16 sctp_implied_length = 0;
954  u16 error0 = SCTP_ERROR_NONE, next0 = sctp_next_drop (is_ip4);
955  u8 idx;
956 
957  bi0 = from[0];
958  to_next[0] = bi0;
959  from += 1;
960  to_next += 1;
961  n_left_from -= 1;
962  n_left_to_next -= 1;
963 
964  b0 = vlib_get_buffer (vm, bi0);
965 
966  /* If we are in SCTP_COOKIE_WAIT_STATE then the connection
967  * will come from the half-open connections pool.
968  */
969  sctp_conn =
971  sctp.connection_index);
972 
973  if (PREDICT_FALSE (sctp_conn == 0))
974  {
976  ("sctp_conn == NULL; return SCTP_ERROR_INVALID_CONNECTION");
977  error0 = SCTP_ERROR_INVALID_CONNECTION;
978  goto drop;
979  }
980  if (is_ip4)
981  {
982  ip4_hdr = vlib_buffer_get_current (b0);
983  sctp_hdr = ip4_next_header (ip4_hdr);
984  idx = sctp_sub_conn_id_via_ip4h (sctp_conn, ip4_hdr);
985  }
986  else
987  {
988  ip6_hdr = vlib_buffer_get_current (b0);
989  sctp_hdr = ip6_next_header (ip6_hdr);
990  idx = sctp_sub_conn_id_via_ip6h (sctp_conn, ip6_hdr);
991  }
992 
993  sctp_conn->sub_conn[idx].subconn_idx = idx;
994  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
995 
996  sctp_chunk_hdr =
997  (sctp_chunks_common_hdr_t *) (&full_hdr->common_hdr);
998 
999  sctp_implied_length =
1000  sctp_calculate_implied_length (ip4_hdr, ip6_hdr, is_ip4);
1001 
1002  u8 chunk_type = vnet_sctp_get_chunk_type (&full_hdr->common_hdr);
1003 
1004  switch (chunk_type)
1005  {
1006  case INIT_ACK:
1007  error0 =
1008  sctp_is_valid_init_ack (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1009  b0, sctp_implied_length);
1010 
1011  if (error0 == SCTP_ERROR_NONE)
1012  {
1013  pool_get (tm->connections[my_thread_index], new_sctp_conn);
1014  clib_memcpy (new_sctp_conn, sctp_conn,
1015  sizeof (*new_sctp_conn));
1016  new_sctp_conn->sub_conn[idx].c_c_index =
1017  new_sctp_conn - tm->connections[my_thread_index];
1018  new_sctp_conn->sub_conn[idx].c_thread_index =
1019  my_thread_index;
1020  new_sctp_conn->sub_conn[idx].PMTU =
1021  sctp_conn->sub_conn[idx].PMTU;
1022  new_sctp_conn->sub_conn[idx].subconn_idx = idx;
1023 
1024  if (sctp_half_open_connection_cleanup (sctp_conn))
1025  {
1026  SCTP_DBG
1027  ("Cannot cleanup half-open connection; not the owning thread");
1028  }
1029 
1030  sctp_connection_timers_init (new_sctp_conn);
1031 
1032  sctp_init_cwnd (new_sctp_conn);
1033 
1034  error0 =
1035  sctp_handle_init_ack (sctp_hdr, sctp_chunk_hdr,
1036  new_sctp_conn, idx, b0,
1037  sctp_implied_length);
1038 
1040  (&new_sctp_conn->sub_conn[idx].connection, 0))
1041  {
1042  SCTP_DBG
1043  ("conn_index = %u: session_stream_connect_notify error; cleaning up connection",
1044  new_sctp_conn->sub_conn[idx].connection.c_index);
1045  sctp_connection_cleanup (new_sctp_conn);
1046  goto drop;
1047  }
1048  next0 = sctp_next_output (is_ip4);
1049  }
1050  break;
1051 
1052  case OPERATION_ERROR:
1053  error0 =
1054  sctp_handle_operation_err (sctp_hdr, sctp_conn, idx, b0,
1055  &next0);
1056  break;
1057 
1058  /* All UNEXPECTED scenarios (wrong chunk received per state-machine)
1059  * are handled by the input-dispatcher function using the table-lookup
1060  * hence we should never get to the "default" case below.
1061  */
1062  default:
1063  error0 = SCTP_ERROR_UNKOWN_CHUNK;
1064  next0 = sctp_next_drop (is_ip4);
1065  goto drop;
1066  }
1067 
1068  if (error0 != SCTP_ERROR_NONE)
1069  {
1070  clib_warning ("error while parsing chunk");
1071  sctp_connection_cleanup (sctp_conn);
1072  next0 = sctp_next_drop (is_ip4);
1073  goto drop;
1074  }
1075 
1076  drop:
1077  b0->error = node->errors[error0];
1078  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1079  {
1080  sctp_rx_trace_t *t0 =
1081  vlib_add_trace (vm, node, b0, sizeof (*t0));
1082  sctp_set_rx_trace_data (t0, sctp_conn, sctp_hdr, b0, is_ip4);
1083  }
1084 
1085  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1086  n_left_to_next, bi0, next0);
1087  }
1088 
1089  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1090  }
1091  return from_frame->n_vectors;
1092 }
1093 
1094 static uword
1096  vlib_frame_t * from_frame)
1097 {
1098  return sctp46_rcv_phase_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1099 }
1100 
1101 static uword
1103  vlib_frame_t * from_frame)
1104 {
1105  return sctp46_rcv_phase_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1106 }
1107 
1108 u8 *
1109 format_sctp_rx_trace_short (u8 * s, va_list * args)
1110 {
1111  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1112  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1113  sctp_rx_trace_t *t = va_arg (*args, sctp_rx_trace_t *);
1114 
1115  s = format (s, "%d -> %d (%U)",
1116  clib_net_to_host_u16 (t->sctp_header.src_port),
1117  clib_net_to_host_u16 (t->sctp_header.dst_port),
1119 
1120  return s;
1121 }
1122 
1123 /* *INDENT-OFF* */
1125 {
1126  .function = sctp4_rcv_phase,
1127  .name = "sctp4-rcv",
1128  /* Takes a vector of packets. */
1129  .vector_size = sizeof (u32),
1130  .n_errors = SCTP_N_ERROR,
1131  .error_strings = sctp_error_strings,
1132  .n_next_nodes = SCTP_RCV_PHASE_N_NEXT,
1133  .next_nodes =
1134  {
1135 #define _(s,n) [SCTP_RCV_PHASE_NEXT_##s] = n,
1137 #undef _
1138  },
1139  .format_trace = format_sctp_rx_trace_short,
1140 };
1141 /* *INDENT-ON* */
1142 
1144 
1145 /* *INDENT-OFF* */
1147 {
1148  .function = sctp6_rcv_phase,
1149  .name = "sctp6-rcv",
1150  /* Takes a vector of packets. */
1151  .vector_size = sizeof (u32),
1152  .n_errors = SCTP_N_ERROR,
1153  .error_strings = sctp_error_strings,
1154  .n_next_nodes = SCTP_RCV_PHASE_N_NEXT,
1155  .next_nodes =
1156  {
1157 #define _(s,n) [SCTP_RCV_PHASE_NEXT_##s] = n,
1159 #undef _
1160  },
1161  .format_trace = format_sctp_rx_trace_short,
1162 };
1163 /* *INDENT-ON* */
1164 
1166 
1169 
1172  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
1173  sctp_connection_t * sctp_conn, u8 idx,
1174  vlib_buffer_t * b0, u16 sctp_implied_length,
1175  u16 * next0)
1176 {
1177  sctp_shutdown_association_chunk_t *shutdown_chunk =
1178  (sctp_shutdown_association_chunk_t *) (sctp_hdr);
1179 
1180  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1181  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
1182  {
1183  return SCTP_ERROR_INVALID_TAG;
1184  }
1185 
1186  /*
1187  * It is not possible to bundle any other CHUNK with the SHUTDOWN chunk
1188  */
1189  if (sctp_is_bundling (sctp_implied_length, &shutdown_chunk->chunk_hdr))
1190  return SCTP_ERROR_BUNDLING_VIOLATION;
1191 
1192  switch (sctp_conn->state)
1193  {
1194  case SCTP_STATE_ESTABLISHED:
1195  if (sctp_check_outstanding_data_chunks (sctp_conn) == 0)
1196  sctp_conn->state = SCTP_STATE_SHUTDOWN_RECEIVED;
1197  sctp_send_shutdown_ack (sctp_conn, idx, b0);
1198  break;
1199 
1200  case SCTP_STATE_SHUTDOWN_SENT:
1201  sctp_send_shutdown_ack (sctp_conn, idx, b0);
1202  break;
1203  }
1204 
1205  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
1206 
1207  return SCTP_ERROR_NONE;
1208 }
1209 
1212  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
1213  sctp_connection_t * sctp_conn, u8 idx,
1214  vlib_buffer_t * b0, u16 sctp_implied_length,
1215  u16 * next0)
1216 {
1217  sctp_shutdown_ack_chunk_t *shutdown_ack_chunk =
1218  (sctp_shutdown_ack_chunk_t *) (sctp_hdr);
1219 
1220  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1221  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
1222  {
1223  return SCTP_ERROR_INVALID_TAG;
1224  }
1225 
1226  /*
1227  * It is not possible to bundle any other CHUNK with the SHUTDOWN chunk
1228  */
1229  if (sctp_is_bundling (sctp_implied_length, &shutdown_ack_chunk->chunk_hdr))
1230  return SCTP_ERROR_BUNDLING_VIOLATION;
1231 
1232  /* Whether we are in SCTP_STATE_SHUTDOWN_SENT or SCTP_STATE_SHUTDOWN_ACK_SENT
1233  * the reception of a SHUTDOWN_ACK chunk leads to the same actions:
1234  * - STOP T2_SHUTDOWN timer
1235  * - SEND SHUTDOWN_COMPLETE chunk
1236  */
1237  sctp_timer_reset (sctp_conn, SCTP_PRIMARY_PATH_IDX, SCTP_TIMER_T2_SHUTDOWN);
1238 
1239  sctp_send_shutdown_complete (sctp_conn, idx, b0);
1240 
1241  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
1242 
1243  return SCTP_ERROR_NONE;
1244 }
1245 
1248  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
1249  sctp_connection_t * sctp_conn, u8 idx,
1250  vlib_buffer_t * b0, u16 sctp_implied_length,
1251  u16 * next0)
1252 {
1253  sctp_shutdown_complete_chunk_t *shutdown_complete =
1254  (sctp_shutdown_complete_chunk_t *) (sctp_hdr);
1255 
1256  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1257  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
1258  {
1259  return SCTP_ERROR_INVALID_TAG;
1260  }
1261 
1262  /*
1263  * It is not possible to bundle any other CHUNK with the SHUTDOWN chunk
1264  */
1265  if (sctp_is_bundling (sctp_implied_length, &shutdown_complete->chunk_hdr))
1266  return SCTP_ERROR_BUNDLING_VIOLATION;
1267 
1268  sctp_timer_reset (sctp_conn, idx, SCTP_TIMER_T2_SHUTDOWN);
1269 
1270  stream_session_disconnect_notify (&sctp_conn->sub_conn[idx].connection);
1271 
1272  sctp_conn->state = SCTP_STATE_CLOSED;
1273 
1274  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1275 
1276  return SCTP_ERROR_NONE;
1277 }
1278 
1281  vlib_node_runtime_t * node,
1282  vlib_frame_t * from_frame, int is_ip4)
1283 {
1284  u32 n_left_from, next_index, *from, *to_next;
1285  u32 my_thread_index = vm->thread_index;
1286 
1287  from = vlib_frame_vector_args (from_frame);
1288  n_left_from = from_frame->n_vectors;
1289 
1290  next_index = node->cached_next_index;
1291 
1292  while (n_left_from > 0)
1293  {
1294  u32 n_left_to_next;
1295 
1296  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1297 
1298  while (n_left_from > 0 && n_left_to_next > 0)
1299  {
1300  u32 bi0;
1301  vlib_buffer_t *b0;
1302  sctp_rx_trace_t *sctp_trace;
1303  sctp_header_t *sctp_hdr = 0;
1304  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
1305  ip4_header_t *ip4_hdr = 0;
1306  ip6_header_t *ip6_hdr = 0;
1307  sctp_connection_t *sctp_conn;
1308  u16 sctp_implied_length = 0;
1309  u16 error0 = SCTP_ERROR_NONE, next0 = SCTP_RCV_PHASE_N_NEXT;
1310  u8 idx = 0;
1311 
1312  bi0 = from[0];
1313  to_next[0] = bi0;
1314  from += 1;
1315  to_next += 1;
1316  n_left_from -= 1;
1317  n_left_to_next -= 1;
1318 
1319  b0 = vlib_get_buffer (vm, bi0);
1320  sctp_conn =
1321  sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
1322  my_thread_index);
1323 
1324  if (PREDICT_FALSE (sctp_conn == 0))
1325  {
1326  SCTP_DBG
1327  ("sctp_conn == NULL; return SCTP_ERROR_INVALID_CONNECTION");
1328  error0 = SCTP_ERROR_INVALID_CONNECTION;
1329  goto drop;
1330  }
1331 
1332  if (is_ip4)
1333  {
1334  ip4_hdr = vlib_buffer_get_current (b0);
1335  sctp_hdr = ip4_next_header (ip4_hdr);
1336  idx = sctp_sub_conn_id_via_ip4h (sctp_conn, ip4_hdr);
1337  }
1338  else
1339  {
1340  ip6_hdr = vlib_buffer_get_current (b0);
1341  sctp_hdr = ip6_next_header (ip6_hdr);
1342  idx = sctp_sub_conn_id_via_ip6h (sctp_conn, ip6_hdr);
1343  }
1344 
1345  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
1346  sctp_chunk_hdr = &full_hdr->common_hdr;
1347 
1348  sctp_implied_length =
1349  sctp_calculate_implied_length (ip4_hdr, ip6_hdr, is_ip4);
1350 
1351  u8 chunk_type = vnet_sctp_get_chunk_type (sctp_chunk_hdr);
1352  switch (chunk_type)
1353  {
1354  case SHUTDOWN:
1355  error0 =
1356  sctp_handle_shutdown (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1357  idx, b0, sctp_implied_length, &next0);
1358  break;
1359 
1360  case SHUTDOWN_ACK:
1361  error0 =
1362  sctp_handle_shutdown_ack (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1363  idx, b0, sctp_implied_length,
1364  &next0);
1365  break;
1366 
1367  case SHUTDOWN_COMPLETE:
1368  error0 =
1369  sctp_handle_shutdown_complete (sctp_hdr, sctp_chunk_hdr,
1370  sctp_conn, idx, b0,
1371  sctp_implied_length, &next0);
1372 
1373  sctp_connection_cleanup (sctp_conn);
1374  break;
1375 
1376  /*
1377  * DATA chunks can still be transmitted/received in the SHUTDOWN-PENDING
1378  * and SHUTDOWN-SENT states (as per RFC4960 Section 6)
1379  */
1380  case DATA:
1381  error0 =
1383  sctp_conn, idx, b0, &next0);
1384  break;
1385 
1386  case OPERATION_ERROR:
1387  error0 =
1388  sctp_handle_operation_err (sctp_hdr, sctp_conn, idx, b0,
1389  &next0);
1390  break;
1391 
1392  case COOKIE_ECHO: /* Cookie Received While Shutting Down */
1393  sctp_prepare_operation_error (sctp_conn, idx, b0,
1395  error0 = SCTP_ERROR_NONE;
1396  next0 = sctp_next_output (is_ip4);
1397  break;
1398  /* All UNEXPECTED scenarios (wrong chunk received per state-machine)
1399  * are handled by the input-dispatcher function using the table-lookup
1400  * hence we should never get to the "default" case below.
1401  */
1402  default:
1403  error0 = SCTP_ERROR_UNKOWN_CHUNK;
1404  next0 = sctp_next_drop (is_ip4);
1405  goto drop;
1406  }
1407 
1408  if (error0 != SCTP_ERROR_NONE)
1409  {
1410  clib_warning ("error while parsing chunk");
1411  sctp_connection_cleanup (sctp_conn);
1412  next0 = sctp_next_drop (is_ip4);
1413  goto drop;
1414  }
1415 
1416  drop:
1417  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1418  {
1419  sctp_trace =
1420  vlib_add_trace (vm, node, b0, sizeof (*sctp_trace));
1421 
1422  if (sctp_hdr != NULL)
1423  clib_memcpy (&sctp_trace->sctp_header, sctp_hdr,
1424  sizeof (sctp_trace->sctp_header));
1425 
1426  if (sctp_conn != NULL)
1427  clib_memcpy (&sctp_trace->sctp_connection, sctp_conn,
1428  sizeof (sctp_trace->sctp_connection));
1429  }
1430 
1431  b0->error = node->errors[error0];
1432 
1433  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1434  n_left_to_next, bi0, next0);
1435  }
1436 
1437  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1438  }
1439 
1440  return from_frame->n_vectors;
1441 
1442 }
1443 
1444 static uword
1446  vlib_frame_t * from_frame)
1447 {
1448  return sctp46_shutdown_phase_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1449 }
1450 
1451 static uword
1453  vlib_frame_t * from_frame)
1454 {
1455  return sctp46_shutdown_phase_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1456 }
1457 
1458 /* *INDENT-OFF* */
1460 {
1461  .function = sctp4_shutdown_phase,
1462  .name = "sctp4-shutdown",
1463  /* Takes a vector of packets. */
1464  .vector_size = sizeof (u32),
1465  .n_errors = SCTP_N_ERROR,
1466  .error_strings = sctp_error_strings,
1467  .n_next_nodes = SCTP_SHUTDOWN_PHASE_N_NEXT,
1468  .next_nodes =
1469  {
1470 #define _(s,n) [SCTP_SHUTDOWN_PHASE_NEXT_##s] = n,
1472 #undef _
1473  },
1474  .format_trace = format_sctp_rx_trace_short,
1475 };
1476 /* *INDENT-ON* */
1477 
1480 
1481 /* *INDENT-OFF* */
1483 {
1484  .function = sctp6_shutdown_phase,
1485  .name = "sctp6-shutdown",
1486  /* Takes a vector of packets. */
1487  .vector_size = sizeof (u32),
1488  .n_errors = SCTP_N_ERROR,
1489  .error_strings = sctp_error_strings,
1490  .n_next_nodes = SCTP_SHUTDOWN_PHASE_N_NEXT,
1491  .next_nodes =
1492  {
1493 #define _(s,n) [SCTP_SHUTDOWN_PHASE_NEXT_##s] = n,
1495 #undef _
1496  },
1497  .format_trace = format_sctp_rx_trace_short,
1498 };
1499 /* *INDENT-ON* */
1500 
1503 
1506 
1509 
1512  sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b0,
1513  u16 * next0)
1514 {
1515 
1516  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1517  if (sctp_conn->local_tag != sack_chunk->sctp_hdr.verification_tag)
1518  {
1519  return SCTP_ERROR_INVALID_TAG;
1520  }
1521 
1522  sctp_conn->sub_conn[idx].state = SCTP_SUBCONN_SACK_RECEIVED;
1523 
1524  sctp_conn->sub_conn[idx].last_seen = sctp_time_now ();
1525 
1526  /* Section 7.2.2; point (2) */
1527  if (sctp_conn->sub_conn[idx].cwnd > sctp_conn->sub_conn[idx].ssthresh)
1528  sctp_conn->sub_conn[idx].partially_acked_bytes =
1529  sctp_conn->next_tsn - sack_chunk->cumulative_tsn_ack;
1530 
1531  /* Section 7.2.2; point (5) */
1532  if (sctp_conn->next_tsn - sack_chunk->cumulative_tsn_ack == 0)
1533  sctp_conn->sub_conn[idx].partially_acked_bytes = 0;
1534 
1535  sctp_conn->last_unacked_tsn = sack_chunk->cumulative_tsn_ack;
1536 
1537  sctp_calculate_rto (sctp_conn, idx);
1538 
1539  sctp_timer_update (sctp_conn, idx, SCTP_TIMER_T3_RXTX,
1540  sctp_conn->sub_conn[idx].RTO);
1541 
1542  sctp_conn->sub_conn[idx].RTO_pending = 0;
1543 
1544  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1545 
1546  return SCTP_ERROR_NONE;
1547 }
1548 
1551  sctp_connection_t * sctp_conn, u8 idx,
1552  vlib_buffer_t * b0, u16 * next0)
1553 {
1554  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1555  if (sctp_conn->local_tag != sctp_hb_chunk->sctp_hdr.verification_tag)
1556  {
1557  return SCTP_ERROR_INVALID_TAG;
1558  }
1559 
1560  sctp_prepare_heartbeat_ack_chunk (sctp_conn, idx, b0);
1561 
1562  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].connection.is_ip4);
1563 
1564  return SCTP_ERROR_NONE;
1565 }
1566 
1569  sctp_connection_t * sctp_conn, u8 idx,
1570  vlib_buffer_t * b0, u16 * next0)
1571 {
1572  sctp_conn->sub_conn[idx].last_seen = sctp_time_now ();
1573 
1574  sctp_conn->sub_conn[idx].unacknowledged_hb -= 1;
1575 
1576  sctp_timer_update (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT,
1577  sctp_conn->sub_conn[idx].RTO);
1578 
1579  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1580 
1581  return SCTP_ERROR_NONE;
1582 }
1583 
1584 always_inline void
1585 sctp_node_inc_counter (vlib_main_t * vm, u32 sctp4_node, u32 sctp6_node,
1586  u8 is_ip4, u8 evt, u8 val)
1587 {
1588  if (PREDICT_TRUE (!val))
1589  return;
1590 
1591  if (is_ip4)
1592  vlib_node_increment_counter (vm, sctp4_node, evt, val);
1593  else
1594  vlib_node_increment_counter (vm, sctp6_node, evt, val);
1595 }
1596 
1599  vlib_node_runtime_t * node,
1600  vlib_frame_t * from_frame, int is_ip4)
1601 {
1602  u32 n_left_from, next_index, *from, *to_next;
1603  u32 my_thread_index = vm->thread_index;
1604 
1605  from = vlib_frame_vector_args (from_frame);
1606  n_left_from = from_frame->n_vectors;
1607 
1608  next_index = node->cached_next_index;
1609 
1610  while (n_left_from > 0)
1611  {
1612  u32 n_left_to_next;
1613 
1614  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1615 
1616  while (n_left_from > 0 && n_left_to_next > 0)
1617  {
1618  u32 bi0;
1619  vlib_buffer_t *b0;
1620  sctp_header_t *sctp_hdr = 0;
1621  ip4_header_t *ip4_hdr;
1622  ip6_header_t *ip6_hdr;
1623  sctp_connection_t *child_conn;
1624  sctp_connection_t *sctp_listener;
1625  u16 next0 = sctp_next_drop (is_ip4), error0 = SCTP_ERROR_ENQUEUED;
1626 
1627  bi0 = from[0];
1628  to_next[0] = bi0;
1629  from += 1;
1630  to_next += 1;
1631  n_left_from -= 1;
1632  n_left_to_next -= 1;
1633 
1634  b0 = vlib_get_buffer (vm, bi0);
1635  sctp_listener =
1636  sctp_listener_get (vnet_buffer (b0)->sctp.connection_index);
1637 
1638  if (is_ip4)
1639  {
1640  ip4_hdr = vlib_buffer_get_current (b0);
1641  sctp_hdr = ip4_next_header (ip4_hdr);
1642  }
1643  else
1644  {
1645  ip6_hdr = vlib_buffer_get_current (b0);
1646  sctp_hdr = ip6_next_header (ip6_hdr);
1647  }
1648 
1649  child_conn =
1650  sctp_lookup_connection (sctp_listener->sub_conn
1651  [SCTP_PRIMARY_PATH_IDX].c_fib_index, b0,
1652  my_thread_index, is_ip4);
1653 
1654  if (PREDICT_FALSE (child_conn->state != SCTP_STATE_CLOSED))
1655  {
1656  SCTP_DBG
1657  ("conn_index = %u: child_conn->state != SCTP_STATE_CLOSED.... STATE=%s",
1658  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
1659  connection.c_index,
1660  sctp_state_to_string (child_conn->state));
1661  error0 = SCTP_ERROR_CREATE_EXISTS;
1662  goto drop;
1663  }
1664 
1665  /* Create child session and send SYN-ACK */
1666  child_conn = sctp_connection_new (my_thread_index);
1667  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx =
1669  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_port =
1670  sctp_hdr->dst_port;
1671  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_port =
1672  sctp_hdr->src_port;
1673  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_is_ip4 = is_ip4;
1674  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto =
1675  sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto;
1676  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU =
1677  sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU;
1678  child_conn->state = SCTP_STATE_CLOSED;
1679  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.fib_index =
1680  sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].
1681  connection.fib_index;
1682 
1683  if (is_ip4)
1684  {
1685  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_ip4.as_u32 =
1686  ip4_hdr->dst_address.as_u32;
1687  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_ip4.as_u32 =
1688  ip4_hdr->src_address.as_u32;
1689  }
1690  else
1691  {
1692  clib_memcpy (&child_conn->
1693  sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_ip6,
1694  &ip6_hdr->dst_address, sizeof (ip6_address_t));
1695  clib_memcpy (&child_conn->
1696  sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_ip6,
1697  &ip6_hdr->src_address, sizeof (ip6_address_t));
1698  }
1699 
1700  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
1701  sctp_chunks_common_hdr_t *sctp_chunk_hdr = &full_hdr->common_hdr;
1702 
1703  u8 chunk_type = vnet_sctp_get_chunk_type (sctp_chunk_hdr);
1704  if (chunk_type != INIT && chunk_type != DATA
1705  && chunk_type != OPERATION_ERROR)
1706  {
1707  SCTP_DBG
1708  ("conn_index = %u: chunk_type != INIT... chunk_type=%s",
1709  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
1710  connection.c_index, sctp_chunk_to_string (chunk_type));
1711 
1712  error0 = SCTP_ERROR_UNKOWN_CHUNK;
1713  next0 = sctp_next_drop (is_ip4);
1714  goto drop;
1715  }
1716 
1717  u16 sctp_implied_length =
1718  sctp_calculate_implied_length (ip4_hdr, ip6_hdr, is_ip4);
1719 
1720  switch (chunk_type)
1721  {
1722  case INIT:
1723  sctp_connection_timers_init (child_conn);
1724 
1725  sctp_init_snd_vars (child_conn);
1726 
1727  sctp_init_cwnd (child_conn);
1728 
1729  error0 =
1730  sctp_handle_init (sctp_hdr, sctp_chunk_hdr, child_conn, b0,
1731  sctp_implied_length);
1732 
1733  if (error0 == SCTP_ERROR_NONE)
1734  {
1736  (&child_conn->
1737  sub_conn[SCTP_PRIMARY_PATH_IDX].connection,
1738  sctp_listener->
1739  sub_conn[SCTP_PRIMARY_PATH_IDX].c_s_index, 0))
1740  {
1741  clib_warning ("session accept fail");
1742  sctp_connection_cleanup (child_conn);
1743  error0 = SCTP_ERROR_CREATE_SESSION_FAIL;
1744  goto drop;
1745  }
1746  next0 = sctp_next_output (is_ip4);
1747  }
1748  break;
1749 
1750  /* Reception of a DATA chunk whilst in the CLOSED state is called
1751  * "Out of the Blue" packet and handling of the chunk needs special treatment
1752  * as per RFC4960 section 8.4
1753  */
1754  case DATA:
1755  break;
1756 
1757  case OPERATION_ERROR:
1758  error0 =
1759  sctp_handle_operation_err (sctp_hdr, child_conn,
1760  SCTP_PRIMARY_PATH_IDX, b0, &next0);
1761  break;
1762  }
1763 
1764  drop:
1765  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1766  {
1767  sctp_rx_trace_t *t0 =
1768  vlib_add_trace (vm, node, b0, sizeof (*t0));
1769  clib_memcpy (&t0->sctp_header, sctp_hdr,
1770  sizeof (t0->sctp_header));
1771  clib_memcpy (&t0->sctp_connection, sctp_listener,
1772  sizeof (t0->sctp_connection));
1773  }
1774 
1775  b0->error = node->errors[error0];
1776 
1777  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1778  n_left_to_next, bi0, next0);
1779  }
1780  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1781 
1782  }
1783  return from_frame->n_vectors;
1784 }
1785 
1786 static uword
1788  vlib_frame_t * from_frame)
1789 {
1790  return sctp46_listen_process_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1791 }
1792 
1793 static uword
1795  vlib_frame_t * from_frame)
1796 {
1797  return sctp46_listen_process_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1798 }
1799 
1802  vlib_frame_t * from_frame, int is_ip4)
1803 {
1804  u32 n_left_from, next_index, *from, *to_next;
1805  u32 my_thread_index = vm->thread_index, errors = 0;
1806 
1807  from = vlib_frame_vector_args (from_frame);
1808  n_left_from = from_frame->n_vectors;
1809 
1810  next_index = node->cached_next_index;
1811 
1812  while (n_left_from > 0)
1813  {
1814  u32 n_left_to_next;
1815 
1816  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1817 
1818  while (n_left_from > 0 && n_left_to_next > 0)
1819  {
1820  u32 bi0;
1821  vlib_buffer_t *b0;
1822  sctp_header_t *sctp_hdr = 0;
1823  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
1824  ip4_header_t *ip4_hdr = 0;
1825  ip6_header_t *ip6_hdr = 0;
1826  sctp_connection_t *sctp_conn;
1827  u16 error0 = SCTP_ERROR_ENQUEUED, next0 =
1829  u8 idx;
1830 
1831  bi0 = from[0];
1832  to_next[0] = bi0;
1833  from += 1;
1834  to_next += 1;
1835  n_left_from -= 1;
1836  n_left_to_next -= 1;
1837 
1838  b0 = vlib_get_buffer (vm, bi0);
1839  sctp_conn =
1840  sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
1841  my_thread_index);
1842 
1843  if (PREDICT_FALSE (sctp_conn == 0))
1844  {
1845  SCTP_DBG
1846  ("sctp_conn == NULL; return SCTP_ERROR_INVALID_CONNECTION");
1847  error0 = SCTP_ERROR_INVALID_CONNECTION;
1848  goto done;
1849  }
1850  if (is_ip4)
1851  {
1852  ip4_hdr = vlib_buffer_get_current (b0);
1853  sctp_hdr = ip4_next_header (ip4_hdr);
1854  idx = sctp_sub_conn_id_via_ip4h (sctp_conn, ip4_hdr);
1855  }
1856  else
1857  {
1858  ip6_hdr = vlib_buffer_get_current (b0);
1859  sctp_hdr = ip6_next_header (ip6_hdr);
1860  idx = sctp_sub_conn_id_via_ip6h (sctp_conn, ip6_hdr);
1861  }
1862 
1863  sctp_conn->sub_conn[idx].subconn_idx = idx;
1864 
1865  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
1866  sctp_chunk_hdr =
1867  (sctp_chunks_common_hdr_t *) (&full_hdr->common_hdr);
1868 
1869  u8 chunk_type = vnet_sctp_get_chunk_type (&full_hdr->common_hdr);
1870 
1871  switch (chunk_type)
1872  {
1873  case COOKIE_ECHO:
1874  error0 =
1875  sctp_handle_cookie_echo (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1876  idx, b0, &next0);
1877  break;
1878 
1879  case COOKIE_ACK:
1880  error0 =
1881  sctp_handle_cookie_ack (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1882  idx, b0, &next0);
1883  break;
1884 
1885  case SACK:
1886  error0 =
1888  sctp_conn, idx, b0, &next0);
1889  break;
1890 
1891  case HEARTBEAT:
1892  error0 =
1894  sctp_conn, idx, b0, &next0);
1895  break;
1896 
1897  case HEARTBEAT_ACK:
1898  error0 =
1900  sctp_conn, idx, b0, &next0);
1901  break;
1902 
1903  case DATA:
1904  error0 =
1906  sctp_conn, idx, b0, &next0);
1907  break;
1908 
1909  case OPERATION_ERROR:
1910  error0 =
1911  sctp_handle_operation_err (sctp_hdr, sctp_conn, idx, b0,
1912  &next0);
1913  break;
1914 
1915  /* All UNEXPECTED scenarios (wrong chunk received per state-machine)
1916  * are handled by the input-dispatcher function using the table-lookup
1917  * hence we should never get to the "default" case below.
1918  */
1919  default:
1920  error0 = SCTP_ERROR_UNKOWN_CHUNK;
1921  next0 = sctp_next_drop (is_ip4);
1922  goto done;
1923  }
1924 
1925  done:
1926  b0->error = node->errors[error0];
1927  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1928  {
1929  sctp_rx_trace_t *t0 =
1930  vlib_add_trace (vm, node, b0, sizeof (*t0));
1931  sctp_set_rx_trace_data (t0, sctp_conn, sctp_hdr, b0, is_ip4);
1932  }
1933 
1934  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1935  n_left_to_next, bi0, next0);
1936  }
1937 
1938  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1939  }
1940 
1942  my_thread_index);
1943 
1946  SCTP_ERROR_EVENT_FIFO_FULL, errors);
1947  sctp_flush_frame_to_output (vm, my_thread_index, is_ip4);
1948 
1949  return from_frame->n_vectors;
1950 }
1951 
1952 static uword
1954  vlib_frame_t * from_frame)
1955 {
1956  return sctp46_established_phase_inline (vm, node, from_frame,
1957  1 /* is_ip4 */ );
1958 }
1959 
1960 static uword
1962  vlib_frame_t * from_frame)
1963 {
1964  return sctp46_established_phase_inline (vm, node, from_frame,
1965  0 /* is_ip4 */ );
1966 }
1967 
1968 u8 *
1969 format_sctp_rx_trace (u8 * s, va_list * args)
1970 {
1971  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1972  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1973  sctp_rx_trace_t *t = va_arg (*args, sctp_rx_trace_t *);
1974  u32 indent = format_get_indent (s);
1975 
1976  s = format (s, "%U\n%U%U",
1977  format_sctp_header, &t->sctp_header, 128,
1978  format_white_space, indent,
1980 
1981  return s;
1982 }
1983 
1984 /* *INDENT-OFF* */
1986 {
1987  .function = sctp4_listen_phase,
1988  .name = "sctp4-listen",
1989  /* Takes a vector of packets. */
1990  .vector_size = sizeof (u32),
1991  .n_errors = SCTP_N_ERROR,
1992  .error_strings = sctp_error_strings,
1993  .n_next_nodes = SCTP_LISTEN_PHASE_N_NEXT,
1994  .next_nodes =
1995  {
1996 #define _(s,n) [SCTP_LISTEN_PHASE_NEXT_##s] = n,
1998 #undef _
1999  },
2000  .format_trace = format_sctp_rx_trace_short,
2001 };
2002 /* *INDENT-ON* */
2003 
2005 
2006 /* *INDENT-OFF* */
2008 {
2009  .function = sctp6_listen_phase,
2010  .name = "sctp6-listen",
2011  /* Takes a vector of packets. */
2012  .vector_size = sizeof (u32),
2013  .n_errors = SCTP_N_ERROR,
2014  .error_strings = sctp_error_strings,
2015  .n_next_nodes = SCTP_LISTEN_PHASE_N_NEXT,
2016  .next_nodes =
2017  {
2018 #define _(s,n) [SCTP_LISTEN_PHASE_NEXT_##s] = n,
2020 #undef _
2021  },
2022  .format_trace = format_sctp_rx_trace_short,
2023 };
2024 /* *INDENT-ON* */
2025 
2027 
2028 /* *INDENT-OFF* */
2030 {
2031  .function = sctp4_established_phase,
2032  .name = "sctp4-established",
2033  /* Takes a vector of packets. */
2034  .vector_size = sizeof (u32),
2035  .n_errors = SCTP_N_ERROR,
2036  .error_strings = sctp_error_strings,
2037  .n_next_nodes = SCTP_ESTABLISHED_PHASE_N_NEXT,
2038  .next_nodes =
2039  {
2040 #define _(s,n) [SCTP_ESTABLISHED_PHASE_NEXT_##s] = n,
2042 #undef _
2043  },
2044  .format_trace = format_sctp_rx_trace_short,
2045 };
2046 /* *INDENT-ON* */
2047 
2050 
2051 /* *INDENT-OFF* */
2053 {
2054  .function = sctp6_established_phase,
2055  .name = "sctp6-established",
2056  /* Takes a vector of packets. */
2057  .vector_size = sizeof (u32),
2058  .n_errors = SCTP_N_ERROR,
2059  .error_strings = sctp_error_strings,
2060  .n_next_nodes = SCTP_LISTEN_PHASE_N_NEXT,
2061  .next_nodes =
2062  {
2063 #define _(s,n) [SCTP_LISTEN_PHASE_NEXT_##s] = n,
2065 #undef _
2066  },
2067  .format_trace = format_sctp_rx_trace_short,
2068 };
2069 /* *INDENT-ON* */
2070 
2073 
2074 /*
2075  * This is the function executed first for the SCTP graph.
2076  * It takes care of doing the initial message parsing and
2077  * dispatch to the specialized function.
2078  */
2081  vlib_frame_t * from_frame, int is_ip4)
2082 {
2083  u32 n_left_from, next_index, *from, *to_next;
2084  u32 my_thread_index = vm->thread_index;
2085  u8 is_filtered;
2087 
2088  from = vlib_frame_vector_args (from_frame);
2089  n_left_from = from_frame->n_vectors;
2090  next_index = node->cached_next_index;
2091  sctp_set_time_now (my_thread_index);
2092 
2093  while (n_left_from > 0)
2094  {
2095  u32 n_left_to_next;
2096 
2097  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2098 
2099  while (n_left_from > 0 && n_left_to_next > 0)
2100  {
2101  int n_advance_bytes0, n_data_bytes0;
2102  u32 bi0, fib_index0;
2103  vlib_buffer_t *b0;
2104  sctp_header_t *sctp_hdr = 0;
2105  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
2106  sctp_connection_t *sctp_conn;
2107  transport_connection_t *trans_conn;
2108  ip4_header_t *ip4_hdr;
2109  ip6_header_t *ip6_hdr;
2110  u32 error0 = SCTP_ERROR_NO_LISTENER, next0 = SCTP_INPUT_NEXT_DROP;
2111 
2112  bi0 = from[0];
2113  to_next[0] = bi0;
2114  from += 1;
2115  to_next += 1;
2116  n_left_from -= 1;
2117  n_left_to_next -= 1;
2118 
2119  b0 = vlib_get_buffer (vm, bi0);
2120  vnet_buffer (b0)->sctp.flags = 0;
2121  fib_index0 = vnet_buffer (b0)->ip.fib_index;
2122 
2123  /* Checksum computed by ipx_local no need to compute again */
2124 
2125  if (is_ip4)
2126  {
2127  ip4_hdr = vlib_buffer_get_current (b0);
2128  sctp_hdr = ip4_next_header (ip4_hdr);
2129 
2130  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
2131  sctp_chunk_hdr = &full_hdr->common_hdr;
2132 
2133  n_advance_bytes0 =
2134  (ip4_header_bytes (ip4_hdr) +
2135  sizeof (sctp_payload_data_chunk_t));
2136  n_data_bytes0 =
2137  clib_net_to_host_u16 (ip4_hdr->length) - n_advance_bytes0;
2138 
2139  trans_conn = session_lookup_connection_wt4 (fib_index0,
2140  &ip4_hdr->dst_address,
2141  &ip4_hdr->src_address,
2142  sctp_hdr->dst_port,
2143  sctp_hdr->src_port,
2145  my_thread_index,
2146  &is_filtered);
2147  }
2148  else
2149  {
2150  ip6_hdr = vlib_buffer_get_current (b0);
2151  sctp_hdr = ip6_next_header (ip6_hdr);
2152 
2153  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
2154  sctp_chunk_hdr = &full_hdr->common_hdr;
2155 
2156  n_advance_bytes0 = sctp_header_bytes ();
2157  n_data_bytes0 =
2158  clib_net_to_host_u16 (ip6_hdr->payload_length) -
2159  n_advance_bytes0;
2160  n_advance_bytes0 += sizeof (ip6_hdr[0]);
2161 
2162  trans_conn = session_lookup_connection_wt6 (fib_index0,
2163  &ip6_hdr->dst_address,
2164  &ip6_hdr->src_address,
2165  sctp_hdr->dst_port,
2166  sctp_hdr->src_port,
2168  my_thread_index,
2169  &is_filtered);
2170  }
2171 
2172  /* Length check */
2173  if (PREDICT_FALSE (n_advance_bytes0 < 0))
2174  {
2175  error0 = SCTP_ERROR_LENGTH;
2176  goto done;
2177  }
2178 
2179  sctp_conn = sctp_get_connection_from_transport (trans_conn);
2180  vnet_sctp_common_hdr_params_net_to_host (sctp_chunk_hdr);
2181 
2182  u8 chunk_type = vnet_sctp_get_chunk_type (sctp_chunk_hdr);
2183  if (chunk_type >= UNKNOWN)
2184  {
2185  clib_warning
2186  ("Received an unrecognized chunk; sending back OPERATION_ERROR chunk");
2187 
2190 
2191  error0 = SCTP_ERROR_UNKOWN_CHUNK;
2192  next0 = sctp_next_output (is_ip4);
2193  goto done;
2194  }
2195 
2196  vnet_buffer (b0)->sctp.hdr_offset =
2197  (u8 *) sctp_hdr - (u8 *) vlib_buffer_get_current (b0);
2198 
2199  /* Session exists */
2200  if (PREDICT_TRUE (0 != sctp_conn))
2201  {
2202  /* Save connection index */
2203  vnet_buffer (b0)->sctp.connection_index = trans_conn->c_index;
2204  vnet_buffer (b0)->sctp.data_offset = n_advance_bytes0;
2205  vnet_buffer (b0)->sctp.data_len = n_data_bytes0;
2206 
2207  next0 = tm->dispatch_table[sctp_conn->state][chunk_type].next;
2208  error0 = tm->dispatch_table[sctp_conn->state][chunk_type].error;
2209 
2211  ("S_INDEX = %u, C_INDEX = %u, TRANS_CONN = %p, SCTP_CONN = %p, CURRENT_CONNECTION_STATE = %s,"
2212  "CHUNK_TYPE_RECEIVED = %s " "NEXT_PHASE = %s",
2213  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
2214  connection.s_index,
2215  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
2216  connection.c_index, trans_conn, sctp_conn,
2217  sctp_state_to_string (sctp_conn->state),
2218  sctp_chunk_to_string (chunk_type), phase_to_string (next0));
2219 
2220  if (chunk_type == DATA)
2221  SCTP_ADV_DBG ("n_advance_bytes0 = %u, n_data_bytes0 = %u",
2222  n_advance_bytes0, n_data_bytes0);
2223 
2224  }
2225  else
2226  {
2227  if (is_filtered)
2228  {
2229  next0 = SCTP_INPUT_NEXT_DROP;
2230  error0 = SCTP_ERROR_FILTERED;
2231  }
2232  else if ((is_ip4 && tm->punt_unknown4) ||
2233  (!is_ip4 && tm->punt_unknown6))
2234  {
2236  error0 = SCTP_ERROR_PUNT;
2237  }
2238  else
2239  {
2240  next0 = SCTP_INPUT_NEXT_DROP;
2241  error0 = SCTP_ERROR_NO_LISTENER;
2242  }
2243  SCTP_DBG_STATE_MACHINE ("sctp_conn == NULL, NEXT_PHASE = %s",
2244  phase_to_string (next0));
2245  sctp_conn = 0;
2246  }
2247 
2248  done:
2249  b0->error = error0 ? node->errors[error0] : 0;
2250 
2251  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2252  {
2253  sctp_rx_trace_t *t0 =
2254  vlib_add_trace (vm, node, b0, sizeof (*t0));
2255  sctp_set_rx_trace_data (t0, sctp_conn, sctp_hdr, b0, is_ip4);
2256  }
2257  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2258  n_left_to_next, bi0, next0);
2259  }
2260 
2261  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2262  }
2263  return from_frame->n_vectors;
2264 }
2265 
2266 static uword
2268  vlib_frame_t * from_frame)
2269 {
2270  return sctp46_input_dispatcher (vm, node, from_frame, 1 /* is_ip4 */ );
2271 }
2272 
2273 static uword
2275  vlib_frame_t * from_frame)
2276 {
2277  return sctp46_input_dispatcher (vm, node, from_frame, 0 /* is_ip4 */ );
2278 }
2279 
2280 /* *INDENT-OFF* */
2282 {
2283  .function = sctp4_input_dispatcher,
2284  .name = "sctp4-input",
2285  /* Takes a vector of packets. */
2286  .vector_size = sizeof (u32),
2287  .n_errors = SCTP_N_ERROR,
2288  .error_strings = sctp_error_strings,
2289  .n_next_nodes = SCTP_INPUT_N_NEXT,
2290  .next_nodes =
2291  {
2292 #define _(s,n) [SCTP_INPUT_NEXT_##s] = n,
2294 #undef _
2295  },
2296  .format_buffer = format_sctp_header,
2297  .format_trace = format_sctp_rx_trace,
2298 };
2299 /* *INDENT-ON* */
2300 
2302 
2303 /* *INDENT-OFF* */
2305 {
2306  .function = sctp6_input_dispatcher,
2307  .name = "sctp6-input",
2308  /* Takes a vector of packets. */
2309  .vector_size = sizeof (u32),
2310  .n_errors = SCTP_N_ERROR,
2311  .error_strings = sctp_error_strings,
2312  .n_next_nodes = SCTP_INPUT_N_NEXT,
2313  .next_nodes =
2314  {
2315 #define _(s,n) [SCTP_INPUT_NEXT_##s] = n,
2317 #undef _
2318  },
2319  .format_buffer = format_sctp_header,
2320  .format_trace = format_sctp_rx_trace,
2321 };
2322 /* *INDENT-ON* */
2323 
2325 
2328 
2329 static void
2331 {
2332  int i, j;
2333  for (i = 0; i < ARRAY_LEN (tm->dispatch_table); i++)
2334  for (j = 0; j < ARRAY_LEN (tm->dispatch_table[i]); j++)
2335  {
2336  tm->dispatch_table[i][j].next = SCTP_INPUT_NEXT_DROP;
2337  tm->dispatch_table[i][j].error = SCTP_ERROR_DISPATCH;
2338  }
2339 
2340 #define _(t,f,n,e) \
2341 do { \
2342  tm->dispatch_table[SCTP_STATE_##t][f].next = (n); \
2343  tm->dispatch_table[SCTP_STATE_##t][f].error = (e); \
2344 } while (0)
2345 
2346  /*
2347  * SCTP STATE-MACHINE states:
2348  *
2349  * _(CLOSED, "CLOSED") \
2350  * _(COOKIE_WAIT, "COOKIE_WAIT") \
2351  * _(COOKIE_ECHOED, "COOKIE_ECHOED") \
2352  * _(ESTABLISHED, "ESTABLISHED") \
2353  * _(SHUTDOWN_PENDING, "SHUTDOWN_PENDING") \
2354  * _(SHUTDOWN_SENT, "SHUTDOWN_SENT") \
2355  * _(SHUTDOWN_RECEIVED, "SHUTDOWN_RECEIVED") \
2356  * _(SHUTDOWN_ACK_SENT, "SHUTDOWN_ACK_SENT")
2357  */
2358  //_(CLOSED, DATA, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED DATA chunk which requires special handling */
2359  _(CLOSED, INIT, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE);
2360  _(CLOSED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2361  _(CLOSED, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2362  _(CLOSED, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2363  _(CLOSED, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2364  _(CLOSED, ABORT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE);
2365  _(CLOSED, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2366  _(CLOSED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2367  _(CLOSED, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2368  _(CLOSED, COOKIE_ECHO, SCTP_INPUT_NEXT_ESTABLISHED_PHASE, SCTP_ERROR_NONE);
2369  _(CLOSED, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2370  _(CLOSED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2371  _(CLOSED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2372  _(CLOSED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2373  _(CLOSED, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE);
2374 
2375  _(COOKIE_WAIT, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_NONE); /* UNEXPECTED DATA chunk which requires special handling */
2376  _(COOKIE_WAIT, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk which requires special handling */
2377  _(COOKIE_WAIT, INIT_ACK, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE);
2378  _(COOKIE_WAIT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2379  _(COOKIE_WAIT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2380  _(COOKIE_WAIT, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2381  _(COOKIE_WAIT, ABORT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE);
2382  _(COOKIE_WAIT, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2383  _(COOKIE_WAIT, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2384  _(COOKIE_WAIT, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2385  _(COOKIE_WAIT, COOKIE_ECHO, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_COOKIE_ECHO_VIOLATION); /* UNEXPECTED COOKIE_ECHO chunk */
2386  _(COOKIE_WAIT, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2387  _(COOKIE_WAIT, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2388  _(COOKIE_WAIT, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2389  _(COOKIE_WAIT, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2391  SCTP_ERROR_NONE);
2392 
2393  _(COOKIE_ECHOED, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_NONE);
2394  _(COOKIE_ECHOED, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk which requires special handling */
2395  _(COOKIE_ECHOED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2396  _(COOKIE_ECHOED, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2397  _(COOKIE_ECHOED, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2398  _(COOKIE_ECHOED, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2399  _(COOKIE_ECHOED, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2400  _(COOKIE_ECHOED, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2401  _(COOKIE_ECHOED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2402  _(COOKIE_ECHOED, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2403  _(COOKIE_ECHOED, COOKIE_ECHO, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_COOKIE_ECHO_VIOLATION); /* UNEXPECTED COOKIE_ECHO chunk */
2405  SCTP_ERROR_NONE);
2406  _(COOKIE_ECHOED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2407  _(COOKIE_ECHOED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2408  _(COOKIE_ECHOED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2410  SCTP_ERROR_NONE);
2411 
2412  _(ESTABLISHED, DATA, SCTP_INPUT_NEXT_ESTABLISHED_PHASE, SCTP_ERROR_NONE);
2413  _(ESTABLISHED, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2414  _(ESTABLISHED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2415  _(ESTABLISHED, SACK, SCTP_INPUT_NEXT_ESTABLISHED_PHASE, SCTP_ERROR_NONE);
2417  SCTP_ERROR_NONE);
2419  SCTP_ERROR_NONE);
2420  _(ESTABLISHED, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2421  _(ESTABLISHED, SHUTDOWN, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2422  _(ESTABLISHED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2423  _(ESTABLISHED, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2424  _(ESTABLISHED, COOKIE_ECHO, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_COOKIE_ECHO_VIOLATION); /* UNEXPECTED COOKIE_ECHO chunk */
2425  _(ESTABLISHED, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2426  _(ESTABLISHED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2427  _(ESTABLISHED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2428  _(ESTABLISHED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2430  SCTP_ERROR_NONE);
2431 
2432  _(SHUTDOWN_PENDING, DATA, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2433  _(SHUTDOWN_PENDING, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2434  _(SHUTDOWN_PENDING, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2435  _(SHUTDOWN_PENDING, SACK, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE);
2436  _(SHUTDOWN_PENDING, HEARTBEAT, SCTP_INPUT_NEXT_LISTEN_PHASE,
2437  SCTP_ERROR_NONE);
2438  _(SHUTDOWN_PENDING, HEARTBEAT_ACK, SCTP_INPUT_NEXT_LISTEN_PHASE,
2439  SCTP_ERROR_NONE);
2440  _(SHUTDOWN_PENDING, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2441  _(SHUTDOWN_PENDING, SHUTDOWN, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2442  SCTP_ERROR_NONE);
2443  _(SHUTDOWN_PENDING, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2444  _(SHUTDOWN_PENDING, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2445  _(SHUTDOWN_PENDING, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2446  SCTP_ERROR_NONE);
2447  _(SHUTDOWN_PENDING, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2448  _(SHUTDOWN_PENDING, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2449  _(SHUTDOWN_PENDING, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2450  _(SHUTDOWN_PENDING, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2451  _(SHUTDOWN_PENDING, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE,
2452  SCTP_ERROR_NONE);
2453 
2454  _(SHUTDOWN_SENT, DATA, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2455  _(SHUTDOWN_SENT, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2456  _(SHUTDOWN_SENT, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2457  _(SHUTDOWN_SENT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2458  _(SHUTDOWN_SENT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2459  _(SHUTDOWN_SENT, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2460  _(SHUTDOWN_SENT, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2461  _(SHUTDOWN_SENT, SHUTDOWN, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2462  _(SHUTDOWN_SENT, SHUTDOWN_ACK, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2463  SCTP_ERROR_NONE);
2464  _(SHUTDOWN_SENT, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2465  SCTP_ERROR_NONE);
2466  _(SHUTDOWN_SENT, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2467  _(SHUTDOWN_SENT, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2468  _(SHUTDOWN_SENT, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2469  _(SHUTDOWN_SENT, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2471  SCTP_ERROR_NONE);
2472 
2473  _(SHUTDOWN_RECEIVED, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_DATA_CHUNK_VIOLATION); /* UNEXPECTED DATA chunk */
2474  _(SHUTDOWN_RECEIVED, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2475  _(SHUTDOWN_RECEIVED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2476  _(SHUTDOWN_RECEIVED, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2477  _(SHUTDOWN_RECEIVED, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2478  _(SHUTDOWN_RECEIVED, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2479  _(SHUTDOWN_RECEIVED, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2480  _(SHUTDOWN_RECEIVED, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2481  _(SHUTDOWN_RECEIVED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2482  SCTP_ERROR_NONE);
2483  _(SHUTDOWN_RECEIVED, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2484  SCTP_ERROR_NONE);
2485  _(SHUTDOWN_RECEIVED, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2486  _(SHUTDOWN_RECEIVED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2487  _(SHUTDOWN_RECEIVED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2488  _(SHUTDOWN_RECEIVED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2489  _(SHUTDOWN_RECEIVED, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE,
2490  SCTP_ERROR_NONE);
2491 
2492  _(SHUTDOWN_ACK_SENT, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_DATA_CHUNK_VIOLATION); /* UNEXPECTED DATA chunk */
2493  _(SHUTDOWN_ACK_SENT, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk */
2494  _(SHUTDOWN_ACK_SENT, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2495  _(SHUTDOWN_ACK_SENT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2496  _(SHUTDOWN_ACK_SENT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2497  _(SHUTDOWN_ACK_SENT, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2498  _(SHUTDOWN_ACK_SENT, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2499  _(SHUTDOWN_ACK_SENT, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2500  _(SHUTDOWN_ACK_SENT, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2501  _(SHUTDOWN_ACK_SENT, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2502  SCTP_ERROR_NONE);
2503  _(SHUTDOWN_ACK_SENT, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2504  _(SHUTDOWN_ACK_SENT, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2505  _(SHUTDOWN_ACK_SENT, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2506  _(SHUTDOWN_ACK_SENT, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2507  SCTP_ERROR_NONE);
2508  _(SHUTDOWN_ACK_SENT, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE,
2509  SCTP_ERROR_NONE);
2510 
2511  /* TODO: Handle COOKIE ECHO when a TCB Exists */
2512 
2513 #undef _
2514 }
2515 
2516 clib_error_t *
2518 {
2519  clib_error_t *error = 0;
2521 
2522  if ((error = vlib_call_init_function (vm, sctp_init)))
2523  return error;
2524 
2525  /* Initialize dispatch table. */
2527 
2528  return error;
2529 }
2530 
2532 
2533 /*
2534  * fd.io coding-style-patch-verification: ON
2535  *
2536  * Local Variables:
2537  * eval: (c-set-style "gnu")
2538  * End:
2539  */
void sctp_flush_frame_to_output(vlib_main_t *vm, u8 thread_index, u8 is_ip4)
Flush tx frame populated by retransmits and timer pops.
Definition: sctp_output.c:54
static u16 sctp_handle_shutdown_complete(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 sctp_implied_length, u16 *next0)
Definition: sctp_input.c:1247
u16 sctp_check_outstanding_data_chunks(sctp_connection_t *sctp_conn)
Definition: sctp.c:543
static sctp_connection_t * sctp_lookup_connection(u32 fib_index, vlib_buffer_t *b, u8 thread_index, u8 is_ip4)
Lookup transport connection.
Definition: sctp_input.c:146
struct _sctp_main sctp_main_t
static void sctp_timer_set(sctp_connection_t *tc, u8 conn_idx, u8 timer_id, u32 interval)
Definition: sctp.h:594
void sctp_connection_timers_init(sctp_connection_t *sctp_conn)
Initialize all connection timers as invalid.
Definition: sctp.c:133
static void sctp_is_connection_gapping(sctp_connection_t *sctp_conn, u32 tsn, u8 *gapping)
Definition: sctp_input.c:754
static u8 sctp_sub_conn_id_via_ip4h(sctp_connection_t *sctp_conn, ip4_header_t *ip4h)
Definition: sctp.h:807
#define SCTP_DBG(_fmt, _args...)
Definition: sctp_debug.h:38
void sctp_init_snd_vars(sctp_connection_t *sctp_conn)
Initialize connection send variables.
Definition: sctp.c:246
#define CLIB_UNUSED(x)
Definition: clib.h:79
static u16 sctp_handle_init(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, vlib_buffer_t *b0, u16 sctp_implied_length)
Definition: sctp_input.c:316
static u16 sctp_is_valid_init_ack(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, vlib_buffer_t *b0, u16 sctp_implied_length)
Definition: sctp_input.c:464
ip4_address_t src_address
Definition: ip4_packet.h:164
static u8 sctp_lookup_is_valid(transport_connection_t *trans_conn, sctp_header_t *sctp_hdr)
Definition: sctp_input.c:126
struct _transport_connection transport_connection_t
enum _sctp_listen_phase_next sctp_listen_phase_next_t
static uword sctp46_established_phase_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
Definition: sctp_input.c:1801
#define COOKIE_RECEIVED_WHILE_SHUTTING_DOWN
Definition: sctp_packet.h:1007
#define PREDICT_TRUE(x)
Definition: clib.h:106
u64 as_u64[2]
Definition: ip6_packet.h:51
static int ip4_header_bytes(ip4_header_t *i)
Definition: ip4_packet.h:227
sctp_header_t sctp_header
Definition: sctp_input.c:230
#define NULL
Definition: clib.h:55
sctp_chunks_common_hdr_t chunk_hdr
Definition: sctp_packet.h:591
static u8 vnet_sctp_get_ebit(sctp_chunks_common_hdr_t *h)
Definition: sctp_packet.h:329
enum _sctp_rcv_phase_next sctp_rcv_phase_next_t
u32 thread_index
Definition: main.h:176
#define SCTP_ADV_DBG(_fmt, _args...)
Definition: sctp_debug.h:45
static u16 sctp_handle_cookie_echo(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 *next0)
Definition: sctp_input.c:849
sctp_chunks_common_hdr_t chunk_hdr
Definition: sctp_packet.h:412
int i
#define SCTP_HOSTNAME_ADDRESS_TYPE
Definition: sctp_packet.h:784
void sctp_prepare_cookie_ack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Definition: sctp_output.c:526
static u32 format_get_indent(u8 *s)
Definition: format.h:72
static u32 sctp_set_time_now(u32 thread_index)
Definition: sctp.h:586
void sctp_prepare_abort_for_collision(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, ip4_address_t *ip4_addr, ip6_address_t *ip6_addr)
Convert buffer to ABORT.
Definition: sctp_output.c:688
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static u16 sctp_handle_shutdown_ack(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 sctp_implied_length, u16 *next0)
Definition: sctp_input.c:1211
static void sctp_calculate_rto(sctp_connection_t *sctp_conn, u8 conn_idx)
Definition: sctp.h:677
int session_enqueue_stream_connection(transport_connection_t *tc, vlib_buffer_t *b, u32 offset, u8 queue_event, u8 is_in_order)
Definition: session.c:304
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:415
static char * sctp_error_strings[]
Definition: sctp_input.c:22
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
ip6_address_t src_address
Definition: ip6_packet.h:342
static sctp_main_t * vnet_get_sctp_main()
Definition: sctp.h:542
vlib_node_registration_t sctp4_established_phase_node
(constructor) VLIB_REGISTER_NODE (sctp4_established_phase_node)
Definition: sctp_input.c:1507
static void sctp_dispatch_table_init(sctp_main_t *tm)
Definition: sctp_input.c:2330
enum _sctp_input_next sctp_input_next_t
sctp_chunks_common_hdr_t chunk_hdr
Definition: sctp_packet.h:1411
enum _sctp_shutdown_phase_next sctp_shutdown_phase_next_t
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static void sctp_init_cwnd(sctp_connection_t *sctp_conn)
Definition: sctp.h:901
void stream_session_accept_notify(transport_connection_t *tc)
Definition: session.c:687
#define always_inline
Definition: clib.h:92
ip4_address_t dst_address
Definition: ip4_packet.h:164
void sctp_prepare_initack_chunk_for_collision(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, ip4_address_t *ip4_addr, ip6_address_t *ip6_addr)
Convert buffer to INIT-ACK.
Definition: sctp_output.c:729
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
#define FQDN_MAX_LENGTH
Definition: sctp_packet.h:914
vlib_node_registration_t sctp6_input_node
(constructor) VLIB_REGISTER_NODE (sctp6_input_node)
Definition: sctp_input.c:2304
#define STALE_COOKIE_ERROR
Definition: sctp_packet.h:1000
#define UNRECOGNIZED_CHUNK_TYPE
Definition: sctp_packet.h:1003
vlib_node_registration_t sctp4_input_node
(constructor) VLIB_REGISTER_NODE (sctp4_input_node)
Definition: sctp_input.c:2281
static void vnet_sctp_common_hdr_params_net_to_host(sctp_chunks_common_hdr_t *h)
Definition: sctp_packet.h:290
static void * ip4_next_header(ip4_header_t *i)
Definition: ip4_packet.h:233
void sctp_prepare_sack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to SACK.
Definition: sctp_output.c:1123
static int sctp_half_open_connection_cleanup(sctp_connection_t *tc)
Try to cleanup half-open connection.
Definition: sctp.h:632
sctp_connection_t * sctp_connection_new(u8 thread_index)
Definition: sctp.c:417
#define vlib_call_init_function(vm, x)
Definition: init.h:162
#define SCTP_STATE_COOKIE_TYPE
Definition: sctp_packet.h:780
static uword sctp46_input_dispatcher(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
Definition: sctp_input.c:2080
#define SCTP_UNRECOGNIZED_TYPE
Definition: sctp_packet.h:781
vlib_node_registration_t sctp4_shutdown_phase_node
(constructor) VLIB_REGISTER_NODE (sctp4_shutdown_phase_node)
Definition: sctp_input.c:1167
static u16 sctp_handle_shutdown(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 sctp_implied_length, u16 *next0)
Definition: sctp_input.c:1171
ip6_address_t address
Definition: sctp_packet.h:842
void sctp_prepare_heartbeat_ack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to HEARTBEAT_ACK.
Definition: sctp_output.c:1161
static void sctp_timer_reset(sctp_connection_t *tc, u8 conn_idx, u8 timer_id)
Definition: sctp.h:609
static u16 sctp_calculate_implied_length(ip4_header_t *ip4_hdr, ip6_header_t *ip6_hdr, int is_ip4)
Definition: sctp_input.c:260
static sctp_connection_t * sctp_get_connection_from_transport(transport_connection_t *tconn)
Definition: sctp.h:650
static u32 sctp_time_now(void)
Definition: sctp.h:669
VLIB_NODE_FUNCTION_MULTIARCH(sctp4_rcv_phase_node, sctp4_rcv_phase)
sctp_init_chunk_t sctp_init_ack_chunk_t
Definition: sctp_packet.h:690
vlib_node_registration_t sctp6_listen_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_listen_phase_node)
Definition: sctp_input.c:1505
vlib_node_registration_t sctp4_rcv_phase_node
(constructor) VLIB_REGISTER_NODE (sctp4_rcv_phase_node)
Definition: sctp_input.c:1124
vlib_node_registration_t sctp6_shutdown_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_shutdown_phase_node)
Definition: sctp_input.c:1168
static u8 vnet_sctp_get_bbit(sctp_chunks_common_hdr_t *h)
Definition: sctp_packet.h:316
u8 sctp_sub_connection_add_ip4(vlib_main_t *vm, ip4_address_t *lcl_addr, ip4_address_t *rmt_addr)
Definition: sctp.c:286
static u8 sctp_is_bundling(u16 sctp_implied_length, sctp_chunks_common_hdr_t *sctp_common_hdr)
Definition: sctp_input.c:276
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:209
static uword sctp6_established_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1961
sctp_header_t sctp_hdr
Definition: sctp_packet.h:1253
static int sctp_session_enqueue_data(sctp_connection_t *sctp_conn, vlib_buffer_t *b, u16 data_len, u8 conn_idx)
Enqueue data for delivery to application.
Definition: sctp_input.c:665
static uword sctp46_rcv_phase_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
Definition: sctp_input.c:925
#define PREDICT_FALSE(x)
Definition: clib.h:105
static u16 sctp_handle_heartbeat(sctp_hb_req_chunk_t *sctp_hb_chunk, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 *next0)
Definition: sctp_input.c:1550
struct _sctp_connection sctp_connection_t
#define SCTP_IPV6_ADDRESS_TYPE
Definition: sctp_packet.h:778
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
int stream_session_accept(transport_connection_t *tc, u32 listener_index, u8 notify)
Accept a stream session.
Definition: session.c:771
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:364
#define MAX_SCTP_CONNECTIONS
Definition: sctp.h:80
u32 verification_tag
Definition: sctp_packet.h:73
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:130
static char * sctp_state_to_string(u8 state)
Definition: sctp.h:365
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1166
static u16 sctp_handle_init_ack(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 sctp_implied_length)
Definition: sctp_input.c:488
static u8 vnet_sctp_get_chunk_type(sctp_chunks_common_hdr_t *h)
Definition: sctp_packet.h:342
static uword sctp4_listen_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1787
#define MAX_ENQUEABLE_SACKS
Definition: sctp.h:178
u8 * format_sctp_rx_trace_short(u8 *s, va_list *args)
Definition: sctp_input.c:1109
sctp_chunks_common_hdr_t common_hdr
Definition: sctp_packet.h:261
ip4_address_t address
Definition: sctp_packet.h:804
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
void sctp_set_rx_trace_data(sctp_rx_trace_t *rx_trace, sctp_connection_t *sctp_conn, sctp_header_t *sctp_hdr, vlib_buffer_t *b0, u8 is_ip4)
Definition: sctp_input.c:241
u16 n_vectors
Definition: node.h:344
vlib_main_t * vm
Definition: buffer.c:294
u8 * format_sctp_connection(u8 *s, va_list *args)
Definition: sctp.c:226
static uword sctp4_input_dispatcher(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:2267
#define clib_warning(format, args...)
Definition: error.h:59
#define clib_memcpy(a, b, c)
Definition: string.h:75
#define ARRAY_LEN(x)
Definition: clib.h:59
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:454
#define foreach_sctp4_input_next
Definition: sctp_input.c:108
static u32 sctp_header_bytes()
Definition: sctp.h:644
clib_error_t * sctp_input_init(vlib_main_t *vm)
Definition: sctp_input.c:2517
#define sctp_next_drop(is_ip4)
Definition: sctp_input.c:237
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:369
char hostname[FQDN_MAX_LENGTH]
Definition: sctp_packet.h:945
static u16 sctp_handle_heartbeat_ack(sctp_hb_ack_chunk_t *sctp_hb_ack_chunk, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 *next0)
Definition: sctp_input.c:1568
void stream_session_disconnect_notify(transport_connection_t *tc)
Notification from transport that connection is being closed.
Definition: session.c:705
void sctp_send_shutdown_complete(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0)
Definition: sctp_output.c:1297
vlib_node_registration_t sctp6_established_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_established_phase_node)
Definition: sctp_input.c:1508
vlib_node_registration_t sctp6_init_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_init_phase_node)
Definition: sctp_input.c:1146
static uword sctp6_rcv_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1102
transport_connection_t * session_lookup_connection_wt4(u32 fib_index, ip4_address_t *lcl, ip4_address_t *rmt, u16 lcl_port, u16 rmt_port, u8 proto, u32 thread_index, u8 *is_filtered)
Lookup connection with ip4 and transport layer information.
void sctp_prepare_operation_error(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u8 err_cause)
Convert buffer to ERROR.
Definition: sctp_output.c:643
sctp_header_t sctp_hdr
Definition: sctp_packet.h:590
static sctp_connection_t * sctp_half_open_connection_get(u32 conn_index)
Definition: sctp.h:558
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:456
static u16 sctp_handle_operation_err(sctp_header_t *sctp_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u16 *next0)
Definition: sctp_input.c:286
#define ASSERT(truth)
sctp_opt_params_hdr_t param_hdr
Definition: sctp_packet.h:1313
unsigned int u32
Definition: types.h:88
static int sctp_session_enqueue_data_ooo(sctp_connection_t *sctp_conn, vlib_buffer_t *b, u16 data_len, u8 conn_idx)
Enqueue data out-of-order for delivery to application.
Definition: sctp_input.c:610
#define SCTP_PRIMARY_PATH_IDX
Definition: sctp.h:81
static uword sctp46_shutdown_phase_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
Definition: sctp_input.c:1280
#define SCTP_CONN_TRACKING_DBG(_fmt, _args...)
Definition: sctp_debug.h:66
sctp_connection_t sctp_connection
Definition: sctp_input.c:231
format_function_t format_sctp_header
Definition: format.h:102
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:222
sctp_chunks_common_hdr_t chunk_hdr
Definition: sctp_packet.h:1452
void sctp_connection_cleanup(sctp_connection_t *sctp_conn)
Cleans up connection state.
Definition: sctp.c:513
transport_connection_t * session_lookup_connection_wt6(u32 fib_index, ip6_address_t *lcl, ip6_address_t *rmt, u16 lcl_port, u16 rmt_port, u8 proto, u32 thread_index, u8 *is_filtered)
Lookup connection with ip6 and transport layer information.
enum _sctp_established_phase_next sctp_established_phase_next_t
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
void sctp_prepare_initack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, ip4_address_t *ip4_addr, u8 add_ip4, ip6_address_t *ip6_addr, u8 add_ip6)
Convert buffer to INIT-ACK.
Definition: sctp_output.c:869
void sctp_prepare_cookie_echo_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u8 reuse_buffer)
Definition: sctp_output.c:560
u64 uword
Definition: types.h:112
static void sctp_timer_update(sctp_connection_t *tc, u8 conn_idx, u8 timer_id, u32 interval)
Definition: sctp.h:730
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
static u16 sctp_handle_sack(sctp_selective_ack_chunk_t *sack_chunk, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 *next0)
Definition: sctp_input.c:1511
struct _vlib_node_registration vlib_node_registration_t
static sctp_connection_t * sctp_connection_get(u32 conn_index, u32 thread_index)
Definition: sctp.h:755
unsigned short u16
Definition: types.h:57
u16 payload_length
Definition: ip6_packet.h:333
#define SCTP_IPV4_ADDRESS_TYPE
Definition: sctp_packet.h:776
unsigned char u8
Definition: types.h:56
static uword sctp46_listen_process_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
Definition: sctp_input.c:1598
static u16 sctp_handle_data(sctp_payload_data_chunk_t *sctp_data_chunk, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u16 *next0)
Definition: sctp_input.c:770
sctp_err_cause_param_t err_causes[]
Definition: sctp_packet.h:1340
static uword sctp4_shutdown_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1445
static u16 sctp_handle_cookie_ack(sctp_header_t *sctp_hdr, sctp_chunks_common_hdr_t *sctp_chunk_hdr, sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0, u16 *next0)
Definition: sctp_input.c:895
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
static uword sctp4_rcv_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1095
#define sctp_next_output(is_ip4)
Definition: sctp_input.c:234
static u8 sctp_is_sack_delayable(sctp_connection_t *sctp_conn, u8 idx, u8 is_gapping)
Definition: sctp_input.c:717
clib_error_t * sctp_init(vlib_main_t *vm)
Definition: sctp.c:955
sctp_chunks_common_hdr_t chunk_hdr
Definition: sctp_packet.h:771
static uword sctp4_established_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1953
#define vnet_buffer(b)
Definition: buffer.h:372
int session_manager_flush_enqueue_events(u8 transport_proto, u32 thread_index)
Flushes queue of sessions that are to be notified of new data enqueued events.
Definition: session.c:510
static u16 vnet_sctp_get_chunk_length(sctp_chunks_common_hdr_t *h)
Definition: sctp_packet.h:355
static char * sctp_chunk_to_string(u8 type)
Definition: sctp.h:390
int session_stream_connect_notify(transport_connection_t *tc, u8 is_fail)
Definition: session.c:549
static u8 sctp_sub_conn_id_via_ip6h(sctp_connection_t *sctp_conn, ip6_header_t *ip6h)
Definition: sctp.h:785
u8 data[0]
Packet data.
Definition: buffer.h:179
u8 * format_sctp_rx_trace(u8 *s, va_list *args)
Definition: sctp_input.c:1969
#define SCTP_COOKIE_PRESERVATIVE_TYPE
Definition: sctp_packet.h:782
static sctp_connection_t * sctp_listener_get(u32 tli)
Definition: sctp.h:747
vlib_node_registration_t sctp4_listen_phase_node
(constructor) VLIB_REGISTER_NODE (sctp4_listen_phase_node)
Definition: sctp_input.c:1504
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:111
#define foreach_sctp6_input_next
Definition: sctp_input.c:117
static sctp_header_t * sctp_buffer_hdr(vlib_buffer_t *b)
Definition: sctp.h:548
u8 sctp_sub_connection_add_ip6(vlib_main_t *vm, ip6_address_t *lcl_addr, ip6_address_t *rmt_addr)
Definition: sctp.c:343
enum _sctp_state_next sctp_state_next_t
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
#define foreach_sctp_state_next
Definition: sctp_input.c:29
static void sctp_node_inc_counter(vlib_main_t *vm, u32 sctp4_node, u32 sctp6_node, u8 is_ip4, u8 evt, u8 val)
Definition: sctp_input.c:1585
#define SCTP_DBG_STATE_MACHINE(_fmt, _args...)
Definition: sctp_debug.h:31
static uword sctp6_shutdown_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1452
static uword sctp6_listen_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1794
static uword sctp6_input_dispatcher(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:2274
void sctp_send_shutdown_ack(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Definition: sctp_output.c:1106
format_function_t format_sctp_state
Definition: sctp.h:302
ip6_address_t dst_address
Definition: ip6_packet.h:342
char * phase_to_string(u8 phase)
Definition: sctp_input.c:88
#define SCTP_SUPPORTED_ADDRESS_TYPES
Definition: sctp_packet.h:785