diff options
author | 2006-01-24 14:48:47 +0000 | |
---|---|---|
committer | 2006-01-24 14:48:47 +0000 | |
commit | 8cbfadc183a146d309b05651e1384dba91536658 (patch) | |
tree | c463f476e6fe9fbc4724cd3d26a4c1bd8914a25e | |
parent | Functions in the poll() loop should only be moved around if there are no (diff) | |
download | wireguard-openbsd-8cbfadc183a146d309b05651e1384dba91536658.tar.xz wireguard-openbsd-8cbfadc183a146d309b05651e1384dba91536658.zip |
Last bits for softreconfig in support. Now bgpd will automaticaly rei-filter
the RIB after a reload so you no longer need to clear sessions because you
modified filters. Looks good henning@.
-rw-r--r-- | usr.sbin/bgpd/rde.c | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index bb6121fb1c1..cfcd1150e0c 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.197 2006/01/24 14:14:04 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.198 2006/01/24 14:48:47 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -64,6 +64,7 @@ void rde_dump_as(struct filter_as *, pid_t); void rde_dump_prefix_upcall(struct pt_entry *, void *); void rde_dump_prefix(struct ctl_show_rib_prefix *, pid_t); void rde_softreconfig_out(struct pt_entry *, void *); +void rde_softreconfig_in(struct pt_entry *, void *); void rde_up_dump_upcall(struct pt_entry *, void *); void rde_update_queue_runner(void); void rde_update6_queue_runner(void); @@ -545,6 +546,9 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) reconf_in = 1; } } + /* sync local-RIB first */ + if (reconf_in) + pt_dump(rde_softreconfig_in, NULL, AF_UNSPEC); /* then sync peers */ if (reconf_out) pt_dump(rde_softreconfig_out, NULL, AF_UNSPEC); @@ -1706,10 +1710,8 @@ rde_send_nexthop(struct bgpd_addr *next, int valid) } /* - * update specific functions + * soft reconfig specific functions */ -u_char queue_buf[4096]; - void rde_softreconfig_out(struct pt_entry *pt, void *ptr) { @@ -1765,6 +1767,69 @@ done: } void +rde_softreconfig_in(struct pt_entry *pt, void *ptr) +{ + struct prefix *p, *np; + struct rde_peer *peer; + struct rde_aspath *asp, *oasp, *nasp; + enum filter_actions oa, na; + struct bgpd_addr addr; + + pt_getaddr(pt, &addr); + for(p = LIST_FIRST(&pt->prefix_h); p != NULL; p = np) { + np = LIST_NEXT(p, prefix_l); + if (!(p->flags & F_ORIGINAL)) + continue; + + /* store aspath as prefix may change till we're done */ + asp = p->aspath; + peer = asp->peer; + + if (peer->reconf_in == 0) + continue; + + /* check if prefix changed */ + oa = rde_filter(&oasp, rules_l, peer, asp, &addr, + pt->prefixlen, peer, DIR_IN); + na = rde_filter(&nasp, newrules, peer, asp, &addr, + pt->prefixlen, peer, DIR_IN); + oasp = oasp != NULL ? oasp : asp; + nasp = nasp != NULL ? nasp : asp; + + if (oa == ACTION_DENY && na == ACTION_DENY) + /* nothing todo */ + goto done; + if (oa == ACTION_DENY && na == ACTION_ALLOW) { + /* update Local-RIB */ + path_update(peer, nasp, &addr, pt->prefixlen, F_LOCAL); + goto done; + } + if (oa == ACTION_ALLOW && na == ACTION_DENY) { + /* remove from Local-RIB */ + prefix_remove(peer, &addr, pt->prefixlen, F_LOCAL); + goto done; + } + if (oa == ACTION_ALLOW && na == ACTION_ALLOW) { + if (path_compare(nasp, oasp) == 0) + goto done; + /* send update */ + path_update(peer, nasp, &addr, pt->prefixlen, F_LOCAL); + } + +done: + if (oasp != asp) + path_put(oasp); + if (nasp != asp) + path_put(nasp); + } +} + +/* + * update specific functions + */ +u_char queue_buf[4096]; + +void rde_up_dump_upcall(struct pt_entry *pt, void *ptr) { struct rde_peer *peer = ptr; |