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

tests: add connected/recursive/duplicte/route-map NHG tests #6245

Merged
merged 1 commit into from
Apr 20, 2020
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
10 changes: 8 additions & 2 deletions tests/topotests/all-protocol-startup/r1/ipv4_routes.ref
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ C>* 192.168.8.0/26 is directly connected, r1-eth8, XX:XX:XX
C>* 192.168.9.0/26 is directly connected, r1-eth9, XX:XX:XX
O 192.168.0.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX
O 192.168.3.0/26 [110/10] is directly connected, r1-eth3, weight 1, XX:XX:XX
S>* 1.1.1.1/32 [1/0] is directly connected, r1-eth0, weight 1, XX:XX:XX
S>* 1.1.1.2/32 [1/0] is directly connected, r1-eth1, weight 1, XX:XX:XX
S>* 1.1.1.1/32 [1/0] is directly connected, r1-eth1, weight 1, XX:XX:XX
S>* 1.1.1.2/32 [1/0] is directly connected, r1-eth2, weight 1, XX:XX:XX
S>* 1.1.1.3/32 [1/0] is directly connected, r1-eth3, weight 1, XX:XX:XX
S>* 1.1.1.4/32 [1/0] is directly connected, r1-eth4, weight 1, XX:XX:XX
S>* 1.1.1.5/32 [1/0] is directly connected, r1-eth5, weight 1, XX:XX:XX
S>* 1.1.1.6/32 [1/0] is directly connected, r1-eth6, weight 1, XX:XX:XX
S>* 1.1.1.7/32 [1/0] is directly connected, r1-eth7, weight 1, XX:XX:XX
S>* 1.1.1.8/32 [1/0] is directly connected, r1-eth8, weight 1, XX:XX:XX
S>* 4.5.6.10/32 [1/0] via 192.168.0.2, r1-eth0, weight 1, XX:XX:XX
S>* 4.5.6.11/32 [1/0] via 192.168.0.2, r1-eth0, weight 1, XX:XX:XX
S>* 4.5.6.12/32 [1/0] is directly connected, r1-eth0, weight 1, XX:XX:XX
Expand Down
10 changes: 8 additions & 2 deletions tests/topotests/all-protocol-startup/r1/zebra.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ ipv6 route 4:5::6:12/128 r1-eth0
ip route 4.5.6.15/32 192.168.0.2 255
ipv6 route 4:5::6:15/128 fc00:0:0:0::2 255
# Routes to put into a nexthop-group
ip route 1.1.1.1/32 r1-eth0
ip route 1.1.1.2/32 r1-eth1
ip route 1.1.1.1/32 r1-eth1
ip route 1.1.1.2/32 r1-eth2
ip route 1.1.1.3/32 r1-eth3
ip route 1.1.1.4/32 r1-eth4
ip route 1.1.1.5/32 r1-eth5
ip route 1.1.1.6/32 r1-eth6
ip route 1.1.1.7/32 r1-eth7
ip route 1.1.1.8/32 r1-eth8

# Create a route that has overlapping distance
# so we have backups
Expand Down
181 changes: 169 additions & 12 deletions tests/topotests/all-protocol-startup/test_all_protocol_startup.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,35 @@ def test_converge_protocols():
# For debugging after starting FRR/Quagga daemons, uncomment the next line
## CLI(net)

def route_get_nhg_id(route_str):
output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str)
match = re.search(r"Nexthop Group ID: (\d+)", output)
assert match is not None, "Nexthop Group ID not found for sharpd route %s" % route_str

nhg_id = int(match.group(1))
return nhg_id

def verify_nexthop_group(nhg_id, recursive=False):
# Verify NHG is valid/installed
output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)

match = re.search(r"Valid", output)
assert match is not None, "Nexthop Group ID=%d not marked Valid" % nhg_id

# If recursive, we need to look at its resolved group
if recursive:
match = re.search(r"Depends: \((\d+)\)", output)
resolved_id = int(match.group(1))
verify_nexthop_group(resolved_id, False)
else:
match = re.search(r"Installed", output)
assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id

def verify_route_nexthop_group(route_str, recursive=False):
# Verify route and that zebra created NHGs for and they are valid/installed
nhg_id = route_get_nhg_id(route_str)
verify_nexthop_group(nhg_id, recursive)

