summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bgpd/bgpd.c12
-rw-r--r--usr.sbin/bgpd/bgpd.h3
-rw-r--r--usr.sbin/bgpd/rde.c23
-rw-r--r--usr.sbin/bgpd/rde_rib.c16
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));