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