diff options
| author | Piotr Suchy <piotrsuchy@proton.me> | 2024-05-08 21:04:04 +0000 | 
|---|---|---|
| committer | Piotr Suchy <piotrsuchy6@tlen.pl> | 2024-05-14 13:22:20 +0200 | 
| commit | 70e5005cba584a000c8d4d19807565c7a3394f4e (patch) | |
| tree | 867d1e0548d337972b6e354c516196f2b7fe01a6 | |
| parent | 281c891f167c198d0cdd90f54e06f2f30e403e87 (diff) | |
lib, vtysh, topotests: fix 'show ip[v6] access-list ... json' formatting
Similarly to recently fixed 'show ip[v6] prefix-list ...' - PR#15750,
json output is not valid for 'show ip[v6] access-list ... json' commands,
as it goes through all the running daemons and for each one it calls
'filter_show' creating a new json object. To aggreagate the output
and create a valid json that can later be parsed, the commands were
moved to vtysh and formatted accordingly
Signed-off-by: Piotr Suchy <piotrsuchy@proton.me>
| -rw-r--r-- | lib/filter.c | 18 | ||||
| -rw-r--r-- | tests/topotests/nb_config/test_nb_config.py | 4 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 102 | ||||
| -rw-r--r-- | vtysh/vtysh.h | 4 | 
4 files changed, 114 insertions, 14 deletions
diff --git a/lib/filter.c b/lib/filter.c index 5a0790f8bf..0722bed1cb 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -458,7 +458,6 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi,  	struct filter_cisco *filter;  	bool first;  	json_object *json = NULL; -	json_object *json_proto = NULL;  	master = access_master_get(afi);  	if (master == NULL) { @@ -469,12 +468,7 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi,  	if (use_json)  		json = json_object_new_object(); - -	/* Print the name of the protocol */ -	if (json) { -		json_proto = json_object_new_object(); -		json_object_object_add(json, frr_protoname, json_proto); -	} else +	else  		vty_out(vty, "%s:\n", frr_protoname);  	for (access = master->str.head; access; access = access->next) { @@ -496,7 +490,7 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi,  				if (json) {  					json_acl = json_object_new_object(); -					json_object_object_add(json_proto, +					json_object_object_add(json,  							       access->name,  							       json_acl); @@ -596,7 +590,7 @@ DEFUN (show_mac_access_list_name,  	return filter_show(vty, argv[3]->arg, AFI_L2VPN, false);  } -DEFUN (show_ip_access_list, +DEFUN_NOSH (show_ip_access_list,         show_ip_access_list_cmd,         "show ip access-list [json]",         SHOW_STR @@ -608,7 +602,7 @@ DEFUN (show_ip_access_list,  	return filter_show(vty, NULL, AFI_IP, uj);  } -DEFUN (show_ip_access_list_name, +DEFUN_NOSH (show_ip_access_list_name,         show_ip_access_list_name_cmd,         "show ip access-list ACCESSLIST4_NAME [json]",         SHOW_STR @@ -622,7 +616,7 @@ DEFUN (show_ip_access_list_name,  	return filter_show(vty, argv[idx_acl]->arg, AFI_IP, uj);  } -DEFUN (show_ipv6_access_list, +DEFUN_NOSH (show_ipv6_access_list,         show_ipv6_access_list_cmd,         "show ipv6 access-list [json]",         SHOW_STR @@ -634,7 +628,7 @@ DEFUN (show_ipv6_access_list,  	return filter_show(vty, NULL, AFI_IP6, uj);  } -DEFUN (show_ipv6_access_list_name, +DEFUN_NOSH (show_ipv6_access_list_name,         show_ipv6_access_list_name_cmd,         "show ipv6 access-list ACCESSLIST6_NAME [json]",         SHOW_STR diff --git a/tests/topotests/nb_config/test_nb_config.py b/tests/topotests/nb_config/test_nb_config.py index 8def19ffd5..9099ef10b8 100644 --- a/tests/topotests/nb_config/test_nb_config.py +++ b/tests/topotests/nb_config/test_nb_config.py @@ -50,7 +50,7 @@ def test_access_list_config_ordering(tgen):      output = r1.vtysh_cmd("show ip access-list test json")      got = json.loads(output)      expected = json.loads( -        '{"ZEBRA":{"test":{"type":"Standard", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "address":"10.0.0.1", "mask":"0.0.0.0"}]}}}' +        '{"zebra":{"test":{"type":"Standard", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "address":"10.0.0.1", "mask":"0.0.0.0"}]}}}'      )      result = json_cmp(got, expected)      assert result is None @@ -63,7 +63,7 @@ def test_access_list_config_ordering(tgen):      output = r1.vtysh_cmd("show ip access-list test json")      got = json.loads(output)      expected = json.loads( -        '{"ZEBRA":{"test":{"type":"Zebra", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "prefix":"10.0.0.0/8", "exact-match":false}]}}}' +        '{"zebra":{"test":{"type":"Zebra", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "prefix":"10.0.0.0/8", "exact-match":false}]}}}'      )      result = json_cmp(got, expected)      assert result is None diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 1a358017dc..b1c957d043 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -3628,6 +3628,104 @@ DEFPY (show_ipv6_prefix_list_detail,  	return CMD_SUCCESS;  } +static void show_access_list_send(afi_t afi, const char *access_list, bool json) +{ +	unsigned int i; +	bool first = true; +	char command_line[128]; + +	if (afi == AFI_IP) +		snprintf(command_line, sizeof(command_line), +			 "do show ip access-list "); +	else if (afi == AFI_IP6) +		snprintf(command_line, sizeof(command_line), +			 "do show ipv6 access-list "); +	if (access_list) +		strlcat(command_line, access_list, sizeof(command_line)); +	if (json) { +		strlcat(command_line, " json", sizeof(command_line)); +		vty_out(vty, "{"); +	} + +	for (i = 0; i < array_size(vtysh_client); i++) { +		const struct vtysh_client *client = &vtysh_client[i]; +		bool is_connected = true; + +		if (!CHECK_FLAG(client->flag, VTYSH_ACCESS_LIST_SHOW)) +			continue; + +		for (; client; client = client->next) +			if (client->fd < 0) +				is_connected = false; + +		if (!is_connected) +			continue; + +		if (json && !first) +			vty_out(vty, ","); +		else +			first = false; + +		if (json) +			vty_out(vty, "\"%s\":", vtysh_client[i].name); + +		vtysh_client_execute_name(vtysh_client[i].name, command_line); +	} + +	if (json) +		vty_out(vty, "}\n"); +} + +DEFPY (show_ip_access_list, +       show_ip_access_list_cmd, +       "show ip access-list [json$uj]", +       SHOW_STR +       IP_STR +       "List IP access lists\n" +       JSON_STR) +{ +	show_access_list_send(AFI_IP, NULL, !!uj); +	return CMD_SUCCESS; +} + +DEFPY (show_ip_access_list_name, +       show_ip_access_list_name_cmd, +       "show ip access-list ACCESSLIST4_NAME$name [json$uj]", +       SHOW_STR +       IP_STR +       "List IP access lists\n" +       "IP access-list name\n" +       JSON_STR) +{ +	show_access_list_send(AFI_IP, name, !!uj); +	return CMD_SUCCESS; +} + +DEFPY (show_ipv6_access_list, +       show_ipv6_access_list_cmd, +       "show ipv6 access-list [json$uj]", +       SHOW_STR +       IPV6_STR +       "List IPv6 access lists\n" +       JSON_STR) +{ +	show_access_list_send(AFI_IP6, NULL, !!uj); +	return CMD_SUCCESS; +} + +DEFPY (show_ipv6_access_list_name, +       show_ipv6_access_list_name_cmd, +       "show ipv6 access-list ACCESSLIST6_NAME$name [json$uj]", +       SHOW_STR +       IPV6_STR +       "List IPv6 access lists\n" +       "IPv6 access-list name\n" +       JSON_STR) +{ +	show_access_list_send(AFI_IP6, name, !!uj); +	return CMD_SUCCESS; +} +  DEFUN (vtysh_integrated_config,         vtysh_integrated_config_cmd,         "service integrated-vtysh-config", @@ -5234,6 +5332,10 @@ void vtysh_init_vty(void)  	install_element(ENABLE_NODE, &show_ipv6_prefix_list_cmd);  	install_element(ENABLE_NODE, &show_ipv6_prefix_list_summary_cmd);  	install_element(ENABLE_NODE, &show_ipv6_prefix_list_detail_cmd); +	install_element(ENABLE_NODE, &show_ip_access_list_cmd); +	install_element(ENABLE_NODE, &show_ip_access_list_name_cmd); +	install_element(ENABLE_NODE, &show_ipv6_access_list_cmd); +	install_element(ENABLE_NODE, &show_ipv6_access_list_name_cmd);  	/* "write terminal" command. */  	install_element(ENABLE_NODE, &vtysh_write_terminal_cmd); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 131fbef8ba..b1d57aa3c2 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -68,6 +68,10 @@ extern struct event_loop *master;  	VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \  		VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD |         \  		VTYSH_FABRICD +#define VTYSH_ACCESS_LIST_SHOW                                                 \ +	VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \ +		VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD |         \ +		VTYSH_FABRICD  #define VTYSH_PREFIX_LIST_SHOW                                                 \  	VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \  		VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD |         \  | 
