> ## Content Index
> Fetch the complete content index at: https://www.pinglabz.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Designing BGP Policy with Communities: A Practical Framework
- URL: https://www.pinglabz.com/bgp-community-policy-design/
- Published: 2026-07-12T06:32:03.000Z
- Updated: 2026-08-24T09:43:22.000Z
- Description: A well-designed BGP community scheme turns per-neighbor route-maps into a scalable signaling system. This guide builds one end to end on IOS XE, proves it with lab output, and includes a working RTBH trigger.
- Author: Jaime
- Tags: BGP, Labs, CCIE, Network Security, #Import 2026-08-01 19:54

Most networks use BGP communities the way most people use a junk drawer: things get put in, nobody agrees what they mean, and after two years nobody dares throw anything away. That is a shame, because a well-designed community scheme is the single highest-leverage thing you can build in a BGP network. It turns policy from a pile of per-neighbor route-maps into a signalling system that scales.

This article builds a real community framework end to end, implements it on Cisco IOS XE, and proves each behavior with lab output - including a working remote-triggered black hole (RTBH) and one platform behavior that will absolutely catch you out. For the fundamentals, see the [complete BGP guide](https://www.pinglabz.com/bgp/).

## What a community actually is

A BGP community is a 32-bit tag attached to a route as an optional transitive attribute. That is the whole specification. BGP itself assigns no meaning to any value (with four well-known exceptions). The meaning is a convention that you and your peers agree on.

The universal convention is to write them as `ASN:value`. AS 65001's community 101 is written `65001:101`. The first half identifies who defined the meaning; the second half is theirs to allocate.

The well-known ones, which every implementation honours without configuration:

**no-export** Do not advertise this route to any eBGP peer outside the local AS or confederation. The route stays inside. 

**no-advertise** Do not advertise this route to *any* peer at all, internal or external. It dies at the router that received it. 

**local-AS (no-export-subconfed)** Do not advertise outside the local confederation sub-AS. 

**internet** Advertise to everyone. Effectively a no-op, but useful as an explicit "match all" in community-lists. 

Everything else is yours to define.

This article assumes you can already tag, match and act on a community on a Cisco box. If any of that is new, [setting and matching communities on IOS XE](https://www.pinglabz.com/bgp-communities/) covers the syntax and the `send-community` line everyone forgets, and the design decisions below will read much more clearly afterwards.

### First, turn on new-format

Before anything else, on every router in the design:

```
ip bgp-community new-format
```

Without it, IOS displays communities as raw 32-bit integers - `Community: 6554600 4259905637` \- and `show ip bgp community 65001:666` is rejected as invalid input. It is enabled by default on most modern images but not all, and it costs nothing to be explicit. It is a display and parsing setting only; the wire format never changes.

## Designing the scheme

A community scheme is an addressing plan for policy. Like an addressing plan, the value is in the structure, not the individual numbers. Allocate ranges by *purpose*, and leave gaps.

Here is the scheme used in the lab, which is a realistic small-enterprise pattern:

65001:1xx - Origin

Where did this route come from? `65001:101` \= HQ, `65001:102` \= branch, `65001:103` \= data center. Set once, at the point of origination. Never changed downstream.

65001:2xx - Scope

How far should it go? `65001:201` \= ISP-A only, `65001:202` \= ISP-B only, `65001:210` \= everywhere. Consumed by the edge routers' outbound policy.

65001:666 - Blackhole

Discard traffic to this prefix. The RTBH trigger. Deliberately memorable, deliberately unmistakable.

100:1xx - Provider's own tags

ISP-A tags what it sends you: `100:110` \= my own routes, `100:120` \= transit routes I learned elsewhere. You act on those inbound.

Three rules make a scheme survive contact with reality:

1. **One community, one meaning.** Never overload a value. If you need to express two things, use two communities - they are cheap and a route can carry many.
2. **Set at the edge, act at the edge.** Origin communities are set where the route enters BGP. Scope communities are consumed where the route leaves your AS. The middle of your network should be a dumb pipe that preserves them.
3. **Document it in one place, and version it.** A community scheme with no document is a scheme that will be reverse-engineered from route-maps by a stranger at 3 a.m.

## Implementation: tagging on origination

R1 is the AS 65001 edge toward ISP-A. It originates 10.10.10.0/24 (a normal site prefix) and 10.10.10.66/32 (a host under attack that we want black-holed). Both get tagged on the way out:

```
ip prefix-list SITE-A seq 5 permit 10.10.10.0/24
ip prefix-list SITE-A seq 10 permit 1.1.1.1/32
ip prefix-list BLACKHOLE-PFX seq 5 permit 10.10.10.66/32

route-map ISPA-OUT permit 10
 match ip address prefix-list BLACKHOLE-PFX
 set community 65001:101 65001:666
route-map ISPA-OUT permit 20
 match ip address prefix-list SITE-A
 set community 65001:101 65001:210
route-map ISPA-OUT permit 30

router bgp 65001
 address-family ipv4
  neighbor 10.0.13.2 send-community both
  neighbor 10.0.13.2 route-map ISPA-OUT out
```

Two details that are easy to get wrong:

- **`send-community` is not on by default.** Without it, IOS strips communities on egress and your entire scheme silently evaporates. `both` sends standard and extended communities.
- **The empty `permit 30` at the end is load-bearing.** A route-map has an implicit deny. Without a bare permit clause, every prefix that does not match sequences 10 or 20 is dropped. This one line is responsible for a substantial fraction of all BGP outages.

## Implementation: acting on communities

ISP-A (R3) is where the policy is enforced. It matches the blackhole community, rewrites the next-hop to a discard address, drops the local preference, and adds `no-export` so the black-holed route never leaves AS 100:

```
ip route 192.0.2.1 255.255.255.255 Null0
interface Loopback254
 description RTBH discard next-hop lives here
 ip address 192.0.2.254 255.255.255.0

ip community-list standard CUST-BLACKHOLE permit 65001:666

route-map CUST-IN permit 10
 match community CUST-BLACKHOLE
 set ip next-hop 192.0.2.1
 set local-preference 50
 set community no-export additive
route-map CUST-IN permit 20
 set community 100:1000 additive

router bgp 100
 address-family ipv4
  neighbor 10.0.13.1 route-map CUST-IN in
```

`additive` is the keyword to memorise. Without it, `set community` *replaces* every community on the route. With it, the new value is appended and the customer's origin tag survives. Getting this wrong destroys other people's policy silently.

### The RTBH, working

```
R3#show ip bgp 10.10.10.66/32
BGP routing table entry for 10.10.10.66/32
Paths: (2 available, best #2, table default, not advertised to EBGP peer)
  65001
    192.0.2.1 from 10.0.13.1 (1.1.1.1)
      Origin IGP, metric 0, localpref 50, valid, external, best
      Community: 65001:101 65001:666 no-export

R3#show ip cef 10.10.10.66 255.255.255.255
10.10.10.66/32
  nexthop 192.0.2.1 Null0
```

Read that carefully, because there is a lot in it:

- The customer's origin tag `65001:101` survived (that is `additive` doing its job).
- `no-export` is present, and IOS explicitly says `not advertised to EBGP peer`. The black hole stays inside AS 100.
- CEF resolves the prefix to `Null0`. Traffic destined for the victim is dropped at the provider edge, which is exactly the point - the attack traffic never reaches the customer's circuit.

### The platform trap: a Null0 static is not enough

The textbook RTBH recipe is "set the next-hop to a discard address and add `ip route 192.0.2.1 255.255.255.255 Null0`". On IOS XE 17.18 that **does not work on its own**. Verified both ways in the lab:

```
! With ONLY the Null0 static, no connected route covering 192.0.2.0/24:
R3#show ip bgp 10.10.10.66/32
Paths: (2 available, no best path)
    192.0.2.1 (inaccessible) from 10.0.113.1 (1.1.1.1)
    192.0.2.1 (inaccessible) from 10.0.13.1 (1.1.1.1)

R3#show ip cef 10.10.10.66 255.255.255.255
%Prefix not found
```

BGP's next-hop validation refuses to accept a next-hop whose only resolution is a Null0 static. The path is `valid` but the next-hop is `(inaccessible)`, so it never becomes best and never reaches the RIB. Your black hole does nothing.

The fix is to give the discard address a connected route to live in. A loopback carrying 192.0.2.254/24 makes 192.0.2.0/24 a connected network, which satisfies next-hop validation - while the more specific /32 Null0 static still wins in CEF and does the actual dropping:

```
interface Loopback254
 ip address 192.0.2.254 255.255.255.0
ip route 192.0.2.1 255.255.255.255 Null0
```

We removed the loopback and re-tested to confirm the causality, and the route went straight back to `(inaccessible)`. This is not a lab artifact. If your RTBH silently does nothing, check `show ip cef` before you check anything else.

## Implementation: the inbound side

ISP-A tags what it sends you, and you act on it. Its own routes get preferential treatment; the transit routes it learned from someone else do not:

```
ip community-list standard ISPA-OWN permit 100:110

route-map ISPA-IN permit 10
 match community ISPA-OWN
 set local-preference 200
route-map ISPA-IN permit 20
```

And the result, which is the whole scheme working in miniature:

```
R1#show ip bgp 100.100.100.0/24
  100
    10.0.13.2 from 10.0.13.2 (3.3.3.3)
      Origin IGP, metric 0, localpref 200, valid, external, multipath, best
      Community: 100:110

R1#show ip bgp 6.6.60.0/24 | include Community|localpref
      Origin IGP, localpref 100, valid, external, multipath, best
      Community: 100:120
```

ISP-A's own network gets local-pref 200\. Everything it merely transits stays at 100\. Not one prefix was named in a route-map. Add a thousand more prefixes tomorrow and the policy still holds, because the policy is expressed in tags, not addresses. **That is the payoff.**

## Standard, extended, and large communities

Standard (RFC 1997)

**Size:** 32-bit, written ASN:value  
**Breaks on:** 4-byte ASNs - your AS number will not fit in 16 bits  
**Use for:** everything, if you have a 2-byte ASN

Extended (RFC 4360)

**Size:** 64-bit, typed  
**Used by:** MPLS L3VPN route targets, EIGRP SoO  
**Not:** a general-purpose replacement for standard communities

Large (RFC 8092)

**Size:** 96-bit, ASN:function:parameter  
**Solves:** 4-byte ASNs properly  
**Use for:** any new design with a 4-byte ASN - this is the modern answer

If you have a 4-byte AS number, standard communities cannot encode it and you should be designing with **large communities** from day one. IOS XE supports them, and the CLI mirrors the standard-community commands (`set large-community`, `ip large-community-list`, `send-community both` covers them).

## Troubleshooting checklist

1. **Communities not arriving?** `send-community` is missing on the sender. This is the number one cause, every time.
2. **Communities arriving but the previous tags are gone?** Somebody used `set community` without `additive`.
3. **`show ip bgp community 65001:666` rejected?** `ip bgp-community new-format` is not on.
4. **Route-map matching nothing?** Community-lists are matched as a set, and a *standard* community-list with multiple values on one line requires *all* of them to be present. Use separate `permit` lines for OR logic.
5. **Random prefixes disappearing after you added a route-map?** The implicit deny at the end. Add a bare `permit` clause.
6. **RTBH tagged correctly but traffic still flowing?** Check `show ip cef <prefix>`. If the BGP entry says `(inaccessible)`, your discard next-hop needs a connected route (see above).

## Key takeaways

- Communities carry no built-in meaning. They are a signalling convention, and their value comes entirely from having a structure and sticking to it.
- Allocate ranges by purpose - origin, scope, action - and leave gaps. Document it once, and treat that document as the contract.
- Set tags at origination, act on them at the edge, and let the middle of your network preserve them untouched.
- `send-community both` on every neighbor, and `additive` on every `set community` that is not deliberately replacing the whole set.
- The empty `permit` at the end of an outbound route-map is not optional.
- RTBH is a community scheme's killer app: one tag, and your provider drops the attack traffic before it reaches your circuit. On IOS XE 17.x the discard next-hop needs a connected route to survive BGP next-hop validation.
- 4-byte ASN? Use large communities (RFC 8092), not standard.

Next: [BGP multipath and load sharing](https://www.pinglabz.com/bgp-multipath-load-sharing/), and a next-hop behavior that hides a classic misconfiguration completely. The full cluster index lives on the [BGP pillar guide](https://www.pinglabz.com/bgp/).