Skip to main content
RunBook Academy

VyOSXXIX · BGP CommunitiesCommunities

Large communities — RFC 8092, the 12-byte format, and the 4-byte ASN problem

Advanced⏱ ~22 minshow ip bgpshow ip bgp <prefix>show ip bgp large-communityshow ip bgp large-community <value>set policy large-community-listset policy route-map set large-communityshow route-mapvtysh -c show running-configtcpdump

What you'll learn

  • Explain why the standard 32-bit community cannot represent a 4-byte ASN in its AA field
  • State the RFC 8092 12-byte format: Global Administrator (4 bytes) + Local Data (8 bytes)
  • Configure `set large-community` in a route-map on VyOS 1.5 LTS
  • Match large-community values with `large-community-list` and regex
  • Read `show ip bgp large-community` and decode the `Global:Local1:Local2` triple
  • Choose standard vs large communities when the AS is 4-byte or the data field needs more than 16 bits

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-19

Not yet marked complete on this device.

A standard community is 32 bits: 16 bits for the ASN, 16 bits for the tag. The 16-bit ASN field is a holdover from RFC 1997, when 2-byte ASNs were the only kind. When 4-byte ASNs (RFC 6793) became available, the 16-bit AA field in the standard community could no longer represent the ASN — there was no way to write 200000:100 for a 4-byte AS. The same path also created a data-space problem: the 16-bit NN field could only hold 65 535 unique values, which is fine for “EU/North America/infrastructure” but is too small for “tag every customer with a unique ID”.

RFC 8092 solves both. The large community is a 12-byte value composed of three 4-byte fields: Global Administrator, Local Data Part 1, Local Data Part 2. The Global Administrator is the ASN (4 bytes, can hold any 4-byte value). The two Local Data parts are operator-chosen 32-bit values. The format is GA:LD1:LD2.

Where the standard community breaks

The standard community format AA:NN is one 32-bit value with the AA in the upper 16 bits and the NN in the lower 16. The arithmetic is AA * 65536 + NN. The upper 16 bits are limited to 0..65535. A 4-byte ASN is 0..4294967295. The values 65536..4294967295 cannot be encoded in the AA field.

flowchart LR
  subgraph STD["Standard community (4 bytes)"]
    AA["AA: 16 bits, max 65535"]
    NN["NN: 16 bits, max 65535"]
  end
  subgraph LARGE["Large community (12 bytes)"]
    GA["GA: 32 bits, max 4294967295 (any 4-byte ASN)"]
    L1["LD1: 32 bits, max 4294967295"]
    L2["LD2: 32 bits, max 4294967295"]
  end

The NN field is also bounded at 65535. An operator who wants to tag every customer with a unique ID has 65 535 values to play with — fine for “EU/North America/South America” but not for “every customer has a unique ID”. The two Large Data fields together give 2^64 unique combinations per ASN.

The first problem (4-byte ASN) is the historical driver. The second (data space) is the modern driver. The large community is the canonical answer for both.

The large community wire format

The large community is Path Attribute code 32, type Optional Transitive. The wire format is:

+------------------------------------------------------+
|  Attribute Flags (1 octet)                           |
|    Optional 0x80 + Transitive 0x40 = 0xC0            |
|    Partial 0x20 and Extended Length 0x10 both clear  |
+------------------------------------------------------+
|  Attribute Type Code = 32 (1 octet)                  |
+------------------------------------------------------+
|  Attribute Length (1 octet; 2 if Extended Length set) |
+------------------------------------------------------+
|  Attribute Value: N × 12 octets, each one:           |
|    Global Administrator (4 octets, big-endian)       |
|    Local Data Part 1 (4 octets, big-endian)          |
|    Local Data Part 2 (4 octets, big-endian)          |
+------------------------------------------------------+

Flags first, then type code, then length — that is the RFC 4271 path-attribute framing every attribute shares, and the large community is an ordinary attribute inside it.

The value block is N × 12 octets. A route with three large communities has Length 36. The attribute is a separate Path Attribute; it is not embedded in the standard community attribute (code 8). A route can carry both a standard community attribute and a large community attribute — the two are independent.

The display form is GA:LD1:LD2:

Wire valueDisplayMeaning
65001:100:4265001:100:42AS 65001, tag 100, sub-tag 42
200000:1:1200000:1:14-byte AS 200000, tag 1, sub-tag 1
4294967295:4294967295:42949672954294967295:4294967295:4294967295Maximum values (all 0xFF)

Read as one big-endian integer, the whole 12-byte field is GA * 2^64 + LD1 * 2^32 + LD2. Nothing displays it that way: show ip bgp <prefix> and its json form both print the decoded GA:LD1:LD2 triple, and the only place the raw octets appear is a packet capture.

