diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-04-23 19:23:28 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-04-23 19:23:28 +0000 |
commit | 494f39a1befc308729799247c26849ad4c2c1a50 (patch) | |
tree | 9b51c476c22bd280b7fa15bf6dc1d678e75f679a /usr.sbin/bgpd | |
parent | 9bac2bbde33a8f9b7e1d52e78e5db683f788aad9 (diff) |
Rework the way we handle announced networks. Instead of two freak rde_peers
use one that is less freaky. Merge bgpctl and config networks into one tree.
First step of a larger change in the RDE and this goes now in to allow to
move forward.
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r-- | usr.sbin/bgpd/rde.c | 112 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 6 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_decide.c | 11 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 32 |
4 files changed, 77 insertions, 84 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 93d63f19644..c8618fec25b 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.240 2009/03/18 19:45:09 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.241 2009/04/23 19:23:27 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -97,7 +97,6 @@ void network_init(struct network_head *); void network_add(struct network_config *, int); void network_delete(struct network_config *, int); void network_dump_upcall(struct pt_entry *, void *); -void network_flush(int); void rde_shutdown(void); int sa_cmp(struct bgpd_addr *, struct sockaddr *); @@ -106,8 +105,7 @@ volatile sig_atomic_t rde_quit = 0; struct bgpd_config *conf, *nconf; time_t reloadtime; struct rde_peer_head peerlist; -struct rde_peer peerself; -struct rde_peer peerdynamic; +struct rde_peer *peerself; struct filter_head *rules_l, *newrules; struct imsgbuf *ibuf_se; struct imsgbuf *ibuf_se_ctl; @@ -439,7 +437,8 @@ badnet: log_warnx("rde_dispatch: wrong imsg len"); break; } - network_flush(0); + prefix_network_clean(peerself, time(NULL), + F_ANN_DYNAMIC); break; case IMSG_FILTER_SET: if (imsg.hdr.len - IMSG_HEADER_SIZE != @@ -629,10 +628,12 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) free(nconf); nconf = NULL; parent_set = NULL; - prefix_network_clean(&peerself, reloadtime); + prefix_network_clean(peerself, reloadtime, 0); /* check if filter changed */ LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->conf.id == 0) + continue; peer->reconf_out = 0; peer->reconf_in = 0; if (peer->conf.softreconfig_out && @@ -1824,8 +1825,6 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req) rde_dump_filterout(peer, p, req); return; } - LIST_FOREACH(peer, &peerlist, peer_l) - rde_dump_filterout(peer, p, req); } } @@ -2122,6 +2121,8 @@ rde_softreconfig_out(struct pt_entry *pt, void *ptr) pt_getaddr(pt, &addr); LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->conf.id == 0) + continue; if (peer->reconf_out == 0) continue; if (up_test_update(peer, p) != 1) @@ -2249,6 +2250,8 @@ rde_generate_updates(struct prefix *new, struct prefix *old) return; LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->conf.id == 0) + continue; if (peer->state != PEER_UP) continue; up_generate_updates(rules_l, peer, new, old); @@ -2266,6 +2269,8 @@ rde_update_queue_runner(void) do { sent = 0; LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->conf.id == 0) + continue; if (peer->state != PEER_UP) continue; /* first withdraws */ @@ -2312,6 +2317,8 @@ rde_update6_queue_runner(void) do { sent = 0; LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->conf.id == 0) + continue; if (peer->state != PEER_UP) continue; len = sizeof(queue_buf) - MSGSIZE_HEADER; @@ -2333,6 +2340,8 @@ rde_update6_queue_runner(void) do { sent = 0; LIST_FOREACH(peer, &peerlist, peer_l) { + if (peer->conf.id == 0) + continue; if (peer->state != PEER_UP) continue; len = sizeof(queue_buf) - MSGSIZE_HEADER; @@ -2395,6 +2404,8 @@ struct peer_table { void peer_init(u_int32_t hashsize) { + struct peer_config pc; + struct in_addr id; u_int32_t hs, i; for (hs = 1; hs < hashsize; hs <<= 1) @@ -2408,6 +2419,19 @@ peer_init(u_int32_t hashsize) LIST_INIT(&peerlist); peertable.peer_hashmask = hs - 1; + + bzero(&pc, sizeof(pc)); + pc.remote_as = conf->as; + id.s_addr = conf->bgpid; + snprintf(pc.descr, sizeof(pc.descr), "LOCAL: ID %s", inet_ntoa(id)); + + peerself = peer_add(0, &pc); + if (peerself == NULL) + fatalx("peer_init add self"); + + peerself->state = PEER_UP; + peerself->remote_bgpid = ntohl(conf->bgpid); + peerself->short_as = conf->short_as; } void @@ -2660,24 +2684,8 @@ void network_init(struct network_head *net_l) { struct network *n; - struct in_addr id; reloadtime = time(NULL); - bzero(&peerself, sizeof(peerself)); - peerself.state = PEER_UP; - peerself.remote_bgpid = ntohl(conf->bgpid); - id.s_addr = conf->bgpid; - peerself.conf.remote_as = conf->as; - peerself.short_as = conf->short_as; - snprintf(peerself.conf.descr, sizeof(peerself.conf.descr), - "LOCAL: ID %s", inet_ntoa(id)); - bzero(&peerdynamic, sizeof(peerdynamic)); - peerdynamic.state = PEER_UP; - peerdynamic.remote_bgpid = ntohl(conf->bgpid); - peerdynamic.conf.remote_as = conf->as; - peerdynamic.short_as = conf->short_as; - snprintf(peerdynamic.conf.descr, sizeof(peerdynamic.conf.descr), - "LOCAL: ID %s", inet_ntoa(id)); while ((n = TAILQ_FIRST(net_l)) != NULL) { TAILQ_REMOVE(net_l, n, entry); @@ -2690,7 +2698,7 @@ void network_add(struct network_config *nc, int flagstatic) { struct rde_aspath *asp; - struct rde_peer *p; + u_int32_t flags = F_PREFIX_ANNOUNCED; asp = path_get(); asp->aspath = aspath_get(NULL, 0); @@ -2698,15 +2706,12 @@ network_add(struct network_config *nc, int flagstatic) asp->flags = F_ATTR_ORIGIN | F_ATTR_ASPATH | F_ATTR_LOCALPREF | F_PREFIX_ANNOUNCED; /* the nexthop is unset unless a default set overrides it */ + if (!flagstatic) + flags |= F_ANN_DYNAMIC; - if (flagstatic) - p = &peerself; - else - p = &peerdynamic; - - rde_apply_set(asp, &nc->attrset, nc->prefix.af, p, p); - path_update(p, asp, &nc->prefix, nc->prefixlen, F_ORIGINAL); - path_update(p, asp, &nc->prefix, nc->prefixlen, F_LOCAL); + rde_apply_set(asp, &nc->attrset, nc->prefix.af, peerself, peerself); + path_update(peerself, asp, &nc->prefix, nc->prefixlen, flags | F_ORIGINAL); + path_update(peerself, asp, &nc->prefix, nc->prefixlen, flags | F_LOCAL); path_put(asp); filterset_free(&nc->attrset); @@ -2715,15 +2720,13 @@ network_add(struct network_config *nc, int flagstatic) void network_delete(struct network_config *nc, int flagstatic) { - struct rde_peer *p; + u_int32_t flags = F_PREFIX_ANNOUNCED; - if (flagstatic) - p = &peerself; - else - p = &peerdynamic; + if (!flagstatic) + flags |= F_ANN_DYNAMIC; - prefix_remove(p, &nc->prefix, nc->prefixlen, F_LOCAL); - prefix_remove(p, &nc->prefix, nc->prefixlen, F_ORIGINAL); + prefix_remove(peerself, &nc->prefix, nc->prefixlen, flags | F_LOCAL); + prefix_remove(peerself, &nc->prefix, nc->prefixlen, flags | F_ORIGINAL); } void @@ -2745,7 +2748,7 @@ network_dump_upcall(struct pt_entry *pt, void *ptr) pt_getaddr(p->prefix, &addr); k.prefix.s_addr = addr.v4.s_addr; k.prefixlen = p->prefix->prefixlen; - if (p->aspath->peer == &peerself) + if (p->aspath->peer == peerself) k.flags = F_KERNEL; if (imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_NETWORK, 0, pid, -1, &k, sizeof(k)) == -1) @@ -2757,7 +2760,7 @@ network_dump_upcall(struct pt_entry *pt, void *ptr) pt_getaddr(p->prefix, &addr); memcpy(&k6.prefix, &addr.v6, sizeof(k6.prefix)); k6.prefixlen = p->prefix->prefixlen; - if (p->aspath->peer == &peerself) + if (p->aspath->peer == peerself) k6.flags = F_KERNEL; if (imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_NETWORK6, 0, pid, -1, &k6, sizeof(k6)) == -1) @@ -2767,21 +2770,11 @@ network_dump_upcall(struct pt_entry *pt, void *ptr) } } -void -network_flush(int flagstatic) -{ - if (flagstatic) - prefix_network_clean(&peerself, time(NULL)); - else - prefix_network_clean(&peerdynamic, time(NULL)); -} - /* clean up */ void rde_shutdown(void) { struct rde_peer *p; - struct rde_aspath *asp, *nasp; struct filter_rule *r; u_int32_t i; @@ -2797,21 +2790,6 @@ rde_shutdown(void) while ((p = LIST_FIRST(&peertable.peer_hashtbl[i])) != NULL) peer_down(p->conf.id); - /* free announced network prefixes */ - peerself.remote_bgpid = 0; - peerself.state = PEER_DOWN; - for (asp = LIST_FIRST(&peerself.path_h); asp != NULL; asp = nasp) { - nasp = LIST_NEXT(asp, peer_l); - path_remove(asp); - } - - peerdynamic.remote_bgpid = 0; - peerdynamic.state = PEER_DOWN; - for (asp = LIST_FIRST(&peerdynamic.path_h); asp != NULL; asp = nasp) { - nasp = LIST_NEXT(asp, peer_l); - path_remove(asp); - } - /* free filters */ while ((r = TAILQ_FIRST(rules_l)) != NULL) { TAILQ_REMOVE(rules_l, r, entry); diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index e2709d4e513..78debe20f4b 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.105 2009/03/19 06:52:59 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.106 2009/04/23 19:23:27 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -164,6 +164,8 @@ LIST_HEAD(prefix_head, prefix); #define F_ATTR_LINKED 0x20000 #define F_LOCAL 0x40000 /* Local-RIB */ #define F_ORIGINAL 0x80000 /* Adj-RIB-In */ +#define F_RIB_MASK (F_LOCAL | F_ORIGINAL) +#define F_ANN_DYNAMIC 0x100000 #define ORIGIN_IGP 0 @@ -357,7 +359,7 @@ struct prefix *prefix_bypeer(struct pt_entry *, struct rde_peer *, u_int32_t); void prefix_updateall(struct rde_aspath *, enum nexthop_state, enum nexthop_state); void prefix_destroy(struct prefix *); -void prefix_network_clean(struct rde_peer *, time_t); +void prefix_network_clean(struct rde_peer *, time_t, u_int32_t); void nexthop_init(u_int32_t); void nexthop_shutdown(void); diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c index 963d95718be..c7f0d2dd93a 100644 --- a/usr.sbin/bgpd/rde_decide.c +++ b/usr.sbin/bgpd/rde_decide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_decide.c,v 1.51 2008/05/08 09:51:46 henning Exp $ */ +/* $OpenBSD: rde_decide.c,v 1.52 2009/04/23 19:23:27 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> @@ -201,9 +201,16 @@ prefix_cmp(struct prefix *p1, struct prefix *p2) &p2->aspath->peer->remote_addr, sizeof(p1->aspath->peer->remote_addr))); + /* 12. for announced prefixes prefer dynamic routes */ + if ((p1->flags & F_ANN_DYNAMIC) != (p2->flags & F_ANN_DYNAMIC)) { + if (p1->flags & F_ANN_DYNAMIC) + return (1); + else + return (-1); + } + fatalx("Uh, oh a politician in the decision process"); /* NOTREACHED */ - return (0); } /* diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index 6e3410cb31a..299cea252a1 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.97 2008/11/21 17:41:22 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.98 2009/04/23 19:23:27 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> @@ -104,14 +104,14 @@ path_update(struct rde_peer *peer, struct rde_aspath *nasp, NULL) { do { if (path_compare(nasp, p->aspath) == 0) { - if ((p->flags & flags) == 0) { + if ((p->flags & flags & F_RIB_MASK) == 0) { if (oldp != NULL) { asp = oldp->aspath; prefix_destroy(oldp); if (path_empty(asp)) path_destroy(asp); } - p->flags |= flags; + p->flags |= flags & F_RIB_MASK; PREFIX_COUNT(p->aspath, flags, 1); PREFIX_COUNT(peer, flags, 1); @@ -136,7 +136,7 @@ path_update(struct rde_peer *peer, struct rde_aspath *nasp, } /* Do not try to move a prefix that is in the wrong RIB. */ - if (p == NULL || (p->flags & flags) == 0) + if (p == NULL || (p->flags & flags & F_RIB_MASK) == 0) p = oldp; /* @@ -477,12 +477,12 @@ prefix_move(struct rde_aspath *asp, struct prefix *p, u_int32_t flags) * to flags the old prefix p may not be removed but instead p->flags * needs to be adjusted. */ - if (p->flags != flags) { - if ((p->flags & flags) == 0) + if ((p->flags & F_RIB_MASK) != (flags & F_RIB_MASK)) { + if ((p->flags & flags & F_RIB_MASK) == 0) fatalx("prefix_move: " "prefix is not part of desired RIB"); - p->flags &= ~flags; + p->flags &= ~(flags & F_RIB_MASK); PREFIX_COUNT(p->aspath, flags, -1); /* as before peer count needs no update because of move */ @@ -557,8 +557,8 @@ prefix_remove(struct rde_peer *peer, struct bgpd_addr *prefix, int prefixlen, } /* if prefix belongs to more than one RIB just remove one instance */ - if (p->flags != flags) { - p->flags &= ~flags; + if ((p->flags & F_RIB_MASK) != (flags & F_RIB_MASK)) { + p->flags &= ~(flags & F_RIB_MASK); PREFIX_COUNT(p->aspath, flags, -1); PREFIX_COUNT(peer, flags, -1); @@ -609,8 +609,13 @@ prefix_bypeer(struct pt_entry *pte, struct rde_peer *peer, u_int32_t flags) struct prefix *p; LIST_FOREACH(p, &pte->prefix_h, prefix_l) { - if (p->aspath->peer == peer && p->flags & flags) - return (p); + if (p->aspath->peer != peer || + (p->flags & flags & F_RIB_MASK) == 0) + continue; + if (flags & F_PREFIX_ANNOUNCED && + (flags & F_ANN_DYNAMIC) != (p->flags & F_ANN_DYNAMIC)) + continue; + return (p); } return (NULL); } @@ -679,7 +684,7 @@ prefix_destroy(struct prefix *p) * helper function to clean up the connected networks after a reload */ void -prefix_network_clean(struct rde_peer *peer, time_t reloadtime) +prefix_network_clean(struct rde_peer *peer, time_t reloadtime, u_int32_t flags) { struct rde_aspath *asp, *xasp; struct prefix *p, *xp; @@ -689,7 +694,8 @@ prefix_network_clean(struct rde_peer *peer, time_t reloadtime) xasp = LIST_NEXT(asp, peer_l); for (p = LIST_FIRST(&asp->prefix_h); p != NULL; p = xp) { xp = LIST_NEXT(p, path_l); - if (reloadtime > p->lastchange) { + if (reloadtime > p->lastchange && + (p->flags & F_ANN_DYNAMIC) == flags) { pte = p->prefix; prefix_unlink(p); prefix_free(p); |