示例#1
0
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);
}
示例#2
0
int
merge_config(struct bgpd_config *xconf, struct bgpd_config *conf,
    struct peer *peer_l, struct listen_addrs *listen_addrs)
{
	struct listen_addr			*nla, *ola, *next;

	/*
	 * merge the freshly parsed conf into the running xconf
	 */

	/* preserve cmd line opts */
	conf->opts = xconf->opts;
	conf->csock = xconf->csock;
	conf->rcsock = xconf->rcsock;

	if (!conf->as) {
		log_warnx("configuration error: AS not given");
		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;

	conf->listen_addrs = xconf->listen_addrs;
	memcpy(xconf, conf, sizeof(struct bgpd_config));

	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;

	} 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 */
				ola->reconf = RECONF_KEEP;
		}

		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);
			}
		}

		while ((ola = TAILQ_FIRST(listen_addrs)) != NULL) {
			TAILQ_REMOVE(listen_addrs, ola, entry);
			free(ola);
		}
		free(listen_addrs);
	}

	return (0);
}