diff options
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r-- | usr.sbin/bgpd/rde.c | 27 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 14 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 5 |
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); |