diff options
author | 2006-01-24 14:14:04 +0000 | |
---|---|---|
committer | 2006-01-24 14:14:04 +0000 | |
commit | 1972c2cde5ceda0340e76da357519658239a62b2 (patch) | |
tree | 292b2a91f94f6dbadf0512ee299c4f8a286993b0 | |
parent | Finally start using the Adj-RIB-In. The most complex part is the modification (diff) | |
download | wireguard-openbsd-1972c2cde5ceda0340e76da357519658239a62b2.tar.xz wireguard-openbsd-1972c2cde5ceda0340e76da357519658239a62b2.zip |
Check if filter changed on a per peer basis. This should speed up the
table run done later as many filter evaluations can be skipped.
From the softreconfig in tree. Looks good henning@
-rw-r--r-- | usr.sbin/bgpd/rde.c | 26 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 27 |
3 files changed, 52 insertions, 7 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 6297f76686f..bb6121fb1c1 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.196 2006/01/24 13:34:33 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.197 2006/01/24 14:14:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -453,10 +453,11 @@ void rde_dispatch_imsg_parent(struct imsgbuf *ibuf) { struct imsg imsg; + struct rde_peer *peer; struct filter_rule *r; struct filter_set *s; struct mrt *xmrt; - int n; + int n, reconf_in = 0, reconf_out = 0; if ((n = imsg_read(ibuf)) == -1) fatal("rde_dispatch_imsg_parent: imsg_read error"); @@ -529,8 +530,25 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) parent_set = NULL; prefix_network_clean(&peerself, reloadtime); - if (!rde_filter_equal(rules_l, newrules, DIR_OUT)) + /* check if filter changed */ + LIST_FOREACH(peer, &peerlist, peer_l) { + peer->reconf_out = 0; + peer->reconf_in = 0; + if (!rde_filter_equal(rules_l, newrules, peer, + DIR_OUT)) { + peer->reconf_out = 1; + reconf_out = 1; + } + if (!rde_filter_equal(rules_l, newrules, peer, + DIR_IN)) { + peer->reconf_in = 1; + reconf_in = 1; + } + } + /* then sync peers */ + if (reconf_out) pt_dump(rde_softreconfig_out, NULL, AF_UNSPEC); + while ((r = TAILQ_FIRST(rules_l)) != NULL) { TAILQ_REMOVE(rules_l, r, entry); filterset_free(&r->set); @@ -1706,6 +1724,8 @@ rde_softreconfig_out(struct pt_entry *pt, void *ptr) pt_getaddr(pt, &addr); LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->reconf_out == 0) + continue; if (up_test_update(peer, p) != 1) continue; diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 2826417c304..724bcdf54cc 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.86 2006/01/24 13:34:33 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.87 2006/01/24 14:14:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -69,6 +69,8 @@ struct rde_peer { u_int32_t up_nlricnt; u_int32_t up_wcnt; enum peer_state state; + u_int8_t reconf_in; /* in filter changed */ + u_int8_t reconf_out; /* out filter changed */ }; #define AS_SET 1 @@ -371,7 +373,7 @@ void rde_apply_set(struct rde_aspath *, struct filter_set_head *, sa_family_t, struct rde_peer *, enum directions); int rde_filter_community(struct rde_aspath *, int, int); int rde_filter_equal(struct filter_head *, struct filter_head *, - enum directions); + struct rde_peer *, enum directions); /* util.c */ u_int16_t aspath_extract(const void *, int); diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index 1013e7e3aef..7e47f85084e 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.41 2006/01/12 14:05:13 claudio Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.42 2006/01/24 14:14:04 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -284,7 +284,7 @@ rde_filter_community(struct rde_aspath *asp, int as, int type) int rde_filter_equal(struct filter_head *a, struct filter_head *b, - enum directions dir) + struct rde_peer *peer, enum directions dir) { struct filter_rule *fa, *fb; @@ -302,6 +302,29 @@ rde_filter_equal(struct filter_head *a, struct filter_head *b, continue; } + /* skip all rules with wrong peer */ + if (fa != NULL && fa->peer.groupid != 0 && + fa->peer.groupid != peer->conf.groupid) { + fa = TAILQ_NEXT(fa, entry); + continue; + } + if (fa != NULL && fa->peer.peerid != 0 && + fa->peer.peerid != peer->conf.id) { + fa = TAILQ_NEXT(fa, entry); + continue; + } + + if (fb != NULL && fb->peer.groupid != 0 && + fb->peer.groupid != peer->conf.groupid) { + fb = TAILQ_NEXT(fb, entry); + continue; + } + if (fb != NULL && fb->peer.peerid != 0 && + fb->peer.peerid != peer->conf.id) { + fb = TAILQ_NEXT(fb, entry); + continue; + } + /* compare the two rules */ if ((fa == NULL && fb != NULL) || (fa != NULL && fb == NULL)) /* new rule added or removed */ |