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

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

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