15 #include <netinet/in.h> 29 u32 session_tables[2];
36 #define _(node_name, node_var, is_out, is_ip6, is_track) \ 37 static u8 * format_## node_var ##_trace (u8 * s, va_list * args) \ 39 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); \ 40 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); \ 41 l2sess_trace_t * t = va_arg (*args, l2sess_trace_t *); \ 43 s = format (s, node_name ": sw_if_index %d, next index %d trace_flags %08x L4 proto %d\n" \ 44 " tables [ %d, %d ] nexts [ %d, %d ]", \ 45 t->sw_if_index, t->next_index, t->trace_flags, t->l4_proto, \ 46 t->session_tables[0], t->session_tables[1], \ 47 t->session_nexts[0], t->session_nexts[1]); \ 52 #define foreach_l2sess_error \ 53 _(SWAPPED, "Mac swap packets processed") 56 #define _(sym,str) L2SESS_ERROR_##sym, 63 #define _(sym,string) string, 99 flags_offset = 14 + 40 + 13;
103 flags_offset = 14 + 20 + 13;
112 return ((proto == 6) || (proto == 17));
117 int node_is_out,
int node_is_ip6,
u8 l4_proto,
118 u32 * session_tables)
128 u32 output_table_index;
129 u32 input_table_index;
139 classify_table_index_by_sw_if_index
147 classify_table_index_by_sw_if_index
158 classify_table_index_by_sw_if_index
166 classify_table_index_by_sw_if_index
177 session_tables[0] = output_table_index;
178 session_tables[1] = input_table_index;
182 session_tables[0] = input_table_index;
183 session_tables[1] = output_table_index;
189 int node_is_out,
int node_is_ip6,
u8 l4_proto,
197 u32 input_node_index;
198 u32 output_node_index;
212 session_nexts[0] = output_node_index;
213 session_nexts[1] = input_node_index;
217 session_nexts[0] = input_node_index;
218 session_nexts[1] = output_node_index;
263 u32 session_table,
u32 session_match_next,
270 #ifdef DEBUG_SESSIONS 271 printf (
"Adding session to table %d with next %d\n", session_table,
276 session_match_next, opaque_index, 0, action,
330 *(
u16 *) & match[54] = htons (sess->
side[1 - is_out].
port);
331 *(
u16 *) & match[56] = htons (sess->
side[is_out].
port);
338 *(
u16 *) & match[34] = htons (sess->
side[1 - is_out].
port);
339 *(
u16 *) & match[36] = htons (sess->
side[is_out].
port);
348 u32 session_tables[2] = { ~0, ~0 };
357 if (session_tables[1] != ~0)
363 if (session_tables[1] != ~0)
374 int which_side,
u64 now)
390 int which_side,
u64 now)
460 int is_alive = ((now - last_active) < timeout);
461 if (last_active_cache)
462 *last_active_cache = last_active;
475 #ifdef DEBUG_SESSIONS_VERBOSE 505 #ifdef DEBUG_SESSIONS 506 clib_warning (
"Restarting timer for session %d", (
int) session_index);
516 #ifdef DEBUG_SESSIONS 517 clib_warning (
"Deleting session %d", (
int) session_index);
530 int node_is_out,
int node_is_ip6,
int node_is_track,
531 u32 *feat_next_node_index)
533 u32 n_left_from, *from, *to_next;
535 u32 pkts_swapped = 0;
545 while (n_left_from > 0)
553 while (n_left_from > 0 && n_left_to_next > 0)
580 u32 session_tables[2] = { ~0, ~0 };
581 u32 session_nexts[2] = { ~0, ~0 };
595 feature_bitmap0 =
vnet_buffer (b0)->l2.feature_bitmap;
643 sess->
is_ip6 = node_is_ip6;
654 node_is_ip6, l4_proto,
657 node_is_ip6, l4_proto,
660 if (session_tables[1] != ~0)
663 session_tables[1], session_nexts[1],
667 if (session_tables[0] != ~0)
670 session_tables[0], session_nexts[0],
724 to_next, n_left_to_next,
731 L2SESS_ERROR_SWAPPED, pkts_swapped);
736 #define _(node_name, node_var, is_out, is_ip6, is_track) \ 738 node_var ## node_fn (vlib_main_t * vm, \ 739 vlib_node_runtime_t * node, \ 740 vlib_frame_t * frame) \ 742 l2sess_main_t *sm = &l2sess_main; \ 743 return l2sess_node_fn(vm, node, frame, \ 744 is_out, is_ip6, is_track, \ 745 sm->node_var ## _feat_next_node_index); \ 747 VLIB_REGISTER_NODE (node_var) = { \ 748 .function = node_var ## node_fn, \ 750 .vector_size = sizeof (u32), \ 751 .format_trace = format_ ## node_var ## _trace, \ 752 .type = VLIB_NODE_TYPE_INTERNAL, \ 754 .n_errors = ARRAY_LEN(l2sess_error_strings), \ 755 .error_strings = l2sess_error_strings, \ 757 .n_next_nodes = L2SESS_N_NEXT, \ 759 [L2SESS_NEXT_DROP] = "error-drop", \ 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.
void l2sess_get_session_nexts(l2sess_main_t *sm, u32 sw_if_index, int node_is_out, int node_is_ip6, u8 l4_proto, u32 *session_nexts)
sll srl srl sll sra u16x4 i
static int l4_tcp_or_udp(u8 proto)
static void swap_bytes(vlib_buffer_t *b0, int off_a, int off_b, int nbytes)
static u64 get_session_last_active_time(l2s_session_t *sess)
#define TCP_FLAGS_RSTFINACKSYN
static uword l2sess_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int node_is_out, int node_is_ip6, int node_is_track, u32 *feat_next_node_index)
static void build_match_from_session(l2sess_main_t *sm, u8 *match, l2s_session_t *sess, int is_out)
static u64 clib_cpu_time_now(void)
#define pool_is_free(P, E)
Use free bitmap to query whether given element is free.
void timing_wheel_insert(timing_wheel_t *w, u64 insert_cpu_time, u32 user_data)
static u64 udp_session_get_timeout(l2sess_main_t *sm, l2s_session_t *sess, u64 now)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static int session_is_alive(l2sess_main_t *sm, l2s_session_t *sess, u64 now, u64 *last_active_cache)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
void l2sess_add_session(vlib_buffer_t *b0, int node_is_out, int node_is_ip6, u32 session_table, u32 session_match_next, u32 opaque_index)
#define clib_warning(format, args...)
l2s_session_side_t side[L2S_N_SESSION_SIDES]
int vnet_classify_add_del_session(vnet_classify_main_t *cm, u32 table_index, u8 *match, u32 hit_next_index, u32 opaque_index, i32 advance, u8 action, u32 metadata, int is_add)
static char * l2sess_error_strings[]
void l2sess_flip_l3l4_fields(vlib_buffer_t *b0, int node_is_ip6, u8 l4_proto)
l2_output_classify_main_t l2_output_classify_main
l2 output classifier main data structure.
#define foreach_l2sess_error
u16 current_length
Nbytes between current data and the end of this buffer.
timing_wheel_t timing_wheel
struct _l2_classify_main l2_output_classify_main_t
#define pool_put(P, E)
Free an object E in pool P.
void l2sess_get_session_tables(l2sess_main_t *sm, u32 sw_if_index, int node_is_out, int node_is_ip6, u8 l4_proto, u32 *session_tables)
#define foreach_l2sess_node
static u32 feat_bitmap_get_next_node_index(u32 *next_nodes, u32 bitmap)
Return the graph node index for the feature corresponding to the first set bit in the bitmap...
#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).
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
u8 l2sess_get_l4_proto(vlib_buffer_t *b0, int node_is_ip6)
static u64 tcp_session_get_timeout(l2sess_main_t *sm, l2s_session_t *sess, u64 now)
static void delete_session(l2sess_main_t *sm, u32 sw_if_index, u32 session_index)
#define clib_memcpy(a, b, c)
u32 * timing_wheel_advance(timing_wheel_t *w, u64 advance_cpu_time, u32 *expired_user_data, u64 *next_expiring_element_cpu_time)
void timing_wheel_delete(timing_wheel_t *w, u32 user_data)
void session_store_ip4_l3l4_info(vlib_buffer_t *b0, l2s_session_t *sess, int node_is_out)
l2_input_classify_main_t l2_input_classify_main
l2 input classifier main data structure.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
struct _vnet_classify_main vnet_classify_main_t
u64 timer_wheel_next_expiring_time
u32 * data_from_advancing_timing_wheel
l2sess_main_t l2sess_main
#define VLIB_NODE_FLAG_TRACE
vnet_classify_main_t vnet_classify_main
void session_store_ip6_l3l4_info(vlib_buffer_t *b0, l2s_session_t *sess, int node_is_out)
#define VLIB_BUFFER_IS_TRACED
u8 l2sess_get_tcp_flags(vlib_buffer_t *b0, int node_is_ip6)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
template key/value backing page structure
static void * get_ptr_to_offset(vlib_buffer_t *b0, int offset)
struct _l2_classify_main l2_input_classify_main_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static void tcp_session_account_buffer(vlib_buffer_t *b0, l2s_session_t *s, int which_side, u64 now)
static void check_idle_sessions(l2sess_main_t *sm, u32 sw_if_index, u64 now)
struct clib_bihash_value offset
template key/value backing page structure
static void udp_session_account_buffer(vlib_buffer_t *b0, l2s_session_t *s, int which_side, u64 now)
u64 udp_session_idle_timeout
u64 counter_attempted_delete_free_session
u64 tcp_session_transient_timeout
static u64 session_get_timeout(l2sess_main_t *sm, l2s_session_t *sess, u64 now)
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
u64 tcp_session_idle_timeout
u32 next_slot_track_node_by_is_ip6_is_out[2][2]