Latest Cisco, PMP, AWS, CompTIA, Microsoft Materials on SALE Get Now Get Now

BGP Communities Design and Lab: Classify Once at Ingress, Act at Egress, Strip on the Way Out

Communities are the only BGP attribute whose value is entirely conventional. A prefix carrying 65000:1001 means whatever your network has decided it means, and it means nothing at all to a router that has no route-map matching it. That property is what makes communities powerful — you can encode any classification you like — and it is also why community deployments fail. A scheme invented one prefix at a time, documented in one engineer's memory, applied inconsistently across border routers, is worse than no scheme, because policy now depends on tags whose meaning nobody can reconstruct.

The deployments that work all share a shape. Classification happens once, at ingress, where a prefix enters the autonomous system and the router knows what kind of neighbour sent it — customer, peer, or transit. That classification is written as a community and never recomputed. Every subsequent decision anywhere in the network matches on the community rather than on the prefix or the AS path, so adding a customer means tagging their session and nothing else. And at egress, internal communities are stripped before advertisement so your topology and your policy scheme do not leak into other people's networks.

This article builds that scheme as a lab. Section one lays out the topology and the numbering plan, and explains why the number space is designed rather than allocated ad hoc. Section two builds the ingress tagging on customer, peer, and transit sessions. Section three builds the egress policy that acts on those tags, including the outbound filter that prevents transit leaks. Section four covers the MPLS L3VPN portion of the lab, where extended communities do structurally similar work with a very different encoding. Section five is verification and troubleshooting for the whole scheme.

Blog ClaimA community scheme succeeds or fails on whether classification happens exactly once at ingress — every design that re-derives "is this a customer route" at each border router eventually has two borders that disagree.
Classification happens once at ingress and is carried as a community; every later decision matches the tag rather than re-deriving it, and internal tags are stripped on the way out.

What Does the Lab Topology and Community Scheme Look Like?

How should the number space be designed?

Divide the sixteen-bit local half into ranges by purpose rather than allocating values as requirements arrive. One range for neighbour class, so every prefix in the network carries exactly one of customer, peer, or transit. One for geography, so reporting and regional preference can match on where a prefix entered. One for requested actions, which is the range a customer is permitted to set and your egress policy acts on. One for operational markings such as blackhole requests. Ranges make an expanded community list able to match a whole category with a single regular expression, and they make an unfamiliar value self-describing.

A Deeper Dive into the Plan and Topology

The lab

AS 65000 has two border routers and one PE. BR-1 faces two customers, AS 65100 originating 203.0.113.0/24 and AS 65200 originating 198.51.100.0/22. BR-2 faces a settlement-free peer, AS 65300, and a transit provider, AS 65400, that sends a full table. PE-1 carries an MPLS L3VPN for a customer with two sites. That covers the three external neighbour classes plus the extended-community case in one topology.

The numbering plan in full

Community Meaning Set where Acted on where
65000:1000 Learned from a customer Ingress on customer sessions Egress to peers and transit
65000:1100 Learned from a settlement-free peer Ingress on peer sessions Egress — never advertised onward
65000:1200 Learned from transit Ingress on transit sessions Egress — never advertised onward
65000:1900 Originated by AS 65000 itself On the network statement Egress to everyone
65000:2001 / 2002 Entered in EMEA / AMER Ingress, per border router Regional local-preference and reporting
65000:3001 Customer request: prepend once to transit Customer sets it; we honour it Egress route-map to transit
65000:3003 Customer request: prepend three times Customer sets it Egress route-map to transit
65000:3100 Customer request: do not advertise to peers Customer sets it Egress route-map to peers
65000:9999 Blackhole this prefix Customer or operations Sets next hop to a discard interface

Base configuration on the border routers

! ===== BR-1: sessions and the community lists the policy will use
router bgp 65000
 bgp router-id 10.0.0.1
 bgp log-neighbor-changes
 ! Customers
 neighbor 192.0.2.2 remote-as 65100
 neighbor 192.0.2.6 remote-as 65200
 !
 address-family ipv4 unicast
  network 10.100.0.0 mask 255.255.0.0 route-map TAG-OWN
  neighbor 192.0.2.2 activate
  neighbor 192.0.2.6 activate
  ! Communities are not sent unless this is present
  neighbor 192.0.2.2 send-community both
  neighbor 192.0.2.6 send-community both
 exit-address-family
