]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Implement draft-li-idr-link-bandwidth-ext-01
authorDonatas Abraitis <donatas@opensourcerouting.org>
Wed, 10 Apr 2024 07:16:01 +0000 (10:16 +0300)
committerDonatas Abraitis <donatas@opensourcerouting.org>
Mon, 22 Apr 2024 14:50:08 +0000 (17:50 +0300)
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
bgpd/bgp_attr.c
bgpd/bgp_ecommunity.c
bgpd/bgp_ecommunity.h
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_routemap_nb_config.c
bgpd/bgpd.h
lib/routemap_cli.c
yang/frr-bgp-route-map.yang

index dc13616b1d486f92695ae02725ea309d7c227a63..b57a142d8d048f19e1b320a3995440f646554a03 100644 (file)
@@ -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;
-
-                       for (i = 0; i < ecomm->size; i++) {
-                               pnt = ecomm->val + (i * 8);
-                               tbit = *pnt;
+               if (CHECK_FLAG(attr->flag,
+                              ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
+                       struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
 
-                               if (CHECK_FLAG(tbit,
-                                              ECOMMUNITY_FLAG_NON_TRANSITIVE))
-                                       continue;
+                       bgp_packet_ecommunity_attribute(s, peer, ecomm,
+                                                       transparent,
+                                                       BGP_ATTR_EXT_COMMUNITIES);
+               }
 
-                               ecom_tr_size++;
-                       }
+               if (CHECK_FLAG(attr->flag,
+                              ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES))) {
+                       struct ecommunity *ecomm =
+                               bgp_attr_get_ipv6_ecommunity(attr);
 
-                       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_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(
-                                                   tbit,
-                                                   ECOMMUNITY_FLAG_NON_TRANSITIVE))
-                                               continue;
-
-                                       stream_put(s, pnt, 8);
-                               }
-                       }
+                       bgp_packet_ecommunity_attribute(s, peer, ecomm,
+                                                       transparent,
+                                                       BGP_ATTR_IPV6_EXT_COMMUNITIES);
                }
        }
 
index 6cded922c2b8f08da5e52fde05c530a4164e33fb..ac3bc09e9fb6d13f1ea5ea12f0688bc43a473cfb 100644 (file)
@@ -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);
-       new = ecommunity_dup(ecom);
-       ecommunity_add_val(new, &lb_eval, true, true);
+
+       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;
 }
index d3198468874a244690a3eb5c2312f84b1bda2f08..74616f01a5a3d6af1dadb8cb9086e434486ea76d 100644 (file)
 #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.
  */
 /* 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);
 
index 7c9b6415039740a1dc4bad4e545823ffa187355d..c9289f97e5fb4fcdde8b544fbe9aa88c0329b6ed 100644 (file)
@@ -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))
-               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)));
+           !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),
+                                       false));
+       }
 
        return true;
 }
index 8b0872bbed83c24aa692b5a2ac4dcb6399947c35..1515b64b77addd4fa9e017d1433d69985a146065 100644 (file)
@@ -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,26 +3241,48 @@ route_set_ecommunity_lb(void *rule, const struct prefix *prefix, void *object)
                bw_bytes *= mpath_count;
        }
 
-       encode_lb_extcomm(as, bw_bytes, rels->non_trans, &lb_eval,
-                         CHECK_FLAG(peer->flags,
-                                    PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
+       if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_LINK_BANDWIDTH)) {
+               struct ecommunity_val_ipv6 lb_eval;
 
-       /* add to route or merge with existing */
-       old_ecom = bgp_attr_get_ecommunity(path->attr);
-       if (old_ecom) {
-               new_ecom = ecommunity_dup(old_ecom);
-               ecommunity_add_val(new_ecom, &lb_eval, true, true);
-               if (!old_ecom->refcnt)
-                       ecommunity_free(&old_ecom);
+               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 {
-               ecom_lb.size = 1;
-               ecom_lb.unit_size = ECOMMUNITY_SIZE;
-               ecom_lb.val = (uint8_t *)lb_eval.val;
-               new_ecom = ecommunity_dup(&ecom_lb);
-       }
+               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));
+
+               old_ecom = bgp_attr_get_ecommunity(path->attr);
+               if (old_ecom) {
+                       new_ecom = ecommunity_dup(old_ecom);
+                       ecommunity_add_val(new_ecom, &lb_eval, true, true);
+                       if (!old_ecom->refcnt)
+                               ecommunity_free(&old_ecom);
+               } else {
+                       ecom_lb.size = 1;
+                       ecom_lb.unit_size = ECOMMUNITY_SIZE;
+                       ecom_lb.val = (uint8_t *)lb_eval.val;
+                       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);
+               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"
index c1d6ee12e147cae4f0a900e7a2821fa8e5266121..15c32eaa2856bfcd5d999b8a0adc7916e91901ea 100644 (file)
@@ -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");
index 642453d90d360922ea241116f698d73040854547..06ef1d353770d4e8f6a820197d9d9d0a509a499d 100644 (file)
@@ -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. */
index 88b341cac080da376bafc34b6530428aeb8a954e..a12a07c14fbc67d54082db0d745d891f0b01149d 100644 (file)
@@ -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);
index c679f3b9118732042d148d3d4ba07c15de1306c5..b0858e153cece282e2c91967fbd74bc618d16740 100644 (file)
@@ -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";
         }