Skip to main content
RunBook Academy

VyOSXXV · BGP Route AdvertisementAdvertisement

Redistributing OSPF into BGP — E1/E2 metric types, route-maps, and feedback

Advanced⏱ ~24 minvyosvtyshset protocols bgp address-family ipv4-unicast redistribute ospfshow ip ospf database externalshow ip bgpshow ip route

What you'll learn

  • Configure `redistribute ospf` under the BGP address-family with a metric and a route-map
  • Explain the difference between E1 and E2 external metrics in OSPF and how each reaches the BGP MED
  • Apply FRR's route-map semantics — implicit deny, and an entry with no match clause matching everything
  • Recognise and prevent the OSPF-into-BGP-into-OSPF feedback loop
  • Diagnose why an OSPF route is or is not advertised into BGP

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.

Redistributing OSPF into BGP is the bridge between the IGP and the EGP. On VyOS 1.5 LTS / FRR 10.x the configuration lives under the BGP address family: set protocols bgp address-family ipv4-unicast redistribute ospf [metric <m>] [route-map <name>]. The route-map is the safety belt — without it, every OSPF route in the RIB becomes a BGP advertisement, and the canonical route leak begins.

This lesson is the operator’s reference for OSPF-to-BGP redistribution: how the metric carries through, what attributes the routes inherit, why the route-map is mandatory, and how to prevent the OSPF-BGP-OSPF feedback loop.

What the redistribution does

The BGP redistribute ospf statement tells FRR: “every OSPF route in the RIB should be considered for redistribution into BGP”. zebra hands bgpd each OSPF route as it appears:

  1. Find every route with source ospf (intra-area, inter-area, external-1, external-2, NSSA-external).
  2. Filter through the route-map (if configured).
  3. Routes that pass are installed in the BGP Loc-RIB as locally originated.
  4. The Loc-RIB entries participate in best-path.
  5. Surviving best paths are filtered through outbound policy and advertised to peers.
flowchart LR
  OSPF["OSPF routes\n(RIB)\n- intra-area\n- inter-area\n- E1\n- E2\n- NSSA"]
  RM{"Route-map\nfilter"}
  INSTALL["Install in Loc-RIB\n(origin: incomplete)"]
  BEST["Best-path algorithm"]
  POLICY["Outbound policy"]
  PEER["BGP peer"]

  OSPF --> RM
  RM -- "permit" --> INSTALL
  RM -- "deny" --> X["Drop"]
  INSTALL --> BEST
  BEST --> POLICY
  POLICY --> PEER

The default attributes on a redistributed route:

  • Originincomplete (?). bgpd builds the attribute set for a redistributed route with the origin hard-coded to incomplete; there is no configuration that changes that before the route-map runs.
  • Weight — 32768, FRR’s default weight for a locally originated path.
  • AS-path — empty.
  • MEDthe metric zebra reported for the route. For an OSPF route that is the OSPF cost as the RIB holds it. This is the part most operators get wrong: the default is not zero.
  • Next-hop — carried through from the redistributed route. A route with an IP next-hop keeps it; an interface route (no gateway) appears with 0.0.0.0. On eBGP advertisement the next-hop is rewritten to the local session address.

E1 vs E2 in OSPF — and how it carries through

OSPF’s external routes (routes learned via redistribution into OSPF) have two metric types:

  • E1 (External Type 1) — the metric is the redistribution metric plus the OSPF cost to the ASBR. As the route is propagated through the OSPF domain, the metric accumulates.
  • E2 (External Type 2) — the metric is the redistribution metric only. The OSPF cost to the ASBR is ignored. The metric does not change as the route is propagated.

The metric type is part of the OSPF LSA (Type 5 or Type 7). It is not a BGP attribute. When the OSPF route is redistributed into BGP, the type information is lost — but the metric value is not. Whatever number the RIB is holding for that route becomes the MED.

That number differs by type. For an E2 route the RIB holds the redistribution metric alone; for an E1 route it holds the redistribution metric plus this router’s cost to the ASBR. So two routers redistributing the same E1 route into BGP will advertise different MEDs, while two routers redistributing the same E2 route will advertise the same one.

flowchart LR
  ASBR["ASBR\n(redistribute static into OSPF)"]
  L5["OSPF Type 5 LSA\nmetric-type: E2\nmetric: 50"]
  ABR1["ABR (area 0)"]
  ABR2["ABR (area 1)"]
  R1["Internal router (area 1)"]
  BGP_R["Same router\nredistributes OSPF into BGP"]

  ASBR --> L5
  L5 --> ABR1
  ABR1 --> ABR2
  ABR2 --> R1
  R1 --> BGP_R
  BGP_R --> BGP["BGP advertisement\nMED: 50\nORIGIN: incomplete"]

