]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: Add helper function for working with argv, update bgpd to use it
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 20 Oct 2016 20:31:24 +0000 (20:31 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 20 Oct 2016 20:31:24 +0000 (20:31 +0000)
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
bgpd/bgp_route.c
bgpd/bgp_vty.c
lib/command.c
lib/command.h

index 6362b48b54a7f9dbb95ce9acbd7f9d872a55dc98..b03b296ea8f48cfa870bd4f20307640a40879a79 100644 (file)
@@ -8015,7 +8015,20 @@ bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str,
 /* BGP route print out function. */
 DEFUN (show_ip_bgp_ipv4,
        show_ip_bgp_ipv4_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] [<cidr-only|community|dampening <flap-statistics|dampened-paths>|route-map WORD|prefix-list WORD|filter-list WORD|community <AA:NN|local-AS|no-advertise|no-export> [exact-match]|community-list <(1-500)|WORD> [exact-match]|A.B.C.D/M longer-prefixes|X:X::X:X/M longer-prefixes>] [json]",
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>]\
+          [<\
+             cidr-only\
+             |community\
+             |dampening <flap-statistics|dampened-paths>\
+             |route-map WORD\
+             |prefix-list WORD\
+             |filter-list WORD\
+             |community <AA:NN|local-AS|no-advertise|no-export> [exact-match]\
+             |community-list <(1-500)|WORD> [exact-match]\
+             |A.B.C.D/M longer-prefixes\
+             |X:X::X:X/M longer-prefixes\
+           >]\
+          [json]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -8056,92 +8069,108 @@ DEFUN (show_ip_bgp_ipv4,
        "Display route and more specific routes\n"
        "JavaScript Object Notation\n")
 {
-  int idx_view_vrf = 3;
-  int idx_vrf = 4;
-  int idx_afi;
-  int idx_safi;
-  int idx_sh_type;
-  int exact_match = 0;
   char *vrf = NULL;
-  afi_t afi;
-  safi_t safi;
+  afi_t afi = AFI_IP6;
+  safi_t safi = SAFI_UNICAST;
+  int exact_match;
   enum bgp_show_type sh_type = bgp_show_type_normal;
-  struct bgp *bgp;
-  u_char uj = use_json(argc, argv);
 
-  vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
-  idx_safi = idx_afi + 1;
-  bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_sh_type);
+  int idx = 0;
+
+  if (argv_find (argv, argc, "ip", &idx))
+    afi = AFI_IP;
+  if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+    vrf = argv[++idx]->arg;
+  if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
+  {
+    afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+    if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
+      safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
+  }
+  else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
+  {
+    afi = AFI_IP;
+    safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
+    // advance idx if necessary
+    argv_find (argv, argc, "unicast", &idx);
+  }
+
+  int uj = use_json (argc, argv);
+  if (uj) argc--;
 
-  bgp = bgp_lookup_by_name (vrf);
+  struct bgp *bgp = bgp_lookup_by_name (vrf);
   if (bgp == NULL)
    {
      vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
      return CMD_WARNING;
    }
 
-  if (strmatch(argv[idx_sh_type]->text, "cidr-only"))
-    return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
+  if (++idx < argc)
+  {
+    if (strmatch(argv[idx]->text, "cidr-only"))
+      return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
 
-  else if (strmatch(argv[idx_sh_type]->text, "dampening"))
-    {
-      if (strmatch(argv[idx_sh_type + 1]->text, "dampened-paths"))
-        return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, 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_sh_type + 1]->text, "flap-statistics"))
-        return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, 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_sh_type]->text, "dampened-paths"))
-    return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, 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_sh_type]->text, "flap-statistics"))
-    return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, 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_sh_type]->text, "regexp"))
-    return bgp_show_regexp (vty, argc, argv, afi, safi, bgp_show_type_regexp);
+    else if (strmatch(argv[idx]->text, "regexp"))
+      return bgp_show_regexp (vty, argc, argv, afi, safi, bgp_show_type_regexp);
 
