linux/include/linux/netfilter_bridge/ebtables.h
<<
>>
Prefs
   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/* 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
  33
  34struct xt_match;
  35struct xt_target;
  36
  37struct ebt_counter {
  38        uint64_t pcnt;
  39        uint64_t bcnt;
  40};
  41
  42struct ebt_replace {
  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
  58struct ebt_replace_kernel {
  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
  74struct 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.
  95 * Using this simplifies the code alot, while still being able to use
  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
 120struct ebt_entry_match {
 121        union {
 122                char name[EBT_FUNCTION_MAXNAMELEN];
 123                struct xt_match *match;
 124        } u;
 125        /* size of data */
 126        unsigned int match_size;
 127        unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
 128};
 129
 130struct ebt_entry_watcher {
 131        union {
 132                char name[EBT_FUNCTION_MAXNAMELEN];
 133                struct xt_target *watcher;
 134        } u;
 135        /* size of data */
 136        unsigned int watcher_size;
 137        unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
 138};
 139
 140struct ebt_entry_target {
 141        union {
 142                char name[EBT_FUNCTION_MAXNAMELEN];
 143                struct xt_target *target;
 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"
 151struct ebt_standard_target {
 152        struct ebt_entry_target target;
 153        int verdict;
 154};
 155
 156/* one entry */
 157struct ebt_entry {
 158        /* this needs to be the first field */
 159        unsigned int bitmask;
 160        unsigned int invflags;
 161        __be16 ethproto;
 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
 202struct ebt_match {
 203        struct list_head list;
 204        const char name[EBT_FUNCTION_MAXNAMELEN];
 205        bool (*match)(const struct sk_buff *skb, const struct net_device *in,
 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);
 213        unsigned int matchsize;
 214        u_int8_t revision;
 215        u_int8_t family;
 216        struct module *me;
 217};
 218
 219struct ebt_watcher {
 220        struct list_head list;
 221        const char name[EBT_FUNCTION_MAXNAMELEN];
 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);
 230        unsigned int targetsize;
 231        u_int8_t revision;
 232        u_int8_t family;
 233        struct module *me;
 234};
 235
 236struct ebt_target {
 237        struct list_head list;
 238        const char name[EBT_FUNCTION_MAXNAMELEN];
 239        /* returns one of the standard EBT_* verdicts */
 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);
 248        unsigned int targetsize;
 249        u_int8_t revision;
 250        u_int8_t family;
 251        struct module *me;
 252};
 253
 254/* used for jumping from and into user defined chains (udc) */
 255struct ebt_chainstack {
 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
 261struct ebt_table_info {
 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
 273struct ebt_table {
 274        struct list_head list;
 275        char name[EBT_TABLE_MAXNAMELEN];
 276        struct ebt_replace_kernel *table;
 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))
 290extern struct ebt_table *ebt_register_table(struct net *net,
 291                                            const struct ebt_table *table);
 292extern void ebt_unregister_table(struct net *net, struct ebt_table *table);
 293extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb,
 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 */
 301#define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS))
 302/* Clear the bit in the hook mask that tells if the rule is on a base chain */
 303#define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS))
 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
 381