On Wed, Aug 29, 2018 at 01:07:33PM +0200, Claudio Jeker wrote:
> 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?
OK denis@
> --
> :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,
>