lib: Add helper function for working with argv, update bgpd to use it

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2016-10-20 20:31:24 +00:00
parent e8d5696d45
commit ae19d7dd48
4 changed files with 304 additions and 177 deletions

View file

@ -8015,7 +8015,20 @@ bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str,
/* BGP route print out function. */
DEFUN (show_ip_bgp_ipv4,
show_ip_bgp_ipv4_cmd,
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] [<cidr-only|community|dampening <flap-statistics|dampened-paths>|route-map WORD|prefix-list WORD|filter-list WORD|community <AA:NN|local-AS|no-advertise|no-export> [exact-match]|community-list <(1-500)|WORD> [exact-match]|A.B.C.D/M longer-prefixes|X:X::X:X/M longer-prefixes>] [json]",
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>]\
[<\
cidr-only\
|community\
|dampening <flap-statistics|dampened-paths>\
|route-map WORD\
|prefix-list WORD\
|filter-list WORD\
|community <AA:NN|local-AS|no-advertise|no-export> [exact-match]\
|community-list <(1-500)|WORD> [exact-match]\
|A.B.C.D/M longer-prefixes\
|X:X::X:X/M longer-prefixes\
>]\
[json]",
SHOW_STR
IP_STR
BGP_STR
@ -8056,92 +8069,108 @@ DEFUN (show_ip_bgp_ipv4,
"Display route and more specific routes\n"
"JavaScript Object Notation\n")
{
int idx_view_vrf = 3;
int idx_vrf = 4;
int idx_afi;
int idx_safi;
int idx_sh_type;
int exact_match = 0;
char *vrf = NULL;
afi_t afi;
safi_t safi;
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
int exact_match;
enum bgp_show_type sh_type = bgp_show_type_normal;
struct bgp *bgp;
u_char uj = use_json(argc, argv);
vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
idx_safi = idx_afi + 1;
bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_sh_type);
int idx = 0;
bgp = bgp_lookup_by_name (vrf);
if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP;
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
vrf = argv[++idx]->arg;
if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
{
afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
}
else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
{
afi = AFI_IP;
safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
// advance idx if necessary
argv_find (argv, argc, "unicast", &idx);
}
int uj = use_json (argc, argv);
if (uj) argc--;
struct bgp *bgp = bgp_lookup_by_name (vrf);
if (bgp == NULL)
{
vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
return CMD_WARNING;
}
if (strmatch(argv[idx_sh_type]->text, "cidr-only"))
if (++idx < argc)
{
if (strmatch(argv[idx]->text, "cidr-only"))
return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
else if (strmatch(argv[idx_sh_type]->text, "dampening"))
else if (strmatch(argv[idx]->text, "dampening"))
{
if (strmatch(argv[idx_sh_type + 1]->text, "dampened-paths"))
if (strmatch(argv[idx + 1]->text, "dampened-paths"))
return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
else if (strmatch(argv[idx_sh_type + 1]->text, "flap-statistics"))
else if (strmatch(argv[idx + 1]->text, "flap-statistics"))
return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
}
else if (strmatch(argv[idx_sh_type]->text, "dampened-paths"))
else if (strmatch(argv[idx]->text, "dampened-paths"))
return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
else if (strmatch(argv[idx_sh_type]->text, "flap-statistics"))
else if (strmatch(argv[idx]->text, "flap-statistics"))
return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
else if (strmatch(argv[idx_sh_type]->text, "regexp"))
else if (strmatch(argv[idx]->text, "regexp"))
return bgp_show_regexp (vty, argc, argv, afi, safi, bgp_show_type_regexp);
else if (strmatch(argv[idx_sh_type]->text, "prefix-list"))
return bgp_show_prefix_list (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_prefix_list);
else if (strmatch(argv[idx]->text, "prefix-list"))
return bgp_show_prefix_list (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_list);
else if (strmatch(argv[idx_sh_type]->text, "filter-list"))
return bgp_show_filter_list (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_filter_list);
else if (strmatch(argv[idx]->text, "filter-list"))
return bgp_show_filter_list (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_filter_list);
else if (strmatch(argv[idx_sh_type]->text, "route-map"))
return bgp_show_route_map (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_route_map);
else if (strmatch(argv[idx]->text, "route-map"))
return bgp_show_route_map (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_route_map);
else if (strmatch(argv[idx_sh_type]->text, "community"))
/* show a specific community */
if (argv[idx_sh_type + 1]->type == VARIABLE_TKN ||
strmatch(argv[idx_sh_type + 1]->text, "local-AS") ||
strmatch(argv[idx_sh_type + 1]->text, "no-advertise") ||
strmatch(argv[idx_sh_type + 1]->text, "no-export"))
else if (strmatch(argv[idx]->text, "community"))
{
if (strmatch(argv[idx_sh_type + 2]->text, "exact_match"))
/* show a specific community */
if (argv[idx + 1]->type == VARIABLE_TKN ||
strmatch(argv[idx + 1]->text, "local-AS") ||
strmatch(argv[idx + 1]->text, "no-advertise") ||
strmatch(argv[idx + 1]->text, "no-export"))
{
if (strmatch(argv[idx + 2]->text, "exact_match"))
exact_match = 1;
return bgp_show_community (vty, vrf, argc, argv, exact_match, afi, safi);
}
/* show all communities */
else
return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj);
else if (strmatch(argv[idx_sh_type]->text, "community-list"))
{
if (strmatch(argv[idx_sh_type + 2]->text, "exact_match"))
exact_match = 1;
return bgp_show_community_list (vty, vrf, argv[idx_sh_type + 1]->arg, exact_match, afi, safi);
}
else if (strmatch(argv[idx]->text, "community-list"))
{
if (strmatch(argv[idx + 2]->text, "exact_match"))
exact_match = 1;
return bgp_show_community_list (vty, vrf, argv[idx + 1]->arg, exact_match, afi, safi);
}
/* prefix-longer */
else if (argv[idx_sh_type]->type == IPV4_TKN || argv[idx_sh_type]->type == IPV6_TKN)
return bgp_show_prefix_longer (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_prefix_longer);
else if (argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV6_TKN)
return bgp_show_prefix_longer (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_longer);
}
return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
}
DEFUN (show_ip_bgp_route,
show_ip_bgp_route_cmd,
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>]"
"<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
SHOW_STR
IP_STR
BGP_STR
@ -8165,68 +8194,102 @@ DEFUN (show_ip_bgp_route,
"Display only multipaths\n"
"JavaScript Object Notation\n")
{
int idx_view_vrf = 3;
int idx_vrf = 4;
int idx_afi;
int idx_safi;
int idx_prefix;
int idx_path_type;
int prefix_check = 0;
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
char *vrf = NULL;
afi_t afi;
safi_t safi;
char *prefix = NULL;
enum bgp_path_type path_type;
struct prefix_rd prd;
struct prefix_rd *prd_ptr = NULL;
u_char uj = use_json(argc, argv);
vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
idx_safi = idx_afi + 1;
bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_prefix);
int idx = 0;
if (strmatch(argv[idx_afi]->text, "encap") && strmatch(argv[idx_safi + 1]->text, "rd"))
/* show [ip] bgp */
if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP;
/* [<view|vrf> WORD] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
vrf = argv[++idx]->arg;
/* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
{
str2prefix_rd (argv[idx_safi + 2]->arg, &prd);
prd_ptr = &prd;
afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
}
else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
{
afi = AFI_IP;
safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
// advance idx if necessary
argv_find (argv, argc, "unicast", &idx);
}
if (argv[idx_prefix]->type == IPV4_TKN || argv[idx_prefix]->type == IPV6_TKN)
/* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
if (argv_find (argv, argc, "A.B.C.D", &idx) || argv_find (argv, argc, "X:X::X:X", &idx))
prefix_check = 0;
else if (argv[idx_prefix]->type == IPV4_PREFIX_TKN || argv[idx_prefix]->type == IPV6_PREFIX_TKN)
else if (argv_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx))
prefix_check = 1;
idx_path_type = idx_prefix + 1;
if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN) && afi != AFI_IP6)
{
vty_out (vty, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE);
return CMD_WARNING;
}
if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN) && afi != AFI_IP)
{
vty_out (vty, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE);
return CMD_WARNING;
}
if (strmatch(argv[idx_path_type]->text, "bestpath"))
prefix = argv[idx]->arg;
/* [<bestpath|multipath>] */
if (argv_find (argv, argc, "bestpath", &idx))
path_type = BGP_PATH_BESTPATH;
else if (strmatch(argv[idx_path_type]->text, "bestpath"))
else if (argv_find (argv, argc, "multipath", &idx))
path_type = BGP_PATH_MULTIPATH;
else
path_type = BGP_PATH_ALL;
return bgp_show_route (vty, vrf, argv[idx_prefix]->arg, afi, safi, prd_ptr, prefix_check, path_type, uj);
return bgp_show_route (vty, vrf, prefix, afi, safi, NULL, prefix_check, path_type, uj);
}
DEFUN (show_ip_bgp_instance_all,
show_ip_bgp_instance_all_cmd,
"show [ip] bgp <view|vrf> all [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] [json]",
"show [ip] bgp <view|vrf> all [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_ALL_HELP_STR
"JavaScript Object Notation\n")
{
int idx_view_vrf = 3;
int idx_vrf = 4;
int idx_afi;
int idx_safi;
afi_t afi;
safi_t safi;
afi_t afi = AFI_IP;
safi_t safi = SAFI_UNICAST;
int idx = 0;
/* show [ip] bgp */
if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP;
/* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
{
afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
}
else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
{
afi = AFI_IP;
safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
// advance idx if necessary
argv_find (argv, argc, "unicast", &idx);
}
u_char uj = use_json(argc, argv);
bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
idx_safi = idx_afi + 1;
bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, NULL);
bgp_show_all_instances_routes_vty (vty, afi, safi, uj);
return CMD_SUCCESS;

View file

@ -5969,7 +5969,7 @@ bgp_get_argv_afi_safi (int argc, struct cmd_token **argv,
/* one clear bgp command to rule them all */
DEFUN (clear_ip_bgp_all,
clear_ip_bgp_all_cmd,
"clear [ip] bgp [<view|vrf> WORD] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] [<soft [<in|out>]|in [prefix-filter]|out>]",
"clear [ip] bgp [<view|vrf> WORD] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [<soft [<in|out>]|in [prefix-filter]|out>]",
CLEAR_STR
IP_STR
BGP_STR
@ -6002,50 +6002,44 @@ DEFUN (clear_ip_bgp_all,
BGP_SOFT_IN_STR
BGP_SOFT_OUT_STR)
{
int idx_view_vrf = 3;
int idx_vrf = 4;
int idx_clr_sort = 5;
int idx_soft_in_out;
int idx_afi;
int idx_safi;
char *vrf = NULL;
afi_t afi;
safi_t safi;
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
enum clear_sort clr_sort = clear_peer;
enum bgp_clear_type clr_type;
char *clr_arg = NULL;
vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_clr_sort);
int idx = 0;
/* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external> */
if (strmatch(argv[idx_clr_sort]->text, "*"))
/* clear [ip] bgp */
if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP;
/* [<view|vrf> WORD] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
{
vrf = argv[idx + 1]->arg;
idx += 2;
}
/* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */
if (argv_find (argv, argc, "*", &idx))
{
clr_sort = clear_all;
}
else if (argv[idx_clr_sort]->type == IPV4_TKN)
else if (argv_find (argv, argc, "A.B.C.D", &idx))
{
clr_sort = clear_peer;
clr_arg = argv[idx_clr_sort]->arg;
clr_arg = argv[idx]->arg;
}
else if (argv[idx_clr_sort]->type == IPV6_TKN)
else if (argv_find (argv, argc, "X:X::X:X", &idx))
{
clr_sort = clear_peer;
clr_arg = argv[idx_clr_sort]->arg;
clr_arg = argv[idx]->arg;
}
else if (argv[idx_clr_sort]->type == RANGE_TKN)
{
clr_sort = clear_as;
clr_arg = argv[idx_clr_sort]->arg;
}
else if (strmatch(argv[idx_clr_sort]->text, "external"))
{
clr_sort = clear_external;
}
else if (strmatch(argv[idx_clr_sort]->text, "peer-group"))
else if (argv_find (argv, argc, "peer-group", &idx))
{
clr_sort = clear_group;
idx_clr_sort++;
clr_arg = argv[idx_clr_sort]->arg;
idx++;
clr_arg = argv[idx]->arg;
if (! peer_group_lookup (vty->index, clr_arg))
{
@ -6053,12 +6047,12 @@ DEFUN (clear_ip_bgp_all,
return CMD_WARNING;
}
}
else if (argv[idx_clr_sort]->type == WORD_TKN)
else if (argv_find (argv, argc, "WORD", &idx))
{
if (peer_lookup_by_conf_if (vty->index, argv[idx_clr_sort]->arg))
if (peer_lookup_by_conf_if (vty->index, argv[idx]->arg))
{
clr_sort = clear_peer;
clr_arg = argv[idx_clr_sort]->arg;
clr_arg = argv[idx]->arg;
}
else
{
@ -6066,27 +6060,47 @@ DEFUN (clear_ip_bgp_all,
return CMD_WARNING;
}
}
/* afi safi */
idx_afi = idx_clr_sort + 1;
idx_safi = idx_clr_sort + 2;
idx_soft_in_out = 0;
if (argc > idx_afi)
bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_soft_in_out);
clr_type = BGP_CLEAR_SOFT_NONE;
if (idx_soft_in_out && argc > idx_soft_in_out)
else if (argv_find (argv, argc, "(1-4294967295)", &idx))
{
/* soft, soft in, or soft out */
if (strmatch(argv[idx_soft_in_out]->text, "in"))
clr_type = BGP_CLEAR_SOFT_IN;
else if (strmatch(argv[idx_soft_in_out]->text, "out"))
clr_type = BGP_CLEAR_SOFT_OUT;
else if (strmatch(argv[idx_soft_in_out]->text, "soft"))
clr_type = BGP_CLEAR_SOFT_BOTH;
else if (strmatch(argv[idx_soft_in_out]->text, "prefix-filter"))
clr_type = BGP_CLEAR_SOFT_IN_ORF_PREFIX;
clr_sort = clear_as;
clr_arg = argv[idx]->arg;
}
else if (argv_find (argv, argc, "external", &idx))
{
clr_sort = clear_external;
}
/* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]||vpnv4 [unicast]>] */
if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
{
afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
}
else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
{
afi = AFI_IP;
safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
// advance idx if necessary
argv_find (argv, argc, "unicast", &idx);
}
/* [<soft [<in|out>]|in [prefix-filter]|out>] */
if (argv_find (argv, argc, "soft", &idx))
{
if (argv_find (argv, argc, "in", &idx) || argv_find (argv, argc, "out", &idx))
clr_type = strmatch (argv[idx]->text, "in") ? BGP_CLEAR_SOFT_IN : BGP_CLEAR_SOFT_OUT;
else
clr_type = BGP_CLEAR_SOFT_BOTH;
}
else if (argv_find (argv, argc, "in", &idx))
{
clr_type = argv_find (argv, argc, "prefix-filter", &idx) ? BGP_CLEAR_SOFT_IN_ORF_PREFIX : BGP_CLEAR_SOFT_IN;
}
else if (argv_find (argv, argc, "out", &idx))
{
clr_type = BGP_CLEAR_SOFT_OUT;
}
else
clr_type = BGP_CLEAR_SOFT_NONE;
return bgp_clear_vty (vty, vrf, afi, safi, clr_sort, clr_type, clr_arg);
}
@ -6843,7 +6857,7 @@ bgp_show_summary_vty (struct vty *vty, const char *name,
/* `show ip bgp summary' commands. */
DEFUN (show_ip_bgp_summary,
show_ip_bgp_summary_cmd,
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] summary [json]",
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] summary [json]",
SHOW_STR
IP_STR
BGP_STR
@ -6861,18 +6875,33 @@ DEFUN (show_ip_bgp_summary,
"Summary of BGP neighbor status\n"
"JavaScript Object Notation\n")
{
int idx_view_vrf = 3;
int idx_vrf = 4;
int idx_afi;
int idx_safi;
char *vrf = NULL;
afi_t afi;
safi_t safi;
u_char uj = use_json(argc, argv);
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
idx_safi = idx_afi + 1;
bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, NULL);
int idx = 0;
/* show [ip] bgp */
if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP;
/* [<view|vrf> WORD] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
vrf = argv[++idx]->arg;
/* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
{
afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
}
else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
{
afi = AFI_IP;
safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
// advance idx if necessary
argv_find (argv, argc, "unicast", &idx);
}
int uj = use_json (argc, argv);
return bgp_show_summary_vty (vty, vrf, afi, safi, uj);
}
@ -8889,7 +8918,7 @@ bgp_show_update_groups(struct vty *vty, const char *name,
DEFUN (show_ip_bgp_updgrps,
show_ip_bgp_updgrps_cmd,
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] update-groups [SUBGROUP-ID]",
"show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] update-groups [SUBGROUP-ID]",
SHOW_STR
IP_STR
BGP_STR
@ -8907,24 +8936,38 @@ DEFUN (show_ip_bgp_updgrps,
"Detailed info about dynamic update groups\n"
"Specific subgroup to display detailed info for\n")
{
int idx_view_vrf = 3;
int idx_vrf = 4;
int idx_afi;
int idx_safi;
int idx_updgrp;
int idx_subgroup_id;
char *vrf = NULL;
afi_t afi;
safi_t safi;
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
uint64_t subgrp_id = 0;
vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
idx_safi = idx_afi + 1;
bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_updgrp);
idx_subgroup_id = idx_updgrp + 1;
int idx = 0;
if (! strmatch(argv[idx_subgroup_id]->text, "update-groups"))
VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
/* show [ip] bgp */
if (argv_find (argv, argc, "ip", &idx))
afi = AFI_IP;
/* [<view|vrf> WORD] */
if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
vrf = argv[++idx]->arg;
/* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
{
afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
}
else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
{
afi = AFI_IP;
safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
// advance idx if necessary
argv_find (argv, argc, "unicast", &idx);
}
/* get subgroup id, if provided */
idx = argc - 1;
if (argv[idx]->type == VARIABLE_TKN)
VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx]->arg);
return (bgp_show_update_groups(vty, vrf, afi, safi, subgrp_id));
}

View file

@ -193,6 +193,26 @@ argv_concat (struct cmd_token **argv, int argc, int shift)
return str;
}
/**
* Convenience function for accessing argv data.
*
* @param argc
* @param argv
* @param text definition snippet of the desired token
* @param index the starting index, and where to store the
* index of the found token if it exists
* @return 1 if found, 0 otherwise
*/
int
argv_find (struct cmd_token **argv, int argc, const char *text, int *index)
{
int found = 0;
for (int i = *index; i < argc && found == 0; i++)
if ((found = strmatch (text, argv[i]->text)))
*index = i;
return found;
}
/* Install top node of command vector. */
void
install_node (struct cmd_node *node,

View file

@ -408,6 +408,7 @@ extern void install_element (enum node_type, struct cmd_element *);
string with a space between each element (allocated using
XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
extern char *argv_concat (struct cmd_token **argv, int argc, int shift);
extern int argv_find (struct cmd_token **argv, int argc, const char *text, int *index);
extern vector cmd_make_strvec (const char *);
extern void cmd_free_strvec (vector);