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

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

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