summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2006-01-24 14:14:04 +0000
committerclaudio <claudio@openbsd.org>2006-01-24 14:14:04 +0000
commit1972c2cde5ceda0340e76da357519658239a62b2 (patch)
tree292b2a91f94f6dbadf0512ee299c4f8a286993b0
parentFinally start using the Adj-RIB-In. The most complex part is the modification (diff)
downloadwireguard-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.c26
-rw-r--r--usr.sbin/bgpd/rde.h6
-rw-r--r--usr.sbin/bgpd/rde_filter.c27
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 */