X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fadj%2Fadj_midchain.c;h=88648fea0a9f45348b45ad86188750a23ba1d092;hb=3ebebc3a2fe47f1222ba035e04ccd8caed0cf58f;hp=a4b29c8ce35f2edc8f4faeef6ca001f2156b3a5b;hpb=521a8d7df423a0b5aaf259d49ca9230705bc25ee;p=vpp.git diff --git a/src/vnet/adj/adj_midchain.c b/src/vnet/adj/adj_midchain.c index a4b29c8ce35..88648fea0a9 100644 --- a/src/vnet/adj/adj_midchain.c +++ b/src/vnet/adj/adj_midchain.c @@ -30,6 +30,8 @@ static u32 adj_midchain_tx_feature_node[VNET_LINK_NUM]; static u32 adj_midchain_tx_no_count_feature_node[VNET_LINK_NUM]; +static u32 *adj_midchain_feat_count_per_sw_if_index[VNET_LINK_NUM]; + /** * @brief Trace data for packets traversing the midchain tx node */ @@ -69,22 +71,13 @@ adj_midchain_tx_inline (vlib_main_t * vm, while (n_left_from >= 8 && n_left_to_next > 4) { + const ip_adjacency_t *adj0, *adj1, *adj2, *adj3; + const dpo_id_t *dpo0, *dpo1, *dpo2, *dpo3; + vlib_buffer_t * b0, *b1, *b2, *b3; u32 bi0, adj_index0, next0; - const ip_adjacency_t * adj0; - const dpo_id_t *dpo0; - vlib_buffer_t * b0; u32 bi1, adj_index1, next1; - const ip_adjacency_t * adj1; - const dpo_id_t *dpo1; - vlib_buffer_t * b1; u32 bi2, adj_index2, next2; - const ip_adjacency_t * adj2; - const dpo_id_t *dpo2; - vlib_buffer_t * b2; u32 bi3, adj_index3, next3; - const ip_adjacency_t * adj3; - const dpo_id_t *dpo3; - vlib_buffer_t * b3; /* Prefetch next iteration. */ { @@ -454,6 +447,30 @@ adj_nbr_midchain_get_feature_node (ip_adjacency_t *adj) return (adj_midchain_tx_feature_node[adj->ia_link]); } +/** + * adj_midchain_setup + * + * Setup the adj as a mid-chain + */ +void +adj_midchain_teardown (ip_adjacency_t *adj) +{ + u32 feature_index; + u8 arc_index; + + dpo_reset(&adj->sub_type.midchain.next_dpo); + + arc_index = adj_midchain_get_feature_arc_index_for_link_type (adj); + feature_index = adj_nbr_midchain_get_feature_node(adj); + + if (0 == --adj_midchain_feat_count_per_sw_if_index[adj->ia_link][adj->rewrite_header.sw_if_index]) + { + vnet_feature_enable_disable_with_index (arc_index, feature_index, + adj->rewrite_header.sw_if_index, + 0, 0, 0); + } +} + /** * adj_midchain_setup * @@ -482,9 +499,15 @@ adj_midchain_setup (adj_index_t adj_index, feature_index = adj_nbr_midchain_get_feature_node(adj); tx_node = adj_nbr_midchain_get_tx_node(adj); - vnet_feature_enable_disable_with_index (arc_index, feature_index, - adj->rewrite_header.sw_if_index, - 1 /* enable */, 0, 0); + vec_validate (adj_midchain_feat_count_per_sw_if_index[adj->ia_link], + adj->rewrite_header.sw_if_index); + + if (0 == adj_midchain_feat_count_per_sw_if_index[adj->ia_link][adj->rewrite_header.sw_if_index]++) + { + vnet_feature_enable_disable_with_index (arc_index, feature_index, + adj->rewrite_header.sw_if_index, + 1 /* enable */, 0, 0); + } /* * stack the midchain on the drop so it's ready to forward in the adj-midchain-tx. @@ -502,7 +525,7 @@ adj_midchain_setup (adj_index_t adj_index, * adj_nbr_midchain_update_rewrite * * Update the adjacency's rewrite string. A NULL string implies the - * rewrite is reset (i.e. when ARP/ND etnry is gone). + * rewrite is reset (i.e. when ARP/ND entry is gone). * NB: the adj being updated may be handling traffic in the DP. */ void @@ -519,22 +542,17 @@ adj_nbr_midchain_update_rewrite (adj_index_t adj_index, adj = adj_get(adj_index); /* - * one time only update. since we don't support chainging the tunnel + * one time only update. since we don't support changing the tunnel * src,dst, this is all we need. */ - ASSERT((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP) || - (adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN) || - (adj->lookup_next_index == IP_LOOKUP_NEXT_BCAST)); - - /* - * tunnels can always provide a rewrite. - */ - ASSERT(NULL != rewrite); - - adj_midchain_setup(adj_index, fixup, fixup_data, flags); + if (adj->lookup_next_index != IP_LOOKUP_NEXT_MIDCHAIN && + adj->lookup_next_index != IP_LOOKUP_NEXT_MCAST_MIDCHAIN) + { + adj_midchain_setup(adj_index, fixup, fixup_data, flags); + } /* - * update the rewirte with the workers paused. + * update the rewrite with the workers paused. */ adj_nbr_update_rewrite_internal(adj, IP_LOOKUP_NEXT_MIDCHAIN, @@ -685,7 +703,7 @@ adj_ndr_midchain_recursive_loop_detect (adj_index_t ai, { /* * The entry this midchain links to is already in the set - * of visisted entries, this is a loop + * of visited entries, this is a loop */ adj->ia_flags |= ADJ_FLAG_MIDCHAIN_LOOPED; return (1); @@ -704,6 +722,8 @@ format_adj_midchain (u8* s, va_list *ap) ip_adjacency_t * adj = adj_get(index); s = format (s, "%U", format_vnet_link, adj->ia_link); + if (adj->rewrite_header.flags & VNET_REWRITE_HAS_FEATURES) + s = format(s, " [features]"); s = format (s, " via %U", format_ip46_address, &adj->sub_type.nbr.next_hop, adj_proto_to_46(adj->ia_nh_proto));