Skip to main content
RunBook Academy

VyOSXXV · BGP Route AdvertisementAdvertisement

BGP aggregation — aggregate-address, summary-only, and as-set

Advanced⏱ ~24 minvyosvtyshshow bgp ipv4 unicastshow bgp ipv4 unicast neighborsshow bgp ipv4 unicast regexpshow configuration commands

What you'll learn

  • Configure `aggregate-address` under the 1.5 address-family tree to originate a summary prefix
  • Decide when to use `summary-only` and when to keep the more-specifics
  • Use `as-set` to preserve the contributing AS_PATH set when summarising across ASes
  • State where an aggregate's ORIGIN, AGGREGATOR and ATOMIC_AGGREGATE attributes come from
  • Diagnose missing aggregates, missing more-specifics, and attribute loss

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)

Not yet marked complete on this device.

BGP aggregation is the operator’s tool for advertising a summary prefix while the RIB carries more-specific components. On VyOS 1.5 LTS / FRR 10.x the configuration lives under the address family:

set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22

with summary-only, as-set and a route-map available beneath it.

This lesson is the operator’s reference for the aggregate: when to use it, what the options do, which attributes the aggregate really carries, and how it fails in production.

What aggregate-address does

The BGP aggregate-address statement installs a locally originated entry in the BGP Loc-RIB for the configured prefix, but only if at least one more-specific component exists in the BGP table.

flowchart LR
  BGP["BGP table\n(more-specifics)"]
  AGG{"Aggregate has\ncomponents?"}
  ASTATIC["Locally originated aggregate entry"]
  SOMORE["More-specific entries\n(both kept by default)"]
  POLICY["Outbound policy"]
  PEER["BGP peer"]

  BGP --> AGG
  AGG -- "yes" --> ASTATIC
  AGG -- "no" --> X["Nothing\n(no aggregate advertised)"]
  ASTATIC --> POLICY
  SOMORE --> POLICY
  POLICY --> PEER

The aggregate is generated when:

  1. Components exist — at least one more-specific prefix that is a subnet of the aggregate prefix exists in the BGP table (locally originated, learned from a peer, or redistributed).
  2. The component is in the local table — the aggregate’s existence depends on what the local BGP table contains, not on what any peer’s table contains. A component filtered out by an inbound policy never enters the local table and therefore never contributes.

Default behaviour:

  • The aggregate is advertised alongside the more-specifics.
  • The aggregate is locally originated: show bgp displays it with a next hop of 0.0.0.0 and a weight of 32768, the same as any network statement.
  • The aggregate carries an AGGREGATOR attribute naming the router that built it (RFC 4271 §5.1.7), and — when as-set is not configured — an ATOMIC_AGGREGATE attribute (§5.1.6) signalling that AS_PATH information from the components was discarded.

The VyOS 1.5 configuration

configure
set protocols bgp system-as 64512
set protocols bgp parameters router-id 10.255.0.1
set protocols bgp neighbor 10.0.0.2 remote-as 64513
set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22
commit
save

Two things moved between VyOS 1.3 and 1.5 and both appear in that block. The local AS is now system-as rather than a positional number after bgp, and aggregate-address is a child of address-family ipv4-unicast rather than of the BGP instance. Pasting the 1.3 form (set protocols bgp 64512 aggregate-address ...) on a 1.5 router is rejected as an invalid configuration path.

The prefix 192.0.2.0/22 summarises 192.0.2.0/24, 192.0.3.0/24, 192.0.4.0/24 and 192.0.5.0/24. If any of those more-specifics exists in the BGP table, the aggregate is generated.

Read-only / Safeaggregate alongside its components
$ show bgp ipv4 unicast
   Network          Next Hop            Metric LocPrf Weight Path
*> 192.0.2.0/22     0.0.0.0                  0         32768 i
*> 192.0.2.0/24     0.0.0.0                  0         32768 i
*> 192.0.3.0/24     0.0.0.0                  0         32768 i
*> 192.0.4.0/24     0.0.0.0                  0         32768 i
*> 192.0.5.0/24     0.0.0.0                  0         32768 i

Illustrative output

Read the flags rather than the layout. What matters is that five prefixes are present, all five are *> (valid and best), and the /22 is one of them — the aggregate exists and is not suppressing anything.

The operator who wants only the aggregate advertised adds summary-only:

set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22 summary-only

With summary-only the more-specifics are marked suppressed (the s status code) and are not advertised. Only the aggregate leaves the router.

as-set — preserving the AS_PATH set

The default aggregate carries no AS_PATH information from its components: the local router is the originator, and the AGGREGATOR plus ATOMIC_AGGREGATE attributes are the only record that the path was summarised. That is fine for intra-AS aggregation.

For inter-AS aggregation — summarising prefixes that originated in several different ASes — discarding the AS_PATH is information loss that has a protocol consequence. The peer receiving the aggregate cannot see which ASes contributed to it, and neither can any of those ASes, which is what breaks BGP’s loop detection.

