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