Make it possible to filter the RIB for invalid path which resulted in withdrawn
authorclaudio <claudio@openbsd.org>
Wed, 29 Aug 2018 19:47:47 +0000 (19:47 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 29 Aug 2018 19:47:47 +0000 (19:47 +0000)
prefixes. This way it should be possible to inspect which prefixes have been
removed. While there also fix dumping of the Adj-RIB-In when requested to do so.
OK sthen@ denis@

usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/rde.c

index a36b366..046a568 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.330 2018/08/09 21:12:33 claudio Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.331 2018/08/29 19:47:47 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -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 6ba3a49..207281f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.415 2018/08/29 11:46:28 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.416 2018/08/29 19:47:47 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -2085,6 +2085,8 @@ rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int flags)
                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;
@@ -2146,11 +2148,24 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req)
        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))
@@ -2166,18 +2181,7 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req)
                    !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;
-               }
        }
 }
 
@@ -2227,7 +2231,9 @@ rde_dump_ctx_new(struct ctl_show_rib_request *req, pid_t pid,
                    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,