-  else if (strmatch(argv[idx_sh_type]->text, "prefix-list"))
-    return bgp_show_prefix_list (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_prefix_list);
+    else if (strmatch(argv[idx]->text, "prefix-list"))
+      return bgp_show_prefix_list (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_list);
 
-  else if (strmatch(argv[idx_sh_type]->text, "filter-list"))
-    return bgp_show_filter_list (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_filter_list);
+    else if (strmatch(argv[idx]->text, "filter-list"))
+      return bgp_show_filter_list (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_filter_list);
 
-  else if (strmatch(argv[idx_sh_type]->text, "route-map"))
-    return bgp_show_route_map (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_route_map);
+    else if (strmatch(argv[idx]->text, "route-map"))
+      return bgp_show_route_map (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_route_map);
 
-  else if (strmatch(argv[idx_sh_type]->text, "community"))
-    /* show a specific community */
-    if (argv[idx_sh_type + 1]->type == VARIABLE_TKN ||
-        strmatch(argv[idx_sh_type + 1]->text, "local-AS") ||
-        strmatch(argv[idx_sh_type + 1]->text, "no-advertise") ||
-        strmatch(argv[idx_sh_type + 1]->text, "no-export"))
+    else if (strmatch(argv[idx]->text, "community"))
+    {
+      /* 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_sh_type + 2]->text, "exact_match")) 
+        if (strmatch(argv[idx + 2]->text, "exact_match")) 
           exact_match = 1;
-        return bgp_show_community (vty, vrf, argc, argv, exact_match, afi, safi);
+        return bgp_show_community_list (vty, vrf, argv[idx + 1]->arg, exact_match, afi, safi);
       }
-    /* show all communities */
-    else
-      return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj);
-
-  else if (strmatch(argv[idx_sh_type]->text, "community-list"))
-    {
-      if (strmatch(argv[idx_sh_type + 2]->text, "exact_match")) 
-        exact_match = 1;
-      return bgp_show_community_list (vty, vrf, argv[idx_sh_type + 1]->arg, exact_match, afi, safi);
-    }
-
-  /* prefix-longer */
-  else if (argv[idx_sh_type]->type == IPV4_TKN || argv[idx_sh_type]->type == IPV6_TKN)
-    return bgp_show_prefix_longer (vty, vrf, argv[idx_sh_type + 1]->arg, afi, safi, bgp_show_type_prefix_longer);
+    /* prefix-longer */
+    else if (argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV6_TKN)
+      return bgp_show_prefix_longer (vty, vrf, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_longer);
+  }
 
   return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
 }
 
 DEFUN (show_ip_bgp_route,
        show_ip_bgp_route_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>]"
+       "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -8165,68 +8194,102 @@ DEFUN (show_ip_bgp_route,
        "Display only multipaths\n"
        "JavaScript Object Notation\n")
 {
-  int idx_view_vrf = 3;
-  int idx_vrf = 4;
-  int idx_afi;
-  int idx_safi;
-  int idx_prefix;
-  int idx_path_type;
   int prefix_check = 0;
+
+  afi_t afi = AFI_IP6;
+  safi_t safi = SAFI_UNICAST;
   char *vrf = NULL;
-  afi_t afi;
-  safi_t safi;
+  char *prefix = NULL;
+
   enum bgp_path_type path_type;
-  struct prefix_rd prd;
-  struct prefix_rd *prd_ptr = NULL;
   u_char uj = use_json(argc, argv);
 
-  vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
-  idx_safi = idx_afi + 1;
-  bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_prefix);
-
-  if (strmatch(argv[idx_afi]->text, "encap") && strmatch(argv[idx_safi + 1]->text, "rd"))
-    {
-      str2prefix_rd (argv[idx_safi + 2]->arg, &prd);
-      prd_ptr = &prd;
-    }
+  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);
+  }
 