The 4-byte ASN requirement

The standard community was originally defined to hold a 16-bit ASN. RFC 8092 says explicitly that the Global Administrator field is to be populated with the AS number of the originating network. The format does not require a 4-byte ASN; the GA field is a 4-byte space and can hold any 32-bit value, including a 2-byte ASN.

The practical design choice is:

  • Use a standard community (AA:NN) when the ASN is 16-bit and the tag space is sufficient.
  • Use a large community (GA:LD1:LD2) when the ASN is 4-byte, or when the operator wants more than 16 bits of tag.

Be precise about what “not possible” means for the 4-byte AS. A router in AS 200000 can still set and match standard communities — the community value is just a 32-bit number and has no relationship to the local AS. What it cannot do is write a self-identifying standard community, because 200000:100 is not a representable value: 200000 does not fit the 16-bit AA field, so the value is rejected as out of range rather than truncated or dropped later. An operator in a 4-byte AS who wants to keep using standard communities must borrow a 2-byte value in the AA field, which means the tag no longer names the AS that set it.

The reverse case (a 16-bit AS using large communities) is entirely possible. It adds 12 bytes per community to every UPDATE instead of 4, and it works.

Configuration on VyOS 1.5 LTS

The configuration form mirrors the standard community, with the prefix large-:

configure
set policy large-community-list PEER-A rule 10 action 'permit'
set policy large-community-list PEER-A rule 10 description 'peer A large community'
set policy large-community-list PEER-A rule 10 large-community '65001:100:42'

set policy route-map TAG-LARGE-IN rule 10 action 'permit'
set policy route-map TAG-LARGE-IN rule 10 match large-community 'PEER-A'
set policy route-map TAG-LARGE-IN rule 10 set large-community '65001:200:1 additive'

set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast route-map import 'TAG-LARGE-IN'
commit
save

Three things in that block are worth naming.

The list lives under policy large-community-list, parallel to policy community-list, and the exact-match leaf is named after the list: large-community here, community there. The same list also takes a regex leaf when the operator wants a pattern rather than a literal value — regex '65001:100:.*' matches every sub-tag under 65001:100. As with community-lists, VyOS decides whether to emit an FRR standard or expanded large-community-list based on which leaf the rule uses.

The route-map clauses carry the large- prefix throughout: match large-community and set large-community, never match community / set community. The two formats live in separate namespaces because they are separate path attributes; a match community clause will not see a large community and the operator gets no warning, only a rule that never fires.

The neighbour binding is the 1.4/1.5 spelling. The local ASN sits under set protocols bgp system-as 65001, the peer under set protocols bgp neighbor, and the direction keyword is route-map import (or route-map export) under the address family. Pre-1.4 VyOS and FRR’s own CLI say in and out; on 1.5 those are not the node names.

The additive semantics are the same as for standard communities. Without additive, the route-map replaces the route’s entire large-community list. With additive, the route-map appends to it.

Validation

The validating commands are:

show ip bgp 198.51.100.0/24
show ip bgp large-community
show ip bgp large-community 65001:100:42
show configuration commands | match large-community-list
show route-map TAG-LARGE-IN

The first shows the attributes on one route. Large communities render on their own line as Large Community: 65001:100:42, separate from the Community: line, because FRR is printing two different attributes rather than two forms of one.

The second filters the BGP table to routes carrying any large community; the third narrows that to a value.

The fourth is the honest way to see the configured lists: it reads them back out of the VyOS configuration. There is no VyOS operational command that reports how many times a large-community-list has matched — the hit counter that does exist belongs to the route-map, which is what show route-map TAG-LARGE-IN prints (FRR reports an Invoked count per policy and per rule). A route-map whose Invoked count stays at zero is not being reached at all, which is a different bug from one whose count climbs while the match never succeeds.

For the wire format itself, tcpdump -n -i any -vvv 'port 179' captures the UPDATE and its path attributes. Whether the large community is decoded or printed as an unknown optional-transitive attribute of type 32 depends on the age of the libpcap/tcpdump build; either way the 12-octet groups are in the hex dump.

Migration patterns

The operator who runs a 16-bit AS and wants to migrate to the large community format has three options:

  • Cutover. All routes are tagged with large-community only. The peers must be reconfigured to match on the new format. The risk is a window where neither the operator nor the peer is matching.
  • Dual-tag. Every route carries both a standard community and a large community. The peers can match on whichever they understand. The cost is one extra Path Attribute per UPDATE.
  • Translator. A box on the edge of the AS translates between the two formats. The peers see only the format they expect. The complexity is the translator.

