mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-13 12:16:31 +00:00
bgpd: Additional options for generating link bandwidth
Implement the code to handle the other route-map options to generate the link bandwidth, namely, to use the cumulative bandwidth or to base this on the number of multipaths. In the latter case, a reference bandwidth is internally chosen - the implementation uses a value of 1 Gbps. These additional options mean that the prefix may need to be advertised if there is a link bandwidth change, which is a new criteria. Define a new path (change) flag to support this and implement the advertisement. Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com> Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com> Reviewed-by: Don Slice <dslice@cumulusnetworks.com>
This commit is contained in:
parent
f6ca545a21
commit
b1875e656c
@ -1132,6 +1132,7 @@ static int evpn_es_route_select_install(struct bgp *bgp,
|
||||
old_select->attr->nexthop);
|
||||
}
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
bgp_zebra_clear_route_change_flags(rn);
|
||||
return ret;
|
||||
}
|
||||
@ -1152,6 +1153,7 @@ static int evpn_es_route_select_install(struct bgp *bgp,
|
||||
bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED);
|
||||
bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED);
|
||||
UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
}
|
||||
|
||||
if (new_select && new_select->type == ZEBRA_ROUTE_BGP
|
||||
@ -1211,6 +1213,7 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
bgp, vpn, (const struct prefix_evpn *)bgp_node_get_prefix(rn),
|
||||
old_select);
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
bgp_zebra_clear_route_change_flags(rn);
|
||||
return ret;
|
||||
}
|
||||
@ -1230,6 +1233,7 @@ static int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED);
|
||||
bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED);
|
||||
UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
}
|
||||
|
||||
if (new_select && new_select->type == ZEBRA_ROUTE_BGP
|
||||
|
@ -500,7 +500,7 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
{
|
||||
uint16_t maxpaths, mpath_count, old_mpath_count;
|
||||
uint32_t bwval;
|
||||
uint64_t cum_bw;
|
||||
uint64_t cum_bw, old_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;
|
||||
@ -513,7 +513,7 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
mpath_count = 0;
|
||||
cur_mpath = NULL;
|
||||
old_mpath_count = 0;
|
||||
cum_bw = 0;
|
||||
old_cum_bw = cum_bw = 0;
|
||||
prev_mpath = new_best;
|
||||
mp_node = listhead(mp_list);
|
||||
debug = bgp_debug_bestpath(rn);
|
||||
@ -530,6 +530,7 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
if (old_best) {
|
||||
cur_mpath = bgp_path_info_mpath_first(old_best);
|
||||
old_mpath_count = bgp_path_info_mpath_count(old_best);
|
||||
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);
|
||||
bgp_path_info_mpath_dequeue(old_best);
|
||||
@ -537,9 +538,10 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
|
||||
if (debug)
|
||||
zlog_debug(
|
||||
"%pRN: starting mpath update, newbest %s num candidates %d old-mpath-count %d",
|
||||
"%pRN: starting mpath update, newbest %s num candidates %d old-mpath-count %d old-cum-bw u%" PRIu64,
|
||||
rn, new_best ? new_best->peer->host : "NONE",
|
||||
mp_list ? listcount(mp_list) : 0, old_mpath_count);
|
||||
mp_list ? listcount(mp_list) : 0,
|
||||
old_mpath_count, old_cum_bw);
|
||||
|
||||
/*
|
||||
* We perform an ordered walk through both lists in parallel.
|
||||
@ -728,6 +730,9 @@ void bgp_path_info_mpath_update(struct bgp_node *rn,
|
||||
if (mpath_changed
|
||||
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
|
||||
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
if ((mpath_count - 1) != old_mpath_count ||
|
||||
old_cum_bw != cum_bw)
|
||||
SET_FLAG(new_best->flags, BGP_PATH_LINK_BW_CHG);
|
||||
}
|
||||
}
|
||||
|
||||
@ -752,6 +757,7 @@ void bgp_mp_dmed_deselect(struct bgp_path_info *dmed_best)
|
||||
|
||||
bgp_path_info_mpath_count_set(dmed_best, 0);
|
||||
UNSET_FLAG(dmed_best->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(dmed_best->flags, BGP_PATH_LINK_BW_CHG);
|
||||
assert(bgp_path_info_mpath_first(dmed_best) == NULL);
|
||||
}
|
||||
|
||||
|
@ -2394,7 +2394,8 @@ bool bgp_zebra_has_route_changed(struct bgp_node *rn,
|
||||
* when the best path has an attribute change anyway.
|
||||
*/
|
||||
if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
|
||||
|| CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG))
|
||||
|| CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
|
||||
|| CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
|
||||
return true;
|
||||
|
||||
/*
|
||||
@ -2563,12 +2564,11 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
||||
bgp, afi, safi);
|
||||
}
|
||||
}
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
bgp_zebra_clear_route_change_flags(rn);
|
||||
|
||||
/* If there is a change of interest to peers, reannounce the
|
||||
* route. */
|
||||
if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
|
||||
|| CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
|
||||
|| CHECK_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED)) {
|
||||
group_announce_route(bgp, afi, safi, rn, new_select);
|
||||
|
||||
@ -2583,6 +2583,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
||||
UNSET_FLAG(rn->flags, BGP_NODE_LABEL_CHANGED);
|
||||
}
|
||||
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
bgp_zebra_clear_route_change_flags(rn);
|
||||
UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
|
||||
return;
|
||||
}
|
||||
@ -2613,6 +2616,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
|
||||
bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED);
|
||||
bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED);
|
||||
UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
}
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
|
@ -237,6 +237,7 @@ struct bgp_path_info {
|
||||
#define BGP_PATH_MULTIPATH_CHG (1 << 12)
|
||||
#define BGP_PATH_RIB_ATTR_CHG (1 << 13)
|
||||
#define BGP_PATH_ANNC_NH_SELF (1 << 14)
|
||||
#define BGP_PATH_LINK_BW_CHG (1 << 15)
|
||||
|
||||
/* BGP route type. This can be static, RIP, OSPF, BGP etc. */
|
||||
uint8_t type;
|
||||
@ -477,6 +478,10 @@ static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi,
|
||||
dst_pi->peer = peer;
|
||||
dst_pi->attr = attr;
|
||||
dst_pi->net = rn;
|
||||
dst_pi->flags = src_pi->flags;
|
||||
dst_pi->type = src_pi->type;
|
||||
dst_pi->sub_type = src_pi->sub_type;
|
||||
dst_pi->mpath = src_pi->mpath;
|
||||
if (src_pi->extra) {
|
||||
memcpy(dst_pie, src_pi->extra,
|
||||
sizeof(struct bgp_path_info_extra));
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "bgpd/bgp_pbr.h"
|
||||
#include "bgpd/bgp_flowspec_util.h"
|
||||
#include "bgpd/bgp_encap_types.h"
|
||||
#include "bgpd/bgp_mpath.h"
|
||||
|
||||
#if ENABLE_BGP_VNC
|
||||
#include "bgpd/rfapi/bgp_rfapi_cfg.h"
|
||||
@ -2552,6 +2553,7 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix,
|
||||
struct ecommunity ecom_lb = {0};
|
||||
struct ecommunity_val lb_eval;
|
||||
uint32_t bw_bytes = 0;
|
||||
uint16_t mpath_count = 0;
|
||||
struct ecommunity *new_ecom;
|
||||
struct ecommunity *old_ecom;
|
||||
as_t as;
|
||||
@ -2566,8 +2568,27 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix,
|
||||
|
||||
/* Build link bandwidth extended community */
|
||||
as = (peer->bgp->as > BGP_AS_MAX) ? BGP_AS_TRANS : peer->bgp->as;
|
||||
if (rels->lb_type == RMAP_ECOMM_LB_SET_VALUE)
|
||||
if (rels->lb_type == RMAP_ECOMM_LB_SET_VALUE) {
|
||||
bw_bytes = ((uint64_t)(rels->bw * 1000 * 1000))/8;
|
||||
} else if (rels->lb_type == RMAP_ECOMM_LB_SET_CUMUL) {
|
||||
/* process this only for the best path. */
|
||||
if (!CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
|
||||
return RMAP_OKAY;
|
||||
|
||||
bw_bytes = (uint32_t)bgp_path_info_mpath_cumbw(path);
|
||||
if (!bw_bytes)
|
||||
return RMAP_OKAY;
|
||||
|
||||
} else if (rels->lb_type == RMAP_ECOMM_LB_SET_NUM_MPATH) {
|
||||
|
||||
/* process this only for the best path. */
|
||||
if (!CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
|
||||
return RMAP_OKAY;
|
||||
|
||||
bw_bytes = ((uint64_t)(peer->bgp->lb_ref_bw * 1000 * 1000))/8;
|
||||
mpath_count = bgp_path_info_mpath_count(path) + 1;
|
||||
bw_bytes *= mpath_count;
|
||||
}
|
||||
|
||||
encode_lb_extcomm(as, bw_bytes, rels->non_trans, &lb_eval);
|
||||
|
||||
|
@ -2970,6 +2970,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
|
||||
bgp->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME;
|
||||
bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT;
|
||||
bgp->dynamic_neighbors_count = 0;
|
||||
bgp->lb_ref_bw = BGP_LINK_BW_REF_BW;
|
||||
bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED;
|
||||
bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED;
|
||||
bgp_addpath_init_bgp_data(&bgp->tx_addpath);
|
||||
|
@ -395,6 +395,14 @@ struct bgp {
|
||||
#define BGP_UPDATE_DELAY_MIN 0
|
||||
#define BGP_UPDATE_DELAY_MAX 3600
|
||||
|
||||
/* Reference bandwidth for BGP link-bandwidth. Used when
|
||||
* the LB value has to be computed based on some other
|
||||
* factor (e.g., number of multipaths for the prefix)
|
||||
* Value is in Mbps
|
||||
*/
|
||||
uint32_t lb_ref_bw;
|
||||
#define BGP_LINK_BW_REF_BW 1
|
||||
|
||||
/* BGP flags. */
|
||||
uint32_t flags;
|
||||
#define BGP_FLAG_ALWAYS_COMPARE_MED (1 << 0)
|
||||
|
Loading…
Reference in New Issue
Block a user