-  if (argv[idx_prefix]->type == IPV4_TKN || argv[idx_prefix]->type == IPV6_TKN)
+  /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
+  if (argv_find (argv, argc, "A.B.C.D", &idx) || argv_find (argv, argc, "X:X::X:X", &idx))
     prefix_check = 0;
-  else if (argv[idx_prefix]->type == IPV4_PREFIX_TKN || argv[idx_prefix]->type == IPV6_PREFIX_TKN)
+  else if (argv_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx))
     prefix_check = 1;
 
-  idx_path_type = idx_prefix + 1;
+  if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN) && afi != AFI_IP6)
+  {
+    vty_out (vty, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE);
+    return CMD_WARNING;
+  }
+  if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN) && afi != AFI_IP)
+  {
+    vty_out (vty, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE);
+    return CMD_WARNING;
+  }
 
-  if (strmatch(argv[idx_path_type]->text, "bestpath"))
+  prefix = argv[idx]->arg;
+
+  /* [<bestpath|multipath>] */
+  if (argv_find (argv, argc, "bestpath", &idx))
     path_type = BGP_PATH_BESTPATH;
-  else if (strmatch(argv[idx_path_type]->text, "bestpath"))
+  else if (argv_find (argv, argc, "multipath", &idx))
     path_type = BGP_PATH_MULTIPATH;
   else
     path_type = BGP_PATH_ALL;
 
-  return bgp_show_route (vty, vrf, argv[idx_prefix]->arg, afi, safi, prd_ptr, prefix_check, path_type, uj);
+  return bgp_show_route (vty, vrf, prefix, afi, safi, NULL, prefix_check, path_type, uj);
 }
 
 DEFUN (show_ip_bgp_instance_all,
        show_ip_bgp_instance_all_cmd,
-       "show [ip] bgp <view|vrf> all [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] [json]",
+       "show [ip] bgp <view|vrf> all [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [json]",
        SHOW_STR
        IP_STR
        BGP_STR
        BGP_INSTANCE_ALL_HELP_STR
        "JavaScript Object Notation\n")
 {
-  int idx_view_vrf = 3;
-  int idx_vrf = 4;
-  int idx_afi;
-  int idx_safi;
-  afi_t afi;
-  safi_t safi;
+  afi_t afi = AFI_IP;
+  safi_t safi = SAFI_UNICAST;
+
+  int idx = 0;
+
+  /* show [ip] bgp */
+  if (argv_find (argv, argc, "ip", &idx))
+    afi = AFI_IP;
+  /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
+  if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
+  {
+    afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+    if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
+      safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
+  }
+  else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
+  {
+    afi = AFI_IP;
+    safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
+    // advance idx if necessary
+    argv_find (argv, argc, "unicast", &idx);
+  }
 
   u_char uj = use_json(argc, argv);
-  bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
-  idx_safi = idx_afi + 1;
-  bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, NULL);
 
   bgp_show_all_instances_routes_vty (vty, afi, safi, uj);
   return CMD_SUCCESS;
