]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Report capabilities in show protocols all
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 20 Dec 2016 16:39:59 +0000 (17:39 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 20 Dec 2016 16:39:59 +0000 (17:39 +0100)
proto/bgp/bgp.c
proto/bgp/bgp.h
proto/bgp/packets.c

index b7229429c665fe0dd96dcf2d735c51cc1587eda2..5df2e38df27a7af3428c0480285710e24e3656a5 100644 (file)
@@ -1756,11 +1756,118 @@ bgp_get_status(struct proto *P, byte *buf)
     bsprintf(buf, "%-14s%s%s", bgp_state_dsc(p), err1, err2);
 }
 
+static void
+bgp_show_afis(int code, char *s, u32 *afis, uint count)
+{
+  buffer b;
+  LOG_BUFFER_INIT(b);
+
+  buffer_puts(&b, s);
+
+  for (u32 *af = afis; af < (afis + count); af++)
+  {
+    const struct bgp_af_desc *desc = bgp_get_af_desc(*af);
+    if (desc)
+      buffer_print(&b, " %s", desc->name);
+    else
+      buffer_print(&b, " <%u/%u>", BGP_AFI(*af), BGP_SAFI(*af));
+  }
+
+  if (b.pos == b.end)
+    strcpy(b.end - 32, " ... <too long>");
+
+  cli_msg(code, b.start);
+}
+
+static void
+bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps)
+{
+  struct bgp_af_caps *ac;
+  uint any_mp_bgp = 0;
+  uint any_gr_able = 0;
+  uint any_add_path = 0;
+  u32 *afl1 = alloca(caps->af_count * sizeof(u32));
+  u32 *afl2 = alloca(caps->af_count * sizeof(u32));
+  uint afn1, afn2;
+
+  WALK_AF_CAPS(caps, ac)
+  {
+    any_mp_bgp |= ac->ready;
+    any_gr_able |= ac->gr_able;
+    any_add_path |= ac->add_path;
+  }
+
+  if (any_mp_bgp)
+  {
+    cli_msg(-1006, "      Multiprotocol");
+
+    afn1 = 0;
+    WALK_AF_CAPS(caps, ac)
+      if (ac->ready)
+       afl1[afn1++] = ac->afi;
+
+    bgp_show_afis(-1006, "        AF announced:", afl1, afn1);
+  }
+
+  if (caps->route_refresh)
+    cli_msg(-1006, "      Route refresh");
+
+  if (caps->ext_messages)
+    cli_msg(-1006, "      Extended message");
+
+  if (caps->gr_aware)
+    cli_msg(-1006, "      Graceful restart");
+
+  if (any_gr_able)
+  {
+    /* Continues from gr_aware */
+    cli_msg(-1006, "        Restart time: %u", caps->gr_time);
+    if (caps->gr_flags & BGP_GRF_RESTART)
+      cli_msg(-1006, "        Restart recovery");
+
+    afn1 = afn2 = 0;
+    WALK_AF_CAPS(caps, ac)
+    {
+      if (ac->gr_able)
+       afl1[afn1++] = ac->afi;
+
+      if (ac->gr_af_flags & BGP_GRF_FORWARDING)
+       afl2[afn2++] = ac->afi;
+    }
+
+    bgp_show_afis(-1006, "        AF supported:", afl1, afn1);
+    bgp_show_afis(-1006, "        AF preserved:", afl2, afn2);
+  }
+
+  if (caps->as4_support)
+    cli_msg(-1006, "      4-octet AS numbers");
+
+  if (any_add_path)
+  {
+    cli_msg(-1006, "      ADD-PATH");
+
+    afn1 = afn2 = 0;
+    WALK_AF_CAPS(caps, ac)
+    {
+      if (ac->add_path & BGP_ADD_PATH_RX)
+       afl1[afn1++] = ac->afi;
+
+      if (ac->add_path & BGP_ADD_PATH_TX)
+       afl2[afn2++] = ac->afi;
+    }
+
+    bgp_show_afis(-1006, "        RX:", afl1, afn1);
+    bgp_show_afis(-1006, "        TX:", afl2, afn2);
+  }
+
+  if (caps->enhanced_refresh)
+    cli_msg(-1006, "      Enhanced refresh");
+}
+
 static void
 bgp_show_proto_info(struct proto *P)
 {
   struct bgp_proto *p = (struct bgp_proto *) P;
-  struct bgp_conn *c = p->conn;
 
   cli_msg(-1006, "  BGP state:          %s", bgp_state_dsc(p));
   cli_msg(-1006, "    Neighbor address: %I%J", p->cf->remote_ip, p->cf->iface);
@@ -1789,15 +1896,11 @@ bgp_show_proto_info(struct proto *P)
   else if (P->proto_state == PS_UP)
   {
     cli_msg(-1006, "    Neighbor ID:      %R", p->remote_id);
+    cli_msg(-1006, "    Local capabilities");
+    bgp_show_capabilities(p, p->conn->local_caps);
+    cli_msg(-1006, "    Neighbor capabilities");
+    bgp_show_capabilities(p, p->conn->remote_caps);
 /* XXXX
-      cli_msg(-1006, "    Neighbor caps:   %s%s%s%s%s%s%s",
-             c->peer_refresh_support ? " refresh" : "",
-             c->peer_enhanced_refresh_support ? " enhanced-refresh" : "",
-             c->peer_gr_able ? " restart-able" : (c->peer_gr_aware ? " restart-aware" : ""),
-             c->peer_as4_support ? " AS4" : "",
-             (c->peer_add_path & ADD_PATH_RX) ? " add-path-rx" : "",
-             (c->peer_add_path & ADD_PATH_TX) ? " add-path-tx" : "",
-             c->peer_ext_messages_support ? " ext-messages" : "");
       cli_msg(-1006, "    Session:          %s%s%s%s%s%s%s%s",
              p->is_internal ? "internal" : "external",
              p->cf->multihop ? " multihop" : "",
@@ -1810,9 +1913,9 @@ bgp_show_proto_info(struct proto *P)
 */
     cli_msg(-1006, "    Source address:   %I", p->source_addr);
     cli_msg(-1006, "    Hold timer:       %d/%d",
-           tm_remains(c->hold_timer), c->hold_time);
+           tm_remains(p->conn->hold_timer), p->conn->hold_time);
     cli_msg(-1006, "    Keepalive timer:  %d/%d",
-           tm_remains(c->keepalive_timer), c->keepalive_time);
+           tm_remains(p->conn->keepalive_timer), p->conn->keepalive_time);
   }
 
   if ((p->last_error_class != BE_NONE) &&
index db9ee8ea0d95a469ee0468fc8df279009490e8b1..a8a0494732ebbb915eb4e36f3907734882ee7380 100644 (file)
@@ -174,6 +174,10 @@ struct bgp_caps {
   struct bgp_af_caps af_data[0];       /* Per-AF capability data */
 };
 
+#define WALK_AF_CAPS(caps,ac) \
+  for (ac = caps->af_data; ac < &caps->af_data[caps->af_count]; ac++)
+
+
 struct bgp_socket {
   node n;                              /* Node in global bgp_sockets */
   sock *sk;                            /* Real listening socket */
index 1ae75a644e05cf764c5130a4abc85521ca457048..43149a0c592a0301b3e74f67f39246728e926291 100644 (file)
@@ -185,9 +185,6 @@ bgp_create_notification(struct bgp_conn *conn, byte *buf)
 
 /* Capability negotiation as per RFC 5492 */
 
-#define WALK_AF_CAPS(caps,ac) \
-  for (ac = caps->af_data; ac < &caps->af_data[caps->af_count]; ac++)
-
 const struct bgp_af_caps *
 bgp_find_af_caps(struct bgp_caps *caps, u32 afi)
 {