From: Donatas Abraitis Date: Thu, 21 Jan 2021 13:03:40 +0000 (+0200) Subject: bgpd: Set NO_ADVERTISE community if blackhole community received X-Git-Tag: base_7.6^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=2721dd613f5f456920b76fd1ed6de2422dc73c71;p=mirror%2Ffrr.git bgpd: Set NO_ADVERTISE community if blackhole community received 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. Sent: ``` router bgp 65534 no bgp ebgp-requires-policy neighbor 192.168.0.2 remote-as 65030 ! address-family ipv4 unicast redistribute connected neighbor 192.168.0.2 route-map spine out exit-address-family ! ! ip prefix-list self seq 5 permit 192.168.100.1/32 ! route-map spine permit 10 match ip address prefix-list self set community blackhole ! ``` Received: ``` spine1-debian-9# show ip bgp 192.168.100.1/32 BGP routing table entry for 192.168.100.1/32 Paths: (1 available, best #1, table default, inform peer to blackhole prefix) Not advertised to any peer 65534 192.168.0.1 from 192.168.0.1 (192.168.100.1) Origin incomplete, metric 0, valid, external, best (First path received) Community: blackhole no-advertise Last update: Thu Jan 21 12:56:39 2021 ``` Signed-off-by: Donatas Abraitis --- diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c index f722a8dbc7..43138b82f6 100644 --- a/bgpd/bgp_community.c +++ b/bgpd/bgp_community.c @@ -56,7 +56,7 @@ void community_free(struct community **com) } /* Add one community value to the community. */ -static void community_add_val(struct community *com, uint32_t val) +void community_add_val(struct community *com, uint32_t val) { com->size++; if (com->val) diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h index b99f38ab64..2a1fbf526a 100644 --- a/bgpd/bgp_community.h +++ b/bgpd/bgp_community.h @@ -88,6 +88,7 @@ extern struct community *community_delete(struct community *, struct community *); extern struct community *community_dup(struct community *); extern bool community_include(struct community *, uint32_t); +extern void community_add_val(struct community *com, uint32_t val); extern void community_del_val(struct community *, uint32_t *); extern unsigned long community_count(void); extern struct hash *community_hash(void); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index c4ab223b7f..a88f39f46b 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 diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index ceaf8c0963..6bcde16269 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -4822,6 +4822,11 @@ DEFUN (set_community, buffer_putstr(b, "no-export"); continue; } + if (strncmp(argv[i]->arg, "blackhole", strlen(argv[i]->arg)) + == 0) { + buffer_putstr(b, "blackhole"); + continue; + } if (strncmp(argv[i]->arg, "graceful-shutdown", strlen(argv[i]->arg)) == 0) {