BGP – RR next hop resolution
1. Intro
We have a small service provider with an small MPLS network with a couple of L3VPNs.

What matters here is the RR configuration:
### R3 config:
root@R2# show protocols | display set
set protocols bgp group iBGP type internal
set protocols bgp group iBGP local-address 17.0.0.2
set protocols bgp group iBGP family inet labeled-unicast
set protocols bgp group iBGP family inet unicast
set protocols bgp group iBGP family inet-vpn unicast
set protocols bgp group iBGP cluster 17.0.0.2
set protocols bgp group iBGP neighbor 17.0.0.1
set protocols bgp group iBGP neighbor 17.0.0.4
set protocols ldp track-igp-metric
set protocols ldp transport-address router-id
set protocols ldp interface ge-0/0/2.0
set protocols ldp interface lo0.0
set protocols mpls interface lo0.0
set protocols mpls interface ge-0/0/2.0
set protocols ospf traffic-engineering
set protocols ospf area 0.0.0.0 interface lo0.0 passive
set protocols ospf area 0.0.0.0 interface ge-0/0/2.0 interface-type p2p
set protocols ospf area 0.0.0.0 interface ge-0/0/2.0 metric 1000
### On the RR router we can see prefixes for our two L3VPNs:
root@R2# run show route table bgp.l3vpn.0
bgp.l3vpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
64512:1:192.45.6.1/32
*[BGP/170] 00:30:57, localpref 100, from 17.0.0.1
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 16, Push 299808(top)
64512:1:192.45.6.4/32
*[BGP/170] 00:26:00, localpref 100, from 17.0.0.4
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 16, Push 299792(top)
64512:8:192.88.0.1/32
*[BGP/170] 00:28:55, localpref 100, from 17.0.0.1
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 17, Push 299808(top)
64512:8:192.88.0.4/32
*[BGP/170] 00:26:00, localpref 100, from 17.0.0.4
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 17, Push 299792(top)
### The inet.3 table:
root@R2# run show route table inet.3
inet.3: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
17.0.0.1/32 *[LDP/9] 00:00:06, metric 2000
> to 17.8.8.2 via ge-0/0/2.0, Push 299808
17.0.0.3/32 *[LDP/9] 00:00:06, metric 1000
> to 17.8.8.2 via ge-0/0/2.0
17.0.0.4/32 *[LDP/9] 00:00:06, metric 2000
> to 17.8.8.2 via ge-0/0/2.0, Push 299792
RR2 will not forward traffic, so we are being asked to remove the LDP configuration. But this will immediately create problems, next hop resolution is no longer working:
root@R2# show | compare
[edit protocols]
- ldp {
- track-igp-metric;
- transport-address router-id;
- interface ge-0/0/2.0;
- interface lo0.0;
- }
[edit]
root@R2# commit
commit complete
### The prefixes are now hidden:
root@R2# run show route table bgp.l3vpn.0
bgp.l3vpn.0: 4 destinations, 4 routes (0 active, 0 holddown, 4 hidden)
### The problem is there is no more next-hop resolution in inet.3:
root@R2# run show route table bgp.l3vpn.0 hidden rd-prefix 64512:1:192.45.6.1/32 extensive
bgp.l3vpn.0: 4 destinations, 4 routes (0 active, 0 holddown, 4 hidden)
64512:1:192.45.6.1/32 (1 entry, 0 announced)
BGP Preference: 170/-101
Route Distinguisher: 64512:1
Next hop type: Unusable, Next hop index: 0
Address: 0x7bbd5b4
Next-hop reference count: 4, key opaque handle: 0x0, non-key opaque handle: 0x0
Kernel Table Id: 0
Source: 17.0.0.1
State: <Hidden Int Ext ProtectionPath ProtectionCand>
Local AS: 100 Peer AS: 100
Age: 35
Validation State: unverified
Task: BGP_100.17.0.0.1
AS path: I
Communities: target:64512:456
Accepted
VPN Label: 16
Localpref: 100
Router ID: 17.0.0.1
Thread: junos-main
Indirect next hops: 1
Protocol next hop: 17.0.0.1 ResolvState: PnhUnresolv
Label operation: Push 16
Label TTL action: prop-ttl
Load balance label: Label 16: None;
Indirect next hop: 0x0 - INH Session ID: 0
### The inet.3 table is empty because LDP is missing:
root@R2# run show route table inet.3
[edit]
root@R2#
In the next sections we will explore a few ways to fix this.
2. Resolution Ribs
Not the preferred solution, but we can tell the router to use inet.0 for BGP next-hop resolution:
root@R2# set routing-options resolution rib bgp.l3vpn.0 resolution-ribs inet.0
[edit]
root@R2# show | compare
[edit routing-options]
+ resolution {
+ rib bgp.l3vpn.0 {
+ resolution-ribs inet.0;
+ }
+ }
[edit]
root@R2# commit
commit complete
### Prefixes are not valid:
root@R2# run show route table bgp.l3vpn.0
bgp.l3vpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
64512:1:192.45.6.1/32
*[BGP/170] 00:00:04, localpref 100, from 17.0.0.1
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 16
64512:1:192.45.6.4/32
*[BGP/170] 00:00:04, localpref 100, from 17.0.0.4
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 16
64512:8:192.88.0.1/32
*[BGP/170] 00:00:04, localpref 100, from 17.0.0.1
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 17
64512:8:192.88.0.4/32
*[BGP/170] 00:00:04, localpref 100, from 17.0.0.4
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 17
root@R2# run show route table inet.3
### We can see the next hop is resolved in inet.0:
root@R2# run show route table bgp.l3vpn.0 rd-prefix 64512:1:192.45.6.1/32 extensive
bgp.l3vpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
64512:1:192.45.6.1/32 (1 entry, 1 announced)
TSI:
Page 0 idx 0, (group iBGP type Internal) Type 1 val 0x9f2b500 (adv_entry)
Advertised metrics:
Nexthop: 17.0.0.1
Localpref: 100
AS path: [100] I
Communities: target:64512:456
Cluster ID: 17.0.0.2
Originator ID: 17.0.0.1
VPN Label: 16
Advertise: 00000002
Path 64512:1:192.45.6.1
from 17.0.0.1
Vector len 4. Val: 0
*BGP Preference: 170/-101
Route Distinguisher: 64512:1
Next hop type: Indirect, Next hop index: 0
Address: 0x7bbec04
Next-hop reference count: 1, key opaque handle: 0x0, non-key opaque handle: 0x0
Kernel Table Id: 0
Source: 17.0.0.1
Protocol next hop: 17.0.0.1
Label operation: Push 16
Label TTL action: prop-ttl
Load balance label: Label 16: None;
Indirect next hop: 0x2 no-forward INH Session ID: 0
State: <Active Int Ext ProtectionPath ProtectionCand>
Local AS: 100 Peer AS: 100
Age: 3:03 Metric2: 2000
Validation State: unverified
Task: BGP_100.17.0.0.1
Announcement bits (1): 0-BGP_RT_Background
AS path: I
Communities: target:64512:456
Accepted
VPN Label: 16
Localpref: 100
Router ID: 17.0.0.1
Thread: junos-main
Indirect next hops: 1
Protocol next hop: 17.0.0.1 Metric: 2000 ResolvState: Resolved
Label operation: Push 16
Label TTL action: prop-ttl
Load balance label: Label 16: None;
Indirect next hop: 0x2 no-forward INH Session ID: 0
Indirect path forwarding next hops: 1
Next hop type: Router
Next hop: 17.8.8.2 via ge-0/0/2.0
Session Id: 0
17.0.0.1/32 Originating RIB: inet.0
Metric: 2000 Node path count: 1
Forwarding nexthops: 1
Next hop type: Router
Next hop: 17.8.8.2 via ge-0/0/2.0
Session Id: 140
3. RIB Groups
A more preferred solution is to use a RIB Group to copy the prefixes from inet.0 to inet.3. Once the prefixes are installed in the inet.3 table, then the BGP resolution will work and prefixes will be valid:
### Delete the previous solution and use rib-groups instead:
delete routing-options resolution
set routing-options rib-groups RIB-BGP-NH import-rib inet.0
set routing-options rib-groups RIB-BGP-NH import-rib inet.3
set routing-options rib-groups RIB-BGP-NH import-policy PS-BGP-NH
set policy-options policy-statement PS-BGP-NH term 1 from route-filter 17.0.0.0/24 prefix-length-range /32-/32
set policy-options policy-statement PS-BGP-NH term 1 then accept
set policy-options policy-statement PS-BGP-NH term DENY then reject
set protocols ospf rib-group RIB-BGP-NH
root@R2# show | compare
[edit policy-options]
+ policy-statement PS-BGP-NH {
+ term 1 {
+ from {
+ route-filter 17.0.0.0/24 prefix-length-range /32-/32;
+ }
+ then accept;
+ }
+ term DENY {
+ then reject;
+ }
+ }
[edit routing-options]
- resolution {
- rib bgp.l3vpn.0 {
- resolution-ribs inet.0;
- }
- }
[edit routing-options rib-groups]
RIB-GLOBAL { ... }
+ RIB-BGP-NH {
+ import-rib [ inet.0 inet.3 ];
+ import-policy PS-BGP-NH;
+ }
[edit protocols ospf]
+ rib-group RIB-BGP-NH;
[edit]
root@R2# commit
commit complete
### We have the next-hops in the inet.3 table:
root@R2# run show route table inet.3
inet.3: 3 destinations, 3 routes (3 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
17.0.0.1/32 *[OSPF/10] 00:00:04, metric 2000
> to 17.8.8.2 via ge-0/0/2.0
17.0.0.3/32 *[OSPF/10] 00:00:04, metric 1000
> to 17.8.8.2 via ge-0/0/2.0
17.0.0.4/32 *[OSPF/10] 00:00:04, metric 2000
> to 17.8.8.2 via ge-0/0/2.0
### BGP prefixes are valid again:
root@R2# run show route table bgp.l3vpn.0
bgp.l3vpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
64512:1:192.45.6.1/32
*[BGP/170] 00:01:49, localpref 100, from 17.0.0.1
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 16
64512:1:192.45.6.4/32
*[BGP/170] 00:01:49, localpref 100, from 17.0.0.4
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 16
64512:8:192.88.0.1/32
*[BGP/170] 00:01:49, localpref 100, from 17.0.0.1
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 17
64512:8:192.88.0.4/32
*[BGP/170] 00:01:49, localpref 100, from 17.0.0.4
AS path: I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 17
root@R2# run show route table bgp.l3vpn.0 rd-prefix 64512:1:192.45.6.1/32 extensive
bgp.l3vpn.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
64512:1:192.45.6.1/32 (1 entry, 1 announced)
TSI:
Page 0 idx 0, (group iBGP type Internal) Type 1 val 0x9f2b500 (adv_entry)
Advertised metrics:
Nexthop: 17.0.0.1
Localpref: 100
AS path: [100] I
Communities: target:64512:456
Cluster ID: 17.0.0.2
Originator ID: 17.0.0.1
VPN Label: 16
Advertise: 00000002
Path 64512:1:192.45.6.1
from 17.0.0.1
Vector len 4. Val: 0
*BGP Preference: 170/-101
Route Distinguisher: 64512:1
Next hop type: Indirect, Next hop index: 0
Address: 0x7bbeb24
Next-hop reference count: 1, key opaque handle: 0x0, non-key opaque handle: 0x0
Kernel Table Id: 0
Source: 17.0.0.1
Protocol next hop: 17.0.0.1
Label operation: Push 16
Label TTL action: prop-ttl
Load balance label: Label 16: None;
Indirect next hop: 0x2 no-forward INH Session ID: 0
State: <Active Int Ext ProtectionPath ProtectionCand>
Local AS: 100 Peer AS: 100
Age: 1:56 Metric2: 2000
Validation State: unverified
Task: BGP_100.17.0.0.1
Announcement bits (1): 0-BGP_RT_Background
AS path: I
Communities: target:64512:456
Accepted
VPN Label: 16
Localpref: 100
Router ID: 17.0.0.1
Thread: junos-main
Indirect next hops: 1
Protocol next hop: 17.0.0.1 Metric: 2000 ResolvState: Resolved
Label operation: Push 16
Label TTL action: prop-ttl
Load balance label: Label 16: None;
Indirect next hop: 0x2 no-forward INH Session ID: 0
Indirect path forwarding next hops: 1
Next hop type: Router
Next hop: 17.8.8.2 via ge-0/0/2.0
Session Id: 0
17.0.0.1/32 Originating RIB: inet.3
Metric: 2000 Node path count: 1
Forwarding nexthops: 1
Next hop type: Router
Next hop: 17.8.8.2 via ge-0/0/2.0
Session Id: 140
4. resolve-vpn
Now, same Route Reflector, but via family inet labeled-unicast we are receiving the 17.0.0.8/32 prefix which is installed in inet.0. We need this also in inet.3 to be used for BGP next-hop resolution (Option C like setup).
It is true that we could use a RIB Group again, but we will show a different solution instead, resolve-vpn:
### The 17.0.0.8/32 prefix is installed only in inet.0
root@R2# run show route 17.0.0.8
inet.0: 29 destinations, 29 routes (29 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
17.0.0.8/32 *[BGP/170] 00:02:44, MED 2000, localpref 100, from 17.0.0.4
AS path: 200 I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 300928
### Use the 'resolve-vpn' option:
root@R2# show | compare
[edit protocols bgp group iBGP family inet labeled-unicast]
+ resolve-vpn;
[edit]
root@R2# commit
commit complete
### Now the 17.0.0.8 was copied from inet.0 to inet.3:
root@R2# run show route 17.0.0.8
inet.0: 29 destinations, 29 routes (29 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
17.0.0.8/32 *[BGP/170] 00:07:12, MED 2000, localpref 100, from 17.0.0.4
AS path: 200 I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 300928
inet.3: 7 destinations, 7 routes (7 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
17.0.0.8/32 *[BGP/170] 00:00:02, MED 2000, localpref 100, from 17.0.0.4
AS path: 200 I, validation-state: unverified
> to 17.8.8.2 via ge-0/0/2.0, Push 300928
External Resources: