From: Paul Jakma <paul.jakma@sun.com>
Date: Thu, 4 Sep 2008 22:27:13 +0000 (+0100)
Subject: [bgp/pgbgp] Add some pgbgp commands to restricted-mode and other command tweaks
X-Git-Url: http://git.ozo.com/?p=quagga-pgbg.git;a=commitdiff_plain;h=06ac72f9f6021635e9e1e5105c3e22bf7eb0d6c3

[bgp/pgbgp] Add some pgbgp commands to restricted-mode and other command tweaks

* bgp_pgbgp.c:
  (edge_neighbor_iterator) make ASN==0 mean 'iterate over all ASNs'
  (bgp_pgbgp_stats_origin_one) new function, to display one origin AS status.
  (bgp_pgbgp_stats_origins) adapt to use previous.
  Adapt to iterate over all stats if no prefix was giving.
  (show_ip_bgp_pgbgp_neighbors_cmd) recognise no ASN argument case
  (show_ip_bgp_pgbgp_neighbors_all_cmd) Iterate over all
  (show_ip_bgp_pgbgp_origins_cmd) similar
  (show_ip_bgp_pgbgp_origins_all_cmd)
  (bgp_pgbgp_enable) install the lookup commands to ther new RESTRICTED_NODE
* bgp_route.c:
  (route_vty_short_status_out) only allowed to print one char for anomalous
  status.
  (route_vty_out_detail) Add support for printing out more detail on
  PG-BGP status
---

