]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: add new nft_ops->post_parse hook
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 12 May 2013 14:47:11 +0000 (16:47 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 30 Dec 2013 22:50:29 +0000 (23:50 +0100)
Move specific layer 3 protocol post argument parsing code
to the respective nft-ipv[4|6].c files.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
iptables/nft-ipv4.c
iptables/nft-ipv6.c
iptables/nft-shared.h
iptables/xtables.c

index 0a601243ce80f753d0a73f5fb8d91b78f2d702ce..51ee422c7d58641edcf992483662c24daec81121 100644 (file)
@@ -298,12 +298,59 @@ static uint8_t nft_ipv4_print_firewall(const struct iptables_command_state *cs,
        return cs->fw.ip.flags;
 }
 
+static void nft_ipv4_post_parse(int command,
+                               struct iptables_command_state *cs,
+                               struct xtables_args *args)
+{
+       cs->fw.ip.proto = args->proto;
+       cs->fw.ip.invflags = args->invflags;
+       cs->fw.ip.flags = args->flags;
+
+       strncpy(cs->fw.ip.iniface, args->iniface, IFNAMSIZ);
+       memcpy(cs->fw.ip.iniface_mask,
+              args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+       strncpy(cs->fw.ip.outiface, args->outiface, IFNAMSIZ);
+       memcpy(cs->fw.ip.outiface_mask,
+              args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+       if (args->goto_set)
+               cs->fw.ip.flags |= IPT_F_GOTO;
+
+       cs->counters.pcnt = args->pcnt_cnt;
+       cs->counters.bcnt = args->bcnt_cnt;
+
+       if (command & (CMD_REPLACE | CMD_INSERT |
+                       CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
+               if (!(cs->options & OPT_DESTINATION))
+                       args->dhostnetworkmask = "0.0.0.0/0";
+               if (!(cs->options & OPT_SOURCE))
+                       args->shostnetworkmask = "0.0.0.0/0";
+       }
+
+       if (args->shostnetworkmask)
+               xtables_ipparse_multiple(args->shostnetworkmask,
+                                        &args->s.addr.v4, &args->s.mask.v4,
+                                        &args->s.naddrs);
+       if (args->dhostnetworkmask)
+               xtables_ipparse_multiple(args->dhostnetworkmask,
+                                        &args->d.addr.v4, &args->d.mask.v4,
+                                        &args->d.naddrs);
+
+       if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
+           (cs->fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
+               xtables_error(PARAMETER_PROBLEM,
+                             "! not allowed with multiple"
+                             " source or destination IP addresses");
+}
+
 struct nft_family_ops nft_family_ops_ipv4 = {
        .add                    = nft_ipv4_add,
        .is_same                = nft_ipv4_is_same,
        .print_payload          = nft_ipv4_print_payload,
        .parse_meta             = nft_ipv4_parse_meta,
        .parse_payload          = nft_ipv4_parse_payload,
-       .parse_immediate        = nft_ipv4_parse_immediate,
-       .print_firewall         = nft_ipv4_print_firewall,
+       .parse_immediate        = nft_ipv4_parse_immediate,
+       .print_firewall         = nft_ipv4_print_firewall,
+       .post_parse             = nft_ipv4_post_parse,
 };
index 65a894900541f355269195946020e3e97615effe..61c660a521f4f1812b6e6ee14d7bc71c2f8753db 100644 (file)
@@ -208,6 +208,72 @@ static uint8_t nft_ipv6_print_firewall(const struct iptables_command_state *cs,
        return cs->fw6.ipv6.flags;
 }
 
+/* These are invalid numbers as upper layer protocol */
+static int is_exthdr(uint16_t proto)
+{
+       return (proto == IPPROTO_ROUTING ||
+               proto == IPPROTO_FRAGMENT ||
+               proto == IPPROTO_AH ||
+               proto == IPPROTO_DSTOPTS);
+}
+
+static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs,
+                               struct xtables_args *args)
+{
+       if (args->proto != 0)
+               args->flags |= IP6T_F_PROTO;
+
+       cs->fw6.ipv6.proto = args->proto;
+       cs->fw6.ipv6.invflags = args->invflags;
+       cs->fw6.ipv6.flags = args->flags;
+
+       if (is_exthdr(cs->fw6.ipv6.proto)
+           && (cs->fw6.ipv6.invflags & XT_INV_PROTO) == 0)
+               fprintf(stderr,
+                       "Warning: never matched protocol: %s. "
+                       "use extension match instead.\n",
+                       cs->protocol);
+
+       strncpy(cs->fw6.ipv6.iniface, args->iniface, IFNAMSIZ);
+       memcpy(cs->fw6.ipv6.iniface_mask,
+              args->iniface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+       strncpy(cs->fw6.ipv6.outiface, args->outiface, IFNAMSIZ);
+       memcpy(cs->fw6.ipv6.outiface_mask,
+              args->outiface_mask, IFNAMSIZ*sizeof(unsigned char));
+
+       if (args->goto_set)
+               cs->fw6.ipv6.flags |= IP6T_F_GOTO;
+
+       cs->fw6.counters.pcnt = args->pcnt_cnt;
+       cs->fw6.counters.bcnt = args->bcnt_cnt;
+
+       if (command & (CMD_REPLACE | CMD_INSERT |
+                       CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
+               if (!(cs->options & OPT_DESTINATION))
+                       args->dhostnetworkmask = "::0/0";
+               if (!(cs->options & OPT_SOURCE))
+                       args->shostnetworkmask = "::0/0";
+       }
+
+       if (args->shostnetworkmask)
+               xtables_ip6parse_multiple(args->shostnetworkmask,
+                                         &args->s.addr.v6,
+                                         &args->s.mask.v6,
+                                         &args->s.naddrs);
+       if (args->dhostnetworkmask)
+               xtables_ip6parse_multiple(args->dhostnetworkmask,
+                                         &args->d.addr.v6,
+                                         &args->d.mask.v6,
+                                         &args->d.naddrs);
+
+       if ((args->s.naddrs > 1 || args->d.naddrs > 1) &&
+           (cs->fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
+               xtables_error(PARAMETER_PROBLEM,
+                             "! not allowed with multiple"
+                             " source or destination IP addresses");
+}
+
 struct nft_family_ops nft_family_ops_ipv6 = {
        .add                    = nft_ipv6_add,
        .is_same                = nft_ipv6_is_same,
@@ -216,4 +282,5 @@ struct nft_family_ops nft_family_ops_ipv6 = {
        .parse_payload          = nft_ipv6_parse_payload,
        .parse_immediate        = nft_ipv6_parse_immediate,
        .print_firewall         = nft_ipv6_print_firewall,
+       .post_parse             = nft_ipv6_post_parse,
 };
index 30e87bb385ee2099d43f021949f3cfbe973f1ebf..59734d9de4fd591dcf9119c7b7b8b677254cc5be 100644 (file)
@@ -34,6 +34,8 @@
                        | FMT_NUMERIC | FMT_NOTABLE)
 #define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab))
 
+struct xtables_args;
+
 struct nft_family_ops {
        int (*add)(struct nft_rule *r, struct iptables_command_state *cs);
        bool (*is_same)(const struct iptables_command_state *a,
@@ -49,6 +51,8 @@ struct nft_family_ops {
        uint8_t (*print_firewall)(const struct iptables_command_state *cs,
                                  const char *targname, unsigned int num,
                                  unsigned int format);
+       void (*post_parse)(int command, struct iptables_command_state *cs,
+                          struct xtables_args *args);
 };
 
 void add_meta(struct nft_rule *r, uint32_t key);
@@ -116,4 +120,21 @@ struct xtables_args {
        unsigned long long pcnt_cnt, bcnt_cnt;
 };
 
+#define CMD_NONE               0x0000U
+#define CMD_INSERT             0x0001U
+#define CMD_DELETE             0x0002U
+#define CMD_DELETE_NUM         0x0004U
+#define CMD_REPLACE            0x0008U
+#define CMD_APPEND             0x0010U
+#define CMD_LIST               0x0020U
+#define CMD_FLUSH              0x0040U
+#define CMD_ZERO               0x0080U
+#define CMD_NEW_CHAIN          0x0100U
+#define CMD_DELETE_CHAIN       0x0200U
+#define CMD_SET_POLICY         0x0400U
+#define CMD_RENAME_CHAIN       0x0800U
+#define CMD_LIST_RULES         0x1000U
+#define CMD_ZERO_NUM           0x2000U
+#define CMD_CHECK              0x4000U
+
 #endif
index 6a1a16467eeca8bf4fe958974e5bc8a389f83f6d..e3a6c8022401f43c0f05caa7b8cca360c8ff5828 100644 (file)
 #define FALSE 0
 #endif
 
-#define CMD_NONE               0x0000U
-#define CMD_INSERT             0x0001U
-#define CMD_DELETE             0x0002U
-#define CMD_DELETE_NUM         0x0004U
-#define CMD_REPLACE            0x0008U
-#define CMD_APPEND             0x0010U
-#define CMD_LIST               0x0020U
-#define CMD_FLUSH              0x0040U
-#define CMD_ZERO               0x0080U
-#define CMD_NEW_CHAIN          0x0100U
-#define CMD_DELETE_CHAIN       0x0200U
-#define CMD_SET_POLICY         0x0400U
-#define CMD_RENAME_CHAIN       0x0800U
-#define CMD_LIST_RULES         0x1000U
-#define CMD_ZERO_NUM           0x2000U
-#define CMD_CHECK              0x4000U
 #define NUMBER_OF_CMD  16
 static const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
                                 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
@@ -376,15 +360,6 @@ add_command(unsigned int *cmd, const int newcmd, const int othercmds,
  *     return global static data.
 */
 
-/* These are invalid numbers as upper layer protocol */
-static int is_exthdr(uint16_t proto)
-{
-       return (proto == IPPROTO_ROUTING ||
-               proto == IPPROTO_FRAGMENT ||
-               proto == IPPROTO_AH ||
-               proto == IPPROTO_DSTOPTS);
-}
-
 /* Christophe Burki wants `-p 6' to imply `-m tcp'.  */
 /* Can't be zero. */
 static int
@@ -1141,110 +1116,6 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table)
                xtables_error(PARAMETER_PROBLEM,
                           "nothing appropriate following !");
 
-       switch (args.family) {
-       case AF_INET:
-               cs.fw.ip.proto = args.proto;
-               cs.fw.ip.invflags = args.invflags;
-               cs.fw.ip.flags = args.flags;
-
-               strncpy(cs.fw.ip.iniface, args.iniface, IFNAMSIZ);
-               memcpy(cs.fw.ip.iniface_mask,
-                      args.iniface_mask, IFNAMSIZ*sizeof(unsigned char));
-
-               strncpy(cs.fw.ip.outiface, args.outiface, IFNAMSIZ);
-               memcpy(cs.fw.ip.outiface_mask,
-                      args.outiface_mask, IFNAMSIZ*sizeof(unsigned char));
-
-               if (args.goto_set)
-                       cs.fw.ip.flags |= IPT_F_GOTO;
-
-               cs.counters.pcnt = args.pcnt_cnt;
-               cs.counters.bcnt = args.bcnt_cnt;
-
-               if (command & (CMD_REPLACE | CMD_INSERT |
-                               CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
-                       if (!(cs.options & OPT_DESTINATION))
-                               args.dhostnetworkmask = "0.0.0.0/0";
-                       if (!(cs.options & OPT_SOURCE))
-                               args.shostnetworkmask = "0.0.0.0/0";
-               }
-
-               if (args.shostnetworkmask)
-                       xtables_ipparse_multiple(args.shostnetworkmask,
-                                                &args.s.addr.v4,
-                                                &args.s.mask.v4,
-                                                &args.s.naddrs);
-               if (args.dhostnetworkmask)
-                       xtables_ipparse_multiple(args.dhostnetworkmask,
-                                                &args.d.addr.v4,
-                                                &args.d.mask.v4,
-                                                &args.d.naddrs);
-
-               if ((args.s.naddrs > 1 || args.d.naddrs > 1) &&
-                   (cs.fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP)))
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "! not allowed with multiple"
-                                     " source or destination IP addresses");
-               break;
-       case AF_INET6:
-               if (args.proto != 0)
-                       args.flags |= IP6T_F_PROTO;
-
-               cs.fw6.ipv6.proto = args.proto;
-               cs.fw6.ipv6.invflags = args.invflags;
-               cs.fw6.ipv6.flags = args.flags;
-
-               if (is_exthdr(cs.fw6.ipv6.proto)
-                   && (cs.fw6.ipv6.invflags & XT_INV_PROTO) == 0)
-                       fprintf(stderr,
-                               "Warning: never matched protocol: %s. "
-                               "use extension match instead.\n",
-                               cs.protocol);
-
-               strncpy(cs.fw6.ipv6.iniface, args.iniface, IFNAMSIZ);
-               memcpy(cs.fw6.ipv6.iniface_mask,
-                      args.iniface_mask, IFNAMSIZ*sizeof(unsigned char));
-
-               strncpy(cs.fw6.ipv6.outiface, args.outiface, IFNAMSIZ);
-               memcpy(cs.fw6.ipv6.outiface_mask,
-                      args.outiface_mask, IFNAMSIZ*sizeof(unsigned char));
-
-               if (args.goto_set)
-                       cs.fw6.ipv6.flags |= IP6T_F_GOTO;
-
-               cs.fw6.counters.pcnt = args.pcnt_cnt;
-               cs.fw6.counters.bcnt = args.bcnt_cnt;
-
-               if (command & (CMD_REPLACE | CMD_INSERT |
-                               CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
-                       if (!(cs.options & OPT_DESTINATION))
-                               args.dhostnetworkmask = "::0/0";
-                       if (!(cs.options & OPT_SOURCE))
-                               args.shostnetworkmask = "::0/0";
-               }
-
-               if (args.shostnetworkmask)
-                       xtables_ip6parse_multiple(args.shostnetworkmask,
-                                                 &args.s.addr.v6,
-                                                 &args.s.mask.v6,
-                                                 &args.s.naddrs);
-               if (args.dhostnetworkmask)
-                       xtables_ip6parse_multiple(args.dhostnetworkmask,
-                                                 &args.d.addr.v6,
-                                                 &args.d.mask.v6,
-                                                 &args.d.naddrs);
-
-               if ((args.s.naddrs > 1 || args.d.naddrs > 1) &&
-                   (cs.fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "! not allowed with multiple"
-                                     " source or destination IP addresses");
-               break;
-       default:
-               exit_tryhelp(2);
-               break;
-       }
-
        /* Set only if required, needed by xtables-restore */
        if (h->family == AF_UNSPEC)
                h->family = args.family;
@@ -1253,6 +1124,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table)
        if (h->ops == NULL)
                xtables_error(PARAMETER_PROBLEM, "Unknown family");
 
+       h->ops->post_parse(command, &cs, &args);
+
        if (command == CMD_REPLACE &&
            (args.s.naddrs != 1 || args.d.naddrs != 1))
                xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "