}
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;
}
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;
#include <netdb.h>
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <xtables.h>
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)
{
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);
+}
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 */