summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-11-01 15:21:55 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-11-01 15:21:55 +0000
commit00ea89f7b42ca780e837db36cf74c4f202d32b80 (patch)
tree22172bde139ac55423f48b694bfd6f592dc6262a
parente3e46433283cced91d63dc20ff9081b4c112c361 (diff)
Softreconfig out support. On config reload filter changes of outgoing rules
will propagte directly to the neighbors. There is no need to restart bgpd in that case. Currently not optimal but a good start. "get it in" henning@
-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;