Thanks to a report by Marko Cupac a mistake could be identified when
generating the data shown in 'bgpctl show rib out nei $FOO'.
The nexthop shown is actually the nexthop of the Loc-RIB and not from
Adj-RIB-Out and so the effect of a filter rule like 'match to $FOO set
nexthop 192.0.2.17' was not visible. Instead of using the nexthop from
struct prefix the nexthop from the filter-state needs to be used.

The following diff adjusts this problem.
-- 
:wq Claudio

Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.438
diff -u -p -r1.438 rde.c
--- rde.c       22 Oct 2018 07:46:55 -0000      1.438
+++ rde.c       22 Oct 2018 13:35:57 -0000
@@ -69,14 +69,6 @@ void          rde_update_log(const char *, u_in
 void            rde_as4byte_fixup(struct rde_peer *, struct rde_aspath *);
 void            rde_reflector(struct rde_peer *, struct rde_aspath *);
 
-void            rde_dump_rib_as(struct prefix *, struct rde_aspath *, pid_t,
-                    int);
-void            rde_dump_filter(struct prefix *,
-                    struct ctl_show_rib_request *);
-void            rde_dump_filterout(struct rde_peer *, struct prefix *,
-                    struct ctl_show_rib_request *);
-void            rde_dump_upcall(struct rib_entry *, void *);
-void            rde_dump_prefix_upcall(struct rib_entry *, void *);
 void            rde_dump_ctx_new(struct ctl_show_rib_request *, pid_t,
                     enum imsg_type);
 void            rde_dump_ctx_throttle(pid_t pid, int throttle);
@@ -2148,8 +2140,9 @@ rde_reflector(struct rde_peer *peer, str
 /*
  * control specific functions
  */
-void
-rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int flags)
+static void
+rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp,
+    struct nexthop *nexthop, pid_t pid, int flags)
 {
        struct ctl_show_rib      rib;
        struct ibuf             *wbuf;
@@ -2167,10 +2160,10 @@ rde_dump_rib_as(struct prefix *p, struct
        memcpy(&rib.remote_addr, &prefix_peer(p)->remote_addr,
            sizeof(rib.remote_addr));
        rib.remote_id = prefix_peer(p)->remote_bgpid;
-       if (prefix_nexthop(p) != NULL) {
-               memcpy(&rib.true_nexthop, &prefix_nexthop(p)->true_nexthop,
+       if (nexthop != NULL) {
+               memcpy(&rib.true_nexthop, &nexthop->true_nexthop,
                    sizeof(rib.true_nexthop));
-               memcpy(&rib.exit_nexthop, &prefix_nexthop(p)->exit_nexthop,
+               memcpy(&rib.exit_nexthop, &nexthop->exit_nexthop,
                    sizeof(rib.exit_nexthop));
        } else {
                /* announced network may have a NULL nexthop */
@@ -2190,8 +2183,7 @@ rde_dump_rib_as(struct prefix *p, struct
                rib.flags |= F_PREF_INTERNAL;
        if (asp->flags & F_PREFIX_ANNOUNCED)
                rib.flags |= F_PREF_ANNOUNCE;
-       if (prefix_nexthop(p) == NULL ||
-           prefix_nexthop(p)->state == NEXTHOP_REACH)
+       if (nexthop == NULL || nexthop->state == NEXTHOP_REACH)
                rib.flags |= F_PREF_ELIGIBLE;
        if (asp->flags & F_ATTR_LOOP)
                rib.flags &= ~F_PREF_ELIGIBLE;
@@ -2232,7 +2224,7 @@ rde_dump_rib_as(struct prefix *p, struct
                }
 }
 
-void
+static void
 rde_dump_filterout(struct rde_peer *peer, struct prefix *p,
     struct ctl_show_rib_request *req)
 {
@@ -2247,12 +2239,13 @@ rde_dump_filterout(struct rde_peer *peer
        a = rde_filter(out_rules, peer, p, &state);
 
        if (a == ACTION_ALLOW)
-               rde_dump_rib_as(p, &state.aspath, req->pid, req->flags);
+               rde_dump_rib_as(p, &state.aspath, state.nexthop, req->pid,
+                   req->flags);
 
        rde_filterstate_clean(&state);
 }
 
-void
+static void
 rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req)
 {
        struct rde_peer         *peer;
@@ -2293,11 +2286,12 @@ rde_dump_filter(struct prefix *p, struct
                        return;
                if (!ovs_match(p, req->flags))
                        return;
-               rde_dump_rib_as(p, asp, req->pid, req->flags);
+               rde_dump_rib_as(p, asp, prefix_nexthop(p), req->pid,
+                   req->flags);
        }
 }
 
-void
+static void
 rde_dump_upcall(struct rib_entry *re, void *ptr)
 {
        struct prefix           *p;
@@ -2307,7 +2301,7 @@ rde_dump_upcall(struct rib_entry *re, vo
                rde_dump_filter(p, &ctx->req);
 }
 
-void
+static void
 rde_dump_prefix_upcall(struct rib_entry *re, void *ptr)
 {
        struct rde_dump_ctx     *ctx = ptr;

Reply via email to