File:  [ELWIX - Embedded LightWeight unIX -] / fwsync / driver / fwsync_mod.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 22 13:01:55 2022 UTC (22 months, 3 weeks ago) by misho
Branches: misho
CVS tags: start, fwsync1_0
FWSync driver

/*************************************************************************
* (C) 2022 CloudSigma AG - Sofia/Bulgaria
*  by Michael Pounov <misho@elwix.org>
**************************************************************************/
#include "fwsync.h"


MALLOC_DEFINE(M_FWSYNC, "fwsync_memory", "FWSync - memory");

static struct ipfw_sopt_handler	soc[] = {
	{ IP_FW_SYNC_XCONFIG,	0,	HDIR_SET,	fwsync_cfg },
	{ IP_FW_SYNC_DESTROY,	0,	HDIR_SET,	fwsync_destroy },
	{ IP_FW_SYNC_XGETCONFIG,	0,	HDIR_GET,	fwsync_get_cfg },
	{ IP_FW_SYNC_LIST,	0,	HDIR_GET,	fwsync_list },
	{ IP_FW_SYNC_START,	0,	HDIR_SET,	fwsync_start },
	{ IP_FW_SYNC_STOP,	0,	HDIR_SET,	fwsync_stop },
};

static volatile int fwsync_hooked = 0;
struct fwsync_context fws_ctx = { 0 };
int fwsync_debug = DRV_DEBUG;
static struct sysctl_ctx_list fwsync_sysctl_ctx;
struct cfg_sync fws_cfg;
//static struct sysctl_oid *fws_sysctl_oid, *fws_sysctl_dir;

struct task fws_sndpkt_task;

SYSCTL_NODE(_net_inet_ip, IFT_FWSYNC, fwsync, CTLFLAG_RW, 0, "IPFW Sync - Sync firewall states");
SYSCTL_INT(_net_inet_ip_fwsync, OID_AUTO, debug, CTLFLAG_RW, &fwsync_debug, 0, "Debug driver");

static int
fws_fini(void *arg)
{
	DTRACE();

	if (!fwsync_hooked)
		return EBUSY;

	if (fws_cfg.cfg.on || fws_ctx.config) {
		uprintf("Unable to unload ELWIX %s driver, cause you have active configuration.\n"
				"Before unload driver flush configuration!\n", DRV_NAME);
		return EBUSY;
	}

	IPFW_DEL_SOPT_HANDLER(1, soc);

	fwsync_hooked = 0;

	/* sysctl context */
	sysctl_ctx_free(&fwsync_sysctl_ctx);

	uprintf("Unloaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
	return 0;
}

static int
fws_shut(void *arg)
{
	DTRACE();

	fws_fini(arg);

	return 0;
}

static int
fws_init(void *arg)
{
	DTRACE();

	if (fwsync_hooked)
		return 0;

	memset(&fws_cfg, 0, sizeof fws_cfg);

	/* sysctl context */
	sysctl_ctx_init(&fwsync_sysctl_ctx);

	IPFW_ADD_SOPT_HANDLER(1, soc);

	memset(&fws_ctx, 0, sizeof fws_ctx);

	fwsync_hooked = 1;
	uprintf("Loaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
	return 0;
}
static int
fwsync_main(module_t m, int what, void *arg)
{
	int ret = 0;

	switch (what) {
		case MOD_LOAD:
			ret = fws_init(arg);
			break;
		case MOD_UNLOAD:
			ret = fws_fini(arg);
			break;
		case MOD_SHUTDOWN:
			ret = fws_shut(arg);
			break;
		case MOD_QUIESCE:
			/* don't unload driver if there have configured driver */
			if (fws_cfg.cfg.on || fws_ctx.config)
				ret = EBUSY;
			break;
		default:
			ret = EINVAL;
			break;
	}

	return ret;
}

static moduledata_t fwsync_mod = {
	"ipfw_sync",
	fwsync_main,
	NULL
};

DECLARE_MODULE(ipfw_sync, fwsync_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
MODULE_DEPEND(ipfw_sync, ipfw, 3, 3, 3);
MODULE_VERSION(ipfw_sync, DRV_VERSION);

SYSINIT(fws_init, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_init, NULL);
SYSUNINIT(fws_fini, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_fini, NULL);

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>