reads good running on a machine here without problems
ok benno@ Claudio Jeker([email protected]) on 2018.06.27 16:55:57 +0200: > My plan is to make struct prefix the main object that holds references to > aspath, nexthop and rib. This diff is the next little step towards that. > > Pass a struct prefix to rde_filter and remove some of the arguments which > are now fetched from struct prefix. Currently some trickery is needed > for export default-route but this will get better once Adj-RIB-Out comes. > > Please test and review > -- > :wq Claudio > > Index: rde.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v > retrieving revision 1.381 > diff -u -p -r1.381 rde.c > --- rde.c 25 Jun 2018 14:28:33 -0000 1.381 > +++ rde.c 27 Jun 2018 13:18:01 -0000 > @@ -1364,6 +1364,7 @@ rde_update_update(struct rde_peer *peer, > struct bgpd_addr *prefix, u_int8_t prefixlen) > { > struct rde_aspath *fasp; > + struct prefix *p; > enum filter_actions action; > u_int16_t i; > > @@ -1372,12 +1373,15 @@ rde_update_update(struct rde_peer *peer, > if (path_update(&ribs[RIB_ADJ_IN].rib, peer, asp, prefix, prefixlen, 0)) > peer->prefix_cnt++; > > + p = prefix_get(&ribs[RIB_ADJ_IN].rib, peer, prefix, prefixlen, 0); > + if (p == NULL) > + fatalx("rde_update_update: no prefix in Adj-RIB-In"); > + > for (i = RIB_LOC_START; i < rib_size; i++) { > if (*ribs[i].name == '\0') > break; > /* input filter */ > - action = rde_filter(ribs[i].in_rules, &fasp, peer, asp, prefix, > - prefixlen, peer); > + action = rde_filter(ribs[i].in_rules, peer, &fasp, p, asp); > > if (fasp == NULL) > fasp = asp; > @@ -2303,8 +2307,7 @@ rde_dump_filterout(struct rde_peer *peer > > pt_getaddr(p->re->prefix, &addr); > asp = prefix_aspath(p); > - a = rde_filter(out_rules, &fasp, peer, asp, &addr, > - p->re->prefix->prefixlen, asp->peer); > + a = rde_filter(out_rules, peer, &fasp, p, asp); > if (fasp) > fasp->peer = asp->peer; > else > @@ -3064,16 +3067,14 @@ rde_softreconfig_in(struct rib_entry *re > > /* check if prefix changed */ > if (rib->state == RECONF_RELOAD) { > - oa = rde_filter(rib->in_rules_tmp, &oasp, peer, > - asp, &addr, pt->prefixlen, peer); > + oa = rde_filter(rib->in_rules_tmp, peer, &oasp, p, asp); > oasp = oasp != NULL ? oasp : asp; > } else { > /* make sure we update everything for RECONF_REINIT */ > oa = ACTION_DENY; > oasp = asp; > } > - na = rde_filter(rib->in_rules, &nasp, peer, asp, > - &addr, pt->prefixlen, peer); > + na = rde_filter(rib->in_rules, peer, &nasp, p, asp); > nasp = nasp != NULL ? nasp : asp; > > /* go through all 4 possible combinations */ > @@ -3122,10 +3123,8 @@ rde_softreconfig_out(struct rib_entry *r > if (up_test_update(peer, p) != 1) > return; > > - oa = rde_filter(out_rules_tmp, &oasp, peer, prefix_aspath(p), > - &addr, pt->prefixlen, prefix_peer(p)); > - na = rde_filter(out_rules, &nasp, peer, prefix_aspath(p), > - &addr, pt->prefixlen, prefix_peer(p)); > + oa = rde_filter(out_rules_tmp, peer, &oasp, p, prefix_aspath(p)); > + na = rde_filter(out_rules, peer, &nasp, p, prefix_aspath(p)); > oasp = oasp != NULL ? oasp : prefix_aspath(p); > nasp = nasp != NULL ? nasp : prefix_aspath(p); > > @@ -3167,8 +3166,7 @@ rde_softreconfig_unload_peer(struct rib_ > if (up_test_update(peer, p) != 1) > return; > > - oa = rde_filter(out_rules_tmp, &oasp, peer, prefix_aspath(p), > - &addr, pt->prefixlen, prefix_peer(p)); > + oa = rde_filter(out_rules_tmp, peer, &oasp, p, prefix_aspath(p)); > oasp = oasp != NULL ? oasp : prefix_aspath(p); > > if (oa == ACTION_DENY) > @@ -3648,9 +3646,9 @@ network_add(struct network_config *nc, i > } > if (!flagstatic) > asp->flags |= F_ANN_DYNAMIC; > - rde_apply_set(asp, &nc->attrset, nc->prefix.aid, peerself, peerself); > + rde_apply_set(&nc->attrset, asp, nc->prefix.aid, peerself, peerself); > if (vpnset) > - rde_apply_set(asp, vpnset, nc->prefix.aid, peerself, peerself); > + rde_apply_set(vpnset, asp, nc->prefix.aid, peerself, peerself); > for (i = RIB_LOC_START; i < rib_size; i++) { > if (*ribs[i].name == '\0') > break; > Index: rde.h > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v > retrieving revision 1.171 > diff -u -p -r1.171 rde.h > --- rde.h 27 Jun 2018 13:14:44 -0000 1.171 > +++ rde.h 27 Jun 2018 13:20:17 -0000 > @@ -402,10 +402,10 @@ u_char *community_ext_delete_non_trans( > void prefix_evaluate(struct prefix *, struct rib_entry *); > > /* rde_filter.c */ > -enum filter_actions rde_filter(struct filter_head *, struct rde_aspath **, > - struct rde_peer *, struct rde_aspath *, > - struct bgpd_addr *, u_int8_t, struct rde_peer *); > -void rde_apply_set(struct rde_aspath *, struct filter_set_head *, > +enum filter_actions rde_filter(struct filter_head *, struct rde_peer *, > + struct rde_aspath **, struct prefix *, > + struct rde_aspath *); > +void rde_apply_set(struct filter_set_head *, struct rde_aspath *, > u_int8_t, struct rde_peer *, struct rde_peer *); > int rde_filter_equal(struct filter_head *, struct filter_head *, > struct rde_peer *, struct prefixset_head *); > @@ -479,6 +479,8 @@ struct rde_aspath *path_get(void); > void path_put(struct rde_aspath *); > > #define PREFIX_SIZE(x) (((x) + 7) / 8 + 1) > +struct prefix *prefix_get(struct rib *, struct rde_peer *, > + struct bgpd_addr *, int, u_int32_t); > int prefix_remove(struct rib *, struct rde_peer *, > struct bgpd_addr *, int, u_int32_t); > int prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t, int); > Index: rde_filter.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v > retrieving revision 1.90 > diff -u -p -r1.90 rde_filter.c > --- rde_filter.c 27 Jun 2018 11:06:49 -0000 1.90 > +++ rde_filter.c 27 Jun 2018 11:34:07 -0000 > @@ -29,13 +29,13 @@ > #include "rde.h" > #include "log.h" > > -int rde_filter_match(struct filter_rule *, struct rde_aspath *, > - struct bgpd_addr *, u_int8_t, struct rde_peer *, struct rde_peer *); > +int rde_filter_match(struct filter_rule *, struct rde_peer *, > + struct rde_aspath *, struct prefix *); > +int rde_prefix_match(struct filter_prefix *, struct prefix *); > int filterset_equal(struct filter_set_head *, struct filter_set_head *); > -int rde_test_prefix(struct filter_prefix *, struct bgpd_addr *, u_int8_t); > > void > -rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh, > +rde_apply_set(struct filter_set_head *sh, struct rde_aspath *asp, > u_int8_t aid, struct rde_peer *from, struct rde_peer *peer) > { > struct filter_set *set; > @@ -330,9 +330,8 @@ rde_apply_set(struct rde_aspath *asp, st > } > > int > -rde_filter_match(struct filter_rule *f, struct rde_aspath *asp, > - struct bgpd_addr *prefix, u_int8_t plen, struct rde_peer *peer, > - struct rde_peer *from) > +rde_filter_match(struct filter_rule *f, struct rde_peer *peer, > + struct rde_aspath *asp, struct prefix *p) > { > u_int32_t pas; > int cas, type; > @@ -453,7 +452,7 @@ rde_filter_match(struct filter_rule *f, > if (f->match.nexthop.flags == FILTER_NEXTHOP_ADDR) > cmpaddr = &f->match.nexthop.addr; > else > - cmpaddr = &from->remote_addr; > + cmpaddr = &prefix_peer(p)->remote_addr; > if (cmpaddr->aid != nexthop->aid) > /* don't use IPv4 rules for IPv6 and vice versa */ > return (0); > @@ -481,7 +480,7 @@ rde_filter_match(struct filter_rule *f, > log_debug("%s: processing filter for prefixset %s", > __func__, f->match.prefixset.name); > SIMPLEQ_FOREACH(psi, &f->match.prefixset.ps->psitems, entry) { > - if (rde_test_prefix(&psi->p, prefix, plen)) { > + if (rde_prefix_match(&psi->p, p)) { > log_debug("%s: prefixset %s matched %s", > __func__, f->match.prefixset.ps->name, > log_addr(&psi->p.addr)); > @@ -490,7 +489,7 @@ rde_filter_match(struct filter_rule *f, > } > return (0); > } else if (f->match.prefix.addr.aid != 0) > - return (rde_test_prefix(&f->match.prefix, prefix, plen)); > + return (rde_prefix_match(&f->match.prefix, p)); > > /* matched somewhen or is anymatch rule */ > return (1); > @@ -498,9 +497,14 @@ rde_filter_match(struct filter_rule *f, > > /* return 1 when prefix matches filter_prefix, 0 if not */ > int > -rde_test_prefix(struct filter_prefix *fp, struct bgpd_addr *prefix, > - u_int8_t plen) > +rde_prefix_match(struct filter_prefix *fp, struct prefix *p) > { > + struct bgpd_addr addr, *prefix = &addr; > + u_int8_t plen; > + > + pt_getaddr(p->re->prefix, prefix); > + plen = p->re->prefix->prefixlen; > + > if (fp->addr.aid != prefix->aid) > /* don't use IPv4 rules for IPv6 and vice versa */ > return (0); > @@ -976,9 +980,8 @@ rde_filter_calc_skip_steps(struct filter > } while (0) > > enum filter_actions > -rde_filter(struct filter_head *rules, struct rde_aspath **new, > - struct rde_peer *peer, struct rde_aspath *asp, struct bgpd_addr *prefix, > - u_int8_t prefixlen, struct rde_peer *from) > +rde_filter(struct filter_head *rules, struct rde_peer *peer, > + struct rde_aspath **new, struct prefix *p, struct rde_aspath *asp) > { > struct filter_rule *f; > enum filter_actions action = ACTION_DENY; /* default deny */ > @@ -1010,7 +1013,8 @@ rde_filter(struct filter_head *rules, st > (f->peer.peerid && > f->peer.peerid != peer->conf.id), > f->skip[RDE_FILTER_SKIP_PEERID].ptr); > - if (rde_filter_match(f, asp, prefix, prefixlen, peer, from)) { > + > + if (rde_filter_match(f, peer, asp, p)) { > if (asp != NULL && new != NULL) { > /* asp may get modified so create a copy */ > if (*new == NULL) { > @@ -1018,8 +1022,8 @@ rde_filter(struct filter_head *rules, st > /* ... and use the copy from now on */ > asp = *new; > } > - rde_apply_set(asp, &f->set, prefix->aid, > - from, peer); > + rde_apply_set(&f->set, asp, p->re->prefix->aid, > + prefix_peer(p), peer); > } > if (f->action != ACTION_NONE) > action = f->action; > Index: rde_rib.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v > retrieving revision 1.162 > diff -u -p -r1.162 rde_rib.c > --- rde_rib.c 27 Jun 2018 13:14:44 -0000 1.162 > +++ rde_rib.c 27 Jun 2018 13:19:44 -0000 > @@ -47,8 +47,6 @@ struct rib_entry *rib_restart(struct rib > RB_PROTOTYPE(rib_tree, rib_entry, rib_e, rib_compare); > RB_GENERATE(rib_tree, rib_entry, rib_e, rib_compare); > > -struct prefix *prefix_get(struct rib *, struct rde_peer *, > - struct bgpd_addr *, int, u_int32_t); > int prefix_add(struct rib *, struct rde_aspath *, > struct bgpd_addr *, int, int); > void prefix_move(struct rde_aspath *, struct prefix *, int); > Index: rde_update.c > =================================================================== > RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v > retrieving revision 1.91 > diff -u -p -r1.91 rde_update.c > --- rde_update.c 26 Jun 2018 13:34:26 -0000 1.91 > +++ rde_update.c 27 Jun 2018 14:46:31 -0000 > @@ -411,8 +411,7 @@ withdraw: > > asp = prefix_aspath(old); > pt_getaddr(old->re->prefix, &addr); > - if (rde_filter(rules, NULL, peer, asp, &addr, > - old->re->prefix->prefixlen, asp->peer) == ACTION_DENY) > + if (rde_filter(rules, peer, NULL, old, asp) == ACTION_DENY) > return; > > /* withdraw prefix */ > @@ -429,8 +428,7 @@ withdraw: > > asp = prefix_aspath(new); > pt_getaddr(new->re->prefix, &addr); > - if (rde_filter(rules, &fasp, peer, asp, &addr, > - new->re->prefix->prefixlen, asp->peer) == ACTION_DENY) { > + if (rde_filter(rules, peer, &fasp, new, asp) == ACTION_DENY) { > path_put(fasp); > goto withdraw; > } > @@ -445,12 +443,18 @@ withdraw: > } > } > > +struct rib_entry *rib_add(struct rib *, struct bgpd_addr *, int); > +void rib_remove(struct rib_entry *); > +int rib_empty(struct rib_entry *); > + > /* send a default route to the specified peer */ > void > up_generate_default(struct filter_head *rules, struct rde_peer *peer, > u_int8_t aid) > { > struct rde_aspath *asp, *fasp; > + struct prefix p; > + struct rib_entry *re; > struct bgpd_addr addr; > > if (peer->capa.mp[aid] == 0) > @@ -467,12 +471,23 @@ up_generate_default(struct filter_head * > */ > /* rde_apply_set(asp, set, af, NULL ???, DIR_IN); */ > > - /* filter as usual */ > + /* > + * XXX this is ugly but it will get better once we have a proper > + * Adj-RIB-Out. Since then this will be just inserted there. > + */ > + bzero(&p, sizeof(p)); > bzero(&addr, sizeof(addr)); > addr.aid = aid; > + re = rib_get(peer->rib, &addr, 0); > + if (re == NULL) > + re = rib_add(peer->rib, &addr, 0); > + p.re = re; > + p.aspath = asp; > + p.peer = peer; > + p.flags = 0; > > - if (rde_filter(rules, &fasp, peer, asp, &addr, 0, NULL) == > - ACTION_DENY) { > + /* filter as usual */ > + if (rde_filter(rules, peer, &fasp, &p, asp) == ACTION_DENY) { > path_put(fasp); > path_put(asp); > return; > @@ -487,6 +502,9 @@ up_generate_default(struct filter_head * > if (fasp != asp) > path_put(fasp); > path_put(asp); > + > + if (rib_empty(re)) > + rib_remove(re); > } > > /* generate a EoR marker in the update list. This is a horrible hack. */ >
