diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2015-07-16 18:26:05 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2015-07-16 18:26:05 +0000 |
commit | c6cb371fbc1b2375ef6fd924c2e5c143016e804c (patch) | |
tree | b426df863013770baf6c669983459e6e1faa8d95 /usr.sbin | |
parent | 1464285131929dd9a6b13696f3fb32f734ca414b (diff) |
Next round of config cleanup. Move various lists into the bgpd_config struct.
This is the next step to better split parsing and merging the config.
OK benno@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 76 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 22 | ||||
-rw-r--r-- | usr.sbin/bgpd/config.c | 225 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 114 | ||||
-rw-r--r-- | usr.sbin/bgpd/printconf.c | 19 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_filter.c | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/session.h | 8 |
7 files changed, 247 insertions, 222 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index 9021f96a9a5..ec8b09c58f5 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.176 2015/03/14 02:43:02 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.177 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -41,8 +41,7 @@ __dead void usage(void); int main(int, char *[]); int check_child(pid_t, const char *); int send_filterset(struct imsgbuf *, struct filter_set_head *); -int reconfigure(char *, struct bgpd_config *, struct mrt_head *, - struct peer **); +int reconfigure(char *, struct bgpd_config *, struct peer **); int dispatch_imsg(struct imsgbuf *, int, struct bgpd_config *); int control_setup(struct bgpd_config *); @@ -102,11 +101,8 @@ int cmd_opts; int main(int argc, char *argv[]) { - struct bgpd_config conf; - struct mrt_head mrt_l; + struct bgpd_config *conf; struct peer *peer_l, *p; - struct mrt *m; - struct listen_addr *la; struct pollfd pfd[POLL_MAX]; pid_t io_pid = 0, rde_pid = 0, pid; char *conffile; @@ -123,8 +119,7 @@ main(int argc, char *argv[]) log_init(1); /* log to stderr until daemonized */ log_verbose(1); - bzero(&conf, sizeof(conf)); - LIST_INIT(&mrt_l); + conf = new_config(); peer_l = NULL; while ((ch = getopt(argc, argv, "cdD:f:nv")) != -1) { @@ -164,17 +159,12 @@ main(int argc, char *argv[]) usage(); if (cmd_opts & BGPD_OPT_NOACTION) { - struct network_head net_l; - struct rdomain_head rdom_l; - struct filter_head rules_l; - - if (parse_config(conffile, &conf, &mrt_l, &peer_l, &net_l, - &rules_l, &rdom_l)) + if (parse_config(conffile, conf, &peer_l)) exit(1); if (cmd_opts & BGPD_OPT_VERBOSE) - print_config(&conf, &ribnames, &net_l, peer_l, &rules_l, - &mrt_l, &rdom_l); + print_config(conf, &ribnames, &conf->networks, peer_l, + conf->filters, conf->mrt, &conf->rdomains); else fprintf(stderr, "configuration OK\n"); exit(0); @@ -234,7 +224,7 @@ main(int argc, char *argv[]) mrt_init(ibuf_rde, ibuf_se); if ((rfd = kr_init()) == -1) quit = 1; - quit = reconfigure(conffile, &conf, &mrt_l, &peer_l); + quit = reconfigure(conffile, conf, &peer_l); if (pftable_clear_all() != 0) quit = 1; @@ -251,7 +241,7 @@ main(int argc, char *argv[]) pfd[PFD_SOCK_ROUTE].fd = rfd; pfd[PFD_SOCK_ROUTE].events = POLLIN; - timeout = mrt_timeout(&mrt_l); + timeout = mrt_timeout(conf->mrt); if (timeout > MAX_TIMEOUT) timeout = MAX_TIMEOUT; @@ -275,13 +265,13 @@ main(int argc, char *argv[]) } if (nfds > 0 && pfd[PFD_PIPE_SESSION].revents & POLLIN) { - if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, &conf) == + if (dispatch_imsg(ibuf_se, PFD_PIPE_SESSION, conf) == -1) quit = 1; } if (nfds > 0 && pfd[PFD_PIPE_ROUTE].revents & POLLIN) { - if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE, &conf) == + if (dispatch_imsg(ibuf_rde, PFD_PIPE_ROUTE, conf) == -1) quit = 1; } @@ -295,7 +285,7 @@ main(int argc, char *argv[]) u_int error; reconfig = 0; - switch (reconfigure(conffile, &conf, &mrt_l, &peer_l)) { + switch (reconfigure(conffile, conf, &peer_l)) { case -1: /* fatal error */ quit = 1; break; @@ -330,7 +320,7 @@ main(int argc, char *argv[]) if (mrtdump) { mrtdump = 0; - mrt_handler(&mrt_l); + mrt_handler(conf->mrt); } } @@ -346,23 +336,14 @@ main(int argc, char *argv[]) peer_l = p->next; free(p); } - while ((m = LIST_FIRST(&mrt_l)) != NULL) { - LIST_REMOVE(m, entry); - free(m); - } - if (conf.listen_addrs) - while ((la = TAILQ_FIRST(conf.listen_addrs)) != NULL) { - TAILQ_REMOVE(conf.listen_addrs, la, entry); - close(la->fd); - free(la); - } - control_cleanup(conf.csock); - control_cleanup(conf.rcsock); + control_cleanup(conf->csock); + control_cleanup(conf->rcsock); carp_demote_shutdown(); - kr_shutdown(conf.fib_priority); + kr_shutdown(conf->fib_priority); pftable_clear_all(); - free(conf.listen_addrs); + + free_config(conf); do { if ((pid = wait(NULL)) == -1 && @@ -414,12 +395,8 @@ send_filterset(struct imsgbuf *i, struct filter_set_head *set) } int -reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, - struct peer **peer_l) +reconfigure(char *conffile, struct bgpd_config *conf, struct peer **peer_l) { - struct network_head net_l; - struct rdomain_head rdom_l; - struct filter_head rules_l; struct peer *p; struct filter_rule *r; struct listen_addr *la; @@ -433,8 +410,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, reconfpending = 2; /* one per child */ log_info("rereading config"); - if (parse_config(conffile, conf, mrt_l, peer_l, &net_l, &rules_l, - &rdom_l)) { + if (parse_config(conffile, conf, peer_l)) { log_warnx("config file %s has errors, not reloading", conffile); reconfpending = 0; @@ -488,12 +464,12 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, } /* networks go via kroute to the RDE */ - if (kr_net_reload(0, &net_l)) + if (kr_net_reload(0, &conf->networks)) return (-1); /* filters for the RDE */ - while ((r = TAILQ_FIRST(&rules_l)) != NULL) { - TAILQ_REMOVE(&rules_l, r, entry); + while ((r = TAILQ_FIRST(conf->filters)) != NULL) { + TAILQ_REMOVE(conf->filters, r, entry); if (imsg_compose(ibuf_rde, IMSG_RECONF_FILTER, 0, 0, -1, r, sizeof(struct filter_rule)) == -1) return (-1); @@ -503,8 +479,8 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, free(r); } - while ((rd = SIMPLEQ_FIRST(&rdom_l)) != NULL) { - SIMPLEQ_REMOVE_HEAD(&rdom_l, entry); + while ((rd = SIMPLEQ_FIRST(&conf->rdomains)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&conf->rdomains, entry); if (ktable_update(rd->rtableid, rd->descr, rd->ifmpe, rd->flags, conf->fib_priority) == -1) { log_warnx("failed to load rdomain %d", @@ -547,7 +523,7 @@ reconfigure(char *conffile, struct bgpd_config *conf, struct mrt_head *mrt_l, return (-1); /* mrt changes can be sent out of bound */ - mrt_reconfigure(mrt_l); + mrt_reconfigure(conf->mrt); return (0); } diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index e21cfa84ccf..da550f1a0eb 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.285 2015/04/25 15:28:18 phessler Exp $ */ +/* $OpenBSD: bgpd.h,v 1.286 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -195,8 +195,21 @@ struct listen_addr { TAILQ_HEAD(listen_addrs, listen_addr); TAILQ_HEAD(filter_set_head, filter_set); +struct rdomain; +SIMPLEQ_HEAD(rdomain_head, rdomain); + +struct network; +TAILQ_HEAD(network_head, network); + +struct filter_rule; +TAILQ_HEAD(filter_head, filter_rule); + struct bgpd_config { + struct rdomain_head rdomains; + struct network_head networks; + struct filter_head *filters; struct listen_addrs *listen_addrs; + struct mrt_head *mrt; char *csock; char *rcsock; int flags; @@ -331,8 +344,6 @@ struct network_config { u_int8_t old; /* used for reloading */ }; -TAILQ_HEAD(network_head, network); - struct network { struct network_config net; TAILQ_ENTRY(network) entry; @@ -773,8 +784,6 @@ struct filter_match { struct filter_extcommunity ext_community; }; -TAILQ_HEAD(filter_head, filter_rule); - struct filter_rule { TAILQ_ENTRY(filter_rule) entry; char rib[PEER_DESCR_LEN]; @@ -840,7 +849,6 @@ struct rdomain { u_int label; int flags; }; -SIMPLEQ_HEAD(rdomain_head, rdomain); struct rde_rib { SIMPLEQ_ENTRY(rde_rib) entry; @@ -931,6 +939,8 @@ void control_cleanup(const char *); int control_imsg_relay(struct imsg *); /* config.c */ +struct bgpd_config *new_config(void); +void free_config(struct bgpd_config *); void filterlist_free(struct filter_head *); int host(const char *, struct bgpd_addr *, u_int8_t *); diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c index 25d55f371a5..a842f541f99 100644 --- a/usr.sbin/bgpd/config.c +++ b/usr.sbin/bgpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.60 2015/03/14 02:43:02 claudio Exp $ */ +/* $OpenBSD: config.c,v 1.61 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org> @@ -38,11 +38,93 @@ u_int32_t get_bgpid(void); int host_v4(const char *, struct bgpd_addr *, u_int8_t *); int host_v6(const char *, struct bgpd_addr *); +struct bgpd_config * +new_config(void) +{ + struct bgpd_config *conf; + + if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL) + fatal(NULL); + + conf->min_holdtime = MIN_HOLDTIME; + conf->bgpid = get_bgpid(); + conf->fib_priority = RTP_BGP; + + if ((conf->csock = strdup(SOCKET_NAME)) == NULL) + fatal(NULL); + + if ((conf->filters = calloc(1, sizeof(struct filter_head))) == NULL) + fatal(NULL); + if ((conf->listen_addrs = calloc(1, sizeof(struct listen_addrs))) == + NULL) + fatal(NULL); + if ((conf->mrt = calloc(1, sizeof(struct mrt_head))) == NULL) + fatal(NULL); + + /* init the various list for later */ + TAILQ_INIT(&conf->networks); + SIMPLEQ_INIT(&conf->rdomains); + + TAILQ_INIT(conf->filters); + TAILQ_INIT(conf->listen_addrs); + LIST_INIT(conf->mrt); + + return (conf); +} + +void +free_config(struct bgpd_config *conf) +{ + struct rdomain *rd; + struct network *n; + struct listen_addr *la; + struct mrt *m; + + while ((rd = SIMPLEQ_FIRST(&conf->rdomains)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&conf->rdomains, entry); + filterset_free(&rd->export); + filterset_free(&rd->import); + + while ((n = TAILQ_FIRST(&rd->net_l)) != NULL) { + TAILQ_REMOVE(&rd->net_l, n, entry); + filterset_free(&n->net.attrset); + free(n); + } + free(rd); + } + + while ((n = TAILQ_FIRST(&conf->networks)) != NULL) { + TAILQ_REMOVE(&conf->networks, n, entry); + filterset_free(&n->net.attrset); + free(n); + } + + filterlist_free(conf->filters); + + while ((la = TAILQ_FIRST(conf->listen_addrs)) != NULL) { + TAILQ_REMOVE(conf->listen_addrs, la, entry); + free(la); + } + free(conf->listen_addrs); + + while ((m = LIST_FIRST(conf->mrt)) != NULL) { + LIST_REMOVE(m, entry); + free(m); + } + free(conf->mrt); + + free(conf->csock); + free(conf->rcsock); + + free(conf); +} + int merge_config(struct bgpd_config *xconf, struct bgpd_config *conf, - struct peer *peer_l, struct listen_addrs *listen_addrs) + struct peer *peer_l) { struct listen_addr *nla, *ola, *next; + struct network *n; /* * merge the freshly parsed conf into the running xconf @@ -53,92 +135,101 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf, return (1); } - if (!conf->min_holdtime) - conf->min_holdtime = MIN_HOLDTIME; - - if (!conf->bgpid) - conf->bgpid = get_bgpid(); if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0) conf->clusterid = conf->bgpid; - if (!conf->fib_priority) - conf->fib_priority = RTP_BGP; - - free(xconf->csock); - free(xconf->rcsock); - conf->listen_addrs = xconf->listen_addrs; /* adjust FIB priority if changed */ /* if xconf is uninitalized we get RTP_NONE */ - if (xconf->fib_priority != RTP_NONE && xconf->fib_priority != - conf->fib_priority) { + if (xconf->fib_priority != conf->fib_priority) { kr_fib_decouple_all(xconf->fib_priority); kr_fib_update_prio_all(conf->fib_priority); kr_fib_couple_all(conf->fib_priority); } - memcpy(xconf, conf, sizeof(struct bgpd_config)); + /* take over the easy config changes */ + xconf->flags = conf->flags; + xconf->log = conf->log; + xconf->bgpid = conf->bgpid; + xconf->clusterid = conf->clusterid; + xconf->as = conf->as; + xconf->short_as = conf->short_as; + xconf->holdtime = conf->holdtime; + xconf->min_holdtime = conf->min_holdtime; + xconf->connectretry = conf->connectretry; + xconf->fib_priority = conf->fib_priority; + + /* clear old control sockets and use new */ + free(xconf->csock); + free(xconf->rcsock); + xconf->csock = conf->csock; + xconf->rcsock = conf->rcsock; + /* set old one to NULL so we don't double free */ + conf->csock = NULL; + conf->rcsock = NULL; + + /* clear all current filters and take over the new ones */ + filterlist_free(xconf->filters); + xconf->filters = conf->filters; + conf->filters = NULL; + + /* switch the network statements, but first remove the old ones */ + while ((n = TAILQ_FIRST(&xconf->networks)) != NULL) { + TAILQ_REMOVE(&xconf->networks, n, entry); + filterset_free(&n->net.attrset); + free(n); + } + while ((n = TAILQ_FIRST(&conf->networks)) != NULL) { + TAILQ_REMOVE(&conf->networks, n, entry); + TAILQ_INSERT_TAIL(&xconf->networks, n, entry); + } - if (conf->listen_addrs == NULL) { - /* there is no old conf, just copy new one over */ - xconf->listen_addrs = listen_addrs; - TAILQ_FOREACH(nla, xconf->listen_addrs, entry) - nla->reconf = RECONF_REINIT; + /* + * merge new listeners: + * -flag all existing ones as to be deleted + * -those that are in both new and old: flag to keep + * -new ones get inserted and flagged as to reinit + * -remove all that are still flagged for deletion + */ - } else { - /* - * merge new listeners: - * -flag all existing ones as to be deleted - * -those that are in both new and old: flag to keep - * -new ones get inserted and flagged as to reinit - * -remove all that are still flagged for deletion - */ - - TAILQ_FOREACH(nla, xconf->listen_addrs, entry) - nla->reconf = RECONF_DELETE; - - /* no new listeners? preserve default ones */ - if (TAILQ_EMPTY(listen_addrs)) - TAILQ_FOREACH(ola, xconf->listen_addrs, entry) - if (ola->flags & DEFAULT_LISTENER) - ola->reconf = RECONF_KEEP; - - for (nla = TAILQ_FIRST(listen_addrs); nla != NULL; nla = next) { - next = TAILQ_NEXT(nla, entry); - - TAILQ_FOREACH(ola, xconf->listen_addrs, entry) - if (!memcmp(&nla->sa, &ola->sa, - sizeof(nla->sa))) - break; - - if (ola == NULL) { - /* new listener, copy over */ - TAILQ_REMOVE(listen_addrs, nla, entry); - TAILQ_INSERT_TAIL(xconf->listen_addrs, - nla, entry); - nla->reconf = RECONF_REINIT; - } else /* exists, just flag */ + TAILQ_FOREACH(nla, xconf->listen_addrs, entry) + nla->reconf = RECONF_DELETE; + + /* no new listeners? preserve default ones */ + if (TAILQ_EMPTY(conf->listen_addrs)) + TAILQ_FOREACH(ola, xconf->listen_addrs, entry) + if (ola->flags & DEFAULT_LISTENER) ola->reconf = RECONF_KEEP; - } + /* else loop over listeners and merge configs */ + for (nla = TAILQ_FIRST(conf->listen_addrs); nla != NULL; nla = next) { + next = TAILQ_NEXT(nla, entry); - for (nla = TAILQ_FIRST(xconf->listen_addrs); nla != NULL; - nla = next) { - next = TAILQ_NEXT(nla, entry); - if (nla->reconf == RECONF_DELETE) { - TAILQ_REMOVE(xconf->listen_addrs, nla, entry); - free(nla); - } - } + TAILQ_FOREACH(ola, xconf->listen_addrs, entry) + if (!memcmp(&nla->sa, &ola->sa, sizeof(nla->sa))) + break; - while ((ola = TAILQ_FIRST(listen_addrs)) != NULL) { - TAILQ_REMOVE(listen_addrs, ola, entry); - free(ola); + if (ola == NULL) { + /* new listener, copy over */ + TAILQ_REMOVE(conf->listen_addrs, nla, entry); + TAILQ_INSERT_TAIL(xconf->listen_addrs, nla, entry); + nla->reconf = RECONF_REINIT; + } else /* exists, just flag */ + ola->reconf = RECONF_KEEP; + } + /* finally clean up the original list and remove all stale entires */ + for (nla = TAILQ_FIRST(xconf->listen_addrs); nla != NULL; nla = next) { + next = TAILQ_NEXT(nla, entry); + if (nla->reconf == RECONF_DELETE) { + TAILQ_REMOVE(xconf->listen_addrs, nla, entry); + free(nla); } - free(listen_addrs); } + /* conf is merged so free it */ + free_config(conf); + return (0); } diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index a34d87b9fbd..15543eb29bd 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.280 2015/04/26 20:12:03 benno Exp $ */ +/* $OpenBSD: parse.y,v 1.281 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -77,19 +77,16 @@ int symset(const char *, const char *, int); char *symget(const char *); static struct bgpd_config *conf; -static struct mrt_head *mrtconf; -static struct network_head *netconf, *gnetconf; +static struct network_head *netconf; static struct peer *peer_l, *peer_l_old; static struct peer *curpeer; static struct peer *curgroup; static struct rdomain *currdom; -static struct rdomain_head *rdom_l; static struct filter_head *filter_l; static struct filter_head *peerfilter_l; static struct filter_head *groupfilter_l; static struct filter_rule *curpeer_filter[2]; static struct filter_rule *curgroup_filter[2]; -static struct listen_addrs *listen_addrs; static u_int32_t id; struct filter_peers_l { @@ -375,7 +372,7 @@ conf_main : AS as4number { la->fd = -1; memcpy(&la->sa, addr2sa(&$3, BGP_PORT), sizeof(la->sa)); - TAILQ_INSERT_TAIL(listen_addrs, la, entry); + TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry); } | FIBPRIORITY NUMBER { if ($2 <= RTP_NONE || $2 > RTP_MAX) { @@ -761,9 +758,9 @@ rdomain : RDOMAIN NUMBER optnl '{' optnl { } rdomainopts_l '}' { /* insert into list */ - SIMPLEQ_INSERT_TAIL(rdom_l, currdom, entry); + SIMPLEQ_INSERT_TAIL(&conf->rdomains, currdom, entry); currdom = NULL; - netconf = gnetconf; + netconf = &conf->networks; } rdomainopts_l : rdomainopts_l rdomainoptsl @@ -2580,41 +2577,21 @@ popfile(void) } int -parse_config(char *filename, struct bgpd_config *xconf, - struct mrt_head *xmconf, struct peer **xpeers, struct network_head *nc, - struct filter_head *xfilter_l, struct rdomain_head *xrdom_l) +parse_config(char *filename, struct bgpd_config *xconf, struct peer **xpeers) { struct sym *sym, *next; struct peer *p, *pnext; - struct listen_addr *la; - struct network *n; struct rde_rib *rr; - struct rdomain *rd; int errors = 0; - if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL) - fatal(NULL); - - conf->csock = strdup(SOCKET_NAME); + conf = new_config(); - if ((file = pushfile(filename, 1)) == NULL) { - free(conf); - return (-1); - } - topfile = file; - - if ((mrtconf = calloc(1, sizeof(struct mrt_head))) == NULL) - fatal(NULL); - if ((listen_addrs = calloc(1, sizeof(struct listen_addrs))) == NULL) - fatal(NULL); if ((filter_l = calloc(1, sizeof(struct filter_head))) == NULL) fatal(NULL); if ((peerfilter_l = calloc(1, sizeof(struct filter_head))) == NULL) fatal(NULL); if ((groupfilter_l = calloc(1, sizeof(struct filter_head))) == NULL) fatal(NULL); - LIST_INIT(mrtconf); - TAILQ_INIT(listen_addrs); TAILQ_INIT(filter_l); TAILQ_INIT(peerfilter_l); TAILQ_INIT(groupfilter_l); @@ -2625,17 +2602,17 @@ parse_config(char *filename, struct bgpd_config *xconf, curgroup = NULL; id = 1; - /* network list is always empty in the parent */ - gnetconf = netconf = nc; - TAILQ_INIT(netconf); - /* init the empty filter list for later */ - TAILQ_INIT(xfilter_l); - SIMPLEQ_INIT(xrdom_l); - rdom_l = xrdom_l; + netconf = &conf->networks; add_rib("Adj-RIB-In", 0, F_RIB_NOFIB | F_RIB_NOEVALUATE); add_rib("Loc-RIB", 0, 0); + if ((file = pushfile(filename, 1)) == NULL) { + free(conf); + return (-1); + } + topfile = file; + yyparse(); errors = file->errors; popfile(); @@ -2655,51 +2632,33 @@ parse_config(char *filename, struct bgpd_config *xconf, } if (errors) { - /* XXX more leaks in this case */ - free(conf->csock); - free(conf->rcsock); - - while ((la = TAILQ_FIRST(listen_addrs)) != NULL) { - TAILQ_REMOVE(listen_addrs, la, entry); - free(la); - } - free(listen_addrs); - for (p = peer_l; p != NULL; p = pnext) { pnext = p->next; free(p); } - while ((n = TAILQ_FIRST(netconf)) != NULL) { - TAILQ_REMOVE(netconf, n, entry); - filterset_free(&n->net.attrset); - free(n); - } - - filterlist_free(filter_l); - filterlist_free(peerfilter_l); - filterlist_free(groupfilter_l); - while ((rr = SIMPLEQ_FIRST(&ribnames)) != NULL) { SIMPLEQ_REMOVE_HEAD(&ribnames, entry); free(rr); } - while ((rd = SIMPLEQ_FIRST(rdom_l)) != NULL) { - SIMPLEQ_REMOVE_HEAD(rdom_l, entry); - filterset_free(&rd->export); - filterset_free(&rd->import); - while ((n = TAILQ_FIRST(&rd->net_l)) != NULL) { - TAILQ_REMOVE(&rd->net_l, n, entry); - filterset_free(&n->net.attrset); - free(n); - } + filterlist_free(filter_l); + filterlist_free(peerfilter_l); + filterlist_free(groupfilter_l); - free(rd); - } + free_config(conf); } else { - errors += merge_config(xconf, conf, peer_l, listen_addrs); - errors += mrt_mergeconfig(xmconf, mrtconf); + /* + * Move filter list and static group and peer filtersets + * together. Static group sets come first then peer sets + * last normal filter rules. + */ + merge_filter_lists(conf->filters, groupfilter_l); + merge_filter_lists(conf->filters, peerfilter_l); + merge_filter_lists(conf->filters, filter_l); + + errors += mrt_mergeconfig(xconf->mrt, conf->mrt); + errors += merge_config(xconf, conf, peer_l); *xpeers = peer_l; for (p = peer_l_old; p != NULL; p = pnext) { @@ -2707,22 +2666,11 @@ parse_config(char *filename, struct bgpd_config *xconf, free(p); } - /* - * Move filter list and static group and peer filtersets - * together. Static group sets come first then peer sets - * last normal filter rules. - */ - merge_filter_lists(xfilter_l, groupfilter_l); - merge_filter_lists(xfilter_l, peerfilter_l); - merge_filter_lists(xfilter_l, filter_l); free(filter_l); free(peerfilter_l); free(groupfilter_l); } - free(conf); - free(mrtconf); - return (errors ? -1 : 0); } @@ -3081,7 +3029,7 @@ add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p, { struct mrt *m, *n; - LIST_FOREACH(m, mrtconf, entry) { + LIST_FOREACH(m, conf->mrt, entry) { if ((rib && strcmp(rib, m->rib)) || (!rib && *m->rib)) continue; @@ -3135,7 +3083,7 @@ add_mrtconfig(enum mrt_type type, char *name, int timeout, struct peer *p, } } - LIST_INSERT_HEAD(mrtconf, n, entry); + LIST_INSERT_HEAD(conf->mrt, n, entry); return (0); } diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index b7feb3bfed6..61bab4365dd 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.94 2015/04/25 15:28:18 phessler Exp $ */ +/* $OpenBSD: printconf.c,v 1.95 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -43,7 +43,8 @@ const char *print_enc_alg(u_int8_t); void print_announce(struct peer_config *, const char *); void print_rule(struct peer *, struct filter_rule *); const char * mrt_type(enum mrt_type); -void print_mrt(u_int32_t, u_int32_t, const char *, const char *); +void print_mrt(struct bgpd_config *, u_int32_t, u_int32_t, + const char *, const char *); void print_groups(struct bgpd_config *, struct peer *); int peer_compare(const void *, const void *); @@ -461,7 +462,7 @@ print_peer(struct peer_config *p, struct bgpd_config *conf, const char *c) printf("%s\tsoftreconfig out no\n", c); - print_mrt(p->id, p->groupid, c, "\t"); + print_mrt(conf, p->id, p->groupid, c, "\t"); printf("%s}\n", c); } @@ -628,17 +629,16 @@ mrt_type(enum mrt_type t) return "unfluffy MRT"; } -struct mrt_head *xmrt_l = NULL; - void -print_mrt(u_int32_t pid, u_int32_t gid, const char *prep, const char *prep2) +print_mrt(struct bgpd_config *conf, u_int32_t pid, u_int32_t gid, + const char *prep, const char *prep2) { struct mrt *m; - if (xmrt_l == NULL) + if (conf->mrt == NULL) return; - LIST_FOREACH(m, xmrt_l, entry) + LIST_FOREACH(m, conf->mrt, entry) if ((gid != 0 && m->group_id == gid) || (m->peer_id == pid && m->group_id == gid)) { printf("%s%sdump ", prep, prep2); @@ -722,7 +722,6 @@ print_config(struct bgpd_config *conf, struct rib_names *rib_l, struct rde_rib *rr; struct rdomain *rd; - xmrt_l = mrt_l; print_mainconf(conf); printf("\n"); TAILQ_FOREACH(n, net_l, entry) @@ -742,7 +741,7 @@ print_config(struct bgpd_config *conf, struct rib_names *rib_l, "no" : "yes"); } printf("\n"); - print_mrt(0, 0, "", ""); + print_mrt(conf, 0, 0, "", ""); printf("\n"); print_groups(conf, peer_l); printf("\n"); diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index b82651a0438..74d202e22ad 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.73 2015/04/25 15:28:18 phessler Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.74 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -471,6 +471,9 @@ filterset_free(struct filter_set_head *sh) struct filter_set *s; struct nexthop *nh; + if (sh == NULL) + return; + while ((s = TAILQ_FIRST(sh)) != NULL) { TAILQ_REMOVE(sh, s, entry); if (s->type == ACTION_RTLABEL_ID) diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 01e6c4734c2..a36bb37cef1 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.117 2015/02/09 11:37:31 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.118 2015/07/16 18:26:04 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -240,7 +240,7 @@ int carp_demote_set(char *, int); /* config.c */ int merge_config(struct bgpd_config *, struct bgpd_config *, - struct peer *, struct listen_addrs *); + struct peer *); void prepare_listeners(struct bgpd_config *); int get_mpe_label(struct rdomain *); @@ -267,9 +267,7 @@ void mrt_dump_state(struct mrt *, u_int16_t, u_int16_t, void mrt_done(void *); /* parse.y */ -int parse_config(char *, struct bgpd_config *, struct mrt_head *, - struct peer **, struct network_head *, struct filter_head *, - struct rdomain_head *); +int parse_config(char *, struct bgpd_config *, struct peer **); /* pfkey.c */ int pfkey_read(int, struct sadb_msg *); |