mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-30 04:42:58 +00:00
bgpd: Implement draft-li-idr-link-bandwidth-ext-01
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
parent
b29fdafa3f
commit
09e2a362a3
142
bgpd/bgp_attr.c
142
bgpd/bgp_attr.c
@ -4352,6 +4352,69 @@ static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bgp_packet_ecommunity_attribute(struct stream *s, struct peer *peer,
|
||||
struct ecommunity *ecomm,
|
||||
bool transparent, int attribute)
|
||||
{
|
||||
if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED ||
|
||||
transparent) {
|
||||
if (ecomm->size * ecomm->unit_size > 255) {
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
|
||||
BGP_ATTR_FLAG_TRANS |
|
||||
BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, attribute);
|
||||
stream_putw(s, ecomm->size * ecomm->unit_size);
|
||||
} else {
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
|
||||
BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, attribute);
|
||||
stream_putc(s, ecomm->size * ecomm->unit_size);
|
||||
}
|
||||
stream_put(s, ecomm->val, ecomm->size * ecomm->unit_size);
|
||||
} else {
|
||||
uint8_t *pnt;
|
||||
int tbit;
|
||||
int ecom_tr_size = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ecomm->size; i++) {
|
||||
pnt = ecomm->val + (i * ecomm->unit_size);
|
||||
tbit = *pnt;
|
||||
|
||||
if (CHECK_FLAG(tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE))
|
||||
continue;
|
||||
|
||||
ecom_tr_size++;
|
||||
}
|
||||
|
||||
if (ecom_tr_size) {
|
||||
if (ecom_tr_size * ecomm->unit_size > 255) {
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
|
||||
BGP_ATTR_FLAG_TRANS |
|
||||
BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, attribute);
|
||||
stream_putw(s, ecom_tr_size * ecomm->unit_size);
|
||||
} else {
|
||||
stream_putc(s, BGP_ATTR_FLAG_OPTIONAL |
|
||||
BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, attribute);
|
||||
stream_putc(s, ecom_tr_size * ecomm->unit_size);
|
||||
}
|
||||
|
||||
for (i = 0; i < ecomm->size; i++) {
|
||||
pnt = ecomm->val + (i * ecomm->unit_size);
|
||||
tbit = *pnt;
|
||||
|
||||
if (CHECK_FLAG(tbit,
|
||||
ECOMMUNITY_FLAG_NON_TRANSITIVE))
|
||||
continue;
|
||||
|
||||
stream_put(s, pnt, ecomm->unit_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make attribute packet. */
|
||||
bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
struct stream *s, struct attr *attr,
|
||||
@ -4654,82 +4717,31 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
|
||||
}
|
||||
}
|
||||
|
||||
/* Extended Communities attribute. */
|
||||
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)
|
||||
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
|
||||
struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
|
||||
/* Extended IPv6/Communities attributes. */
|
||||
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) {
|
||||
bool transparent = CHECK_FLAG(peer->af_flags[afi][safi],
|
||||
PEER_FLAG_RSERVER_CLIENT) &&
|
||||
from &&
|
||||
CHECK_FLAG(from->af_flags[afi][safi],
|
||||
PEER_FLAG_RSERVER_CLIENT);
|
||||
|
||||
if (peer->sort == BGP_PEER_IBGP ||
|
||||
peer->sort == BGP_PEER_CONFED || transparent) {
|
||||
if (ecomm->size * 8 > 255) {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
|
||||
stream_putw(s, ecomm->size * 8);
|
||||
} else {
|
||||
stream_putc(s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s, BGP_ATTR_EXT_COMMUNITIES);
|
||||
stream_putc(s, ecomm->size * 8);
|
||||
}
|
||||
stream_put(s, ecomm->val, ecomm->size * 8);
|
||||
} else {
|
||||
uint8_t *pnt;
|
||||
int tbit;
|
||||
int ecom_tr_size = 0;
|
||||
uint32_t i;
|
||||
if (CHECK_FLAG(attr->flag,
|
||||
ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
|
||||
struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
|
||||
|
||||
for (i = 0; i < ecomm->size; i++) {
|
||||
pnt = ecomm->val + (i * 8);
|
||||
tbit = *pnt;
|
||||
|
||||
if (CHECK_FLAG(tbit,
|
||||
ECOMMUNITY_FLAG_NON_TRANSITIVE))
|
||||
continue;
|
||||
|
||||
ecom_tr_size++;
|
||||
}
|
||||
|
||||
if (ecom_tr_size) {
|
||||
if (ecom_tr_size * 8 > 255) {
|
||||
stream_putc(
|
||||
s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS
|
||||
| BGP_ATTR_FLAG_EXTLEN);
|
||||
stream_putc(s,
|
||||
bgp_packet_ecommunity_attribute(s, peer, ecomm,
|
||||
transparent,
|
||||
BGP_ATTR_EXT_COMMUNITIES);
|
||||
stream_putw(s, ecom_tr_size * 8);
|
||||
} else {
|
||||
stream_putc(
|
||||
s,
|
||||
BGP_ATTR_FLAG_OPTIONAL
|
||||
| BGP_ATTR_FLAG_TRANS);
|
||||
stream_putc(s,
|
||||
BGP_ATTR_EXT_COMMUNITIES);
|
||||
stream_putc(s, ecom_tr_size * 8);
|
||||
}
|
||||
|
||||
for (i = 0; i < ecomm->size; i++) {
|
||||
pnt = ecomm->val + (i * 8);
|
||||
tbit = *pnt;
|
||||
if (CHECK_FLAG(attr->flag,
|
||||
ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES))) {
|
||||
struct ecommunity *ecomm =
|
||||
bgp_attr_get_ipv6_ecommunity(attr);
|
||||
|
||||
if (CHECK_FLAG(
|
||||
tbit,
|
||||
ECOMMUNITY_FLAG_NON_TRANSITIVE))
|
||||
continue;
|
||||
|
||||
stream_put(s, pnt, 8);
|
||||
}
|
||||
}
|
||||
bgp_packet_ecommunity_attribute(s, peer, ecomm,
|
||||
transparent,
|
||||
BGP_ATTR_IPV6_EXT_COMMUNITIES);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1025,10 +1025,6 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
||||
uint32_t bw_tmp, bw;
|
||||
char bps_buf[20] = {0};
|
||||
|
||||
#define ONE_GBPS_BYTES (1000 * 1000 * 1000 / 8)
|
||||
#define ONE_MBPS_BYTES (1000 * 1000 / 8)
|
||||
#define ONE_KBPS_BYTES (1000 / 8)
|
||||
|
||||
as = (*pnt++ << 8);
|
||||
as |= (*pnt++);
|
||||
(void)ptr_get_be32(pnt, &bw_tmp);
|
||||
@ -1052,6 +1048,33 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
||||
return len;
|
||||
}
|
||||
|
||||
static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt)
|
||||
{
|
||||
int len = 0;
|
||||
as_t as;
|
||||
uint64_t bw;
|
||||
char bps_buf[20] = { 0 };
|
||||
|
||||
pnt += 2; /* Reserved */
|
||||
pnt = ptr_get_be64(pnt, &bw);
|
||||
(void)ptr_get_be32(pnt, &as);
|
||||
|
||||
if (bw >= ONE_GBPS_BYTES)
|
||||
snprintf(bps_buf, sizeof(bps_buf), "%.3f Gbps",
|
||||
(float)(bw / ONE_GBPS_BYTES));
|
||||
else if (bw >= ONE_MBPS_BYTES)
|
||||
snprintf(bps_buf, sizeof(bps_buf), "%.3f Mbps",
|
||||
(float)(bw / ONE_MBPS_BYTES));
|
||||
else if (bw >= ONE_KBPS_BYTES)
|
||||
snprintf(bps_buf, sizeof(bps_buf), "%.3f Kbps",
|
||||
(float)(bw / ONE_KBPS_BYTES));
|
||||
else
|
||||
snprintf(bps_buf, sizeof(bps_buf), "%" PRIu64 " bps", bw * 8);
|
||||
|
||||
len = snprintf(buf, bufsz, "LB:%u:%" PRIu64 " (%s)", as, bw, bps_buf);
|
||||
return len;
|
||||
}
|
||||
|
||||
bool ecommunity_has_route_target(struct ecommunity *ecom)
|
||||
{
|
||||
uint32_t i;
|
||||
@ -1152,6 +1175,12 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
||||
ecommunity_lb_str(
|
||||
encbuf, sizeof(encbuf), pnt,
|
||||
ecom->disable_ieee_floating);
|
||||
} else if (sub_type ==
|
||||
ECOMMUNITY_EXTENDED_LINK_BANDWIDTH &&
|
||||
type == ECOMMUNITY_ENCODE_AS4) {
|
||||
ipv6_ecommunity_lb_str(encbuf,
|
||||
sizeof(encbuf),
|
||||
pnt);
|
||||
} else if (sub_type == ECOMMUNITY_NODE_TARGET &&
|
||||
type == ECOMMUNITY_ENCODE_IP) {
|
||||
ecommunity_node_target_str(
|
||||
@ -1369,6 +1398,13 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
||||
ecom->disable_ieee_floating);
|
||||
else
|
||||
unk_ecom = 1;
|
||||
} else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) {
|
||||
sub_type = *pnt++;
|
||||
if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH)
|
||||
ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf),
|
||||
pnt);
|
||||
else
|
||||
unk_ecom = 1;
|
||||
} else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS) {
|
||||
sub_type = *pnt++;
|
||||
if (sub_type == ECOMMUNITY_NODE_TARGET)
|
||||
@ -1818,7 +1854,6 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw)
|
||||
for (i = 0; i < ecom->size; i++) {
|
||||
const uint8_t *pnt;
|
||||
uint8_t type, sub_type;
|
||||
uint32_t bwval;
|
||||
|
||||
eval = pnt = (ecom->val + (i * ecom->unit_size));
|
||||
type = *pnt++;
|
||||
@ -1827,6 +1862,8 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw)
|
||||
if ((type == ECOMMUNITY_ENCODE_AS ||
|
||||
type == ECOMMUNITY_ENCODE_AS_NON_TRANS) &&
|
||||
sub_type == ECOMMUNITY_LINK_BANDWIDTH) {
|
||||
uint32_t bwval;
|
||||
|
||||
pnt += 2; /* bandwidth is encoded as AS:val */
|
||||
pnt = ptr_get_be32(pnt, &bwval);
|
||||
(void)pnt; /* consume value */
|
||||
@ -1836,6 +1873,18 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw)
|
||||
: ieee_float_uint32_to_uint32(
|
||||
bwval));
|
||||
return eval;
|
||||
} else if (type == ECOMMUNITY_ENCODE_AS4 &&
|
||||
sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH) {
|
||||
uint64_t bwval;
|
||||
|
||||
pnt += 2; /* Reserved */
|
||||
pnt = ptr_get_be64(pnt, &bwval);
|
||||
(void)pnt;
|
||||
|
||||
if (bw)
|
||||
*bw = bwval;
|
||||
|
||||
return eval;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1845,10 +1894,10 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw)
|
||||
|
||||
struct ecommunity *ecommunity_replace_linkbw(as_t as, struct ecommunity *ecom,
|
||||
uint64_t cum_bw,
|
||||
bool disable_ieee_floating)
|
||||
bool disable_ieee_floating,
|
||||
bool extended)
|
||||
{
|
||||
struct ecommunity *new;
|
||||
struct ecommunity_val lb_eval;
|
||||
const uint8_t *eval;
|
||||
uint8_t type;
|
||||
uint64_t cur_bw;
|
||||
@ -1875,10 +1924,21 @@ struct ecommunity *ecommunity_replace_linkbw(as_t as, struct ecommunity *ecom,
|
||||
*/
|
||||
if (cum_bw > 0xFFFFFFFF)
|
||||
cum_bw = 0xFFFFFFFF;
|
||||
encode_lb_extcomm(as > BGP_AS_MAX ? BGP_AS_TRANS : as, cum_bw, false,
|
||||
&lb_eval, disable_ieee_floating);
|
||||
|
||||
if (extended) {
|
||||
struct ecommunity_val_ipv6 lb_eval;
|
||||
|
||||
encode_lb_extended_extcomm(as, cum_bw, false, &lb_eval);
|
||||
new = ecommunity_dup(ecom);
|
||||
ecommunity_add_val_ipv6(new, &lb_eval, true, true);
|
||||
} else {
|
||||
struct ecommunity_val lb_eval;
|
||||
|
||||
encode_lb_extcomm(as > BGP_AS_MAX ? BGP_AS_TRANS : as, cum_bw,
|
||||
false, &lb_eval, disable_ieee_floating);
|
||||
new = ecommunity_dup(ecom);
|
||||
ecommunity_add_val(new, &lb_eval, true, true);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include "bgpd/bgp_rpki.h"
|
||||
#include "bgpd/bgpd.h"
|
||||
|
||||
#define ONE_GBPS_BYTES (1000 * 1000 * 1000 / 8)
|
||||
#define ONE_MBPS_BYTES (1000 * 1000 / 8)
|
||||
#define ONE_KBPS_BYTES (1000 / 8)
|
||||
|
||||
/* Refer to rfc7153 for the IANA registry definitions. These are
|
||||
* updated by other standards like rfc7674.
|
||||
*/
|
||||
@ -55,6 +59,11 @@
|
||||
/* RFC 8956 */
|
||||
#define ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6 0x0d
|
||||
|
||||
/* https://datatracker.ietf.org/doc/html/draft-li-idr-link-bandwidth-ext-01
|
||||
* Sub-type is not allocated by IANA, but let's get the first available.
|
||||
*/
|
||||
#define ECOMMUNITY_EXTENDED_LINK_BANDWIDTH 0x0016
|
||||
|
||||
/* Low-order octet of the Extended Communities type field for EVPN types */
|
||||
#define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY 0x00
|
||||
#define ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL 0x01
|
||||
@ -245,6 +254,33 @@ static inline void encode_lb_extcomm(as_t as, uint64_t bw, bool non_trans,
|
||||
eval->val[7] = bandwidth & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode BGP Link Bandwidth inside IPv6 Extended Community,
|
||||
* bandwidth is in bytes per second.
|
||||
*/
|
||||
static inline void encode_lb_extended_extcomm(as_t as, uint64_t bandwidth,
|
||||
bool non_trans,
|
||||
struct ecommunity_val_ipv6 *eval)
|
||||
{
|
||||
memset(eval, 0, sizeof(*eval));
|
||||
eval->val[0] = ECOMMUNITY_ENCODE_AS4;
|
||||
if (non_trans)
|
||||
eval->val[0] |= ECOMMUNITY_FLAG_NON_TRANSITIVE;
|
||||
eval->val[1] = ECOMMUNITY_EXTENDED_LINK_BANDWIDTH;
|
||||
eval->val[4] = (bandwidth >> 56) & 0xff;
|
||||
eval->val[5] = (bandwidth >> 48) & 0xff;
|
||||
eval->val[6] = (bandwidth >> 40) & 0xff;
|
||||
eval->val[7] = (bandwidth >> 32) & 0xff;
|
||||
eval->val[8] = (bandwidth >> 24) & 0xff;
|
||||
eval->val[9] = (bandwidth >> 16) & 0xff;
|
||||
eval->val[10] = (bandwidth >> 8) & 0xff;
|
||||
eval->val[11] = bandwidth & 0xff;
|
||||
eval->val[12] = (as >> 24) & 0xff;
|
||||
eval->val[13] = (as >> 16) & 0xff;
|
||||
eval->val[14] = (as >> 8) & 0xff;
|
||||
eval->val[15] = as & 0xff;
|
||||
}
|
||||
|
||||
static inline void encode_origin_validation_state(enum rpki_states state,
|
||||
struct ecommunity_val *eval)
|
||||
{
|
||||
@ -386,10 +422,9 @@ extern void bgp_remove_ecomm_from_aggregate_hash(
|
||||
extern void bgp_aggr_ecommunity_remove(void *arg);
|
||||
extern const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom,
|
||||
uint64_t *bw);
|
||||
extern struct ecommunity *ecommunity_replace_linkbw(as_t as,
|
||||
struct ecommunity *ecom,
|
||||
uint64_t cum_bw,
|
||||
bool disable_ieee_floating);
|
||||
extern struct ecommunity *
|
||||
ecommunity_replace_linkbw(as_t as, struct ecommunity *ecom, uint64_t cum_bw,
|
||||
bool disable_ieee_floating, bool extended);
|
||||
|
||||
extern bool soo_in_ecom(struct ecommunity *ecom, struct ecommunity *soo);
|
||||
|
||||
|
@ -2771,17 +2771,26 @@ 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) &&
|
||||
if (nh_reset && bgp_path_info_mpath_chkwtd(bgp, pi) &&
|
||||
(cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
|
||||
!CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
|
||||
!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(
|
||||
attr,
|
||||
ecommunity_replace_linkbw(bgp->as,
|
||||
bgp_attr_get_ipv6_ecommunity(
|
||||
attr),
|
||||
cum_bw, false, true));
|
||||
else
|
||||
bgp_attr_set_ecommunity(
|
||||
attr,
|
||||
ecommunity_replace_linkbw(
|
||||
bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
|
||||
CHECK_FLAG(
|
||||
peer->flags,
|
||||
PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
|
||||
bgp->as, bgp_attr_get_ecommunity(attr),
|
||||
cum_bw,
|
||||
CHECK_FLAG(peer->flags,
|
||||
PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE),
|
||||
false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3206,7 +3206,6 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
|
||||
struct bgp_path_info *path;
|
||||
struct peer *peer;
|
||||
struct ecommunity ecom_lb = {0};
|
||||
struct ecommunity_val lb_eval;
|
||||
uint64_t bw_bytes = 0;
|
||||
uint16_t mpath_count = 0;
|
||||
struct ecommunity *new_ecom;
|
||||
@ -3242,11 +3241,33 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
|
||||
bw_bytes *= mpath_count;
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_LINK_BANDWIDTH)) {
|
||||
struct ecommunity_val_ipv6 lb_eval;
|
||||
|
||||
encode_lb_extended_extcomm(as, bw_bytes, rels->non_trans,
|
||||
&lb_eval);
|
||||
|
||||
old_ecom = bgp_attr_get_ipv6_ecommunity(path->attr);
|
||||
if (old_ecom) {
|
||||
new_ecom = ecommunity_dup(old_ecom);
|
||||
ecommunity_add_val_ipv6(new_ecom, &lb_eval, true, true);
|
||||
if (!old_ecom->refcnt)
|
||||
ecommunity_free(&old_ecom);
|
||||
} else {
|
||||
ecom_lb.size = 1;
|
||||
ecom_lb.unit_size = IPV6_ECOMMUNITY_SIZE;
|
||||
ecom_lb.val = (uint8_t *)lb_eval.val;
|
||||
new_ecom = ecommunity_dup(&ecom_lb);
|
||||
}
|
||||
|
||||
bgp_attr_set_ipv6_ecommunity(path->attr, new_ecom);
|
||||
} else {
|
||||
struct ecommunity_val lb_eval;
|
||||
|
||||
encode_lb_extcomm(as, bw_bytes, rels->non_trans, &lb_eval,
|
||||
CHECK_FLAG(peer->flags,
|
||||
PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
|
||||
|
||||
/* add to route or merge with existing */
|
||||
old_ecom = bgp_attr_get_ecommunity(path->attr);
|
||||
if (old_ecom) {
|
||||
new_ecom = ecommunity_dup(old_ecom);
|
||||
@ -3260,8 +3281,8 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
|
||||
new_ecom = ecommunity_dup(&ecom_lb);
|
||||
}
|
||||
|
||||
/* new_ecom will be intern()'d or attr_flush()'d in call stack */
|
||||
bgp_attr_set_ecommunity(path->attr, new_ecom);
|
||||
}
|
||||
|
||||
/* Mark that route-map has set link bandwidth; used in attribute
|
||||
* setting decisions.
|
||||
@ -6875,7 +6896,7 @@ DEFUN_YANG(no_set_ecommunity_none, no_set_ecommunity_none_cmd,
|
||||
|
||||
DEFUN_YANG (set_ecommunity_lb,
|
||||
set_ecommunity_lb_cmd,
|
||||
"set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
|
||||
"set extcommunity bandwidth <(1-4294967295)|cumulative|num-multipaths> [non-transitive]",
|
||||
SET_STR
|
||||
"BGP extended community attribute\n"
|
||||
"Link bandwidth extended community\n"
|
||||
@ -6929,7 +6950,7 @@ DEFUN_YANG (set_ecommunity_lb,
|
||||
|
||||
DEFUN_YANG (no_set_ecommunity_lb,
|
||||
no_set_ecommunity_lb_cmd,
|
||||
"no set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
|
||||
"no set extcommunity bandwidth <(1-4294967295)|cumulative|num-multipaths> [non-transitive]",
|
||||
NO_STR
|
||||
SET_STR
|
||||
"BGP extended community attribute\n"
|
||||
|
@ -2937,7 +2937,7 @@ lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_finish(
|
||||
struct routemap_hook_context *rhc;
|
||||
enum ecommunity_lb_type lb_type;
|
||||
char str[VTY_BUFSIZ];
|
||||
uint16_t bandwidth;
|
||||
uint32_t bandwidth;
|
||||
int ret;
|
||||
|
||||
/* Add configuration. */
|
||||
@ -2951,8 +2951,8 @@ lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_finish(
|
||||
|
||||
switch (lb_type) {
|
||||
case EXPLICIT_BANDWIDTH:
|
||||
bandwidth = yang_dnode_get_uint16(args->dnode, "bandwidth");
|
||||
snprintf(str, sizeof(str), "%d", bandwidth);
|
||||
bandwidth = yang_dnode_get_uint32(args->dnode, "bandwidth");
|
||||
snprintf(str, sizeof(str), "%u", bandwidth);
|
||||
break;
|
||||
case CUMULATIVE_BANDWIDTH:
|
||||
snprintf(str, sizeof(str), "%s", "cumulative");
|
||||
|
@ -478,7 +478,7 @@ struct bgp {
|
||||
* factor (e.g., number of multipaths for the prefix)
|
||||
* Value is in Mbps
|
||||
*/
|
||||
uint32_t lb_ref_bw;
|
||||
uint64_t lb_ref_bw;
|
||||
#define BGP_LINK_BW_REF_BW 1
|
||||
|
||||
/* BGP flags. */
|
||||
|
@ -1252,14 +1252,14 @@ void route_map_action_show(struct vty *vty, const struct lyd_node *dnode,
|
||||
} else if (IS_SET_EXTCOMMUNITY_LB(action)) {
|
||||
enum ecommunity_lb_type lb_type;
|
||||
char str[VTY_BUFSIZ];
|
||||
uint16_t bandwidth;
|
||||
uint32_t bandwidth;
|
||||
|
||||
lb_type = yang_dnode_get_enum(
|
||||
dnode,
|
||||
"./rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type");
|
||||
switch (lb_type) {
|
||||
case EXPLICIT_BANDWIDTH:
|
||||
bandwidth = yang_dnode_get_uint16(
|
||||
bandwidth = yang_dnode_get_uint32(
|
||||
dnode,
|
||||
"./rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth");
|
||||
snprintf(str, sizeof(str), "%d", bandwidth);
|
||||
|
@ -881,9 +881,7 @@ identity set-extcommunity-color {
|
||||
leaf bandwidth {
|
||||
when "../lb-type = 'explicit-bandwidth'";
|
||||
mandatory true;
|
||||
type uint16 {
|
||||
range "1..25600";
|
||||
}
|
||||
type uint32;
|
||||
description
|
||||
"Bandwidth value in Mbps";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user