X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=blobdiff_plain;f=src%2Fvnet%2Fbier%2Fbier_table.c;h=a9f8a6d338f21a1a5feb852d5d86734e08762fd0;hp=0f0f37677e94bff0ad70191f926dca3c37a7b084;hb=8feeaff56;hpb=9128637ee8f7b0d903551f165a1447d427e8dd19 diff --git a/src/vnet/bier/bier_table.c b/src/vnet/bier/bier_table.c index 0f0f37677e9..a9f8a6d338f 100644 --- a/src/vnet/bier/bier_table.c +++ b/src/vnet/bier/bier_table.c @@ -251,7 +251,7 @@ bier_table_mk_lfib (bier_table_t *bt) FIB_SOURCE_BIER); /* - * stack the entry on the forwarding chain prodcued by the + * stack the entry on the forwarding chain produced by the * path-list via the ECMP tables. */ fib_path_list_contribute_forwarding(bt->bt_pl, @@ -309,7 +309,7 @@ bier_table_mk_ecmp (index_t bti) } /* - * no oppotunity to share, this the resolving ECMP tables are unique + * no opportunity to share, this the resolving ECMP tables are unique * to this table. * no need to be a child of the path list, we can do nothing with any * notifications it would generate [not that it will]. @@ -329,6 +329,70 @@ bier_table_mk_ecmp (index_t bti) return (bt); } + +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; + + 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); + + /* + * 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); + } + } + + 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 + { + bti = bier_table_get_index(bt); + } + + bier_table_lock_i(bt); + + return (bti); +} + index_t bier_table_add_or_lock (const bier_table_id_t *btid, mpls_label_t local_label) @@ -379,36 +443,8 @@ bier_table_add_or_lock (const bier_table_id_t *btid, } else { - /* - * add a new table - */ - u32 key; - - 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); - - /* - * 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_create(btid, local_label); + bt = bier_table_get(bti); } bier_table_lock_i(bt); @@ -510,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; @@ -552,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) { @@ -562,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; @@ -584,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