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