aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/l2
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/l2')
-rw-r--r--src/vnet/l2/l2_input.c3
-rw-r--r--src/vnet/l2/l2_output.h15
-rw-r--r--src/vnet/l2/l2_output_classify.c2
3 files changed, 17 insertions, 3 deletions
diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c
index fbd75f222e0..3aa5331bf7a 100644
--- a/src/vnet/l2/l2_input.c
+++ b/src/vnet/l2/l2_input.c
@@ -703,10 +703,11 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */
shg = 0; /* not used in xconnect */
}
- /* set up split-horizon group */
+ /* set up split-horizon group and set output feature bit */
config->shg = shg;
out_config = l2output_intf_config (sw_if_index);
out_config->shg = shg;
+ out_config->feature_bitmap |= L2OUTPUT_FEAT_OUTPUT;
/*
* Test: remove this when non-IP features can be configured.
diff --git a/src/vnet/l2/l2_output.h b/src/vnet/l2/l2_output.h
index c683b1ade73..9597205caed 100644
--- a/src/vnet/l2/l2_output.h
+++ b/src/vnet/l2/l2_output.h
@@ -94,6 +94,7 @@ l2output_main_t l2output_main;
/* Mappings from feature ID to graph node name */
#define foreach_l2output_feat \
+ _(OUTPUT, "interface-output") \
_(SPAN, "feature-bitmap-drop") \
_(CFM, "feature-bitmap-drop") \
_(QOS, "feature-bitmap-drop") \
@@ -217,9 +218,21 @@ l2_output_dispatch (vlib_main_t * vlib_main,
vlib_buffer_t * b0,
u32 sw_if_index, u32 feature_bitmap, u32 * next0)
{
- if (feature_bitmap)
+ /*
+ * The output feature bitmap always have at least the output feature bit set
+ * for a normal L2 interface (or all 0's if the interface is changed from L2
+ * to L3 mode). So if next_nodes specified is that from the l2-output node and
+ * the bitmap is all clear except output feature bit, we know there is no more
+ * feature and will fall through to output packet. If next_nodes is from a L2
+ * output feature node (and not l2-output), we always want to get the node for
+ * the next L2 output feature, including the last feature being interface-
+ * output node to output packet.
+ */
+ if ((next_nodes != &l2output_main.next_nodes)
+ || ((feature_bitmap & ~L2OUTPUT_FEAT_OUTPUT) != 0))
{
/* There are some features to execute */
+ ASSERT (feature_bitmap != 0);
/* Save bitmap for the next feature graph nodes */
vnet_buffer (b0)->l2.feature_bitmap = feature_bitmap;
diff --git a/src/vnet/l2/l2_output_classify.c b/src/vnet/l2/l2_output_classify.c
index 27d5eb39514..832be1a11c0 100644
--- a/src/vnet/l2/l2_output_classify.c
+++ b/src/vnet/l2/l2_output_classify.c
@@ -493,7 +493,7 @@ l2_output_classify_init (vlib_main_t * vm)
l2_output_classify_node.index,
L2OUTPUT_N_FEAT,
l2output_get_feat_names (),
- cm->feat_next_node_index);
+ cm->next_nodes.feat_next_node_index);
rt->l2cm = cm;
rt->vcm = cm->vnet_classify_main;