--- a/bgpd/bgp_pgbgp.c
+++ b/bgpd/bgp_pgbgp.c
@@ -227,7 +227,7 @@ static void
 edge_neighbor_iterator (struct hash_backet *backet, struct nsearch *pns)
 {
   struct bgp_pgbgp_edge *hedge = backet->data;
-  if ((hedge->e.a == pns->asn || hedge->e.b == pns->asn)
+  if ((!pns->asn || hedge->e.a == pns->asn || hedge->e.b == pns->asn)
       && hedge->e.a != hedge->e.b)
     {
       struct vty *vty = pns->pvty;
@@ -254,13 +254,39 @@ bgp_pgbgp_stats_neighbors (struct vty *v
   return CMD_SUCCESS;
 }
 
+static void
+bgp_pgbgp_stats_origin_one (struct vty *vty, struct bgp_node *rn,
+                            time_t t_now)
+{
+  char str[INET6_BUFSIZ];
+  
+  if (!rn->hist)
+    return;
+  
+  prefix2str (&rn->p, str, sizeof(str));
+  vty_out (vty, "%s%s", str, VTY_NEWLINE);
+  
+  for (struct bgp_pgbgp_origin * cur = rn->hist->o; cur != NULL;
+       cur = cur->next)
+    {
+      if (cur->deprefUntil > t_now)
+        vty_out (vty, "Untrusted Origin AS: %d%s", cur->originAS,
+                 VTY_NEWLINE);
+      else
+        vty_out (vty, "Trusted Origin AS: %d%s", cur->originAS,
+                 VTY_NEWLINE);
+    } 
+}
+
 static int
 bgp_pgbgp_stats_origins (struct vty *vty, afi_t afi, safi_t safi,
                          const char *prefix)
 {
   struct bgp *bgp;
   struct bgp_table *table;
+  struct bgp_node *rn;
   time_t t_now = time (NULL);
+  
   bgp = bgp_get_default ();
   if (bgp == NULL)
     return CMD_WARNING;
@@ -269,28 +295,22 @@ bgp_pgbgp_stats_origins (struct vty *vty
   table = bgp->rib[afi][safi];
   if (table == NULL)
     return CMD_WARNING;
-
-  struct prefix p;
-  str2prefix (prefix, &p);
-  struct bgp_node *rn = bgp_node_match (table, &p);
-  vty_out (vty, "%s%s", prefix, VTY_NEWLINE);
-  if (rn)
+  
+  if (prefix)
     {
+      struct prefix p;
+      str2prefix (prefix, &p);
+      rn = bgp_node_match (table, &p);
       if (rn->hist)
-        {
-          for (struct bgp_pgbgp_origin * cur = rn->hist->o; cur != NULL;
-               cur = cur->next)
-            {
-              if (cur->deprefUntil > t_now)
-                vty_out (vty, "Untrusted Origin AS: %d%s", cur->originAS,
-                         VTY_NEWLINE);
-              else
-                vty_out (vty, "Trusted Origin AS: %d%s", cur->originAS,
-                         VTY_NEWLINE);
-            }
-        }
+        bgp_pgbgp_stats_origin_one (vty, rn, t_now);
       bgp_unlock_node (rn);
+      return CMD_SUCCESS;
     }
+  
+  for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+    if (rn->hist)
+      bgp_pgbgp_stats_origin_one (vty, rn, t_now);
+
   return CMD_SUCCESS;
 }
 
@@ -377,7 +397,7 @@ bgp_pgbgp_stats (struct vty *vty, afi_t
 DEFUN (show_ip_bgp_pgbgp,
        show_ip_bgp_pgbgp_cmd,
        "show ip bgp pgbgp",
-       SHOW_STR IP_STR BGP_STR "Display PGBGP statistics\n")
+       SHOW_STR IP_STR BGP_STR "Pretty-Good BGP statistics\n")
 {
   return bgp_pgbgp_stats (vty, AFI_IP, SAFI_UNICAST);
 }
@@ -385,29 +405,46 @@ DEFUN (show_ip_bgp_pgbgp,
 DEFUN (show_ip_bgp_pgbgp_neighbors,
        show_ip_bgp_pgbgp_neighbors_cmd,
        "show ip bgp pgbgp neighbors WORD",
-       SHOW_STR
-       IP_STR
-       BGP_STR
-       "BGP pgbgp\n"
-       "BGP pgbgp neighbors\n" "ASN whos neighbors should be displayed\n")
+       SHOW_STR IP_STR BGP_STR
+       "Pretty-Good BGP statistics\n"
+       "PG-BGP neighbor information\n"
+       "AS to show neighbors of\n")
 {
   return bgp_pgbgp_stats_neighbors (vty, AFI_IP, SAFI_UNICAST,
-                                    atoi (argv[0]));
+                                    argc == 1 ? atoi (argv[0]) : 0);
 }
 
+ALIAS (show_ip_bgp_pgbgp_neighbors,
+       show_ip_bgp_pgbgp_neighbors_all_cmd,
+       "show ip bgp pgbgp neighbors",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       "Pretty-Good BGP statistics\n"
+       "PG-BGP neighbors information\n")
+
 DEFUN (show_ip_bgp_pgbgp_origins,
        show_ip_bgp_pgbgp_origins_cmd,
        "show ip bgp pgbgp origins A.B.C.D/M",
        SHOW_STR
        IP_STR
        BGP_STR
-       "BGP pgbgp\n"
-       "BGP pgbgp neighbors\n" "Prefix to look up origin ASes of\n")
+       "Pretty-Good BGP statistics\n"
+       "PG-BGP prefix origin information\n"
+       "Prefix to look up origin ASes of\n")
 {
-  return bgp_pgbgp_stats_origins (vty, AFI_IP, SAFI_UNICAST, argv[0]);
+  return bgp_pgbgp_stats_origins (vty, AFI_IP, SAFI_UNICAST,
+                                  argc == 1 ? argv[0] : NULL);
 }
 
-
+ALIAS (show_ip_bgp_pgbgp_origins,
+       show_ip_bgp_pgbgp_origins_all_cmd,
+       "show ip bgp pgbgp origins",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       "Pretty-Good BGP statistics\n"
+       "PG-BGP prefixes origin information")
 
 
 /*! --------------- VTY (others exist in bgp_route.c)  ------------------ !*/
@@ -749,12 +786,19 @@ bgp_pgbgp_enable (struct bgp *bgp, afi_t
   pgbgp->lastgc = time (NULL);
   pgbgp->lastStore = time (NULL);
   pgbgp->startTime = time (NULL);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_pgbgp_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_pgbgp_neighbors_cmd);
+  install_element (RESTRICTED_NODE, &show_ip_bgp_pgbgp_origins_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_pgbgp_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_pgbgp_neighbors_cmd);
-  install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_neighbors_cmd);
   install_element (VIEW_NODE, &show_ip_bgp_pgbgp_origins_cmd);
+  install_element (VIEW_NODE, &show_ip_bgp_pgbgp_neighbors_all_cmd);
+  install_element (VIEW_NODE, &show_ip_bgp_pgbgp_origins_all_cmd);
+  install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_cmd);
+  install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_neighbors_cmd);
   install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_origins_cmd);
