This is the bgpd diff that allows bgpctl to show invalid / error paths
which act as an implicit withdraw.

While there also fix 'bgpctl show rib in nei foo' since until now that
code actually printed the same as 'bgpctl show rib nei foo'.

The code is a bit shuffled to make the if statement in rde_dump_filter()
simpler.

OK?
-- 
:wq Claudio

? obj
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.330
diff -u -p -r1.330 bgpd.h
--- bgpd.h      9 Aug 2018 21:12:33 -0000       1.330
+++ bgpd.h      29 Aug 2018 11:03:57 -0000
@@ -87,6 +87,7 @@
 #define        F_CTL_ACTIVE            0x8000
 #define        F_RTLABEL               0x10000
 #define        F_CTL_SSV               0x20000 /* only used by bgpctl */
+#define        F_CTL_INVALID           0x40000 /* only used by bgpctl */
 
 /*
  * Limit the number of messages queued in the session engine.
@@ -612,6 +613,7 @@ struct ctl_neighbor {
 #define        F_PREF_INTERNAL 0x04
 #define        F_PREF_ANNOUNCE 0x08
 #define        F_PREF_STALE    0x10
+#define        F_PREF_INVALID  0x20
 
 struct ctl_show_rib {
        struct bgpd_addr        true_nexthop;
@@ -712,8 +714,8 @@ struct ctl_show_rib_request {
        struct filter_extcommunity extcommunity;
        struct filter_largecommunity large_community;
        u_int32_t               peerid;
+       u_int32_t               flags;
        pid_t                   pid;
-       u_int16_t               flags;
        enum imsg_type          type;
        u_int8_t                prefixlen;
        u_int8_t                aid;
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.414
diff -u -p -r1.414 rde.c
--- rde.c       9 Aug 2018 12:54:06 -0000       1.414
+++ rde.c       29 Aug 2018 11:03:57 -0000
@@ -2081,6 +2081,8 @@ rde_dump_rib_as(struct prefix *p, struct
                rib.flags |= F_PREF_ELIGIBLE;
        if (asp->flags & F_ATTR_LOOP)
                rib.flags &= ~F_PREF_ELIGIBLE;
+       if (asp->flags & F_ATTR_PARSE_ERR)
+               rib.flags |= F_PREF_INVALID;
        staletime = prefix_peer(p)->staletime[p->re->prefix->aid];
        if (staletime && p->lastchange <= staletime)
                rib.flags |= F_PREF_STALE;
@@ -2142,11 +2144,24 @@ rde_dump_filter(struct prefix *p, struct
        struct rde_peer         *peer;
        struct rde_aspath       *asp;
 
-       if (req->flags & F_CTL_ADJ_IN ||
-           !(req->flags & (F_CTL_ADJ_IN|F_CTL_ADJ_OUT))) {
+       if (req->flags & F_CTL_ADJ_OUT) {
+               if (p->re->active != p)
+                       /* only consider active prefix */
+                       return;
+               if (req->peerid) {
+                       if ((peer = peer_get(req->peerid)) != NULL)
+                               rde_dump_filterout(peer, p, req);
+                       return;
+               }
+       } else {
                asp = prefix_aspath(p);
                if (req->peerid && req->peerid != prefix_peer(p)->conf.id)
                        return;
+               if ((req->flags & F_CTL_ACTIVE) && p->re->active != p)
+                       return;
+               if ((req->flags & F_CTL_INVALID) &&
+                   (asp->flags & F_ATTR_PARSE_ERR) == 0)
+                       return;
                if (req->type == IMSG_CTL_SHOW_RIB_AS &&
                    !aspath_match(asp->aspath->data, asp->aspath->len,
                    &req->as, req->as.as))
@@ -2162,18 +2177,7 @@ rde_dump_filter(struct prefix *p, struct
                    !community_large_match(asp, req->large_community.as,
                    req->large_community.ld1, req->large_community.ld2))
                        return;
-               if ((req->flags & F_CTL_ACTIVE) && p->re->active != p)
-                       return;
                rde_dump_rib_as(p, asp, req->pid, req->flags);
-       } else if (req->flags & F_CTL_ADJ_OUT) {
-               if (p->re->active != p)
-                       /* only consider active prefix */
-                       return;
-               if (req->peerid) {
-                       if ((peer = peer_get(req->peerid)) != NULL)
-                               rde_dump_filterout(peer, p, req);
-                       return;
-               }
        }
 }
 
@@ -2223,7 +2227,9 @@ rde_dump_ctx_new(struct ctl_show_rib_req
                    sizeof(error));
                return;
        }
-       if ((rib = rib_find(req->rib)) == NULL) {
+       if (req->flags & (F_CTL_ADJ_IN | F_CTL_INVALID)) {
+               rib = &ribs[RIB_ADJ_IN].rib;
+       } else if ((rib = rib_find(req->rib)) == NULL) {
                log_warnx("rde_dump_ctx_new: no such rib %s", req->rib);
                error = CTL_RES_NOSUCHPEER;
                imsg_compose(ibuf_se_ctl, IMSG_CTL_RESULT, 0, pid, -1, &error,

Reply via email to