Пример #1
0
/**
 * Break the netmaks string and convert them into network_pair elements in
 * the local_networks array. IP's are in network order.
 */
void
parse_netmasks(const char *str)
{
	char **masks = g_strsplit(str, ";", 0);
	char *p;
	guint32 mask_div;
	int i;

	free_networks();

    if (!masks)
        return;

	for (i = 0; masks[i]; i++)
		/* just count */ ;

	number_local_networks = i;

	if (i == 0) {
        g_strfreev(masks);
		return;
    }

	local_networks = g_malloc(i * sizeof *local_networks);

	for (i = 0; masks[i]; i++) {
		/* Network is of the form ip/mask or ip/bits */
		if ((p = strchr(masks[i], '/')) && *p) {
			*p++ = '\0';

			if (strchr(p, '.')) {
				/* get the network address from the user */
				if (!string_to_ip_strict(p, &local_networks[i].mask, NULL))
					g_warning("parse_netmasks(): Invalid netmask: \"%s\"", p);
			}
			else {
				int error;

				mask_div = parse_uint32(p, NULL, 10, &error);
				mask_div = MIN(32, mask_div);
				if (error)
					g_warning("parse_netmasks(): "
						"Invalid CIDR prefixlen: \"%s\"", p);
				else
					local_networks[i].mask = (guint32) -1 << (32 - mask_div);
			}
		}
		else {
			/* Assume single-host */
			local_networks[i].mask = -1; /* 255.255.255.255 */
		}
		/* get the network address from the user */
		if (!string_to_ip_strict(masks[i], &local_networks[i].net, NULL))
			g_warning("parse_netmasks(): Invalid netmask: \"%s\"", masks[i]);
	}

	g_strfreev(masks);
}
Пример #2
0
void
free_rdomains(struct rdomain_head *rdomains)
{
	struct rdomain		*rd;

	while ((rd = SIMPLEQ_FIRST(rdomains)) != NULL) {
		SIMPLEQ_REMOVE_HEAD(rdomains, entry);
		filterset_free(&rd->export);
		filterset_free(&rd->import);
		free_networks(&rd->net_l);
		free(rd);
	}
}
Пример #3
0
int
merge_config(struct bgpd_config *xconf, struct bgpd_config *conf,
    struct peer *peer_l)
{
	struct listen_addr	*nla, *ola, *next;
	struct network		*n;
	struct rdomain		*rd;

	/*
	 * merge the freshly parsed conf into the running xconf
	 */
	if (!conf->as) {
		log_warnx("configuration error: AS not given");
		return (1);
	}

	if ((conf->flags & BGPD_FLAG_REFLECTOR) && conf->clusterid == 0)
		conf->clusterid = conf->bgpid;


	/* adjust FIB priority if changed */
	/* if xconf is uninitialized we get RTP_NONE */
	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);
	}

	/* 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 */
	free_networks(&xconf->networks);
	while ((n = TAILQ_FIRST(&conf->networks)) != NULL) {
		TAILQ_REMOVE(&conf->networks, n, entry);
		TAILQ_INSERT_TAIL(&xconf->networks, n, entry);
	}

	/* switch the rdomain configs, first remove the old ones */
	free_rdomains(&xconf->rdomains);
	while ((rd = SIMPLEQ_FIRST(&conf->rdomains)) != NULL) {
		SIMPLEQ_REMOVE_HEAD(&conf->rdomains, entry);
		SIMPLEQ_INSERT_TAIL(&xconf->rdomains, rd, entry);
	}

	/*
	 * 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(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);

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

	/* conf is merged so free it */
	free_config(conf);

	return (0);
}