summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2006-05-28 23:24:16 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2006-05-28 23:24:16 +0000
commit170ae77a02c1c6dd3df3fadc9b848c46f185c4fb (patch)
tree851e1f8be5382b9ae18dbc98865b131c9cb98809 /usr.sbin/bgpd
parente478d770baf19ef2f71f91c58294908cface9e61 (diff)
Even better nexthop delete behaviour. Do not delete nexthop if they are used
by filter sets or if the nexthop is currently looked up. With this the "nexthop_update: non-existent nexthop" warning should be history. OK henning@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/rde.h3
-rw-r--r--usr.sbin/bgpd/rde_filter.c11
-rw-r--r--usr.sbin/bgpd/rde_rib.c34
3 files changed, 33 insertions, 15 deletions
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index bb3c0e9d6ce..f3cdb01a0ba 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.94 2006/05/28 22:07:54 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.95 2006/05/28 23:24:15 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -335,6 +335,7 @@ void nexthop_modify(struct rde_aspath *, struct bgpd_addr *,
enum action_types, sa_family_t);
void nexthop_link(struct rde_aspath *);
void nexthop_unlink(struct rde_aspath *);
+int nexthop_delete(struct nexthop *);
void nexthop_update(struct kroute_nexthop *);
struct nexthop *nexthop_get(struct bgpd_addr *);
int nexthop_compare(struct nexthop *, struct nexthop *);
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index 12eaa717876..97d4b992a32 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.49 2006/05/28 22:07:54 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.50 2006/05/28 23:24:15 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -439,13 +439,8 @@ filterset_free(struct filter_set_head *sh)
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);
- }
+ --nh->refcnt;
+ (void)nexthop_delete(nh);
}
free(s);
}
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index a566c0288ad..30dc4256c1b 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.86 2006/05/28 22:07:54 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.87 2006/05/28 23:24:15 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -801,10 +801,18 @@ void
nexthop_shutdown(void)
{
u_int32_t i;
-
- for (i = 0; i <= nexthoptable.nexthop_hashmask; i++)
+ struct nexthop *nh, *nnh;
+
+ for (i = 0; i <= nexthoptable.nexthop_hashmask; i++) {
+ for(nh = LIST_FIRST(&nexthoptable.nexthop_hashtbl[i]);
+ nh != NULL; nh = nnh) {
+ nnh = LIST_NEXT(nh, nexthop_l);
+ nh->state = NEXTHOP_UNREACH;
+ (void)nexthop_delete(nh);
+ }
if (!LIST_EMPTY(&nexthoptable.nexthop_hashtbl[i]))
log_warnx("nexthop_shutdown: non-free table");
+ }
free(nexthoptable.nexthop_hashtbl);
}
@@ -817,7 +825,8 @@ nexthop_update(struct kroute_nexthop *msg)
nh = nexthop_lookup(&msg->nexthop);
if (nh == NULL) {
- log_warnx("nexthop_update: non-existent nexthop");
+ log_warnx("nexthop_update: non-existent nexthop %s",
+ log_addr(&msg->nexthop));
return;
}
@@ -826,6 +835,10 @@ nexthop_update(struct kroute_nexthop *msg)
else
nh->state = NEXTHOP_UNREACH;
+ if (nexthop_delete(nh))
+ /* nexthop no longer used */
+ return;
+
if (msg->connected) {
nh->flags |= NEXTHOP_CONNECTED;
memcpy(&nh->true_nexthop, &nh->exit_nexthop,
@@ -918,8 +931,15 @@ nexthop_unlink(struct rde_aspath *asp)
nh = asp->nexthop;
asp->nexthop = NULL;
- if (nh->refcnt > 0)
- return;
+ (void)nexthop_delete(nh);
+}
+
+int
+nexthop_delete(struct nexthop *nh)
+{
+ /* either pinned or in a state where it may not be deleted */
+ if (nh->refcnt > 0 || nh->state == NEXTHOP_LOOKUP)
+ return (0);
if (LIST_EMPTY(&nh->path_h)) {
LIST_REMOVE(nh, nexthop_l);
@@ -927,7 +947,9 @@ nexthop_unlink(struct rde_aspath *asp)
rdemem.nexthop_cnt--;
free(nh);
+ return (1);
}
+ return (0);
}
struct nexthop *