Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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