Annotation of fwsync/driver/fwsync.c, revision 1.1

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: static intptr_t fwsync_wchan;
        !             9: 
        !            10: 
        !            11: static void
        !            12: fwsync_edge_proc(void *arg)
        !            13: {
        !            14:        int e, rcvflg;
        !            15:        struct uio uio;
        !            16:        struct mbuf *m = NULL;
        !            17: 
        !            18:        DTRACE();
        !            19: 
        !            20:        memset(&uio, 0, sizeof uio);
        !            21:        uio.uio_resid = 1000000000;
        !            22:        uio.uio_td = curthread;
        !            23: 
        !            24:        fws_ctx.config |= CTX_EDGE_ONLINE;
        !            25:        while ((fws_cfg.cfg.on & CFG_SYNC_EDGE) && (fws_ctx.config & CTX_EDGE_READY)) {
        !            26:                if (m)
        !            27:                        m_freem(m);
        !            28:                m = NULL;
        !            29:                rcvflg = MSG_DONTWAIT;
        !            30:                e = soreceive(fws_ctx.sockz[CFG_SYNC_ADDR_EDGE], NULL, &uio, &m, NULL, &rcvflg);
        !            31:                if (e) {
        !            32:                        if (e != EAGAIN)
        !            33:                                printf("error in edge handler #%d\n", e);
        !            34:                        tsleep(&fwsync_wchan, 0, "edge_handler", hz);
        !            35:                        continue;
        !            36:                }
        !            37: 
        !            38:                printf("%u...-> %s\n", m->m_len, m->m_data);
        !            39:        }
        !            40:        fws_ctx.config &= ~CTX_EDGE_ONLINE;
        !            41: 
        !            42:        kproc_exit(0);
        !            43: }
        !            44: 
        !            45: int
        !            46: fwsync_cfg(struct ip_fw_chain *ch, ip_fw3_opheader *op3, struct sockopt_data *sd)
        !            47: {
        !            48:        ipfw_obj_header *oh;
        !            49:        struct ipfw_sync_cfg *ucfg;
        !            50:        size_t sz;
        !            51:        int e;
        !            52: 
        !            53:        DTRACE();
        !            54: 
        !            55:        sz = sizeof(*oh) + sizeof(*ucfg);
        !            56:        /* Check minimum header size */
        !            57:        if (sd->valsize < sz)
        !            58:                return (EINVAL);
        !            59: 
        !            60:        oh = (ipfw_obj_header*) sd->kbuf;
        !            61: 
        !            62:        /* Basic length checks for TLVs */
        !            63:        if (oh->ntlv.head.length != sizeof(oh->ntlv))
        !            64:                return (EINVAL);
        !            65: 
        !            66:        ucfg = (struct ipfw_sync_cfg*) (oh + 1);
        !            67: 
        !            68:        /* Check if name is properly terminated */
        !            69:        if (strnlen(ucfg->name, sizeof(ucfg->name)) == sizeof(ucfg->name))
        !            70:                return (EINVAL);
        !            71: 
        !            72:        if (ucfg->mode == CFG_SYNC_EDGE && !fws_cfg.cfg.edge && !(fws_ctx.config & CTX_CFG_EDGE) && 
        !            73:                        !strcmp(ucfg->name, "edge") && ucfg->addrs == 1) {
        !            74:                fws_cfg.cfg.edge = 1;
        !            75:                memcpy(&fws_cfg.cfg_addr[CFG_SYNC_ADDR_EDGE], &ucfg->addr[CFG_SYNC_ADDR_EDGE], 
        !            76:                                sizeof fws_cfg.cfg_addr[CFG_SYNC_ADDR_EDGE]);
        !            77:                fws_ctx.config |= CTX_CFG_EDGE;
        !            78: 
        !            79:                e = socreate((fws_cfg.cfg_addr[CFG_SYNC_ADDR_EDGE].addr.sa_family == AF_INET) ? AF_INET : AF_INET6, 
        !            80:                                &fws_ctx.sockz[CFG_SYNC_ADDR_EDGE], SOCK_DGRAM, IPPROTO_UDP, curthread->td_ucred, curthread);
        !            81:                if (e) {
        !            82:                        printf("fwsync edge socreate failed #%d\n", e);
        !            83:                        return e;
        !            84:                }
        !            85: 
        !            86:                e = sobind(fws_ctx.sockz[CFG_SYNC_ADDR_EDGE], &fws_cfg.cfg_addr[CFG_SYNC_ADDR_EDGE].addr, curthread);
        !            87:                if (e) {
        !            88:                        if (e != EADDRINUSE)
        !            89:                                printf("fwsync edge sobind failed #%d\n", e);
        !            90:                        else
        !            91:                                printf("fwsync edge address in use!\n");
        !            92:                        return e;
        !            93:                } else
        !            94:                        fws_ctx.config |= CTX_EDGE_READY;
        !            95:        } else if (ucfg->mode == CFG_SYNC_COLLECTOR && !(fws_ctx.config & CTX_CFG_COLLECTOR_1) && 
        !            96:                        !strcmp(ucfg->name, "collector") && ucfg->addrs > 0 && ucfg->addrs < 3) {
        !            97:                fws_cfg.cfg.collector = 1;
        !            98:                fws_cfg.cfg.addrs = ucfg->addrs;
        !            99:                memcpy(&fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_1], &ucfg->addr[CFG_SYNC_ADDR_COLLECTOR_1], 
        !           100:                                sizeof fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_1]);
        !           101: 
        !           102:                fws_ctx.config |= CTX_CFG_COLLECTOR_1;
        !           103: 
        !           104:                e = socreate((fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_1].addr.sa_family == AF_INET) ? AF_INET : AF_INET6, 
        !           105:                                &fws_ctx.sockz[CFG_SYNC_ADDR_COLLECTOR_1], SOCK_DGRAM, IPPROTO_UDP, curthread->td_ucred, curthread);
        !           106:                if (e) {
        !           107:                        printf("fwsync collector %d socreate failed #%d\n", e, CFG_SYNC_ADDR_COLLECTOR_1);
        !           108:                        return e;
        !           109:                } else
        !           110:                        fws_ctx.config |= CTX_COLLECTOR_1_READY;
        !           111: 
        !           112:                if (fws_cfg.cfg.addrs > 1) {
        !           113:                        memcpy(&fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_2], &ucfg->addr[CFG_SYNC_ADDR_COLLECTOR_2], 
        !           114:                                        sizeof fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_2]);
        !           115: 
        !           116:                        fws_ctx.config |= CTX_CFG_COLLECTOR_2;
        !           117: 
        !           118:                        e = socreate((fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_2].addr.sa_family == AF_INET) ? AF_INET : AF_INET6, 
        !           119:                                        &fws_ctx.sockz[CFG_SYNC_ADDR_COLLECTOR_2], SOCK_DGRAM, IPPROTO_UDP, curthread->td_ucred, curthread);
        !           120:                        if (e) {
        !           121:                                printf("fwsync collector %d socreate failed #%d\n", e, CFG_SYNC_ADDR_COLLECTOR_2);
        !           122:                                return e;
        !           123:                        } else
        !           124:                                fws_ctx.config |= CTX_COLLECTOR_2_READY;
        !           125:                }
        !           126:        } else
        !           127:                return (EINVAL);
        !           128: 
        !           129:        return 0;
        !           130: }
        !           131: 
        !           132: int
        !           133: fwsync_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3, struct sockopt_data *sd)
        !           134: {
        !           135:        int *n;
        !           136:        ipfw_obj_header *oh;
        !           137:        size_t sz;
        !           138: 
        !           139:        DTRACE();
        !           140: 
        !           141:        sz = sizeof(*oh) + sizeof(int);
        !           142:        /* Check minimum header size */
        !           143:        if (sd->valsize < sz)
        !           144:                return (EINVAL);
        !           145: 
        !           146:        oh = (ipfw_obj_header*) sd->kbuf;
        !           147: 
        !           148:        /* Basic length checks for TLVs */
        !           149:        if (oh->ntlv.head.length != sizeof(oh->ntlv))
        !           150:                return (EINVAL);
        !           151: 
        !           152:        n = (int*) (oh + 1);
        !           153:        if (*n & CFG_SYNC_EDGE) {
        !           154:                fws_cfg.cfg.on &= ~CFG_SYNC_EDGE;
        !           155:                fws_cfg.cfg.edge = 0;
        !           156:                fws_cfg.cfg.addrs = 0;
        !           157:                memset(fws_cfg.cfg_addr, 0, sizeof fws_cfg.cfg_addr[0]);
        !           158: 
        !           159:                if (fws_ctx.config & CTX_EDGE_READY) {
        !           160:                        soshutdown(fws_ctx.sockz[CFG_SYNC_ADDR_EDGE], SHUT_RD);
        !           161:                        tsleep(&fwsync_wchan, 0, "fwsedge_kill", 2 * hz);
        !           162:                        soclose(fws_ctx.sockz[CFG_SYNC_ADDR_EDGE]);
        !           163:                }
        !           164:        }
        !           165:        if (*n & CFG_SYNC_COLLECTOR) {
        !           166:                if (fws_ctx.config & (CTX_COLLECTOR_1_ONLINE | CTX_COLLECTOR_2_ONLINE)) {
        !           167:                        ipfw_unregister_state_hook();
        !           168:                        ipfw_unregister_alias_hook();
        !           169:                }
        !           170: 
        !           171:                fws_cfg.cfg.on &= ~CFG_SYNC_COLLECTOR;
        !           172:                fws_cfg.cfg.collector = 0;
        !           173:                fws_cfg.cfg.addrs = 0;
        !           174:                memset(fws_cfg.cfg_addr + 1, 0, sizeof fws_cfg.cfg_addr[0] * 2);
        !           175: 
        !           176:                if (fws_ctx.config & CTX_COLLECTOR_2_READY)
        !           177:                        soclose(fws_ctx.sockz[CFG_SYNC_ADDR_COLLECTOR_2]);
        !           178:                if (fws_ctx.config & CTX_COLLECTOR_1_READY)
        !           179:                        soclose(fws_ctx.sockz[CFG_SYNC_ADDR_COLLECTOR_1]);
        !           180:        }
        !           181: 
        !           182:        fws_ctx.config ^= fws_ctx.config;
        !           183: 
        !           184:        return 0;
        !           185: }
        !           186: 
        !           187: int
        !           188: fwsync_get_cfg(struct ip_fw_chain *ch, ip_fw3_opheader *op3, struct sockopt_data *sd)
        !           189: {
        !           190:        ipfw_obj_header *oh;
        !           191:        struct ipfw_sync_cfg *ucfg;
        !           192:        size_t sz;
        !           193: 
        !           194:        DTRACE();
        !           195: 
        !           196:        sz = sizeof(*oh) + sizeof(*ucfg);
        !           197:        /* Check minimum header size */
        !           198:        if (sd->valsize < sz)
        !           199:                return (EINVAL);
        !           200: 
        !           201:        oh = (struct _ipfw_obj_header*) ipfw_get_sopt_header(sd, sz);
        !           202: 
        !           203:        /* Basic length checks for TLVs */
        !           204:        if (oh->ntlv.head.length != sizeof(oh->ntlv))
        !           205:                return (EINVAL);
        !           206: 
        !           207:        ucfg = (struct ipfw_sync_cfg*) (oh + 1);
        !           208: 
        !           209:        /* Check if name is properly terminated */
        !           210:        if (strnlen(ucfg->name, sizeof(ucfg->name)) == sizeof(ucfg->name))
        !           211:                return (EINVAL);
        !           212: 
        !           213:        snprintf(ucfg->name, sizeof ucfg->name, "%d", fws_cfg.cfg.on);
        !           214:        ucfg->mode = 0;
        !           215:        if (fws_cfg.cfg.edge)
        !           216:                ucfg->mode |= CFG_SYNC_EDGE;
        !           217:        if (fws_cfg.cfg.collector)
        !           218:                ucfg->mode |= CFG_SYNC_COLLECTOR;
        !           219:        ucfg->addrs = (fws_cfg.cfg.addrs != 1) ? fws_cfg.cfg.addrs : 1;
        !           220:        memcpy(ucfg->addr, fws_cfg.cfg_addr, sizeof ucfg->addr);
        !           221: 
        !           222:        return 0;
        !           223: }
        !           224: 
        !           225: int
        !           226: fwsync_list(struct ip_fw_chain *ch, ip_fw3_opheader *op3, struct sockopt_data *sd)
        !           227: {
        !           228:        DTRACE();
        !           229: 
        !           230:        return 0;
        !           231: }
        !           232: 
        !           233: int
        !           234: fwsync_start(struct ip_fw_chain *ch, ip_fw3_opheader *op3, struct sockopt_data *sd)
        !           235: {
        !           236:        int *n, e;
        !           237:        ipfw_obj_header *oh;
        !           238:        size_t sz;
        !           239: 
        !           240:        DTRACE();
        !           241: 
        !           242:        sz = sizeof(*oh) + sizeof(int);
        !           243:        /* Check minimum header size */
        !           244:        if (sd->valsize < sz)
        !           245:                return (EINVAL);
        !           246: 
        !           247:        oh = (ipfw_obj_header*) sd->kbuf;
        !           248: 
        !           249:        /* Basic length checks for TLVs */
        !           250:        if (oh->ntlv.head.length != sizeof(oh->ntlv))
        !           251:                return (EINVAL);
        !           252: 
        !           253:        n = (int*) (oh + 1);
        !           254: 
        !           255:        if ((*n & CFG_SYNC_EDGE) && (fws_ctx.config & CTX_EDGE_READY)) {
        !           256:                fws_cfg.cfg.on |= CFG_SYNC_EDGE;
        !           257: 
        !           258:                e = kproc_create(fwsync_edge_proc, NULL, &fws_ctx.procz[CFG_SYNC_ADDR_EDGE], 
        !           259:                                0, 0, "fwsync_edge");
        !           260:                if (e) {
        !           261:                        printf("fwsync fwsync_edge failed #%d\n", e);
        !           262:                        return e;
        !           263:                }
        !           264:        }
        !           265: 
        !           266:        if ((*n & CFG_SYNC_COLLECTOR) && (fws_ctx.config & CTX_COLLECTOR_1_READY)) {
        !           267:                fws_cfg.cfg.on |= CFG_SYNC_COLLECTOR;
        !           268: 
        !           269:                if (!(fws_ctx.config & (CTX_COLLECTOR_1_ONLINE | CTX_COLLECTOR_2_ONLINE))) {
        !           270:                        ipfw_register_state_hook(fwsync_state_handler);
        !           271:                        ipfw_register_alias_hook(fwsync_alias_handler);
        !           272:                }
        !           273: 
        !           274:                fws_ctx.config |= CTX_COLLECTOR_1_ONLINE;
        !           275:        }
        !           276: 
        !           277:        if ((*n & CFG_SYNC_COLLECTOR) && (fws_ctx.config & CTX_COLLECTOR_2_READY)) {
        !           278:                fws_cfg.cfg.on |= CFG_SYNC_COLLECTOR;
        !           279: 
        !           280:                if (!(fws_ctx.config & (CTX_COLLECTOR_1_ONLINE | CTX_COLLECTOR_2_ONLINE))) {
        !           281:                        ipfw_register_state_hook(fwsync_state_handler);
        !           282:                        ipfw_register_alias_hook(fwsync_alias_handler);
        !           283:                }
        !           284: 
        !           285:                fws_ctx.config |= CTX_COLLECTOR_2_ONLINE;
        !           286:        }
        !           287: 
        !           288:        /* at last but not at least, activate config status of started sync service */
        !           289:        fws_cfg.cfg.on |= *n;
        !           290:        return 0;
        !           291: }
        !           292: 
        !           293: int
        !           294: fwsync_stop(struct ip_fw_chain *ch, ip_fw3_opheader *op3, struct sockopt_data *sd)
        !           295: {
        !           296:        int *n;
        !           297:        ipfw_obj_header *oh;
        !           298:        size_t sz;
        !           299: 
        !           300:        DTRACE();
        !           301: 
        !           302:        sz = sizeof(*oh) + sizeof(int);
        !           303:        /* Check minimum header size */
        !           304:        if (sd->valsize < sz)
        !           305:                return (EINVAL);
        !           306: 
        !           307:        oh = (ipfw_obj_header*) sd->kbuf;
        !           308: 
        !           309:        /* Basic length checks for TLVs */
        !           310:        if (oh->ntlv.head.length != sizeof(oh->ntlv))
        !           311:                return (EINVAL);
        !           312: 
        !           313:        n = (int*) (oh + 1);
        !           314: 
        !           315:        if ((*n & CFG_SYNC_EDGE) && (fws_ctx.config & CTX_CFG_EDGE))
        !           316:                fws_cfg.cfg.on &= ~CFG_SYNC_EDGE;
        !           317: 
        !           318:        if ((*n & CFG_SYNC_COLLECTOR) && (fws_ctx.config & CTX_COLLECTOR_2_ONLINE))
        !           319:                fws_ctx.config &= ~CTX_COLLECTOR_2_ONLINE;
        !           320:        if ((*n & CFG_SYNC_COLLECTOR) && (fws_ctx.config & CTX_COLLECTOR_1_ONLINE))
        !           321:                fws_ctx.config &= ~CTX_COLLECTOR_1_ONLINE;
        !           322: 
        !           323:        if ((*n & CFG_SYNC_COLLECTOR) && 
        !           324:                        !(fws_ctx.config & (CTX_COLLECTOR_1_ONLINE | CTX_COLLECTOR_2_ONLINE))) {
        !           325:                fws_cfg.cfg.on &= ~CFG_SYNC_COLLECTOR;
        !           326: 
        !           327:                ipfw_unregister_state_hook();
        !           328:                ipfw_unregister_alias_hook();
        !           329:        }
        !           330: 
        !           331:        /* at last but not at least, stop sync service */
        !           332:        fws_cfg.cfg.on &= ~*n;
        !           333:        return 0;
        !           334: }

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