diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2006-05-28 23:24:16 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2006-05-28 23:24:16 +0000 |
commit | 170ae77a02c1c6dd3df3fadc9b848c46f185c4fb (patch) | |
tree | 851e1f8be5382b9ae18dbc98865b131c9cb98809 /usr.sbin/bgpd | |
parent | e478d770baf19ef2f71f91c58294908cface9e61 (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.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 11 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 34 |
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 * |