bgpctl can show all routes under a prefix. For example bgpctl show rib 8/8 all but there was no way to do the inverse, show all routes which cover a certain prefix. Since bgpd.conf has or-longer for the same as the all keywork in bgpctl the idea was to call this or-shorter (and add or-longer as alias to all)
e.g. bgpctl show rib 8.8.8.8 or-shorter or bgpctl show rib 8.8.8.0/24 or-shorter 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 *> N 8.0.0.0/9 62.48.0.253 100 0 1299 3356 i *> N 8.0.0.0/12 62.48.0.253 100 0 1299 3356 i *> N 8.8.8.0/24 62.48.0.253 100 0 15169 i This was requested by Job and I agree that this is useful. -- :wq Claudio Index: bgpctl/bgpctl.8 =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.8,v retrieving revision 1.91 diff -u -p -r1.91 bgpctl.8 --- bgpctl/bgpctl.8 25 Sep 2019 15:35:50 -0000 1.91 +++ bgpctl/bgpctl.8 26 Sep 2019 19:29:46 -0000 @@ -223,7 +223,7 @@ Show routes from an MRT table dump file. .Ar filter can be an IP address, a CIDR prefix, an AS filter, a combination or nothing: .Pp -.Bl -tag -width "address/len all" -compact +.Bl -tag -width "address/len or-shorter" -compact .It Ar address Show best matching route for address. .It Ar address Ns Li / Ns Ar len @@ -234,6 +234,11 @@ Show RIB entry for this CIDR prefix. .Xc Show all entries in the specified range. .\".It Ar address/len Cm longer-prefixes +.It Xo +.Ar address Ns Li / Ns Ar len +.Cm or-shorter +.Xc +Show all entries covering and including the specified prefix. .It Cm as Ar as Show all entries with .Ar as @@ -312,7 +317,7 @@ Routing Information Base. .Ar filter can be an IP address, a CIDR prefix, an AS filter or nothing: .Pp -.Bl -tag -width "address/len all" -compact +.Bl -tag -width "address/len or-shorter" -compact .It Ar address Show best matching route for address. .It Ar address Ns Li / Ns Ar len @@ -323,6 +328,11 @@ Show RIB entry for this CIDR prefix. .Xc Show all entries in the specified range. .\".It Ar address/len Cm longer-prefixes +.It Xo +.Ar address Ns Li / Ns Ar len +.Cm or-shorter +.Xc +Show all entries covering and including the specified prefix. .It Cm as Ar as Show all entries with .Ar as Index: bgpctl/bgpctl.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v retrieving revision 1.245 diff -u -p -r1.245 bgpctl.c --- bgpctl/bgpctl.c 25 Sep 2019 15:35:50 -0000 1.245 +++ bgpctl/bgpctl.c 26 Sep 2019 19:28:00 -0000 @@ -2132,15 +2132,25 @@ show_mrt_dump(struct mrt_rib *mr, struct return; /* filter by prefix */ if (req->prefix.aid != AID_UNSPEC) { - if (!prefix_compare(&req->prefix, &ctl.prefix, - req->prefixlen)) { - if (req->flags & F_LONGER) { - if (req->prefixlen > ctl.prefixlen) - return; - } else if (req->prefixlen != ctl.prefixlen) + if (req->flags & F_LONGER) { + if (req->prefixlen > ctl.prefixlen) return; - } else - return; + if (prefix_compare(&req->prefix, &ctl.prefix, + req->prefixlen)) + return; + } else if (req->flags & F_SHORTER) { + if (req->prefixlen < ctl.prefixlen) + return; + if (prefix_compare(&req->prefix, &ctl.prefix, + ctl.prefixlen)) + return; + } else { + if (req->prefixlen != ctl.prefixlen) + return; + if (prefix_compare(&req->prefix, &ctl.prefix, + req->prefixlen)) + return; + } } /* filter by AS */ if (req->as.type != AS_UNDEF && Index: bgpctl/parser.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v retrieving revision 1.98 diff -u -p -r1.98 parser.c --- bgpctl/parser.c 28 Jun 2019 12:12:06 -0000 1.98 +++ bgpctl/parser.c 26 Sep 2019 17:47:59 -0000 @@ -305,6 +305,8 @@ static const struct token t_show_prefix[ { NOTOKEN, "", NONE, NULL}, { FLAG, "all", F_LONGER, NULL}, { FLAG, "longer-prefixes", F_LONGER, NULL}, + { FLAG, "or-longer", F_LONGER, NULL}, + { FLAG, "or-shorter", F_SHORTER, NULL}, { ENDTOKEN, "", NONE, NULL} }; Index: bgpd/bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v retrieving revision 1.392 diff -u -p -r1.392 bgpd.h --- bgpd/bgpd.h 7 Aug 2019 10:26:41 -0000 1.392 +++ bgpd/bgpd.h 26 Sep 2019 17:40:51 -0000 @@ -80,7 +80,8 @@ #define F_REJECT 0x0080 #define F_BLACKHOLE 0x0100 #define F_LONGER 0x0200 -#define F_MPLS 0x0400 +#define F_SHORTER 0x0400 +#define F_MPLS 0x0800 #define F_CTL_DETAIL 0x1000 /* only set on requests */ #define F_CTL_ADJ_IN 0x2000 /* only set on requests */ #define F_CTL_ADJ_OUT 0x4000 /* only set on requests */ Index: bgpd/rde.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v retrieving revision 1.487 diff -u -p -r1.487 rde.c --- bgpd/rde.c 14 Aug 2019 11:57:21 -0000 1.487 +++ bgpd/rde.c 26 Sep 2019 17:39:59 -0000 @@ -2353,11 +2353,21 @@ rde_dump_prefix_upcall(struct rib_entry pt_getaddr(pt, &addr); if (addr.aid != ctx->req.prefix.aid) return; - if (ctx->req.prefixlen > pt->prefixlen) - return; - if (!prefix_compare(&ctx->req.prefix, &addr, ctx->req.prefixlen)) - LIST_FOREACH(p, &re->prefix_h, entry.list.rib) - rde_dump_filter(p, &ctx->req); + if (ctx->req.flags & F_LONGER) { + if (ctx->req.prefixlen > pt->prefixlen) + return; + if (!prefix_compare(&ctx->req.prefix, &addr, + ctx->req.prefixlen)) + LIST_FOREACH(p, &re->prefix_h, entry.list.rib) + rde_dump_filter(p, &ctx->req); + } else { + if (ctx->req.prefixlen < pt->prefixlen) + return; + if (!prefix_compare(&addr, &ctx->req.prefix, + pt->prefixlen)) + LIST_FOREACH(p, &re->prefix_h, entry.list.rib) + rde_dump_filter(p, &ctx->req); + } } static void @@ -2382,10 +2392,19 @@ rde_dump_adjout_prefix_upcall(struct pre pt_getaddr(p->pt, &addr); if (addr.aid != ctx->req.prefix.aid) return; - if (ctx->req.prefixlen > p->pt->prefixlen) - return; - if (!prefix_compare(&ctx->req.prefix, &addr, ctx->req.prefixlen)) - rde_dump_filter(p, &ctx->req); + if (ctx->req.flags & F_LONGER) { + if (ctx->req.prefixlen > p->pt->prefixlen) + return; + if (!prefix_compare(&ctx->req.prefix, &addr, + ctx->req.prefixlen)) + rde_dump_filter(p, &ctx->req); + } else { + if (ctx->req.prefixlen < p->pt->prefixlen) + return; + if (!prefix_compare(&addr, &ctx->req.prefix, + p->pt->prefixlen)) + rde_dump_filter(p, &ctx->req); + } } static int @@ -2489,7 +2508,7 @@ rde_dump_ctx_new(struct ctl_show_rib_req goto nomem; break; case IMSG_CTL_SHOW_RIB_PREFIX: - if (req->flags & F_LONGER) { + if (req->flags & (F_LONGER|F_SHORTER)) { if (prefix_dump_new(peer, ctx->req.aid, CTL_MSG_HIGH_MARK, ctx, rde_dump_adjout_prefix_upcall, @@ -2553,7 +2572,7 @@ rde_dump_ctx_new(struct ctl_show_rib_req goto nomem; break; case IMSG_CTL_SHOW_RIB_PREFIX: - if (req->flags & F_LONGER) { + if (req->flags & (F_LONGER|F_SHORTER)) { if (rib_dump_new(rid, ctx->req.aid, CTL_MSG_HIGH_MARK, ctx, rde_dump_prefix_upcall, rde_dump_done, rde_dump_throttled) == -1)