summaryrefslogtreecommitdiff
path: root/bgpd/bgp_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r--bgpd/bgp_attr.c108
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. */