18 #include <openssl/hmac.h> 28 #define foreach_sctp4_output_next \ 29 _ (DROP, "error-drop") \ 30 _ (IP_LOOKUP, "ip4-lookup") 32 #define foreach_sctp6_output_next \ 33 _ (DROP, "error-drop") \ 34 _ (IP_LOOKUP, "ip6-lookup") 37 #define sctp_error(n,s) s, 42 typedef enum _sctp_output_next
58 return sctp_conn->sub_conn[idx].is_retransmitting;
66 u32 n_left_from, next_index, *from, *to_next;
74 while (n_left_from > 0)
80 while (n_left_from > 0 && n_left_to_next > 0)
88 u32 error0 = SCTP_ERROR_PKTS_SENT, next0 =
91 #if SCTP_DEBUG_STATE_MACHINE 92 u16 packet_length = 0;
110 error0 = SCTP_ERROR_INVALID_CONNECTION;
140 packet_length = clib_net_to_host_u16 (iph4->
length);
177 (
"Trying to send an unrecognized chunk... something is really bad.");
178 error0 = SCTP_ERROR_UNKNOWN_CHUNK;
183 #if SCTP_DEBUG_STATE_MACHINE 185 (sctp_conn->sub_conn[idx].connection.lcl_port ==
187 || sctp_conn->sub_conn[idx].connection.lcl_port ==
189 && (sctp_conn->sub_conn[idx].connection.rmt_port ==
191 || sctp_conn->sub_conn[idx].connection.rmt_port ==
197 "packet_length = %u, " 198 "chunk_type = %u [%s], " 199 "connection.lcl_port = %u, sctp_hdr->src_port = %u, " 200 "connection.rmt_port = %u, sctp_hdr->dst_port = %u",
201 sctp_conn->sub_conn[idx].
202 connection.c_index, packet_length,
205 sctp_conn->sub_conn[idx].
206 connection.lcl_port, sctp_hdr->
src_port,
207 sctp_conn->sub_conn[idx].
211 error0 = SCTP_ERROR_UNKNOWN_CHUNK;
217 (
"SESSION_INDEX = %u, CONN_INDEX = %u, CURR_CONN_STATE = %u (%s), " 218 "CHUNK_TYPE = %s, " "SRC_PORT = %u, DST_PORT = %u",
219 sctp_conn->sub_conn[idx].connection.s_index,
220 sctp_conn->sub_conn[idx].connection.c_index,
226 #if SCTP_DEBUG_STATE_MACHINE 227 if (sctp_validate_output_state_machine (sctp_conn, chunk_type) != 0)
230 (
"Sending the wrong chunk (%s) based on state-machine status (%s)",
234 error0 = SCTP_ERROR_UNKNOWN_CHUNK;
247 if (chunk_type ==
DATA 248 && sctp_conn->sub_conn[idx].RTO_pending == 0)
250 sctp_conn->sub_conn[idx].RTO_pending = 1;
262 sctp_conn->state = SCTP_STATE_COOKIE_ECHOED;
270 sctp_conn->sub_conn[idx].RTO);
277 sctp_conn->sub_conn[idx].RTO);
278 sctp_conn->state = SCTP_STATE_SHUTDOWN_SENT;
285 sctp_conn->sub_conn[idx].RTO);
286 sctp_conn->state = SCTP_STATE_SHUTDOWN_ACK_SENT;
291 sctp_conn->state = SCTP_STATE_CLOSED;
298 sctp_conn->sub_conn[idx].c_fib_index;
300 b0->
flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
303 (
"SESSION_INDEX = %u, CONNECTION_INDEX = %u, " "NEW_STATE = %s, " 304 "CHUNK_SENT = %s", sctp_conn->sub_conn[idx].connection.s_index,
305 sctp_conn->sub_conn[idx].connection.c_index,
330 n_left_to_next, bi0, next0);
356 .name =
"sctp4-output",
358 .vector_size =
sizeof (
u32),
363 #define _(s,n) [SCTP_OUTPUT_NEXT_##s] = n, 375 .name =
"sctp6-output",
377 .vector_size =
sizeof (
u32),
382 #define _(s,n) [SCTP_OUTPUT_NEXT_##s] = n, 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_timer_set(sctp_connection_t *tc, u8 conn_idx, u8 timer_id, u32 interval)
#define SCTP_ADV_DBG_OUTPUT(_fmt, _args...)
#define clib_memcpy_fast(a, b, c)
u32 ip4_sctp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip4_header_t *ip0)
static u64 sctp_time_now(void)
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
#define VLIB_NODE_FN(node)
vlib_error_t * errors
Vector of errors for this node.
static void vnet_sctp_common_hdr_params_host_to_net(sctp_chunks_common_hdr_t *h)
#define foreach_sctp6_output_next
enum _sctp_output_next sctp_output_next_t
static void * ip4_next_header(ip4_header_t *i)
static char * sctp_error_strings[]
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static uword sctp46_output_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
u8 * format_sctp_tx_trace(u8 *s, va_list *args)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
struct _sctp_connection sctp_connection_t
static u64 sctp_set_time_now(u32 thread_index)
vlib_node_registration_t sctp4_output_node
(constructor) VLIB_REGISTER_NODE (sctp4_output_node)
#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.
#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).
vlib_node_registration_t sctp6_output_node
(constructor) VLIB_REGISTER_NODE (sctp6_output_node)
static char * sctp_state_to_string(u8 state)
static u8 vnet_sctp_get_chunk_type(sctp_chunks_common_hdr_t *h)
sctp_chunks_common_hdr_t common_hdr
#define VLIB_REGISTER_NODE(x,...)
#define foreach_sctp4_output_next
#define clib_warning(format, args...)
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.
static void * ip6_next_header(ip6_header_t *i)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
sctp_connection_t sctp_connection
u32 ip6_sctp_compute_checksum(vlib_main_t *vm, vlib_buffer_t *p0, ip6_header_t *ip0, int *bogus_lengthp)
sctp_header_t sctp_header
static void sctp_timer_update(sctp_connection_t *tc, u8 conn_idx, u8 timer_id, u32 interval)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static sctp_connection_t * sctp_connection_get(u32 conn_index, u32 thread_index)
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.
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define SCTP_DEBUG_STATE_MACHINE
Linear Congruential Random Number Generator.
static char * sctp_chunk_to_string(u8 type)
static u8 sctp_is_retransmitting(sctp_connection_t *sctp_conn, u8 idx)
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...)