The OSPF internal routers see the metric as 50 (the redistribution metric, unchanged because it is E2). The BGP advertisement carries 50 as the MED. The receiving BGP peer sees MED 50 and cannot tell whether the route was E1 or E2 in OSPF, or indeed that OSPF was involved at all.

If the operator wants the MED to be a deliberate policy value rather than whatever the IGP happened to compute, the route-map is where to set it:

set policy route-map OSPF-TO-BGP rule 10 action permit
set policy route-map OSPF-TO-BGP rule 10 match ip address prefix-list INTERNAL-NETWORKS
set policy route-map OSPF-TO-BGP rule 10 set metric 100

Now every prefix that passes rule 10 is advertised with MED 100 regardless of its OSPF cost, and a link-cost change inside the OSPF domain no longer ripples out into the neighbouring AS’s best-path decision.

The VyOS configuration

configure
set protocols bgp system-as 64512
set protocols bgp address-family ipv4-unicast redistribute ospf
commit
save

The simplest form: every OSPF route in the RIB is redistributed into BGP. Note that the ASN is now a leaf of its own — system-as — rather than a tag in the path; the 1.3 form set protocols bgp 64512 redistribute ospf does not exist on 1.4 or 1.5, and redistribution moved under the address family.

With a uniform metric:

set protocols bgp address-family ipv4-unicast redistribute ospf metric 100

With a route-map (the production pattern):

set policy prefix-list INTERNAL-NETWORKS rule 10 action permit
set policy prefix-list INTERNAL-NETWORKS rule 10 prefix 10.10.0.0/16
set policy prefix-list INTERNAL-NETWORKS rule 20 action permit
set policy prefix-list INTERNAL-NETWORKS rule 20 prefix 192.168.0.0/16
set policy prefix-list INTERNAL-NETWORKS rule 20 le 19

set policy route-map OSPF-TO-BGP rule 10 action permit
set policy route-map OSPF-TO-BGP rule 10 match ip address prefix-list INTERNAL-NETWORKS
set policy route-map OSPF-TO-BGP rule 10 set metric 100
set policy route-map OSPF-TO-BGP rule 10 set community add 64512:400

set protocols bgp address-family ipv4-unicast redistribute ospf route-map OSPF-TO-BGP

The route-map:

  • Filters which OSPF routes are redistributed (INTERNAL-NETWORKS allows only the operator’s own internal prefixes).
  • Sets the metric (100) which becomes the BGP MED.
  • Stamps a community for downstream policy. On 1.4/1.5 the additive form is set community add <value>; replace and delete are the other two verbs.

How the filter actually decides — FRR’s route-map semantics

This is where operators who learned filtering on ACLs get caught out. Three rules govern every route-map in FRR:

  1. A route-map entry with no match clause matches every route. A bare action deny rule is not a no-op; it is a deny-all.
  2. A prefix-list ends in an implicit deny. A prefix that matches no rule does not match the list.
  3. A route-map ends in an implicit deny. A route that matches no entry is denied. There is no implicit permit at the bottom, unlike some vendors’ route-maps.

Put together: the two-line filter above is already complete. 10.10.0.0/16 matches the prefix-list, so rule 10 permits it. 172.16.0.0/16 does not match the prefix-list, so rule 10 does not match, no other entry exists, and the implicit deny at the end of the route-map drops it. Nothing more is needed.

After commit, show ip bgp should show the OSPF routes as locally originated entries with origin ? and the configured metric:

Read-only / Safe
$ show ip bgp
BGP table version is 5, local router ID is 1.1.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
            r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

 Network          Next Hop            Metric LocPrf Weight Path
*> 10.10.0.0/16     10.0.1.2               100         32768 ?
*> 192.168.0.0/19   10.0.1.2               100         32768 ?

Illustrative output

Note the ? in the Path column (origin incomplete), the weight of 32768 that marks a locally originated path, and the Metric column carrying the MED the route-map set.

The feedback loop problem

The classic OSPF-BGP-OSPF feedback loop:

flowchart LR
  R1["R1\nBGP AS 64512\nOSPF area 0"]
  R2["R2\nBGP AS 64513\nOSPF area 0"]
  BGP["eBGP session\nR1 <-> R2"]

  R1 -- "redistribute ospf into BGP" --> BGP
  BGP -- "advertises 10.10.0.0/16" --> R2
  R2 -- "redistribute bgp into ospf" --> R1
  R1 -- "sees 10.10.0.0/16 as OSPF E2\n(competing with the internal route)" --> R1

