BGP communities for route filtering

Published 2026-08-28


I'd like to share a BGP route filtering design I keep coming back to in my work as a network engineer. It's based on BGP communities, a tool that is widely used by Internet Service Providers, although the way they use them are different from what I will explain below.

The idea is to tag (or label) BGP routes with a community, grouping them together. This then allows you to act on that group of routes, controlling where routes are advertised.

This is the topology we'll be playing with. Our main focus is R1, but we also control R2 and R3. We have two internet circuits via separate ISPs. We shall receive a default route from each via BGP. We want to advertise our DMZ route (11.22.0/24) to both ISPs. BGP will also exchange routes with R2 over the IPVPN private WAN circuit. Lastly there's an IPsec tunnel to R3, over which BGP will exchange internal routes.

We will use a two-step process: label incoming routes with BGP communities, then use the communities to filter outbound routes.

Origin labeling

The first step is labeling each route with its origin. In this topology I have identifies the origins DMZ, INET, IPSEC, IPVPN and LAN. The default routes I receive from my two ISPs are labeled INET. The routes I receive from R2 will be labeled IPVPN. My 10.1/16 is redistributed from static/connected into BGP with label LAN. Routes from R3 are labeled with IPSEC.

These labels are applied using BGP communities. They are two-field numbers that are attached to BGP routes. The first number usually represent the local AS, giving the community a local scope. The second number is the community itself. The value doesn't matter, it's up to you to give each number a meaning.

In this example I will use the following BGP communities:

  • 1122:0 DMZ
  • 1122:1 INET
  • 1122:2 IPSEC
  • 1122:3 IPVPN
  • 1122:4 LAN

I will use inbound route-maps on each BGP neighbor to apply a community to routes received from that neighbor. This is what such a configuration might look like on a Cisco IOS device:

ip bgp-community new-format!route-map RM_BGP_REDIST_DMZ permit 10 set community 1122:0route-map RM_BGP_INET_IN permit 10 set community 1122:1route-map RM_BGP_IPSEC_IN permit 10 set community 1122:2route-map RM_BGP_IPVPN_IN permit 10 set community 1122:3route-map RM_BGP_REDIST_LAN permit 10 set community 1122:4!router bgp 1122 network 10.1.0.0 mask 255.255.0.0 route-map RM_BGP_REDIST_LAN network 11.22.0.0 mask 255.255.255.0 route-map RM_BGP_REDIST_DMZ neighbor 12.99.0.1 remote-as 1299 neighbor 12.99.0.1 route-map RM_BGP_INET_IN in neighbor 17.4.0.1 remote-as 174 neighbor 17.4.0.1 route-map RM_BGP_INET_IN in neighbor 172.31.0.1 remote-as 65000 neighbor 172.31.0.1 route-map RM_BGP_IPVPN_IN in neighbor 172.31.0.5 remote-as 65000 neighbor 172.31.0.5 route-map RM_BGP_IPSEC_IN in

Syntax is Cisco IOS but this works on any Network OS that support BGP communities

Filtering

Now that all routes that enter the BGP RIB are labeled with a community, we can start filtering. We achieve this with an outbound route-map on each BGP neighbor. For example, we don't want routes learned from ISP1 to be forwarded to ISP2. The fix is simple; deny routes labeled with the INET community from being advertised to INET neighbors. Even better, we should only advertise DMZ routes to our INET neighbors; all other route origins are for internal use.

Likewise, we technically only need to advertise a default route to R2 as R1 is its connection to the rest of the world. R3, on the other hand, require some finesse as it should receive LAN and IPVPN routes. Whether to advertise the DMZ route to R3 is debatable, but I'll choose to advertise it in this example.

This is what the outbound route-maps may look like:

ip community-list standard DMZ permit 1122:0ip community-list standard INET permit 1122:1ip community-list standard IPSEC permit 1122:2ip community-list standard IPVPN permit 1122:3ip community-list standard LAN permit 1122:4!route-map RM_BGP_INET_OUT permit 10 match community DMZroute-map RM_BGP_IPVPN_OUT permit 10 match community INETroute-map RM_BGP_IPSEC_OUT permit 10 match community DMZ IPVPN LAN!router bgp 1122 neighbor 12.99.0.1 route-map RM_BGP_INET_OUT out neighbor 17.4.0.1 route-map RM_BGP_INET_OUT out neighbor 172.31.0.1 route-map RM_BGP_IPVPN_OUT out neighbor 172.31.0.5 route-map RM_BGP_IPSEC_OUT out

Readability is king

That's it!

That's all we have to do. The main benefit for me is how readable the outbound route-maps become. It is clear which routes are advertised to whom. It scales well as new routes matching these communities are automatically filtered without any extra work. It also reduces human error as routes without a community are not advertised anywhere. This minimizes the risk of configuration errors causing routing issues.

Any time I have a moderately complex BGP setup like above I find myself implementing this solution. The hard part is taking the time to think and consider what the different origins are. Once you have them defined, implementation is often quick and flow naturally.

Drawbacks

It's not a perfect system. I find that it can break if you receive multiple route "origins" from a single neighbor or when the number of origins grow too large. Redistributing connected/static routes can also be a bit awkward when you have a route that you want to advertise but does not fit any existing origins very well. In this case you may have to create an origin for only that route.

You probably want to make sure that your communities are cleaned up before you advertise the routes to any external neighbors. On Cisco IOS you apply the set community none command next to the match community line.

Thanks for reading this far. I hope this post provided some inspiration for you. Bye for now!

Copyright 2021-2026, Emil Boklund.
All Rights Reserved.