+ /* increment TX interface stat */
+ vlib_increment_combined_counter (im->combined_sw_if_counters +
+ VNET_INTERFACE_COUNTER_TX,
+ thread_index, new_rx_sw_if_index,
+ 4 /* pkts */ , n_bytes);
+ b += 4;
+ next += 4;
+ n_left_from -= 4;
+ continue;
+ }
+
+ /*
+ * Slow path: we know that at least one of the pkts
+ * was transmitted on a different sw_if_index, so
+ * check each sw_if_index against the cached data and proceed
+ * accordingly.
+ *
+ * This shouldn't happen, but code can (and does) bypass the
+ * per-interface output node, so deal with it.
+ */
+ if (PREDICT_FALSE (vnet_buffer (b[0])->sw_if_index[VLIB_TX]
+ != new_rx_sw_if_index))
+ {
+ config = l2input_intf_config
+ (vnet_buffer (b[0])->sw_if_index[VLIB_TX]);
+ next_index =
+ config->bridge ? VNET_SIMULATED_ETHERNET_TX_NEXT_L2_INPUT :
+ VNET_SIMULATED_ETHERNET_TX_NEXT_ETHERNET_INPUT;
+ new_tx_sw_if_index = config->bvi ? L2INPUT_BVI : ~0;
+ new_rx_sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
+ }
+ next[0] = next_index;
+ vnet_buffer (b[0])->sw_if_index[VLIB_RX] = new_rx_sw_if_index;
+ vnet_buffer (b[0])->sw_if_index[VLIB_TX] = new_tx_sw_if_index;
+ n_bytes = vlib_buffer_length_in_chain (vm, b[0]);
+ if (next_index == VNET_SIMULATED_ETHERNET_TX_NEXT_L2_INPUT)
+ vnet_update_l2_len (b[0]);
+
+ vlib_increment_combined_counter (im->combined_sw_if_counters +
+ VNET_INTERFACE_COUNTER_TX,
+ thread_index, new_rx_sw_if_index,
+ 1 /* pkts */ , n_bytes);