flowchart TB
  subgraph "AS 64512"
    A["192.0.2.0/24"]
  end
  subgraph "AS 64513"
    B["192.0.3.0/24"]
  end
  subgraph "AS 64514"
    C["192.0.4.0/24"]
  end
  subgraph "AS 64515 (aggregator)"
    AGG["aggregate 192.0.2.0/22\ndefault: AS_PATH carries no component ASes\nas-set: AS_SET {64512,64513,64514}"]
  end

  A --> AGG
  B --> AGG
  C --> AGG

The fix is as-set:

set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22 as-set summary-only

With as-set, the aggregate’s AS_PATH gains an AS_SET segment holding the ASes of the contributing more-specifics. The set is displayed with curly braces: {64512,64513,64514}. A set is unordered — it records that the route may have transited any of those ASes, not that it transited all of them in that order.

The set format has consequences that matter operationally:

  • An AS_SET counts as 1 towards AS_PATH length, however many ASes it holds. So adding as-set does not lengthen the path in the eyes of best-path selection, and an aggregate with three contributing ASes does not look “worse” than one with a single contributor.
  • The set is unordered, so downstream policy can only test membership. Regular expressions that anchor on path position (^64513_, _64514$) will not behave as their author expects against an AS_SET.
  • Loop detection works on membership. RFC 4271’s AS_PATH loop check rejects a route whose AS_PATH contains the receiving router’s own AS, and an AS appearing inside an AS_SET counts. That is precisely the protection the default aggregate throws away.

Where the aggregate’s attributes come from

The aggregate is a new BGP entry created by the local router. Its attributes are not inherited from the components, with one important exception.

The exception is ORIGIN. RFC 4271 §9.2.2.2 defines the aggregation rule: the aggregate’s ORIGIN is INCOMPLETE if any contributing route is INCOMPLETE; otherwise EGP if any is EGP; otherwise IGP. FRR implements that rule, which is why an aggregate over four network-originated /24s shows i (IGP) while an aggregate that picks up one redistributed component shows ? (INCOMPLETE). If the ORIGIN of your aggregate changes without you changing anything, a component changed how it was originated.

Everything else — communities, MED, local-preference — starts empty and is the operator’s to set:

set policy route-map AGG-OUT rule 10 action permit
set policy route-map AGG-OUT rule 10 set community add 64512:200
set policy route-map AGG-OUT rule 10 set metric 100

set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22 route-map AGG-OUT

The route-map is matched against the aggregate itself, not against the more-specifics, and is applied as the aggregate is built.

Note the community syntax. VyOS 1.3 wrote set community 64512:200 additive, where additive was part of the value. VyOS 1.4 and 1.5 split that into an explicit verb: set community add <value> adds to the existing community set, set community replace <value> overwrites it. add is what the old additive meant; a bare 1.3-style value with additive appended is rejected.

summary-only and the suppress flag

When summary-only is set, the more-specifics are flagged suppressed. The suppression is automatic: FRR flags every prefix in the BGP table that is a subnet of the aggregate.

Read-only / Safecomponents suppressed by summary-only
$ show bgp ipv4 unicast
   Network          Next Hop            Metric LocPrf Weight Path
*> 192.0.2.0/22     0.0.0.0                  0         32768 i
s> 192.0.2.0/24     0.0.0.0                  0         32768 i
s> 192.0.3.0/24     0.0.0.0                  0         32768 i
s> 192.0.4.0/24     0.0.0.0                  0         32768 i
s> 192.0.5.0/24     0.0.0.0                  0         32768 i

Illustrative output

s> means “suppressed, and was the best path”. The more-specifics are still in the BGP table and still install into the RIB; they are simply not advertised.

The consequences are worth being explicit about:

  • Forwarding is unaffected. Suppression is an advertisement decision. The local router still forwards using whichever route it selected, aggregate or component.
  • Suppression is per-router. An iBGP peer that receives the aggregate has its own aggregation configuration, or none. If that peer also originates the more-specifics, it will advertise them to its own eBGP peers regardless of what this router suppressed.
  • The external view collapses. The peer sees one /22 where it used to see four /24s. Any traffic engineering the peer was doing on the /24s stops working at the moment of commit, silently and from their side.

Validation

# 1. The aggregate exists in the local BGP table
show bgp ipv4 unicast 192.0.2.0/22

# 2. The components are present, and suppressed if summary-only
show bgp ipv4 unicast 192.0.2.0/24
show bgp ipv4 unicast 192.0.3.0/24

# 3. What the peer is actually sent
show bgp ipv4 unicast neighbors 10.0.0.2 advertised-routes

# 4. The summary-only check: only the /22 should appear
show bgp ipv4 unicast neighbors 10.0.0.2 advertised-routes | match 192.0.2

# 5. What the configuration says, in one line
show configuration commands | match aggregate-address

Step 3 is the one that settles arguments. advertised-routes is the post-policy view of what this router hands to that peer — if the /24s appear there, summary-only is not in effect, whatever the intent was. If the /22 appears there and the peer still says it has no route, the problem is on the peer’s side of the session, not in the aggregation.

Note the pipe: VyOS operational mode filters with | match, not | grep.

Failure modes

The aggregate does not exist

