Dear all,

This small patch exposes the origin validation state in 'bgpctl show
rib' and 'bgpctl show rib detail'. This will help debugging, and draw
attention to routing problems.

I know we're weary of spending horizontal space, but I think spending 3
chars to show the OV state (and as such make it a first class citizen)
will be worth it. When I tried putting the ovs state in the 'flags'
column it just didn't look right.

Example output:

    $ bgpctl show rib
    flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
           S = Stale, E = Error
    origin validation state: N = not-found, V = valid, ! = invalid
    origin: i = IGP, e = EGP, ? = Incomplete

    flags ovs destination          gateway          lpref   med aspath origin
    *>      V 192.0.2.0/24         100.64.2.3         100     0 2 i
    *>      ! 192.0.2.0/26         100.64.2.3         100     0 2 i
    $ bgpctl show rib detail

    BGP routing table entry for 192.0.2.0/24
        2
        Nexthop 100.64.2.3 (via 100.64.2.3) from 100.64.2.3 (192.147.168.1)
        Origin IGP, metric 0, localpref 100, weight 0, ovs valid, external, 
valid, best
        Last update: 00:02:19 ago

    BGP routing table entry for 192.0.2.0/26
        2
        Nexthop 100.64.2.3 (via 100.64.2.3) from 100.64.2.3 (192.147.168.1)
        Origin IGP, metric 0, localpref 100, weight 0, ovs invalid, external, 
valid, best
        Last update: 00:02:19 ago

OK?

Kind regards,

Job

diff --git usr.sbin/bgpctl/bgpctl.c usr.sbin/bgpctl/bgpctl.c
index 7275ea6a2c4..70648ed8f5b 100644
--- usr.sbin/bgpctl/bgpctl.c
+++ usr.sbin/bgpctl/bgpctl.c
@@ -72,8 +72,9 @@ int            show_nexthop_msg(struct imsg *);
 void            show_interface_head(void);
 int             show_interface_msg(struct imsg *);
 void            show_rib_summary_head(void);
-void            print_prefix(struct bgpd_addr *, u_int8_t, u_int8_t);
+void            print_prefix(struct bgpd_addr *, u_int8_t, u_int8_t, u_int8_t);
 const char *    print_origin(u_int8_t, int);
+const char *    print_ovs(u_int8_t, int);
 void            print_flags(u_int8_t, int);
 int             show_rib_summary_msg(struct imsg *);
 int             show_rib_detail_msg(struct imsg *, int, int);
@@ -183,6 +184,7 @@ main(int argc, char *argv[])
                ribreq.neighbor = neighbor;
                ribreq.aid = res->aid;
                ribreq.flags = res->flags;
+               ribreq.validation_state = res->validation_state;
                show_mrt.arg = &ribreq;
                if (!(res->flags & F_CTL_DETAIL))
                        show_rib_summary_head();
