]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
ebtables-compat: use ebtables_command_state in bootstrap code
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 9 Oct 2014 18:11:16 +0000 (20:11 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 24 Nov 2014 10:35:34 +0000 (11:35 +0100)
And introduce fake ebt_entry.

This gets the code in sync in other existing compat tools. This
will likely allow to consolidate common infrastructure.

This code is still quite experimental.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter_bridge/ebtables.h [deleted file]
iptables/nft-bridge.c
iptables/nft-bridge.h [new file with mode: 0644]
iptables/nft-shared.c
iptables/nft-shared.h
iptables/nft.h
iptables/xtables-eb-standalone.c
iptables/xtables-eb.c
iptables/xtables-ebtables.h [deleted file]

diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
deleted file mode 100644 (file)
index f7ed1dc..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- *  ebtables
- *
- *     Authors:
- *     Bart De Schuymer                <bdschuym@pandora.be>
- *
- *  ebtables.c,v 2.0, April, 2002
- *
- *  This code is stongly inspired on the iptables code which is
- *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
- */
-
-/* Local copy of the kernel file, needed for Sparc64 support */
-#ifndef __LINUX_BRIDGE_EFF_H
-#define __LINUX_BRIDGE_EFF_H
-#include <net/if.h>
-#include <linux/netfilter_bridge.h>
-#include <linux/if_ether.h>
-
-#define EBT_TABLE_MAXNAMELEN 32
-#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-
-/* verdicts >0 are "branches" */
-#define EBT_ACCEPT   -1
-#define EBT_DROP     -2
-#define EBT_CONTINUE -3
-#define EBT_RETURN   -4
-#define NUM_STANDARD_TARGETS   4
-/* ebtables target modules store the verdict inside an int. We can
- * reclaim a part of this int for backwards compatible extensions.
- * The 4 lsb are more than enough to store the verdict. */
-#define EBT_VERDICT_BITS 0x0000000F
-
-struct ebt_counter
-{
-       uint64_t pcnt;
-       uint64_t bcnt;
-};
-
-struct ebt_replace
-{
-       char name[EBT_TABLE_MAXNAMELEN];
-       unsigned int valid_hooks;
-       /* nr of rules in the table */
-       unsigned int nentries;
-       /* total size of the entries */
-       unsigned int entries_size;
-       /* start of the chains */
-#ifdef KERNEL_64_USERSPACE_32
-       uint64_t hook_entry[NF_BR_NUMHOOKS];
-#else
-       struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
-#endif
-       /* nr of counters userspace expects back */
-       unsigned int num_counters;
-       /* where the kernel will put the old counters */
-#ifdef KERNEL_64_USERSPACE_32
-       uint64_t counters;
-       uint64_t entries;
-#else
-       struct ebt_counter *counters;
-       char *entries;
-#endif
-};
-
-struct ebt_entries {
-       /* this field is always set to zero
-        * See EBT_ENTRY_OR_ENTRIES.
-        * Must be same size as ebt_entry.bitmask */
-       unsigned int distinguisher;
-       /* the chain name */
-       char name[EBT_CHAIN_MAXNAMELEN];
-       /* counter offset for this chain */
-       unsigned int counter_offset;
-       /* one standard (accept, drop, return) per hook */
-       int policy;
-       /* nr. of entries */
-       unsigned int nentries;
-       /* entry list */
-       char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-/* used for the bitmask of struct ebt_entry */
-
-/* This is a hack to make a difference between an ebt_entry struct and an
- * ebt_entries struct when traversing the entries from start to end.
- * Using this simplifies the code alot, while still being able to use
- * ebt_entries.
- * Contrary, iptables doesn't use something like ebt_entries and therefore uses
- * different techniques for naming the policy and such. So, iptables doesn't
- * need a hack like this.
- */
-#define EBT_ENTRY_OR_ENTRIES 0x01
-/* these are the normal masks */
-#define EBT_NOPROTO 0x02
-#define EBT_802_3 0x04
-#define EBT_SOURCEMAC 0x08
-#define EBT_DESTMAC 0x10
-#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
-   | EBT_ENTRY_OR_ENTRIES)
-
-#define EBT_IPROTO 0x01
-#define EBT_IIN 0x02
-#define EBT_IOUT 0x04
-#define EBT_ISOURCE 0x8
-#define EBT_IDEST 0x10
-#define EBT_ILOGICALIN 0x20
-#define EBT_ILOGICALOUT 0x40
-#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
-   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
-
-struct ebt_entry_match
-{
-       union {
-               char name[EBT_FUNCTION_MAXNAMELEN];
-               struct ebt_match *match;
-       } u;
-       /* size of data */
-       unsigned int match_size;
-#ifdef KERNEL_64_USERSPACE_32
-       unsigned int pad;
-#endif
-       unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-struct ebt_entry_watcher
-{
-       union {
-               char name[EBT_FUNCTION_MAXNAMELEN];
-               struct ebt_watcher *watcher;
-       } u;
-       /* size of data */
-       unsigned int watcher_size;
-#ifdef KERNEL_64_USERSPACE_32
-       unsigned int pad;
-#endif
-       unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-struct ebt_entry_target
-{
-       union {
-               char name[EBT_FUNCTION_MAXNAMELEN];
-               struct ebt_target *target;
-       } u;
-       /* size of data */
-       unsigned int target_size;
-#ifdef KERNEL_64_USERSPACE_32
-       unsigned int pad;
-#endif
-       unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-#define EBT_STANDARD_TARGET "standard"
-struct ebt_standard_target
-{
-       struct ebt_entry_target target;
-       int verdict;
-#ifdef KERNEL_64_USERSPACE_32
-       unsigned int pad;
-#endif
-};
-
-/* one entry */
-struct ebt_entry {
-       /* this needs to be the first field */
-       unsigned int bitmask;
-       unsigned int invflags;
-       uint16_t ethproto;
-       /* the physical in-dev */
-       char in[IFNAMSIZ];
-       /* the logical in-dev */
-       char logical_in[IFNAMSIZ];
-       /* the physical out-dev */
-       char out[IFNAMSIZ];
-       /* the logical out-dev */
-       char logical_out[IFNAMSIZ];
-       unsigned char sourcemac[ETH_ALEN];
-       unsigned char sourcemsk[ETH_ALEN];
-       unsigned char destmac[ETH_ALEN];
-       unsigned char destmsk[ETH_ALEN];
-       /* sizeof ebt_entry + matches */
-       unsigned int watchers_offset;
-       /* sizeof ebt_entry + matches + watchers */
-       unsigned int target_offset;
-       /* sizeof ebt_entry + matches + watchers + target */
-       unsigned int next_offset;
-       unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-/* {g,s}etsockopt numbers */
-#define EBT_BASE_CTL            128
-
-#define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
-#define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
-#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
-
-#define EBT_SO_GET_INFO         (EBT_BASE_CTL)
-#define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
-#define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
-#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
-#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
-
-/* blatently stolen from ip_tables.h
- * fn returns 0 to continue iteration */
-#define EBT_MATCH_ITERATE(e, fn, args...)                   \
-({                                                          \
-       unsigned int __i;                                   \
-       int __ret = 0;                                      \
-       struct ebt_entry_match *__match;                    \
-                                                           \
-       for (__i = sizeof(struct ebt_entry);                \
-            __i < (e)->watchers_offset;                    \
-            __i += __match->match_size +                   \
-            sizeof(struct ebt_entry_match)) {              \
-               __match = (void *)(e) + __i;                \
-                                                           \
-               __ret = fn(__match , ## args);              \
-               if (__ret != 0)                             \
-                       break;                              \
-       }                                                   \
-       if (__ret == 0) {                                   \
-               if (__i != (e)->watchers_offset)            \
-                       __ret = -EINVAL;                    \
-       }                                                   \
-       __ret;                                              \
-})
-
-#define EBT_WATCHER_ITERATE(e, fn, args...)                 \
-({                                                          \
-       unsigned int __i;                                   \
-       int __ret = 0;                                      \
-       struct ebt_entry_watcher *__watcher;                \
-                                                           \
-       for (__i = e->watchers_offset;                      \
-            __i < (e)->target_offset;                      \
-            __i += __watcher->watcher_size +               \
-            sizeof(struct ebt_entry_watcher)) {            \
-               __watcher = (void *)(e) + __i;              \
-                                                           \
-               __ret = fn(__watcher , ## args);            \
-               if (__ret != 0)                             \
-                       break;                              \
-       }                                                   \
-       if (__ret == 0) {                                   \
-               if (__i != (e)->target_offset)              \
-                       __ret = -EINVAL;                    \
-       }                                                   \
-       __ret;                                              \
-})
-
-#define EBT_ENTRY_ITERATE(entries, size, fn, args...)       \
-({                                                          \
-       unsigned int __i;                                   \
-       int __ret = 0;                                      \
-       struct ebt_entry *__entry;                          \
-                                                           \
-       for (__i = 0; __i < (size);) {                      \
-               __entry = (void *)(entries) + __i;          \
-               __ret = fn(__entry , ## args);              \
-               if (__ret != 0)                             \
-                       break;                              \
-               if (__entry->bitmask != 0)                  \
-                       __i += __entry->next_offset;        \
-               else                                        \
-                       __i += sizeof(struct ebt_entries);  \
-       }                                                   \
-       if (__ret == 0) {                                   \
-               if (__i != (size))                          \
-                       __ret = -EINVAL;                    \
-       }                                                   \
-       __ret;                                              \
-})
-
-#endif
index 66361ee98c0e7454f834633df4795df48557e89f..ab97881de7efaf0de7660653eb005ce79d5b9057 100644 (file)
 #include <ebtables/ethernetdb.h>
 
 #include "nft-shared.h"
+#include "nft-bridge.h"
 #include "nft.h"
 
 /* 0: default, print only 2 digits if necessary
  * 2: always print 2 digits, a printed mac address
- * then always has the same length */
+ * then always has the same length
+ */
 int ebt_printstyle_mac;
 
 static void ebt_print_mac(const unsigned char *mac)
@@ -132,31 +134,36 @@ static void add_logical_outiface(struct nft_rule *r, char *iface, int invflags)
                add_cmp_ptr(r, op, iface, iface_len + 1);
 }
 
-static int _add_action(struct nft_rule *r, struct xtables_ebt_entry *fw)
+/* TODO: Use generic add_action() once we convert this to use
+ * iptables_command_state.
+ */
+static int _add_action(struct nft_rule *r, struct ebtables_command_state *cs)
 {
        int ret = 0;
 
-       /* If no target at all, add nothing (default to continue) */
-       if (fw->target != NULL) {
-              /* Standard target? */
-              if (strcmp(fw->jumpto, XTC_LABEL_ACCEPT) == 0)
-                      ret = add_verdict(r, NF_ACCEPT);
-              else if (strcmp(fw->jumpto, XTC_LABEL_DROP) == 0)
-                      ret = add_verdict(r, NF_DROP);
-              else if (strcmp(fw->jumpto, XTC_LABEL_RETURN) == 0)
-                      ret = add_verdict(r, NFT_RETURN);
-              else
-                      ret = add_target(r, fw->target->t);
-       } else if (strlen(fw->jumpto) > 0)
+       /* If no target at all, add nothing (default to continue) */
+       if (cs->target != NULL) {
+               /* Standard target? */
+               if (strcmp(cs->jumpto, XTC_LABEL_ACCEPT) == 0)
+                       ret = add_verdict(r, NF_ACCEPT);
+               else if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0)
+                       ret = add_verdict(r, NF_DROP);
+               else if (strcmp(cs->jumpto, XTC_LABEL_RETURN) == 0)
+                       ret = add_verdict(r, NFT_RETURN);
+               else
+                       ret = add_target(r, cs->target->t);
+       } else if (strlen(cs->jumpto) > 0) {
                /* Not standard, then it's a jump to chain */
-               ret = add_jumpto(r, fw->jumpto, NFT_JUMP);
+               ret = add_jumpto(r, cs->jumpto, NFT_JUMP);
+       }
 
-       return ret;
+       return ret;
 }
 
 static int nft_bridge_add(struct nft_rule *r, void *data)
 {
-       struct xtables_ebt_entry *fw = data;
+       struct ebtables_command_state *cs = data;
+       struct ebt_entry *fw = &cs->fw;
        uint8_t flags = ebt_to_ipt_flags(fw->invflags);
        char *addr;
 
@@ -189,13 +196,14 @@ static int nft_bridge_add(struct nft_rule *r, void *data)
                add_cmp_u16(r, fw->ethproto, NFT_CMP_EQ);
        }
 
-       return _add_action(r, fw);
+       return _add_action(r, cs);
 }
 
 static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
                                  struct nft_rule_expr *e, void *data)
 {
-       struct xtables_ebt_entry *fw = data;
+       struct ebtables_command_state *cs = data;
+       struct ebt_entry *fw = &cs->fw;
        uint8_t flags = 0;
        int iface = 0;
        const void *ifname;
@@ -214,7 +222,7 @@ static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
 
                memcpy(fw->logical_in, ifname, len);
 
-               if (fw->logical_in[len] == '\0') 
+               if (fw->logical_in[len] == '\0')
                        memset(fw->in_mask, 0xff, len);
                else {
                        fw->logical_in[len] = '+';
@@ -248,7 +256,8 @@ out:
 static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
                                     struct nft_rule_expr *e, void *data)
 {
-       struct xtables_ebt_entry *fw = data;
+       struct ebtables_command_state *cs = data;
+       struct ebt_entry *fw = &cs->fw;
        unsigned char addr[ETH_ALEN];
        unsigned short int ethproto;
        bool inv;
@@ -271,28 +280,30 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
                break;
        }
 }
+
 static void nft_bridge_parse_immediate(const char *jumpto, bool nft_goto,
                                       void *data)
 {
-       struct xtables_ebt_entry *fw = data;
+       struct ebtables_command_state *cs = data;
 
-       fw->jumpto = jumpto;
+       cs->jumpto = jumpto;
 }
 
 static void nft_bridge_parse_target(struct xtables_target *t, void *data)
 {
-       struct xtables_ebt_entry *fw = data;
+       struct ebtables_command_state *cs = data;
 
-       fw->target = t;
+       cs->target = t;
 }
 
-void nft_rule_to_xtables_ebt_entry(struct nft_rule *r, struct xtables_ebt_entry *fw)
+void nft_rule_to_ebtables_command_state(struct nft_rule *r,
+                                       struct ebtables_command_state *cs)
 {
        struct nft_rule_expr_iter *iter;
        struct nft_rule_expr *expr;
        int family = nft_rule_attr_get_u32(r, NFT_RULE_ATTR_FAMILY);
        struct nft_xt_ctx ctx = {
-               .state.ebfw = fw,
+               .state.cs_eb = cs,
                .family = family,
        };
 
@@ -306,15 +317,19 @@ void nft_rule_to_xtables_ebt_entry(struct nft_rule *r, struct xtables_ebt_entry
                        nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);
 
                if (strcmp(name, "counter") == 0)
-                       nft_parse_counter(expr, &fw->counters);
+                       nft_parse_counter(expr, &cs->counters);
                else if (strcmp(name, "payload") == 0)
                        nft_parse_payload(&ctx, expr);
                else if (strcmp(name, "meta") == 0)
                        nft_parse_meta(&ctx, expr);
+                else if (strcmp(name, "bitwise") == 0)
+                        nft_parse_bitwise(&ctx, expr);
                else if (strcmp(name, "cmp") == 0)
                        nft_parse_cmp(&ctx, expr);
                else if (strcmp(name, "immediate") == 0)
                        nft_parse_immediate(&ctx, expr);
+               else if (strcmp(name, "match") == 0)
+                       nft_parse_match(&ctx, expr);
                else if (strcmp(name, "target") == 0)
                        nft_parse_target(&ctx, expr);
 
@@ -323,12 +338,12 @@ void nft_rule_to_xtables_ebt_entry(struct nft_rule *r, struct xtables_ebt_entry
 
        nft_rule_expr_iter_destroy(iter);
 
-       if (fw->target != NULL)
-               fw->jumpto = fw->target->name;
-       else if (fw->jumpto != NULL)
-               fw->target = xtables_find_target(fw->jumpto, XTF_TRY_LOAD);
+       if (cs->target != NULL)
+               cs->jumpto = cs->target->name;
+       else if (cs->jumpto != NULL)
+               cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
        else
-               fw->jumpto = "";
+               cs->jumpto = "";
 }
 
 static void print_iface(const char *iface)
@@ -351,81 +366,80 @@ static void nft_bridge_print_header(unsigned int format, const char *chain,
        print_header(format, chain, pol, counters, basechain, refs);
 }
 
-static void
-nft_bridge_print_firewall(struct nft_rule *r, unsigned int num,
-                      unsigned int format)
+static void nft_bridge_print_firewall(struct nft_rule *r, unsigned int num,
+                                     unsigned int format)
 {
-       struct xtables_ebt_entry fw = {};
+       struct ebtables_command_state cs = {};
        char *addr;
 
-       nft_rule_to_xtables_ebt_entry(r, &fw);
+       nft_rule_to_ebtables_command_state(r, &cs);
 
        if (format & FMT_LINENUMBERS)
                printf("%d ", num);
 
        /* Dont print anything about the protocol if no protocol was
         * specified, obviously this means any protocol will do. */
-       if (fw.ethproto != 0) {
+       if (cs.fw.ethproto != 0) {
                printf("-p ");
-               if (fw.invflags & EBT_IPROTO)
+               if (cs.fw.invflags & EBT_IPROTO)
                        printf("! ");
-               if (fw.bitmask & EBT_802_3)
+               if (cs.fw.bitmask & EBT_802_3)
                        printf("Length ");
                else {
                        struct ethertypeent *ent;
 
-                       ent = getethertypebynumber(ntohs(fw.ethproto));
+                       ent = getethertypebynumber(ntohs(cs.fw.ethproto));
                        if (!ent)
-                               printf("0x%x ", ntohs(fw.ethproto));
+                               printf("0x%x ", ntohs(cs.fw.ethproto));
                        else
                                printf("%s ", ent->e_name);
                }
        }
 
-       addr = ether_ntoa((struct ether_addr *) fw.sourcemac);
+       addr = ether_ntoa((struct ether_addr *) cs.fw.sourcemac);
        if (strcmp(addr, "0:0:0:0:0:0") != 0) {
                printf("-s ");
-               if (fw.invflags & EBT_ISOURCE)
+               if (cs.fw.invflags & EBT_ISOURCE)
                        printf("! ");
-               ebt_print_mac_and_mask(fw.sourcemac, fw.sourcemsk);
+               ebt_print_mac_and_mask(cs.fw.sourcemac, cs.fw.sourcemsk);
                printf(" ");
        }
 
-       addr = ether_ntoa((struct ether_addr *) fw.destmac);
+       addr = ether_ntoa((struct ether_addr *) cs.fw.destmac);
        if (strcmp(addr, "0:0:0:0:0:0") != 0) {
                printf("-d ");
-               if (fw.invflags & EBT_IDEST)
+               if (cs.fw.invflags & EBT_IDEST)
                        printf("! ");
-               ebt_print_mac_and_mask(fw.destmac, fw.destmsk);
+               ebt_print_mac_and_mask(cs.fw.destmac, cs.fw.destmsk);
                printf(" ");
        }
 
-       if (fw.in[0] != '\0') {
+       if (cs.fw.in[0] != '\0') {
                printf("-i ");
-               if (fw.invflags & EBT_IIN)
+               if (cs.fw.invflags & EBT_IIN)
                        printf("! ");
-               print_iface(fw.in);
+               print_iface(cs.fw.in);
        }
 
-       if (fw.logical_in[0] != '\0') {
+       if (cs.fw.logical_in[0] != '\0') {
                printf("--logical-in ");
-               if (fw.invflags & EBT_ILOGICALIN)
+               if (cs.fw.invflags & EBT_ILOGICALIN)
                        printf("! ");
-               print_iface(fw.logical_in);
+               print_iface(cs.fw.logical_in);
        }
 
-       if (fw.logical_out[0] != '\0') {
+       if (cs.fw.logical_out[0] != '\0') {
                printf("--logical-out ");
-               if (fw.invflags & EBT_ILOGICALOUT)
+               if (cs.fw.invflags & EBT_ILOGICALOUT)
                        printf("! ");
-               print_iface(fw.logical_out);
+               print_iface(cs.fw.logical_out);
        }
 
-       if (fw.out[0] != '\0') {
+       if (cs.fw.out[0] != '\0') {
                printf("-o ");
-               if (fw.invflags & EBT_IOUT)
+               if (cs.fw.invflags & EBT_IOUT)
                        printf("! ");
-               print_iface(fw.out);
+               print_iface(cs.fw.out);
        }
 
        /* old code to adapt
@@ -447,12 +461,12 @@ nft_bridge_print_firewall(struct nft_rule *r, unsigned int num,
        }*/
        printf("-j ");
        if (!(format & FMT_NOTARGET))
-               printf("%s", fw.jumpto);
+               printf("%s", cs.jumpto);
 
-       if (fw.target != NULL) {
-               if (fw.target->print != NULL) {
-                       fw.target->print(&fw, fw.target->t,
-                                        format & FMT_NUMERIC);
+       if (cs.target != NULL) {
+               if (cs.target->print != NULL) {
+                       cs.target->print(&cs.fw, cs.target->t,
+                                           format & FMT_NUMERIC);
                }
        }
 
@@ -460,16 +474,15 @@ nft_bridge_print_firewall(struct nft_rule *r, unsigned int num,
                fputc('\n', stdout);
 }
 
-static bool nft_bridge_is_same(const void *data_a,
-                              const void *data_b)
+static bool nft_bridge_is_same(const void *data_a, const void *data_b)
 {
-       const struct xtables_ebt_entry *a = data_a;
-       const struct xtables_ebt_entry *b = data_b;
+       const struct ebt_entry *a = data_a;
+       const struct ebt_entry *b = data_b;
        int i;
 
-       if (a->ethproto != b->ethproto
-           /*|| a->flags != b->flags*/
-           || a->invflags != b->invflags) {
+       if (a->ethproto != b->ethproto ||
+           /* FIXME: a->flags != b->flags || */
+           a->invflags != b->invflags) {
                DEBUGP("different proto/flags/invflags\n");
                return false;
        }
@@ -515,27 +528,27 @@ static bool nft_bridge_is_same(const void *data_a,
 static bool nft_bridge_rule_find(struct nft_family_ops *ops, struct nft_rule *r,
                                 void *data)
 {
-       struct xtables_ebt_entry *fw = data;
-       struct xtables_ebt_entry this = {};
+       struct ebtables_command_state *cs = data;
+       struct ebtables_command_state this = {};
 
-       nft_rule_to_xtables_ebt_entry(r, &this);
+       nft_rule_to_ebtables_command_state(r, &this);
 
        DEBUGP("comparing with... ");
 
-       if (!ops->is_same(fw, &this))
+       if (!nft_bridge_is_same(cs, &this))
                return false;
 
-       if (!compare_matches(fw->matches, this.matches)) {
+       if (!compare_matches(cs->matches, this.matches)) {
                DEBUGP("Different matches\n");
                return false;
        }
 
-       if (!compare_targets(fw->target, this.target)) {
+       if (!compare_targets(cs->target, this.target)) {
                DEBUGP("Different target\n");
                return false;
        }
 
-       if (strcmp(fw->jumpto, this.jumpto) != 0) {
+       if (strcmp(cs->jumpto, this.jumpto) != 0) {
                DEBUGP("Different verdict\n");
                return false;
        }
@@ -550,9 +563,11 @@ struct nft_family_ops nft_family_ops_bridge = {
        .parse_meta             = nft_bridge_parse_meta,
        .parse_payload          = nft_bridge_parse_payload,
        .parse_immediate        = nft_bridge_parse_immediate,
+       .parse_target           = nft_bridge_parse_target,
        .print_header           = nft_bridge_print_header,
        .print_firewall         = nft_bridge_print_firewall,
+       .save_firewall          = NULL,
+       .save_counters          = NULL,
        .post_parse             = NULL,
        .rule_find              = nft_bridge_rule_find,
-       .parse_target           = nft_bridge_parse_target,
 };
diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
new file mode 100644 (file)
index 0000000..1e3f0a1
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef _NFT_BRIDGE_H_
+#define _NFT_BRIDGE_H_
+
+#include <netinet/in.h>
+//#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter/x_tables.h>
+
+/* We use replace->flags, so we can't use the following values:
+ * 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO */
+#define LIST_N   0x04
+#define LIST_C   0x08
+#define LIST_X   0x10
+#define LIST_MAC2 0x20
+
+/* Be backwards compatible, so don't use '+' in kernel */
+#define IF_WILDCARD 1
+
+extern unsigned char eb_mac_type_unicast[ETH_ALEN];
+extern unsigned char eb_msk_type_unicast[ETH_ALEN];
+extern unsigned char eb_mac_type_multicast[ETH_ALEN];
+extern unsigned char eb_msk_type_multicast[ETH_ALEN];
+extern unsigned char eb_mac_type_broadcast[ETH_ALEN];
+extern unsigned char eb_msk_type_broadcast[ETH_ALEN];
+extern unsigned char eb_mac_type_bridge_group[ETH_ALEN];
+extern unsigned char eb_msk_type_bridge_group[ETH_ALEN];
+
+int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask);
+
+/* From: include/linux/netfilter_bridge/ebtables.h
+ *
+ * Adapted for the need of the ebtables-compat.
+ */
+
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+
+/* verdicts >0 are "branches" */
+#define EBT_ACCEPT   -1
+#define EBT_DROP     -2
+#define EBT_CONTINUE -3
+#define EBT_RETURN   -4
+#define NUM_STANDARD_TARGETS   4
+
+#define EBT_ENTRY_OR_ENTRIES 0x01
+/* these are the normal masks */
+#define EBT_NOPROTO 0x02
+#define EBT_802_3 0x04
+#define EBT_SOURCEMAC 0x08
+#define EBT_DESTMAC 0x10
+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
+   | EBT_ENTRY_OR_ENTRIES)
+
+#define EBT_IPROTO 0x01
+#define EBT_IIN 0x02
+#define EBT_IOUT 0x04
+#define EBT_ISOURCE 0x8
+#define EBT_IDEST 0x10
+#define EBT_ILOGICALIN 0x20
+#define EBT_ILOGICALOUT 0x40
+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
+   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+
+/* Fake ebt_entry */
+struct ebt_entry {
+       /* this needs to be the first field */
+       unsigned int bitmask;
+       unsigned int invflags;
+       uint16_t ethproto;
+       /* the physical in-dev */
+       char in[IFNAMSIZ];
+       /* the logical in-dev */
+       char logical_in[IFNAMSIZ];
+       /* the physical out-dev */
+       char out[IFNAMSIZ];
+       /* the logical out-dev */
+       char logical_out[IFNAMSIZ];
+       unsigned char sourcemac[ETH_ALEN];
+       unsigned char sourcemsk[ETH_ALEN];
+       unsigned char destmac[ETH_ALEN];
+       unsigned char destmsk[ETH_ALEN];
+
+       unsigned char in_mask[IFNAMSIZ];
+       unsigned char out_mask[IFNAMSIZ];
+};
+
+struct ebtables_command_state {
+       struct ebt_entry fw;
+       struct xtables_target *target;
+       struct xtables_rule_match *matches;
+       const char *jumpto;
+       struct xt_counters counters;
+};
+
+void nft_rule_to_ebtables_command_state(struct nft_rule *r,
+                                       struct ebtables_command_state *cs);
+
+#endif
index 9ca2e35c102c48c70d034f4d9aee6432940b391c..71c4476354f3012e2bcac6e307400222bba91385 100644 (file)
@@ -280,7 +280,7 @@ static void *nft_get_data(struct nft_xt_ctx *ctx)
        case NFPROTO_ARP:
                return ctx->state.cs_arp;
        case NFPROTO_BRIDGE:
-               return ctx->state.ebfw;
+               return ctx->state.cs_eb;
        default:
                /* Should not happen */
                return NULL;
@@ -320,7 +320,7 @@ void nft_parse_target(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
        ops->parse_target(target, data);
 }
 
-static void nft_parse_match(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
+void nft_parse_match(struct nft_xt_ctx *ctx, struct nft_rule_expr *e)
 {
        uint32_t mt_len;
        const char *mt_name = nft_rule_expr_get_str(e, NFT_EXPR_MT_NAME);
index 97d41df8d174e782678b65fbdd292e4ea77f47eb..361e956646dbe824dd1ae9f1148a97714e6892ea 100644 (file)
@@ -48,7 +48,7 @@ struct nft_xt_ctx {
        union {
                struct iptables_command_state *cs;
                struct arptables_command_state *cs_arp;
-               struct xtables_ebt_entry *ebfw;
+               struct ebtables_command_state *cs_eb;
        } state;
        struct nft_rule_expr_iter *iter;
        int family;
@@ -130,6 +130,7 @@ void print_proto(uint16_t proto, int invert);
 void get_cmp_data(struct nft_rule_expr *e, void *data, size_t dlen, bool *inv);
 void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
 void nft_parse_cmp(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
+void nft_parse_match(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
 void nft_parse_target(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
 void nft_parse_meta(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
 void nft_parse_payload(struct nft_xt_ctx *ctx, struct nft_rule_expr *e);
index 4f0b733cbd1bb0b64589efa63bfb8affd707c9db..ab3d64aca15dd5e332ab0beadff5d8f36824b840 100644 (file)
@@ -170,13 +170,4 @@ int nft_arp_rule_insert(struct nft_handle *h, const char *chain,
 
 void nft_rule_to_arpt_entry(struct nft_rule *r, struct arpt_entry *fw);
 
-/*
- * BRIDGE
- */
-
-#include "xtables-ebtables.h"
-
-struct xtables_ebt_entry;
-
-void nft_rule_to_xtables_ebt_entry(struct nft_rule *r, struct xtables_ebt_entry *fw);
 #endif
index 6ec418cb7c5ab9feae9f6d9595ff5c2aa69350df..1c3cbf078c355dfbc2153839cf4c866240992944 100644 (file)
@@ -83,5 +83,8 @@ int xtables_eb_main(int argc, char *argv[])
        if (ret)
                ret = nft_commit(&h);
 
+       if (!ret)
+               fprintf(stderr, "%s\n", nft_strerror(errno));
+
        exit(!ret);
 }
index 73a38db9f53767482080c33f89c796683fcb7a43..99d930e56186412ddb9d5d4121f3e19a629253d4 100644 (file)
 #include <netinet/ether.h>
 #include <xtables.h>
 
+#include <linux/netfilter_bridge.h>
 #include <ebtables/ethernetdb.h>
 #include "xshared.h"
 #include "nft.h"
+#include "nft-bridge.h"
 
 extern struct xtables_globals xtables_globals;
 #define prog_name xtables_globals.program_name
@@ -213,16 +215,16 @@ static int
 append_entry(struct nft_handle *h,
             const char *chain,
             const char *table,
-            struct xtables_ebt_entry *fw,
+            struct ebtables_command_state *cs,
             int rule_nr,
             bool verbose, bool append)
 {
        int ret = 1;
 
        if (append)
-               ret = nft_rule_append(h, chain, table, fw, 0, verbose);
+               ret = nft_rule_append(h, chain, table, cs, 0, verbose);
        else
-               ret = nft_rule_insert(h, chain, table, fw, rule_nr, verbose);
+               ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose);
 
        return ret;
 }
@@ -231,7 +233,7 @@ static int
 delete_entry(struct nft_handle *h,
             const char *chain,
             const char *table,
-            struct xtables_ebt_entry *fw,
+            struct ebtables_command_state *cs,
             int rule_nr,
             int rule_nr_end,
             bool verbose)
@@ -239,7 +241,7 @@ delete_entry(struct nft_handle *h,
        int ret = 1;
 
        if (rule_nr == -1)
-               ret = nft_rule_delete(h, chain, table, fw, verbose);
+               ret = nft_rule_delete(h, chain, table, cs, verbose);
        else {
                do {
                        ret = nft_rule_delete_num(h, chain, table,
@@ -342,7 +344,7 @@ static struct option *ebt_options = ebt_original_options;
 /*
  * More glue code.
  */
-static struct xtables_target *command_jump(struct xtables_ebt_entry *fw,
+static struct xtables_target *command_jump(struct ebtables_command_state *cs,
                                           const char *jumpto)
 {
        struct xtables_target *target;
@@ -490,7 +492,7 @@ static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
 /* Incrementing or decrementing rules in daemon mode is not supported as the
  * involved code overload is not worth it (too annoying to take the increased
  * counters in the kernel into account). */
-static int parse_change_counters_rule(int argc, char **argv, int *rule_nr, int *rule_nr_end, int exec_style, struct xtables_ebt_entry *fw)
+static int parse_change_counters_rule(int argc, char **argv, int *rule_nr, int *rule_nr_end, int exec_style, struct ebtables_command_state *cs)
 {
        char *buffer;
        int ret = 0;
@@ -515,16 +517,16 @@ daemon_incr:
                        xtables_error(PARAMETER_PROBLEM,
                                      "Incrementing rule counters (%s) not allowed in daemon mode", argv[optind]);
                ret += 1;
-               fw->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
+               cs->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
        } else if (argv[optind][0] == '-') {
                if (exec_style == EXEC_STYLE_DAEMON)
 daemon_decr:
                        xtables_error(PARAMETER_PROBLEM,
                                      "Decrementing rule counters (%s) not allowed in daemon mode", argv[optind]);
                ret += 2;
-               fw->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
+               cs->counters.pcnt = strtoull(argv[optind] + 1, &buffer, 10);
        } else
-               fw->counters.pcnt = strtoull(argv[optind], &buffer, 10);
+               cs->counters.pcnt = strtoull(argv[optind], &buffer, 10);
 
        if (*buffer != '\0')
                goto invalid;
@@ -533,14 +535,14 @@ daemon_decr:
                if (exec_style == EXEC_STYLE_DAEMON)
                        goto daemon_incr;
                ret += 3;
-               fw->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
+               cs->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
        } else if (argv[optind][0] == '-') {
                if (exec_style == EXEC_STYLE_DAEMON)
                        goto daemon_decr;
                ret += 6;
-               fw->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
+               cs->counters.bcnt = strtoull(argv[optind] + 1, &buffer, 10);
        } else
-               fw->counters.bcnt = strtoull(argv[optind], &buffer, 10);
+               cs->counters.bcnt = strtoull(argv[optind], &buffer, 10);
 
        if (*buffer != '\0')
                goto invalid;
@@ -577,7 +579,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table)
        int ret = 0;
        unsigned int flags = 0;
        struct xtables_target *t;
-       struct xtables_ebt_entry fw;
+       struct ebtables_command_state cs;
        char command = 'h';
        const char *chain = NULL;
        const char *newname = NULL;
@@ -585,7 +587,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table)
        int exec_style = EXEC_STYLE_PRG;
        int selected_chain = -1;
 
-       memset(&fw, 0, sizeof(fw));
+       memset(&cs, 0, sizeof(cs));
 
        if (nft_init(h, xtables_bridge) < 0)
                xtables_error(OTHER_PROBLEM,
@@ -651,7 +653,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table)
                                                         "Problem with the specified rule number(s) '%s'", argv[optind]);
                                optind++;
                        } else if (c == 'C') {
-                               if ((chcounter = parse_change_counters_rule(argc, argv, &rule_nr, &rule_nr_end, exec_style, &fw)) == -1)
+                               if ((chcounter = parse_change_counters_rule(argc, argv, &rule_nr, &rule_nr_end, exec_style, &cs)) == -1)
                                        return -1;
                        } else if (c == 'I') {
                                if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
@@ -748,7 +750,7 @@ print_zero:
                                struct ebt_u_watcher *w;*/
 
                                if (!strcasecmp("list_extensions", argv[optind])) {
-                                       ebt_list_extensions(xtables_targets, fw.matches);
+                                       ebt_list_extensions(xtables_targets, cs.matches);
                                        exit(0);
                                }
                                /*if ((m = ebt_find_match(argv[optind])))
@@ -761,7 +763,7 @@ print_zero:
                                        if (flags & OPT_JUMP)
                                                xtables_error(PARAMETER_PROBLEM,"Sorry, you can only see help for one target extension at a time");
                                        flags |= OPT_JUMP;
-                                       fw.target = t;
+                                       cs.target = t;
                                //}
                                optind++;
                        }
@@ -798,14 +800,14 @@ print_zero:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Use -i only in INPUT, FORWARD, PREROUTING and BROUTING chains");
                                if (ebt_check_inverse2(optarg, argc, argv))
-                                       fw.invflags |= EBT_IIN;
+                                       cs.fw.invflags |= EBT_IIN;
 
                                if (strlen(optarg) >= IFNAMSIZ)
 big_iface_length:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Interface name length cannot exceed %d characters",
                                                      IFNAMSIZ - 1);
-                               xtables_parse_interface(optarg, fw.in, fw.in_mask);
+                               xtables_parse_interface(optarg, cs.fw.in, cs.fw.in_mask);
                                break;
                        } else if (c == 2) {
                                ebt_check_option2(&flags, OPT_LOGICALIN);
@@ -813,12 +815,12 @@ big_iface_length:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Use --logical-in only in INPUT, FORWARD, PREROUTING and BROUTING chains");
                                if (ebt_check_inverse2(optarg, argc, argv))
-                                       fw.invflags |= EBT_ILOGICALIN;
+                                       cs.fw.invflags |= EBT_ILOGICALIN;
 
                                if (strlen(optarg) >= IFNAMSIZ)
                                        goto big_iface_length;
-                               strcpy(fw.logical_in, optarg);
-                               if (parse_iface(fw.logical_in, "--logical-in"))
+                               strcpy(cs.fw.logical_in, optarg);
+                               if (parse_iface(cs.fw.logical_in, "--logical-in"))
                                        return -1;
                                break;
                        } else if (c == 'o') {
@@ -827,12 +829,12 @@ big_iface_length:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Use -o only in OUTPUT, FORWARD and POSTROUTING chains");
                                if (ebt_check_inverse2(optarg, argc, argv))
-                                       fw.invflags |= EBT_IOUT;
+                                       cs.fw.invflags |= EBT_IOUT;
 
                                if (strlen(optarg) >= IFNAMSIZ)
                                        goto big_iface_length;
 
-                               xtables_parse_interface(optarg, fw.out, fw.out_mask);
+                               xtables_parse_interface(optarg, cs.fw.out, cs.fw.out_mask);
                                break;
                        } else if (c == 3) {
                                ebt_check_option2(&flags, OPT_LOGICALOUT);
@@ -840,36 +842,36 @@ big_iface_length:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Use --logical-out only in OUTPUT, FORWARD and POSTROUTING chains");
                                if (ebt_check_inverse2(optarg, argc, argv))
-                                       fw.invflags |= EBT_ILOGICALOUT;
+                                       cs.fw.invflags |= EBT_ILOGICALOUT;
 
                                if (strlen(optarg) >= IFNAMSIZ)
                                        goto big_iface_length;
-                               strcpy(fw.logical_out, optarg);
-                               if (parse_iface(fw.logical_out, "--logical-out"))
+                               strcpy(cs.fw.logical_out, optarg);
+                               if (parse_iface(cs.fw.logical_out, "--logical-out"))
                                        return -1;
                                break;
                        } else if (c == 'j') {
                                ebt_check_option2(&flags, OPT_JUMP);
-                               fw.jumpto = parse_target(optarg);
-                               fw.target = command_jump(&fw, fw.jumpto);
+                               cs.jumpto = parse_target(optarg);
+                               cs.target = command_jump(&cs, cs.jumpto);
                                break;
                        } else if (c == 's') {
                                ebt_check_option2(&flags, OPT_SOURCE);
                                if (ebt_check_inverse2(optarg, argc, argv))
-                                       fw.invflags |= EBT_ISOURCE;
+                                       cs.fw.invflags |= EBT_ISOURCE;
 
-                               if (ebt_get_mac_and_mask(optarg, fw.sourcemac, fw.sourcemsk))
+                               if (ebt_get_mac_and_mask(optarg, cs.fw.sourcemac, cs.fw.sourcemsk))
                                        xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg);
-                               fw.bitmask |= EBT_SOURCEMAC;
+                               cs.fw.bitmask |= EBT_SOURCEMAC;
                                break;
                        } else if (c == 'd') {
                                ebt_check_option2(&flags, OPT_DEST);
                                if (ebt_check_inverse2(optarg, argc, argv))
-                                       fw.invflags |= EBT_IDEST;
+                                       cs.fw.invflags |= EBT_IDEST;
 
-                               if (ebt_get_mac_and_mask(optarg, fw.destmac, fw.destmsk))
+                               if (ebt_get_mac_and_mask(optarg, cs.fw.destmac, cs.fw.destmsk))
                                        xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg);
-                               fw.bitmask |= EBT_DESTMAC;
+                               cs.fw.bitmask |= EBT_DESTMAC;
                                break;
                        } else if (c == 'c') {
                                ebt_check_option2(&flags, OPT_COUNT);
@@ -880,12 +882,12 @@ big_iface_length:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Option -c needs 2 arguments");
 
-                               fw.counters.pcnt = strtoull(optarg, &buffer, 10);
+                               cs.counters.pcnt = strtoull(optarg, &buffer, 10);
                                if (*buffer != '\0')
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Packet counter '%s' invalid",
                                                      optarg);
-                               fw.counters.bcnt = strtoull(argv[optind], &buffer, 10);
+                               cs.counters.bcnt = strtoull(argv[optind], &buffer, 10);
                                if (*buffer != '\0')
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Packet counter '%s' invalid",
@@ -895,9 +897,9 @@ big_iface_length:
                        }
                        ebt_check_option2(&flags, OPT_PROTOCOL);
                        if (ebt_check_inverse2(optarg, argc, argv))
-                               fw.invflags |= EBT_IPROTO;
+                               cs.fw.invflags |= EBT_IPROTO;
 
-                       fw.bitmask &= ~((unsigned int)EBT_NOPROTO);
+                       cs.fw.bitmask &= ~((unsigned int)EBT_NOPROTO);
                        i = strtol(optarg, &buffer, 16);
                        if (*buffer == '\0' && (i < 0 || i > 0xFFFF))
                                xtables_error(PARAMETER_PROBLEM,
@@ -906,18 +908,18 @@ big_iface_length:
                                struct ethertypeent *ent;
 
                                if (!strcasecmp(optarg, "LENGTH")) {
-                                       fw.bitmask |= EBT_802_3;
+                                       cs.fw.bitmask |= EBT_802_3;
                                        break;
                                }
                                ent = getethertypebyname(optarg);
                                if (!ent)
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "Problem with the specified Ethernet protocol '%s', perhaps "_PATH_ETHERTYPES " is missing", optarg);
-                               fw.ethproto = ent->e_ethertype;
+                               cs.fw.ethproto = ent->e_ethertype;
                        } else
-                               fw.ethproto = i;
+                               cs.fw.ethproto = i;
 
-                       if (fw.ethproto < 0x0600)
+                       if (cs.fw.ethproto < 0x0600)
                                xtables_error(PARAMETER_PROBLEM,
                                              "Sorry, protocols have values above or equal to 0x0600");
                        break;
@@ -1103,7 +1105,7 @@ check_extension: */
                ebt_print_error2("Bad table name");*/
 
        if (command == 'h' && !(flags & OPT_ZERO)) {
-               print_help(fw.target, fw.matches, *table);
+               print_help(cs.target, cs.matches, *table);
                if (exec_style == EXEC_STYLE_PRG)
                        exit(0);
        }
@@ -1142,7 +1144,7 @@ check_extension: */
        }*/
        /* So, the extensions can work with the host endian.
         * The kernel does not have to do this of course */
-       fw.ethproto = htons(fw.ethproto);
+       cs.fw.ethproto = htons(cs.fw.ethproto);
 
        if (command == 'P') {
                if (selected_chain < NF_BR_NUMHOOKS && strcmp(policy, "RETURN")==0)
@@ -1166,13 +1168,13 @@ check_extension: */
        } else if (command == 'F') {
                ret = nft_rule_flush(h, chain, *table);
        } else if (command == 'A') {
-               ret = append_entry(h, chain, *table, &fw, 0,
+               ret = append_entry(h, chain, *table, &cs, 0,
                                   flags&OPT_VERBOSE, true);
        } else if (command == 'I') {
-               ret = append_entry(h, chain, *table, &fw, rule_nr - 1,
+               ret = append_entry(h, chain, *table, &cs, rule_nr - 1,
                                   flags&OPT_VERBOSE, false);
        } else if (command == 'D') {
-               ret = delete_entry(h, chain, *table, &fw, rule_nr - 1,
+               ret = delete_entry(h, chain, *table, &cs, rule_nr - 1,
                                   rule_nr_end, flags&OPT_VERBOSE);
        } /*else if (replace->command == 'C') {
                ebt_change_counters(replace, new_entry, rule_nr, rule_nr_end, &(new_entry->cnt_surplus), chcounter);
diff --git a/iptables/xtables-ebtables.h b/iptables/xtables-ebtables.h
deleted file mode 100644 (file)
index 1e479b1..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef _XTABLES_EBTABLES_H_
-#define _XTABLES_EBTABLES_H_
-
-#include <netinet/in.h>
-#include <linux/netfilter_bridge/ebtables.h>
-#include <linux/netfilter/x_tables.h>
-
-/* We use replace->flags, so we can't use the following values:
- * 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO */
-#define LIST_N    0x04
-#define LIST_C    0x08
-#define LIST_X    0x10
-#define LIST_MAC2 0x20
-
-/* Be backwards compatible, so don't use '+' in kernel */
-#define IF_WILDCARD 1
-
-extern unsigned char eb_mac_type_unicast[ETH_ALEN];
-extern unsigned char eb_msk_type_unicast[ETH_ALEN];
-extern unsigned char eb_mac_type_multicast[ETH_ALEN];
-extern unsigned char eb_msk_type_multicast[ETH_ALEN];
-extern unsigned char eb_mac_type_broadcast[ETH_ALEN];
-extern unsigned char eb_msk_type_broadcast[ETH_ALEN];
-extern unsigned char eb_mac_type_bridge_group[ETH_ALEN];
-extern unsigned char eb_msk_type_bridge_group[ETH_ALEN];
-
-int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask);
-
-struct xtables_ebt_entry {
-       unsigned int bitmask;
-       unsigned int invflags;
-       unsigned int flags;
-       uint16_t ethproto;
-       char in[IFNAMSIZ];
-       char logical_in[IFNAMSIZ];
-       unsigned char in_mask[IFNAMSIZ];
-       char out[IFNAMSIZ];
-       char logical_out[IFNAMSIZ];
-       unsigned char out_mask[IFNAMSIZ];
-       unsigned char sourcemac[ETH_ALEN];
-       unsigned char sourcemsk[ETH_ALEN];
-       unsigned char destmac[ETH_ALEN];
-       unsigned char destmsk[ETH_ALEN];
-       struct xtables_rule_match *matches;
-       struct xtables_target *target;
-       struct xt_counters counters;
-       const char *jumpto;
-};
-#endif