X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fbier%2Fbier_table.c;h=edfb754ecc18e92b3053a4f25abd411fd2cce947;hb=fe4e48f617f3e0f62880adebdcfb5989aa4e6db7;hp=74a099106012e373caa5103dc60fa0237b08f4cc;hpb=d792d9c01e60656cbfe1b0f1fd6a9b125f5dab0c;p=vpp.git diff --git a/src/vnet/bier/bier_table.c b/src/vnet/bier/bier_table.c index 74a09910601..edfb754ecc1 100644 --- a/src/vnet/bier/bier_table.c +++ b/src/vnet/bier/bier_table.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -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 { @@ -109,6 +107,33 @@ 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) { @@ -116,6 +141,9 @@ bier_table_rm_lfib (bier_table_t *bt) { 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, @@ -292,50 +329,122 @@ bier_table_mk_ecmp (index_t bti) return (bt); } -index_t -bier_table_add_or_lock (const bier_table_id_t *btid, - mpls_label_t local_label) + +static index_t +bier_table_create (const bier_table_id_t *btid, + mpls_label_t local_label) { + /* + * add a new table + */ bier_table_t *bt; index_t bti; + u32 key; - bt = bier_table_find(btid); + key = bier_table_mk_key(btid); + + pool_get_aligned(bier_table_pool, bt, CLIB_CACHE_LINE_BYTES); + bier_table_init(bt, btid, local_label); + + hash_set(bier_tables_by_key, key, bier_table_get_index(bt)); + bti = bier_table_get_index(bt); + + if (bier_table_is_main(bt)) + { + bt = bier_table_mk_ecmp(bti); - if (NULL != bt) { /* - * modify an existing table. - * change the lfib entry to the new local label + * add whichever mpls-fib or bift we need */ - if (bier_table_is_main(bt) && - (local_label != MPLS_LABEL_INVALID)) + if (local_label != MPLS_LABEL_INVALID) { - bier_table_rm_lfib(bt); - bt->bt_ll = local_label; bier_table_mk_lfib(bt); } - bti = bier_table_get_index(bt); + else + { + bier_table_mk_bift(bt); + } + } + + return (bti); +} + +index_t +bier_table_lock (const bier_table_id_t *btid) +{ + bier_table_t *bt; + index_t bti; + + bt = bier_table_find(btid); + + if (NULL == bt) + { + bti = bier_table_create(btid, MPLS_LABEL_INVALID); + bt = bier_table_get(bti); } else { - /* - * add a new table - */ - u32 key; + bti = bier_table_get_index(bt); + } - key = bier_table_mk_key(btid); + bier_table_lock_i(bt); - pool_get_aligned(bier_table_pool, bt, CLIB_CACHE_LINE_BYTES); - bier_table_init(bt, btid, local_label); + return (bti); +} - hash_set(bier_tables_by_key, key, bier_table_get_index(bt)); - bti = bier_table_get_index(bt); +index_t +bier_table_add_or_lock (const bier_table_id_t *btid, + mpls_label_t local_label) +{ + bier_table_t *bt; + index_t bti; + + bt = bier_table_find(btid); + if (NULL != bt) { + /* + * modify an existing table. + * change the lfib entry to the new local label + */ if (bier_table_is_main(bt)) { - bt = bier_table_mk_ecmp(bti); - bier_table_mk_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; + + /* + * 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); + } + else + { + bti = bier_table_create(btid, local_label); + bt = bier_table_get(bti); } bier_table_lock_i(bt); @@ -393,7 +502,8 @@ const static dpo_vft_t bier_table_dpo_vft = { const static char *const bier_table_mpls_nodes[] = { - "bier-input" + "bier-input", + NULL }; const static char * const * const bier_table_nodes[DPO_PROTO_NUM] = { @@ -436,9 +546,10 @@ bier_table_remove (bier_table_t *bt, } void -bier_table_route_add (const bier_table_id_t *btid, - bier_bp_t bp, - fib_route_path_t *brps) +bier_table_route_path_update_i (const bier_table_id_t *btid, + bier_bp_t bp, + fib_route_path_t *brps, + u8 is_replace) { index_t bfmi, bti, bei, *bfmip, *bfmis = NULL; fib_route_path_t *brp; @@ -458,16 +569,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) @@ -475,7 +589,23 @@ bier_table_route_add (const bier_table_id_t *btid, bei = bier_entry_create(bti, bp); bier_table_insert(bt, bp, bei); } - bier_entry_path_add(bei, brps); + + if (is_replace) + { + bier_entry_path_update(bei, brps); + } + else + { + fib_route_path_t *t_paths = NULL; + + vec_foreach(brp, brps) + { + vec_add1(t_paths, *brp); + bier_entry_path_add(bei, t_paths); + vec_reset_length(t_paths); + } + vec_free(t_paths); + } vec_foreach(bfmip, bfmis) { @@ -485,15 +615,28 @@ bier_table_route_add (const bier_table_id_t *btid, } void -bier_table_route_remove (const bier_table_id_t *bti, - bier_bp_t bp, - fib_route_path_t *brps) +bier_table_route_path_update (const bier_table_id_t *btid, + bier_bp_t bp, + fib_route_path_t *brps) +{ + bier_table_route_path_update_i(btid, bp, brps, 1); +} +void +bier_table_route_path_add (const bier_table_id_t *btid, + bier_bp_t bp, + fib_route_path_t *brps) +{ + bier_table_route_path_update_i(btid, bp, brps, 0); +} + +void +bier_table_route_delete (const bier_table_id_t *btid, + bier_bp_t bp) { - fib_route_path_t *brp = NULL; bier_table_t *bt; index_t bei; - bt = bier_table_find(bti); + bt = bier_table_find(btid); if (NULL == bt) { return; @@ -507,17 +650,78 @@ bier_table_route_remove (const bier_table_id_t *bti, return; } - vec_foreach(brp, brps) + bier_table_remove(bt, bp); + bier_entry_delete(bei); +} + +void +bier_table_route_path_remove (const bier_table_id_t *btid, + bier_bp_t bp, + fib_route_path_t *brps) +{ + fib_route_path_t *brp = NULL, *t_paths = NULL; + index_t bfmi, bti, bei; + bier_table_t *bt; + u32 ii; + + bt = bier_table_find(btid); + + if (NULL == bt) { + return; + } + + bti = bier_table_get_index(bt); + bei = bier_table_lookup(bt, bp); + + if (INDEX_INVALID == bei) { - brp->frp_bier_fib_index = bier_table_get_index(bt); + /* no such entry */ + return; } - if (0 == bier_entry_path_remove(bei, brps)) + /* + * set the FIB index in the path to the BIER table index + */ + vec_foreach_index(ii, brps) { - /* 0 remaining paths */ - bier_table_remove(bt, bp); - bier_entry_delete(bei); + brp = &brps[ii]; + bfmi = bier_fmask_db_find(bti, brp); + + if (INDEX_INVALID == bfmi) + { + /* + * no matching fmask, not a path we can remove + */ + vec_del1(brps, ii); + continue; + } + + /* + * 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 (0 == vec_len(brps)) + { + return; + } + + vec_foreach(brp, brps) + { + vec_add1(t_paths, *brp); + if (0 == bier_entry_path_remove(bei, t_paths)) + { + /* 0 remaining paths */ + bier_table_remove(bt, bp); + bier_entry_delete(bei); + break; + } + vec_reset_length(t_paths); } + vec_free(t_paths); } void @@ -535,6 +739,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 @@ -641,12 +846,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);