! ===== The community lists, defined once and reused everywhere
ip community-list standard CUSTOMER    permit 65000:1000
ip community-list standard PEER        permit 65000:1100
ip community-list standard TRANSIT     permit 65000:1200
ip community-list standard OWN         permit 65000:1900
!
! One list matching every prefix we may advertise externally
ip community-list standard ADVERTISABLE permit 65000:1000
ip community-list standard ADVERTISABLE permit 65000:1900
! ^ Separate lines = OR. A prefix needs only one of them.
!
! Customer-settable action communities
ip community-list standard PREPEND-1   permit 65000:3001
ip community-list standard PREPEND-3   permit 65000:3003
ip community-list standard NO-PEERS    permit 65000:3100
ip community-list standard BLACKHOLE   permit 65000:9999
!
! Everything in our own namespace, for stripping on egress
ip community-list expanded ALL-OURS    permit _65000:[0-9]+_

What a community scheme replaces

Without communities, the same decisions are made by re-deriving the classification everywhere it is needed. An egress filter matches an AS-path list enumerating every customer AS, which means onboarding a customer is an edit on every border router. A regional preference matches a prefix-list enumerating every regional allocation, which drifts the moment an allocation changes. A blackhole request becomes a manual static route somebody has to remember to remove. Each of these works in isolation and none of them survives growth, because the number of places holding a copy of the classification grows with the number of borders and the classification itself changes weekly.

Replacing all of it with a tag applied once has a cost worth naming: the scheme becomes load-bearing. A prefix that arrives with no class tag is invisible to every egress filter and will simply never be advertised, with no error anywhere. That failure mode is the price of the design, and it is why section five treats "does every prefix carry exactly one class tag" as a first-class verification step rather than an afterthought.

Pitfall: an untagged prefix that silently never leaves the network Symptom: a newly originated aggregate or a redistributed prefix is present in the BGP table on every router, appears healthy, and is advertised to nobody. Customers report they cannot reach it from outside. Cause: the egress policy matches a class community, and this prefix was originated without one — typically an aggregate-address statement that has no attribute-map, or a redistribution added without a route-map. Confirm: show ip bgp <prefix> shows no Community line; show ip bgp neighbors <peer> advertised-routes | include <prefix> returns nothing. Fix: apply the origination tag, and add a periodic check that the per-class prefix counts sum to the table size so an untagged prefix is caught by monitoring rather than by a customer.
Why ranges beat individual valuesAn expanded community list can match _65000:1[0-9][0-9][0-9]_ and catch every neighbour-class tag including ones added next year. A scheme with values scattered across the number space needs every value enumerated in every list that should include it, and the list that somebody forgets to update is the one that causes the incident.
Publish the plan where the configuration livesPut the numbering table in the same repository as the router configurations, and reference the community values from it rather than from memory. A community whose meaning exists only in one person's head is a policy you cannot safely change, and the scheme's whole value is that it outlives the person who designed it.
Sub claimThe number space is a design artefact, not an allocation log — ranges by purpose let a single regular expression match a whole category, and that is what keeps the policy stable as the network grows.

How Do I Tag Routes at Ingress?

What does an ingress route-map need to do?

Four things, in one map per neighbour class. Reject anything that should never be accepted — bogons, overly specific prefixes, and for a customer session anything outside their registered allocation. Set the neighbour-class community, additively so nothing already present is lost. Set the geography community for the region this border router serves. Set local preference according to the class, so customer routes beat peer routes and peer routes beat transit. Anything else the design needs is a matter of adding clauses, but those four are the irreducible core.

A Deeper Dive into Ingress Policy

Customer ingress: the strictest of the three

A customer session accepts only prefixes from that customer's registered allocation, so the prefix-list is per customer and is the one piece of configuration that changes when the customer adds address space. Everything else in the map is identical across all customers, which is why it belongs in a template.

! ===== Per-customer prefix list - the only per-customer element
ip prefix-list CUST-A-PFX seq 5 permit 203.0.113.0/24
ip prefix-list CUST-B-PFX seq 5 permit 198.51.100.0/22 le 24
!
! ===== Customer ingress, CUST-A =====
route-map CUST-A-IN deny 10
 match ip address prefix-list BOGONS
!
route-map CUST-A-IN permit 20
 match ip address prefix-list CUST-A-PFX
 ! Class, then geography, then preference
 set community 65000:1000 65000:2001 additive
 set local-preference 300
!
! implicit deny 65535 - anything outside their allocation is rejected
!
router bgp 65000
 address-family ipv4 unicast
  neighbor 192.0.2.2 route-map CUST-A-IN in
  neighbor 192.0.2.2 maximum-prefix 100 80 warning-only

Peer and transit ingress

A settlement-free peer should send only its own and its customers' prefixes; a transit provider sends a full table. Neither should ever send a default route unless the design asks for one, and neither should send anything longer than a /24 in IPv4. The class community and the local preference differ; the structure does not.

