Skip to main content
RunBook Academy

VyOSXXVI · BGP AttributesAttributes

AS path — prepend, aggregation loss, and the loop prevention

Advanced⏱ ~24 minvyosvtyshshow bgp ipv4 unicastshow bgp ipv4 regexpshow bgp neighbor

What you'll learn

  • Explain why AS_PATH is well-known mandatory and what it carries
  • Configure AS path prepend on an outbound route-map for outbound traffic engineering
  • Recognise the attribute loss during aggregation and how `as-set` preserves it
  • Diagnose loop detection, prepend being ignored, and unexpected path selection

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.

AS_PATH is the path-vector mechanism that makes BGP a path-vector protocol. Every BGP UPDATE carries the AS_PATH: the sequence of ASes the route has transited. On VyOS 1.5 LTS / FRR 10.x, the configuration is set policy route-map ... set as-path prepend for outbound engineering, plus the aggregation behaviour covered in xxv-02.

This lesson is the operator’s reference for AS_PATH: the well-known mandatory classification, prepend configuration, attribute loss on aggregation, loop prevention, and how it fails in production.

What AS_PATH does

AS_PATH is the canonical BGP attribute. Every BGP UPDATE must include it (it is well-known mandatory in RFC 4271’s classification). The attribute carries:

  • The sequence of ASes the route has transited (AS_SEQUENCE).
  • Optional AS_SETs (unordered sets of ASes) when summarising.
  • An AS_CONFED_SEQUENCE for confederations.
flowchart LR
  R15["R15 · AS 64515 · originator"]
  R14["R14 · AS 64514"]
  R13["R13 · AS 64513"]
  R12["R12 · AS 64512"]

  R15 -- "AS_PATH: 64515" --> R14
  R14 -- "AS_PATH: 64514 64515" --> R13
  R13 -- "AS_PATH: 64513 64514 64515" --> R12

In R15’s own BGP table the locally-originated route has an empty AS_PATH. The AS is added at the moment of eBGP advertisement: the sending router prepends its own AS to the front of the path, so R14 receives 64515. Each subsequent eBGP hop prepends again, leftmost-is-newest, so the path R12 holds reads back as “originated in 64515, reached me via 64514 then 64513”.

The receiving router can read the AS_PATH and:

  1. Choose a path — shorter AS_PATH is preferred in the best-path algorithm (shorter = fewer AS hops).
  2. Detect loops — if the local AS is already in the AS_PATH, the router refuses to install the route (it would be a loop).
  3. Apply policy — filter based on AS_PATH content (regex match, AS_PATH length, neighbour-AS).

The VyOS configuration for prepend

AS path prepend is the operator’s tool for outbound traffic engineering — making the local AS look longer to a peer, so the peer prefers a different path for traffic destined to the local AS.

VyOS 1.4 restructured the BGP tree: the local AS moved from set protocols bgp <asn> to set protocols bgp system-as <asn>, neighbours moved to set protocols bgp neighbor ..., and per-neighbour route-maps moved under an explicit address-family node.

# Define the route-map
set policy route-map PREPEND-TO-PROVIDER-A rule 10 action 'permit'
set policy route-map PREPEND-TO-PROVIDER-A rule 10 set as-path prepend '64512 64512 64512'

# Apply outbound to the peer
set protocols bgp system-as '64512'
set protocols bgp neighbor 10.0.0.1 remote-as '64998'
set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map export 'PREPEND-TO-PROVIDER-A'

commit
save

The set as-path prepend '64512 64512 64512' adds three copies of the local AS to the AS_PATH of every route advertised to Provider A. When Provider A’s peer (and downstream peers) see the AS_PATH, they see the route as having transited AS 64512 three extra times — making the path look longer than it actually is.

The effect: traffic destined to AS 64512’s prefixes prefers Provider B over Provider A, because Provider A’s path is longer.

Verifying the prepend needs care, because there are two prepends in play: the explicit one from the route-map, and the implicit one the sender adds at eBGP transmit.

Read-only / Safe
$ show bgp ipv4 neighbors 10.0.0.1 advertised-routes
   Network          Next Hop         Metric LocPrf Weight Path
*> 192.0.2.0/24     0.0.0.0                          32768 64512 64512 64512 i

Illustrative output

Read the Path column, not the row count. The three 64512 entries are the explicit prepend from the route-map. Whether the implicit eBGP prepend also appears in this local view is an implementation detail of how the sender renders its outbound table, so do not use this command to count total path length. The authoritative answer is on the other side: ask Provider A, or look the prefix up in a public looking glass, and count the ASNs there.

Aggregation and AS_PATH loss

When the operator aggregates multiple prefixes into a summary, the aggregate is a locally-originated route: its AS_PATH is empty in the local BGP table, and an eBGP peer receives it carrying only the aggregator’s AS. The AS_PATHs of the contributing more-specifics are lost.

