18 #include <openssl/hmac.h> 26 if (
sctp_main.tx_frames[!is_ip4][thread_index])
31 sctp_main.tx_frames[!is_ip4][thread_index]);
32 sctp_main.tx_frames[!is_ip4][thread_index] = 0;
42 if (
sctp_main.ip_lookup_tx_frames[!is_ip4][thread_index])
49 sctp_main.ip_lookup_tx_frames[!is_ip4][thread_index] = 0;
71 u32 ip_header_length, payload_length_host_byte_order;
72 u32 n_this_buffer, n_bytes_left, n_ip_bytes_this_buffer;
73 void *data_this_buffer;
77 payload_length_host_byte_order =
78 clib_net_to_host_u16 (ip0->
length) - ip_header_length;
80 clib_host_to_net_u32 (payload_length_host_byte_order +
97 n_bytes_left = n_this_buffer = payload_length_host_byte_order;
98 data_this_buffer = (
void *) ip0 + ip_header_length;
99 n_ip_bytes_this_buffer =
101 if (n_this_buffer + ip_header_length > n_ip_bytes_this_buffer)
103 n_this_buffer = n_ip_bytes_this_buffer > ip_header_length ?
104 n_ip_bytes_this_buffer - ip_header_length : 0;
110 n_bytes_left -= n_this_buffer;
111 if (n_bytes_left == 0)
128 u16 payload_length_host_byte_order;
129 u32 i, n_this_buffer, n_bytes_left;
130 u32 headers_size =
sizeof (ip0[0]);
131 void *data_this_buffer;
138 payload_length_host_byte_order = clib_net_to_host_u16 (ip0->
payload_length);
139 data_this_buffer = (
void *) (ip0 + 1);
158 ip6_hop_by_hop_ext_t *ext_hdr =
159 (ip6_hop_by_hop_ext_t *) data_this_buffer;
164 skip_bytes = 8 * (1 + ext_hdr->n_data_u64s);
165 data_this_buffer = (
void *) ((
u8 *) data_this_buffer + skip_bytes);
167 payload_length_host_byte_order -= skip_bytes;
168 headers_size += skip_bytes;
171 n_bytes_left = n_this_buffer = payload_length_host_byte_order;
180 n_bytes_left -= n_this_buffer;
181 if (n_bytes_left == 0)
184 if (!(p0->
flags & VLIB_BUFFER_NEXT_PRESENT))
203 if (sctp_sub_conn->c_is_ip4)
226 if (b->
flags & VLIB_BUFFER_NEXT_PRESENT)
229 b->
flags &= VLIB_BUFFER_NEXT_PRESENT - 1;
243 ASSERT ((b->
flags & VLIB_BUFFER_NEXT_PRESENT) == 0);
244 b->
flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
257 u32 current_length =
vec_len (tm->tx_buffers[thread_index]);
261 current_length + n_free_buffers - 1);
265 _vec_len (tm->tx_buffers[thread_index]) = current_length + n_allocated;
267 if (
vec_len (tm->tx_buffers[thread_index]) == 0)
285 my_tx_buffers = tm->tx_buffers[thread_index];
286 *bidx = my_tx_buffers[
vec_len (my_tx_buffers) - 1];
287 _vec_len (my_tx_buffers) -= 1;
297 u32 *to_next, next_index;
300 b->
flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
308 f = tm->tx_frames[!is_ip4][thread_index];
313 tm->tx_frames[!is_ip4][thread_index] = f;
321 tm->tx_frames[!is_ip4][thread_index] = 0;
334 u8 is_ip4,
u32 fib_index,
u8 flush)
338 u32 *to_next, next_index;
341 b->
flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
355 f = tm->ip_lookup_tx_frames[!is_ip4][thread_index];
360 tm->ip_lookup_tx_frames[!is_ip4][thread_index] = f;
369 tm->ip_lookup_tx_frames[!is_ip4][thread_index] = 0;
375 u8 is_ip4,
u32 fib_index)
396 if (sub_conn->c_is_ip4)
410 u16 pointer_offset =
sizeof (init_chunk);
411 if (sub_conn->c_is_ip4)
421 ip6_param->
address.
as_u64[0] = sub_conn->c_lcl_ip.ip6.as_u64[0];
422 ip6_param->
address.
as_u64[1] = sub_conn->c_lcl_ip.ip6.as_u64[1];
439 init_chunk->
a_rwnd = clib_host_to_net_u32 (sctp_conn->sub_conn[idx].cwnd);
447 clib_host_to_net_u32 (sctp_conn->local_initial_tsn);
449 sctp_conn->local_initial_tsn);
453 vnet_buffer (b)->sctp.connection_index = sub_conn->c_c_index;
458 "SRC_PORT = %u, DST_PORT = %u",
459 sub_conn->connection.c_index,
471 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 476 unsigned int len = 0;
477 const EVP_MD *md = EVP_sha1 ();
478 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 479 ctx = HMAC_CTX_new ();
482 HMAC_Update (ctx, (
const unsigned char *) &sctp_conn,
sizeof (sctp_conn));
483 HMAC_Final (ctx, state_cookie->
mac, &len);
485 HMAC_CTX_init (&ctx);
488 HMAC_Update (&ctx, (
const unsigned char *) &sctp_conn,
sizeof (sctp_conn));
489 HMAC_Final (&ctx, state_cookie->
mac, &len);
490 HMAC_CTX_cleanup (&ctx);
518 sctp_conn->sub_conn[idx].connection.lcl_port;
520 sctp_conn->sub_conn[idx].connection.rmt_port;
526 sctp_conn->sub_conn[idx].connection.c_index;
550 sctp_conn->sub_conn[idx].connection.lcl_port;
552 sctp_conn->sub_conn[idx].connection.rmt_port;
560 sctp_conn->sub_conn[idx].connection.c_index;
578 clib_warning (
"Reached MAX_INIT_RETRANS times. Aborting connection.");
600 sctp_conn->sub_conn[idx].RTO);
603 sctp_conn->state = SCTP_STATE_COOKIE_WAIT;
637 err_chunk->
sctp_hdr.
src_port = sctp_conn->sub_conn[idx].connection.lcl_port;
638 err_chunk->
sctp_hdr.
dst_port = sctp_conn->sub_conn[idx].connection.rmt_port;
651 sctp_conn->sub_conn[idx].connection.c_index;
682 sctp_conn->sub_conn[idx].connection.lcl_port;
684 sctp_conn->sub_conn[idx].connection.rmt_port;
692 sctp_conn->sub_conn[idx].connection.c_index;
726 if (sctp_conn->sub_conn[idx].connection.is_ip4)
787 if (sctp_conn->sub_conn[idx].connection.is_ip4)
791 sctp_conn->sub_conn[idx].connection.lcl_ip.ip4.as_u32;
799 sctp_conn->sub_conn[idx].connection.lcl_ip.ip6.as_u64[0];
801 sctp_conn->sub_conn[idx].connection.lcl_ip.ip6.as_u64[1];
809 sctp_conn->sub_conn[idx].connection.lcl_port;
811 sctp_conn->sub_conn[idx].connection.rmt_port;
815 clib_host_to_net_u32 (sctp_conn->local_initial_tsn);
825 clib_host_to_net_u32 (sctp_conn->sub_conn[idx].cwnd);
832 sctp_conn->sub_conn[idx].connection.c_index;
866 if (sctp_conn->sub_conn[idx].connection.is_ip4)
927 if (sctp_conn->sub_conn[idx].connection.is_ip4)
931 sctp_conn->sub_conn[idx].connection.lcl_ip.ip4.as_u32;
939 sctp_conn->sub_conn[idx].connection.lcl_ip.ip6.as_u64[0];
941 sctp_conn->sub_conn[idx].connection.lcl_ip.ip6.as_u64[1];
949 sctp_conn->sub_conn[idx].connection.lcl_port;
951 sctp_conn->sub_conn[idx].connection.rmt_port;
955 clib_host_to_net_u32 (sctp_conn->local_initial_tsn);
963 clib_host_to_net_u32 (
random_u32 (&random_seed));
966 clib_host_to_net_u32 (sctp_conn->sub_conn[idx].cwnd);
975 sctp_conn->sub_conn[idx].connection.c_index;
1001 sctp_conn->sub_conn[idx].connection.lcl_port;
1003 sctp_conn->sub_conn[idx].connection.rmt_port;
1011 sctp_conn->sub_conn[idx].connection.c_index;
1039 sctp_conn->sub_conn[idx].connection.is_ip4);
1060 sctp_conn->sub_conn[idx].connection.lcl_port;
1062 sctp_conn->sub_conn[idx].connection.rmt_port;
1069 sctp_conn->sub_conn[idx].connection.c_index;
1121 sctp_conn->ack_state = 0;
1124 sctp_conn->sub_conn[idx].connection.c_index;
1163 sctp_conn->sub_conn[idx].connection.c_index;
1198 sctp_conn->sub_conn[idx].connection.c_index;
1228 sctp_conn->sub_conn[i].
1231 sctp_conn->sub_conn[
i].unacknowledged_hb += 1;
1254 sctp_conn->sub_conn[idx].connection.lcl_port;
1256 sctp_conn->sub_conn[idx].connection.rmt_port;
1263 sctp_conn->sub_conn[idx].connection.c_index;
1294 clib_warning (
"Reached MAX_INIT_RETRANS times. Aborting connection.");
1317 sctp_conn->sub_conn[idx].c_fib_index);
1321 sctp_conn->sub_conn[idx].RTO);
1324 sctp_conn->state = SCTP_STATE_COOKIE_WAIT;
1339 if (b->
flags & VLIB_BUFFER_TOTAL_LENGTH_VALID)
1343 || (b->
flags & VLIB_BUFFER_NEXT_PRESENT));
1346 "b->current_data = %p " 1351 if (data_padding > 0)
1365 (
"SCTP_CONN = %p, IDX = %u, S_INDEX = %u, C_INDEX = %u, sctp_conn->[...].LCL_PORT = %u, sctp_conn->[...].RMT_PORT = %u",
1366 sctp_conn, idx, sctp_conn->sub_conn[idx].connection.s_index,
1367 sctp_conn->sub_conn[idx].connection.c_index,
1368 sctp_conn->sub_conn[idx].connection.lcl_port,
1369 sctp_conn->sub_conn[idx].connection.rmt_port);
1372 sctp_conn->sub_conn[idx].connection.lcl_port;
1374 sctp_conn->sub_conn[idx].connection.rmt_port;
1377 data_chunk->
tsn = clib_host_to_net_u32 (sctp_conn->next_tsn);
1378 data_chunk->
stream_id = clib_host_to_net_u16 (0);
1379 data_chunk->
stream_seq = clib_host_to_net_u16 (0);
1393 sctp_conn->last_unacked_tsn = sctp_conn->next_tsn;
1396 sctp_conn->next_tsn += data_len;
1398 u32 inflight = sctp_conn->next_tsn - sctp_conn->last_unacked_tsn;
1400 if (sctp_conn->sub_conn[idx].partially_acked_bytes >=
1401 sctp_conn->sub_conn[idx].cwnd
1402 && inflight >= sctp_conn->sub_conn[idx].cwnd)
1404 sctp_conn->sub_conn[idx].cwnd += sctp_conn->sub_conn[idx].PMTU;
1405 sctp_conn->sub_conn[idx].partially_acked_bytes -=
1406 sctp_conn->sub_conn[idx].cwnd;
1412 sctp_conn->sub_conn[idx].connection.c_index;
1424 "S_INDEX = %u, C_INDEX = %u," 1425 "trans_conn->LCL_PORT = %u, trans_conn->RMT_PORT = %u",
1428 trans_conn->s_index,
1429 trans_conn->c_index,
1430 trans_conn->lcl_port, trans_conn->rmt_port);
1448 u32 bi, available_bytes, seg_size;
1451 ASSERT (sctp_conn->state >= SCTP_STATE_ESTABLISHED);
1452 ASSERT (max_deq_bytes != 0);
1459 ASSERT (available_bytes >= offset);
1460 available_bytes -=
offset;
1461 if (!available_bytes)
1463 max_deq_bytes =
clib_min (sctp_conn->sub_conn[idx].cwnd, max_deq_bytes);
1464 max_deq_bytes =
clib_min (available_bytes, max_deq_bytes);
1466 seg_size = max_deq_bytes;
1482 data, offset, max_deq_bytes);
1483 ASSERT (n_bytes == max_deq_bytes);
1496 u32 bi, n_bytes = 0;
1501 (
"SCTP_CONN = %p, IDX = %u, S_INDEX = %u, C_INDEX = %u, sctp_conn->[...].LCL_PORT = %u, sctp_conn->[...].RMT_PORT = %u",
1502 sctp_conn, idx, sctp_conn->sub_conn[idx].connection.s_index,
1503 sctp_conn->sub_conn[idx].connection.c_index,
1504 sctp_conn->sub_conn[idx].connection.lcl_port,
1505 sctp_conn->sub_conn[idx].connection.rmt_port);
1507 if (sctp_conn->state >= SCTP_STATE_ESTABLISHED)
1514 sctp_conn->sub_conn[idx].cwnd, &b);
1521 sctp_conn->sub_conn[idx].connection.is_ip4);
1526 #if SCTP_DEBUG_STATE_MACHINE 1532 switch (sctp_conn->state)
1534 case SCTP_STATE_CLOSED:
1538 case SCTP_STATE_ESTABLISHED:
1544 case SCTP_STATE_COOKIE_WAIT:
1548 case SCTP_STATE_SHUTDOWN_SENT:
1552 case SCTP_STATE_SHUTDOWN_RECEIVED:
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
void sctp_prepare_heartbeat_ack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to HEARTBEAT_ACK.
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static void sctp_enqueue_to_ip_lookup(vlib_main_t *vm, vlib_buffer_t *b, u32 bi, u8 is_ip4, u32 fib_index)
void sctp_connection_timers_reset(sctp_connection_t *sctp_conn)
Stop all connection timers.
sctp_chunks_common_hdr_t chunk_hdr
u16 sctp_check_outstanding_data_chunks(sctp_connection_t *sctp_conn)
struct _sctp_main sctp_main_t
static void sctp_timer_set(sctp_connection_t *tc, u8 conn_idx, u8 timer_id, u32 interval)
void session_flush_frames_main_thread(vlib_main_t *vm)
static void vnet_sctp_set_ebit(sctp_chunks_common_hdr_t *h)
sctp_state_cookie_param_t cookie
static uword random_default_seed(void)
Default random seed (unix/linux user-mode)
void sctp_flush_frames_to_output(u8 thread_index)
Flush v4 and v6 sctp and ip-lookup tx frames for thread index.
int session_tx_fifo_peek_bytes(transport_connection_t *tc, u8 *buffer, u32 offset, u32 max_bytes)
void sctp_prepare_cookie_ack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
#define SCTP_ADV_DBG_OUTPUT(_fmt, _args...)
#define SCTP_IPV4_ADDRESS_TYPE_LENGTH
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
struct _sctp_sub_connection sctp_sub_connection_t
#define clib_memcpy_fast(a, b, c)
#define INBOUND_STREAMS_COUNT
sctp_chunks_common_hdr_t chunk_hdr
static u64 sctp_time_now(void)
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.
u16 current_length
Nbytes between current data and the end of this buffer.
vlib_node_registration_t sctp6_output_node
(constructor) VLIB_REGISTER_NODE (sctp6_output_node)
sctp_chunks_common_hdr_t chunk_hdr
static ip_csum_t ip_csum_with_carry(ip_csum_t sum, ip_csum_t x)
sctp_chunks_common_hdr_t chunk_hdr
void sctp_compute_mac(sctp_connection_t *sctp_conn, sctp_state_cookie_param_t *state_cookie)
sctp_chunks_common_hdr_t chunk_hdr
uword as_uword[16/sizeof(uword)]
static sctp_main_t * vnet_get_sctp_main()
static void vnet_sctp_common_hdr_params_host_to_net(sctp_chunks_common_hdr_t *h)
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
void sctp_send_shutdown_ack(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
void sctp_prepare_sack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to SACK.
sctp_chunks_common_hdr_t chunk_hdr
static void sctp_init_cwnd(sctp_connection_t *sctp_conn)
static void vnet_sctp_set_chunk_type(sctp_chunks_common_hdr_t *h, sctp_chunk_type t)
static void sctp_enqueue_to_ip_lookup_i(vlib_main_t *vm, vlib_buffer_t *b, u32 bi, u8 is_ip4, u32 fib_index, u8 flush)
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
static void sctp_enqueue_to_output_now(vlib_main_t *vm, vlib_buffer_t *b, u32 bi, u8 is_ip4)
#define SCTP_STATE_COOKIE_TYPE
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
static void sctp_push_hdr_i(sctp_connection_t *sctp_conn, vlib_buffer_t *b, sctp_state_t next_state)
Push SCTP header and update connection variables.
vlib_error_t error
Error code for buffers to be enqueued to error handler.
#define TRANSPORT_MAX_HDRS_LEN
#define SCTP_DBG_OUTPUT(_fmt, _args...)
void sctp_data_retransmit(sctp_connection_t *sctp_conn)
void sctp_prepare_init_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to INIT.
static sctp_connection_t * sctp_get_connection_from_transport(transport_connection_t *tconn)
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.
static void * vlib_buffer_make_headroom(vlib_buffer_t *b, u8 size)
Make head room, typically for packet headers.
sctp_init_chunk_t sctp_init_ack_chunk_t
sctp_opt_params_hdr_t param_hdr
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
static void sctp_enqueue_to_output_i(vlib_main_t *vm, vlib_buffer_t *b, u32 bi, u8 is_ip4, u8 flush)
#define OUTBOUND_STREAMS_COUNT
struct _sctp_connection sctp_connection_t
#define SCTP_IPV6_ADDRESS_TYPE
vl_api_address_union_t src_address
static void * sctp_reuse_buffer(vlib_main_t *vm, vlib_buffer_t *b)
#define MAX_SCTP_CONNECTIONS
static void sctp_flush_frame_to_ip_lookup(vlib_main_t *vm, u8 thread_index, u8 is_ip4)
Flush ip lookup tx frames populated by timer pops.
static char * sctp_state_to_string(u8 state)
vlib_node_registration_t sctp4_output_node
(constructor) VLIB_REGISTER_NODE (sctp4_output_node)
sctp_hb_req_chunk_t sctp_hb_ack_chunk_t
enum _sctp_state sctp_state_t
unsigned char mac[SHA1_OUTPUT_LENGTH]
static_always_inline uword vlib_get_thread_index(void)
void sctp_push_ip_hdr(sctp_main_t *tm, sctp_sub_connection_t *sctp_sub_conn, vlib_buffer_t *b)
sctp_chunks_common_hdr_t chunk_hdr
static ip_csum_t ip_incremental_checksum(ip_csum_t sum, void *_data, uword n_bytes)
void sctp_send_init(sctp_connection_t *sctp_conn)
#define clib_warning(format, args...)
#define VLIB_BUFFER_TRACE_TRAJECTORY
Compile time buffer trajectory tracing option Turn this on if you run into "bad monkey" contexts...
void sctp_send_cookie_echo(sctp_connection_t *sctp_conn)
void sctp_prepare_shutdown_ack_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to SHUTDOWN_ACK.
static int sctp_alloc_tx_buffers(sctp_main_t *tm, u8 thread_index, u32 n_free_buffers)
struct _transport_connection transport_connection_t
#define sctp_trajectory_add_start(b, start)
void sctp_prepare_shutdown_complete_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to SHUTDOWN_COMPLETE.
sctp_opt_params_hdr_t param_hdr
u32 ip4_sctp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
static u32 transport_max_tx_dequeue(transport_connection_t *tc)
vlib_node_registration_t ip6_lookup_node
(constructor) VLIB_REGISTER_NODE (ip6_lookup_node)
void sctp_prepare_shutdown_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to SHUTDOWN.
sctp_opt_params_hdr_t param_hdr
u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]
Space for inserting data before buffer start.
#define SCTP_PRIMARY_PATH_IDX
static u16 vnet_sctp_calculate_padding(u16 base_length)
#define SCTP_CONN_TRACKING_DBG(_fmt, _args...)
static void * sctp_init_buffer(vlib_main_t *vm, vlib_buffer_t *b)
#define clib_mem_unaligned(pointer, type)
sctp_chunks_common_hdr_t chunk_hdr
void sctp_connection_cleanup(sctp_connection_t *sctp_conn)
Cleans up connection state.
static_always_inline void clib_memset_u8(void *p, u8 val, uword count)
static vlib_main_t * vlib_get_main(void)
sctp_hb_info_param_t hb_info
template key/value backing page structure
void sctp_prepare_heartbeat_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b)
Convert buffer to HEARTBEAT.
void sctp_send_shutdown_complete(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b0)
static void * vlib_buffer_push_uninit(vlib_buffer_t *b, u8 size)
Prepend uninitialized data to buffer.
#define SCTP_IPV4_ADDRESS_TYPE
u32 ip6_sctp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
u32 sctp_prepare_data_retransmit(sctp_connection_t *sctp_conn, u8 idx, u32 offset, u32 max_deq_bytes, vlib_buffer_t **b)
static void * vlib_buffer_push_ip6(vlib_main_t *vm, vlib_buffer_t *b, ip6_address_t *src, ip6_address_t *dst, int proto)
Push IPv6 header to buffer.
void sctp_send_heartbeat(sctp_connection_t *sctp_conn)
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.
void sctp_prepare_operation_error(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u8 err_cause)
Convert buffer to ERROR.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u32 next_buffer
Next buffer for this linked-list of buffers.
sctp_err_cause_param_t err_causes[]
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
VLIB buffer representation.
#define SCTP_VALID_COOKIE_LIFE
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Linear Congruential Random Number Generator.
sctp_chunks_common_hdr_t chunk_hdr
struct clib_bihash_value offset
template key/value backing page structure
u32 sctp_push_header(transport_connection_t *trans_conn, vlib_buffer_t *b)
void sctp_prepare_cookie_echo_chunk(sctp_connection_t *sctp_conn, u8 idx, vlib_buffer_t *b, u8 reuse_buffer)
static char * sctp_chunk_to_string(u8 type)
static u32 random_u32(u32 *seed)
32-bit random number generator
int session_stream_connect_notify(transport_connection_t *tc, u8 is_fail)
#define ENDIANESS_SWAP(x)
static u32 vlib_num_workers()
sctp_opt_params_hdr_t param_hdr
static void * vlib_buffer_put_uninit(vlib_buffer_t *b, u16 size)
Append uninitialized data to buffer.
u16 outbound_streams_count
static void vlib_buffer_free_one(vlib_main_t *vm, u32 buffer_index)
Free one buffer Shorthand to free a single buffer chain.
static int ip4_header_bytes(const ip4_header_t *i)
static int sctp_get_free_buffer_index(sctp_main_t *tm, u32 *bidx)
static void vnet_sctp_set_bbit(sctp_chunks_common_hdr_t *h)
static u8 sctp_data_subconn_select(sctp_connection_t *sctp_conn)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
#define SCTP_IPV6_ADDRESS_TYPE_LENGTH
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
sctp_chunks_common_hdr_t chunk_hdr
sctp_opt_params_hdr_t param_hdr
static void vnet_sctp_set_chunk_length(sctp_chunks_common_hdr_t *h, u16 length)
static void * vlib_buffer_push_ip4(vlib_main_t *vm, vlib_buffer_t *b, ip4_address_t *src, ip4_address_t *dst, int proto, u8 csum_offload)
Push IPv4 header to buffer.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
#define SCTP_DBG_STATE_MACHINE(_fmt, _args...)
#define SCTP_MAX_INIT_RETRANS
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.
void sctp_send_shutdown(sctp_connection_t *sctp_conn)
sctp_chunks_common_hdr_t chunk_hdr