typedef struct _vnet_feature_registration
{
/** next registration in list of all registrations*/
- struct _vnet_feature_registration *next;
+ struct _vnet_feature_registration *next, *next_in_arc;
/** Feature arc name */
char *arc_name;
/** Graph node name */
vnet_feat_arc_##x.next = fm->next_arc; \
fm->next_arc = & vnet_feat_arc_##x; \
} \
+static void __vnet_rm_feature_arc_registration_##x (void) \
+ __attribute__((__destructor__)) ; \
+static void __vnet_rm_feature_arc_registration_##x (void) \
+{ \
+ vnet_feature_main_t * fm = &feature_main; \
+ vnet_feature_arc_registration_t *r = &vnet_feat_arc_##x; \
+ VLIB_REMOVE_FROM_LINKED_LIST (fm->next_arc, r, next); \
+} \
__VA_ARGS__ vnet_feature_arc_registration_t vnet_feat_arc_##x
#define VNET_FEATURE_INIT(x,...) \
vnet_feat_##x.next = fm->next_feature; \
fm->next_feature = & vnet_feat_##x; \
} \
+static void __vnet_rm_feature_registration_##x (void) \
+ __attribute__((__destructor__)) ; \
+static void __vnet_rm_feature_registration_##x (void) \
+{ \
+ vnet_feature_main_t * fm = &feature_main; \
+ vnet_feature_registration_t *r = &vnet_feat_##x; \
+ VLIB_REMOVE_FROM_LINKED_LIST (fm->next_feature, r, next); \
+} \
__VA_ARGS__ vnet_feature_registration_t vnet_feat_##x
void
if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
{
- b->feature_arc_index = arc;
+ vnet_buffer (b)->feature_arc_index = arc;
b->current_config_index =
vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
return vnet_get_config_data (&cm->config_main, &b->current_config_index,
vlib_buffer_t * b0, u32 n_data_bytes)
{
vnet_feature_main_t *fm = &feature_main;
- u8 arc = b0->feature_arc_index;
+ u8 arc = vnet_buffer (b0)->feature_arc_index;
vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
return vnet_get_config_data (&cm->config_main,
vnet_feature_next_with_data (sw_if_index, next0, b0, 0);
}
+static_always_inline int
+vnet_device_input_have_features (u32 sw_if_index)
+{
+ vnet_feature_main_t *fm = &feature_main;
+ return vnet_have_features (fm->device_input_feature_arc_index, sw_if_index);
+}
+
static_always_inline void
vnet_feature_start_device_input_x1 (u32 sw_if_index, u32 * next0,
vlib_buffer_t * b0)
*/
u16 adv;
- vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
adv = device_input_next_node_advance[*next0];
- vnet_buffer (b0)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b0, -adv);
- b0->feature_arc_index = feature_arc_index;
+ vnet_buffer (b0)->feature_arc_index = feature_arc_index;
b0->current_config_index =
vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
vnet_get_config_data (&cm->config_main, &b0->current_config_index,
*/
u16 adv;
- vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
adv = device_input_next_node_advance[*next0];
- vnet_buffer (b0)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b0, -adv);
- vnet_buffer (b1)->device_input_feat.saved_next_index = *next1;
adv = device_input_next_node_advance[*next1];
- vnet_buffer (b1)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b1, -adv);
- b0->feature_arc_index = feature_arc_index;
- b1->feature_arc_index = feature_arc_index;
+ vnet_buffer (b0)->feature_arc_index = feature_arc_index;
+ vnet_buffer (b1)->feature_arc_index = feature_arc_index;
b0->current_config_index =
vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
b1->current_config_index = b0->current_config_index;
*/
u16 adv;
- vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
adv = device_input_next_node_advance[*next0];
- vnet_buffer (b0)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b0, -adv);
- vnet_buffer (b1)->device_input_feat.saved_next_index = *next1;
adv = device_input_next_node_advance[*next1];
- vnet_buffer (b1)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b1, -adv);
- vnet_buffer (b2)->device_input_feat.saved_next_index = *next2;
adv = device_input_next_node_advance[*next2];
- vnet_buffer (b2)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b2, -adv);
- vnet_buffer (b3)->device_input_feat.saved_next_index = *next3;
adv = device_input_next_node_advance[*next3];
- vnet_buffer (b3)->device_input_feat.buffer_advance = adv;
vlib_buffer_advance (b3, -adv);
- b0->feature_arc_index = feature_arc_index;
- b1->feature_arc_index = feature_arc_index;
- b2->feature_arc_index = feature_arc_index;
- b3->feature_arc_index = feature_arc_index;
+ vnet_buffer (b0)->feature_arc_index = feature_arc_index;
+ vnet_buffer (b1)->feature_arc_index = feature_arc_index;
+ vnet_buffer (b2)->feature_arc_index = feature_arc_index;
+ vnet_buffer (b3)->feature_arc_index = feature_arc_index;
b0->current_config_index =
vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
vnet_feature_registration_t *
first_reg, char ***feature_nodes);
-void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index);
+void vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index,
+ int verbose);
#endif /* included_feature_h */