flowchart LR
  A["192.0.2.0/24 from AS 64513"]
  B["192.0.3.0/24 from AS 64514"]
  C["192.0.4.0/24 from AS 64515"]
  AGG["AS 64512 aggregates 192.0.2.0/22"]
  D1["default: peer sees AS_PATH 64512"]
  D2["as-set: peer sees 64512 {64513,64514,64515}"]

  A --> AGG
  B --> AGG
  C --> AGG
  AGG --> D1
  AGG --> D2

The default aggregate carries no trace of where the more-specifics came from. The receiving peer cannot tell which ASes originated them.

The fix is as-set:

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

With as-set, the AS_PATH gains an AS_SET segment listing the ASes from the contributing paths: {64513,64514,64515}. The set is unordered — it records membership, not sequence.

The set format has consequences:

  • The whole set counts as one hop — an AS_SET contributes 1 to AS_PATH length no matter how many ASes are inside it. A three-AS set and a one-AS set look the same length to the best-path algorithm.
  • Loop detection is by membership — if the local AS is in the set, the receiving router refuses the route, exactly as if it had appeared in a sequence.
  • Downstream path-length-based filtering is weakened — a peer that uses AS_PATH length as a tie-breaker sees the aggregate as barely longer than a single-AS advertisement, whatever it is really summarising.

iBGP handling of AS_PATH

When a route is advertised between iBGP peers (within the same AS), the AS_PATH is not modified. The advertising router does not prepend its AS to the path on iBGP.

flowchart LR
  EXT["eBGP peer in AS 64513"]
  R1["R1 · AS 64512"]
  R3["R3 · AS 64512 · iBGP"]
  R4["R4 · AS 64512 · iBGP"]

  EXT -- "AS_PATH: 64513" --> R1
  R1 -- "AS_PATH: 64513 · unchanged" --> R3
  R1 -- "AS_PATH: 64513 · unchanged" --> R4

R3 and R4 see the AS_PATH as 64513 (the upstream AS). They do not see 64512 64513, which is what they would see if the AS_PATH were modified on iBGP.

This is the loop-prevention mechanism for iBGP: if the local AS were prepended to the path on iBGP, every iBGP peer would see its own AS in the path and reject the route.

Loop detection and the local AS in the path

When the local AS appears in a received AS_PATH, the route is discarded at input. It does not become a “valid but not best” entry — it never enters the BGP table at all, so show bgp ipv4 unicast 192.0.2.0/24 reports that the network is not in the table.

That silence is the diagnostic problem: the absence of a route looks the same whether the peer never sent it, a prefix-list filtered it, or loop detection ate it. To tell them apart, turn on inbound soft reconfiguration so the router keeps the unmodified received UPDATEs:

set protocols bgp neighbor 10.0.0.2 address-family ipv4-unicast soft-reconfiguration inbound

Now compare the two views:

show bgp ipv4 neighbors 10.0.0.2 received-routes
show bgp ipv4 unicast 192.0.2.0/24

If the prefix is in the first output and missing from the second, the router received it and threw it away. Read the Path column in the first output: if your own ASN is in there, you are looking at loop detection, and the fault is in the topology or in someone’s redistribution — not in your BGP configuration.

The deliberate override exists, for the case where two sites genuinely share one ASN and are joined through a provider:

set protocols bgp neighbor 10.0.0.2 address-family ipv4-unicast allowas-in number '2'

allowas-in number accepts a path containing the local AS up to that many times (1-10), on eBGP peers only. It switches off the protocol’s only loop protection for that neighbour, so use it where the topology makes a loop impossible, and nowhere else.

A subtle case: as-set loop detection. With as-set, the local AS appearing in the set is a loop just as much as in a sequence. Membership is what is checked, not order.

Validation

# 1. The AS_PATH the local router holds
show bgp ipv4 unicast 192.0.2.0/24

# 2. The prepend as it leaves this router
show bgp ipv4 neighbors 10.0.0.1 advertised-routes

# 3. The aggregate's AS_PATH
show bgp ipv4 unicast 192.0.2.0/22

# 4. What the iBGP peers hold, run on the iBGP peer itself
show bgp ipv4 unicast 192.0.2.0/24

For AS_PATH regex matching:

show bgp ipv4 regexp _64513_

The underscore matches an AS_PATH separator — a space, the start of the path, or the end — so _64513_ finds AS 64513 anywhere in the path without also matching 645130 or 164513.

There is no “does not traverse” form of this command. To express the negative you build it as policy, where a deny rule is available:

set policy as-path-list NOT-VIA-64513 rule 10 action 'deny'
set policy as-path-list NOT-VIA-64513 rule 10 regex '_64513_'
set policy as-path-list NOT-VIA-64513 rule 20 action 'permit'
set policy as-path-list NOT-VIA-64513 rule 20 regex '.*'
set policy route-map AVOID-64513 rule 10 action 'permit'
set policy route-map AVOID-64513 rule 10 match as-path 'NOT-VIA-64513'

Failure modes

Prepend is ignored

