xref: /freebsd/sys/netpfil/ipfw/ip_fw_table.h (revision 4a77657cbc011ea657ccb079fff6b58b295eccb0)
1ea761a5dSAlexander V. Chernikov /*-
2ea761a5dSAlexander V. Chernikov  * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
3ea761a5dSAlexander V. Chernikov  *
4ea761a5dSAlexander V. Chernikov  * Redistribution and use in source and binary forms, with or without
5ea761a5dSAlexander V. Chernikov  * modification, are permitted provided that the following conditions
6ea761a5dSAlexander V. Chernikov  * are met:
7ea761a5dSAlexander V. Chernikov  * 1. Redistributions of source code must retain the above copyright
8ea761a5dSAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer.
9ea761a5dSAlexander V. Chernikov  * 2. Redistributions in binary form must reproduce the above copyright
10ea761a5dSAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer in the
11ea761a5dSAlexander V. Chernikov  *    documentation and/or other materials provided with the distribution.
12ea761a5dSAlexander V. Chernikov  *
13ea761a5dSAlexander V. Chernikov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14ea761a5dSAlexander V. Chernikov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15ea761a5dSAlexander V. Chernikov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16ea761a5dSAlexander V. Chernikov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17ea761a5dSAlexander V. Chernikov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18ea761a5dSAlexander V. Chernikov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19ea761a5dSAlexander V. Chernikov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20ea761a5dSAlexander V. Chernikov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21ea761a5dSAlexander V. Chernikov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22ea761a5dSAlexander V. Chernikov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23ea761a5dSAlexander V. Chernikov  * SUCH DAMAGE.
24ea761a5dSAlexander V. Chernikov  */
25ea761a5dSAlexander V. Chernikov 
26ea761a5dSAlexander V. Chernikov #ifndef _IPFW2_TABLE_H
27ea761a5dSAlexander V. Chernikov #define _IPFW2_TABLE_H
28ea761a5dSAlexander V. Chernikov 
29ea761a5dSAlexander V. Chernikov /*
30ea761a5dSAlexander V. Chernikov  * Internal constants and data structures used by ipfw tables
31d20facb2SAlexander V. Chernikov  * not meant to be exported outside the kernel.
32ea761a5dSAlexander V. Chernikov  */
33ea761a5dSAlexander V. Chernikov #ifdef _KERNEL
34ea761a5dSAlexander V. Chernikov 
350cba2b28SAlexander V. Chernikov struct table_algo;
360cba2b28SAlexander V. Chernikov struct tables_config {
370cba2b28SAlexander V. Chernikov 	struct namedobj_instance	*namehash;
380cba2b28SAlexander V. Chernikov 	struct namedobj_instance	*valhash;
390cba2b28SAlexander V. Chernikov 	uint32_t			val_size;
400cba2b28SAlexander V. Chernikov 	uint32_t			algo_count;
410cba2b28SAlexander V. Chernikov 	struct table_algo 		*algo[256];
420cba2b28SAlexander V. Chernikov 	struct table_algo		*def_algo[IPFW_TABLE_MAXTYPE + 1];
430cba2b28SAlexander V. Chernikov 	TAILQ_HEAD(op_state_l,op_state)	state_list;
440cba2b28SAlexander V. Chernikov };
450cba2b28SAlexander V. Chernikov #define	CHAIN_TO_TCFG(chain)	((struct tables_config *)(chain)->tblcfg)
460cba2b28SAlexander V. Chernikov 
47ea761a5dSAlexander V. Chernikov struct table_info {
48ea761a5dSAlexander V. Chernikov 	table_lookup_t	*lookup;	/* Lookup function */
49ea761a5dSAlexander V. Chernikov 	void		*state;		/* Lookup radix/other structure */
50ea761a5dSAlexander V. Chernikov 	void		*xstate;	/* eXtended state */
51ea761a5dSAlexander V. Chernikov 	u_long		data;		/* Hints for given func */
52ea761a5dSAlexander V. Chernikov };
53ea761a5dSAlexander V. Chernikov 
540cba2b28SAlexander V. Chernikov struct table_value;
55d3a4f924SAlexander V. Chernikov struct tentry_info {
56d3a4f924SAlexander V. Chernikov 	void		*paddr;
570cba2b28SAlexander V. Chernikov 	struct table_value	*pvalue;
580cba2b28SAlexander V. Chernikov 	void		*ptv;		/* Temporary field to hold obj	*/
59d3a4f924SAlexander V. Chernikov 	uint8_t		masklen;	/* mask length			*/
60ac35ff17SAlexander V. Chernikov 	uint8_t		subtype;
61d3a4f924SAlexander V. Chernikov 	uint16_t	flags;		/* record flags			*/
620cba2b28SAlexander V. Chernikov 	uint32_t	value;		/* value index			*/
63d3a4f924SAlexander V. Chernikov };
643a845e10SAlexander V. Chernikov #define	TEI_FLAGS_UPDATE	0x0001	/* Add or update rec if exists	*/
653a845e10SAlexander V. Chernikov #define	TEI_FLAGS_UPDATED	0x0002	/* Entry has been updated	*/
663a845e10SAlexander V. Chernikov #define	TEI_FLAGS_COMPAT	0x0004	/* Called from old ABI		*/
673a845e10SAlexander V. Chernikov #define	TEI_FLAGS_DONTADD	0x0008	/* Do not create new rec	*/
683a845e10SAlexander V. Chernikov #define	TEI_FLAGS_ADDED		0x0010	/* Entry was added		*/
693a845e10SAlexander V. Chernikov #define	TEI_FLAGS_DELETED	0x0020	/* Entry was deleted		*/
703a845e10SAlexander V. Chernikov #define	TEI_FLAGS_LIMIT		0x0040	/* Limit was hit		*/
713a845e10SAlexander V. Chernikov #define	TEI_FLAGS_ERROR		0x0080	/* Unknown request error	*/
723a845e10SAlexander V. Chernikov #define	TEI_FLAGS_NOTFOUND	0x0100	/* Entry was not found		*/
733a845e10SAlexander V. Chernikov #define	TEI_FLAGS_EXISTS	0x0200	/* Entry already exists		*/
74d3a4f924SAlexander V. Chernikov 
7568394ec8SAlexander V. Chernikov typedef int (ta_init)(struct ip_fw_chain *ch, void **ta_state,
76914bffb6SAlexander V. Chernikov     struct table_info *ti, char *data, uint8_t tflags);
77ea761a5dSAlexander V. Chernikov typedef void (ta_destroy)(void *ta_state, struct table_info *ti);
7868394ec8SAlexander V. Chernikov typedef int (ta_prepare_add)(struct ip_fw_chain *ch, struct tentry_info *tei,
7968394ec8SAlexander V. Chernikov     void *ta_buf);
8068394ec8SAlexander V. Chernikov typedef int (ta_prepare_del)(struct ip_fw_chain *ch, struct tentry_info *tei,
8168394ec8SAlexander V. Chernikov     void *ta_buf);
82ea761a5dSAlexander V. Chernikov typedef int (ta_add)(void *ta_state, struct table_info *ti,
83b6ee846eSAlexander V. Chernikov     struct tentry_info *tei, void *ta_buf, uint32_t *pnum);
84ea761a5dSAlexander V. Chernikov typedef int (ta_del)(void *ta_state, struct table_info *ti,
85b6ee846eSAlexander V. Chernikov     struct tentry_info *tei, void *ta_buf, uint32_t *pnum);
8668394ec8SAlexander V. Chernikov typedef void (ta_flush_entry)(struct ip_fw_chain *ch, struct tentry_info *tei,
8768394ec8SAlexander V. Chernikov     void *ta_buf);
88db785d31SAlexander V. Chernikov 
89301290bcSAlexander V. Chernikov typedef int (ta_need_modify)(void *ta_state, struct table_info *ti,
90b6ee846eSAlexander V. Chernikov     uint32_t count, uint64_t *pflags);
91db785d31SAlexander V. Chernikov typedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags);
92db785d31SAlexander V. Chernikov typedef int (ta_fill_mod)(void *ta_state, struct table_info *ti,
93db785d31SAlexander V. Chernikov     void *ta_buf, uint64_t *pflags);
94301290bcSAlexander V. Chernikov typedef void (ta_modify)(void *ta_state, struct table_info *ti,
95db785d31SAlexander V. Chernikov     void *ta_buf, uint64_t pflags);
96db785d31SAlexander V. Chernikov typedef void (ta_flush_mod)(void *ta_buf);
97db785d31SAlexander V. Chernikov 
9868394ec8SAlexander V. Chernikov typedef void (ta_change_ti)(void *ta_state, struct table_info *ti);
99ac35ff17SAlexander V. Chernikov typedef void (ta_print_config)(void *ta_state, struct table_info *ti, char *buf,
100ac35ff17SAlexander V. Chernikov     size_t bufsize);
101ea761a5dSAlexander V. Chernikov 
102ea761a5dSAlexander V. Chernikov typedef int ta_foreach_f(void *node, void *arg);
103ea761a5dSAlexander V. Chernikov typedef void ta_foreach(void *ta_state, struct table_info *ti, ta_foreach_f *f,
104ea761a5dSAlexander V. Chernikov   void *arg);
10581d3153dSAlexander V. Chernikov typedef int ta_dump_tentry(void *ta_state, struct table_info *ti, void *e,
10681d3153dSAlexander V. Chernikov     ipfw_obj_tentry *tent);
107914bffb6SAlexander V. Chernikov typedef int ta_find_tentry(void *ta_state, struct table_info *ti,
108914bffb6SAlexander V. Chernikov     ipfw_obj_tentry *tent);
1095f379342SAlexander V. Chernikov typedef void ta_dump_tinfo(void *ta_state, struct table_info *ti,
1105f379342SAlexander V. Chernikov     ipfw_ta_tinfo *tinfo);
111d3b00c08SAlexander V. Chernikov typedef uint32_t ta_get_count(void *ta_state, struct table_info *ti);
112ea761a5dSAlexander V. Chernikov 
113ea761a5dSAlexander V. Chernikov struct table_algo {
1149490a627SAlexander V. Chernikov 	char		name[16];
11557a1cf95SAlexander V. Chernikov 	uint32_t	idx;
11657a1cf95SAlexander V. Chernikov 	uint32_t	type;
11757a1cf95SAlexander V. Chernikov 	uint32_t	refcnt;
11857a1cf95SAlexander V. Chernikov 	uint32_t	flags;
1190cba2b28SAlexander V. Chernikov 	uint32_t	vlimit;
12057a1cf95SAlexander V. Chernikov 	size_t		ta_buf_size;
121ea761a5dSAlexander V. Chernikov 	ta_init		*init;
122ea761a5dSAlexander V. Chernikov 	ta_destroy	*destroy;
123ea761a5dSAlexander V. Chernikov 	ta_prepare_add	*prepare_add;
124ea761a5dSAlexander V. Chernikov 	ta_prepare_del	*prepare_del;
125ea761a5dSAlexander V. Chernikov 	ta_add		*add;
126ea761a5dSAlexander V. Chernikov 	ta_del		*del;
127ea761a5dSAlexander V. Chernikov 	ta_flush_entry	*flush_entry;
128914bffb6SAlexander V. Chernikov 	ta_find_tentry	*find_tentry;
129301290bcSAlexander V. Chernikov 	ta_need_modify	*need_modify;
130db785d31SAlexander V. Chernikov 	ta_prepare_mod	*prepare_mod;
131db785d31SAlexander V. Chernikov 	ta_fill_mod	*fill_mod;
132db785d31SAlexander V. Chernikov 	ta_modify	*modify;
133db785d31SAlexander V. Chernikov 	ta_flush_mod	*flush_mod;
134914bffb6SAlexander V. Chernikov 	ta_change_ti	*change_ti;
135ea761a5dSAlexander V. Chernikov 	ta_foreach	*foreach;
13681d3153dSAlexander V. Chernikov 	ta_dump_tentry	*dump_tentry;
137ac35ff17SAlexander V. Chernikov 	ta_print_config	*print_config;
138914bffb6SAlexander V. Chernikov 	ta_dump_tinfo	*dump_tinfo;
139d3b00c08SAlexander V. Chernikov 	ta_get_count	*get_count;
140ea761a5dSAlexander V. Chernikov };
141fd0869d5SAlexander V. Chernikov #define	TA_FLAG_DEFAULT		0x01	/* Algo is default for given type */
142fd0869d5SAlexander V. Chernikov #define	TA_FLAG_READONLY	0x02	/* Algo does not support modifications*/
143d3b00c08SAlexander V. Chernikov #define	TA_FLAG_EXTCOUNTER	0x04	/* Algo has external counter available*/
14468394ec8SAlexander V. Chernikov 
1450b565ac0SAlexander V. Chernikov int ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta,
1460b565ac0SAlexander V. Chernikov     size_t size, int *idx);
1470b565ac0SAlexander V. Chernikov void ipfw_del_table_algo(struct ip_fw_chain *ch, int idx);
148914bffb6SAlexander V. Chernikov 
149d3a4f924SAlexander V. Chernikov void ipfw_table_algo_init(struct ip_fw_chain *chain);
150d3a4f924SAlexander V. Chernikov void ipfw_table_algo_destroy(struct ip_fw_chain *chain);
151d3a4f924SAlexander V. Chernikov 
152b1d105bcSAlexander V. Chernikov MALLOC_DECLARE(M_IPFW_TBL);
1531832a7b3SAlexander V. Chernikov /* Exported to support legacy opcodes */
1541832a7b3SAlexander V. Chernikov int add_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
1553a845e10SAlexander V. Chernikov     struct tentry_info *tei, uint8_t flags, uint32_t count);
1561832a7b3SAlexander V. Chernikov int del_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
1573a845e10SAlexander V. Chernikov     struct tentry_info *tei, uint8_t flags, uint32_t count);
1581832a7b3SAlexander V. Chernikov int flush_table(struct ip_fw_chain *ch, struct tid_info *ti);
1590cba2b28SAlexander V. Chernikov 
1600cba2b28SAlexander V. Chernikov /* ipfw_table_value.c functions */
1610cba2b28SAlexander V. Chernikov struct table_config;
1620cba2b28SAlexander V. Chernikov struct tableop_state;
1636b988f3aSAlexander V. Chernikov void ipfw_table_value_init(struct ip_fw_chain *ch, int first);
1646b988f3aSAlexander V. Chernikov void ipfw_table_value_destroy(struct ip_fw_chain *ch, int last);
16557ddf396SAlexander V. Chernikov int ipfw_link_table_values(struct ip_fw_chain *ch, struct tableop_state *ts,
16657ddf396SAlexander V. Chernikov     uint8_t flags);
16771af39bfSAlexander V. Chernikov void ipfw_garbage_table_values(struct ip_fw_chain *ch, struct table_config *tc,
1680cba2b28SAlexander V. Chernikov     struct tentry_info *tei, uint32_t count, int rollback);
1690cba2b28SAlexander V. Chernikov void ipfw_import_table_value_v1(ipfw_table_value *iv);
1700cba2b28SAlexander V. Chernikov void ipfw_export_table_value_v1(struct table_value *v, ipfw_table_value *iv);
1710cba2b28SAlexander V. Chernikov void ipfw_unref_table_values(struct ip_fw_chain *ch, struct table_config *tc,
1720cba2b28SAlexander V. Chernikov     struct table_algo *ta, void *astate, struct table_info *ti);
17371af39bfSAlexander V. Chernikov void rollback_table_values(struct tableop_state *ts);
174ac35ff17SAlexander V. Chernikov 
175d3a4f924SAlexander V. Chernikov int ipfw_rewrite_table_uidx(struct ip_fw_chain *chain,
176d3a4f924SAlexander V. Chernikov     struct rule_check_info *ci);
177563b5ab1SAlexander V. Chernikov int ipfw_mark_table_kidx(struct ip_fw_chain *chain, struct ip_fw *rule,
178563b5ab1SAlexander V. Chernikov     uint32_t *bmask);
179*4a77657cSAndrey V. Elsukov int ipfw_export_table_ntlv(struct ip_fw_chain *ch, uint32_t kidx,
180563b5ab1SAlexander V. Chernikov     struct sockopt_data *sd);
181e5eec6ddSAlexander V. Chernikov void ipfw_unref_rule_tables(struct ip_fw_chain *chain, struct ip_fw *rule);
18274b22066SAlexander V. Chernikov struct namedobj_instance *ipfw_get_table_objhash(struct ip_fw_chain *ch);
183d3a4f924SAlexander V. Chernikov 
184d3a4f924SAlexander V. Chernikov /* utility functions  */
185a73d728dSAlexander V. Chernikov int ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
186a73d728dSAlexander V. Chernikov     uint32_t new_set);
187a73d728dSAlexander V. Chernikov void ipfw_swap_tables_sets(struct ip_fw_chain *ch, uint32_t old_set,
188a73d728dSAlexander V. Chernikov     uint32_t new_set, int mv);
189*4a77657cSAndrey V. Elsukov int ipfw_foreach_table_tentry(struct ip_fw_chain *ch, uint32_t kidx,
1904dff4ae0SAlexander V. Chernikov     ta_foreach_f f, void *arg);
191d3a4f924SAlexander V. Chernikov 
1920cba2b28SAlexander V. Chernikov /* internal functions */
1930cba2b28SAlexander V. Chernikov void tc_ref(struct table_config *tc);
1940cba2b28SAlexander V. Chernikov void tc_unref(struct table_config *tc);
1950cba2b28SAlexander V. Chernikov 
1960cba2b28SAlexander V. Chernikov struct op_state;
1970cba2b28SAlexander V. Chernikov typedef void (op_rollback_f)(void *object, struct op_state *state);
1980cba2b28SAlexander V. Chernikov struct op_state {
1990cba2b28SAlexander V. Chernikov 	TAILQ_ENTRY(op_state)	next;	/* chain link */
2000cba2b28SAlexander V. Chernikov 	op_rollback_f		*func;
2010cba2b28SAlexander V. Chernikov };
2020cba2b28SAlexander V. Chernikov 
2030cba2b28SAlexander V. Chernikov struct tableop_state {
2040cba2b28SAlexander V. Chernikov 	struct op_state	opstate;
2050cba2b28SAlexander V. Chernikov 	struct ip_fw_chain *ch;
2060cba2b28SAlexander V. Chernikov 	struct table_config *tc;
2070cba2b28SAlexander V. Chernikov 	struct table_algo *ta;
2080cba2b28SAlexander V. Chernikov 	struct tentry_info *tei;
2090cba2b28SAlexander V. Chernikov 	uint32_t count;
2100cba2b28SAlexander V. Chernikov 	uint32_t vmask;
2110cba2b28SAlexander V. Chernikov 	int vshared;
2120cba2b28SAlexander V. Chernikov 	int modified;
2130cba2b28SAlexander V. Chernikov };
2140cba2b28SAlexander V. Chernikov 
2150cba2b28SAlexander V. Chernikov void add_toperation_state(struct ip_fw_chain *ch, struct tableop_state *ts);
2160cba2b28SAlexander V. Chernikov void del_toperation_state(struct ip_fw_chain *ch, struct tableop_state *ts);
2170cba2b28SAlexander V. Chernikov void rollback_toperation_state(struct ip_fw_chain *ch, void *object);
2180cba2b28SAlexander V. Chernikov 
219ea761a5dSAlexander V. Chernikov #endif /* _KERNEL */
220ea761a5dSAlexander V. Chernikov #endif /* _IPFW2_TABLE_H */
221