index 0f8d0c76ddea34ebc0e3e9319f7c65e7b8638320..cd61252a0cec6054c2dc1f9e9b71989e0a23b518 100644 (file)
@@ -5969,7 +5969,7 @@ bgp_get_argv_afi_safi (int argc, struct cmd_token **argv,
 /* one clear bgp command to rule them all */
 DEFUN (clear_ip_bgp_all,
        clear_ip_bgp_all_cmd,
-       "clear [ip] bgp [<view|vrf> WORD] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] [<soft [<in|out>]|in [prefix-filter]|out>]",
+       "clear [ip] bgp [<view|vrf> WORD] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] [<soft [<in|out>]|in [prefix-filter]|out>]",
        CLEAR_STR
        IP_STR
        BGP_STR
@@ -6002,63 +6002,57 @@ DEFUN (clear_ip_bgp_all,
        BGP_SOFT_IN_STR
        BGP_SOFT_OUT_STR)
 {
-  int idx_view_vrf = 3;
-  int idx_vrf = 4;
-  int idx_clr_sort = 5;
-  int idx_soft_in_out;
-  int idx_afi;
-  int idx_safi;
   char *vrf = NULL;
-  afi_t afi;
-  safi_t safi;
+  afi_t afi = AFI_IP6;
+  safi_t safi = SAFI_UNICAST;
   enum clear_sort clr_sort = clear_peer;
   enum bgp_clear_type clr_type;
   char *clr_arg = NULL;
 
-  vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_clr_sort);
+  int idx = 0;
 
-  /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external> */
-  if (strmatch(argv[idx_clr_sort]->text, "*"))
+  /* clear [ip] bgp */
+  if (argv_find (argv, argc, "ip", &idx))
+    afi = AFI_IP;
+  /* [<view|vrf> WORD] */
+  if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
     {
-      clr_sort = clear_all;
+      vrf = argv[idx + 1]->arg;
+      idx += 2;
     }
-  else if (argv[idx_clr_sort]->type == IPV4_TKN)
+  /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */
+  if (argv_find (argv, argc, "*", &idx))
     {
-      clr_sort = clear_peer;
-      clr_arg = argv[idx_clr_sort]->arg;
+      clr_sort = clear_all;
     }
-  else if (argv[idx_clr_sort]->type == IPV6_TKN)
+  else if (argv_find (argv, argc, "A.B.C.D", &idx))
     {
       clr_sort = clear_peer;
-      clr_arg = argv[idx_clr_sort]->arg;
+      clr_arg = argv[idx]->arg;
     }
-  else if (argv[idx_clr_sort]->type == RANGE_TKN)
+  else if (argv_find (argv, argc, "X:X::X:X", &idx))
     {
-      clr_sort = clear_as;
-      clr_arg = argv[idx_clr_sort]->arg;
-    }
-  else if (strmatch(argv[idx_clr_sort]->text, "external"))
-    {
-      clr_sort = clear_external;
+      clr_sort = clear_peer;
+      clr_arg = argv[idx]->arg;
     }
-  else if (strmatch(argv[idx_clr_sort]->text, "peer-group"))
+  else if (argv_find (argv, argc, "peer-group", &idx))
     {
       clr_sort = clear_group;
-      idx_clr_sort++;
-      clr_arg = argv[idx_clr_sort]->arg;
+      idx++;
+      clr_arg = argv[idx]->arg;
 
       if (! peer_group_lookup (vty->index, clr_arg))
         {
           vty_out (vty, "%% No such peer-group%s", VTY_NEWLINE);
-         return CMD_WARNING;
+          return CMD_WARNING;
         }
     }
-  else if (argv[idx_clr_sort]->type == WORD_TKN)
+  else if (argv_find (argv, argc, "WORD", &idx))
     {
-      if (peer_lookup_by_conf_if (vty->index, argv[idx_clr_sort]->arg))
+      if (peer_lookup_by_conf_if (vty->index, argv[idx]->arg))
         {
           clr_sort = clear_peer;
-          clr_arg = argv[idx_clr_sort]->arg;
+          clr_arg = argv[idx]->arg;
         }
       else
         {
@@ -6066,27 +6060,47 @@ DEFUN (clear_ip_bgp_all,
          return CMD_WARNING;
         }
     }
-
-  /* afi safi */
-  idx_afi = idx_clr_sort + 1;
-  idx_safi = idx_clr_sort + 2;
-  idx_soft_in_out = 0;
-  if (argc > idx_afi)
-    bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_soft_in_out);
-
-  clr_type = BGP_CLEAR_SOFT_NONE;
-  if (idx_soft_in_out && argc > idx_soft_in_out)
-  {
-    /* soft, soft in, or soft out */
-    if (strmatch(argv[idx_soft_in_out]->text, "in"))
-      clr_type = BGP_CLEAR_SOFT_IN;
-    else if (strmatch(argv[idx_soft_in_out]->text, "out"))
+  else if (argv_find (argv, argc, "(1-4294967295)", &idx))
+    {
+      clr_sort = clear_as;
+      clr_arg = argv[idx]->arg;
+    }
+  else if (argv_find (argv, argc, "external", &idx))
+    {
+      clr_sort = clear_external;
+    }
+  /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]||vpnv4 [unicast]>] */
+  if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
+    {
+      afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+      if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
+        safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
+    }
+  else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
+    {
+      afi = AFI_IP;
+      safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
+      // advance idx if necessary
+      argv_find (argv, argc, "unicast", &idx);
+    }
+  /* [<soft [<in|out>]|in [prefix-filter]|out>] */
+  if (argv_find (argv, argc, "soft", &idx))
+    {
+      if (argv_find (argv, argc, "in", &idx) || argv_find (argv, argc, "out", &idx))
+        clr_type = strmatch (argv[idx]->text, "in") ? BGP_CLEAR_SOFT_IN : BGP_CLEAR_SOFT_OUT;
+      else
+        clr_type = BGP_CLEAR_SOFT_BOTH;
+    }
+  else if (argv_find (argv, argc, "in", &idx))
+    {
+      clr_type = argv_find (argv, argc, "prefix-filter", &idx) ? BGP_CLEAR_SOFT_IN_ORF_PREFIX : BGP_CLEAR_SOFT_IN;
+    }
+  else if (argv_find (argv, argc, "out", &idx))
+    {
       clr_type = BGP_CLEAR_SOFT_OUT;
-    else if (strmatch(argv[idx_soft_in_out]->text, "soft"))
-      clr_type = BGP_CLEAR_SOFT_BOTH;
-    else if (strmatch(argv[idx_soft_in_out]->text, "prefix-filter"))
-      clr_type = BGP_CLEAR_SOFT_IN_ORF_PREFIX;
-  }
+    }
+  else
+    clr_type = BGP_CLEAR_SOFT_NONE;
 
   return bgp_clear_vty (vty, vrf, afi, safi, clr_sort, clr_type, clr_arg);
 }
