1234949Sbapt/*-
2234949Sbapt * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
3234949Sbapt *
4234949Sbapt * Redistribution and use in source and binary forms, with or without
5234949Sbapt * modification, are permitted provided that the following conditions
6234949Sbapt * are met:
7234949Sbapt * 1. Redistributions of source code must retain the above copyright
8234949Sbapt *    notice, this list of conditions and the following disclaimer.
9234949Sbapt * 2. Redistributions in binary form must reproduce the above copyright
10234949Sbapt *    notice, this list of conditions and the following disclaimer in the
11234949Sbapt *    documentation and/or other materials provided with the distribution.
12234949Sbapt *
13234949Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14234949Sbapt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15234949Sbapt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16234949Sbapt * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17234949Sbapt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18234949Sbapt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19234949Sbapt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20234949Sbapt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21234949Sbapt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22234949Sbapt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23234949Sbapt * SUCH DAMAGE.
24234949Sbapt */
25234949Sbapt
26234949Sbapt#ifndef _IPFW2_TABLE_H
27234949Sbapt#define _IPFW2_TABLE_H
28234949Sbapt
29234949Sbapt/*
30234949Sbapt * Internal constants and data structures used by ipfw tables
31234949Sbapt * not meant to be exported outside the kernel.
32234949Sbapt */
33234949Sbapt#ifdef _KERNEL
34234949Sbapt
35234949Sbaptstruct table_algo;
36234949Sbaptstruct tables_config {
37234949Sbapt	struct namedobj_instance	*namehash;
38234949Sbapt	struct namedobj_instance	*valhash;
39234949Sbapt	uint32_t			val_size;
40234949Sbapt	uint32_t			algo_count;
41234949Sbapt	struct table_algo 		*algo[256];
42234949Sbapt	struct table_algo		*def_algo[IPFW_TABLE_MAXTYPE + 1];
43234949Sbapt	TAILQ_HEAD(op_state_l,op_state)	state_list;
44234949Sbapt};
45234949Sbapt#define	CHAIN_TO_TCFG(chain)	((struct tables_config *)(chain)->tblcfg)
46234949Sbapt
47234949Sbaptstruct table_info {
48234949Sbapt	table_lookup_t	*lookup;	/* Lookup function */
49234949Sbapt	void		*state;		/* Lookup radix/other structure */
50234949Sbapt	void		*xstate;	/* eXtended state */
51234949Sbapt	u_long		data;		/* Hints for given func */
52234949Sbapt};
53234949Sbapt
54234949Sbaptstruct table_value;
55234949Sbaptstruct tentry_info {
56234949Sbapt	void		*paddr;
57234949Sbapt	struct table_value	*pvalue;
58234949Sbapt	void		*ptv;		/* Temporary field to hold obj	*/
59234949Sbapt	uint8_t		masklen;	/* mask length			*/
60234949Sbapt	uint8_t		subtype;
61234949Sbapt	uint16_t	flags;		/* record flags			*/
62234949Sbapt	uint32_t	value;		/* value index			*/
63234949Sbapt};
64234949Sbapt#define	TEI_FLAGS_UPDATE	0x0001	/* Add or update rec if exists	*/
65234949Sbapt#define	TEI_FLAGS_UPDATED	0x0002	/* Entry has been updated	*/
66234949Sbapt#define	TEI_FLAGS_COMPAT	0x0004	/* Called from old ABI		*/
67234949Sbapt#define	TEI_FLAGS_DONTADD	0x0008	/* Do not create new rec	*/
68234949Sbapt#define	TEI_FLAGS_ADDED		0x0010	/* Entry was added		*/
69234949Sbapt#define	TEI_FLAGS_DELETED	0x0020	/* Entry was deleted		*/
70234949Sbapt#define	TEI_FLAGS_LIMIT		0x0040	/* Limit was hit		*/
71234949Sbapt#define	TEI_FLAGS_ERROR		0x0080	/* Unknown request error	*/
72234949Sbapt#define	TEI_FLAGS_NOTFOUND	0x0100	/* Entry was not found		*/
73234949Sbapt#define	TEI_FLAGS_EXISTS	0x0200	/* Entry already exists		*/
74234949Sbapt
75234949Sbapttypedef int (ta_init)(struct ip_fw_chain *ch, void **ta_state,
76234949Sbapt    struct table_info *ti, char *data, uint8_t tflags);
77234949Sbapttypedef void (ta_destroy)(void *ta_state, struct table_info *ti);
78234949Sbapttypedef int (ta_prepare_add)(struct ip_fw_chain *ch, struct tentry_info *tei,
79234949Sbapt    void *ta_buf);
80234949Sbapttypedef int (ta_prepare_del)(struct ip_fw_chain *ch, struct tentry_info *tei,
81234949Sbapt    void *ta_buf);
82234949Sbapttypedef int (ta_add)(void *ta_state, struct table_info *ti,
83234949Sbapt    struct tentry_info *tei, void *ta_buf, uint32_t *pnum);
84234949Sbapttypedef int (ta_del)(void *ta_state, struct table_info *ti,
85234949Sbapt    struct tentry_info *tei, void *ta_buf, uint32_t *pnum);
86234949Sbapttypedef void (ta_flush_entry)(struct ip_fw_chain *ch, struct tentry_info *tei,
87234949Sbapt    void *ta_buf);
88234949Sbapt
89234949Sbapttypedef int (ta_need_modify)(void *ta_state, struct table_info *ti,
90234949Sbapt    uint32_t count, uint64_t *pflags);
91234949Sbapttypedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags);
92234949Sbapttypedef int (ta_fill_mod)(void *ta_state, struct table_info *ti,
93234949Sbapt    void *ta_buf, uint64_t *pflags);
94234949Sbapttypedef void (ta_modify)(void *ta_state, struct table_info *ti,
95234949Sbapt    void *ta_buf, uint64_t pflags);
96234949Sbapttypedef void (ta_flush_mod)(void *ta_buf);
97234949Sbapt
98234949Sbapttypedef void (ta_change_ti)(void *ta_state, struct table_info *ti);
99234949Sbapttypedef void (ta_print_config)(void *ta_state, struct table_info *ti, char *buf,
100234949Sbapt    size_t bufsize);
101234949Sbapt
102234949Sbapttypedef int ta_foreach_f(void *node, void *arg);
103234949Sbapttypedef void ta_foreach(void *ta_state, struct table_info *ti, ta_foreach_f *f,
104234949Sbapt  void *arg);
105234949Sbapttypedef int ta_dump_tentry(void *ta_state, struct table_info *ti, void *e,
106234949Sbapt    ipfw_obj_tentry *tent);
107234949Sbapttypedef int ta_find_tentry(void *ta_state, struct table_info *ti,
108234949Sbapt    ipfw_obj_tentry *tent);
109234949Sbapttypedef void ta_dump_tinfo(void *ta_state, struct table_info *ti,
110234949Sbapt    ipfw_ta_tinfo *tinfo);
111234949Sbapttypedef uint32_t ta_get_count(void *ta_state, struct table_info *ti);
112234949Sbapt
113234949Sbaptstruct table_algo {
114234949Sbapt	char		name[16];
115234949Sbapt	uint32_t	idx;
116234949Sbapt	uint32_t	type;
117234949Sbapt	uint32_t	refcnt;
118234949Sbapt	uint32_t	flags;
119234949Sbapt	uint32_t	vlimit;
120234949Sbapt	size_t		ta_buf_size;
121234949Sbapt	ta_init		*init;
122234949Sbapt	ta_destroy	*destroy;
123234949Sbapt	ta_prepare_add	*prepare_add;
124234949Sbapt	ta_prepare_del	*prepare_del;
125234949Sbapt	ta_add		*add;
126234949Sbapt	ta_del		*del;
127234949Sbapt	ta_flush_entry	*flush_entry;
128234949Sbapt	ta_find_tentry	*find_tentry;
129234949Sbapt	ta_need_modify	*need_modify;
130234949Sbapt	ta_prepare_mod	*prepare_mod;
131234949Sbapt	ta_fill_mod	*fill_mod;
132234949Sbapt	ta_modify	*modify;
133234949Sbapt	ta_flush_mod	*flush_mod;
134234949Sbapt	ta_change_ti	*change_ti;
135234949Sbapt	ta_foreach	*foreach;
136234949Sbapt	ta_dump_tentry	*dump_tentry;
137234949Sbapt	ta_print_config	*print_config;
138234949Sbapt	ta_dump_tinfo	*dump_tinfo;
139234949Sbapt	ta_get_count	*get_count;
140234949Sbapt};
141234949Sbapt#define	TA_FLAG_DEFAULT		0x01	/* Algo is default for given type */
142234949Sbapt#define	TA_FLAG_READONLY	0x02	/* Algo does not support modifications*/
143234949Sbapt#define	TA_FLAG_EXTCOUNTER	0x04	/* Algo has external counter available*/
144234949Sbapt
145234949Sbaptint ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta,
146234949Sbapt    size_t size, int *idx);
147234949Sbaptvoid ipfw_del_table_algo(struct ip_fw_chain *ch, int idx);
148234949Sbapt
149234949Sbaptvoid ipfw_table_algo_init(struct ip_fw_chain *chain);
150234949Sbaptvoid ipfw_table_algo_destroy(struct ip_fw_chain *chain);
151234949Sbapt
152234949SbaptMALLOC_DECLARE(M_IPFW_TBL);
153234949Sbapt/* Exported to support legacy opcodes */
154234949Sbaptint add_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
155234949Sbapt    struct tentry_info *tei, uint8_t flags, uint32_t count);
156234949Sbaptint del_table_entry(struct ip_fw_chain *ch, struct tid_info *ti,
157234949Sbapt    struct tentry_info *tei, uint8_t flags, uint32_t count);
158234949Sbaptint flush_table(struct ip_fw_chain *ch, struct tid_info *ti);
159234949Sbaptvoid ipfw_import_table_value_legacy(uint32_t value, struct table_value *v);
160234949Sbaptuint32_t ipfw_export_table_value_legacy(struct table_value *v);
161234949Sbaptint ipfw_get_table_size(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
162234949Sbapt    struct sockopt_data *sd);
163234949Sbapt
164234949Sbapt/* ipfw_table_value.c functions */
165234949Sbaptstruct table_config;
166234949Sbaptstruct tableop_state;
167234949Sbaptvoid ipfw_table_value_init(struct ip_fw_chain *ch, int first);
168234949Sbaptvoid ipfw_table_value_destroy(struct ip_fw_chain *ch, int last);
169234949Sbaptint ipfw_link_table_values(struct ip_fw_chain *ch, struct tableop_state *ts,
170234949Sbapt    uint8_t flags);
171234949Sbaptvoid ipfw_garbage_table_values(struct ip_fw_chain *ch, struct table_config *tc,
172234949Sbapt    struct tentry_info *tei, uint32_t count, int rollback);
173234949Sbaptvoid ipfw_import_table_value_v1(ipfw_table_value *iv);
174234949Sbaptvoid ipfw_export_table_value_v1(struct table_value *v, ipfw_table_value *iv);
175234949Sbaptvoid ipfw_unref_table_values(struct ip_fw_chain *ch, struct table_config *tc,
176234949Sbapt    struct table_algo *ta, void *astate, struct table_info *ti);
177234949Sbaptvoid rollback_table_values(struct tableop_state *ts);
178234949Sbapt
179234949Sbaptint ipfw_rewrite_table_uidx(struct ip_fw_chain *chain,
180234949Sbapt    struct rule_check_info *ci);
181234949Sbaptint ipfw_mark_table_kidx(struct ip_fw_chain *chain, struct ip_fw *rule,
182234949Sbapt    uint32_t *bmask);
183234949Sbaptint ipfw_export_table_ntlv(struct ip_fw_chain *ch, uint16_t kidx,
184234949Sbapt    struct sockopt_data *sd);
185234949Sbaptvoid ipfw_unref_rule_tables(struct ip_fw_chain *chain, struct ip_fw *rule);
186234949Sbaptstruct namedobj_instance *ipfw_get_table_objhash(struct ip_fw_chain *ch);
187234949Sbapt
188234949Sbapt/* utility functions  */
189234949Sbaptint ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt,
190234949Sbapt    uint32_t new_set);
191234949Sbaptvoid ipfw_swap_tables_sets(struct ip_fw_chain *ch, uint32_t old_set,
192234949Sbapt    uint32_t new_set, int mv);
193234949Sbaptint ipfw_foreach_table_tentry(struct ip_fw_chain *ch, uint16_t kidx,
194234949Sbapt    ta_foreach_f f, void *arg);
195234949Sbapt
196234949Sbapt/* internal functions */
197234949Sbaptvoid tc_ref(struct table_config *tc);
198234949Sbaptvoid tc_unref(struct table_config *tc);
199234949Sbapt
200234949Sbaptstruct op_state;
201234949Sbapttypedef void (op_rollback_f)(void *object, struct op_state *state);
202234949Sbaptstruct op_state {
203234949Sbapt	TAILQ_ENTRY(op_state)	next;	/* chain link */
204234949Sbapt	op_rollback_f		*func;
205234949Sbapt};
206234949Sbapt
207234949Sbaptstruct tableop_state {
208234949Sbapt	struct op_state	opstate;
209234949Sbapt	struct ip_fw_chain *ch;
210234949Sbapt	struct table_config *tc;
211234949Sbapt	struct table_algo *ta;
212234949Sbapt	struct tentry_info *tei;
213234949Sbapt	uint32_t count;
214234949Sbapt	uint32_t vmask;
215234949Sbapt	int vshared;
216234949Sbapt	int modified;
217251143Sbapt};
218234949Sbapt
219234949Sbaptvoid add_toperation_state(struct ip_fw_chain *ch, struct tableop_state *ts);
220234949Sbaptvoid del_toperation_state(struct ip_fw_chain *ch, struct tableop_state *ts);
221234949Sbaptvoid rollback_toperation_state(struct ip_fw_chain *ch, void *object);
222234949Sbapt
223234949Sbapt/* Legacy interfaces */
224234949Sbaptint ipfw_count_table(struct ip_fw_chain *ch, struct tid_info *ti,
225234949Sbapt    uint32_t *cnt);
226234949Sbaptint ipfw_count_xtable(struct ip_fw_chain *ch, struct tid_info *ti,
227234949Sbapt    uint32_t *cnt);
228234949Sbaptint ipfw_dump_table_legacy(struct ip_fw_chain *ch, struct tid_info *ti,
229234949Sbapt    ipfw_table *tbl);
230234949Sbapt
231234949Sbapt#endif /* _KERNEL */
232234949Sbapt#endif /* _IPFW2_TABLE_H */
233234949Sbapt