diff options
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 12 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 23 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 16 |
4 files changed, 47 insertions, 7 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index 6ae8fc0abef..43e284b9336 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.147 2009/06/05 20:26:38 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.148 2009/06/07 00:30:23 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -459,6 +459,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, struct peer *p; struct filter_rule *r; struct listen_addr *la; + struct rde_rib *rr; if (parse_config(conffile, conf, mrt_l, peer_l, &net_l, rules_l)) { log_warnx("config file %s has errors, not reloading", @@ -495,6 +496,15 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, la->fd = -1; } + /* RIBs for the RDE */ + while ((rr = SIMPLEQ_FIRST(&ribnames))) { + SIMPLEQ_REMOVE_HEAD(&ribnames, entry); + if (imsg_compose(ibuf_rde, IMSG_RECONF_RIB, 0, 0, -1, + rr, sizeof(struct rde_rib)) == -1) + return (-1); + free(rr); + } + /* networks for the RDE */ while ((n = TAILQ_FIRST(&net_l)) != NULL) { if (imsg_compose(ibuf_rde, IMSG_NETWORK_ADD, 0, 0, -1, diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index ff08a5dece5..45d70a80dad 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.239 2009/06/06 21:35:32 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.240 2009/06/07 00:30:23 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -298,6 +298,7 @@ enum imsg_type { IMSG_NETWORK_DONE, IMSG_FILTER_SET, IMSG_RECONF_CONF, + IMSG_RECONF_RIB, IMSG_RECONF_PEER, IMSG_RECONF_FILTER, IMSG_RECONF_LISTENER, diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 4662ced96c1..2140cfffd65 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.260 2009/06/06 21:21:37 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.261 2009/06/07 00:30:23 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -555,12 +555,14 @@ void rde_dispatch_imsg_parent(struct imsgbuf *ibuf) { struct imsg imsg; + struct mrt xmrt; + struct rde_rib rn; struct rde_peer *peer; struct filter_rule *r; struct filter_set *s; - struct mrt xmrt; struct nexthop *nh; int n, fd, reconf_in = 0, reconf_out = 0; + u_int16_t rid; if ((n = imsg_read(ibuf)) == -1) fatal("rde_dispatch_imsg_parent: imsg_read error"); @@ -584,6 +586,8 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) NULL) fatal(NULL); memcpy(nconf, imsg.data, sizeof(struct bgpd_config)); + for (rid = 0; rid < rib_size; rid++) + ribs[rid].state = RIB_DELETE; break; case IMSG_NETWORK_ADD: memcpy(&netconf_p, imsg.data, sizeof(netconf_p)); @@ -604,6 +608,17 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) TAILQ_INIT(&netconf_p.attrset); network_delete(&netconf_p, 1); break; + case IMSG_RECONF_RIB: + if (imsg.hdr.len - IMSG_HEADER_SIZE != + sizeof(struct rde_rib)) + fatalx("IMSG_RECONF_RIB bad len"); + memcpy(&rn, imsg.data, sizeof(rn)); + rid = rib_find(rn.name); + if (rid == RIB_FAILED) + rib_new(-1, rn.name, rn.flags); + else + ribs[rid].state = RIB_ACTIVE; + break; case IMSG_RECONF_FILTER: if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(struct filter_rule)) @@ -673,6 +688,10 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) } free(rules_l); rules_l = newrules; + for (rid = 0; rid < rib_size; rid++) { + if (ribs[rid].state == RIB_DELETE) + rib_free(&ribs[rid]); + } log_info("RDE reconfigured"); break; case IMSG_NEXTHOP_UPDATE: diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index b3b6bdab6dd..dae2a0b546b 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.114 2009/06/04 21:53:43 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.115 2009/06/07 00:30:23 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> @@ -111,6 +111,8 @@ rib_free(struct rib *rib) for (ctx = LIST_FIRST(&rib_dump_h); ctx != NULL; ctx = next) { next = LIST_NEXT(ctx, entry); if (ctx->ctx_rib == rib) { + re = ctx->ctx_re; + re->flags &= ~F_RIB_ENTRYLOCK; LIST_REMOVE(ctx, entry); if (ctx->ctx_done) ctx->ctx_done(ctx->ctx_arg); @@ -122,8 +124,14 @@ rib_free(struct rib *rib) for (re = RB_MIN(rib_tree, &rib->rib); re != NULL; re = xre) { xre = RB_NEXT(rib_tree, &rib->rib, re); - for (p = LIST_FIRST(&re->prefix_h); p != NULL; p = np) { - np = LIST_NEXT(p, path_l); + /* + * Removing the prefixes is tricky because the last one + * will remove the rib_entry as well and at because we do + * a empty check in prefix_destroy() it is not possible to + * use the default for loop. + */ + while ((p = LIST_FIRST(&re->prefix_h))) { + np = LIST_NEXT(p, rib_l); if (p->aspath->pftableid) { struct bgpd_addr addr; @@ -133,6 +141,8 @@ rib_free(struct rib *rib) p->prefix->prefixlen, 1); } prefix_destroy(p); + if (np == NULL) + break; } } bzero(rib, sizeof(struct rib)); |