The dual-tag pattern is the most common in production. The operator sets set community '64512:100 additive' and set large-community '65001:100:42 additive' in the same route-map. The route leaves the router carrying both attributes, to every peer — this is not a per-peer selection. Each receiving router matches on whichever attribute its own policy understands and ignores the other, which is what makes a peer-by-peer migration possible without a flag day.

flowchart LR
  IN["Route arrives with no community"]
  IN --> RM["route-map TAG-IN<br/>set community 64512:100 additive<br/>set large-community 65001:100:42 additive"]
  RM --> RIB["BGP table: both attributes"]
  RIB --> PEER["Outbound: both attributes advertised"]

The cost is one extra Path Attribute (12 bytes per community plus the header overhead) plus the routing-policy complexity. The benefit is the operator can migrate peers one at a time without a network-wide cutover.

How it fails

Production failure modes:

  • The AS is 4-byte and the operator tries to name it in a standard community. set policy route-map RM rule 10 set community '200000:100' does not commit — 200000 exceeds the 16-bit AA field, so the value is rejected as malformed. Nothing is truncated and nothing is dropped later; the failure is loud and at configuration time. The fix is set large-community '200000:100:1'.
  • The operator borrows a 2-byte value to keep using standard communities. This commits, propagates, and works — and the tag no longer identifies the AS that set it, so a downstream matching “AS 200000’s tag” finds nothing and a third party using the same borrowed value collides with it. This is the quiet version of the previous failure and the reason RFC 8092 exists.
  • The operator configures set community instead of set large-community. The standard community is set and the large community is not. There is no error: they are different attributes, both spellings are valid, and the peer simply never receives the value the operator meant to send. The match side has the same trap — match community does not see a large community.
  • The peer does not support large communities. There is no capability to negotiate; large-community support is not advertised in the OPEN. Because the attribute is optional transitive, a speaker that does not recognise it forwards it on with the Partial bit set (RFC 4271) rather than dropping it, so the value usually survives the transit — but that router cannot match on it, so any policy you expected it to apply does not happen. The fix is not a knob, it is knowing which routers in the path can act on the tag.
  • The tag space is exhaustible. The operator who tags every customer with a unique NN value in a 16-bit AS will run out of values at 65535. The large community’s two LD fields, each 32 bits, give 2^64 combinations; the operator who plans to tag every customer with a unique ID should use the large community from the start.

Rollback

Large-community configuration is regular VyOS configuration. The rollback path is:

  • compare to see the diff before commit.
  • commit-confirm 10 for any remote change, which reverts after ten minutes unless a second commit confirms it.
  • rollback N; commit; save to revert to the previous configuration.
  • load /config/archive/<known-good-file>; commit; save to revert to a specific snapshot.

The operator who changes the large-community policy must also know how to roll back the change. The large community itself is on the route in the BGP table; rollback only affects the policy that reads and writes the large community.

Production discipline

Cross-course references

The Linux course’s XIX-Linux-NetFoundations covers the FIB. The OPNsense course’s XXX-OPNsense-DynamicRouting covers the equivalent large-community handling on the firewall side. The BGP lessons vyos-xxiii-01-as-numbers (4-byte AS) and vyos-xxix-01-community-concept (standard community) cover the prerequisites; the lesson vyos-xxix-04-extended-communities covers the third BGP community format (8-byte extended, used for MPLS VPN RT/RD), and vyos-xxix-06-community-troubleshoot covers the propagation-failure debugging for all three formats.

Quiz

Knowledge check · 4 questions

  1. Q1. An operator runs AS 200000 (a 4-byte ASN) and wants to tag every customer route with a unique value. Which community format is the right choice?

  2. Q2. The large community attribute uses the same Path Attribute code (8) as the standard community; the two formats differ only in the value encoding.

  3. Q3. An operator runs AS 200000 (4-byte) and wants every customer route to carry a tag that names their own AS. They write `set policy route-map TAG-IN rule 10 set community '200000:100 additive'` and the change will not commit. What is happening, and what is the fix?

    The operator's AS is 200000. They write `set policy route-map TAG-IN rule 10 set community '200000:100 additive'` intending to tag customer routes with their own AS. The commit is rejected. A colleague suggests writing `64512:100` instead, which does commit.

  4. Q4. An operator runs a mixed AS (16-bit AS 64512) and is migrating to a 4-byte AS (200000). The existing route-map writes `set community 64512:100 additive`. The operator wants the migration to be transparent to the upstream. What is the canonical dual-tag pattern?

    The operator's AS is 64512, migrating to 200000. The upstream matches on `64512:100`. The operator wants to add the new format without breaking the upstream, and to move peers over one at a time.

Passing score: 75%. Answers are checked in this browser.