mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 16:04:49 +00:00
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 <donatas.abraitis@gmail.com>
This commit is contained in:
parent
7dac521ffb
commit
2721dd613f
@ -56,7 +56,7 @@ void community_free(struct community **com)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add one community value to the community. */
|
/* 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++;
|
com->size++;
|
||||||
if (com->val)
|
if (com->val)
|
||||||
|
@ -88,6 +88,7 @@ extern struct community *community_delete(struct community *,
|
|||||||
struct community *);
|
struct community *);
|
||||||
extern struct community *community_dup(struct community *);
|
extern struct community *community_dup(struct community *);
|
||||||
extern bool community_include(struct community *, uint32_t);
|
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 void community_del_val(struct community *, uint32_t *);
|
||||||
extern unsigned long community_count(void);
|
extern unsigned long community_count(void);
|
||||||
extern struct hash *community_hash(void);
|
extern struct hash *community_hash(void);
|
||||||
|
@ -3505,6 +3505,34 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
|
|||||||
return ret;
|
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,
|
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,
|
struct attr *attr, afi_t afi, safi_t safi, int type,
|
||||||
int sub_type, struct prefix_rd *prd, mpls_label_t *label,
|
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) {
|
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
|
/* If we receive the graceful-shutdown community from an eBGP
|
||||||
* peer we must lower local-preference */
|
* peer we must lower local-preference */
|
||||||
if (new_attr.community
|
if (new_attr.community
|
||||||
|
@ -4822,6 +4822,11 @@ DEFUN (set_community,
|
|||||||
buffer_putstr(b, "no-export");
|
buffer_putstr(b, "no-export");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strncmp(argv[i]->arg, "blackhole", strlen(argv[i]->arg))
|
||||||
|
== 0) {
|
||||||
|
buffer_putstr(b, "blackhole");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (strncmp(argv[i]->arg, "graceful-shutdown",
|
if (strncmp(argv[i]->arg, "graceful-shutdown",
|
||||||
strlen(argv[i]->arg))
|
strlen(argv[i]->arg))
|
||||||
== 0) {
|
== 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user