diff options
-rw-r--r-- | vnet/vnet/devices/devices.c | 1 | ||||
-rw-r--r-- | vnet/vnet/feature/feature.c | 54 | ||||
-rw-r--r-- | vnet/vnet/feature/feature.h | 3 |
3 files changed, 35 insertions, 23 deletions
diff --git a/vnet/vnet/devices/devices.c b/vnet/vnet/devices/devices.c index a1100194f3d..624cf76b2c2 100644 --- a/vnet/vnet/devices/devices.c +++ b/vnet/vnet/devices/devices.c @@ -52,6 +52,7 @@ VNET_FEATURE_ARC_INIT (device_input, static) = { .arc_name = "device-input", .start_nodes = VNET_FEATURES ("device-input"), + .end_node = "ethernet-input", .arc_index_ptr = &feature_main.device_input_feature_arc_index, }; diff --git a/vnet/vnet/feature/feature.c b/vnet/vnet/feature/feature.c index e1d172e5707..032fe784ace 100644 --- a/vnet/vnet/feature/feature.c +++ b/vnet/vnet/feature/feature.c @@ -108,6 +108,9 @@ vnet_feature_init (vlib_main_t * vm) freg = freg->next; } + cm->end_feature_index = + vnet_get_feature_index (arc_index, areg->end_node); + /* next */ areg = areg->next; arc_index++; @@ -118,25 +121,6 @@ vnet_feature_init (vlib_main_t * vm) VLIB_INIT_FUNCTION (vnet_feature_init); -void -vnet_config_update_feature_count (vnet_feature_main_t * fm, u8 arc, - u32 sw_if_index, int is_add) -{ - uword bit_value; - - vec_validate (fm->feature_count_by_sw_if_index[arc], sw_if_index); - - fm->feature_count_by_sw_if_index[arc][sw_if_index] += is_add ? 1 : -1; - - ASSERT (fm->feature_count_by_sw_if_index[arc][sw_if_index] >= 0); - - bit_value = fm->feature_count_by_sw_if_index[arc][sw_if_index] > 0; - - fm->sw_if_index_has_features[arc] = - clib_bitmap_set (fm->sw_if_index_has_features[arc], sw_if_index, - bit_value); -} - u8 vnet_get_feature_arc_index (const char *s) { @@ -180,6 +164,9 @@ vnet_get_feature_index (u8 arc, const char *s) vnet_feature_registration_t *reg; uword *p; + if (s == 0) + return ~0; + p = hash_get_mem (fm->next_feature_by_name[arc], s); if (p == 0) return ~0; @@ -196,6 +183,8 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, { vnet_feature_main_t *fm = &feature_main; vnet_feature_config_main_t *cm; + i16 feature_count; + int is_first_or_last; u32 ci; if (arc_index == (u8) ~ 0) @@ -209,8 +198,9 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, ci = cm->config_index_by_sw_if_index[sw_if_index]; vec_validate (fm->feature_count_by_sw_if_index[arc_index], sw_if_index); - if (!enable_disable - && fm->feature_count_by_sw_if_index[arc_index][sw_if_index] < 1) + feature_count = fm->feature_count_by_sw_if_index[arc_index][sw_if_index]; + + if (!enable_disable && feature_count < 1) return 0; ci = (enable_disable @@ -220,9 +210,27 @@ vnet_feature_enable_disable_with_index (u8 arc_index, u32 feature_index, n_feature_config_bytes); cm->config_index_by_sw_if_index[sw_if_index] = ci; - vnet_config_update_feature_count (fm, arc_index, sw_if_index, - enable_disable); + /* update feature count */ + enable_disable = (enable_disable > 0); + feature_count += enable_disable ? 1 : -1; + is_first_or_last = (feature_count == enable_disable); + ASSERT (feature_count >= 0); + + if (is_first_or_last && cm->end_feature_index != ~0) + { + /*register end node */ + ci = (enable_disable + ? vnet_config_add_feature + : vnet_config_del_feature) + (vlib_get_main (), &cm->config_main, ci, cm->end_feature_index, 0, 0); + cm->config_index_by_sw_if_index[sw_if_index] = ci; + } + + fm->sw_if_index_has_features[arc_index] = + clib_bitmap_set (fm->sw_if_index_has_features[arc_index], sw_if_index, + (feature_count > 0)); + fm->feature_count_by_sw_if_index[arc_index][sw_if_index] = feature_count; return 0; } diff --git a/vnet/vnet/feature/feature.h b/vnet/vnet/feature/feature.h index 0b33f0567e9..b27aaf17804 100644 --- a/vnet/vnet/feature/feature.h +++ b/vnet/vnet/feature/feature.h @@ -29,6 +29,8 @@ typedef struct _vnet_feature_arc_registration /** Start nodes */ char **start_nodes; int n_start_nodes; + /** End node */ + char *end_node; /* Feature arc index, assigned by init function */ u8 feature_arc_index; u8 *arc_index_ptr; @@ -63,6 +65,7 @@ typedef struct vnet_feature_config_main_t_ { vnet_config_main_t config_main; u32 *config_index_by_sw_if_index; + u32 end_feature_index; } vnet_feature_config_main_t; typedef struct |