summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-08-10 08:34:07 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-08-10 08:34:07 +0000
commit5880db9fd4879245236af7d488336e9e2313b4fa (patch)
tree4f972828d1d21fbceb0166af40b4d6be9e8c4a6f
parent590b5f3b7041069f1a53ccf599beaf010f13b07f (diff)
Pass the correct peer to rde_apply_set(). rde_apply_set() needs to know
the peer where the prefix came from so that prepend-neighbor works. Extend rde_filter() and make sure that the correct peer is passed. Until now most cases resulted in a NULL peer causing a nasty crash that was found by David Ulevitch. OK henning@
-rw-r--r--usr.sbin/bgpd/rde.c12
-rw-r--r--usr.sbin/bgpd/rde.h4
-rw-r--r--usr.sbin/bgpd/rde_filter.c13
-rw-r--r--usr.sbin/bgpd/rde_update.c20
4 files changed, 28 insertions, 21 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 5647fa86ae5..e9a6210038c 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.168 2005/07/29 22:26:30 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.169 2005/08/10 08:34:06 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -706,7 +706,7 @@ rde_update_dispatch(struct imsg *imsg)
}
/* input filter */
- if (rde_filter(peer, NULL, &prefix, prefixlen,
+ if (rde_filter(peer, NULL, &prefix, prefixlen, peer,
DIR_IN) == ACTION_DENY)
continue;
@@ -763,7 +763,7 @@ rde_update_dispatch(struct imsg *imsg)
/* input filter */
if (rde_filter(peer, NULL, &prefix, prefixlen,
- DIR_IN) == ACTION_DENY)
+ peer, DIR_IN) == ACTION_DENY)
continue;
rde_update_log("withdraw", peer, NULL,
@@ -825,7 +825,7 @@ rde_update_dispatch(struct imsg *imsg)
*/
fasp = path_copy(asp);
/* input filter */
- if (rde_filter(peer, fasp, &prefix, prefixlen,
+ if (rde_filter(peer, fasp, &prefix, prefixlen, peer,
DIR_IN) == ACTION_DENY) {
path_put(fasp);
continue;
@@ -909,8 +909,8 @@ rde_update_dispatch(struct imsg *imsg)
fasp = path_copy(asp);
/* input filter */
- if (rde_filter(peer, fasp, &prefix,
- prefixlen, DIR_IN) == ACTION_DENY) {
+ if (rde_filter(peer, fasp, &prefix, prefixlen,
+ peer, DIR_IN) == ACTION_DENY) {
path_put(fasp);
continue;
}
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index bd6f8bcbcf7..1bef56b5e49 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.69 2005/07/29 12:38:40 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.70 2005/08/10 08:34:06 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -350,7 +350,7 @@ void pt_dump(void (*)(struct pt_entry *, void *), void *,
/* rde_filter.c */
enum filter_actions rde_filter(struct rde_peer *, struct rde_aspath *,
- struct bgpd_addr *, u_int8_t, enum directions);
+ struct bgpd_addr *, u_int8_t, struct rde_peer *, enum directions);
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);
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index c22226fc23d..62aeaf36175 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.33 2005/07/04 09:37:24 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.34 2005/08/10 08:34:06 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -31,7 +31,8 @@ int rde_filter_match(struct filter_rule *, struct rde_aspath *,
enum filter_actions
rde_filter(struct rde_peer *peer, struct rde_aspath *asp,
- struct bgpd_addr *prefix, u_int8_t prefixlen, enum directions dir)
+ struct bgpd_addr *prefix, u_int8_t prefixlen, struct rde_peer *from,
+ enum directions dir)
{
struct filter_rule *f;
enum filter_actions action = ACTION_ALLOW; /* default allow */
@@ -48,7 +49,7 @@ rde_filter(struct rde_peer *peer, struct rde_aspath *asp,
if (rde_filter_match(f, asp, prefix, prefixlen)) {
if (asp != NULL)
rde_apply_set(asp, &f->set, prefix->af,
- asp->peer, dir);
+ from, dir);
if (f->action != ACTION_NONE)
action = f->action;
if (f->quick)
@@ -60,7 +61,7 @@ rde_filter(struct rde_peer *peer, struct rde_aspath *asp,
void
rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
- sa_family_t af, struct rde_peer *peer, enum directions dir)
+ sa_family_t af, struct rde_peer *from, enum directions dir)
{
struct filter_set *set;
struct aspath *new;
@@ -149,7 +150,9 @@ rde_apply_set(struct rde_aspath *asp, struct filter_set_head *sh,
asp->aspath = new;
break;
case ACTION_SET_PREPEND_PEER:
- as = peer->conf.remote_as;
+ if (from == NULL)
+ break;
+ as = from->conf.remote_as;
prepend = set->action.prepend;
new = aspath_prepend(asp->aspath, as, prepend);
aspath_put(asp->aspath);
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 505121db7a0..0b6f835891b 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.38 2005/07/29 22:26:30 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.39 2005/08/10 08:34:06 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -360,8 +360,8 @@ up_generate_updates(struct rde_peer *peer,
/* default override not needed here as this is a withdraw */
- if (rde_filter(peer, fasp, &addr,
- old->prefix->prefixlen, DIR_OUT) == ACTION_DENY) {
+ if (rde_filter(peer, fasp, &addr, old->prefix->prefixlen,
+ old->peer, DIR_OUT) == ACTION_DENY) {
path_put(fasp);
return;
}
@@ -471,13 +471,13 @@ up_generate_updates(struct rde_peer *peer,
/*
* apply default outgoing overrides,
- * actually only prepend-self
+ * actually only prepend-self and nexthop no-modify
*/
rde_apply_set(fasp, &peer->conf.attrset, new->prefix->af,
- fasp->peer, DIR_DEFAULT_OUT);
+ new->aspath->peer, DIR_DEFAULT_OUT);
- if (rde_filter(peer, fasp, &addr,
- new->prefix->prefixlen, DIR_OUT) == ACTION_DENY) {
+ if (rde_filter(peer, fasp, &addr, new->prefix->prefixlen,
+ new->peer, DIR_OUT) == ACTION_DENY) {
path_put(fasp);
up_generate_updates(peer, NULL, old);
return;
@@ -561,7 +561,11 @@ up_generate_default(struct rde_peer *peer, sa_family_t af)
/* filter as usual */
bzero(&addr, sizeof(addr));
addr.af = af;
- if (rde_filter(peer, asp, &addr, 0, DIR_OUT) == ACTION_DENY) {
+ /*
+ * XXX we should pass peerself here. This will be fixed with the
+ * apply default overrides.
+ */
+ if (rde_filter(peer, asp, &addr, 0, NULL, DIR_OUT) == ACTION_DENY) {
path_put(asp);
return;
}