aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/feature
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2018-05-26 10:48:55 -0400
committerOle Trøan <otroan@employees.org>2018-05-27 04:39:56 +0000
commit525c9d0f8645ef9901316f042c195adc970b4546 (patch)
tree88486d59b7c9ec37bae5e8434dbd7508a1e3c92e /src/vnet/feature
parentfc23f12c252a9843aeeb8dae7bf60264908f084d (diff)
VPP-1294: add missing feature arc constraint
the ip4-dhcp-client-detect feature MUST run prior to nat44-out2in, or inbound dhcp broadcast packets will be dropped. Certain dhcp servers answer lease renewal dhcp-request packets with broadcast dhcp-acks, leading to unrecoverable lease loss. In detail, this constraint: VNET_FEATURE_INIT (ip4_snat_out2in, static) = { .arc_name = "ip4-unicast", .node_name = "nat44-out2in", .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"), }; doesn't get the job done: ip4-unicast: [17] nat44-out2in [23] ip4-dhcp-client-detect [26] ip4-not-enabled Add a proper constraint: VNET_FEATURE_INIT (ip4_snat_out2in, static) = { .arc_name = "ip4-unicast", .node_name = "nat44-out2in", .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa", "ip4-dhcp-client-detect"), }; and the interface feature order is OK, at least in this regard: ip4-unicast: [17] ip4-dhcp-client-detect [18] nat44-out2in [26] ip4-not-enabled We need to carefully audit (especially) the ip4-unicast feature arc, which has [gasp] 37 features on it! Change-Id: I5e749ead7ab2a25d80839a331de6261e112977ad Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vnet/feature')
-rw-r--r--src/vnet/feature/feature.c46
-rw-r--r--src/vnet/feature/feature.h3
2 files changed, 42 insertions, 7 deletions
diff --git a/src/vnet/feature/feature.c b/src/vnet/feature/feature.c
index 714e20e8e72..e1cea21d7b6 100644
--- a/src/vnet/feature/feature.c
+++ b/src/vnet/feature/feature.c
@@ -250,6 +250,14 @@ vnet_feature_enable_disable (const char *arc_name, const char *node_name,
n_feature_config_bytes);
}
+static int
+feature_cmp (void *a1, void *a2)
+{
+ vnet_feature_registration_t *reg1 = a1;
+ vnet_feature_registration_t *reg2 = a2;
+
+ return (int) reg1->feature_index - reg2->feature_index;
+}
/** Display the set of available driver features.
Useful for verifying that expected features are present
@@ -262,24 +270,45 @@ show_features_command_fn (vlib_main_t * vm,
vnet_feature_main_t *fm = &feature_main;
vnet_feature_arc_registration_t *areg;
vnet_feature_registration_t *freg;
+ vnet_feature_registration_t *feature_regs = 0;
+ int verbose = 0;
+
+ if (unformat (input, "verbose"))
+ verbose = 1;
vlib_cli_output (vm, "Available feature paths");
areg = fm->next_arc;
while (areg)
{
- vlib_cli_output (vm, "%s:", areg->arc_name);
+ if (verbose)
+ vlib_cli_output (vm, "[%2d] %s:", areg->feature_arc_index,
+ areg->arc_name);
+ else
+ vlib_cli_output (vm, "%s:", areg->arc_name);
+
freg = fm->next_feature_by_arc[areg->feature_arc_index];
while (freg)
{
- vlib_cli_output (vm, " %s\n", freg->node_name);
+ vec_add1 (feature_regs, freg[0]);
freg = freg->next_in_arc;
}
+ vec_sort_with_function (feature_regs, feature_cmp);
+ vec_foreach (freg, feature_regs)
+ {
+ if (verbose)
+ vlib_cli_output (vm, " [%2d]: %s\n", freg->feature_index,
+ freg->node_name);
+ else
+ vlib_cli_output (vm, " %s\n", freg->node_name);
+ }
+ vec_reset_length (feature_regs);
/* next */
areg = areg->next;
}
+ vec_free (feature_regs);
return 0;
}
@@ -289,7 +318,7 @@ show_features_command_fn (vlib_main_t * vm,
*
* @cliexpar
* Example:
- * @cliexcmd{show ip features}
+ * @cliexcmd{show features [verbose]}
* @cliexend
* @endparblock
?*/
@@ -306,7 +335,7 @@ VLIB_CLI_COMMAND (show_features_command, static) = {
*/
void
-vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index)
+vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index, int verbose)
{
vnet_feature_main_t *fm = &feature_main;
u32 node_index, current_config_index;
@@ -320,7 +349,7 @@ vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index)
vlib_node_t *n;
int i;
- vlib_cli_output (vm, "Driver feature paths configured on %U...",
+ vlib_cli_output (vm, "Feature paths configured on %U...",
format_vnet_sw_if_index_name,
vnet_get_main (), sw_if_index);
@@ -361,7 +390,10 @@ vnet_interface_features_show (vlib_main_t * vm, u32 sw_if_index)
feat = cfg->features + i;
node_index = feat->node_index;
n = vlib_get_node (vm, node_index);
- vlib_cli_output (vm, " %v", n->name);
+ if (verbose)
+ vlib_cli_output (vm, " [%2d] %v", feat->feature_index, n->name);
+ else
+ vlib_cli_output (vm, " %v", n->name);
}
}
}
@@ -396,6 +428,8 @@ set_interface_features_command_fn (vlib_main_t * vm,
enable = 0;
else
{
+ if (feature_name && arc_name)
+ break;
error = unformat_parse_error (line_input);
goto done;
}
diff --git a/src/vnet/feature/feature.h b/src/vnet/feature/feature.h
index ce9e2ca3570..81224ebf0e2 100644
--- a/src/vnet/feature/feature.h
+++ b/src/vnet/feature/feature.h
@@ -397,7 +397,8 @@ clib_error_t *vnet_feature_arc_init (vlib_main_t * vm,
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 */