diff options
author | hasso <hasso> | 2004-05-20 10:20:02 +0000 |
---|---|---|
committer | hasso <hasso> | 2004-05-20 10:20:02 +0000 |
commit | 4372df71e191fcf6a6f9616fad80d11cd131c82d (patch) | |
tree | dd01502f61566bb57fd75e1c4a388181140f2f1d /bgpd/bgp_attr.c | |
parent | e0701b7955b883c5437269a382e1afc76ee71e5c (diff) |
Merge bgpd changeset 1184 from Zebra repository by Rivo Nurges.
Diffstat (limited to 'bgpd/bgp_attr.c')
-rw-r--r-- | bgpd/bgp_attr.c | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 91a0e07c..7d48374d 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1653,19 +1653,67 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY) && (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES))) { - if (attr->ecommunity->size * 8 > 255) + if (peer_sort (peer) == BGP_PEER_IBGP || peer_sort (peer) == BGP_PEER_CONFED) { - 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, attr->ecommunity->size * 8); + if (attr->ecommunity->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, attr->ecommunity->size * 8); + } + else + { + stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); + stream_putc (s, BGP_ATTR_EXT_COMMUNITIES); + stream_putc (s, attr->ecommunity->size * 8); + } + stream_put (s, attr->ecommunity->val, attr->ecommunity->size * 8); } else { - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_EXT_COMMUNITIES); - stream_putc (s, attr->ecommunity->size * 8); + u_char *pnt; + int tbit; + int ecom_tr_size = 0; + int i; + + for (i = 0; i < attr->ecommunity->size; i++) + { + pnt = attr->ecommunity->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_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 < attr->ecommunity->size; i++) + { + pnt = attr->ecommunity->val + (i * 8); + tbit = *pnt; + + if (CHECK_FLAG (tbit, ECOMMUNITY_FLAG_NON_TRANSITIVE)) + continue; + + stream_put (s, pnt, 8); + } + } } - stream_put (s, attr->ecommunity->val, attr->ecommunity->size * 8); } /* Unknown transit attribute. */ |