1200580Sluigi/*-
2200580Sluigi * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
3200580Sluigi *
4200580Sluigi * Redistribution and use in source and binary forms, with or without
5200580Sluigi * modification, are permitted provided that the following conditions
6200580Sluigi * are met:
7200580Sluigi * 1. Redistributions of source code must retain the above copyright
8200580Sluigi *    notice, this list of conditions and the following disclaimer.
9200580Sluigi * 2. Redistributions in binary form must reproduce the above copyright
10200580Sluigi *    notice, this list of conditions and the following disclaimer in the
11200580Sluigi *    documentation and/or other materials provided with the distribution.
12200580Sluigi *
13200580Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14200580Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15200580Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16200580Sluigi * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17200580Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18200580Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19200580Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20200580Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21200580Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22200580Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23200580Sluigi * SUCH DAMAGE.
24200580Sluigi *
25200580Sluigi * $FreeBSD: releng/10.3/sys/netpfil/ipfw/ip_fw_private.h 265700 2014-05-08 19:11:41Z melifaro $
26200580Sluigi */
27200580Sluigi
28200580Sluigi#ifndef _IPFW2_PRIVATE_H
29200580Sluigi#define _IPFW2_PRIVATE_H
30200580Sluigi
31200580Sluigi/*
32200580Sluigi * Internal constants and data structures used by ipfw components
33200580Sluigi * and not meant to be exported outside the kernel.
34200580Sluigi */
35200580Sluigi
36200580Sluigi#ifdef _KERNEL
37200580Sluigi
38204591Sluigi/*
39204591Sluigi * For platforms that do not have SYSCTL support, we wrap the
40204591Sluigi * SYSCTL_* into a function (one per file) to collect the values
41204591Sluigi * into an array at module initialization. The wrapping macros,
42204591Sluigi * SYSBEGIN() and SYSEND, are empty in the default case.
43204591Sluigi */
44204591Sluigi#ifndef SYSBEGIN
45204591Sluigi#define SYSBEGIN(x)
46204591Sluigi#endif
47204591Sluigi#ifndef SYSEND
48204591Sluigi#define SYSEND
49204591Sluigi#endif
50200580Sluigi
51234946Smelifaro/* Return values from ipfw_chk() */
52234946Smelifaroenum {
53234946Smelifaro	IP_FW_PASS = 0,
54234946Smelifaro	IP_FW_DENY,
55234946Smelifaro	IP_FW_DIVERT,
56234946Smelifaro	IP_FW_TEE,
57234946Smelifaro	IP_FW_DUMMYNET,
58234946Smelifaro	IP_FW_NETGRAPH,
59234946Smelifaro	IP_FW_NGTEE,
60234946Smelifaro	IP_FW_NAT,
61234946Smelifaro	IP_FW_REASS,
62234946Smelifaro};
63234946Smelifaro
64234946Smelifaro/*
65234946Smelifaro * Structure for collecting parameters to dummynet for ip6_output forwarding
66234946Smelifaro */
67234946Smelifarostruct _ip6dn_args {
68234946Smelifaro       struct ip6_pktopts *opt_or;
69234946Smelifaro       struct route_in6 ro_or;
70234946Smelifaro       int flags_or;
71234946Smelifaro       struct ip6_moptions *im6o_or;
72234946Smelifaro       struct ifnet *origifp_or;
73234946Smelifaro       struct ifnet *ifp_or;
74234946Smelifaro       struct sockaddr_in6 dst_or;
75234946Smelifaro       u_long mtu_or;
76234946Smelifaro       struct route_in6 ro_pmtu_or;
77234946Smelifaro};
78234946Smelifaro
79234946Smelifaro
80234946Smelifaro/*
81234946Smelifaro * Arguments for calling ipfw_chk() and dummynet_io(). We put them
82234946Smelifaro * all into a structure because this way it is easier and more
83234946Smelifaro * efficient to pass variables around and extend the interface.
84234946Smelifaro */
85234946Smelifarostruct ip_fw_args {
86234946Smelifaro	struct mbuf	*m;		/* the mbuf chain		*/
87234946Smelifaro	struct ifnet	*oif;		/* output interface		*/
88234946Smelifaro	struct sockaddr_in *next_hop;	/* forward address		*/
89234946Smelifaro	struct sockaddr_in6 *next_hop6; /* ipv6 forward address		*/
90234946Smelifaro
91234946Smelifaro	/*
92234946Smelifaro	 * On return, it points to the matching rule.
93234946Smelifaro	 * On entry, rule.slot > 0 means the info is valid and
94234946Smelifaro	 * contains the starting rule for an ipfw search.
95234946Smelifaro	 * If chain_id == chain->id && slot >0 then jump to that slot.
96234946Smelifaro	 * Otherwise, we locate the first rule >= rulenum:rule_id
97234946Smelifaro	 */
98234946Smelifaro	struct ipfw_rule_ref rule;	/* match/restart info		*/
99234946Smelifaro
100234946Smelifaro	struct ether_header *eh;	/* for bridged packets		*/
101234946Smelifaro
102234946Smelifaro	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
103234946Smelifaro	//uint32_t	cookie;		/* a cookie depending on rule action */
104234946Smelifaro	struct inpcb	*inp;
105234946Smelifaro
106234946Smelifaro	struct _ip6dn_args	dummypar; /* dummynet->ip6_output */
107234946Smelifaro	struct sockaddr_in hopstore;	/* store here if cannot use a pointer */
108234946Smelifaro};
109234946Smelifaro
110200580SluigiMALLOC_DECLARE(M_IPFW);
111200580Sluigi
112234946Smelifaro/*
113234946Smelifaro * Hooks sometime need to know the direction of the packet
114234946Smelifaro * (divert, dummynet, netgraph, ...)
115234946Smelifaro * We use a generic definition here, with bit0-1 indicating the
116234946Smelifaro * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the
117234946Smelifaro * specific protocol
118234946Smelifaro * indicating the protocol (if necessary)
119234946Smelifaro */
120234946Smelifaroenum {
121234946Smelifaro	DIR_MASK =	0x3,
122234946Smelifaro	DIR_OUT =	0,
123234946Smelifaro	DIR_IN =	1,
124234946Smelifaro	DIR_FWD =	2,
125234946Smelifaro	DIR_DROP =	3,
126234946Smelifaro	PROTO_LAYER2 =	0x4, /* set for layer 2 */
127234946Smelifaro	/* PROTO_DEFAULT = 0, */
128234946Smelifaro	PROTO_IPV4 =	0x08,
129234946Smelifaro	PROTO_IPV6 =	0x10,
130234946Smelifaro	PROTO_IFB =	0x0c, /* layer2 + ifbridge */
131234946Smelifaro   /*	PROTO_OLDBDG =	0x14, unused, old bridge */
132234946Smelifaro};
133234946Smelifaro
134201527Sluigi/* wrapper for freeing a packet, in case we need to do more work */
135204591Sluigi#ifndef FREE_PKT
136204591Sluigi#if defined(__linux__) || defined(_WIN32)
137204591Sluigi#define FREE_PKT(m)	netisr_dispatch(-1, m)
138204591Sluigi#else
139201527Sluigi#define FREE_PKT(m)	m_freem(m)
140204591Sluigi#endif
141204591Sluigi#endif /* !FREE_PKT */
142201527Sluigi
143201122Sluigi/*
144200580Sluigi * Function definitions.
145200580Sluigi */
146200580Sluigi
147201122Sluigi/* attach (arg = 1) or detach (arg = 0) hooks */
148201122Sluigiint ipfw_attach_hooks(int);
149200580Sluigi#ifdef NOTYET
150200580Sluigivoid ipfw_nat_destroy(void);
151200580Sluigi#endif
152200580Sluigi
153200580Sluigi/* In ip_fw_log.c */
154200580Sluigistruct ip;
155200654Sluigivoid ipfw_log_bpf(int);
156200580Sluigivoid ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
157200580Sluigi	struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
158200580Sluigi	struct ip *ip);
159200580SluigiVNET_DECLARE(u_int64_t, norule_counter);
160200580Sluigi#define	V_norule_counter	VNET(norule_counter)
161200580SluigiVNET_DECLARE(int, verbose_limit);
162200580Sluigi#define	V_verbose_limit		VNET(verbose_limit)
163200580Sluigi
164200580Sluigi/* In ip_fw_dynamic.c */
165200580Sluigi
166200580Sluigienum { /* result for matching dynamic rules */
167200580Sluigi	MATCH_REVERSE = 0,
168200580Sluigi	MATCH_FORWARD,
169200580Sluigi	MATCH_NONE,
170200580Sluigi	MATCH_UNKNOWN,
171200580Sluigi};
172200580Sluigi
173200580Sluigi/*
174200580Sluigi * The lock for dynamic rules is only used once outside the file,
175200580Sluigi * and only to release the result of lookup_dyn_rule().
176200580Sluigi * Eventually we may implement it with a callback on the function.
177200580Sluigi */
178243707Smelifarostruct ip_fw_chain;
179243707Smelifarovoid ipfw_expire_dyn_rules(struct ip_fw_chain *, struct ip_fw *, int);
180243707Smelifarovoid ipfw_dyn_unlock(ipfw_dyn_rule *q);
181200580Sluigi
182200580Sluigistruct tcphdr;
183200601Sluigistruct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
184200580Sluigi    u_int32_t, u_int32_t, int);
185200601Sluigiint ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
186200580Sluigi    struct ip_fw_args *args, uint32_t tablearg);
187200601Sluigiipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt,
188200601Sluigi	int *match_direction, struct tcphdr *tcp);
189200601Sluigivoid ipfw_remove_dyn_children(struct ip_fw *rule);
190243707Smelifarovoid ipfw_get_dynamic(struct ip_fw_chain *chain, char **bp, const char *ep);
191200580Sluigi
192243707Smelifarovoid ipfw_dyn_init(struct ip_fw_chain *);	/* per-vnet initialization */
193200580Sluigivoid ipfw_dyn_uninit(int);	/* per-vnet deinitialization */
194200580Sluigiint ipfw_dyn_len(void);
195200580Sluigi
196200580Sluigi/* common variables */
197200580SluigiVNET_DECLARE(int, fw_one_pass);
198200601Sluigi#define	V_fw_one_pass		VNET(fw_one_pass)
199200601Sluigi
200200580SluigiVNET_DECLARE(int, fw_verbose);
201200601Sluigi#define	V_fw_verbose		VNET(fw_verbose)
202200601Sluigi
203200580SluigiVNET_DECLARE(struct ip_fw_chain, layer3_chain);
204200601Sluigi#define	V_layer3_chain		VNET(layer3_chain)
205200601Sluigi
206200590SluigiVNET_DECLARE(u_int32_t, set_disable);
207200590Sluigi#define	V_set_disable		VNET(set_disable)
208200580Sluigi
209200601SluigiVNET_DECLARE(int, autoinc_step);
210200601Sluigi#define V_autoinc_step		VNET(autoinc_step)
211200580Sluigi
212233478SmelifaroVNET_DECLARE(unsigned int, fw_tables_max);
213233478Smelifaro#define V_fw_tables_max		VNET(fw_tables_max)
214232865Smelifaro
215200580Sluigistruct ip_fw_chain {
216265700Smelifaro	struct ip_fw	**map;		/* array of rule ptrs to ease lookup */
217265700Smelifaro	uint32_t	id;		/* ruleset id */
218200838Sluigi	int		n_rules;	/* number of static rules */
219200580Sluigi	LIST_HEAD(nat_list, cfg_nat) nat;       /* list of nat entries */
220232865Smelifaro	struct radix_node_head **tables;	/* IPv4 tables */
221232865Smelifaro	struct radix_node_head **xtables;	/* extended tables */
222232865Smelifaro	uint8_t		*tabletype;	/* Array of table types */
223204591Sluigi#if defined( __linux__ ) || defined( _WIN32 )
224204591Sluigi	spinlock_t rwmtx;
225265700Smelifaro#else
226265700Smelifaro	struct rwlock	rwmtx;
227265700Smelifaro#endif
228265700Smelifaro	int		static_len;	/* total len of static rules */
229265700Smelifaro	uint32_t	gencnt;		/* NAT generation count */
230265700Smelifaro	struct ip_fw	*reap;		/* list of rules to reap */
231265700Smelifaro	struct ip_fw	*default_rule;
232265700Smelifaro#if defined( __linux__ ) || defined( _WIN32 )
233204591Sluigi	spinlock_t uh_lock;
234204591Sluigi#else
235200855Sluigi	struct rwlock	uh_lock;	/* lock for upper half */
236204591Sluigi#endif
237200580Sluigi};
238200580Sluigi
239200580Sluigistruct sockopt;	/* used by tcp_var.h */
240200580Sluigi
241243711Smelifaro/* Macro for working with various counters */
242243711Smelifaro#define	IPFW_INC_RULE_COUNTER(_cntr, _bytes)	do {	\
243243711Smelifaro	(_cntr)->pcnt++;				\
244243711Smelifaro	(_cntr)->bcnt += _bytes;			\
245243711Smelifaro	(_cntr)->timestamp = time_uptime;		\
246243711Smelifaro	} while (0)
247243711Smelifaro
248243711Smelifaro#define	IPFW_INC_DYN_COUNTER(_cntr, _bytes)	do {		\
249243711Smelifaro	(_cntr)->pcnt++;				\
250243711Smelifaro	(_cntr)->bcnt += _bytes;			\
251243711Smelifaro	} while (0)
252243711Smelifaro
253243711Smelifaro#define	IPFW_ZERO_RULE_COUNTER(_cntr) do {		\
254243711Smelifaro	(_cntr)->pcnt = 0;				\
255243711Smelifaro	(_cntr)->bcnt = 0;				\
256243711Smelifaro	(_cntr)->timestamp = 0;				\
257243711Smelifaro	} while (0)
258243711Smelifaro
259243711Smelifaro#define	IPFW_ZERO_DYN_COUNTER(_cntr) do {		\
260243711Smelifaro	(_cntr)->pcnt = 0;				\
261243711Smelifaro	(_cntr)->bcnt = 0;				\
262243711Smelifaro	} while (0)
263244633Smelifaro
264244634Smelifaro#define	IP_FW_ARG_TABLEARG(a)	(((a) == IP_FW_TABLEARG) ? tablearg : (a))
265200580Sluigi/*
266200580Sluigi * The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c
267200580Sluigi * so the variable and the macros must be here.
268200580Sluigi */
269200580Sluigi
270200855Sluigi#define	IPFW_LOCK_INIT(_chain) do {			\
271200855Sluigi	rw_init(&(_chain)->rwmtx, "IPFW static rules");	\
272200855Sluigi	rw_init(&(_chain)->uh_lock, "IPFW UH lock");	\
273200855Sluigi	} while (0)
274200855Sluigi
275200855Sluigi#define	IPFW_LOCK_DESTROY(_chain) do {			\
276200855Sluigi	rw_destroy(&(_chain)->rwmtx);			\
277200855Sluigi	rw_destroy(&(_chain)->uh_lock);			\
278200855Sluigi	} while (0)
279200855Sluigi
280242632Smelifaro#define	IPFW_RLOCK_ASSERT(_chain)	rw_assert(&(_chain)->rwmtx, RA_RLOCKED)
281200580Sluigi#define	IPFW_WLOCK_ASSERT(_chain)	rw_assert(&(_chain)->rwmtx, RA_WLOCKED)
282200580Sluigi
283248491Sae#define	IPFW_RLOCK(p)			rw_rlock(&(p)->rwmtx)
284248491Sae#define	IPFW_RUNLOCK(p)			rw_runlock(&(p)->rwmtx)
285248491Sae#define	IPFW_WLOCK(p)			rw_wlock(&(p)->rwmtx)
286248491Sae#define	IPFW_WUNLOCK(p)			rw_wunlock(&(p)->rwmtx)
287248491Sae#define	IPFW_PF_RLOCK(p)		IPFW_RLOCK(p)
288248491Sae#define	IPFW_PF_RUNLOCK(p)		IPFW_RUNLOCK(p)
289200580Sluigi
290243707Smelifaro#define	IPFW_UH_RLOCK_ASSERT(_chain)	rw_assert(&(_chain)->uh_lock, RA_RLOCKED)
291243707Smelifaro#define	IPFW_UH_WLOCK_ASSERT(_chain)	rw_assert(&(_chain)->uh_lock, RA_WLOCKED)
292243707Smelifaro
293200855Sluigi#define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock)
294200855Sluigi#define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock)
295200855Sluigi#define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock)
296200855Sluigi#define IPFW_UH_WUNLOCK(p) rw_wunlock(&(p)->uh_lock)
297200855Sluigi
298200590Sluigi/* In ip_fw_sockopt.c */
299200855Sluigiint ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
300200590Sluigiint ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule);
301200590Sluigiint ipfw_ctl(struct sockopt *sopt);
302200590Sluigiint ipfw_chk(struct ip_fw_args *args);
303200590Sluigivoid ipfw_reap_rules(struct ip_fw *head);
304200590Sluigi
305200590Sluigi/* In ip_fw_table.c */
306200590Sluigistruct radix_node;
307200590Sluigiint ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
308200590Sluigi    uint32_t *val);
309232865Smelifaroint ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
310232865Smelifaro    uint32_t *val, int type);
311200590Sluigiint ipfw_init_tables(struct ip_fw_chain *ch);
312204837Sbzvoid ipfw_destroy_tables(struct ip_fw_chain *ch);
313200590Sluigiint ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl);
314232865Smelifaroint ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
315232865Smelifaro    uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value);
316232865Smelifaroint ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
317232865Smelifaro    uint8_t plen, uint8_t mlen, uint8_t type);
318232865Smelifaroint ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
319200590Sluigiint ipfw_dump_table_entry(struct radix_node *rn, void *arg);
320200590Sluigiint ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
321232865Smelifaroint ipfw_count_xtable(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
322232865Smelifaroint ipfw_dump_xtable(struct ip_fw_chain *ch, ipfw_xtable *tbl);
323233478Smelifaroint ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables);
324200590Sluigi
325201735Sluigi/* In ip_fw_nat.c -- XXX to be moved to ip_var.h */
326201527Sluigi
327200580Sluigiextern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
328200580Sluigi
329200580Sluigitypedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
330200580Sluigitypedef int ipfw_nat_cfg_t(struct sockopt *);
331200580Sluigi
332254776StrocinyVNET_DECLARE(int, ipfw_nat_ready);
333254776Strociny#define	V_ipfw_nat_ready	VNET(ipfw_nat_ready)
334254776Strociny#define	IPFW_NAT_LOADED	(V_ipfw_nat_ready)
335254776Strociny
336200590Sluigiextern ipfw_nat_t *ipfw_nat_ptr;
337200590Sluigiextern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
338200590Sluigiextern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
339200590Sluigiextern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
340200590Sluigiextern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
341200590Sluigi
342200580Sluigi#endif /* _KERNEL */
343200580Sluigi#endif /* _IPFW2_PRIVATE_H */
344