! ===== Peer ingress =====
route-map PEER-IN deny 10
 match ip address prefix-list BOGONS
!
route-map PEER-IN permit 20
 set community 65000:1100 65000:2002 additive
 set local-preference 200
!
! ===== Transit ingress =====
route-map TRANSIT-IN deny 10
 match ip address prefix-list BOGONS
!
route-map TRANSIT-IN permit 20
 set community 65000:1200 65000:2002 additive
 set local-preference 100
!
router bgp 65000
 address-family ipv4 unicast
  neighbor 198.51.0.2 route-map PEER-IN in
  neighbor 198.51.0.6 route-map TRANSIT-IN in
  ! Transit sends a full table - size the limit accordingly
  neighbor 198.51.0.6 maximum-prefix 1200000 90 restart 30

Ordering within the ingress map

The clauses in an ingress map have to run in a specific order and the order encodes security assumptions. Rejection comes first, because a bogon or an out-of-allocation prefix should never be evaluated further. Stripping the customer's attempt to set your internal tags comes second, before anything of yours is applied, so that a customer cannot pre-set a value your later clause would then match on. Your own tagging comes third. Local preference last, because it may depend on the tags just applied. Reversing any two of those produces a map that works in testing and has a hole in it.

The specific hole worth understanding: if you match on a class community in the same map that sets it, and the customer can set that community, then a customer prefix carrying 65000:1000 arrives already looking like a customer route to any clause that runs before your strip. On a customer session that is harmless because the class is what you were going to apply anyway. On a peer or transit session, where the class should be 1100 or 1200, a peer that sets 65000:1000 would have their prefixes treated as customer routes and re-advertised to your other providers. That is a leak somebody else can trigger.

! ===== Correct ordering, peer session =====
route-map PEER-IN deny 10
 ! 1. Reject before anything else is evaluated
 match ip address prefix-list BOGONS
!
route-map PEER-IN permit 20
 ! 2. Strip everything in our namespace - a peer sets NONE of ours
 set comm-list ALL-OURS delete
 ! 3. Apply our classification
 set community 65000:1100 65000:2002 additive
 ! 4. Preference, which may depend on the tags above
 set local-preference 200
! ^ On a peer or transit session, strip ALL of our namespace.
!   Only customers are permitted to set 65000:3xxx.

Tagging your own prefixes

Prefixes originated by AS 65000 need a class community too, because the egress filter matches on class and a prefix with no class tag would be rejected. Apply it on the network statement or on the redistribution, so origination and classification happen in the same place.

route-map TAG-OWN permit 10
 set community 65000:1900 additive
!
router bgp 65000
 address-family ipv4 unicast
  network 10.100.0.0 mask 255.255.0.0 route-map TAG-OWN
  ! Aggregates need it as well - they are separately originated
  aggregate-address 10.100.0.0 255.255.0.0 summary-only attribute-map TAG-OWN
 exit-address-family

Accepting customer action requests safely

Letting a customer set communities that drive your policy is genuinely useful and needs a guard: a customer must not be able to set your internal class or geography tags. Strip everything in your namespace that is not in the permitted action range before the class tag is applied, then add your own. That ordering matters — strip first, tag second.

! Everything of ours a customer must NOT be able to set
ip community-list expanded CUST-CANNOT-SET permit _65000:[12][0-9][0-9][0-9]_
! ^ Matches 65000:1xxx and 65000:2xxx. Leaves 65000:3xxx alone.
!
route-map CUST-A-IN permit 20
 match ip address prefix-list CUST-A-PFX
 ! 1. Remove any class or geography tags the customer set
 set comm-list CUST-CANNOT-SET delete
 ! 2. Now apply ours. Their 65000:3xxx requests survive.
 set community 65000:1000 65000:2001 additive
 set local-preference 300
Pitfall: set community without additive in an ingress map Symptom: customer-requested action communities stop working after an unrelated change to the ingress route-map, and prefixes arrive carrying only your class tag. Cause: a set community statement without additive replaces the entire community list, discarding whatever the customer sent — including the 65000:3xxx requests your egress policy was supposed to honour. Confirm: show ip bgp <prefix> and compare against show ip bgp neighbors <customer> received-routes, which shows the pre-policy community set. Fix: add additive. Where you genuinely need to clear first, use set comm-list ... delete for the specific ranges rather than wiping everything.
Sub claimIngress is the only place in the network that knows what kind of neighbour sent a prefix, which is why classification belongs there and nowhere else — every later router only needs to read the tag.

How Do I Act on Communities at Egress?

What does egress policy have to get right?

