Ejemplo n.º 1
0
void
npf_config_init(void)
{
	npf_ruleset_t *rlset, *nset;
	npf_rprocset_t *rpset;
	npf_tableset_t *tset;

	mutex_init(&npf_config_lock, MUTEX_DEFAULT, IPL_SOFTNET);
	npf_config_psz = pserialize_create();

	/* Load the empty configuration. */
	tset = npf_tableset_create(0);
	rpset = npf_rprocset_create();
	rlset = npf_ruleset_create(0);
	nset = npf_ruleset_create(0);
	npf_config_load(rlset, tset, nset, rpset, NULL, true);
	KASSERT(npf_config != NULL);
}
Ejemplo n.º 2
0
/*
 * npfctl_load: store passed data i.e. update settings, create passed
 * tables, rules and atomically activate all them.
 */
int
npfctl_load(u_long cmd, void *data)
{
	struct plistref *pref = data;
	prop_dictionary_t npf_dict, errdict;
	prop_array_t alglist, natlist, tables, rprocs, rules, conlist;
	npf_tableset_t *tblset = NULL;
	npf_rprocset_t *rpset = NULL;
	npf_ruleset_t *rlset = NULL;
	npf_ruleset_t *nset = NULL;
	npf_conndb_t *conndb = NULL;
	uint32_t ver = 0;
	size_t nitems;
	bool flush;
	int error;

	/* Retrieve the dictionary. */
#ifndef _NPF_TESTING
	error = prop_dictionary_copyin_ioctl(pref, cmd, &npf_dict);
	if (error)
		return error;
#else
	npf_dict = (prop_dictionary_t)pref;
#endif

	/* Dictionary for error reporting and version check. */
	errdict = prop_dictionary_create();
	prop_dictionary_get_uint32(npf_dict, "version", &ver);
	if (ver != NPF_VERSION) {
		error = EPROGMISMATCH;
		goto fail;
	}

	/* ALGs. */
	alglist = prop_dictionary_get(npf_dict, "algs");
	error = npf_mk_algs(alglist, errdict);
	if (error) {
		goto fail;
	}

	/* NAT policies. */
	natlist = prop_dictionary_get(npf_dict, "nat");
	if ((nitems = prop_array_count(natlist)) > NPF_MAX_RULES) {
		error = E2BIG;
		goto fail;
	}

	nset = npf_ruleset_create(nitems);
	error = npf_mk_natlist(nset, natlist, errdict);
	if (error) {
		goto fail;
	}

	/* Tables. */
	tables = prop_dictionary_get(npf_dict, "tables");
	if ((nitems = prop_array_count(tables)) > NPF_MAX_TABLES) {
		error = E2BIG;
		goto fail;
	}
	tblset = npf_tableset_create(nitems);
	error = npf_mk_tables(tblset, tables, errdict);
	if (error) {
		goto fail;
	}

	/* Rule procedures. */
	rprocs = prop_dictionary_get(npf_dict, "rprocs");
	if ((nitems = prop_array_count(rprocs)) > NPF_MAX_RPROCS) {
		error = E2BIG;
		goto fail;
	}
	rpset = npf_rprocset_create();
	error = npf_mk_rprocs(rpset, rprocs, errdict);
	if (error) {
		goto fail;
	}

	/* Rules. */
	rules = prop_dictionary_get(npf_dict, "rules");
	if ((nitems = prop_array_count(rules)) > NPF_MAX_RULES) {
		error = E2BIG;
		goto fail;
	}

	rlset = npf_ruleset_create(nitems);
	error = npf_mk_rules(rlset, rules, rpset, errdict);
	if (error) {
		goto fail;
	}

	/* Connections (if loading any). */
	if ((conlist = prop_dictionary_get(npf_dict, "conn-list")) != NULL) {
		error = npf_mk_connlist(conlist, nset, &conndb, errdict);
		if (error) {
			goto fail;
		}
	}

	flush = false;
	prop_dictionary_get_bool(npf_dict, "flush", &flush);

	/*
	 * Finally - perform the load.
	 */
	npf_config_load(rlset, tblset, nset, rpset, conndb, flush);

	/* Done.  Since data is consumed now, we shall not destroy it. */
	tblset = NULL;
	rpset = NULL;
	rlset = NULL;
	nset = NULL;
fail:
	/*
	 * Note: destroy rulesets first, to drop references to the tableset.
	 */
	KASSERT(error == 0 || (nset || rpset || rlset || tblset));
	if (nset) {
		npf_ruleset_destroy(nset);
	}
	if (rlset) {
		npf_ruleset_destroy(rlset);
	}
	if (rpset) {
		npf_rprocset_destroy(rpset);
	}
	if (tblset) {
		npf_tableset_destroy(tblset);
	}
	prop_object_release(npf_dict);

	/* Error report. */
#ifndef _NPF_TESTING
	prop_dictionary_set_int32(errdict, "errno", error);
	prop_dictionary_copyout_ioctl(pref, cmd, errdict);
	prop_object_release(errdict);
	error = 0;
#endif
	return error;
}