FD.io VPP  v18.07.1-19-g511ce25
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  u64 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  u64 creation_time =
868  clib_net_to_host_u64 (cookie_echo->cookie.creation_time);
869  u64 cookie_lifespan =
870  clib_net_to_host_u32 (cookie_echo->cookie.cookie_lifespan);
871 
872  if (now > creation_time + cookie_lifespan)
873  {
874  SCTP_DBG ("now (%u) > creation_time (%u) + cookie_lifespan (%u)",
875  now, creation_time, cookie_lifespan);
876  return SCTP_ERROR_COOKIE_ECHO_VIOLATION;
877  }
878 
879  sctp_prepare_cookie_ack_chunk (sctp_conn, idx, b0);
880 
881  /* Change state */
882  sctp_conn->state = SCTP_STATE_ESTABLISHED;
883  sctp_conn->sub_conn[idx].state = SCTP_SUBCONN_STATE_UP;
884  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
885 
886  sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT,
887  sctp_conn->sub_conn[idx].RTO);
888 
889  stream_session_accept_notify (&sctp_conn->sub_conn[idx].connection);
890 
891  return SCTP_ERROR_NONE;
892 
893 }
894 
897  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
898  sctp_connection_t * sctp_conn, u8 idx,
899  vlib_buffer_t * b0, u16 * next0)
900 {
901  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
902  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
903  {
904  return SCTP_ERROR_INVALID_TAG;
905  }
906 
907  sctp_calculate_rto (sctp_conn, idx);
908 
909  sctp_timer_reset (sctp_conn, idx, SCTP_TIMER_T1_COOKIE);
910  /* Change state */
911  sctp_conn->state = SCTP_STATE_ESTABLISHED;
912  sctp_conn->sub_conn[idx].state = SCTP_SUBCONN_STATE_UP;
913 
914  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
915 
916  sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT,
917  sctp_conn->sub_conn[idx].RTO);
918 
919  stream_session_accept_notify (&sctp_conn->sub_conn[idx].connection);
920 
921  return SCTP_ERROR_NONE;
922 
923 }
924 
927  vlib_frame_t * from_frame, int is_ip4)
928 {
930 
931  u32 n_left_from, next_index, *from, *to_next;
932  u32 my_thread_index = vm->thread_index;
933 
934  from = vlib_frame_vector_args (from_frame);
935  n_left_from = from_frame->n_vectors;
936 
937  next_index = node->cached_next_index;
938 
939  while (n_left_from > 0)
940  {
941  u32 n_left_to_next;
942 
943  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
944 
945  while (n_left_from > 0 && n_left_to_next > 0)
946  {
947  u32 bi0;
948  vlib_buffer_t *b0;
949  sctp_header_t *sctp_hdr = 0;
950  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
951  ip4_header_t *ip4_hdr = 0;
952  ip6_header_t *ip6_hdr = 0;
953  sctp_connection_t *sctp_conn, *new_sctp_conn;
954  u16 sctp_implied_length = 0;
955  u16 error0 = SCTP_ERROR_NONE, next0 = sctp_next_drop (is_ip4);
956  u8 idx;
957 
958  bi0 = from[0];
959  to_next[0] = bi0;
960  from += 1;
961  to_next += 1;
962  n_left_from -= 1;
963  n_left_to_next -= 1;
964 
965  b0 = vlib_get_buffer (vm, bi0);
966 
967  /* If we are in SCTP_COOKIE_WAIT_STATE then the connection
968  * will come from the half-open connections pool.
969  */
970  sctp_conn =
972  sctp.connection_index);
973 
974  if (PREDICT_FALSE (sctp_conn == 0))
975  {
977  ("sctp_conn == NULL; return SCTP_ERROR_INVALID_CONNECTION");
978  error0 = SCTP_ERROR_INVALID_CONNECTION;
979  goto drop;
980  }
981  if (is_ip4)
982  {
983  ip4_hdr = vlib_buffer_get_current (b0);
984  sctp_hdr = ip4_next_header (ip4_hdr);
985  idx = sctp_sub_conn_id_via_ip4h (sctp_conn, ip4_hdr);
986  }
987  else
988  {
989  ip6_hdr = vlib_buffer_get_current (b0);
990  sctp_hdr = ip6_next_header (ip6_hdr);
991  idx = sctp_sub_conn_id_via_ip6h (sctp_conn, ip6_hdr);
992  }
993 
994  sctp_conn->sub_conn[idx].subconn_idx = idx;
995  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
996 
997  sctp_chunk_hdr =
998  (sctp_chunks_common_hdr_t *) (&full_hdr->common_hdr);
999 
1000  sctp_implied_length =
1001  sctp_calculate_implied_length (ip4_hdr, ip6_hdr, is_ip4);
1002 
1003  u8 chunk_type = vnet_sctp_get_chunk_type (&full_hdr->common_hdr);
1004 
1005  switch (chunk_type)
1006  {
1007  case INIT_ACK:
1008  error0 =
1009  sctp_is_valid_init_ack (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1010  b0, sctp_implied_length);
1011 
1012  if (error0 == SCTP_ERROR_NONE)
1013  {
1014  pool_get (tm->connections[my_thread_index], new_sctp_conn);
1015  clib_memcpy (new_sctp_conn, sctp_conn,
1016  sizeof (*new_sctp_conn));
1017  new_sctp_conn->sub_conn[idx].c_c_index =
1018  new_sctp_conn - tm->connections[my_thread_index];
1019  new_sctp_conn->sub_conn[idx].c_thread_index =
1020  my_thread_index;
1021  new_sctp_conn->sub_conn[idx].PMTU =
1022  sctp_conn->sub_conn[idx].PMTU;
1023  new_sctp_conn->sub_conn[idx].subconn_idx = idx;
1024 
1025  if (sctp_half_open_connection_cleanup (sctp_conn))
1026  {
1027  SCTP_DBG
1028  ("Cannot cleanup half-open connection; not the owning thread");
1029  }
1030 
1031  sctp_connection_timers_init (new_sctp_conn);
1032 
1033  sctp_init_cwnd (new_sctp_conn);
1034 
1035  error0 =
1036  sctp_handle_init_ack (sctp_hdr, sctp_chunk_hdr,
1037  new_sctp_conn, idx, b0,
1038  sctp_implied_length);
1039 
1041  (&new_sctp_conn->sub_conn[idx].connection, 0))
1042  {
1043  SCTP_DBG
1044  ("conn_index = %u: session_stream_connect_notify error; cleaning up connection",
1045  new_sctp_conn->sub_conn[idx].connection.c_index);
1046  sctp_connection_cleanup (new_sctp_conn);
1047  goto drop;
1048  }
1049  next0 = sctp_next_output (is_ip4);
1050  }
1051  break;
1052 
1053  case OPERATION_ERROR:
1054  error0 =
1055  sctp_handle_operation_err (sctp_hdr, sctp_conn, idx, b0,
1056  &next0);
1057  break;
1058 
1059  /* All UNEXPECTED scenarios (wrong chunk received per state-machine)
1060  * are handled by the input-dispatcher function using the table-lookup
1061  * hence we should never get to the "default" case below.
1062  */
1063  default:
1064  error0 = SCTP_ERROR_UNKNOWN_CHUNK;
1065  next0 = sctp_next_drop (is_ip4);
1066  goto drop;
1067  }
1068 
1069  if (error0 != SCTP_ERROR_NONE)
1070  {
1071  clib_warning ("error while parsing chunk");
1072  sctp_connection_cleanup (sctp_conn);
1073  next0 = sctp_next_drop (is_ip4);
1074  goto drop;
1075  }
1076 
1077  drop:
1078  b0->error = node->errors[error0];
1079  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1080  {
1081  sctp_rx_trace_t *t0 =
1082  vlib_add_trace (vm, node, b0, sizeof (*t0));
1083  sctp_set_rx_trace_data (t0, sctp_conn, sctp_hdr, b0, is_ip4);
1084  }
1085 
1086  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1087  n_left_to_next, bi0, next0);
1088  }
1089 
1090  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1091  }
1092  return from_frame->n_vectors;
1093 }
1094 
1095 static uword
1097  vlib_frame_t * from_frame)
1098 {
1099  return sctp46_rcv_phase_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1100 }
1101 
1102 static uword
1104  vlib_frame_t * from_frame)
1105 {
1106  return sctp46_rcv_phase_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1107 }
1108 
1109 u8 *
1110 format_sctp_rx_trace_short (u8 * s, va_list * args)
1111 {
1112  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1113  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1114  sctp_rx_trace_t *t = va_arg (*args, sctp_rx_trace_t *);
1115 
1116  s = format (s, "%d -> %d (%U)",
1117  clib_net_to_host_u16 (t->sctp_header.src_port),
1118  clib_net_to_host_u16 (t->sctp_header.dst_port),
1120 
1121  return s;
1122 }
1123 
1124 /* *INDENT-OFF* */
1126 {
1127  .function = sctp4_rcv_phase,
1128  .name = "sctp4-rcv",
1129  /* Takes a vector of packets. */
1130  .vector_size = sizeof (u32),
1131  .n_errors = SCTP_N_ERROR,
1132  .error_strings = sctp_error_strings,
1133  .n_next_nodes = SCTP_RCV_PHASE_N_NEXT,
1134  .next_nodes =
1135  {
1136 #define _(s,n) [SCTP_RCV_PHASE_NEXT_##s] = n,
1138 #undef _
1139  },
1140  .format_trace = format_sctp_rx_trace_short,
1141 };
1142 /* *INDENT-ON* */
1143 
1145 
1146 /* *INDENT-OFF* */
1148 {
1149  .function = sctp6_rcv_phase,
1150  .name = "sctp6-rcv",
1151  /* Takes a vector of packets. */
1152  .vector_size = sizeof (u32),
1153  .n_errors = SCTP_N_ERROR,
1154  .error_strings = sctp_error_strings,
1155  .n_next_nodes = SCTP_RCV_PHASE_N_NEXT,
1156  .next_nodes =
1157  {
1158 #define _(s,n) [SCTP_RCV_PHASE_NEXT_##s] = n,
1160 #undef _
1161  },
1162  .format_trace = format_sctp_rx_trace_short,
1163 };
1164 /* *INDENT-ON* */
1165 
1167 
1170 
1173  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
1174  sctp_connection_t * sctp_conn, u8 idx,
1175  vlib_buffer_t * b0, u16 sctp_implied_length,
1176  u16 * next0)
1177 {
1178  sctp_shutdown_association_chunk_t *shutdown_chunk =
1179  (sctp_shutdown_association_chunk_t *) (sctp_hdr);
1180 
1181  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1182  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
1183  {
1184  return SCTP_ERROR_INVALID_TAG;
1185  }
1186 
1187  /*
1188  * It is not possible to bundle any other CHUNK with the SHUTDOWN chunk
1189  */
1190  if (sctp_is_bundling (sctp_implied_length, &shutdown_chunk->chunk_hdr))
1191  return SCTP_ERROR_BUNDLING_VIOLATION;
1192 
1193  switch (sctp_conn->state)
1194  {
1195  case SCTP_STATE_ESTABLISHED:
1196  if (sctp_check_outstanding_data_chunks (sctp_conn) == 0)
1197  sctp_conn->state = SCTP_STATE_SHUTDOWN_RECEIVED;
1198  sctp_send_shutdown_ack (sctp_conn, idx, b0);
1199  break;
1200 
1201  case SCTP_STATE_SHUTDOWN_SENT:
1202  sctp_send_shutdown_ack (sctp_conn, idx, b0);
1203  break;
1204  }
1205 
1206  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
1207 
1208  return SCTP_ERROR_NONE;
1209 }
1210 
1213  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
1214  sctp_connection_t * sctp_conn, u8 idx,
1215  vlib_buffer_t * b0, u16 sctp_implied_length,
1216  u16 * next0)
1217 {
1218  sctp_shutdown_ack_chunk_t *shutdown_ack_chunk =
1219  (sctp_shutdown_ack_chunk_t *) (sctp_hdr);
1220 
1221  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1222  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
1223  {
1224  return SCTP_ERROR_INVALID_TAG;
1225  }
1226 
1227  /*
1228  * It is not possible to bundle any other CHUNK with the SHUTDOWN chunk
1229  */
1230  if (sctp_is_bundling (sctp_implied_length, &shutdown_ack_chunk->chunk_hdr))
1231  return SCTP_ERROR_BUNDLING_VIOLATION;
1232 
1233  /* Whether we are in SCTP_STATE_SHUTDOWN_SENT or SCTP_STATE_SHUTDOWN_ACK_SENT
1234  * the reception of a SHUTDOWN_ACK chunk leads to the same actions:
1235  * - STOP T2_SHUTDOWN timer
1236  * - SEND SHUTDOWN_COMPLETE chunk
1237  */
1238  sctp_timer_reset (sctp_conn, SCTP_PRIMARY_PATH_IDX, SCTP_TIMER_T2_SHUTDOWN);
1239 
1240  sctp_send_shutdown_complete (sctp_conn, idx, b0);
1241 
1242  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].c_is_ip4);
1243 
1244  return SCTP_ERROR_NONE;
1245 }
1246 
1249  sctp_chunks_common_hdr_t * sctp_chunk_hdr,
1250  sctp_connection_t * sctp_conn, u8 idx,
1251  vlib_buffer_t * b0, u16 sctp_implied_length,
1252  u16 * next0)
1253 {
1254  sctp_shutdown_complete_chunk_t *shutdown_complete =
1255  (sctp_shutdown_complete_chunk_t *) (sctp_hdr);
1256 
1257  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1258  if (sctp_conn->local_tag != sctp_hdr->verification_tag)
1259  {
1260  return SCTP_ERROR_INVALID_TAG;
1261  }
1262 
1263  /*
1264  * It is not possible to bundle any other CHUNK with the SHUTDOWN chunk
1265  */
1266  if (sctp_is_bundling (sctp_implied_length, &shutdown_complete->chunk_hdr))
1267  return SCTP_ERROR_BUNDLING_VIOLATION;
1268 
1269  sctp_timer_reset (sctp_conn, idx, SCTP_TIMER_T2_SHUTDOWN);
1270 
1271  stream_session_disconnect_notify (&sctp_conn->sub_conn[idx].connection);
1272 
1273  sctp_conn->state = SCTP_STATE_CLOSED;
1274 
1275  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1276 
1277  return SCTP_ERROR_NONE;
1278 }
1279 
1282  vlib_node_runtime_t * node,
1283  vlib_frame_t * from_frame, int is_ip4)
1284 {
1285  u32 n_left_from, next_index, *from, *to_next;
1286  u32 my_thread_index = vm->thread_index;
1287 
1288  from = vlib_frame_vector_args (from_frame);
1289  n_left_from = from_frame->n_vectors;
1290 
1291  next_index = node->cached_next_index;
1292 
1293  while (n_left_from > 0)
1294  {
1295  u32 n_left_to_next;
1296 
1297  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1298 
1299  while (n_left_from > 0 && n_left_to_next > 0)
1300  {
1301  u32 bi0;
1302  vlib_buffer_t *b0;
1303  sctp_rx_trace_t *sctp_trace;
1304  sctp_header_t *sctp_hdr = 0;
1305  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
1306  ip4_header_t *ip4_hdr = 0;
1307  ip6_header_t *ip6_hdr = 0;
1308  sctp_connection_t *sctp_conn;
1309  u16 sctp_implied_length = 0;
1310  u16 error0 = SCTP_ERROR_NONE, next0 = SCTP_RCV_PHASE_N_NEXT;
1311  u8 idx = 0;
1312 
1313  bi0 = from[0];
1314  to_next[0] = bi0;
1315  from += 1;
1316  to_next += 1;
1317  n_left_from -= 1;
1318  n_left_to_next -= 1;
1319 
1320  b0 = vlib_get_buffer (vm, bi0);
1321  sctp_conn =
1322  sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
1323  my_thread_index);
1324 
1325  if (PREDICT_FALSE (sctp_conn == 0))
1326  {
1327  SCTP_DBG
1328  ("sctp_conn == NULL; return SCTP_ERROR_INVALID_CONNECTION");
1329  error0 = SCTP_ERROR_INVALID_CONNECTION;
1330  goto drop;
1331  }
1332 
1333  if (is_ip4)
1334  {
1335  ip4_hdr = vlib_buffer_get_current (b0);
1336  sctp_hdr = ip4_next_header (ip4_hdr);
1337  idx = sctp_sub_conn_id_via_ip4h (sctp_conn, ip4_hdr);
1338  }
1339  else
1340  {
1341  ip6_hdr = vlib_buffer_get_current (b0);
1342  sctp_hdr = ip6_next_header (ip6_hdr);
1343  idx = sctp_sub_conn_id_via_ip6h (sctp_conn, ip6_hdr);
1344  }
1345 
1346  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
1347  sctp_chunk_hdr = &full_hdr->common_hdr;
1348 
1349  sctp_implied_length =
1350  sctp_calculate_implied_length (ip4_hdr, ip6_hdr, is_ip4);
1351 
1352  u8 chunk_type = vnet_sctp_get_chunk_type (sctp_chunk_hdr);
1353  switch (chunk_type)
1354  {
1355  case SHUTDOWN:
1356  error0 =
1357  sctp_handle_shutdown (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1358  idx, b0, sctp_implied_length, &next0);
1359  break;
1360 
1361  case SHUTDOWN_ACK:
1362  error0 =
1363  sctp_handle_shutdown_ack (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1364  idx, b0, sctp_implied_length,
1365  &next0);
1366  break;
1367 
1368  case SHUTDOWN_COMPLETE:
1369  error0 =
1370  sctp_handle_shutdown_complete (sctp_hdr, sctp_chunk_hdr,
1371  sctp_conn, idx, b0,
1372  sctp_implied_length, &next0);
1373 
1374  sctp_connection_cleanup (sctp_conn);
1375  break;
1376 
1377  /*
1378  * DATA chunks can still be transmitted/received in the SHUTDOWN-PENDING
1379  * and SHUTDOWN-SENT states (as per RFC4960 Section 6)
1380  */
1381  case DATA:
1382  error0 =
1384  sctp_conn, idx, b0, &next0);
1385  break;
1386 
1387  case OPERATION_ERROR:
1388  error0 =
1389  sctp_handle_operation_err (sctp_hdr, sctp_conn, idx, b0,
1390  &next0);
1391  break;
1392 
1393  case COOKIE_ECHO: /* Cookie Received While Shutting Down */
1394  sctp_prepare_operation_error (sctp_conn, idx, b0,
1396  error0 = SCTP_ERROR_NONE;
1397  next0 = sctp_next_output (is_ip4);
1398  break;
1399  /* All UNEXPECTED scenarios (wrong chunk received per state-machine)
1400  * are handled by the input-dispatcher function using the table-lookup
1401  * hence we should never get to the "default" case below.
1402  */
1403  default:
1404  error0 = SCTP_ERROR_UNKNOWN_CHUNK;
1405  next0 = sctp_next_drop (is_ip4);
1406  goto drop;
1407  }
1408 
1409  if (error0 != SCTP_ERROR_NONE)
1410  {
1411  clib_warning ("error while parsing chunk");
1412  sctp_connection_cleanup (sctp_conn);
1413  next0 = sctp_next_drop (is_ip4);
1414  goto drop;
1415  }
1416 
1417  drop:
1418  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1419  {
1420  sctp_trace =
1421  vlib_add_trace (vm, node, b0, sizeof (*sctp_trace));
1422 
1423  if (sctp_hdr != NULL)
1424  clib_memcpy (&sctp_trace->sctp_header, sctp_hdr,
1425  sizeof (sctp_trace->sctp_header));
1426 
1427  if (sctp_conn != NULL)
1428  clib_memcpy (&sctp_trace->sctp_connection, sctp_conn,
1429  sizeof (sctp_trace->sctp_connection));
1430  }
1431 
1432  b0->error = node->errors[error0];
1433 
1434  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1435  n_left_to_next, bi0, next0);
1436  }
1437 
1438  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1439  }
1440 
1441  return from_frame->n_vectors;
1442 
1443 }
1444 
1445 static uword
1447  vlib_frame_t * from_frame)
1448 {
1449  return sctp46_shutdown_phase_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1450 }
1451 
1452 static uword
1454  vlib_frame_t * from_frame)
1455 {
1456  return sctp46_shutdown_phase_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1457 }
1458 
1459 /* *INDENT-OFF* */
1461 {
1462  .function = sctp4_shutdown_phase,
1463  .name = "sctp4-shutdown",
1464  /* Takes a vector of packets. */
1465  .vector_size = sizeof (u32),
1466  .n_errors = SCTP_N_ERROR,
1467  .error_strings = sctp_error_strings,
1468  .n_next_nodes = SCTP_SHUTDOWN_PHASE_N_NEXT,
1469  .next_nodes =
1470  {
1471 #define _(s,n) [SCTP_SHUTDOWN_PHASE_NEXT_##s] = n,
1473 #undef _
1474  },
1475  .format_trace = format_sctp_rx_trace_short,
1476 };
1477 /* *INDENT-ON* */
1478 
1481 
1482 /* *INDENT-OFF* */
1484 {
1485  .function = sctp6_shutdown_phase,
1486  .name = "sctp6-shutdown",
1487  /* Takes a vector of packets. */
1488  .vector_size = sizeof (u32),
1489  .n_errors = SCTP_N_ERROR,
1490  .error_strings = sctp_error_strings,
1491  .n_next_nodes = SCTP_SHUTDOWN_PHASE_N_NEXT,
1492  .next_nodes =
1493  {
1494 #define _(s,n) [SCTP_SHUTDOWN_PHASE_NEXT_##s] = n,
1496 #undef _
1497  },
1498  .format_trace = format_sctp_rx_trace_short,
1499 };
1500 /* *INDENT-ON* */
1501 
1504 
1507 
1510 
1513  sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b0,
1514  u16 * next0)
1515 {
1516 
1517  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1518  if (sctp_conn->local_tag != sack_chunk->sctp_hdr.verification_tag)
1519  {
1520  SCTP_ADV_DBG
1521  ("sctp_conn->local_tag != sack_chunk->sctp_hdr.verification_tag");
1522 
1523  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1524 
1525  return SCTP_ERROR_INVALID_TAG;
1526  }
1527 
1528  sctp_conn->sub_conn[idx].state = SCTP_SUBCONN_SACK_RECEIVED;
1529 
1530  sctp_conn->sub_conn[idx].last_seen = sctp_time_now ();
1531 
1532  /* Section 7.2.2; point (2) */
1533  if (sctp_conn->sub_conn[idx].cwnd > sctp_conn->sub_conn[idx].ssthresh)
1534  sctp_conn->sub_conn[idx].partially_acked_bytes =
1535  sctp_conn->next_tsn - sack_chunk->cumulative_tsn_ack;
1536 
1537  /* Section 7.2.2; point (5) */
1538  if (sctp_conn->next_tsn - sack_chunk->cumulative_tsn_ack == 0)
1539  sctp_conn->sub_conn[idx].partially_acked_bytes = 0;
1540 
1541  sctp_conn->last_unacked_tsn = sack_chunk->cumulative_tsn_ack;
1542 
1543  sctp_calculate_rto (sctp_conn, idx);
1544 
1545  sctp_timer_update (sctp_conn, idx, SCTP_TIMER_T3_RXTX,
1546  sctp_conn->sub_conn[idx].RTO);
1547 
1548  sctp_conn->sub_conn[idx].RTO_pending = 0;
1549 
1550  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1551 
1552  return SCTP_ERROR_NONE;
1553 }
1554 
1557  sctp_connection_t * sctp_conn, u8 idx,
1558  vlib_buffer_t * b0, u16 * next0)
1559 {
1560  /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */
1561  if (sctp_conn->local_tag != sctp_hb_chunk->sctp_hdr.verification_tag)
1562  {
1563  return SCTP_ERROR_INVALID_TAG;
1564  }
1565 
1566  sctp_prepare_heartbeat_ack_chunk (sctp_conn, idx, b0);
1567 
1568  *next0 = sctp_next_output (sctp_conn->sub_conn[idx].connection.is_ip4);
1569 
1570  return SCTP_ERROR_NONE;
1571 }
1572 
1575  sctp_connection_t * sctp_conn, u8 idx,
1576  vlib_buffer_t * b0, u16 * next0)
1577 {
1578  sctp_conn->sub_conn[idx].last_seen = sctp_time_now ();
1579 
1580  sctp_conn->sub_conn[idx].unacknowledged_hb -= 1;
1581 
1582  sctp_timer_update (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT,
1583  sctp_conn->sub_conn[idx].RTO);
1584 
1585  *next0 = sctp_next_drop (sctp_conn->sub_conn[idx].c_is_ip4);
1586 
1587  return SCTP_ERROR_NONE;
1588 }
1589 
1590 always_inline void
1591 sctp_node_inc_counter (vlib_main_t * vm, u32 sctp4_node, u32 sctp6_node,
1592  u8 is_ip4, u8 evt, u8 val)
1593 {
1594  if (PREDICT_TRUE (!val))
1595  return;
1596 
1597  if (is_ip4)
1598  vlib_node_increment_counter (vm, sctp4_node, evt, val);
1599  else
1600  vlib_node_increment_counter (vm, sctp6_node, evt, val);
1601 }
1602 
1605  vlib_node_runtime_t * node,
1606  vlib_frame_t * from_frame, int is_ip4)
1607 {
1608  u32 n_left_from, next_index, *from, *to_next;
1609  u32 my_thread_index = vm->thread_index;
1610 
1611  from = vlib_frame_vector_args (from_frame);
1612  n_left_from = from_frame->n_vectors;
1613 
1614  next_index = node->cached_next_index;
1615 
1616  while (n_left_from > 0)
1617  {
1618  u32 n_left_to_next;
1619 
1620  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1621 
1622  while (n_left_from > 0 && n_left_to_next > 0)
1623  {
1624  u32 bi0;
1625  vlib_buffer_t *b0;
1626  sctp_header_t *sctp_hdr = 0;
1627  ip4_header_t *ip4_hdr;
1628  ip6_header_t *ip6_hdr;
1629  sctp_connection_t *child_conn;
1630  sctp_connection_t *sctp_listener;
1631  u16 next0 = sctp_next_drop (is_ip4), error0 = SCTP_ERROR_ENQUEUED;
1632 
1633  bi0 = from[0];
1634  to_next[0] = bi0;
1635  from += 1;
1636  to_next += 1;
1637  n_left_from -= 1;
1638  n_left_to_next -= 1;
1639 
1640  b0 = vlib_get_buffer (vm, bi0);
1641  sctp_listener =
1642  sctp_listener_get (vnet_buffer (b0)->sctp.connection_index);
1643 
1644  if (is_ip4)
1645  {
1646  ip4_hdr = vlib_buffer_get_current (b0);
1647  sctp_hdr = ip4_next_header (ip4_hdr);
1648  }
1649  else
1650  {
1651  ip6_hdr = vlib_buffer_get_current (b0);
1652  sctp_hdr = ip6_next_header (ip6_hdr);
1653  }
1654 
1655  child_conn =
1656  sctp_lookup_connection (sctp_listener->sub_conn
1657  [SCTP_PRIMARY_PATH_IDX].c_fib_index, b0,
1658  my_thread_index, is_ip4);
1659 
1660  if (PREDICT_FALSE (child_conn->state != SCTP_STATE_CLOSED))
1661  {
1662  SCTP_DBG
1663  ("conn_index = %u: child_conn->state != SCTP_STATE_CLOSED.... STATE=%s",
1664  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
1665  connection.c_index,
1666  sctp_state_to_string (child_conn->state));
1667  error0 = SCTP_ERROR_CREATE_EXISTS;
1668  goto drop;
1669  }
1670 
1671  /* Create child session and send SYN-ACK */
1672  child_conn = sctp_connection_new (my_thread_index);
1673  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx =
1675  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_port =
1676  sctp_hdr->dst_port;
1677  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_port =
1678  sctp_hdr->src_port;
1679  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_is_ip4 = is_ip4;
1680  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto =
1681  sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto;
1682  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU =
1683  sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU;
1684  child_conn->state = SCTP_STATE_CLOSED;
1685  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.fib_index =
1686  sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].
1687  connection.fib_index;
1688 
1689  if (is_ip4)
1690  {
1691  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_ip4.as_u32 =
1692  ip4_hdr->dst_address.as_u32;
1693  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_ip4.as_u32 =
1694  ip4_hdr->src_address.as_u32;
1695  }
1696  else
1697  {
1698  clib_memcpy (&child_conn->
1699  sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_ip6,
1700  &ip6_hdr->dst_address, sizeof (ip6_address_t));
1701  clib_memcpy (&child_conn->
1702  sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_ip6,
1703  &ip6_hdr->src_address, sizeof (ip6_address_t));
1704  }
1705 
1706  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
1707  sctp_chunks_common_hdr_t *sctp_chunk_hdr = &full_hdr->common_hdr;
1708 
1709  u8 chunk_type = vnet_sctp_get_chunk_type (sctp_chunk_hdr);
1710  if (chunk_type != INIT && chunk_type != DATA
1711  && chunk_type != OPERATION_ERROR)
1712  {
1713  SCTP_DBG
1714  ("conn_index = %u: chunk_type != INIT... chunk_type=%s",
1715  child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
1716  connection.c_index, sctp_chunk_to_string (chunk_type));
1717 
1718  error0 = SCTP_ERROR_UNKNOWN_CHUNK;
1719  next0 = sctp_next_drop (is_ip4);
1720  goto drop;
1721  }
1722 
1723  u16 sctp_implied_length =
1724  sctp_calculate_implied_length (ip4_hdr, ip6_hdr, is_ip4);
1725 
1726  switch (chunk_type)
1727  {
1728  case INIT:
1729  sctp_connection_timers_init (child_conn);
1730 
1731  sctp_init_snd_vars (child_conn);
1732 
1733  sctp_init_cwnd (child_conn);
1734 
1735  error0 =
1736  sctp_handle_init (sctp_hdr, sctp_chunk_hdr, child_conn, b0,
1737  sctp_implied_length);
1738 
1739  if (error0 == SCTP_ERROR_NONE)
1740  {
1742  (&child_conn->
1743  sub_conn[SCTP_PRIMARY_PATH_IDX].connection,
1744  sctp_listener->
1745  sub_conn[SCTP_PRIMARY_PATH_IDX].c_s_index, 0))
1746  {
1747  clib_warning ("session accept fail");
1748  sctp_connection_cleanup (child_conn);
1749  error0 = SCTP_ERROR_CREATE_SESSION_FAIL;
1750  goto drop;
1751  }
1752  next0 = sctp_next_output (is_ip4);
1753  }
1754  break;
1755 
1756  /* Reception of a DATA chunk whilst in the CLOSED state is called
1757  * "Out of the Blue" packet and handling of the chunk needs special treatment
1758  * as per RFC4960 section 8.4
1759  */
1760  case DATA:
1761  break;
1762 
1763  case OPERATION_ERROR:
1764  error0 =
1765  sctp_handle_operation_err (sctp_hdr, child_conn,
1766  SCTP_PRIMARY_PATH_IDX, b0, &next0);
1767  break;
1768  }
1769 
1770  drop:
1771  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1772  {
1773  sctp_rx_trace_t *t0 =
1774  vlib_add_trace (vm, node, b0, sizeof (*t0));
1775  clib_memcpy (&t0->sctp_header, sctp_hdr,
1776  sizeof (t0->sctp_header));
1777  clib_memcpy (&t0->sctp_connection, sctp_listener,
1778  sizeof (t0->sctp_connection));
1779  }
1780 
1781  b0->error = node->errors[error0];
1782 
1783  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1784  n_left_to_next, bi0, next0);
1785  }
1786  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1787 
1788  }
1789  return from_frame->n_vectors;
1790 }
1791 
1792 static uword
1794  vlib_frame_t * from_frame)
1795 {
1796  return sctp46_listen_process_inline (vm, node, from_frame, 1 /* is_ip4 */ );
1797 }
1798 
1799 static uword
1801  vlib_frame_t * from_frame)
1802 {
1803  return sctp46_listen_process_inline (vm, node, from_frame, 0 /* is_ip4 */ );
1804 }
1805 
1808  vlib_frame_t * from_frame, int is_ip4)
1809 {
1810  u32 n_left_from, next_index, *from, *to_next;
1811  u32 my_thread_index = vm->thread_index, errors = 0;
1812 
1813  from = vlib_frame_vector_args (from_frame);
1814  n_left_from = from_frame->n_vectors;
1815 
1816  next_index = node->cached_next_index;
1817 
1818  while (n_left_from > 0)
1819  {
1820  u32 n_left_to_next;
1821 
1822  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
1823 
1824  while (n_left_from > 0 && n_left_to_next > 0)
1825  {
1826  u32 bi0;
1827  vlib_buffer_t *b0;
1828  sctp_header_t *sctp_hdr = 0;
1829  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
1830  ip4_header_t *ip4_hdr = 0;
1831  ip6_header_t *ip6_hdr = 0;
1832  sctp_connection_t *sctp_conn;
1833  u16 error0 = SCTP_ERROR_ENQUEUED, next0 =
1835  u8 idx;
1836 
1837  bi0 = from[0];
1838  to_next[0] = bi0;
1839  from += 1;
1840  to_next += 1;
1841  n_left_from -= 1;
1842  n_left_to_next -= 1;
1843 
1844  b0 = vlib_get_buffer (vm, bi0);
1845  sctp_conn =
1846  sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
1847  my_thread_index);
1848 
1849  if (PREDICT_FALSE (sctp_conn == 0))
1850  {
1851  SCTP_DBG
1852  ("sctp_conn == NULL; return SCTP_ERROR_INVALID_CONNECTION");
1853  error0 = SCTP_ERROR_INVALID_CONNECTION;
1854  goto done;
1855  }
1856  if (is_ip4)
1857  {
1858  ip4_hdr = vlib_buffer_get_current (b0);
1859  sctp_hdr = ip4_next_header (ip4_hdr);
1860  idx = sctp_sub_conn_id_via_ip4h (sctp_conn, ip4_hdr);
1861  }
1862  else
1863  {
1864  ip6_hdr = vlib_buffer_get_current (b0);
1865  sctp_hdr = ip6_next_header (ip6_hdr);
1866  idx = sctp_sub_conn_id_via_ip6h (sctp_conn, ip6_hdr);
1867  }
1868 
1869  sctp_conn->sub_conn[idx].subconn_idx = idx;
1870 
1871  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
1872  sctp_chunk_hdr =
1873  (sctp_chunks_common_hdr_t *) (&full_hdr->common_hdr);
1874 
1875  u8 chunk_type = vnet_sctp_get_chunk_type (&full_hdr->common_hdr);
1876 
1877  switch (chunk_type)
1878  {
1879  case COOKIE_ECHO:
1880  error0 =
1881  sctp_handle_cookie_echo (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1882  idx, b0, &next0);
1883  break;
1884 
1885  case COOKIE_ACK:
1886  error0 =
1887  sctp_handle_cookie_ack (sctp_hdr, sctp_chunk_hdr, sctp_conn,
1888  idx, b0, &next0);
1889  break;
1890 
1891  case SACK:
1892  error0 =
1894  sctp_conn, idx, b0, &next0);
1895  break;
1896 
1897  case HEARTBEAT:
1898  error0 =
1900  sctp_conn, idx, b0, &next0);
1901  break;
1902 
1903  case HEARTBEAT_ACK:
1904  error0 =
1906  sctp_conn, idx, b0, &next0);
1907  break;
1908 
1909  case DATA:
1910  error0 =
1912  sctp_conn, idx, b0, &next0);
1913  break;
1914 
1915  case OPERATION_ERROR:
1916  error0 =
1917  sctp_handle_operation_err (sctp_hdr, sctp_conn, idx, b0,
1918  &next0);
1919  break;
1920 
1921  /* All UNEXPECTED scenarios (wrong chunk received per state-machine)
1922  * are handled by the input-dispatcher function using the table-lookup
1923  * hence we should never get to the "default" case below.
1924  */
1925  default:
1926  error0 = SCTP_ERROR_UNKNOWN_CHUNK;
1927  next0 = sctp_next_drop (is_ip4);
1928  goto done;
1929  }
1930 
1931  done:
1932  b0->error = node->errors[error0];
1933  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
1934  {
1935  sctp_rx_trace_t *t0 =
1936  vlib_add_trace (vm, node, b0, sizeof (*t0));
1937  sctp_set_rx_trace_data (t0, sctp_conn, sctp_hdr, b0, is_ip4);
1938  }
1939 
1940  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
1941  n_left_to_next, bi0, next0);
1942  }
1943 
1944  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
1945  }
1946 
1948  my_thread_index);
1949 
1952  SCTP_ERROR_EVENT_FIFO_FULL, errors);
1953  sctp_flush_frame_to_output (vm, my_thread_index, is_ip4);
1954 
1955  return from_frame->n_vectors;
1956 }
1957 
1958 static uword
1960  vlib_frame_t * from_frame)
1961 {
1962  return sctp46_established_phase_inline (vm, node, from_frame,
1963  1 /* is_ip4 */ );
1964 }
1965 
1966 static uword
1968  vlib_frame_t * from_frame)
1969 {
1970  return sctp46_established_phase_inline (vm, node, from_frame,
1971  0 /* is_ip4 */ );
1972 }
1973 
1974 u8 *
1975 format_sctp_rx_trace (u8 * s, va_list * args)
1976 {
1977  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
1978  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
1979  sctp_rx_trace_t *t = va_arg (*args, sctp_rx_trace_t *);
1980  u32 indent = format_get_indent (s);
1981 
1982  s = format (s, "%U\n%U%U",
1983  format_sctp_header, &t->sctp_header, 128,
1984  format_white_space, indent,
1986 
1987  return s;
1988 }
1989 
1990 /* *INDENT-OFF* */
1992 {
1993  .function = sctp4_listen_phase,
1994  .name = "sctp4-listen",
1995  /* Takes a vector of packets. */
1996  .vector_size = sizeof (u32),
1997  .n_errors = SCTP_N_ERROR,
1998  .error_strings = sctp_error_strings,
1999  .n_next_nodes = SCTP_LISTEN_PHASE_N_NEXT,
2000  .next_nodes =
2001  {
2002 #define _(s,n) [SCTP_LISTEN_PHASE_NEXT_##s] = n,
2004 #undef _
2005  },
2006  .format_trace = format_sctp_rx_trace_short,
2007 };
2008 /* *INDENT-ON* */
2009 
2011 
2012 /* *INDENT-OFF* */
2014 {
2015  .function = sctp6_listen_phase,
2016  .name = "sctp6-listen",
2017  /* Takes a vector of packets. */
2018  .vector_size = sizeof (u32),
2019  .n_errors = SCTP_N_ERROR,
2020  .error_strings = sctp_error_strings,
2021  .n_next_nodes = SCTP_LISTEN_PHASE_N_NEXT,
2022  .next_nodes =
2023  {
2024 #define _(s,n) [SCTP_LISTEN_PHASE_NEXT_##s] = n,
2026 #undef _
2027  },
2028  .format_trace = format_sctp_rx_trace_short,
2029 };
2030 /* *INDENT-ON* */
2031 
2033 
2034 /* *INDENT-OFF* */
2036 {
2037  .function = sctp4_established_phase,
2038  .name = "sctp4-established",
2039  /* Takes a vector of packets. */
2040  .vector_size = sizeof (u32),
2041  .n_errors = SCTP_N_ERROR,
2042  .error_strings = sctp_error_strings,
2043  .n_next_nodes = SCTP_ESTABLISHED_PHASE_N_NEXT,
2044  .next_nodes =
2045  {
2046 #define _(s,n) [SCTP_ESTABLISHED_PHASE_NEXT_##s] = n,
2048 #undef _
2049  },
2050  .format_trace = format_sctp_rx_trace_short,
2051 };
2052 /* *INDENT-ON* */
2053 
2056 
2057 /* *INDENT-OFF* */
2059 {
2060  .function = sctp6_established_phase,
2061  .name = "sctp6-established",
2062  /* Takes a vector of packets. */
2063  .vector_size = sizeof (u32),
2064  .n_errors = SCTP_N_ERROR,
2065  .error_strings = sctp_error_strings,
2066  .n_next_nodes = SCTP_LISTEN_PHASE_N_NEXT,
2067  .next_nodes =
2068  {
2069 #define _(s,n) [SCTP_LISTEN_PHASE_NEXT_##s] = n,
2071 #undef _
2072  },
2073  .format_trace = format_sctp_rx_trace_short,
2074 };
2075 /* *INDENT-ON* */
2076 
2079 
2080 /*
2081  * This is the function executed first for the SCTP graph.
2082  * It takes care of doing the initial message parsing and
2083  * dispatch to the specialized function.
2084  */
2087  vlib_frame_t * from_frame, int is_ip4)
2088 {
2089  u32 n_left_from, next_index, *from, *to_next;
2090  u32 my_thread_index = vm->thread_index;
2091  u8 is_filtered;
2093 
2094  from = vlib_frame_vector_args (from_frame);
2095  n_left_from = from_frame->n_vectors;
2096  next_index = node->cached_next_index;
2097  sctp_set_time_now (my_thread_index);
2098 
2099  while (n_left_from > 0)
2100  {
2101  u32 n_left_to_next;
2102 
2103  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
2104 
2105  while (n_left_from > 0 && n_left_to_next > 0)
2106  {
2107  int n_advance_bytes0, n_data_bytes0;
2108  u32 bi0, fib_index0;
2109  vlib_buffer_t *b0;
2110  sctp_header_t *sctp_hdr = 0;
2111  sctp_chunks_common_hdr_t *sctp_chunk_hdr = 0;
2112  sctp_connection_t *sctp_conn;
2113  transport_connection_t *trans_conn;
2114  ip4_header_t *ip4_hdr;
2115  ip6_header_t *ip6_hdr;
2116  u32 error0 = SCTP_ERROR_NO_LISTENER, next0 = SCTP_INPUT_NEXT_DROP;
2117 
2118  bi0 = from[0];
2119  to_next[0] = bi0;
2120  from += 1;
2121  to_next += 1;
2122  n_left_from -= 1;
2123  n_left_to_next -= 1;
2124 
2125  b0 = vlib_get_buffer (vm, bi0);
2126  vnet_buffer (b0)->sctp.flags = 0;
2127  fib_index0 = vnet_buffer (b0)->ip.fib_index;
2128 
2129  /* Checksum computed by ipx_local no need to compute again */
2130 
2131  if (is_ip4)
2132  {
2133  ip4_hdr = vlib_buffer_get_current (b0);
2134  sctp_hdr = ip4_next_header (ip4_hdr);
2135 
2136  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
2137  sctp_chunk_hdr = &full_hdr->common_hdr;
2138 
2139  n_advance_bytes0 =
2140  (ip4_header_bytes (ip4_hdr) +
2141  sizeof (sctp_payload_data_chunk_t));
2142  n_data_bytes0 =
2143  clib_net_to_host_u16 (ip4_hdr->length) - n_advance_bytes0;
2144 
2145  trans_conn = session_lookup_connection_wt4 (fib_index0,
2146  &ip4_hdr->dst_address,
2147  &ip4_hdr->src_address,
2148  sctp_hdr->dst_port,
2149  sctp_hdr->src_port,
2151  my_thread_index,
2152  &is_filtered);
2153  }
2154  else
2155  {
2156  ip6_hdr = vlib_buffer_get_current (b0);
2157  sctp_hdr = ip6_next_header (ip6_hdr);
2158 
2159  sctp_full_hdr_t *full_hdr = (sctp_full_hdr_t *) sctp_hdr;
2160  sctp_chunk_hdr = &full_hdr->common_hdr;
2161 
2162  n_advance_bytes0 = sctp_header_bytes ();
2163  n_data_bytes0 =
2164  clib_net_to_host_u16 (ip6_hdr->payload_length) -
2165  n_advance_bytes0;
2166  n_advance_bytes0 += sizeof (ip6_hdr[0]);
2167 
2168  trans_conn = session_lookup_connection_wt6 (fib_index0,
2169  &ip6_hdr->dst_address,
2170  &ip6_hdr->src_address,
2171  sctp_hdr->dst_port,
2172  sctp_hdr->src_port,
2174  my_thread_index,
2175  &is_filtered);
2176  }
2177 
2178  /* Length check */
2179  if (PREDICT_FALSE (n_advance_bytes0 < 0))
2180  {
2181  error0 = SCTP_ERROR_LENGTH;
2182  goto done;
2183  }
2184 
2185  sctp_conn = sctp_get_connection_from_transport (trans_conn);
2186  vnet_sctp_common_hdr_params_net_to_host (sctp_chunk_hdr);
2187 
2188  u8 chunk_type = vnet_sctp_get_chunk_type (sctp_chunk_hdr);
2189  if (chunk_type >= UNKNOWN)
2190  {
2191  clib_warning
2192  ("Received an unrecognized chunk; sending back OPERATION_ERROR chunk");
2193 
2196 
2197  error0 = SCTP_ERROR_UNKNOWN_CHUNK;
2198  next0 = sctp_next_output (is_ip4);
2199  goto done;
2200  }
2201 
2202  vnet_buffer (b0)->sctp.hdr_offset =
2203  (u8 *) sctp_hdr - (u8 *) vlib_buffer_get_current (b0);
2204 
2205  /* Session exists */
2206  if (PREDICT_TRUE (0 != sctp_conn))
2207  {
2208  /* Save connection index */
2209  vnet_buffer (b0)->sctp.connection_index = trans_conn->c_index;
2210  vnet_buffer (b0)->sctp.data_offset = n_advance_bytes0;
2211  vnet_buffer (b0)->sctp.data_len = n_data_bytes0;
2212 
2213  next0 = tm->dispatch_table[sctp_conn->state][chunk_type].next;
2214  error0 = tm->dispatch_table[sctp_conn->state][chunk_type].error;
2215 
2217  ("S_INDEX = %u, C_INDEX = %u, TRANS_CONN = %p, SCTP_CONN = %p, CURRENT_CONNECTION_STATE = %s,"
2218  "CHUNK_TYPE_RECEIVED = %s " "NEXT_PHASE = %s",
2219  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
2220  connection.s_index,
2221  sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
2222  connection.c_index, trans_conn, sctp_conn,
2223  sctp_state_to_string (sctp_conn->state),
2224  sctp_chunk_to_string (chunk_type), phase_to_string (next0));
2225 
2226  if (chunk_type == DATA)
2227  SCTP_ADV_DBG ("n_advance_bytes0 = %u, n_data_bytes0 = %u",
2228  n_advance_bytes0, n_data_bytes0);
2229 
2230  }
2231  else
2232  {
2233  if (is_filtered)
2234  {
2235  next0 = SCTP_INPUT_NEXT_DROP;
2236  error0 = SCTP_ERROR_FILTERED;
2237  }
2238  else if ((is_ip4 && tm->punt_unknown4) ||
2239  (!is_ip4 && tm->punt_unknown6))
2240  {
2242  error0 = SCTP_ERROR_PUNT;
2243  }
2244  else
2245  {
2246  next0 = SCTP_INPUT_NEXT_DROP;
2247  error0 = SCTP_ERROR_NO_LISTENER;
2248  }
2249  SCTP_DBG_STATE_MACHINE ("sctp_conn == NULL, NEXT_PHASE = %s",
2250  phase_to_string (next0));
2251  sctp_conn = 0;
2252  }
2253 
2254  done:
2255  b0->error = error0 ? node->errors[error0] : 0;
2256 
2257  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
2258  {
2259  sctp_rx_trace_t *t0 =
2260  vlib_add_trace (vm, node, b0, sizeof (*t0));
2261  sctp_set_rx_trace_data (t0, sctp_conn, sctp_hdr, b0, is_ip4);
2262  }
2263  vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
2264  n_left_to_next, bi0, next0);
2265  }
2266 
2267  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
2268  }
2269  return from_frame->n_vectors;
2270 }
2271 
2272 static uword
2274  vlib_frame_t * from_frame)
2275 {
2276  return sctp46_input_dispatcher (vm, node, from_frame, 1 /* is_ip4 */ );
2277 }
2278 
2279 static uword
2281  vlib_frame_t * from_frame)
2282 {
2283  return sctp46_input_dispatcher (vm, node, from_frame, 0 /* is_ip4 */ );
2284 }
2285 
2286 /* *INDENT-OFF* */
2288 {
2289  .function = sctp4_input_dispatcher,
2290  .name = "sctp4-input",
2291  /* Takes a vector of packets. */
2292  .vector_size = sizeof (u32),
2293  .n_errors = SCTP_N_ERROR,
2294  .error_strings = sctp_error_strings,
2295  .n_next_nodes = SCTP_INPUT_N_NEXT,
2296  .next_nodes =
2297  {
2298 #define _(s,n) [SCTP_INPUT_NEXT_##s] = n,
2300 #undef _
2301  },
2302  .format_buffer = format_sctp_header,
2303  .format_trace = format_sctp_rx_trace,
2304 };
2305 /* *INDENT-ON* */
2306 
2308 
2309 /* *INDENT-OFF* */
2311 {
2312  .function = sctp6_input_dispatcher,
2313  .name = "sctp6-input",
2314  /* Takes a vector of packets. */
2315  .vector_size = sizeof (u32),
2316  .n_errors = SCTP_N_ERROR,
2317  .error_strings = sctp_error_strings,
2318  .n_next_nodes = SCTP_INPUT_N_NEXT,
2319  .next_nodes =
2320  {
2321 #define _(s,n) [SCTP_INPUT_NEXT_##s] = n,
2323 #undef _
2324  },
2325  .format_buffer = format_sctp_header,
2326  .format_trace = format_sctp_rx_trace,
2327 };
2328 /* *INDENT-ON* */
2329 
2331 
2334 
2335 static void
2337 {
2338  int i, j;
2339  for (i = 0; i < ARRAY_LEN (tm->dispatch_table); i++)
2340  for (j = 0; j < ARRAY_LEN (tm->dispatch_table[i]); j++)
2341  {
2342  tm->dispatch_table[i][j].next = SCTP_INPUT_NEXT_DROP;
2343  tm->dispatch_table[i][j].error = SCTP_ERROR_DISPATCH;
2344  }
2345 
2346 #define _(t,f,n,e) \
2347 do { \
2348  tm->dispatch_table[SCTP_STATE_##t][f].next = (n); \
2349  tm->dispatch_table[SCTP_STATE_##t][f].error = (e); \
2350 } while (0)
2351 
2352  /*
2353  * SCTP STATE-MACHINE states:
2354  *
2355  * _(CLOSED, "CLOSED") \
2356  * _(COOKIE_WAIT, "COOKIE_WAIT") \
2357  * _(COOKIE_ECHOED, "COOKIE_ECHOED") \
2358  * _(ESTABLISHED, "ESTABLISHED") \
2359  * _(SHUTDOWN_PENDING, "SHUTDOWN_PENDING") \
2360  * _(SHUTDOWN_SENT, "SHUTDOWN_SENT") \
2361  * _(SHUTDOWN_RECEIVED, "SHUTDOWN_RECEIVED") \
2362  * _(SHUTDOWN_ACK_SENT, "SHUTDOWN_ACK_SENT")
2363  */
2364  //_(CLOSED, DATA, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED DATA chunk which requires special handling */
2365  _(CLOSED, INIT, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE);
2366  _(CLOSED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2367  _(CLOSED, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2368  _(CLOSED, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2369  _(CLOSED, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2370  _(CLOSED, ABORT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE);
2371  _(CLOSED, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2372  _(CLOSED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2373  _(CLOSED, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2374  _(CLOSED, COOKIE_ECHO, SCTP_INPUT_NEXT_ESTABLISHED_PHASE, SCTP_ERROR_NONE);
2375  _(CLOSED, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2376  _(CLOSED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2377  _(CLOSED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2378  _(CLOSED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2379  _(CLOSED, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE);
2380 
2381  _(COOKIE_WAIT, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_NONE); /* UNEXPECTED DATA chunk which requires special handling */
2382  _(COOKIE_WAIT, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk which requires special handling */
2383  _(COOKIE_WAIT, INIT_ACK, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE);
2384  _(COOKIE_WAIT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2385  _(COOKIE_WAIT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2386  _(COOKIE_WAIT, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2387  _(COOKIE_WAIT, ABORT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE);
2388  _(COOKIE_WAIT, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2389  _(COOKIE_WAIT, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2390  _(COOKIE_WAIT, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2391  _(COOKIE_WAIT, COOKIE_ECHO, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_COOKIE_ECHO_VIOLATION); /* UNEXPECTED COOKIE_ECHO chunk */
2392  _(COOKIE_WAIT, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2393  _(COOKIE_WAIT, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2394  _(COOKIE_WAIT, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2395  _(COOKIE_WAIT, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2397  SCTP_ERROR_NONE);
2398 
2399  _(COOKIE_ECHOED, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_NONE);
2400  _(COOKIE_ECHOED, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk which requires special handling */
2401  _(COOKIE_ECHOED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2402  _(COOKIE_ECHOED, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2403  _(COOKIE_ECHOED, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2404  _(COOKIE_ECHOED, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2405  _(COOKIE_ECHOED, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2406  _(COOKIE_ECHOED, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2407  _(COOKIE_ECHOED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2408  _(COOKIE_ECHOED, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2409  _(COOKIE_ECHOED, COOKIE_ECHO, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_COOKIE_ECHO_VIOLATION); /* UNEXPECTED COOKIE_ECHO chunk */
2411  SCTP_ERROR_NONE);
2412  _(COOKIE_ECHOED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2413  _(COOKIE_ECHOED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2414  _(COOKIE_ECHOED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2416  SCTP_ERROR_NONE);
2417 
2418  _(ESTABLISHED, DATA, SCTP_INPUT_NEXT_ESTABLISHED_PHASE, SCTP_ERROR_NONE);
2419  _(ESTABLISHED, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2420  _(ESTABLISHED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2421  _(ESTABLISHED, SACK, SCTP_INPUT_NEXT_ESTABLISHED_PHASE, SCTP_ERROR_NONE);
2423  SCTP_ERROR_NONE);
2425  SCTP_ERROR_NONE);
2426  _(ESTABLISHED, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2427  _(ESTABLISHED, SHUTDOWN, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2428  _(ESTABLISHED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2429  _(ESTABLISHED, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2430  _(ESTABLISHED, COOKIE_ECHO, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_COOKIE_ECHO_VIOLATION); /* UNEXPECTED COOKIE_ECHO chunk */
2431  _(ESTABLISHED, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2432  _(ESTABLISHED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2433  _(ESTABLISHED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2434  _(ESTABLISHED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2436  SCTP_ERROR_NONE);
2437 
2438  _(SHUTDOWN_PENDING, DATA, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2439  _(SHUTDOWN_PENDING, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2440  _(SHUTDOWN_PENDING, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2441  _(SHUTDOWN_PENDING, SACK, SCTP_INPUT_NEXT_LISTEN_PHASE, SCTP_ERROR_NONE);
2442  _(SHUTDOWN_PENDING, HEARTBEAT, SCTP_INPUT_NEXT_LISTEN_PHASE,
2443  SCTP_ERROR_NONE);
2444  _(SHUTDOWN_PENDING, HEARTBEAT_ACK, SCTP_INPUT_NEXT_LISTEN_PHASE,
2445  SCTP_ERROR_NONE);
2446  _(SHUTDOWN_PENDING, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2447  _(SHUTDOWN_PENDING, SHUTDOWN, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2448  SCTP_ERROR_NONE);
2449  _(SHUTDOWN_PENDING, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2450  _(SHUTDOWN_PENDING, OPERATION_ERROR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_OPERATION_ERROR_VIOLATION); /* UNEXPECTED OPERATION_ERROR chunk */
2451  _(SHUTDOWN_PENDING, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2452  SCTP_ERROR_NONE);
2453  _(SHUTDOWN_PENDING, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2454  _(SHUTDOWN_PENDING, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2455  _(SHUTDOWN_PENDING, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2456  _(SHUTDOWN_PENDING, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2457  _(SHUTDOWN_PENDING, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE,
2458  SCTP_ERROR_NONE);
2459 
2460  _(SHUTDOWN_SENT, DATA, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2461  _(SHUTDOWN_SENT, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2462  _(SHUTDOWN_SENT, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2463  _(SHUTDOWN_SENT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED SACK chunk */
2464  _(SHUTDOWN_SENT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2465  _(SHUTDOWN_SENT, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2466  _(SHUTDOWN_SENT, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2467  _(SHUTDOWN_SENT, SHUTDOWN, SCTP_INPUT_NEXT_SHUTDOWN_PHASE, SCTP_ERROR_NONE);
2468  _(SHUTDOWN_SENT, SHUTDOWN_ACK, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2469  SCTP_ERROR_NONE);
2470  _(SHUTDOWN_SENT, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2471  SCTP_ERROR_NONE);
2472  _(SHUTDOWN_SENT, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2473  _(SHUTDOWN_SENT, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2474  _(SHUTDOWN_SENT, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2475  _(SHUTDOWN_SENT, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2477  SCTP_ERROR_NONE);
2478 
2479  _(SHUTDOWN_RECEIVED, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_DATA_CHUNK_VIOLATION); /* UNEXPECTED DATA chunk */
2480  _(SHUTDOWN_RECEIVED, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2481  _(SHUTDOWN_RECEIVED, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2482  _(SHUTDOWN_RECEIVED, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2483  _(SHUTDOWN_RECEIVED, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2484  _(SHUTDOWN_RECEIVED, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2485  _(SHUTDOWN_RECEIVED, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2486  _(SHUTDOWN_RECEIVED, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2487  _(SHUTDOWN_RECEIVED, SHUTDOWN_ACK, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2488  SCTP_ERROR_NONE);
2489  _(SHUTDOWN_RECEIVED, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2490  SCTP_ERROR_NONE);
2491  _(SHUTDOWN_RECEIVED, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2492  _(SHUTDOWN_RECEIVED, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2493  _(SHUTDOWN_RECEIVED, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2494  _(SHUTDOWN_RECEIVED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */
2495  _(SHUTDOWN_RECEIVED, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE,
2496  SCTP_ERROR_NONE);
2497 
2498  _(SHUTDOWN_ACK_SENT, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_DATA_CHUNK_VIOLATION); /* UNEXPECTED DATA chunk */
2499  _(SHUTDOWN_ACK_SENT, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk */
2500  _(SHUTDOWN_ACK_SENT, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */
2501  _(SHUTDOWN_ACK_SENT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */
2502  _(SHUTDOWN_ACK_SENT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */
2503  _(SHUTDOWN_ACK_SENT, HEARTBEAT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_ACK_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT_ACK chunk */
2504  _(SHUTDOWN_ACK_SENT, ABORT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ABORT_CHUNK_VIOLATION); /* UNEXPECTED ABORT chunk */
2505  _(SHUTDOWN_ACK_SENT, SHUTDOWN, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN chunk */
2506  _(SHUTDOWN_ACK_SENT, SHUTDOWN_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_ACK_CHUNK_VIOLATION); /* UNEXPECTED SHUTDOWN_ACK chunk */
2507  _(SHUTDOWN_ACK_SENT, COOKIE_ECHO, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2508  SCTP_ERROR_NONE);
2509  _(SHUTDOWN_ACK_SENT, COOKIE_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED COOKIE_ACK chunk */
2510  _(SHUTDOWN_ACK_SENT, ECNE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ECNE_VIOLATION); /* UNEXPECTED ECNE chunk */
2511  _(SHUTDOWN_ACK_SENT, CWR, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_CWR_VIOLATION); /* UNEXPECTED CWR chunk */
2512  _(SHUTDOWN_ACK_SENT, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_SHUTDOWN_PHASE,
2513  SCTP_ERROR_NONE);
2514  _(SHUTDOWN_ACK_SENT, OPERATION_ERROR, SCTP_INPUT_NEXT_LISTEN_PHASE,
2515  SCTP_ERROR_NONE);
2516 
2517  /* TODO: Handle COOKIE ECHO when a TCB Exists */
2518 
2519 #undef _
2520 }
2521 
2522 clib_error_t *
2524 {
2525  clib_error_t *error = 0;
2527 
2528  if ((error = vlib_call_init_function (vm, sctp_init)))
2529  return error;
2530 
2531  /* Initialize dispatch table. */
2533 
2534  return error;
2535 }
2536 
2538 
2539 /*
2540  * fd.io coding-style-patch-verification: ON
2541  *
2542  * Local Variables:
2543  * eval: (c-set-style "gnu")
2544  * End:
2545  */
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:1248
u16 sctp_check_outstanding_data_chunks(sctp_connection_t *sctp_conn)
Definition: sctp.c:551
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:137
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:250
#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:169
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:1807
#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
unsigned long u64
Definition: types.h:89
static int ip4_header_bytes(ip4_header_t *i)
Definition: ip4_packet.h:234
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
static u64 sctp_time_now(void)
Definition: sctp.h:669
enum _sctp_rcv_phase_next sctp_rcv_phase_next_t
u32 thread_index
Definition: main.h:179
#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:528
static u32 format_get_indent(u8 *s)
Definition: format.h:72
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:690
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:1212
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:306
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:451
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:228
ip6_address_t src_address
Definition: ip6_packet.h:347
unsigned char u8
Definition: types.h:56
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:1508
static void sctp_dispatch_table_init(sctp_main_t *tm)
Definition: sctp_input.c:2336
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:156
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:729
#define always_inline
Definition: clib.h:92
ip4_address_t dst_address
Definition: ip4_packet.h:169
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:731
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:2310
#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:2287
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:240
void sctp_prepare_sack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to SACK.
Definition: sctp_output.c:1125
static int sctp_half_open_connection_cleanup(sctp_connection_t *tc)
Try to cleanup half-open connection.
Definition: sctp.h:632
unsigned int u32
Definition: types.h:88
sctp_connection_t * sctp_connection_new(u8 thread_index)
Definition: sctp.c:421
#define vlib_call_init_function(vm, x)
Definition: init.h:227
#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:2086
#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:1168
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:1172
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:1163
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
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:1506
unsigned short u16
Definition: types.h:57
vlib_node_registration_t sctp4_rcv_phase_node
(constructor) VLIB_REGISTER_NODE (sctp4_rcv_phase_node)
Definition: sctp_input.c:1125
vlib_node_registration_t sctp6_shutdown_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_shutdown_phase_node)
Definition: sctp_input.c:1169
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:290
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:202
static uword sctp6_established_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1967
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:926
#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:1556
struct _sctp_connection sctp_connection_t
#define SCTP_IPV6_ADDRESS_TYPE
Definition: sctp_packet.h:778
static u64 sctp_set_time_now(u32 thread_index)
Definition: sctp.h:586
#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:816
#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:135
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:1168
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:1793
#define MAX_ENQUEABLE_SACKS
Definition: sctp.h:178
u8 * format_sctp_rx_trace_short(u8 *s, va_list *args)
Definition: sctp_input.c:1110
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:153
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:380
vlib_main_t * vm
Definition: buffer.c:294
u8 * format_sctp_connection(u8 *s, va_list *args)
Definition: sctp.c:230
static uword sctp4_input_dispatcher(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:2273
#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:2523
#define sctp_next_drop(is_ip4)
Definition: sctp_input.c:237
static void * ip6_next_header(ip6_header_t *i)
Definition: ip6_packet.h:374
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:1574
void stream_session_disconnect_notify(transport_connection_t *tc)
Notification from transport that connection is being closed.
Definition: session.c:747
void sctp_send_shutdown_complete(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0)
Definition: sctp_output.c:1299
vlib_node_registration_t sctp6_established_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_established_phase_node)
Definition: sctp_input.c:1509
vlib_node_registration_t sctp6_init_phase_node
(constructor) VLIB_REGISTER_NODE (sctp6_init_phase_node)
Definition: sctp_input.c:1147
static uword sctp6_rcv_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1103
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:645
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:492
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
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:1281
#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:107
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:215
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:521
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:871
void sctp_prepare_cookie_echo_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u8 reuse_buffer)
Definition: sctp_output.c:562
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:1512
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
u16 payload_length
Definition: ip6_packet.h:338
#define SCTP_IPV4_ADDRESS_TYPE
Definition: sctp_packet.h:776
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:1604
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:1446
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:896
u64 uword
Definition: types.h:112
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:1096
#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:963
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:1959
#define vnet_buffer(b)
Definition: buffer.h:360
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:542
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:591
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:172
u8 * format_sctp_rx_trace(u8 *s, va_list *args)
Definition: sctp_input.c:1975
#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:1505
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:347
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:1591
#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:1453
static uword sctp6_listen_phase(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:1800
static uword sctp6_input_dispatcher(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: sctp_input.c:2280
void sctp_send_shutdown_ack(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Definition: sctp_output.c:1108
format_function_t format_sctp_state
Definition: sctp.h:302
ip6_address_t dst_address
Definition: ip6_packet.h:347
char * phase_to_string(u8 phase)
Definition: sctp_input.c:88
#define SCTP_SUPPORTED_ADDRESS_TYPES
Definition: sctp_packet.h:785