Two things, and the second is the one that protects other people. First, advertise only what class permits: to a peer or a transit provider, that means prefixes tagged customer or own-origin and nothing else, which is the outbound filter that prevents your network becoming transit between two providers. Second, honour the action communities a customer set — prepending, peer suppression, blackholing — because that is the interface you published. Then strip every community in your own namespace before the update leaves the autonomous system.

A Deeper Dive into Egress Policy

The outbound filter, expressed as a class match

Because ingress already classified everything, the outbound filter is one match against one community list. It stays correct when a customer adds a prefix, when a new customer is onboarded, and when a new transit provider is added — none of which require touching this map.

! ===== Egress to transit and peers: class-based, not prefix-based
route-map TRANSIT-OUT permit 10
 match community ADVERTISABLE
 ! Honour a triple prepend if the customer asked for one
 match community PREPEND-3
 set as-path prepend 65000 65000 65000
 set comm-list ALL-OURS delete
!
route-map TRANSIT-OUT permit 20
 match community ADVERTISABLE
 match community PREPEND-1
 set as-path prepend 65000
 set comm-list ALL-OURS delete
!
route-map TRANSIT-OUT permit 30
 match community ADVERTISABLE
 set comm-list ALL-OURS delete
!
! implicit deny 65535 - anything not customer or own-origin is dropped
! ===== Egress to a settlement-free peer: same, plus 65000:3100
route-map PEER-OUT deny 10
 ! Customer asked us not to advertise this to peers
 match community NO-PEERS
!
route-map PEER-OUT permit 20
 match community ADVERTISABLE
 set comm-list ALL-OURS delete
!
router bgp 65000
 address-family ipv4 unicast
  neighbor 198.51.0.2 route-map PEER-OUT out
  neighbor 198.51.0.6 route-map TRANSIT-OUT out
  neighbor 198.51.0.2 send-community both
  neighbor 198.51.0.6 send-community both

Using the geography tag for regional exit preference

The second range in the plan carries where a prefix entered the network, and its most useful application is keeping traffic regional. A router in EMEA should prefer an exit that a prefix entered through in EMEA, all else being equal, rather than hauling traffic across the core to an AMER border. Because the tag was applied at ingress, expressing that preference is one clause in a route-map applied inbound on the iBGP sessions of each region — no prefix lists, no per-allocation maintenance.

The clause has to be careful about ordering with the class-based preference. Class must dominate: a customer route entering in AMER should still beat a transit route entering in EMEA, because reaching a customer directly matters more than staying regional. Setting the class preference in hundreds and the geography adjustment in tens keeps the two independent.

! Class sets the hundreds; geography adjusts within the class
!   customer  300 base   peer 200 base   transit 100 base
!   local region +10, remote region +0
!
! Applied inbound on iBGP sessions at an EMEA router
route-map REGIONAL-EMEA permit 10
 match community CUSTOMER
 match community GEO-EMEA
 set local-preference 310
!
route-map REGIONAL-EMEA permit 20
 match community CUSTOMER
 set local-preference 300
!
route-map REGIONAL-EMEA permit 30
 match community TRANSIT
 match community GEO-EMEA
 set local-preference 110
!
route-map REGIONAL-EMEA permit 40
 set local-preference 100
!
ip community-list standard GEO-EMEA permit 65000:2001
ip community-list standard GEO-AMER permit 65000:2002

Why matching on class beats matching on AS path

Approach Onboarding a customer Customer adds a prefix Risk of drift
Community class match Tag the new session; egress unchanged Nothing to change Low — one map, one list
AS-path filter list Add the AS to the filter list on every border Nothing to change Medium — per-border edits
Prefix-list on egress Add prefixes on every border Edit every border High — drifts constantly
No egress filter Nothing Nothing Leak

Blackhole communities

A blackhole community lets a customer or your own operations team ask that traffic to a prefix be discarded at the edge rather than carried across the network to a saturated link. The egress policy sets the next hop to an address routed to Null0, which the forwarding plane discards at line rate. RFC 7999 defines a well-known value, 65535:666, for interoperable use between networks.

! A discard route the blackhole next hop resolves to
ip route 192.0.2.254 255.255.255.255 Null0
!
! Honour a blackhole request from a customer, within their allocation
route-map CUST-A-IN permit 15
 match ip address prefix-list CUST-A-PFX
 match community BLACKHOLE
 set ip next-hop 192.0.2.254
 set community no-export additive
! ^ no-export keeps the blackhole inside our AS.
!
! The well-known interoperable value from RFC 7999
ip community-list standard RFC7999-BH permit 65535:666
!
! Verify a blackholed prefix resolves to the discard route
BR-1# show ip route 203.0.113.66
  Known via "bgp 65000", distance 20, metric 0
  * 192.0.2.254, from 192.0.2.2, 00:00:41 ago
