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

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.7     ! misho      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; 
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: 
1.7     ! misho      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: 
1.6       misho      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);
1.2       misho      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);
1.6       misho      86:        mtx_destroy(&fws_mtx_u);
1.7     ! misho      87:        mtx_destroy(&fws_mtx_n);
1.2       misho      88: 
1.1       misho      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);
1.2       misho     117:        memset(&fws_ctx, 0, sizeof fws_ctx);
                    118: 
                    119:        TAILQ_INIT(&fwsync_sndpkt);
1.6       misho     120:        TAILQ_INIT(&fwsync_updpkt);
1.7     ! misho     121:        TAILQ_INIT(&fwsync_natpkt);
1.2       misho     122: 
                    123:        /* mutexes */
1.7     ! misho     124:        mtx_init(&fws_mtx_n, "fwsync mtx alias", NULL, MTX_DEF);
        !           125:        mtx_init(&fws_mtx_u, "fwsync mtx dynamic", NULL, MTX_DEF);
1.2       misho     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");
1.1       misho     138: 
1.6       misho     139:        TASK_INIT(&fws_sndpkt_task, 0, fwsync_sndpkt_handler, &fwsync_sndpkt);
                    140: 
1.5       misho     141:        /* callout */
                    142: 
                    143:        callout_init_mtx(&fws_co, &fws_mtx_e, 0);
                    144: 
1.1       misho     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);
1.4       misho     189: MODULE_DEPEND(ipfw_sync, libalias, 1, 1, 1);
1.1       misho     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>