summaryrefslogtreecommitdiffstats
path: root/vnet/vnet/feature/feature.h
diff options
context:
space:
mode:
Diffstat (limited to 'vnet/vnet/feature/feature.h')
-rw-r--r--vnet/vnet/feature/feature.h104
1 files changed, 88 insertions, 16 deletions
diff --git a/vnet/vnet/feature/feature.h b/vnet/vnet/feature/feature.h
index 1706dec5456..ad4317afd6f 100644
--- a/vnet/vnet/feature/feature.h
+++ b/vnet/vnet/feature/feature.h
@@ -29,7 +29,7 @@ typedef struct _vnet_feature_arc_registration
char **start_nodes;
int n_start_nodes;
/* Feature arc index, assigned by init function */
- u16 feature_arc_index;
+ u8 feature_arc_index;
} vnet_feature_arc_registration_t;
/** feature registration object */
@@ -79,6 +79,9 @@ typedef struct
/** feature reference counts by interface */
i16 **feature_count_by_sw_if_index;
+ /** Feature arc index for device-input */
+ u8 device_input_feature_arc_index;
+
/** convenience */
vlib_main_t *vlib_main;
vnet_main_t *vnet_main;
@@ -111,10 +114,11 @@ static void __vnet_add_feature_registration_##x (void) \
__VA_ARGS__ vnet_feature_registration_t vnet_feat_##x
void
-vnet_config_update_feature_count (vnet_feature_main_t * fm, u16 arc,
+vnet_config_update_feature_count (vnet_feature_main_t * fm, u8 arc,
u32 sw_if_index, int is_add);
-u32 vnet_feature_index_from_node_name (u16 type, const char *s);
+u32 vnet_get_feature_index (u8 arc, const char *s);
+u8 vnet_get_feature_arc_index (const char *s);
void
vnet_feature_enable_disable (const char *arc_name, const char *node_name,
@@ -124,29 +128,86 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name,
static_always_inline int
-vnet_have_features (u32 arc, u32 sw_if_index)
+vnet_have_features (u8 arc, u32 sw_if_index)
{
vnet_feature_main_t *fm = &feature_main;
return clib_bitmap_get (fm->sw_if_index_has_features[arc], sw_if_index);
}
static_always_inline u32
-vnet_feature_get_config_index (u16 arc, u32 sw_if_index)
+vnet_get_feature_config_index (u8 arc, u32 sw_if_index)
{
vnet_feature_main_t *fm = &feature_main;
vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
return vec_elt (cm->config_index_by_sw_if_index, sw_if_index);
}
+static_always_inline void *
+vnet_feature_arc_start_with_data (u8 arc, u32 sw_if_index, u32 * next,
+ vlib_buffer_t * b, u32 n_data_bytes)
+{
+ vnet_feature_main_t *fm = &feature_main;
+ vnet_feature_config_main_t *cm;
+ cm = &fm->feature_config_mains[arc];
+
+ if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
+ {
+ 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,
+ next, n_data_bytes);
+ }
+}
+
static_always_inline void
-vnet_feature_redirect (u16 arc, u32 sw_if_index, u32 * next0,
- vlib_buffer_t * b0)
+vnet_feature_arc_start (u8 arc, u32 sw_if_index, u32 * next0,
+ vlib_buffer_t * b0)
+{
+ vnet_feature_arc_start_with_data (arc, sw_if_index, next0, b0, 0);
+}
+
+static_always_inline void *
+vnet_feature_next_with_data (u32 sw_if_index, u32 * next0,
+ vlib_buffer_t * b0, u32 n_data_bytes)
{
vnet_feature_main_t *fm = &feature_main;
+ u8 arc = b0->feature_arc_index;
vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc];
- if (PREDICT_FALSE (vnet_have_features (arc, sw_if_index)))
+ return vnet_get_config_data (&cm->config_main,
+ &b0->current_config_index, next0,
+ n_data_bytes);
+}
+
+static_always_inline void
+vnet_feature_next (u32 sw_if_index, u32 * next0, vlib_buffer_t * b0)
+{
+ vnet_feature_next_with_data (sw_if_index, next0, b0, 0);
+}
+
+static_always_inline void
+vnet_feature_start_device_input_x1 (u32 sw_if_index, u32 * next0,
+ vlib_buffer_t * b0, u16 buffer_advanced0)
+{
+ vnet_feature_main_t *fm = &feature_main;
+ vnet_feature_config_main_t *cm;
+ u8 feature_arc_index = fm->device_input_feature_arc_index;
+ cm = &fm->feature_config_mains[feature_arc_index];
+
+ if (PREDICT_FALSE
+ (clib_bitmap_get
+ (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
{
+ /*
+ * Save next0 so that the last feature in the chain
+ * can skip ethernet-input if indicated...
+ */
+ vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
+ vnet_buffer (b0)->device_input_feat.buffer_advance = buffer_advanced0;
+ vlib_buffer_advance (b0, -buffer_advanced0);
+
+ 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,
@@ -155,36 +216,47 @@ vnet_feature_redirect (u16 arc, u32 sw_if_index, u32 * next0,
}
static_always_inline void
-vnet_feature_device_input_redirect_x1 (vlib_node_runtime_t * node,
- u32 sw_if_index, u32 * next0,
- vlib_buffer_t * b0,
- u16 buffer_advanced0)
+vnet_feature_start_device_input_x2 (u32 sw_if_index,
+ u32 * next0,
+ u32 * next1,
+ vlib_buffer_t * b0,
+ vlib_buffer_t * b1,
+ u16 buffer_advanced0,
+ u16 buffer_advanced1)
{
vnet_feature_main_t *fm = &feature_main;
vnet_feature_config_main_t *cm;
-
- ASSERT (node->feature_arc_index != ~(u16) 0);
- cm = &fm->feature_config_mains[node->feature_arc_index];
+ u8 feature_arc_index = fm->device_input_feature_arc_index;
+ cm = &fm->feature_config_mains[feature_arc_index];
if (PREDICT_FALSE
(clib_bitmap_get
- (fm->sw_if_index_has_features[node->feature_arc_index], sw_if_index)))
+ (fm->sw_if_index_has_features[feature_arc_index], sw_if_index)))
{
/*
* Save next0 so that the last feature in the chain
* can skip ethernet-input if indicated...
*/
vnet_buffer (b0)->device_input_feat.saved_next_index = *next0;
+ vnet_buffer (b1)->device_input_feat.saved_next_index = *next1;
vnet_buffer (b0)->device_input_feat.buffer_advance = buffer_advanced0;
+ vnet_buffer (b1)->device_input_feat.buffer_advance = buffer_advanced1;
vlib_buffer_advance (b0, -buffer_advanced0);
+ vlib_buffer_advance (b1, -buffer_advanced1);
+ b0->feature_arc_index = feature_arc_index;
+ 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;
vnet_get_config_data (&cm->config_main, &b0->current_config_index,
next0, /* # bytes of config data */ 0);
+ vnet_get_config_data (&cm->config_main, &b1->current_config_index,
+ next1, /* # bytes of config data */ 0);
}
}
+
#define ORDER_CONSTRAINTS (char*[])
#define VNET_FEATURES(...) (char*[]) { __VA_ARGS__, 0}