Skip to content

Commit 0a41049

Browse files
committed
A router with localas_ibgp session MUST change NH on all IBGP routes
The routes received over localas_ibgp session have to be reflected to other IBGP neighbors. The next hop on those reflected routes MUST be changed because we're not advertising the inter-AS subnet into IGP. That makes the router with localas_ibgp session unsuitable to be a RR. This change adds an extra step after the IBGP and EBGP sessions have been built. It checks for the presence of localas_ibgp session and sets neighbor.next_hop_self to 'all' on all IBGP sessions if needed.
1 parent a9c7d71 commit 0a41049

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

netsim/modules/bgp.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,33 @@ def build_ebgp_sessions(node: Box, sessions: Box, topology: Box) -> None:
398398
else: # Global neighbor
399399
data.append_to_list(node.bgp,'neighbors',ebgp_data)
400400

401+
"""
402+
localas_ibgp_nhs_fixup: Set 'next_hop_self' to 'all' on IBGP neighbors if a router
403+
has at least one 'localas_ibgp' session. Also, a router with 'localas_ibgp' session
404+
SHOULD NOT be a route reflector.
405+
406+
See https://blog.ipspace.net/2025/08/ibgp-local-as-rr/ (after August 29th 2025) for details
407+
"""
408+
def localas_ibgp_nhs_fixup(node: Box,topology: Box) -> None:
409+
ngb_list = node.bgp.get('neighbors',None)
410+
if not ngb_list: # No neighbors, no worries ;)
411+
return
412+
413+
localas_ibgp_list = [ ngb for ngb in ngb_list if ngb.type == 'localas_ibgp' ]
414+
if not localas_ibgp_list: # No localas_ibgp sessions, no worries
415+
return
416+
417+
for ngb in ngb_list: # We have at least one localas_ibgp session
418+
if ngb.type != 'ibgp': # Now we have to iterate over all true IBGP neighbors
419+
continue
420+
ngb.next_hop_self = 'all' # And enable next-hop-self on all routes
421+
422+
if node.get('bgp.rr',None):
423+
log.warning(
424+
text='{node.name} has a local-as IBGP session and SHOULD NOT be a route reflector',
425+
module='bgp',
426+
flag='localas_ibgp_rr')
427+
401428
"""
402429
activate_bgp_default_af -- activate default AF on IPv4 and/or IPv6 transport sessions
403430
@@ -468,6 +495,7 @@ def build_bgp_sessions(node: Box, topology: Box) -> None:
468495

469496
build_ibgp_sessions(node,bgp_sessions,topology)
470497
build_ebgp_sessions(node,bgp_sessions,topology)
498+
localas_ibgp_nhs_fixup(node,topology)
471499

472500
# Calculate BGP address families
473501
#

0 commit comments

Comments
 (0)