13b3a8eb9SGleb Smirnoff /*- 23b3a8eb9SGleb Smirnoff * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 33b3a8eb9SGleb Smirnoff * 43b3a8eb9SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 53b3a8eb9SGleb Smirnoff * modification, are permitted provided that the following conditions 63b3a8eb9SGleb Smirnoff * are met: 73b3a8eb9SGleb Smirnoff * 1. Redistributions of source code must retain the above copyright 83b3a8eb9SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 93b3a8eb9SGleb Smirnoff * 2. Redistributions in binary form must reproduce the above copyright 103b3a8eb9SGleb Smirnoff * notice, this list of conditions and the following disclaimer in the 113b3a8eb9SGleb Smirnoff * documentation and/or other materials provided with the distribution. 123b3a8eb9SGleb Smirnoff * 133b3a8eb9SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 143b3a8eb9SGleb Smirnoff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 153b3a8eb9SGleb Smirnoff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 163b3a8eb9SGleb Smirnoff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 173b3a8eb9SGleb Smirnoff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 183b3a8eb9SGleb Smirnoff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 193b3a8eb9SGleb Smirnoff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 203b3a8eb9SGleb Smirnoff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 213b3a8eb9SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 223b3a8eb9SGleb Smirnoff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 233b3a8eb9SGleb Smirnoff * SUCH DAMAGE. 243b3a8eb9SGleb Smirnoff * 253b3a8eb9SGleb Smirnoff * $FreeBSD$ 263b3a8eb9SGleb Smirnoff */ 273b3a8eb9SGleb Smirnoff 283b3a8eb9SGleb Smirnoff #ifndef _IPFW2_PRIVATE_H 293b3a8eb9SGleb Smirnoff #define _IPFW2_PRIVATE_H 303b3a8eb9SGleb Smirnoff 313b3a8eb9SGleb Smirnoff /* 323b3a8eb9SGleb Smirnoff * Internal constants and data structures used by ipfw components 333b3a8eb9SGleb Smirnoff * and not meant to be exported outside the kernel. 343b3a8eb9SGleb Smirnoff */ 353b3a8eb9SGleb Smirnoff 363b3a8eb9SGleb Smirnoff #ifdef _KERNEL 373b3a8eb9SGleb Smirnoff 383b3a8eb9SGleb Smirnoff /* 393b3a8eb9SGleb Smirnoff * For platforms that do not have SYSCTL support, we wrap the 403b3a8eb9SGleb Smirnoff * SYSCTL_* into a function (one per file) to collect the values 413b3a8eb9SGleb Smirnoff * into an array at module initialization. The wrapping macros, 423b3a8eb9SGleb Smirnoff * SYSBEGIN() and SYSEND, are empty in the default case. 433b3a8eb9SGleb Smirnoff */ 443b3a8eb9SGleb Smirnoff #ifndef SYSBEGIN 453b3a8eb9SGleb Smirnoff #define SYSBEGIN(x) 463b3a8eb9SGleb Smirnoff #endif 473b3a8eb9SGleb Smirnoff #ifndef SYSEND 483b3a8eb9SGleb Smirnoff #define SYSEND 493b3a8eb9SGleb Smirnoff #endif 503b3a8eb9SGleb Smirnoff 513b3a8eb9SGleb Smirnoff /* Return values from ipfw_chk() */ 523b3a8eb9SGleb Smirnoff enum { 533b3a8eb9SGleb Smirnoff IP_FW_PASS = 0, 543b3a8eb9SGleb Smirnoff IP_FW_DENY, 553b3a8eb9SGleb Smirnoff IP_FW_DIVERT, 563b3a8eb9SGleb Smirnoff IP_FW_TEE, 573b3a8eb9SGleb Smirnoff IP_FW_DUMMYNET, 583b3a8eb9SGleb Smirnoff IP_FW_NETGRAPH, 593b3a8eb9SGleb Smirnoff IP_FW_NGTEE, 603b3a8eb9SGleb Smirnoff IP_FW_NAT, 613b3a8eb9SGleb Smirnoff IP_FW_REASS, 623b3a8eb9SGleb Smirnoff }; 633b3a8eb9SGleb Smirnoff 643b3a8eb9SGleb Smirnoff /* 653b3a8eb9SGleb Smirnoff * Structure for collecting parameters to dummynet for ip6_output forwarding 663b3a8eb9SGleb Smirnoff */ 673b3a8eb9SGleb Smirnoff struct _ip6dn_args { 683b3a8eb9SGleb Smirnoff struct ip6_pktopts *opt_or; 693b3a8eb9SGleb Smirnoff int flags_or; 703b3a8eb9SGleb Smirnoff struct ip6_moptions *im6o_or; 713b3a8eb9SGleb Smirnoff struct ifnet *origifp_or; 723b3a8eb9SGleb Smirnoff struct ifnet *ifp_or; 733b3a8eb9SGleb Smirnoff struct sockaddr_in6 dst_or; 743b3a8eb9SGleb Smirnoff u_long mtu_or; 753b3a8eb9SGleb Smirnoff }; 763b3a8eb9SGleb Smirnoff 773b3a8eb9SGleb Smirnoff 783b3a8eb9SGleb Smirnoff /* 793b3a8eb9SGleb Smirnoff * Arguments for calling ipfw_chk() and dummynet_io(). We put them 803b3a8eb9SGleb Smirnoff * all into a structure because this way it is easier and more 813b3a8eb9SGleb Smirnoff * efficient to pass variables around and extend the interface. 823b3a8eb9SGleb Smirnoff */ 833b3a8eb9SGleb Smirnoff struct ip_fw_args { 843b3a8eb9SGleb Smirnoff struct mbuf *m; /* the mbuf chain */ 853b3a8eb9SGleb Smirnoff struct ifnet *oif; /* output interface */ 863b3a8eb9SGleb Smirnoff struct sockaddr_in *next_hop; /* forward address */ 873b3a8eb9SGleb Smirnoff struct sockaddr_in6 *next_hop6; /* ipv6 forward address */ 883b3a8eb9SGleb Smirnoff 893b3a8eb9SGleb Smirnoff /* 903b3a8eb9SGleb Smirnoff * On return, it points to the matching rule. 913b3a8eb9SGleb Smirnoff * On entry, rule.slot > 0 means the info is valid and 923b3a8eb9SGleb Smirnoff * contains the starting rule for an ipfw search. 933b3a8eb9SGleb Smirnoff * If chain_id == chain->id && slot >0 then jump to that slot. 943b3a8eb9SGleb Smirnoff * Otherwise, we locate the first rule >= rulenum:rule_id 953b3a8eb9SGleb Smirnoff */ 963b3a8eb9SGleb Smirnoff struct ipfw_rule_ref rule; /* match/restart info */ 973b3a8eb9SGleb Smirnoff 983b3a8eb9SGleb Smirnoff struct ether_header *eh; /* for bridged packets */ 993b3a8eb9SGleb Smirnoff 1003b3a8eb9SGleb Smirnoff struct ipfw_flow_id f_id; /* grabbed from IP header */ 1013b3a8eb9SGleb Smirnoff //uint32_t cookie; /* a cookie depending on rule action */ 1023b3a8eb9SGleb Smirnoff struct inpcb *inp; 1033b3a8eb9SGleb Smirnoff 1043b3a8eb9SGleb Smirnoff struct _ip6dn_args dummypar; /* dummynet->ip6_output */ 1052530ed9eSAndrey V. Elsukov union { /* store here if cannot use a pointer */ 1062530ed9eSAndrey V. Elsukov struct sockaddr_in hopstore; 1072530ed9eSAndrey V. Elsukov struct sockaddr_in6 hopstore6; 1082530ed9eSAndrey V. Elsukov }; 1093b3a8eb9SGleb Smirnoff }; 1103b3a8eb9SGleb Smirnoff 1113b3a8eb9SGleb Smirnoff MALLOC_DECLARE(M_IPFW); 1123b3a8eb9SGleb Smirnoff 1133b3a8eb9SGleb Smirnoff /* 1143b3a8eb9SGleb Smirnoff * Hooks sometime need to know the direction of the packet 1153b3a8eb9SGleb Smirnoff * (divert, dummynet, netgraph, ...) 1163b3a8eb9SGleb Smirnoff * We use a generic definition here, with bit0-1 indicating the 1173b3a8eb9SGleb Smirnoff * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the 1183b3a8eb9SGleb Smirnoff * specific protocol 1193b3a8eb9SGleb Smirnoff * indicating the protocol (if necessary) 1203b3a8eb9SGleb Smirnoff */ 1213b3a8eb9SGleb Smirnoff enum { 1223b3a8eb9SGleb Smirnoff DIR_MASK = 0x3, 1233b3a8eb9SGleb Smirnoff DIR_OUT = 0, 1243b3a8eb9SGleb Smirnoff DIR_IN = 1, 1253b3a8eb9SGleb Smirnoff DIR_FWD = 2, 1263b3a8eb9SGleb Smirnoff DIR_DROP = 3, 1273b3a8eb9SGleb Smirnoff PROTO_LAYER2 = 0x4, /* set for layer 2 */ 1283b3a8eb9SGleb Smirnoff /* PROTO_DEFAULT = 0, */ 1293b3a8eb9SGleb Smirnoff PROTO_IPV4 = 0x08, 1303b3a8eb9SGleb Smirnoff PROTO_IPV6 = 0x10, 1313b3a8eb9SGleb Smirnoff PROTO_IFB = 0x0c, /* layer2 + ifbridge */ 1323b3a8eb9SGleb Smirnoff /* PROTO_OLDBDG = 0x14, unused, old bridge */ 1333b3a8eb9SGleb Smirnoff }; 1343b3a8eb9SGleb Smirnoff 1353b3a8eb9SGleb Smirnoff /* wrapper for freeing a packet, in case we need to do more work */ 1363b3a8eb9SGleb Smirnoff #ifndef FREE_PKT 1373b3a8eb9SGleb Smirnoff #if defined(__linux__) || defined(_WIN32) 1383b3a8eb9SGleb Smirnoff #define FREE_PKT(m) netisr_dispatch(-1, m) 1393b3a8eb9SGleb Smirnoff #else 1403b3a8eb9SGleb Smirnoff #define FREE_PKT(m) m_freem(m) 1413b3a8eb9SGleb Smirnoff #endif 1423b3a8eb9SGleb Smirnoff #endif /* !FREE_PKT */ 1433b3a8eb9SGleb Smirnoff 1443b3a8eb9SGleb Smirnoff /* 1453b3a8eb9SGleb Smirnoff * Function definitions. 1463b3a8eb9SGleb Smirnoff */ 1473b3a8eb9SGleb Smirnoff 1483b3a8eb9SGleb Smirnoff /* attach (arg = 1) or detach (arg = 0) hooks */ 1493b3a8eb9SGleb Smirnoff int ipfw_attach_hooks(int); 1503b3a8eb9SGleb Smirnoff #ifdef NOTYET 1513b3a8eb9SGleb Smirnoff void ipfw_nat_destroy(void); 1523b3a8eb9SGleb Smirnoff #endif 1533b3a8eb9SGleb Smirnoff 1543b3a8eb9SGleb Smirnoff /* In ip_fw_log.c */ 1553b3a8eb9SGleb Smirnoff struct ip; 1560cba2b28SAlexander V. Chernikov struct ip_fw_chain; 1573b3a8eb9SGleb Smirnoff void ipfw_log_bpf(int); 1580cba2b28SAlexander V. Chernikov void ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, 1590cba2b28SAlexander V. Chernikov struct ip_fw_args *args, struct mbuf *m, struct ifnet *oif, 1600cba2b28SAlexander V. Chernikov u_short offset, uint32_t tablearg, struct ip *ip); 1613b3a8eb9SGleb Smirnoff VNET_DECLARE(u_int64_t, norule_counter); 1623b3a8eb9SGleb Smirnoff #define V_norule_counter VNET(norule_counter) 1633b3a8eb9SGleb Smirnoff VNET_DECLARE(int, verbose_limit); 1643b3a8eb9SGleb Smirnoff #define V_verbose_limit VNET(verbose_limit) 1653b3a8eb9SGleb Smirnoff 1663b3a8eb9SGleb Smirnoff /* In ip_fw_dynamic.c */ 1673b3a8eb9SGleb Smirnoff 1683b3a8eb9SGleb Smirnoff enum { /* result for matching dynamic rules */ 1693b3a8eb9SGleb Smirnoff MATCH_REVERSE = 0, 1703b3a8eb9SGleb Smirnoff MATCH_FORWARD, 1713b3a8eb9SGleb Smirnoff MATCH_NONE, 1723b3a8eb9SGleb Smirnoff MATCH_UNKNOWN, 1733b3a8eb9SGleb Smirnoff }; 1743b3a8eb9SGleb Smirnoff 1753b3a8eb9SGleb Smirnoff /* 1763b3a8eb9SGleb Smirnoff * The lock for dynamic rules is only used once outside the file, 1773b3a8eb9SGleb Smirnoff * and only to release the result of lookup_dyn_rule(). 1783b3a8eb9SGleb Smirnoff * Eventually we may implement it with a callback on the function. 1793b3a8eb9SGleb Smirnoff */ 1802e089d5cSAlexander V. Chernikov struct ip_fw_chain; 181563b5ab1SAlexander V. Chernikov struct sockopt_data; 182a73d728dSAlexander V. Chernikov int ipfw_is_dyn_rule(struct ip_fw *rule); 183a73d728dSAlexander V. Chernikov void ipfw_expire_dyn_rules(struct ip_fw_chain *, ipfw_range_tlv *); 1842e089d5cSAlexander V. Chernikov void ipfw_dyn_unlock(ipfw_dyn_rule *q); 1853b3a8eb9SGleb Smirnoff 1863b3a8eb9SGleb Smirnoff struct tcphdr; 1873b3a8eb9SGleb Smirnoff struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *, 1883b3a8eb9SGleb Smirnoff u_int32_t, u_int32_t, int); 1890cba2b28SAlexander V. Chernikov int ipfw_install_state(struct ip_fw_chain *chain, struct ip_fw *rule, 1900cba2b28SAlexander V. Chernikov ipfw_insn_limit *cmd, struct ip_fw_args *args, uint32_t tablearg); 1913b3a8eb9SGleb Smirnoff ipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt, 1923b3a8eb9SGleb Smirnoff int *match_direction, struct tcphdr *tcp); 1933b3a8eb9SGleb Smirnoff void ipfw_remove_dyn_children(struct ip_fw *rule); 1942e089d5cSAlexander V. Chernikov void ipfw_get_dynamic(struct ip_fw_chain *chain, char **bp, const char *ep); 195563b5ab1SAlexander V. Chernikov int ipfw_dump_states(struct ip_fw_chain *chain, struct sockopt_data *sd); 1963b3a8eb9SGleb Smirnoff 1972e089d5cSAlexander V. Chernikov void ipfw_dyn_init(struct ip_fw_chain *); /* per-vnet initialization */ 1983b3a8eb9SGleb Smirnoff void ipfw_dyn_uninit(int); /* per-vnet deinitialization */ 1993b3a8eb9SGleb Smirnoff int ipfw_dyn_len(void); 2006447bae6SAlexander V. Chernikov int ipfw_dyn_get_count(void); 2013b3a8eb9SGleb Smirnoff 2023b3a8eb9SGleb Smirnoff /* common variables */ 2033b3a8eb9SGleb Smirnoff VNET_DECLARE(int, fw_one_pass); 2043b3a8eb9SGleb Smirnoff #define V_fw_one_pass VNET(fw_one_pass) 2053b3a8eb9SGleb Smirnoff 2063b3a8eb9SGleb Smirnoff VNET_DECLARE(int, fw_verbose); 2073b3a8eb9SGleb Smirnoff #define V_fw_verbose VNET(fw_verbose) 2083b3a8eb9SGleb Smirnoff 2093b3a8eb9SGleb Smirnoff VNET_DECLARE(struct ip_fw_chain, layer3_chain); 2103b3a8eb9SGleb Smirnoff #define V_layer3_chain VNET(layer3_chain) 2113b3a8eb9SGleb Smirnoff 21298eff10eSAlexander V. Chernikov VNET_DECLARE(int, ipfw_vnet_ready); 21398eff10eSAlexander V. Chernikov #define V_ipfw_vnet_ready VNET(ipfw_vnet_ready) 21498eff10eSAlexander V. Chernikov 2153b3a8eb9SGleb Smirnoff VNET_DECLARE(u_int32_t, set_disable); 2163b3a8eb9SGleb Smirnoff #define V_set_disable VNET(set_disable) 2173b3a8eb9SGleb Smirnoff 2183b3a8eb9SGleb Smirnoff VNET_DECLARE(int, autoinc_step); 2193b3a8eb9SGleb Smirnoff #define V_autoinc_step VNET(autoinc_step) 2203b3a8eb9SGleb Smirnoff 2213b3a8eb9SGleb Smirnoff VNET_DECLARE(unsigned int, fw_tables_max); 2223b3a8eb9SGleb Smirnoff #define V_fw_tables_max VNET(fw_tables_max) 2233b3a8eb9SGleb Smirnoff 224b074b7bbSAlexander V. Chernikov VNET_DECLARE(unsigned int, fw_tables_sets); 225b074b7bbSAlexander V. Chernikov #define V_fw_tables_sets VNET(fw_tables_sets) 226b074b7bbSAlexander V. Chernikov 227b074b7bbSAlexander V. Chernikov struct tables_config; 228b074b7bbSAlexander V. Chernikov 2297e767c79SAlexander V. Chernikov #ifdef _KERNEL 2307e767c79SAlexander V. Chernikov /* 2317e767c79SAlexander V. Chernikov * Here we have the structure representing an ipfw rule. 2327e767c79SAlexander V. Chernikov * 2337e767c79SAlexander V. Chernikov * It starts with a general area 2347e767c79SAlexander V. Chernikov * followed by an array of one or more instructions, which the code 2357e767c79SAlexander V. Chernikov * accesses as an array of 32-bit values. 2367e767c79SAlexander V. Chernikov * 2377e767c79SAlexander V. Chernikov * Given a rule pointer r: 2387e767c79SAlexander V. Chernikov * 2397e767c79SAlexander V. Chernikov * r->cmd is the start of the first instruction. 2407e767c79SAlexander V. Chernikov * ACTION_PTR(r) is the start of the first action (things to do 2417e767c79SAlexander V. Chernikov * once a rule matched). 2427e767c79SAlexander V. Chernikov */ 2437e767c79SAlexander V. Chernikov 2447e767c79SAlexander V. Chernikov struct ip_fw { 2457e767c79SAlexander V. Chernikov uint16_t act_ofs; /* offset of action in 32-bit units */ 2467e767c79SAlexander V. Chernikov uint16_t cmd_len; /* # of 32-bit words in cmd */ 2477e767c79SAlexander V. Chernikov uint16_t rulenum; /* rule number */ 2487e767c79SAlexander V. Chernikov uint8_t set; /* rule set (0..31) */ 2497e767c79SAlexander V. Chernikov uint8_t flags; /* currently unused */ 2507e767c79SAlexander V. Chernikov counter_u64_t cntr; /* Pointer to rule counters */ 2517e767c79SAlexander V. Chernikov uint32_t timestamp; /* tv_sec of last match */ 2527e767c79SAlexander V. Chernikov uint32_t id; /* rule id */ 253030b184fSAlexander V. Chernikov uint32_t cached_id; /* used by jump_fast */ 254030b184fSAlexander V. Chernikov uint32_t cached_pos; /* used by jump_fast */ 2557e767c79SAlexander V. Chernikov 2567e767c79SAlexander V. Chernikov ipfw_insn cmd[1]; /* storage for commands */ 2577e767c79SAlexander V. Chernikov }; 2587e767c79SAlexander V. Chernikov 2593535eac4SAlexander V. Chernikov #define IPFW_RULE_CNTR_SIZE (2 * sizeof(uint64_t)) 2600d90989bSAlexander V. Chernikov 2617e767c79SAlexander V. Chernikov #endif 2627e767c79SAlexander V. Chernikov 2633b3a8eb9SGleb Smirnoff struct ip_fw_chain { 2643b3a8eb9SGleb Smirnoff struct ip_fw **map; /* array of rule ptrs to ease lookup */ 2655fa3fdd3SAlexander V. Chernikov uint32_t id; /* ruleset id */ 2665fa3fdd3SAlexander V. Chernikov int n_rules; /* number of static rules */ 2679f7d47b0SAlexander V. Chernikov void *tablestate; /* runtime table info */ 2680cba2b28SAlexander V. Chernikov void *valuestate; /* runtime table value info */ 269d5eb80cbSAlexander V. Chernikov int *idxmap; /* skipto array of rules */ 27074b22066SAlexander V. Chernikov void **srvstate; /* runtime service mappings */ 2713b3a8eb9SGleb Smirnoff #if defined( __linux__ ) || defined( _WIN32 ) 2723b3a8eb9SGleb Smirnoff spinlock_t rwmtx; 2733b3a8eb9SGleb Smirnoff #else 274ccba94b8SAlexander V. Chernikov struct rmlock rwmtx; 2755fa3fdd3SAlexander V. Chernikov #endif 2767e767c79SAlexander V. Chernikov int static_len; /* total len of static rules (v0) */ 2775fa3fdd3SAlexander V. Chernikov uint32_t gencnt; /* NAT generation count */ 27874b22066SAlexander V. Chernikov LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */ 2795fa3fdd3SAlexander V. Chernikov struct ip_fw *default_rule; 280b074b7bbSAlexander V. Chernikov struct tables_config *tblcfg; /* tables module data */ 28168394ec8SAlexander V. Chernikov void *ifcfg; /* interface module data */ 282d5eb80cbSAlexander V. Chernikov int *idxmap_back; /* standby skipto array of rules */ 28374b22066SAlexander V. Chernikov struct namedobj_instance *srvmap; /* cfg name->number mappings */ 2845fa3fdd3SAlexander V. Chernikov #if defined( __linux__ ) || defined( _WIN32 ) 2855fa3fdd3SAlexander V. Chernikov spinlock_t uh_lock; 2865fa3fdd3SAlexander V. Chernikov #else 2873b3a8eb9SGleb Smirnoff struct rwlock uh_lock; /* lock for upper half */ 2883b3a8eb9SGleb Smirnoff #endif 2893b3a8eb9SGleb Smirnoff }; 2903b3a8eb9SGleb Smirnoff 2910cba2b28SAlexander V. Chernikov /* 64-byte structure representing multi-field table value */ 2920cba2b28SAlexander V. Chernikov struct table_value { 2930cba2b28SAlexander V. Chernikov uint32_t tag; /* O_TAG/O_TAGGED */ 2940cba2b28SAlexander V. Chernikov uint32_t pipe; /* O_PIPE/O_QUEUE */ 2950cba2b28SAlexander V. Chernikov uint16_t divert; /* O_DIVERT/O_TEE */ 2960cba2b28SAlexander V. Chernikov uint16_t skipto; /* skipto, CALLRET */ 2970cba2b28SAlexander V. Chernikov uint32_t netgraph; /* O_NETGRAPH/O_NGTEE */ 2980cba2b28SAlexander V. Chernikov uint32_t fib; /* O_SETFIB */ 2990cba2b28SAlexander V. Chernikov uint32_t nat; /* O_NAT */ 3000cba2b28SAlexander V. Chernikov uint32_t nh4; 3010cba2b28SAlexander V. Chernikov uint8_t dscp; 3022530ed9eSAndrey V. Elsukov uint8_t spare0; 3032530ed9eSAndrey V. Elsukov uint16_t spare1; 3040cba2b28SAlexander V. Chernikov /* -- 32 bytes -- */ 3050cba2b28SAlexander V. Chernikov struct in6_addr nh6; 3060cba2b28SAlexander V. Chernikov uint32_t limit; /* O_LIMIT */ 3072530ed9eSAndrey V. Elsukov uint32_t zoneid; /* scope zone id for nh6 */ 3080cba2b28SAlexander V. Chernikov uint64_t refcnt; /* Number of references */ 3090cba2b28SAlexander V. Chernikov }; 3100cba2b28SAlexander V. Chernikov 31168394ec8SAlexander V. Chernikov 31268394ec8SAlexander V. Chernikov struct named_object { 31368394ec8SAlexander V. Chernikov TAILQ_ENTRY(named_object) nn_next; /* namehash */ 31468394ec8SAlexander V. Chernikov TAILQ_ENTRY(named_object) nv_next; /* valuehash */ 31568394ec8SAlexander V. Chernikov char *name; /* object name */ 31674b22066SAlexander V. Chernikov uint8_t subtype; /* object subtype within class */ 31774b22066SAlexander V. Chernikov uint8_t etlv; /* Export TLV id */ 31874b22066SAlexander V. Chernikov uint16_t spare[2]; 31968394ec8SAlexander V. Chernikov uint16_t kidx; /* object kernel index */ 32068394ec8SAlexander V. Chernikov uint32_t set; /* set object belongs to */ 32168394ec8SAlexander V. Chernikov uint32_t refcnt; /* number of references */ 32268394ec8SAlexander V. Chernikov }; 32368394ec8SAlexander V. Chernikov TAILQ_HEAD(namedobjects_head, named_object); 32468394ec8SAlexander V. Chernikov 3253b3a8eb9SGleb Smirnoff struct sockopt; /* used by tcp_var.h */ 3262d99a349SAlexander V. Chernikov struct sockopt_data { 3272d99a349SAlexander V. Chernikov caddr_t kbuf; /* allocated buffer */ 3282d99a349SAlexander V. Chernikov size_t ksize; /* given buffer size */ 3292d99a349SAlexander V. Chernikov size_t koff; /* data already used */ 3302d99a349SAlexander V. Chernikov size_t kavail; /* number of bytes available */ 3312d99a349SAlexander V. Chernikov size_t ktotal; /* total bytes pushed */ 3322d99a349SAlexander V. Chernikov struct sockopt *sopt; /* socket data */ 333b6ee846eSAlexander V. Chernikov caddr_t sopt_val; /* sopt user buffer */ 3342d99a349SAlexander V. Chernikov size_t valsize; /* original data size */ 3352d99a349SAlexander V. Chernikov }; 3363b3a8eb9SGleb Smirnoff 33768394ec8SAlexander V. Chernikov struct ipfw_ifc; 33868394ec8SAlexander V. Chernikov 33968394ec8SAlexander V. Chernikov typedef void (ipfw_ifc_cb)(struct ip_fw_chain *ch, void *cbdata, 34068394ec8SAlexander V. Chernikov uint16_t ifindex); 34168394ec8SAlexander V. Chernikov 34268394ec8SAlexander V. Chernikov struct ipfw_iface { 34368394ec8SAlexander V. Chernikov struct named_object no; 34468394ec8SAlexander V. Chernikov char ifname[64]; 34568394ec8SAlexander V. Chernikov int resolved; 34668394ec8SAlexander V. Chernikov uint16_t ifindex; 34768394ec8SAlexander V. Chernikov uint16_t spare; 34868394ec8SAlexander V. Chernikov uint64_t gencnt; 34968394ec8SAlexander V. Chernikov TAILQ_HEAD(, ipfw_ifc) consumers; 35068394ec8SAlexander V. Chernikov }; 35168394ec8SAlexander V. Chernikov 35268394ec8SAlexander V. Chernikov struct ipfw_ifc { 35368394ec8SAlexander V. Chernikov TAILQ_ENTRY(ipfw_ifc) next; 35468394ec8SAlexander V. Chernikov struct ipfw_iface *iface; 35568394ec8SAlexander V. Chernikov ipfw_ifc_cb *cb; 35668394ec8SAlexander V. Chernikov void *cbdata; 35768394ec8SAlexander V. Chernikov }; 35868394ec8SAlexander V. Chernikov 359c187c1fbSAlexander V. Chernikov /* Macro for working with various counters */ 3607e767c79SAlexander V. Chernikov #define IPFW_INC_RULE_COUNTER(_cntr, _bytes) do { \ 3617e767c79SAlexander V. Chernikov counter_u64_add((_cntr)->cntr, 1); \ 3627e767c79SAlexander V. Chernikov counter_u64_add((_cntr)->cntr + 1, _bytes); \ 3637e767c79SAlexander V. Chernikov if ((_cntr)->timestamp != time_uptime) \ 3647e767c79SAlexander V. Chernikov (_cntr)->timestamp = time_uptime; \ 3657e767c79SAlexander V. Chernikov } while (0) 3667e767c79SAlexander V. Chernikov 3677e767c79SAlexander V. Chernikov #define IPFW_INC_DYN_COUNTER(_cntr, _bytes) do { \ 3687e767c79SAlexander V. Chernikov (_cntr)->pcnt++; \ 3697e767c79SAlexander V. Chernikov (_cntr)->bcnt += _bytes; \ 3707e767c79SAlexander V. Chernikov } while (0) 3717e767c79SAlexander V. Chernikov 3727e767c79SAlexander V. Chernikov #define IPFW_ZERO_RULE_COUNTER(_cntr) do { \ 3737e767c79SAlexander V. Chernikov counter_u64_zero((_cntr)->cntr); \ 3747e767c79SAlexander V. Chernikov counter_u64_zero((_cntr)->cntr + 1); \ 3757e767c79SAlexander V. Chernikov (_cntr)->timestamp = 0; \ 3767e767c79SAlexander V. Chernikov } while (0) 3777e767c79SAlexander V. Chernikov 3787e767c79SAlexander V. Chernikov #define IPFW_ZERO_DYN_COUNTER(_cntr) do { \ 3797e767c79SAlexander V. Chernikov (_cntr)->pcnt = 0; \ 3807e767c79SAlexander V. Chernikov (_cntr)->bcnt = 0; \ 3817e767c79SAlexander V. Chernikov } while (0) 3827e767c79SAlexander V. Chernikov 3830cba2b28SAlexander V. Chernikov #define TARG_VAL(ch, k, f) ((struct table_value *)((ch)->valuestate))[k].f 3840cba2b28SAlexander V. Chernikov #define IP_FW_ARG_TABLEARG(ch, a, f) \ 3850cba2b28SAlexander V. Chernikov (((a) == IP_FW_TARG) ? TARG_VAL(ch, tablearg, f) : (a)) 3863b3a8eb9SGleb Smirnoff /* 3873b3a8eb9SGleb Smirnoff * The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c 3883b3a8eb9SGleb Smirnoff * so the variable and the macros must be here. 3893b3a8eb9SGleb Smirnoff */ 3903b3a8eb9SGleb Smirnoff 391ccba94b8SAlexander V. Chernikov #if defined( __linux__ ) || defined( _WIN32 ) 3923b3a8eb9SGleb Smirnoff #define IPFW_LOCK_INIT(_chain) do { \ 3933b3a8eb9SGleb Smirnoff rw_init(&(_chain)->rwmtx, "IPFW static rules"); \ 3943b3a8eb9SGleb Smirnoff rw_init(&(_chain)->uh_lock, "IPFW UH lock"); \ 3953b3a8eb9SGleb Smirnoff } while (0) 3963b3a8eb9SGleb Smirnoff 3973b3a8eb9SGleb Smirnoff #define IPFW_LOCK_DESTROY(_chain) do { \ 3983b3a8eb9SGleb Smirnoff rw_destroy(&(_chain)->rwmtx); \ 3993b3a8eb9SGleb Smirnoff rw_destroy(&(_chain)->uh_lock); \ 4003b3a8eb9SGleb Smirnoff } while (0) 4013b3a8eb9SGleb Smirnoff 4025d0cd926SAlexander V. Chernikov #define IPFW_RLOCK_ASSERT(_chain) rw_assert(&(_chain)->rwmtx, RA_RLOCKED) 4033b3a8eb9SGleb Smirnoff #define IPFW_WLOCK_ASSERT(_chain) rw_assert(&(_chain)->rwmtx, RA_WLOCKED) 4043b3a8eb9SGleb Smirnoff 405ccba94b8SAlexander V. Chernikov #define IPFW_RLOCK_TRACKER 4063b3a8eb9SGleb Smirnoff #define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx) 4073b3a8eb9SGleb Smirnoff #define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx) 4083b3a8eb9SGleb Smirnoff #define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx) 4093b3a8eb9SGleb Smirnoff #define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx) 41093bb4f9eSAndrey V. Elsukov #define IPFW_PF_RLOCK(p) IPFW_RLOCK(p) 41193bb4f9eSAndrey V. Elsukov #define IPFW_PF_RUNLOCK(p) IPFW_RUNLOCK(p) 412ccba94b8SAlexander V. Chernikov #else /* FreeBSD */ 413ccba94b8SAlexander V. Chernikov #define IPFW_LOCK_INIT(_chain) do { \ 414ccba94b8SAlexander V. Chernikov rm_init(&(_chain)->rwmtx, "IPFW static rules"); \ 415ccba94b8SAlexander V. Chernikov rw_init(&(_chain)->uh_lock, "IPFW UH lock"); \ 416ccba94b8SAlexander V. Chernikov } while (0) 417ccba94b8SAlexander V. Chernikov 418ccba94b8SAlexander V. Chernikov #define IPFW_LOCK_DESTROY(_chain) do { \ 419ccba94b8SAlexander V. Chernikov rm_destroy(&(_chain)->rwmtx); \ 420ccba94b8SAlexander V. Chernikov rw_destroy(&(_chain)->uh_lock); \ 421ccba94b8SAlexander V. Chernikov } while (0) 422ccba94b8SAlexander V. Chernikov 423ccba94b8SAlexander V. Chernikov #define IPFW_RLOCK_ASSERT(_chain) rm_assert(&(_chain)->rwmtx, RA_RLOCKED) 424ccba94b8SAlexander V. Chernikov #define IPFW_WLOCK_ASSERT(_chain) rm_assert(&(_chain)->rwmtx, RA_WLOCKED) 425ccba94b8SAlexander V. Chernikov 426ccba94b8SAlexander V. Chernikov #define IPFW_RLOCK_TRACKER struct rm_priotracker _tracker 427ccba94b8SAlexander V. Chernikov #define IPFW_RLOCK(p) rm_rlock(&(p)->rwmtx, &_tracker) 428ccba94b8SAlexander V. Chernikov #define IPFW_RUNLOCK(p) rm_runlock(&(p)->rwmtx, &_tracker) 429ccba94b8SAlexander V. Chernikov #define IPFW_WLOCK(p) rm_wlock(&(p)->rwmtx) 430ccba94b8SAlexander V. Chernikov #define IPFW_WUNLOCK(p) rm_wunlock(&(p)->rwmtx) 431ccba94b8SAlexander V. Chernikov #define IPFW_PF_RLOCK(p) IPFW_RLOCK(p) 432ccba94b8SAlexander V. Chernikov #define IPFW_PF_RUNLOCK(p) IPFW_RUNLOCK(p) 433ccba94b8SAlexander V. Chernikov #endif 4343b3a8eb9SGleb Smirnoff 4352e089d5cSAlexander V. Chernikov #define IPFW_UH_RLOCK_ASSERT(_chain) rw_assert(&(_chain)->uh_lock, RA_RLOCKED) 4362e089d5cSAlexander V. Chernikov #define IPFW_UH_WLOCK_ASSERT(_chain) rw_assert(&(_chain)->uh_lock, RA_WLOCKED) 4370caab009SAlexander V. Chernikov #define IPFW_UH_UNLOCK_ASSERT(_chain) rw_assert(&(_chain)->uh_lock, RA_UNLOCKED) 4382e089d5cSAlexander V. Chernikov 4393b3a8eb9SGleb Smirnoff #define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock) 4403b3a8eb9SGleb Smirnoff #define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock) 4413b3a8eb9SGleb Smirnoff #define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock) 4423b3a8eb9SGleb Smirnoff #define IPFW_UH_WUNLOCK(p) rw_wunlock(&(p)->uh_lock) 4433b3a8eb9SGleb Smirnoff 444b074b7bbSAlexander V. Chernikov struct obj_idx { 445b074b7bbSAlexander V. Chernikov uint16_t uidx; /* internal index supplied by userland */ 446b074b7bbSAlexander V. Chernikov uint16_t kidx; /* kernel object index */ 447b074b7bbSAlexander V. Chernikov uint16_t off; /* tlv offset from rule end in 4-byte words */ 4480468c5baSAlexander V. Chernikov uint8_t spare; 449b074b7bbSAlexander V. Chernikov uint8_t type; /* object type within its category */ 450b074b7bbSAlexander V. Chernikov }; 451b074b7bbSAlexander V. Chernikov 452b074b7bbSAlexander V. Chernikov struct rule_check_info { 4533a845e10SAlexander V. Chernikov uint16_t flags; /* rule-specific check flags */ 45474b22066SAlexander V. Chernikov uint16_t object_opcodes; /* num of opcodes referencing objects */ 4557e767c79SAlexander V. Chernikov uint16_t urule_numoff; /* offset of rulenum in bytes */ 4567e767c79SAlexander V. Chernikov uint8_t version; /* rule version */ 4573a845e10SAlexander V. Chernikov uint8_t spare; 4586c2997ffSAlexander V. Chernikov ipfw_obj_ctlv *ctlv; /* name TLV containter */ 459b074b7bbSAlexander V. Chernikov struct ip_fw *krule; /* resulting rule pointer */ 4607e767c79SAlexander V. Chernikov caddr_t urule; /* original rule pointer */ 461b074b7bbSAlexander V. Chernikov struct obj_idx obuf[8]; /* table references storage */ 462b074b7bbSAlexander V. Chernikov }; 463b074b7bbSAlexander V. Chernikov 4647e767c79SAlexander V. Chernikov /* Legacy interface support */ 4657e767c79SAlexander V. Chernikov /* 4667e767c79SAlexander V. Chernikov * FreeBSD 8 export rule format 4677e767c79SAlexander V. Chernikov */ 4687e767c79SAlexander V. Chernikov struct ip_fw_rule0 { 4697e767c79SAlexander V. Chernikov struct ip_fw *x_next; /* linked list of rules */ 4707e767c79SAlexander V. Chernikov struct ip_fw *next_rule; /* ptr to next [skipto] rule */ 4717e767c79SAlexander V. Chernikov /* 'next_rule' is used to pass up 'set_disable' status */ 4727e767c79SAlexander V. Chernikov 4737e767c79SAlexander V. Chernikov uint16_t act_ofs; /* offset of action in 32-bit units */ 4747e767c79SAlexander V. Chernikov uint16_t cmd_len; /* # of 32-bit words in cmd */ 4757e767c79SAlexander V. Chernikov uint16_t rulenum; /* rule number */ 4767e767c79SAlexander V. Chernikov uint8_t set; /* rule set (0..31) */ 4777e767c79SAlexander V. Chernikov uint8_t _pad; /* padding */ 4787e767c79SAlexander V. Chernikov uint32_t id; /* rule id */ 4797e767c79SAlexander V. Chernikov 4807e767c79SAlexander V. Chernikov /* These fields are present in all rules. */ 4817e767c79SAlexander V. Chernikov uint64_t pcnt; /* Packet counter */ 4827e767c79SAlexander V. Chernikov uint64_t bcnt; /* Byte counter */ 4837e767c79SAlexander V. Chernikov uint32_t timestamp; /* tv_sec of last match */ 4847e767c79SAlexander V. Chernikov 4857e767c79SAlexander V. Chernikov ipfw_insn cmd[1]; /* storage for commands */ 4867e767c79SAlexander V. Chernikov }; 4877e767c79SAlexander V. Chernikov 4887e767c79SAlexander V. Chernikov struct ip_fw_bcounter0 { 4897e767c79SAlexander V. Chernikov uint64_t pcnt; /* Packet counter */ 4907e767c79SAlexander V. Chernikov uint64_t bcnt; /* Byte counter */ 4917e767c79SAlexander V. Chernikov uint32_t timestamp; /* tv_sec of last match */ 4927e767c79SAlexander V. Chernikov }; 4937e767c79SAlexander V. Chernikov 4947e767c79SAlexander V. Chernikov /* Kernel rule length */ 4957e767c79SAlexander V. Chernikov /* 4967e767c79SAlexander V. Chernikov * RULE _K_ SIZE _V_ -> 4977e767c79SAlexander V. Chernikov * get kernel size from userland rool version _V_. 4987e767c79SAlexander V. Chernikov * RULE _U_ SIZE _V_ -> 4997e767c79SAlexander V. Chernikov * get user size version _V_ from kernel rule 5007e767c79SAlexander V. Chernikov * RULESIZE _V_ -> 5017e767c79SAlexander V. Chernikov * get user size rule length 5027e767c79SAlexander V. Chernikov */ 5037e767c79SAlexander V. Chernikov /* FreeBSD8 <> current kernel format */ 5047e767c79SAlexander V. Chernikov #define RULEUSIZE0(r) (sizeof(struct ip_fw_rule0) + (r)->cmd_len * 4 - 4) 5057e767c79SAlexander V. Chernikov #define RULEKSIZE0(r) roundup2((sizeof(struct ip_fw) + (r)->cmd_len*4 - 4), 8) 5067e767c79SAlexander V. Chernikov /* FreeBSD11 <> current kernel format */ 5077e767c79SAlexander V. Chernikov #define RULEUSIZE1(r) (roundup2(sizeof(struct ip_fw_rule) + \ 5087e767c79SAlexander V. Chernikov (r)->cmd_len * 4 - 4, 8)) 5097e767c79SAlexander V. Chernikov #define RULEKSIZE1(r) roundup2((sizeof(struct ip_fw) + (r)->cmd_len*4 - 4), 8) 5107e767c79SAlexander V. Chernikov 51174b22066SAlexander V. Chernikov /* 51274b22066SAlexander V. Chernikov * Tables/Objects index rewriting code 51374b22066SAlexander V. Chernikov */ 51474b22066SAlexander V. Chernikov 51574b22066SAlexander V. Chernikov /* Default and maximum number of ipfw tables/objects. */ 51674b22066SAlexander V. Chernikov #define IPFW_TABLES_MAX 65536 51774b22066SAlexander V. Chernikov #define IPFW_TABLES_DEFAULT 128 51874b22066SAlexander V. Chernikov #define IPFW_OBJECTS_MAX 65536 51974b22066SAlexander V. Chernikov #define IPFW_OBJECTS_DEFAULT 128 52074b22066SAlexander V. Chernikov 52174b22066SAlexander V. Chernikov #define CHAIN_TO_SRV(ch) ((ch)->srvmap) 52274b22066SAlexander V. Chernikov 52374b22066SAlexander V. Chernikov struct tid_info { 52474b22066SAlexander V. Chernikov uint32_t set; /* table set */ 52574b22066SAlexander V. Chernikov uint16_t uidx; /* table index */ 52674b22066SAlexander V. Chernikov uint8_t type; /* table type */ 52774b22066SAlexander V. Chernikov uint8_t atype; 52874b22066SAlexander V. Chernikov uint8_t spare; 52974b22066SAlexander V. Chernikov int tlen; /* Total TLV size block */ 53074b22066SAlexander V. Chernikov void *tlvs; /* Pointer to first TLV */ 53174b22066SAlexander V. Chernikov }; 53274b22066SAlexander V. Chernikov 53374b22066SAlexander V. Chernikov /* 53474b22066SAlexander V. Chernikov * Classifier callback. Checks if @cmd opcode contains kernel object reference. 53574b22066SAlexander V. Chernikov * If true, returns its index and type. 53674b22066SAlexander V. Chernikov * Returns 0 if match is found, 1 overwise. 53774b22066SAlexander V. Chernikov */ 53874b22066SAlexander V. Chernikov typedef int (ipfw_obj_rw_cl)(ipfw_insn *cmd, uint16_t *puidx, uint8_t *ptype); 53974b22066SAlexander V. Chernikov /* 54074b22066SAlexander V. Chernikov * Updater callback. Sets kernel object reference index to @puidx 54174b22066SAlexander V. Chernikov */ 54274b22066SAlexander V. Chernikov typedef void (ipfw_obj_rw_upd)(ipfw_insn *cmd, uint16_t puidx); 54374b22066SAlexander V. Chernikov /* 54474b22066SAlexander V. Chernikov * Finder callback. Tries to find named object by name (specified via @ti). 54574b22066SAlexander V. Chernikov * Stores found named object pointer in @pno. 54674b22066SAlexander V. Chernikov * If object was not found, NULL is stored. 54774b22066SAlexander V. Chernikov * 54874b22066SAlexander V. Chernikov * Return 0 if input data was valid. 54974b22066SAlexander V. Chernikov */ 55074b22066SAlexander V. Chernikov typedef int (ipfw_obj_fname_cb)(struct ip_fw_chain *ch, 55174b22066SAlexander V. Chernikov struct tid_info *ti, struct named_object **pno); 55274b22066SAlexander V. Chernikov /* 55374b22066SAlexander V. Chernikov * Another finder callback. Tries to findex named object by kernel index. 55474b22066SAlexander V. Chernikov * 55574b22066SAlexander V. Chernikov * Returns pointer to named object or NULL. 55674b22066SAlexander V. Chernikov */ 55774b22066SAlexander V. Chernikov typedef struct named_object *(ipfw_obj_fidx_cb)(struct ip_fw_chain *ch, 55874b22066SAlexander V. Chernikov uint16_t kidx); 55974b22066SAlexander V. Chernikov /* 56074b22066SAlexander V. Chernikov * Object creator callback. Tries to create object specified by @ti. 56174b22066SAlexander V. Chernikov * Stores newly-allocated object index in @pkidx. 56274b22066SAlexander V. Chernikov * 56374b22066SAlexander V. Chernikov * Returns 0 on success. 56474b22066SAlexander V. Chernikov */ 56574b22066SAlexander V. Chernikov typedef int (ipfw_obj_create_cb)(struct ip_fw_chain *ch, struct tid_info *ti, 56674b22066SAlexander V. Chernikov uint16_t *pkidx); 567*1cf09efeSAndrey V. Elsukov /* 568*1cf09efeSAndrey V. Elsukov * Object destroy callback. Intended to free resources allocated by 569*1cf09efeSAndrey V. Elsukov * create_object callback. 570*1cf09efeSAndrey V. Elsukov */ 571*1cf09efeSAndrey V. Elsukov typedef void (ipfw_obj_destroy_cb)(struct ip_fw_chain *ch, 572*1cf09efeSAndrey V. Elsukov struct named_object *no); 57374b22066SAlexander V. Chernikov 57474b22066SAlexander V. Chernikov struct opcode_obj_rewrite { 57574b22066SAlexander V. Chernikov uint32_t opcode; /* Opcode to act upon */ 57674b22066SAlexander V. Chernikov uint32_t etlv; /* Relevant export TLV id */ 57774b22066SAlexander V. Chernikov ipfw_obj_rw_cl *classifier; /* Check if rewrite is needed */ 57874b22066SAlexander V. Chernikov ipfw_obj_rw_upd *update; /* update cmd with new value */ 57974b22066SAlexander V. Chernikov ipfw_obj_fname_cb *find_byname; /* Find named object by name */ 58074b22066SAlexander V. Chernikov ipfw_obj_fidx_cb *find_bykidx; /* Find named object by kidx */ 58174b22066SAlexander V. Chernikov ipfw_obj_create_cb *create_object; /* Create named object */ 582*1cf09efeSAndrey V. Elsukov ipfw_obj_destroy_cb *destroy_object;/* Destroy named object */ 58374b22066SAlexander V. Chernikov }; 58474b22066SAlexander V. Chernikov 58574b22066SAlexander V. Chernikov #define IPFW_ADD_OBJ_REWRITER(f, c) do { \ 58674b22066SAlexander V. Chernikov if ((f) != 0) \ 58774b22066SAlexander V. Chernikov ipfw_add_obj_rewriter(c, \ 58874b22066SAlexander V. Chernikov sizeof(c) / sizeof(c[0])); \ 58974b22066SAlexander V. Chernikov } while(0) 59074b22066SAlexander V. Chernikov #define IPFW_DEL_OBJ_REWRITER(l, c) do { \ 59174b22066SAlexander V. Chernikov if ((l) != 0) \ 59274b22066SAlexander V. Chernikov ipfw_del_obj_rewriter(c, \ 59374b22066SAlexander V. Chernikov sizeof(c) / sizeof(c[0])); \ 59474b22066SAlexander V. Chernikov } while(0) 5957e767c79SAlexander V. Chernikov 59668394ec8SAlexander V. Chernikov /* In ip_fw_iface.c */ 59768394ec8SAlexander V. Chernikov int ipfw_iface_init(void); 59868394ec8SAlexander V. Chernikov void ipfw_iface_destroy(void); 59968394ec8SAlexander V. Chernikov void vnet_ipfw_iface_destroy(struct ip_fw_chain *ch); 60068394ec8SAlexander V. Chernikov int ipfw_iface_ref(struct ip_fw_chain *ch, char *name, 60168394ec8SAlexander V. Chernikov struct ipfw_ifc *ic); 60268394ec8SAlexander V. Chernikov void ipfw_iface_unref(struct ip_fw_chain *ch, struct ipfw_ifc *ic); 60368394ec8SAlexander V. Chernikov void ipfw_iface_add_notify(struct ip_fw_chain *ch, struct ipfw_ifc *ic); 60468394ec8SAlexander V. Chernikov void ipfw_iface_del_notify(struct ip_fw_chain *ch, struct ipfw_ifc *ic); 60568394ec8SAlexander V. Chernikov 6063b3a8eb9SGleb Smirnoff /* In ip_fw_sockopt.c */ 607d5eb80cbSAlexander V. Chernikov void ipfw_init_skipto_cache(struct ip_fw_chain *chain); 608d5eb80cbSAlexander V. Chernikov void ipfw_destroy_skipto_cache(struct ip_fw_chain *chain); 6093b3a8eb9SGleb Smirnoff int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id); 610b429d43cSAlexander V. Chernikov int ipfw_ctl3(struct sockopt *sopt); 6113b3a8eb9SGleb Smirnoff int ipfw_chk(struct ip_fw_args *args); 612030b184fSAlexander V. Chernikov void ipfw_reap_add(struct ip_fw_chain *chain, struct ip_fw **head, 613030b184fSAlexander V. Chernikov struct ip_fw *rule); 6143b3a8eb9SGleb Smirnoff void ipfw_reap_rules(struct ip_fw *head); 6157e767c79SAlexander V. Chernikov void ipfw_init_counters(void); 6167e767c79SAlexander V. Chernikov void ipfw_destroy_counters(void); 6177e767c79SAlexander V. Chernikov struct ip_fw *ipfw_alloc_rule(struct ip_fw_chain *chain, size_t rulesize); 618a73d728dSAlexander V. Chernikov int ipfw_match_range(struct ip_fw *rule, ipfw_range_tlv *rt); 6193b3a8eb9SGleb Smirnoff 6206b988f3aSAlexander V. Chernikov typedef int (sopt_handler_f)(struct ip_fw_chain *ch, 6216b988f3aSAlexander V. Chernikov ip_fw3_opheader *op3, struct sockopt_data *sd); 6226b988f3aSAlexander V. Chernikov struct ipfw_sopt_handler { 6236b988f3aSAlexander V. Chernikov uint16_t opcode; 6246b988f3aSAlexander V. Chernikov uint8_t version; 6256b988f3aSAlexander V. Chernikov uint8_t dir; 6266b988f3aSAlexander V. Chernikov sopt_handler_f *handler; 6276b988f3aSAlexander V. Chernikov uint64_t refcnt; 6286b988f3aSAlexander V. Chernikov }; 6296b988f3aSAlexander V. Chernikov #define HDIR_SET 0x01 /* Handler is used to set some data */ 6306b988f3aSAlexander V. Chernikov #define HDIR_GET 0x02 /* Handler is used to retrieve data */ 6316b988f3aSAlexander V. Chernikov #define HDIR_BOTH HDIR_GET|HDIR_SET 6326b988f3aSAlexander V. Chernikov 6336b988f3aSAlexander V. Chernikov void ipfw_init_sopt_handler(void); 6346b988f3aSAlexander V. Chernikov void ipfw_destroy_sopt_handler(void); 6356b988f3aSAlexander V. Chernikov void ipfw_add_sopt_handler(struct ipfw_sopt_handler *sh, size_t count); 6366b988f3aSAlexander V. Chernikov int ipfw_del_sopt_handler(struct ipfw_sopt_handler *sh, size_t count); 6372d99a349SAlexander V. Chernikov caddr_t ipfw_get_sopt_space(struct sockopt_data *sd, size_t needed); 6382d99a349SAlexander V. Chernikov caddr_t ipfw_get_sopt_header(struct sockopt_data *sd, size_t needed); 6396b988f3aSAlexander V. Chernikov #define IPFW_ADD_SOPT_HANDLER(f, c) do { \ 6406b988f3aSAlexander V. Chernikov if ((f) != 0) \ 6416b988f3aSAlexander V. Chernikov ipfw_add_sopt_handler(c, \ 6426b988f3aSAlexander V. Chernikov sizeof(c) / sizeof(c[0])); \ 6436b988f3aSAlexander V. Chernikov } while(0) 6446b988f3aSAlexander V. Chernikov #define IPFW_DEL_SOPT_HANDLER(l, c) do { \ 6456b988f3aSAlexander V. Chernikov if ((l) != 0) \ 6466b988f3aSAlexander V. Chernikov ipfw_del_sopt_handler(c, \ 6476b988f3aSAlexander V. Chernikov sizeof(c) / sizeof(c[0])); \ 6486b988f3aSAlexander V. Chernikov } while(0) 6492d99a349SAlexander V. Chernikov 65074b22066SAlexander V. Chernikov struct namedobj_instance; 651b074b7bbSAlexander V. Chernikov typedef void (objhash_cb_t)(struct namedobj_instance *ni, struct named_object *, 652b074b7bbSAlexander V. Chernikov void *arg); 65313263632SAlexander V. Chernikov typedef uint32_t (objhash_hash_f)(struct namedobj_instance *ni, void *key, 65413263632SAlexander V. Chernikov uint32_t kopt); 65513263632SAlexander V. Chernikov typedef int (objhash_cmp_f)(struct named_object *no, void *key, uint32_t kopt); 656b074b7bbSAlexander V. Chernikov struct namedobj_instance *ipfw_objhash_create(uint32_t items); 657b074b7bbSAlexander V. Chernikov void ipfw_objhash_destroy(struct namedobj_instance *); 658b074b7bbSAlexander V. Chernikov void ipfw_objhash_bitmap_alloc(uint32_t items, void **idx, int *pblocks); 6599f7d47b0SAlexander V. Chernikov void ipfw_objhash_bitmap_merge(struct namedobj_instance *ni, 6609f7d47b0SAlexander V. Chernikov void **idx, int *blocks); 6619f7d47b0SAlexander V. Chernikov void ipfw_objhash_bitmap_swap(struct namedobj_instance *ni, 662b074b7bbSAlexander V. Chernikov void **idx, int *blocks); 663b074b7bbSAlexander V. Chernikov void ipfw_objhash_bitmap_free(void *idx, int blocks); 66413263632SAlexander V. Chernikov void ipfw_objhash_set_hashf(struct namedobj_instance *ni, objhash_hash_f *f); 665b074b7bbSAlexander V. Chernikov struct named_object *ipfw_objhash_lookup_name(struct namedobj_instance *ni, 666b074b7bbSAlexander V. Chernikov uint32_t set, char *name); 66774b22066SAlexander V. Chernikov struct named_object *ipfw_objhash_lookup_name_type(struct namedobj_instance *ni, 66874b22066SAlexander V. Chernikov uint32_t set, uint32_t type, char *name); 669ac35ff17SAlexander V. Chernikov struct named_object *ipfw_objhash_lookup_kidx(struct namedobj_instance *ni, 670ac35ff17SAlexander V. Chernikov uint16_t idx); 6719490a627SAlexander V. Chernikov int ipfw_objhash_same_name(struct namedobj_instance *ni, struct named_object *a, 6729490a627SAlexander V. Chernikov struct named_object *b); 673b074b7bbSAlexander V. Chernikov void ipfw_objhash_add(struct namedobj_instance *ni, struct named_object *no); 674b074b7bbSAlexander V. Chernikov void ipfw_objhash_del(struct namedobj_instance *ni, struct named_object *no); 6759f7d47b0SAlexander V. Chernikov uint32_t ipfw_objhash_count(struct namedobj_instance *ni); 676b074b7bbSAlexander V. Chernikov void ipfw_objhash_foreach(struct namedobj_instance *ni, objhash_cb_t *f, 677b074b7bbSAlexander V. Chernikov void *arg); 678ac35ff17SAlexander V. Chernikov int ipfw_objhash_free_idx(struct namedobj_instance *ni, uint16_t idx); 679ac35ff17SAlexander V. Chernikov int ipfw_objhash_alloc_idx(void *n, uint16_t *pidx); 68013263632SAlexander V. Chernikov void ipfw_objhash_set_funcs(struct namedobj_instance *ni, 68113263632SAlexander V. Chernikov objhash_hash_f *hash_f, objhash_cmp_f *cmp_f); 6825dc5a0e0SAndrey V. Elsukov void ipfw_export_obj_ntlv(struct named_object *no, ipfw_obj_ntlv *ntlv); 68374b22066SAlexander V. Chernikov void ipfw_init_obj_rewriter(void); 68474b22066SAlexander V. Chernikov void ipfw_destroy_obj_rewriter(void); 68574b22066SAlexander V. Chernikov void ipfw_add_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count); 68674b22066SAlexander V. Chernikov int ipfw_del_obj_rewriter(struct opcode_obj_rewrite *rw, size_t count); 68774b22066SAlexander V. Chernikov 68874b22066SAlexander V. Chernikov int ipfw_rewrite_rule_uidx(struct ip_fw_chain *chain, 68974b22066SAlexander V. Chernikov struct rule_check_info *ci); 69074b22066SAlexander V. Chernikov int ipfw_mark_object_kidx(struct ip_fw_chain *chain, struct ip_fw *rule, 69174b22066SAlexander V. Chernikov uint32_t *bmask); 69274b22066SAlexander V. Chernikov int ref_opcode_object(struct ip_fw_chain *ch, ipfw_insn *cmd, struct tid_info *ti, 69374b22066SAlexander V. Chernikov struct obj_idx *pidx, int *found, int *unresolved); 69474b22066SAlexander V. Chernikov void unref_oib_objects(struct ip_fw_chain *ch, ipfw_insn *cmd, 69574b22066SAlexander V. Chernikov struct obj_idx *oib, struct obj_idx *end); 69674b22066SAlexander V. Chernikov int create_objects_compat(struct ip_fw_chain *ch, ipfw_insn *cmd, 69774b22066SAlexander V. Chernikov struct obj_idx *oib, struct obj_idx *pidx, struct tid_info *ti); 69874b22066SAlexander V. Chernikov void update_opcode_kidx(ipfw_insn *cmd, uint16_t idx); 69974b22066SAlexander V. Chernikov int classify_opcode_kidx(ipfw_insn *cmd, uint16_t *puidx); 70074b22066SAlexander V. Chernikov void ipfw_init_srv(struct ip_fw_chain *ch); 70174b22066SAlexander V. Chernikov void ipfw_destroy_srv(struct ip_fw_chain *ch); 702f81431ccSAndrey V. Elsukov int ipfw_check_object_name_generic(const char *name); 703b074b7bbSAlexander V. Chernikov 7043b3a8eb9SGleb Smirnoff /* In ip_fw_table.c */ 7059f7d47b0SAlexander V. Chernikov struct table_info; 7069f7d47b0SAlexander V. Chernikov 7079f7d47b0SAlexander V. Chernikov typedef int (table_lookup_t)(struct table_info *ti, void *key, uint32_t keylen, 7089f7d47b0SAlexander V. Chernikov uint32_t *val); 7099f7d47b0SAlexander V. Chernikov 7103b3a8eb9SGleb Smirnoff int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr, 7113b3a8eb9SGleb Smirnoff uint32_t *val); 7129f7d47b0SAlexander V. Chernikov int ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, uint16_t plen, 7139f7d47b0SAlexander V. Chernikov void *paddr, uint32_t *val); 7146b988f3aSAlexander V. Chernikov int ipfw_init_tables(struct ip_fw_chain *ch, int first); 7153b3a8eb9SGleb Smirnoff int ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables); 716a73d728dSAlexander V. Chernikov int ipfw_switch_tables_namespace(struct ip_fw_chain *ch, unsigned int nsets); 7176b988f3aSAlexander V. Chernikov void ipfw_destroy_tables(struct ip_fw_chain *ch, int last); 7189f7d47b0SAlexander V. Chernikov 7193b3a8eb9SGleb Smirnoff /* In ip_fw_nat.c -- XXX to be moved to ip_var.h */ 7203b3a8eb9SGleb Smirnoff 7213b3a8eb9SGleb Smirnoff extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int); 7223b3a8eb9SGleb Smirnoff 7233b3a8eb9SGleb Smirnoff typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *); 7243b3a8eb9SGleb Smirnoff typedef int ipfw_nat_cfg_t(struct sockopt *); 7253b3a8eb9SGleb Smirnoff 7268856400bSMikolaj Golub VNET_DECLARE(int, ipfw_nat_ready); 7278856400bSMikolaj Golub #define V_ipfw_nat_ready VNET(ipfw_nat_ready) 7288856400bSMikolaj Golub #define IPFW_NAT_LOADED (V_ipfw_nat_ready) 7293b3a8eb9SGleb Smirnoff 7308856400bSMikolaj Golub extern ipfw_nat_t *ipfw_nat_ptr; 7313b3a8eb9SGleb Smirnoff extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr; 7323b3a8eb9SGleb Smirnoff extern ipfw_nat_cfg_t *ipfw_nat_del_ptr; 7333b3a8eb9SGleb Smirnoff extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr; 7343b3a8eb9SGleb Smirnoff extern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr; 7353b3a8eb9SGleb Smirnoff 736af9aa0a8SAndrey V. Elsukov /* Helper functions for IP checksum adjustment */ 737af9aa0a8SAndrey V. Elsukov static __inline uint16_t 738af9aa0a8SAndrey V. Elsukov cksum_add(uint16_t sum, uint16_t a) 739af9aa0a8SAndrey V. Elsukov { 740af9aa0a8SAndrey V. Elsukov uint16_t res; 741af9aa0a8SAndrey V. Elsukov 742af9aa0a8SAndrey V. Elsukov res = sum + a; 743af9aa0a8SAndrey V. Elsukov return (res + (res < a)); 744af9aa0a8SAndrey V. Elsukov } 745af9aa0a8SAndrey V. Elsukov 746af9aa0a8SAndrey V. Elsukov static __inline uint16_t 747af9aa0a8SAndrey V. Elsukov cksum_adjust(uint16_t oldsum, uint16_t old, uint16_t new) 748af9aa0a8SAndrey V. Elsukov { 749af9aa0a8SAndrey V. Elsukov 750af9aa0a8SAndrey V. Elsukov return (~cksum_add(cksum_add(~oldsum, ~old), new)); 751af9aa0a8SAndrey V. Elsukov } 752af9aa0a8SAndrey V. Elsukov 7533b3a8eb9SGleb Smirnoff #endif /* _KERNEL */ 7543b3a8eb9SGleb Smirnoff #endif /* _IPFW2_PRIVATE_H */ 755