X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fbonding%2Fnode.c;h=a606d20f19cf84cba7f25ac22d64000a18e6f5fd;hb=4d1423c5ace249f6609a41fadec9e4b9c4b323de;hp=ce5aefab2fd87729c3416dbce5540095dd01d359;hpb=bac326cb7c5f8856786ca046df8cfa3be9f53926;p=vpp.git diff --git a/src/vnet/bonding/node.c b/src/vnet/bonding/node.c index ce5aefab2fd..a606d20f19c 100644 --- a/src/vnet/bonding/node.c +++ b/src/vnet/bonding/node.c @@ -28,6 +28,7 @@ bond_main_t bond_main; #define foreach_bond_input_error \ _(NONE, "no error") \ _(IF_DOWN, "interface down") \ + _(PASSIVE_IF, "traffic received on passive interface") \ _(PASS_THRU, "pass through (CDP, LLDP, slow protocols)") typedef enum @@ -142,31 +143,56 @@ bond_update_next (vlib_main_t * vm, vlib_node_runtime_t * node, slave_if_t *sif; bond_if_t *bif; + *next_index = BOND_INPUT_NEXT_DROP; + *error = 0; + if (PREDICT_TRUE (*last_slave_sw_if_index == slave_sw_if_index)) - return; + goto next; *last_slave_sw_if_index = slave_sw_if_index; - *next_index = BOND_INPUT_NEXT_DROP; sif = bond_get_slave_by_sw_if_index (slave_sw_if_index); - ASSERT (sif); + ALWAYS_ASSERT (sif); bif = bond_get_master_by_dev_instance (sif->bif_dev_instance); - ASSERT (bif); + ALWAYS_ASSERT (bif); ASSERT (vec_len (bif->slaves)); - if (PREDICT_TRUE (bif->admin_up == 0)) + if (PREDICT_FALSE (bif->admin_up == 0)) { *bond_sw_if_index = slave_sw_if_index; *error = node->errors[BOND_INPUT_ERROR_IF_DOWN]; } + if (PREDICT_FALSE ((bif->mode == BOND_MODE_ACTIVE_BACKUP) && + vec_len (bif->active_slaves) && + (slave_sw_if_index != bif->active_slaves[0]))) + { + *bond_sw_if_index = slave_sw_if_index; + *error = node->errors[BOND_INPUT_ERROR_PASSIVE_IF]; + return; + } + *bond_sw_if_index = bif->sw_if_index; - *error = 0; + +next: vnet_feature_next (next_index, b); } +static_always_inline void +bond_update_next_x4 (vlib_buffer_t * b0, vlib_buffer_t * b1, + vlib_buffer_t * b2, vlib_buffer_t * b3) +{ + u32 tmp0, tmp1, tmp2, tmp3; + + tmp0 = tmp1 = tmp2 = tmp3 = BOND_INPUT_NEXT_DROP; + vnet_feature_next (&tmp0, b0); + vnet_feature_next (&tmp1, b1); + vnet_feature_next (&tmp2, b2); + vnet_feature_next (&tmp3, b3); +} + VLIB_NODE_FN (bond_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) @@ -223,6 +249,22 @@ VLIB_NODE_FN (bond_input_node) (vlib_main_t * vm, if (PREDICT_TRUE (x == 0)) { + /* + * Optimize to call update_next only if there is a feature arc + * after bond-input. Test feature count greater than 1 because + * bond-input itself is a feature arc for this slave interface. + */ + ASSERT ((vnet_buffer (b[0])->feature_arc_index == + vnet_buffer (b[1])->feature_arc_index) && + (vnet_buffer (b[0])->feature_arc_index == + vnet_buffer (b[2])->feature_arc_index) && + (vnet_buffer (b[0])->feature_arc_index == + vnet_buffer (b[3])->feature_arc_index)); + if (PREDICT_FALSE (vnet_get_feature_count + (vnet_buffer (b[0])->feature_arc_index, + last_slave_sw_if_index) > 1)) + bond_update_next_x4 (b[0], b[1], b[2], b[3]); + next[0] = next[1] = next[2] = next[3] = next_index; if (next_index == BOND_INPUT_NEXT_DROP) {