diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-08-10 08:34:07 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-08-10 08:34:07 +0000 |
commit | 5880db9fd4879245236af7d488336e9e2313b4fa (patch) | |
tree | 4f972828d1d21fbceb0166af40b4d6be9e8c4a6f | |
parent | 590b5f3b7041069f1a53ccf599beaf010f13b07f (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.c | 12 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 13 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_update.c | 20 |
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; } |