summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-12-31 15:34:03 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-12-31 15:34:03 +0000
commite4a9fa1df41cf5958271c8e82af5c52664f5b056 (patch)
tree5463401bf6d774198a906b62bafd806e96ac8721 /usr.sbin
parent6de774ec35c4faedf0d1243732019cb612cefd8f (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.c55
-rw-r--r--usr.sbin/bgpd/rde.c72
-rw-r--r--usr.sbin/bgpd/session.c70
-rw-r--r--usr.sbin/bgpd/session.h13
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 *);