Annotation of fwsync/driver/fwsync_mod.c, revision 1.8.2.2

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

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