X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fbier%2Fbier_entry.c;h=e8bf722d88ffeae8be145eb6bdee72fc3c4e702f;hb=097fa66b986f06281f603767d321ab13ab6c88c3;hp=2f8d25008ccf661bf70612f82e16373cb13ab63a;hpb=9128637ee8f7b0d903551f165a1447d427e8dd19;p=vpp.git diff --git a/src/vnet/bier/bier_entry.c b/src/vnet/bier/bier_entry.c index 2f8d25008cc..e8bf722d88f 100644 --- a/src/vnet/bier/bier_entry.c +++ b/src/vnet/bier/bier_entry.c @@ -73,27 +73,6 @@ bier_entry_create (index_t bti, return (bier_entry_get_index(be)); } -void -bier_entry_delete (index_t bei) -{ - bier_entry_t *be; - - be = bier_entry_get(bei); - - /* - * if we still ahve a path-list, unlink from it - */ - if (FIB_NODE_INDEX_INVALID != be->be_path_list) - { - fib_path_list_walk(be->be_path_list, - bier_entry_unlink_walk, - be); - fib_path_list_child_remove(be->be_path_list, - be->be_sibling_index); - } - - pool_put(bier_entry_pool, be); -} static void bier_entry_table_ecmp_walk_add_fmask (index_t btei, @@ -160,6 +139,33 @@ bier_entry_table_ecmp_walk_add_fmask (index_t btei, } } +void +bier_entry_delete (index_t bei) +{ + bier_entry_t *be; + + be = bier_entry_get(bei); + + /* + * if we still have a path-list, unlink from it + */ + if (FIB_NODE_INDEX_INVALID != be->be_path_list) + { + fib_path_list_walk(be->be_path_list, + bier_entry_unlink_walk, + be); + fib_path_list_child_remove(be->be_path_list, + be->be_sibling_index); + + be->be_path_list = FIB_NODE_INDEX_INVALID; + bier_table_ecmp_walk(be->be_bti, + bier_entry_table_ecmp_walk_add_fmask, + be); + } + + pool_put(bier_entry_pool, be); +} + void bier_entry_path_add (index_t bei, const fib_route_path_t *rpaths) @@ -218,7 +224,63 @@ bier_entry_path_add (index_t bei, } /* - * update the ECNP tables with the new choice + * update the ECMP tables with the new choice + */ + bier_table_ecmp_walk(be->be_bti, + bier_entry_table_ecmp_walk_add_fmask, + be); + + /* + * symmetric unlock. The old path-list may not exist hereinafter + */ + fib_path_list_unlock(old_pl_index); +} + +void +bier_entry_path_update (index_t bei, + const fib_route_path_t *rpaths) +{ + fib_node_index_t old_pl_index; + bier_entry_t *be; + + be = bier_entry_get(bei); + old_pl_index = be->be_path_list; + + /* + * lock the path-list so it does not go away before we unlink + * from its resolved fmasks + */ + fib_path_list_lock(old_pl_index); + + if (FIB_NODE_INDEX_INVALID != old_pl_index) + { + fib_path_list_child_remove(old_pl_index, + be->be_sibling_index); + } + + be->be_path_list = fib_path_list_create((FIB_PATH_LIST_FLAG_SHARED | + FIB_PATH_LIST_FLAG_NO_URPF), + rpaths); + be->be_sibling_index = fib_path_list_child_add(be->be_path_list, + FIB_NODE_TYPE_BIER_ENTRY, + bier_entry_get_index(be)); + + /* + * link the entry's bit-position to each fmask in the new path-list + * then unlink from the old. + */ + fib_path_list_walk(be->be_path_list, + bier_entry_link_walk, + be); + if (FIB_NODE_INDEX_INVALID != old_pl_index) + { + fib_path_list_walk(old_pl_index, + bier_entry_unlink_walk, + be); + } + + /* + * update the ECMP tables with the new choice */ bier_table_ecmp_walk(be->be_bti, bier_entry_table_ecmp_walk_add_fmask, @@ -279,9 +341,8 @@ bier_entry_path_remove (index_t bei, } fib_path_list_unlock(old_pl_index); - /* - * update the ECNP tables with the new choice + * update the ECMP tables with the new choice */ bier_table_ecmp_walk(be->be_bti, bier_entry_table_ecmp_walk_add_fmask,