ip_fw_private.h revision 201122
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.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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 * $FreeBSD: head/sys/netinet/ipfw/ip_fw_private.h 201122 2009-12-28 10:47:04Z luigi $
26 */
27
28#ifndef _IPFW2_PRIVATE_H
29#define _IPFW2_PRIVATE_H
30
31/*
32 * Internal constants and data structures used by ipfw components
33 * and not meant to be exported outside the kernel.
34 */
35
36#ifdef _KERNEL
37
38#define MTAG_IPFW	1148380143	/* IPFW-tagged cookie */
39
40/* Return values from ipfw_chk() */
41enum {
42	IP_FW_PASS = 0,
43	IP_FW_DENY,
44	IP_FW_DIVERT,
45	IP_FW_TEE,
46	IP_FW_DUMMYNET,
47	IP_FW_NETGRAPH,
48	IP_FW_NGTEE,
49	IP_FW_NAT,
50	IP_FW_REASS,
51};
52
53/* flags for divert mtag */
54#define	IP_FW_DIVERT_LOOPBACK_FLAG	0x00080000
55#define	IP_FW_DIVERT_OUTPUT_FLAG	0x00100000
56
57/*
58 * Structure for collecting parameters to dummynet for ip6_output forwarding
59 */
60struct _ip6dn_args {
61       struct ip6_pktopts *opt_or;
62       struct route_in6 ro_or;
63       int flags_or;
64       struct ip6_moptions *im6o_or;
65       struct ifnet *origifp_or;
66       struct ifnet *ifp_or;
67       struct sockaddr_in6 dst_or;
68       u_long mtu_or;
69       struct route_in6 ro_pmtu_or;
70};
71
72/*
73 * Arguments for calling ipfw_chk() and dummynet_io(). We put them
74 * all into a structure because this way it is easier and more
75 * efficient to pass variables around and extend the interface.
76 */
77struct ip_fw_args {
78	struct mbuf	*m;		/* the mbuf chain		*/
79	struct ifnet	*oif;		/* output interface		*/
80	struct sockaddr_in *next_hop;	/* forward address		*/
81
82	/* chain_id validates 'slot', the location of the pointer to
83	 * a matching rule.
84	 * If invalid, we can lookup the rule using rule_id and rulenum
85	 */
86	uint32_t	slot;		/* slot for matching rule	*/
87	uint32_t	rulenum;	/* matching rule number		*/
88	uint32_t	rule_id;	/* matching rule id		*/
89	uint32_t	chain_id;	/* ruleset id			*/
90
91	struct ether_header *eh;	/* for bridged packets		*/
92
93	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
94	uint32_t	cookie;		/* a cookie depending on rule action */
95	struct inpcb	*inp;
96
97	struct _ip6dn_args	dummypar; /* dummynet->ip6_output */
98	struct sockaddr_in hopstore;	/* store here if cannot use a pointer */
99};
100
101MALLOC_DECLARE(M_IPFW);
102
103/*
104 * Hooks sometime need to know the direction of the packet
105 * (divert, dummynet, netgraph, ...)
106 * We use a generic definition here, with bit0-1 indicating the
107 * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the
108 * specific protocol
109 * indicating the protocol (if necessary)
110 */
111enum {
112	DIR_MASK =	0x3,
113	DIR_OUT =	0,
114	DIR_IN =	1,
115	DIR_FWD =	2,
116	DIR_DROP =	3,
117	PROTO_LAYER2 =	0x4, /* set for layer 2 */
118	/* PROTO_DEFAULT = 0, */
119	PROTO_IPV4 =	0x08,
120	PROTO_IPV6 =	0x10,
121	PROTO_IFB =	0x0c, /* layer2 + ifbridge */
122   /*	PROTO_OLDBDG =	0x14, unused, old bridge */
123};
124
125/*
126 * Function definitions.
127 */
128
129/* attach (arg = 1) or detach (arg = 0) hooks */
130int ipfw_attach_hooks(int);
131#ifdef NOTYET
132void ipfw_nat_destroy(void);
133#endif
134
135/* In ip_fw_log.c */
136struct ip;
137void ipfw_log_bpf(int);
138void ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
139	struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
140	struct ip *ip);
141VNET_DECLARE(u_int64_t, norule_counter);
142#define	V_norule_counter	VNET(norule_counter)
143VNET_DECLARE(int, verbose_limit);
144#define	V_verbose_limit		VNET(verbose_limit)
145
146/* In ip_fw_dynamic.c */
147
148enum { /* result for matching dynamic rules */
149	MATCH_REVERSE = 0,
150	MATCH_FORWARD,
151	MATCH_NONE,
152	MATCH_UNKNOWN,
153};
154
155/*
156 * The lock for dynamic rules is only used once outside the file,
157 * and only to release the result of lookup_dyn_rule().
158 * Eventually we may implement it with a callback on the function.
159 */
160void ipfw_dyn_unlock(void);
161
162struct tcphdr;
163struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
164    u_int32_t, u_int32_t, int);
165int ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
166    struct ip_fw_args *args, uint32_t tablearg);
167ipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt,
168	int *match_direction, struct tcphdr *tcp);
169void ipfw_remove_dyn_children(struct ip_fw *rule);
170void ipfw_get_dynamic(char **bp, const char *ep);
171
172void ipfw_dyn_attach(void);	/* uma_zcreate .... */
173void ipfw_dyn_detach(void);	/* uma_zdestroy ... */
174void ipfw_dyn_init(void);	/* per-vnet initialization */
175void ipfw_dyn_uninit(int);	/* per-vnet deinitialization */
176int ipfw_dyn_len(void);
177
178/* common variables */
179VNET_DECLARE(int, fw_one_pass);
180#define	V_fw_one_pass		VNET(fw_one_pass)
181
182VNET_DECLARE(int, fw_verbose);
183#define	V_fw_verbose		VNET(fw_verbose)
184
185VNET_DECLARE(struct ip_fw_chain, layer3_chain);
186#define	V_layer3_chain		VNET(layer3_chain)
187
188VNET_DECLARE(u_int32_t, set_disable);
189#define	V_set_disable		VNET(set_disable)
190
191VNET_DECLARE(int, autoinc_step);
192#define V_autoinc_step		VNET(autoinc_step)
193
194struct ip_fw_chain {
195	struct ip_fw	*rules;		/* list of rules */
196	struct ip_fw	*reap;		/* list of rules to reap */
197	struct ip_fw	*default_rule;
198	int		n_rules;	/* number of static rules */
199	int		static_len;	/* total len of static rules */
200	struct ip_fw    **map;	/* array of rule ptrs to ease lookup */
201	LIST_HEAD(nat_list, cfg_nat) nat;       /* list of nat entries */
202	struct radix_node_head *tables[IPFW_TABLES_MAX];
203	struct rwlock	rwmtx;
204	struct rwlock	uh_lock;	/* lock for upper half */
205	uint32_t	id;		/* ruleset id */
206};
207
208struct sockopt;	/* used by tcp_var.h */
209
210/*
211 * The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c
212 * so the variable and the macros must be here.
213 */
214
215#define	IPFW_LOCK_INIT(_chain) do {			\
216	rw_init(&(_chain)->rwmtx, "IPFW static rules");	\
217	rw_init(&(_chain)->uh_lock, "IPFW UH lock");	\
218	} while (0)
219
220#define	IPFW_LOCK_DESTROY(_chain) do {			\
221	rw_destroy(&(_chain)->rwmtx);			\
222	rw_destroy(&(_chain)->uh_lock);			\
223	} while (0)
224
225#define	IPFW_WLOCK_ASSERT(_chain)	rw_assert(&(_chain)->rwmtx, RA_WLOCKED)
226
227#define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx)
228#define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx)
229#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx)
230#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx)
231
232#define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock)
233#define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock)
234#define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock)
235#define IPFW_UH_WUNLOCK(p) rw_wunlock(&(p)->uh_lock)
236
237/* In ip_fw_sockopt.c */
238int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
239int ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule);
240int ipfw_ctl(struct sockopt *sopt);
241int ipfw_chk(struct ip_fw_args *args);
242void ipfw_reap_rules(struct ip_fw *head);
243
244/* In ip_fw_table.c */
245struct radix_node;
246int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
247    uint32_t *val);
248int ipfw_init_tables(struct ip_fw_chain *ch);
249int ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl);
250void ipfw_flush_tables(struct ip_fw_chain *ch);
251int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
252    uint8_t mlen, uint32_t value);
253int ipfw_dump_table_entry(struct radix_node *rn, void *arg);
254int ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
255    uint8_t mlen);
256int ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
257int ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
258
259/* In ip_fw_nat.c */
260
261extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
262
263typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
264typedef int ipfw_nat_cfg_t(struct sockopt *);
265
266extern ipfw_nat_t *ipfw_nat_ptr;
267#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
268
269extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
270extern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
271extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
272extern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
273
274/* netgraph prototypes */
275#define NGM_IPFW_COOKIE      1105988990
276
277typedef int ng_ipfw_input_t(struct mbuf **, int, struct ip_fw_args *, int);
278extern  ng_ipfw_input_t *ng_ipfw_input_p;
279#define NG_IPFW_LOADED  (ng_ipfw_input_p != NULL)
280
281struct ng_ipfw_tag {
282        struct m_tag    mt;             /* tag header */
283	/* reinject info */
284        uint32_t        slot;           /* slot for next rule */
285        uint32_t        rulenum;        /* matching rule number */
286        uint32_t        rule_id;        /* matching rule id */
287        uint32_t        chain_id;       /* ruleset id */
288        int             dir;
289
290//        struct ifnet    *ifp;           /* interface, for ip_output */
291};
292
293#define TAGSIZ  (sizeof(struct ng_ipfw_tag) - sizeof(struct m_tag))
294
295
296#endif /* _KERNEL */
297#endif /* _IPFW2_PRIVATE_H */
298