]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
src: deduplicate and simplify implicit protocol extension loading
authorJan Engelhardt <jengelh@medozas.de>
Mon, 7 Feb 2011 02:18:53 +0000 (03:18 +0100)
committerJan Engelhardt <jengelh@medozas.de>
Mon, 7 Feb 2011 02:23:55 +0000 (03:23 +0100)
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
ip6tables.c
iptables.c
xshared.c
xshared.h

index 7f8a8df64a79e2995f6ac59e821f22619c585eb2..3330420f5a365f9c2d1e7f8e1384e14a665d9208 100644 (file)
@@ -1268,39 +1268,7 @@ static void command_default(struct iptables_command_state *cs)
                }
                m = matchp ? matchp->match : NULL;
 
-               /* If you listen carefully, you can
-                  actually hear this code suck. */
-
-               /* some explanations (after four different bugs
-                * in 3 different releases): If we encounter a
-                * parameter, that has not been parsed yet,
-                * it's not an option of an explicitly loaded
-                * match or a target.  However, we support
-                * implicit loading of the protocol match
-                * extension.  '-p tcp' means 'l4 proto 6' and
-                * at the same time 'load tcp protocol match on
-                * demand if we specify --dport'.
-                *
-                * To make this work, we need to make sure:
-                * - the parameter has not been parsed by
-                *   a match (m above)
-                * - a protocol has been specified
-                * - the protocol extension has not been
-                *   loaded yet, or is loaded and unused
-                *   [think of ip6tables-restore!]
-                * - the protocol extension can be successively
-                *   loaded
-                */
-               if (m == NULL
-                   && cs->protocol
-                   && (!find_proto(cs->protocol, XTF_DONT_LOAD,
-                                  cs->options&OPT_NUMERIC, NULL)
-                       || (find_proto(cs->protocol, XTF_DONT_LOAD,
-                                       cs->options&OPT_NUMERIC, NULL)
-                           && (cs->proto_used == 0))
-                      )
-                   && (m = find_proto(cs->protocol, XTF_TRY_LOAD,
-                                      cs->options&OPT_NUMERIC, &cs->matches))) {
+               if (m == NULL && (m = load_proto(cs)) != NULL) {
                        /* Try loading protocol */
                        size_t size;
 
index 0de656e9d9b3cca971bbde41276e235ddf6b3f6a..bae14afcc4fa75b36ace3d643af65c28c0f234d1 100644 (file)
@@ -1292,39 +1292,7 @@ static void command_default(struct iptables_command_state *cs)
                }
                m = matchp ? matchp->match : NULL;
 
-               /* If you listen carefully, you can
-                  actually hear this code suck. */
-
-               /* some explanations (after four different bugs
-                * in 3 different releases): If we encounter a
-                * parameter, that has not been parsed yet,
-                * it's not an option of an explicitly loaded
-                * match or a target.  However, we support
-                * implicit loading of the protocol match
-                * extension.  '-p tcp' means 'l4 proto 6' and
-                * at the same time 'load tcp protocol match on
-                * demand if we specify --dport'.
-                *
-                * To make this work, we need to make sure:
-                * - the parameter has not been parsed by
-                *   a match (m above)
-                * - a protocol has been specified
-                * - the protocol extension has not been
-                *   loaded yet, or is loaded and unused
-                *   [think of iptables-restore!]
-                * - the protocol extension can be successively
-                *   loaded
-                */
-               if (m == NULL
-                   && cs->protocol
-                   && (!find_proto(cs->protocol, XTF_DONT_LOAD,
-                                  cs->options&OPT_NUMERIC, NULL)
-                       || (find_proto(cs->protocol, XTF_DONT_LOAD,
-                                       cs->options&OPT_NUMERIC, NULL)
-                           && (cs->proto_used == 0))
-                      )
-                   && (m = find_proto(cs->protocol, XTF_TRY_LOAD,
-                                      cs->options&OPT_NUMERIC, &cs->matches))) {
+               if (m == NULL && (m = load_proto(cs)) != NULL) {
                        /* Try loading protocol */
                        size_t size;
 
index 40b6b560e687f564f368e1155f2cc838242ba458..b47beb1e3a52291eeaf440eb53d97215034eb2cb 100644 (file)
--- a/xshared.c
+++ b/xshared.c
@@ -1,4 +1,5 @@
 #include <netdb.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <xtables.h>
@@ -50,7 +51,7 @@ proto_to_name(uint8_t proto, int nolookup)
        return NULL;
 }
 
-struct xtables_match *
+static struct xtables_match *
 find_proto(const char *pname, enum xtables_tryload tryload,
           int nolookup, struct xtables_rule_match **matches)
 {
@@ -66,3 +67,35 @@ find_proto(const char *pname, enum xtables_tryload tryload,
 
        return NULL;
 }
+
+/*
+ * Some explanations (after four different bugs in 3 different releases): If
+ * we encounter a parameter, that has not been parsed yet, it's not an option
+ * of an explicitly loaded match or a target. However, we support implicit
+ * loading of the protocol match extension. '-p tcp' means 'l4 proto 6' and at
+ * the same time 'load tcp protocol match on demand if we specify --dport'.
+ *
+ * To make this work, we need to make sure:
+ * - the parameter has not been parsed by a match (m above)
+ * - a protocol has been specified
+ * - the protocol extension has not been loaded yet, or is loaded and unused
+ *   [think of ip6tables-restore!]
+ * - the protocol extension can be successively loaded
+ */
+static bool should_load_proto(struct iptables_command_state *cs)
+{
+       if (cs->protocol == NULL)
+               return false;
+       if (find_proto(cs->protocol, XTF_DONT_LOAD,
+           cs->options & OPT_NUMERIC, NULL) != NULL)
+               return true;
+       return cs->proto_used;
+}
+
+struct xtables_match *load_proto(struct iptables_command_state *cs)
+{
+       if (!should_load_proto(cs))
+               return NULL;
+       return find_proto(cs->protocol, XTF_TRY_LOAD,
+                         cs->options & OPT_NUMERIC, &cs->matches);
+}
index 06d73ab982a0cfdb177a3e921ea2afd5bdda43df..d0cb5162986279b05e5e545bd58c7f997f9299e4 100644 (file)
--- a/xshared.h
+++ b/xshared.h
@@ -45,7 +45,6 @@ enum {
 extern void print_extension_helps(const struct xtables_target *,
        const struct xtables_rule_match *);
 extern const char *proto_to_name(uint8_t, int);
-extern struct xtables_match *find_proto(const char *, enum xtables_tryload,
-       int, struct xtables_rule_match **);
+extern struct xtables_match *load_proto(struct iptables_command_state *);
 
 #endif /* IPTABLES_XSHARED_H */