BR-1# show ip cef 203.0.113.66 | include Null0
Pitfall: forgetting to strip internal communities on egress Symptom: a peer or a looking glass shows your prefixes carrying 65000:1000, 65000:2001 and similar tags, exposing your internal classification and geography to anyone who queries. Occasionally another network's policy matches one of them with unintended results. Cause: the egress route-map has no set comm-list ... delete clause, so internal tags propagate. Confirm: show ip bgp neighbors <peer> advertised-routes detail, or look up one of your prefixes on any public looking glass. Fix: add set comm-list ALL-OURS delete to every clause of every external egress map. It must be in every clause, because a prefix takes only one.
Publish the action communities you honourIf customers are expected to set 65000:3001 to request a prepend, that has to be documented somewhere they can read. An undocumented action community is a feature nobody uses; a documented one that a route-map no longer honours is worse, because customers will believe it is working.
Sub claimAn egress filter that matches a class community stays correct through every customer and prefix change, which is the entire operational argument for classifying at ingress rather than filtering by prefix at the border.

How Do Extended Communities Work in the MPLS L3VPN Part of the Lab?

What is structurally different about extended communities?

Three things. They are eight bytes rather than four, with a type and subtype field that gives them structure — a Route Target and a Site of Origin are both extended communities distinguished by their subtype, so a router knows what kind of value it is looking at without any local convention. They are carried in a separate attribute, type 16, which means send-community extended is a separate requirement from send-community. And in an L3VPN they are not policy hints but the actual mechanism of VPN membership: a VRF imports a prefix because its Route Target matches, not because a route-map said so.

A Deeper Dive into Extended Communities in the Lab

Route Target as membership, not policy

A VRF exports a Route Target on every prefix it originates and imports any prefix carrying a Route Target in its import list. That is the whole membership model. A hub-and-spoke VPN is built by giving the hub and spokes asymmetric import and export lists rather than by writing filters; an extranet between two customers is built by importing each other's Route Targets. No route-map is involved in the common cases.

! ===== PE-1: a simple any-to-any VPN =====
vrf definition CUST-A-VPN
 rd 65000:100
 address-family ipv4
  route-target export 65000:100
  route-target import 65000:100
 exit-address-family
!
! ===== Hub-and-spoke: asymmetric RTs, no route-map needed
vrf definition HUB
 rd 65000:200
 address-family ipv4
  route-target export 65000:200   ! hub routes
  route-target import 65000:201   ! spoke routes
 exit-address-family
!
vrf definition SPOKE
 rd 65000:201
 address-family ipv4
  route-target export 65000:201   ! spoke routes
  route-target import 65000:200   ! hub routes only
 exit-address-family
! ^ Spokes cannot see each other because neither imports 65000:201.

Why the Route Distinguisher is not an extended community

An RD and an RT look alike and are unrelated. The Route Distinguisher is eight bytes prepended to the IPv4 prefix to make it unique across VRFs — it is part of the NLRI, not an attribute, and it exists so two customers using 10.0.0.0/8 produce two distinct VPNv4 prefixes. The Route Target is an extended community attached to that prefix and controls which VRFs import it. An RD affects uniqueness and nothing else; changing it does not change who receives a route. Confusing the two produces designs where somebody tries to control VPN membership by manipulating RDs, which does not work.

One place the distinction matters operationally: using a unique RD per PE for the same VPN gives every PE's copy of a prefix a different VPNv4 NLRI, so a route reflector treats them as distinct prefixes and reflects all of them rather than picking one best path. That is a common technique for restoring path diversity in an L3VPN without deploying Add-Path.

! Same VPN, unique RD per PE - restores multipath through an RR
! On PE-1:
vrf definition CUST-A-VPN
 rd 65000:100
 address-family ipv4
  route-target export 65000:100
  route-target import 65000:100
!
! On PE-2: different RD, SAME route targets
vrf definition CUST-A-VPN
 rd 65000:101
 address-family ipv4
  route-target export 65000:100
  route-target import 65000:100
!
! The RR now sees two distinct VPNv4 prefixes and reflects both
RR-1# show bgp vpnv4 unicast all | include 172.16.5.0
Route Distinguisher: 65000:100
 *>i  172.16.5.0/24    10.0.0.1
Route Distinguisher: 65000:101
 *>i  172.16.5.0/24    10.0.0.2

The send-community extended requirement

A VPNv4 session that does not send extended communities carries no Route Targets, so nothing imports anywhere and the VPN appears completely broken while every session is established and every prefix is present in the VPNv4 table. This is the single most common L3VPN misconfiguration and it is one missing keyword.

