From: Quentin Young Date: Fri, 21 Oct 2016 19:27:49 +0000 (+0000) Subject: Merge branch 'cmaster-next' into vtysh-grammar X-Git-Tag: frr-3.0-branchpoint~129^2~69 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=39e92c066f210b0b550489e98d3b767ee1553e52;p=mirror%2Ffrr.git Merge branch 'cmaster-next' into vtysh-grammar Signed-off-by: Quentin Young Conflicts: bgpd/bgp_encap.c bgpd/bgp_route.c lib/command.c lib/command.h ospf6d/ospf6d.c vtysh/vtysh.c --- 39e92c066f210b0b550489e98d3b767ee1553e52 diff --cc bgpd/bgp_encap.c index bb62e37134,c60b592133..499401bd4f --- a/bgpd/bgp_encap.c +++ b/bgpd/bgp_encap.c @@@ -630,14 -620,12 +630,13 @@@ DEFUN (show_bgp_ipv4_encap_neighbor_rou "Neighbor to display information about\n" "Display routes learned from neighbor\n") { + int idx_peer = 5; - union sockunion *su; + union sockunion su; struct peer *peer; - - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) + - if (str2sockunion(argv[0], &su)) ++ if (sockunion_str2su (argv[idx_peer]->arg)) { - vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); + vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } @@@ -662,14 -650,12 +661,13 @@@ DEFUN (show_bgp_ipv6_encap_neighbor_rou "Neighbor to display information about\n" "Display routes learned from neighbor\n") { + int idx_peer = 5; - union sockunion *su; + union sockunion su; struct peer *peer; - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) - if (str2sockunion(argv[0], &su)) ++ if (str2sockunion(argv[idx_peer]->arg, &su)) { - vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); + vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } @@@ -698,10 -684,8 +696,10 @@@ DEFUN (show_bgp_ipv4_encap_rd_neighbor_ "Neighbor to display information about\n" "Display routes learned from neighbor\n") { + int idx_rd = 5; + int idx_peer = 7; int ret; - union sockunion *su; + union sockunion su; struct peer *peer; struct prefix_rd prd; @@@ -712,10 -696,9 +710,9 @@@ return CMD_WARNING; } - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) - if (str2sockunion(argv[1], &su)) ++ if (str2sockunion(argv[idx_peer]->arg, &su)) { - vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); + vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } @@@ -743,10 -726,8 +740,10 @@@ DEFUN (show_bgp_ipv6_encap_rd_neighbor_ "Neighbor to display information about\n" "Display routes learned from neighbor\n") { + int idx_rd = 5; + int idx_peer = 7; int ret; - union sockunion *su; + union sockunion su; struct peer *peer; struct prefix_rd prd; @@@ -757,10 -738,9 +754,9 @@@ return CMD_WARNING; } - su = sockunion_str2su (argv[idx_peer]->arg); - if (su == NULL) - if (str2sockunion(argv[1], &su)) ++ if (str2sockunion(argv[idx_peer]->arg, &su)) { - vty_out (vty, "Malformed address: %s%s", argv[1], VTY_NEWLINE); + vty_out (vty, "Malformed address: %s%s", argv[idx_peer]->arg, VTY_NEWLINE); return CMD_WARNING; } diff --cc bgpd/bgp_route.c index b03b296ea8,44377c3692..cfe4f8b7b4 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@@ -8032,366 -8223,283 +8032,362 @@@ DEFUN (show_ip_bgp_ipv4 SHOW_STR IP_STR BGP_STR + BGP_INSTANCE_HELP_STR + "Address family\n" + "Address Family modifier\n" + "Address family\n" + "Address Family modifier\n" + "Address family\n" + "Address Family modifier\n" "Address family\n" "Address Family modifier\n" + "Address family\n" "Address Family modifier\n" + "Display only routes with non-natural netmasks\n" + "Display routes matching the communities\n" + "Display detailed information about dampening\n" + "Display flap statistics of routes\n" + "Display paths suppressed due to dampening\n" + "Display routes matching the route-map\n" + "A route-map to match on\n" + "Display routes conforming to the prefix-list\n" + "prefix-list name\n" + "Display routes conforming to the filter-list\n" + "Regular expression access list name\n" + "Display routes matching the communities\n" + COMMUNITY_AANN_STR + "Do not send outside local AS (well-known community)\n" + "Do not advertise to any peer (well-known community)\n" + "Do not export to next AS (well-known community)\n" + "Exact match of the communities\n" + "Display routes matching the community-list\n" + "community-list number\n" + "community-list name\n" + "Exact match of the communities\n" + "IPv4 prefix /, e.g., 35.0.0.0/8\n" + "IPv6 prefix /\n" + "Display route and more specific routes\n" "JavaScript Object Notation\n") { - u_char uj = use_json(argc, argv); + char *vrf = NULL; + afi_t afi = AFI_IP6; + safi_t safi = SAFI_UNICAST; + int exact_match; + enum bgp_show_type sh_type = bgp_show_type_normal; + + int idx = 0; + + 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); + } - if (strncmp (argv[0], "m", 1) == 0) - return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal, - NULL, uj); - - return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL, uj); + 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 (++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]->text, "dampening")) - { - 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 + 1]->text, "flap-statistics")) - return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj); - } - + 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]->text, "flap-statistics")) + return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj); + + 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]->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]->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]->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]->text, "community")) + { + /* 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]->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]->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); } -ALIAS (show_ip_bgp_ipv4, - show_bgp_ipv4_safi_cmd, - "show bgp ipv4 (unicast|multicast) {json}", +DEFUN (show_ip_bgp_route, + show_ip_bgp_route_cmd, + "show [ip] bgp [ WORD] []|ipv6 []|encap [unicast]|vpnv4 [unicast]>]" + " [] [json]", SHOW_STR + IP_STR BGP_STR + BGP_INSTANCE_HELP_STR + "Address family\n" + "Address Family modifier\n" "Address family\n" "Address Family modifier\n" + "Address family\n" + "Address Family modifier\n" + "Address family\n" + "Address Family modifier\n" + "Address family\n" "Address Family modifier\n" + "Display information for a route distinguisher\n" + "VPN Route Distinguisher\n" + "Network in the BGP routing table to display\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "IPv6 prefix /\n" + "Display only the bestpath\n" + "Display only multipaths\n" "JavaScript Object Notation\n") +{ + int prefix_check = 0; -DEFUN (show_ip_bgp_route, - show_ip_bgp_route_cmd, - "show ip bgp A.B.C.D {json}", - SHOW_STR - IP_STR - BGP_STR - "Network in the BGP routing table to display\n" - "JavaScript Object Notation\n") -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json(argc, argv)); -} + afi_t afi = AFI_IP6; + safi_t safi = SAFI_UNICAST; + char *vrf = NULL; + char *prefix = NULL; -DEFUN (show_ip_bgp_route_pathtype, - show_ip_bgp_route_pathtype_cmd, - "show ip bgp A.B.C.D (bestpath|multipath) {json}", - SHOW_STR - IP_STR - BGP_STR - "IP prefix /, e.g., 35.0.0.0/8\n" - "Display only the bestpath\n" - "Display only multipaths\n" - "JavaScript Object Notation\n") -{ + enum bgp_path_type path_type; u_char uj = use_json(argc, argv); - if (strncmp (argv[1], "b", 1) == 0) - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj); - else - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj); -} + int idx = 0; + + /* show [ip] bgp */ + if (argv_find (argv, argc, "ip", &idx)) + afi = AFI_IP; + /* [ WORD] */ + if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx)) + vrf = argv[++idx]->arg; + /* []|ipv6 []|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); + } -DEFUN (show_bgp_ipv4_safi_route_pathtype, - show_bgp_ipv4_safi_route_pathtype_cmd, - "show bgp ipv4 (unicast|multicast) A.B.C.D (bestpath|multipath) {json}", - SHOW_STR - BGP_STR - "Address family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "IP prefix /, e.g., 35.0.0.0/8\n" - "Display only the bestpath\n" - "Display only multipaths\n" - "JavaScript Object Notation\n") -{ - u_char uj = use_json(argc, argv); + /* */ + 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_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx)) + prefix_check = 1; - if (strncmp (argv[0], "m", 1) == 0) - if (strncmp (argv[2], "b", 1) == 0) - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0, BGP_PATH_BESTPATH, uj); - else - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0, BGP_PATH_MULTIPATH, uj); - else - if (strncmp (argv[2], "b", 1) == 0) - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_BESTPATH, uj); - else - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_MULTIPATH, uj); -} + 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; + } -DEFUN (show_bgp_ipv4_prefix, - show_bgp_ipv4_prefix_cmd, - "show bgp ipv4 A.B.C.D/M {json}", - SHOW_STR - BGP_STR - IP_STR - "IP prefix /, e.g., 35.0.0.0/8\n" - JSON_STR) -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json (argc, argv)); -} + prefix = argv[idx]->arg; -DEFUN (show_bgp_ipv6_route, - show_bgp_ipv6_route_cmd, - "show bgp ipv6 X:X::X:X {json}", - SHOW_STR - BGP_STR - "Address family\n" - "Network in the BGP routing table to display\n" - JSON_STR) -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, use_json (argc, argv)); -} + /* [] */ + if (argv_find (argv, argc, "bestpath", &idx)) + path_type = BGP_PATH_BESTPATH; + else if (argv_find (argv, argc, "multipath", &idx)) + path_type = BGP_PATH_MULTIPATH; + else + path_type = BGP_PATH_ALL; -DEFUN (show_bgp_ipv6_prefix, - show_bgp_ipv6_prefix_cmd, - "show bgp ipv6 X:X::X:X/M {json}", - SHOW_STR - BGP_STR - IP_STR - "IPv6 prefix /\n" - JSON_STR) -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json (argc,argv)); + return bgp_show_route (vty, vrf, prefix, afi, safi, NULL, prefix_check, path_type, uj); } -DEFUN (show_ip_bgp_ipv4_route, - show_ip_bgp_ipv4_route_cmd, - "show ip bgp ipv4 (unicast|multicast) A.B.C.D {json}", +DEFUN (show_ip_bgp_instance_all, + show_ip_bgp_instance_all_cmd, + "show [ip] bgp all []|ipv6 []|encap [unicast]|vpnv4 [unicast]>] [json]", SHOW_STR IP_STR BGP_STR - "Address family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Network in the BGP routing table to display\n" + BGP_INSTANCE_ALL_HELP_STR "JavaScript Object Notation\n") { - u_char uj = use_json(argc, argv); + afi_t afi = AFI_IP; + safi_t safi = SAFI_UNICAST; - if (strncmp (argv[0], "m", 1) == 0) - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MULTICAST, NULL, 0, BGP_PATH_ALL, uj); + int idx = 0; - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0, BGP_PATH_ALL, uj); -} + /* show [ip] bgp */ + if (argv_find (argv, argc, "ip", &idx)) + afi = AFI_IP; + /* []|ipv6 []|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); + } -ALIAS (show_ip_bgp_ipv4_route, - show_bgp_ipv4_safi_route_cmd, - "show bgp ipv4 (unicast|multicast) A.B.C.D {json}", - SHOW_STR - BGP_STR - "Address family\n" - "Address Family modifier\n" - "Address Family modifier\n" - "Network in the BGP routing table to display\n" - "JavaScript Object Notation\n") + u_char uj = use_json(argc, argv); -DEFUN (show_ip_bgp_vpnv4_all_route, - show_ip_bgp_vpnv4_all_route_cmd, - "show ip bgp vpnv4 all A.B.C.D {json}", - SHOW_STR - IP_STR - BGP_STR - "Display VPNv4 NLRI specific information\n" - "Display information about all VPNv4 NLRIs\n" - "Network in the BGP routing table to display\n" - "JavaScript Object Notation\n") -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv)); + bgp_show_all_instances_routes_vty (vty, afi, safi, uj); + return CMD_SUCCESS; } -DEFUN (show_bgp_ipv4_vpn_route, - show_bgp_ipv4_vpn_route_cmd, - "show bgp ipv4 vpn A.B.C.D {json}", - SHOW_STR - BGP_STR - "Address Family\n" - "Display VPN NLRI specific information\n" - "Network in the BGP routing table to display\n" - JSON_STR) -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json (argc, argv)); -} + -DEFUN (show_bgp_ipv6_vpn_route, - show_bgp_ipv6_vpn_route_cmd, - "show bgp ipv6 vpn X:X::X:X {json}", - SHOW_STR - BGP_STR - "Address Family\n" - "Display VPN NLRI specific information\n" - "Network in the BGP routing table to display\n" - JSON_STR) +static int +bgp_show_regexp (struct vty *vty, int argc, struct cmd_token **argv, afi_t afi, + safi_t safi, enum bgp_show_type type) { - return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json (argc, argv)); -} ++ return CMD_SUCCESS; ++/* XXX(vtysh-grammar): Needs updating for new CLI backend. + -DEFUN (show_bgp_ipv4_vpn_rd_route, - show_bgp_ipv4_vpn_rd_route_cmd, - "show bgp ipv4 vpn rd ASN:nn_or_IP-address:nn A.B.C.D {json}", - SHOW_STR - BGP_STR - IP_STR - "Display VPN NLRI specific information\n" - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - "Network in the BGP routing table to display\n" - JSON_STR) -{ - int ret; - struct prefix_rd prd; + int i; + struct buffer *b; + char *regstr; + int first; + regex_t *regex; + int rc; + + first = 0; + b = buffer_new (1024); + for (i = 0; i < argc; i++) + { + if (first) + buffer_putc (b, ' '); + else + { + if ((strcmp (argv[i]->arg, "unicast") == 0) || (strcmp (argv[i]->arg, "multicast") == 0)) + continue; + first = 1; + } - ret = str2prefix_rd (argv[0], &prd); - if (! ret) + buffer_putstr (b, argv[i]->arg); + } + buffer_putc (b, '\0'); + + regstr = buffer_getstr (b); + buffer_free (b); + + regex = bgp_regcomp (regstr); + XFREE(MTYPE_TMP, regstr); + if (! regex) { - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); + vty_out (vty, "Can't compile regexp %s%s", argv[0]->arg, + VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv)); + + rc = bgp_show (vty, NULL, afi, safi, type, regex, 0); + bgp_regex_free (regex); + return rc; ++*/ } -DEFUN (show_bgp_ipv6_vpn_rd_route, - show_bgp_ipv6_vpn_rd_route_cmd, - "show bgp ipv6 vpn rd ASN:nn_or_IP-address:nn X:X::X:X {json}", - SHOW_STR - BGP_STR - "Address Family\n" - "Display VPN NLRI specific information\n" - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - "Network in the BGP routing table to display\n" - JSON_STR) +static int +bgp_show_prefix_list (struct vty *vty, const char *name, + const char *prefix_list_str, afi_t afi, + safi_t safi, enum bgp_show_type type) { - int ret; - struct prefix_rd prd; + struct prefix_list *plist; + struct bgp *bgp = NULL; - ret = str2prefix_rd (argv[0], &prd); - if (! ret) + if (name && !(bgp = bgp_lookup_by_name(name))) + { + vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE); + return CMD_WARNING; + } + + plist = prefix_list_lookup (afi, prefix_list_str); + if (plist == NULL) { - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); + vty_out (vty, "%% %s is not a valid prefix-list name%s", + prefix_list_str, VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv)); + + return bgp_show (vty, bgp, afi, safi, type, plist, 0); } -DEFUN (show_ip_bgp_vpnv4_rd_route, - show_ip_bgp_vpnv4_rd_route_cmd, - "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn A.B.C.D {json}", - SHOW_STR - IP_STR - BGP_STR - "Display VPNv4 NLRI specific information\n" - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - "Network in the BGP routing table to display\n" - "JavaScript Object Notation\n") +static int +bgp_show_filter_list (struct vty *vty, const char *name, + const char *filter, afi_t afi, + safi_t safi, enum bgp_show_type type) { - int ret; - struct prefix_rd prd; - u_char uj= use_json(argc, argv); + struct as_list *as_list; + struct bgp *bgp = NULL; - ret = str2prefix_rd (argv[0], &prd); - if (! ret) + if (name && !(bgp = bgp_lookup_by_name(name))) { - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); + vty_out (vty, "%% No such BGP instance exists%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, uj); -} -DEFUN (show_ip_bgp_prefix, - show_ip_bgp_prefix_cmd, - "show ip bgp A.B.C.D/M {json}", - SHOW_STR - IP_STR - BGP_STR - "IP prefix /, e.g., 35.0.0.0/8\n" - "JavaScript Object Notation\n") -{ - return bgp_show_route (vty, NULL, argv[0], AFI_IP, SAFI_UNICAST, NULL, 1, BGP_PATH_ALL, use_json(argc, argv)); + as_list = as_list_lookup (filter); + if (as_list == NULL) + { + vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE); + return CMD_WARNING; + } + + return bgp_show (vty, bgp, afi, safi, type, as_list, 0); } -DEFUN (show_ip_bgp_prefix_pathtype, - show_ip_bgp_prefix_pathtype_cmd, - "show ip bgp A.B.C.D/M (bestpath|multipath) {json}", +DEFUN (show_ip_bgp_dampening_info, + show_ip_bgp_dampening_params_cmd, + "show ip bgp dampening parameters", SHOW_STR IP_STR BGP_STR @@@ -9785,49 -13915,87 +9781,49 @@@ DEFUN (show_ip_bgp_neighbor_routes "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display routes learned from neighbor\n" - "JavaScript Object Notation\n") - -/* old command */ -DEFUN (ipv6_mbgp_neighbor_routes, - ipv6_mbgp_neighbor_routes_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", - SHOW_STR - IPV6_STR - MBGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n" + "Display the dampened routes received from neighbor\n" + "Display flap statistics of the routes learned from neighbor\n" "JavaScript Object Notation\n") { + int idx_view_vrf = 3; + int idx_vrf = 4; + int idx_afi; + int idx_safi; + int idx_peer; + int idx_sh_type; + char *vrf = NULL; + afi_t afi; + safi_t safi; struct peer *peer; + enum bgp_show_type sh_type = bgp_show_type_neighbor; u_char uj = use_json(argc, argv); - peer = peer_lookup_in_view (vty, NULL, argv[0], uj); + 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_peer); + + peer = peer_lookup_in_view (vty, vrf, argv[idx_peer]->arg, uj); if (! peer) - return CMD_WARNING; - - bgp_show_ipv6_bgp_deprecate_warning(vty); - return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_MULTICAST, - bgp_show_type_neighbor, uj); -} + { + vty_out (vty, "No such neighbor%s", VTY_NEWLINE); + return CMD_WARNING; + } -ALIAS (show_bgp_instance_neighbor_flap, - show_bgp_neighbor_flap_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", - SHOW_STR - BGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n" - "JavaScript Object Notation\n") + idx_sh_type = idx_peer + 1; -ALIAS (show_bgp_instance_neighbor_flap, - show_bgp_ipv6_neighbor_flap_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", - SHOW_STR - BGP_STR - "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n" - "JavaScript Object Notation\n") + if (strmatch(argv[idx_sh_type]->text, "routes")) + sh_type = bgp_show_type_neighbor; -ALIAS (show_bgp_instance_neighbor_damp, - show_bgp_neighbor_damp_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", - SHOW_STR - BGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n" - "JavaScript Object Notation\n") + else if (strmatch(argv[idx_sh_type]->text, "dampened-routes")) + sh_type = bgp_show_type_damp_neighbor; -ALIAS (show_bgp_instance_neighbor_damp, - show_bgp_ipv6_neighbor_damp_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", - SHOW_STR - BGP_STR - "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n" - "JavaScript Object Notation\n") + else if (strmatch(argv[idx_sh_type]->text, "flap-statistics")) + sh_type = bgp_show_type_flap_neighbor; -#endif /* HAVE_IPV6 */ + return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj); +} - struct bgp_table *bgp_distance_table; + struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX]; struct bgp_distance { @@@ -10024,16 -14193,17 +10021,20 @@@ DEFUN (bgp_distance "Distance for routes internal to the AS\n" "Distance for local routes\n") { + int idx_number = 2; + int idx_number_2 = 3; + int idx_number_3 = 4; struct bgp *bgp; + afi_t afi; + safi_t safi; bgp = vty->index; + afi = bgp_node_afi (vty); + safi = bgp_node_safi (vty); - bgp->distance_ebgp = atoi (argv[idx_number]->arg); - bgp->distance_ibgp = atoi (argv[idx_number_2]->arg); - bgp->distance_local = atoi (argv[idx_number_3]->arg); - bgp->distance_ebgp[afi][safi] = atoi (argv[0]); - bgp->distance_ibgp[afi][safi] = atoi (argv[1]); - bgp->distance_local[afi][safi] = atoi (argv[2]); ++ bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg); ++ bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg); ++ bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg); return CMD_SUCCESS; } @@@ -10116,9 -14286,57 +10121,57 @@@ DEFUN (no_bgp_distance_source_access_li return CMD_SUCCESS; } + DEFUN (ipv6_bgp_distance_source, + ipv6_bgp_distance_source_cmd, - "distance <1-255> X:X::X:X/M", ++ "distance (1-255) X:X::X:X/M", + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n") + { - bgp_distance_set (vty, argv[0], argv[1], NULL); ++ bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, NULL); + return CMD_SUCCESS; + } + + DEFUN (no_ipv6_bgp_distance_source, + no_ipv6_bgp_distance_source_cmd, - "no distance <1-255> X:X::X:X/M", ++ "no distance (1-255) X:X::X:X/M", + NO_STR + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n") + { - bgp_distance_unset (vty, argv[0], argv[1], NULL); ++ bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, NULL); + return CMD_SUCCESS; + } + + DEFUN (ipv6_bgp_distance_source_access_list, + ipv6_bgp_distance_source_access_list_cmd, - "distance <1-255> X:X::X:X/M WORD", ++ "distance (1-255) X:X::X:X/M WORD", + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n" + "Access list name\n") + { - bgp_distance_set (vty, argv[0], argv[1], argv[2]); ++ bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, argv[3]->arg); + return CMD_SUCCESS; + } + + DEFUN (no_ipv6_bgp_distance_source_access_list, + no_ipv6_bgp_distance_source_access_list_cmd, - "no distance <1-255> X:X::X:X/M WORD", ++ "no distance (1-255) X:X::X:X/M WORD", + NO_STR + "Define an administrative distance\n" + "Administrative distance\n" + "IP source prefix\n" + "Access list name\n") + { - bgp_distance_unset (vty, argv[0], argv[1], argv[2]); ++ bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, argv[4]->arg); + return CMD_SUCCESS; + } + DEFUN (bgp_damp_set, bgp_damp_set_cmd, - "bgp dampening <1-45> <1-20000> <1-20000> <1-255>", + "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]", "BGP Specific commands\n" "Enable route-flap dampening\n" "Half-life time for the penalty\n" @@@ -10656,11 -15248,47 +10722,35 @@@ bgp_route_init (void install_element (BGP_NODE, &no_bgp_distance_source_cmd); install_element (BGP_NODE, &bgp_distance_source_access_list_cmd); install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4_NODE, &bgp_distance_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd); - install_element (BGP_IPV4_NODE, &no_bgp_distance2_cmd); + install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd); + install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4M_NODE, &bgp_distance_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd); - install_element (BGP_IPV4M_NODE, &no_bgp_distance2_cmd); + install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd); + install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6_NODE, &bgp_distance_cmd); + install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd); - install_element (BGP_IPV6_NODE, &no_bgp_distance2_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6M_NODE, &bgp_distance_cmd); + install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd); - install_element (BGP_IPV6M_NODE, &no_bgp_distance2_cmd); + install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd); + install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd); + install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd); install_element (BGP_NODE, &bgp_damp_set_cmd); - install_element (BGP_NODE, &bgp_damp_set2_cmd); - install_element (BGP_NODE, &bgp_damp_set3_cmd); install_element (BGP_NODE, &bgp_damp_unset_cmd); - install_element (BGP_NODE, &bgp_damp_unset2_cmd); - install_element (BGP_NODE, &bgp_damp_unset3_cmd); install_element (BGP_IPV4_NODE, &bgp_damp_set_cmd); - install_element (BGP_IPV4_NODE, &bgp_damp_set2_cmd); - install_element (BGP_IPV4_NODE, &bgp_damp_set3_cmd); install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd); - install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd); - install_element (BGP_IPV4_NODE, &bgp_damp_unset3_cmd); /* IPv4 Multicast Mode */ install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd); diff --cc lib/command.c index 3416bcd1c7,56c262a647..f9c4107745 --- a/lib/command.c +++ b/lib/command.c @@@ -193,38 -224,27 +193,51 @@@ argv_concat (struct cmd_token **argv, i 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; +} + + static unsigned int + cmd_hash_key (void *p) + { + return (uintptr_t) p; + } + + static int + cmd_hash_cmp (const void *a, const void *b) + { + return a == b; + } + /* Install top node of command vector. */ void -install_node (struct cmd_node *node, - int (*func) (struct vty *)) +install_node (struct cmd_node *node, + int (*func) (struct vty *)) { vector_set_index (cmdvec, node->node, node); node->func = func; + node->cmdgraph = graph_new (); node->cmd_vector = vector_init (VECTOR_MIN_SIZE); + // add start node + struct cmd_token *token = new_cmd_token (START_TKN, NULL, NULL); + graph_new_node (node->cmdgraph, token, (void (*)(void *)) &del_cmd_token); + node->cmd_hash = hash_create (cmd_hash_key, cmd_hash_cmp); } /* Breaking up string into each command piece. I assume given @@@ -329,34 -714,37 +342,36 @@@ voi install_element (enum node_type ntype, struct cmd_element *cmd) { struct cmd_node *cnode; - + /* cmd_init hasn't been called */ if (!cmdvec) - return; - + { + fprintf (stderr, "%s called before cmd_init, breakage likely\n", + __func__); + return; + } + cnode = vector_slot (cmdvec, ntype); - if (cnode == NULL) + if (cnode == NULL) { fprintf (stderr, "Command node %d doesn't exist, please check it\n", - ntype); - exit (1); + ntype); + exit (EXIT_FAILURE); } - - // add node to command graph and command vector - // idiotic O(n) deduplication logic, should just use a merkle tree - for (unsigned int i = 0; i < vector_active (cnode->cmd_vector); i++) - { - struct cmd_element *existing = vector_slot (cnode->cmd_vector, i); - if (strmatch (existing->string, cmd->string)) + + if (hash_lookup (cnode->cmd_hash, cmd) != NULL) { - zlog_warn ("Duplicate command: %s\n", cmd->string); + fprintf (stderr, + "Multiple command installs to node %d of command:\n%s\n", + ntype, cmd->string); return; } - } - + + assert (hash_get (cnode->cmd_hash, cmd, hash_alloc_intern)); + + command_parse_format (cnode->cmdgraph, cmd); vector_set (cnode->cmd_vector, cmd); - if (cmd->tokens == NULL) - cmd->tokens = cmd_parse_format(cmd->string, cmd->doc); if (ntype == VIEW_NODE) install_element (ENABLE_NODE, cmd); @@@ -2427,13 -4379,22 +2442,16 @@@ cmd_terminate ( if (cmdvec) { - for (i = 0; i < vector_active (cmdvec); i++) + for (unsigned int i = 0; i < vector_active (cmdvec); i++) if ((cmd_node = vector_slot (cmdvec, i)) != NULL) - { - cmd_node_v = cmd_node->cmd_vector; - - for (j = 0; j < vector_active (cmd_node_v); j++) - if ((cmd_element = vector_slot (cmd_node_v, j)) != NULL) - cmd_terminate_element(cmd_element); - - vector_free (cmd_node_v); - hash_clean (cmd_node->cmd_hash, NULL); - hash_free (cmd_node->cmd_hash); - cmd_node->cmd_hash = NULL; - } + { + // deleting the graph delets the cmd_element as well + graph_delete_graph (cmd_node->cmdgraph); + vector_free (cmd_node->cmd_vector); ++ hash_clean (cmd_node->cmd_hash, NULL); ++ hash_free (cmd_node->cmd_hash); ++ cmd_node->cmd_hash = NULL; + } vector_free (cmdvec); cmdvec = NULL; diff --cc lib/command.h index 0e2d27f19c,e4aa10196f..4d60c5b4fe --- a/lib/command.h +++ b/lib/command.h @@@ -26,8 -26,8 +26,9 @@@ #include "vector.h" #include "vty.h" #include "lib/route_types.h" +#include "graph.h" #include "memory.h" + #include "hash.h" DECLARE_MTYPE(HOST) @@@ -147,68 -147,70 +148,71 @@@ struct cmd_nod /* Node's configuration write function */ int (*func) (struct vty *); + /* Node's command graph */ + struct graph *cmdgraph; + /* Vector of this node's command list. */ vector cmd_vector; + + /* Hashed index of command node list, for de-dupping primarily */ + struct hash *cmd_hash; }; -enum +/** + * Types for tokens. + * + * The type determines what kind of data the token can match (in the + * matching use case) or hold (in the argv use case). + */ +enum cmd_token_type { - CMD_ATTR_DEPRECATED = 1, - CMD_ATTR_HIDDEN, + WORD_TKN, // words + VARIABLE_TKN, // almost anything + RANGE_TKN, // integer range + IPV4_TKN, // IPV4 addresses + IPV4_PREFIX_TKN, // IPV4 network prefixes + IPV6_TKN, // IPV6 prefixes + IPV6_PREFIX_TKN, // IPV6 network prefixes + + /* plumbing types */ + SELECTOR_TKN, // marks beginning of selector + OPTION_TKN, // marks beginning of option + NUL_TKN, // dummy token + START_TKN, // first token in line + END_TKN, // last token in line }; -/* Structure of command element. */ -struct cmd_element +/** + * Token struct. + */ +struct cmd_token { - const char *string; /* Command specification by string. */ - int (*func) (struct cmd_element *, struct vty *, int, const char *[]); - const char *doc; /* Documentation of this command. */ - int daemon; /* Daemon to which this command belong. */ - vector tokens; /* Vector of cmd_tokens */ - u_char attr; /* Command attributes */ -}; + enum cmd_token_type type; // token type + char *text; // token text + char *desc; // token description -enum cmd_token_type -{ - TOKEN_TERMINAL = 0, - TOKEN_MULTIPLE, - TOKEN_KEYWORD, + long long min, max; // for ranges + + char *arg; // user input that matches this token }; -enum cmd_terminal_type +enum { - _TERMINAL_BUG = 0, - TERMINAL_LITERAL, - TERMINAL_OPTION, - TERMINAL_VARIABLE, - TERMINAL_VARARG, - TERMINAL_RANGE, - TERMINAL_IPV4, - TERMINAL_IPV4_PREFIX, - TERMINAL_IPV6, - TERMINAL_IPV6_PREFIX, + CMD_ATTR_DEPRECATED = 1, + CMD_ATTR_HIDDEN, }; -/* argument to be recorded on argv[] if it's not a literal */ -#define TERMINAL_RECORD(t) ((t) >= TERMINAL_OPTION) - -/* Command description structure. */ -struct cmd_token +/* Structure of command element. */ +struct cmd_element { - enum cmd_token_type type; - enum cmd_terminal_type terminal; - - /* Used for type == MULTIPLE */ - vector multiple; /* vector of cmd_token, type == FINAL */ - - /* Used for type == KEYWORD */ - vector keyword; /* vector of vector of cmd_tokens */ + const char *string; /* Command specification by string. */ + const char *doc; /* Documentation of this command. */ + int daemon; /* Daemon to which this command belong. */ + u_char attr; /* Command attributes */ - /* Used for type == TERMINAL */ - char *cmd; /* Command string. */ - char *desc; /* Command's description. */ + /* handler function for command */ + int (*func) (struct cmd_element *, struct vty *, int, struct cmd_token *[]); }; /* Return value of the commands. */ diff --cc ospf6d/ospf6_top.c index 31cdbd3c5d,3d632b644e..5471e58622 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@@ -447,7 -456,147 +452,214 @@@ DEFUN (no_ospf6_timers_lsa return CMD_SUCCESS; } -ALIAS (no_ospf6_timers_lsa, - no_ospf6_timers_lsa_val_cmd, - "no timers lsa min-arrival <0-600000>", - NO_STR - "Adjust routing timers\n" - "OSPF6 LSA timers\n" - "Minimum delay in receiving new version of a LSA\n" - "Delay in milliseconds\n") + DEFUN (ospf6_distance, + ospf6_distance_cmd, - "distance <1-255>", ++ "distance (1-255)", + "Administrative distance\n" + "OSPF6 Administrative distance\n") + { + struct ospf6 *o = vty->index; + - o->distance_all = atoi (argv[0]); ++ o->distance_all = atoi (argv[1]->arg); + + return CMD_SUCCESS; + } + + DEFUN (no_ospf6_distance, + no_ospf6_distance_cmd, - "no distance <1-255>", ++ "no distance (1-255)", + NO_STR + "Administrative distance\n" + "OSPF6 Administrative distance\n") + { + struct ospf6 *o = vty->index; + + o->distance_all = 0; + + return CMD_SUCCESS; + } + + DEFUN (ospf6_distance_ospf6, + ospf6_distance_ospf6_cmd, - "distance ospf6 {intra-area <1-255>|inter-area <1-255>|external <1-255>}", ++ "distance ospf6 ", + "Administrative distance\n" + "OSPF6 distance\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" ++ "Distance for external routes\n" ++ "Intra-area routes\n" ++ "Distance for intra-area routes\n" ++ "Inter-area routes\n" ++ "Distance for inter-area routes\n" ++ "External routes\n" ++ "Distance for external routes\n" ++ "Intra-area routes\n" ++ "Distance for intra-area routes\n" ++ "Inter-area routes\n" ++ "Distance for inter-area routes\n" ++ "External routes\n" + "Distance for external routes\n") + { + struct ospf6 *o = vty->index; + - if (argc < 3) /* should not happen */ ++ char *intra, *inter, *external; ++ intra = inter = external = NULL; ++ ++ int idx = 0; ++ if (argv_find (argv, argc, "intra-area", &idx)) ++ intra = argv[++idx]->arg; ++ if (argv_find (argv, argc, "intra-area", &idx)) ++ { ++ vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } ++ ++ idx = 0; ++ if (argv_find (argv, argc, "inter-area", &idx)) ++ inter = argv[++idx]->arg; ++ if (argv_find (argv, argc, "inter-area", &idx)) ++ { ++ vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE); + return CMD_WARNING; ++ } ++ ++ idx = 0; ++ if (argv_find (argv, argc, "external", &idx)) ++ external = argv[++idx]->arg; ++ if (argv_find (argv, argc, "external", &idx)) ++ { ++ vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } + - if (!argv[0] && !argv[1] && !argv[2]) - { - vty_out(vty, "%% Command incomplete. (Arguments required)%s", - VTY_NEWLINE); - return CMD_WARNING; - } + - if (argv[0] != NULL) - o->distance_intra = atoi (argv[0]); ++ if (intra) ++ o->distance_intra = atoi (intra); + - if (argv[1] != NULL) - o->distance_inter = atoi (argv[1]); ++ if (inter) ++ o->distance_inter = atoi (inter); + - if (argv[2] != NULL) - o->distance_external = atoi (argv[2]); ++ if (external) ++ o->distance_external = atoi (external); + + return CMD_SUCCESS; + } + + DEFUN (no_ospf6_distance_ospf6, + no_ospf6_distance_ospf6_cmd, - "no distance ospf6 {intra-area <1-255>|inter-area <1-255>|external <1-255>}", ++ "no distance ospf6 [ ]", + NO_STR + "Administrative distance\n" + "OSPF6 distance\n" + "Intra-area routes\n" + "Distance for intra-area routes\n" + "Inter-area routes\n" + "Distance for inter-area routes\n" + "External routes\n" ++ "Distance for external routes\n" ++ "Intra-area routes\n" ++ "Distance for intra-area routes\n" ++ "Inter-area routes\n" ++ "Distance for inter-area routes\n" ++ "External routes\n" ++ "Distance for external routes\n" ++ "Intra-area routes\n" ++ "Distance for intra-area routes\n" ++ "Inter-area routes\n" ++ "Distance for inter-area routes\n" ++ "External routes\n" + "Distance for external routes\n") + { + struct ospf6 *o = vty->index; + ++ char *intra, *inter, *external; ++ intra = inter = external = NULL; ++ ++ if (argc == 3) ++ { ++ /* If no arguments are given, clear all distance information */ ++ o->distance_intra = 0; ++ o->distance_inter = 0; ++ o->distance_external = 0; ++ return CMD_SUCCESS; ++ } ++ ++ int idx = 0; ++ if (argv_find (argv, argc, "intra-area", &idx)) ++ intra = argv[++idx]->arg; ++ if (argv_find (argv, argc, "intra-area", &idx)) ++ { ++ vty_out (vty, "%% Cannot specify intra-area distance twice%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } ++ ++ idx = 0; ++ if (argv_find (argv, argc, "inter-area", &idx)) ++ inter = argv[++idx]->arg; ++ if (argv_find (argv, argc, "inter-area", &idx)) ++ { ++ vty_out (vty, "%% Cannot specify inter-area distance twice%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } ++ ++ idx = 0; ++ if (argv_find (argv, argc, "external", &idx)) ++ external = argv[++idx]->arg; ++ if (argv_find (argv, argc, "external", &idx)) ++ { ++ vty_out (vty, "%% Cannot specify external distance twice%s", VTY_NEWLINE); ++ return CMD_WARNING; ++ } + if (argc < 3) /* should not happen */ + return CMD_WARNING; + - if (argv[0] != NULL) ++ if (intra) + o->distance_intra = 0; + - if (argv[1] != NULL) ++ if (inter) + o->distance_inter = 0; + - if (argv[2] != NULL) ++ if (external) + o->distance_external = 0; + - if (argv[0] || argv[1] || argv[2]) - return CMD_SUCCESS; - - /* If no arguments are given, clear all distance information */ - o->distance_intra = 0; - o->distance_inter = 0; - o->distance_external = 0; - + return CMD_SUCCESS; + } + + DEFUN (ospf6_distance_source, + ospf6_distance_source_cmd, - "distance <1-255> X:X::X:X/M [WORD]", ++ "distance (1-255) X:X::X:X/M [WORD]", + "Administrative distance\n" + "Distance value\n" + "IP source prefix\n" + "Access list name\n") + { + struct ospf6 *o = vty->index; - - ospf6_distance_set (vty, o, argv[0], argv[1], argc == 3 ? argv[2] : NULL); ++ char *alname = (argc == 4) ? argv[3]->arg : NULL; ++ ospf6_distance_set (vty, o, argv[1]->arg, argv[2]->arg, alname); + + return CMD_SUCCESS; + } + + DEFUN (no_ospf6_distance_source, + no_ospf6_distance_source_cmd, - "no distance <1-255> X:X::X:X/M [WORD]", ++ "no distance (1-255) X:X::X:X/M [WORD]", + NO_STR + "Administrative distance\n" + "Distance value\n" + "IP source prefix\n" + "Access list name\n") + { + struct ospf6 *o = vty->index; - - ospf6_distance_unset (vty, o, argv[0], argv[1], argc == 3 ? argv[2] : NULL); ++ char *alname = (argc == 5) ? argv[4]->arg : NULL; ++ ospf6_distance_unset (vty, o, argv[2]->arg, argv[3]->arg, alname); + + return CMD_SUCCESS; + } + DEFUN (ospf6_interface_area, ospf6_interface_area_cmd, "interface IFNAME area A.B.C.D", @@@ -953,6 -1213,15 +1204,13 @@@ ospf6_top_init (void install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd); install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd); */ - } - + install_element (OSPF6_NODE, &ospf6_distance_cmd); + install_element (OSPF6_NODE, &no_ospf6_distance_cmd); + install_element (OSPF6_NODE, &ospf6_distance_ospf6_cmd); + install_element (OSPF6_NODE, &no_ospf6_distance_ospf6_cmd); + #if 0 + install_element (OSPF6_NODE, &ospf6_distance_source_cmd); + install_element (OSPF6_NODE, &no_ospf6_distance_source_cmd); + #endif + } - -