The operator configured set as-path prepend '64512 64512 64512' on the outbound route-map, but the peer does not see the prepend.

Diagnostic:

  1. Is the route-map applied, and in which direction? show bgp neighbor 10.0.0.1 reports the policy attached to the session; show configuration commands | match "neighbor 10.0.0.1" shows whether the node says route-map export or route-map import. Prepend belongs on export.
  2. Is the rule matching? show configuration commands | match "route-map PREPEND-TO-PROVIDER-A". Walk the rules and confirm the set as-path prepend clause sits on a permit rule that the prefix actually reaches — a deny rule earlier in the list stops it dead.
  3. Is the session eBGP? Compare the neighbour’s remote-as with system-as. Prepend is only meaningful across an eBGP boundary: prepend your own AS towards an iBGP peer in the same AS and that peer’s loop detection is entitled to drop the route.
  4. Did the route-map take effect on the existing session? A new outbound policy applies to subsequent advertisements. reset bgp ipv4 10.0.0.1 soft out re-sends the table without tearing the session down.

Prepend is applied but the path is still preferred

The operator prepended to Provider A; Provider B’s path is still preferred by the operator’s downstream peers.

Possible causes:

  • The prepend is too short — three prepended ASes may not be enough; the operator may need five or ten.
  • AS_PATH length is not the tie-breaker — the downstream peer uses LOCAL_PREF or weight to make the decision; AS_PATH is only consulted when those are equal.
  • The downstream peer has its own policy — the downstream peer may be preferring Provider B for reasons outside the operator’s control.

The fix is more prepend, or a different attribute (LOCAL_PREF on the downstream peer, if the operator can influence it).

Aggregation lost the AS_PATH

The operator aggregated prefixes from multiple ASes; the peer sees only the aggregator’s AS.

The fix:

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

The aggregate’s AS_PATH gains an AS_SET segment.

Loop detected

The local AS appears in the AS_PATH of a received route. The route is discarded.

Diagnostic:

  • The topology has a routing loop. The fix is at the topology level.
  • The aggregate’s as-set includes the local AS. The fix is to remove as-set and accept the information loss.
  • A redistribution is causing the route to be advertised back into a path that already contains the local AS. The fix is a filter on the redistribution, not allowas-in.

Rollback

# Remove the prepend from the route-map
delete policy route-map PREPEND-TO-PROVIDER-A rule 10 set as-path prepend
commit

# Remove the route-map from the neighbour
delete protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map export
commit

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

The rollback for a prepend that caused a routing problem:

  1. Capture the before state (show bgp ipv4 neighbors 10.0.0.1 advertised-routes).
  2. Remove the prepend and commit.
  3. Push the change out with reset bgp ipv4 10.0.0.1 soft out rather than waiting for the next update.
  4. Confirm the downstream peers have re-converged — which means asking them or checking a looking glass, not reading your own table.

Production discipline

Cross-course references

  • Part XXV-02 (XXV-VyOS-BGPAdvertise / aggregate) covers the aggregation that loses AS_PATH without as-set.
  • Part XXVI-01 (XXVI-VyOS-BGPAttributes / local-preference) is the higher-precedence attribute in the best-path algorithm.
  • Part XXVII (XXVII-VyOS-BGPBestPath) covers the best-path algorithm in full.
  • Part XXXIII (XXXIII-VyOS-RoutePolicy) covers the route-map primitives used here.

Quiz

Knowledge check · 4 questions

  1. Q1. An operator wants to influence outbound traffic engineering. Where should the AS path prepend be configured?

  2. Q2. When a route is advertised between iBGP peers (within the same AS), the AS_PATH is not modified by the advertising router.

  3. Q3. R1 defines a route-map with `set as-path prepend '64512 64512 64512'` and attaches it with `set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map import 'PREPEND'`. The peer does not see the prepend. What is wrong?

    R1's configuration: set policy route-map PREPEND rule 10 action 'permit' set policy route-map PREPEND rule 10 set as-path prepend '64512 64512 64512' set protocols bgp system-as '64512' set protocols bgp neighbor 10.0.0.1 remote-as '64998' set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map import 'PREPEND' The operator expects the peer at 10.0.0.1 to see a prepended AS_PATH. `show bgp ipv4 neighbors 10.0.0.1 advertised-routes` shows the original path, and the peer confirms the same.

  4. Q4. R1 (AS 64512) aggregates 192.0.2.0/22 from three different ASes (64513, 64514, 64515) and advertises to Provider Z. Provider Z's engineer asks 'where did these prefixes originate?'. What is the fix?

    R1: set protocols bgp system-as '64512' set protocols bgp address-family ipv4-unicast aggregate-address 192.0.2.0/22 summary-only set protocols bgp neighbor 10.0.0.99 remote-as '64999' The aggregate is advertised to Provider Z (AS 64999). Provider Z's engineer sees the aggregate with AS_PATH `64512` and nothing else — no indication of which ASes originated the contributing prefixes.

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