diff options
Diffstat (limited to 'src/vnet/bier/bier_table.c')
-rw-r--r-- | src/vnet/bier/bier_table.c | 127 |
1 files changed, 102 insertions, 25 deletions
diff --git a/src/vnet/bier/bier_table.c b/src/vnet/bier/bier_table.c index 191ac01e373..0f0f37677e9 100644 --- a/src/vnet/bier/bier_table.c +++ b/src/vnet/bier/bier_table.c @@ -20,6 +20,7 @@ #include <vnet/bier/bier_update.h> #include <vnet/bier/bier_fmask_db.h> #include <vnet/bier/bier_fmask.h> +#include <vnet/bier/bier_bift_table.h> #include <vnet/fib/mpls_fib.h> #include <vnet/mpls/mpls.h> @@ -96,9 +97,6 @@ bier_table_init (bier_table_t *bt, num_entries, INDEX_INVALID, CLIB_CACHE_LINE_BYTES); - fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS, - MPLS_FIB_DEFAULT_TABLE_ID, - FIB_SOURCE_BIER); } else { @@ -110,12 +108,42 @@ bier_table_init (bier_table_t *bt, } static void +bier_table_rm_bift (bier_table_t *bt) +{ + ASSERT(MPLS_LABEL_INVALID == bt->bt_ll); + + bier_bift_table_entry_remove(bier_bift_id_encode(bt->bt_id.bti_set, + bt->bt_id.bti_sub_domain, + bt->bt_id.bti_hdr_len)); +} + +static void +bier_table_mk_bift (bier_table_t *bt) +{ + dpo_id_t dpo = DPO_INVALID; + + ASSERT(MPLS_LABEL_INVALID == bt->bt_ll); + + bier_table_contribute_forwarding(bier_table_get_index(bt), &dpo); + + bier_bift_table_entry_add(bier_bift_id_encode(bt->bt_id.bti_set, + bt->bt_id.bti_sub_domain, + bt->bt_id.bti_hdr_len), + &dpo); + + dpo_reset(&dpo); +} + +static void bier_table_rm_lfib (bier_table_t *bt) { if (FIB_NODE_INDEX_INVALID != bt->bt_lfei) { fib_table_entry_delete_index(bt->bt_lfei, FIB_SOURCE_BIER); + fib_table_unlock(MPLS_FIB_DEFAULT_TABLE_ID, + FIB_PROTOCOL_MPLS, + FIB_SOURCE_BIER); } bt->bt_lfei = FIB_NODE_INDEX_INVALID; } @@ -127,6 +155,15 @@ bier_table_destroy (bier_table_t *bt) { index_t *bei; + if (MPLS_LABEL_INVALID != bt->bt_ll) + { + bier_table_rm_lfib(bt); + } + else + { + bier_table_rm_bift(bt); + } + fib_path_list_unlock(bt->bt_pl); bt->bt_pl = FIB_NODE_INDEX_INVALID; /* @@ -140,10 +177,6 @@ bier_table_destroy (bier_table_t *bt) } } vec_free (bt->bt_entries); - fib_table_unlock(fib_table_find(FIB_PROTOCOL_MPLS, - MPLS_FIB_DEFAULT_TABLE_ID), - FIB_PROTOCOL_MPLS, - FIB_SOURCE_BIER); } else { @@ -177,7 +210,6 @@ bier_table_unlock_i (bier_table_t *bt) if (0 == bt->bt_locks) { - bier_table_rm_lfib(bt); bier_table_destroy(bt); } } @@ -214,12 +246,17 @@ bier_table_mk_lfib (bier_table_t *bt) u32 mpls_fib_index; dpo_id_t dpo = DPO_INVALID; + fib_table_find_or_create_and_lock(FIB_PROTOCOL_MPLS, + MPLS_FIB_DEFAULT_TABLE_ID, + FIB_SOURCE_BIER); + /* * stack the entry on the forwarding chain prodcued by the * path-list via the ECMP tables. */ fib_path_list_contribute_forwarding(bt->bt_pl, FIB_FORW_CHAIN_TYPE_BIER, + FIB_PATH_LIST_FWD_FLAG_COLLAPSE, &dpo); mpls_fib_index = fib_table_find(FIB_PROTOCOL_MPLS, @@ -306,13 +343,37 @@ bier_table_add_or_lock (const bier_table_id_t *btid, * modify an existing table. * change the lfib entry to the new local label */ - if (bier_table_is_main(bt) && - (local_label != MPLS_LABEL_INVALID)) + if (bier_table_is_main(bt)) { - bier_table_rm_lfib(bt); + /* + * remove the mpls-fib or bift entry + */ + if (MPLS_LABEL_INVALID != bt->bt_ll) + { + bier_table_rm_lfib(bt); + } + else + { + bier_table_rm_bift(bt); + } + + /* + * reset + */ + bt->bt_ll = MPLS_LABEL_INVALID; - bt->bt_ll = local_label; - bier_table_mk_lfib(bt); + /* + * add whichever mpls-fib or bift we need + */ + if (local_label != MPLS_LABEL_INVALID) + { + bt->bt_ll = local_label; + bier_table_mk_lfib(bt); + } + else + { + bier_table_mk_bift(bt); + } } bti = bier_table_get_index(bt); } @@ -334,7 +395,19 @@ bier_table_add_or_lock (const bier_table_id_t *btid, if (bier_table_is_main(bt)) { bt = bier_table_mk_ecmp(bti); - bier_table_mk_lfib(bt); + + /* + * add whichever mpls-fib or bift we need + */ + if (local_label != MPLS_LABEL_INVALID) + { + bt->bt_ll = local_label; + bier_table_mk_lfib(bt); + } + else + { + bier_table_mk_bift(bt); + } } } @@ -459,16 +532,19 @@ bier_table_route_add (const bier_table_id_t *btid, */ vec_foreach(brp, brps) { - bier_fmask_id_t fmid = { - .bfmi_nh = brp->frp_addr, - .bfmi_hdr_type = BIER_HDR_O_MPLS, - }; - bfmi = bier_fmask_db_find_or_create_and_lock(bier_table_get_index(bt), - &fmid, - brp); - - brp->frp_bier_fib_index = bti; + /* + * First use the path to find or construct an FMask object + * via the next-hop + */ + bfmi = bier_fmask_db_find_or_create_and_lock(bti, brp); vec_add1(bfmis, bfmi); + + /* + * then modify the path to resolve via this fmask object + * and use it to resolve the BIER entry. + */ + brp->frp_flags = FIB_ROUTE_PATH_BIER_FMASK; + brp->frp_bier_fmask = bfmi; } if (INDEX_INVALID == bei) @@ -536,6 +612,7 @@ bier_table_contribute_forwarding (index_t bti, */ fib_path_list_contribute_forwarding(bt->bt_pl, FIB_FORW_CHAIN_TYPE_BIER, + FIB_PATH_LIST_FWD_FLAG_COLLAPSE, dpo); } else @@ -642,12 +719,12 @@ format_bier_table (u8 *s, va_list *ap) if (pool_is_free_index(bier_table_pool, bti)) { - return (format(s, "No BIER f-mask %d", bti)); + return (format(s, "No BIER table %d", bti)); } bt = bier_table_get(bti); - s = format(s, "[@%d] bier-table:[%U local-label:%U]", + s = format(s, "[@%d] bier-table:[%U local-label:%U", bti, format_bier_table_id, &bt->bt_id, format_mpls_unicast_label, bt->bt_ll); |