When adding the filterstate to rde_filter I also passed a struct prefix
pointer to rde_filter instead of passing the 4 values. This resulted in
some ugly hacks because in some cases there was no prefix handy to pass
in and while working on RIB pipelines I noticed that this is hurting me
again. So time to change it and just pass the prefix_peer, prefix_vstate
and the prefix addr/len right into rde_filter().
While there I also reordered the args to rde_attr_set() to match
rde_filter(). This is mostly a mechanical change.

OK?
-- 
:wq Claudio

Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.484
diff -u -p -r1.484 rde.c
--- rde.c       9 Aug 2019 13:44:27 -0000       1.484
+++ rde.c       13 Aug 2019 07:50:31 -0000
@@ -1402,7 +1402,6 @@ rde_update_update(struct rde_peer *peer,
     struct bgpd_addr *prefix, u_int8_t prefixlen)
 {
        struct filterstate       state;
-       struct prefix           *p;
        enum filter_actions      action;
        u_int8_t                 vstate;
        u_int16_t                i;
@@ -1428,17 +1427,14 @@ rde_update_update(struct rde_peer *peer,
        if (in->aspath.flags & F_ATTR_PARSE_ERR)
                wmsg = "path invalid, withdraw";
 
-       p = prefix_get(&ribs[RIB_ADJ_IN].rib, peer, prefix, prefixlen);
-       if (p == NULL)
-               fatalx("rde_update_update: no prefix in Adj-RIB-In");
-
        for (i = RIB_LOC_START; i < rib_size; i++) {
                if (!rib_valid(i))
                        continue;
                rde_filterstate_prep(&state, &in->aspath, &in->communities,
                    in->nexthop, in->nhflags);
                /* input filter */
-               action = rde_filter(ribs[i].in_rules, peer, p, &state);
+               action = rde_filter(ribs[i].in_rules, peer, peer, prefix,
+                   prefixlen, vstate, &state);
 
                if (action == ACTION_ALLOW) {
                        rde_update_log("update", i, peer,
@@ -3327,7 +3323,8 @@ rde_softreconfig_in(struct rib_entry *re
 
                        rde_filterstate_prep(&state, asp, prefix_communities(p),
                            prefix_nexthop(p), prefix_nhflags(p));
-                       action = rde_filter(rib->in_rules, peer, p, &state);
+                       action = rde_filter(rib->in_rules, peer, peer, &prefix,
+                           pt->prefixlen, p->validation_state, &state);
 
                        if (action == ACTION_ALLOW) {
                                /* update Local-RIB */
@@ -3959,10 +3956,10 @@ network_add(struct network_config *nc, s
                }
        }
 
-       rde_apply_set(&nc->attrset, state, nc->prefix.aid, peerself, peerself);
+       rde_apply_set(&nc->attrset, peerself, peerself, state, nc->prefix.aid);
        if (vpnset)
-               rde_apply_set(vpnset, state, nc->prefix.aid, peerself,
-                   peerself);
+               rde_apply_set(vpnset, peerself, peerself, state,
+                   nc->prefix.aid);
 
        vstate = rde_roa_validity(&conf->rde_roa, &nc->prefix,
            nc->prefixlen, aspath_origin(state->aspath.aspath));
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.223
diff -u -p -r1.223 rde.h
--- rde.h       9 Aug 2019 13:44:27 -0000       1.223
+++ rde.h       12 Aug 2019 14:46:38 -0000
@@ -464,16 +464,17 @@ int        community_to_rd(struct community *,
 void            prefix_evaluate(struct prefix *, struct rib_entry *);
 
 /* rde_filter.c */
-void            rde_filterstate_prep(struct filterstate *, struct rde_aspath *,
-                    struct rde_community *, struct nexthop *, u_int8_t);
-void            rde_filterstate_clean(struct filterstate *);
+void   rde_apply_set(struct filter_set_head *, struct rde_peer *,
+           struct rde_peer *, struct filterstate *, u_int8_t);
+void   rde_filterstate_prep(struct filterstate *, struct rde_aspath *,
+           struct rde_community *, struct nexthop *, u_int8_t);
+void   rde_filterstate_clean(struct filterstate *);
+int    rde_filter_equal(struct filter_head *, struct filter_head *,
+           struct rde_peer *);
+void   rde_filter_calc_skip_steps(struct filter_head *);
 enum filter_actions rde_filter(struct filter_head *, struct rde_peer *,
-                    struct prefix *, struct filterstate *);
-void            rde_apply_set(struct filter_set_head *, struct filterstate *,
-                    u_int8_t, struct rde_peer *, struct rde_peer *);
-int             rde_filter_equal(struct filter_head *, struct filter_head *,
-                    struct rde_peer *);
-void            rde_filter_calc_skip_steps(struct filter_head *);
+           struct rde_peer *, struct bgpd_addr *, u_int8_t, u_int8_t,
+           struct filterstate *);
 
 /* rde_prefix.c */
 void    pt_init(void);
Index: rde_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
retrieving revision 1.121
diff -u -p -r1.121 rde_filter.c
--- rde_filter.c        1 Jul 2019 07:07:08 -0000       1.121
+++ rde_filter.c        12 Aug 2019 14:43:57 -0000
@@ -29,14 +29,11 @@
 #include "rde.h"
 #include "log.h"
 
-int    rde_filter_match(struct filter_rule *, struct rde_peer *,
-           struct filterstate *, struct prefix *);
-int    rde_prefix_match(struct filter_prefix *, struct prefix *);
 int    filterset_equal(struct filter_set_head *, struct filter_set_head *);
 
 void
-rde_apply_set(struct filter_set_head *sh, struct filterstate *state,
-    u_int8_t aid, struct rde_peer *from, struct rde_peer *peer)
+rde_apply_set(struct filter_set_head *sh, struct rde_peer *peer,
+    struct rde_peer *from, struct filterstate *state, u_int8_t aid)
 {
        struct filter_set       *set;
        u_char                  *np;
@@ -178,9 +175,42 @@ rde_apply_set(struct filter_set_head *sh
        }
 }
 
-int
+/* return 1 when prefix matches filter_prefix, 0 if not */
+static int
+rde_prefix_match(struct filter_prefix *fp, struct bgpd_addr *prefix,
+    u_int8_t plen)
+{
+       if (fp->addr.aid != prefix->aid)
+               /* don't use IPv4 rules for IPv6 and vice versa */
+               return (0);
+
+       if (prefix_compare(prefix, &fp->addr, fp->len))
+               return (0);
+
+       /* test prefixlen stuff too */
+       switch (fp->op) {
+       case OP_NONE: /* perfect match */
+               return (plen == fp->len);
+       case OP_EQ:
+               return (plen == fp->len_min);
+       case OP_NE:
+               return (plen != fp->len_min);
+       case OP_RANGE:
+               return ((plen >= fp->len_min) &&
+                   (plen <= fp->len_max));
+       case OP_XRANGE:
+               return ((plen < fp->len_min) ||
+                   (plen > fp->len_max));
+       default:
+               log_warnx("%s: unsupported prefix operation", __func__);
+               return (0);
+       }
+}
+
+static int
 rde_filter_match(struct filter_rule *f, struct rde_peer *peer,
-    struct filterstate *state, struct prefix *p)
+    struct rde_peer *from, struct filterstate *state,
+    struct bgpd_addr *prefix, u_int8_t plen, u_int8_t vstate)
 {
        struct rde_aspath *asp = &state->aspath;
        int i;
@@ -191,7 +221,7 @@ rde_filter_match(struct filter_rule *f, 
                return (0);
 
        if (f->match.ovs.is_set) {
-               if (prefix_vstate(p) != f->match.ovs.validity)
+               if (vstate != f->match.ovs.validity)
                        return (0);
        }
 
@@ -223,7 +253,7 @@ rde_filter_match(struct filter_rule *f, 
                if (f->match.nexthop.flags == FILTER_NEXTHOP_ADDR)
                        cmpaddr = &f->match.nexthop.addr;
                else
-                       cmpaddr = &prefix_peer(p)->remote_addr;
+                       cmpaddr = &from->remote_addr;
                if (cmpaddr->aid != nexthop->aid)
                        /* don't use IPv4 rules for IPv6 and vice versa */
                        return (0);
@@ -245,11 +275,6 @@ rde_filter_match(struct filter_rule *f, 
 
        /* origin-set lookups match only on ROA_VALID */
        if (asp != NULL && f->match.originset.ps != NULL) {
-               struct bgpd_addr addr, *prefix = &addr;
-               u_int8_t plen;
-
-               pt_getaddr(p->pt, prefix);
-               plen = p->pt->prefixlen;
                if (trie_roa_check(&f->match.originset.ps->th, prefix, plen,
                    aspath_origin(asp->aspath)) != ROA_VALID)
                        return (0);
@@ -259,59 +284,17 @@ rde_filter_match(struct filter_rule *f, 
         * prefixset and prefix filter rules are mutual exclusive
         */
        if (f->match.prefixset.flags != 0) {
-               struct bgpd_addr addr, *prefix = &addr;
-               u_int8_t plen;
-
-               pt_getaddr(p->pt, prefix);
-               plen = p->pt->prefixlen;
                if (f->match.prefixset.ps == NULL ||
                    !trie_match(&f->match.prefixset.ps->th, prefix, plen,
                    (f->match.prefixset.flags & PREFIXSET_FLAG_LONGER)))
                        return (0);
        } else if (f->match.prefix.addr.aid != 0)
-               return (rde_prefix_match(&f->match.prefix, p));
+               return (rde_prefix_match(&f->match.prefix, prefix, plen));
 
        /* matched somewhen or is anymatch rule  */
        return (1);
 }
 
-/* return 1 when prefix matches filter_prefix, 0 if not */
-int
-rde_prefix_match(struct filter_prefix *fp, struct prefix *p)
-{
-       struct bgpd_addr addr, *prefix = &addr;
-       u_int8_t plen;
-
-       pt_getaddr(p->pt, prefix);
-       plen = p->pt->prefixlen;
-
-       if (fp->addr.aid != prefix->aid)
-               /* don't use IPv4 rules for IPv6 and vice versa */
-               return (0);
-
-       if (prefix_compare(prefix, &fp->addr, fp->len))
-               return (0);
-
-       /* test prefixlen stuff too */
-       switch (fp->op) {
-       case OP_NONE: /* perfect match */
-               return (plen == fp->len);
-       case OP_EQ:
-               return (plen == fp->len_min);
-       case OP_NE:
-               return (plen != fp->len_min);
-       case OP_RANGE:
-               return ((plen >= fp->len_min) &&
-                   (plen <= fp->len_max));
-       case OP_XRANGE:
-               return ((plen < fp->len_min) ||
-                   (plen > fp->len_max));
-       default:
-               log_warnx("%s: unsupported prefix operation", __func__);
-               return (0);
-       }
-}
-
 /* return true when the rule f can never match for this peer */
 static int
 rde_filter_skip_rule(struct rde_peer *peer, struct filter_rule *f)
@@ -753,7 +736,8 @@ rde_filter_calc_skip_steps(struct filter
 
 enum filter_actions
 rde_filter(struct filter_head *rules, struct rde_peer *peer,
-    struct prefix *p, struct filterstate *state)
+    struct rde_peer *from, struct bgpd_addr *prefix, u_int8_t plen,
+    u_int8_t vstate, struct filterstate *state)
 {
        struct filter_rule      *f;
        enum filter_actions      action = ACTION_DENY; /* default deny */
@@ -783,9 +767,9 @@ rde_filter(struct filter_head *rules, st
                     f->peer.peerid != peer->conf.id),
                     f->skip[RDE_FILTER_SKIP_PEERID]);
 
-               if (rde_filter_match(f, peer, state, p)) {
-                       rde_apply_set(&f->set, state, p->pt->aid,
-                           prefix_peer(p), peer);
+               if (rde_filter_match(f, peer, from, state, prefix, plen,
+                   vstate)) {
+                       rde_apply_set(&f->set, peer, from, state, prefix->aid);
                        if (f->action != ACTION_NONE)
                                action = f->action;
                        if (f->quick)
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.121
diff -u -p -r1.121 rde_update.c
--- rde_update.c        9 Aug 2019 13:44:27 -0000       1.121
+++ rde_update.c        12 Aug 2019 14:56:44 -0000
@@ -159,13 +159,14 @@ withdraw:
                rde_filterstate_prep(&state, prefix_aspath(new),
                    prefix_communities(new), prefix_nexthop(new),
                    prefix_nhflags(new));
-               if (rde_filter(rules, peer, new, &state) == ACTION_DENY) {
+               pt_getaddr(new->pt, &addr);
+               if (rde_filter(rules, peer, prefix_peer(new), &addr,
+                   new->pt->prefixlen, prefix_vstate(new), &state) ==
+                   ACTION_DENY) {
                        rde_filterstate_clean(&state);
                        goto withdraw;
                }
 
-               pt_getaddr(new->pt, &addr);
-
                /* only send update if path changed */
                if (prefix_adjout_update(peer, &state, &addr,
                    new->pt->prefixlen, prefix_vstate(new)) == 1)
@@ -184,10 +185,9 @@ void
 up_generate_default(struct filter_head *rules, struct rde_peer *peer,
     u_int8_t aid)
 {
+       extern struct rde_peer  *peerself;
        struct filterstate       state;
        struct rde_aspath       *asp;
-       struct prefix            p;
-       struct pt_entry         *pte;
        struct bgpd_addr         addr;
 
        if (peer->capa.mp[aid] == 0)
@@ -203,26 +203,13 @@ up_generate_default(struct filter_head *
         * XXX apply default overrides. Not yet possible, mainly a parse.y
         * problem.
         */
-       /* rde_apply_set(asp, set, af, &state, DIR_IN); */
+       /* rde_apply_set(asp, peerself, peerself, set, af); */
 
-       /*
-        * XXX this is ugly because we need to have a prefix for rde_filter()
-        * but it will be added after filtering. So fake it till we make it.
-        * rde_filter() only accesses prefix_peer(), prefix_vstate() and the
-        * pt pointer.
-        */
-       bzero(&p, sizeof(p));
        bzero(&addr, sizeof(addr));
        addr.aid = aid;
-       pte = pt_get(&addr, 0);
-       if (pte == NULL)
-               pte = pt_add(&addr, 0);
-       p.pt = pt_ref(pte);
-       p.validation_state = ROA_NOTFOUND;
-       p.peer = peer;          /* XXX should be peerself */
-
        /* outbound filter as usual */
-       if (rde_filter(rules, peer, &p, &state) == ACTION_DENY) {
+       if (rde_filter(rules, peer, peerself, &addr, 0, ROA_NOTFOUND,
+           &state) == ACTION_DENY) {
                rde_filterstate_clean(&state);
                return;
        }
@@ -232,8 +219,6 @@ up_generate_default(struct filter_head *
 
        /* no longer needed */
        rde_filterstate_clean(&state);
-
-       pt_unref(pte);
 }
 
 /* only for IPv4 */

Reply via email to