xref: /dragonfly/sys/net/ipfw3/ip_fw3.c (revision 7e82238e)
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) 2015 The DragonFly Project.  All rights reserved.
6  *
7  * This code is derived from software contributed to The DragonFly Project
8  * by Bill Yuan <bycn82@gmail.com>
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/systm.h>
47 #include <sys/malloc.h>
48 #include <sys/mbuf.h>
49 #include <sys/kernel.h>
50 #include <sys/proc.h>
51 #include <sys/socket.h>
52 #include <sys/socketvar.h>
53 #include <sys/sysctl.h>
54 #include <sys/syslog.h>
55 #include <sys/ucred.h>
56 #include <sys/in_cksum.h>
57 #include <sys/lock.h>
58 #include <sys/thread2.h>
59 #include <sys/mplock2.h>
60 
61 #include <netinet/in.h>
62 #include <netinet/in_systm.h>
63 #include <netinet/in_var.h>
64 #include <netinet/in_pcb.h>
65 #include <netinet/ip.h>
66 #include <netinet/ip_var.h>
67 #include <netinet/ip_icmp.h>
68 #include <netinet/tcp.h>
69 #include <netinet/tcp_timer.h>
70 #include <netinet/tcp_var.h>
71 #include <netinet/tcpip.h>
72 #include <netinet/udp.h>
73 #include <netinet/udp_var.h>
74 #include <netinet/ip_divert.h>
75 #include <netinet/if_ether.h>
76 
77 #include <net/if.h>
78 #include <net/radix.h>
79 #include <net/route.h>
80 #include <net/pfil.h>
81 #include <net/netmsg2.h>
82 
83 #include <net/ipfw3/ip_fw.h>
84 #include <net/ipfw3/ip_fw3_table.h>
85 #include <net/ipfw3_basic/ip_fw3_basic.h>
86 #include <net/ipfw3_nat/ip_fw3_nat.h>
87 #include <net/dummynet3/ip_dummynet3.h>
88 
89 MALLOC_DEFINE(M_IPFW3, "IPFW3", "ip_fw3 default module");
90 
91 #ifdef IPFIREWALL_DEBUG
92 #define DPRINTF(fmt, ...)			\
93 do { 						\
94 	if (fw_debug > 0) 			\
95 		kprintf(fmt, __VA_ARGS__); 	\
96 } while (0)
97 #else
98 #define DPRINTF(fmt, ...)	((void)0)
99 #endif
100 
101 #define MAX_MODULE		10
102 #define MAX_OPCODE_PER_MODULE	100
103 
104 #define IPFW_AUTOINC_STEP_MIN	1
105 #define IPFW_AUTOINC_STEP_MAX	1000
106 #define IPFW_AUTOINC_STEP_DEF	100
107 
108 
109 struct netmsg_ipfw {
110 	struct netmsg_base base;
111 	const struct ipfw_ioc_rule *ioc_rule;
112 	struct ip_fw	*rule;
113 	struct ip_fw	*next_rule;
114 	struct ip_fw	*prev_rule;
115 	struct ip_fw	*sibling;	/* sibling in prevous CPU */
116 };
117 
118 struct netmsg_del {
119 	struct netmsg_base base;
120 	struct ip_fw	*rule;
121 	struct ip_fw	*start_rule;
122 	struct ip_fw	*prev_rule;
123 	struct ipfw_ioc_state *ioc_state;
124 	uint16_t	rulenum;
125 	uint8_t		from_set;
126 	uint8_t		to_set;
127 };
128 
129 struct netmsg_zent {
130 	struct netmsg_base base;
131 	struct ip_fw	*start_rule;
132 	uint16_t	rulenum;
133 	uint16_t	log_only;
134 };
135 
136 ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
137 ipfw_nat_cfg_t *ipfw_nat_del_ptr;
138 ipfw_nat_cfg_t *ipfw_nat_flush_ptr;
139 ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
140 ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
141 
142 /* handlers which implemented in ipfw_basic module */
143 ipfw_basic_delete_state_t *ipfw_basic_flush_state_prt = NULL;
144 ipfw_basic_append_state_t *ipfw_basic_append_state_prt = NULL;
145 
146 static struct ipfw_nat_context *ipfw_nat_ctx;
147 
148 extern int ip_fw_loaded;
149 static uint32_t static_count;	/* # of static rules */
150 static uint32_t static_ioc_len;	/* bytes of static rules */
151 static int ipfw_flushing;
152 static int fw_verbose;
153 static int verbose_limit;
154 static int fw_debug;
155 static int autoinc_step = IPFW_AUTOINC_STEP_DEF;
156 
157 static int	ipfw_sysctl_enable(SYSCTL_HANDLER_ARGS);
158 static int	ipfw_sysctl_autoinc_step(SYSCTL_HANDLER_ARGS);
159 
160 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw3, CTLFLAG_RW, 0, "Firewall");
161 SYSCTL_PROC(_net_inet_ip_fw3, OID_AUTO, enable, CTLTYPE_INT | CTLFLAG_RW,
162 	&fw3_enable, 0, ipfw_sysctl_enable, "I", "Enable ipfw");
163 SYSCTL_PROC(_net_inet_ip_fw3, OID_AUTO, autoinc_step, CTLTYPE_INT | CTLFLAG_RW,
164 	&autoinc_step, 0, ipfw_sysctl_autoinc_step, "I",
165 	"Rule number autincrement step");
166 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO,one_pass,CTLFLAG_RW,
167 	&fw3_one_pass, 0,
168 	"Only do a single pass through ipfw when using dummynet(4)");
169 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO, debug, CTLFLAG_RW,
170 	&fw_debug, 0, "Enable printing of debug ip_fw statements");
171 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO, verbose, CTLFLAG_RW,
172 	&fw_verbose, 0, "Log matches to ipfw rules");
173 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO, verbose_limit, CTLFLAG_RW,
174 	&verbose_limit, 0, "Set upper limit of matches of ipfw rules logged");
175 SYSCTL_INT(_net_inet_ip_fw3, OID_AUTO, static_count, CTLFLAG_RD,
176 	&static_count, 0, "Number of static rules");
177 
178 filter_func filter_funcs[MAX_MODULE][MAX_OPCODE_PER_MODULE];
179 struct ipfw_module ipfw_modules[MAX_MODULE];
180 struct ipfw_context *ipfw_ctx[MAXCPU];
181 static int ipfw_ctl(struct sockopt *sopt);
182 
183 
184 void
185 check_accept(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args,
186 		struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len);
187 void
188 check_deny(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args,
189 		struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len);
190 void init_module(void);
191 
192 
193 void
194 register_ipfw_module(int module_id,char *module_name)
195 {
196 	struct ipfw_module *tmp;
197 	int i;
198 
199 	tmp = ipfw_modules;
200 	for (i=0; i < MAX_MODULE; i++) {
201 		if (tmp->type == 0) {
202 			tmp->type = 1;
203 			tmp->id = module_id;
204 			strncpy(tmp->name, module_name, strlen(module_name));
205 			break;
206 		}
207 		tmp++;
208 	}
209 	kprintf("ipfw3 module %s loaded ", module_name);
210 }
211 
212 int
213 unregister_ipfw_module(int module_id)
214 {
215 	struct ipfw_module *tmp;
216 	struct ip_fw *fw;
217 	ipfw_insn *cmd;
218 	int i, len, cmdlen, found;
219 
220 	found = 0;
221 	tmp = ipfw_modules;
222 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
223 	fw = ctx->ipfw_rule_chain;
224 	for (; fw; fw = fw->next) {
225 		for (len = fw->cmd_len, cmd = fw->cmd; len > 0;
226 			len -= cmdlen,
227 			cmd = (ipfw_insn *)((uint32_t *)cmd + cmdlen)) {
228 			cmdlen = F_LEN(cmd);
229 			if (cmd->module == 0 &&
230 				(cmd->opcode == 0 || cmd->opcode == 1)) {
231 				//action accept or deny
232 			} else if (cmd->module == module_id) {
233 				found = 1;
234 				goto decide;
235 			}
236 		}
237 	}
238 decide:
239 	if (found) {
240 		return 1;
241 	} else {
242 		for (i = 0; i < MAX_MODULE; i++) {
243 			if (tmp->type == 1 && tmp->id == module_id) {
244 				tmp->type = 0;
245 				kprintf("ipfw3 module %s unloaded ", tmp->name);
246 				break;
247 			}
248 			tmp++;
249 		}
250 
251 		for (i = 0; i < MAX_OPCODE_PER_MODULE; i++) {
252 			if (module_id == 0) {
253 				if (i ==0 || i == 1) {
254 					continue;
255 				}
256 			}
257 			filter_funcs[module_id][i] = NULL;
258 		}
259 		return 0;
260 	}
261 }
262 
263 void
264 register_ipfw_filter_funcs(int module, int opcode, filter_func func)
265 {
266 	filter_funcs[module][opcode] = func;
267 }
268 
269 void
270 check_accept(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args,
271 		struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len)
272 {
273 	*cmd_val = IP_FW_PASS;
274 	*cmd_ctl = IP_FW_CTL_DONE;
275 }
276 
277 void
278 check_deny(int *cmd_ctl, int *cmd_val, struct ip_fw_args **args,
279 		struct ip_fw **f, ipfw_insn *cmd, uint16_t ip_len)
280 {
281 	*cmd_val = IP_FW_DENY;
282 	*cmd_ctl = IP_FW_CTL_DONE;
283 }
284 
285 void
286 init_module(void)
287 {
288 	memset(ipfw_modules, 0, sizeof(struct ipfw_module) * MAX_MODULE);
289 	memset(filter_funcs, 0, sizeof(filter_func) *
290 			MAX_OPCODE_PER_MODULE * MAX_MODULE);
291 	register_ipfw_filter_funcs(0, O_BASIC_ACCEPT,
292 			(filter_func)check_accept);
293 	register_ipfw_filter_funcs(0, O_BASIC_DENY, (filter_func)check_deny);
294 }
295 
296 static __inline int
297 ipfw_free_rule(struct ip_fw *rule)
298 {
299 	kfree(rule, M_IPFW3);
300 	rule = NULL;
301 	return 1;
302 }
303 
304 static struct ip_fw *
305 lookup_next_rule(struct ip_fw *me)
306 {
307 	struct ip_fw *rule = NULL;
308 	ipfw_insn *cmd;
309 
310 	/* look for action, in case it is a skipto */
311 	cmd = ACTION_PTR(me);
312 	if ((int)cmd->module == MODULE_BASIC_ID &&
313 		(int)cmd->opcode == O_BASIC_SKIPTO) {
314 		for (rule = me->next; rule; rule = rule->next) {
315 			if (rule->rulenum >= cmd->arg1)
316 				break;
317 		}
318 	}
319 	if (rule == NULL) {	/* failure or not a skipto */
320 		rule = me->next;
321 	}
322 	me->next_rule = rule;
323 	return rule;
324 }
325 
326 /*
327  * rules are stored in ctx->ipfw_rule_chain.
328  * and each rule is combination of multiple cmds.(ipfw_insn)
329  * in each rule, it begin with filter cmds. and end with action cmds.
330  * 'outer/inner loop' are looping the rules/cmds.
331  * it will invoke the cmds relatived function according to the cmd's
332  * module id and opcode id. and process according to return value.
333  */
334 static int
335 ipfw_chk(struct ip_fw_args *args)
336 {
337 	struct mbuf *m = args->m;
338 	struct ip *ip = mtod(m, struct ip *);
339 	struct ip_fw *f = NULL;		/* matching rule */
340 	int cmd_val = IP_FW_PASS;
341 	struct m_tag *mtag;
342 	struct divert_info *divinfo;
343 
344 	/*
345 	 * hlen	The length of the IPv4 header.
346 	 *	hlen >0 means we have an IPv4 packet.
347 	 */
348 	u_int hlen = 0;		/* hlen >0 means we have an IP pkt */
349 
350 	/*
351 	 * offset	The offset of a fragment. offset != 0 means that
352 	 *	we have a fragment at this offset of an IPv4 packet.
353 	 *	offset == 0 means that (if this is an IPv4 packet)
354 	 *	this is the first or only fragment.
355 	 */
356 	u_short offset = 0;
357 
358 	uint8_t proto;
359 	uint16_t src_port = 0, dst_port = 0;	/* NOTE: host format	*/
360 	struct in_addr src_ip, dst_ip;		/* NOTE: network format	*/
361 	uint16_t ip_len = 0;
362 	uint8_t prev_module = -1, prev_opcode = -1; /* previous module & opcode */
363 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
364 
365 	if (m->m_pkthdr.fw_flags & IPFW_MBUF_GENERATED)
366 		return IP_FW_PASS;	/* accept */
367 
368 	if (args->eh == NULL ||		/* layer 3 packet */
369 		(m->m_pkthdr.len >= sizeof(struct ip) &&
370 		 ntohs(args->eh->ether_type) == ETHERTYPE_IP))
371 		hlen = ip->ip_hl << 2;
372 
373 	/*
374 	 * Collect parameters into local variables for faster matching.
375 	 */
376 	if (hlen == 0) {	/* do not grab addresses for non-ip pkts */
377 		proto = args->f_id.proto = 0;	/* mark f_id invalid */
378 		goto after_ip_checks;
379 	}
380 
381 	proto = args->f_id.proto = ip->ip_p;
382 	src_ip = ip->ip_src;
383 	dst_ip = ip->ip_dst;
384 	if (args->eh != NULL) { /* layer 2 packets are as on the wire */
385 		offset = ntohs(ip->ip_off) & IP_OFFMASK;
386 		ip_len = ntohs(ip->ip_len);
387 	} else {
388 		offset = ip->ip_off & IP_OFFMASK;
389 		ip_len = ip->ip_len;
390 	}
391 
392 #define PULLUP_TO(len)					\
393 do {							\
394 	if (m->m_len < (len)) {				\
395 		args->m = m = m_pullup(m, (len));	\
396 			if (m == NULL)			\
397 				goto pullup_failed;	\
398 		ip = mtod(m, struct ip *);		\
399 	}						\
400 } while (0)
401 
402 	if (offset == 0) {
403 		switch (proto) {
404 			case IPPROTO_TCP:
405 				{
406 					struct tcphdr *tcp;
407 
408 					PULLUP_TO(hlen + sizeof(struct tcphdr));
409 					tcp = L3HDR(struct tcphdr, ip);
410 					dst_port = tcp->th_dport;
411 					src_port = tcp->th_sport;
412 					args->f_id.flags = tcp->th_flags;
413 				}
414 				break;
415 
416 			case IPPROTO_UDP:
417 				{
418 					struct udphdr *udp;
419 
420 					PULLUP_TO(hlen + sizeof(struct udphdr));
421 					udp = L3HDR(struct udphdr, ip);
422 					dst_port = udp->uh_dport;
423 					src_port = udp->uh_sport;
424 				}
425 				break;
426 
427 			case IPPROTO_ICMP:
428 				PULLUP_TO(hlen + 4);
429 				args->f_id.flags =
430 					L3HDR(struct icmp, ip)->icmp_type;
431 				break;
432 
433 			default:
434 				break;
435 		}
436 	}
437 
438 #undef PULLUP_TO
439 
440 	args->f_id.src_ip = ntohl(src_ip.s_addr);
441 	args->f_id.dst_ip = ntohl(dst_ip.s_addr);
442 	args->f_id.src_port = src_port = ntohs(src_port);
443 	args->f_id.dst_port = dst_port = ntohs(dst_port);
444 
445 after_ip_checks:
446 	if (args->rule) {
447 		/*
448 		 * Packet has already been tagged. Look for the next rule
449 		 * to restart processing.
450 		 *
451 		 * If fw3_one_pass != 0 then just accept it.
452 		 * XXX should not happen here, but optimized out in
453 		 * the caller.
454 		 */
455 		if (fw3_one_pass)
456 			return IP_FW_PASS;
457 
458 		/* This rule is being/has been flushed */
459 		if (ipfw_flushing)
460 			return IP_FW_DENY;
461 
462 		f = args->rule->next_rule;
463 		if (f == NULL)
464 			f = lookup_next_rule(args->rule);
465 	} else {
466 		/*
467 		 * Find the starting rule. It can be either the first
468 		 * one, or the one after divert_rule if asked so.
469 		 */
470 		int skipto;
471 
472 		mtag = m_tag_find(m, PACKET_TAG_IPFW_DIVERT, NULL);
473 		if (mtag != NULL) {
474 			divinfo = m_tag_data(mtag);
475 			skipto = divinfo->skipto;
476 		} else {
477 			skipto = 0;
478 		}
479 
480 		f = ctx->ipfw_rule_chain;
481 		if (args->eh == NULL && skipto != 0) {
482 			/* No skipto during rule flushing */
483 			if (ipfw_flushing) {
484 				return IP_FW_DENY;
485 			}
486 			if (skipto >= IPFW_DEFAULT_RULE) {
487 				return IP_FW_DENY; /* invalid */
488 			}
489 			while (f && f->rulenum <= skipto) {
490 				f = f->next;
491 			}
492 			if (f == NULL) {	/* drop packet */
493 				return IP_FW_DENY;
494 			}
495 		} else if (ipfw_flushing) {
496 			/* Rules are being flushed; skip to default rule */
497 			f = ctx->ipfw_default_rule;
498 		}
499 	}
500 	if ((mtag = m_tag_find(m, PACKET_TAG_IPFW_DIVERT, NULL)) != NULL) {
501 		m_tag_delete(m, mtag);
502 	}
503 
504 	/*
505 	 * Now scan the rules, and parse microinstructions for each rule.
506 	 */
507 	int prev_val;	/*  previous result of 'or' filter */
508 	int l, cmdlen;
509 	ipfw_insn *cmd;
510 	int cmd_ctl;
511 	/* foreach rule in chain */
512 	for (; f; f = f->next) {
513 again:  /* check the rule again*/
514 		if (ctx->ipfw_set_disable & (1 << f->set)) {
515 			continue;
516 		}
517 
518 		prev_val = -1;
519 		 /* foreach cmd in rule */
520 		for (l = f->cmd_len, cmd = f->cmd; l > 0; l -= cmdlen,
521 			cmd = (ipfw_insn *)((uint32_t *)cmd+ cmdlen)) {
522 			cmdlen = F_LEN(cmd);
523 
524 			/* skip 'or' filter when already match */
525 			if (cmd->len & F_OR &&
526 				cmd->module == prev_module &&
527 				cmd->opcode == prev_opcode &&
528 				prev_val == 1) {
529 				goto next_cmd;
530 			}
531 
532 check_body: /* check the body of the rule again.*/
533 			(filter_funcs[cmd->module][cmd->opcode])
534 				(&cmd_ctl, &cmd_val, &args, &f, cmd, ip_len);
535 			switch(cmd_ctl) {
536 				case IP_FW_CTL_DONE:
537 					if (prev_val == 0) /* but 'or' failed */
538 						goto next_rule;
539 					goto done;
540 				case IP_FW_CTL_AGAIN:
541 					goto again;
542 				case IP_FW_CTL_NEXT:
543 					goto next_rule;
544 				case IP_FW_CTL_NAT:
545 					args->rule=f;
546 					goto done;
547 				case IP_FW_CTL_CHK_STATE:
548 					/* update the cmd and l */
549 					cmd = ACTION_PTR(f);
550 					l = f->cmd_len - f->act_ofs;
551 					goto check_body;
552 			}
553 			if (cmd->len & F_NOT)
554 				cmd_val= !cmd_val;
555 
556 			if (cmd->len & F_OR) {	/* has 'or' */
557 				if (!cmd_val) {	/* not matched */
558 					if(prev_val == -1){	/* first 'or' */
559 						prev_val = 0;
560 						prev_module = cmd->module;
561 						prev_opcode = cmd->opcode;
562 					} else if (prev_module == cmd->module &&
563 						prev_opcode == cmd->opcode) {
564 						/* continuous 'or' filter */
565 					} else if (prev_module != cmd->module ||
566 						prev_opcode != cmd->opcode) {
567 						/* 'or' filter changed */
568 						if(prev_val == 0){
569 							goto next_rule;
570 						} else {
571 							prev_val = 0;
572 							prev_module = cmd->module;
573 							prev_opcode = cmd->opcode;
574 						}
575 					}
576 				} else { /* has 'or' and matched */
577 					prev_val = 1;
578 					prev_module = cmd->module;
579 					prev_opcode = cmd->opcode;
580 				}
581 			} else { /* no or */
582 				if (!cmd_val) {	/* not matched */
583 					goto next_rule;
584 				} else {
585 					if (prev_val == 0) {
586 						/* previous 'or' not matched */
587 						goto next_rule;
588 					} else {
589 						prev_val = -1;
590 					}
591 				}
592 			}
593 next_cmd:;
594 		}	/* end of inner for, scan opcodes */
595 next_rule:;		/* try next rule		*/
596 	}		/* end of outer for, scan rules */
597 	kprintf("+++ ipfw: ouch!, skip past end of rules, denying packet\n");
598 	return IP_FW_DENY;
599 
600 done:
601 	/* Update statistics */
602 	f->pcnt++;
603 	f->bcnt += ip_len;
604 	f->timestamp = time_second;
605 	return cmd_val;
606 
607 pullup_failed:
608 	if (fw_verbose)
609 		kprintf("pullup failed\n");
610 	return IP_FW_DENY;
611 }
612 
613 static void
614 ipfw_dummynet_io(struct mbuf *m, int pipe_nr, int dir, struct ip_fw_args *fwa)
615 {
616 	struct m_tag *mtag;
617 	struct dn_pkt *pkt;
618 	ipfw_insn *cmd;
619 	const struct ipfw_flow_id *id;
620 	struct dn_flow_id *fid;
621 
622 	M_ASSERTPKTHDR(m);
623 
624 	mtag = m_tag_get(PACKET_TAG_DUMMYNET, sizeof(*pkt), M_NOWAIT);
625 	if (mtag == NULL) {
626 		m_freem(m);
627 		return;
628 	}
629 	m_tag_prepend(m, mtag);
630 
631 	pkt = m_tag_data(mtag);
632 	bzero(pkt, sizeof(*pkt));
633 
634 	cmd = (ipfw_insn *)((uint32_t *)fwa->rule->cmd + fwa->rule->act_ofs);
635 	KASSERT(cmd->opcode == O_DUMMYNET_PIPE ||
636 			cmd->opcode == O_DUMMYNET_QUEUE,
637 			("Rule is not PIPE or QUEUE, opcode %d", cmd->opcode));
638 
639 	pkt->dn_m = m;
640 	pkt->dn_flags = (dir & DN_FLAGS_DIR_MASK);
641 	pkt->ifp = fwa->oif;
642 	pkt->pipe_nr = pipe_nr;
643 
644 	pkt->cpuid = mycpuid;
645 	pkt->msgport = netisr_curport();
646 
647 	id = &fwa->f_id;
648 	fid = &pkt->id;
649 	fid->fid_dst_ip = id->dst_ip;
650 	fid->fid_src_ip = id->src_ip;
651 	fid->fid_dst_port = id->dst_port;
652 	fid->fid_src_port = id->src_port;
653 	fid->fid_proto = id->proto;
654 	fid->fid_flags = id->flags;
655 
656 	pkt->dn_priv = fwa->rule;
657 
658 	if ((int)cmd->opcode == O_DUMMYNET_PIPE)
659 		pkt->dn_flags |= DN_FLAGS_IS_PIPE;
660 
661 	m->m_pkthdr.fw_flags |= DUMMYNET_MBUF_TAGGED;
662 }
663 
664 static __inline void
665 ipfw_inc_static_count(struct ip_fw *rule)
666 {
667 	/* Static rule's counts are updated only on CPU0 */
668 	KKASSERT(mycpuid == 0);
669 
670 	static_count++;
671 	static_ioc_len += IOC_RULESIZE(rule);
672 }
673 
674 static __inline void
675 ipfw_dec_static_count(struct ip_fw *rule)
676 {
677 	int l = IOC_RULESIZE(rule);
678 
679 	/* Static rule's counts are updated only on CPU0 */
680 	KKASSERT(mycpuid == 0);
681 
682 	KASSERT(static_count > 0, ("invalid static count %u", static_count));
683 	static_count--;
684 
685 	KASSERT(static_ioc_len >= l,
686 			("invalid static len %u", static_ioc_len));
687 	static_ioc_len -= l;
688 }
689 
690 static void
691 ipfw_add_rule_dispatch(netmsg_t nmsg)
692 {
693 	struct netmsg_ipfw *fwmsg = (struct netmsg_ipfw *)nmsg;
694 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
695 	struct ip_fw *rule, *prev,*next;
696 	const struct ipfw_ioc_rule *ioc_rule;
697 
698 	ioc_rule = fwmsg->ioc_rule;
699 	 // create rule by ioc_rule
700 	rule = kmalloc(RULESIZE(ioc_rule), M_IPFW3, M_WAITOK | M_ZERO);
701 	rule->act_ofs = ioc_rule->act_ofs;
702 	rule->cmd_len = ioc_rule->cmd_len;
703 	rule->rulenum = ioc_rule->rulenum;
704 	rule->set = ioc_rule->set;
705 	bcopy(ioc_rule->cmd, rule->cmd, rule->cmd_len * 4);
706 
707 	for (prev = NULL, next = ctx->ipfw_rule_chain;
708 		next; prev = next, next = next->next) {
709 		if (next->rulenum > ioc_rule->rulenum) {
710 			break;
711 		}
712 	}
713 	KASSERT(next != NULL, ("no default rule?!"));
714 
715 	/*
716 	 * Insert rule into the pre-determined position
717 	 */
718 	if (prev != NULL) {
719 		rule->next = next;
720 		prev->next = rule;
721 	} else {
722 		rule->next = ctx->ipfw_rule_chain;
723 		ctx->ipfw_rule_chain = rule;
724 	}
725 
726 	/*
727 	 * if sibiling in last CPU is exists,
728 	 * then it's sibling should be current rule
729 	 */
730 	if (fwmsg->sibling != NULL) {
731 		fwmsg->sibling->sibling = rule;
732 	}
733 	/* prepare for next CPU */
734 	fwmsg->sibling = rule;
735 
736 	if (mycpuid == 0) {
737 		/* Statistics only need to be updated once */
738 		ipfw_inc_static_count(rule);
739 	}
740 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
741 }
742 
743 /*
744  * confirm the rulenumber
745  * call dispatch function to add rule into the list
746  * Update the statistic
747  */
748 static void
749 ipfw_add_rule(struct ipfw_ioc_rule *ioc_rule)
750 {
751 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
752 	struct netmsg_ipfw fwmsg;
753 	struct netmsg_base *nmsg;
754 	struct ip_fw *f;
755 
756 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
757 
758 	/*
759 	 * If rulenum is 0, find highest numbered rule before the
760 	 * default rule, and add rule number incremental step.
761 	 */
762 	if (ioc_rule->rulenum == 0) {
763 		int step = autoinc_step;
764 
765 		KKASSERT(step >= IPFW_AUTOINC_STEP_MIN &&
766 				step <= IPFW_AUTOINC_STEP_MAX);
767 
768 		/*
769 		 * Locate the highest numbered rule before default
770 		 */
771 		for (f = ctx->ipfw_rule_chain; f; f = f->next) {
772 			if (f->rulenum == IPFW_DEFAULT_RULE)
773 				break;
774 			ioc_rule->rulenum = f->rulenum;
775 		}
776 		if (ioc_rule->rulenum < IPFW_DEFAULT_RULE - step)
777 			ioc_rule->rulenum += step;
778 	}
779 	KASSERT(ioc_rule->rulenum != IPFW_DEFAULT_RULE &&
780 			ioc_rule->rulenum != 0,
781 			("invalid rule num %d", ioc_rule->rulenum));
782 
783 	bzero(&fwmsg, sizeof(fwmsg));
784 	nmsg = &fwmsg.base;
785 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
786 			0, ipfw_add_rule_dispatch);
787 	fwmsg.ioc_rule = ioc_rule;
788 
789 	ifnet_domsg(&nmsg->lmsg, 0);
790 
791 	DPRINTF("++ installed rule %d, static count now %d\n",
792 			ioc_rule->rulenum, static_count);
793 }
794 
795 /**
796  * Free storage associated with a static rule (including derived
797  * dynamic rules).
798  * The caller is in charge of clearing rule pointers to avoid
799  * dangling pointers.
800  * @return a pointer to the next entry.
801  * Arguments are not checked, so they better be correct.
802  * Must be called at splimp().
803  */
804 static struct ip_fw *
805 ipfw_delete_rule(struct ipfw_context *ctx,
806 		 struct ip_fw *prev, struct ip_fw *rule)
807 {
808 	if (prev == NULL)
809 		ctx->ipfw_rule_chain = rule->next;
810 	else
811 		prev->next = rule->next;
812 
813 	if (mycpuid == IPFW_CFGCPUID)
814 		ipfw_dec_static_count(rule);
815 
816 	kfree(rule, M_IPFW3);
817 	rule = NULL;
818 	return NULL;
819 }
820 
821 static void
822 ipfw_flush_rule_dispatch(netmsg_t nmsg)
823 {
824 	struct lwkt_msg *lmsg = &nmsg->lmsg;
825 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
826 	struct ip_fw *rule, *the_rule;
827 	int kill_default = lmsg->u.ms_result;
828 
829 	rule = ctx->ipfw_rule_chain;
830 	while (rule != NULL) {
831 		if (rule->rulenum == IPFW_DEFAULT_RULE && kill_default == 0) {
832 			ctx->ipfw_rule_chain = rule;
833 			break;
834 		}
835 		the_rule = rule;
836 		rule = rule->next;
837 		if (mycpuid == IPFW_CFGCPUID)
838 			ipfw_dec_static_count(the_rule);
839 
840 		kfree(the_rule, M_IPFW3);
841 	}
842 
843 	ifnet_forwardmsg(lmsg, mycpuid + 1);
844 }
845 
846 static void
847 ipfw_append_state_dispatch(netmsg_t nmsg)
848 {
849 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
850 	struct ipfw_ioc_state *ioc_state = dmsg->ioc_state;
851 	(*ipfw_basic_append_state_prt)(ioc_state);
852 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
853 }
854 
855 static void
856 ipfw_delete_state_dispatch(netmsg_t nmsg)
857 {
858 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
859 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
860 	struct ip_fw *rule = ctx->ipfw_rule_chain;
861 	while (rule != NULL) {
862 		if (rule->rulenum == dmsg->rulenum) {
863 			break;
864 		}
865 		rule = rule->next;
866 	}
867 
868 	(*ipfw_basic_flush_state_prt)(rule);
869 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
870 }
871 
872 /*
873  * Deletes all rules from a chain (including the default rule
874  * if the second argument is set).
875  * Must be called at splimp().
876  */
877 static void
878 ipfw_ctl_flush_rule(int kill_default)
879 {
880 	struct netmsg_del dmsg;
881 	struct netmsg_base nmsg;
882 	struct lwkt_msg *lmsg;
883 
884 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
885 
886 	/*
887 	 * If 'kill_default' then caller has done the necessary
888 	 * msgport syncing; unnecessary to do it again.
889 	 */
890 	if (!kill_default) {
891 		/*
892 		 * Let ipfw_chk() know the rules are going to
893 		 * be flushed, so it could jump directly to
894 		 * the default rule.
895 		 */
896 		ipfw_flushing = 1;
897 		netmsg_service_sync();
898 	}
899 
900 	/*
901 	 * if ipfw_basic_flush_state_prt
902 	 * flush all states in all CPU
903 	 */
904 	if (ipfw_basic_flush_state_prt != NULL) {
905 		bzero(&dmsg, sizeof(dmsg));
906 		netmsg_init(&dmsg.base, NULL, &curthread->td_msgport,
907 				0, ipfw_delete_state_dispatch);
908 		ifnet_domsg(&dmsg.base.lmsg, 0);
909 	}
910 	/*
911 	 * Press the 'flush' button
912 	 */
913 	bzero(&nmsg, sizeof(nmsg));
914 	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
915 			0, ipfw_flush_rule_dispatch);
916 	lmsg = &nmsg.lmsg;
917 	lmsg->u.ms_result = kill_default;
918 	ifnet_domsg(lmsg, 0);
919 
920 	if (kill_default) {
921 		KASSERT(static_count == 0,
922 				("%u static rules remain", static_count));
923 		KASSERT(static_ioc_len == 0,
924 				("%u bytes of static rules remain", static_ioc_len));
925 	}
926 
927 	/* Flush is done */
928 	ipfw_flushing = 0;
929 }
930 
931 static void
932 ipfw_delete_rule_dispatch(netmsg_t nmsg)
933 {
934 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
935 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
936 	struct ip_fw *rule, *prev = NULL;
937 
938 	rule = ctx->ipfw_rule_chain;
939 	while (rule!=NULL) {
940 		if (rule->rulenum == dmsg->rulenum) {
941 			ipfw_delete_rule(ctx, prev, rule);
942 			break;
943 		}
944 		prev = rule;
945 		rule = rule->next;
946 	}
947 
948 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
949 }
950 
951 static int
952 ipfw_alt_delete_rule(uint16_t rulenum)
953 {
954 	struct netmsg_del dmsg;
955 	struct netmsg_base *nmsg;
956 
957 	/*
958 	 * delete the state which stub is the rule
959 	 * which belongs to the CPU and the rulenum
960 	 */
961 	bzero(&dmsg, sizeof(dmsg));
962 	nmsg = &dmsg.base;
963 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
964 			0, ipfw_delete_state_dispatch);
965 	dmsg.rulenum = rulenum;
966 	ifnet_domsg(&nmsg->lmsg, 0);
967 
968 	/*
969 	 * Get rid of the rule duplications on all CPUs
970 	 */
971 	bzero(&dmsg, sizeof(dmsg));
972 	nmsg = &dmsg.base;
973 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
974 			0, ipfw_delete_rule_dispatch);
975 	dmsg.rulenum = rulenum;
976 	ifnet_domsg(&nmsg->lmsg, 0);
977 	return 0;
978 }
979 
980 static void
981 ipfw_alt_delete_ruleset_dispatch(netmsg_t nmsg)
982 {
983 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
984 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
985 	struct ip_fw *prev, *rule;
986 #ifdef INVARIANTS
987 	int del = 0;
988 #endif
989 
990 	prev = NULL;
991 	rule = ctx->ipfw_rule_chain;
992 	while (rule != NULL) {
993 		if (rule->set == dmsg->from_set) {
994 			rule = ipfw_delete_rule(ctx, prev, rule);
995 #ifdef INVARIANTS
996 			del = 1;
997 #endif
998 		} else {
999 			prev = rule;
1000 			rule = rule->next;
1001 		}
1002 	}
1003 	KASSERT(del, ("no match set?!"));
1004 
1005 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
1006 }
1007 
1008 static void
1009 ipfw_disable_ruleset_state_dispatch(netmsg_t nmsg)
1010 {
1011 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
1012 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1013 	struct ip_fw *rule;
1014 #ifdef INVARIANTS
1015 	int cleared = 0;
1016 #endif
1017 
1018 	for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1019 		if (rule->set == dmsg->from_set) {
1020 #ifdef INVARIANTS
1021 			cleared = 1;
1022 #endif
1023 		}
1024 	}
1025 	KASSERT(cleared, ("no match set?!"));
1026 
1027 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
1028 }
1029 
1030 static int
1031 ipfw_alt_delete_ruleset(uint8_t set)
1032 {
1033 	struct netmsg_del dmsg;
1034 	struct netmsg_base *nmsg;
1035 	int state, del;
1036 	struct ip_fw *rule;
1037 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1038 
1039 	/*
1040 	 * Check whether the 'set' exists.  If it exists,
1041 	 * then check whether any rules within the set will
1042 	 * try to create states.
1043 	 */
1044 	state = 0;
1045 	del = 0;
1046 	for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1047 		if (rule->set == set) {
1048 			del = 1;
1049 		}
1050 	}
1051 	if (!del)
1052 		return 0; /* XXX EINVAL? */
1053 
1054 	if (state) {
1055 		/*
1056 		 * Clear the STATE flag, so no more states will be
1057 		 * created based the rules in this set.
1058 		 */
1059 		bzero(&dmsg, sizeof(dmsg));
1060 		nmsg = &dmsg.base;
1061 		netmsg_init(nmsg, NULL, &curthread->td_msgport,
1062 				0, ipfw_disable_ruleset_state_dispatch);
1063 		dmsg.from_set = set;
1064 
1065 		ifnet_domsg(&nmsg->lmsg, 0);
1066 	}
1067 
1068 	/*
1069 	 * Delete this set
1070 	 */
1071 	bzero(&dmsg, sizeof(dmsg));
1072 	nmsg = &dmsg.base;
1073 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1074 			0, ipfw_alt_delete_ruleset_dispatch);
1075 	dmsg.from_set = set;
1076 
1077 	ifnet_domsg(&nmsg->lmsg, 0);
1078 	return 0;
1079 }
1080 
1081 static void
1082 ipfw_alt_move_rule_dispatch(netmsg_t nmsg)
1083 {
1084 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
1085 	struct ip_fw *rule;
1086 
1087 	rule = dmsg->start_rule;
1088 
1089 	/*
1090 	 * Move to the position on the next CPU
1091 	 * before the msg is forwarded.
1092 	 */
1093 
1094 	while (rule && rule->rulenum <= dmsg->rulenum) {
1095 		if (rule->rulenum == dmsg->rulenum)
1096 			rule->set = dmsg->to_set;
1097 		rule = rule->next;
1098 	}
1099 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
1100 }
1101 
1102 static int
1103 ipfw_alt_move_rule(uint16_t rulenum, uint8_t set)
1104 {
1105 	struct netmsg_del dmsg;
1106 	struct netmsg_base *nmsg;
1107 	struct ip_fw *rule;
1108 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1109 
1110 	/*
1111 	 * Locate first rule to move
1112 	 */
1113 	for (rule = ctx->ipfw_rule_chain;
1114 		rule && rule->rulenum <= rulenum; rule = rule->next) {
1115 		if (rule->rulenum == rulenum && rule->set != set)
1116 			break;
1117 	}
1118 	if (rule == NULL || rule->rulenum > rulenum)
1119 		return 0; /* XXX error? */
1120 
1121 	bzero(&dmsg, sizeof(dmsg));
1122 	nmsg = &dmsg.base;
1123 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1124 			0, ipfw_alt_move_rule_dispatch);
1125 	dmsg.start_rule = rule;
1126 	dmsg.rulenum = rulenum;
1127 	dmsg.to_set = set;
1128 
1129 	ifnet_domsg(&nmsg->lmsg, 0);
1130 	KKASSERT(dmsg.start_rule == NULL);
1131 	return 0;
1132 }
1133 
1134 static void
1135 ipfw_alt_move_ruleset_dispatch(netmsg_t nmsg)
1136 {
1137 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
1138 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1139 	struct ip_fw *rule;
1140 
1141 	for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1142 		if (rule->set == dmsg->from_set)
1143 			rule->set = dmsg->to_set;
1144 	}
1145 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
1146 }
1147 
1148 static int
1149 ipfw_alt_move_ruleset(uint8_t from_set, uint8_t to_set)
1150 {
1151 	struct netmsg_del dmsg;
1152 	struct netmsg_base *nmsg;
1153 
1154 	bzero(&dmsg, sizeof(dmsg));
1155 	nmsg = &dmsg.base;
1156 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1157 			0, ipfw_alt_move_ruleset_dispatch);
1158 	dmsg.from_set = from_set;
1159 	dmsg.to_set = to_set;
1160 
1161 	ifnet_domsg(&nmsg->lmsg, 0);
1162 	return 0;
1163 }
1164 
1165 static void
1166 ipfw_alt_swap_ruleset_dispatch(netmsg_t nmsg)
1167 {
1168 	struct netmsg_del *dmsg = (struct netmsg_del *)nmsg;
1169 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1170 	struct ip_fw *rule;
1171 
1172 	for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1173 		if (rule->set == dmsg->from_set)
1174 			rule->set = dmsg->to_set;
1175 		else if (rule->set == dmsg->to_set)
1176 			rule->set = dmsg->from_set;
1177 	}
1178 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
1179 }
1180 
1181 static int
1182 ipfw_alt_swap_ruleset(uint8_t set1, uint8_t set2)
1183 {
1184 	struct netmsg_del dmsg;
1185 	struct netmsg_base *nmsg;
1186 
1187 	bzero(&dmsg, sizeof(dmsg));
1188 	nmsg = &dmsg.base;
1189 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1190 			0, ipfw_alt_swap_ruleset_dispatch);
1191 	dmsg.from_set = set1;
1192 	dmsg.to_set = set2;
1193 
1194 	ifnet_domsg(&nmsg->lmsg, 0);
1195 	return 0;
1196 }
1197 
1198 
1199 static int
1200 ipfw_ctl_alter(uint32_t arg)
1201 {
1202 	uint16_t rulenum;
1203 	uint8_t cmd, new_set;
1204 	int error = 0;
1205 
1206 	rulenum = arg & 0xffff;
1207 	cmd = (arg >> 24) & 0xff;
1208 	new_set = (arg >> 16) & 0xff;
1209 
1210 	if (cmd > 4)
1211 		return EINVAL;
1212 	if (new_set >= IPFW_DEFAULT_SET)
1213 		return EINVAL;
1214 	if (cmd == 0 || cmd == 2) {
1215 		if (rulenum == IPFW_DEFAULT_RULE)
1216 			return EINVAL;
1217 	} else {
1218 		if (rulenum >= IPFW_DEFAULT_SET)
1219 			return EINVAL;
1220 	}
1221 
1222 	switch (cmd) {
1223 	case 0:	/* delete rules with given number */
1224 		error = ipfw_alt_delete_rule(rulenum);
1225 		break;
1226 
1227 	case 1:	/* delete all rules with given set number */
1228 		error = ipfw_alt_delete_ruleset(rulenum);
1229 		break;
1230 
1231 	case 2:	/* move rules with given number to new set */
1232 		error = ipfw_alt_move_rule(rulenum, new_set);
1233 		break;
1234 
1235 	case 3: /* move rules with given set number to new set */
1236 		error = ipfw_alt_move_ruleset(rulenum, new_set);
1237 		break;
1238 
1239 	case 4: /* swap two sets */
1240 		error = ipfw_alt_swap_ruleset(rulenum, new_set);
1241 		break;
1242 	}
1243 	return error;
1244 }
1245 
1246 /*
1247  * Clear counters for a specific rule.
1248  */
1249 static void
1250 clear_counters(struct ip_fw *rule)
1251 {
1252 	rule->bcnt = rule->pcnt = 0;
1253 	rule->timestamp = 0;
1254 }
1255 
1256 static void
1257 ipfw_zero_entry_dispatch(netmsg_t nmsg)
1258 {
1259 	struct netmsg_zent *zmsg = (struct netmsg_zent *)nmsg;
1260 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1261 	struct ip_fw *rule;
1262 
1263 	if (zmsg->rulenum == 0) {
1264 		for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1265 			clear_counters(rule);
1266 		}
1267 	} else {
1268 		for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1269 			if (rule->rulenum == zmsg->rulenum) {
1270 				clear_counters(rule);
1271 			}
1272 		}
1273 	}
1274 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
1275 }
1276 
1277 /**
1278  * Reset some or all counters on firewall rules.
1279  * @arg frwl is null to clear all entries, or contains a specific
1280  * rule number.
1281  * @arg log_only is 1 if we only want to reset logs, zero otherwise.
1282  */
1283 static int
1284 ipfw_ctl_zero_entry(int rulenum, int log_only)
1285 {
1286 	struct netmsg_zent zmsg;
1287 	struct netmsg_base *nmsg;
1288 	const char *msg;
1289 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1290 
1291 	bzero(&zmsg, sizeof(zmsg));
1292 	nmsg = &zmsg.base;
1293 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1294 			0, ipfw_zero_entry_dispatch);
1295 	zmsg.log_only = log_only;
1296 
1297 	if (rulenum == 0) {
1298 		msg = log_only ? "ipfw: All logging counts reset.\n"
1299 				   : "ipfw: Accounting cleared.\n";
1300 	} else {
1301 		struct ip_fw *rule;
1302 
1303 		/*
1304 		 * Locate the first rule with 'rulenum'
1305 		 */
1306 		for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1307 			if (rule->rulenum == rulenum)
1308 				break;
1309 		}
1310 		if (rule == NULL) /* we did not find any matching rules */
1311 			return (EINVAL);
1312 		zmsg.start_rule = rule;
1313 		zmsg.rulenum = rulenum;
1314 
1315 		msg = log_only ? "ipfw: Entry %d logging count reset.\n"
1316 				   : "ipfw: Entry %d cleared.\n";
1317 	}
1318 	ifnet_domsg(&nmsg->lmsg, 0);
1319 	KKASSERT(zmsg.start_rule == NULL);
1320 
1321 	if (fw_verbose)
1322 		log(LOG_SECURITY | LOG_NOTICE, msg, rulenum);
1323 	return (0);
1324 }
1325 
1326 static int
1327 ipfw_ctl_add_state(struct sockopt *sopt)
1328 {
1329 	struct ipfw_ioc_state *ioc_state;
1330 	ioc_state = sopt->sopt_val;
1331 	if (ipfw_basic_append_state_prt != NULL) {
1332 		struct netmsg_del dmsg;
1333 		bzero(&dmsg, sizeof(dmsg));
1334 		netmsg_init(&dmsg.base, NULL, &curthread->td_msgport,
1335 			0, ipfw_append_state_dispatch);
1336 		(&dmsg)->ioc_state = ioc_state;
1337 		ifnet_domsg(&dmsg.base.lmsg, 0);
1338 	}
1339 	return 0;
1340 }
1341 
1342 static int
1343 ipfw_ctl_delete_state(struct sockopt *sopt)
1344 {
1345 	int rulenum = 0, error;
1346 	if (sopt->sopt_valsize != 0) {
1347 		error = soopt_to_kbuf(sopt, &rulenum, sizeof(int), sizeof(int));
1348 		if (error) {
1349 			return -1;
1350 		}
1351 	}
1352 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1353 	struct ip_fw *rule = ctx->ipfw_rule_chain;
1354 
1355 	while (rule!=NULL) {
1356 		if (rule->rulenum == rulenum) {
1357 			break;
1358 		}
1359 		rule = rule->next;
1360 	}
1361 	if (rule == NULL) {
1362 		return -1;
1363 	}
1364 
1365 	struct netmsg_del dmsg;
1366 	struct netmsg_base *nmsg;
1367 	/*
1368 	 * delete the state which stub is the rule
1369 	 * which belongs to the CPU and the rulenum
1370 	 */
1371 	bzero(&dmsg, sizeof(dmsg));
1372 	nmsg = &dmsg.base;
1373 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1374 			0, ipfw_delete_state_dispatch);
1375 	dmsg.rulenum = rulenum;
1376 	ifnet_domsg(&nmsg->lmsg, 0);
1377 	return 0;
1378 }
1379 
1380 static int
1381 ipfw_ctl_flush_state(struct sockopt *sopt)
1382 {
1383 	struct netmsg_del dmsg;
1384 	struct netmsg_base *nmsg;
1385 	/*
1386 	 * delete the state which stub is the rule
1387 	 * which belongs to the CPU and the rulenum
1388 	 */
1389 	bzero(&dmsg, sizeof(dmsg));
1390 	nmsg = &dmsg.base;
1391 	netmsg_init(nmsg, NULL, &curthread->td_msgport,
1392 			0, ipfw_delete_state_dispatch);
1393 	dmsg.rulenum = 0;
1394 	ifnet_domsg(&nmsg->lmsg, 0);
1395 	return 0;
1396 }
1397 
1398 /*
1399  * Get the ioc_rule from the sopt
1400  * call ipfw_add_rule to add the rule
1401  */
1402 static int
1403 ipfw_ctl_add_rule(struct sockopt *sopt)
1404 {
1405 	struct ipfw_ioc_rule *ioc_rule;
1406 	size_t size;
1407 
1408 	size = sopt->sopt_valsize;
1409 	if (size > (sizeof(uint32_t) * IPFW_RULE_SIZE_MAX) ||
1410 			size < sizeof(*ioc_rule)) {
1411 		return EINVAL;
1412 	}
1413 	if (size != (sizeof(uint32_t) * IPFW_RULE_SIZE_MAX)) {
1414 		sopt->sopt_val = krealloc(sopt->sopt_val, sizeof(uint32_t) *
1415 				IPFW_RULE_SIZE_MAX, M_TEMP, M_WAITOK);
1416 	}
1417 	ioc_rule = sopt->sopt_val;
1418 
1419 	ipfw_add_rule(ioc_rule);
1420 	return 0;
1421 }
1422 
1423 static void *
1424 ipfw_copy_state(struct ip_fw_state *state, struct ipfw_ioc_state *ioc_state, int cpuid)
1425 {
1426 	ioc_state->pcnt = state->pcnt;
1427 	ioc_state->bcnt = state->bcnt;
1428 	ioc_state->lifetime = state->lifetime;
1429 	ioc_state->timestamp = state->timestamp;
1430 	ioc_state->cpuid = cpuid;
1431 	ioc_state->expiry = state->expiry;
1432 	ioc_state->rulenum = state->stub->rulenum;
1433 
1434 	bcopy(&state->flow_id, &ioc_state->flow_id, sizeof(struct ipfw_flow_id));
1435 	return ioc_state + 1;
1436 }
1437 
1438 static void *
1439 ipfw_copy_rule(const struct ip_fw *rule, struct ipfw_ioc_rule *ioc_rule)
1440 {
1441 	const struct ip_fw *sibling;
1442 #ifdef INVARIANTS
1443 	int i;
1444 #endif
1445 
1446 	ioc_rule->act_ofs = rule->act_ofs;
1447 	ioc_rule->cmd_len = rule->cmd_len;
1448 	ioc_rule->rulenum = rule->rulenum;
1449 	ioc_rule->set = rule->set;
1450 
1451 	ioc_rule->set_disable = ipfw_ctx[mycpuid]->ipfw_set_disable;
1452 	ioc_rule->static_count = static_count;
1453 	ioc_rule->static_len = static_ioc_len;
1454 
1455 	ioc_rule->pcnt = 1;
1456 	ioc_rule->bcnt = 0;
1457 	ioc_rule->timestamp = 0;
1458 
1459 #ifdef INVARIANTS
1460 	i = 0;
1461 #endif
1462 	ioc_rule->pcnt = 0;
1463 	ioc_rule->bcnt = 0;
1464 	ioc_rule->timestamp = 0;
1465 	for (sibling = rule; sibling != NULL; sibling = sibling->sibling) {
1466 		ioc_rule->pcnt += sibling->pcnt;
1467 		ioc_rule->bcnt += sibling->bcnt;
1468 		if (sibling->timestamp > ioc_rule->timestamp)
1469 			ioc_rule->timestamp = sibling->timestamp;
1470 #ifdef INVARIANTS
1471 		++i;
1472 #endif
1473 	}
1474 
1475 	KASSERT(i == ncpus, ("static rule is not duplicated on every cpu"));
1476 
1477 	bcopy(rule->cmd, ioc_rule->cmd, ioc_rule->cmd_len * 4 /* XXX */);
1478 
1479 	return ((uint8_t *)ioc_rule + IOC_RULESIZE(ioc_rule));
1480 }
1481 
1482 static int
1483 ipfw_ctl_get_modules(struct sockopt *sopt)
1484 {
1485 	int i;
1486 	struct ipfw_module *mod;
1487 	char module_str[1024];
1488 	memset(module_str,0,1024);
1489 	for (i = 0, mod = ipfw_modules; i < MAX_MODULE; i++, mod++) {
1490 		if (mod->type != 0) {
1491 			if (i > 0)
1492 				strcat(module_str,",");
1493 			strcat(module_str,mod->name);
1494 		}
1495 	}
1496 	bzero(sopt->sopt_val, sopt->sopt_valsize);
1497 	bcopy(module_str, sopt->sopt_val, strlen(module_str));
1498 	sopt->sopt_valsize = strlen(module_str);
1499 	return 0;
1500 }
1501 
1502 /*
1503  * Copy all static rules and states on all CPU
1504  */
1505 static int
1506 ipfw_ctl_get_rules(struct sockopt *sopt)
1507 {
1508 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1509 	struct ipfw_state_context *state_ctx;
1510 	struct ip_fw *rule;
1511 	struct ip_fw_state *state;
1512 	void *bp;
1513 	size_t size;
1514 	int i, j, state_count = 0;
1515 
1516 	size = static_ioc_len;
1517 	for (i = 0; i < ncpus; i++) {
1518 		for (j = 0; j < ctx->state_hash_size; j++) {
1519 			state_ctx = &ipfw_ctx[i]->state_ctx[j];
1520 			state_count += state_ctx->count;
1521 		}
1522 	}
1523 	if (state_count > 0) {
1524 		size += state_count * sizeof(struct ipfw_ioc_state);
1525 	}
1526 
1527 	if (sopt->sopt_valsize < size) {
1528 		/* XXX TODO sopt_val is not big enough */
1529 		bzero(sopt->sopt_val, sopt->sopt_valsize);
1530 		return 0;
1531 	}
1532 
1533 	sopt->sopt_valsize = size;
1534 	bp = sopt->sopt_val;
1535 
1536 	for (rule = ctx->ipfw_rule_chain; rule; rule = rule->next) {
1537 		bp = ipfw_copy_rule(rule, bp);
1538 	}
1539 	if (state_count > 0 ) {
1540 		for (i = 0; i < ncpus; i++) {
1541 			for (j = 0; j < ctx->state_hash_size; j++) {
1542 				state_ctx = &ipfw_ctx[i]->state_ctx[j];
1543 				state = state_ctx->state;
1544 				while (state != NULL) {
1545 					bp = ipfw_copy_state(state, bp, i);
1546 					state = state->next;
1547 				}
1548 			}
1549 		}
1550 	}
1551 	return 0;
1552 }
1553 
1554 static void
1555 ipfw_set_disable_dispatch(netmsg_t nmsg)
1556 {
1557 	struct lwkt_msg *lmsg = &nmsg->lmsg;
1558 	struct ipfw_context *ctx = ipfw_ctx[mycpuid];
1559 
1560 	ctx->ipfw_set_disable = lmsg->u.ms_result32;
1561 
1562 	ifnet_forwardmsg(lmsg, mycpuid + 1);
1563 }
1564 
1565 static void
1566 ipfw_ctl_set_disable(uint32_t disable, uint32_t enable)
1567 {
1568 	struct netmsg_base nmsg;
1569 	struct lwkt_msg *lmsg;
1570 	uint32_t set_disable;
1571 
1572 	/* IPFW_DEFAULT_SET is always enabled */
1573 	enable |= (1 << IPFW_DEFAULT_SET);
1574 	set_disable = (ipfw_ctx[mycpuid]->ipfw_set_disable | disable) & ~enable;
1575 
1576 	bzero(&nmsg, sizeof(nmsg));
1577 	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
1578 			0, ipfw_set_disable_dispatch);
1579 	lmsg = &nmsg.lmsg;
1580 	lmsg->u.ms_result32 = set_disable;
1581 
1582 	ifnet_domsg(lmsg, 0);
1583 }
1584 
1585 
1586 /*
1587  * ipfw_ctl_x - extended version of ipfw_ctl
1588  * remove the x_header, and adjust the sopt_name,sopt_val and sopt_valsize.
1589  */
1590 int
1591 ipfw_ctl_x(struct sockopt *sopt)
1592 {
1593 	ip_fw_x_header *x_header;
1594 	x_header = (ip_fw_x_header *)(sopt->sopt_val);
1595 	sopt->sopt_name = x_header->opcode;
1596 	sopt->sopt_valsize -= sizeof(ip_fw_x_header);
1597 	bcopy(++x_header, sopt->sopt_val, sopt->sopt_valsize);
1598 	return ipfw_ctl(sopt);
1599 }
1600 
1601 
1602 /**
1603  * {set|get}sockopt parser.
1604  */
1605 static int
1606 ipfw_ctl(struct sockopt *sopt)
1607 {
1608 	int error, rulenum;
1609 	uint32_t *masks;
1610 	size_t size;
1611 
1612 	error = 0;
1613 	switch (sopt->sopt_name) {
1614 		case IP_FW_X:
1615 			ipfw_ctl_x(sopt);
1616 			break;
1617 		case IP_FW_GET:
1618 			error = ipfw_ctl_get_rules(sopt);
1619 			break;
1620 		case IP_FW_MODULE:
1621 			error = ipfw_ctl_get_modules(sopt);
1622 			break;
1623 
1624 		case IP_FW_FLUSH:
1625 			ipfw_ctl_flush_rule(0);
1626 			break;
1627 
1628 		case IP_FW_ADD:
1629 			error = ipfw_ctl_add_rule(sopt);
1630 			break;
1631 
1632 		case IP_FW_DEL:
1633 			/*
1634 			 * IP_FW_DEL is used for deleting single rules or sets,
1635 			 * and (ab)used to atomically manipulate sets.
1636 			 * Argument size is used to distinguish between the two:
1637 			 *	sizeof(uint32_t)
1638 			 *	delete single rule or set of rules,
1639 			 *	or reassign rules (or sets) to a different set.
1640 			 *	2 * sizeof(uint32_t)
1641 			 *	atomic disable/enable sets.
1642 			 *	first uint32_t contains sets to be disabled,
1643 			 *	second uint32_t contains sets to be enabled.
1644 			 */
1645 			masks = sopt->sopt_val;
1646 			size = sopt->sopt_valsize;
1647 			if (size == sizeof(*masks)) {
1648 				/*
1649 				 * Delete or reassign static rule
1650 				 */
1651 				error = ipfw_ctl_alter(masks[0]);
1652 			} else if (size == (2 * sizeof(*masks))) {
1653 				/*
1654 				 * Set enable/disable
1655 				 */
1656 				ipfw_ctl_set_disable(masks[0], masks[1]);
1657 			} else {
1658 				error = EINVAL;
1659 			}
1660 			break;
1661 		case IP_FW_ZERO:
1662 		case IP_FW_RESETLOG: /* argument is an int, the rule number */
1663 			rulenum = 0;
1664 			if (sopt->sopt_valsize != 0) {
1665 				error = soopt_to_kbuf(sopt, &rulenum,
1666 						sizeof(int), sizeof(int));
1667 				if (error) {
1668 					break;
1669 				}
1670 			}
1671 			error = ipfw_ctl_zero_entry(rulenum,
1672 					sopt->sopt_name == IP_FW_RESETLOG);
1673 			break;
1674 		case IP_FW_NAT_CFG:
1675 			error = ipfw_nat_cfg_ptr(sopt);
1676 			break;
1677 		case IP_FW_NAT_DEL:
1678 			error = ipfw_nat_del_ptr(sopt);
1679 			break;
1680 		case IP_FW_NAT_FLUSH:
1681 			error = ipfw_nat_flush_ptr(sopt);
1682 			break;
1683 		case IP_FW_NAT_GET:
1684 			error = ipfw_nat_get_cfg_ptr(sopt);
1685 			break;
1686 		case IP_FW_NAT_LOG:
1687 			error = ipfw_nat_get_log_ptr(sopt);
1688 			break;
1689 		case IP_DUMMYNET_GET:
1690 		case IP_DUMMYNET_CONFIGURE:
1691 		case IP_DUMMYNET_DEL:
1692 		case IP_DUMMYNET_FLUSH:
1693 			error = ip_dn_sockopt(sopt);
1694 			break;
1695 		case IP_FW_STATE_ADD:
1696 			error = ipfw_ctl_add_state(sopt);
1697 			break;
1698 		case IP_FW_STATE_DEL:
1699 			error = ipfw_ctl_delete_state(sopt);
1700 			break;
1701 		case IP_FW_STATE_FLUSH:
1702 			error = ipfw_ctl_flush_state(sopt);
1703 			break;
1704 		case IP_FW_TABLE_CREATE:
1705 		case IP_FW_TABLE_DELETE:
1706 		case IP_FW_TABLE_APPEND:
1707 		case IP_FW_TABLE_REMOVE:
1708 		case IP_FW_TABLE_LIST:
1709 		case IP_FW_TABLE_FLUSH:
1710 		case IP_FW_TABLE_SHOW:
1711 		case IP_FW_TABLE_TEST:
1712 		case IP_FW_TABLE_RENAME:
1713 			error = ipfw_ctl_table_sockopt(sopt);
1714 			break;
1715 		default:
1716 			kprintf("ipfw_ctl invalid option %d\n",
1717 				sopt->sopt_name);
1718 			error = EINVAL;
1719 	}
1720 	return error;
1721 }
1722 
1723 static int
1724 ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
1725 {
1726 	struct ip_fw_args args;
1727 	struct mbuf *m = *m0;
1728 	struct m_tag *mtag;
1729 	int tee = 0, error = 0, ret;
1730 	// again:
1731 	if (m->m_pkthdr.fw_flags & DUMMYNET_MBUF_TAGGED) {
1732 		/* Extract info from dummynet tag */
1733 		mtag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
1734 		KKASSERT(mtag != NULL);
1735 		args.rule = ((struct dn_pkt *)m_tag_data(mtag))->dn_priv;
1736 		KKASSERT(args.rule != NULL);
1737 
1738 		m_tag_delete(m, mtag);
1739 		m->m_pkthdr.fw_flags &= ~DUMMYNET_MBUF_TAGGED;
1740 	} else {
1741 		args.rule = NULL;
1742 	}
1743 
1744 	args.eh = NULL;
1745 	args.oif = NULL;
1746 	args.m = m;
1747 	ret = ipfw_chk(&args);
1748 	m = args.m;
1749 
1750 	if (m == NULL) {
1751 		error = EACCES;
1752 		goto back;
1753 	}
1754 	switch (ret) {
1755 		case IP_FW_PASS:
1756 			break;
1757 
1758 		case IP_FW_DENY:
1759 			m_freem(m);
1760 			m = NULL;
1761 			error = EACCES;
1762 			break;
1763 
1764 		case IP_FW_DUMMYNET:
1765 			/* Send packet to the appropriate pipe */
1766 			ipfw_dummynet_io(m, args.cookie, DN_TO_IP_IN, &args);
1767 			break;
1768 
1769 		case IP_FW_TEE:
1770 			tee = 1;
1771 			/* FALL THROUGH */
1772 
1773 		case IP_FW_DIVERT:
1774 			/*
1775 			 * Must clear bridge tag when changing
1776 			 */
1777 			m->m_pkthdr.fw_flags &= ~BRIDGE_MBUF_TAGGED;
1778 			if (ip_divert_p != NULL) {
1779 				m = ip_divert_p(m, tee, 1);
1780 			} else {
1781 				m_freem(m);
1782 				m = NULL;
1783 				/* not sure this is the right error msg */
1784 				error = EACCES;
1785 			}
1786 			break;
1787 
1788 		case IP_FW_NAT:
1789 			break;
1790 		case IP_FW_ROUTE:
1791 			break;
1792 		default:
1793 			panic("unknown ipfw return value: %d", ret);
1794 	}
1795 back:
1796 	*m0 = m;
1797 	return error;
1798 }
1799 
1800 static int
1801 ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir)
1802 {
1803 	struct ip_fw_args args;
1804 	struct mbuf *m = *m0;
1805 	struct m_tag *mtag;
1806 	int tee = 0, error = 0, ret;
1807 	// again:
1808 	if (m->m_pkthdr.fw_flags & DUMMYNET_MBUF_TAGGED) {
1809 		/* Extract info from dummynet tag */
1810 		mtag = m_tag_find(m, PACKET_TAG_DUMMYNET, NULL);
1811 		KKASSERT(mtag != NULL);
1812 		args.rule = ((struct dn_pkt *)m_tag_data(mtag))->dn_priv;
1813 		KKASSERT(args.rule != NULL);
1814 
1815 		m_tag_delete(m, mtag);
1816 		m->m_pkthdr.fw_flags &= ~DUMMYNET_MBUF_TAGGED;
1817 	} else {
1818 		args.rule = NULL;
1819 	}
1820 
1821 	args.eh = NULL;
1822 	args.m = m;
1823 	args.oif = ifp;
1824 	ret = ipfw_chk(&args);
1825 	m = args.m;
1826 
1827 	if (m == NULL) {
1828 		error = EACCES;
1829 		goto back;
1830 	}
1831 
1832 	switch (ret) {
1833 		case IP_FW_PASS:
1834 			break;
1835 
1836 		case IP_FW_DENY:
1837 			m_freem(m);
1838 			m = NULL;
1839 			error = EACCES;
1840 			break;
1841 
1842 		case IP_FW_DUMMYNET:
1843 			ipfw_dummynet_io(m, args.cookie, DN_TO_IP_OUT, &args);
1844 			break;
1845 
1846 		case IP_FW_TEE:
1847 			tee = 1;
1848 			/* FALL THROUGH */
1849 
1850 		case IP_FW_DIVERT:
1851 			if (ip_divert_p != NULL) {
1852 				m = ip_divert_p(m, tee, 0);
1853 			} else {
1854 				m_freem(m);
1855 				m = NULL;
1856 				/* not sure this is the right error msg */
1857 				error = EACCES;
1858 			}
1859 			break;
1860 
1861 		case IP_FW_NAT:
1862 			break;
1863 		case IP_FW_ROUTE:
1864 			break;
1865 		default:
1866 			panic("unknown ipfw return value: %d", ret);
1867 	}
1868 back:
1869 	*m0 = m;
1870 	return error;
1871 }
1872 
1873 static void
1874 ipfw_hook(void)
1875 {
1876 	struct pfil_head *pfh;
1877 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
1878 
1879 	pfh = pfil_head_get(PFIL_TYPE_AF, AF_INET);
1880 	if (pfh == NULL)
1881 		return;
1882 
1883 	pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_MPSAFE, pfh);
1884 	pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_MPSAFE, pfh);
1885 }
1886 
1887 static void
1888 ipfw_dehook(void)
1889 {
1890 	struct pfil_head *pfh;
1891 
1892 	IPFW_ASSERT_CFGPORT(&curthread->td_msgport);
1893 
1894 	pfh = pfil_head_get(PFIL_TYPE_AF, AF_INET);
1895 	if (pfh == NULL)
1896 		return;
1897 
1898 	pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN, pfh);
1899 	pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT, pfh);
1900 }
1901 
1902 static void
1903 ipfw_sysctl_enable_dispatch(netmsg_t nmsg)
1904 {
1905 	struct lwkt_msg *lmsg = &nmsg->lmsg;
1906 	int enable = lmsg->u.ms_result;
1907 
1908 	if (fw3_enable == enable)
1909 		goto reply;
1910 
1911 	fw3_enable = enable;
1912 	if (fw3_enable)
1913 		ipfw_hook();
1914 	else
1915 		ipfw_dehook();
1916 
1917 reply:
1918 	lwkt_replymsg(lmsg, 0);
1919 }
1920 
1921 static int
1922 ipfw_sysctl_enable(SYSCTL_HANDLER_ARGS)
1923 {
1924 	struct netmsg_base nmsg;
1925 	struct lwkt_msg *lmsg;
1926 	int enable, error;
1927 
1928 	enable = fw3_enable;
1929 	error = sysctl_handle_int(oidp, &enable, 0, req);
1930 	if (error || req->newptr == NULL)
1931 		return error;
1932 
1933 	netmsg_init(&nmsg, NULL, &curthread->td_msgport,
1934 			0, ipfw_sysctl_enable_dispatch);
1935 	lmsg = &nmsg.lmsg;
1936 	lmsg->u.ms_result = enable;
1937 
1938 	return lwkt_domsg(IPFW_CFGPORT, lmsg, 0);
1939 }
1940 
1941 static int
1942 ipfw_sysctl_autoinc_step(SYSCTL_HANDLER_ARGS)
1943 {
1944 	return sysctl_int_range(oidp, arg1, arg2, req,
1945 			IPFW_AUTOINC_STEP_MIN, IPFW_AUTOINC_STEP_MAX);
1946 }
1947 
1948 
1949 static void
1950 ipfw_ctx_init_dispatch(netmsg_t nmsg)
1951 {
1952 	struct netmsg_ipfw *fwmsg = (struct netmsg_ipfw *)nmsg;
1953 	struct ipfw_context *ctx;
1954 	struct ip_fw *def_rule;
1955 
1956 	if (mycpuid == 0 ) {
1957 		ipfw_nat_ctx = kmalloc(sizeof(struct ipfw_nat_context),
1958 				M_IPFW3, M_WAITOK | M_ZERO);
1959 	}
1960 
1961 	ctx = kmalloc(sizeof(struct ipfw_context), M_IPFW3, M_WAITOK | M_ZERO);
1962 	ipfw_ctx[mycpuid] = ctx;
1963 
1964 	def_rule = kmalloc(sizeof(struct ip_fw), M_IPFW3, M_WAITOK | M_ZERO);
1965 	def_rule->act_ofs = 0;
1966 	def_rule->rulenum = IPFW_DEFAULT_RULE;
1967 	def_rule->cmd_len = 2;
1968 	def_rule->set = IPFW_DEFAULT_SET;
1969 
1970 	def_rule->cmd[0].len = LEN_OF_IPFWINSN;
1971 	def_rule->cmd[0].module = MODULE_BASIC_ID;
1972 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
1973 	def_rule->cmd[0].opcode = O_BASIC_ACCEPT;
1974 #else
1975 	if (filters_default_to_accept)
1976 		def_rule->cmd[0].opcode = O_BASIC_ACCEPT;
1977 	else
1978 		def_rule->cmd[0].opcode = O_BASIC_DENY;
1979 #endif
1980 
1981 	/* Install the default rule */
1982 	ctx->ipfw_default_rule = def_rule;
1983 	ctx->ipfw_rule_chain = def_rule;
1984 
1985 	/*
1986 	 * if sibiling in last CPU is exists,
1987 	 * then it's sibling should be current rule
1988 	 */
1989 	if (fwmsg->sibling != NULL) {
1990 		fwmsg->sibling->sibling = def_rule;
1991 	}
1992 	/* prepare for next CPU */
1993 	fwmsg->sibling = def_rule;
1994 
1995 	/* Statistics only need to be updated once */
1996 	if (mycpuid == 0)
1997 		ipfw_inc_static_count(def_rule);
1998 
1999 	ifnet_forwardmsg(&nmsg->lmsg, mycpuid + 1);
2000 }
2001 
2002 static void
2003 ipfw_init_dispatch(netmsg_t nmsg)
2004 {
2005 	struct netmsg_ipfw fwmsg;
2006 	int error = 0;
2007 	if (IPFW3_LOADED) {
2008 		kprintf("IP firewall already loaded\n");
2009 		error = EEXIST;
2010 		goto reply;
2011 	}
2012 
2013 	bzero(&fwmsg, sizeof(fwmsg));
2014 	netmsg_init(&fwmsg.base, NULL, &curthread->td_msgport,
2015 			0, ipfw_ctx_init_dispatch);
2016 	ifnet_domsg(&fwmsg.base.lmsg, 0);
2017 
2018 	ip_fw_chk_ptr = ipfw_chk;
2019 	ip_fw_ctl_x_ptr = ipfw_ctl_x;
2020 	ip_fw_dn_io_ptr = ipfw_dummynet_io;
2021 
2022 	kprintf("ipfw3 initialized, default to %s, logging ",
2023 		(int)(ipfw_ctx[mycpuid]->ipfw_default_rule->cmd[0].opcode) ==
2024 		O_BASIC_ACCEPT ? "accept" : "deny");
2025 
2026 #ifdef IPFIREWALL_VERBOSE
2027 	fw_verbose = 1;
2028 #endif
2029 #ifdef IPFIREWALL_VERBOSE_LIMIT
2030 	verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
2031 #endif
2032 	if (fw_verbose == 0) {
2033 		kprintf("disabled ");
2034 	} else if (verbose_limit == 0) {
2035 		kprintf("unlimited ");
2036 	} else {
2037 		kprintf("limited to %d packets/entry by default ",
2038 				verbose_limit);
2039 	}
2040 	kprintf("\n");
2041 	ip_fw3_loaded = 1;
2042 	if (fw3_enable)
2043 		ipfw_hook();
2044 reply:
2045 	lwkt_replymsg(&nmsg->lmsg, error);
2046 }
2047 
2048 static int
2049 ipfw3_init(void)
2050 {
2051 	struct netmsg_base smsg;
2052 	int error;
2053 
2054 	init_module();
2055 	netmsg_init(&smsg, NULL, &curthread->td_msgport,
2056 			0, ipfw_init_dispatch);
2057 	error = lwkt_domsg(IPFW_CFGPORT, &smsg.lmsg, 0);
2058 	netmsg_init(&smsg, NULL, &curthread->td_msgport,
2059 			0, table_init_dispatch);
2060 	error = lwkt_domsg(IPFW_CFGPORT, &smsg.lmsg, 0);
2061 	return error;
2062 }
2063 
2064 #ifdef KLD_MODULE
2065 
2066 static void
2067 ipfw_fini_dispatch(netmsg_t nmsg)
2068 {
2069 	int error = 0, cpu;
2070 
2071 	ip_fw3_loaded = 0;
2072 
2073 	ipfw_dehook();
2074 	netmsg_service_sync();
2075 	ip_fw_chk_ptr = NULL;
2076 	ip_fw_ctl_x_ptr = NULL;
2077 	ip_fw_dn_io_ptr = NULL;
2078 	ipfw_ctl_flush_rule(1 /* kill default rule */);
2079 	table_fini();
2080 	/* Free pre-cpu context */
2081 	for (cpu = 0; cpu < ncpus; ++cpu) {
2082 		if (ipfw_ctx[cpu] != NULL) {
2083 			kfree(ipfw_ctx[cpu], M_IPFW3);
2084 			ipfw_ctx[cpu] = NULL;
2085 		}
2086 	}
2087 	kfree(ipfw_nat_ctx,M_IPFW3);
2088 	ipfw_nat_ctx = NULL;
2089 	kprintf("IP firewall unloaded\n");
2090 
2091 	lwkt_replymsg(&nmsg->lmsg, error);
2092 }
2093 
2094 static int
2095 ipfw3_fini(void)
2096 {
2097 	struct netmsg_base smsg;
2098 	netmsg_init(&smsg, NULL, &curthread->td_msgport,
2099 			0, ipfw_fini_dispatch);
2100 	return lwkt_domsg(IPFW_CFGPORT, &smsg.lmsg, 0);
2101 }
2102 
2103 #endif	/* KLD_MODULE */
2104 
2105 static int
2106 ipfw3_modevent(module_t mod, int type, void *unused)
2107 {
2108 	int err = 0;
2109 
2110 	switch (type) {
2111 		case MOD_LOAD:
2112 			err = ipfw3_init();
2113 			break;
2114 
2115 		case MOD_UNLOAD:
2116 
2117 #ifndef KLD_MODULE
2118 			kprintf("ipfw statically compiled, cannot unload\n");
2119 			err = EBUSY;
2120 #else
2121 			err = ipfw3_fini();
2122 #endif
2123 			break;
2124 		default:
2125 			break;
2126 	}
2127 	return err;
2128 }
2129 
2130 static moduledata_t ipfw3mod = {
2131 	"ipfw3",
2132 	ipfw3_modevent,
2133 	0
2134 };
2135 DECLARE_MODULE(ipfw3, ipfw3mod, SI_SUB_PROTO_END, SI_ORDER_ANY);
2136 MODULE_VERSION(ipfw3, 1);
2137