The sequence:

  1. R1 has an OSPF-learned route 10.10.0.0/16 from an internal router.
  2. R1 redistributes the OSPF route into BGP and advertises it to R2.
  3. R2 receives the BGP route and (if R2 has redistribute bgp into OSPF) redistributes it back into OSPF as an external route.
  4. R1 sees the prefix in OSPF again, now as an E2 external route originated by R2.
  5. If the internal route ever goes away, the external version becomes the best OSPF path.
  6. R1’s BGP redistribution re-picks up the OSPF route — but now with a different metric, a different originator, and a dependency on R2 for a prefix R1 owns.

The loop is quiet while the internal route is healthy, which is exactly what makes it dangerous: it is armed long before it fires, and it fires during the outage that removed the internal route.

The fix is two-fold:

  1. Tag the routes on redistribution. When R1 redistributes OSPF into BGP, stamp a community. When R2 redistributes BGP back into OSPF, deny any route carrying it.

    # On R1 (origin side)
    set policy route-map OSPF-TO-BGP rule 10 action permit
    set policy route-map OSPF-TO-BGP rule 10 match ip address prefix-list INTERNAL-NETWORKS
    set policy route-map OSPF-TO-BGP rule 10 set community add 64512:400
    set protocols bgp address-family ipv4-unicast redistribute ospf route-map OSPF-TO-BGP
    
    # On R2 (receiving side)
    set policy community-list OSPF-FROM-R1 rule 10 action permit
    set policy community-list OSPF-FROM-R1 rule 10 regex 64512:400
    set policy route-map BGP-FILTER rule 10 action deny
    set policy route-map BGP-FILTER rule 10 match community community-list OSPF-FROM-R1
    set policy route-map BGP-FILTER rule 20 action permit
    set protocols ospf redistribute bgp route-map BGP-FILTER

    Note the 1.4/1.5 spellings: a community-list rule takes a regex, not a community, and a route-map matches community community-list <name> rather than naming the list directly.

    Rule 20 here is a deliberate catch-all permit, and it is correct in this route-map: the intent is “redistribute everything except my own routes coming back”, so everything that is not denied by rule 10 must be permitted. The same construct that ruined the allow-list in the previous section is the right answer in a deny-list. What matters is which one you meant to write.

  2. Or filter on the prefix set directly — deny the local AS’s own prefixes on the BGP-into-OSPF redistribution. This needs no cooperation from the far side and no community, but it needs the prefix list to be kept current.

Administrative-distance trap

The administrative distance (AD) preference between OSPF internal and OSPF external matters when a route is reachable via both.

SourceDefault AD in FRR
Connected0
Static1
eBGP20
OSPF (internal and external alike)110
iBGP200

FRR does not give OSPF external routes a distance of their own — every OSPF route carries 110 — so the choice between an internal and an external path for the same prefix is made inside ospfd by the OSPF path preference rules, not by AD. The intra-area path wins over the inter-area path, which wins over the external one. Only the winner is offered to zebra, so only the winner can be redistributed.

When the internal route disappears (the originating router goes away), the external version becomes the OSPF best path, gets installed in the RIB, and is redistributed into BGP in its place — with the external metric, which may be worse, and with R2 as the path to a prefix R1 owns. That is the moment the feedback loop stops being theoretical.

The fix: deny the redistributed-back version explicitly, by community or by prefix, so it never becomes a candidate.

Validation

# 1. The OSPF route is in the RIB
show ip route ospf

# 2. The route is in the BGP table with the right origin
show ip bgp 10.10.0.0/16

# 3. The route is advertised to the peer
show ip bgp neighbors 10.0.0.2 advertised-routes

# 4. The route-map is doing what you think
show route-map OSPF-TO-BGP
show ip prefix-list INTERNAL-NETWORKS

# 5. The feedback loop is not present (check the OSPF LSDB)
show ip ospf database external self-originate
show ip ospf database external

The ? in the Path column is the signature of a redistributed route. show route-map prints FRR’s view including a match counter per entry — an entry whose counter never moves is not matching what you think it matches, and that is usually faster evidence than reading the configuration again.

Failure modes

OSPF route is not advertised

show ip bgp 10.10.0.0/16 returns nothing. Diagnostic path:

  1. Is the OSPF route in the RIB? show ip route ospf. Redistribution reads the RIB, not the LSDB. A prefix that is in the OSPF database but lost the path selection to another source is not a candidate.
  2. Does the prefix-list permit it? show ip prefix-list INTERNAL-NETWORKS. Remember the implicit deny, and the ge/le bounds.
  3. Does the route-map permit it? show route-map OSPF-TO-BGP. Remember the implicit deny at the end.
  4. Is outbound policy blocking? show ip bgp neighbors 10.0.0.2 advertised-routes — the route may be in the Loc-RIB and filtered on the way out.

OSPF route is advertised but changes character

The prefix stops being served by the internal path and starts being served by the redistributed-back external one. The cause is the feedback loop through a peer that redistributes BGP into OSPF.