@@ -1183,17 +1185,20 @@ show_rib_summary_head(void)
 {
        printf("flags: * = Valid, > = Selected, I = via IBGP, A = Announced,\n"
            "       S = Stale, E = Error\n");
+       printf("origin validation state: N = not-found, V = valid, ! = 
invalid\n");
        printf("origin: i = IGP, e = EGP, ? = Incomplete\n\n");
-       printf("%-5s %-20s %-15s  %5s %5s %s\n", "flags", "destination",
+       printf("%-5s %3s %-20s %-15s  %5s %5s %s\n", "flags", "ovs", 
"destination",
            "gateway", "lpref", "med", "aspath origin");
 }
 
 void
-print_prefix(struct bgpd_addr *prefix, u_int8_t prefixlen, u_int8_t flags)
+print_prefix(struct bgpd_addr *prefix, u_int8_t prefixlen, u_int8_t flags,
+    u_int8_t ovs)
 {
        char                    *p;
 
        print_flags(flags, 1);
+       printf("%3s ", print_ovs(ovs, 1));
        if (asprintf(&p, "%s/%u", log_addr(prefix), prefixlen) == -1)
                err(1, NULL);
        printf("%-20s", p);
@@ -1252,6 +1257,19 @@ print_flags(u_int8_t flags, int sum)
        }
 }
 
+const char *
+print_ovs(u_int8_t validation_state, int sum)
+{
+       switch (validation_state) {
+       case ROA_INVALID:
+               return (sum ? "!" : "invalid");
+       case ROA_VALID:
+               return (sum ? "V" : "valid");
+       default:
+               return (sum ? "N" : "not-found");
+       }
+}
+
 int
 show_rib_summary_msg(struct imsg *imsg)
 {
@@ -1309,7 +1327,7 @@ show_rib_brief(struct ctl_show_rib *r, u_char *asdata)
 {
        char                    *aspath;
 
-       print_prefix(&r->prefix, r->prefixlen, r->flags);
+       print_prefix(&r->prefix, r->prefixlen, r->flags, r->validation_state);
        printf(" %-15s ", log_addr(&r->exit_nexthop));
        printf(" %5u %5u ", r->local_pref, r->med);
 
@@ -1346,8 +1364,9 @@ show_rib_detail(struct ctl_show_rib *r, u_char *asdata, 
int nodescr, int flag0)
        id.s_addr = htonl(r->remote_id);
        printf("%s)%c", inet_ntoa(id), EOL0(flag0));
 
-       printf("    Origin %s, metric %u, localpref %u, weight %u, ",
-           print_origin(r->origin, 0), r->med, r->local_pref, r->weight);
+       printf("    Origin %s, metric %u, localpref %u, weight %u, ovs %s, ",
+           print_origin(r->origin, 0), r->med, r->local_pref, r->weight,
+           print_ovs(r->validation_state, 0));
        print_flags(r->flags, 0);
 
        now = time(NULL);
diff --git usr.sbin/bgpctl/parser.h usr.sbin/bgpctl/parser.h
index fd4847b199c..fd4e96f6efa 100644
--- usr.sbin/bgpctl/parser.h
+++ usr.sbin/bgpctl/parser.h
@@ -70,6 +70,7 @@ struct parse_result {
        char                     shutcomm[SHUT_COMM_LEN];
        char                    *irr_outdir;
        int                      flags;
+       u_int8_t                 validation_state;
        u_int                    rtableid;
        enum actions             action;
        u_int8_t                 prefixlen;
diff --git usr.sbin/bgpd/bgpd.h usr.sbin/bgpd/bgpd.h
index 8e6a4bcb2c7..2c4ba61d503 100644
--- usr.sbin/bgpd/bgpd.h
+++ usr.sbin/bgpd/bgpd.h
@@ -89,6 +89,15 @@
 #define        F_CTL_SSV               0x20000 /* only used by bgpctl */
 #define        F_CTL_INVALID           0x40000 /* only used by bgpctl */
 
+/*
+ * Note that these numeric assignments differ from the numbers commonly
+ * used in route origin validation context.
+ */
+#define        ROA_NOTFOUND            0x0     /* default */
+#define        ROA_INVALID             0x1
+#define        ROA_VALID               0x2
+#define        ROA_MASK                0x3
+
 /*
  * Limit the number of messages queued in the session engine.
  * The SE will send an IMSG_XOFF messages to the RDE if the high water mark
@@ -668,6 +677,7 @@ struct ctl_show_rib {
        u_int16_t               aspath_len;
        u_int8_t                prefixlen;
        u_int8_t                origin;
+       u_int8_t                validation_state;
        /* plus a aspath_len bytes long aspath */
 };
 
@@ -768,6 +778,7 @@ struct ctl_show_rib_request {
        struct filter_largecommunity large_community;
        u_int32_t               peerid;
        u_int32_t               flags;
+       u_int8_t                validation_state;
        pid_t                   pid;
        enum imsg_type          type;
        u_int8_t                prefixlen;
diff --git usr.sbin/bgpd/rde.c usr.sbin/bgpd/rde.c
index 8c4e2bdf017..871e419f53a 100644
--- usr.sbin/bgpd/rde.c
+++ usr.sbin/bgpd/rde.c
@@ -2177,6 +2177,7 @@ rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, 
pid_t pid, int flags)
        pt_getaddr(p->re->prefix, &rib.prefix);
        rib.prefixlen = p->re->prefix->prefixlen;
        rib.origin = asp->origin;
+       rib.validation_state = p->validation_state;
        rib.flags = 0;
        if (p->re->active == p)
                rib.flags |= F_PREF_ACTIVE;
diff --git usr.sbin/bgpd/rde.h usr.sbin/bgpd/rde.h
index 69962d83585..76e78865e76 100644
--- usr.sbin/bgpd/rde.h
+++ usr.sbin/bgpd/rde.h
@@ -36,11 +36,6 @@ enum peer_state {
        PEER_ERR        /* error occurred going to PEER_DOWN state */
 };
 
-#define        ROA_NOTFOUND    0x0     /* default */
-#define        ROA_INVALID     0x1
-#define        ROA_VALID       0x2
-#define        ROA_MASK        0x3
-
 /*
  * How do we identify peers between the session handler and the rde?
  * Currently I assume that we can do that with the neighbor_ip...

Reply via email to