@@ -6843,7 +6857,7 @@ bgp_show_summary_vty (struct vty *vty, const char *name,
 /* `show ip bgp summary' commands. */
 DEFUN (show_ip_bgp_summary,
        show_ip_bgp_summary_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] summary [json]",
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] summary [json]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -6861,18 +6875,33 @@ DEFUN (show_ip_bgp_summary,
        "Summary of BGP neighbor status\n"
        "JavaScript Object Notation\n")
 {
-  int idx_view_vrf = 3;
-  int idx_vrf = 4;
-  int idx_afi;
-  int idx_safi;
   char *vrf = NULL;
-  afi_t afi;
-  safi_t safi;
-  u_char uj = use_json(argc, argv);
-
-  vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
-  idx_safi = idx_afi + 1;
-  bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, NULL);
+  afi_t afi = AFI_IP6;
+  safi_t safi = SAFI_UNICAST;
+
+  int idx = 0;
+
+  /* show [ip] bgp */
+  if (argv_find (argv, argc, "ip", &idx))
+    afi = AFI_IP;
+  /* [<view|vrf> WORD] */
+  if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
+    vrf = argv[++idx]->arg;
+  /* [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] */
+  if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
+  {
+    afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+    if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
+      safi = strmatch (argv[idx]->text, "unicast") ? SAFI_UNICAST : SAFI_MULTICAST;
+  }
+  else if (argv_find (argv, argc, "encap", &idx) || argv_find (argv, argc, "vpnv4", &idx))
+  {
+    afi = AFI_IP;
+    safi = strmatch (argv[idx]->text, "encap") ? SAFI_ENCAP : SAFI_MPLS_VPN;
+    // advance idx if necessary
+    argv_find (argv, argc, "unicast", &idx);
+  }
+  int uj = use_json (argc, argv);
 
   return bgp_show_summary_vty (vty, vrf, afi, safi, uj);
 }
