xref: /netbsd-src/sys/net/npf/npf.h (revision 1165567d464ddaea17519088825bd9604f80b47c)
12e6f2099Srmind /*-
2068cee29Srmind  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
32e6f2099Srmind  * All rights reserved.
42e6f2099Srmind  *
52e6f2099Srmind  * This material is based upon work partially supported by The
62e6f2099Srmind  * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
72e6f2099Srmind  *
82e6f2099Srmind  * Redistribution and use in source and binary forms, with or without
92e6f2099Srmind  * modification, are permitted provided that the following conditions
102e6f2099Srmind  * are met:
112e6f2099Srmind  * 1. Redistributions of source code must retain the above copyright
122e6f2099Srmind  *    notice, this list of conditions and the following disclaimer.
132e6f2099Srmind  * 2. Redistributions in binary form must reproduce the above copyright
142e6f2099Srmind  *    notice, this list of conditions and the following disclaimer in the
152e6f2099Srmind  *    documentation and/or other materials provided with the distribution.
162e6f2099Srmind  *
172e6f2099Srmind  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
182e6f2099Srmind  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
192e6f2099Srmind  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
202e6f2099Srmind  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
212e6f2099Srmind  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
222e6f2099Srmind  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
232e6f2099Srmind  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
242e6f2099Srmind  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
252e6f2099Srmind  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
262e6f2099Srmind  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
272e6f2099Srmind  * POSSIBILITY OF SUCH DAMAGE.
282e6f2099Srmind  */
292e6f2099Srmind 
302e6f2099Srmind /*
312e6f2099Srmind  * Public NPF interfaces.
322e6f2099Srmind  */
332e6f2099Srmind 
3407ac07d3Srmind #ifndef _NPF_NET_H_
3507ac07d3Srmind #define _NPF_NET_H_
362e6f2099Srmind 
372e6f2099Srmind #include <sys/param.h>
382e6f2099Srmind #include <sys/types.h>
392e6f2099Srmind 
40dadc88e3Srmind #define	NPF_VERSION		22
412e6f2099Srmind 
42f75d79ebSchristos #if defined(_NPF_STANDALONE)
43f75d79ebSchristos #include "npf_stand.h"
44f75d79ebSchristos #else
45f75d79ebSchristos #include <sys/ioctl.h>
46f75d79ebSchristos #include <netinet/in_systm.h>
47f75d79ebSchristos #include <netinet/in.h>
48f75d79ebSchristos #endif
492e6f2099Srmind 
50f75d79ebSchristos struct npf;
51f75d79ebSchristos typedef struct npf npf_t;
52f75d79ebSchristos 
53f75d79ebSchristos /*
54f75d79ebSchristos  * Storage of address (both for IPv4 and IPv6) and netmask.
55f75d79ebSchristos  */
56f75d79ebSchristos typedef union {
57f75d79ebSchristos 	uint8_t			word8[16];
58f75d79ebSchristos 	uint16_t		word16[8];
59f75d79ebSchristos 	uint32_t		word32[4];
60f75d79ebSchristos } npf_addr_t;
61f75d79ebSchristos 
6209cdfd6aSrmind typedef uint8_t			npf_netmask_t;
635a5d868dSzoltan 
64fad8b2d7Srmind #define	NPF_MAX_NETMASK		(128)
6509cdfd6aSrmind #define	NPF_NO_NETMASK		((npf_netmask_t)~0)
662e6f2099Srmind 
674e592132Srmind /* BPF coprocessor. */
684e592132Srmind #if defined(NPF_BPFCOP)
694e592132Srmind #define	NPF_COP_L3		0
704e592132Srmind #define	NPF_COP_TABLE		1
714e592132Srmind 
724e592132Srmind #define	BPF_MW_IPVER		0
734e592132Srmind #define	BPF_MW_L4OFF		1
744e592132Srmind #define	BPF_MW_L4PROTO		2
754e592132Srmind #endif
76263d30c4Srmind /* The number of words used. */
77263d30c4Srmind #define	NPF_BPF_NWORDS		3
784e592132Srmind 
79f75d79ebSchristos /*
80f75d79ebSchristos  * In-kernel declarations and definitions.
81f75d79ebSchristos  */
82f75d79ebSchristos 
83f75d79ebSchristos #if defined(_KERNEL) || defined(_NPF_STANDALONE)
8497b932f1Srmind 
858c6e21bfSrmind #define	NPF_DECISION_BLOCK	0
868c6e21bfSrmind #define	NPF_DECISION_PASS	1
8707ac07d3Srmind 
888c6e21bfSrmind #define	NPF_EXT_MODULE(name, req)	\
8912e775ebSchristos     MODULE(MODULE_CLASS_MISC, name, (sizeof(req) - 1) ? ("npf," req) : "npf")
9007ac07d3Srmind 
91352f1606Srmind #include <net/if.h>
9297b932f1Srmind #include <netinet/ip.h>
9397b932f1Srmind #include <netinet/ip6.h>
9497b932f1Srmind #include <netinet/tcp.h>
9597b932f1Srmind #include <netinet/udp.h>
9697b932f1Srmind #include <netinet/ip_icmp.h>
977cf84a83Sspz #include <netinet/icmp6.h>
9897b932f1Srmind 
99a7d2a608Srmind /*
100a7d2a608Srmind  * Network buffer interface.
101a7d2a608Srmind  */
102a7d2a608Srmind 
103a7d2a608Srmind #define	NBUF_DATAREF_RESET	0x01
104a7d2a608Srmind 
105f75d79ebSchristos struct mbuf;
106f75d79ebSchristos struct nbuf;
107f75d79ebSchristos typedef struct nbuf nbuf_t;
108a7d2a608Srmind 
109f75d79ebSchristos void		nbuf_init(npf_t *, nbuf_t *, struct mbuf *, const ifnet_t *);
110a7d2a608Srmind void		nbuf_reset(nbuf_t *);
111a7d2a608Srmind struct mbuf *	nbuf_head_mbuf(nbuf_t *);
112a7d2a608Srmind 
113a7d2a608Srmind bool		nbuf_flag_p(const nbuf_t *, int);
114a7d2a608Srmind void		nbuf_unset_flag(nbuf_t *, int);
115a7d2a608Srmind 
116a7d2a608Srmind void *		nbuf_dataptr(nbuf_t *);
117a7d2a608Srmind size_t		nbuf_offset(const nbuf_t *);
118a7d2a608Srmind void *		nbuf_advance(nbuf_t *, size_t, size_t);
119a7d2a608Srmind 
120a7d2a608Srmind void *		nbuf_ensure_contig(nbuf_t *, size_t);
121a7d2a608Srmind void *		nbuf_ensure_writable(nbuf_t *, size_t);
122a7d2a608Srmind 
123a7d2a608Srmind bool		nbuf_cksum_barrier(nbuf_t *, int);
124f453fec4Srmind int		nbuf_add_tag(nbuf_t *, uint32_t);
125*1165567dSkardel int		npf_mbuf_add_tag(nbuf_t *, struct mbuf *, uint32_t);
126f453fec4Srmind int		nbuf_find_tag(nbuf_t *, uint32_t *);
127a7d2a608Srmind 
128a7d2a608Srmind /*
129a7d2a608Srmind  * Packet information cache.
130a7d2a608Srmind  */
131a7d2a608Srmind 
1328274d601Srmind #define	NPC_IP4		0x01	/* Indicates IPv4 header. */
13397b932f1Srmind #define	NPC_IP6		0x02	/* Indicates IPv6 header. */
1345a5d868dSzoltan #define	NPC_IPFRAG	0x04	/* IPv4/IPv6 fragment. */
13597b932f1Srmind #define	NPC_LAYER4	0x08	/* Layer 4 has been fetched. */
1362e6f2099Srmind 
13797b932f1Srmind #define	NPC_TCP		0x10	/* TCP header. */
13897b932f1Srmind #define	NPC_UDP		0x20	/* UDP header. */
13997b932f1Srmind #define	NPC_ICMP	0x40	/* ICMP header. */
14097b932f1Srmind #define	NPC_ICMP_ID	0x80	/* ICMP with query ID. */
14197b932f1Srmind 
142352f1606Srmind #define	NPC_ALG_EXEC	0x100	/* ALG execution. */
143352f1606Srmind 
144b24cc1c5Smaxv #define	NPC_FMTERR	0x200	/* Format error. */
145b24cc1c5Smaxv 
14697b932f1Srmind #define	NPC_IP46	(NPC_IP4|NPC_IP6)
14797b932f1Srmind 
148b899bfd9Srmind struct npf_connkey;
149b899bfd9Srmind 
1502e6f2099Srmind typedef struct {
151f75d79ebSchristos 	/* NPF context, information flags and the nbuf. */
152f75d79ebSchristos 	npf_t *			npc_ctx;
1532e6f2099Srmind 	uint32_t		npc_info;
154a7d2a608Srmind 	nbuf_t *		npc_nbuf;
1558a8347bdSrmind 
1568a8347bdSrmind 	/*
1578a8347bdSrmind 	 * Pointers to the IP source and destination addresses,
1588a8347bdSrmind 	 * and the address length (4 for IPv4 or 16 for IPv6).
1598a8347bdSrmind 	 */
1608a8347bdSrmind 	npf_addr_t *		npc_ips[2];
161352f1606Srmind 	uint8_t			npc_alen;
1628a8347bdSrmind 
1638a8347bdSrmind 	/* IP header length and L4 protocol. */
164e5989af6Smaxv 	uint32_t		npc_hlen;
165352f1606Srmind 	uint16_t		npc_proto;
1668a8347bdSrmind 
16797b932f1Srmind 	/* IPv4, IPv6. */
16897b932f1Srmind 	union {
169352f1606Srmind 		struct ip *		v4;
170352f1606Srmind 		struct ip6_hdr *	v6;
17197b932f1Srmind 	} npc_ip;
1728a8347bdSrmind 
173b899bfd9Srmind 	/* TCP, UDP, ICMP or other protocols. */
17497b932f1Srmind 	union {
175352f1606Srmind 		struct tcphdr *		tcp;
176352f1606Srmind 		struct udphdr *		udp;
177352f1606Srmind 		struct icmp *		icmp;
178352f1606Srmind 		struct icmp6_hdr *	icmp6;
179352f1606Srmind 		void *			hdr;
18097b932f1Srmind 	} npc_l4;
181b899bfd9Srmind 
182b899bfd9Srmind 	/*
183b899bfd9Srmind 	 * Override the connection key, if not NULL.  This affects the
184b899bfd9Srmind 	 * behaviour of npf_conn_lookup() and npf_conn_establish().
185b899bfd9Srmind 	 * Note: npc_ckey is of npf_connkey_t type.
186b899bfd9Srmind 	 */
187b899bfd9Srmind 	const void *		npc_ckey;
1882e6f2099Srmind } npf_cache_t;
1892e6f2099Srmind 
19039013e66Srmind static inline bool
npf_iscached(const npf_cache_t * npc,const int inf)1912e6f2099Srmind npf_iscached(const npf_cache_t *npc, const int inf)
1922e6f2099Srmind {
193e5b140c1Srmind 	KASSERT(npc->npc_nbuf != NULL);
1942e6f2099Srmind 	return __predict_true((npc->npc_info & inf) != 0);
1952e6f2099Srmind }
1962e6f2099Srmind 
1978c6e21bfSrmind /*
1988c6e21bfSrmind  * Misc.
1998c6e21bfSrmind  */
2008c6e21bfSrmind 
2018c6e21bfSrmind bool		npf_autounload_p(void);
2028c6e21bfSrmind 
20363012b51Srmind #endif	/* _KERNEL */
2042e6f2099Srmind 
205b899bfd9Srmind #define	NPF_SRC		0
206b899bfd9Srmind #define	NPF_DST		1
207b899bfd9Srmind 
2082e6f2099Srmind /* Rule attributes. */
209d9b974c9Srmind #define	NPF_RULE_PASS			0x00000001
210d9b974c9Srmind #define	NPF_RULE_GROUP			0x00000002
211d9b974c9Srmind #define	NPF_RULE_FINAL			0x00000004
212d9b974c9Srmind #define	NPF_RULE_STATEFUL		0x00000008
213d9b974c9Srmind #define	NPF_RULE_RETRST			0x00000010
214d9b974c9Srmind #define	NPF_RULE_RETICMP		0x00000020
215d9b974c9Srmind #define	NPF_RULE_DYNAMIC		0x00000040
216dadc88e3Srmind #define	NPF_RULE_GSTATEFUL		0x00000080
2170e218254Srmind 
2180e218254Srmind #define	NPF_DYNAMIC_GROUP		(NPF_RULE_GROUP | NPF_RULE_DYNAMIC)
2192e6f2099Srmind 
22097b932f1Srmind #define	NPF_RULE_IN			0x10000000
22197b932f1Srmind #define	NPF_RULE_OUT			0x20000000
22297b932f1Srmind #define	NPF_RULE_DIMASK			(NPF_RULE_IN | NPF_RULE_OUT)
2230e218254Srmind #define	NPF_RULE_FORW			0x40000000
2240e218254Srmind 
225d9b974c9Srmind /* Private range of rule attributes (not public and should not be set). */
226d9b974c9Srmind #define	NPF_RULE_PRIVMASK		0x0f000000
227d9b974c9Srmind 
2280e218254Srmind #define	NPF_RULE_MAXNAMELEN		64
2290e218254Srmind #define	NPF_RULE_MAXKEYLEN		32
2300e218254Srmind 
2310e218254Srmind /* Priority values. */
2320e218254Srmind #define	NPF_PRI_FIRST			(-2)
2330e218254Srmind #define	NPF_PRI_LAST			(-1)
2340e218254Srmind 
2350e218254Srmind /* Types of code. */
2363d9a792dSrmind #define	NPF_CODE_BPF			1
2372e6f2099Srmind 
23863012b51Srmind /* Address translation types and flags. */
23963012b51Srmind #define	NPF_NATIN			1
24063012b51Srmind #define	NPF_NATOUT			2
24163012b51Srmind 
24263012b51Srmind #define	NPF_NAT_PORTS			0x01
24363012b51Srmind #define	NPF_NAT_PORTMAP			0x02
2448274d601Srmind #define	NPF_NAT_STATIC			0x04
24563012b51Srmind 
2463d9a792dSrmind #define	NPF_NAT_PRIVMASK		0x0f000000
2473d9a792dSrmind 
2483d9a792dSrmind #define	NPF_ALGO_NONE			0
2493d9a792dSrmind #define	NPF_ALGO_NETMAP			1
2503d9a792dSrmind #define	NPF_ALGO_IPHASH			2
2513d9a792dSrmind #define	NPF_ALGO_RR			3
2523d9a792dSrmind #define	NPF_ALGO_NPT66			4
253068cee29Srmind 
2542e6f2099Srmind /* Table types. */
2553d9a792dSrmind #define	NPF_TABLE_IPSET			1
2563d9a792dSrmind #define	NPF_TABLE_LPM			2
2573d9a792dSrmind #define	NPF_TABLE_CONST			3
2583d9a792dSrmind #define	NPF_TABLE_IFADDR		4
2592e6f2099Srmind 
2601e7342c1Srmind #define	NPF_TABLE_MAXNAMELEN		32
2611e7342c1Srmind 
2622e6f2099Srmind /* Layers. */
2632e6f2099Srmind #define	NPF_LAYER_2			2
2642e6f2099Srmind #define	NPF_LAYER_3			3
2652e6f2099Srmind 
266e8d97573Srmind /*
267e8d97573Srmind  * Flags passed via nbuf tags.
268e8d97573Srmind  */
269f453fec4Srmind #define	NPF_NTAG_PASS			0x0001
2702e6f2099Srmind 
2712e6f2099Srmind /*
2720e218254Srmind  * Rule commands (non-ioctl).
2732e6f2099Srmind  */
2742e6f2099Srmind 
2750e218254Srmind #define	NPF_CMD_RULE_ADD		1
2760e218254Srmind #define	NPF_CMD_RULE_INSERT		2
2770e218254Srmind #define	NPF_CMD_RULE_REMOVE		3
2780e218254Srmind #define	NPF_CMD_RULE_REMKEY		4
27950c5afcaSrmind #define	NPF_CMD_RULE_LIST		5
28050c5afcaSrmind #define	NPF_CMD_RULE_FLUSH		6
2810e218254Srmind 
2820e218254Srmind /*
2830e218254Srmind  * NPF ioctl(2): table commands and structures.
2840e218254Srmind  */
2850e218254Srmind 
2860e218254Srmind #define	NPF_CMD_TABLE_LOOKUP		1
2870e218254Srmind #define	NPF_CMD_TABLE_ADD		2
2880e218254Srmind #define	NPF_CMD_TABLE_REMOVE		3
2890e218254Srmind #define	NPF_CMD_TABLE_LIST		4
2900e218254Srmind #define	NPF_CMD_TABLE_FLUSH		5
29164647e51Srmind 
29264647e51Srmind typedef struct npf_ioctl_ent {
29364647e51Srmind 	int			alen;
29464647e51Srmind 	npf_addr_t		addr;
29564647e51Srmind 	npf_netmask_t		mask;
29664647e51Srmind } npf_ioctl_ent_t;
29764647e51Srmind 
29864647e51Srmind typedef struct npf_ioctl_buf {
29964647e51Srmind 	void *			buf;
30064647e51Srmind 	size_t			len;
30164647e51Srmind } npf_ioctl_buf_t;
3022e6f2099Srmind 
3032e6f2099Srmind typedef struct npf_ioctl_table {
3040e218254Srmind 	int			nct_cmd;
3051e7342c1Srmind 	const char *		nct_name;
30664647e51Srmind 	union {
30764647e51Srmind 		npf_ioctl_ent_t	ent;
30864647e51Srmind 		npf_ioctl_buf_t	buf;
30964647e51Srmind 	} nct_data;
3102e6f2099Srmind } npf_ioctl_table_t;
3112e6f2099Srmind 
3120e218254Srmind /*
3130e218254Srmind  * IOCTL operations.
3140e218254Srmind  */
3150e218254Srmind 
3160e218254Srmind #define	IOC_NPF_VERSION		_IOR('N', 100, int)
3170e218254Srmind #define	IOC_NPF_SWITCH		_IOW('N', 101, int)
31839013e66Srmind #define	IOC_NPF_LOAD		_IOWR('N', 102, nvlist_ref_t)
3190e218254Srmind #define	IOC_NPF_TABLE		_IOW('N', 103, struct npf_ioctl_table)
3200e218254Srmind #define	IOC_NPF_STATS		_IOW('N', 104, void *)
32139013e66Srmind #define	IOC_NPF_SAVE		_IOR('N', 105, nvlist_ref_t)
32239013e66Srmind #define	IOC_NPF_RULE		_IOWR('N', 107, nvlist_ref_t)
32339013e66Srmind #define	IOC_NPF_CONN_LOOKUP	_IOWR('N', 108, nvlist_ref_t)
3240e1944daSrmind #define	IOC_NPF_TABLE_REPLACE	_IOWR('N', 109, nvlist_ref_t)
3250e218254Srmind 
3260e218254Srmind /*
327f75d79ebSchristos  * NPF error report.
328f75d79ebSchristos  */
329f75d79ebSchristos 
330f75d79ebSchristos typedef struct {
331f75d79ebSchristos 	int64_t		id;
332dadc88e3Srmind 	char *		error_msg;
333f75d79ebSchristos 	char *		source_file;
334dadc88e3Srmind 	unsigned	source_line;
335f75d79ebSchristos } npf_error_t;
336f75d79ebSchristos 
337f75d79ebSchristos /*
3380e218254Srmind  * Statistics counters.
3390e218254Srmind  */
3400e218254Srmind 
341628e094cSrmind typedef enum {
342628e094cSrmind 	/* Packets passed. */
343628e094cSrmind 	NPF_STAT_PASS_DEFAULT,
344628e094cSrmind 	NPF_STAT_PASS_RULESET,
345a02b7176Srmind 	NPF_STAT_PASS_CONN,
346628e094cSrmind 	/* Packets blocked. */
347628e094cSrmind 	NPF_STAT_BLOCK_DEFAULT,
348628e094cSrmind 	NPF_STAT_BLOCK_RULESET,
3490621553dSrmind 	/* Connection and NAT entries. */
350a02b7176Srmind 	NPF_STAT_CONN_CREATE,
351a02b7176Srmind 	NPF_STAT_CONN_DESTROY,
352628e094cSrmind 	NPF_STAT_NAT_CREATE,
353628e094cSrmind 	NPF_STAT_NAT_DESTROY,
354628e094cSrmind 	/* Invalid state cases. */
355628e094cSrmind 	NPF_STAT_INVALID_STATE,
356628e094cSrmind 	NPF_STAT_INVALID_STATE_TCP1,
357628e094cSrmind 	NPF_STAT_INVALID_STATE_TCP2,
358628e094cSrmind 	NPF_STAT_INVALID_STATE_TCP3,
359628e094cSrmind 	/* Raced packets. */
360a02b7176Srmind 	NPF_STAT_RACE_CONN,
361628e094cSrmind 	NPF_STAT_RACE_NAT,
362a3b239f6Srmind 	/* Fragments. */
363a3b239f6Srmind 	NPF_STAT_FRAGMENTS,
364a3b239f6Srmind 	NPF_STAT_REASSEMBLY,
365a3b239f6Srmind 	NPF_STAT_REASSFAIL,
366f9383718Srmind 	/* Other errors. */
367f9383718Srmind 	NPF_STAT_ERROR,
368352f1606Srmind 	/* nbuf non-contiguous cases. */
369352f1606Srmind 	NPF_STAT_NBUF_NONCONTIG,
370352f1606Srmind 	NPF_STAT_NBUF_CONTIG_FAIL,
371628e094cSrmind 	/* Count (last). */
372628e094cSrmind 	NPF_STATS_COUNT
373628e094cSrmind } npf_stats_t;
374628e094cSrmind 
375628e094cSrmind #define	NPF_STATS_SIZE		(sizeof(uint64_t) * NPF_STATS_COUNT)
376628e094cSrmind 
37707ac07d3Srmind #endif	/* _NPF_NET_H_ */
378