def test_nexthop_groups():
global fatal_error
global net
Expand All @@ -358,25 +387,77 @@ def test_nexthop_groups():
print("\n\n** Verifying Nexthop Groups")
print("******************************************\n")

### Nexthop Group Tests

## Basic test

# Create a lib nexthop-group
net["r1"].cmd('vtysh -c "c t" -c "nexthop-group red" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')

# Create with sharpd using nexthop-group
net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group red 1"')
net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"')

# Verify route and that zebra created NHGs for and they are valid/installed
output = net["r1"].cmd('vtysh -c "show ip route 2.2.2.1/32 nexthop-group"')
match = re.search(r"Nexthop Group ID: (\d+)", output);
assert match is not None, "Nexthop Group ID not found for sharpd route 2.2.2.1/32"
verify_route_nexthop_group("2.2.2.1/32")

nhe_id = int(match.group(1))
## Connected

output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhe_id)
match = re.search(r"Valid", output)
assert match is not None, "Nexthop Group ID=%d not marked Valid" % nhe_id
net["r1"].cmd('vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"')

match = re.search(r"Installed", output)
assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhe_id
net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"')

verify_route_nexthop_group("2.2.2.2/32")

## Recursive

net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"')

net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"')

verify_route_nexthop_group("3.3.3.1/32", True)

## Duplicate

net["r1"].cmd('vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"')

net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"')

verify_route_nexthop_group("3.3.3.2/32")

## Two 4-Way ECMP

net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \
-c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"')

net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"')

verify_route_nexthop_group("4.4.4.1/32")

net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \
-c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"')

net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"')

verify_route_nexthop_group("4.4.4.2/32")

## Recursive to 8-Way ECMP

net["r1"].cmd('vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"')

net["r1"].cmd('vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"')

verify_route_nexthop_group("5.5.5.1/32")

##CLI(net)

## Remove all NHG routes

net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.1 1"')
net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.2 1"')
net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.1 1"')
net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.2 1"')
net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.1 1"')
net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"')
net["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"')

def test_rip_status():
global fatal_error
Expand Down Expand Up @@ -924,6 +1005,82 @@ def test_route_map():

assert failures == 0, "Show route-map command failed for router r%s:\n%s" % (i, diff)

def test_nexthop_groups_with_route_maps():
global fatal_error
global net

# Skip if previous fatal error condition is raised
if (fatal_error != ""):
pytest.skip(fatal_error)

print("\n\n** Verifying Nexthop Groups With Route-Maps")
print("******************************************\n")

### Nexthop Group With Route-Map Tests

# Create a lib nexthop-group
net["r1"].cmd('vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')

## Route-Map Proto Source

route_str = "2.2.2.1"
src_str = "192.168.0.1"

net["r1"].cmd('vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str)
net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"')

net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str)

verify_route_nexthop_group("%s/32" % route_str)

# Only a valid test on linux using nexthop objects
if sys.platform.startswith("linux"):
output = net["r1"].cmd('ip route show %s/32' % route_str)
match = re.search(r"src %s" % src_str, output)
assert match is not None, "Route %s/32 not installed with src %s" % (route_str, src_str)

# Remove NHG routes and route-map
net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str)
net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"')
net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str)
net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"')

## Route-Map Deny/Permit with same nexthop group

permit_route_str = "3.3.3.1"
deny_route_str = "3.3.3.2"

net["r1"].cmd('vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str)
net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"')
net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"')
net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"')

# This route should be permitted
net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str)

verify_route_nexthop_group("%s/32" % permit_route_str)

# This route should be denied
net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str)

nhg_id = route_get_nhg_id(deny_route_str)
output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)

match = re.search(r"Valid", output)
assert match is None, "Nexthop Group ID=%d should not be marked Valid" % nhg_id

match = re.search(r"Installed", output)
assert match is None, "Nexthop Group ID=%d should not be marked Installed" % nhg_id

# Remove NHG routes and route-map
net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % permit_route_str)
net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % deny_route_str)
net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NOPE"')
net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"')
net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"')
net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"')
net["r1"].cmd('vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str)

def test_mpls_interfaces():
global fatal_error
global net
Expand Down