+  install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_neighbors_all_cmd);
+  install_element (ENABLE_NODE, &show_ip_bgp_pgbgp_origins_all_cmd);
   pgbgp->edgeT = hash_create_size (131072, edge_key_make, edge_cmp);
   bgp_pgbgp_restore ();
   return 0;
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -5597,20 +5597,6 @@ enum bgp_display_type
 static void
 route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo)
 {
-  if (ANOMALOUS(binfo->flags))
-    {
-      vty_out(vty, "a[");
-      if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_P))
-	vty_out(vty, "i");
-      if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_O))
-	vty_out(vty, "p");
-      if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_E))
-	vty_out(vty, "e");
-      if (CHECK_FLAG(binfo->flags, BGP_INFO_IGNORED_P))
-	vty_out(vty, "s");
-      vty_out(vty, "] ");
-    }
-
  /* Route status display. */
   if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
     vty_out (vty, "R");
@@ -5626,6 +5612,17 @@ route_vty_short_status_out (struct vty *
   /* Selected */
   if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
     vty_out (vty, "h");
+  else if (ANOMALOUS(binfo->flags))
+    {
+      if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_O)) 
+        vty_out(vty, "p");
+      else if (CHECK_FLAG(binfo->flags, BGP_INFO_IGNORED_P))
+        vty_out(vty, "P");
+      else if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_P))
+        vty_out(vty, "a");
+      if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_E))
+        vty_out(vty, "a");
+    }
   else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
     vty_out (vty, "d");
   else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
@@ -6104,7 +6101,22 @@ route_vty_out_detail (struct vty *vty, s
       if (binfo->extra && binfo->extra->damp_info)
 	bgp_damp_info_vty (vty, binfo);
 
-      /* Line 7 display Uptime */
+      /* 8: PGBGP status */
+      if (ANOMALOUS(binfo->flags))
+        {
+	  vty_out (vty, "      Anomalous:");
+	  if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_P))
+	    vty_out (vty, " divergent sub-prefixes,");
+	  if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_O))
+	    vty_out (vty, " origin AS (prefix hijack?),");
+	  if (CHECK_FLAG(binfo->flags, BGP_INFO_SUSPICIOUS_E))
+	    vty_out (vty, " new edge in path,");
+	  if (CHECK_FLAG(binfo->flags, BGP_INFO_IGNORED_P))
+	    vty_out (vty, " origin AS (sub-prefix hijack?),");
+	  vty_out (vty, "%s", VTY_NEWLINE);
+	} 
+
+      /* Line 9 display Uptime */	
 #ifdef HAVE_CLOCK_MONOTONIC
       tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
       vty_out (vty, "      Last update: %s", ctime(&tbuf));
@@ -6115,8 +6127,9 @@ route_vty_out_detail (struct vty *vty, s
   vty_out (vty, "%s", VTY_NEWLINE);
 }  
 
-#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s              r RIB-failure, S Stale, R Removed%s"
-#define BGP_SHOW_PCODE_HEADER "Status code: a (anomalous) of:  [p] prefix hijack, [s] sub-prefix hijack,%s              [i] informant of sub-prefix [e] new edge%s"
+#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s" \
+  "              r RIB-failure, S Stale, R Removed, %s" \
+  "              p prefix hijack, P sub-prefix hijack, a other anomaly%s"
 #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s"
 #define BGP_SHOW_HEADER "   Network          Next Hop            Metric LocPrf Weight Path%s"
 #define BGP_SHOW_DAMP_HEADER "   Network          From             Reuse    Path%s"
@@ -6325,8 +6338,7 @@ bgp_show_table (struct vty *vty, struct
 	    if (header)
 	      {
 		vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*router_id), VTY_NEWLINE);
-		vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
-		vty_out (vty, BGP_SHOW_PCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
+		vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
 		vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
 		if (type == bgp_show_type_dampend_paths
 		    || type == bgp_show_type_damp_neighbor)
@@ -9858,7 +9870,7 @@ show_adj_route (struct vty *vty, struct
 			  PEER_STATUS_DEFAULT_ORIGINATE))
     {
       vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
-      vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
+      vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
       vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
 
       vty_out (vty, "Originating default network 0.0.0.0%s%s",
@@ -9875,7 +9887,7 @@ show_adj_route (struct vty *vty, struct
 	      if (header1)
 		{
 		  vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
-		  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
+		  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
 		  vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
 		  header1 = 0;
 		}
@@ -9899,7 +9911,7 @@ show_adj_route (struct vty *vty, struct
 	      if (header1)
 		{
 		  vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
-		  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
+		  vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
 		  vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
 		  header1 = 0;
 		}