summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bgpd/rde.c78
-rw-r--r--usr.sbin/bgpd/rde.h12
-rw-r--r--usr.sbin/bgpd/rde_filter.c12
-rw-r--r--usr.sbin/bgpd/rde_update.c17
4 files changed, 87 insertions, 32 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index d2dcd3559ca..14eda22d516 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.176 2005/11/01 14:37:16 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.177 2005/11/01 15:21:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -65,6 +65,7 @@ void rde_dump_upcall(struct pt_entry *, void *);
void rde_dump_as(struct filter_as *, pid_t);
void rde_dump_prefix_upcall(struct pt_entry *, void *);
void rde_dump_prefix(struct ctl_show_rib_prefix *, pid_t);
+void rde_softreconfig_out(struct pt_entry *, void *);
void rde_up_dump_upcall(struct pt_entry *, void *);
void rde_update_queue_runner(void);
void rde_update6_queue_runner(void);
@@ -520,7 +521,8 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
nconf = NULL;
parent_set = NULL;
prefix_network_clean(&peerself, reloadtime);
- /* soft reconfig 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);
@@ -706,7 +708,7 @@ rde_update_dispatch(struct imsg *imsg)
}
/* input filter */
- if (rde_filter(peer, NULL, &prefix, prefixlen, peer,
+ if (rde_filter(rules_l, peer, NULL, &prefix, prefixlen, peer,
DIR_IN) == ACTION_DENY)
continue;
@@ -762,8 +764,8 @@ rde_update_dispatch(struct imsg *imsg)
mplen -= pos;
/* input filter */
- if (rde_filter(peer, NULL, &prefix, prefixlen,
- peer, DIR_IN) == ACTION_DENY)
+ if (rde_filter(rules_l, peer, NULL, &prefix,
+ prefixlen, peer, DIR_IN) == ACTION_DENY)
continue;
rde_update_log("withdraw", peer, NULL,
@@ -827,7 +829,7 @@ rde_update_dispatch(struct imsg *imsg)
*/
fasp = path_copy(asp);
/* input filter */
- if (rde_filter(peer, fasp, &prefix, prefixlen, peer,
+ if (rde_filter(rules_l, peer, fasp, &prefix, prefixlen, peer,
DIR_IN) == ACTION_DENY) {
path_put(fasp);
continue;
@@ -908,8 +910,8 @@ rde_update_dispatch(struct imsg *imsg)
fasp = path_copy(asp);
/* input filter */
- if (rde_filter(peer, fasp, &prefix, prefixlen,
- peer, DIR_IN) == ACTION_DENY) {
+ if (rde_filter(rules_l, peer, fasp, &prefix,
+ prefixlen, peer, DIR_IN) == ACTION_DENY) {
path_put(fasp);
continue;
}
@@ -1777,13 +1779,65 @@ rde_send_nexthop(struct bgpd_addr *next, int valid)
u_char queue_buf[4096];
void
+rde_softreconfig_out(struct pt_entry *pt, void *ptr)
+{
+ struct prefix *p = pt->active;
+ struct rde_peer *peer;
+ struct rde_aspath *oasp, *nasp;
+ enum filter_actions oa, na;
+ struct bgpd_addr addr;
+
+ if (p == NULL)
+ return;
+
+ pt_getaddr(pt, &addr);
+ LIST_FOREACH(peer, &peerlist, peer_l) {
+ if (up_test_update(peer, p) != 1)
+ continue;
+
+ /* copy attributes for output filter */
+ oasp = path_copy(p->aspath);
+ nasp = path_copy(p->aspath);
+
+ oa = rde_filter(rules_l, peer, oasp, &addr, pt->prefixlen,
+ p->peer, DIR_OUT);
+ na = rde_filter(newrules, peer, nasp, &addr, pt->prefixlen,
+ p->peer, DIR_OUT);
+
+ if (oa == ACTION_DENY && na == ACTION_DENY)
+ /* nothing todo */
+ goto done;
+ if (oa == ACTION_DENY && na == ACTION_ALLOW) {
+ /* send update */
+ up_generate(peer, nasp, &addr, pt->prefixlen);
+ goto done;
+ }
+ if (oa == ACTION_ALLOW && na == ACTION_DENY) {
+ /* send withdraw */
+ up_generate(peer, NULL, &addr, pt->prefixlen);
+ goto done;
+ }
+ if (oa == ACTION_ALLOW && na == ACTION_ALLOW) {
+ if (path_compare(nasp, oasp) == 0)
+ goto done;
+ /* send update */
+ up_generate(peer, nasp, &addr, pt->prefixlen);
+ }
+
+done:
+ path_put(oasp);
+ path_put(nasp);
+ }
+}
+
+void
rde_up_dump_upcall(struct pt_entry *pt, void *ptr)
{
struct rde_peer *peer = ptr;
if (pt->active == NULL)
return;
- up_generate_updates(peer, pt->active, NULL);
+ up_generate_updates(rules_l, peer, pt->active, NULL);
}
void
@@ -1803,7 +1857,7 @@ rde_generate_updates(struct prefix *new, struct prefix *old)
LIST_FOREACH(peer, &peerlist, peer_l) {
if (peer->state != PEER_UP)
continue;
- up_generate_updates(peer, new, old);
+ up_generate_updates(rules_l, peer, new, old);
}
}
@@ -2150,7 +2204,7 @@ peer_dump(u_int32_t id, u_int16_t afi, u_int8_t safi)
safi == SAFI_BOTH) {
if (peer->conf.announce_type ==
ANNOUNCE_DEFAULT_ROUTE)
- up_generate_default(peer, AF_INET);
+ up_generate_default(rules_l, peer, AF_INET);
else
pt_dump(rde_up_dump_upcall, peer, AF_INET);
}
@@ -2159,7 +2213,7 @@ peer_dump(u_int32_t id, u_int16_t afi, u_int8_t safi)
safi == SAFI_BOTH) {
if (peer->conf.announce_type ==
ANNOUNCE_DEFAULT_ROUTE)
- up_generate_default(peer, AF_INET6);
+ up_generate_default(rules_l, peer, AF_INET6);
else
pt_dump(rde_up_dump_upcall, peer, AF_INET6);
}
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index b9fd7b8a41a..7e4988bc3ed 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.71 2005/11/01 14:37:16 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.72 2005/11/01 15:21:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -331,9 +331,10 @@ void up_down(struct rde_peer *);
int up_test_update(struct rde_peer *, struct prefix *);
int up_generate(struct rde_peer *, struct rde_aspath *,
struct bgpd_addr *, u_int8_t);
-void up_generate_updates(struct rde_peer *,
+void up_generate_updates(struct filter_head *, struct rde_peer *,
struct prefix *, struct prefix *);
-void up_generate_default(struct rde_peer *, sa_family_t);
+void up_generate_default(struct filter_head *, struct rde_peer *,
+ sa_family_t);
int up_dump_prefix(u_char *, int, struct uplist_prefix *,
struct rde_peer *);
int up_dump_attrnlri(u_char *, int, struct rde_peer *);
@@ -353,8 +354,9 @@ void pt_dump(void (*)(struct pt_entry *, void *), void *,
sa_family_t);
/* rde_filter.c */
-enum filter_actions rde_filter(struct rde_peer *, struct rde_aspath *,
- struct bgpd_addr *, u_int8_t, struct rde_peer *, enum directions);
+enum filter_actions rde_filter(struct filter_head *, struct rde_peer *,
+ struct rde_aspath *, 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 9d197c7f19a..b238eb40da9 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.35 2005/11/01 10:58:29 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.36 2005/11/01 15:21:54 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -24,20 +24,18 @@
#include "bgpd.h"
#include "rde.h"
-extern struct filter_head *rules_l; /* XXX ugly */
-
int rde_filter_match(struct filter_rule *, struct rde_aspath *,
struct bgpd_addr *, u_int8_t);
enum filter_actions
-rde_filter(struct rde_peer *peer, struct rde_aspath *asp,
- struct bgpd_addr *prefix, u_int8_t prefixlen, struct rde_peer *from,
- enum directions dir)
+rde_filter(struct filter_head *rules, struct rde_peer *peer,
+ struct rde_aspath *asp, 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 */
- TAILQ_FOREACH(f, rules_l, entry) {
+ TAILQ_FOREACH(f, rules, entry) {
if (dir != f->dir)
continue;
if (f->peer.groupid != 0 &&
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 86b21cb8b16..5703cdee03e 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.42 2005/11/01 14:37:16 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.43 2005/11/01 15:21:54 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -394,7 +394,7 @@ up_generate(struct rde_peer *peer, struct rde_aspath *asp,
}
void
-up_generate_updates(struct rde_peer *peer,
+up_generate_updates(struct filter_head *rules, struct rde_peer *peer,
struct prefix *new, struct prefix *old)
{
struct rde_aspath *fasp;
@@ -412,7 +412,7 @@ up_generate_updates(struct rde_peer *peer,
fasp = path_copy(old->aspath);
pt_getaddr(old->prefix, &addr);
- if (rde_filter(peer, fasp, &addr, old->prefix->prefixlen,
+ if (rde_filter(rules, peer, fasp, &addr, old->prefix->prefixlen,
old->peer, DIR_OUT) == ACTION_DENY) {
path_put(fasp);
return;
@@ -426,7 +426,7 @@ up_generate_updates(struct rde_peer *peer,
case 1:
break;
case 0:
- up_generate_updates(peer, NULL, old);
+ up_generate_updates(rules, peer, NULL, old);
return;
case -1:
return;
@@ -436,10 +436,10 @@ up_generate_updates(struct rde_peer *peer,
fasp = path_copy(new->aspath);
pt_getaddr(new->prefix, &addr);
- if (rde_filter(peer, fasp, &addr, new->prefix->prefixlen,
+ if (rde_filter(rules, peer, fasp, &addr, new->prefix->prefixlen,
new->peer, DIR_OUT) == ACTION_DENY) {
path_put(fasp);
- up_generate_updates(peer, NULL, old);
+ up_generate_updates(rules, peer, NULL, old);
return;
}
@@ -453,7 +453,8 @@ up_generate_updates(struct rde_peer *peer,
/* send a default route to the specified peer */
void
-up_generate_default(struct rde_peer *peer, sa_family_t af)
+up_generate_default(struct filter_head *rules, struct rde_peer *peer,
+ sa_family_t af)
{
struct rde_aspath *asp;
struct bgpd_addr addr;
@@ -482,7 +483,7 @@ up_generate_default(struct rde_peer *peer, sa_family_t af)
bzero(&addr, sizeof(addr));
addr.af = af;
- if (rde_filter(peer, asp, &addr, 0, NULL, DIR_OUT) ==
+ if (rde_filter(rules, peer, asp, &addr, 0, NULL, DIR_OUT) ==
ACTION_DENY) {
path_put(asp);
return;