From 24302c25d3533712dc7914932a9e9cac1453574b Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 20 Dec 2024 08:47:04 +0100 Subject: [PATCH 1/2] bgpd: display rpki state in 'show bgp ipvX detail' The rpki current state was ignored when calling for the 'show bgp ipvX detail' command. Handle the support for this, with json support too. > "rpkiValidationState" : "valid", > "rpkiValidationState" : "invalid", > "rpkiValidationState" : "not used", > "rpkiValidationState" : "not found", Signed-off-by: Philippe Guibert Signed-off-by: Dmytro Shytyi --- bgpd/bgp_route.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index bd2fda56fc..7645c67734 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -11975,14 +11975,13 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa continue; } - if (type == bgp_show_type_rpki) { - if (dest_p->family == AF_INET - || dest_p->family == AF_INET6) - rpki_curr_state = hook_call( - bgp_rpki_prefix_status, - pi->peer, pi->attr, dest_p); - if (rpki_target_state != RPKI_NOT_BEING_USED - && rpki_curr_state != rpki_target_state) + if ((dest_p->family == AF_INET || dest_p->family == AF_INET6) && + (detail_routes || detail_json || type == bgp_show_type_rpki)) { + rpki_curr_state = hook_call(bgp_rpki_prefix_status, pi->peer, + pi->attr, dest_p); + if (type == bgp_show_type_rpki && + rpki_target_state != RPKI_NOT_BEING_USED && + rpki_curr_state != rpki_target_state) continue; } @@ -12213,7 +12212,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa route_vty_out_detail(vty, bgp, dest, dest_p, pi, family2afi(dest_p->family), safi, - RPKI_NOT_BEING_USED, json_paths, NULL); + rpki_curr_state, json_paths, NULL); } else { route_vty_out(vty, dest_p, pi, display, safi, json_paths, wide); From 5f50b98f8ea8887853e0f11625355d20aa9be20f Mon Sep 17 00:00:00 2001 From: Dmytro Shytyi Date: Thu, 26 Dec 2024 14:22:41 +0100 Subject: [PATCH 2/2] tests: add bgp rpki topo1 rpkiValidationState Topotest to verify the next key-value "rpkiValidationState": "valid" Signed-off-by: Dmytro Shytyi --- .../bgp_rpki_topo1/r2/bgp_rpki_valid.json | 70 +++++++++++++++++++ .../bgp_rpki_topo1/test_bgp_rpki_topo1.py | 29 ++++++++ 2 files changed, 99 insertions(+) create mode 100644 tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json diff --git a/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json b/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json new file mode 100644 index 0000000000..016c019d10 --- /dev/null +++ b/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json @@ -0,0 +1,70 @@ +{ + "vrfId": 0, + "vrfName": "default", + "tableVersion": 3, + "routerId": "192.0.2.2", + "defaultLocPrf": 100, + "localAS": 65002, + "routes": { + "198.51.100.0/24": [ + { + "origin": "IGP", + "metric": 0, + "valid": true, + "version": 2, + "rpkiValidationState": "valid", + "bestpath": { + "overall": true, + "selectionReason": "First path received" + }, + "nexthops": [ + { + "ip": "192.0.2.1", + "hostname": "r1", + "afi": "ipv4", + "metric": 0, + "accessible": true, + "used": true + } + ], + "peer": { + "peerId": "192.0.2.1", + "routerId": "192.0.2.1", + "hostname": "r1", + "type": "external" + } + } + ], + "203.0.113.0/24": [ + { + "origin": "IGP", + "metric": 0, + "valid": true, + "version": 3, + "rpkiValidationState": "valid", + "bestpath": { + "overall": true, + "selectionReason": "First path received" + }, + "nexthops": [ + { + "ip": "192.0.2.1", + "hostname": "r1", + "afi": "ipv4", + "metric": 0, + "accessible": true, + "used": true + } + ], + "peer": { + "peerId": "192.0.2.1", + "routerId": "192.0.2.1", + "hostname": "r1", + "type": "external" + } + } + ] + }, + "totalRoutes": 3, + "totalPaths": 3 +} \ No newline at end of file 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..5b775aa6cb 100644 --- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py +++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py @@ -101,6 +101,16 @@ def show_rpki_prefixes(rname, expected, vrf=None): return topotest.json_cmp(output, expected) +def show_rpki_valid(rname, expected, vrf=None): + tgen = get_topogen() + + cmd = "show bgp ipv4 detail json" + + output = json.loads(tgen.gears[rname].vtysh_cmd(cmd)) + + return topotest.json_cmp(output, expected) + + def show_bgp_ipv4_table_rpki(rname, rpki_state, expected, vrf=None): tgen = get_topogen() @@ -123,6 +133,25 @@ def show_bgp_ipv4_table_rpki(rname, rpki_state, expected, vrf=None): return topotest.json_cmp(output, expected) +def test_show_bgp_rpki_prefixes_valid(): + 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) + + rname = "r2" + expected = open(os.path.join(CWD, "{}/bgp_rpki_valid.json".format(rname))).read() + expected_json = json.loads(expected) + test_func = functools.partial(show_rpki_valid, rname, expected_json) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see RPKI on {}".format(rname) + + def test_show_bgp_rpki_prefixes(): tgen = get_topogen()