feature: introduce feature arc end nodes
This change allows us to keep feature path disabled
until 1st feature is enabled. Enabling 1st feature also means
that end feature node is enabled helping feature arc tenants
to reach the end.
Change-Id: Idbd64e681bd2b42e7c67612074649e5ae51f46e6
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/vnet/vnet/devices/devices.c b/vnet/vnet/devices/devices.c
index a110019..624cf76 100644
--- a/vnet/vnet/devices/devices.c
+++ b/vnet/vnet/devices/devices.c
@@ -52,6 +52,7 @@
{
.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 e1d172e..032fe78 100644
--- a/vnet/vnet/feature/feature.c
+++ b/vnet/vnet/feature/feature.c
@@ -108,6 +108,9 @@
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 @@
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_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_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 @@
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 @@
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 0b33f05..b27aaf1 100644
--- a/vnet/vnet/feature/feature.h
+++ b/vnet/vnet/feature/feature.h
@@ -29,6 +29,8 @@
/** 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 @@
{
vnet_config_main_t config_main;
u32 *config_index_by_sw_if_index;
+ u32 end_feature_index;
} vnet_feature_config_main_t;
typedef struct