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