]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * ebtables | |
3 | * | |
4 | * Authors: | |
5 | * Bart De Schuymer <bdschuym@pandora.be> | |
6 | * | |
7 | * ebtables.c,v 2.0, April, 2002 | |
8 | * | |
9 | * This code is stongly inspired on the iptables code which is | |
10 | * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling | |
11 | */ | |
12 | ||
13 | #ifndef __LINUX_BRIDGE_EFF_H | |
14 | #define __LINUX_BRIDGE_EFF_H | |
15 | #include <linux/if.h> | |
16 | #include <linux/netfilter_bridge.h> | |
17 | #include <linux/if_ether.h> | |
18 | ||
19 | #define EBT_TABLE_MAXNAMELEN 32 | |
20 | #define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN | |
21 | #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN | |
22 | ||
23 | /* verdicts >0 are "branches" */ | |
24 | #define EBT_ACCEPT -1 | |
25 | #define EBT_DROP -2 | |
26 | #define EBT_CONTINUE -3 | |
27 | #define EBT_RETURN -4 | |
28 | #define NUM_STANDARD_TARGETS 4 | |
d12cdc3c BDS |
29 | /* ebtables target modules store the verdict inside an int. We can |
30 | * reclaim a part of this int for backwards compatible extensions. | |
31 | * The 4 lsb are more than enough to store the verdict. */ | |
32 | #define EBT_VERDICT_BITS 0x0000000F | |
1da177e4 | 33 | |
2d06d4a5 JE |
34 | struct xt_match; |
35 | struct xt_target; | |
36 | ||
1da177e4 LT |
37 | struct ebt_counter |
38 | { | |
39 | uint64_t pcnt; | |
40 | uint64_t bcnt; | |
41 | }; | |
42 | ||
43 | struct ebt_replace | |
1e419cd9 AV |
44 | { |
45 | char name[EBT_TABLE_MAXNAMELEN]; | |
46 | unsigned int valid_hooks; | |
47 | /* nr of rules in the table */ | |
48 | unsigned int nentries; | |
49 | /* total size of the entries */ | |
50 | unsigned int entries_size; | |
51 | /* start of the chains */ | |
52 | struct ebt_entries __user *hook_entry[NF_BR_NUMHOOKS]; | |
53 | /* nr of counters userspace expects back */ | |
54 | unsigned int num_counters; | |
55 | /* where the kernel will put the old counters */ | |
56 | struct ebt_counter __user *counters; | |
57 | char __user *entries; | |
58 | }; | |
59 | ||
60 | struct ebt_replace_kernel | |
1da177e4 LT |
61 | { |
62 | char name[EBT_TABLE_MAXNAMELEN]; | |
63 | unsigned int valid_hooks; | |
64 | /* nr of rules in the table */ | |
65 | unsigned int nentries; | |
66 | /* total size of the entries */ | |
67 | unsigned int entries_size; | |
68 | /* start of the chains */ | |
69 | struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; | |
70 | /* nr of counters userspace expects back */ | |
71 | unsigned int num_counters; | |
72 | /* where the kernel will put the old counters */ | |
73 | struct ebt_counter *counters; | |
74 | char *entries; | |
75 | }; | |
76 | ||
77 | struct ebt_entries { | |
78 | /* this field is always set to zero | |
79 | * See EBT_ENTRY_OR_ENTRIES. | |
80 | * Must be same size as ebt_entry.bitmask */ | |
81 | unsigned int distinguisher; | |
82 | /* the chain name */ | |
83 | char name[EBT_CHAIN_MAXNAMELEN]; | |
84 | /* counter offset for this chain */ | |
85 | unsigned int counter_offset; | |
86 | /* one standard (accept, drop, return) per hook */ | |
87 | int policy; | |
88 | /* nr. of entries */ | |
89 | unsigned int nentries; | |
90 | /* entry list */ | |
91 | char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); | |
92 | }; | |
93 | ||
94 | /* used for the bitmask of struct ebt_entry */ | |
95 | ||
96 | /* This is a hack to make a difference between an ebt_entry struct and an | |
97 | * ebt_entries struct when traversing the entries from start to end. | |
98 | * Using this simplifies the code alot, while still being able to use | |
99 | * ebt_entries. | |
100 | * Contrary, iptables doesn't use something like ebt_entries and therefore uses | |
101 | * different techniques for naming the policy and such. So, iptables doesn't | |
102 | * need a hack like this. | |
103 | */ | |
104 | #define EBT_ENTRY_OR_ENTRIES 0x01 | |
105 | /* these are the normal masks */ | |
106 | #define EBT_NOPROTO 0x02 | |
107 | #define EBT_802_3 0x04 | |
108 | #define EBT_SOURCEMAC 0x08 | |
109 | #define EBT_DESTMAC 0x10 | |
110 | #define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ | |
111 | | EBT_ENTRY_OR_ENTRIES) | |
112 | ||
113 | #define EBT_IPROTO 0x01 | |
114 | #define EBT_IIN 0x02 | |
115 | #define EBT_IOUT 0x04 | |
116 | #define EBT_ISOURCE 0x8 | |
117 | #define EBT_IDEST 0x10 | |
118 | #define EBT_ILOGICALIN 0x20 | |
119 | #define EBT_ILOGICALOUT 0x40 | |
120 | #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ | |
121 | | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) | |
122 | ||
123 | struct ebt_entry_match | |
124 | { | |
125 | union { | |
126 | char name[EBT_FUNCTION_MAXNAMELEN]; | |
043ef46c | 127 | struct xt_match *match; |
1da177e4 LT |
128 | } u; |
129 | /* size of data */ | |
130 | unsigned int match_size; | |
131 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); | |
132 | }; | |
133 | ||
134 | struct ebt_entry_watcher | |
135 | { | |
136 | union { | |
137 | char name[EBT_FUNCTION_MAXNAMELEN]; | |
043ef46c | 138 | struct xt_target *watcher; |
1da177e4 LT |
139 | } u; |
140 | /* size of data */ | |
141 | unsigned int watcher_size; | |
142 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); | |
143 | }; | |
144 | ||
145 | struct ebt_entry_target | |
146 | { | |
147 | union { | |
148 | char name[EBT_FUNCTION_MAXNAMELEN]; | |
043ef46c | 149 | struct xt_target *target; |
1da177e4 LT |
150 | } u; |
151 | /* size of data */ | |
152 | unsigned int target_size; | |
153 | unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); | |
154 | }; | |
155 | ||
156 | #define EBT_STANDARD_TARGET "standard" | |
157 | struct ebt_standard_target | |
158 | { | |
159 | struct ebt_entry_target target; | |
160 | int verdict; | |
161 | }; | |
162 | ||
163 | /* one entry */ | |
164 | struct ebt_entry { | |
165 | /* this needs to be the first field */ | |
166 | unsigned int bitmask; | |
167 | unsigned int invflags; | |
47c183fa | 168 | __be16 ethproto; |
1da177e4 LT |
169 | /* the physical in-dev */ |
170 | char in[IFNAMSIZ]; | |
171 | /* the logical in-dev */ | |
172 | char logical_in[IFNAMSIZ]; | |
173 | /* the physical out-dev */ | |
174 | char out[IFNAMSIZ]; | |
175 | /* the logical out-dev */ | |
176 | char logical_out[IFNAMSIZ]; | |
177 | unsigned char sourcemac[ETH_ALEN]; | |
178 | unsigned char sourcemsk[ETH_ALEN]; | |
179 | unsigned char destmac[ETH_ALEN]; | |
180 | unsigned char destmsk[ETH_ALEN]; | |
181 | /* sizeof ebt_entry + matches */ | |
182 | unsigned int watchers_offset; | |
183 | /* sizeof ebt_entry + matches + watchers */ | |
184 | unsigned int target_offset; | |
185 | /* sizeof ebt_entry + matches + watchers + target */ | |
186 | unsigned int next_offset; | |
187 | unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); | |
188 | }; | |
189 | ||
190 | /* {g,s}etsockopt numbers */ | |
191 | #define EBT_BASE_CTL 128 | |
192 | ||
193 | #define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) | |
194 | #define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) | |
195 | #define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) | |
196 | ||
197 | #define EBT_SO_GET_INFO (EBT_BASE_CTL) | |
198 | #define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) | |
199 | #define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) | |
200 | #define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) | |
201 | #define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) | |
202 | ||
203 | #ifdef __KERNEL__ | |
204 | ||
205 | /* return values for match() functions */ | |
206 | #define EBT_MATCH 0 | |
207 | #define EBT_NOMATCH 1 | |
208 | ||
209 | struct ebt_match | |
210 | { | |
211 | struct list_head list; | |
212 | const char name[EBT_FUNCTION_MAXNAMELEN]; | |
8cc784ee | 213 | bool (*match)(const struct sk_buff *skb, const struct net_device *in, |
2d06d4a5 JE |
214 | const struct net_device *out, const struct xt_match *match, |
215 | const void *matchinfo, int offset, unsigned int protoff, | |
216 | bool *hotdrop); | |
217 | bool (*checkentry)(const char *table, const void *entry, | |
218 | const struct xt_match *match, void *matchinfo, | |
219 | unsigned int hook_mask); | |
220 | void (*destroy)(const struct xt_match *match, void *matchinfo); | |
18219d3f | 221 | unsigned int matchsize; |
001a18d3 JE |
222 | u_int8_t revision; |
223 | u_int8_t family; | |
1da177e4 LT |
224 | struct module *me; |
225 | }; | |
226 | ||
227 | struct ebt_watcher | |
228 | { | |
229 | struct list_head list; | |
230 | const char name[EBT_FUNCTION_MAXNAMELEN]; | |
2d06d4a5 JE |
231 | unsigned int (*target)(struct sk_buff *skb, |
232 | const struct net_device *in, const struct net_device *out, | |
233 | unsigned int hook_num, const struct xt_target *target, | |
234 | const void *targinfo); | |
235 | bool (*checkentry)(const char *table, const void *entry, | |
236 | const struct xt_target *target, void *targinfo, | |
237 | unsigned int hook_mask); | |
238 | void (*destroy)(const struct xt_target *target, void *targinfo); | |
18219d3f | 239 | unsigned int targetsize; |
001a18d3 JE |
240 | u_int8_t revision; |
241 | u_int8_t family; | |
1da177e4 LT |
242 | struct module *me; |
243 | }; | |
244 | ||
245 | struct ebt_target | |
246 | { | |
247 | struct list_head list; | |
248 | const char name[EBT_FUNCTION_MAXNAMELEN]; | |
0ac6ab1f | 249 | /* returns one of the standard EBT_* verdicts */ |
2d06d4a5 JE |
250 | unsigned int (*target)(struct sk_buff *skb, |
251 | const struct net_device *in, const struct net_device *out, | |
252 | unsigned int hook_num, const struct xt_target *target, | |
253 | const void *targinfo); | |
254 | bool (*checkentry)(const char *table, const void *entry, | |
255 | const struct xt_target *target, void *targinfo, | |
256 | unsigned int hook_mask); | |
257 | void (*destroy)(const struct xt_target *target, void *targinfo); | |
18219d3f | 258 | unsigned int targetsize; |
001a18d3 JE |
259 | u_int8_t revision; |
260 | u_int8_t family; | |
1da177e4 LT |
261 | struct module *me; |
262 | }; | |
263 | ||
264 | /* used for jumping from and into user defined chains (udc) */ | |
265 | struct ebt_chainstack | |
266 | { | |
267 | struct ebt_entries *chaininfo; /* pointer to chain data */ | |
268 | struct ebt_entry *e; /* pointer to entry data */ | |
269 | unsigned int n; /* n'th entry */ | |
270 | }; | |
271 | ||
272 | struct ebt_table_info | |
273 | { | |
274 | /* total size of the entries */ | |
275 | unsigned int entries_size; | |
276 | unsigned int nentries; | |
277 | /* pointers to the start of the chains */ | |
278 | struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; | |
279 | /* room to maintain the stack used for jumping from and into udc */ | |
280 | struct ebt_chainstack **chainstack; | |
281 | char *entries; | |
282 | struct ebt_counter counters[0] ____cacheline_aligned; | |
283 | }; | |
284 | ||
285 | struct ebt_table | |
286 | { | |
287 | struct list_head list; | |
288 | char name[EBT_TABLE_MAXNAMELEN]; | |
1e419cd9 | 289 | struct ebt_replace_kernel *table; |
1da177e4 LT |
290 | unsigned int valid_hooks; |
291 | rwlock_t lock; | |
292 | /* e.g. could be the table explicitly only allows certain | |
293 | * matches, targets, ... 0 == let it in */ | |
294 | int (*check)(const struct ebt_table_info *info, | |
295 | unsigned int valid_hooks); | |
296 | /* the data used by the kernel */ | |
297 | struct ebt_table_info *private; | |
298 | struct module *me; | |
299 | }; | |
300 | ||
301 | #define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \ | |
302 | ~(__alignof__(struct ebt_replace)-1)) | |
6beceee5 | 303 | extern struct ebt_table *ebt_register_table(struct net *net, |
35aad0ff | 304 | const struct ebt_table *table); |
1da177e4 | 305 | extern void ebt_unregister_table(struct ebt_table *table); |
3db05fea | 306 | extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb, |
1da177e4 LT |
307 | const struct net_device *in, const struct net_device *out, |
308 | struct ebt_table *table); | |
309 | ||
310 | /* Used in the kernel match() functions */ | |
311 | #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) | |
312 | /* True if the hook mask denotes that the rule is in a base chain, | |
313 | * used in the check() functions */ | |
af5d6dc2 | 314 | #define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS)) |
1da177e4 | 315 | /* Clear the bit in the hook mask that tells if the rule is on a base chain */ |
af5d6dc2 | 316 | #define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS)) |
1da177e4 LT |
317 | /* True if the target is not a standard target */ |
318 | #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) | |
319 | ||
320 | #endif /* __KERNEL__ */ | |
321 | ||
322 | /* blatently stolen from ip_tables.h | |
323 | * fn returns 0 to continue iteration */ | |
324 | #define EBT_MATCH_ITERATE(e, fn, args...) \ | |
325 | ({ \ | |
326 | unsigned int __i; \ | |
327 | int __ret = 0; \ | |
328 | struct ebt_entry_match *__match; \ | |
329 | \ | |
330 | for (__i = sizeof(struct ebt_entry); \ | |
331 | __i < (e)->watchers_offset; \ | |
332 | __i += __match->match_size + \ | |
333 | sizeof(struct ebt_entry_match)) { \ | |
334 | __match = (void *)(e) + __i; \ | |
335 | \ | |
336 | __ret = fn(__match , ## args); \ | |
337 | if (__ret != 0) \ | |
338 | break; \ | |
339 | } \ | |
340 | if (__ret == 0) { \ | |
341 | if (__i != (e)->watchers_offset) \ | |
342 | __ret = -EINVAL; \ | |
343 | } \ | |
344 | __ret; \ | |
345 | }) | |
346 | ||
347 | #define EBT_WATCHER_ITERATE(e, fn, args...) \ | |
348 | ({ \ | |
349 | unsigned int __i; \ | |
350 | int __ret = 0; \ | |
351 | struct ebt_entry_watcher *__watcher; \ | |
352 | \ | |
353 | for (__i = e->watchers_offset; \ | |
354 | __i < (e)->target_offset; \ | |
355 | __i += __watcher->watcher_size + \ | |
356 | sizeof(struct ebt_entry_watcher)) { \ | |
357 | __watcher = (void *)(e) + __i; \ | |
358 | \ | |
359 | __ret = fn(__watcher , ## args); \ | |
360 | if (__ret != 0) \ | |
361 | break; \ | |
362 | } \ | |
363 | if (__ret == 0) { \ | |
364 | if (__i != (e)->target_offset) \ | |
365 | __ret = -EINVAL; \ | |
366 | } \ | |
367 | __ret; \ | |
368 | }) | |
369 | ||
370 | #define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ | |
371 | ({ \ | |
372 | unsigned int __i; \ | |
373 | int __ret = 0; \ | |
374 | struct ebt_entry *__entry; \ | |
375 | \ | |
376 | for (__i = 0; __i < (size);) { \ | |
377 | __entry = (void *)(entries) + __i; \ | |
378 | __ret = fn(__entry , ## args); \ | |
379 | if (__ret != 0) \ | |
380 | break; \ | |
381 | if (__entry->bitmask != 0) \ | |
382 | __i += __entry->next_offset; \ | |
383 | else \ | |
384 | __i += sizeof(struct ebt_entries); \ | |
385 | } \ | |
386 | if (__ret == 0) { \ | |
387 | if (__i != (size)) \ | |
388 | __ret = -EINVAL; \ | |
389 | } \ | |
390 | __ret; \ | |
391 | }) | |
392 | ||
393 | #endif |