From 7bf5cb49641a9786bf3130b17d329bf9881bfcb3 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 12 Apr 2025 16:56:30 -0400 Subject: bgpd: Prevent crash when issuing a show rpki connections When attempting to check rpki status and the connection has been turned off, let's check to see if we are connected before we ask the rpki subsystem, else we will get a crash in the rpki library. Signed-off-by: Donald Sharp (cherry picked from commit dcf43ae009ffecf206fb8cf8896eb5cd616ba4e5) --- bgpd/bgp_rpki.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 04a709b350..aefb58094b 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -529,7 +529,10 @@ static struct rtr_mgr_group *get_groups(struct list *cache_list) inline bool is_synchronized(struct rpki_vrf *rpki_vrf) { - return rpki_vrf->rtr_is_synced; + if (is_running(rpki_vrf)) + return rpki_vrf->rtr_is_synced; + else + return false; } inline bool is_running(struct rpki_vrf *rpki_vrf) -- cgit v1.2.3 From 4c2a7ceacb098cf21e5807789601428142ceeb6b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 12 Apr 2025 16:32:34 -0400 Subject: tests: Add more tests to bgp_rpki_topo1 test Looking at the gcov of the rpki code, I noticed that there was some functionality that is not covered in our test suites. Add the functionality. Signed-off-by: Donald Sharp (cherry picked from commit dbff585b411edba20fc73b5e509ef9c1bc0697b2) --- .../bgp_rpki_topo1/test_bgp_rpki_topo1.py | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py index 7b40bbdae8..2531cfc088 100644 --- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py +++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py @@ -448,6 +448,121 @@ def test_bgp_ecommunity_rpki(): assert result is None, "Received RPKI extended community" +def test_show_bgp_rpki_as_number(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Check RPKI prefixes for ASN 65531") + + rname = "r2" + output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki as-number 65531 json")) + + # Expected output should show no prefixes for this ASN + expected = {"ipv4PrefixCount": 0, "ipv6PrefixCount": 0, "prefixes": []} + + assert output == expected, "Found unexpected RPKI prefixes for ASN 65531" + + +def test_show_bgp_rpki_as_number_65530(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Check RPKI prefixes for ASN 65530") + + rname = "r2" + output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki as-number 65530 json")) + + expected = { + "prefixes": [ + { + "prefix": "198.51.100.0", + "prefixLenMin": 24, + "prefixLenMax": 24, + "asn": 65530, + }, + { + "prefix": "203.0.113.0", + "prefixLenMin": 24, + "prefixLenMax": 24, + "asn": 65530, + }, + ], + "ipv4PrefixCount": 2, + "ipv6PrefixCount": 0, + } + + assert ( + output == expected + ), "RPKI prefixes for ASN 65530 do not match expected output" + + +def test_rpki_stop_and_check_connection(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Stop RPKI on r2") + rname = "r2" + tgen.gears[rname].vtysh_cmd("rpki stop") + + step("Check RPKI cache connection status") + output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki cache-connection json")) + + expected = {"error": "No connection to RPKI cache server."} + assert ( + output == expected + ), "RPKI cache connection status does not show as disconnected" + + +def test_rpki_start_and_check_connection(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + step("Start RPKI on r2") + rname = "r2" + tgen.gears[rname].vtysh_cmd("rpki start") + + def _check_rpki_connection(): + output = json.loads( + tgen.gears[rname].vtysh_cmd("show rpki cache-connection json") + ) + # We expect to see a connected group and at least one connection + return "connectedGroup" in output and "connections" in output + + step("Check RPKI cache connection status") + _, result = topotest.run_and_expect( + _check_rpki_connection, True, count=60, wait=0.5 + ) + assert result, "RPKI cache connection did not establish after start" + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) -- cgit v1.2.3