File:  [ELWIX - Embedded LightWeight unIX -] / fwsync / driver / fwsync_mod.c
Revision 1.7: download - view: text, annotated - select for diffs - revision graph
Sat Aug 13 18:16:39 2022 UTC (22 months, 1 week ago) by misho
Branches: MAIN
CVS tags: HEAD
init nat sync code

    1: /*************************************************************************
    2: * (C) 2022 CloudSigma AG - Sofia/Bulgaria
    3: *  by Michael Pounov <misho@elwix.org>
    4: **************************************************************************/
    5: #include "fwsync.h"
    6: 
    7: 
    8: MALLOC_DEFINE(M_FWSYNC, "fwsync_memory", "FWSync - memory");
    9: 
   10: static struct ipfw_sopt_handler	soc[] = {
   11: 	{ IP_FW_SYNC_XCONFIG,	0,	HDIR_SET,	fwsync_cfg },
   12: 	{ IP_FW_SYNC_DESTROY,	0,	HDIR_SET,	fwsync_destroy },
   13: 	{ IP_FW_SYNC_XGETCONFIG,	0,	HDIR_GET,	fwsync_get_cfg },
   14: 	{ IP_FW_SYNC_LIST,	0,	HDIR_GET,	fwsync_list },
   15: 	{ IP_FW_SYNC_START,	0,	HDIR_SET,	fwsync_start },
   16: 	{ IP_FW_SYNC_STOP,	0,	HDIR_SET,	fwsync_stop },
   17: };
   18: 
   19: static volatile int fwsync_hooked = 0;
   20: struct fwsync_context fws_ctx = { 0 };
   21: int fwsync_debug = DRV_DEBUG;
   22: static struct sysctl_ctx_list fwsync_sysctl_ctx;
   23: struct cfg_sync fws_cfg;
   24: //static struct sysctl_oid *fws_sysctl_oid, *fws_sysctl_dir;
   25: 
   26: struct task fws_sndpkt_task;
   27: struct taskqueue *fws_tq;
   28: struct callout fws_co;
   29: struct mtx fws_mtx_c, fws_mtx_e, fws_mtx_u, fws_mtx_n;
   30: fwsync_sndpkt_t fwsync_sndpkt, fwsync_updpkt, fwsync_natpkt; 
   31: 
   32: SYSCTL_NODE(_net_inet_ip, IFT_FWSYNC, fwsync, CTLFLAG_RW, 0, "IPFW Sync - Sync firewall states");
   33: SYSCTL_INT(_net_inet_ip_fwsync, OID_AUTO, debug, CTLFLAG_RW, &fwsync_debug, 0, "Debug driver");
   34: 
   35: static int
   36: fws_fini(void *arg)
   37: {
   38: 	struct fws_sndpkt *p;
   39: 
   40: 	DTRACE();
   41: 
   42: 	if (!fwsync_hooked)
   43: 		return EBUSY;
   44: 
   45: 	if (fws_cfg.cfg.on || fws_ctx.config) {
   46: 		uprintf("Unable to unload ELWIX %s driver, cause you have active configuration.\n"
   47: 				"Before unload driver flush configuration!\n", DRV_NAME);
   48: 		return EBUSY;
   49: 	}
   50: 
   51: 	IPFW_DEL_SOPT_HANDLER(1, soc);
   52: 
   53: 	callout_drain(&fws_co);
   54: 
   55: 	if (fws_tq) {
   56: 		taskqueue_drain_all(fws_tq);
   57: 		taskqueue_free(fws_tq);
   58: 	}
   59: 
   60: 	mtx_lock(&fws_mtx_n);
   61: 	while (!TAILQ_EMPTY(&fwsync_natpkt)) {
   62: 		p = TAILQ_FIRST(&fwsync_natpkt);
   63: 		TAILQ_REMOVE(&fwsync_natpkt, p, sp_next);
   64: 		free(p, M_FWSYNC);
   65: 	}
   66: 	mtx_unlock(&fws_mtx_n);
   67: 
   68: 	mtx_lock(&fws_mtx_u);
   69: 	while (!TAILQ_EMPTY(&fwsync_updpkt)) {
   70: 		p = TAILQ_FIRST(&fwsync_updpkt);
   71: 		TAILQ_REMOVE(&fwsync_updpkt, p, sp_next);
   72: 		free(p, M_FWSYNC);
   73: 	}
   74: 	mtx_unlock(&fws_mtx_u);
   75: 
   76: 	mtx_lock(&fws_mtx_c);
   77: 	while (!TAILQ_EMPTY(&fwsync_sndpkt)) {
   78: 		p = TAILQ_FIRST(&fwsync_sndpkt);
   79: 		TAILQ_REMOVE(&fwsync_sndpkt, p, sp_next);
   80: 		free(p, M_FWSYNC);
   81: 	}
   82: 	mtx_unlock(&fws_mtx_c);
   83: 
   84: 	mtx_destroy(&fws_mtx_c);
   85: 	mtx_destroy(&fws_mtx_e);
   86: 	mtx_destroy(&fws_mtx_u);
   87: 	mtx_destroy(&fws_mtx_n);
   88: 
   89: 	fwsync_hooked = 0;
   90: 
   91: 	/* sysctl context */
   92: 	sysctl_ctx_free(&fwsync_sysctl_ctx);
   93: 
   94: 	uprintf("Unloaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
   95: 	return 0;
   96: }
   97: 
   98: static int
   99: fws_shut(void *arg)
  100: {
  101: 	DTRACE();
  102: 
  103: 	fws_fini(arg);
  104: 
  105: 	return 0;
  106: }
  107: 
  108: static int
  109: fws_init(void *arg)
  110: {
  111: 	DTRACE();
  112: 
  113: 	if (fwsync_hooked)
  114: 		return 0;
  115: 
  116: 	memset(&fws_cfg, 0, sizeof fws_cfg);
  117: 	memset(&fws_ctx, 0, sizeof fws_ctx);
  118: 
  119: 	TAILQ_INIT(&fwsync_sndpkt);
  120: 	TAILQ_INIT(&fwsync_updpkt);
  121: 	TAILQ_INIT(&fwsync_natpkt);
  122: 
  123: 	/* mutexes */
  124: 	mtx_init(&fws_mtx_n, "fwsync mtx alias", NULL, MTX_DEF);
  125: 	mtx_init(&fws_mtx_u, "fwsync mtx dynamic", NULL, MTX_DEF);
  126: 	mtx_init(&fws_mtx_e, "fwsync mtx edge", NULL, MTX_DEF);
  127: 	mtx_init(&fws_mtx_c, "fwsync mtx collector", NULL, MTX_DEF);
  128: 
  129: 	/* taskqueue */
  130: 	fws_tq = taskqueue_create("fwsync_tq", M_NOWAIT, taskqueue_thread_enqueue, &fws_tq);
  131: 	if (!fws_tq) {
  132: 		printf("Failed to allocate fwsync task queue\n");
  133: 		mtx_destroy(&fws_mtx_c);
  134: 		mtx_destroy(&fws_mtx_e);
  135: 		return ENOMEM;
  136: 	} else
  137: 		taskqueue_start_threads(&fws_tq, 1, PI_NET, "fwsync tq");
  138: 
  139: 	TASK_INIT(&fws_sndpkt_task, 0, fwsync_sndpkt_handler, &fwsync_sndpkt);
  140: 
  141: 	/* callout */
  142: 
  143: 	callout_init_mtx(&fws_co, &fws_mtx_e, 0);
  144: 
  145: 	/* sysctl context */
  146: 	sysctl_ctx_init(&fwsync_sysctl_ctx);
  147: 
  148: 	IPFW_ADD_SOPT_HANDLER(1, soc);
  149: 
  150: 	fwsync_hooked = 1;
  151: 	uprintf("Loaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
  152: 	return 0;
  153: }
  154: static int
  155: fwsync_main(module_t m, int what, void *arg)
  156: {
  157: 	int ret = 0;
  158: 
  159: 	switch (what) {
  160: 		case MOD_LOAD:
  161: 			ret = fws_init(arg);
  162: 			break;
  163: 		case MOD_UNLOAD:
  164: 			ret = fws_fini(arg);
  165: 			break;
  166: 		case MOD_SHUTDOWN:
  167: 			ret = fws_shut(arg);
  168: 			break;
  169: 		case MOD_QUIESCE:
  170: 			/* don't unload driver if there have configured driver */
  171: 			if (fws_cfg.cfg.on || fws_ctx.config)
  172: 				ret = EBUSY;
  173: 			break;
  174: 		default:
  175: 			ret = EINVAL;
  176: 			break;
  177: 	}
  178: 
  179: 	return ret;
  180: }
  181: 
  182: static moduledata_t fwsync_mod = {
  183: 	"ipfw_sync",
  184: 	fwsync_main,
  185: 	NULL
  186: };
  187: 
  188: DECLARE_MODULE(ipfw_sync, fwsync_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
  189: MODULE_DEPEND(ipfw_sync, libalias, 1, 1, 1);
  190: MODULE_DEPEND(ipfw_sync, ipfw, 3, 3, 3);
  191: MODULE_VERSION(ipfw_sync, DRV_VERSION);
  192: 
  193: SYSINIT(fws_init, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_init, NULL);
  194: SYSUNINIT(fws_fini, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_fini, NULL);

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