Recently when I was just chilling and doing my labs for the JNCIE exam 😛 I faced an issue with the next-hop self policy. It may sound funny but such trivial aspect took me about 20 mins to figure it out.
For those of you who don’t know, such a policy is usually applied when an EBGP speaking router wants to advertise prefixes from its EBGP neighbor to its IBGP neighbors. Since by default, BGP does not change the next-hop of the prefix received from a EBGP neighbor, other IBGP routers will receive such prefix with the next-hop unchanged. It will result with the “unusable” state of this received prefix and in the end such prefix will not be installed in routing table. IBGP neighbor simply doesn’t know where the unchanged next-hop is. Applying the next-hop self policy forces to change this behaviour and changes the next-hop to “self” which is this particular advertising router address.
Another walkaround of this default behaviour is of course:
- advertising the p2p EBGP prefix into an IGP as passive
- export direct routes into IGP
- static routing, or
- enable IGP with EBGP peer – not recommended and honestly probably not often used method
But enough for the theory, let’s get to practice.
I have a couple of routers interconnected with each other, but for the sake of this blog we will focus on three of them.
R1 is an EBGP speaking router – AS65111
R2 is its EBGP neighbor – AS65000
R3 is IBGP router which has session to R2
Topology and addresses look like the below:
My initial state of the BGP and policy configuration looked like this:
On R1:
tomek@vMX_R1> show bgp summary Threading mode: BGP I/O Groups: 1 Peers: 2 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet6.0 1 1 0 0 0 0 inet.0 0 0 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 192.168.1.1 65000 249 251 0 1 1:51:38 Establ inet.0: 0/0/0/0 2001:db8:8000:4200::4 65000 249 249 0 3 1:51:27 Establ inet6.0: 1/1/1/0
So far so good. BGP sessions are established.
Let’s check whether we’re advertising anything to our EBGP neighbor which is the R2
tomek@vMX_R1> show route advertising-protocol bgp 192.168.1.1 inet.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 1.1.1.1/32 Self I * 23.0.0.0/22 Self I tomek@vMX_R1> show route advertising-protocol bgp 2001:db8:8000:4200::4 inet6.0: 11 destinations, 11 routes (11 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 2001:db1::1/128 Self I
Great!!! We’re advertising prefixes that we want.
Quick jump to R2:
tomek@vMX_R2> show bgp summary Threading mode: BGP I/O Groups: 3 Peers: 4 Down peers: 0 Table Tot Paths Act Paths Suppressed History Damp State Pending inet6.0 1 1 0 0 0 0 inet.0 2 2 0 0 0 0 Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped... 3.3.3.3 65000 255 259 0 0 1:54:24 Establ inet.0: 0/0/0/0 192.168.1.0 65111 257 253 0 0 1:54:33 2/2/2/0 0/0/0/0 2001:db8::3 65000 254 256 0 0 1:54:18 Establ inet6.0: 0/0/0/0 2001:db8:8000:4200::8 65111 256 254 0 0 1:54:22 Establ inet6.0: 1/1/1/0
This also looks fine. We have two sessions (v4 and v6) to our EBGP neighbor (R1) and two sessions to IBGP router (3.3.3.3 and 2001:db8::3 which are R3 v4 and v6 loopback addresses respectively advertised via IGP)
Let’s check whether we’re receiving anything from the R1
tomek@vMX_R2> show route receive-protocol bgp 192.168.1.0 inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 1.1.1.1/32 192.168.1.0 65111 I * 23.0.0.0/22 192.168.1.0 65111 I inet6.0: 18 destinations, 18 routes (18 active, 0 holddown, 0 hidden) tomek@vMX_R2> show route receive-protocol bgp 2001:db8:8000:4200::8 inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden) inet6.0: 18 destinations, 18 routes (18 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 2001:db1::1/128 2001:db8:8000:4200::8 65111 I
Ok. That looks good as well. So, we want to advertise those prefixes to the R3, but we also want to change the next-hop to self.
My initial policy and bgp configuration looked like this:
tomek@vMX_R2> show configuration protocols bgp group EBGP { neighbor 2001:db8:8000:4200::8 { authentication-key "$9$v5cMNVDjHP5zFnyeWL-dqmP"; ## SECRET-DATA export to-as65111; peer-as 65111; } neighbor 192.168.1.0 { authentication-key "$9$v5cMNVDjHP5zFnyeWL-dqmP"; ## SECRET-DATA peer-as 65111; } } group IBGP { type internal; export nhs; neighbor 2001:db8::3 { local-address 2001:db8::2; } neighbor 3.3.3.3 { local-address 2.2.2.2; } }
tomek@vMX_R2> show configuration policy-options policy-statement nhs term 1 { from protocol bgp; then { next-hop self; } } term 2 { then reject; }
Verification:
tomek@vMX_R2> show route advertising-protocol bgp 3.3.3.3 tomek@vMX_R2> show route advertising-protocol bgp 2001:db8::3
….and what the heck?!
Where are my prefixes? 🙂
This was my first bgp setup in a few months. I did not use it recently. But my policy seems to look fine.
Next-hop self action – check, finishing term – check. And I usually add it since the BGP tends to advertise everything from bgp by default.
But here is my MEMERROR() issue. It took me 20 mins to figure it out. I just forgot that the next-hop self will not do anything in my configuration.
The default policy for bgp is to export all prefixes received from bgp protocol. When my policy ends with reject statement, then there is no advertisement.
When I change my policy to:
tomek@vMX_R2> show configuration policy-options policy-statement nhs term 1 { from protocol bgp; then { next-hop self; accept; } } term 2 { then reject; }
Or remove the second term:
tomek@vMX_R2> show configuration policy-options policy-statement nhs term 1 { from protocol bgp; then { next-hop self; } }
All prefixes are properly advertised:
tomek@vMX_R2> show route advertising-protocol bgp 3.3.3.3 inet.0: 17 destinations, 17 routes (17 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 1.1.1.1/32 Self 100 65111 I * 23.0.0.0/22 Self 100 65111 I tomek@vMX_R2> show route advertising-protocol bgp 2001:db8::3 inet6.0: 18 destinations, 18 routes (18 active, 0 holddown, 0 hidden) Prefix Nexthop MED Lclpref AS path * 2001:db1::1/128 Self 100 65111 I
When I only have one term with the next-hop self, then the finishing action is “accept”, which is a default policy in bgp. I’m writing this because you can often see an example of next-hop self policy as just: next-hop self. And if you won’t remember of a default bgp policy you can stuck debugging as I was.
So, remember those wise words kids. Next-hop self is NOT a terminating (or rather flow control) action. It just changes the route characteristics.
And lastly a quick Route Reflector next-hop self consideration.
Applying next-hop self policy on a RR can be tricky, since you can end up with suboptimal routing in your network. But what to do when you RR is also injecting EBGP routes to your AS?
Just limit your NHS policy to the EBGP neighbor or interface for example:
[edit policy-options policy-statement restricted-nhs] user@router# show term only-from-EBGP { from { protocol bgp; neighbor <your EBGP neighbor address>; } then { next-hop self; } }