Annotation of fwsync/driver/fwsync_mod.c, revision 1.6
1.1 misho 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;
1.2 misho 27: struct taskqueue *fws_tq;
1.5 misho 28: struct callout fws_co;
1.6 ! misho 29: struct mtx fws_mtx_c, fws_mtx_e, fws_mtx_u;
! 30: fwsync_sndpkt_t fwsync_sndpkt, fwsync_updpkt;
1.1 misho 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: {
1.2 misho 38: struct fws_sndpkt *p;
39:
1.1 misho 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:
1.6 ! misho 53: callout_drain(&fws_co);
! 54:
! 55: if (fws_tq) {
! 56: taskqueue_drain_all(fws_tq);
1.2 misho 57: taskqueue_free(fws_tq);
1.6 ! misho 58: }
! 59:
! 60: mtx_lock(&fws_mtx_u);
! 61: while (!TAILQ_EMPTY(&fwsync_updpkt)) {
! 62: p = TAILQ_FIRST(&fwsync_updpkt);
! 63: TAILQ_REMOVE(&fwsync_updpkt, p, sp_next);
! 64: free(p, M_FWSYNC);
! 65: }
! 66: mtx_unlock(&fws_mtx_u);
1.2 misho 67:
68: mtx_lock(&fws_mtx_c);
69: while (!TAILQ_EMPTY(&fwsync_sndpkt)) {
70: p = TAILQ_FIRST(&fwsync_sndpkt);
71: TAILQ_REMOVE(&fwsync_sndpkt, p, sp_next);
72: free(p, M_FWSYNC);
73: }
74: mtx_unlock(&fws_mtx_c);
75:
76: mtx_destroy(&fws_mtx_c);
77: mtx_destroy(&fws_mtx_e);
1.6 ! misho 78: mtx_destroy(&fws_mtx_u);
1.2 misho 79:
1.1 misho 80: fwsync_hooked = 0;
81:
82: /* sysctl context */
83: sysctl_ctx_free(&fwsync_sysctl_ctx);
84:
85: uprintf("Unloaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
86: return 0;
87: }
88:
89: static int
90: fws_shut(void *arg)
91: {
92: DTRACE();
93:
94: fws_fini(arg);
95:
96: return 0;
97: }
98:
99: static int
100: fws_init(void *arg)
101: {
102: DTRACE();
103:
104: if (fwsync_hooked)
105: return 0;
106:
107: memset(&fws_cfg, 0, sizeof fws_cfg);
1.2 misho 108: memset(&fws_ctx, 0, sizeof fws_ctx);
109:
110: TAILQ_INIT(&fwsync_sndpkt);
1.6 ! misho 111: TAILQ_INIT(&fwsync_updpkt);
1.2 misho 112:
113: /* mutexes */
1.6 ! misho 114: mtx_init(&fws_mtx_u, "fwsync mtx update", NULL, MTX_DEF);
1.2 misho 115: mtx_init(&fws_mtx_e, "fwsync mtx edge", NULL, MTX_DEF);
116: mtx_init(&fws_mtx_c, "fwsync mtx collector", NULL, MTX_DEF);
117:
118: /* taskqueue */
119: fws_tq = taskqueue_create("fwsync_tq", M_NOWAIT, taskqueue_thread_enqueue, &fws_tq);
120: if (!fws_tq) {
121: printf("Failed to allocate fwsync task queue\n");
122: mtx_destroy(&fws_mtx_c);
123: mtx_destroy(&fws_mtx_e);
124: return ENOMEM;
125: } else
126: taskqueue_start_threads(&fws_tq, 1, PI_NET, "fwsync tq");
1.1 misho 127:
1.6 ! misho 128: TASK_INIT(&fws_sndpkt_task, 0, fwsync_sndpkt_handler, &fwsync_sndpkt);
! 129:
1.5 misho 130: /* callout */
131:
132: callout_init_mtx(&fws_co, &fws_mtx_e, 0);
133:
1.1 misho 134: /* sysctl context */
135: sysctl_ctx_init(&fwsync_sysctl_ctx);
136:
137: IPFW_ADD_SOPT_HANDLER(1, soc);
138:
139: fwsync_hooked = 1;
140: uprintf("Loaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
141: return 0;
142: }
143: static int
144: fwsync_main(module_t m, int what, void *arg)
145: {
146: int ret = 0;
147:
148: switch (what) {
149: case MOD_LOAD:
150: ret = fws_init(arg);
151: break;
152: case MOD_UNLOAD:
153: ret = fws_fini(arg);
154: break;
155: case MOD_SHUTDOWN:
156: ret = fws_shut(arg);
157: break;
158: case MOD_QUIESCE:
159: /* don't unload driver if there have configured driver */
160: if (fws_cfg.cfg.on || fws_ctx.config)
161: ret = EBUSY;
162: break;
163: default:
164: ret = EINVAL;
165: break;
166: }
167:
168: return ret;
169: }
170:
171: static moduledata_t fwsync_mod = {
172: "ipfw_sync",
173: fwsync_main,
174: NULL
175: };
176:
177: DECLARE_MODULE(ipfw_sync, fwsync_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
1.4 misho 178: MODULE_DEPEND(ipfw_sync, libalias, 1, 1, 1);
1.1 misho 179: MODULE_DEPEND(ipfw_sync, ipfw, 3, 3, 3);
180: MODULE_VERSION(ipfw_sync, DRV_VERSION);
181:
182: SYSINIT(fws_init, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_init, NULL);
183: SYSUNINIT(fws_fini, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_fini, NULL);
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>