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, 133 #ifndef CLIB_MARCH_VARIANT 137 #define get_u16(addr) ( *((u16 *)(addr)) ) 138 #define L2_FEAT_ARC_VEC_SIZE 2 144 for (ii = 0; ii < vector_sz; ii++)
150 u32 * out_sw_if_index)
153 for (ii = 0; ii < vector_sz; ii++)
165 for (ii = 0; ii < vector_sz; ii++)
169 out_ethertype[ii] = clib_net_to_host_u16 (
get_u16 (l3h0 - 2));
177 u16 * ethertype,
u8 ip4_arc,
u8 ip6_arc,
178 u8 nonip_arc,
u16 * out_next)
181 for (ii = 0; ii < vector_sz; ii++)
185 switch (ethertype[ii])
187 case ETHERNET_TYPE_IP4:
188 feature_arc = ip4_arc;
190 case ETHERNET_TYPE_IP6:
191 feature_arc = ip6_arc;
194 feature_arc = nonip_arc;
198 sw_if_index[ii], &next_index, b[ii]);
202 is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
203 L2INPUT_FEAT_INPUT_FEAT_ARC);
205 out_next[ii] = next_index;
214 for (ii = 0; ii < vector_sz; ii++)
218 is_output ? L2OUTPUT_FEAT_OUTPUT_FEAT_ARC :
219 L2INPUT_FEAT_INPUT_FEAT_ARC);
231 for (ii = 0; ii < vector_sz; ii++)
239 t->
ethertype = arc_head ? ethertype[ii] : 0;
248 int arc_head,
int do_trace)
267 ethertype = ethertypes;
268 sw_if_index = sw_if_indices;
284 sw_if_index, ethertype, ip4_arc_index,
285 ip6_arc_index, nonip_arc_index, next);
293 maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
298 sw_if_index += vec_sz;
306 const int vec_sz = 1;
313 sw_if_index, ethertype, ip4_arc_index,
314 ip6_arc_index, nonip_arc_index, next);
322 maybe_trace_xN (vec_sz, arc_head, vm, node, b, sw_if_index, ethertype,
327 sw_if_index += vec_sz;
345 &l2_in_feat_arc_node, 1, 1);
349 &l2_in_feat_arc_node, 1, 0);
359 &l2_out_feat_arc_node, 1, 1);
363 &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);
387 &l2_out_feat_arc_end_node, 0, 1);
391 &l2_out_feat_arc_end_node, 0, 0);
395 #ifndef CLIB_MARCH_VARIANT 402 (
u32) enable_disable);
405 (
u32) enable_disable);
412 .arc_name =
"l2-input-ip4",
419 .arc_name =
"l2-output-ip4",
426 .arc_name =
"l2-input-ip6",
432 .arc_name =
"l2-output-ip6",
439 .arc_name =
"l2-input-nonip",
445 .arc_name =
"l2-output-nonip",
456 .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",
468 .vector_size =
sizeof (
u32),
472 .n_errors =
ARRAY_LEN(l2_out_feat_arc_error_strings),
478 .name =
"l2-input-feat-arc-end",
479 .vector_size =
sizeof (
u32),
481 .sibling_of =
"l2-input-feat-arc",
485 .name =
"l2-output-feat-arc-end",
486 .vector_size =
sizeof (
u32),
488 .sibling_of =
"l2-output-feat-arc",
493 .arc_name =
"l2-input-ip4",
494 .node_name =
"l2-input-feat-arc-end",
500 .arc_name =
"l2-output-ip4",
501 .node_name =
"l2-output-feat-arc-end",
507 .arc_name =
"l2-input-ip6",
508 .node_name =
"l2-input-feat-arc-end",
515 .arc_name =
"l2-output-ip6",
516 .node_name =
"l2-output-feat-arc-end",
522 .arc_name =
"l2-input-nonip",
523 .node_name =
"l2-input-feat-arc-end",
530 .arc_name =
"l2-output-nonip",
531 .node_name =
"l2-output-feat-arc-end",
537 #ifndef CLIB_MARCH_VARIANT 548 l2_in_feat_arc_end_node.index,
564 int has_features = 0;
572 return has_features > 0;
598 void *feature_config,
599 u32 n_feature_config_bytes)
602 if (arc_index == (
u8) ~ 0)
603 return VNET_API_ERROR_INVALID_VALUE;
609 enable_disable, feature_config,
610 n_feature_config_bytes);
616 if (had_features != has_features)
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)
#define VLIB_NODE_FN(node)
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
#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)
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_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)
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 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)
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
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)