! ===== VPNv4 session - the keyword that must not be omitted
router bgp 65000
 neighbor 10.0.0.9 remote-as 65000
 neighbor 10.0.0.9 update-source Loopback0
 !
 address-family vpnv4
  neighbor 10.0.0.9 activate
  neighbor 10.0.0.9 send-community extended
  ! 'both' is safer as a habit - covers standard communities too
 exit-address-family
!
! Symptom of the omission: prefixes present, nothing imported
PE-2# show bgp vpnv4 unicast all | count 65000:100
Number of lines which match regexp = 14
PE-2# show ip route vrf CUST-A-VPN | count ^B
Number of lines which match regexp = 0
! ^ VPNv4 table has them; the VRF imported none. Check the keyword.

Site of Origin, and the loop it prevents

A customer site with two PE attachments can receive its own prefix back from the second PE, install it, and create a loop. Site of Origin tags every prefix with the site it came from, and a PE will not advertise a prefix back toward a site whose SoO it carries. It is the extended-community equivalent of AS_PATH loop detection, scoped to a VPN site.

! Tag prefixes with the site they came from
route-map SET-SOO-SITE1 permit 10
 set extcommunity soo 65000:1
!
router bgp 65000
 address-family ipv4 vrf CUST-A-VPN
  neighbor 172.16.1.2 remote-as 65100
  neighbor 172.16.1.2 activate
  neighbor 172.16.1.2 route-map SET-SOO-SITE1 in
 exit-address-family
!
! Verify the SoO is attached
PE-1# show bgp vpnv4 unicast vrf CUST-A-VPN 172.16.5.0/24 | include Extended
      Extended Community: RT:65000:100 SoO:65000:1

Standard and extended communities compared

Property Standard (RFC 1997) Extended (RFC 4360) Large (RFC 8092)
Attribute type code 8 16 32
Size 4 bytes 8 bytes 12 bytes
Structure AS:value by convention only Type and subtype fields Three 4-byte fields
Works with 4-byte ASNs No — AS field is 16 bits Yes, with the 4-octet type Yes, natively
Meaning Local convention Standardised per subtype Local convention
Typical use Policy signalling Route Target, SoO, OSPF Domain ID Policy signalling with 4-byte ASNs
Cisco enabling keyword send-community send-community extended send-community both plus large support
! Matching on extended and large communities uses their own list types
ip extcommunity-list standard RT-CUSTA permit rt 65000:100
ip extcommunity-list standard SOO-SITE1 permit soo 65000:1
ip extcommunity-list expanded ANY-OUR-RT permit _RT:65000:[0-9]+_
!
ip large-community-list standard LC-CUST permit 4200000000:1000:1
!
route-map MATCH-RT permit 10
 match extcommunity RT-CUSTA
route-map MATCH-LC permit 10
 match large-community LC-CUST
Keep the two namespaces separate in your headA standard community and an extended community with similar-looking numbers are unrelated objects carried in different attributes and matched with different list types. 65000:100 as a standard community is a policy tag your network invented; RT:65000:100 is a VPN membership rule. Using the same numeric value for both, which is common and convenient, makes the distinction easy to lose in a hurry — prefix the extended ones in documentation as RT: and SoO: so the type is never ambiguous.
Large communities exist for one reasonA standard community packs an AS number into sixteen bits, which stopped being sufficient when four-byte AS numbers were allocated. A network with AS 4200000000 cannot express "my AS, value 100" in a standard community at all. Large communities give three full four-byte fields — conventionally AS, function, and parameter — which is why they appear in modern provider community documentation alongside the legacy standard values.
Sub claimExtended communities are not a bigger version of standard ones — the type and subtype fields make them self-describing, which is what allows Route Target to be a membership mechanism rather than a convention two routers have to agree on.

How Do I Verify and Troubleshoot the Whole Scheme?

What proves the scheme is working end to end?

Four checks in order. On ingress, confirm the class and geography communities were applied by comparing pre-policy and post-policy views of the same neighbour. Internally, confirm every prefix in the table carries exactly one class tag — a prefix with none will be dropped by egress, and a prefix with two means something classified it twice. On egress, confirm the advertised prefix count matches the number of customer and own-origin prefixes rather than the full table. And on the far side, confirm your internal communities are absent from what the peer received.

A Deeper Dive into Verification

Communities as an operational data source

Once every prefix carries a class and a geography tag, the BGP table becomes queryable in ways that would otherwise require an external database. How many prefixes does each customer contribute? How much of the table entered through a given region? Did a peer suddenly start sending an order of magnitude more than yesterday? Each is a single command against a community value, and each is cheap enough to poll on a schedule. That reporting capability is a genuine second benefit of the scheme rather than a side effect, and it is often what justifies the effort of building it.

