Annotation of fwsync/driver/fwsync_workers.c, revision 1.9
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:
1.6 misho 8: static int
1.9 ! misho 9: fwsync_add_state_4(struct ipfw_flow_id *fid, u_int ruleid, u_short rulenum,
! 10: u_short kidx, u_char cmdtype)
1.6 misho 11: {
1.7 misho 12: struct ip_fw *rule = NULL;
13:
1.6 misho 14: DTRACE();
15:
1.9 ! misho 16: return ipfw_dyn_install_sync_state(fid, rule, ruleid, rulenum, kidx, cmdtype);
1.6 misho 17: }
18:
19: static int
1.9 ! misho 20: fwsync_add_state_6(struct ipfw_flow_id *fid, u_int ruleid, u_short rulenum,
! 21: u_short kidx, u_char cmdtype)
1.6 misho 22: {
23: DTRACE();
24:
25: return 0;
26: }
27:
28: int
29: fwsync_add_state(const struct fws_proto *pkt)
30: {
1.9 ! misho 31: struct fws_sndpkt *p;
1.7 misho 32:
1.6 misho 33: DTRACE();
34:
1.9 ! misho 35: if (!pkt || pkt->fws_addrtype == 1)
! 36: return 0; /* skip ethernet packet */
1.7 misho 37:
1.9 ! misho 38: p = malloc(sizeof(struct fws_sndpkt), M_FWSYNC, M_NOWAIT | M_ZERO);
! 39: if (!p) {
! 40: return ENOMEM;
! 41: } else
! 42: memcpy(&p->sp_proto, pkt, sizeof(struct fws_proto));
1.6 misho 43:
1.9 ! misho 44: mtx_lock(&fws_mtx_u);
! 45: TAILQ_INSERT_TAIL(&fwsync_updpkt, p, sp_next);
! 46: mtx_unlock(&fws_mtx_u);
1.6 misho 47: return 0;
48: }
49:
1.9 ! misho 50:
1.6 misho 51: int
52: fwsync_add_alias(const struct fws_proto *pkt)
53: {
54: DTRACE();
55:
56: return 0;
57: }
58:
59:
1.2 misho 60: void
1.3 misho 61: fwsync_sndpkt_handler(void *context, int pending)
1.1 misho 62: {
1.2 misho 63: struct fws_sndpkt *pkt;
64: struct mbuf *m2, *m;
1.1 misho 65: int e;
66:
67: DTRACE();
68:
1.2 misho 69: do {
70: mtx_lock(&fws_mtx_c);
71: pkt = TAILQ_FIRST(&fwsync_sndpkt);
1.4 misho 72: if (pkt)
73: TAILQ_REMOVE(&fwsync_sndpkt, pkt, sp_next);
1.2 misho 74: mtx_unlock(&fws_mtx_c);
75:
1.4 misho 76: if (!pkt) /* sending queue is empty */
77: break;
78:
79: if (!(fws_cfg.cfg.on & CFG_SYNC_COLLECTOR)) {
80: free(pkt, M_FWSYNC);
1.2 misho 81: continue;
1.4 misho 82: }
1.2 misho 83:
84: m = m_gethdr(M_NOWAIT, MT_DATA);
1.4 misho 85: if (!m) {
86: free(pkt, M_FWSYNC);
1.2 misho 87: continue;
1.4 misho 88: }
1.2 misho 89:
90: memcpy(mtod(m, struct fws_proto *), &pkt->sp_proto, sizeof pkt->sp_proto);
91: m->m_len = sizeof pkt->sp_proto;
92: m_fixhdr(m);
93:
1.1 misho 94: if ((fws_ctx.config & (CTX_COLLECTOR_2_ONLINE | CTX_COLLECTOR_2_READY)) ==
95: (CTX_COLLECTOR_2_ONLINE | CTX_COLLECTOR_2_READY)) {
96: m2 = m_copypacket(m, M_NOWAIT);
97: if (!m2) {
98: printf("error in copypacket for second collector\n");
99: goto out;
100: }
101: e = sosend(fws_ctx.sockz[CFG_SYNC_ADDR_COLLECTOR_2],
102: &fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_2].addr, NULL,
103: m2, NULL, 0, curthread);
1.2 misho 104: if (e && e != EAGAIN)
1.1 misho 105: printf("error in collector %d handler #%d\n", CFG_SYNC_ADDR_COLLECTOR_2, e);
106: }
107:
108: if ((fws_ctx.config & (CTX_COLLECTOR_1_ONLINE | CTX_COLLECTOR_1_READY)) ==
109: (CTX_COLLECTOR_1_ONLINE | CTX_COLLECTOR_1_READY)) {
110: m2 = m_copypacket(m, M_NOWAIT);
111: if (!m2) {
112: printf("error in copypacket for first collector\n");
113: goto out;
114: }
115: e = sosend(fws_ctx.sockz[CFG_SYNC_ADDR_COLLECTOR_1],
116: &fws_cfg.cfg_addr[CFG_SYNC_ADDR_COLLECTOR_1].addr, NULL,
117: m2, NULL, 0, curthread);
1.2 misho 118: if (e && e != EAGAIN)
1.1 misho 119: printf("error in collector %d handler #%d\n", CFG_SYNC_ADDR_COLLECTOR_1, e);
120: }
121: out:
1.2 misho 122: m_freem(m);
1.4 misho 123: free(pkt, M_FWSYNC);
1.2 misho 124: } while (--pending);
1.1 misho 125: }
126:
127: int
1.7 misho 128: fwsync_state_handler(const void *arg, const void *extdata)
1.1 misho 129: {
1.4 misho 130: const struct ipfw_flow_id *pkt = arg;
1.7 misho 131: const struct ipfw_dyn_hook_extdata *edata = extdata;
1.1 misho 132: struct fws_proto *spkt;
1.2 misho 133: struct fws_sndpkt *p;
1.1 misho 134:
135: DTRACE();
136:
1.4 misho 137: if (!pkt || pkt->addr_type == 1)
1.1 misho 138: return 0; /* skip ethernet packet */
139:
1.2 misho 140: mtx_lock(&fws_mtx_c);
141:
1.5 misho 142: p = malloc(sizeof(struct fws_sndpkt), M_FWSYNC, M_NOWAIT | M_ZERO);
1.2 misho 143: if (!p) {
144: mtx_unlock(&fws_mtx_c);
145: return 0;
146: } else
147: spkt = &p->sp_proto;
1.1 misho 148:
149: spkt->fws_version = FWS_PKTVER_STATE;
150: spkt->fws_fib = pkt->fib;
1.9 ! misho 151: spkt->fws_cmdtype = edata->cmdtype;
! 152: spkt->fws_kidx = edata->kidx;
1.7 misho 153: spkt->fws_ruleid = edata->ruleid;
154: spkt->fws_rulenum = edata->rulenum;
1.1 misho 155: spkt->fws_proto = pkt->proto;
156: spkt->fws_addrtype = pkt->addr_type;
157: spkt->fws_sport = pkt->src_port;
158: spkt->fws_dport = pkt->dst_port;
159:
160: switch (pkt->addr_type) {
161: case 4:
162: spkt->fws_saddr.s_addr = pkt->src_ip;
163: spkt->fws_daddr.s_addr = pkt->dst_ip;
164: spkt->fws_scopeid = 0;
165: break;
166: case 6:
167: memcpy(&spkt->fws_saddr6, &pkt->src_ip6, sizeof spkt->fws_saddr6);
168: memcpy(&spkt->fws_daddr6, &pkt->dst_ip6, sizeof spkt->fws_daddr6);
169: spkt->fws_scopeid = pkt->flow_id6;
170: break;
171: default:
1.2 misho 172: free(p, M_FWSYNC);
173: mtx_unlock(&fws_mtx_c);
174: return EINVAL;
1.1 misho 175: }
176:
1.2 misho 177: TAILQ_INSERT_TAIL(&fwsync_sndpkt, p, sp_next);
178:
179: mtx_unlock(&fws_mtx_c);
180:
181: taskqueue_enqueue(fws_tq, &fws_sndpkt_task);
1.1 misho 182: return 0;
183: }
184:
185: int
1.7 misho 186: fwsync_alias_handler(const void *arg, const void *extdata)
1.1 misho 187: {
1.4 misho 188: const struct alias_link *lnk = arg;
189: struct fws_proto *spkt;
190: struct fws_sndpkt *p;
191:
1.1 misho 192: DTRACE();
193:
1.4 misho 194: if (!lnk || lnk->link_type >= IPPROTO_MAX)
195: return 0;
196:
197: mtx_lock(&fws_mtx_c);
198:
1.5 misho 199: p = malloc(sizeof(struct fws_sndpkt), M_FWSYNC, M_NOWAIT | M_ZERO);
1.4 misho 200: if (!p) {
201: mtx_unlock(&fws_mtx_c);
202: return 0;
203: } else
204: spkt = &p->sp_proto;
205:
206: spkt->fws_version = FWS_PKTVER_ALIAS;
207: spkt->fws_proto = lnk->link_type;
208: spkt->fws_addrtype = 4;
209: spkt->fws_sport = lnk->src_port;
210: spkt->fws_dport = lnk->dst_port;
211: spkt->fws_aport = lnk->alias_port;
212: spkt->fws_pport = lnk->proxy_port;
213: spkt->fws_saddr.s_addr = lnk->src_addr.s_addr;
214: spkt->fws_daddr.s_addr = lnk->dst_addr.s_addr;
215: spkt->fws_aaddr.s_addr = lnk->alias_addr.s_addr;
216: spkt->fws_paddr.s_addr = lnk->proxy_addr.s_addr;
217:
218: TAILQ_INSERT_TAIL(&fwsync_sndpkt, p, sp_next);
219:
220: mtx_unlock(&fws_mtx_c);
221:
222: taskqueue_enqueue(fws_tq, &fws_sndpkt_task);
1.1 misho 223: return 0;
224: }
1.9 ! misho 225:
! 226: int
! 227: fwsync_state_sync(const void *arg, const void *extdata)
! 228: {
! 229: struct fws_sndpkt *pkt;
! 230: struct ipfw_flow_id fid;
! 231:
! 232: DTRACE();
! 233:
! 234: mtx_lock(&fws_mtx_u);
! 235: pkt = TAILQ_FIRST(&fwsync_updpkt);
! 236: if (pkt)
! 237: TAILQ_REMOVE(&fwsync_updpkt, pkt, sp_next);
! 238: mtx_unlock(&fws_mtx_u);
! 239:
! 240: if (!pkt) /* update queue is empty */
! 241: return 0;
! 242:
! 243: if (!(fws_cfg.cfg.on & CFG_SYNC_EDGE)) {
! 244: free(pkt, M_FWSYNC);
! 245: return EAGAIN;
! 246: }
! 247:
! 248: memset(&fid, 0, sizeof fid);
! 249: fid.fib = pkt->sp_proto.fws_fib;
! 250: fid.proto = pkt->sp_proto.fws_proto;
! 251: fid.addr_type = pkt->sp_proto.fws_addrtype;
! 252: fid.src_port = pkt->sp_proto.fws_sport;
! 253: fid.dst_port = pkt->sp_proto.fws_dport;
! 254: switch (pkt->sp_proto.fws_addrtype) {
! 255: case 4:
! 256: fid.src_ip = pkt->sp_proto.fws_saddr.s_addr;
! 257: fid.dst_ip = pkt->sp_proto.fws_daddr.s_addr;
! 258: break;
! 259: case 6:
! 260: memcpy(&fid.src_ip6, &pkt->sp_proto.fws_saddr6, sizeof fid.src_ip6);
! 261: memcpy(&fid.dst_ip6, &pkt->sp_proto.fws_daddr6, sizeof fid.dst_ip6);
! 262: fid.flow_id6 = pkt->sp_proto.fws_scopeid;
! 263: break;
! 264: default:
! 265: free(pkt, M_FWSYNC);
! 266: return EINVAL;
! 267: }
! 268:
! 269: if (pkt->sp_proto.fws_addrtype == 4)
! 270: fwsync_add_state_4(&fid, pkt->sp_proto.fws_ruleid, pkt->sp_proto.fws_rulenum,
! 271: pkt->sp_proto.fws_kidx, pkt->sp_proto.fws_cmdtype);
! 272: else if (pkt->sp_proto.fws_addrtype == 6)
! 273: fwsync_add_state_6(&fid, pkt->sp_proto.fws_ruleid, pkt->sp_proto.fws_rulenum,
! 274: pkt->sp_proto.fws_kidx, pkt->sp_proto.fws_cmdtype);
! 275:
! 276: free(pkt, M_FWSYNC);
! 277: return 0;
! 278: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>