72 "%s: head %d feature_bitmap %x ethertype %x sw_if_index %d, next_index %d",
73 is_output ?
"OUT-FEAT-ARC" :
"IN-FEAT-ARC", t->
arc_head,
95 #define foreach_l2_in_feat_arc_error \ 96 _(DEFAULT, "in default") \ 99 #define foreach_l2_out_feat_arc_error \ 100 _(DEFAULT, "out default") \ 105 #define _(sym,str) L2_IN_FEAT_ARC_ERROR_##sym, 111 static char *l2_in_feat_arc_error_strings[] = {
112 #define _(sym,string) string, 119 #define _(sym,str) L2_OUT_FEAT_ARC_ERROR_##sym, 125 static char *l2_out_feat_arc_error_strings[] = {
126 #define _(sym,string) string, 134 #define get_u16(addr) ( *((u16 *)(addr)) ) 135 #define L2_FEAT_ARC_VEC_SIZE 2 141 for (ii = 0; ii < vector_sz; ii++)
147 u32 * out_sw_if_index)
150 for (ii = 0; ii < vector_sz; ii++)
162 for (ii = 0; ii < vector_sz; ii++)
166 out_ethertype[ii] = clib_net_to_host_u16 (
get_u16 (l3h0 - 2));
174 u16 * ethertype,
u8 ip4_arc,
u8 ip6_arc,
175 u8 nonip_arc,
u16 * out_next)
178 for (ii = 0; ii < vector_sz; ii++)
182 switch (ethertype[ii])
184 case ETHERNET_TYPE_IP4:
185 feature_arc = ip4_arc;
187 case ETHERNET_TYPE_IP6:
188 feature_arc = ip6_arc;
191 feature_arc = nonip_arc;
195 sw_if_index[ii], &next_index, b[ii]);
199 is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
200 L2INPUT_FEAT_INPUT_FEAT_ARC);
202 out_next[ii] = next_index;
211 for (ii = 0; ii < vector_sz; ii++)
215 is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
216 L2INPUT_FEAT_INPUT_FEAT_ARC);
228 for (ii = 0; ii < vector_sz; ii++)
236 t->
ethertype = arc_head ? ethertype[ii] : 0;
245 int arc_head,
int do_trace)
264 ethertype = ethertypes;
265 sw_if_index = sw_if_indices;
281 sw_if_index, ethertype, ip4_arc_index,
282 ip6_arc_index, nonip_arc_index, next);
290 maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
295 sw_if_index += vec_sz;
303 const int vec_sz = 1;
310 sw_if_index, ethertype, ip4_arc_index,
311 ip6_arc_index, nonip_arc_index, next);
319 maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
324 sw_if_index += vec_sz;
343 &l2_in_feat_arc_node, 1, 1);
347 &l2_in_feat_arc_node, 1, 0);
358 &l2_out_feat_arc_node, 1, 1);
362 &l2_out_feat_arc_node, 1, 0);
373 &l2_in_feat_arc_end_node, 0, 1);
377 &l2_in_feat_arc_end_node, 0, 0);
388 &l2_out_feat_arc_end_node, 0, 1);
392 &l2_out_feat_arc_end_node, 0, 0);
402 (
u32) enable_disable);
405 (
u32) enable_disable);
411 .arc_name =
"l2-input-ip4",
418 .arc_name =
"l2-output-ip4",
425 .arc_name =
"l2-input-ip6",
431 .arc_name =
"l2-output-ip6",
438 .arc_name =
"l2-input-nonip",
444 .arc_name =
"l2-output-nonip",
455 .name =
"l2-input-feat-arc",
457 .vector_size =
sizeof (
u32),
461 .n_errors =
ARRAY_LEN(l2_in_feat_arc_error_strings),
467 .name =
"l2-output-feat-arc",
469 .vector_size =
sizeof (
u32),
473 .n_errors =
ARRAY_LEN(l2_out_feat_arc_error_strings),
479 .name =
"l2-input-feat-arc-end",
481 .vector_size =
sizeof (
u32),
483 .sibling_of =
"l2-input-feat-arc",
487 .name =
"l2-output-feat-arc-end",
489 .vector_size =
sizeof (
u32),
491 .sibling_of =
"l2-output-feat-arc",
496 .arc_name =
"l2-input-ip4",
497 .node_name =
"l2-input-feat-arc-end",
503 .arc_name =
"l2-output-ip4",
504 .node_name =
"l2-output-feat-arc-end",
510 .arc_name =
"l2-input-ip6",
511 .node_name =
"l2-input-feat-arc-end",
518 .arc_name =
"l2-output-ip6",
519 .node_name =
"l2-output-feat-arc-end",
525 .arc_name =
"l2-input-nonip",
526 .node_name =
"l2-input-feat-arc-end",
533 .arc_name =
"l2-output-nonip",
534 .node_name =
"l2-output-feat-arc-end",
557 l2_in_feat_arc_end_node.index,
573 int has_features = 0;
581 return has_features > 0;
607 void *feature_config,
608 u32 n_feature_config_bytes)
611 if (arc_index == (
u8) ~ 0)
612 return VNET_API_ERROR_INVALID_VALUE;
618 enable_disable, feature_config,
619 n_feature_config_bytes);
625 if (had_features != has_features)
static vlib_node_registration_t l2_in_feat_arc_end_node
(constructor) VLIB_REGISTER_NODE (l2_in_feat_arc_end_node)
VNET_FEATURE_ARC_INIT(l2_in_ip4_arc, static)
static u8 * format_l2_out_feat_arc_trace(u8 *s, va_list *args)
char ** l2output_get_feat_names(void)
static int l2_is_input_arc(u8 arc_index)
u8 vnet_get_feature_arc_index(const char *s)
static int l2_has_features(u32 sw_if_index, int is_output)
u8 nonip_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
vnet_main_t * vnet_get_main(void)
static_always_inline void get_sw_if_index_xN(int vector_sz, int is_output, vlib_buffer_t **b, u32 *out_sw_if_index)
void vnet_l2_in_out_feat_arc_enable_disable(u32 sw_if_index, int is_output, int enable_disable)
static char * l2_in_feat_arc_error_strings[]
static_always_inline int vnet_have_features(u8 arc, u32 sw_if_index)
static u32 vnet_l2_feature_next(vlib_buffer_t *b, u32 *next_nodes, u32 feat_bit)
Return the graph node index for the feature corresponding to the next set bit after clearing the curr...
VNET_FEATURE_INIT(l2_in_ip4_arc_end, static)
#define static_always_inline
static vlib_node_registration_t l2_out_feat_arc_node
(constructor) VLIB_REGISTER_NODE (l2_out_feat_arc_node)
#define VLIB_INIT_FUNCTION(x)
#define foreach_l2_out_feat_arc_error
static u8 * format_l2_in_feat_arc_trace(u8 *s, va_list *args)
static_always_inline void get_ethertype_xN(int vector_sz, int is_output, vlib_buffer_t **b, u16 *out_ethertype)
#define VLIB_NODE_FUNCTION_MULTIARCH(node, fn)
static_always_inline void set_next_in_arc_tail_xN(int vector_sz, int is_output, u32 *next_nodes, vlib_buffer_t **b, u16 *out_next)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define L2_FEAT_ARC_VEC_SIZE
void l2output_intf_bitmap_enable(u32 sw_if_index, l2output_feat_masks_t feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
static_always_inline void maybe_trace_xN(int vector_sz, int arc_head, vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t **b, u32 *sw_if_index, u16 *ethertype, u16 *next)
static char * l2_out_feat_arc_error_strings[]
int vnet_l2_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
#define VLIB_REGISTER_NODE(x,...)
#define CLIB_PREFETCH(addr, size, type)
static vlib_node_registration_t l2_out_feat_arc_end_node
(constructor) VLIB_REGISTER_NODE (l2_out_feat_arc_end_node)
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
static uword l2_in_out_feat_arc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int is_output, vlib_node_registration_t *fa_node, int arc_head, int do_trace)
static void feat_bitmap_init_next_nodes(vlib_main_t *vm, u32 node_index, u32 num_features, char **feat_names, u32 *next_nodes)
Initialize the feature next-node indexes of a graph node.
static_always_inline void buffer_prefetch_xN(int vector_sz, vlib_buffer_t **b)
static uword l2_in_feat_arc_end_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
u32 feat_next_node_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS][32]
static_always_inline void set_next_in_arc_head_xN(int vector_sz, int is_output, u32 *next_nodes, vlib_buffer_t **b, u32 *sw_if_index, u16 *ethertype, u8 ip4_arc, u8 ip6_arc, u8 nonip_arc, u16 *out_next)
#define foreach_l2_in_feat_arc_error
u8 ip4_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
#define VNET_FEATURES(...)
static uword l2_out_feat_arc_end_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
clib_error_t * l2_in_out_feat_arc_init(vlib_main_t *vm)
struct _vlib_node_registration vlib_node_registration_t
l2_in_out_feat_arc_main_t l2_in_out_feat_arc_main
static u8 * format_l2_in_out_feat_arc_trace(u8 *s, u32 is_output, va_list *args)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static uword l2_out_feat_arc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static uword l2_in_feat_arc_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static vlib_node_registration_t l2_in_feat_arc_node
(constructor) VLIB_REGISTER_NODE (l2_in_feat_arc_node)
u16 flags
Copy of main node flags.
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
#define VLIB_NODE_FLAG_TRACE
#define CLIB_CACHE_LINE_BYTES
u8 ip6_feat_arc_index[IN_OUT_FEAT_ARC_N_TABLE_GROUPS]
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
static int l2_is_output_arc(u8 arc_index)
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)