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