-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15285 from idryzhov/staticd-nexthop-refcounter
staticd: fix nexthop tracking memory leak and add a topotest for VRFs
- Loading branch information
Showing
6 changed files
with
175 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
interface r1-eth0 vrf red | ||
ip address 192.0.2.1/23 | ||
exit | ||
|
||
interface r1-eth1 vrf blue | ||
ip address 192.0.2.129/24 | ||
exit | ||
|
||
ip route 198.51.100.1/32 192.0.2.2 nexthop-vrf red | ||
ip route 198.51.100.1/32 192.0.2.130 nexthop-vrf blue | ||
ip route 198.51.100.2/32 r1-eth0 nexthop-vrf red | ||
ip route 198.51.100.2/32 r1-eth1 nexthop-vrf blue | ||
|
||
ip route 203.0.113.1/32 192.0.2.130 vrf red nexthop-vrf blue | ||
ip route 203.0.113.2/32 r1-eth1 vrf red nexthop-vrf blue | ||
|
||
ip route 203.0.113.129/32 192.0.2.2 vrf blue nexthop-vrf red | ||
ip route 203.0.113.130/32 r1-eth0 vrf blue nexthop-vrf red |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 eval: (blacken-mode 1) -*- | ||
# SPDX-License-Identifier: ISC | ||
# | ||
# Copyright (c) 2024 NFWare Inc. | ||
# | ||
# noqa: E501 | ||
# | ||
""" | ||
Test static route functionality | ||
""" | ||
|
||
import ipaddress | ||
|
||
import pytest | ||
from lib.topogen import Topogen | ||
from lib.common_config import retry | ||
|
||
pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd] | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def tgen(request): | ||
"Setup/Teardown the environment and provide tgen argument to tests" | ||
|
||
topodef = {"s1": ("r1",), "s2": ("r1",)} | ||
|
||
tgen = Topogen(topodef, request.module.__name__) | ||
tgen.start_topology() | ||
|
||
router_list = tgen.routers() | ||
for rname, router in router_list.items(): | ||
# Setup VRF red | ||
router.net.add_l3vrf("red", 10) | ||
router.net.attach_iface_to_l3vrf(rname + "-eth0", "red") | ||
# Setup VRF blue | ||
router.net.add_l3vrf("blue", 20) | ||
router.net.attach_iface_to_l3vrf(rname + "-eth1", "blue") | ||
# Load configuration | ||
router.load_frr_config("frr.conf") | ||
|
||
tgen.start_router() | ||
yield tgen | ||
tgen.stop_topology() | ||
|
||
|
||
@retry(retry_timeout=1, initial_wait=0.1) | ||
def check_kernel(r1, prefix, nexthops, vrf, expected_p=True, expected_nh=True): | ||
vrfstr = f" vrf {vrf}" if vrf else "" | ||
|
||
net = ipaddress.ip_network(prefix) | ||
if net.version == 6: | ||
kernel = r1.run(f"ip -6 route show{vrfstr} {prefix}") | ||
else: | ||
kernel = r1.run(f"ip -4 route show{vrfstr} {prefix}") | ||
|
||
if expected_p: | ||
assert prefix in kernel, f"Failed to find \n'{prefix}'\n in \n'{kernel:.1920}'" | ||
else: | ||
assert ( | ||
prefix not in kernel | ||
), f"Failed found \n'{prefix}'\n in \n'{kernel:.1920}'" | ||
|
||
if not expected_p: | ||
return | ||
|
||
for nh in nexthops: | ||
if expected_nh: | ||
assert f"{nh}" in kernel, f"Failed to find \n'{nh}'\n in \n'{kernel:.1920}'" | ||
else: | ||
assert ( | ||
f"{nh}" not in kernel | ||
), f"Failed found \n'{nh}'\n in \n'{kernel:.1920}'" | ||
|
||
|
||
def test_static_vrf(tgen): | ||
if tgen.routers_have_failure(): | ||
pytest.skip(tgen.errors) | ||
|
||
r1 = tgen.gears["r1"] | ||
|
||
# Check initial configuration | ||
check_kernel(r1, "198.51.100.1", ["192.0.2.2", "192.0.2.130"], None) | ||
check_kernel(r1, "198.51.100.2", ["r1-eth0", "r1-eth1"], None) | ||
check_kernel(r1, "203.0.113.1", ["192.0.2.130"], "red") | ||
check_kernel(r1, "203.0.113.2", ["r1-eth1"], "red") | ||
check_kernel(r1, "203.0.113.129", ["192.0.2.2"], "blue") | ||
check_kernel(r1, "203.0.113.130", ["r1-eth0"], "blue") | ||
|
||
# Delete VRF red | ||
r1.net.del_iface("red") | ||
|
||
# Check that "red" nexthops are removed, "blue" nexthops are still there | ||
check_kernel(r1, "198.51.100.1", ["192.0.2.2"], None, expected_nh=False) | ||
check_kernel(r1, "198.51.100.1", ["192.0.2.130"], None) | ||
check_kernel(r1, "198.51.100.2", ["r1-eth0"], None, expected_nh=False) | ||
check_kernel(r1, "198.51.100.2", ["r1-eth1"], None) | ||
check_kernel(r1, "203.0.113.129", ["192.0.2.2"], "blue", expected_p=False) | ||
check_kernel(r1, "203.0.113.130", ["r1-eth0"], "blue", expected_p=False) | ||
|
||
# Delete VRF blue | ||
r1.net.del_iface("blue") | ||
|
||
# Check that "blue" nexthops are removed | ||
check_kernel(r1, "198.51.100.1", ["192.0.2.130"], None, expected_p=False) | ||
check_kernel(r1, "198.51.100.2", ["r1-eth1"], None, expected_p=False) | ||
|
||
# Add VRF red back, attach "eth0" to it | ||
r1.net.add_l3vrf("red", 10) | ||
r1.net.attach_iface_to_l3vrf("r1-eth0", "red") | ||
|
||
# Check that "red" nexthops are restored | ||
check_kernel(r1, "198.51.100.1", ["192.0.2.2"], None) | ||
check_kernel(r1, "198.51.100.2", ["r1-eth0"], None) | ||
|
||
# Add VRF blue back, attach "eth1" to it | ||
r1.net.add_l3vrf("blue", 20) | ||
r1.net.attach_iface_to_l3vrf("r1-eth1", "blue") | ||
|
||
# Check that everything is restored | ||
check_kernel(r1, "198.51.100.1", ["192.0.2.2", "192.0.2.130"], None) | ||
check_kernel(r1, "198.51.100.2", ["r1-eth0", "r1-eth1"], None) | ||
check_kernel(r1, "203.0.113.1", ["192.0.2.130"], "red") | ||
check_kernel(r1, "203.0.113.2", ["r1-eth1"], "red") | ||
check_kernel(r1, "203.0.113.129", ["192.0.2.2"], "blue") | ||
check_kernel(r1, "203.0.113.130", ["r1-eth0"], "blue") |