xref: /freebsd/sys/netinet/ip_fw.h (revision 78e4dbc34559f7b18ea85cafd6663db4e6d54af9)
1c398230bSWarner Losh /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3fe267a55SPedro F. Giffuni  *
4b87ce554SLuigi Rizzo  * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
5100ba1a6SJordan K. Hubbard  *
69758b77fSLuigi Rizzo  * Redistribution and use in source and binary forms, with or without
79758b77fSLuigi Rizzo  * modification, are permitted provided that the following conditions
89758b77fSLuigi Rizzo  * are met:
99758b77fSLuigi Rizzo  * 1. Redistributions of source code must retain the above copyright
109758b77fSLuigi Rizzo  *    notice, this list of conditions and the following disclaimer.
119758b77fSLuigi Rizzo  * 2. Redistributions in binary form must reproduce the above copyright
129758b77fSLuigi Rizzo  *    notice, this list of conditions and the following disclaimer in the
139758b77fSLuigi Rizzo  *    documentation and/or other materials provided with the distribution.
14100ba1a6SJordan K. Hubbard  *
159758b77fSLuigi Rizzo  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
169758b77fSLuigi Rizzo  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
179758b77fSLuigi Rizzo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
189758b77fSLuigi Rizzo  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199758b77fSLuigi Rizzo  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
209758b77fSLuigi Rizzo  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
219758b77fSLuigi Rizzo  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
229758b77fSLuigi Rizzo  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
239758b77fSLuigi Rizzo  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249758b77fSLuigi Rizzo  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
259758b77fSLuigi Rizzo  * SUCH DAMAGE.
26100ba1a6SJordan K. Hubbard  */
27100ba1a6SJordan K. Hubbard 
289758b77fSLuigi Rizzo #ifndef _IPFW2_H
299758b77fSLuigi Rizzo #define _IPFW2_H
309b932e9eSAndre Oppermann 
31e4676ba6SJulian Elischer /*
32eb29d14cSRoman Kurakin  * The default rule number.  By the design of ip_fw, the default rule
33eb29d14cSRoman Kurakin  * is the last one, so its number can also serve as the highest number
34eb29d14cSRoman Kurakin  * allowed for a rule.  The ip_fw code relies on both meanings of this
35eb29d14cSRoman Kurakin  * constant.
368191aa7cSRoman Kurakin  */
378191aa7cSRoman Kurakin #define	IPFW_DEFAULT_RULE	65535
388191aa7cSRoman Kurakin 
397e767c79SAlexander V. Chernikov #define	RESVD_SET		31	/*set for default and persistent rules*/
407e767c79SAlexander V. Chernikov #define	IPFW_MAX_SETS		32	/* Number of sets supported by ipfw*/
41b074b7bbSAlexander V. Chernikov 
42b074b7bbSAlexander V. Chernikov /*
4374b22066SAlexander V. Chernikov  * Compat values for old clients
44f7b5554eSRoman Kurakin  */
4574b22066SAlexander V. Chernikov #ifndef	_KERNEL
46732d27b3SAlexander V. Chernikov #define	IPFW_TABLES_MAX		65535
47732d27b3SAlexander V. Chernikov #define	IPFW_TABLES_DEFAULT	128
4874b22066SAlexander V. Chernikov #endif
49f7b5554eSRoman Kurakin 
50f7b5554eSRoman Kurakin /*
51b87ce554SLuigi Rizzo  * Most commands (queue, pipe, tag, untag, limit...) can have a 16-bit
521940fa77SAlexander V. Chernikov  * argument between 1 and 65534. The value 0 (IP_FW_TARG) is used
531940fa77SAlexander V. Chernikov  * to represent 'tablearg' value, e.g.  indicate the use of a 'tablearg'
54b87ce554SLuigi Rizzo  * result of the most recent table() lookup.
55b87ce554SLuigi Rizzo  * Note that 16bit is only a historical limit, resulting from
56b87ce554SLuigi Rizzo  * the use of a 16-bit fields for that value. In reality, we can have
571940fa77SAlexander V. Chernikov  * 2^32 pipes, queues, tag values and so on.
58b87ce554SLuigi Rizzo  */
59b87ce554SLuigi Rizzo #define	IPFW_ARG_MIN		1
60b87ce554SLuigi Rizzo #define	IPFW_ARG_MAX		65534
611940fa77SAlexander V. Chernikov #define IP_FW_TABLEARG		65535	/* Compat value for old clients */
621940fa77SAlexander V. Chernikov #define	IP_FW_TARG		0	/* Current tablearg value */
63d6eb9b02SAndrey V. Elsukov #define	IP_FW_NAT44_GLOBAL	65535	/* arg1 value for "nat global" */
64b87ce554SLuigi Rizzo 
65b87ce554SLuigi Rizzo /*
669527ec6eSAndrey V. Elsukov  * Number of entries in the call stack of the call/return commands.
679527ec6eSAndrey V. Elsukov  * Call stack currently is an uint16_t array with rule numbers.
689527ec6eSAndrey V. Elsukov  */
699527ec6eSAndrey V. Elsukov #define	IPFW_CALLSTACK_SIZE	16
709527ec6eSAndrey V. Elsukov 
71f8bee51aSAlexander V. Chernikov /* IP_FW3 header/opcodes */
72f8bee51aSAlexander V. Chernikov typedef struct _ip_fw3_opheader {
73f8bee51aSAlexander V. Chernikov 	uint16_t opcode;	/* Operation opcode */
74d3a4f924SAlexander V. Chernikov 	uint16_t version;	/* Opcode version */
75d3a4f924SAlexander V. Chernikov 	uint16_t reserved[2];	/* Align to 64-bit boundary */
76f8bee51aSAlexander V. Chernikov } ip_fw3_opheader;
77f8bee51aSAlexander V. Chernikov 
7818ad4197SAlexander V. Chernikov /* IP_FW3 opcodes */
79f8bee51aSAlexander V. Chernikov #define	IP_FW_TABLE_XADD	86	/* add entry */
80f8bee51aSAlexander V. Chernikov #define	IP_FW_TABLE_XDEL	87	/* delete entry */
81d3a4f924SAlexander V. Chernikov #define	IP_FW_TABLE_XGETSIZE	88	/* get table size (deprecated) */
82f8bee51aSAlexander V. Chernikov #define	IP_FW_TABLE_XLIST	89	/* list table contents */
83d3a4f924SAlexander V. Chernikov #define	IP_FW_TABLE_XDESTROY	90	/* destroy table */
849490a627SAlexander V. Chernikov #define	IP_FW_TABLES_XLIST	92	/* list all tables  */
859490a627SAlexander V. Chernikov #define	IP_FW_TABLE_XINFO	93	/* request info for one table */
869490a627SAlexander V. Chernikov #define	IP_FW_TABLE_XFLUSH	94	/* flush table data */
879490a627SAlexander V. Chernikov #define	IP_FW_TABLE_XCREATE	95	/* create new table  */
88adf3b2b9SAlexander V. Chernikov #define	IP_FW_TABLE_XMODIFY	96	/* modify existing table */
89563b5ab1SAlexander V. Chernikov #define	IP_FW_XGET		97	/* Retrieve configuration */
90a73d728dSAlexander V. Chernikov #define	IP_FW_XADD		98	/* add rule */
91a73d728dSAlexander V. Chernikov #define	IP_FW_XDEL		99	/* del rule */
92a73d728dSAlexander V. Chernikov #define	IP_FW_XMOVE		100	/* move rules to different set  */
93a73d728dSAlexander V. Chernikov #define	IP_FW_XZERO		101	/* clear accounting */
94a73d728dSAlexander V. Chernikov #define	IP_FW_XRESETLOG		102	/* zero rules logs */
95a73d728dSAlexander V. Chernikov #define	IP_FW_SET_SWAP		103	/* Swap between 2 sets */
96a73d728dSAlexander V. Chernikov #define	IP_FW_SET_MOVE		104	/* Move one set to another one */
97a73d728dSAlexander V. Chernikov #define	IP_FW_SET_ENABLE	105	/* Enable/disable sets */
98a73d728dSAlexander V. Chernikov #define	IP_FW_TABLE_XFIND	106	/* finds an entry */
99a73d728dSAlexander V. Chernikov #define	IP_FW_XIFLIST		107	/* list tracked interfaces */
100a73d728dSAlexander V. Chernikov #define	IP_FW_TABLES_ALIST	108	/* list table algorithms */
101a73d728dSAlexander V. Chernikov #define	IP_FW_TABLE_XSWAP	109	/* swap two tables */
1020cba2b28SAlexander V. Chernikov #define	IP_FW_TABLE_VLIST	110	/* dump table value hash */
103d3a4f924SAlexander V. Chernikov 
104d6164b77SAlexander V. Chernikov #define	IP_FW_NAT44_XCONFIG	111	/* Create/modify NAT44 instance */
105d6164b77SAlexander V. Chernikov #define	IP_FW_NAT44_DESTROY	112	/* Destroys NAT44 instance */
106d6164b77SAlexander V. Chernikov #define	IP_FW_NAT44_XGETCONFIG	113	/* Get NAT44 instance config */
107d6164b77SAlexander V. Chernikov #define	IP_FW_NAT44_LIST_NAT	114	/* List all NAT44 instances */
108d6164b77SAlexander V. Chernikov #define	IP_FW_NAT44_XGETLOG	115	/* Get log from NAT44 instance */
109d6164b77SAlexander V. Chernikov 
110be8bc457SAlexander V. Chernikov #define	IP_FW_DUMP_SOPTCODES	116	/* Dump available sopts/versions */
1115dc5a0e0SAndrey V. Elsukov #define	IP_FW_DUMP_SRVOBJECTS	117	/* Dump existing named objects */
112be8bc457SAlexander V. Chernikov 
113d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64STL_CREATE	130	/* Create stateless NAT64 instance */
114d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64STL_DESTROY	131	/* Destroy stateless NAT64 instance */
115d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64STL_CONFIG	132	/* Modify stateless NAT64 instance */
116d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64STL_LIST	133	/* List stateless NAT64 instances */
117d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64STL_STATS	134	/* Get NAT64STL instance statistics */
118d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64STL_RESET_STATS 135	/* Reset NAT64STL instance statistics */
119d8caf56eSAndrey V. Elsukov 
120d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_CREATE	140	/* Create stateful NAT64 instance */
121d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_DESTROY	141	/* Destroy stateful NAT64 instance */
122d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_CONFIG	142	/* Modify stateful NAT64 instance */
123d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_LIST	143	/* List stateful NAT64 instances */
124d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_STATS	144	/* Get NAT64LSN instance statistics */
125d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_LIST_STATES 145	/* Get stateful NAT64 states */
126d8caf56eSAndrey V. Elsukov #define	IP_FW_NAT64LSN_RESET_STATS 146	/* Reset NAT64LSN instance statistics */
127d8caf56eSAndrey V. Elsukov 
128b867e84eSAndrey V. Elsukov #define	IP_FW_NPTV6_CREATE	150	/* Create NPTv6 instance */
129b867e84eSAndrey V. Elsukov #define	IP_FW_NPTV6_DESTROY	151	/* Destroy NPTv6 instance */
130b867e84eSAndrey V. Elsukov #define	IP_FW_NPTV6_CONFIG	152	/* Modify NPTv6 instance */
131b867e84eSAndrey V. Elsukov #define	IP_FW_NPTV6_LIST	153	/* List NPTv6 instances */
132b867e84eSAndrey V. Elsukov #define	IP_FW_NPTV6_STATS	154	/* Get NPTv6 instance statistics */
13357fb3b7aSAndrey V. Elsukov #define	IP_FW_NPTV6_RESET_STATS	155	/* Reset NPTv6 instance statistics */
134b867e84eSAndrey V. Elsukov 
1355c04f73eSAndrey V. Elsukov #define	IP_FW_NAT64CLAT_CREATE	160	/* Create clat NAT64 instance */
1365c04f73eSAndrey V. Elsukov #define	IP_FW_NAT64CLAT_DESTROY	161	/* Destroy clat NAT64 instance */
1375c04f73eSAndrey V. Elsukov #define	IP_FW_NAT64CLAT_CONFIG	162	/* Modify clat NAT64 instance */
1385c04f73eSAndrey V. Elsukov #define	IP_FW_NAT64CLAT_LIST	163	/* List clat NAT64 instances */
1395c04f73eSAndrey V. Elsukov #define	IP_FW_NAT64CLAT_STATS	164	/* Get NAT64CLAT instance statistics */
1405c04f73eSAndrey V. Elsukov #define	IP_FW_NAT64CLAT_RESET_STATS 165	/* Reset NAT64CLAT instance statistics */
1415c04f73eSAndrey V. Elsukov 
142d3a4f924SAlexander V. Chernikov /*
1439758b77fSLuigi Rizzo  * The kernel representation of ipfw rules is made of a list of
1449758b77fSLuigi Rizzo  * 'instructions' (for all practical purposes equivalent to BPF
1459758b77fSLuigi Rizzo  * instructions), which specify which fields of the packet
146330462a3SBernd Walter  * (or its metadata) should be analysed.
147e4676ba6SJulian Elischer  *
1489758b77fSLuigi Rizzo  * Each instruction is stored in a structure which begins with
1499758b77fSLuigi Rizzo  * "ipfw_insn", and can contain extra fields depending on the
1509758b77fSLuigi Rizzo  * instruction type (listed below).
151330462a3SBernd Walter  * Note that the code is written so that individual instructions
152330462a3SBernd Walter  * have a size which is a multiple of 32 bits. This means that, if
153330462a3SBernd Walter  * such structures contain pointers or other 64-bit entities,
154330462a3SBernd Walter  * (there is just one instance now) they may end up unaligned on
155330462a3SBernd Walter  * 64-bit architectures, so the must be handled with care.
1569758b77fSLuigi Rizzo  *
1579758b77fSLuigi Rizzo  * "enum ipfw_opcodes" are the opcodes supported. We can have up
15831c88a30SChristian S.J. Peron  * to 256 different opcodes. When adding new opcodes, they should
15931c88a30SChristian S.J. Peron  * be appended to the end of the opcode list before O_LAST_OPCODE,
16031c88a30SChristian S.J. Peron  * this will prevent the ABI from being broken, otherwise users
16131c88a30SChristian S.J. Peron  * will have to recompile ipfw(8) when they update the kernel.
162e4676ba6SJulian Elischer  */
163e4676ba6SJulian Elischer 
1649758b77fSLuigi Rizzo enum ipfw_opcodes {		/* arguments (4 byte each)	*/
1659758b77fSLuigi Rizzo 	O_NOP,
1669758b77fSLuigi Rizzo 
1679758b77fSLuigi Rizzo 	O_IP_SRC,		/* u32 = IP			*/
1689758b77fSLuigi Rizzo 	O_IP_SRC_MASK,		/* ip = IP/mask			*/
1699758b77fSLuigi Rizzo 	O_IP_SRC_ME,		/* none				*/
1709758b77fSLuigi Rizzo 	O_IP_SRC_SET,		/* u32=base, arg1=len, bitmap	*/
1719758b77fSLuigi Rizzo 
1729758b77fSLuigi Rizzo 	O_IP_DST,		/* u32 = IP			*/
1739758b77fSLuigi Rizzo 	O_IP_DST_MASK,		/* ip = IP/mask			*/
1749758b77fSLuigi Rizzo 	O_IP_DST_ME,		/* none				*/
1759758b77fSLuigi Rizzo 	O_IP_DST_SET,		/* u32=base, arg1=len, bitmap	*/
1769758b77fSLuigi Rizzo 
1779758b77fSLuigi Rizzo 	O_IP_SRCPORT,		/* (n)port list:mask 4 byte ea	*/
1789758b77fSLuigi Rizzo 	O_IP_DSTPORT,		/* (n)port list:mask 4 byte ea	*/
1799758b77fSLuigi Rizzo 	O_PROTO,		/* arg1=protocol		*/
1809758b77fSLuigi Rizzo 
1819758b77fSLuigi Rizzo 	O_MACADDR2,		/* 2 mac addr:mask		*/
1829758b77fSLuigi Rizzo 	O_MAC_TYPE,		/* same as srcport		*/
1839758b77fSLuigi Rizzo 
1849758b77fSLuigi Rizzo 	O_LAYER2,		/* none				*/
1859758b77fSLuigi Rizzo 	O_IN,			/* none				*/
1869758b77fSLuigi Rizzo 	O_FRAG,			/* none				*/
1879758b77fSLuigi Rizzo 
1889758b77fSLuigi Rizzo 	O_RECV,			/* none				*/
1899758b77fSLuigi Rizzo 	O_XMIT,			/* none				*/
1909758b77fSLuigi Rizzo 	O_VIA,			/* none				*/
1919758b77fSLuigi Rizzo 
1929758b77fSLuigi Rizzo 	O_IPOPT,		/* arg1 = 2*u8 bitmap		*/
1939758b77fSLuigi Rizzo 	O_IPLEN,		/* arg1 = len			*/
1949758b77fSLuigi Rizzo 	O_IPID,			/* arg1 = id			*/
1959758b77fSLuigi Rizzo 
1969758b77fSLuigi Rizzo 	O_IPTOS,		/* arg1 = id			*/
1975e43aef8SLuigi Rizzo 	O_IPPRECEDENCE,		/* arg1 = precedence << 5	*/
1989758b77fSLuigi Rizzo 	O_IPTTL,		/* arg1 = TTL			*/
1999758b77fSLuigi Rizzo 
2009758b77fSLuigi Rizzo 	O_IPVER,		/* arg1 = version		*/
2019758b77fSLuigi Rizzo 	O_UID,			/* u32 = id			*/
2029758b77fSLuigi Rizzo 	O_GID,			/* u32 = id			*/
2039758b77fSLuigi Rizzo 	O_ESTAB,		/* none (tcp established)	*/
2049758b77fSLuigi Rizzo 	O_TCPFLAGS,		/* arg1 = 2*u8 bitmap		*/
2059758b77fSLuigi Rizzo 	O_TCPWIN,		/* arg1 = desired win		*/
2069758b77fSLuigi Rizzo 	O_TCPSEQ,		/* u32 = desired seq.		*/
2079758b77fSLuigi Rizzo 	O_TCPACK,		/* u32 = desired seq.		*/
2089758b77fSLuigi Rizzo 	O_ICMPTYPE,		/* u32 = icmp bitmap		*/
2099758b77fSLuigi Rizzo 	O_TCPOPTS,		/* arg1 = 2*u8 bitmap		*/
2109758b77fSLuigi Rizzo 
211010dabb0SCrist J. Clark 	O_VERREVPATH,		/* none				*/
21222b5770bSAndre Oppermann 	O_VERSRCREACH,		/* none				*/
213010dabb0SCrist J. Clark 
2149758b77fSLuigi Rizzo 	O_PROBE_STATE,		/* none				*/
2159758b77fSLuigi Rizzo 	O_KEEP_STATE,		/* none				*/
2169758b77fSLuigi Rizzo 	O_LIMIT,		/* ipfw_insn_limit		*/
2179758b77fSLuigi Rizzo 	O_LIMIT_PARENT,		/* dyn_type, not an opcode.	*/
218f030c151SLuigi Rizzo 
2199758b77fSLuigi Rizzo 	/*
220f030c151SLuigi Rizzo 	 * These are really 'actions'.
2219758b77fSLuigi Rizzo 	 */
2229758b77fSLuigi Rizzo 
2239758b77fSLuigi Rizzo 	O_LOG,			/* ipfw_insn_log		*/
2249758b77fSLuigi Rizzo 	O_PROB,			/* u32 = match probability	*/
2259758b77fSLuigi Rizzo 
2269758b77fSLuigi Rizzo 	O_CHECK_STATE,		/* none				*/
2279758b77fSLuigi Rizzo 	O_ACCEPT,		/* none				*/
2289758b77fSLuigi Rizzo 	O_DENY,			/* none 			*/
2299758b77fSLuigi Rizzo 	O_REJECT,		/* arg1=icmp arg (same as deny)	*/
2309758b77fSLuigi Rizzo 	O_COUNT,		/* none				*/
2319758b77fSLuigi Rizzo 	O_SKIPTO,		/* arg1=next rule number	*/
2329758b77fSLuigi Rizzo 	O_PIPE,			/* arg1=pipe number		*/
2339758b77fSLuigi Rizzo 	O_QUEUE,		/* arg1=queue number		*/
2349758b77fSLuigi Rizzo 	O_DIVERT,		/* arg1=port number		*/
2359758b77fSLuigi Rizzo 	O_TEE,			/* arg1=port number		*/
2369758b77fSLuigi Rizzo 	O_FORWARD_IP,		/* fwd sockaddr			*/
2379758b77fSLuigi Rizzo 	O_FORWARD_MAC,		/* fwd mac			*/
238ff2f6fe8SPaolo Pisati 	O_NAT,                  /* nope                         */
239eb2e4119SPaolo Pisati 	O_REASS,                /* none                         */
240f030c151SLuigi Rizzo 
241f030c151SLuigi Rizzo 	/*
242f030c151SLuigi Rizzo 	 * More opcodes.
243f030c151SLuigi Rizzo 	 */
244f030c151SLuigi Rizzo 	O_IPSEC,		/* has ipsec history 		*/
245cd8b5ae0SRuslan Ermilov 	O_IP_SRC_LOOKUP,	/* arg1=table number, u32=value	*/
246cd8b5ae0SRuslan Ermilov 	O_IP_DST_LOOKUP,	/* arg1=table number, u32=value	*/
2475af87d0eSDavid E. O'Brien 	O_ANTISPOOF,		/* none				*/
24831c88a30SChristian S.J. Peron 	O_JAIL,			/* u32 = id			*/
249974dfe30SBrian Feldman 	O_ALTQ,			/* u32 = altq classif. qid	*/
2506daf7ebdSBrian Feldman 	O_DIVERTED,		/* arg1=bitmap (1:loop, 2:out)	*/
251c99ee9e0SBrian Feldman 	O_TCPDATALEN,		/* arg1 = tcp data len		*/
2528195404bSBrooks Davis 	O_IP6_SRC,		/* address without mask		*/
2538195404bSBrooks Davis 	O_IP6_SRC_ME,		/* my addresses			*/
2548195404bSBrooks Davis 	O_IP6_SRC_MASK,		/* address with the mask	*/
2558195404bSBrooks Davis 	O_IP6_DST,
2568195404bSBrooks Davis 	O_IP6_DST_ME,
2578195404bSBrooks Davis 	O_IP6_DST_MASK,
2588195404bSBrooks Davis 	O_FLOW6ID,		/* for flow id tag in the ipv6 pkt */
2598195404bSBrooks Davis 	O_ICMP6TYPE,		/* icmp6 packet type filtering	*/
2608195404bSBrooks Davis 	O_EXT_HDR,		/* filtering for ipv6 extension header */
2618195404bSBrooks Davis 	O_IP6,
262f030c151SLuigi Rizzo 
263670742a1SGleb Smirnoff 	/*
264670742a1SGleb Smirnoff 	 * actions for ng_ipfw
265670742a1SGleb Smirnoff 	 */
266670742a1SGleb Smirnoff 	O_NETGRAPH,		/* send to ng_ipfw		*/
267670742a1SGleb Smirnoff 	O_NGTEE,		/* copy to ng_ipfw		*/
268670742a1SGleb Smirnoff 
26957cd6d26SMax Laier 	O_IP4,
27057cd6d26SMax Laier 
2719066356bSBjoern A. Zeeb 	O_UNREACH6,		/* arg1=icmpv6 code arg (deny)  */
2729066356bSBjoern A. Zeeb 
2736a7d5cb6SOleg Bulyzhin 	O_TAG,   		/* arg1=tag number */
2746a7d5cb6SOleg Bulyzhin 	O_TAGGED,		/* arg1=tag number */
2756a7d5cb6SOleg Bulyzhin 
2768b07e49aSJulian Elischer 	O_SETFIB,		/* arg1=FIB number */
2778b07e49aSJulian Elischer 	O_FIB,			/* arg1=FIB desired fib number */
2788b07e49aSJulian Elischer 
279ae99fd0eSLuigi Rizzo 	O_SOCKARG,		/* socket argument */
280ae99fd0eSLuigi Rizzo 
2819527ec6eSAndrey V. Elsukov 	O_CALLRETURN,		/* arg1=called rule number */
2829527ec6eSAndrey V. Elsukov 
2838a006adbSBjoern A. Zeeb 	O_FORWARD_IP6,		/* fwd sockaddr_in6             */
2848a006adbSBjoern A. Zeeb 
285ae01d73cSAlexander V. Chernikov 	O_DSCP,			/* 2 u32 = DSCP mask */
286ae01d73cSAlexander V. Chernikov 	O_SETDSCP,		/* arg1=DSCP value */
287914bffb6SAlexander V. Chernikov 	O_IP_FLOW_LOOKUP,	/* arg1=table number, u32=value	*/
288ae01d73cSAlexander V. Chernikov 
2892acdf79fSAndrey V. Elsukov 	O_EXTERNAL_ACTION,	/* arg1=id of external action handler */
2902acdf79fSAndrey V. Elsukov 	O_EXTERNAL_INSTANCE,	/* arg1=id of eaction handler instance */
29111c56650SAndrey V. Elsukov 	O_EXTERNAL_DATA,	/* variable length data */
2922acdf79fSAndrey V. Elsukov 
293f7c4fdeeSAndrey V. Elsukov 	O_SKIP_ACTION,		/* none				*/
294978f2d17SAndrey V. Elsukov 	O_TCPMSS,		/* arg1=MSS value */
295f7c4fdeeSAndrey V. Elsukov 
29681cac390SArseny Smalyuk 	O_MAC_SRC_LOOKUP,	/* arg1=table number, u32=value */
29781cac390SArseny Smalyuk 	O_MAC_DST_LOOKUP,	/* arg1=table number, u32=value */
29881cac390SArseny Smalyuk 
299fc727ad6SBoris Lytochkin 	O_SETMARK,		/* u32 = value */
300fc727ad6SBoris Lytochkin 	O_MARK,			/* 2 u32 = value, bitmask */
301fc727ad6SBoris Lytochkin 
3029758b77fSLuigi Rizzo 	O_LAST_OPCODE		/* not an opcode!		*/
303e4676ba6SJulian Elischer };
304e4676ba6SJulian Elischer 
305100ba1a6SJordan K. Hubbard /*
30681cac390SArseny Smalyuk  * Defines key types used by lookup instruction
30781cac390SArseny Smalyuk  */
30881cac390SArseny Smalyuk enum ipfw_table_lookup_type {
30981cac390SArseny Smalyuk 	LOOKUP_DST_IP,
31081cac390SArseny Smalyuk 	LOOKUP_SRC_IP,
31181cac390SArseny Smalyuk 	LOOKUP_DST_PORT,
31281cac390SArseny Smalyuk 	LOOKUP_SRC_PORT,
31381cac390SArseny Smalyuk 	LOOKUP_UID,
31481cac390SArseny Smalyuk 	LOOKUP_JAIL,
31581cac390SArseny Smalyuk 	LOOKUP_DSCP,
31681cac390SArseny Smalyuk 	LOOKUP_DST_MAC,
31781cac390SArseny Smalyuk 	LOOKUP_SRC_MAC,
318fc727ad6SBoris Lytochkin 	LOOKUP_MARK,
31981cac390SArseny Smalyuk };
32081cac390SArseny Smalyuk 
32181cac390SArseny Smalyuk /*
3228195404bSBrooks Davis  * The extension header are filtered only for presence using a bit
3238195404bSBrooks Davis  * vector with a flag for each header.
3248195404bSBrooks Davis  */
3258195404bSBrooks Davis #define EXT_FRAGMENT	0x1
3268195404bSBrooks Davis #define EXT_HOPOPTS	0x2
3278195404bSBrooks Davis #define EXT_ROUTING	0x4
3288195404bSBrooks Davis #define EXT_AH		0x8
3298195404bSBrooks Davis #define EXT_ESP		0x10
3309066356bSBjoern A. Zeeb #define EXT_DSTOPTS	0x20
3317a92401aSBjoern A. Zeeb #define EXT_RTHDR0		0x40
3327a92401aSBjoern A. Zeeb #define EXT_RTHDR2		0x80
3338195404bSBrooks Davis 
3348195404bSBrooks Davis /*
3359758b77fSLuigi Rizzo  * Template for instructions.
336100ba1a6SJordan K. Hubbard  *
3379758b77fSLuigi Rizzo  * ipfw_insn is used for all instructions which require no operands,
3389758b77fSLuigi Rizzo  * a single 16-bit value (arg1), or a couple of 8-bit values.
3399758b77fSLuigi Rizzo  *
3409758b77fSLuigi Rizzo  * For other instructions which require different/larger arguments
3419758b77fSLuigi Rizzo  * we have derived structures, ipfw_insn_*.
3429758b77fSLuigi Rizzo  *
3439758b77fSLuigi Rizzo  * The size of the instruction (in 32-bit words) is in the low
3449758b77fSLuigi Rizzo  * 6 bits of "len". The 2 remaining bits are used to implement
3459758b77fSLuigi Rizzo  * NOT and OR on individual instructions. Given a type, you can
3469758b77fSLuigi Rizzo  * compute the length to be put in "len" using F_INSN_SIZE(t)
3479758b77fSLuigi Rizzo  *
3489758b77fSLuigi Rizzo  * F_NOT	negates the match result of the instruction.
3499758b77fSLuigi Rizzo  *
3509758b77fSLuigi Rizzo  * F_OR		is used to build or blocks. By default, instructions
3519758b77fSLuigi Rizzo  *		are evaluated as part of a logical AND. An "or" block
3529758b77fSLuigi Rizzo  *		{ X or Y or Z } contains F_OR set in all but the last
3539758b77fSLuigi Rizzo  *		instruction of the block. A match will cause the code
3549758b77fSLuigi Rizzo  *		to skip past the last instruction of the block.
3559758b77fSLuigi Rizzo  *
3569758b77fSLuigi Rizzo  * NOTA BENE: in a couple of places we assume that
3579758b77fSLuigi Rizzo  *	sizeof(ipfw_insn) == sizeof(u_int32_t)
3589758b77fSLuigi Rizzo  * this needs to be fixed.
3599758b77fSLuigi Rizzo  *
360100ba1a6SJordan K. Hubbard  */
3619758b77fSLuigi Rizzo typedef struct	_ipfw_insn {	/* template for instructions */
362a81c165bSAlex Richardson 	_Alignas(_Alignof(u_int32_t)) u_int8_t 	opcode;
3631f6ef666SRobert Watson 	u_int8_t	len;	/* number of 32-bit words */
3649758b77fSLuigi Rizzo #define	F_NOT		0x80
3659758b77fSLuigi Rizzo #define	F_OR		0x40
3669758b77fSLuigi Rizzo #define	F_LEN_MASK	0x3f
3679758b77fSLuigi Rizzo #define	F_LEN(cmd)	((cmd)->len & F_LEN_MASK)
3689758b77fSLuigi Rizzo 
3699758b77fSLuigi Rizzo 	u_int16_t	arg1;
3709758b77fSLuigi Rizzo } ipfw_insn;
371100ba1a6SJordan K. Hubbard 
372d60315beSLuigi Rizzo /*
3739758b77fSLuigi Rizzo  * The F_INSN_SIZE(type) computes the size, in 4-byte words, of
3749758b77fSLuigi Rizzo  * a given type.
375d60315beSLuigi Rizzo  */
3769758b77fSLuigi Rizzo #define	F_INSN_SIZE(t)	((sizeof (t))/sizeof(u_int32_t))
377d60315beSLuigi Rizzo 
3789758b77fSLuigi Rizzo /*
3799758b77fSLuigi Rizzo  * This is used to store an array of 16-bit entries (ports etc.)
3809758b77fSLuigi Rizzo  */
3819758b77fSLuigi Rizzo typedef struct	_ipfw_insn_u16 {
3829758b77fSLuigi Rizzo 	ipfw_insn o;
3839758b77fSLuigi Rizzo 	u_int16_t ports[2];	/* there may be more */
3849758b77fSLuigi Rizzo } ipfw_insn_u16;
385d60315beSLuigi Rizzo 
3869758b77fSLuigi Rizzo /*
3879758b77fSLuigi Rizzo  * This is used to store an array of 32-bit entries
3889758b77fSLuigi Rizzo  * (uid, single IPv4 addresses etc.)
3899758b77fSLuigi Rizzo  */
3909758b77fSLuigi Rizzo typedef struct	_ipfw_insn_u32 {
3919758b77fSLuigi Rizzo 	ipfw_insn o;
3929758b77fSLuigi Rizzo 	u_int32_t d[1];	/* one or more */
3939758b77fSLuigi Rizzo } ipfw_insn_u32;
3949758b77fSLuigi Rizzo 
3959758b77fSLuigi Rizzo /*
3969758b77fSLuigi Rizzo  * This is used to store IP addr-mask pairs.
3979758b77fSLuigi Rizzo  */
3989758b77fSLuigi Rizzo typedef struct	_ipfw_insn_ip {
3999758b77fSLuigi Rizzo 	ipfw_insn o;
4009758b77fSLuigi Rizzo 	struct in_addr	addr;
4019758b77fSLuigi Rizzo 	struct in_addr	mask;
4029758b77fSLuigi Rizzo } ipfw_insn_ip;
4039758b77fSLuigi Rizzo 
4049758b77fSLuigi Rizzo /*
405f030c151SLuigi Rizzo  * This is used to forward to a given address (ip).
4069758b77fSLuigi Rizzo  */
4079758b77fSLuigi Rizzo typedef struct  _ipfw_insn_sa {
4089758b77fSLuigi Rizzo 	ipfw_insn o;
4099758b77fSLuigi Rizzo 	struct sockaddr_in sa;
4109758b77fSLuigi Rizzo } ipfw_insn_sa;
4119758b77fSLuigi Rizzo 
4129758b77fSLuigi Rizzo /*
4138a006adbSBjoern A. Zeeb  * This is used to forward to a given address (ipv6).
4148a006adbSBjoern A. Zeeb  */
4158a006adbSBjoern A. Zeeb typedef struct _ipfw_insn_sa6 {
4168a006adbSBjoern A. Zeeb 	ipfw_insn o;
4178a006adbSBjoern A. Zeeb 	struct sockaddr_in6 sa;
4188a006adbSBjoern A. Zeeb } ipfw_insn_sa6;
4198a006adbSBjoern A. Zeeb 
4208a006adbSBjoern A. Zeeb /*
4219758b77fSLuigi Rizzo  * This is used for MAC addr-mask pairs.
4229758b77fSLuigi Rizzo  */
4239758b77fSLuigi Rizzo typedef struct	_ipfw_insn_mac {
4249758b77fSLuigi Rizzo 	ipfw_insn o;
4259758b77fSLuigi Rizzo 	u_char addr[12];	/* dst[6] + src[6] */
4269758b77fSLuigi Rizzo 	u_char mask[12];	/* dst[6] + src[6] */
4279758b77fSLuigi Rizzo } ipfw_insn_mac;
4289758b77fSLuigi Rizzo 
4299758b77fSLuigi Rizzo /*
430f030c151SLuigi Rizzo  * This is used for interface match rules (recv xx, xmit xx).
4319758b77fSLuigi Rizzo  */
4329758b77fSLuigi Rizzo typedef struct	_ipfw_insn_if {
4339758b77fSLuigi Rizzo 	ipfw_insn o;
434830cc178SLuigi Rizzo 	union {
4359758b77fSLuigi Rizzo 		struct in_addr ip;
4369bf40edeSBrooks Davis 		int glob;
4372c452b20SAlexander V. Chernikov 		uint16_t kidx;
4389758b77fSLuigi Rizzo 	} p;
4399758b77fSLuigi Rizzo 	char name[IFNAMSIZ];
4409758b77fSLuigi Rizzo } ipfw_insn_if;
441830cc178SLuigi Rizzo 
4429758b77fSLuigi Rizzo /*
443974dfe30SBrian Feldman  * This is used for storing an altq queue id number.
444974dfe30SBrian Feldman  */
445974dfe30SBrian Feldman typedef struct _ipfw_insn_altq {
446974dfe30SBrian Feldman 	ipfw_insn	o;
447974dfe30SBrian Feldman 	u_int32_t	qid;
448974dfe30SBrian Feldman } ipfw_insn_altq;
449974dfe30SBrian Feldman 
450974dfe30SBrian Feldman /*
4519758b77fSLuigi Rizzo  * This is used for limit rules.
45225549c00SJosef Karthauser  */
4539758b77fSLuigi Rizzo typedef struct	_ipfw_insn_limit {
4549758b77fSLuigi Rizzo 	ipfw_insn o;
4559758b77fSLuigi Rizzo 	u_int8_t _pad;
4569758b77fSLuigi Rizzo 	u_int8_t limit_mask;	/* combination of DYN_* below	*/
457830cc178SLuigi Rizzo #define	DYN_SRC_ADDR	0x1
458830cc178SLuigi Rizzo #define	DYN_SRC_PORT	0x2
459830cc178SLuigi Rizzo #define	DYN_DST_ADDR	0x4
460830cc178SLuigi Rizzo #define	DYN_DST_PORT	0x8
46125549c00SJosef Karthauser 
4629758b77fSLuigi Rizzo 	u_int16_t conn_limit;
4639758b77fSLuigi Rizzo } ipfw_insn_limit;
464e4676ba6SJulian Elischer 
46506dae58bSJosef Karthauser /*
466f030c151SLuigi Rizzo  * This is used for log instructions.
4679758b77fSLuigi Rizzo  */
4689758b77fSLuigi Rizzo typedef struct  _ipfw_insn_log {
4699758b77fSLuigi Rizzo         ipfw_insn o;
4709758b77fSLuigi Rizzo 	u_int32_t max_log;	/* how many do we log -- 0 = all */
4719758b77fSLuigi Rizzo 	u_int32_t log_left;	/* how many left to log 	*/
4729758b77fSLuigi Rizzo } ipfw_insn_log;
4739758b77fSLuigi Rizzo 
474d6164b77SAlexander V. Chernikov /* Legacy NAT structures, compat only */
475d6164b77SAlexander V. Chernikov #ifndef	_KERNEL
476bb5081a7SRobert Watson /*
477bb5081a7SRobert Watson  * Data structures required by both ipfw(8) and ipfw(4) but not part of the
478bcf5b9faSRobert Watson  * management API are protected by IPFW_INTERNAL.
479bb5081a7SRobert Watson  */
480bb5081a7SRobert Watson #ifdef IPFW_INTERNAL
481ff2f6fe8SPaolo Pisati /* Server pool support (LSNAT). */
482ff2f6fe8SPaolo Pisati struct cfg_spool {
483ff2f6fe8SPaolo Pisati 	LIST_ENTRY(cfg_spool)   _next;          /* chain of spool instances */
484ff2f6fe8SPaolo Pisati 	struct in_addr          addr;
485ff2f6fe8SPaolo Pisati 	u_short                 port;
486ff2f6fe8SPaolo Pisati };
487bb5081a7SRobert Watson #endif
488ff2f6fe8SPaolo Pisati 
489ff2f6fe8SPaolo Pisati /* Redirect modes id. */
490ff2f6fe8SPaolo Pisati #define REDIR_ADDR      0x01
491ff2f6fe8SPaolo Pisati #define REDIR_PORT      0x02
492ff2f6fe8SPaolo Pisati #define REDIR_PROTO     0x04
493ff2f6fe8SPaolo Pisati 
494bb5081a7SRobert Watson #ifdef IPFW_INTERNAL
495ff2f6fe8SPaolo Pisati /* Nat redirect configuration. */
496ff2f6fe8SPaolo Pisati struct cfg_redir {
497ff2f6fe8SPaolo Pisati 	LIST_ENTRY(cfg_redir)   _next;          /* chain of redir instances */
498ff2f6fe8SPaolo Pisati 	u_int16_t               mode;           /* type of redirect mode */
499ff2f6fe8SPaolo Pisati 	struct in_addr	        laddr;          /* local ip address */
500ff2f6fe8SPaolo Pisati 	struct in_addr	        paddr;          /* public ip address */
501ff2f6fe8SPaolo Pisati 	struct in_addr	        raddr;          /* remote ip address */
502ff2f6fe8SPaolo Pisati 	u_short                 lport;          /* local port */
503ff2f6fe8SPaolo Pisati 	u_short                 pport;          /* public port */
504ff2f6fe8SPaolo Pisati 	u_short                 rport;          /* remote port  */
505ff2f6fe8SPaolo Pisati 	u_short                 pport_cnt;      /* number of public ports */
506ff2f6fe8SPaolo Pisati 	u_short                 rport_cnt;      /* number of remote ports */
507ff2f6fe8SPaolo Pisati 	int                     proto;          /* protocol: tcp/udp */
508ff2f6fe8SPaolo Pisati 	struct alias_link       **alink;
509ff2f6fe8SPaolo Pisati 	/* num of entry in spool chain */
510ff2f6fe8SPaolo Pisati 	u_int16_t               spool_cnt;
511ff2f6fe8SPaolo Pisati 	/* chain of spool instances */
512ff2f6fe8SPaolo Pisati 	LIST_HEAD(spool_chain, cfg_spool) spool_chain;
513ff2f6fe8SPaolo Pisati };
514bb5081a7SRobert Watson #endif
515ff2f6fe8SPaolo Pisati 
516bb5081a7SRobert Watson #ifdef IPFW_INTERNAL
517ff2f6fe8SPaolo Pisati /* Nat configuration data struct. */
518ff2f6fe8SPaolo Pisati struct cfg_nat {
519ff2f6fe8SPaolo Pisati 	/* chain of nat instances */
520ff2f6fe8SPaolo Pisati 	LIST_ENTRY(cfg_nat)     _next;
521ff2f6fe8SPaolo Pisati 	int                     id;                     /* nat id */
522ff2f6fe8SPaolo Pisati 	struct in_addr          ip;                     /* nat ip address */
523ff2f6fe8SPaolo Pisati 	char                    if_name[IF_NAMESIZE];   /* interface name */
524ff2f6fe8SPaolo Pisati 	int                     mode;                   /* aliasing mode */
525ff2f6fe8SPaolo Pisati 	struct libalias	        *lib;                   /* libalias instance */
526ff2f6fe8SPaolo Pisati 	/* number of entry in spool chain */
527ff2f6fe8SPaolo Pisati 	int                     redir_cnt;
528ff2f6fe8SPaolo Pisati 	/* chain of redir instances */
529ff2f6fe8SPaolo Pisati 	LIST_HEAD(redir_chain, cfg_redir) redir_chain;
530ff2f6fe8SPaolo Pisati };
531bb5081a7SRobert Watson #endif
532ff2f6fe8SPaolo Pisati 
533ff2f6fe8SPaolo Pisati #define SOF_NAT         sizeof(struct cfg_nat)
534ff2f6fe8SPaolo Pisati #define SOF_REDIR       sizeof(struct cfg_redir)
535ff2f6fe8SPaolo Pisati #define SOF_SPOOL       sizeof(struct cfg_spool)
536ff2f6fe8SPaolo Pisati 
537d6164b77SAlexander V. Chernikov #endif	/* ifndef _KERNEL */
538d6164b77SAlexander V. Chernikov 
539d6164b77SAlexander V. Chernikov struct nat44_cfg_spool {
540d6164b77SAlexander V. Chernikov 	struct in_addr	addr;
541d6164b77SAlexander V. Chernikov 	uint16_t	port;
542d6164b77SAlexander V. Chernikov 	uint16_t	spare;
543d6164b77SAlexander V. Chernikov };
544d6164b77SAlexander V. Chernikov #define NAT44_REDIR_ADDR	0x01
545d6164b77SAlexander V. Chernikov #define NAT44_REDIR_PORT	0x02
546d6164b77SAlexander V. Chernikov #define NAT44_REDIR_PROTO	0x04
547d6164b77SAlexander V. Chernikov 
548d6164b77SAlexander V. Chernikov /* Nat redirect configuration. */
549d6164b77SAlexander V. Chernikov struct nat44_cfg_redir {
550d6164b77SAlexander V. Chernikov 	struct in_addr	laddr;		/* local ip address */
551d6164b77SAlexander V. Chernikov 	struct in_addr	paddr;		/* public ip address */
552d6164b77SAlexander V. Chernikov 	struct in_addr	raddr;		/* remote ip address */
553d6164b77SAlexander V. Chernikov 	uint16_t	lport;		/* local port */
554d6164b77SAlexander V. Chernikov 	uint16_t	pport;		/* public port */
555d6164b77SAlexander V. Chernikov 	uint16_t	rport;		/* remote port  */
556d6164b77SAlexander V. Chernikov 	uint16_t	pport_cnt;	/* number of public ports */
557d6164b77SAlexander V. Chernikov 	uint16_t	rport_cnt;	/* number of remote ports */
558d6164b77SAlexander V. Chernikov 	uint16_t	mode;		/* type of redirect mode */
559d6164b77SAlexander V. Chernikov 	uint16_t	spool_cnt;	/* num of entry in spool chain */
560d6164b77SAlexander V. Chernikov 	uint16_t	spare;
561d6164b77SAlexander V. Chernikov 	uint32_t	proto;		/* protocol: tcp/udp */
562d6164b77SAlexander V. Chernikov };
563d6164b77SAlexander V. Chernikov 
564d6164b77SAlexander V. Chernikov /* Nat configuration data struct. */
565d6164b77SAlexander V. Chernikov struct nat44_cfg_nat {
566d6164b77SAlexander V. Chernikov 	char		name[64];	/* nat name */
567d6164b77SAlexander V. Chernikov 	char		if_name[64];	/* interface name */
568d6164b77SAlexander V. Chernikov 	uint32_t	size;		/* structure size incl. redirs */
569d6164b77SAlexander V. Chernikov 	struct in_addr	ip;		/* nat IPv4 address */
570d6164b77SAlexander V. Chernikov 	uint32_t	mode;		/* aliasing mode */
571d6164b77SAlexander V. Chernikov 	uint32_t	redir_cnt;	/* number of entry in spool chain */
572a08cdb6cSNeel Chauhan 	u_short		alias_port_lo;	/* low range for port aliasing */
573a08cdb6cSNeel Chauhan 	u_short		alias_port_hi;	/* high range for port aliasing */
574d6164b77SAlexander V. Chernikov };
575d6164b77SAlexander V. Chernikov 
576ff2f6fe8SPaolo Pisati /* Nat command. */
577ff2f6fe8SPaolo Pisati typedef struct	_ipfw_insn_nat {
578ff2f6fe8SPaolo Pisati  	ipfw_insn	o;
579ff2f6fe8SPaolo Pisati  	struct cfg_nat *nat;
580ff2f6fe8SPaolo Pisati } ipfw_insn_nat;
581ff2f6fe8SPaolo Pisati 
5828195404bSBrooks Davis /* Apply ipv6 mask on ipv6 addr */
5835786c6b9SAndrey V. Elsukov #define APPLY_MASK(addr,mask)	do {					\
5848195404bSBrooks Davis     (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \
5858195404bSBrooks Davis     (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \
5868195404bSBrooks Davis     (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \
5875786c6b9SAndrey V. Elsukov     (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; \
5885786c6b9SAndrey V. Elsukov } while (0)
5898195404bSBrooks Davis 
5908195404bSBrooks Davis /* Structure for ipv6 */
5918195404bSBrooks Davis typedef struct _ipfw_insn_ip6 {
5928195404bSBrooks Davis        ipfw_insn o;
5938195404bSBrooks Davis        struct in6_addr addr6;
5948195404bSBrooks Davis        struct in6_addr mask6;
5958195404bSBrooks Davis } ipfw_insn_ip6;
5968195404bSBrooks Davis 
5978195404bSBrooks Davis /* Used to support icmp6 types */
5988195404bSBrooks Davis typedef struct _ipfw_insn_icmp6 {
5998195404bSBrooks Davis        ipfw_insn o;
6008195404bSBrooks Davis        uint32_t d[7]; /* XXX This number si related to the netinet/icmp6.h
6018195404bSBrooks Davis                        *     define ICMP6_MAXTYPE
6028195404bSBrooks Davis                        *     as follows: n = ICMP6_MAXTYPE/32 + 1
6038195404bSBrooks Davis                         *     Actually is 203
6048195404bSBrooks Davis                        */
6058195404bSBrooks Davis } ipfw_insn_icmp6;
6068195404bSBrooks Davis 
6079758b77fSLuigi Rizzo /*
6089758b77fSLuigi Rizzo  * Here we have the structure representing an ipfw rule.
60932f967a3SLuigi Rizzo  *
6107e767c79SAlexander V. Chernikov  * Layout:
6117e767c79SAlexander V. Chernikov  * struct ip_fw_rule
6127e767c79SAlexander V. Chernikov  * [ counter block, size = rule->cntr_len ]
6137e767c79SAlexander V. Chernikov  * [ one or more instructions, size = rule->cmd_len * 4 ]
6147e767c79SAlexander V. Chernikov  *
6157e767c79SAlexander V. Chernikov  * It starts with a general area (with link fields).
6167e767c79SAlexander V. Chernikov  * Counter block may be next (if rule->cntr_len > 0),
6179758b77fSLuigi Rizzo  * followed by an array of one or more instructions, which the code
6187e767c79SAlexander V. Chernikov  * accesses as an array of 32-bit values. rule->cmd_len represents
6197e767c79SAlexander V. Chernikov  * the total instructions legth in u32 worrd, while act_ofs represents
6207e767c79SAlexander V. Chernikov  * rule action offset in u32 words.
6219758b77fSLuigi Rizzo  *
6229758b77fSLuigi Rizzo  * When assembling instruction, remember the following:
6239758b77fSLuigi Rizzo  *
6249758b77fSLuigi Rizzo  *  + if a rule has a "keep-state" (or "limit") option, then the
6259758b77fSLuigi Rizzo  *	first instruction (at r->cmd) MUST BE an O_PROBE_STATE
6269758b77fSLuigi Rizzo  *  + if a rule has a "log" option, then the first action
6279758b77fSLuigi Rizzo  *	(at ACTION_PTR(r)) MUST be O_LOG
628974dfe30SBrian Feldman  *  + if a rule has an "altq" option, it comes after "log"
6296a7d5cb6SOleg Bulyzhin  *  + if a rule has an O_TAG option, it comes after "log" and "altq"
6309758b77fSLuigi Rizzo  *
6317e767c79SAlexander V. Chernikov  *
6327e767c79SAlexander V. Chernikov  * All structures (excluding instructions) are u64-aligned.
6337e767c79SAlexander V. Chernikov  * Please keep this.
63432f967a3SLuigi Rizzo  */
63532f967a3SLuigi Rizzo 
6367e767c79SAlexander V. Chernikov struct ip_fw_rule {
6377e767c79SAlexander V. Chernikov 	uint16_t	act_ofs;	/* offset of action in 32-bit units */
6387e767c79SAlexander V. Chernikov 	uint16_t	cmd_len;	/* # of 32-bit words in cmd	*/
6397e767c79SAlexander V. Chernikov 	uint16_t	spare;
6407e767c79SAlexander V. Chernikov 	uint8_t		set;		/* rule set (0..31)		*/
6417e767c79SAlexander V. Chernikov 	uint8_t		flags;		/* rule flags			*/
6427e767c79SAlexander V. Chernikov 	uint32_t	rulenum;	/* rule number			*/
6437e767c79SAlexander V. Chernikov 	uint32_t	id;		/* rule id			*/
6447e767c79SAlexander V. Chernikov 
6457e767c79SAlexander V. Chernikov 	ipfw_insn	cmd[1];		/* storage for commands		*/
6467e767c79SAlexander V. Chernikov };
6477e767c79SAlexander V. Chernikov #define	IPFW_RULE_NOOPT		0x01	/* Has no options in body	*/
648094d6f8dSAndrey V. Elsukov #define	IPFW_RULE_JUSTOPTS	0x02	/* new format of rule body	*/
6497e767c79SAlexander V. Chernikov 
6507e767c79SAlexander V. Chernikov /* Unaligned version */
6517e767c79SAlexander V. Chernikov 
6527e767c79SAlexander V. Chernikov /* Base ipfw rule counter block. */
6537e767c79SAlexander V. Chernikov struct ip_fw_bcounter {
6547e767c79SAlexander V. Chernikov 	uint16_t	size;		/* Size of counter block, bytes	*/
6557e767c79SAlexander V. Chernikov 	uint8_t		flags;		/* flags for given block	*/
6567e767c79SAlexander V. Chernikov 	uint8_t		spare;
6577e767c79SAlexander V. Chernikov 	uint32_t	timestamp;	/* tv_sec of last match		*/
6587e767c79SAlexander V. Chernikov 	uint64_t	pcnt;		/* Packet counter		*/
6597e767c79SAlexander V. Chernikov 	uint64_t	bcnt;		/* Byte counter			*/
6607e767c79SAlexander V. Chernikov };
6617e767c79SAlexander V. Chernikov 
6627e767c79SAlexander V. Chernikov #ifndef	_KERNEL
6637e767c79SAlexander V. Chernikov /*
6647e767c79SAlexander V. Chernikov  * Legacy rule format
6657e767c79SAlexander V. Chernikov  */
6669758b77fSLuigi Rizzo struct ip_fw {
667de240d10SLuigi Rizzo 	struct ip_fw	*x_next;	/* linked list of rules		*/
668a8c102a2SLuigi Rizzo 	struct ip_fw	*next_rule;	/* ptr to next [skipto] rule	*/
669f030c151SLuigi Rizzo 	/* 'next_rule' is used to pass up 'set_disable' status		*/
670f030c151SLuigi Rizzo 
671dda10d62SOleg Bulyzhin 	uint16_t	act_ofs;	/* offset of action in 32-bit units */
672dda10d62SOleg Bulyzhin 	uint16_t	cmd_len;	/* # of 32-bit words in cmd	*/
673dda10d62SOleg Bulyzhin 	uint16_t	rulenum;	/* rule number			*/
674dda10d62SOleg Bulyzhin 	uint8_t		set;		/* rule set (0..31)		*/
675dda10d62SOleg Bulyzhin 	uint8_t		_pad;		/* padding			*/
676dda10d62SOleg Bulyzhin 	uint32_t	id;		/* rule id */
6779758b77fSLuigi Rizzo 
6789758b77fSLuigi Rizzo 	/* These fields are present in all rules.			*/
679dda10d62SOleg Bulyzhin 	uint64_t	pcnt;		/* Packet counter		*/
680dda10d62SOleg Bulyzhin 	uint64_t	bcnt;		/* Byte counter			*/
681dda10d62SOleg Bulyzhin 	uint32_t	timestamp;	/* tv_sec of last match		*/
6829758b77fSLuigi Rizzo 
6839758b77fSLuigi Rizzo 	ipfw_insn	cmd[1];		/* storage for commands		*/
6849758b77fSLuigi Rizzo };
6857e767c79SAlexander V. Chernikov #endif
6869758b77fSLuigi Rizzo 
6879758b77fSLuigi Rizzo #define ACTION_PTR(rule)				\
6889758b77fSLuigi Rizzo 	(ipfw_insn *)( (u_int32_t *)((rule)->cmd) + ((rule)->act_ofs) )
6899758b77fSLuigi Rizzo 
6907e767c79SAlexander V. Chernikov #define RULESIZE(rule)  (sizeof(*(rule)) + (rule)->cmd_len * 4 - 4)
6917e767c79SAlexander V. Chernikov 
692f9f7bde3SLuigi Rizzo #if 1 // should be moved to in.h
693100ba1a6SJordan K. Hubbard /*
6949758b77fSLuigi Rizzo  * This structure is used as a flow mask and a flow id for various
6959758b77fSLuigi Rizzo  * parts of the code.
696f9f7bde3SLuigi Rizzo  * addr_type is used in userland and kernel to mark the address type.
697f9f7bde3SLuigi Rizzo  * fib is used in the kernel to record the fib in use.
698f9f7bde3SLuigi Rizzo  * _flags is used in the kernel to store tcp flags for dynamic rules.
69903c61266SLuigi Rizzo  */
70003c61266SLuigi Rizzo struct ipfw_flow_id {
701cc4d3c30SLuigi Rizzo 	uint32_t	dst_ip;
702cc4d3c30SLuigi Rizzo 	uint32_t	src_ip;
703cc4d3c30SLuigi Rizzo 	uint16_t	dst_port;
704cc4d3c30SLuigi Rizzo 	uint16_t	src_port;
705b99a6823SAndrey V. Elsukov 	uint8_t		fib;	/* XXX: must be uint16_t */
706cc4d3c30SLuigi Rizzo 	uint8_t		proto;
707f9f7bde3SLuigi Rizzo 	uint8_t		_flags;	/* protocol-specific flags */
708f9f7bde3SLuigi Rizzo 	uint8_t		addr_type; /* 4=ip4, 6=ip6, 1=ether ? */
709cc4d3c30SLuigi Rizzo 	struct in6_addr dst_ip6;
7108195404bSBrooks Davis 	struct in6_addr src_ip6;
711cc4d3c30SLuigi Rizzo 	uint32_t	flow_id6;
712f9f7bde3SLuigi Rizzo 	uint32_t	extra; /* queue/pipe or frag_id */
71303c61266SLuigi Rizzo };
714cc4d3c30SLuigi Rizzo #endif
71503c61266SLuigi Rizzo 
716b99a6823SAndrey V. Elsukov #define	IS_IP4_FLOW_ID(id)	((id)->addr_type == 4)
7178195404bSBrooks Davis #define IS_IP6_FLOW_ID(id)	((id)->addr_type == 6)
7188195404bSBrooks Davis 
71903c61266SLuigi Rizzo /*
720f030c151SLuigi Rizzo  * Dynamic ipfw rule.
72103c61266SLuigi Rizzo  */
7229758b77fSLuigi Rizzo typedef struct _ipfw_dyn_rule ipfw_dyn_rule;
7239758b77fSLuigi Rizzo 
7249758b77fSLuigi Rizzo struct _ipfw_dyn_rule {
7259758b77fSLuigi Rizzo 	ipfw_dyn_rule	*next;		/* linked list of rules.	*/
726830cc178SLuigi Rizzo 	struct ip_fw *rule;		/* pointer to rule		*/
727f030c151SLuigi Rizzo 	/* 'rule' is used to pass up the rule number (from the parent)	*/
728f030c151SLuigi Rizzo 
7299758b77fSLuigi Rizzo 	ipfw_dyn_rule *parent;		/* pointer to parent rule	*/
7309758b77fSLuigi Rizzo 	u_int64_t	pcnt;		/* packet match counter		*/
7319758b77fSLuigi Rizzo 	u_int64_t	bcnt;		/* byte match counter		*/
732330462a3SBernd Walter 	struct ipfw_flow_id id;		/* (masked) flow id		*/
733330462a3SBernd Walter 	u_int32_t	expire;		/* expire time			*/
73403c61266SLuigi Rizzo 	u_int32_t	bucket;		/* which bucket in hash table	*/
73525549c00SJosef Karthauser 	u_int32_t	state;		/* state of this rule (typically a
73625549c00SJosef Karthauser 					 * combination of TCP flags)
73725549c00SJosef Karthauser 					 */
738d66f9c86SAndrey V. Elsukov #define	IPFW_DYN_ORPHANED	0x40000	/* state's parent rule was deleted */
739a8c102a2SLuigi Rizzo 	u_int32_t	ack_fwd;	/* most recent ACKs in forward	*/
740a8c102a2SLuigi Rizzo 	u_int32_t	ack_rev;	/* and reverse directions (used	*/
741a8c102a2SLuigi Rizzo 					/* to generate keepalives)	*/
74232f967a3SLuigi Rizzo 	u_int16_t	dyn_type;	/* rule type			*/
74332f967a3SLuigi Rizzo 	u_int16_t	count;		/* refcount			*/
744ed22e564SAndrey V. Elsukov 	u_int16_t	kidx;		/* index of named object */
745ed22e564SAndrey V. Elsukov } __packed __aligned(8);
74603c61266SLuigi Rizzo 
74703c61266SLuigi Rizzo /*
74837afa1e8SUgen J.S. Antsilevich  * Definitions for IP option names.
74937afa1e8SUgen J.S. Antsilevich  */
75037afa1e8SUgen J.S. Antsilevich #define	IP_FW_IPOPT_LSRR	0x01
75137afa1e8SUgen J.S. Antsilevich #define	IP_FW_IPOPT_SSRR	0x02
75237afa1e8SUgen J.S. Antsilevich #define	IP_FW_IPOPT_RR		0x04
75337afa1e8SUgen J.S. Antsilevich #define	IP_FW_IPOPT_TS		0x08
75437afa1e8SUgen J.S. Antsilevich 
75537afa1e8SUgen J.S. Antsilevich /*
7569714563dSDan Moschuk  * Definitions for TCP option names.
7579714563dSDan Moschuk  */
7589714563dSDan Moschuk #define	IP_FW_TCPOPT_MSS	0x01
7599714563dSDan Moschuk #define	IP_FW_TCPOPT_WINDOW	0x02
7609714563dSDan Moschuk #define	IP_FW_TCPOPT_SACK	0x04
7619714563dSDan Moschuk #define	IP_FW_TCPOPT_TS		0x08
7629714563dSDan Moschuk #define	IP_FW_TCPOPT_CC		0x10
7639714563dSDan Moschuk 
7649758b77fSLuigi Rizzo #define	ICMP_REJECT_RST		0x100	/* fake ICMP code (send a TCP RST) */
7659066356bSBjoern A. Zeeb #define	ICMP6_UNREACH_RST	0x100	/* fake ICMPv6 code (send a TCP RST) */
766665c8a2eSMichael Tuexen #define	ICMP_REJECT_ABORT	0x101	/* fake ICMP code (send an SCTP ABORT) */
767665c8a2eSMichael Tuexen #define	ICMP6_UNREACH_ABORT	0x101	/* fake ICMPv6 code (send an SCTP ABORT) */
7689758b77fSLuigi Rizzo 
7699714563dSDan Moschuk /*
770cd8b5ae0SRuslan Ermilov  * These are used for lookup tables.
771cd8b5ae0SRuslan Ermilov  */
772f8bee51aSAlexander V. Chernikov 
773c21034b7SAlexander V. Chernikov #define	IPFW_TABLE_ADDR		1	/* Table for holding IPv4/IPv6 prefixes */
774f8bee51aSAlexander V. Chernikov #define	IPFW_TABLE_INTERFACE	2	/* Table for holding interface names */
775b23d5de9SAlexander V. Chernikov #define	IPFW_TABLE_NUMBER	3	/* Table for holding ports/uid/gid/etc */
776914bffb6SAlexander V. Chernikov #define	IPFW_TABLE_FLOW		4	/* Table for holding flow data */
77781cac390SArseny Smalyuk #define	IPFW_TABLE_MAC		5	/* Table for holding mac address prefixes */
77881cac390SArseny Smalyuk #define	IPFW_TABLE_MAXTYPE	5	/* Maximum valid number */
779ac35ff17SAlexander V. Chernikov 
780c21034b7SAlexander V. Chernikov #define	IPFW_TABLE_CIDR	IPFW_TABLE_ADDR	/* compat */
781c21034b7SAlexander V. Chernikov 
782adf3b2b9SAlexander V. Chernikov /* Value types */
7830cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_LEGACY	0xFFFFFFFF	/* All data is filled in */
7840cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_SKIPTO	0x00000001	/* skipto/call/callreturn */
7850cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_PIPE		0x00000002	/* pipe/queue */
7860cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_FIB		0x00000004	/* setfib */
7870cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_NAT		0x00000008	/* nat */
7880cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_DSCP		0x00000010	/* dscp */
7890cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_TAG		0x00000020	/* tag/untag */
7900cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_DIVERT	0x00000040	/* divert/tee */
7910cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_NETGRAPH	0x00000080	/* netgraph/ngtee */
7922530ed9eSAndrey V. Elsukov #define	IPFW_VTYPE_LIMIT	0x00000100	/* limit */
7930cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_NH4		0x00000200	/* IPv4 nexthop */
7940cba2b28SAlexander V. Chernikov #define	IPFW_VTYPE_NH6		0x00000400	/* IPv6 nexthop */
795fc727ad6SBoris Lytochkin #define	IPFW_VTYPE_MARK		0x00000800	/* [fw]mark */
796f8bee51aSAlexander V. Chernikov 
79781cac390SArseny Smalyuk /* MAC/InfiniBand/etc address length */
79881cac390SArseny Smalyuk #define	IPFW_MAX_L2_ADDR_LEN	20
79981cac390SArseny Smalyuk 
800cd8b5ae0SRuslan Ermilov typedef struct	_ipfw_table_entry {
801cd8b5ae0SRuslan Ermilov 	in_addr_t	addr;		/* network address		*/
802cd8b5ae0SRuslan Ermilov 	u_int32_t	value;		/* value			*/
803cd8b5ae0SRuslan Ermilov 	u_int16_t	tbl;		/* table number			*/
804cd8b5ae0SRuslan Ermilov 	u_int8_t	masklen;	/* mask length			*/
805cd8b5ae0SRuslan Ermilov } ipfw_table_entry;
806cd8b5ae0SRuslan Ermilov 
807f8bee51aSAlexander V. Chernikov typedef struct	_ipfw_table_xentry {
808f8bee51aSAlexander V. Chernikov 	uint16_t	len;		/* Total entry length		*/
809f8bee51aSAlexander V. Chernikov 	uint8_t		type;		/* entry type			*/
810f8bee51aSAlexander V. Chernikov 	uint8_t		masklen;	/* mask length			*/
811f8bee51aSAlexander V. Chernikov 	uint16_t	tbl;		/* table number			*/
812c3015737SAlexander V. Chernikov 	uint16_t	flags;		/* record flags			*/
813f8bee51aSAlexander V. Chernikov 	uint32_t	value;		/* value			*/
814f8bee51aSAlexander V. Chernikov 	union {
815f8bee51aSAlexander V. Chernikov 		/* Longest field needs to be aligned by 4-byte boundary	*/
816f8bee51aSAlexander V. Chernikov 		struct in6_addr	addr6;	/* IPv6 address 		*/
817f8bee51aSAlexander V. Chernikov 		char	iface[IF_NAMESIZE];	/* interface name	*/
818f8bee51aSAlexander V. Chernikov 	} k;
819f8bee51aSAlexander V. Chernikov } ipfw_table_xentry;
820c3015737SAlexander V. Chernikov #define	IPFW_TCF_INET	0x01		/* CIDR flags: IPv4 record	*/
821f8bee51aSAlexander V. Chernikov 
822cd8b5ae0SRuslan Ermilov typedef struct	_ipfw_table {
823cd8b5ae0SRuslan Ermilov 	u_int32_t	size;		/* size of entries in bytes	*/
824cd8b5ae0SRuslan Ermilov 	u_int32_t	cnt;		/* # of entries			*/
825cd8b5ae0SRuslan Ermilov 	u_int16_t	tbl;		/* table number			*/
826cd8b5ae0SRuslan Ermilov 	ipfw_table_entry ent[0];	/* entries			*/
827cd8b5ae0SRuslan Ermilov } ipfw_table;
828cd8b5ae0SRuslan Ermilov 
829f8bee51aSAlexander V. Chernikov typedef struct	_ipfw_xtable {
830b074b7bbSAlexander V. Chernikov 	ip_fw3_opheader	opheader;	/* IP_FW3 opcode */
831f8bee51aSAlexander V. Chernikov 	uint32_t	size;		/* size of entries in bytes	*/
832f8bee51aSAlexander V. Chernikov 	uint32_t	cnt;		/* # of entries			*/
833f8bee51aSAlexander V. Chernikov 	uint16_t	tbl;		/* table number			*/
834f8bee51aSAlexander V. Chernikov 	uint8_t		type;		/* table type			*/
835f8bee51aSAlexander V. Chernikov 	ipfw_table_xentry xent[0];	/* entries			*/
836f8bee51aSAlexander V. Chernikov } ipfw_xtable;
837f8bee51aSAlexander V. Chernikov 
8389f7d47b0SAlexander V. Chernikov typedef struct  _ipfw_obj_tlv {
839b074b7bbSAlexander V. Chernikov 	uint16_t        type;		/* TLV type */
840ac35ff17SAlexander V. Chernikov 	uint16_t	flags;		/* TLV-specific flags		*/
841563b5ab1SAlexander V. Chernikov 	uint32_t        length;		/* Total length, aligned to u64	*/
8429f7d47b0SAlexander V. Chernikov } ipfw_obj_tlv;
843563b5ab1SAlexander V. Chernikov #define	IPFW_TLV_TBL_NAME	1
844563b5ab1SAlexander V. Chernikov #define	IPFW_TLV_TBLNAME_LIST	2
845563b5ab1SAlexander V. Chernikov #define	IPFW_TLV_RULE_LIST	3
8466447bae6SAlexander V. Chernikov #define	IPFW_TLV_DYNSTATE_LIST	4
847ac35ff17SAlexander V. Chernikov #define	IPFW_TLV_TBL_ENT	5
8486447bae6SAlexander V. Chernikov #define	IPFW_TLV_DYN_ENT	6
8497e767c79SAlexander V. Chernikov #define	IPFW_TLV_RULE_ENT	7
85068394ec8SAlexander V. Chernikov #define	IPFW_TLV_TBLENT_LIST	8
851a73d728dSAlexander V. Chernikov #define	IPFW_TLV_RANGE		9
8522acdf79fSAndrey V. Elsukov #define	IPFW_TLV_EACTION	10
853b867e84eSAndrey V. Elsukov #define	IPFW_TLV_COUNTERS	11
854d8caf56eSAndrey V. Elsukov #define	IPFW_TLV_OBJDATA	12
855ed22e564SAndrey V. Elsukov #define	IPFW_TLV_STATE_NAME	14
8562acdf79fSAndrey V. Elsukov 
8572acdf79fSAndrey V. Elsukov #define	IPFW_TLV_EACTION_BASE	1000
8582acdf79fSAndrey V. Elsukov #define	IPFW_TLV_EACTION_NAME(arg)	(IPFW_TLV_EACTION_BASE + (arg))
859b074b7bbSAlexander V. Chernikov 
860d8caf56eSAndrey V. Elsukov typedef struct _ipfw_obj_data {
861d8caf56eSAndrey V. Elsukov 	ipfw_obj_tlv	head;
862d8caf56eSAndrey V. Elsukov 	void		*data[0];
863d8caf56eSAndrey V. Elsukov } ipfw_obj_data;
864d8caf56eSAndrey V. Elsukov 
865b074b7bbSAlexander V. Chernikov /* Object name TLV */
8669f7d47b0SAlexander V. Chernikov typedef struct _ipfw_obj_ntlv {
8679f7d47b0SAlexander V. Chernikov 	ipfw_obj_tlv	head;		/* TLV header			*/
868b074b7bbSAlexander V. Chernikov 	uint16_t	idx;		/* Name index			*/
8692685841bSAndrey V. Elsukov 	uint8_t		set;		/* set, if applicable		*/
870ac35ff17SAlexander V. Chernikov 	uint8_t		type;		/* object type, if applicable	*/
8712685841bSAndrey V. Elsukov 	uint32_t	spare;		/* unused			*/
872b074b7bbSAlexander V. Chernikov 	char		name[64];	/* Null-terminated name		*/
8739f7d47b0SAlexander V. Chernikov } ipfw_obj_ntlv;
874b074b7bbSAlexander V. Chernikov 
875914bffb6SAlexander V. Chernikov /* IPv4/IPv6 L4 flow description */
876914bffb6SAlexander V. Chernikov struct tflow_entry {
877914bffb6SAlexander V. Chernikov 	uint8_t		af;
878914bffb6SAlexander V. Chernikov 	uint8_t		proto;
879914bffb6SAlexander V. Chernikov 	uint16_t	spare;
880914bffb6SAlexander V. Chernikov 	uint16_t	sport;
881914bffb6SAlexander V. Chernikov 	uint16_t	dport;
882914bffb6SAlexander V. Chernikov 	union {
883914bffb6SAlexander V. Chernikov 		struct {
884914bffb6SAlexander V. Chernikov 			struct in_addr	sip;
885914bffb6SAlexander V. Chernikov 			struct in_addr	dip;
886914bffb6SAlexander V. Chernikov 		} a4;
887914bffb6SAlexander V. Chernikov 		struct {
888914bffb6SAlexander V. Chernikov 			struct in6_addr	sip6;
889914bffb6SAlexander V. Chernikov 			struct in6_addr	dip6;
890914bffb6SAlexander V. Chernikov 		} a6;
891914bffb6SAlexander V. Chernikov 	} a;
892914bffb6SAlexander V. Chernikov };
893914bffb6SAlexander V. Chernikov 
894fc727ad6SBoris Lytochkin /* 64-byte structure representing multi-field table value */
8950cba2b28SAlexander V. Chernikov typedef struct _ipfw_table_value {
8960cba2b28SAlexander V. Chernikov 	uint32_t	tag;		/* O_TAG/O_TAGGED */
8970cba2b28SAlexander V. Chernikov 	uint32_t	pipe;		/* O_PIPE/O_QUEUE */
8980cba2b28SAlexander V. Chernikov 	uint16_t	divert;		/* O_DIVERT/O_TEE */
8990cba2b28SAlexander V. Chernikov 	uint16_t	skipto;		/* skipto, CALLRET */
9000cba2b28SAlexander V. Chernikov 	uint32_t	netgraph;	/* O_NETGRAPH/O_NGTEE */
9010cba2b28SAlexander V. Chernikov 	uint32_t	fib;		/* O_SETFIB */
9020cba2b28SAlexander V. Chernikov 	uint32_t	nat;		/* O_NAT */
9030cba2b28SAlexander V. Chernikov 	uint32_t	nh4;
9040cba2b28SAlexander V. Chernikov 	uint8_t		dscp;
9052530ed9eSAndrey V. Elsukov 	uint8_t		spare0;
906fc727ad6SBoris Lytochkin 	uint16_t	kidx;		/* value kernel index */
9070cba2b28SAlexander V. Chernikov 	struct in6_addr	nh6;
9080cba2b28SAlexander V. Chernikov 	uint32_t	limit;		/* O_LIMIT */
9092530ed9eSAndrey V. Elsukov 	uint32_t	zoneid;		/* scope zone id for nh6 */
910fc727ad6SBoris Lytochkin 	uint32_t	mark;		/* O_SETMARK/O_MARK */
911fc727ad6SBoris Lytochkin 	uint32_t	refcnt;		/* XXX 64-bit in kernel */
9120cba2b28SAlexander V. Chernikov } ipfw_table_value;
9130cba2b28SAlexander V. Chernikov 
914ac35ff17SAlexander V. Chernikov /* Table entry TLV */
915ac35ff17SAlexander V. Chernikov typedef struct	_ipfw_obj_tentry {
916ac35ff17SAlexander V. Chernikov 	ipfw_obj_tlv	head;		/* TLV header			*/
917ac35ff17SAlexander V. Chernikov 	uint8_t		subtype;	/* subtype (IPv4,IPv6)		*/
918ac35ff17SAlexander V. Chernikov 	uint8_t		masklen;	/* mask length			*/
9193a845e10SAlexander V. Chernikov 	uint8_t		result;		/* request result		*/
9203a845e10SAlexander V. Chernikov 	uint8_t		spare0;
9214bbd1577SAlexander V. Chernikov 	uint16_t	idx;		/* Table name index		*/
9223a845e10SAlexander V. Chernikov 	uint16_t	spare1;
923ac35ff17SAlexander V. Chernikov 	union {
924ac35ff17SAlexander V. Chernikov 		/* Longest field needs to be aligned by 8-byte boundary	*/
925ac35ff17SAlexander V. Chernikov 		struct in_addr		addr;		/* IPv4 address		*/
926ac35ff17SAlexander V. Chernikov 		uint32_t		key;		/* uid/gid/port		*/
927ac35ff17SAlexander V. Chernikov 		struct in6_addr		addr6;		/* IPv6 address 	*/
928ac35ff17SAlexander V. Chernikov 		char	iface[IF_NAMESIZE];		/* interface name	*/
92981cac390SArseny Smalyuk 		u_char	mac[IPFW_MAX_L2_ADDR_LEN];	/* MAC address		*/
930914bffb6SAlexander V. Chernikov 		struct tflow_entry	flow;
931ac35ff17SAlexander V. Chernikov 	} k;
9324bbd1577SAlexander V. Chernikov 	union {
9330cba2b28SAlexander V. Chernikov 		ipfw_table_value	value;	/* value data */
9340cba2b28SAlexander V. Chernikov 		uint32_t		kidx;	/* value kernel index */
9354bbd1577SAlexander V. Chernikov 	} v;
936ac35ff17SAlexander V. Chernikov } ipfw_obj_tentry;
937ac35ff17SAlexander V. Chernikov #define	IPFW_TF_UPDATE	0x01		/* Update record if exists	*/
9383a845e10SAlexander V. Chernikov /* Container TLV */
9393a845e10SAlexander V. Chernikov #define	IPFW_CTF_ATOMIC	0x01		/* Perform atomic operation	*/
9403a845e10SAlexander V. Chernikov /* Operation results */
9413a845e10SAlexander V. Chernikov #define	IPFW_TR_IGNORED		0	/* Entry was ignored (rollback)	*/
942a4641f4eSPedro F. Giffuni #define	IPFW_TR_ADDED		1	/* Entry was successfully added	*/
943a4641f4eSPedro F. Giffuni #define	IPFW_TR_UPDATED		2	/* Entry was successfully updated*/
944a4641f4eSPedro F. Giffuni #define	IPFW_TR_DELETED		3	/* Entry was successfully deleted*/
9453a845e10SAlexander V. Chernikov #define	IPFW_TR_LIMIT		4	/* Entry was ignored (limit)	*/
9463a845e10SAlexander V. Chernikov #define	IPFW_TR_NOTFOUND	5	/* Entry was not found		*/
9473a845e10SAlexander V. Chernikov #define	IPFW_TR_EXISTS		6	/* Entry already exists		*/
9483a845e10SAlexander V. Chernikov #define	IPFW_TR_ERROR		7	/* Request has failed (unknown)	*/
949ac35ff17SAlexander V. Chernikov 
9506447bae6SAlexander V. Chernikov typedef struct _ipfw_obj_dyntlv {
9516447bae6SAlexander V. Chernikov 	ipfw_obj_tlv	head;
9526447bae6SAlexander V. Chernikov 	ipfw_dyn_rule	state;
9536447bae6SAlexander V. Chernikov } ipfw_obj_dyntlv;
9546447bae6SAlexander V. Chernikov #define	IPFW_DF_LAST	0x01		/* Last state in chain		*/
9556447bae6SAlexander V. Chernikov 
956563b5ab1SAlexander V. Chernikov /* Containter TLVs */
957563b5ab1SAlexander V. Chernikov typedef struct _ipfw_obj_ctlv {
958563b5ab1SAlexander V. Chernikov 	ipfw_obj_tlv	head;		/* TLV header			*/
959563b5ab1SAlexander V. Chernikov 	uint32_t	count;		/* Number of sub-TLVs		*/
9607e767c79SAlexander V. Chernikov 	uint16_t	objsize;	/* Single object size		*/
9617e767c79SAlexander V. Chernikov 	uint8_t		version;	/* TLV version			*/
9623a845e10SAlexander V. Chernikov 	uint8_t		flags;		/* TLV-specific flags		*/
963563b5ab1SAlexander V. Chernikov } ipfw_obj_ctlv;
964563b5ab1SAlexander V. Chernikov 
965a73d728dSAlexander V. Chernikov /* Range TLV */
966a73d728dSAlexander V. Chernikov typedef struct _ipfw_range_tlv {
967a73d728dSAlexander V. Chernikov 	ipfw_obj_tlv	head;		/* TLV header			*/
968a73d728dSAlexander V. Chernikov 	uint32_t	flags;		/* Range flags			*/
969a73d728dSAlexander V. Chernikov 	uint16_t	start_rule;	/* Range start			*/
970a73d728dSAlexander V. Chernikov 	uint16_t	end_rule;	/* Range end			*/
971a73d728dSAlexander V. Chernikov 	uint32_t	set;		/* Range set to match		 */
972a73d728dSAlexander V. Chernikov 	uint32_t	new_set;	/* New set to move/swap to	*/
973a73d728dSAlexander V. Chernikov } ipfw_range_tlv;
974a73d728dSAlexander V. Chernikov #define	IPFW_RCFLAG_RANGE	0x01	/* rule range is set		*/
975a73d728dSAlexander V. Chernikov #define	IPFW_RCFLAG_ALL		0x02	/* match ALL rules		*/
976a73d728dSAlexander V. Chernikov #define	IPFW_RCFLAG_SET		0x04	/* match rules in given set	*/
977d66f9c86SAndrey V. Elsukov #define	IPFW_RCFLAG_DYNAMIC	0x08	/* match only dynamic states	*/
9782930362fSAlexander V. Chernikov /* User-settable flags */
9792930362fSAlexander V. Chernikov #define	IPFW_RCFLAG_USER	(IPFW_RCFLAG_RANGE | IPFW_RCFLAG_ALL | \
980d66f9c86SAndrey V. Elsukov 	IPFW_RCFLAG_SET | IPFW_RCFLAG_DYNAMIC)
9812930362fSAlexander V. Chernikov /* Internally used flags */
982*78e4dbc3SGordon Bergling #define	IPFW_RCFLAG_DEFAULT	0x0100	/* Do not skip default rule	*/
983a73d728dSAlexander V. Chernikov 
9845f379342SAlexander V. Chernikov typedef struct _ipfw_ta_tinfo {
985914bffb6SAlexander V. Chernikov 	uint32_t	flags;		/* Format flags			*/
9865f379342SAlexander V. Chernikov 	uint32_t	spare;
9875f379342SAlexander V. Chernikov 	uint8_t		taclass4;	/* algorithm class		*/
9885f379342SAlexander V. Chernikov 	uint8_t		spare4;
9895f379342SAlexander V. Chernikov 	uint16_t	itemsize4;	/* item size in runtime		*/
9905f379342SAlexander V. Chernikov 	uint32_t	size4;		/* runtime structure size	*/
9915f379342SAlexander V. Chernikov 	uint32_t	count4;		/* number of items in runtime	*/
9925f379342SAlexander V. Chernikov 	uint8_t		taclass6;	/* algorithm class		*/
9935f379342SAlexander V. Chernikov 	uint8_t		spare6;
9945f379342SAlexander V. Chernikov 	uint16_t	itemsize6;	/* item size in runtime		*/
9955f379342SAlexander V. Chernikov 	uint32_t	size6;		/* runtime structure size	*/
9965f379342SAlexander V. Chernikov 	uint32_t	count6;		/* number of items in runtime	*/
9975f379342SAlexander V. Chernikov } ipfw_ta_tinfo;
998914bffb6SAlexander V. Chernikov #define	IPFW_TACLASS_HASH	1	/* algo is based on hash	*/
999914bffb6SAlexander V. Chernikov #define	IPFW_TACLASS_ARRAY	2	/* algo is based on array	*/
1000914bffb6SAlexander V. Chernikov #define	IPFW_TACLASS_RADIX	3	/* algo is based on radix tree	*/
1001914bffb6SAlexander V. Chernikov 
1002914bffb6SAlexander V. Chernikov #define	IPFW_TATFLAGS_DATA	0x0001		/* Has data filled in	*/
10035f379342SAlexander V. Chernikov #define	IPFW_TATFLAGS_AFDATA	0x0002		/* Separate data per AF	*/
10045f379342SAlexander V. Chernikov #define	IPFW_TATFLAGS_AFITEM	0x0004		/* diff. items per AF	*/
1005914bffb6SAlexander V. Chernikov 
10069f7d47b0SAlexander V. Chernikov typedef struct _ipfw_xtable_info {
1007c21034b7SAlexander V. Chernikov 	uint8_t		type;		/* table type (addr,iface,..)	*/
1008914bffb6SAlexander V. Chernikov 	uint8_t		tflags;		/* type flags			*/
1009adf3b2b9SAlexander V. Chernikov 	uint16_t	mflags;		/* modification flags		*/
10104f43138aSAlexander V. Chernikov 	uint16_t	flags;		/* generic table flags		*/
10110cba2b28SAlexander V. Chernikov 	uint16_t	spare[3];
10120cba2b28SAlexander V. Chernikov 	uint32_t	vmask;		/* bitmask with value types 	*/
10139f7d47b0SAlexander V. Chernikov 	uint32_t	set;		/* set table is in		*/
10149f7d47b0SAlexander V. Chernikov 	uint32_t	kidx;		/* kernel index			*/
10159f7d47b0SAlexander V. Chernikov 	uint32_t	refcnt;		/* number of references		*/
10169f7d47b0SAlexander V. Chernikov 	uint32_t	count;		/* Number of records		*/
1017914bffb6SAlexander V. Chernikov 	uint32_t	size;		/* Total size of records(export)*/
10184c0c07a5SAlexander V. Chernikov 	uint32_t	limit;		/* Max number of records	*/
10199f7d47b0SAlexander V. Chernikov 	char		tablename[64];	/* table name */
1020914bffb6SAlexander V. Chernikov 	char		algoname[64];	/* algorithm name		*/
10215f379342SAlexander V. Chernikov 	ipfw_ta_tinfo	ta_info;	/* additional algo stats	*/
10229f7d47b0SAlexander V. Chernikov } ipfw_xtable_info;
10234f43138aSAlexander V. Chernikov /* Generic table flags */
10244f43138aSAlexander V. Chernikov #define	IPFW_TGFLAGS_LOCKED	0x01	/* Tables is locked from changes*/
10254f43138aSAlexander V. Chernikov /* Table type-specific flags */
1026914bffb6SAlexander V. Chernikov #define	IPFW_TFFLAG_SRCIP	0x01
1027914bffb6SAlexander V. Chernikov #define	IPFW_TFFLAG_DSTIP	0x02
1028914bffb6SAlexander V. Chernikov #define	IPFW_TFFLAG_SRCPORT	0x04
1029914bffb6SAlexander V. Chernikov #define	IPFW_TFFLAG_DSTPORT	0x08
1030914bffb6SAlexander V. Chernikov #define	IPFW_TFFLAG_PROTO	0x10
10314f43138aSAlexander V. Chernikov /* Table modification flags */
10324f43138aSAlexander V. Chernikov #define	IPFW_TMFLAGS_LIMIT	0x0002	/* Change limit value		*/
10334f43138aSAlexander V. Chernikov #define	IPFW_TMFLAGS_LOCK	0x0004	/* Change table lock state	*/
10349f7d47b0SAlexander V. Chernikov 
103568394ec8SAlexander V. Chernikov typedef struct _ipfw_iface_info {
103668394ec8SAlexander V. Chernikov 	char		ifname[64];	/* interface name		*/
103768394ec8SAlexander V. Chernikov 	uint32_t	ifindex;	/* interface index		*/
103868394ec8SAlexander V. Chernikov 	uint32_t	flags;		/* flags			*/
103968394ec8SAlexander V. Chernikov 	uint32_t	refcnt;		/* number of references		*/
104068394ec8SAlexander V. Chernikov 	uint32_t	gencnt;		/* number of changes		*/
104168394ec8SAlexander V. Chernikov 	uint64_t	spare;
104268394ec8SAlexander V. Chernikov } ipfw_iface_info;
104368394ec8SAlexander V. Chernikov #define	IPFW_IFFLAG_RESOLVED	0x01	/* Interface exists		*/
104468394ec8SAlexander V. Chernikov 
10459d099b4fSAlexander V. Chernikov typedef struct _ipfw_ta_info {
1046914bffb6SAlexander V. Chernikov 	char		algoname[64];	/* algorithm name		*/
10479d099b4fSAlexander V. Chernikov 	uint32_t	type;		/* lookup type			*/
10489d099b4fSAlexander V. Chernikov 	uint32_t	flags;
10499d099b4fSAlexander V. Chernikov 	uint32_t	refcnt;
10509d099b4fSAlexander V. Chernikov 	uint32_t	spare0;
10519d099b4fSAlexander V. Chernikov 	uint64_t	spare1;
10529d099b4fSAlexander V. Chernikov } ipfw_ta_info;
10539d099b4fSAlexander V. Chernikov 
1054b074b7bbSAlexander V. Chernikov typedef struct _ipfw_obj_header {
1055b074b7bbSAlexander V. Chernikov 	ip_fw3_opheader	opheader;	/* IP_FW3 opcode		*/
105681d3153dSAlexander V. Chernikov 	uint32_t	spare;
1057b074b7bbSAlexander V. Chernikov 	uint16_t	idx;		/* object name index		*/
10589f7d47b0SAlexander V. Chernikov 	uint8_t		objtype;	/* object type			*/
10599f7d47b0SAlexander V. Chernikov 	uint8_t		objsubtype;	/* object subtype		*/
10609f7d47b0SAlexander V. Chernikov 	ipfw_obj_ntlv	ntlv;		/* object name tlv		*/
1061b074b7bbSAlexander V. Chernikov } ipfw_obj_header;
10629f7d47b0SAlexander V. Chernikov 
10639f7d47b0SAlexander V. Chernikov typedef struct _ipfw_obj_lheader {
10649f7d47b0SAlexander V. Chernikov 	ip_fw3_opheader	opheader;	/* IP_FW3 opcode		*/
1065ac35ff17SAlexander V. Chernikov 	uint32_t	set_mask;	/* disabled set mask		*/
10669f7d47b0SAlexander V. Chernikov 	uint32_t	count;		/* Total objects count		*/
106768394ec8SAlexander V. Chernikov 	uint32_t	size;		/* Total size (incl. header)	*/
10689f7d47b0SAlexander V. Chernikov 	uint32_t	objsize;	/* Size of one object		*/
10699f7d47b0SAlexander V. Chernikov } ipfw_obj_lheader;
1070b074b7bbSAlexander V. Chernikov 
10717e767c79SAlexander V. Chernikov #define	IPFW_CFG_GET_STATIC	0x01
10727e767c79SAlexander V. Chernikov #define	IPFW_CFG_GET_STATES	0x02
10737e767c79SAlexander V. Chernikov #define	IPFW_CFG_GET_COUNTERS	0x04
1074563b5ab1SAlexander V. Chernikov typedef struct _ipfw_cfg_lheader {
1075563b5ab1SAlexander V. Chernikov 	ip_fw3_opheader	opheader;	/* IP_FW3 opcode		*/
1076ac35ff17SAlexander V. Chernikov 	uint32_t	set_mask;	/* enabled set mask		*/
10777e767c79SAlexander V. Chernikov 	uint32_t	spare;
1078563b5ab1SAlexander V. Chernikov 	uint32_t	flags;		/* Request flags		*/
1079563b5ab1SAlexander V. Chernikov 	uint32_t	size;		/* neded buffer size		*/
1080563b5ab1SAlexander V. Chernikov 	uint32_t	start_rule;
1081563b5ab1SAlexander V. Chernikov 	uint32_t	end_rule;
1082563b5ab1SAlexander V. Chernikov } ipfw_cfg_lheader;
1083563b5ab1SAlexander V. Chernikov 
1084a73d728dSAlexander V. Chernikov typedef struct _ipfw_range_header {
1085a73d728dSAlexander V. Chernikov 	ip_fw3_opheader	opheader;	/* IP_FW3 opcode		*/
1086a73d728dSAlexander V. Chernikov 	ipfw_range_tlv	range;
1087a73d728dSAlexander V. Chernikov } ipfw_range_header;
1088a73d728dSAlexander V. Chernikov 
1089be8bc457SAlexander V. Chernikov typedef struct _ipfw_sopt_info {
1090be8bc457SAlexander V. Chernikov 	uint16_t	opcode;
1091be8bc457SAlexander V. Chernikov 	uint8_t		version;
1092be8bc457SAlexander V. Chernikov 	uint8_t		dir;
1093be8bc457SAlexander V. Chernikov 	uint8_t		spare;
1094be8bc457SAlexander V. Chernikov 	uint64_t	refcnt;
1095be8bc457SAlexander V. Chernikov } ipfw_sopt_info;
1096be8bc457SAlexander V. Chernikov 
10979758b77fSLuigi Rizzo #endif /* _IPFW2_H */
1098