X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Ffib%2Ffib_entry.c;h=24b506379ac5f353a83f7a715c3fe56ab3a9cb27;hb=3a2a1c47bc1f319d1f46abd2a364b3cf82404405;hp=1047c50e1d283dd28ebf9e9ccc51b0bab4413264;hpb=948e00ff5eded0806fc7f54e8f3943aade2bd14a;p=vpp.git diff --git a/vnet/vnet/fib/fib_entry.c b/vnet/vnet/fib/fib_entry.c index 1047c50e1d2..24b506379ac 100644 --- a/vnet/vnet/fib/fib_entry.c +++ b/vnet/vnet/fib/fib_entry.c @@ -64,47 +64,6 @@ fib_entry_get_proto (const fib_entry_t * fib_entry) return (fib_entry->fe_prefix.fp_proto); } -/** - * @brief Turn the chain type requested by the client into the one they - * really wanted - */ -static fib_forward_chain_type_t -fib_entry_chain_type_fixup (const fib_entry_t *entry, - fib_forward_chain_type_t fct) -{ - if (FIB_FORW_CHAIN_TYPE_MPLS_EOS == fct) - { - /* - * The EOS chain is a tricky since one cannot know the adjacency - * to link to without knowing what the packets payload protocol - * will be once the label is popped. - */ - fib_forward_chain_type_t dfct; - - dfct = fib_entry_get_default_chain_type(entry); - - if (FIB_FORW_CHAIN_TYPE_MPLS_EOS == dfct) - { - /* - * If the entry being asked is a eos-MPLS label entry, - * then use the payload-protocol field, that we stashed there - * for just this purpose - */ - return (fib_forw_chain_type_from_dpo_proto( - entry->fe_prefix.fp_payload_proto)); - } - /* - * else give them what this entry would be by default. i.e. if it's a v6 - * entry, then the label its local labelled should be carrying v6 traffic. - * If it's a non-EOS label entry, then there are more labels and we want - * a non-eos chain. - */ - return (dfct); - } - - return (fct); -} - fib_forward_chain_type_t fib_entry_get_default_chain_type (const fib_entry_t *fib_entry) { @@ -189,8 +148,8 @@ format_fib_entry (u8 * s, va_list * args) s = format(s, "\n tracking %d covered: ", n_covered); s = fib_entry_cover_list_format(fib_entry, s); } - s = fib_ae_import_format(fib_entry->fe_import, s); - s = fib_ae_export_format(fib_entry->fe_export, s); + s = fib_ae_import_format(fib_entry, s); + s = fib_ae_export_format(fib_entry, s); s = format (s, "\n forwarding: "); } @@ -201,34 +160,33 @@ format_fib_entry (u8 * s, va_list * args) fct = fib_entry_get_default_chain_type(fib_entry); - if (!dpo_id_is_valid(&fib_entry->fe_lb[fct])) + if (!dpo_id_is_valid(&fib_entry->fe_lb)) { s = format (s, " UNRESOLVED\n"); return (s); } else { + s = format(s, " %U-chain\n %U", + format_fib_forw_chain_type, fct, + format_dpo_id, + &fib_entry->fe_lb, + 2); + s = format(s, "\n"); + if (level >= FIB_ENTRY_FORMAT_DETAIL2) { + fib_entry_delegate_type_t fdt; + fib_entry_delegate_t *fed; - FOR_EACH_FIB_FORW_MPLS_CHAIN(fct) + FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed, { s = format(s, " %U-chain\n %U", - format_fib_forw_chain_type, fct, - format_dpo_id, - &fib_entry->fe_lb[fct], - 2); + format_fib_forw_chain_type, + fib_entry_delegate_type_to_chain_type(fdt), + format_dpo_id, &fed->fd_dpo, 2); s = format(s, "\n"); - } - } - else - { - s = format(s, " %U-chain\n %U", - format_fib_forw_chain_type, fct, - format_dpo_id, - &fib_entry->fe_lb[fct], - 2); - s = format(s, "\n"); + }); } } @@ -238,68 +196,6 @@ format_fib_entry (u8 * s, va_list * args) s = fib_node_children_format(fib_entry->fe_node.fn_children, s); } - /* adj = adj_get(fib_entry->fe_prefix.fp_proto, fib_entry->fe_adj_index); */ - - /* ip_multipath_next_hop_t * nhs, tmp_nhs[1]; */ - /* u32 i, j, n_left, n_nhs; */ - /* vlib_counter_t c, sum; */ - /* ip_lookup_main_t *lm = fib_get_lookup_main(fib_entry->fe_prefix.fp_proto); */ - - /* if (adj->n_adj == 1) */ - /* { */ - /* nhs = &tmp_nhs[0]; */ - /* nhs[0].next_hop_adj_index = ~0; /\* not used *\/ */ - /* nhs[0].weight = 1; */ - /* n_nhs = 1; */ - /* } */ - /* else */ - /* { */ - /* ip_multipath_adjacency_t * madj; */ - /* madj = vec_elt_at_index (lm->multipath_adjacencies, adj->heap_handle); */ - /* nhs = heap_elt_at_index (lm->next_hop_heap, madj->normalized_next_hops.heap_offset); */ - /* n_nhs = madj->normalized_next_hops.count; */ - /* } */ - - /* n_left = nhs[0].weight; */ - /* vlib_counter_zero (&sum); */ - /* for (i = j = 0; i < adj->n_adj; i++) */ - /* { */ - /* n_left -= 1; */ - /* vlib_get_combined_counter(&lm->adjacency_counters, */ - /* fib_entry->fe_adj_index + i, */ - /* &c); */ - /* /\* if (clear) *\/ */ - /* /\* vlib_zero_combined_counter (&lm->adjacency_counters, *\/ */ - /* /\* fib_entry->fe_adj_index + i); *\/ */ - - /* vlib_counter_add (&sum, &c); */ - /* if (n_left == 0) */ - /* { */ - /* s = format (s, "%16Ld%16Ld ", sum.packets, sum.bytes); */ - /* s = format (s, "weight %d, index %d", */ - /* nhs[j].weight, fib_entry->fe_adj_index + i); */ - - /* if (adj->n_adj > 1) */ - /* s = format (s, ", multipath"); */ - - /* s = format (s, "\n%U", */ - /* format_ip_adjacency, */ - /* vnet_get_main(), lm, fib_entry->fe_adj_index + i); */ - - /* // vlib_cli_output (vm, "%v", msg); */ - /* //vec_free (msg); */ - /* } */ - /* else */ - /* { */ - /* j++; */ - /* if (j < n_nhs) */ - /* { */ - /* n_left = nhs[j].weight; */ - /* vlib_counter_zero (&sum); */ - /* } */ - /* } */ - /* } */ - return (s); } @@ -315,20 +211,25 @@ fib_entry_from_fib_node (fib_node_t *node) static void fib_entry_last_lock_gone (fib_node_t *node) { - fib_forward_chain_type_t fct; + fib_entry_delegate_type_t fdt; + fib_entry_delegate_t *fed; fib_entry_t *fib_entry; fib_entry = fib_entry_from_fib_node(node); - FOR_EACH_FIB_FORW_MPLS_CHAIN(fct) + FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed, { - dpo_reset(&fib_entry->fe_lb[fct]); - } + dpo_reset(&fed->fd_dpo); + fib_entry_delegate_remove(fib_entry, fdt); + }); FIB_ENTRY_DBG(fib_entry, "last-lock"); fib_node_deinit(&fib_entry->fe_node); // FIXME -RR Backwalk + + ASSERT(0 == vec_len(fib_entry->fe_delegates)); + vec_free(fib_entry->fe_delegates); pool_put(fib_entry_pool, fib_entry); } @@ -393,6 +294,7 @@ fib_entry_back_walk_notify (fib_node_t *node, if (FIB_NODE_BW_REASON_FLAG_EVALUATE & ctx->fnbw_reason || FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE & ctx->fnbw_reason || + FIB_NODE_BW_REASON_FLAG_ADJ_DOWN & ctx->fnbw_reason || FIB_NODE_BW_REASON_FLAG_INTERFACE_UP & ctx->fnbw_reason || FIB_NODE_BW_REASON_FLAG_INTERFACE_DOWN & ctx->fnbw_reason || FIB_NODE_BW_REASON_FLAG_INTERFACE_DELETE & ctx->fnbw_reason) @@ -410,6 +312,11 @@ fib_entry_back_walk_notify (fib_node_t *node, */ ctx->fnbw_reason = FIB_NODE_BW_REASON_FLAG_EVALUATE; + /* + * ... and nothing is forced sync from now on. + */ + ctx->fnbw_flags &= ~FIB_NODE_BW_FLAG_FORCE_SYNC; + /* * propagate the backwalk further if we haven't already reached the * maximum depth. @@ -481,44 +388,58 @@ fib_entry_contribute_urpf (fib_node_index_t entry_index, */ void fib_entry_contribute_forwarding (fib_node_index_t fib_entry_index, - fib_forward_chain_type_t type, + fib_forward_chain_type_t fct, dpo_id_t *dpo) { + fib_entry_delegate_t *fed; fib_entry_t *fib_entry; fib_entry = fib_entry_get(fib_entry_index); - /* - * these are not the droids you are looking for... - */ - type = fib_entry_chain_type_fixup(fib_entry, type); - - if (!dpo_id_is_valid(&fib_entry->fe_lb[type])) + if (fct == fib_entry_get_default_chain_type(fib_entry)) { - /* - * on-demand create eos/non-eos. - * There is no on-demand delete because: - * - memory versus complexity & reliability: - * leaving unrequired [n]eos LB arounds wastes memory, cleaning - * then up on the right trigger is more code. i favour the latter. - */ - fib_entry_src_mk_lb(fib_entry, - fib_entry_get_best_src_i(fib_entry), - type, - &fib_entry->fe_lb[type]); + dpo_copy(dpo, &fib_entry->fe_lb); } + else + { + fed = fib_entry_delegate_get(fib_entry, + fib_entry_chain_type_to_delegate_type(fct)); - dpo_copy(dpo, &fib_entry->fe_lb[type]); + if (NULL == fed) + { + fed = fib_entry_delegate_find_or_add( + fib_entry, + fib_entry_chain_type_to_delegate_type(fct)); + /* + * on-demand create eos/non-eos. + * There is no on-demand delete because: + * - memory versus complexity & reliability: + * leaving unrequired [n]eos LB arounds wastes memory, cleaning + * then up on the right trigger is more code. i favour the latter. + */ + fib_entry_src_mk_lb(fib_entry, + fib_entry_get_best_src_i(fib_entry), + fct, + &fed->fd_dpo); + } + + dpo_copy(dpo, &fed->fd_dpo); + } } const dpo_id_t * fib_entry_contribute_ip_forwarding (fib_node_index_t fib_entry_index) { + fib_forward_chain_type_t fct; fib_entry_t *fib_entry; fib_entry = fib_entry_get(fib_entry_index); + fct = fib_entry_get_default_chain_type(fib_entry); - return (&fib_entry->fe_lb[fib_entry_get_default_chain_type(fib_entry)]); + ASSERT((fct == FIB_FORW_CHAIN_TYPE_UNICAST_IP4 || + fct == FIB_FORW_CHAIN_TYPE_UNICAST_IP6)); + + return (&fib_entry->fe_lb); } adj_index_t @@ -564,6 +485,27 @@ fib_entry_child_remove (fib_node_index_t fib_entry_index, fib_node_child_remove(FIB_NODE_TYPE_ENTRY, fib_entry_index, sibling_index); + + if (0 == fib_node_get_n_children(FIB_NODE_TYPE_ENTRY, + fib_entry_index)) + { + /* + * if there are no children left then there is no reason to keep + * the non-default forwarding chains. those chains are built only + * because the children want them. + */ + fib_entry_delegate_type_t fdt; + fib_entry_delegate_t *fed; + fib_entry_t *fib_entry; + + fib_entry = fib_entry_get(fib_entry_index); + + FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed, + { + dpo_reset(&fed->fd_dpo); + fib_entry_delegate_remove(fib_entry, fdt); + }); + } } static fib_entry_t * @@ -571,8 +513,8 @@ fib_entry_alloc (u32 fib_index, const fib_prefix_t *prefix, fib_node_index_t *fib_entry_index) { - fib_forward_chain_type_t fct; fib_entry_t *fib_entry; + fib_prefix_t *fep; pool_get(fib_entry_pool, fib_entry); memset(fib_entry, 0, sizeof(*fib_entry)); @@ -581,20 +523,25 @@ fib_entry_alloc (u32 fib_index, FIB_NODE_TYPE_ENTRY); fib_entry->fe_fib_index = fib_index; - fib_entry->fe_prefix = *prefix; + + /* + * the one time we need to update the const prefix is when + * the entry is first created + */ + fep = (fib_prefix_t*)&(fib_entry->fe_prefix); + *fep = *prefix; + if (FIB_PROTOCOL_MPLS == fib_entry->fe_prefix.fp_proto) { - fib_entry->fe_prefix.fp_len = 21; + fep->fp_len = 21; + if (MPLS_NON_EOS == fep->fp_eos) + { + fep->fp_payload_proto = DPO_PROTO_MPLS; + } ASSERT(DPO_PROTO_NONE != fib_entry->fe_prefix.fp_payload_proto); } - fib_entry->fe_export = FIB_NODE_INDEX_INVALID; - fib_entry->fe_import = FIB_NODE_INDEX_INVALID; - fib_entry->fe_covered = FIB_NODE_INDEX_INVALID; - FOR_EACH_FIB_FORW_MPLS_CHAIN(fct) - { - dpo_reset(&fib_entry->fe_lb[fct]); - } + dpo_reset(&fib_entry->fe_lb); *fib_entry_index = fib_entry_get_index(fib_entry); @@ -1310,7 +1257,6 @@ fib_entry_recursive_loop_detect (fib_node_index_t entry_index, if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent) { fib_node_index_t *entries = *entry_indicies; - fib_forward_chain_type_t fct; vec_add1(entries, entry_index); was_looped = fib_path_list_is_looped(fib_entry->fe_parent); @@ -1325,16 +1271,16 @@ fib_entry_recursive_loop_detect (fib_node_index_t entry_index, * re-evaluate all the entry's forwarding * NOTE: this is an inplace modify */ - FOR_EACH_FIB_FORW_MPLS_CHAIN(fct) - { - if (dpo_id_is_valid(&fib_entry->fe_lb[fct])) - { - fib_entry_src_mk_lb(fib_entry, - fib_entry_get_best_src_i(fib_entry), - fct, - &fib_entry->fe_lb[fct]); - } - } + fib_entry_delegate_type_t fdt; + fib_entry_delegate_t *fed; + + FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed, + { + fib_entry_src_mk_lb(fib_entry, + fib_entry_get_best_src_i(fib_entry), + fib_entry_delegate_type_to_chain_type(fdt), + &fed->fd_dpo); + }); } } else @@ -1373,8 +1319,8 @@ fib_entry_get_best_source (fib_node_index_t entry_index) } static int -fib_ip4_address_compare (ip4_address_t * a1, - ip4_address_t * a2) +fib_ip4_address_compare (const ip4_address_t * a1, + const ip4_address_t * a2) { /* * IP addresses are unsiged ints. the return value here needs to be signed @@ -1387,8 +1333,8 @@ fib_ip4_address_compare (ip4_address_t * a1, } static int -fib_ip6_address_compare (ip6_address_t * a1, - ip6_address_t * a2) +fib_ip6_address_compare (const ip6_address_t * a1, + const ip6_address_t * a2) { int i; for (i = 0; i < ARRAY_LEN (a1->as_u16); i++) @@ -1472,6 +1418,16 @@ fib_entry_module_init (void) fib_node_register_type (FIB_NODE_TYPE_ENTRY, &fib_entry_vft); } +void +fib_entry_encode (fib_node_index_t fib_entry_index, + fib_route_path_encode_t **api_rpaths) +{ + fib_entry_t *fib_entry; + + fib_entry = fib_entry_get(fib_entry_index); + fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths); +} + void fib_entry_get_prefix (fib_node_index_t fib_entry_index, fib_prefix_t *pfx)