diff options
-rw-r--r-- | usr.sbin/bgpd/rde.c | 63 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 3 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 4 |
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; |