summaryrefslogtreecommitdiffstats
path: root/ip6tables.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2002-08-26 14:37:35 +0000
committerHarald Welte <laforge@gnumonks.org>2002-08-26 14:37:35 +0000
commit00f5a9caea1b46a946e5b7c8e09df54df55cdcc2 (patch)
treed964da2c940addfb2d7749963b0de6efc4a6af1a /ip6tables.c
parent2a7116ec8070adfe2c17abf822e23c8875da164e (diff)
bring ip6tables up-to-date with recent iptables change (proto match ext)
Diffstat (limited to 'ip6tables.c')
-rw-r--r--ip6tables.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/ip6tables.c b/ip6tables.c
index a26ff8c2..023acbf5 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -1660,6 +1660,7 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle)
const char *jumpto = "";
char *protocol = NULL;
const char *modprobe = NULL;
+ int proto_used = 0;
char icmp6p[] = "icmpv6";
memset(&fw, 0, sizeof(fw));
@@ -2022,6 +2023,60 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle)
&m->m))
break;
}
+
+ /* If you listen carefully, you can
+ actually hear this code suck. */
+
+ /* some explanations (after four different bugs
+ * in 3 different releases): If we encountere 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
+ && protocol
+ && (!find_proto(protocol, DONT_LOAD,
+ options&OPT_NUMERIC)
+ || (find_proto(protocol, DONT_LOAD,
+ options&OPT_NUMERIC)
+ && (proto_used == 0))
+ )
+ && (m = find_proto(protocol, TRY_LOAD,
+ options&OPT_NUMERIC))) {
+ /* Try loading protocol */
+ size_t size;
+
+ proto_used = 1;
+
+ size = IP6T_ALIGN(sizeof(struct ip6t_entry_match))
+ + m->size;
+
+ m->m = fw_calloc(1, size);
+ m->m->u.match_size = size;
+ strcpy(m->m->u.user.name, m->name);
+ m->init(m->m, &fw.nfcache);
+
+ opts = merge_options(opts,
+ m->extra_opts, &m->option_offset);
+
+ optind--;
+ continue;
+ }
+
if (!m)
exit_error(PARAMETER_PROBLEM,
"Unknown arg `%s'",