summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/rde.c27
-rw-r--r--usr.sbin/bgpd/rde.h3
-rw-r--r--usr.sbin/bgpd/rde_filter.c14
-rw-r--r--usr.sbin/bgpd/rde_rib.c5
4 files changed, 45 insertions, 4 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 2b7dd2ab9e5..0ae7ccf70b2 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.205 2006/04/21 08:55:21 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.206 2006/05/28 22:07:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -126,6 +126,9 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
struct peer *p;
struct listen_addr *la;
struct pollfd pfd[3];
+ struct filter_rule *f;
+ struct filter_set *set;
+ struct nexthop *nh;
int i;
switch (pid = fork()) {
@@ -201,6 +204,15 @@ rde_main(struct bgpd_config *config, struct peer *peer_l,
log_info("route decision engine ready");
+ TAILQ_FOREACH(f, rules, entry) {
+ TAILQ_FOREACH(set, &f->set, entry) {
+ if (set->type == ACTION_SET_NEXTHOP) {
+ nh = nexthop_get(&set->action.nexthop);
+ nh->refcnt++;
+ }
+ }
+ }
+
while (rde_quit == 0) {
bzero(pfd, sizeof(pfd));
pfd[PFD_PIPE_MAIN].fd = ibuf_main->fd;
@@ -280,6 +292,7 @@ rde_dispatch_imsg_session(struct imsgbuf *ibuf)
struct rde_peer *peer;
struct session_up sup;
struct filter_set *s;
+ struct nexthop *nh;
pid_t pid;
int n;
sa_family_t af = AF_UNSPEC;
@@ -393,6 +406,11 @@ badnet:
fatal(NULL);
memcpy(s, imsg.data, sizeof(struct filter_set));
TAILQ_INSERT_TAIL(session_set, s, entry);
+
+ if (s->type == ACTION_SET_NEXTHOP) {
+ nh = nexthop_get(&s->action.nexthop);
+ nh->refcnt++;
+ }
break;
case IMSG_CTL_SHOW_NETWORK:
if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(af)) {
@@ -474,6 +492,7 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
struct filter_rule *r;
struct filter_set *s;
struct mrt *xmrt;
+ struct nexthop *nh;
int n, reconf_in = 0, reconf_out = 0;
if ((n = imsg_read(ibuf)) == -1)
@@ -593,6 +612,11 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
fatal(NULL);
memcpy(s, imsg.data, sizeof(struct filter_set));
TAILQ_INSERT_TAIL(parent_set, s, entry);
+
+ if (s->type == ACTION_SET_NEXTHOP) {
+ nh = nexthop_get(&s->action.nexthop);
+ nh->refcnt++;
+ }
break;
case IMSG_MRT_OPEN:
case IMSG_MRT_REOPEN:
@@ -2439,6 +2463,7 @@ rde_shutdown(void)
/* free filters */
while ((r = TAILQ_FIRST(rules_l)) != NULL) {
TAILQ_REMOVE(rules_l, r, entry);
+ filterset_free(&r->set);
free(r);
}
free(rules_l);
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 198e8c4700c..bb3c0e9d6ce 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.93 2006/04/12 14:05:46 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.94 2006/05/28 22:07:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -201,6 +201,7 @@ struct nexthop {
*/
u_int32_t costs;
#endif
+ int refcnt; /* filterset reference counter */
enum nexthop_state state;
u_int8_t nexthop_netlen;
u_int8_t flags;
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index 887e60efaba..12eaa717876 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.48 2006/04/26 17:13:14 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.49 2006/05/28 22:07:54 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -428,6 +428,7 @@ void
filterset_free(struct filter_set_head *sh)
{
struct filter_set *s;
+ struct nexthop *nh;
while ((s = TAILQ_FIRST(sh)) != NULL) {
TAILQ_REMOVE(sh, s, entry);
@@ -435,6 +436,17 @@ filterset_free(struct filter_set_head *sh)
rtlabel_unref(s->action.id);
else if (s->type == ACTION_PFTABLE_ID)
pftable_unref(s->action.id);
+ else if (s->type == ACTION_SET_NEXTHOP &&
+ bgpd_process == PROC_RDE) {
+ nh = nexthop_get(&s->action.nexthop);
+ if (--nh->refcnt <= 0 && LIST_EMPTY(&nh->path_h)) {
+ LIST_REMOVE(nh, nexthop_l);
+ rde_send_nexthop(&nh->exit_nexthop, 0);
+
+ rdemem.nexthop_cnt--;
+ free(nh);
+ }
+ }
free(s);
}
}
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index 2d93bdfe1f8..a566c0288ad 100644
--- a/usr.sbin/bgpd/rde_rib.c
+++ b/usr.sbin/bgpd/rde_rib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_rib.c,v 1.85 2006/04/04 12:03:26 henning Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.86 2006/05/28 22:07:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -918,6 +918,9 @@ nexthop_unlink(struct rde_aspath *asp)
nh = asp->nexthop;
asp->nexthop = NULL;
+ if (nh->refcnt > 0)
+ return;
+
if (LIST_EMPTY(&nh->path_h)) {
LIST_REMOVE(nh, nexthop_l);
rde_send_nexthop(&nh->exit_nexthop, 0);