The queries also make change validation concrete. Before a maintenance window, record the per-class counts. Afterwards, compare. A count that moved when nothing about that class was supposed to change is a finding, and it surfaces within seconds rather than during the next incident.

! Per-class inventory - one command each, cheap to poll
BR-1# show ip bgp community 65000:1000 | include Total
BR-1# show ip bgp community 65000:1100 | include Total
BR-1# show ip bgp community 65000:1200 | include Total
!
! Per-region inventory
BR-1# show ip bgp community 65000:2001 | include Total
BR-1# show ip bgp community 65000:2002 | include Total
!
! Which customers are asking for a prepend right now?
BR-1# show ip bgp community 65000:3003
!
! Everything currently blackholed - useful during an incident
BR-1# show ip bgp community 65000:9999
!
! Match a whole range with a community list rather than one value
ip community-list expanded ANY-ACTION permit _65000:3[0-9][0-9][0-9]_
BR-1# show ip bgp community-list ANY-ACTION | include Total

Check one: did ingress tagging work

! Pre-policy: what the customer actually sent
BR-1# show ip bgp neighbors 192.0.2.2 received-routes
! ^ Needs soft-reconfiguration inbound; enable it for the check
!
! Post-policy: what we kept and how we tagged it
BR-1# show ip bgp 203.0.113.0/24
  65100
    192.0.2.2 from 192.0.2.2 (192.0.2.2)
      Origin IGP, metric 0, localpref 300, valid, external, best
      Community: 65000:1000 65000:2001
! ^ Class 1000, geography 2001, local preference 300. Correct.

Check two: does every prefix carry exactly one class

! Count prefixes per class - the three should sum to the table size
BR-1# show ip bgp community 65000:1000 | include Total
Total number of prefixes 6
BR-1# show ip bgp community 65000:1100 | include Total
Total number of prefixes 4218
BR-1# show ip bgp community 65000:1200 | include Total
Total number of prefixes 892104
BR-1# show ip bgp | include Total number
Total number of prefixes 896330
! 6 + 4218 + 892104 + own-origin = 896330. Nothing untagged.
!
! Find anything with no class tag at all - these will be dropped
BR-1# show ip bgp community-list ADVERTISABLE | include Total

Check three: what is actually advertised outbound

! The number that matters. Should be customers plus own origin.
BR-2# show ip bgp neighbors 198.51.0.6 advertised-routes | include Total
Total number of prefixes 9
! ^ Six customer prefixes plus three of our own. Not 896330.
!   A number near the full table size is a leak in progress.
!
! Confirm internal tags were stripped
BR-2# show ip bgp neighbors 198.51.0.6 advertised-routes 203.0.113.0
! Better still, check from the other side or a looking glass:
R-TRANSIT# show ip bgp 203.0.113.0/24 | include Community
      Community: 65400:100
! ^ Only the transit provider's own tag. Ours are gone. Correct.

Troubleshooting a tag that is not where you expect it

When a community is missing, the question is always which of four places lost it, and the four are distinguishable in order. Did the sender transmit it — check received-routes, which shows the pre-policy view. Did our ingress map strip it — compare received-routes against routes for the same neighbour. Did an internal policy remove it in transit — check the same prefix on an intermediate router. Did our egress map strip it deliberately — check advertised-routes and compare against the map's comm-list delete clauses. Working the sequence takes four commands and identifies the exact hop, which is considerably faster than reading route-maps hoping to spot the clause.

! 1. Did the peer send it? (needs soft-reconfiguration inbound)
BR-1# show ip bgp neighbors 192.0.2.2 received-routes 203.0.113.0
!
! 2. Did our ingress keep it?
BR-1# show ip bgp neighbors 192.0.2.2 routes 203.0.113.0
!
! 3. Does it survive internally?
BR-2# show ip bgp 203.0.113.0/24 | include Community
!
! 4. What leaves the network?
BR-2# show ip bgp neighbors 198.51.0.6 advertised-routes 203.0.113.0
! ^ The first step where the community is absent is the culprit.

Check four: are the action communities honoured

! Customer sets 65000:3003 asking for a triple prepend
BR-2# show ip bgp 198.51.100.0/22 | include Community
      Community: 65000:1000 65000:2001 65000:3003
!
! ...and the advertisement carries the prepend
R-TRANSIT# show ip bgp 198.51.100.0/22
  65000 65000 65000 65000 65200
    198.51.0.5 from 198.51.0.5 (10.0.0.2)
