Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4658,12 +4658,12 @@ static void bgp_packet_nhc(struct stream *s, struct peer *peer, afi_t afi, safi_
if (!bpi)
return;

if (bgp_path_info_mpath_count(bpi) < 2 && !nhc)
if (bgp_path_info_mpath_count(bpi->net) < 2 && !nhc)
return;

prefix = bgp_dest_get_prefix(bpi->net);

total = bgp_path_info_mpath_count(bpi) * IPV4_MAX_BYTELEN;
total = bgp_path_info_mpath_count(bpi->net) * IPV4_MAX_BYTELEN;
total += IPV4_MAX_BYTELEN; /* Next-hop BGP ID */

stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS);
Expand Down Expand Up @@ -4705,7 +4705,7 @@ static void bgp_packet_nhc(struct stream *s, struct peer *peer, afi_t afi, safi_
* | Next-next-hop BGP IDs (variable) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
if (bgp_path_info_mpath_count(bpi) > 1) {
if (bgp_path_info_mpath_count(bpi->net) > 1) {
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug("%pBP: Sending NHC TLV (%d) for %pFX", peer,
BGP_ATTR_NHC_TLV_NNHN, prefix);
Expand Down
112 changes: 56 additions & 56 deletions bgpd/bgp_mpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,23 +227,23 @@ void bgp_path_info_mpath_free(struct bgp_path_info_mpath **mpath)
/*
* bgp_path_info_mpath_get
*
* Fetch the mpath element for the given bgp_path_info. Used for
* Fetch the mpath element for the given bgp_dest. Used for
* doing lazy allocation.
*/
static struct bgp_path_info_mpath *
bgp_path_info_mpath_get(struct bgp_path_info *path)
bgp_path_info_mpath_get(struct bgp_dest *dest)
{
struct bgp_path_info_mpath *mpath;

if (!path)
if (!dest)
return NULL;

if (!path->mpath) {
if (!dest->mpath) {
mpath = bgp_path_info_mpath_new();
path->mpath = mpath;
mpath->mp_info = path;
dest->mpath = mpath;
mpath->mp_dest = dest;
}
return path->mpath;
return dest->mpath;
}

/*
Expand Down Expand Up @@ -278,28 +278,28 @@ struct bgp_path_info *bgp_path_info_mpath_first(struct bgp_path_info *path)
/*
* bgp_path_info_mpath_count
*
* Given the bestpath bgp_path_info, return the number of multipath entries
* Given the bgp_dest, return the number of multipath entries
*/
uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path)
uint32_t bgp_path_info_mpath_count(struct bgp_dest *dest)
{
if (!path->mpath)
if (!dest->mpath)
return 1;

return path->mpath->mp_count;
return dest->mpath->mp_count;
}

/*
* bgp_path_info_mpath_count_set
*
* Sets the count of multipaths into bestpath's mpath element
* Sets the count of multipaths into bgp_dest's mpath element
*/
static void bgp_path_info_mpath_count_set(struct bgp_path_info *path,
static void bgp_path_info_mpath_count_set(struct bgp_dest *dest,
uint16_t count)
{
struct bgp_path_info_mpath *mpath;
if (!count && !path->mpath)
if (!count && !dest->mpath)
return;
mpath = bgp_path_info_mpath_get(path);
mpath = bgp_path_info_mpath_get(dest);
if (!mpath)
return;
mpath->mp_count = count;
Expand All @@ -310,21 +310,21 @@ static void bgp_path_info_mpath_count_set(struct bgp_path_info *path,
*
* 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
* This is set on mpath of the bgp_dest,
* 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,
static void bgp_path_info_mpath_lb_update(struct bgp_dest *dest, bool set,
bool all_paths_lb, uint64_t cum_bw)
{
struct bgp_path_info_mpath *mpath;

mpath = path->mpath;
mpath = dest->mpath;
if (mpath == NULL) {
if (!set || (cum_bw == 0 && !all_paths_lb))
return;

mpath = bgp_path_info_mpath_get(path);
mpath = bgp_path_info_mpath_get(dest);
if (!mpath)
return;
}
Expand All @@ -347,33 +347,33 @@ static void bgp_path_info_mpath_lb_update(struct bgp_path_info *path, bool set,
/*
* bgp_path_info_mpath_attr
*
* Given bestpath bgp_path_info, return aggregated attribute set used
* Given bgp_dest, return aggregated attribute set used
* for advertising the multipath route
*/
struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path)
struct attr *bgp_path_info_mpath_attr(struct bgp_dest *dest)
{
if (!path->mpath)
if (!dest->mpath)
return NULL;
return path->mpath->mp_attr;
return dest->mpath->mp_attr;
}

/*
* bgp_path_info_chkwtd
*
* Return if we should attempt to do weighted ECMP or not
* The path passed in is the bestpath.
* Pass the bgp_dest in.
*/
enum bgp_wecmp_behavior bgp_path_info_mpath_chkwtd(struct bgp *bgp, struct bgp_path_info *path)
enum bgp_wecmp_behavior bgp_path_info_mpath_chkwtd(struct bgp *bgp, struct bgp_dest *dest)
{
/* Check if not multipath */
if (!path->mpath)
if (!dest->mpath)
return BGP_WECMP_BEHAVIOR_NONE;

/* If link bandwidth is to be ignored, check if we have Next-Next Hop Nodes
* characteristic and do weighted ECMP based on that.
*/
if (bgp->lb_handling == BGP_LINK_BW_IGNORE_BW) {
if (CHECK_FLAG(path->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NHC)))
if (CHECK_FLAG(bgp_dest_get_bgp_path_info(dest)->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NHC)))
return BGP_WECMP_BEHAVIOR_NNHN_COUNT;
}

Expand All @@ -382,13 +382,13 @@ enum bgp_wecmp_behavior bgp_path_info_mpath_chkwtd(struct bgp *bgp, struct bgp_p
*/
if (bgp->lb_handling != BGP_LINK_BW_SKIP_MISSING &&
bgp->lb_handling != BGP_LINK_BW_DEFWT_4_MISSING) {
if (CHECK_FLAG(path->mpath->mp_flags, BGP_MP_LB_ALL))
if (CHECK_FLAG(dest->mpath->mp_flags, BGP_MP_LB_ALL))
return BGP_WECMP_BEHAVIOR_LINK_BW;
else
return BGP_WECMP_BEHAVIOR_NONE;
}

if (CHECK_FLAG(path->mpath->mp_flags, BGP_MP_LB_PRESENT))
if (CHECK_FLAG(dest->mpath->mp_flags, BGP_MP_LB_PRESENT))
return BGP_WECMP_BEHAVIOR_LINK_BW;

return BGP_WECMP_BEHAVIOR_NONE;
Expand All @@ -397,28 +397,28 @@ enum bgp_wecmp_behavior bgp_path_info_mpath_chkwtd(struct bgp *bgp, struct bgp_p
/*
* bgp_path_info_mpath_attr
*
* Given bestpath bgp_path_info, return cumulative bandwidth
* Given bgp_dest, return cumulative bandwidth
* computed for all multipaths with bandwidth info
*/
uint64_t bgp_path_info_mpath_cumbw(struct bgp_path_info *path)
uint64_t bgp_path_info_mpath_cumbw(struct bgp_dest *dest)
{
if (!path->mpath)
if (!dest->mpath)
return 0;
return path->mpath->cum_bw;
return dest->mpath->cum_bw;
}

/*
* bgp_path_info_mpath_attr_set
*
* Sets the aggregated attribute into bestpath's mpath element
* Sets the aggregated attribute into bgp_dest's mpath element
*/
static void bgp_path_info_mpath_attr_set(struct bgp_path_info *path,
static void bgp_path_info_mpath_attr_set(struct bgp_dest *dest,
struct attr *attr)
{
struct bgp_path_info_mpath *mpath;
if (!attr && !path->mpath)
if (!attr && !dest->mpath)
return;
mpath = bgp_path_info_mpath_get(path);
mpath = bgp_path_info_mpath_get(dest);
if (!mpath)
return;
mpath->mp_attr = attr;
Expand Down Expand Up @@ -451,14 +451,14 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
debug = bgp_debug_bestpath(dest);

if (old_best) {
old_mpath_count = bgp_path_info_mpath_count(old_best);
old_mpath_count = bgp_path_info_mpath_count(old_best->net);
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);
bgp_path_info_mpath_free(&old_best->mpath);
old_best->mpath = NULL;
old_cum_bw = bgp_path_info_mpath_cumbw(old_best->net);
bgp_path_info_mpath_count_set(old_best->net, 0);
bgp_path_info_mpath_lb_update(old_best->net, false, false, 0);
bgp_path_info_mpath_free(&old_best->net->mpath);
old_best->net->mpath = NULL;
}

if (new_best) {
Expand Down Expand Up @@ -564,9 +564,9 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
}

if (new_best) {
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 (mpath_count > 1 || new_best->net->mpath) {
bgp_path_info_mpath_count_set(new_best->net, mpath_count);
bgp_path_info_mpath_lb_update(new_best->net, 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,
Expand All @@ -577,7 +577,7 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest,
if (mpath_count == 1)
UNSET_FLAG(new_best->flags, BGP_PATH_MULTIPATH);
if (mpath_changed
|| (bgp_path_info_mpath_count(new_best) != old_mpath_count))
|| (bgp_path_info_mpath_count(new_best->net) != old_mpath_count))
SET_FLAG(new_best->flags, BGP_PATH_MULTIPATH_CHG);
if ((mpath_count) != old_mpath_count || old_cum_bw != cum_bw)
SET_FLAG(new_best->flags, BGP_PATH_LINK_BW_CHG);
Expand Down Expand Up @@ -610,18 +610,18 @@ void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,
struct attr attr = {0};

if (old_best && (old_best != new_best)
&& (old_attr = bgp_path_info_mpath_attr(old_best))) {
&& (old_attr = bgp_path_info_mpath_attr(old_best->net))) {
bgp_attr_unintern(&old_attr);
bgp_path_info_mpath_attr_set(old_best, NULL);
bgp_path_info_mpath_attr_set(old_best->net, NULL);
}

if (!new_best)
return;

if (bgp_path_info_mpath_count(new_best) == 1) {
if ((new_attr = bgp_path_info_mpath_attr(new_best))) {
if (bgp_path_info_mpath_count(new_best->net) == 1) {
if ((new_attr = bgp_path_info_mpath_attr(new_best->net))) {
bgp_attr_unintern(&new_attr);
bgp_path_info_mpath_attr_set(new_best, NULL);
bgp_path_info_mpath_attr_set(new_best->net, NULL);
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
}
return;
Expand Down Expand Up @@ -716,10 +716,10 @@ void bgp_path_info_mpath_aggregate_update(struct bgp_path_info *new_best,

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)))
if (new_attr != bgp_path_info_mpath_attr(new_best->net)) {
if ((old_attr = bgp_path_info_mpath_attr(new_best->net)))
bgp_attr_unintern(&old_attr);
bgp_path_info_mpath_attr_set(new_best, new_attr);
bgp_path_info_mpath_attr_set(new_best->net, new_attr);
SET_FLAG(new_best->flags, BGP_PATH_ATTR_CHANGED);
} else
bgp_attr_unintern(&new_attr);
Expand Down
14 changes: 7 additions & 7 deletions bgpd/bgp_mpath.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ enum bgp_wecmp_behavior {
BGP_WECMP_BEHAVIOR_NNHN_COUNT = 2
};

/* Supplemental information linked to bgp_path_info for keeping track of
/* Supplemental information linked to bgp_dest for keeping track of
* multipath selections, lazily allocated to save memory
*/
struct bgp_path_info_mpath {
/* Points to bgp_path_info associated with this multipath info */
struct bgp_path_info *mp_info;
/* Points to bgp_dest associated with this multipath info */
struct bgp_dest *mp_dest;

/* When attached to best path, the number of selected multipaths */
uint16_t mp_count;
Expand Down Expand Up @@ -70,10 +70,10 @@ extern struct bgp_path_info *
bgp_path_info_mpath_next(struct bgp_path_info *path);

/* Accessors for multipath information */
extern uint32_t bgp_path_info_mpath_count(struct bgp_path_info *path);
extern struct attr *bgp_path_info_mpath_attr(struct bgp_path_info *path);
extern uint32_t bgp_path_info_mpath_count(struct bgp_dest *dest);
extern struct attr *bgp_path_info_mpath_attr(struct bgp_dest *dest);
extern enum bgp_wecmp_behavior bgp_path_info_mpath_chkwtd(struct bgp *bgp,
struct bgp_path_info *path);
extern uint64_t bgp_path_info_mpath_cumbw(struct bgp_path_info *path);
struct bgp_dest *dest);
extern uint64_t bgp_path_info_mpath_cumbw(struct bgp_dest *dest);

#endif /* _FRR_BGP_MPATH_H */
9 changes: 4 additions & 5 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,6 @@ void bgp_path_info_free_with_caller(const char *name,

bgp_unlink_nexthop(path);
bgp_path_info_extra_free(&path->extra);
bgp_path_info_mpath_free(&path->mpath);
if (path->net)
bgp_addpath_free_info_data(&path->tx_addpath,
&path->net->tx_addpath);
Expand Down Expand Up @@ -2187,7 +2186,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
from = pi->peer;
filter = &peer->filter[afi][safi];
bgp = SUBGRP_INST(subgrp);
piattr = bgp_path_info_mpath_count(pi) > 1 ? bgp_path_info_mpath_attr(pi) : pi->attr;
piattr = bgp_path_info_mpath_count(pi->net) > 1 ? bgp_path_info_mpath_attr(pi->net) : pi->attr;

if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
peer->pmax_out[afi][safi] != 0 &&
Expand Down Expand Up @@ -2862,8 +2861,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
* the most sense. However, don't modify if the link-bandwidth has
* been explicitly set by user policy.
*/
if (nh_reset && bgp_path_info_mpath_chkwtd(bgp, pi) == BGP_WECMP_BEHAVIOR_LINK_BW &&
(cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
if (nh_reset && bgp_path_info_mpath_chkwtd(bgp, pi->net) == BGP_WECMP_BEHAVIOR_LINK_BW &&
(cum_bw = bgp_path_info_mpath_cumbw(pi->net)) != 0 &&
!CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET)) {
if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_LINK_BANDWIDTH))
bgp_attr_set_ipv6_ecommunity(
Expand Down Expand Up @@ -12284,7 +12283,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
}

if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH) ||
(CHECK_FLAG(path->flags, BGP_PATH_SELECTED) && bgp_path_info_mpath_count(path) > 1)) {
(CHECK_FLAG(path->flags, BGP_PATH_SELECTED) && bgp_path_info_mpath_count(path->net) > 1)) {
if (json_paths)
json_object_boolean_true_add(json_path, "multipath");
else
Expand Down
5 changes: 0 additions & 5 deletions bgpd/bgp_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,6 @@ struct bgp_path_info {
/* Extra information */
struct bgp_path_info_extra *extra;


/* Multipath information */
struct bgp_path_info_mpath *mpath;

/* Uptime. */
time_t uptime;

Expand Down Expand Up @@ -667,7 +663,6 @@ static inline void prep_for_rmap_apply(struct bgp_path_info *dst_pi,
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));
Expand Down
4 changes: 2 additions & 2 deletions bgpd/bgp_routemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -3414,7 +3414,7 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
if (!CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
return RMAP_OKAY;

bw_bytes = bgp_path_info_mpath_cumbw(path);
bw_bytes = bgp_path_info_mpath_cumbw(path->net);
if (!bw_bytes)
return RMAP_OKAY;

Expand All @@ -3425,7 +3425,7 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
return RMAP_OKAY;

bw_bytes = (peer->bgp->lb_ref_bw * 1000 * 1000) / 8;
mpath_count = bgp_path_info_mpath_count(path);
mpath_count = bgp_path_info_mpath_count(path->net);
bw_bytes *= mpath_count;
}

Expand Down
Loading
Loading