X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Ffib%2Ffib_entry_src.c;h=c79b745b5b5d1b3ac3c7a3f21da9f0c2c068039d;hb=58f37b21eace1c93ed5b20047cae4d0056cba376;hp=616d77e8b0a6a30d233809f46479c17f76592836;hpb=89541992000433b743cbbe8cb396faab42bcf6ae;p=vpp.git diff --git a/src/vnet/fib/fib_entry_src.c b/src/vnet/fib/fib_entry_src.c index 616d77e8b0a..c79b745b5b5 100644 --- a/src/vnet/fib/fib_entry_src.c +++ b/src/vnet/fib/fib_entry_src.c @@ -23,17 +23,51 @@ #include #include #include +#include /* * per-source type vft */ -static fib_entry_src_vft_t fib_entry_src_vft[FIB_SOURCE_MAX]; +static fib_entry_src_vft_t fib_entry_src_bh_vft[FIB_SOURCE_BH_MAX]; + +/** + * Get the VFT for a given source. This is a combination of the source + * enum and the interposer flags + */ +const fib_entry_src_vft_t* +fib_entry_src_get_vft (const fib_entry_src_t *esrc) +{ + fib_source_behaviour_t bh; + + bh = fib_source_get_behaviour(esrc->fes_src); + + if (esrc->fes_entry_flags & FIB_ENTRY_FLAG_INTERPOSE) + { + return (&fib_entry_src_bh_vft[FIB_SOURCE_BH_INTERPOSE]); + } + + ASSERT(bh < FIB_SOURCE_BH_MAX); + return (&fib_entry_src_bh_vft[bh]); +} + +static void +fib_entry_src_copy_default (const fib_entry_src_t *orig_src, + const fib_entry_t *fib_entry, + fib_entry_src_t *copy_src) +{ + clib_memcpy(©_src->u, &orig_src->u, sizeof(copy_src->u)); +} void -fib_entry_src_register (fib_source_t source, - const fib_entry_src_vft_t *vft) +fib_entry_src_behaviour_register (fib_source_behaviour_t bh, + const fib_entry_src_vft_t *vft) { - fib_entry_src_vft[source] = *vft; + fib_entry_src_bh_vft[bh] = *vft; + + if (NULL == fib_entry_src_bh_vft[bh].fesv_copy) + { + fib_entry_src_bh_vft[bh].fesv_copy = fib_entry_src_copy_default; + } } static int @@ -42,24 +76,23 @@ fib_entry_src_cmp_for_sort (void * v1, { fib_entry_src_t *esrc1 = v1, *esrc2 = v2; - return (esrc1->fes_src - esrc2->fes_src); + return (fib_source_get_prio(esrc1->fes_src) - + fib_source_get_prio(esrc2->fes_src)); } -void +static void fib_entry_src_action_init (fib_entry_t *fib_entry, - fib_source_t source) - + fib_source_t source, + fib_entry_flag_t flags) { fib_entry_src_t esrc = { .fes_pl = FIB_NODE_INDEX_INVALID, .fes_flags = FIB_ENTRY_SRC_FLAG_NONE, .fes_src = source, + .fes_entry_flags = flags, }; - if (NULL != fib_entry_src_vft[source].fesv_init) - { - fib_entry_src_vft[source].fesv_init(&esrc); - } + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, &esrc, fesv_init, (&esrc)); vec_add1(fib_entry->fe_srcs, esrc); vec_sort_with_function(fib_entry->fe_srcs, @@ -67,9 +100,9 @@ fib_entry_src_action_init (fib_entry_t *fib_entry, } static fib_entry_src_t * -fib_entry_src_find (const fib_entry_t *fib_entry, - fib_source_t source, - u32 *index) +fib_entry_src_find_i (const fib_entry_t *fib_entry, + fib_source_t source, + u32 *index) { fib_entry_src_t *esrc; @@ -95,6 +128,14 @@ fib_entry_src_find (const fib_entry_t *fib_entry, return (NULL); } +fib_entry_src_t * +fib_entry_src_find (const fib_entry_t *fib_entry, + fib_source_t source) + +{ + return (fib_entry_src_find_i(fib_entry, source, NULL)); +} + int fib_entry_is_sourced (fib_node_index_t fib_entry_index, fib_source_t source) @@ -103,26 +144,65 @@ fib_entry_is_sourced (fib_node_index_t fib_entry_index, fib_entry = fib_entry_get(fib_entry_index); - return (NULL != fib_entry_src_find(fib_entry, source, NULL)); + return (NULL != fib_entry_src_find(fib_entry, source)); +} + +int +fib_entry_is_marked (fib_node_index_t fib_entry_index, + fib_source_t source) +{ + fib_entry_t *fib_entry; + fib_entry_src_t *esrc; + + fib_entry = fib_entry_get(fib_entry_index); + + esrc = fib_entry_src_find(fib_entry, source); + + if (NULL == esrc) + { + return (0); + } + else + { + return (!!(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_STALE)); + } +} + +void +fib_entry_mark (fib_node_index_t fib_entry_index, + fib_source_t source) +{ + fib_entry_t *fib_entry; + fib_entry_src_t *esrc; + + fib_entry = fib_entry_get(fib_entry_index); + + esrc = fib_entry_src_find(fib_entry, source); + + if (NULL != esrc) + { + esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_STALE; + } } static fib_entry_src_t * fib_entry_src_find_or_create (fib_entry_t *fib_entry, - fib_source_t source) + fib_source_t source, + fib_entry_flag_t flags) { fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL == esrc) { - fib_entry_src_action_init(fib_entry, source); + fib_entry_src_action_init(fib_entry, source, flags); } - return (fib_entry_src_find(fib_entry, source, NULL)); + return (fib_entry_src_find(fib_entry, source)); } -void +static void fib_entry_src_action_deinit (fib_entry_t *fib_entry, fib_source_t source) @@ -130,29 +210,24 @@ fib_entry_src_action_deinit (fib_entry_t *fib_entry, fib_entry_src_t *esrc; u32 index = ~0; - esrc = fib_entry_src_find(fib_entry, source, &index); + esrc = fib_entry_src_find_i(fib_entry, source, &index); ASSERT(NULL != esrc); - if (NULL != fib_entry_src_vft[source].fesv_deinit) - { - fib_entry_src_vft[source].fesv_deinit(esrc); - } + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_deinit, (esrc)); fib_path_ext_list_flush(&esrc->fes_path_exts); vec_del1(fib_entry->fe_srcs, index); + vec_sort_with_function(fib_entry->fe_srcs, + fib_entry_src_cmp_for_sort); } fib_entry_src_cover_res_t fib_entry_src_action_cover_change (fib_entry_t *fib_entry, - fib_source_t source) + fib_entry_src_t *esrc) { - if (NULL != fib_entry_src_vft[source].fesv_cover_change) - { - return (fib_entry_src_vft[source].fesv_cover_change( - fib_entry_src_find(fib_entry, source, NULL), - fib_entry)); - } + FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_cover_change, + (esrc, fib_entry)); fib_entry_src_cover_res_t res = { .install = !0, @@ -163,14 +238,10 @@ fib_entry_src_action_cover_change (fib_entry_t *fib_entry, fib_entry_src_cover_res_t fib_entry_src_action_cover_update (fib_entry_t *fib_entry, - fib_source_t source) + fib_entry_src_t *esrc) { - if (NULL != fib_entry_src_vft[source].fesv_cover_update) - { - return (fib_entry_src_vft[source].fesv_cover_update( - fib_entry_src_find(fib_entry, source, NULL), - fib_entry)); - } + FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_cover_update, + (esrc, fib_entry)); fib_entry_src_cover_res_t res = { .install = !0, @@ -183,25 +254,27 @@ typedef struct fib_entry_src_collect_forwarding_ctx_t_ { load_balance_path_t *next_hops; const fib_entry_t *fib_entry; - const fib_entry_src_t *esrc; + i32 start_source_index, end_source_index; fib_forward_chain_type_t fct; int n_recursive_constrained; u16 preference; + dpo_proto_t payload_proto; } fib_entry_src_collect_forwarding_ctx_t; /** * @brief Determine whether this FIB entry should use a load-balance MAP * to support PIC edge fast convergence */ -load_balance_flags_t -fib_entry_calc_lb_flags (fib_entry_src_collect_forwarding_ctx_t *ctx) +static load_balance_flags_t +fib_entry_calc_lb_flags (fib_entry_src_collect_forwarding_ctx_t *ctx, + const fib_entry_src_t *esrc) { /** * We'll use a LB map if the path-list has multiple recursive paths. * recursive paths implies BGP, and hence scale. */ if (ctx->n_recursive_constrained > 1 && - fib_path_list_is_popular(ctx->esrc->fes_pl)) + fib_path_list_is_popular(esrc->fes_pl)) { return (LOAD_BALANCE_FLAG_USES_MAP); } @@ -212,52 +285,12 @@ static int fib_entry_src_valid_out_label (mpls_label_t label) { return ((MPLS_LABEL_IS_REAL(label) || + MPLS_LABEL_POP == label || MPLS_IETF_IPV4_EXPLICIT_NULL_LABEL == label || MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL == label || MPLS_IETF_IMPLICIT_NULL_LABEL == label)); } -/** - * @brief Turn the chain type requested by the client into the one they - * really wanted - */ -fib_forward_chain_type_t -fib_entry_chain_type_fixup (const fib_entry_t *entry, - fib_forward_chain_type_t 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; - - if (FIB_FORW_CHAIN_TYPE_MPLS_EOS != fct) - { - return (fct); - } - - 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); -} - static dpo_proto_t fib_prefix_get_payload_proto (const fib_prefix_t *pfx) { @@ -299,7 +332,8 @@ fib_entry_src_get_path_forwarding (fib_node_index_t path_index, nh->path_index = path_index; nh->path_weight = fib_path_get_weight(path_index); - fib_path_contribute_forwarding(path_index, ctx->fct, &nh->path_dpo); + fib_path_contribute_forwarding(path_index, ctx->fct, + ctx->payload_proto, &nh->path_dpo); break; case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS: @@ -312,6 +346,7 @@ fib_entry_src_get_path_forwarding (fib_node_index_t path_index, nh->path_weight = fib_path_get_weight(path_index); fib_path_contribute_forwarding(path_index, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, + ctx->payload_proto, &nh->path_dpo); } break; @@ -325,11 +360,12 @@ fib_entry_src_get_path_forwarding (fib_node_index_t path_index, nh->path_index = path_index; nh->path_weight = fib_path_get_weight(path_index); fib_path_contribute_forwarding(path_index, - fib_entry_chain_type_fixup(ctx->fib_entry, - ctx->fct), + ctx->fct, + ctx->payload_proto, &nh->path_dpo); fib_path_stack_mpls_disp(path_index, - fib_prefix_get_payload_proto(&ctx->fib_entry->fe_prefix), + ctx->payload_proto, + FIB_MPLS_LSP_MODE_PIPE, &nh->path_dpo); break; @@ -347,9 +383,17 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, void *arg) { fib_entry_src_collect_forwarding_ctx_t *ctx; + const fib_entry_src_t *esrc; fib_path_ext_t *path_ext; + u32 n_nhs; ctx = arg; + n_nhs = vec_len(ctx->next_hops); + + /* + * walk the paths and extension of the best non-interpose source + */ + esrc = &ctx->fib_entry->fe_srcs[ctx->end_source_index]; /* * if the path is not resolved, don't include it. @@ -383,7 +427,7 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, /* * get the matching path-extension for the path being visited. */ - path_ext = fib_path_ext_list_find_by_path_index(&ctx->esrc->fes_path_exts, + path_ext = fib_path_ext_list_find_by_path_index(&esrc->fes_path_exts, path_index); if (NULL != path_ext) @@ -391,7 +435,7 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, switch (path_ext->fpe_type) { case FIB_PATH_EXT_MPLS: - if (fib_entry_src_valid_out_label(path_ext->fpe_label_stack[0])) + if (fib_entry_src_valid_out_label(path_ext->fpe_label_stack[0].fml_value)) { /* * found a matching extension. stack it to obtain the forwarding @@ -399,9 +443,8 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, */ ctx->next_hops = fib_path_ext_stack(path_ext, + ctx->payload_proto, ctx->fct, - fib_entry_chain_type_fixup(ctx->fib_entry, - ctx->fct), ctx->next_hops); } else @@ -417,7 +460,7 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, /* * else * the path does not refine the cover, meaning that - * the adjacency doesdoes not match the sub-net on the link. + * the adjacency does/does not match the sub-net on the link. * So this path does not contribute forwarding. */ break; @@ -428,16 +471,92 @@ fib_entry_src_collect_forwarding (fib_node_index_t pl_index, fib_entry_src_get_path_forwarding(path_index, ctx); } + /* + * a this point 'ctx' has the DPO the path contributed, plus + * any labels from path extensions. + * check if there are any interpose sources that want to contribute + */ + if (n_nhs < vec_len(ctx->next_hops)) + { + /* + * the path contributed a new choice. + */ + const fib_entry_src_vft_t *vft; + + /* + * roll up the sources that are interposes + */ + i32 index; + + for (index = ctx->end_source_index; + index >= ctx->start_source_index; + index--) + { + const dpo_id_t *interposer; + + esrc = &ctx->fib_entry->fe_srcs[index]; + vft = fib_entry_src_get_vft(esrc); + + if (!(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_CONTRIBUTING) || + !(esrc->fes_entry_flags & FIB_ENTRY_FLAG_INTERPOSE)) + continue; + + ASSERT(vft->fesv_contribute_interpose); + interposer = vft->fesv_contribute_interpose(esrc, ctx->fib_entry); + + if (NULL != interposer) + { + dpo_id_t clone = DPO_INVALID; + + dpo_mk_interpose(interposer, + &ctx->next_hops[n_nhs].path_dpo, + &clone); + + dpo_copy(&ctx->next_hops[n_nhs].path_dpo, &clone); + dpo_reset(&clone); + } + } + } + return (FIB_PATH_LIST_WALK_CONTINUE); } void fib_entry_src_mk_lb (fib_entry_t *fib_entry, - const fib_entry_src_t *esrc, + fib_source_t source, fib_forward_chain_type_t fct, dpo_id_t *dpo_lb) { + const fib_entry_src_t *esrc; dpo_proto_t lb_proto; + u32 start, end; + + /* + * The source passed here is the 'best', i.e. the one the client + * wants. however, if it's an interpose then it does not contribute + * the forwarding, the next best source that is not an interpose does. + * So roll down the sources, to find the best non-interpose + */ + vec_foreach_index (start, fib_entry->fe_srcs) + { + if (source == fib_entry->fe_srcs[start].fes_src) + break; + } + for (end = start; end < vec_len (fib_entry->fe_srcs); end++) + { + if (!(fib_entry->fe_srcs[end].fes_entry_flags & + FIB_ENTRY_FLAG_INTERPOSE) && + (fib_entry->fe_srcs[end].fes_flags & + FIB_ENTRY_SRC_FLAG_CONTRIBUTING)) + break; + } + if (end == vec_len(fib_entry->fe_srcs)) + { + /* didn't find any contributing non-interpose sources */ + end = start; + } + + esrc = &fib_entry->fe_srcs[end]; /* * If the entry has path extensions then we construct a load-balance @@ -445,17 +564,19 @@ fib_entry_src_mk_lb (fib_entry_t *fib_entry, * Otherwise we use the load-balance of the path-list */ fib_entry_src_collect_forwarding_ctx_t ctx = { - .esrc = esrc, .fib_entry = fib_entry, .next_hops = NULL, .n_recursive_constrained = 0, .fct = fct, .preference = 0xffff, + .start_source_index = start, + .end_source_index = end, + .payload_proto = fib_prefix_get_payload_proto(&fib_entry->fe_prefix), }; /* * As an optimisation we allocate the vector of next-hops to be sized - * equal to the maximum nuber of paths we will need, which is also the + * equal to the maximum number of paths we will need, which is also the * most likely number we will need, since in most cases the paths are 'up'. */ vec_validate(ctx.next_hops, fib_path_list_get_n_paths(esrc->fes_pl)); @@ -535,7 +656,7 @@ fib_entry_src_mk_lb (fib_entry_t *fib_entry, { load_balance_multipath_update(dpo_lb, ctx.next_hops, - fib_entry_calc_lb_flags(&ctx)); + fib_entry_calc_lb_flags(&ctx, esrc)); vec_free(ctx.next_hops); /* @@ -579,11 +700,9 @@ fib_entry_src_action_install (fib_entry_t *fib_entry, * tables */ fib_forward_chain_type_t fct; - fib_entry_src_t *esrc; int insert; fct = fib_entry_get_default_chain_type(fib_entry); - esrc = fib_entry_src_find(fib_entry, source, NULL); /* * Every entry has its own load-balance object. All changes to the entry's @@ -593,7 +712,7 @@ fib_entry_src_action_install (fib_entry_t *fib_entry, */ insert = !dpo_id_is_valid(&fib_entry->fe_lb); - fib_entry_src_mk_lb(fib_entry, esrc, fct, &fib_entry->fe_lb); + fib_entry_src_mk_lb(fib_entry, source, fct, &fib_entry->fe_lb); ASSERT(dpo_id_is_valid(&fib_entry->fe_lb)); FIB_ENTRY_DBG(fib_entry, "install: %d", fib_entry->fe_lb); @@ -617,7 +736,7 @@ fib_entry_src_action_install (fib_entry_t *fib_entry, FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed, { - fib_entry_src_mk_lb(fib_entry, esrc, + fib_entry_src_mk_lb(fib_entry, source, fib_entry_delegate_type_to_chain_type(fdt), &fed->fd_dpo); }); @@ -629,8 +748,7 @@ fib_entry_src_action_uninstall (fib_entry_t *fib_entry) /* * uninstall the forwarding chain from the forwarding tables */ - FIB_ENTRY_DBG(fib_entry, "uninstall: %d", - fib_entry->fe_adj_index); + FIB_ENTRY_DBG(fib_entry, "uninstall"); if (dpo_id_is_valid(&fib_entry->fe_lb)) { @@ -639,6 +757,7 @@ fib_entry_src_action_uninstall (fib_entry_t *fib_entry) &fib_entry->fe_prefix, &fib_entry->fe_lb); + vlib_worker_wait_one_loop(); dpo_reset(&fib_entry->fe_lb); } } @@ -658,18 +777,34 @@ fib_entry_recursive_loop_detect_i (fib_node_index_t path_list_index) * * copy a source data from another entry to this one */ -fib_entry_t * +static fib_entry_t * fib_entry_src_action_copy (fib_entry_t *fib_entry, const fib_entry_src_t *orig_src) { fib_entry_src_t *esrc; - esrc = fib_entry_src_find_or_create(fib_entry, orig_src->fes_src); + esrc = fib_entry_src_find_or_create(fib_entry, + orig_src->fes_src, + orig_src->fes_entry_flags); + + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_copy, + (orig_src, fib_entry, esrc)); + + fib_path_list_unlock(esrc->fes_pl); - *esrc = *orig_src; + /* + * copy over all the data ... + */ + esrc->fes_flags = orig_src->fes_flags; + esrc->fes_pl = orig_src->fes_pl; + + /* + * ... then update + */ esrc->fes_ref_count = 1; esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_INHERITED; - esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_ACTIVE; + esrc->fes_flags &= ~(FIB_ENTRY_SRC_FLAG_ACTIVE | + FIB_ENTRY_SRC_FLAG_CONTRIBUTING); esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_COVERED_INHERIT; /* @@ -692,7 +827,9 @@ fib_entry_src_action_update_from_cover (fib_entry_t *fib_entry, { fib_entry_src_t *esrc; - esrc = fib_entry_src_find_or_create(fib_entry, orig_src->fes_src); + esrc = fib_entry_src_find_or_create(fib_entry, + orig_src->fes_src, + orig_src->fes_entry_flags); /* * the source owns a lock on the entry @@ -710,7 +847,7 @@ fib_entry_src_covered_inherit_add_i (fib_entry_t *fib_entry, { fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, cover_src->fes_src, NULL); + esrc = fib_entry_src_find(fib_entry, cover_src->fes_src); if (cover_src == esrc) { @@ -727,7 +864,7 @@ fib_entry_src_covered_inherit_add_i (fib_entry_t *fib_entry, /* * the covered source is itself a COVERED_INHERIT, i.e. * it also pushes this source down the sub-tree. - * We consider this more specfic covered to be the owner + * We consider this more specific covered to be the owner * of the sub-tree from this point down. */ return (FIB_TABLE_WALK_SUB_TREE_STOP); @@ -745,7 +882,7 @@ fib_entry_src_covered_inherit_add_i (fib_entry_t *fib_entry, { /* * The covered's source was not inherited and it is also - * not inherting. Nevertheless, it still owns the sub-tree from + * not inheriting. Nevertheless, it still owns the sub-tree from * this point down. */ return (FIB_TABLE_WALK_SUB_TREE_STOP); @@ -785,7 +922,7 @@ fib_entry_src_covered_inherit_walk_remove (fib_node_index_t fei, fib_entry = fib_entry_get(fei); cover_src = ctx; - esrc = fib_entry_src_find(fib_entry, cover_src->fes_src, NULL); + esrc = fib_entry_src_find(fib_entry, cover_src->fes_src); if (cover_src == esrc) { @@ -802,7 +939,7 @@ fib_entry_src_covered_inherit_walk_remove (fib_node_index_t fei, /* * the covered source is itself a COVERED_INHERIT, i.e. * it also pushes this source down the sub-tree. - * We consider this more specfic covered to be the owner + * We consider this more specific covered to be the owner * of the sub-tree from this point down. */ return (FIB_TABLE_WALK_SUB_TREE_STOP); @@ -823,7 +960,7 @@ fib_entry_src_covered_inherit_walk_remove (fib_node_index_t fei, { /* * The covered's source was not inherited and it is also - * not inherting. Nevertheless, it still owns the sub-tree from + * not inheriting. Nevertheless, it still owns the sub-tree from * this point down. */ return (FIB_TABLE_WALK_SUB_TREE_STOP); @@ -864,7 +1001,7 @@ fib_entry_src_covered_inherit_add (fib_entry_t *fib_entry, { fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE); @@ -902,19 +1039,21 @@ fib_entry_src_action_activate (fib_entry_t *fib_entry, { int houston_we_are_go_for_install; + const fib_entry_src_vft_t *vft; fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); ASSERT(!(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE)); ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ADDED); - esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_ACTIVE; + esrc->fes_flags |= (FIB_ENTRY_SRC_FLAG_ACTIVE | + FIB_ENTRY_SRC_FLAG_CONTRIBUTING); + vft = fib_entry_src_get_vft(esrc); - if (NULL != fib_entry_src_vft[source].fesv_activate) + if (NULL != vft->fesv_activate) { - houston_we_are_go_for_install = - fib_entry_src_vft[source].fesv_activate(esrc, fib_entry); + houston_we_are_go_for_install = vft->fesv_activate(esrc, fib_entry); } else { @@ -963,16 +1102,15 @@ fib_entry_src_action_deactivate (fib_entry_t *fib_entry, fib_node_index_t path_list_index; fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE); - if (NULL != fib_entry_src_vft[source].fesv_deactivate) - { - fib_entry_src_vft[source].fesv_deactivate(esrc, fib_entry); - } + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_deactivate, + (esrc, fib_entry)); - esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_ACTIVE; + esrc->fes_flags &= ~(FIB_ENTRY_SRC_FLAG_ACTIVE | + FIB_ENTRY_SRC_FLAG_CONTRIBUTING); FIB_ENTRY_DBG(fib_entry, "deactivate: %d", fib_entry->fe_parent); @@ -1007,12 +1145,8 @@ fib_entry_src_action_fwd_update (const fib_entry_t *fib_entry, vec_foreach(esrc, fib_entry->fe_srcs) { - if (NULL != fib_entry_src_vft[esrc->fes_src].fesv_fwd_update) - { - fib_entry_src_vft[esrc->fes_src].fesv_fwd_update(esrc, - fib_entry, - source); - } + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_fwd_update, + (esrc, fib_entry, source)); } } @@ -1021,9 +1155,11 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry, fib_source_t source) { fib_node_index_t path_list_index; + const fib_entry_src_vft_t *vft; fib_entry_src_t *esrc; + int remain_installed; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ACTIVE); @@ -1031,10 +1167,22 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry, fib_entry->fe_parent, esrc->fes_pl); - if (fib_entry->fe_parent != esrc->fes_pl) + /* + * call the source to reactive and get the go/no-go to remain installed + */ + vft = fib_entry_src_get_vft(esrc); + + if (NULL != vft->fesv_reactivate) { - int remain_installed; + remain_installed = vft->fesv_reactivate(esrc, fib_entry); + } + else + { + remain_installed = 1; + } + if (fib_entry->fe_parent != esrc->fes_pl) + { /* * un-link from an old path-list. Check for any loops this will clear */ @@ -1069,49 +1217,37 @@ fib_entry_src_action_reactivate (fib_entry_t *fib_entry, fib_entry_recursive_loop_detect_i(fib_entry->fe_parent); fib_path_list_unlock(path_list_index); - /* - * call the source to reactive and get the go/no-go to remain installed - */ - if (NULL != fib_entry_src_vft[source].fesv_reactivate) - { - remain_installed = - fib_entry_src_vft[source].fesv_reactivate(esrc, fib_entry); - } - else - { - remain_installed = 1; - } - /* * If this source should push its state to covered prefixs, do that now. */ fib_entry_src_covered_inherit_add(fib_entry, source); + } - if (!remain_installed) - { - fib_entry_src_action_uninstall(fib_entry); - return; - } + if (!remain_installed) + { + fib_entry_src_action_uninstall(fib_entry); + } + else + { + fib_entry_src_action_install(fib_entry, source); } - fib_entry_src_action_install(fib_entry, source); fib_entry_src_action_fwd_update(fib_entry, source); } -void -fib_entry_src_action_installed (const fib_entry_t *fib_entry, +fib_entry_t * +fib_entry_src_action_installed (fib_entry_t *fib_entry, fib_source_t source) { fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); - if (NULL != fib_entry_src_vft[source].fesv_installed) - { - fib_entry_src_vft[source].fesv_installed(esrc, - fib_entry); - } + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_installed, + (esrc, fib_entry)); fib_entry_src_action_fwd_update(fib_entry, source); + + return (fib_entry); } /* @@ -1128,13 +1264,20 @@ fib_entry_src_action_add (fib_entry_t *fib_entry, fib_entry_flag_t flags, const dpo_id_t *dpo) { - fib_node_index_t fib_entry_index; fib_entry_src_t *esrc; - esrc = fib_entry_src_find_or_create(fib_entry, source); + esrc = fib_entry_src_find_or_create(fib_entry, source, flags); + ASSERT(esrc->fes_ref_count < 255); esrc->fes_ref_count++; + if (flags != esrc->fes_entry_flags) + { + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_flags_change, + (esrc, fib_entry, flags)); + } + esrc->fes_entry_flags = flags; + if (1 != esrc->fes_ref_count) { /* @@ -1143,23 +1286,12 @@ fib_entry_src_action_add (fib_entry_t *fib_entry, return (fib_entry); } - esrc->fes_entry_flags = flags; - - /* - * save variable so we can recover from a fib_entry realloc. - */ - fib_entry_index = fib_entry_get_index(fib_entry); - - if (NULL != fib_entry_src_vft[source].fesv_add) - { - fib_entry_src_vft[source].fesv_add(esrc, - fib_entry, - flags, - fib_entry_get_dpo_proto(fib_entry), - dpo); - } - - fib_entry = fib_entry_get(fib_entry_index); + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_add, + (esrc, + fib_entry, + flags, + fib_entry_get_dpo_proto(fib_entry), + dpo)); esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_ADDED; @@ -1187,10 +1319,10 @@ fib_entry_src_action_update (fib_entry_t *fib_entry, fib_entry_flag_t flags, const dpo_id_t *dpo) { - fib_node_index_t fib_entry_index, old_path_list_index; + fib_node_index_t old_path_list_index; fib_entry_src_t *esrc; - esrc = fib_entry_src_find_or_create(fib_entry, source); + esrc = fib_entry_src_find_or_create(fib_entry, source, flags); if (NULL == esrc) { @@ -1200,21 +1332,12 @@ fib_entry_src_action_update (fib_entry_t *fib_entry, old_path_list_index = esrc->fes_pl; esrc->fes_entry_flags = flags; - /* - * save variable so we can recover from a fib_entry realloc. - */ - fib_entry_index = fib_entry_get_index(fib_entry); - - if (NULL != fib_entry_src_vft[source].fesv_add) - { - fib_entry_src_vft[source].fesv_add(esrc, - fib_entry, - flags, - fib_entry_get_dpo_proto(fib_entry), - dpo); - } - - fib_entry = fib_entry_get(fib_entry_index); + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_add, + (esrc, + fib_entry, + flags, + fib_entry_get_dpo_proto(fib_entry), + dpo)); esrc->fes_flags |= FIB_ENTRY_SRC_FLAG_ADDED; @@ -1230,7 +1353,7 @@ fib_entry_src_action_remove_or_update_inherit (fib_entry_t *fib_entry, { fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL == esrc) return (FIB_ENTRY_SRC_FLAG_ACTIVE); @@ -1259,7 +1382,7 @@ fib_entry_src_action_remove_or_update_inherit (fib_entry_t *fib_entry, ASSERT(coveri != fib_entry_get_index(fib_entry)); cover = fib_entry_get(coveri); - cover_src = fib_entry_src_find(cover, source, NULL); + cover_src = fib_entry_src_find(cover, source); ASSERT(NULL != cover_src); @@ -1288,7 +1411,7 @@ fib_entry_src_action_remove (fib_entry_t *fib_entry, fib_entry_src_flag_t sflags; fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL == esrc) return (FIB_ENTRY_SRC_FLAG_ACTIVE); @@ -1308,13 +1431,16 @@ fib_entry_src_action_remove (fib_entry_t *fib_entry, { fib_entry_src_action_deactivate(fib_entry, source); } + else if (esrc->fes_flags & FIB_ENTRY_SRC_FLAG_CONTRIBUTING) + { + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_deactivate, + (esrc, fib_entry)); + esrc->fes_flags &= ~FIB_ENTRY_SRC_FLAG_CONTRIBUTING; + } old_path_list = esrc->fes_pl; - if (NULL != fib_entry_src_vft[source].fesv_remove) - { - fib_entry_src_vft[source].fesv_remove(esrc); - } + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_remove, (esrc)); fib_path_list_unlock(old_path_list); fib_entry_unlock(fib_entry_get_index(fib_entry)); @@ -1331,48 +1457,38 @@ fib_entry_src_action_remove (fib_entry_t *fib_entry, * Return true the the route is attached via an interface that * is not in the same table as the route */ -static inline int +static int fib_route_attached_cross_table (const fib_entry_t *fib_entry, const fib_route_path_t *rpath) { - /* - * - All zeros next-hop - * - a valid interface - * - entry's fib index not equeal to interface's index - */ - if (ip46_address_is_zero(&rpath->frp_addr) && - (~0 != rpath->frp_sw_if_index) && - (fib_entry->fe_fib_index != - fib_table_get_index_for_sw_if_index(fib_entry_get_proto(fib_entry), - rpath->frp_sw_if_index))) + const fib_prefix_t *pfx = &fib_entry->fe_prefix; + + switch (pfx->fp_proto) { - return (!0); + case FIB_PROTOCOL_MPLS: + /* MPLS routes are never imported/exported */ + return (0); + case FIB_PROTOCOL_IP6: + /* Ignore link local addresses these also can't be imported/exported */ + if (ip6_address_is_link_local_unicast (&pfx->fp_addr.ip6)) + { + return (0); + } + break; + case FIB_PROTOCOL_IP4: + break; } - return (0); -} -/* - * fib_route_attached_cross_table - * - * Return true the the route is attached via an interface that - * is not in the same table as the route - */ -static inline int -fib_path_is_attached (const fib_route_path_t *rpath) -{ /* - * - All zeros next-hop - * - a valid interface + * an attached path and entry's fib index not equal to interface's index */ - if (ip46_address_is_zero(&rpath->frp_addr) && - (~0 != rpath->frp_sw_if_index)) + if (fib_route_path_is_attached(rpath) && + fib_entry->fe_fib_index != + fib_table_get_index_for_sw_if_index(fib_entry_get_proto(fib_entry), + rpath->frp_sw_if_index)) { return (!0); } - else if (rpath->frp_flags & FIB_ROUTE_PATH_ATTACHED) - { - return (!0); - } return (0); } @@ -1399,33 +1515,39 @@ fib_entry_src_flags_2_path_list_flags (fib_entry_flag_t eflags) static void fib_entry_flags_update (const fib_entry_t *fib_entry, - const fib_route_path_t *rpath, + const fib_route_path_t *rpaths, fib_path_list_flags_t *pl_flags, fib_entry_src_t *esrc) { - if ((esrc->fes_src == FIB_SOURCE_API) || - (esrc->fes_src == FIB_SOURCE_CLI)) - { - if (fib_path_is_attached(rpath)) - { - esrc->fes_entry_flags |= FIB_ENTRY_FLAG_ATTACHED; - } - else - { - esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_ATTACHED; - } - if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG) - { - esrc->fes_entry_flags |= FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT; - } - } - if (fib_route_attached_cross_table(fib_entry, rpath)) - { - esrc->fes_entry_flags |= FIB_ENTRY_FLAG_IMPORT; - } - else + const fib_route_path_t *rpath; + + vec_foreach(rpath, rpaths) { - esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_IMPORT; + if ((esrc->fes_src == FIB_SOURCE_API) || + (esrc->fes_src == FIB_SOURCE_CLI)) + { + if (fib_route_path_is_attached(rpath)) + { + esrc->fes_entry_flags |= FIB_ENTRY_FLAG_ATTACHED; + } + else + { + esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_ATTACHED; + } + if (rpath->frp_flags & FIB_ROUTE_PATH_DEAG) + { + esrc->fes_entry_flags |= FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT; + } + } + if (fib_route_attached_cross_table(fib_entry, rpath) && + !(esrc->fes_entry_flags & FIB_ENTRY_FLAG_NO_ATTACHED_EXPORT)) + { + esrc->fes_entry_flags |= FIB_ENTRY_FLAG_IMPORT; + } + else + { + esrc->fes_entry_flags &= ~FIB_ENTRY_FLAG_IMPORT; + } } } @@ -1441,27 +1563,29 @@ fib_entry_t* fib_entry_src_action_path_add (fib_entry_t *fib_entry, fib_source_t source, fib_entry_flag_t flags, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { - fib_node_index_t old_path_list, fib_entry_index; + fib_node_index_t old_path_list; fib_path_list_flags_t pl_flags; fib_entry_src_t *esrc; - /* - * save variable so we can recover from a fib_entry realloc. - */ - fib_entry_index = fib_entry_get_index(fib_entry); - - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL == esrc) { + const dpo_id_t *dpo; + + if (flags == FIB_ENTRY_FLAG_EXCLUSIVE) { + dpo = &rpaths->dpo; + } else { + dpo = drop_dpo_get(fib_entry_get_dpo_proto(fib_entry)); + } + fib_entry = fib_entry_src_action_add(fib_entry, source, flags, - drop_dpo_get( - fib_entry_get_dpo_proto(fib_entry))); - esrc = fib_entry_src_find(fib_entry, source, NULL); + dpo); + esrc = fib_entry_src_find(fib_entry, source); } /* @@ -1472,13 +1596,13 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry, */ old_path_list = esrc->fes_pl; - ASSERT(NULL != fib_entry_src_vft[source].fesv_path_add); + ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_add)); pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry)); - fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc); + fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc); - fib_entry_src_vft[source].fesv_path_add(esrc, fib_entry, pl_flags, rpath); - fib_entry = fib_entry_get(fib_entry_index); + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_path_add, + (esrc, fib_entry, pl_flags, rpaths)); fib_path_list_lock(esrc->fes_pl); fib_path_list_unlock(old_path_list); @@ -1498,32 +1622,38 @@ fib_entry_src_action_path_add (fib_entry_t *fib_entry, fib_entry_t* fib_entry_src_action_path_swap (fib_entry_t *fib_entry, fib_source_t source, - fib_entry_flag_t flags, + fib_entry_flag_t flags, const fib_route_path_t *rpaths) { - fib_node_index_t old_path_list, fib_entry_index; + fib_node_index_t old_path_list; fib_path_list_flags_t pl_flags; - const fib_route_path_t *rpath; fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); - - /* - * save variable so we can recover from a fib_entry realloc. - */ - fib_entry_index = fib_entry_get_index(fib_entry); + esrc = fib_entry_src_find(fib_entry, source); if (NULL == esrc) { - fib_entry = fib_entry_src_action_add(fib_entry, + const dpo_id_t *dpo; + + if (flags == FIB_ENTRY_FLAG_EXCLUSIVE) { + dpo = &rpaths->dpo; + } else { + dpo = drop_dpo_get(fib_entry_get_dpo_proto(fib_entry)); + } + + fib_entry = fib_entry_src_action_add(fib_entry, source, flags, - drop_dpo_get( - fib_entry_get_dpo_proto(fib_entry))); - esrc = fib_entry_src_find(fib_entry, source, NULL); + dpo); + esrc = fib_entry_src_find(fib_entry, source); } else { + if (flags != esrc->fes_entry_flags) + { + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_flags_change, + (esrc, fib_entry, flags)); + } esrc->fes_entry_flags = flags; } @@ -1534,21 +1664,15 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry, */ old_path_list = esrc->fes_pl; - ASSERT(NULL != fib_entry_src_vft[source].fesv_path_swap); + ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_swap)); pl_flags = fib_entry_src_flags_2_path_list_flags(flags); - vec_foreach(rpath, rpaths) - { - fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc); - } + fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc); - fib_entry_src_vft[source].fesv_path_swap(esrc, - fib_entry, - pl_flags, - rpaths); - - fib_entry = fib_entry_get(fib_entry_index); + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_path_swap, + (esrc, fib_entry, + pl_flags, rpaths)); fib_path_list_lock(esrc->fes_pl); fib_path_list_unlock(old_path_list); @@ -1559,13 +1683,13 @@ fib_entry_src_action_path_swap (fib_entry_t *fib_entry, fib_entry_src_flag_t fib_entry_src_action_path_remove (fib_entry_t *fib_entry, fib_source_t source, - const fib_route_path_t *rpath) + const fib_route_path_t *rpaths) { fib_path_list_flags_t pl_flags; fib_node_index_t old_path_list; fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); ASSERT(NULL != esrc); ASSERT(esrc->fes_flags & FIB_ENTRY_SRC_FLAG_ADDED); @@ -1578,12 +1702,13 @@ fib_entry_src_action_path_remove (fib_entry_t *fib_entry, */ old_path_list = esrc->fes_pl; - ASSERT(NULL != fib_entry_src_vft[source].fesv_path_remove); + ASSERT(FIB_ENTRY_SRC_VFT_EXISTS(esrc, fesv_path_remove)); pl_flags = fib_entry_src_flags_2_path_list_flags(fib_entry_get_flags_i(fib_entry)); - fib_entry_flags_update(fib_entry, rpath, &pl_flags, esrc); + fib_entry_flags_update(fib_entry, rpaths, &pl_flags, esrc); - fib_entry_src_vft[source].fesv_path_remove(esrc, pl_flags, rpath); + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_path_remove, + (esrc, pl_flags, rpaths)); /* * lock the new path-list, unlock the old if it had one @@ -1611,12 +1736,10 @@ fib_entry_src_format (fib_entry_t *fib_entry, { fib_entry_src_t *esrc; - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); + + FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_format, (esrc, s)); - if (NULL != fib_entry_src_vft[source].fesv_format) - { - return (fib_entry_src_vft[source].fesv_format(esrc, s)); - } return (s); } @@ -1631,7 +1754,7 @@ fib_entry_get_adj_for_source (fib_node_index_t fib_entry_index, return (ADJ_INDEX_INVALID); fib_entry = fib_entry_get(fib_entry_index); - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL != esrc) { @@ -1657,7 +1780,7 @@ fib_entry_get_dpo_for_source (fib_node_index_t fib_entry_index, return (0); fib_entry = fib_entry_get(fib_entry_index); - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL != esrc) { @@ -1675,6 +1798,25 @@ fib_entry_get_dpo_for_source (fib_node_index_t fib_entry_index, return (0); } +fib_node_index_t +fib_entry_get_path_list_for_source (fib_node_index_t fib_entry_index, + fib_source_t source) +{ + fib_entry_t *fib_entry; + fib_entry_src_t *esrc; + + if (FIB_NODE_INDEX_INVALID == fib_entry_index) + return FIB_NODE_INDEX_INVALID; + + fib_entry = fib_entry_get(fib_entry_index); + esrc = fib_entry_src_find(fib_entry, source); + + if (esrc) + return esrc->fes_pl; + + return FIB_NODE_INDEX_INVALID; +} + u32 fib_entry_get_resolving_interface_for_source (fib_node_index_t entry_index, fib_source_t source) @@ -1684,7 +1826,7 @@ fib_entry_get_resolving_interface_for_source (fib_node_index_t entry_index, fib_entry = fib_entry_get(entry_index); - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL != esrc) { @@ -1705,7 +1847,7 @@ fib_entry_get_flags_for_source (fib_node_index_t entry_index, fib_entry = fib_entry_get(entry_index); - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); if (NULL != esrc) { @@ -1715,27 +1857,22 @@ fib_entry_get_flags_for_source (fib_node_index_t entry_index, return (FIB_ENTRY_FLAG_NONE); } +fib_source_t +fib_entry_get_source_i (const fib_entry_t *fib_entry) +{ + /* the vector of sources is deliberately arranged in priority order */ + if (0 == vec_len(fib_entry->fe_srcs)) + return (FIB_SOURCE_INVALID); + return (vec_elt(fib_entry->fe_srcs, 0).fes_src); +} + fib_entry_flag_t fib_entry_get_flags_i (const fib_entry_t *fib_entry) { - fib_entry_flag_t flags; - - /* - * the vector of sources is deliberately arranged in priority order - */ + /* the vector of sources is deliberately arranged in priority order */ if (0 == vec_len(fib_entry->fe_srcs)) - { - flags = FIB_ENTRY_FLAG_NONE; - } - else - { - fib_entry_src_t *esrc; - - esrc = vec_elt_at_index(fib_entry->fe_srcs, 0); - flags = esrc->fes_entry_flags; - } - - return (flags); + return (FIB_ENTRY_FLAG_NONE); + return (vec_elt(fib_entry->fe_srcs, 0).fes_entry_flags); } void @@ -1747,12 +1884,12 @@ fib_entry_set_source_data (fib_node_index_t fib_entry_index, fib_entry_src_t *esrc; fib_entry = fib_entry_get(fib_entry_index); - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); - if (NULL != esrc && - NULL != fib_entry_src_vft[source].fesv_set_data) + if (NULL != esrc) { - fib_entry_src_vft[source].fesv_set_data(esrc, fib_entry, data); + FIB_ENTRY_SRC_VFT_INVOKE(fib_entry, esrc, fesv_set_data, + (esrc, fib_entry, data)); } } @@ -1764,12 +1901,12 @@ fib_entry_get_source_data (fib_node_index_t fib_entry_index, fib_entry_src_t *esrc; fib_entry = fib_entry_get(fib_entry_index); - esrc = fib_entry_src_find(fib_entry, source, NULL); + esrc = fib_entry_src_find(fib_entry, source); - if (NULL != esrc && - NULL != fib_entry_src_vft[source].fesv_get_data) + if (NULL != esrc) { - return (fib_entry_src_vft[source].fesv_get_data(esrc, fib_entry)); + FIB_ENTRY_SRC_VFT_INVOKE_AND_RETURN(esrc, fesv_get_data, + (esrc, fib_entry)); } return (NULL); } @@ -1779,8 +1916,9 @@ fib_entry_src_module_init (void) { fib_entry_src_rr_register(); fib_entry_src_interface_register(); - fib_entry_src_default_route_register(); - fib_entry_src_special_register(); + fib_entry_src_interpose_register(); + fib_entry_src_drop_register(); + fib_entry_src_simple_register(); fib_entry_src_api_register(); fib_entry_src_adj_register(); fib_entry_src_mpls_register();