- vlib_node_increment_counter (vm, l2output_node.index,
- L2OUTPUT_ERROR_L2OUTPUT, 4);
-
- /* Get config for the output interface */
- config0 = vec_elt_at_index (msm->configs, sw_if_index0);
- config1 = vec_elt_at_index (msm->configs, sw_if_index1);
- config2 = vec_elt_at_index (msm->configs, sw_if_index2);
- config3 = vec_elt_at_index (msm->configs, sw_if_index3);
-
- /*
- * Get features from the config
- * TODO: mask out any non-applicable features
- */
- feature_bitmap0 = config0->feature_bitmap;
- feature_bitmap1 = config1->feature_bitmap;
- feature_bitmap2 = config2->feature_bitmap;
- feature_bitmap3 = config3->feature_bitmap;
-
- /* Determine next node */
- l2_output_dispatch (msm->vlib_main,
- msm->vnet_main,
- node,
- l2output_node.index,
- &cached_sw_if_index,
- &cached_next_index,
- &msm->next_nodes,
- b0, sw_if_index0, feature_bitmap0, &next0);
-
- l2_output_dispatch (msm->vlib_main,
- msm->vnet_main,
- node,
- l2output_node.index,
- &cached_sw_if_index,
- &cached_next_index,
- &msm->next_nodes,
- b1, sw_if_index1, feature_bitmap1, &next1);
-
- l2_output_dispatch (msm->vlib_main,
- msm->vnet_main,
- node,
- l2output_node.index,
- &cached_sw_if_index,
- &cached_next_index,
- &msm->next_nodes,
- b2, sw_if_index2, feature_bitmap2, &next2);
-
- l2_output_dispatch (msm->vlib_main,
- msm->vnet_main,
- node,
- l2output_node.index,
- &cached_sw_if_index,
- &cached_next_index,
- &msm->next_nodes,
- b3, sw_if_index3, feature_bitmap3, &next3);
-
- l2output_vtr (node, config0, feature_bitmap0, b0, &next0);
- l2output_vtr (node, config1, feature_bitmap1, b1, &next1);
- l2output_vtr (node, config2, feature_bitmap2, b2, &next2);
- l2output_vtr (node, config3, feature_bitmap3, b3, &next3);
-
- /*
- * Perform the split horizon check
- * The check can only fail for non-zero shg's
- */
- if (PREDICT_FALSE (config0->shg + config1->shg +
- config2->shg + config3->shg))
- {
- /* one of the checks might fail, check both */
- if (split_horizon_violation
- (config0->shg, vnet_buffer (b0)->l2.shg))
- {
- next0 = L2OUTPUT_NEXT_DROP;
- b0->error = node->errors[L2OUTPUT_ERROR_SHG_DROP];
- }
- if (split_horizon_violation
- (config1->shg, vnet_buffer (b1)->l2.shg))
- {
- next1 = L2OUTPUT_NEXT_DROP;
- b1->error = node->errors[L2OUTPUT_ERROR_SHG_DROP];
- }
- if (split_horizon_violation
- (config2->shg, vnet_buffer (b2)->l2.shg))
- {
- next2 = L2OUTPUT_NEXT_DROP;
- b2->error = node->errors[L2OUTPUT_ERROR_SHG_DROP];
- }
- if (split_horizon_violation
- (config3->shg, vnet_buffer (b3)->l2.shg))
- {
- next3 = L2OUTPUT_NEXT_DROP;
- b3->error = node->errors[L2OUTPUT_ERROR_SHG_DROP];
- }
- }