xref: /dragonfly/sys/net/ipfw3/ip_fw3.c (revision 106728aa)
1 /*
2  * Copyright (c) 1993 Daniel Boulet
3  * Copyright (c) 1994 Ugen J.S.Antsilevich
4  * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
5  * Copyright (c) 2014 - 2018 The DragonFly Project.  All rights reserved.
6  *
7  * This code is derived from software contributed to The DragonFly Project
8  * by Bill Yuan <bycn82@dragonflybsd.org>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  * 3. Neither the name of The DragonFly Project nor the names of its
21  *    contributors may be used to endorse or promote products derived
22  *    from this software without specific, prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
28  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  */
38 
39 #include "opt_ipfw.h"
40 #include "opt_inet.h"
41 #ifndef INET
42 #error IPFIREWALL3 requires INET.
43 #endif /* INET */
44 
45 #include <sys/param.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/mbuf.h>
49 #include <sys/socketvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/systimer.h>
52 #include <sys/thread2.h>
53 #include <sys/in_cksum.h>
54 #include <sys/systm.h>
55 #include <sys/proc.h>
56 #include <sys/socket.h>
57 #include <sys/syslog.h>
58 #include <sys/ucred.h>
59 #include <sys/lock.h>
60 #include <sys/mplock2.h>
61 
62 #include <net/if.h>
63 #include <net/radix.h>
64 #include <net/route.h>
65 #include <net/pfil.h>
66 #include <net/netmsg2.h>
67 
68 #include <netinet/in.h>
69 #include <netinet/in_systm.h>
70 #include <netinet/in_var.h>
71 #include <netinet/in_pcb.h>
72 #include <netinet/ip.h>
73 #include <netinet/ip_var.h>
74 #include <netinet/ip_icmp.h>
75 #include <netinet/tcp.h>
76 #include <netinet/tcp_timer.h>
77 #include <netinet/tcp_var.h>
78 #include <netinet/tcpip.h>
79 #include <netinet/udp.h>
80 #include <netinet/udp_var.h>
81 #include <netinet/ip_divert.h>
82 #include <netinet/if_ether.h>
83 
84 #include <net/ipfw3/ip_fw.h>
85 #include <net/ipfw3/ip_fw3_set.h>
86 #include <net/ipfw3_basic/ip_fw3_log.h>
87 #include <net/ipfw3_basic/ip_fw3_table.h>
88 #include <net/ipfw3_basic/ip_fw3_sync.h>
89 #include <net/ipfw3_basic/ip_fw3_basic.h>
90 #include <net/ipfw3_basic/ip_fw3_state.h>
91 #include <net/ipfw3_nat/ip_fw3_nat.h>
92 #include <net/dummynet3/ip_dummynet3.h>
93 
94 MALLOC_DEFINE(M_IPFW3, "IPFW3", "ipfw3 module");
95 
96 #define MAX_MODULE		10
97 #define MAX_OPCODE_PER_MODULE	100
98 
99 #define IPFW_AUTOINC_STEP_MIN	1
100 #define IPFW_AUTOINC_STEP_MAX	1000
101 #define IPFW_AUTOINC_STEP_DEF	100
102 
103 
104 struct netmsg_ipfw {
105 	struct netmsg_base base;
106 	const struct ipfw_ioc_rule *ioc_rule;
107 	struct ip_fw	*rule;
108 	struct ip_fw	*next_rule;
109 	struct ip_fw	*prev_rule;
110 	struct ip_fw	*sibling;	/* sibling in prevous CPU */
111 };
112 
113 struct netmsg_del {
114 	struct netmsg_base base;
115 	struct ip_fw	*rule;
116 	struct ip_fw	*start_rule;
117 	struct ip_fw	*prev_rule;
118 	struct ipfw_ioc_state *ioc_state;
119 	uint16_t	rulenum;
120 	uint8_t		set_from;
121 	uint8_t		set_to;
122 	int		kill_default;
123 };
124 
125 struct netmsg_zent {
126 	struct netmsg_base base;
127 	struct ip_fw	*start_rule;
128 	uint16_t	rulenum;
129 	uint16_t	log_only;
130 };
131 
132 ip_fw_ctl_t	*ip_fw3_ctl_nat_ptr = NULL;
133 ip_fw_ctl_t	*ip_fw3_ctl_state_ptr = NULL;
134 ip_fw_ctl_t	*ip_fw3_ctl_table_ptr = NULL;
135 ip_fw_ctl_t	*ip_fw3_ctl_sync_ptr = NULL;
136 ip_fw_log_t	*ip_fw3_log_ptr = NULL;
137 
138 extern int ip_fw_loaded;
139 extern struct ipfw3_state_context 	*fw3_state_ctx[MAXCPU];
140 int 			sysctl_var_fw3_enable = 1;
141 int 			sysctl_var_fw3_one_pass = 1;
142 int 			sysctl_var_fw3_verbose = 0;
143 static int 		sysctl_var_fw3_flushing;
144 static int 		sysctl_var_fw3_debug;
145 static int 		sysctl_var_autoinc_step = IPFW_AUTOINC_STEP_DEF;
146 
147 int	ip_fw3_sysctl_enable(SYSCTL_HANDLER_ARGS);
148 int	ip_fw3_sysctl_autoinc_step(SYSCTL_HANDLER_ARGS);
149 
150 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw3, CTLFLAG_RW, 0, "Firewall");
151 SYSCTL_PROC(_net_inet_ip_fw3, OID_AUTO, enable, CTLTYPE_INT | CTLFLAG_RW,
152 	&sysctl_var_fw3_enable, 0, ip_fw3_sysctl_enable, "I", "Enable ipfw");
153 SYSCTL_PROC(_net_inet_ip_fw3, OID_AUTO, sysctl_var_autoinc_step,
154 	CTLTYPE_INT | CTLFLAG_RW, &sysctl_var_autoinc_step, 0,
155 	ip_fw3_sysctl_autoinc_step, "I", "Rule number autincrement step");
156 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO,one_pass,CTLFLAG_RW,
157 	&sysctl_var_fw3_one_pass, 0,
158 	"Only do a single pass through ipfw3 when using dummynet(4)");
159 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO, debug, CTLFLAG_RW,
160 	&sysctl_var_fw3_debug, 0, "Enable printing of debug ip_fw statements");
161 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO, verbose, CTLFLAG_RW,
162 	&sysctl_var_fw3_verbose, 0, "Log matches to ipfw3 rules");
163 
164 
165 filter_func 			filter_funcs[MAX_MODULE][MAX_OPCODE_PER_MODULE];
166 struct ipfw3_module 		fw3_modules[MAX_MODULE];
167 struct ipfw3_context 		*fw3_ctx[MAXCPU];
168 struct ipfw3_sync_context 	fw3_sync_ctx;
169 
170 
171 void
172 ip_fw3_register_module(int module_id,char *module_name)
173 {
174 	struct ipfw3_module *tmp;
175 	int i;
176 
177 	tmp = fw3_modules;
178 	for (i=0; i < MAX_MODULE; i++) {
179 		if (tmp->type == 0) {
180 			tmp->type = 1;
181 			tmp->id = module_id;
182 			strncpy(tmp->name, module_name, strlen(module_name));
183 			break;
184 		}
185 		tmp++;
186 	}
187 	kprintf("ipfw3 module %s loaded\n", module_name);
188 }
189 
190 int
191 ip_fw3_unregister_module(int module_id)
192 {
193 	struct ipfw3_module *tmp;
194 	struct ip_fw *fw;
195 	ipfw_insn *cmd;
196 	int i, len, cmdlen, found;
197 
198 	found = 0;
199 	tmp = fw3_modules;
200 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
201 	fw = ctx->rules;
202 	for (; fw; fw = fw->next) {
203 		for (len = fw->cmd_len, cmd = fw->cmd; len > 0;
204 			len -= cmdlen,
205 			cmd = (ipfw_insn *)((uint32_t *)cmd + cmdlen)) {
206 			cmdlen = F_LEN(cmd);
207 			if (cmd->module == 0 &&
208 				(cmd->opcode == 0 || cmd->opcode == 1)) {
209 				//action accept or deny
210 			} else if (cmd->module == module_id) {
211 				found = 1;
212 				goto decide;
213 			}
214 		}
215 	}
216 decide:
217 	if (found) {
218 		return 1;
219 	} else {
220 		for (i = 0; i < MAX_MODULE; i++) {
221 			if (tmp->type == 1 && tmp->id == module_id) {
222 				tmp->type = 0;
223 				kprintf("ipfw3 module %s unloaded\n",
224 						tmp->name);
225 				break;
226 			}
227 			tmp++;
228 		}
229 
230 		for (i = 0; i < MAX_OPCODE_PER_MODULE; i++) {
231 			if (module_id == 0) {
232 				if (i ==0 || i == 1) {
233 					continue;
234 				}
235 			}
236 			filter_funcs[module_id][i] = NULL;
237 		}
238 		return 0;
239 	}
240 }
241 
242 void
243 ip_fw3_register_filter_funcs(int module, int opcode, filter_func func)
244 {
245 	filter_funcs[module][opcode] = func;
246 }
247 
248 void
249 check_accept(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args,
250 		struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len)
251 {
252 	*cmd_val = IP_FW_PASS;
253 	*cmd_ctl = IP_FW_CTL_DONE;
254 	if (cmd->arg3 && ip_fw3_log_ptr != NULL) {
255 		ip_fw3_log_ptr((*args)->m, (*args)->eh, cmd->arg1);
256 	}
257 }
258 
259 void
260 check_deny(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args,
261 		struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len)
262 {
263 	*cmd_val = IP_FW_DENY;
264 	*cmd_ctl = IP_FW_CTL_DONE;
265 	if (cmd->arg3 && ip_fw3_log_ptr != NULL) {
266 		ip_fw3_log_ptr((*args)->m, (*args)->eh, cmd->arg1);
267 	}
268 }
269 
270 void
271 init_module(void)
272 {
273 	memset(fw3_modules, 0, sizeof(struct ipfw3_module) * MAX_MODULE);
274 	memset(filter_funcs, 0, sizeof(filter_func) *
275 			MAX_OPCODE_PER_MODULE * MAX_MODULE);
276 	ip_fw3_register_filter_funcs(0, O_BASIC_ACCEPT,
277 			(filter_func)check_accept);
278 	ip_fw3_register_filter_funcs(0, O_BASIC_DENY, (filter_func)check_deny);
279 }
280 
281 int
282 ip_fw3_free_rule(struct ip_fw *rule)
283 {
284 	kfree(rule, M_IPFW3);
285 	rule = NULL;
286 	return 1;
287 }
288 
289 static struct ip_fw *
290 lookup_next_rule(struct ip_fw *me)
291 {
292 	struct ip_fw *rule = NULL;
293 	ipfw_insn *cmd;
294 
295 	/* look for action, in case it is a skipto */
296 	cmd = ACTION_PTR(me);
297 	if ((int)cmd->module == MODULE_BASIC_ID &&
298 		(int)cmd->opcode == O_BASIC_SKIPTO) {
299 		for (rule = me->next; rule; rule = rule->next) {
300 			if (rule->rulenum >= cmd->arg1)
301 				break;
302 		}
303 	}
304 	if (rule == NULL) {	/* failure or not a skipto */
305 		rule = me->next;
306 	}
307 	me->next_rule = rule;
308 	return rule;
309 }
310 
311 /*
312  * rules are stored in ctx->ipfw_rule_chain.
313  * and each rule is combination of multiple cmds.(ipfw_insn)
314  * in each rule, it begin with filter cmds. and end with action cmds.
315  * 'outer/inner loop' are looping the rules/cmds.
316  * it will invoke the cmds relatived function according to the cmd's
317  * module id and opcode id. and process according to return value.
318  */
319 int
320 ip_fw3_chk(struct ip_fw_args *args)
321 {
322 	struct tcphdr *tcp;
323 	struct udphdr *udp;
324 	struct icmp *icmp;
325 
326 	struct mbuf *m = args->m;
327 	struct ip *ip = mtod(m, struct ip *);
328 	struct ip_fw *f = NULL;		/* matching rule */
329 	int cmd_val = IP_FW_PASS;
330 	struct m_tag *mtag;
331 	struct divert_info *divinfo;
332 
333 	/*
334 	 * hlen	The length of the IPv4 header.
335 	 *	hlen >0 means we have an IPv4 packet.
336 	 */
337 	u_int hlen = 0;		/* hlen >0 means we have an IP pkt */
338 
339 	/*
340 	 * offset	The offset of a fragment. offset != 0 means that
341 	 *	we have a fragment at this offset of an IPv4 packet.
342 	 *	offset == 0 means that (if this is an IPv4 packet)
343 	 *	this is the first or only fragment.
344 	 */
345 	u_short offset = 0;
346 
347 	uint8_t proto;
348 	uint16_t src_port = 0, dst_port = 0;	/* NOTE: host format	*/
349 	struct in_addr src_ip, dst_ip;		/* NOTE: network format	*/
350 	uint16_t ip_len = 0;
351 	uint8_t prev_module = -1, prev_opcode = -1; /* previous module & opcode */
352 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
353 
354 	if (m->m_pkthdr.fw_flags & IPFW_MBUF_GENERATED)
355 		return IP_FW_PASS;	/* accept */
356 
357 	if (args->eh == NULL ||		/* layer 3 packet */
358 		(m->m_pkthdr.len >= sizeof(struct ip) &&
359 		 ntohs(args->eh->ether_type) == ETHERTYPE_IP))
360 		hlen = ip->ip_hl << 2;
361 
362 	/*
363 	 * Collect parameters into local variables for faster matching.
364 	 */
365 	if (hlen == 0) {	/* do not grab addresses for non-ip pkts */
366 		proto = args->f_id.proto = 0;	/* mark f_id invalid */
367 		goto after_ip_checks;
368 	}
369 
370 	proto = args->f_id.proto = ip->ip_p;
371 	src_ip = ip->ip_src;
372 	dst_ip = ip->ip_dst;
373 	if (args->eh != NULL) { /* layer 2 packets are as on the wire */
374 		offset = ntohs(ip->ip_off) & IP_OFFMASK;
375 		ip_len = ntohs(ip->ip_len);
376 	} else {
377 		offset = ip->ip_off & IP_OFFMASK;
378 		ip_len = ip->ip_len;
379 	}
380 
381 #define PULLUP_TO(len)					\
382 do {							\
383 	if (m->m_len < (len)) {				\
384 		args->m = m = m_pullup(m, (len));	\
385 			if (m == NULL)			\
386 				goto pullup_failed;	\
387 		ip = mtod(m, struct ip *);		\
388 	}						\
389 } while (0)
390 
391 	if (offset == 0) {
392 		switch (proto) {
393 			case IPPROTO_TCP:
394 				PULLUP_TO(hlen + sizeof(struct tcphdr));
395 				tcp = L3HDR(struct tcphdr, ip);
396 				dst_port = tcp->th_dport;
397 				src_port = tcp->th_sport;
398 				args->f_id.flags = tcp->th_flags;
399 				break;
400 			case IPPROTO_UDP:
401 				PULLUP_TO(hlen + sizeof(struct udphdr));
402 				udp = L3HDR(struct udphdr, ip);
403 				dst_port = udp->uh_dport;
404 				src_port = udp->uh_sport;
405 				break;
406 			case IPPROTO_ICMP:
407 				PULLUP_TO(hlen + 4);
408 				icmp = L3HDR(struct icmp, ip);
409   				args->f_id.flags = icmp->icmp_type;
410 				dst_port = icmp->icmp_id;
411 				src_port = dst_port;
412 				break;
413 			default:
414 				break;
415 		}
416 	}
417 
418 #undef PULLUP_TO
419 
420 	args->f_id.src_ip = ntohl(src_ip.s_addr);
421 	args->f_id.dst_ip = ntohl(dst_ip.s_addr);
422 	args->f_id.src_port = src_port = ntohs(src_port);
423 	args->f_id.dst_port = dst_port = ntohs(dst_port);
424 
425 after_ip_checks:
426 	if (args->rule) {
427 		/*
428 		 * Packet has already been tagged. Look for the next rule
429 		 * to restart processing.
430 		 *
431 		 * If sysctl_var_fw3_one_pass != 0 then just accept it.
432 		 * XXX should not happen here, but optimized out in
433 		 * the caller.
434 		 */
435 		if (sysctl_var_fw3_one_pass)
436 			return IP_FW_PASS;
437 
438 		/* This rule is being/has been flushed */
439 		if (sysctl_var_fw3_flushing)
440 			return IP_FW_DENY;
441 
442 		f = args->rule->next_rule;
443 		if (f == NULL)
444 			f = lookup_next_rule(args->rule);
445 	} else {
446 		/*
447 		 * Find the starting rule. It can be either the first
448 		 * one, or the one after divert_rule if asked so.
449 		 */
450 		int skipto;
451 
452 		mtag = m_tag_find(m, PACKET_TAG_IPFW_DIVERT, NULL);
453 		if (mtag != NULL) {
454 			divinfo = m_tag_data(mtag);
455 			skipto = divinfo->skipto;
456 		} else {
457 			skipto = 0;
458 		}
459 
460 		f = ctx->rules;
461 		if (args->eh == NULL && skipto != 0) {
462 			/* No skipto during rule flushing */
463 			if (sysctl_var_fw3_flushing) {
464 				return IP_FW_DENY;
465 			}
466 			if (skipto >= IPFW_DEFAULT_RULE) {
467 				return IP_FW_DENY; /* invalid */
468 			}
469 			while (f && f->rulenum <= skipto) {
470 				f = f->next;
471 			}
472 			if (f == NULL) {	/* drop packet */
473 				return IP_FW_DENY;
474 			}
475 		} else if (sysctl_var_fw3_flushing) {
476 			/* Rules are being flushed; skip to default rule */
477 			f = ctx->default_rule;
478 		}
479 	}
480 	if ((mtag = m_tag_find(m, PACKET_TAG_IPFW_DIVERT, NULL)) != NULL) {
481 		m_tag_delete(m, mtag);
482 	}
483 
484 	/*
485 	 * Now scan the rules, and parse microinstructions for each rule.
486 	 */
487 	int prev_val;	/*  previous result of 'or' filter */
488 	int l, cmdlen;
489 	ipfw_insn *cmd;
490 	int cmd_ctl;
491 	/* foreach rule in chain */
492 	for (; f; f = f->next) {
493 again:  /* check the rule again*/
494 		if (ctx->sets & (1 << f->set)) {
495 			continue;
496 		}
497 
498 		prev_val = -1;
499 		 /* foreach cmd in rule */
500 		for (l = f->cmd_len, cmd = f->cmd; l > 0; l -= cmdlen,
501 			cmd = (ipfw_insn *)((uint32_t *)cmd+ cmdlen)) {
502 			cmdlen = F_LEN(cmd);
503 
504 			/* skip 'or' filter when already match */
505 			if (cmd->len & F_OR &&
506 				cmd->module == prev_module &&
507 				cmd->opcode == prev_opcode &&
508 				prev_val == 1) {
509 				goto next_cmd;
510 			}
511 
512 check_body: /* check the body of the rule again.*/
513 			(filter_funcs[cmd->module][cmd->opcode])
514 				(&cmd_ctl, &cmd_val, &args, &f, cmd, ip_len);
515 			switch(cmd_ctl) {
516 				case IP_FW_CTL_DONE:
517 					if (prev_val == 0) /* but 'or' failed */
518 						goto next_rule;
519 					goto done;
520 				case IP_FW_CTL_AGAIN:
521 					goto again;
522 				case IP_FW_CTL_NEXT:
523 					goto next_rule;
524 				case IP_FW_CTL_NAT:
525 					args->rule=f;
526 					goto done;
527 				case IP_FW_CTL_CHK_STATE:
528 					/* update the cmd and l */
529 					cmd = ACTION_PTR(f);
530 					l = f->cmd_len - f->act_ofs;
531 					goto check_body;
532 			}
533 			if (cmd->len & F_NOT)
534 				cmd_val= !cmd_val;
535 
536 			if (cmd->len & F_OR) {	/* has 'or' */
537 				if (!cmd_val) {	/* not matched */
538 					if(prev_val == -1){	/* first 'or' */
539 						prev_val = 0;
540 						prev_module = cmd->module;
541 						prev_opcode = cmd->opcode;
542 					} else if (prev_module == cmd->module &&
543 						prev_opcode == cmd->opcode) {
544 						/* continuous 'or' filter */
545 					} else if (prev_module != cmd->module ||
546 						prev_opcode != cmd->opcode) {
547 						/* 'or' filter changed */
548 						if(prev_val == 0){
549 							goto next_rule;
550 						} else {
551 							prev_val = 0;
552 							prev_module = cmd->module;
553 							prev_opcode = cmd->opcode;
554 						}
555 					}
556 				} else { /* has 'or' and matched */
557 					prev_val = 1;
558 					prev_module = cmd->module;
559 					prev_opcode = cmd->opcode;
560 				}
561 			} else { /* no or */
562 				if (!cmd_val) {	/* not matched */
563 					goto next_rule;
564 				} else {
565 					if (prev_val == 0) {
566 						/* previous 'or' not matched */
567 						goto next_rule;
568 					} else {
569 						prev_val = -1;
570 					}
571 				}
572 			}
573 next_cmd:;
574 		}	/* end of inner for, scan opcodes */
575 next_rule:;		/* try next rule		*/
576 	}		/* end of outer for, scan rules */
577 	kprintf("+++ ipfw: ouch!, skip past end of rules, denying packet\n");
578 	return IP_FW_DENY;
579 
580 done:
581 	/* Update statistics */
582 	f->pcnt++;
583 	f->bcnt += ip_len;
584 	f->timestamp = time_second;
585 	return cmd_val;
586 
587 pullup_failed:
588 	if (sysctl_var_fw3_verbose)
589 		kprintf("pullup failed\n");
590 	return IP_FW_DENY;
591 }
592 
593 struct mbuf *
594 ip_fw3_dummynet_io(struct mbuf *m, int pipe_nr, int dir, struct ip_fw_args *fwa)
595 {
596 	struct m_tag *mtag;
597 	struct dn_pkt *pkt;
598 	ipfw_insn *cmd;
599 	const struct ipfw_flow_id *id;
600 	struct dn_flow_id *fid;
601 
602 	M_ASSERTPKTHDR(m);
603 
604 	mtag = m_tag_get(PACKET_TAG_DUMMYNET, sizeof(*pkt),
605 	    M_INTWAIT | M_NULLOK);
606 	if (mtag == NULL) {
607 		m_freem(m);
608 		return (NULL);
609 	}
610 	m_tag_prepend(m, mtag);
611 
612 	pkt = m_tag_data(mtag);
613 	bzero(pkt, sizeof(*pkt));
614 
615 	cmd = (ipfw_insn *)((uint32_t *)fwa->rule->cmd + fwa->rule->act_ofs);
616 	KASSERT(cmd->opcode == O_DUMMYNET_PIPE ||
617 			cmd->opcode == O_DUMMYNET_QUEUE,
618 			("Rule is not PIPE or QUEUE, opcode %d", cmd->opcode));
619 
620 	pkt->dn_m = m;
621 	pkt->dn_flags = (dir & DN_FLAGS_DIR_MASK);
622 	pkt->ifp = fwa->oif;
623 	pkt->pipe_nr = pipe_nr;
624 
625 	pkt->cpuid = mycpuid;
626 	pkt->msgport = netisr_curport();
627 
628 	id = &fwa->f_id;
629 	fid = &pkt->id;
630 	fid->fid_dst_ip = id->dst_ip;
631 	fid->fid_src_ip = id->src_ip;
632 	fid->fid_dst_port = id->dst_port;
633 	fid->fid_src_port = id->src_port;
634 	fid->fid_proto = id->proto;
635 	fid->fid_flags = id->flags;
636 
637 	pkt->dn_priv = fwa->rule;
638 
639 	if ((int)cmd->opcode == O_DUMMYNET_PIPE)
640 		pkt->dn_flags |= DN_FLAGS_IS_PIPE;
641 
642 	m->m_pkthdr.fw_flags |= DUMMYNET_MBUF_TAGGED;
643 	return (m);
644 }
645 
646 
647 void
648 add_rule_dispatch(netmsg_t nmsg)
649 {
650 	struct netmsg_ipfw *fwmsg = (struct netmsg_ipfw *)nmsg;
651 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
652 	struct ip_fw *rule, *prev,*next;
653 	const struct ipfw_ioc_rule *ioc_rule;
654 
655 	ioc_rule = fwmsg->ioc_rule;
656 	 // create rule by ioc_rule
657 	rule = kmalloc(RULESIZE(ioc_rule), M_IPFW3, M_WAITOK | M_ZERO);
658 	rule->act_ofs = ioc_rule->act_ofs;
659 	rule->cmd_len = ioc_rule->cmd_len;
660 	rule->rulenum = ioc_rule->rulenum;
661 	rule->set = ioc_rule->set;
662 	bcopy(ioc_rule->cmd, rule->cmd, rule->cmd_len * 4);
663 
664 	for (prev = NULL, next = ctx->rules;
665 		next; prev = next, next = next->next) {
666 		if (next->rulenum > ioc_rule->rulenum) {
667 			break;
668 		}
669 	}
670 	KASSERT(next != NULL, ("no default rule?!"));
671 
672 	/*
673 	 * Insert rule into the pre-determined position
674 	 */
675 	if (prev != NULL) {
676 		rule->next = next;
677 		prev->next = rule;
678 	} else {
679 		rule->next = ctx->rules;
680 		ctx->rules = rule;
681 	}
682 
683 	/*
684 	 * if sibiling in last CPU is exists,
685 	 * then it's sibling should be current rule
686 	 */
687 	if (fwmsg->sibling != NULL) {
688 		fwmsg->sibling->sibling = rule;
689 	}
690 	/* prepare for next CPU */
691 	fwmsg->sibling = rule;
692 
693 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);
694 }
695 
696 /*
697  * confirm the rulenumber
698  * call dispatch function to add rule into the list
699  * Update the statistic
700  */
701 void
702 ip_fw3_add_rule(struct ipfw_ioc_rule *ioc_rule)
703 {
704 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
705 	struct netmsg_ipfw fwmsg;
706 	struct netmsg_base *nmsg;
707 	struct ip_fw *f;
708 
709 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
710 
711 	/*
712 	 * If rulenum is 0, find highest numbered rule before the
713 	 * default rule, and add rule number incremental step.
714 	 */
715 	if (ioc_rule->rulenum == 0) {
716 		int step = sysctl_var_autoinc_step;
717 
718 		KKASSERT(step >= IPFW_AUTOINC_STEP_MIN &&
719 				step <= IPFW_AUTOINC_STEP_MAX);
720 
721 		/*
722 		 * Locate the highest numbered rule before default
723 		 */
724 		for (f = ctx->rules; f; f = f->next) {
725 			if (f->rulenum == IPFW_DEFAULT_RULE)
726 				break;
727 			ioc_rule->rulenum = f->rulenum;
728 		}
729 		if (ioc_rule->rulenum < IPFW_DEFAULT_RULE - step)
730 			ioc_rule->rulenum += step;
731 	}
732 	KASSERT(ioc_rule->rulenum != IPFW_DEFAULT_RULE &&
733 			ioc_rule->rulenum != 0,
734 			("invalid rule num %d", ioc_rule->rulenum));
735 
736 	bzero(&fwmsg, sizeof(fwmsg));
737 	nmsg = &fwmsg.base;
738 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
739 			0, add_rule_dispatch);
740 	fwmsg.ioc_rule = ioc_rule;
741 
742 	netisr_domsg(nmsg, 0);
743 
744 	IPFW3_DEBUG("++ installed rule %d, static count now %d\n",
745 			ioc_rule->rulenum, static_count);
746 }
747 
748 /**
749  * Free storage associated with a static rule (including derived
750  * dynamic rules).
751  * The caller is in charge of clearing rule pointers to avoid
752  * dangling pointers.
753  * @return a pointer to the next entry.
754  * Arguments are not checked, so they better be correct.
755  * Must be called at splimp().
756  */
757 struct ip_fw *
758 ip_fw3_delete_rule(struct ipfw3_context *ctx,
759 		 struct ip_fw *prev, struct ip_fw *rule)
760 {
761 	if (prev == NULL)
762 		ctx->rules = rule->next;
763 	else
764 		prev->next = rule->next;
765 
766 	kfree(rule, M_IPFW3);
767 	rule = NULL;
768 	return NULL;
769 }
770 
771 void
772 flush_rule_dispatch(netmsg_t nmsg)
773 {
774 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
775 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
776 	struct ip_fw *rule, *the_rule;
777 	int kill_default = dmsg->kill_default;
778 
779 	rule = ctx->rules;
780 	while (rule != NULL) {
781 		if (rule->rulenum == IPFW_DEFAULT_RULE && kill_default == 0) {
782 			ctx->rules = rule;
783 			break;
784 		}
785 		the_rule = rule;
786 		rule = rule->next;
787 
788 		kfree(the_rule, M_IPFW3);
789 	}
790 
791 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);
792 }
793 
794 
795 /*
796  * Deletes all rules from a chain (including the default rule
797  * if the second argument is set).
798  * Must be called at splimp().
799  */
800 void
801 ip_fw3_ctl_flush_rule(int kill_default)
802 {
803 	struct netmsg_del dmsg;
804 
805 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
806 
807 	if (!kill_default) {
808 		sysctl_var_fw3_flushing = 1;
809 		netmsg_service_sync();
810 	}
811 	/*
812 	 * Press the 'flush' button
813 	 */
814 	bzero(&dmsg, sizeof(dmsg));
815 	netmsg_init(&dmsg.base, NULL, &curthread->td_msgport,
816 			0, flush_rule_dispatch);
817 	dmsg.kill_default = kill_default;
818 	netisr_domsg(&dmsg.base, 0);
819 
820 	/* Flush is done */
821 	sysctl_var_fw3_flushing = 0;
822 }
823 
824 void
825 delete_rule_dispatch(netmsg_t nmsg)
826 {
827 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
828 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
829 	struct ip_fw *rule, *prev = NULL;
830 
831 	rule = ctx->rules;
832 	while (rule!=NULL) {
833 		if (rule->rulenum == dmsg->rulenum) {
834 			ip_fw3_delete_rule(ctx, prev, rule);
835 			break;
836 		}
837 		prev = rule;
838 		rule = rule->next;
839 	}
840 
841 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);
842 }
843 
844 int
845 ip_fw3_ctl_delete_rule(struct sockopt *sopt)
846 {
847 	struct netmsg_del dmsg;
848 	struct netmsg_base *nmsg;
849 	int *rulenum;
850 
851 	rulenum = (int *) sopt->sopt_val;
852 
853 
854 	/*
855 	 * Get rid of the rule duplications on all CPUs
856 	 */
857 	bzero(&dmsg, sizeof(dmsg));
858 	nmsg = &dmsg.base;
859 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
860 			0, delete_rule_dispatch);
861 	dmsg.rulenum = *rulenum;
862 	netisr_domsg(nmsg, 0);
863 	return 0;
864 }
865 
866 /*
867  * Clear counters for a specific rule.
868  */
869 void
870 ip_fw3_clear_counters(struct ip_fw *rule)
871 {
872 	rule->bcnt = rule->pcnt = 0;
873 	rule->timestamp = 0;
874 }
875 
876 void
877 ip_fw3_zero_entry_dispatch(netmsg_t nmsg)
878 {
879 	struct netmsg_zent *zmsg = (struct netmsg_zent *)nmsg;
880 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
881 	struct ip_fw *rule;
882 
883 	if (zmsg->rulenum == 0) {
884 		for (rule = ctx->rules; rule; rule = rule->next) {
885 			ip_fw3_clear_counters(rule);
886 		}
887 	} else {
888 		for (rule = ctx->rules; rule; rule = rule->next) {
889 			if (rule->rulenum == zmsg->rulenum) {
890 				ip_fw3_clear_counters(rule);
891 			}
892 		}
893 	}
894 	ip_fw3_clear_counters(ctx->default_rule);
895 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);
896 }
897 
898 /**
899  * Reset some or all counters on firewall rules.
900  * @arg frwl is null to clear all entries, or contains a specific
901  * rule number.
902  * @arg log_only is 1 if we only want to reset logs, zero otherwise.
903  */
904 int
905 ip_fw3_ctl_zero_entry(int rulenum, int log_only)
906 {
907 	struct netmsg_zent zmsg;
908 	struct netmsg_base *nmsg;
909 	const char *msg;
910 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
911 
912 	bzero(&zmsg, sizeof(zmsg));
913 	nmsg = &zmsg.base;
914 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
915 			0, ip_fw3_zero_entry_dispatch);
916 	zmsg.log_only = log_only;
917 
918 	if (rulenum == 0) {
919 		msg = log_only ? "ipfw: All logging counts reset.\n"
920 				   : "ipfw: Accounting cleared.\n";
921 	} else {
922 		struct ip_fw *rule;
923 
924 		/*
925 		 * Locate the first rule with 'rulenum'
926 		 */
927 		for (rule = ctx->rules; rule; rule = rule->next) {
928 			if (rule->rulenum == rulenum)
929 				break;
930 		}
931 		if (rule == NULL) /* we did not find any matching rules */
932 			return (EINVAL);
933 		zmsg.start_rule = rule;
934 		zmsg.rulenum = rulenum;
935 
936 		msg = log_only ? "ipfw: Entry %d logging count reset.\n"
937 				   : "ipfw: Entry %d cleared.\n";
938 	}
939 	netisr_domsg(nmsg, 0);
940 	KKASSERT(zmsg.start_rule == NULL);
941 
942 	if (sysctl_var_fw3_verbose)
943 		log(LOG_SECURITY | LOG_NOTICE, msg, rulenum);
944 	return (0);
945 }
946 
947 /*
948  * Get the ioc_rule from the sopt
949  * call ip_fw3_add_rule to add the rule
950  */
951 int
952 ip_fw3_ctl_add_rule(struct sockopt *sopt)
953 {
954 	struct ipfw_ioc_rule *ioc_rule;
955 	size_t size;
956 
957 	size = sopt->sopt_valsize;
958 	if (size > (sizeof(uint32_t) * IPFW_RULE_SIZE_MAX) ||
959 			size < sizeof(*ioc_rule)) {
960 		return EINVAL;
961 	}
962 	if (size != (sizeof(uint32_t) * IPFW_RULE_SIZE_MAX)) {
963 		sopt->sopt_val = krealloc(sopt->sopt_val, sizeof(uint32_t) *
964 				IPFW_RULE_SIZE_MAX, M_TEMP, M_WAITOK);
965 	}
966 	ioc_rule = sopt->sopt_val;
967 
968 	ip_fw3_add_rule(ioc_rule);
969 	return 0;
970 }
971 
972 int
973 ip_fw3_ctl_get_modules(struct sockopt *sopt)
974 {
975 	int i;
976 	struct ipfw3_module *mod;
977 	char module_str[1024];
978 	memset(module_str,0,1024);
979 	for (i = 0, mod = fw3_modules; i < MAX_MODULE; i++, mod++) {
980 		if (mod->type != 0) {
981 			if (i > 0)
982 				strcat(module_str,",");
983 			strcat(module_str,mod->name);
984 		}
985 	}
986 	bzero(sopt->sopt_val, sopt->sopt_valsize);
987 	bcopy(module_str, sopt->sopt_val, strlen(module_str));
988 	sopt->sopt_valsize = strlen(module_str);
989 	return 0;
990 }
991 
992 /*
993  * Copy all static rules and states on all CPU
994  */
995 int
996 ip_fw3_ctl_get_rules(struct sockopt *sopt)
997 {
998 	struct ipfw3_context *ctx = fw3_ctx[mycpuid];
999 	struct ip_fw *rule;
1000 	struct ipfw_ioc_rule *ioc;
1001 	const struct ip_fw *sibling;
1002 	int total_len = 0;
1003 
1004 	ioc = (struct ipfw_ioc_rule *)sopt->sopt_val;
1005 
1006 	for (rule = ctx->rules; rule; rule = rule->next) {
1007 		total_len += IOC_RULESIZE(rule);
1008 		if (total_len > sopt->sopt_valsize) {
1009 			bzero(sopt->sopt_val, sopt->sopt_valsize);
1010 			return 0;
1011 		}
1012 		ioc->act_ofs = rule->act_ofs;
1013 		ioc->cmd_len = rule->cmd_len;
1014 		ioc->rulenum = rule->rulenum;
1015 		ioc->set = rule->set;
1016 
1017 		ioc->sets = fw3_ctx[mycpuid]->sets;
1018 		ioc->pcnt = 0;
1019 		ioc->bcnt = 0;
1020 		ioc->timestamp = 0;
1021 		for (sibling = rule; sibling != NULL; sibling = sibling->sibling) {
1022 			ioc->pcnt += sibling->pcnt;
1023 			ioc->bcnt += sibling->bcnt;
1024 			if (sibling->timestamp > ioc->timestamp)
1025 				ioc->timestamp = sibling->timestamp;
1026 		}
1027 		bcopy(rule->cmd, ioc->cmd, ioc->cmd_len * 4);
1028 		ioc = (struct ipfw_ioc_rule *)((uint8_t *)ioc + IOC_RULESIZE(ioc));
1029 	}
1030 	sopt->sopt_valsize = total_len;
1031 	return 0;
1032 }
1033 
1034 
1035 /*
1036  * ip_fw3_ctl_x - extended version of ip_fw3_ctl
1037  * remove the x_header, and adjust the sopt_name,sopt_val and sopt_valsize.
1038  */
1039 int
1040 ip_fw3_ctl_x(struct sockopt *sopt)
1041 {
1042 	ip_fw_x_header *x_header;
1043 	x_header = (ip_fw_x_header *)(sopt->sopt_val);
1044 	sopt->sopt_name = x_header->opcode;
1045 	sopt->sopt_valsize -= sizeof(ip_fw_x_header);
1046 	bcopy(++x_header, sopt->sopt_val, sopt->sopt_valsize);
1047 	return ip_fw3_ctl(sopt);
1048 }
1049 
1050 
1051 /**
1052  * {set|get}sockopt parser.
1053  */
1054 int
1055 ip_fw3_ctl(struct sockopt *sopt)
1056 {
1057 	int error = 0;
1058 	switch (sopt->sopt_name) {
1059 		case IP_FW_X:
1060 			ip_fw3_ctl_x(sopt);
1061 			break;
1062 		case IP_FW_GET:
1063 		case IP_FW_MODULE:
1064 		case IP_FW_FLUSH:
1065 		case IP_FW_ADD:
1066 		case IP_FW_DEL:
1067 		case IP_FW_ZERO:
1068 		case IP_FW_RESETLOG:
1069 			error = ip_fw3_ctl_sockopt(sopt);
1070 			break;
1071 		case IP_FW_SET_GET:
1072 		case IP_FW_SET_MOVE_RULE:
1073 		case IP_FW_SET_MOVE_SET:
1074 		case IP_FW_SET_SWAP:
1075 		case IP_FW_SET_TOGGLE:
1076 			error = ip_fw3_ctl_set_sockopt(sopt);
1077 			break;
1078 		case IP_FW_NAT_ADD:
1079 		case IP_FW_NAT_DEL:
1080 		case IP_FW_NAT_FLUSH:
1081 		case IP_FW_NAT_GET:
1082 		case IP_FW_NAT_GET_RECORD:
1083 			if (ip_fw3_ctl_nat_ptr != NULL) {
1084 				error = ip_fw3_ctl_nat_ptr(sopt);
1085 			}
1086 			break;
1087 		case IP_DUMMYNET_GET:
1088 		case IP_DUMMYNET_CONFIGURE:
1089 		case IP_DUMMYNET_DEL:
1090 		case IP_DUMMYNET_FLUSH:
1091 			error = ip_dn_sockopt(sopt);
1092 			break;
1093 		case IP_FW_STATE_ADD:
1094 		case IP_FW_STATE_DEL:
1095 		case IP_FW_STATE_FLUSH:
1096 		case IP_FW_STATE_GET:
1097 			if (ip_fw3_ctl_state_ptr != NULL) {
1098 				error = ip_fw3_ctl_state_ptr(sopt);
1099 			}
1100 			break;
1101 		case IP_FW_TABLE_CREATE:
1102 		case IP_FW_TABLE_DELETE:
1103 		case IP_FW_TABLE_APPEND:
1104 		case IP_FW_TABLE_REMOVE:
1105 		case IP_FW_TABLE_LIST:
1106 		case IP_FW_TABLE_FLUSH:
1107 		case IP_FW_TABLE_SHOW:
1108 		case IP_FW_TABLE_TEST:
1109 		case IP_FW_TABLE_RENAME:
1110 			if (ip_fw3_ctl_table_ptr != NULL) {
1111 				error = ip_fw3_ctl_table_ptr(sopt);
1112 			}
1113 			break;
1114 		case IP_FW_SYNC_SHOW_CONF:
1115 		case IP_FW_SYNC_SHOW_STATUS:
1116 		case IP_FW_SYNC_EDGE_CONF:
1117 		case IP_FW_SYNC_EDGE_START:
1118 		case IP_FW_SYNC_EDGE_STOP:
1119 		case IP_FW_SYNC_EDGE_TEST:
1120 		case IP_FW_SYNC_EDGE_CLEAR:
1121 		case IP_FW_SYNC_CENTRE_CONF:
1122 		case IP_FW_SYNC_CENTRE_START:
1123 		case IP_FW_SYNC_CENTRE_STOP:
1124 		case IP_FW_SYNC_CENTRE_TEST:
1125 		case IP_FW_SYNC_CENTRE_CLEAR:
1126 			if (ip_fw3_ctl_sync_ptr != NULL) {
1127 				error = ip_fw3_ctl_sync_ptr(sopt);
1128 			}
1129 			break;
1130 		default:
1131 			kprintf("ip_fw3_ctl invalid option %d\n",
1132 				sopt->sopt_name);
1133 			error = EINVAL;
1134 	}
1135 	return error;
1136 }
1137 
1138 int
1139 ip_fw3_ctl_sockopt(struct sockopt *sopt)
1140 {
1141 	int error = 0, rulenum;
1142 
1143 	switch (sopt->sopt_name) {
1144 		case IP_FW_GET:
1145 			error = ip_fw3_ctl_get_rules(sopt);
1146 			break;
1147 		case IP_FW_MODULE:
1148 			error = ip_fw3_ctl_get_modules(sopt);
1149 			break;
1150 		case IP_FW_FLUSH:
1151 			ip_fw3_ctl_flush_rule(0);
1152 			break;
1153 		case IP_FW_ADD:
1154 			error = ip_fw3_ctl_add_rule(sopt);
1155 			break;
1156 		case IP_FW_DEL:
1157 			error = ip_fw3_ctl_delete_rule(sopt);
1158 			break;
1159 		case IP_FW_ZERO:
1160 		case IP_FW_RESETLOG: /* argument is an int, the rule number */
1161 			rulenum = 0;
1162 			if (sopt->sopt_valsize != 0) {
1163 				error = soopt_to_kbuf(sopt, &rulenum,
1164 						sizeof(int), sizeof(int));
1165 				if (error) {
1166 					break;
1167 				}
1168 			}
1169 			error = ip_fw3_ctl_zero_entry(rulenum,
1170 					sopt->sopt_name == IP_FW_RESETLOG);
1171 			break;
1172 		default:
1173 			kprintf("ip_fw3_ctl invalid option %d\n",
1174 				sopt->sopt_name);
1175 			error = EINVAL;
1176 	}
1177 	return error;
1178 }
1179 
1180 int
1181 ip_fw3_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
1182 {
1183 	struct ip_fw_args args;
1184 	struct mbuf *m = *m0;
1185 	struct m_tag *mtag;
1186 	int tee = 0, error = 0, ret;
1187 	// again:
1188 	if (m->m_pkthdr.fw_flags & DUMMYNET_MBUF_TAGGED) {
1189 		/* Extract info from dummynet tag */
1190 		mtag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
1191 		KKASSERT(mtag != NULL);
1192 		args.rule = ((struct dn_pkt *)m_tag_data(mtag))->dn_priv;
1193 		KKASSERT(args.rule != NULL);
1194 
1195 		m_tag_delete(m, mtag);
1196 		m->m_pkthdr.fw_flags &= ~DUMMYNET_MBUF_TAGGED;
1197 	} else {
1198 		args.rule = NULL;
1199 	}
1200 
1201 	args.eh = NULL;
1202 	args.oif = NULL;
1203 	args.m = m;
1204 	ret = ip_fw3_chk(&args);
1205 	m = args.m;
1206 
1207 	if (m == NULL) {
1208 		error = EACCES;
1209 		goto back;
1210 	}
1211 	switch (ret) {
1212 		case IP_FW_PASS:
1213 			break;
1214 
1215 		case IP_FW_DENY:
1216 			m_freem(m);
1217 			m = NULL;
1218 			error = EACCES;
1219 			break;
1220 
1221 		case IP_FW_DUMMYNET:
1222 			/* Send packet to the appropriate pipe */
1223 			m = ip_fw3_dummynet_io(m, args.cookie, DN_TO_IP_IN,
1224 			    &args);
1225 			break;
1226 		case IP_FW_TEE:
1227 			tee = 1;
1228 			/* FALL THROUGH */
1229 		case IP_FW_DIVERT:
1230 			/*
1231 			 * Must clear bridge tag when changing
1232 			 */
1233 			m->m_pkthdr.fw_flags &= ~BRIDGE_MBUF_TAGGED;
1234 			if (ip_divert_p != NULL) {
1235 				m = ip_divert_p(m, tee, 1);
1236 			} else {
1237 				m_freem(m);
1238 				m = NULL;
1239 				/* not sure this is the right error msg */
1240 				error = EACCES;
1241 			}
1242 			break;
1243 		case IP_FW_NAT:
1244 			break;
1245 		case IP_FW_ROUTE:
1246 			break;
1247 		default:
1248 			panic("unknown ipfw3 return value: %d", ret);
1249 	}
1250 back:
1251 	*m0 = m;
1252 	return error;
1253 }
1254 
1255 int
1256 ip_fw3_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
1257 {
1258 	struct ip_fw_args args;
1259 	struct mbuf *m = *m0;
1260 	struct m_tag *mtag;
1261 	int tee = 0, error = 0, ret;
1262 	// again:
1263 	if (m->m_pkthdr.fw_flags & DUMMYNET_MBUF_TAGGED) {
1264 		/* Extract info from dummynet tag */
1265 		mtag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
1266 		KKASSERT(mtag != NULL);
1267 		args.rule = ((struct dn_pkt *)m_tag_data(mtag))->dn_priv;
1268 		KKASSERT(args.rule != NULL);
1269 
1270 		m_tag_delete(m, mtag);
1271 		m->m_pkthdr.fw_flags &= ~DUMMYNET_MBUF_TAGGED;
1272 	} else {
1273 		args.rule = NULL;
1274 	}
1275 
1276 	args.eh = NULL;
1277 	args.m = m;
1278 	args.oif = ifp;
1279 	ret = ip_fw3_chk(&args);
1280 	m = args.m;
1281 
1282 	if (m == NULL) {
1283 		error = EACCES;
1284 		goto back;
1285 	}
1286 
1287 	switch (ret) {
1288 		case IP_FW_PASS:
1289 			break;
1290 
1291 		case IP_FW_DENY:
1292 			m_freem(m);
1293 			m = NULL;
1294 			error = EACCES;
1295 			break;
1296 
1297 		case IP_FW_DUMMYNET:
1298 			m = ip_fw3_dummynet_io(m, args.cookie, DN_TO_IP_OUT,
1299 			    &args);
1300 			break;
1301 
1302 		case IP_FW_TEE:
1303 			tee = 1;
1304 			/* FALL THROUGH */
1305 
1306 		case IP_FW_DIVERT:
1307 			if (ip_divert_p != NULL) {
1308 				m = ip_divert_p(m, tee, 0);
1309 			} else {
1310 				m_freem(m);
1311 				m = NULL;
1312 				/* not sure this is the right error msg */
1313 				error = EACCES;
1314 			}
1315 			break;
1316 
1317 		case IP_FW_NAT:
1318 			break;
1319 		case IP_FW_ROUTE:
1320 			break;
1321 		default:
1322 			panic("unknown ipfw3 return value: %d", ret);
1323 	}
1324 back:
1325 	*m0 = m;
1326 	return error;
1327 }
1328 
1329 void
1330 ip_fw3_hook(void)
1331 {
1332 	struct pfil_head *pfh;
1333 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
1334 
1335 	pfh = pfil_head_get(PFIL_TYPE_AF, AF_INET);
1336 	if (pfh == NULL)
1337 		return;
1338 
1339 	pfil_add_hook(ip_fw3_check_in, NULL, PFIL_IN, pfh);
1340 	pfil_add_hook(ip_fw3_check_out, NULL, PFIL_OUT, pfh);
1341 }
1342 
1343 void
1344 ip_fw3_dehook(void)
1345 {
1346 	struct pfil_head *pfh;
1347 
1348 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
1349 
1350 	pfh = pfil_head_get(PFIL_TYPE_AF, AF_INET);
1351 	if (pfh == NULL)
1352 		return;
1353 
1354 	pfil_remove_hook(ip_fw3_check_in, NULL, PFIL_IN, pfh);
1355 	pfil_remove_hook(ip_fw3_check_out, NULL, PFIL_OUT, pfh);
1356 }
1357 
1358 void
1359 ip_fw3_sysctl_enable_dispatch(netmsg_t nmsg)
1360 {
1361 	struct lwkt_msg *lmsg = &nmsg->lmsg;
1362 	int enable = lmsg->u.ms_result;
1363 
1364 	if (sysctl_var_fw3_enable == enable)
1365 		goto reply;
1366 
1367 	sysctl_var_fw3_enable = enable;
1368 	if (sysctl_var_fw3_enable)
1369 		ip_fw3_hook();
1370 	else
1371 		ip_fw3_dehook();
1372 
1373 reply:
1374 	lwkt_replymsg(lmsg, 0);
1375 }
1376 
1377 int
1378 ip_fw3_sysctl_enable(SYSCTL_HANDLER_ARGS)
1379 {
1380 	struct netmsg_base nmsg;
1381 	struct lwkt_msg *lmsg;
1382 	int enable, error;
1383 
1384 	enable = sysctl_var_fw3_enable;
1385 	error = sysctl_handle_int(oidp, &enable, 0, req);
1386 	if (error || req->newptr == NULL)
1387 		return error;
1388 
1389 	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
1390 			0, ip_fw3_sysctl_enable_dispatch);
1391 	lmsg = &nmsg.lmsg;
1392 	lmsg->u.ms_result = enable;
1393 
1394 	return lwkt_domsg(IPFW_CFGPORT, lmsg, 0);
1395 }
1396 
1397 int
1398 ip_fw3_sysctl_autoinc_step(SYSCTL_HANDLER_ARGS)
1399 {
1400 	return sysctl_int_range(oidp, arg1, arg2, req,
1401 			IPFW_AUTOINC_STEP_MIN, IPFW_AUTOINC_STEP_MAX);
1402 }
1403 
1404 void
1405 ctx_init_dispatch(netmsg_t nmsg)
1406 {
1407 	struct netmsg_ipfw *fwmsg = (struct netmsg_ipfw *)nmsg;
1408 	struct ipfw3_context *ctx;
1409 	struct ip_fw *def_rule;
1410 
1411 	ctx = kmalloc(LEN_FW3_CTX, M_IPFW3, M_WAITOK | M_ZERO);
1412 	fw3_ctx[mycpuid] = ctx;
1413 	ctx->sets = IPFW_ALL_SETS;
1414 
1415 	def_rule = kmalloc(LEN_FW3, M_IPFW3, M_WAITOK | M_ZERO);
1416 	def_rule->act_ofs = 0;
1417 	def_rule->rulenum = IPFW_DEFAULT_RULE;
1418 	def_rule->cmd_len = 2;
1419 	def_rule->set = IPFW_DEFAULT_SET;
1420 
1421 	def_rule->cmd[0].len = LEN_OF_IPFWINSN;
1422 	def_rule->cmd[0].module = MODULE_BASIC_ID;
1423 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
1424 	def_rule->cmd[0].opcode = O_BASIC_ACCEPT;
1425 #else
1426 	if (filters_default_to_accept)
1427 		def_rule->cmd[0].opcode = O_BASIC_ACCEPT;
1428 	else
1429 		def_rule->cmd[0].opcode = O_BASIC_DENY;
1430 #endif
1431 
1432 	/* Install the default rule */
1433 	ctx->default_rule = def_rule;
1434 	ctx->rules = def_rule;
1435 
1436 	/*
1437 	 * if sibiling in last CPU is exists,
1438 	 * then it's sibling should be current rule
1439 	 */
1440 	if (fwmsg->sibling != NULL) {
1441 		fwmsg->sibling->sibling = def_rule;
1442 	}
1443 	/* prepare for next CPU */
1444 	fwmsg->sibling = def_rule;
1445 
1446 	netisr_forwardmsg_all(&nmsg->base, mycpuid + 1);
1447 }
1448 
1449 void
1450 init_dispatch(netmsg_t nmsg)
1451 {
1452 	struct netmsg_ipfw fwmsg;
1453 	int error = 0;
1454 	if (IPFW3_LOADED) {
1455 		kprintf("ipfw3 already loaded\n");
1456 		error = EEXIST;
1457 		goto reply;
1458 	}
1459 
1460 	bzero(&fwmsg, sizeof(fwmsg));
1461 	netmsg_init(&fwmsg.base, NULL, &curthread->td_msgport,
1462 			0, ctx_init_dispatch);
1463 	netisr_domsg(&fwmsg.base, 0);
1464 
1465 	ip_fw_chk_ptr = ip_fw3_chk;
1466 	ip_fw_ctl_x_ptr = ip_fw3_ctl_x;
1467 	ip_fw_dn_io_ptr = ip_fw3_dummynet_io;
1468 
1469 	kprintf("ipfw3 initialized, default to %s\n",
1470 			filters_default_to_accept ? "accept" : "deny");
1471 
1472 	ip_fw3_loaded = 1;
1473 	if (sysctl_var_fw3_enable)
1474 		ip_fw3_hook();
1475 reply:
1476 	lwkt_replymsg(&nmsg->lmsg, error);
1477 }
1478 
1479 int
1480 ip_fw3_init(void)
1481 {
1482 	struct netmsg_base smsg;
1483 	int error;
1484 
1485 	init_module();
1486 	netmsg_init(&smsg, NULL, &curthread->td_msgport,
1487 			0, init_dispatch);
1488 	error = lwkt_domsg(IPFW_CFGPORT, &smsg.lmsg, 0);
1489 	return error;
1490 }
1491 
1492 #ifdef KLD_MODULE
1493 
1494 void
1495 fini_dispatch(netmsg_t nmsg)
1496 {
1497 	int error = 0, cpu;
1498 
1499 	ip_fw3_loaded = 0;
1500 
1501 	ip_fw3_dehook();
1502 	netmsg_service_sync();
1503 	ip_fw_chk_ptr = NULL;
1504 	ip_fw_ctl_x_ptr = NULL;
1505 	ip_fw_dn_io_ptr = NULL;
1506 	ip_fw3_ctl_flush_rule(1);
1507 	/* Free pre-cpu context */
1508 	for (cpu = 0; cpu < ncpus; ++cpu) {
1509 		if (fw3_ctx[cpu] != NULL) {
1510 			kfree(fw3_ctx[cpu], M_IPFW3);
1511 			fw3_ctx[cpu] = NULL;
1512 		}
1513 	}
1514 	kprintf("ipfw3 unloaded\n");
1515 
1516 	lwkt_replymsg(&nmsg->lmsg, error);
1517 }
1518 
1519 int
1520 ip_fw3_fini(void)
1521 {
1522 	struct netmsg_base smsg;
1523 
1524 	netmsg_init(&smsg, NULL, &curthread->td_msgport,
1525 			0, fini_dispatch);
1526 	return lwkt_domsg(IPFW_CFGPORT, &smsg.lmsg, 0);
1527 }
1528 
1529 #endif	/* KLD_MODULE */
1530 
1531 static int
1532 ip_fw3_modevent(module_t mod, int type, void *unused)
1533 {
1534 	int err = 0;
1535 
1536 	switch (type) {
1537 		case MOD_LOAD:
1538 			err = ip_fw3_init();
1539 			break;
1540 
1541 		case MOD_UNLOAD:
1542 
1543 #ifndef KLD_MODULE
1544 			kprintf("ipfw3 statically compiled, cannot unload\n");
1545 			err = EBUSY;
1546 #else
1547 			err = ip_fw3_fini();
1548 #endif
1549 			break;
1550 		default:
1551 			break;
1552 	}
1553 	return err;
1554 }
1555 
1556 static moduledata_t ipfw3mod = {
1557 	"ipfw3",
1558 	ip_fw3_modevent,
1559 	0
1560 };
1561 /* ipfw3 must init before ipfw3_basic */
1562 DECLARE_MODULE(ipfw3, ipfw3mod, SI_SUB_PROTO_END, SI_ORDER_FIRST);
1563 MODULE_VERSION(ipfw3, 1);
1564