Skip to content

Commit 7270576

Browse files
authored
Merge pull request FRRouting#19868 from opensourcerouting/fix/route_map_counter_decrement_srv6
bgpd: Track route-map references for srv6 when rmap is used
2 parents 7776f8e + b3e1cf8 commit 7270576

File tree

7 files changed

+219
-13
lines changed

7 files changed

+219
-13
lines changed

bgpd/bgp_srv6.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,11 @@ void bgp_srv6_unicast_delete(struct bgp *bgp, afi_t afi)
171171
if (bgp->srv6_unicast[afi].sid_explicit)
172172
XFREE(MTYPE_BGP_SRV6_SID, bgp->srv6_unicast[afi].sid_explicit);
173173

174-
if (bgp->srv6_unicast[afi].rmap_name)
174+
if (bgp->srv6_unicast[afi].rmap_name) {
175175
XFREE(MTYPE_ROUTE_MAP_NAME, bgp->srv6_unicast[afi].rmap_name);
176+
route_map_counter_decrement(
177+
route_map_lookup_by_name(bgp->srv6_unicast[afi].rmap_name));
178+
}
176179

177180
srv6_locator_free(bgp->srv6_unicast[afi].sid_locator);
178181
bgp->srv6_unicast[afi].sid_locator = NULL;
@@ -248,6 +251,8 @@ void bgp_srv6_unicast_register_route(struct bgp *bgp, afi_t afi, struct bgp_dest
248251

249252
return;
250253
}
254+
255+
route_map_counter_increment(rmap);
251256
} else {
252257
zlog_warn("route-map %s was no found, ignored",
253258
bgp->srv6_unicast[afi].rmap_name);

bgpd/bgp_vty.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10041,6 +10041,8 @@ DEFPY(sid_export,
1004110041

1004210042
if (bgp->srv6_unicast[afi].rmap_name) {
1004310043
XFREE(MTYPE_ROUTE_MAP_NAME, bgp->srv6_unicast[afi].rmap_name);
10044+
route_map_counter_decrement(
10045+
route_map_lookup_by_name(bgp->srv6_unicast[afi].rmap_name));
1004410046
bgp->srv6_unicast[afi].rmap_name = NULL;
1004510047
}
1004610048
if (bgp->srv6_unicast[afi].sid_explicit) {
@@ -10088,8 +10090,11 @@ DEFPY(sid_export,
1008810090
return CMD_WARNING_CONFIG_FAILED;
1008910091
}
1009010092

10091-
if (rmap_str)
10093+
if (rmap_str) {
1009210094
bgp->srv6_unicast[afi].rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
10095+
route_map_counter_increment(
10096+
route_map_lookup_by_name(bgp->srv6_unicast[afi].rmap_name));
10097+
}
1009310098

1009410099
if (sid_auto) {
1009510100
SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_SRV6_UNICAST_SID_AUTO);

doc/user/routemap.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ cont
9797

9898
If the ``json`` option is specified, output is displayed in JSON format.
9999

100+
.. clicmd:: show route-map-unused [json]
101+
102+
Display data about each daemons knowledge of individual unused route-maps.
103+
104+
If the ``json`` option is specified, output is displayed in JSON format.
105+
100106
.. _route-map-clear-counter-command:
101107

102108
.. clicmd:: clear route-map counter [WORD]

lib/routemap.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,11 +1130,15 @@ static int vty_show_route_map(struct vty *vty, const char *name, bool use_json)
11301130
}
11311131

11321132
/* Unused route map details */
1133-
static int vty_show_unused_route_map(struct vty *vty)
1133+
static int vty_show_unused_route_map(struct vty *vty, bool uj)
11341134
{
11351135
struct list *maplist = list_new();
11361136
struct listnode *ln;
11371137
struct route_map *map;
1138+
json_object *json = NULL;
1139+
1140+
if (uj)
1141+
json = json_object_new_object();
11381142

11391143
for (map = route_map_master.head; map; map = map->next) {
11401144
/* If use_count is zero, No protocol is using this routemap.
@@ -1145,16 +1149,22 @@ static int vty_show_unused_route_map(struct vty *vty)
11451149
}
11461150

11471151
if (maplist->count > 0) {
1148-
vty_out(vty, "\n%s:\n", frr_protonameinst);
1152+
if (!uj)
1153+
vty_out(vty, "\n%s:\n", frr_protonameinst);
11491154
list_sort(maplist, sort_route_map);
11501155

11511156
for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
1152-
vty_show_route_map_entry(vty, map, NULL);
1157+
vty_show_route_map_entry(vty, map, json);
11531158
} else {
1154-
vty_out(vty, "\n%s: None\n", frr_protonameinst);
1159+
if (!uj)
1160+
vty_out(vty, "\n%s: None\n", frr_protonameinst);
11551161
}
11561162

11571163
list_delete(&maplist);
1164+
1165+
if (uj)
1166+
vty_json(vty, json);
1167+
11581168
return CMD_SUCCESS;
11591169
}
11601170

@@ -3198,13 +3208,16 @@ DEFUN_NOSH (rmap_show_name,
31983208
return vty_show_route_map(vty, name, uj);
31993209
}
32003210

3201-
DEFUN (rmap_show_unused,
3211+
DEFPY_NOSH (rmap_show_unused,
32023212
rmap_show_unused_cmd,
3203-
"show route-map-unused",
3213+
"show route-map-unused [json$json]",
32043214
SHOW_STR
3205-
"unused route-map information\n")
3215+
"unused route-map information\n"
3216+
JSON_STR)
32063217
{
3207-
return vty_show_unused_route_map(vty);
3218+
bool uj = use_json(argc, argv);
3219+
3220+
return vty_show_unused_route_map(vty, uj);
32083221
}
32093222

32103223
DEFPY (debug_rmap,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
!
2+
int r1-eth0
3+
ip address 10.0.0.1/32
4+
!
5+
route-map test1 permit 10
6+
set weight 1
7+
!
8+
route-map test2 permit 10
9+
set weight 2
10+
!
11+
route-map test3 permit 10
12+
set weight 3
13+
!
14+
route-map test4 permit 10
15+
set weight 4
16+
!
17+
router bgp 65000
18+
neighbor r1-eth0 interface remote-as auto
19+
address-family ipv4 unicast
20+
aggregate-address 10.0.0.0/24 route-map test1
21+
network 10.0.0.0/24 route-map test2
22+
neighbor r1-eth0 route-map test3 in
23+
sid export auto route-map test4
24+
exit-address-family
25+
!
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env python
2+
# SPDX-License-Identifier: ISC
3+
4+
# Copyright (c) 2025 by
5+
# Donatas Abraitis <donatas@opensourcerouting.org>
6+
#
7+
8+
import os
9+
import sys
10+
import json
11+
import pytest
12+
import functools
13+
14+
CWD = os.path.dirname(os.path.realpath(__file__))
15+
sys.path.append(os.path.join(CWD, "../"))
16+
17+
# pylint: disable=C0413
18+
from lib import topotest
19+
from lib.topogen import Topogen, get_topogen
20+
21+
pytestmark = [pytest.mark.bgpd]
22+
23+
24+
def setup_module(mod):
25+
topodef = {"s1": ("r1",)}
26+
tgen = Topogen(topodef, mod.__name__)
27+
tgen.start_topology()
28+
29+
router_list = tgen.routers()
30+
31+
for _, (rname, router) in enumerate(router_list.items(), 1):
32+
router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname)))
33+
34+
tgen.start_router()
35+
36+
37+
def teardown_module(mod):
38+
tgen = get_topogen()
39+
tgen.stop_topology()
40+
41+
42+
def test_route_map_check_unused():
43+
tgen = get_topogen()
44+
45+
if tgen.routers_have_failure():
46+
pytest.skip(tgen.errors)
47+
48+
r1 = tgen.gears["r1"]
49+
50+
def _check_unused_route_maps():
51+
output = json.loads(r1.vtysh_cmd("show route-map-unused json"))
52+
expected = {
53+
"zebra": {
54+
"test1": {
55+
"invoked": 0,
56+
"disabledOptimization": False,
57+
"processedChange": False,
58+
"rules": [
59+
{
60+
"sequenceNumber": 10,
61+
"type": "permit",
62+
"invoked": 0,
63+
"cpuTimeMS": 0,
64+
"matchClauses": [],
65+
"setClauses": [],
66+
"action": "Exit routemap",
67+
}
68+
],
69+
"cpuTimeMS": 0,
70+
},
71+
"test2": {
72+
"invoked": 0,
73+
"disabledOptimization": False,
74+
"processedChange": False,
75+
"rules": [
76+
{
77+
"sequenceNumber": 10,
78+
"type": "permit",
79+
"invoked": 0,
80+
"cpuTimeMS": 0,
81+
"matchClauses": [],
82+
"setClauses": [],
83+
"action": "Exit routemap",
84+
}
85+
],
86+
"cpuTimeMS": 0,
87+
},
88+
"test3": {
89+
"invoked": 0,
90+
"disabledOptimization": False,
91+
"processedChange": False,
92+
"rules": [
93+
{
94+
"sequenceNumber": 10,
95+
"type": "permit",
96+
"invoked": 0,
97+
"cpuTimeMS": 0,
98+
"matchClauses": [],
99+
"setClauses": [],
100+
"action": "Exit routemap",
101+
}
102+
],
103+
"cpuTimeMS": 0,
104+
},
105+
"test4": {
106+
"invoked": 0,
107+
"disabledOptimization": False,
108+
"processedChange": False,
109+
"rules": [
110+
{
111+
"sequenceNumber": 10,
112+
"type": "permit",
113+
"invoked": 0,
114+
"cpuTimeMS": 0,
115+
"matchClauses": [],
116+
"setClauses": [],
117+
"action": "Exit routemap",
118+
}
119+
],
120+
"cpuTimeMS": 0,
121+
},
122+
},
123+
"bgpd": {},
124+
}
125+
126+
return topotest.json_cmp(output, expected, exact=True)
127+
128+
test_func = functools.partial(_check_unused_route_maps)
129+
_, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
130+
assert result is None, "There are some unused route-maps"
131+
132+
133+
if __name__ == "__main__":
134+
args = ["-s"] + sys.argv[1:]
135+
sys.exit(pytest.main(args))

vtysh/vtysh.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3661,13 +3661,17 @@ DEFUN (vtysh_show_running_config,
36613661
return vtysh_write_terminal(self, vty, argc, argv);
36623662
}
36633663

3664-
static void show_route_map_send(const char *route_map, bool json)
3664+
static void show_route_map_send(const char *route_map, bool unused, bool json)
36653665
{
36663666
unsigned int i;
36673667
bool first = true;
36683668
char command_line[128];
36693669

3670-
snprintf(command_line, sizeof(command_line), "do show route-map ");
3670+
if (unused)
3671+
snprintf(command_line, sizeof(command_line), "do show route-map-unused ");
3672+
else
3673+
snprintf(command_line, sizeof(command_line), "do show route-map ");
3674+
36713675
if (route_map)
36723676
strlcat(command_line, route_map, sizeof(command_line));
36733677
if (json)
@@ -3713,7 +3717,19 @@ DEFPY (show_route_map,
37133717
"route-map name\n"
37143718
JSON_STR)
37153719
{
3716-
show_route_map_send(route_map, !!json);
3720+
show_route_map_send(route_map, false, !!json);
3721+
3722+
return CMD_SUCCESS;
3723+
}
3724+
3725+
DEFPY (show_route_map_unused,
3726+
show_route_map_unused_cmd,
3727+
"show route-map-unused [json]$json",
3728+
SHOW_STR
3729+
"unused route-map information\n"
3730+
JSON_STR)
3731+
{
3732+
show_route_map_send(NULL, true, !!json);
37173733

37183734
return CMD_SUCCESS;
37193735
}
@@ -5658,6 +5674,7 @@ void vtysh_init_vty(void)
56585674
install_element(ENABLE_NODE, &vtysh_copy_to_running_cmd);
56595675

56605676
install_element(ENABLE_NODE, &show_route_map_cmd);
5677+
install_element(ENABLE_NODE, &show_route_map_unused_cmd);
56615678
install_element(ENABLE_NODE, &show_ip_prefix_list_cmd);
56625679
install_element(ENABLE_NODE, &show_ip_prefix_list_summary_cmd);
56635680
install_element(ENABLE_NODE, &show_ip_prefix_list_detail_cmd);

0 commit comments

Comments
 (0)