]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
ebtables-compat: finish target infrastructure
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Tue, 3 Feb 2015 16:58:17 +0000 (17:58 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 3 Feb 2015 17:00:59 +0000 (18:00 +0100)
Signed-off-by: Arturo Borrero <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft-bridge.h
iptables/xtables-eb.c

index 8357543288ad2a74947854f3af6949a006ea5f33..cd63c11a17e5c364518828668e1dc3ab52ea303d 100644 (file)
@@ -4,7 +4,9 @@
 #include <netinet/in.h>
 //#include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/nf_tables.h>
 #include <net/ethernet.h>
+#include <libiptc/libxtc.h>
 
 /* We use replace->flags, so we can't use the following values:
  * 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO */
@@ -62,6 +64,12 @@ int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mas
 #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
    | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
 
+/* 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
+
 /* Fake ebt_entry */
 struct ebt_entry {
        /* this needs to be the first field */
@@ -102,4 +110,49 @@ struct ebtables_command_state {
 void nft_rule_to_ebtables_command_state(struct nft_rule *r,
                                        struct ebtables_command_state *cs);
 
+static const char *ebt_standard_targets[NUM_STANDARD_TARGETS] = {
+       "ACCEPT",
+       "DROP",
+       "CONTINUE",
+       "RETURN",
+};
+
+static inline const char *nft_ebt_standard_target(unsigned int num)
+{
+       if (num > NUM_STANDARD_TARGETS)
+               return NULL;
+
+       return ebt_standard_targets[num];
+}
+
+static inline int ebt_fill_target(const char *str, unsigned int *verdict)
+{
+       int i, ret = 0;
+
+       for (i = 0; i < NUM_STANDARD_TARGETS; i++) {
+               if (!strcmp(str, nft_ebt_standard_target(i))) {
+                       *verdict = -i - 1;
+                       break;
+               }
+       }
+
+       if (i == NUM_STANDARD_TARGETS)
+               ret = 1;
+
+       return ret;
+}
+
+static inline const char *ebt_target_name(unsigned int verdict)
+{
+       return nft_ebt_standard_target(-verdict - 1);
+}
+
+#define EBT_CHECK_OPTION(flags, mask) ({                       \
+       if (*flags & mask)                                      \
+               xtables_error(PARAMETER_PROBLEM,                \
+                             "Multiple use of same "           \
+                             "option not allowed");            \
+       *flags |= mask;                                         \
+})                                                             \
+
 #endif
index c30a2e53f7ed90730ecac850fc46d37707aadbe1..db1717c9da6adc414dce6b77ce155599830e682c 100644 (file)
@@ -21,6 +21,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include <ctype.h>
 #include <errno.h>
 #include <getopt.h>
 #include <string.h>
@@ -36,6 +37,7 @@
 #include <linux/netfilter_bridge.h>
 #include <linux/netfilter/nf_tables.h>
 #include <ebtables/ethernetdb.h>
+#include <libiptc/libxtc.h>
 #include "xshared.h"
 #include "nft.h"
 #include "nft-bridge.h"
@@ -46,6 +48,8 @@
 #define EXEC_STYLE_PRG    0
 #define EXEC_STYLE_DAEMON 1
 
+#define ebt_check_option2(flags, mask) EBT_CHECK_OPTION(flags, mask)
+
 /*
  * From useful_functions.c
  */
@@ -105,19 +109,6 @@ int ebt_get_mac_and_mask(const char *from, unsigned char *to,
        return 0;
 }
 
-/* This is a replacement for the ebt_check_option2() macro.
- *
- * Make sure the same option wasn't specified twice. This is used in the parse
- * functions of the extensions and ebtables.c.
- */
-static void ebt_check_option2(unsigned int *flags, unsigned int mask)
-{
-       if (*flags & mask)
-               xtables_error(PARAMETER_PROBLEM,
-                             "Multiple use of same option not allowed");
-       *flags |= mask;
-}
-
 static int ebt_check_inverse2(const char option[], int argc, char **argv)
 {
        if (!option)
@@ -302,8 +293,6 @@ static struct option ebt_original_options[] =
 
 void xtables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
 
-static struct option *ebt_options = ebt_original_options;
-
 struct xtables_globals ebtables_globals = {
        .option_offset          = 0,
        .program_version        = IPTABLES_VERSION,
@@ -320,15 +309,6 @@ struct xtables_globals ebtables_globals = {
  * From libebtc.c
  */
 
-/* The four target names, from libebtc.c */
-const char* ebt_standard_targets[NUM_STANDARD_TARGETS] =
-{
-       "ACCEPT",
-       "DROP",
-       "CONTINUE",
-       "RETURN",
-};
-
 /* Prints all registered extensions */
 static void ebt_list_extensions(const struct xtables_target *t,
                                const struct xtables_rule_match *m)
@@ -363,7 +343,7 @@ static struct option *merge_options(struct option *oldopts,
        struct option *merge;
 
        if (!newopts || !oldopts || !options_offset)
-               xtables_error(OTHER_PROBLEM, "merge wrong");
+               return oldopts;
        for (num_old = 0; oldopts[num_old].name; num_old++);
        for (num_new = 0; newopts[num_new].name; num_new++);
 
@@ -412,14 +392,9 @@ static struct xtables_target *command_jump(struct ebtables_command_state *cs,
 
        xs_init_target(target);
 
-       if (target->x6_options != NULL)
-               ebt_options = xtables_options_xfrm(ebtables_globals.orig_opts,
-                                           ebt_options, target->x6_options,
-                                           &target->option_offset);
-       else
-               ebt_options = xtables_merge_options(ebtables_globals.orig_opts,
-                                            ebt_options, target->extra_opts,
-                                            &target->option_offset);
+       opts = merge_options(opts, target->extra_opts, &target->option_offset);
+       if (opts == NULL)
+               xtables_error(OTHER_PROBLEM, "Can't alloc memory");
 
        return target;
 }
@@ -799,7 +774,7 @@ handle_P:
                                        xtables_error(PARAMETER_PROBLEM,
                                                      "No policy specified");
                                for (i = 0; i < NUM_STANDARD_TARGETS; i++)
-                                       if (!strcmp(argv[optind], ebt_standard_targets[i])) {
+                                       if (!strcmp(argv[optind], nft_ebt_standard_target(i))) {
                                                policy = argv[optind];
                                                if (-i-1 == EBT_CONTINUE)
                                                        xtables_error(PARAMETER_PROBLEM,
@@ -1177,12 +1152,14 @@ big_iface_length:
                        continue;
                default:
                        /* Is it a target option? */
-                       /*t = (struct ebt_u_target *)new_entry->t;
-                       if ((t->parse(c - t->option_offset, argv, argc, new_entry, &t->flags, &t->t))) {
-                               if (ebt_errormsg[0] != '\0')
-                                       return -1;
-                               goto check_extension;
-                       }*/
+                       if (cs.target != NULL && cs.target->parse != NULL) {
+                               int opt_offset = cs.target->option_offset;
+                               if (cs.target->parse(c - opt_offset,
+                                                    argv, ebt_invert,
+                                                    &cs.target->tflags,
+                                                    NULL, &cs.target->t))
+                                       goto check_extension;
+                       }
 
                        /* Is it a match_option? */
                        for (m = xtables_matches; m; m = m->next) {