ip_fw2.c (231852) | ip_fw2.c (232865) |
---|---|
1/*- 2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> |
27__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw2.c 231852 2012-02-17 02:39:58Z bz $"); | 27__FBSDID("$FreeBSD: head/sys/netinet/ipfw/ip_fw2.c 232865 2012-03-12 14:07:57Z melifaro $"); |
28 29/* 30 * The FreeBSD IP packet firewall, main file 31 */ 32 33#include "opt_ipfw.h" 34#include "opt_ipdivert.h" 35#include "opt_inet.h" --- 75 unchanged lines hidden (view full) --- 111static int default_to_accept = 1; 112#else 113static int default_to_accept; 114#endif 115 116VNET_DEFINE(int, autoinc_step); 117VNET_DEFINE(int, fw_one_pass) = 1; 118 | 28 29/* 30 * The FreeBSD IP packet firewall, main file 31 */ 32 33#include "opt_ipfw.h" 34#include "opt_ipdivert.h" 35#include "opt_inet.h" --- 75 unchanged lines hidden (view full) --- 111static int default_to_accept = 1; 112#else 113static int default_to_accept; 114#endif 115 116VNET_DEFINE(int, autoinc_step); 117VNET_DEFINE(int, fw_one_pass) = 1; 118 |
119/* Use 128 tables by default */ 120VNET_DEFINE(int, fw_tables_max) = IPFW_TABLES_MAX; 121 |
|
119/* 120 * Each rule belongs to one of 32 different sets (0..31). 121 * The variable set_disable contains one bit per set. 122 * If the bit is set, all rules in the corresponding set 123 * are disabled. Set RESVD_SET(31) is reserved for the default rule 124 * and rules that are not deleted by the flush command, 125 * and CANNOT be disabled. 126 * Rules in set RESVD_SET can only be deleted individually. --- 13 unchanged lines hidden (view full) --- 140struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int); 141ipfw_nat_cfg_t *ipfw_nat_cfg_ptr; 142ipfw_nat_cfg_t *ipfw_nat_del_ptr; 143ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr; 144ipfw_nat_cfg_t *ipfw_nat_get_log_ptr; 145 146#ifdef SYSCTL_NODE 147uint32_t dummy_def = IPFW_DEFAULT_RULE; | 122/* 123 * Each rule belongs to one of 32 different sets (0..31). 124 * The variable set_disable contains one bit per set. 125 * If the bit is set, all rules in the corresponding set 126 * are disabled. Set RESVD_SET(31) is reserved for the default rule 127 * and rules that are not deleted by the flush command, 128 * and CANNOT be disabled. 129 * Rules in set RESVD_SET can only be deleted individually. --- 13 unchanged lines hidden (view full) --- 143struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int); 144ipfw_nat_cfg_t *ipfw_nat_cfg_ptr; 145ipfw_nat_cfg_t *ipfw_nat_del_ptr; 146ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr; 147ipfw_nat_cfg_t *ipfw_nat_get_log_ptr; 148 149#ifdef SYSCTL_NODE 150uint32_t dummy_def = IPFW_DEFAULT_RULE; |
148uint32_t dummy_tables_max = IPFW_TABLES_MAX; | |
149 150SYSBEGIN(f3) 151 152SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); 153SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass, 154 CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0, 155 "Only do a single pass through ipfw when using dummynet(4)"); 156SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, --- 4 unchanged lines hidden (view full) --- 161 "Log matches to ipfw rules"); 162SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, 163 CTLFLAG_RW, &VNET_NAME(verbose_limit), 0, 164 "Set upper limit of matches of ipfw rules logged"); 165SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD, 166 &dummy_def, 0, 167 "The default/max possible rule number."); 168SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD, | 151 152SYSBEGIN(f3) 153 154SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); 155SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass, 156 CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0, 157 "Only do a single pass through ipfw when using dummynet(4)"); 158SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, --- 4 unchanged lines hidden (view full) --- 163 "Log matches to ipfw rules"); 164SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, 165 CTLFLAG_RW, &VNET_NAME(verbose_limit), 0, 166 "Set upper limit of matches of ipfw rules logged"); 167SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD, 168 &dummy_def, 0, 169 "The default/max possible rule number."); 170SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD, |
169 &dummy_tables_max, 0, | 171 &V_fw_tables_max, 0, |
170 "The maximum number of tables."); 171SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN, 172 &default_to_accept, 0, 173 "Make the default rule accept all packets."); 174TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept); | 172 "The maximum number of tables."); 173SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN, 174 &default_to_accept, 0, 175 "Make the default rule accept all packets."); 176TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept); |
177TUNABLE_INT("net.inet.ip.fw.tables_max", &V_fw_tables_max); |
|
175SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count, 176 CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0, 177 "Number of static rules"); 178 179#ifdef INET6 180SYSCTL_DECL(_net_inet6_ip6); 181SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); 182SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs, --- 153 unchanged lines hidden (view full) --- 336 break; 337 338 } 339 } 340 return (flags_match(cmd, bits)); 341} 342 343static int | 178SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count, 179 CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0, 180 "Number of static rules"); 181 182#ifdef INET6 183SYSCTL_DECL(_net_inet6_ip6); 184SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); 185SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs, --- 153 unchanged lines hidden (view full) --- 339 break; 340 341 } 342 } 343 return (flags_match(cmd, bits)); 344} 345 346static int |
344iface_match(struct ifnet *ifp, ipfw_insn_if *cmd) | 347iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, struct ip_fw_chain *chain, uint32_t *tablearg) |
345{ 346 if (ifp == NULL) /* no iface with this packet, match fails */ 347 return 0; 348 /* Check by name or by IP address */ 349 if (cmd->name[0] != '\0') { /* match by name */ | 348{ 349 if (ifp == NULL) /* no iface with this packet, match fails */ 350 return 0; 351 /* Check by name or by IP address */ 352 if (cmd->name[0] != '\0') { /* match by name */ |
353 if (cmd->name[0] == '\1') /* use tablearg to match */ 354 return ipfw_lookup_table_extended(chain, cmd->p.glob, 355 ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE); |
|
350 /* Check name */ 351 if (cmd->p.glob) { 352 if (fnmatch(cmd->name, ifp->if_xname, 0) == 0) 353 return(1); 354 } else { 355 if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0) 356 return(1); 357 } --- 949 unchanged lines hidden (view full) --- 1307 &ucred_cache); 1308#else 1309 (void *)&ucred_cache); 1310#endif 1311 break; 1312 1313 case O_RECV: 1314 match = iface_match(m->m_pkthdr.rcvif, | 356 /* Check name */ 357 if (cmd->p.glob) { 358 if (fnmatch(cmd->name, ifp->if_xname, 0) == 0) 359 return(1); 360 } else { 361 if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0) 362 return(1); 363 } --- 949 unchanged lines hidden (view full) --- 1313 &ucred_cache); 1314#else 1315 (void *)&ucred_cache); 1316#endif 1317 break; 1318 1319 case O_RECV: 1320 match = iface_match(m->m_pkthdr.rcvif, |
1315 (ipfw_insn_if *)cmd); | 1321 (ipfw_insn_if *)cmd, chain, &tablearg); |
1316 break; 1317 1318 case O_XMIT: | 1322 break; 1323 1324 case O_XMIT: |
1319 match = iface_match(oif, (ipfw_insn_if *)cmd); | 1325 match = iface_match(oif, (ipfw_insn_if *)cmd, 1326 chain, &tablearg); |
1320 break; 1321 1322 case O_VIA: 1323 match = iface_match(oif ? oif : | 1327 break; 1328 1329 case O_VIA: 1330 match = iface_match(oif ? oif : |
1324 m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd); | 1331 m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, 1332 chain, &tablearg); |
1325 break; 1326 1327 case O_MACADDR2: 1328 if (args->eh != NULL) { /* have MAC header */ 1329 u_int32_t *want = (u_int32_t *) 1330 ((ipfw_insn_mac *)cmd)->addr; 1331 u_int32_t *mask = (u_int32_t *) 1332 ((ipfw_insn_mac *)cmd)->mask; --- 110 unchanged lines hidden (view full) --- 1443 cmd->arg1, key, &v); 1444 if (!match) 1445 break; 1446 if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) 1447 match = 1448 ((ipfw_insn_u32 *)cmd)->d[0] == v; 1449 else 1450 tablearg = v; | 1333 break; 1334 1335 case O_MACADDR2: 1336 if (args->eh != NULL) { /* have MAC header */ 1337 u_int32_t *want = (u_int32_t *) 1338 ((ipfw_insn_mac *)cmd)->addr; 1339 u_int32_t *mask = (u_int32_t *) 1340 ((ipfw_insn_mac *)cmd)->mask; --- 110 unchanged lines hidden (view full) --- 1451 cmd->arg1, key, &v); 1452 if (!match) 1453 break; 1454 if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) 1455 match = 1456 ((ipfw_insn_u32 *)cmd)->d[0] == v; 1457 else 1458 tablearg = v; |
1459 } else if (is_ipv6) { 1460 uint32_t v = 0; 1461 void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ? 1462 &args->f_id.dst_ip6: &args->f_id.src_ip6; 1463 match = ipfw_lookup_table_extended(chain, 1464 cmd->arg1, pkey, &v, 1465 IPFW_TABLE_CIDR); 1466 if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) 1467 match = ((ipfw_insn_u32 *)cmd)->d[0] == v; 1468 if (match) 1469 tablearg = v; |
|
1451 } 1452 break; 1453 1454 case O_IP_SRC_MASK: 1455 case O_IP_DST_MASK: 1456 if (is_ipv4) { 1457 uint32_t a = 1458 (cmd->opcode == O_IP_DST_MASK) ? --- 1102 unchanged lines hidden (view full) --- 2561#endif 2562#ifdef IPFIREWALL_VERBOSE_LIMIT 2563 V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT; 2564#endif 2565#ifdef IPFIREWALL_NAT 2566 LIST_INIT(&chain->nat); 2567#endif 2568 | 1470 } 1471 break; 1472 1473 case O_IP_SRC_MASK: 1474 case O_IP_DST_MASK: 1475 if (is_ipv4) { 1476 uint32_t a = 1477 (cmd->opcode == O_IP_DST_MASK) ? --- 1102 unchanged lines hidden (view full) --- 2580#endif 2581#ifdef IPFIREWALL_VERBOSE_LIMIT 2582 V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT; 2583#endif 2584#ifdef IPFIREWALL_NAT 2585 LIST_INIT(&chain->nat); 2586#endif 2587 |
2588 /* Check user-supplied number for validness */ 2589 if (V_fw_tables_max < 0) 2590 V_fw_tables_max = IPFW_TABLES_MAX; 2591 if (V_fw_tables_max > 65534) 2592 V_fw_tables_max = 65534; 2593 |
|
2569 /* insert the default rule and create the initial map */ 2570 chain->n_rules = 1; 2571 chain->static_len = sizeof(struct ip_fw); | 2594 /* insert the default rule and create the initial map */ 2595 chain->n_rules = 1; 2596 chain->static_len = sizeof(struct ip_fw); |
2572 chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_NOWAIT | M_ZERO); | 2597 chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_WAITOK | M_ZERO); |
2573 if (chain->map) | 2598 if (chain->map) |
2574 rule = malloc(chain->static_len, M_IPFW, M_NOWAIT | M_ZERO); 2575 if (rule == NULL) { 2576 if (chain->map) 2577 free(chain->map, M_IPFW); 2578 printf("ipfw2: ENOSPC initializing default rule " 2579 "(support disabled)\n"); 2580 return (ENOSPC); 2581 } | 2599 rule = malloc(chain->static_len, M_IPFW, M_WAITOK | M_ZERO); |
2582 error = ipfw_init_tables(chain); 2583 if (error) { | 2600 error = ipfw_init_tables(chain); 2601 if (error) { |
2584 panic("init_tables"); /* XXX Marko fix this ! */ | 2602 printf("ipfw2: setting up tables failed\n"); 2603 free(chain->map, M_IPFW); 2604 free(rule, M_IPFW); 2605 return (ENOSPC); |
2585 } 2586 2587 /* fill and insert the default rule */ 2588 rule->act_ofs = 0; 2589 rule->rulenum = IPFW_DEFAULT_RULE; 2590 rule->cmd_len = 1; 2591 rule->set = RESVD_SET; 2592 rule->cmd[0].len = 1; --- 46 unchanged lines hidden (view full) --- 2639 (void)ipfw_attach_hooks(0 /* detach */); 2640 V_ip_fw_chk_ptr = NULL; 2641 V_ip_fw_ctl_ptr = NULL; 2642 IPFW_UH_WLOCK(chain); 2643 IPFW_UH_WUNLOCK(chain); 2644 IPFW_UH_WLOCK(chain); 2645 2646 IPFW_WLOCK(chain); | 2606 } 2607 2608 /* fill and insert the default rule */ 2609 rule->act_ofs = 0; 2610 rule->rulenum = IPFW_DEFAULT_RULE; 2611 rule->cmd_len = 1; 2612 rule->set = RESVD_SET; 2613 rule->cmd[0].len = 1; --- 46 unchanged lines hidden (view full) --- 2660 (void)ipfw_attach_hooks(0 /* detach */); 2661 V_ip_fw_chk_ptr = NULL; 2662 V_ip_fw_ctl_ptr = NULL; 2663 IPFW_UH_WLOCK(chain); 2664 IPFW_UH_WUNLOCK(chain); 2665 IPFW_UH_WLOCK(chain); 2666 2667 IPFW_WLOCK(chain); |
2668 ipfw_dyn_uninit(0); /* run the callout_drain */ |
|
2647 IPFW_WUNLOCK(chain); | 2669 IPFW_WUNLOCK(chain); |
2648 IPFW_WLOCK(chain); | |
2649 | 2670 |
2650 ipfw_dyn_uninit(0); /* run the callout_drain */ | |
2651 ipfw_destroy_tables(chain); 2652 reap = NULL; | 2671 ipfw_destroy_tables(chain); 2672 reap = NULL; |
2673 IPFW_WLOCK(chain); |
|
2653 for (i = 0; i < chain->n_rules; i++) { 2654 rule = chain->map[i]; 2655 rule->x_next = reap; 2656 reap = rule; 2657 } 2658 if (chain->map) 2659 free(chain->map, M_IPFW); 2660 IPFW_WUNLOCK(chain); --- 79 unchanged lines hidden --- | 2674 for (i = 0; i < chain->n_rules; i++) { 2675 rule = chain->map[i]; 2676 rule->x_next = reap; 2677 reap = rule; 2678 } 2679 if (chain->map) 2680 free(chain->map, M_IPFW); 2681 IPFW_WUNLOCK(chain); --- 79 unchanged lines hidden --- |