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 */