diff options
Diffstat (limited to 'bgpd/bgp_attr.c')
| -rw-r--r-- | bgpd/bgp_attr.c | 108 |
1 files changed, 24 insertions, 84 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 596d820f1b..b62319b211 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -480,12 +480,11 @@ static bool bgp_attr_aigp_get_tlv_metric(uint8_t *pnt, int length, return false; } -static void stream_put_bgp_aigp_tlv_metric(struct stream *s, - struct bgp_path_info *bpi) +static void stream_put_bgp_aigp_tlv_metric(struct stream *s, uint64_t aigp) { stream_putc(s, BGP_AIGP_TLV_METRIC); stream_putw(s, BGP_AIGP_TLV_METRIC_LEN); - stream_putq(s, bgp_aigp_metric_total(bpi)); + stream_putq(s, aigp); } static bool bgp_attr_aigp_valid(uint8_t *pnt, int length) @@ -4483,77 +4482,30 @@ static bool bgp_append_local_as(struct peer *peer, afi_t afi, safi_t safi) } static void bgp_packet_ecommunity_attribute(struct stream *s, struct peer *peer, - struct ecommunity *ecomm, - bool transparent, int attribute) + struct ecommunity *ecomm, int attribute) { - if (peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED || - peer->sub_sort == BGP_PEER_EBGP_OAD || 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; + if (!ecomm || !ecomm->size) + return; - stream_put(s, pnt, ecomm->unit_size); - } - } + 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); } /* Make attribute packet. */ -bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, - struct stream *s, struct attr *attr, - struct bpacket_attr_vec_arr *vecarr, - struct prefix *p, afi_t afi, safi_t safi, - struct peer *from, struct prefix_rd *prd, - mpls_label_t *label, uint8_t num_labels, - bool addpath_capable, uint32_t addpath_tx_id, - struct bgp_path_info *bpi) +bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct stream *s, + struct attr *attr, struct bpacket_attr_vec_arr *vecarr, + struct prefix *p, afi_t afi, safi_t safi, struct peer *from, + struct prefix_rd *prd, mpls_label_t *label, uint8_t num_labels, + bool addpath_capable, uint32_t addpath_tx_id) { size_t cp; size_t aspath_sizep; @@ -4852,19 +4804,11 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, /* 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 (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr); - bgp_packet_ecommunity_attribute(s, peer, ecomm, - transparent, - BGP_ATTR_EXT_COMMUNITIES); + bgp_packet_ecommunity_attribute(s, peer, ecomm, BGP_ATTR_EXT_COMMUNITIES); } if (CHECK_FLAG(attr->flag, @@ -4873,7 +4817,6 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, bgp_attr_get_ipv6_ecommunity(attr); bgp_packet_ecommunity_attribute(s, peer, ecomm, - transparent, BGP_ATTR_IPV6_EXT_COMMUNITIES); } } @@ -5032,10 +4975,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, } /* AIGP */ - if (bpi && CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) && - (CHECK_FLAG(peer->flags, PEER_FLAG_AIGP) || - peer->sub_sort == BGP_PEER_EBGP_OAD || - peer->sort != BGP_PEER_EBGP)) { + if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) && AIGP_TRANSMIT_ALLOWED(peer)) { /* At the moment only AIGP Metric TLV exists for AIGP * attribute. If more comes in, do not forget to update * attr_len variable to include new ones. @@ -5045,7 +4985,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, stream_putc(s, BGP_ATTR_FLAG_OPTIONAL); stream_putc(s, BGP_ATTR_AIGP); stream_putc(s, attr_len); - stream_put_bgp_aigp_tlv_metric(s, bpi); + stream_put_bgp_aigp_tlv_metric(s, attr->aigp_metric); } /* Unknown transit attribute. */ @@ -5314,7 +5254,7 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi, stream_putc(s, BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS); stream_putc(s, BGP_ATTR_AIGP); stream_putc(s, attr_len); - stream_put_bgp_aigp_tlv_metric(s, bpi); + stream_put_bgp_aigp_tlv_metric(s, attr->aigp_metric); } /* Return total size of attribute. */ |