@@ -8889,7 +8918,7 @@ bgp_show_update_groups(struct vty *vty, const char *name,
 
 DEFUN (show_ip_bgp_updgrps,
        show_ip_bgp_updgrps_cmd,
-       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [unicast]|ipv6 [unicast]|encap [unicast]|ipv4 multicast|vpnv4 unicast>] update-groups [SUBGROUP-ID]",
+       "show [ip] bgp [<view|vrf> WORD] [<ipv4 [<unicast|multicast>]|ipv6 [<unicast|multicast>]|encap [unicast]|vpnv4 [unicast]>] update-groups [SUBGROUP-ID]",
        SHOW_STR
        IP_STR
        BGP_STR
@@ -8907,24 +8936,38 @@ DEFUN (show_ip_bgp_updgrps,
        "Detailed info about dynamic update groups\n"
        "Specific subgroup to display detailed info for\n")
 {
-  int idx_view_vrf = 3;
-  int idx_vrf = 4;
-  int idx_afi;
-  int idx_safi;
-  int idx_updgrp;
-  int idx_subgroup_id;
   char *vrf = NULL;
-  afi_t afi;
-  safi_t safi;
+  afi_t afi = AFI_IP6;
+  safi_t safi = SAFI_UNICAST;
   uint64_t subgrp_id = 0;
 
-  vrf = bgp_get_argv_vrf (argc, argv, &afi, &safi, &idx_view_vrf, &idx_vrf, &idx_afi);
-  idx_safi = idx_afi + 1;
-  bgp_get_argv_afi_safi (argc, argv, idx_afi, idx_safi, &afi, &safi, &idx_updgrp);
-  idx_subgroup_id = idx_updgrp + 1;
+  int idx = 0;
+
+  /* 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);
+  }
 
-  if (! strmatch(argv[idx_subgroup_id]->text, "update-groups"))
-    VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx_subgroup_id]->arg);
+  /* get subgroup id, if provided */
+  idx = argc - 1;
+  if (argv[idx]->type == VARIABLE_TKN)
+    VTY_GET_ULL("subgroup-id", subgrp_id, argv[idx]->arg);
 
   return (bgp_show_update_groups(vty, vrf, afi, safi, subgrp_id));
 }
index 914641724fbae3db28170eb36924ebb113b9eba9..3416bcd1c764839d411b73f3ac012402b5e5b816 100644 (file)
@@ -193,6 +193,26 @@ argv_concat (struct cmd_token **argv, int argc, int shift)
   return str;
 }
 
+/**
+ * Convenience function for accessing argv data.
+ *
+ * @param argc
+ * @param argv
+ * @param text definition snippet of the desired token
+ * @param index the starting index, and where to store the
+ *        index of the found token if it exists
+ * @return 1 if found, 0 otherwise
+ */
+int
+argv_find (struct cmd_token **argv, int argc, const char *text, int *index)
+{
+  int found = 0;
+  for (int i = *index; i < argc && found == 0; i++)
+    if ((found = strmatch (text, argv[i]->text)))
+      *index = i;
+  return found;
+}
+
 /* Install top node of command vector. */
 void
 install_node (struct cmd_node *node,
index aad0c6b3e6d6a76e3a1f3c20943156a2aa753865..0e2d27f19cdbbf2c0177ff214f3b756c03123234 100644 (file)
@@ -408,6 +408,7 @@ extern void install_element (enum node_type, struct cmd_element *);
    string with a space between each element (allocated using
    XMALLOC(MTYPE_TMP)).  Returns NULL if shift >= argc. */
 extern char *argv_concat (struct cmd_token **argv, int argc, int shift);
+extern int argv_find (struct cmd_token **argv, int argc, const char *text, int *index);
 
 extern vector cmd_make_strvec (const char *);
 extern void cmd_free_strvec (vector);