Add `bgpctl show rtr` to display basic information about RTR sessions.
authorclaudio <claudio@openbsd.org>
Tue, 16 Feb 2021 08:30:21 +0000 (08:30 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 16 Feb 2021 08:30:21 +0000 (08:30 +0000)
OK job@

usr.sbin/bgpctl/bgpctl.8
usr.sbin/bgpctl/bgpctl.c
usr.sbin/bgpctl/bgpctl.h
usr.sbin/bgpctl/output.c
usr.sbin/bgpctl/output_json.c
usr.sbin/bgpctl/parser.c
usr.sbin/bgpctl/parser.h

index 4b61250..dab1dda 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpctl.8,v 1.95 2020/05/10 13:38:46 deraadt Exp $
+.\" $OpenBSD: bgpctl.8,v 1.96 2021/02/16 08:30:21 claudio Exp $
 .\"
 .\" Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
 .\"
@@ -14,7 +14,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: May 10 2020 $
+.Dd $Mdocdate: February 16 2021 $
 .Dt BGPCTL 8
 .Os
 .Sh NAME
@@ -33,7 +33,7 @@ program controls the
 .Xr bgpd 8
 daemon.
 Commands may be abbreviated to the minimum unambiguous prefix; for example,
-.Cm s s
+.Cm s su
 for
 .Cm show summary .
 .Pp
@@ -409,6 +409,18 @@ or
 Multiple options can be used at the same time and the
 .Ar neighbor
 filter can be combined with other filters.
+.It Cm show rtr
+Show a list of all
+.Em RTR
+sessions, including information about the session state.
+.It Cm show sets
+Show a list summarizing all
+.Em roa-set ,
+.Em as-set ,
+.Em prefix-set ,
+and
+.Em origin-set
+tables.
 .It Cm show summary
 Show a list of all neighbors, including information about the session state
 and message counters:
index a35a1ee..954abd7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpctl.c,v 1.264 2020/12/30 07:31:19 claudio Exp $ */
+/*     $OpenBSD: bgpctl.c,v 1.265 2021/02/16 08:30:21 claudio Exp $ */
 
 /*
  * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -216,6 +216,9 @@ main(int argc, char *argv[])
        case SHOW_SET:
                imsg_compose(ibuf, IMSG_CTL_SHOW_SET, 0, 0, -1, NULL, 0);
                break;
+       case SHOW_RTR:
+               imsg_compose(ibuf, IMSG_CTL_SHOW_RTR, 0, 0, -1, NULL, 0);
+               break;
        case SHOW_NEIGHBOR:
        case SHOW_NEIGHBOR_TIMERS:
        case SHOW_NEIGHBOR_TERSE:
@@ -393,18 +396,19 @@ int
 show(struct imsg *imsg, struct parse_result *res)
 {
        struct peer             *p;
-       struct ctl_timer        *t;
+       struct ctl_timer         t;
        struct ctl_show_interface       *iface;
        struct ctl_show_nexthop *nh;
-       struct ctl_show_set     *set;
+       struct ctl_show_set      set;
+       struct ctl_show_rtr      rtr;
        struct kroute_full      *kf;
        struct ktable           *kt;
        struct ctl_show_rib      rib;
+       struct rde_memstats      stats;
+       struct rde_hashstats     hash;
        u_char                  *asdata;
-       struct rde_memstats     stats;
-       struct rde_hashstats    hash;
-       u_int                   rescode, ilen;
-       size_t                  aslen;
+       u_int                    rescode, ilen;
+       size_t                   aslen;
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_NEIGHBOR:
@@ -412,9 +416,11 @@ show(struct imsg *imsg, struct parse_result *res)
                output->neighbor(p, res);
                break;
        case IMSG_CTL_SHOW_TIMER:
-               t = imsg->data;
-               if (t->type > 0 && t->type < Timer_Max)
-                       output->timer(t);
+               if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(t))
+                       errx(1, "wrong imsg len");
+               memcpy(&t, imsg->data, sizeof(t));
+               if (t.type > 0 && t.type < Timer_Max)
+                       output->timer(&t);
                break;
        case IMSG_CTL_SHOW_INTERFACE:
                iface = imsg->data;
@@ -463,16 +469,28 @@ show(struct imsg *imsg, struct parse_result *res)
                output->attr(imsg->data, ilen, res);
                break;
        case IMSG_CTL_SHOW_RIB_MEM:
+               if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(stats))
+                       errx(1, "wrong imsg len");
                memcpy(&stats, imsg->data, sizeof(stats));
                output->rib_mem(&stats);
                break;
        case IMSG_CTL_SHOW_RIB_HASH:
+               if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(hash))
+                       errx(1, "wrong imsg len");
                memcpy(&hash, imsg->data, sizeof(hash));
                output->rib_hash(&hash);
                break;
        case IMSG_CTL_SHOW_SET:
-               set = imsg->data;
-               output->set(set);
+               if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(set))
+                       errx(1, "wrong imsg len");
+               memcpy(&set, imsg->data, sizeof(set));
+               output->set(&set);
+               break;
+       case IMSG_CTL_SHOW_RTR:
+               if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(rtr))
+                       errx(1, "wrong imsg len");
+               memcpy(&rtr, imsg->data, sizeof(rtr));
+               output->rtr(&rtr);
                break;
        case IMSG_CTL_RESULT:
                if (imsg->hdr.len != IMSG_HEADER_SIZE + sizeof(rescode)) {
index a3fe10c..3261faa 100644 (file)
@@ -31,6 +31,7 @@ struct output {
        void    (*rib_hash)(struct rde_hashstats *);
        void    (*rib_mem)(struct rde_memstats *);
        void    (*set)(struct ctl_show_set *);
+       void    (*rtr)(struct ctl_show_rtr *);
        void    (*result)(u_int);
        void    (*tail)(void);
 };
index f986fd3..37646a8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: output.c,v 1.12 2021/01/25 09:17:33 claudio Exp $ */
+/*     $OpenBSD: output.c,v 1.13 2021/02/16 08:30:21 claudio Exp $ */
 
 /*
  * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -266,7 +266,7 @@ show_neighbor_full(struct peer *p, struct parse_result *res)
        if (p->conf.down) {
                printf(", marked down");
        }
-       if (*(p->conf.reason)) {
+       if (p->conf.reason[0]) {
                printf(" with shutdown reason \"%s\"",
                    log_reason(p->conf.reason));
        }
@@ -301,7 +301,7 @@ show_neighbor_full(struct peer *p, struct parse_result *res)
 
        show_neighbor_msgstats(p);
        printf("\n");
-       if (*(p->stats.last_reason)) {
+       if (p->stats.last_reason[0]) {
                printf("  Last received shutdown reason: \"%s\"\n",
                    log_reason(p->stats.last_reason));
        }
@@ -977,6 +977,45 @@ show_rib_set(struct ctl_show_set *set)
            buf, fmt_monotime(set->lastchange));
 }
 
+static void
+show_rtr(struct ctl_show_rtr *rtr)
+{
+       static int not_first;
+
+       if (not_first)
+               printf("\n");
+       not_first = 1;
+
+       printf("RTR neighbor is %s, port %u\n",
+           log_addr(&rtr->remote_addr), rtr->remote_port);
+       if (rtr->descr[0])
+               printf(" Description: %s\n", rtr->descr);
+       if (rtr->local_addr.aid != AID_UNSPEC)
+               printf(" Local Address: %s\n", log_addr(&rtr->local_addr));
+       if (rtr->session_id != -1)
+               printf (" Session ID: %d Serial #: %u\n",
+                   rtr->session_id, rtr->serial);
+       printf(" Refresh: %u, Retry: %u, Expire: %u\n",
+           rtr->refresh, rtr->retry, rtr->expire);
+
+       if (rtr->last_sent_error != NO_ERROR) {
+               printf(" Last sent error: %s\n",
+                 log_rtr_error(rtr->last_sent_error));
+               if (rtr->last_sent_msg[0])
+                       printf(" with reason \"%s\"",
+                           log_reason(rtr->last_sent_msg));
+       }
+       if (rtr->last_recv_error != NO_ERROR) {
+               printf("Last received error: %s\n",
+                 log_rtr_error(rtr->last_recv_error));
+               if (rtr->last_recv_msg[0])
+                       printf(" with reason \"%s\"",
+                           log_reason(rtr->last_recv_msg));
+       }
+
+       printf("\n");
+}
+
 static void
 show_result(u_int rescode)
 {
@@ -1009,6 +1048,7 @@ const struct output show_output = {
        .rib_mem = show_rib_mem,
        .rib_hash = show_rib_hash,
        .set = show_rib_set,
+       .rtr = show_rtr,
        .result = show_result,
        .tail = show_tail
 };
index 0e31768..541685b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: output_json.c,v 1.6 2021/01/25 09:17:33 claudio Exp $ */
+/*     $OpenBSD: output_json.c,v 1.7 2021/02/16 08:30:21 claudio Exp $ */
 
 /*
  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
@@ -202,10 +202,10 @@ json_neighbor_full(struct peer *p)
        json_neighbor_stats(p);
 
        /* errors */
-       if (*(p->conf.reason))
+       if (p->conf.reason[0])
                json_do_printf("my_shutdown_reason", "%s",
                    log_reason(p->conf.reason));
-       if (*(p->stats.last_reason))
+       if (p->stats.last_reason[0])
                json_do_printf("last_shutdown_reason", "%s",
                    log_reason(p->stats.last_reason));
        errstr = fmt_errstr(p->stats.last_sent_errcode,
@@ -936,6 +936,43 @@ json_rib_set(struct ctl_show_set *set)
        json_do_end();
 }
 
+static void
+json_rtr(struct ctl_show_rtr *rtr)
+{
+       json_do_array("rtrs");
+
+       json_do_object("rtr");
+       if (rtr->descr[0])
+               json_do_printf("descr", "%s", rtr->descr);
+       json_do_printf("remote_addr", "%s", log_addr(&rtr->remote_addr));
+       json_do_uint("remote_port", rtr->remote_port);
+       if (rtr->local_addr.aid != AID_UNSPEC)
+               json_do_printf("local_addr", "%s", log_addr(&rtr->local_addr));
+
+       if (rtr->session_id != -1) {
+               json_do_uint("session_id", rtr->session_id);
+               json_do_uint("serial", rtr->serial);
+       }
+       json_do_uint("refresh", rtr->refresh);
+       json_do_uint("retry", rtr->retry);
+       json_do_uint("expire", rtr->expire);
+
+       if (rtr->last_sent_error != NO_ERROR) {
+               json_do_printf("last_sent_error", "%s",
+                   log_rtr_error(rtr->last_sent_error));
+               if (rtr->last_sent_msg[0])
+                       json_do_printf("last_sent_msg", "%s",
+                           log_reason(rtr->last_sent_msg));
+       }
+       if (rtr->last_recv_error != NO_ERROR) {
+               json_do_printf("last_recv_error", "%s",
+                   log_rtr_error(rtr->last_recv_error));
+               if (rtr->last_recv_msg[0])
+                       json_do_printf("last_recv_msg", "%s",
+                           log_reason(rtr->last_recv_msg));
+       }
+}
+
 static void
 json_result(u_int rescode)
 {
@@ -971,6 +1008,7 @@ const struct output json_output = {
        .rib_mem = json_rib_mem,
        .rib_hash = json_rib_hash,
        .set = json_rib_set,
+       .rtr = json_rtr,
        .result = json_result,
        .tail = json_tail
 };
index 7a98e6d..5b5e94b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.c,v 1.105 2020/12/30 07:31:19 claudio Exp $ */
+/*     $OpenBSD: parser.c,v 1.106 2021/02/16 08:30:21 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -137,6 +137,7 @@ static const struct token t_show[] = {
        { KEYWORD,      "ip",           NONE,           t_show_ip},
        { KEYWORD,      "summary",      SHOW_SUMMARY,   t_show_summary},
        { KEYWORD,      "sets",         SHOW_SET,       NULL},
+       { KEYWORD,      "rtr",          SHOW_RTR,       NULL},
        { KEYWORD,      "mrt",          SHOW_MRT,       t_show_mrt},
        { ENDTOKEN,     "",             NONE,           NULL}
 };
index 2e63506..3108050 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parser.h,v 1.39 2020/12/30 07:31:19 claudio Exp $ */
+/*     $OpenBSD: parser.h,v 1.40 2021/02/16 08:30:21 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -33,6 +33,7 @@ enum actions {
        SHOW_RIB,
        SHOW_MRT,
        SHOW_SET,
+       SHOW_RTR,
        SHOW_RIB_MEM,
        SHOW_NEXTHOP,
        SHOW_INTERFACE,