summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bgpd/rde.c63
-rw-r--r--usr.sbin/bgpd/rde.h3
-rw-r--r--usr.sbin/bgpd/rde_rib.c4
3 files changed, 59 insertions, 11 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index bd93d3904bc..bdbf3a2d16f 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.266 2009/10/05 11:35:48 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.267 2009/10/05 12:03:45 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -81,6 +81,7 @@ void rde_dump_done(void *);
void rde_up_dump_upcall(struct rib_entry *, void *);
void rde_softreconfig_out(struct rib_entry *, void *);
void rde_softreconfig_in(struct rib_entry *, void *);
+void rde_softreconfig_load(struct rib_entry *, void *);
void rde_update_queue_runner(void);
void rde_update6_queue_runner(void);
@@ -668,7 +669,15 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
reconf_in = 1;
}
}
- /* XXX this needs rework anyway */
+ /* bring ribs in sync before softreconfig dance */
+ for (rid = 0; rid < rib_size; rid++) {
+ if (ribs[rid].state == RIB_DELETE)
+ rib_free(&ribs[rid]);
+ else if (ribs[rid].state == RIB_NEW)
+ rib_dump(&ribs[0],
+ rde_softreconfig_load, &ribs[rid],
+ AF_UNSPEC);
+ }
/* sync local-RIB first */
if (reconf_in)
rib_dump(&ribs[0], rde_softreconfig_in, NULL,
@@ -676,9 +685,13 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf)
/* then sync peers */
if (reconf_out) {
int i;
- for (i = 1; i < rib_size; i++)
+ for (i = 1; i < rib_size; i++) {
+ if (ribs[i].state == RIB_NEW)
+ /* already synced by _load */
+ continue;
rib_dump(&ribs[i], rde_softreconfig_out,
NULL, AF_UNSPEC);
+ }
}
while ((r = TAILQ_FIRST(rules_l)) != NULL) {
@@ -688,10 +701,6 @@ 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:
@@ -2248,6 +2257,10 @@ rde_softreconfig_in(struct rib_entry *re, void *ptr)
continue;
for (i = 1; i < rib_size; i++) {
+ /* only active ribs need a softreconfig rerun */
+ if (ribs[i].state != RIB_ACTIVE)
+ continue;
+
/* check if prefix changed */
oa = rde_filter(i, &oasp, rules_l, peer, asp, &addr,
pt->prefixlen, peer, DIR_IN);
@@ -2275,7 +2288,7 @@ rde_softreconfig_in(struct rib_entry *re, void *ptr)
if (path_compare(nasp, oasp) == 0)
goto done;
/* send update */
- path_update(&ribs[1], peer, nasp, &addr,
+ path_update(&ribs[i], peer, nasp, &addr,
pt->prefixlen);
}
@@ -2288,6 +2301,40 @@ done:
}
}
+void
+rde_softreconfig_load(struct rib_entry *re, void *ptr)
+{
+ struct rib *rib = ptr;
+ struct prefix *p, *np;
+ struct pt_entry *pt;
+ struct rde_peer *peer;
+ struct rde_aspath *asp, *nasp;
+ enum filter_actions action;
+ struct bgpd_addr addr;
+
+ pt = re->prefix;
+ pt_getaddr(pt, &addr);
+ for (p = LIST_FIRST(&re->prefix_h); p != NULL; p = np) {
+ np = LIST_NEXT(p, rib_l);
+
+ /* store aspath as prefix may change till we're done */
+ asp = p->aspath;
+ peer = asp->peer;
+
+ action = rde_filter(rib->id, &nasp, newrules, peer, asp, &addr,
+ pt->prefixlen, peer, DIR_IN);
+ nasp = nasp != NULL ? nasp : asp;
+
+ if (action == ACTION_ALLOW) {
+ /* update Local-RIB */
+ path_update(rib, peer, nasp, &addr, pt->prefixlen);
+ }
+
+ if (nasp != asp)
+ path_put(nasp);
+ }
+}
+
/*
* update specific functions
*/
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index dc2e83a6a1b..bb4a7e929ee 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.121 2009/08/06 08:53:11 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.122 2009/10/05 12:03:45 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -265,6 +265,7 @@ struct rib_entry {
enum rib_state {
RIB_NONE,
+ RIB_NEW,
RIB_ACTIVE,
RIB_DELETE
};
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index 78dc203ec8d..591d4e60936 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.116 2009/06/29 14:13:48 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.117 2009/10/05 12:03:45 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -78,7 +78,7 @@ rib_new(int id, char *name, u_int16_t flags)
bzero(&ribs[id], sizeof(struct rib));
strlcpy(ribs[id].name, name, sizeof(ribs[id].name));
RB_INIT(&ribs[id].rib);
- ribs[id].state = RIB_ACTIVE;
+ ribs[id].state = RIB_NEW;
ribs[id].id = id;
ribs[id].flags = flags;