diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-12-31 15:34:03 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-12-31 15:34:03 +0000 |
commit | e4a9fa1df41cf5958271c8e82af5c52664f5b056 (patch) | |
tree | 5463401bf6d774198a906b62bafd806e96ac8721 /usr.sbin | |
parent | 6de774ec35c4faedf0d1243732019cb612cefd8f (diff) |
Instead of passing the config via arguments to the childs on bootup issue
a config reload as first step in bootup. This allows childs to start with
an empty config and a lot of special cleanup code can bite the dust.
Testing by myself and sthen@ with a few configs (more testing welcome).
Seems like a good idea henning@ & sthen@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 55 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 72 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.c | 70 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 13 |
4 files changed, 59 insertions, 151 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index f9ba8a42d91..3d02f5a9210 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.151 2009/12/01 14:28:05 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.152 2009/12/31 15:34:02 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -101,15 +101,11 @@ int main(int argc, char *argv[]) { struct bgpd_config conf; - struct peer *peer_l, *p; struct mrt_head mrt_l; - struct network_head net_l; + struct peer *peer_l, *p; struct filter_head *rules_l; - struct network *net; - struct filter_rule *r; struct mrt *m; struct listen_addr *la; - struct rde_rib *rr; struct pollfd pfd[POLL_MAX]; pid_t io_pid = 0, rde_pid = 0, pid; char *conffile; @@ -129,9 +125,8 @@ main(int argc, char *argv[]) err(1, NULL); bzero(&conf, sizeof(conf)); - LIST_INIT(&mrt_l); - TAILQ_INIT(&net_l); TAILQ_INIT(rules_l); + LIST_INIT(&mrt_l); peer_l = NULL; conf.csock = SOCKET_NAME; @@ -177,12 +172,15 @@ main(int argc, char *argv[]) if (argc > 0) usage(); - if (parse_config(conffile, &conf, &mrt_l, &peer_l, &net_l, rules_l)) { - free(rules_l); - exit(1); - } - if (conf.opts & BGPD_OPT_NOACTION) { + struct network_head net_l; + TAILQ_INIT(&net_l); + if (parse_config(conffile, &conf, &mrt_l, &peer_l, &net_l, + rules_l)) { + free(rules_l); + exit(1); + } + if (conf.opts & BGPD_OPT_VERBOSE) print_config(&conf, &ribnames, &net_l, peer_l, rules_l, &mrt_l); @@ -226,13 +224,10 @@ main(int argc, char *argv[]) session_socket_blockmode(pipe_s2r_c[0], BM_NONBLOCK); session_socket_blockmode(pipe_s2r_c[1], BM_NONBLOCK); - prepare_listeners(&conf); - /* fork children */ - rde_pid = rde_main(&conf, peer_l, &net_l, rules_l, &mrt_l, &ribnames, - pipe_m2r, pipe_s2r, pipe_m2s, pipe_s2r_c, debug); - io_pid = session_main(&conf, peer_l, &net_l, rules_l, &mrt_l, &ribnames, - pipe_m2s, pipe_s2r, pipe_m2r, pipe_s2r_c); + rde_pid = rde_main(pipe_m2r, pipe_s2r, pipe_m2s, pipe_s2r_c, debug); + io_pid = session_main(pipe_m2s, pipe_s2r, pipe_m2r, pipe_s2r_c, + conf.csock, conf.rcsock); setproctitle("parent"); @@ -260,27 +255,7 @@ main(int argc, char *argv[]) quit = 1; if (pftable_clear_all() != 0) quit = 1; - - while ((net = TAILQ_FIRST(&net_l)) != NULL) { - TAILQ_REMOVE(&net_l, net, entry); - filterset_free(&net->net.attrset); - free(net); - } - - while ((r = TAILQ_FIRST(rules_l)) != NULL) { - TAILQ_REMOVE(rules_l, r, entry); - free(r); - } - TAILQ_FOREACH(la, conf.listen_addrs, entry) { - close(la->fd); - la->fd = -1; - } - while ((rr = SIMPLEQ_FIRST(&ribnames))) { - SIMPLEQ_REMOVE_HEAD(&ribnames, entry); - free(rr); - } - - mrt_reconfigure(&mrt_l); + quit = reconfigure(conffile, &conf, &mrt_l, &peer_l, rules_l); while (quit == 0) { bzero(pfd, sizeof(pfd)); diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index d0d9558e92b..4526de2410d 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.278 2009/12/18 15:51:37 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.279 2009/12/31 15:34:02 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -146,22 +146,13 @@ u_int32_t attrhashsize = 512; u_int32_t nexthophashsize = 64; pid_t -rde_main(struct bgpd_config *config, struct peer *peer_l, - struct network_head *net_l, struct filter_head *rules, - struct mrt_head *mrt_l, struct rib_names *rib_n, int pipe_m2r[2], - int pipe_s2r[2], int pipe_m2s[2], int pipe_s2rctl[2], int debug) +rde_main(int pipe_m2r[2], int pipe_s2r[2], int pipe_m2s[2], int pipe_s2rctl[2], + int debug) { pid_t pid; struct passwd *pw; - struct peer *p; - struct listen_addr *la; struct pollfd *pfd = NULL; - struct filter_rule *f; - struct filter_set *set; - struct nexthop *nh; - struct rde_rib *rr; struct rde_mrt_ctx *mctx, *xmctx; - struct mrt *mrt; void *newp; u_int pfd_elms = 0, i, j; int timeout; @@ -175,8 +166,6 @@ rde_main(struct bgpd_config *config, struct peer *peer_l, return (pid); } - conf = config; - if ((pw = getpwnam(BGPD_USER)) == NULL) fatal("getpwnam"); @@ -197,6 +186,8 @@ rde_main(struct bgpd_config *config, struct peer *peer_l, signal(SIGINT, rde_sighdlr); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); + signal(SIGALRM, SIG_IGN); + signal(SIGUSR1, SIG_IGN); close(pipe_s2r[0]); close(pipe_s2rctl[0]); @@ -213,50 +204,21 @@ rde_main(struct bgpd_config *config, struct peer *peer_l, imsg_init(ibuf_se_ctl, pipe_s2rctl[1]); imsg_init(ibuf_main, pipe_m2r[1]); - /* peer list, mrt list and listener list are not used in the RDE */ - while ((p = peer_l) != NULL) { - peer_l = p->next; - free(p); - } - - while ((mrt = LIST_FIRST(mrt_l)) != NULL) { - LIST_REMOVE(mrt, entry); - free(mrt); - } - - while ((la = TAILQ_FIRST(config->listen_addrs)) != NULL) { - TAILQ_REMOVE(config->listen_addrs, la, entry); - close(la->fd); - free(la); - } - free(config->listen_addrs); - pt_init(); - while ((rr = SIMPLEQ_FIRST(&ribnames))) { - SIMPLEQ_REMOVE_HEAD(&ribnames, entry); - rib_new(-1, rr->name, rr->flags); - free(rr); - } path_init(pathhashsize); aspath_init(pathhashsize); attr_init(attrhashsize); nexthop_init(nexthophashsize); peer_init(peerhashsize); - rules_l = rules; - network_init(net_l); + rules_l = calloc(1, sizeof(struct filter_head)); + if (rules_l == NULL) + fatal(NULL); + TAILQ_INIT(rules_l); + if ((conf = malloc(sizeof(struct bgpd_config))) == NULL) + fatal(NULL); log_info("route decision engine ready"); - TAILQ_FOREACH(f, rules, entry) { - f->peer.ribid = rib_find(f->rib); - TAILQ_FOREACH(set, &f->set, entry) { - if (set->type == ACTION_SET_NEXTHOP) { - nh = nexthop_get(&set->action.nexthop); - nh->refcnt++; - } - } - } - while (rde_quit == 0) { if (pfd_elms < PFD_PIPE_COUNT + rde_mrt_cnt) { if ((newp = realloc(pfd, sizeof(struct pollfd) * @@ -660,6 +622,11 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) free(nconf); nconf = NULL; parent_set = NULL; + /* sync peerself with conf */ + peerself->remote_bgpid = ntohl(conf->bgpid); + peerself->conf.local_as = conf->as; + peerself->conf.remote_as = conf->as; + peerself->short_as = conf->short_as; prefix_network_clean(peerself, reloadtime, 0); /* check if filter changed */ @@ -2567,7 +2534,6 @@ 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) @@ -2583,17 +2549,13 @@ peer_init(u_int32_t hashsize) 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)); + snprintf(pc.descr, sizeof(pc.descr), "LOCAL"); 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 diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index 0575a229867..ece3b1eb1b7 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.302 2009/12/08 14:03:40 claudio Exp $ */ +/* $OpenBSD: session.c,v 1.303 2009/12/31 15:34:02 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -93,11 +93,11 @@ struct peer *getpeerbyip(struct sockaddr *); int session_match_mask(struct peer *, struct bgpd_addr *); struct peer *getpeerbyid(u_int32_t); -struct bgpd_config *conf, *nconf = NULL; +struct bgpd_config *conf, *nconf; struct bgpd_sysdep sysdep; -struct peer *npeers; -volatile sig_atomic_t session_quit = 0; -int pending_reconf = 0; +struct peer *peers, *npeers; +volatile sig_atomic_t session_quit; +int pending_reconf; int csock = -1, rcsock = -1; u_int peer_cnt; struct imsgbuf *ibuf_rde; @@ -174,10 +174,8 @@ setup_listeners(u_int *la_cnt) } pid_t -session_main(struct bgpd_config *config, struct peer *cpeers, - struct network_head *net_l, struct filter_head *rules, - struct mrt_head *m_l, struct rib_names *rib_l, int pipe_m2s[2], - int pipe_s2r[2], int pipe_m2r[2], int pipe_s2rctl[2]) +session_main(int pipe_m2s[2], int pipe_s2r[2], int pipe_m2r[2], + int pipe_s2rctl[2], char *cname, char *rcname) { int nfds, timeout; unsigned int i, j, idx_peers, idx_listeners, idx_mrts; @@ -188,19 +186,13 @@ session_main(struct bgpd_config *config, struct peer *cpeers, u_int32_t ctl_queued; struct passwd *pw; struct peer *p, **peer_l = NULL, *last, *next; - struct network *net; struct mrt *m, *xm, **mrt_l = NULL; - struct filter_rule *r; struct pollfd *pfd = NULL; struct ctl_conn *ctl_conn; struct listen_addr *la; - struct rde_rib *rr; void *newp; short events; - conf = config; - peers = cpeers; - switch (pid = fork()) { case -1: fatal("cannot fork"); @@ -211,10 +203,9 @@ session_main(struct bgpd_config *config, struct peer *cpeers, } /* control socket is outside chroot */ - if ((csock = control_init(0, conf->csock)) == -1) + if ((csock = control_init(0, cname)) == -1) fatalx("control socket setup failed"); - if (conf->rcsock != NULL && - (rcsock = control_init(1, conf->rcsock)) == -1) + if (rcname != NULL && (rcsock = control_init(1, rcname)) == -1) fatalx("control socket setup failed"); if ((pw = getpwnam(BGPD_USER)) == NULL) @@ -236,20 +227,18 @@ session_main(struct bgpd_config *config, struct peer *cpeers, setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("can't drop privileges"); - listener_cnt = 0; - setup_listeners(&listener_cnt); - signal(SIGTERM, session_sighdlr); signal(SIGINT, session_sighdlr); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); - log_info("session engine ready"); + signal(SIGALRM, SIG_IGN); + signal(SIGUSR1, SIG_IGN); + close(pipe_m2s[0]); close(pipe_s2r[1]); close(pipe_s2rctl[1]); close(pipe_m2r[0]); close(pipe_m2r[1]); - init_conf(conf); if ((ibuf_rde = malloc(sizeof(struct imsgbuf))) == NULL || (ibuf_rde_ctl = malloc(sizeof(struct imsgbuf))) == NULL || (ibuf_main = malloc(sizeof(struct imsgbuf))) == NULL) @@ -257,37 +246,23 @@ session_main(struct bgpd_config *config, struct peer *cpeers, imsg_init(ibuf_rde, pipe_s2r[0]); imsg_init(ibuf_rde_ctl, pipe_s2rctl[0]); imsg_init(ibuf_main, pipe_m2s[1]); + TAILQ_INIT(&ctl_conns); control_listen(csock); control_listen(rcsock); LIST_INIT(&mrthead); + listener_cnt = 0; peer_cnt = 0; ctl_cnt = 0; - /* filter rules are not used in the SE */ - while ((r = TAILQ_FIRST(rules)) != NULL) { - TAILQ_REMOVE(rules, r, entry); - free(r); - } - free(rules); - - /* network list is not used in the SE */ - while ((net = TAILQ_FIRST(net_l)) != NULL) { - TAILQ_REMOVE(net_l, net, entry); - filterset_free(&net->net.attrset); - free(net); - } + if ((conf = malloc(sizeof(struct bgpd_config))) == NULL) + fatal(NULL); + if ((conf->listen_addrs = calloc(1, sizeof(struct listen_addrs))) == + NULL) + fatal(NULL); + TAILQ_INIT(conf->listen_addrs); - /* main mrt list is not used in the SE */ - while ((m = LIST_FIRST(m_l)) != NULL) { - LIST_REMOVE(m, entry); - free(m); - } - /* rib names not used in the SE */ - while ((rr = SIMPLEQ_FIRST(&ribnames))) { - SIMPLEQ_REMOVE_HEAD(&ribnames, entry); - free(rr); - } + log_info("session engine ready"); while (session_quit == 0) { /* check for peers to be initialized or deleted */ @@ -308,7 +283,8 @@ session_main(struct bgpd_config *config, struct peer *cpeers, /* reinit due? */ if (p->conf.reconf_action == RECONF_REINIT) { session_stop(p, ERR_CEASE_ADMIN_RESET); - timer_set(p, Timer_IdleHold, 0); + if (!p->conf.down) + timer_set(p, Timer_IdleHold, 0); } /* deletion due? */ diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 5cbdbdce91b..2836e0ff23a 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.103 2009/12/08 14:03:40 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.104 2009/12/31 15:34:02 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -218,7 +218,7 @@ struct peer { u_int8_t passive; }; -struct peer *peers; +extern struct peer *peers; struct ctl_timer { enum Timer type; @@ -227,10 +227,7 @@ struct ctl_timer { /* session.c */ void session_socket_blockmode(int, enum blockmodes); -pid_t session_main(struct bgpd_config *, struct peer *, - struct network_head *, struct filter_head *, - struct mrt_head *, struct rib_names *, - int[2], int[2], int[2], int[2]); +pid_t session_main(int[2], int[2], int[2], int[2], char *, char *); void bgp_fsm(struct peer *, enum session_events); int session_neighbor_rrefresh(struct peer *p); struct peer *getpeerbyaddr(struct bgpd_addr *); @@ -257,9 +254,7 @@ int merge_config(struct bgpd_config *, struct bgpd_config *, void prepare_listeners(struct bgpd_config *); /* rde.c */ -pid_t rde_main(struct bgpd_config *, struct peer *, struct network_head *, - struct filter_head *, struct mrt_head *, struct rib_names *, - int[2], int[2], int[2], int[2], int); +pid_t rde_main(int[2], int[2], int[2], int[2], int); /* control.c */ int control_init(int, char *); |