summaryrefslogtreecommitdiff
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 1d1f3d9b26..6735c1a952 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3505,6 +3505,34 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
return ret;
}
+static void bgp_attr_add_no_advertise_community(struct attr *attr)
+{
+ struct community *old;
+ struct community *new;
+ struct community *merge;
+ struct community *noadv;
+
+ old = attr->community;
+ noadv = community_str2com("no-advertise");
+
+ if (old) {
+ merge = community_merge(community_dup(old), noadv);
+
+ if (!old->refcnt)
+ community_free(&old);
+
+ new = community_uniq_sort(merge);
+ community_free(&merge);
+ } else {
+ new = community_dup(noadv);
+ }
+
+ community_free(&noadv);
+
+ attr->community = new;
+ attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
+}
+
int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
struct attr *attr, afi_t afi, safi_t safi, int type,
int sub_type, struct prefix_rd *prd, mpls_label_t *label,
@@ -3697,6 +3725,20 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
if (peer->sort == BGP_PEER_EBGP) {
+ /* rfc7999:
+ * A BGP speaker receiving an announcement tagged with the
+ * BLACKHOLE community SHOULD add the NO_ADVERTISE or
+ * NO_EXPORT community as defined in RFC1997, or a
+ * similar community, to prevent propagation of the
+ * prefix outside the local AS. The community to prevent
+ * propagation SHOULD be chosen according to the operator's
+ * routing policy.
+ */
+ if (new_attr.community
+ && community_include(new_attr.community,
+ COMMUNITY_BLACKHOLE))
+ bgp_attr_add_no_advertise_community(&new_attr);
+
/* If we receive the graceful-shutdown community from an eBGP
* peer we must lower local-preference */
if (new_attr.community