return path->mpath->mp_attr;
}
+/*
+ * bgp_path_info_chkwtd
+ *
+ * Given bestpath bgp_path_info, return if we should attempt to
+ * do weighted ECMP or not
+ */
+bool bgp_path_info_mpath_chkwtd(struct bgp_path_info *path)
+{
+ if (!path->mpath)
+ return false;
+ return (path->mpath->mp_flags & BGP_MP_LB_ALL);
+}
+
+/*
+ * 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;
+}
+
/*
* bgp_path_info_mpath_attr_set
*
/* 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 bool bgp_path_info_mpath_chkwtd(struct bgp_path_info *path);
+extern uint64_t bgp_path_info_mpath_cumbw(struct bgp_path_info *path);
#endif /* _QUAGGA_BGP_MPATH_H */
return true;
}
+static uint32_t bgp_zebra_nhop_weight(uint32_t bw, uint64_t tot_bw)
+{
+ uint64_t tmp = (uint64_t)bw * 100;
+ return ((uint32_t)(tmp / tot_bw));
+}
+
void bgp_zebra_announce(struct bgp_node *rn, const struct prefix *p,
struct bgp_path_info *info, struct bgp *bgp, afi_t afi,
safi_t safi)
char buf_prefix[PREFIX_STRLEN]; /* filled in if we are debugging */
bool is_evpn;
int nh_updated;
+ bool do_wt_ecmp;
+ uint64_t cum_bw = 0;
/* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
/* Metric is currently based on the best-path only */
metric = info->attr->med;
+
+ /* Determine if we're doing weighted ECMP or not */
+ do_wt_ecmp = bgp_path_info_mpath_chkwtd(info);
+ if (do_wt_ecmp)
+ cum_bw = bgp_path_info_mpath_cumbw(info);
+
for (mpinfo = info; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
if (valid_nh_count >= multipath_num)
break;
}
memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
sizeof(struct ethaddr));
+
+ /* Update next hop's weight for weighted ECMP */
+ if (do_wt_ecmp)
+ api_nh->weight = bgp_zebra_nhop_weight(
+ mpinfo->attr->link_bw, cum_bw);
valid_nh_count++;
}
snprintf(eth_buf, sizeof(eth_buf), " RMAC %s",
prefix_mac2str(&api_nh->rmac,
buf1, sizeof(buf1)));
- zlog_debug(" nhop [%d]: %s if %u VRF %u %s %s",
+ zlog_debug(" nhop [%d]: %s if %u VRF %u wt %u %s %s",
i + 1, nh_buf, api_nh->ifindex,
- api_nh->vrf_id, label_buf, eth_buf);
+ api_nh->vrf_id, api_nh->weight,
+ label_buf, eth_buf);
}
}