Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion netsim/extra/bgp.session/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from box import Box, BoxList

from netsim import api, modules
from netsim.data import append_to_list
from netsim.data import append_to_list, get_box
from netsim.utils import log
from netsim.utils import routing as _bgp

Expand Down Expand Up @@ -156,6 +156,52 @@ def process_bfd_requests(ndata: Box, topology: Box) -> None:
log.IncorrectValue,
_config_name)

'''
Check whether a node originating a default route needs static default route(s)
'''
BGP_DEFAULT = {
'ipv4': { 'ipv4': '0.0.0.0/0', 'floating': True, 'nexthop.discard': True },
'ipv6': { 'ipv6': '::/0', 'floating': True, 'nexthop.discard': True }}

def process_default_requests(ndata: Box, topology: Box) -> None:
if _bgp.get_device_bgp_feature('default_originate',ndata,topology) != 'static':
return # The node does not need static routes to originate default

for ngb in _bgp.neighbors(ndata):
if not 'default_originate' in ngb: # Does the neighbor need a BGP default route?
continue # Nope? Cool

route_list = [ # Find relevant static routes based on neighbor AFs
BGP_DEFAULT[af] for af in log.AF_LIST if af in ngb
]
if not route_list:
continue

append_to_list(ndata,'module','routing') # Activate the routing module in the node
append_to_list(topology,'module','routing') # ... assuming the developer setting BGP features was sane ;)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hope this doesn't activate the routing module on all nodes in the topology?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course not. This is done late in the process (well after the topology.module is copied into node.module). The same two calls are used to add static routes to hosts.


# Get VRF (or global) data and its static routes
#
vrf_data = ndata.vrfs[ngb._src_vrf] if '_src_vrf' in ngb else ndata
vrf_routes = vrf_data.get('routing.static',[])

for sr_data in route_list: # Iterate over routes that have to be added
for af in log.AF_LIST: # We have to check all AFs
if af not in sr_data: # Is this AF relevant for the current entry?
continue

# Get existing route(s) where the AF prefix matches what we need
have_routes = [ r for r in vrf_routes if af in r and r[af] == sr_data[af] ]
if have_routes: # Did the user specify their own default route(s)?
continue # Cool, nothing to do ;)

# No per-AF default route in the target VRF yet, add it
#
sr_final = sr_data # Assume we can use the static route data as-is
if '_src_vrf' in ngb: # But if we have a VRF neighbor, we have to add VRF info
sr_final = get_box({'nexthop': {'vrf': ngb._src_vrf}}) + sr_data
append_to_list(ndata,'routing.static',sr_final)

'''
Zap a BGP neighbor: remove all usable IP addresses, local_if and ifindex
'''
Expand Down Expand Up @@ -288,6 +334,7 @@ def post_transform(topology: Box) -> None:
copy_local_attributes(ndata,topology)
process_tcpao_secrets(ndata,topology)
process_bfd_requests(ndata,topology)
process_default_requests(ndata,topology)
have_rs = process_rs_requests(ndata,topology) or have_rs

# We need to do the RS-related EBGP session cleanup in a second pass
Expand Down
Loading