! ^ Our AS appears four times: one natural plus three prepended.
Symptom Likely cause Confirming command Fix
Peer sees no communities at all send-community missing show ip bgp neighbors X | include Community Add send-community both
Customer action tags disappear set community without additive Compare received-routes and routes Add additive
Prefixes not advertised outbound No class tag, so the egress match fails show ip bgp <prefix> Community line Tag on origination or ingress
Full table advertised to transit Egress map missing or permits too much advertised-routes | include Total Match ADVERTISABLE only
Internal tags visible externally No comm-list delete on egress Public looking glass, or the peer's table Add the delete to every egress clause
L3VPN imports nothing send-community extended missing show bgp vpnv4 unicast all vs VRF table Add the keyword on the VPNv4 session
Community list matches nothing Multiple values on one line means AND show ip community-list One value per permit line
Make the counts part of monitoringThe advertised-prefix count per external neighbour is the single most useful BGP metric to alert on. It should be stable and small on peer and transit sessions, and a sudden jump is a leak in progress — visible within one update cycle, long before anyone else notices. Polling it is cheap and catches the failure mode that costs the most.
Exam contextCommunities appear throughout the CCIE Enterprise Infrastructure blueprint, usually as the mechanism a task expects rather than as the subject. A requirement phrased as "this prefix must not leave the autonomous system" is no-export; "traffic from this customer must prefer the second provider" is a community that some route-map converts into local preference. The reliably tested items are send-community, the additive keyword, and the AND semantics of a multi-value standard community list. The extended-community half is examined more heavily in the MPLS L3VPN material.
Sub claimVerification of a community scheme is four counts, not four configurations — tagged prefixes per class, advertised prefixes per neighbour, communities present on the far side, and action tags honoured.

Conclusion

A community is a four-byte number with no intrinsic meaning, and everything useful about community-based policy comes from the discipline wrapped around that. The number space is designed in ranges so a regular expression can match a category. Classification happens once, at the only place in the network that knows what kind of neighbour sent a prefix. Every later decision reads the tag rather than re-deriving it, which is why onboarding a customer touches one session rather than every border router. And internal tags are stripped on the way out, because a community that escapes your autonomous system is both an information disclosure and an input to somebody else's policy.

Two configuration details cause a disproportionate share of the failures and both are single keywords. Cisco does not transmit communities without send-community, so a scheme can be entirely correct locally and invisible to every peer. And set community replaces rather than appends unless additive is present, so an ingress map that tags a prefix silently discards whatever the customer sent — including the action requests the egress policy was written to honour. Neither produces an error, and neither is visible without comparing pre-policy and post-policy views.

The extended-community half of the lab is worth building even if you do not run MPLS, because it demonstrates the difference between a convention and a mechanism. A Route Target is not a hint that some route-map might act on; it is the membership rule itself, and a VRF imports a prefix because the value matches. That structural difference — self-describing types rather than local agreement — is why Route Target scaled to millions of VPNs while standard communities remain a per-network convention. Build both halves, then verify with counts rather than configurations: prefixes per class, prefixes advertised per neighbour, and what the far side actually received.

Reference Notes

  1. RFC 1997 — the COMMUNITY attribute is optional transitive, type code 8, carrying one or more four-octet values.
  2. RFC 1997 — the well-known communities NO_EXPORT (0xFFFFFF01), NO_ADVERTISE (0xFFFFFF02), and NO_EXPORT_SUBCONFED (0xFFFFFF03).
  3. RFC 4360, Section 2 — the extended community format: a two-octet type field followed by six octets of value, giving structured and self-describing semantics.
  4. RFC 4360, Section 4 — the Route Target extended community and its role in controlling route distribution.
  5. RFC 4360, Section 5 — the Route Origin (Site of Origin) extended community.
  6. RFC 4364, Section 4.3 — Route Targets determine which VRFs import a VPN-IPv4 route, independent of any local policy configuration.
  7. RFC 4364, Section 4.3.5 — Site of Origin prevents a route from being advertised back to the site from which it was learned.
  8. RFC 8092, Section 2 — the Large Community format of three four-octet fields, conventionally Global Administrator plus two Local Data parts.
  9. RFC 7999, Section 2 — the BLACKHOLE well-known community 65535:666 and the recommendation to pair it with NO_EXPORT or NO_ADVERTISE.
  10. Cisco IOS-XE BGP Configuration Guide — communities are not advertised to a neighbour unless send-community is configured, with separate standard, extended, and both options.
  11. Cisco IOS-XE BGP Configuration Guide — set community replaces the existing community list; the additive keyword appends instead.
  12. Cisco IOS-XE BGP Configuration Guide — set comm-list <name> delete removes every community matching the named list from the route.