Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSPF Test Cases #12647

Merged
merged 16 commits into from
Jun 10, 2024
Merged
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
64 changes: 64 additions & 0 deletions tests/ospf/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
'''
Conftest file for OSPF tests
'''

import pytest
import re
from tests.common.config_reload import config_reload
Expand Down Expand Up @@ -73,3 +77,63 @@ def get_ospf_neighbor_interface(host):
':')[1] # Return the interface name
# Return None if interface name is not found or not PortChannels.
return nbr_int_info


@pytest.fixture(scope='module')
def ospf_setup(duthosts, rand_one_dut_hostname, nbrhosts, tbinfo, request):

# verify neighbors are type sonic
if request.config.getoption("neighbor_type") != "sonic":
pytest.skip("Neighbor type must be sonic")

duthost = duthosts[rand_one_dut_hostname]

setup_info = {'nbr_addr': {}, 'bgp_routes': []}

mg_facts = duthost.get_extended_minigraph_facts(tbinfo)

for bgp_nbr in mg_facts['minigraph_bgp']:
setup_info['nbr_addr'][bgp_nbr['name']] = bgp_nbr['addr']

# gather original BGP routes
cmd = "show ip route bgp"
bgp_routes = duthost.shell(cmd)['stdout']
bgp_routes_pattern = re.compile(r'B>\*(\d+\.\d+\.\d+\.\d+/\d+)')
original_prefixes = bgp_routes_pattern.findall(bgp_routes).sort()
setup_info['bgp_routes'] = original_prefixes

for neigh_name in list(nbrhosts.keys()):
ip_addr = None
asn = None
neigh_mg_facts = nbrhosts[neigh_name]["host"].minigraph_facts(host=nbrhosts[neigh_name]["host"].hostname)
for neigh_bgp_nbr in neigh_mg_facts['minigraph_bgp']:
if neigh_bgp_nbr['name'] == duthost.hostname:
ip_addr = neigh_bgp_nbr['addr']
asn = neigh_bgp_nbr['asn']
break
cmd_list = [
'docker exec -it bgp bash',
'cd /usr/lib/frr',
'./ospfd &',
'exit',
'vtysh',
'config t',
'router bgp',
'no neighbor {} remote-as {}'.format(str(ip_addr), str(asn)),
'exit',
'router ospf',
'network {}/31 area 0'.format(str(ip_addr)),
'redistribute bgp',
'do write',
'end',
'exit'
]
nbrhosts[neigh_name]["host"].shell_cmds(cmd_list)

yield setup_info

# restore config to original state on both DUT and neighbor
config_reload(duthost, safe_reload=True)
time.sleep(10)
for neigh_name in list(nbrhosts.keys()):
config_reload(nbrhosts[neigh_name]["host"], is_dut=False)
144 changes: 144 additions & 0 deletions tests/ospf/test_ospf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import pytest
import logging
import time
import re

logger = logging.getLogger(__name__)

pytestmark = [
pytest.mark.topology('t0')
]


def test_ospf_neighborship(ospf_setup, duthosts, rand_one_dut_hostname):
setup_info_nbr_addr = ospf_setup['nbr_addr']
neigh_ip_addrs = list(setup_info_nbr_addr.values())
duthost = duthosts[rand_one_dut_hostname]

# Check get existing bgp routes on the DUT
original_prefixes = ospf_setup['bgp_routes']

# Configure OSPF neighbors in DUT if not already configured
ospf_configured = False
cmd = 'vtysh -c "show ip ospf neighbor"'
ospf_neighbors = duthost.shell(cmd)['stdout'].split("\n")
for neighbor in ospf_neighbors:
if ("ospfd is not running" not in neighbor) and (neighbor != "") and ("Neighbor ID" not in neighbor):
ospf_configured = True

if not ospf_configured:
cmd_list = [
'docker exec -it bgp bash',
'cd /usr/lib/frr',
'./ospfd &',
'exit',
'vtysh',
'config t',
'no router bgp',
'router ospf'
]

