Annotation of fwsync/driver/fwsync_mod.c, revision 1.8
1.8 ! misho 1: /*-
! 2: * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
! 3: *
! 4: * Copyright (c) 2022 Michael Pounov <misho@elwix.org>, CloudSigma AG
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: * 1. Redistributions of source code must retain the above copyright
! 10: * notice, this list of conditions and the following disclaimer.
! 11: * 2. Redistributions in binary form must reproduce the above copyright
! 12: * notice, this list of conditions and the following disclaimer in the
! 13: * documentation and/or other materials provided with the distribution.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 16: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 17: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 18: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 19: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 20: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 21: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 23: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 24: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 25: * SUCH DAMAGE.
! 26: */
1.1 misho 27: #include "fwsync.h"
28:
29:
30: MALLOC_DEFINE(M_FWSYNC, "fwsync_memory", "FWSync - memory");
31:
32: static struct ipfw_sopt_handler soc[] = {
33: { IP_FW_SYNC_XCONFIG, 0, HDIR_SET, fwsync_cfg },
34: { IP_FW_SYNC_DESTROY, 0, HDIR_SET, fwsync_destroy },
35: { IP_FW_SYNC_XGETCONFIG, 0, HDIR_GET, fwsync_get_cfg },
36: { IP_FW_SYNC_LIST, 0, HDIR_GET, fwsync_list },
37: { IP_FW_SYNC_START, 0, HDIR_SET, fwsync_start },
38: { IP_FW_SYNC_STOP, 0, HDIR_SET, fwsync_stop },
39: };
40:
41: static volatile int fwsync_hooked = 0;
42: struct fwsync_context fws_ctx = { 0 };
43: int fwsync_debug = DRV_DEBUG;
44: static struct sysctl_ctx_list fwsync_sysctl_ctx;
45: struct cfg_sync fws_cfg;
46: //static struct sysctl_oid *fws_sysctl_oid, *fws_sysctl_dir;
47:
48: struct task fws_sndpkt_task;
1.2 misho 49: struct taskqueue *fws_tq;
1.5 misho 50: struct callout fws_co;
1.7 misho 51: struct mtx fws_mtx_c, fws_mtx_e, fws_mtx_u, fws_mtx_n;
52: fwsync_sndpkt_t fwsync_sndpkt, fwsync_updpkt, fwsync_natpkt;
1.1 misho 53:
54: SYSCTL_NODE(_net_inet_ip, IFT_FWSYNC, fwsync, CTLFLAG_RW, 0, "IPFW Sync - Sync firewall states");
55: SYSCTL_INT(_net_inet_ip_fwsync, OID_AUTO, debug, CTLFLAG_RW, &fwsync_debug, 0, "Debug driver");
56:
57: static int
58: fws_fini(void *arg)
59: {
1.2 misho 60: struct fws_sndpkt *p;
61:
1.1 misho 62: DTRACE();
63:
64: if (!fwsync_hooked)
65: return EBUSY;
66:
67: if (fws_cfg.cfg.on || fws_ctx.config) {
68: uprintf("Unable to unload ELWIX %s driver, cause you have active configuration.\n"
69: "Before unload driver flush configuration!\n", DRV_NAME);
70: return EBUSY;
71: }
72:
73: IPFW_DEL_SOPT_HANDLER(1, soc);
74:
1.6 misho 75: callout_drain(&fws_co);
76:
77: if (fws_tq) {
78: taskqueue_drain_all(fws_tq);
1.2 misho 79: taskqueue_free(fws_tq);
1.6 misho 80: }
81:
1.7 misho 82: mtx_lock(&fws_mtx_n);
83: while (!TAILQ_EMPTY(&fwsync_natpkt)) {
84: p = TAILQ_FIRST(&fwsync_natpkt);
85: TAILQ_REMOVE(&fwsync_natpkt, p, sp_next);
86: free(p, M_FWSYNC);
87: }
88: mtx_unlock(&fws_mtx_n);
89:
1.6 misho 90: mtx_lock(&fws_mtx_u);
91: while (!TAILQ_EMPTY(&fwsync_updpkt)) {
92: p = TAILQ_FIRST(&fwsync_updpkt);
93: TAILQ_REMOVE(&fwsync_updpkt, p, sp_next);
94: free(p, M_FWSYNC);
95: }
96: mtx_unlock(&fws_mtx_u);
1.2 misho 97:
98: mtx_lock(&fws_mtx_c);
99: while (!TAILQ_EMPTY(&fwsync_sndpkt)) {
100: p = TAILQ_FIRST(&fwsync_sndpkt);
101: TAILQ_REMOVE(&fwsync_sndpkt, p, sp_next);
102: free(p, M_FWSYNC);
103: }
104: mtx_unlock(&fws_mtx_c);
105:
106: mtx_destroy(&fws_mtx_c);
107: mtx_destroy(&fws_mtx_e);
1.6 misho 108: mtx_destroy(&fws_mtx_u);
1.7 misho 109: mtx_destroy(&fws_mtx_n);
1.2 misho 110:
1.1 misho 111: fwsync_hooked = 0;
112:
113: /* sysctl context */
114: sysctl_ctx_free(&fwsync_sysctl_ctx);
115:
116: uprintf("Unloaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
117: return 0;
118: }
119:
120: static int
121: fws_shut(void *arg)
122: {
123: DTRACE();
124:
125: fws_fini(arg);
126:
127: return 0;
128: }
129:
130: static int
131: fws_init(void *arg)
132: {
133: DTRACE();
134:
135: if (fwsync_hooked)
136: return 0;
137:
138: memset(&fws_cfg, 0, sizeof fws_cfg);
1.2 misho 139: memset(&fws_ctx, 0, sizeof fws_ctx);
140:
141: TAILQ_INIT(&fwsync_sndpkt);
1.6 misho 142: TAILQ_INIT(&fwsync_updpkt);
1.7 misho 143: TAILQ_INIT(&fwsync_natpkt);
1.2 misho 144:
145: /* mutexes */
1.7 misho 146: mtx_init(&fws_mtx_n, "fwsync mtx alias", NULL, MTX_DEF);
147: mtx_init(&fws_mtx_u, "fwsync mtx dynamic", NULL, MTX_DEF);
1.2 misho 148: mtx_init(&fws_mtx_e, "fwsync mtx edge", NULL, MTX_DEF);
149: mtx_init(&fws_mtx_c, "fwsync mtx collector", NULL, MTX_DEF);
150:
151: /* taskqueue */
152: fws_tq = taskqueue_create("fwsync_tq", M_NOWAIT, taskqueue_thread_enqueue, &fws_tq);
153: if (!fws_tq) {
154: printf("Failed to allocate fwsync task queue\n");
155: mtx_destroy(&fws_mtx_c);
156: mtx_destroy(&fws_mtx_e);
157: return ENOMEM;
158: } else
159: taskqueue_start_threads(&fws_tq, 1, PI_NET, "fwsync tq");
1.1 misho 160:
1.6 misho 161: TASK_INIT(&fws_sndpkt_task, 0, fwsync_sndpkt_handler, &fwsync_sndpkt);
162:
1.5 misho 163: /* callout */
164:
165: callout_init_mtx(&fws_co, &fws_mtx_e, 0);
166:
1.1 misho 167: /* sysctl context */
168: sysctl_ctx_init(&fwsync_sysctl_ctx);
169:
170: IPFW_ADD_SOPT_HANDLER(1, soc);
171:
172: fwsync_hooked = 1;
173: uprintf("Loaded ELWIX %s driver version %d ...\n", DRV_NAME, DRV_VERSION);
174: return 0;
175: }
176: static int
177: fwsync_main(module_t m, int what, void *arg)
178: {
179: int ret = 0;
180:
181: switch (what) {
182: case MOD_LOAD:
183: ret = fws_init(arg);
184: break;
185: case MOD_UNLOAD:
186: ret = fws_fini(arg);
187: break;
188: case MOD_SHUTDOWN:
189: ret = fws_shut(arg);
190: break;
191: case MOD_QUIESCE:
192: /* don't unload driver if there have configured driver */
193: if (fws_cfg.cfg.on || fws_ctx.config)
194: ret = EBUSY;
195: break;
196: default:
197: ret = EINVAL;
198: break;
199: }
200:
201: return ret;
202: }
203:
204: static moduledata_t fwsync_mod = {
205: "ipfw_sync",
206: fwsync_main,
207: NULL
208: };
209:
210: DECLARE_MODULE(ipfw_sync, fwsync_mod, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY);
1.4 misho 211: MODULE_DEPEND(ipfw_sync, libalias, 1, 1, 1);
1.1 misho 212: MODULE_DEPEND(ipfw_sync, ipfw, 3, 3, 3);
213: MODULE_VERSION(ipfw_sync, DRV_VERSION);
214:
215: SYSINIT(fws_init, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_init, NULL);
216: SYSUNINIT(fws_fini, SI_SUB_PROTO_FIREWALL, (SI_ORDER_ANY - 128), fws_fini, NULL);
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>