Example #1
0
static int
npf_fini(void)
{
	/* At first, detach device and remove pfil hooks. */
#ifdef _MODULE
	devsw_detach(NULL, &npf_cdevsw);
#endif
	npf_pfil_unregister(true);

	/* Flush all sessions, destroy configuration (ruleset, etc). */
	npf_session_tracking(false);
	npf_config_fini();

	/* Finally, safe to destroy the subsystems. */
	npf_ext_sysfini();
	npf_alg_sysfini();
	npf_nat_sysfini();
	npf_session_sysfini();
	npf_tableset_sysfini();
	npf_bpf_sysfini();

	/* Note: worker is the last. */
	npf_worker_sysfini();

	if (npf_sysctl) {
		sysctl_teardown(&npf_sysctl);
	}
	percpu_free(npf_stats_percpu, NPF_STATS_SIZE);

	return 0;
}
Example #2
0
/*
 * npfctl_reload: store passed data i.e. update settings, create passed
 * tables, rules and atomically activate all them.
 */
int
npfctl_reload(u_long cmd, void *data)
{
	struct plistref *pref = data;
	prop_dictionary_t npf_dict, errdict;
	prop_array_t natlist, tables, rprocs, rules;
	npf_tableset_t *tblset = NULL;
	npf_ruleset_t *rlset = NULL;
	npf_ruleset_t *nset = NULL;
	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. */
	errdict = prop_dictionary_create();

	/* NAT policies. */
	nset = npf_ruleset_create();
	natlist = prop_dictionary_get(npf_dict, "translation");
	error = npf_mk_natlist(nset, natlist, errdict);
	if (error) {
		goto fail;
	}

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

	/* Rules and rule procedures. */
	rlset = npf_ruleset_create();
	rprocs = prop_dictionary_get(npf_dict, "rprocs");
	rules = prop_dictionary_get(npf_dict, "rules");
	error = npf_mk_rules(rlset, rules, rprocs, errdict);
	if (error) {
		goto fail;
	}

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

	/*
	 * Finally - reload ruleset, tableset and NAT policies.
	 * Operation will be performed as a single transaction.
	 */
	npf_reload(npf_dict, rlset, tblset, nset, flush);

	/* Turn on/off session tracking accordingly. */
	npf_session_tracking(!flush);

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

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