]> git.puffer.fish Git - mirror/frr.git/commitdiff
Merge branch 'cmaster-next' into vtysh-grammar
authorQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 21 Oct 2016 19:27:49 +0000 (19:27 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Fri, 21 Oct 2016 19:27:49 +0000 (19:27 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Conflicts:
bgpd/bgp_encap.c
bgpd/bgp_route.c
lib/command.c
lib/command.h
ospf6d/ospf6d.c
vtysh/vtysh.c

16 files changed:
1  2 
bgpd/bgp_attr.c
bgpd/bgp_encap.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgpd.c
isisd/isis_routemap.c
lib/command.c
lib/command.h
lib/json.c
lib/json.h
ospf6d/ospf6_spf.c
ospf6d/ospf6_top.c
ospf6d/ospf6_zebra.c
ospfd/ospf_vty.c
ripd/ripd.c
vtysh/vtysh.c

diff --cc bgpd/bgp_attr.c
Simple merge
index bb62e37134ab25556b60ecea6d2d39449e7bed3c,c60b592133933ddeb9486f5d9156cfa7222394fe..499401bd4ff457e4d0868bd2220b8392c2a322f7
@@@ -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")
  {
-   union sockunion *su;
 +  int idx_peer = 5;
+   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")
  {
-   union sockunion *su;
 +  int idx_peer = 5;
+   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;
  
        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;
  
        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;
      }
  
index b03b296ea8f48cfa870bd4f20307640a40879a79,44377c36924a30931bda5919fb8a41a8295763df..cfe4f8b7b49440b11bb852fa8fc07325c83ad7f4
@@@ -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 <network>/<length>, e.g., 35.0.0.0/8\n"
 +       "IPv6 prefix <network>/<length>\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 [<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
 +       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 <network>/<length>, e.g., 35.0.0.0/8\n"
 +       "IPv6 prefix <network>/<length>\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 <network>/<length>, 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;
 +  /* [<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);
 +  }
  
 -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 <network>/<length>, 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);
 +  /* <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_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 <network>/<length>, 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));
 -}
 +  /* [<bestpath|multipath>] */
 +  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 <network>/<length>\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 <view|vrf> all [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|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;
 +  /* [<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);
 +  }
  
 -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 <network>/<length>, 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;
  }
  
 -       "distance <1-255> X:X::X:X/M",
+ DEFUN (ipv6_bgp_distance_source,
+        ipv6_bgp_distance_source_cmd,
 -  bgp_distance_set (vty, argv[0], argv[1], NULL);
++       "distance (1-255) X:X::X:X/M",
+        "Define an administrative distance\n"
+        "Administrative distance\n"
+        "IP source prefix\n")
+ {
 -       "no distance <1-255> X:X::X:X/M",
++  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,
 -  bgp_distance_unset (vty, argv[0], argv[1], NULL);
++       "no distance (1-255) X:X::X:X/M",
+        NO_STR
+        "Define an administrative distance\n"
+        "Administrative distance\n"
+        "IP source prefix\n")
+ {
 -       "distance <1-255> X:X::X:X/M WORD",
++  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,
 -  bgp_distance_set (vty, argv[0], argv[1], argv[2]);
++       "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")
+ {
 -       "no distance <1-255> X:X::X:X/M WORD",
++  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,
 -  bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
++       "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[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, &no_bgp_distance2_cmd);
+   install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
+   install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
 -  install_element (BGP_IPV4M_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_IPV6_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_IPV6M_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, &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);
Simple merge
diff --cc bgpd/bgpd.c
Simple merge
Simple merge
diff --cc lib/command.c
index 3416bcd1c764839d411b73f3ac012402b5e5b816,56c262a647f14da9574f83553355fcf7e41972e4..f9c4107745f298902a71fc4a608c5986e638ce9c
@@@ -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 0e2d27f19cdbbf2c0177ff214f3b756c03123234,e4aa10196fc890a2d3c1fe75819c65eef967536b..4d60c5b4fe30ea4045d4fe1f8df3511fc0e45e52
@@@ -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 lib/json.c
Simple merge
diff --cc lib/json.h
Simple merge
Simple merge
index 31cdbd3c5d0f050e9f1486bf091a47b01646fe3e,3d632b644ed43003bcf7fd36960e57d37cf36d28..5471e58622d0a07bf02adab1ce9839cee8ee8fd4
@@@ -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")
  
 -       "distance <1-255>",
+ DEFUN (ospf6_distance,
+        ospf6_distance_cmd,
 -  o->distance_all = atoi (argv[0]);
++       "distance (1-255)",
+        "Administrative distance\n"
+        "OSPF6 Administrative distance\n")
+ {
+   struct ospf6 *o = vty->index;
 -       "no distance <1-255>",
++  o->distance_all = atoi (argv[1]->arg);
+   return CMD_SUCCESS;
+ }
+ DEFUN (no_ospf6_distance,
+        no_ospf6_distance_cmd,
 -       "distance ospf6 {intra-area <1-255>|inter-area <1-255>|external <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,
 -  if (argc < 3) /* should not happen */
++       "distance ospf6 <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)>",
+        "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 (!argv[0] && !argv[1] && !argv[2])
 -    {
 -      vty_out(vty, "%% Command incomplete. (Arguments required)%s",
 -              VTY_NEWLINE);
 -      return CMD_WARNING;
 -    }
++  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] != NULL)
 -    o->distance_intra = atoi (argv[0]);
 -  if (argv[1] != NULL)
 -    o->distance_inter = atoi (argv[1]);
++  if (intra)
++    o->distance_intra = atoi (intra);
 -  if (argv[2] != NULL)
 -    o->distance_external = atoi (argv[2]);
++  if (inter)
++    o->distance_inter = atoi (inter);
 -       "no distance ospf6 {intra-area <1-255>|inter-area <1-255>|external <1-255>}",
++  if (external)
++    o->distance_external = atoi (external);
+   return CMD_SUCCESS;
+ }
+ DEFUN (no_ospf6_distance_ospf6,
+        no_ospf6_distance_ospf6_cmd,
 -  if (argv[0] != NULL)
++       "no distance ospf6 [<intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)> <intra-area (1-255)|inter-area (1-255)|external (1-255)>]",
+        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[1] != NULL)
++  if (intra)
+     o->distance_intra = 0;
 -  if (argv[2] != NULL)
++  if (inter)
+     o->distance_inter = 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;
 -
++  if (external)
+     o->distance_external = 0;
 -       "distance <1-255> X:X::X:X/M [WORD]",
+   return CMD_SUCCESS;
+ }
+ DEFUN (ospf6_distance_source,
+        ospf6_distance_source_cmd,
 -
 -  ospf6_distance_set (vty, o, argv[0], argv[1], argc == 3 ? argv[2] : NULL);
++       "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;
 -       "no distance <1-255> X:X::X:X/M [WORD]",
++  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,
 -
 -  ospf6_distance_unset (vty, o, argv[0], argv[1], argc == 3 ? argv[2] : NULL);
++       "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;
++  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
+ }
Simple merge
Simple merge
diff --cc ripd/ripd.c
Simple merge
diff --cc vtysh/vtysh.c
Simple merge