summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_mpath.c
diff options
context:
space:
mode:
authorvivek <vivek@cumulusnetworks.com>2020-03-24 20:22:17 +0100
committervivek <vivek@cumulusnetworks.com>2020-03-31 05:12:31 +0200
commit42d436cf01d52948d9fe86cbe579a3e108224d01 (patch)
treeb096071f93f23ed5e7a9ceefc95f1c7382647249 /bgpd/bgp_mpath.c
parentbgpd: Add link-bandwidth fields for multipath calc (diff)
downloadfrr-42d436cf01d52948d9fe86cbe579a3e108224d01.tar.xz
frr-42d436cf01d52948d9fe86cbe579a3e108224d01.zip
bgpd: Track link bandwidth during multipath calc
During multipath update, track the cumulative link bandwidth as well as update flags appropriately. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
Diffstat (limited to 'bgpd/bgp_mpath.c')
-rw-r--r--bgpd/bgp_mpath.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c
index fb0613ebb..4fe57b9bd 100644
--- a/bgpd/bgp_mpath.c
+++ b/bgpd/bgp_mpath.c
@@ -402,6 +402,35 @@ static void bgp_path_info_mpath_count_set(struct bgp_path_info *path,
}
/*
+ * bgp_path_info_mpath_lb_update
+ *
+ * Update cumulative info related to link-bandwidth
+ */
+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;
+
+ if ((mpath = path->mpath) == NULL) {
+ if (!set)
+ return;
+ mpath = bgp_path_info_mpath_get(path);
+ if (!mpath)
+ return;
+ }
+ if (set) {
+ 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;
+ }
+}
+
+/*
* bgp_path_info_mpath_attr
*
* Given bestpath bgp_path_info, return aggregated attribute set used
@@ -444,10 +473,13 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
struct bgp_maxpaths_cfg *mpath_cfg)
{
uint16_t maxpaths, mpath_count, old_mpath_count;
+ uint32_t bwval;
+ uint64_t cum_bw;
struct listnode *mp_node, *mp_next_node;
struct bgp_path_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
int mpath_changed, debug;
char nh_buf[2][INET6_ADDRSTRLEN];
+ bool all_paths_lb;
char path_buf[PATH_ADDPATH_STR_BUFFER];
mpath_changed = 0;
@@ -455,6 +487,7 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
mpath_count = 0;
cur_mpath = NULL;
old_mpath_count = 0;
+ cum_bw = 0;
prev_mpath = new_best;
mp_node = listhead(mp_list);
debug = bgp_debug_bestpath(rn);
@@ -472,6 +505,7 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
cur_mpath = bgp_path_info_mpath_first(old_best);
old_mpath_count = bgp_path_info_mpath_count(old_best);
bgp_path_info_mpath_count_set(old_best, 0);
+ bgp_path_info_mpath_lb_update(old_best, false, false, 0);
bgp_path_info_mpath_dequeue(old_best);
}
@@ -492,6 +526,7 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
* 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. */
while (mp_node || cur_mpath) {
struct bgp_path_info *tmp_info;
@@ -530,6 +565,11 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
cur_mpath);
prev_mpath = cur_mpath;
mpath_count++;
+ if (ecommunity_linkbw_present(
+ cur_mpath->attr->ecommunity, &bwval))
+ cum_bw += bwval;
+ else
+ all_paths_lb = false;
if (debug) {
bgp_path_info_path_with_addpath_rx_str(
cur_mpath, path_buf);
@@ -617,6 +657,11 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
prev_mpath = new_mpath;
mpath_changed = 1;
mpath_count++;
+ if (ecommunity_linkbw_present(
+ new_mpath->attr->ecommunity, &bwval))
+ cum_bw += bwval;
+ else
+ all_paths_lb = false;
if (debug) {
bgp_path_info_path_with_addpath_rx_str(
new_mpath, path_buf);
@@ -636,13 +681,24 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
}
if (new_best) {
+ bgp_path_info_mpath_count_set(new_best, mpath_count - 1);
+ if (mpath_count <= 1 ||
+ !ecommunity_linkbw_present(
+ new_best->attr->ecommunity, &bwval))
+ all_paths_lb = false;
+ else
+ cum_bw += bwval;
+ bgp_path_info_mpath_lb_update(new_best, true,
+ all_paths_lb, cum_bw);
+
if (debug)
zlog_debug(
- "%pRN: New mpath count (incl newbest) %d mpath-change %s",
+ "%pRN: New mpath count (incl newbest) %d mpath-change %s"
+ " all_paths_lb %d cum_bw u%" PRIu64,
rn, mpath_count,
- mpath_changed ? "YES" : "NO");
+ mpath_changed ? "YES" : "NO",
+ all_paths_lb, cum_bw);
- bgp_path_info_mpath_count_set(new_best, mpath_count - 1);
if (mpath_changed
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);