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