show bgp ipv4 unicast 192.0.2.0/22 returns nothing. Overwhelmingly the most common cause is that no component exists — the aggregate is generated only when at least one more-specific is in the BGP table.

Diagnostic:

  • show bgp ipv4 unicast 192.0.2.0/24 — is any component present?
  • If a component should be there but is not, the question moves upstream: was it filtered inbound, was the network statement committed, is the redistribution route-map denying it?

Fix: bring a component into the BGP table, or remove the aggregate if it is not needed. An aggregate-address with no components is not an error and produces no warning; it simply does nothing.

The more-specifics are still advertised

The operator wanted summary-only and the /24s are still in advertised-routes.

Diagnostic: show configuration commands | match aggregate-address and confirm the statement ends in summary-only. A second possibility is that the aggregate and the summary-only were committed as two separate set lines against different prefixes — a typo in the prefix creates a second, componentless aggregate rather than modifying the first.

The peer does not install the aggregate

The aggregate is in advertised-routes but the peer says it has no route. The session is fine, so the UPDATE is arriving; something at the peer is discarding it.

Real causes, in rough order of frequency:

  • The peer’s inbound prefix-list. Most peers filter what they accept, and a filter written for the /24s will not have an entry for the /22.
  • maximum-prefix on the peer’s session, already tripped, so new prefixes are refused.
  • AS_PATH loop. The peer’s own AS appears in the AS_PATH — which with as-set includes the AS_SET segment. This is a correct rejection, not a fault.
  • RPKI. The aggregate’s origin AS and prefix length must match a ROA. A /22 aggregate against a ROA issued for /24s with maxLength 24 is Invalid and may be dropped by the peer’s validation policy.

What is not a cause: the 0.0.0.0 next hop shown in your own BGP table. That is how a locally originated route is displayed locally. When the route is advertised, BGP rewrites NEXT_HOP to the address the peer can reach — the peering-interface address for an eBGP peer, the update-source for iBGP. You do not need a route-map to make the next hop of an aggregate reachable.

Attribute loss

The aggregate arrives at the peer with none of the communities its components carried. This is the designed behaviour, not a bug: an aggregate is a new route and inherits nothing except ORIGIN.

The practical bite is filtering. If the peer’s outbound policy permits “prefixes tagged 64512:100”, a component tagged 64512:100 passes and the aggregate does not — because nobody tagged the aggregate. Fix it by setting the community explicitly, on the aggregate’s own route-map or in the export map, as shown above.

Rollback

# Remove the aggregate entirely
delete protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22
commit

# Keep the aggregate but stop suppressing the more-specifics
delete protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22 summary-only
commit

Both are reversible, but the second one is not symmetric in risk. Removing summary-only advertises the more-specifics to every peer immediately on commit. If a peer’s inbound policy was written for “only the /22” — a very common arrangement — the /24s are rejected, and depending on how that filter ends, the /22 can be rejected with them.

The disciplined order is: audit the peer’s inbound policy first, then remove summary-only, and use commit-confirm if the peer’s policy is unknown.

Production discipline

Cross-course references

  • Part XXV-01 (XXV-VyOS-BGPAdvertise / network statement) covers the other origination primitive and the same address-family tree.
  • Part XXVI (XXVI-VyOS-BGPAttributes) covers the AS_PATH attribute that as-set modifies and the ORIGIN attribute the aggregation rule derives.
  • Part XXXIII (XXXIII-VyOS-RoutePolicy) covers the route-map and prefix-list primitives used to apply attribute policy.
  • Part XXXV (XXXV-VyOS-Summarisation) covers summarisation in the IGPs and how it differs from BGP aggregation.

Quiz

Knowledge check · 4 questions

  1. Q1. An operator commits `set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22` but the BGP table holds no more-specific components. What does `show bgp ipv4 unicast 192.0.2.0/22` return?

  2. Q2. `summary-only` on a BGP aggregate applies globally: every aggregate on the router suppresses its more-specifics.

  3. Q3. R1 (AS 64515) aggregates prefixes originated in AS 64512, 64513 and 64514 into 192.0.2.0/22 with `as-set summary-only`, and advertises it to R2 in AS 64513. R2 never installs the aggregate. Is this a fault, and what mechanism is at work?

    R1 is in AS 64515. Its aggregate 192.0.2.0/22 carries an AS_SET of {64512,64513,64514} because `as-set` is configured. R1 has an eBGP session to R2 in AS 64513, one of the contributing ASes. R2's operator reports that the /22 is not in their table and asks R1's operator to "fix the advertisement".

  4. Q4. R1 has `aggregate-address 192.0.2.0/22 summary-only`. The operator removes `summary-only` and commits. The peer 10.0.0.2 in another AS had been receiving the /22 with no more-specifics. After the change the peer reports it has stopped receiving the /22 as well. What happened?

    R1 has been advertising 192.0.2.0/22 to peer 10.0.0.2 with `summary-only` for six months. The operator removes `summary-only` so the four /24 more-specifics are also advertised. After commit, `show bgp ipv4 unicast neighbors 10.0.0.2 advertised-routes` on R1 shows all four /24s plus the /22. The peer reports it now has no route to 192.0.2.0/22 or to any of the /24s.

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