for ip_addr in neigh_ip_addrs:
cmd_list.append('network {}/31 area 0'.format(str(ip_addr)))

cmd_list.extend([
'do write',
'end',
'exit'
])

duthost.shell_cmds(cmd_list)
time.sleep(5)

# Verify old BGP routes are available as OSPF routes in the DUT
cmd = 'vtysh -c "show ip ospf neighbor"'
ospf_neighbors = duthost.shell(cmd)['stdout'].split("\n")
for neighbor in ospf_neighbors:
if (neighbor != "") and ("Neighbor ID" not in neighbor):
assert "Full" in neighbor

# Compare new OSPF prefixes with old BGP prefixes
cmd = "show ip route ospf"
ospf_routes = duthost.shell(cmd)['stdout']
ospf_routes_pattern = re.compile(r'O>\*(\d+\.\d+\.\d+\.\d+/\d+)')
new_prefixes = ospf_routes_pattern.findall(ospf_routes).sort()

assert original_prefixes == new_prefixes


def test_ospf_dynamic_routing(ospf_setup, duthosts, rand_one_dut_hostname, nbrhosts):
setup_info_nbr_addr = ospf_setup['nbr_addr']
neigh_ip_addrs = list(setup_info_nbr_addr.values())
duthost = duthosts[rand_one_dut_hostname]

# Add loopback interface in the first neighboring device
first_nbr = list(nbrhosts.keys())[0]
loopback_cmd = "config interface ip add Loopback10 192.168.10.1/32"
nbrhosts[first_nbr]["host"].shell(loopback_cmd)

# Advertise newly created loopback network to the DUT via OSPF
advertise_network_cmd = "vtysh -c 'config terminal' -c 'router ospf' -c 'network 192.168.10.1/32 area 0'"
nbrhosts[first_nbr]["host"].shell(advertise_network_cmd)

# Check OSPF already configured in DUT
ospf_configured = False
cmd = 'vtysh -c "show ip ospf neighbor"'
ospf_neighbors = duthost.shell(cmd)['stdout'].split("\n")
for neighbor in ospf_neighbors:
if ("ospfd is not running" not in neighbor) and (neighbor != "") and ("Neighbor ID" not in neighbor):
ospf_configured = True

# Configure OSPF neighbors in DUT if not already configured
if not ospf_configured:
cmd_list = [
'docker exec -it bgp bash',
'cd /usr/lib/frr',
'./ospfd &',
'exit',
'vtysh',
'config t',
'no router bgp',
'router ospf'
]

for ip_addr in neigh_ip_addrs:
cmd_list.append('network {}/31 area 0'.format(str(ip_addr)))

cmd_list.extend([
'do write',
'end',
'exit'
])

duthost.shell_cmds(cmd_list)
time.sleep(5)

# Verify OSPF neighborship successfully established and loopback route shared to the DUT
cmd = 'vtysh -c "show ip ospf neighbor"'
ospf_neighbors = duthost.shell(cmd)['stdout'].split("\n")
for neighbor in ospf_neighbors:
if (neighbor != "") and ("Neighbor ID" not in neighbor):
assert "Full" in neighbor
route_found = False
cmd = 'show ip route ospf'
ospf_routes = duthost.shell(cmd)['stdout'].split("\n")
for route in ospf_routes:
if '192.168.10.1/32' in route:
route_found = True
break
assert route_found is True

# Simulate link down by removing loopback interface from neighbor
rem_loopback_cmd = "config interface ip remove Loopback10 192.168.10.1/32"
nbrhosts[first_nbr]["host"].shell(rem_loopback_cmd)
time.sleep(5)

# Verify that loopback route is not present in DUT
route_found = False
cmd = 'show ip route ospf'
ospf_routes = duthost.shell(cmd)['stdout'].split("\n")
for route in ospf_routes:
if '192.168.10.1/32' in route:
route_found = True
break
assert route_found is False
Loading