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

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

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