diff options
author | Josh Bailey <joshb@google.com> | 2011-07-20 20:46:01 -0700 |
---|---|---|
committer | Josh Bailey <joshb@google.com> | 2011-07-20 20:46:01 -0700 |
commit | de8d5dff1523bb9fe47d54f31c9e5322bd805b44 (patch) | |
tree | 95d71dffb32d9e67a2f892ac5689a884117dcbcd /tests | |
parent | 96450faf3385a6ed9f4dd5c2c58776c4a664a8da (diff) |
bgpd: Adds support to mark up the BGP rib table entry with multipath
information based on the multipath list (mp_list) generated during
the best path calculation. Display "multipath" for paths that are
multipath and also on bestpath if the route is multipath. Flag a
best path with the BGP_INFO_MULTIPATH_CHG if the multipath
set has changed since the last update. This can be used to trigger
updates to zebra and peers.
The multipath markup is a lazily allocated bgp_info_mpath structure
that is added to the best path and any multipaths. The mpath structures
are linked together with the best path element at the head and the
other elements ordered by nexthop and then by peer address. This
markup scheme is updated by calling bgp_info_mpath_update() and passing
in a new mp_list the the current multipath set. There are additional
API's for walking the multipath set, querying the count of multipaths,
and for cleaning up the multipath markup information when freeing path
information.
* bgpd/bgp_mpath.c
* bgp_info_mpath_new(): Allocation of new mpath element
* bgp_info_mpath_free(): Release memory for mpath element
* bgp_info_mpath_get(): Access mpath element of path. Allocate memory
on-demand
* bgp_info_mpath_enqueue(): Enqueue a path onto the multipath list
* bgp_info_mpath_dequeue(): Remove a path from the multipath list
* bgp_info_mpath_first(): Return first path on the multipath list
* bgp_info_mpath_next(): Return next path on the multipath list
* bgp_info_mpath_count(): Return the number of paths on the multipath list
* bgp_info_mpath_count_set(): Set the number of paths on the multipath list
* bgp_info_mpath_update(): Update multipath markup on bgp route table entry
and flag any changes. Emit 'debug bgp event' output on any multipath
change.
* bgpd/bgp_mpath.h
* struct bgp_info_mpath: Information added to a bgp_info path to record
multipath information
* External declarations for new functions in bgp_mpath.c
* bgpd/bgp_route.c
* bgp_info_free(): Free mpath memory when freeing path information
* bgp_info_reap(): Dequeue path from multipath queue before deleting it
* bgp_best_selection(): Calls bgp_info_mpath_update() with latest
mp_list to mark-up rib table entry
* bgp_vty_out_detail(): Add display of multipath flag for a path. Also
display 'multipath' for bestpath if it is a multipath route
* bgpd/bgp_route.h
* struct bgp_info: Add pointer to bgp_info_mpath information
* Add flags to mark a path as multipath (BGP_INFO_MULTIPATH) and
to mark bestpath if multipath information has changed
(BGP_INFO_MULTIPATH_CHG)
* lib/memtypes.c
* Add MTYPE_BGP_MPATH_INFO for allocating memory for bgp_info_mpath
* tests/bgp_mpath_test.c
* Add test case for bgp_info_mpath_update() and supporting functions
Diffstat (limited to 'tests')
-rw-r--r-- | tests/bgp_mpath_test.c | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/tests/bgp_mpath_test.c b/tests/bgp_mpath_test.c index 4d51ddb8..15e450a2 100644 --- a/tests/bgp_mpath_test.c +++ b/tests/bgp_mpath_test.c @@ -194,7 +194,13 @@ testcase_t test_bgp_cfg_maximum_paths = { /*========================================================= * Testcase for bgp_mp_list */ -struct peer test_mp_list_peer[5]; +struct peer test_mp_list_peer[] = { + { .local_as = 1, .as = 2 }, + { .local_as = 1, .as = 2 }, + { .local_as = 1, .as = 2 }, + { .local_as = 1, .as = 2 }, + { .local_as = 1, .as = 2 }, +}; int test_mp_list_peer_count = sizeof (test_mp_list_peer)/ sizeof (struct peer); struct attr test_mp_list_attr[4]; struct bgp_info test_mp_list_info[] = { @@ -278,11 +284,87 @@ testcase_t test_bgp_mp_list = { }; /*========================================================= + * Testcase for bgp_info_mpath_update + */ + +struct bgp_node test_rn; + +static int +setup_bgp_info_mpath_update (testcase_t *t) +{ + int i; + str2prefix ("42.1.1.0/24", &test_rn.p); + setup_bgp_mp_list (t); + for (i = 0; i < test_mp_list_info_count; i++) + bgp_info_add (&test_rn, &test_mp_list_info[i]); + return 0; +} + +static int +run_bgp_info_mpath_update (testcase_t *t) +{ + struct bgp_info *new_best, *old_best, *mpath; + struct list mp_list; + struct bgp_maxpaths_cfg mp_cfg = { 3, 3 }; + int test_result = TEST_PASSED; + bgp_mp_list_init (&mp_list); + bgp_mp_list_add (&mp_list, &test_mp_list_info[4]); + bgp_mp_list_add (&mp_list, &test_mp_list_info[3]); + bgp_mp_list_add (&mp_list, &test_mp_list_info[0]); + bgp_mp_list_add (&mp_list, &test_mp_list_info[1]); + new_best = &test_mp_list_info[3]; + old_best = NULL; + bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg); + bgp_mp_list_clear (&mp_list); + EXPECT_TRUE (bgp_info_mpath_count (new_best) == 2, test_result); + mpath = bgp_info_mpath_first (new_best); + EXPECT_TRUE (mpath == &test_mp_list_info[0], test_result); + EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result); + mpath = bgp_info_mpath_next (mpath); + EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result); + EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result); + + bgp_mp_list_add (&mp_list, &test_mp_list_info[0]); + bgp_mp_list_add (&mp_list, &test_mp_list_info[1]); + new_best = &test_mp_list_info[0]; + old_best = &test_mp_list_info[3]; + bgp_info_mpath_update (&test_rn, new_best, old_best, &mp_list, &mp_cfg); + bgp_mp_list_clear (&mp_list); + EXPECT_TRUE (bgp_info_mpath_count (new_best) == 1, test_result); + mpath = bgp_info_mpath_first (new_best); + EXPECT_TRUE (mpath == &test_mp_list_info[1], test_result); + EXPECT_TRUE (CHECK_FLAG (mpath->flags, BGP_INFO_MULTIPATH), test_result); + EXPECT_TRUE (!CHECK_FLAG (test_mp_list_info[0].flags, BGP_INFO_MULTIPATH), + test_result); + + return test_result; +} + +static int +cleanup_bgp_info_mpath_update (testcase_t *t) +{ + int i; + + for (i = 0; i < test_mp_list_peer_count; i++) + sockunion_free (test_mp_list_peer[i].su_remote); + + return 0; +} + +testcase_t test_bgp_info_mpath_update = { + .desc = "Test bgp_info_mpath_update", + .setup = setup_bgp_info_mpath_update, + .run = run_bgp_info_mpath_update, + .cleanup = cleanup_bgp_info_mpath_update, +}; + +/*========================================================= * Set up testcase vector */ testcase_t *all_tests[] = { &test_bgp_cfg_maximum_paths, &test_bgp_mp_list, + &test_bgp_info_mpath_update, }; int all_tests_count = (sizeof(all_tests)/sizeof(testcase_t *)); |