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