Diagnostic:

  • show ip ospf database external — if the prefix appears as a Type 5 LSA advertised by the far-side router, your route has come home.
  • show ip bgp 10.10.0.0/16 on the receiving side — if the route carries the community you stamp on redistribution, the loop is closed.
  • Compare the MED over time. A MED that moves without a configuration change is the IGP cost moving, or the loop.

Fix: tag the route on redistribution and deny the tag on re-redistribution.

MED is not what the operator expected

Causes, in the order worth checking:

  • No set metric anywhere, so the MED is the OSPF cost from the RIB — which is the default, not zero.
  • A metric leaf on the redistribute statement is overriding the zebra metric for every prefix uniformly.
  • A set metric in the route-map is overriding both, for the prefixes it matches.
  • The OSPF cost itself changed (a link flap, a cost edit) and the MED followed it, because nothing pinned it.

The fix: decide which of the three layers owns the MED, set it there, and leave the other two alone.

The route is advertised with origin i instead of ?

The operator expected incomplete (the default for redistribution) but the BGP table shows igp. The cause: a route-map on the redistribution, or on the outbound policy, explicitly sets origin igp. The fix: audit the route-map chain.

Rollback

# Remove the redistribution entirely
delete protocols bgp address-family ipv4-unicast redistribute ospf
commit

# Remove only the route-map (warning: this re-introduces the leak risk,
# because the bare redistribute statement has no filter at all)
delete protocols bgp address-family ipv4-unicast redistribute ospf route-map
commit

The rollback for a leaked OSPF route:

  1. Remove the redistribution.
  2. Audit which prefixes were leaked (compare the peer’s advertised-routes before and after).
  3. Notify the peer to withdraw the leaked prefixes.

A tested rollback is mandatory for production:

  • Know which OSPF routes are expected to be advertised.
  • Know which peer sessions will receive withdrawals.
  • Have a plan to revert OSPF changes if the redistribution change triggers OSPF instability.

Production discipline

Cross-course references

  • Part XIX (XIX-VyOS-OSPFConfig) covers the OSPF configuration that originates the routes being redistributed.
  • Part XXV-03 (XXV-VyOS-BGPAdvertise / redistribute static) is the analogous lesson for static routes.
  • Part XXVI (XXVI-VyOS-BGPAttributes) covers the MED attribute that this lesson sets.
  • Part XXXIII (XXXIII-VyOS-RoutePolicy) covers the route-map primitives used here.
  • Part XXXIV (XXXIV-VyOS-RouteRedistribution) covers redistribution in general, including the feedback loop and administrative-distance traps.

Quiz

Knowledge check · 4 questions

  1. Q1. An OSPF E2 external route with metric 50 is redistributed into BGP with `redistribute ospf` and no metric or route-map. What MED does the advertised route carry?

  2. Q2. The OSPF-BGP-OSPF feedback loop is a real production failure mode caused by unfiltered mutual redistribution between OSPF and BGP.

  3. Q3. R1 (AS 64512) has `redistribute ospf route-map OSPF-TO-BGP`. R2 (AS 64513) has `redistribute bgp route-map BGP-FILTER` into OSPF. The operator sees `10.10.0.0/16` in R1's OSPF database as a Type 5 LSA whose ASBR is R2, alongside R1's own internal path for the same prefix. What is happening, and why has nothing broken yet?

    R1's internal OSPF has 10.10.0.0/16 with cost 50. R1 redistributes it into BGP, where it picks up MED 50 from the RIB metric. R2 receives the BGP route and redistributes BGP into OSPF, originating a Type 5 LSA for 10.10.0.0/16 with R2 as the ASBR. R1 receives that LSA and files it in the LSDB. R1's own intra-area path still wins OSPF path selection, so the RIB and the BGP advertisement are unchanged.

  4. Q4. R1 redistributes OSPF into BGP through `OSPF-TO-BGP`, whose rule 10 matches prefix-list `INTERNAL-NETWORKS` (permitting only 10.10.0.0/16) and whose rule 100 is `action permit` with a description of 'catch-all' and no match clause. A new OSPF area starts advertising 172.16.0.0/16. Within minutes the peer reports 172.16.0.0/16 in their BGP table. Why?

    The prefix-list: set policy prefix-list INTERNAL-NETWORKS rule 10 action permit set policy prefix-list INTERNAL-NETWORKS rule 10 prefix 10.10.0.0/16 The route-map: set policy route-map OSPF-TO-BGP rule 10 action permit set policy route-map OSPF-TO-BGP rule 10 match ip address prefix-list INTERNAL-NETWORKS set policy route-map OSPF-TO-BGP rule 100 action permit set policy route-map OSPF-TO-BGP rule 100 description 'catch-all' A new OSPF area learns 172.16.0.0/16 and it lands in the RIB.

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