frr/bgpd/bgp_mpath.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

713 lines
18 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* BGP Multipath
* Copyright (C) 2010 Google Inc.
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
* 2024 Nvidia Corporation
* Donald Sharp
*
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
* This file is part of FRR
*/
#include <zebra.h>
#include "command.h"
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
#include "prefix.h"
#include "linklist.h"
#include "sockunion.h"
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
2011-07-21 05:46:01 +02:00
#include "memory.h"
#include "queue.h"
#include "filter.h"
#include "bgpd/bgpd.h"
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
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
2011-07-21 05:46:01 +02:00
#include "bgpd/bgp_debug.h"
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_ecommunity.h"
#include "bgpd/bgp_lcommunity.h"
#include "bgpd/bgp_mpath.h"
/*
* bgp_maximum_paths_set
*
* Record maximum-paths configuration for BGP instance
*/
int bgp_maximum_paths_set(struct bgp *bgp, afi_t afi, safi_t safi, int peertype,
uint16_t maxpaths, bool same_clusterlen)
{
if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
return -1;
switch (peertype) {
case BGP_PEER_IBGP:
bgp->maxpaths[afi][safi].maxpaths_ibgp = maxpaths;
bgp->maxpaths[afi][safi].same_clusterlen = same_clusterlen;
break;
case BGP_PEER_EBGP:
bgp->maxpaths[afi][safi].maxpaths_ebgp = maxpaths;
break;
default:
return -1;
}
return 0;
}
/*
* bgp_maximum_paths_unset
*
* Remove maximum-paths configuration from BGP instance
*/
int bgp_maximum_paths_unset(struct bgp *bgp, afi_t afi, safi_t safi,
int peertype)
{
if (!bgp || (afi >= AFI_MAX) || (safi >= SAFI_MAX))
return -1;
switch (peertype) {
case BGP_PEER_IBGP:
bgp->maxpaths[afi][safi].maxpaths_ibgp = multipath_num;
bgp->maxpaths[afi][safi].same_clusterlen = false;
break;
case BGP_PEER_EBGP:
bgp->maxpaths[afi][safi].maxpaths_ebgp = multipath_num;
break;
default:
return -1;
}
return 0;
}
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
/*
* bgp_interface_same
*
* Return true if ifindex for ifp1 and ifp2 are the same, else return false.
*/
static int bgp_interface_same(struct interface *ifp1, struct interface *ifp2)
{
if (!ifp1 && !ifp2)
return 1;
if (!ifp1 && ifp2)
return 0;
if (ifp1 && !ifp2)
return 0;
return (ifp1->ifindex == ifp2->ifindex);
}
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
/*
* bgp_path_info_nexthop_cmp
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
*
* Compare the nexthops of two paths. Return value is less than, equal to,
* or greater than zero if bpi1 is respectively less than, equal to,
* or greater than bpi2.
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
*/
int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,
struct bgp_path_info *bpi2)
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
{
int compare;
struct in6_addr addr1, addr2;
compare = IPV4_ADDR_CMP(&bpi1->attr->nexthop, &bpi2->attr->nexthop);
if (!compare) {
if (bpi1->attr->mp_nexthop_len == bpi2->attr->mp_nexthop_len) {
switch (bpi1->attr->mp_nexthop_len) {
2015-05-20 03:04:00 +02:00
case BGP_ATTR_NHLEN_IPV4:
case BGP_ATTR_NHLEN_VPNV4:
compare = IPV4_ADDR_CMP(
&bpi1->attr->mp_nexthop_global_in,
&bpi2->attr->mp_nexthop_global_in);
break;
2015-05-20 03:04:00 +02:00
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
compare = IPV6_ADDR_CMP(
&bpi1->attr->mp_nexthop_global,
&bpi2->attr->mp_nexthop_global);
break;
2015-05-20 03:04:00 +02:00
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
addr1 = (CHECK_FLAG(bpi1->attr->nh_flags,
BGP_ATTR_NH_MP_PREFER_GLOBAL))
? bpi1->attr->mp_nexthop_global
: bpi1->attr->mp_nexthop_local;
addr2 = (CHECK_FLAG(bpi2->attr->nh_flags,
BGP_ATTR_NH_MP_PREFER_GLOBAL))
? bpi2->attr->mp_nexthop_global
: bpi2->attr->mp_nexthop_local;
if (!CHECK_FLAG(bpi1->attr->nh_flags,
BGP_ATTR_NH_MP_PREFER_GLOBAL) &&
!CHECK_FLAG(bpi2->attr->nh_flags,
BGP_ATTR_NH_MP_PREFER_GLOBAL))
compare = !bgp_interface_same(
bpi1->peer->ifp,
bpi2->peer->ifp);
if (!compare)
compare = IPV6_ADDR_CMP(&addr1, &addr2);
break;
}
}
/* This can happen if one IPv6 peer sends you global and
* link-local
* nexthops but another IPv6 peer only sends you global
*/
else if (bpi1->attr->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL
|| bpi1->attr->mp_nexthop_len
== BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
compare = IPV6_ADDR_CMP(&bpi1->attr->mp_nexthop_global,
&bpi2->attr->mp_nexthop_global);
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
if (!compare) {
if (bpi1->attr->mp_nexthop_len
< bpi2->attr->mp_nexthop_len)
compare = -1;
else
compare = 1;
}
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
}
}
bgpd: VRF-Lite fix best path selection Description: Incorrect behavior during best path selection for the imported routes. Imported routes are always treated as eBGP routes. Change is intended for fixing the issues related to bgp best path selection for leaked routes: - FRR does ecmp for the imported routes, even without any ecmp related config. If the same prefix is imported from two different VRFs, then we configure the route with ecmp even without any ecmp related config. - Locally imported routes are preferred over imported eBGP routes. If there is a local route and eBGP learned route for the same prefix, if we import both the routes, imported local route is selected as best path. - Same route is imported from multiple tenant VRFs, both imported routes point to the same VRF in nexthop. - When the same route with same nexthop in two different VRFs is imported from those two VRFs, route is not installed as ecmp, even though we had ecmp config. - During best path selection, while comparing the paths for imported routes, we should correctly refer to the original route i.e. the ultimate path. - When the same route is imported from multiple VRF, use the correct VRF while installing in the FIB. - When same route is imported from two different tenant VRFs, while comparing bgp path info as part of bgp best path selection, we should ideally also compare corresponding VRFs. See-also: https://github.com/FRRouting/frr/files/7169555/FRR.and.Cisco.VRF-Lite.Behaviour.pdf Co-authored-by: Santosh P K <sapk@vmware.com> Co-authored-by: Kantesh Mundaragi <kmundaragi@vmware.com> Signed-off-by: Iqra Siddiqui <imujeebsiddi@vmware.com>
2020-06-08 23:40:17 +02:00
/*
* If both nexthops are same then check
* if they belong to same VRF
*/
if (!compare && bpi1->attr->nh_type != NEXTHOP_TYPE_BLACKHOLE) {
if (bpi1->extra && bpi1->extra->vrfleak &&
bpi1->extra->vrfleak->bgp_orig && bpi2->extra &&
bpi2->extra->vrfleak && bpi2->extra->vrfleak->bgp_orig) {
if (bpi1->extra->vrfleak->bgp_orig->vrf_id !=
bpi2->extra->vrfleak->bgp_orig->vrf_id) {
bgpd: VRF-Lite fix best path selection Description: Incorrect behavior during best path selection for the imported routes. Imported routes are always treated as eBGP routes. Change is intended for fixing the issues related to bgp best path selection for leaked routes: - FRR does ecmp for the imported routes, even without any ecmp related config. If the same prefix is imported from two different VRFs, then we configure the route with ecmp even without any ecmp related config. - Locally imported routes are preferred over imported eBGP routes. If there is a local route and eBGP learned route for the same prefix, if we import both the routes, imported local route is selected as best path. - Same route is imported from multiple tenant VRFs, both imported routes point to the same VRF in nexthop. - When the same route with same nexthop in two different VRFs is imported from those two VRFs, route is not installed as ecmp, even though we had ecmp config. - During best path selection, while comparing the paths for imported routes, we should correctly refer to the original route i.e. the ultimate path. - When the same route is imported from multiple VRF, use the correct VRF while installing in the FIB. - When same route is imported from two different tenant VRFs, while comparing bgp path info as part of bgp best path selection, we should ideally also compare corresponding VRFs. See-also: https://github.com/FRRouting/frr/files/7169555/FRR.and.Cisco.VRF-Lite.Behaviour.pdf Co-authored-by: Santosh P K <sapk@vmware.com> Co-authored-by: Kantesh Mundaragi <kmundaragi@vmware.com> Signed-off-by: Iqra Siddiqui <imujeebsiddi@vmware.com>
2020-06-08 23:40:17 +02:00
compare = 1;
}
}
}
bgpd: Adds equal-paths check to path comparison. Paths that are equal to the best path are accumulated onto an ordered list (mp_list) if maximum-paths is configured. A future commit will add the multipath markup to the BGP rib table based on the mp_list. Add unit test for the added mp_list functions. Deterministic MED is not supported in this commit, it will be added later. * bgpd/bgp_aspath.c * Make aspath_cmp() an external symbol so it can be used in equivalent paths check * bgpd/bgp_aspath.h * Add extern declaration of aspath_cmp() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Compares nexthops of two paths * bgp_info_mpath_cmp(): Compare function to order multipaths by nexthop and then by peer address * bgp_mp_list_init(): Initialize a list with the multipath order function * bgp_mp_list_clear(): Clear out the mp_list * bgp_mp_list_add(): Add a multipath to mp_list * bgpd/bgp_mpath.h * External declarations for above added functions in bgp_mpath.c * bgpd/bgp_route.c * bgp_info_cmp(): Add equivalent paths result (paths_eq). If eBGP paths are equal down to IGP metric check, flag as equal if peer AS matches. Similarly for iBGP paths but compare full AS_PATH. * bgp_best_selection(): If multipath is enabled, accumulate equivalent paths in mp_list. Add debug bgp event output to see result (will be filtered later to display only when change occurs) * bgp_process_rsclient(): Pass multipath config to bgp_best_selection() * bgp_process_main(): Pass multipath config to bgp_best_selection() * tests/bgp_mpath_test.c * Add unit test case for bgp_mp_list functions
2011-07-21 05:45:12 +02:00
return compare;
}
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
2011-07-21 05:46:01 +02:00
/*
* bgp_path_info_mpath_new
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
2011-07-21 05:46:01 +02:00
*
* Allocate and zero memory for a new bgp_path_info_mpath element
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
2011-07-21 05:46:01 +02:00
*/
static struct bgp_path_info_mpath *bgp_path_info_mpath_new(void)
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
2011-07-21 05:46:01 +02:00
{
struct bgp_path_info_mpath *new_mpath;
new_mpath = XCALLOC(MTYPE_BGP_MPATH_INFO,
sizeof(struct bgp_path_info_mpath));
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
new_mpath->mp_count = 1;
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
2011-07-21 05:46:01 +02:00
return new_mpath;
}
/*
* bgp_path_info_mpath_free
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
2011-07-21 05:46:01 +02:00
*
* Release resources for a bgp_path_info_mpath element and zero out pointer
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
2011-07-21 05:46:01 +02:00
*/
void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath)
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
2011-07-21 05:46:01 +02:00
{
if (mpath && *mpath) {
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
if ((*mpath)->mp_attr)
bgp_attr_unintern(&(*mpath)->mp_attr);
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
(*mpath)->mp_attr = NULL;
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
2011-07-21 05:46:01 +02:00
XFREE(MTYPE_BGP_MPATH_INFO, *mpath);
}
}
/*
* bgp_path_info_mpath_get
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
2011-07-21 05:46:01 +02:00
*
* Fetch the mpath element for the given bgp_path_info. Used for
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
2011-07-21 05:46:01 +02:00
* doing lazy allocation.
*/
static struct bgp_path_info_mpath *
bgp_path_info_mpath_get(struct bgp_path_info *path)
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
2011-07-21 05:46:01 +02:00
{
struct bgp_path_info_mpath *mpath;
if (!path)
return NULL;
if (!path->mpath) {
mpath = bgp_path_info_mpath_new();
path->mpath = mpath;
mpath->mp_info = path;
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
2011-07-21 05:46:01 +02:00
}
return path->mpath;
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
2011-07-21 05:46:01 +02:00
}
/*
* bgp_path_info_mpath_next
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
2011-07-21 05:46:01 +02:00
*
* Given a bgp_path_info, return the next multipath entry
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
2011-07-21 05:46:01 +02:00
*/
struct bgp_path_info *bgp_path_info_mpath_next(struct bgp_path_info *path)
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
2011-07-21 05:46:01 +02:00
{
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
path = path->next;
while (path) {
if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
return path;
path = path->next;
}
return NULL;
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
2011-07-21 05:46:01 +02:00
}
/*
* bgp_path_info_mpath_first
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
2011-07-21 05:46:01 +02:00
*
* Given bestpath bgp_path_info, return the first multipath entry.
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
2011-07-21 05:46:01 +02:00
*/
struct bgp_path_info *bgp_path_info_mpath_first(struct bgp_path_info *path)
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
2011-07-21 05:46:01 +02:00
{
return bgp_path_info_mpath_next(path);
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
2011-07-21 05:46:01 +02:00
}
/*
* bgp_path_info_mpath_count
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
2011-07-21 05:46:01 +02:00
*
* Given the bestpath bgp_path_info, return the number of multipath entries
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
2011-07-21 05:46:01 +02:00
*/
uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path)
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
2011-07-21 05:46:01 +02:00
{
if (!path->mpath)
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
return 1;
return path->mpath->mp_count;
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
2011-07-21 05:46:01 +02:00
}
/*
* bgp_path_info_mpath_count_set
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
2011-07-21 05:46:01 +02:00
*
* Sets the count of multipaths into bestpath's mpath element
*/
static void bgp_path_info_mpath_count_set(struct bgp_path_info *path,
uint16_t count)
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
2011-07-21 05:46:01 +02:00
{
struct bgp_path_info_mpath *mpath;
if (!count && !path->mpath)
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
2011-07-21 05:46:01 +02:00
return;
mpath = bgp_path_info_mpath_get(path);
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
2011-07-21 05:46:01 +02:00
if (!mpath)
return;
mpath->mp_count = count;
}
/*
* bgp_path_info_mpath_lb_update
*
* Update cumulative info related to link-bandwidth
*
* This is only set on the first mpath of the list
* as such we should UNSET the flags when removing
* to ensure nothing accidently happens
*/
static void bgp_path_info_mpath_lb_update(struct bgp_path_info *path, bool set,
bool all_paths_lb, uint64_t cum_bw)
{
struct bgp_path_info_mpath *mpath;
mpath = path->mpath;
if (mpath == NULL) {
if (!set || (cum_bw == 0 && !all_paths_lb))
return;
mpath = bgp_path_info_mpath_get(path);
if (!mpath)
return;
}
if (set) {
if (cum_bw)
SET_FLAG(mpath->mp_flags, BGP_MP_LB_PRESENT);
else
UNSET_FLAG(mpath->mp_flags, BGP_MP_LB_PRESENT);
if (all_paths_lb)
SET_FLAG(mpath->mp_flags, BGP_MP_LB_ALL);
else
UNSET_FLAG(mpath->mp_flags, BGP_MP_LB_ALL);
mpath->cum_bw = cum_bw;
} else {
mpath->mp_flags = 0;
mpath->cum_bw = 0;
}
}
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
/*
* bgp_path_info_mpath_attr
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
*
* Given bestpath bgp_path_info, return aggregated attribute set used
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
* for advertising the multipath route
*/
struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path)
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
{
if (!path->mpath)
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
return NULL;
return path->mpath->mp_attr;
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}
/*
* bgp_path_info_chkwtd
*
* Return if we should attempt to do weighted ECMP or not
* The path passed in is the bestpath.
*/
bool bgp_path_info_mpath_chkwtd(struct bgp *bgp, struct bgp_path_info *path)
{
/* Check if told to ignore weights or not multipath */
if (bgp->lb_handling == BGP_LINK_BW_IGNORE_BW || !path->mpath)
return false;
/* All paths in multipath should have associated weight (bandwidth)
* unless told explicitly otherwise.
*/
if (bgp->lb_handling != BGP_LINK_BW_SKIP_MISSING &&
bgp->lb_handling != BGP_LINK_BW_DEFWT_4_MISSING)
return CHECK_FLAG(path->mpath->mp_flags, BGP_MP_LB_ALL);
/* At least one path should have bandwidth. */
return CHECK_FLAG(path->mpath->mp_flags, BGP_MP_LB_PRESENT);
}
/*
* bgp_path_info_mpath_attr
*
* Given bestpath bgp_path_info, return cumulative bandwidth
* computed for all multipaths with bandwidth info
*/
uint64_t bgp_path_info_mpath_cumbw(struct bgp_path_info *path)
{
if (!path->mpath)
return 0;
return path->mpath->cum_bw;
}
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
/*
* bgp_path_info_mpath_attr_set
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
*
* Sets the aggregated attribute into bestpath's mpath element
*/
static void bgp_path_info_mpath_attr_set(struct bgp_path_info *path,
struct attr *attr)
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
{
struct bgp_path_info_mpath *mpath;
if (!attr && !path->mpath)
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
return;
mpath = bgp_path_info_mpath_get(path);
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
if (!mpath)
return;
mpath->mp_attr = attr;
}
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
2011-07-21 05:46:01 +02:00
/*
* bgp_path_info_mpath_update
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
2011-07-21 05:46:01 +02:00
*
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
* Compare and sync up the multipath flags with what was choosen
* in best selection
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
2011-07-21 05:46:01 +02:00
*/
void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
struct bgp_path_info *new_best, struct bgp_path_info *old_best,
uint32_t num_candidates, struct bgp_maxpaths_cfg *mpath_cfg)
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
2011-07-21 05:46:01 +02:00
{
uint16_t maxpaths, mpath_count, old_mpath_count;
uint64_t bwval;
uint64_t cum_bw, old_cum_bw;
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
struct bgp_path_info *cur_iterator = NULL;
bool mpath_changed, debug;
bool all_paths_lb;
BGP bestpath debugs need to display the addpath RX ID Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Ticket: CM-8459 Output with fix 2015/12/07 09:47:41.342932 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) and path 10.0.0.7 (addpath rxid 2) are equal via matching aspaths 2015/12/07 09:47:41.342966 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) wins over path 10.0.0.7 (addpath rxid 2) due to Router-ID comparison 2015/12/07 09:47:41.342978 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.342988 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.342999 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343008 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343019 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343029 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343039 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343048 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343058 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath from AS 0 2015/12/07 09:47:41.343068 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the initial bestpath 2015/12/07 09:47:41.343077 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath, now find multipaths 2015/12/07 09:47:41.343088 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 2) has the same nexthop as the bestpath, skip it 2015/12/07 09:47:41.343097 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath, add to the multipath list 2015/12/07 09:47:41.343109 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343119 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343127 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343139 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343164 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343173 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343186 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343196 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343205 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343217 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343227 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343236 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343254 BGP: 1.1.1.1/32 add mpath nexthop 34.34.34.34 path 10.0.0.7 (addpath rxid 4) 2015/12/07 09:47:41.343268 BGP: 1.1.1.1/32 add mpath nexthop 56.56.56.56 path 10.0.0.7 (addpath rxid 6)
2015-12-07 20:56:02 +01:00
char path_buf[PATH_ADDPATH_STR_BUFFER];
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
bool old_mpath, new_mpath;
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
mpath_changed = false;
maxpaths = multipath_num;
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
2011-07-21 05:46:01 +02:00
mpath_count = 0;
old_mpath_count = 0;
old_cum_bw = cum_bw = 0;
debug = bgp_debug_bestpath(dest);
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
2011-07-21 05:46:01 +02:00
if (old_best) {
old_mpath_count = bgp_path_info_mpath_count(old_best);
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (old_mpath_count == 1)
SET_FLAG(old_best->flags, BGP_PATH_MULTIPATH);
old_cum_bw = bgp_path_info_mpath_cumbw(old_best);
bgp_path_info_mpath_count_set(old_best, 0);
bgp_path_info_mpath_lb_update(old_best, false, false, 0);
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
bgp_path_info_mpath_free(&old_best->mpath);
old_best->mpath = NULL;
}
if (new_best) {
maxpaths = (new_best->peer->sort == BGP_PEER_IBGP) ? mpath_cfg->maxpaths_ibgp
: mpath_cfg->maxpaths_ebgp;
cur_iterator = new_best;
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
2011-07-21 05:46:01 +02:00
}
if (debug)
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
zlog_debug("%pBD(%s): starting mpath update, newbest %s num candidates %d old-mpath-count %d old-cum-bw %" PRIu64
" maxpaths set %u",
dest, bgp->name_pretty, new_best ? new_best->peer->host : "NONE",
num_candidates, old_mpath_count, old_cum_bw, maxpaths);
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
2011-07-21 05:46:01 +02:00
/*
* We perform an ordered walk through both lists in parallel.
* The reason for the ordered walk is that if there are paths
* that were previously multipaths and are still multipaths, the walk
* should encounter them in both lists at the same time. Otherwise
* there will be paths that are in one list or another, and we
* will deal with these separately.
*
* Note that new_best might be somewhere in the mp_list, so we need
* to skip over it
*/
all_paths_lb = true; /* We'll reset if any path doesn't have LB. */
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
while (cur_iterator) {
old_mpath = CHECK_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH);
new_mpath = CHECK_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH_NEW);
UNSET_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH_NEW);
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
2011-07-21 05:46:01 +02:00
/*
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
* If the current mpath count is equal to the number of
* maxpaths that can be used then we can bail, after
* we clean up the flags associated with the rest of the
* bestpaths
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
2011-07-21 05:46:01 +02:00
*/
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (mpath_count >= maxpaths) {
while (cur_iterator) {
UNSET_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH);
UNSET_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH_NEW);
cur_iterator = cur_iterator->next;
}
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (debug)
zlog_debug("%pBD(%s): Mpath count %u is equal to maximum paths allowed, finished comparision for MPATHS",
dest, bgp->name_pretty, mpath_count);
break;
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
}
if (debug)
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
zlog_debug("%pBD(%s): Candidate %s old_mpath: %u new_mpath: %u, Nexthop %pI4 current mpath count: %u",
dest, bgp->name_pretty, cur_iterator->peer->host, old_mpath,
new_mpath, &cur_iterator->attr->nexthop, mpath_count);
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
2011-07-21 05:46:01 +02:00
/*
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
* There is nothing to do if the cur_iterator is neither a old path
* or a new path
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
2011-07-21 05:46:01 +02:00
*/
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (!old_mpath && !new_mpath) {
UNSET_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH);
cur_iterator = cur_iterator->next;
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
2011-07-21 05:46:01 +02:00
continue;
}
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (new_mpath) {
mpath_count++;
if (cur_iterator != new_best)
SET_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH);
if (!old_mpath)
mpath_changed = true;
if (ecommunity_linkbw_present(bgp_attr_get_ecommunity(cur_iterator->attr),
&bwval) ||
ecommunity_linkbw_present(bgp_attr_get_ipv6_ecommunity(
cur_iterator->attr),
&bwval))
cum_bw += bwval;
else
all_paths_lb = false;
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
2011-07-21 05:46:01 +02:00
if (debug) {
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
bgp_path_info_path_with_addpath_rx_str(cur_iterator, path_buf,
sizeof(path_buf));
zlog_debug("%pBD: add mpath %s nexthop %pI4, cur count %d cum_bw: %" PRIu64
" all_paths_lb: %u",
dest, path_buf, &cur_iterator->attr->nexthop,
mpath_count, cum_bw, all_paths_lb);
BGP bestpath debugs need to display the addpath RX ID Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Ticket: CM-8459 Output with fix 2015/12/07 09:47:41.342932 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) and path 10.0.0.7 (addpath rxid 2) are equal via matching aspaths 2015/12/07 09:47:41.342966 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) wins over path 10.0.0.7 (addpath rxid 2) due to Router-ID comparison 2015/12/07 09:47:41.342978 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.342988 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.342999 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343008 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343019 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343029 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343039 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343048 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343058 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath from AS 0 2015/12/07 09:47:41.343068 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the initial bestpath 2015/12/07 09:47:41.343077 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath, now find multipaths 2015/12/07 09:47:41.343088 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 2) has the same nexthop as the bestpath, skip it 2015/12/07 09:47:41.343097 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 3) is the bestpath, add to the multipath list 2015/12/07 09:47:41.343109 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343119 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343127 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 4) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343139 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343164 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343173 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 5) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343186 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343196 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343205 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 6) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343217 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) and path 10.0.0.7 (addpath rxid 3) are equal via matching aspaths 2015/12/07 09:47:41.343227 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) loses to path 10.0.0.7 (addpath rxid 3) due to Router-ID comparison 2015/12/07 09:47:41.343236 BGP: 1.1.1.1/32: path 10.0.0.7 (addpath rxid 7) is equivalent to the bestpath, add to the multipath list 2015/12/07 09:47:41.343254 BGP: 1.1.1.1/32 add mpath nexthop 34.34.34.34 path 10.0.0.7 (addpath rxid 4) 2015/12/07 09:47:41.343268 BGP: 1.1.1.1/32 add mpath nexthop 56.56.56.56 path 10.0.0.7 (addpath rxid 6)
2015-12-07 20:56:02 +01:00
}
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
2011-07-21 05:46:01 +02:00
} else {
/*
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
* We know that old_mpath is true and new_mpath is false in this path
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
2011-07-21 05:46:01 +02:00
*/
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
mpath_changed = true;
UNSET_FLAG(cur_iterator->flags, BGP_PATH_MULTIPATH);
}
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
cur_iterator = cur_iterator->next;
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
2011-07-21 05:46:01 +02:00
}
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
2011-07-21 05:46:01 +02:00
if (new_best) {
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (mpath_count > 1 || new_best->mpath) {
bgp_path_info_mpath_count_set(new_best, mpath_count);
bgp_path_info_mpath_lb_update(new_best, true, all_paths_lb, cum_bw);
}
if (debug)
zlog_debug("%pBD(%s): New mpath count (incl newbest) %d mpath-change %s all_paths_lb %d cum_bw %" PRIu64,
dest, bgp->name_pretty, mpath_count,
mpath_changed ? "YES" : "NO", all_paths_lb,
cum_bw);
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (mpath_count == 1)
UNSET_FLAG(new_best->flags, BGP_PATH_MULTIPATH);
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
2011-07-21 05:46:01 +02:00
if (mpath_changed
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if ((mpath_count) != old_mpath_count || old_cum_bw != cum_bw)
SET_FLAG(new_best->flags, BGP_PATH_LINK_BW_CHG);
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
2011-07-21 05:46:01 +02:00
}
}
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
/*
* bgp_path_info_mpath_aggregate_update
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
*
* Set the multipath aggregate attribute. We need to see if the
* aggregate has changed and then set the ATTR_CHANGED flag on the
* bestpath info so that a peer update will be generated. The
* change is detected by generating the current attribute,
* interning it, and then comparing the interned pointer with the
* current value. We can skip this generate/compare step if there
* is no change in multipath selection and no attribute change in
* any multipath.
*/
void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
struct bgp_path_info *old_best)
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
{
struct bgp_path_info *mpinfo;
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
struct aspath *aspath;
struct aspath *asmerge;
struct attr *new_attr, *old_attr;
uint8_t origin;
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
struct community *community, *commerge;
struct ecommunity *ecomm, *ecommerge;
struct lcommunity *lcomm, *lcommerge;
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
struct attr attr = {0};
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
if (old_best && (old_best != new_best)
&& (old_attr = bgp_path_info_mpath_attr(old_best))) {
bgp_attr_unintern(&old_attr);
bgp_path_info_mpath_attr_set(old_best, NULL);
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
if (!new_best)
return;
bgpd: Cleanup multipath figuring out in bgp Currently bgp multipath has these properties: a) mp_info may or may not be on a single path, based upon path perturbations in the past. b) mp_info->count started counting at 0( meaning 1 ). As that the bestpath path_info was never included in the count c) The first mp_info in the list held the multipath data associated with the multipath. As such if you were at any other node that data was not filled in. d) As such the mp_info's that are not first on the list basically were just pointers to the corresponding bgp_path_info that was in the multipath. e) On bestpath calculation, a linklist(struct linklist *) of bgp_path_info's was created. f) This linklist was passed in to a comparison function that took the old mpinfo list and compared it item by item to the linklist and doing magic to figure out how to create a new mp_info list. g) the old mp_info and the link list had to be memory managed and freed up. h) BGP_PATH_MULTIPATH is only set on non bestpath nodes in the multipath. This is really complicated. Let's change the algorithm to this: a) When running bestpath, mark a bgp_path_info node that could be in the ecmp path as BGP_PATH_MULTIPATH_NEW. b) When running multipath, just walk the list of bgp_path_info's and if it has BGP_PATH_MULTIPATH_NEW on it, decide if it is in BGP_MULTIPATH. If we run out of space to put in the ecmp, clear the flag on the rest. c) Clean up the counting of sometimes adding 1 to the mpath count. d) Only allocate a mpath_info node for the bestpath. Clean it up when done with it. e) remove the unneeded list management associated with the linklist and the mp_list. This greatly simplifies multipath computation for bgp and reduces memory load for large scale deployments. 2 full feeds in work_queue_run prior: 0 56367.471 1123 50193 493695 50362 493791 0 0 0 TE work_queue_run BGP multipath info : 1941844 48 110780992 1941844 110780992 2 full feeds in work_queue_run after change: 1 52924.931 1296 40837 465968 41025 487390 0 0 1 TE work_queue_run BGP multipath info : 970860 32 38836880 970866 38837120 Aproximately 4 seconds of saved cpu time for convergence and ~75 mb smaller run time. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2024-09-30 21:09:42 +02:00
if (bgp_path_info_mpath_count(new_best) == 1) {
if ((new_attr = bgp_path_info_mpath_attr(new_best))) {
bgp_attr_unintern(&new_attr);
bgp_path_info_mpath_attr_set(new_best, NULL);
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}
return;
}
attr = *new_best->attr;
if (new_best->peer
&& CHECK_FLAG(new_best->peer->bgp->flags,
BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
/* aggregate attribute from multipath constituents */
aspath = aspath_dup(attr.aspath);
origin = attr.origin;
community =
bgp_attr_get_community(&attr)
? community_dup(bgp_attr_get_community(&attr))
: NULL;
ecomm = (bgp_attr_get_ecommunity(&attr))
? ecommunity_dup(bgp_attr_get_ecommunity(&attr))
: NULL;
lcomm = (bgp_attr_get_lcommunity(&attr))
? lcommunity_dup(bgp_attr_get_lcommunity(&attr))
: NULL;
for (mpinfo = bgp_path_info_mpath_first(new_best); mpinfo;
mpinfo = bgp_path_info_mpath_next(mpinfo)) {
asmerge =
aspath_aggregate(aspath, mpinfo->attr->aspath);
aspath_free(aspath);
aspath = asmerge;
if (origin < mpinfo->attr->origin)
origin = mpinfo->attr->origin;
if (bgp_attr_get_community(mpinfo->attr)) {
if (community) {
commerge = community_merge(
community,
bgp_attr_get_community(
mpinfo->attr));
community =
community_uniq_sort(commerge);
community_free(&commerge);
} else
community = community_dup(
bgp_attr_get_community(
mpinfo->attr));
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}
if (bgp_attr_get_ecommunity(mpinfo->attr)) {
if (ecomm) {
ecommerge = ecommunity_merge(
ecomm, bgp_attr_get_ecommunity(
mpinfo->attr));
ecomm = ecommunity_uniq_sort(ecommerge);
ecommunity_free(&ecommerge);
} else
ecomm = ecommunity_dup(
bgp_attr_get_ecommunity(
mpinfo->attr));
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}
if (bgp_attr_get_lcommunity(mpinfo->attr)) {
if (lcomm) {
lcommerge = lcommunity_merge(
lcomm, bgp_attr_get_lcommunity(
mpinfo->attr));
lcomm = lcommunity_uniq_sort(lcommerge);
lcommunity_free(&lcommerge);
} else
lcomm = lcommunity_dup(
bgp_attr_get_lcommunity(
mpinfo->attr));
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}
}
attr.aspath = aspath;
attr.origin = origin;
if (community)
bgp_attr_set_community(&attr, community);
if (ecomm)
bgp_attr_set_ecommunity(&attr, ecomm);
if (lcomm)
bgp_attr_set_lcommunity(&attr, lcomm);
/* Zap multipath attr nexthop so we set nexthop to self */
attr.nexthop.s_addr = INADDR_ANY;
memset(&attr.mp_nexthop_global, 0, sizeof(struct in6_addr));
/* TODO: should we set ATOMIC_AGGREGATE and AGGREGATOR? */
}
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
new_attr = bgp_attr_intern(&attr);
if (new_attr != bgp_path_info_mpath_attr(new_best)) {
if ((old_attr = bgp_path_info_mpath_attr(new_best)))
bgp_attr_unintern(&old_attr);
bgp_path_info_mpath_attr_set(new_best, new_attr);
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
} else
bgp_attr_unintern(&new_attr);
bgpd: When advertising a multipath route, the attribute set to be advertised is based on the bestpath attribute set, but the following attributes are aggregated from the attribute sets of the multipath constituents: - AS_PATH - ORIGIN - COMMUNITIES - EXTENDED COMMUNITIES In addition the route is advertised with the NEXT_HOP set to the router's interface IP address, instead of the NEXT_HOP of the best path. This is to ensure that traffic will go to this router so it can be fanned out via the multipath route. * bgpd/ecommunity.c * ecommunity_uniq_sort(): Make this function externally accessible * bgpd/ecommunity.h * Add external declaration for ecommunity_uniq_sort() * bgpd/bgp_mpath.c * bgp_info_nexthop_cmp(): Replace calls to bgp_attr_extra_get() to avoid unwanted memory allocation * bgp_info_mpath_free(): Free aggregate attribute for multipath * bgp_info_mpath_attr(): Lookup aggregate attribute of a multipath route * bgp_info_mpath_attr_set(): Set aggregate attribute of a multipath route * bgp_info_mpath_aggregate_update(): Update the aggregate attribute of a multipath route * bgpd/bgp_mpath.h * bgp_info_mpath: Add pointer to hold aggregate attribute of a multipath * Add external declarations for new functions * bgpd/bgp_route.c * bgp_announce_check(): Use aggregate attribute when announcing multipath route * bgp_announce_check_rsclient(): Use aggregate attribute when announcing multipath route * bgp_best_selection(): After updating multipath set, update the multipath aggregate attribute
2011-07-21 05:49:11 +02:00
}