78 }) classify_data_or_mask_t;
84 #define foreach_sticky_hash_miss_error \ 85 _(MISSES, "forward flow classify misses") 89 #define _(sym,str) STICKY_HASH_MISS_ERROR_##sym, 92 STICKY_HASH_MISS_N_ERROR,
95 static char *sticky_hash_miss_error_strings[] = {
96 #define _(sym,string) string, 126 u32 n_left_from, *from, *to_next;
127 sticky_hash_miss_next_t next_index;
139 while (n_left_from > 0)
145 while (n_left_from > 0 && n_left_to_next > 0)
151 u32 fib_index0, ft_index0, rt_index0;
152 vnet_classify_table_3_t *ft0, *rt0;
153 vnet_classify_entry_3_t *fe0, *re0;
154 classify_data_or_mask_t *h0;
179 h0 = (classify_data_or_mask_t *) (mp->
rdata);
182 tmp = h0->ip.src_address.as_u32;
183 h0->ip.src_address.as_u32 = h0->ip.dst_address.as_u32;
184 h0->ip.dst_address.as_u32 = tmp;
193 ft0 = (vnet_classify_table_3_t *)
195 rt0 = (vnet_classify_table_3_t *)
199 vnet_classify_find_or_add_entry_3 (ft0, mp->
fdata, &was_found0);
203 re0 = vnet_classify_find_or_add_entry_3 (rt0, mp->
rdata, 0);
212 fe0->opaque_index = s - mp->
sessions;
213 re0->opaque_index = s - mp->
sessions;
229 em->
counters[node_counter_base_index +
230 STICKY_HASH_MISS_ERROR_MISSES] += 1;
236 to_next, n_left_to_next,
249 .name =
"sticky-hash-miss",
250 .vector_size =
sizeof (
u32),
254 .n_errors =
ARRAY_LEN(sticky_hash_miss_error_strings),
283 u32 fwd_sw_if_index,
u8 * fwd_mask,
284 u32 rev_sw_if_index,
u8 * rev_mask,
u32 nbuckets,
int enable_disable)
291 vnet_classify_table_3_t *ft, *rt;
299 ft = (vnet_classify_table_3_t *)
303 = ft - (vnet_classify_table_3_t *) cm->tables;
306 sticky_hash_miss_node.index);
310 rt = (vnet_classify_table_3_t *)
314 = rt - (vnet_classify_table_3_t *) cm->tables;
333 [fwd_sw_if_index] = ~0;
336 [fwd_sw_if_index] = ~0;
356 [rev_sw_if_index] = ~0;
359 [rev_sw_if_index] = ~0;
371 u32 fwd_sw_if_index = ~0, rev_sw_if_index = ~0;
372 int enable_disable = 1;
376 classify_data_or_mask_t fwd_mask, rev_mask;
389 else if (
unformat (input,
"nbuckets %d", &nbuckets))
391 else if (
unformat (input,
"disable"))
398 nbuckets = 1 <<
max_log2 (nbuckets);
400 if (fwd_sw_if_index == ~0)
403 if (rev_sw_if_index == ~0)
412 memset (&fwd_mask, 0,
sizeof (fwd_mask));
413 memset (&fwd_mask.ip.src_address, 0xff, 4);
415 memset (&rev_mask, 0,
sizeof (rev_mask));
416 memset (&rev_mask.ip.dst_address, 0xff, 4);
426 nbuckets, enable_disable);
437 "ip4_sticky_hash_enable_disable returned %d",
446 .path =
"ip sticky classify",
447 .short_help =
"ip sticky classify fwd <intfc> rev <intfc> " 448 "[nbuckets <nn>][disable]",
459 vnet_classify_table_3_t *t;
460 vnet_classify_entry_3_t *e;
464 classify_data_or_mask_t *match;
468 t = (vnet_classify_table_3_t *)
471 match = (classify_data_or_mask_t *) (e->key);
475 "[%6d] fwd src %U next index %d session %d fib %d\n" 476 " hits %lld last-heard %.6f\n",
479 e->next_index, e->opaque_index, fib->
table_id, e->hits, e->last_heard);
481 if (e->opaque_index != session - mp->
sessions)
482 s =
format (s,
"WARNING: forward session index mismatch!\n");
484 t = (vnet_classify_table_3_t *)
487 match = (classify_data_or_mask_t *) (e->key);
491 "[%6d] rev dst %U next index %d session %d\n" 492 " hits %lld last-heard %.6f\n",
495 e->next_index, e->opaque_index, e->hits, e->last_heard);
497 if (e->opaque_index != session - mp->
sessions)
498 s =
format (s,
"WARNING: reverse session index mismatch!\n");
499 s =
format (s,
"---------\n");
512 int dump_classifier_tables = 0;
521 else if (
unformat (input,
"dump-tables")
522 ||
unformat (input,
"dump-classifier-tables"))
523 dump_classifier_tables = 1;
543 dump_classifier_tables);
551 dump_classifier_tables);
559 vlib_cli_output (vm,
"%U", format_sticky_hash_session, mp, s);
568 .path =
"show sticky classify",
569 .short_help =
"Display sticky classifier tables",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static u8 * format_sticky_hash_miss_trace(u8 *s, va_list *args)
sticky_hash_session_t * sessions
vnet_main_t * vnet_get_main(void)
vlib_node_registration_t sticky_hash_miss_node
(constructor) VLIB_REGISTER_NODE (sticky_hash_miss_node)
u8 rdata[3 *sizeof(u32x4)]
#define foreach_sticky_hash_miss_error
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.
struct _vlib_node_registration vlib_node_registration_t
static char * sticky_hash_miss_error_strings[]
void vnet_l2_input_classify_enable_disable(u32 sw_if_index, int enable_disable)
Enable/disable l2 input classification on a specific interface.
u8 fdata[3 *sizeof(u32x4)]
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
unformat_function_t unformat_vnet_sw_interface
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
vnet_classify_main_t * vnet_classify_main
u32 fwd_classify_table_index
vlib_node_registration_t l2_input_classify_node
(constructor) VLIB_REGISTER_NODE (l2_input_classify_node)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
vnet_classify_table_t * vnet_classify_new_table(vnet_classify_main_t *cm, u8 *mask, u32 nbuckets, u32 memory_size, u32 skip_n_vectors, u32 match_n_vectors)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
u8 * format_sticky_hash_session(u8 *s, va_list *args)
u32 rev_classify_table_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vlib_error_main_t error_main
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
clib_error_t * sticky_hash_miss_init(vlib_main_t *vm)
#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).
#define vec_free(V)
Free vector's memory (no header).
u8 * format_classify_table(u8 *s, va_list *args)
#define VLIB_BUFFER_IS_TRACED
#define clib_memcpy(a, b, c)
typedef CLIB_PACKED(struct{ethernet_header_t eh;ip4_header_t ip;})
l2_input_classify_main_t l2_input_classify_main
l2 input classifier main data structure.
#define VLIB_CLI_COMMAND(x,...)
struct _vnet_classify_main vnet_classify_main_t
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static clib_error_t * show_ip4_sticky_hash_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
#define VLIB_NODE_FLAG_TRACE
vnet_classify_main_t vnet_classify_main
static uword is_pow2(uword x)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
#define vec_elt(v, i)
Get vector value at index i.
static int ip4_sticky_hash_enable_disable(sticky_hash_main_t *mp, u32 fwd_sw_if_index, u8 *fwd_mask, u32 rev_sw_if_index, u8 *rev_mask, u32 nbuckets, int enable_disable)
static uword sticky_hash_miss_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
struct _l2_classify_main l2_input_classify_main_t
static uword max_log2(uword x)
l2_input_classify_main_t * l2_input_classify_main
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define VLIB_REGISTER_NODE(x,...)
ip4_main_t ip4_main
Global ip4 main structure.
struct fib_table_t_ * fibs
Vector of FIBs.
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
#define vec_foreach(var, vec)
Vector iterator.
u16 flags
Copy of main node flags.
static clib_error_t * ip4_sticky_hash_init_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static uword pool_elts(void *v)
Number of active elements in a pool.