@@ -273,6 +273,9 @@ struct xtables_match {
/* ip is struct ipt_ip * for example */
void (*save)(const void *ip, const struct xt_entry_match *match);
+ /* Fixes the match info after init. */
+ void (*tc_init_fixup)(struct xt_entry_match *match);
+
/* Print match name or alias */
const char *(*alias)(const struct xt_entry_match *match);
@@ -925,6 +925,39 @@ delete_chain6(const xt_chainlabel chain, int verbose,
return ip6tc_delete_chain(chain, handle);
}
+
+static int
+tc_init_fixup_match(struct xt_entry_match *m)
+{
+ const struct xtables_match *match =
+ xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL);
+
+ if (match) {
+ if (match->tc_init_fixup && m->u.user.revision == match->revision)
+ match->tc_init_fixup(m);
+ }
+
+ /* Don't stop iterating. */
+ return 0;
+}
+
+static void
+tc_init_fixup(struct xtc_handle *handle)
+{
+ const char *chain;
+
+ for (chain = ip6tc_first_chain(handle);
+ chain;
+ chain = ip6tc_next_chain(handle)) {
+ const struct ip6t_entry *entry = ip6tc_first_rule(chain, handle);
+
+ while (entry) {
+ IP6T_MATCH_ITERATE(entry, tc_init_fixup_match);
+ entry = ip6tc_next_rule(entry, handle);
+ }
+ }
+}
+
static int
list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
int expanded, int linenumbers, struct xtc_handle *handle)
@@ -1795,6 +1828,8 @@ int do_command6(int argc, char *argv[], char **table,
"can't initialize ip6tables table `%s': %s",
*table, ip6tc_strerror(errno));
+ tc_init_fixup(*handle);
+
if (command == CMD_APPEND
|| command == CMD_DELETE
|| command == CMD_CHECK
@@ -909,6 +909,38 @@ delete_chain4(const xt_chainlabel chain, int verbose,
return iptc_delete_chain(chain, handle);
}
+static int
+tc_init_fixup_match(struct xt_entry_match *m)
+{
+ const struct xtables_match *match =
+ xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL);
+
+ if (match) {
+ if (match->tc_init_fixup && m->u.user.revision == match->revision)
+ match->tc_init_fixup(m);
+ }
+
+ /* Don't stop iterating. */
+ return 0;
+}
+
+static void
+tc_init_fixup(struct xtc_handle *handle)
+{
+ const char *chain;
+
+ for (chain = iptc_first_chain(handle);
+ chain;
+ chain = iptc_next_chain(handle)) {
+ const struct ipt_entry *entry = iptc_first_rule(chain, handle);
+
+ while (entry) {
+ IPT_MATCH_ITERATE(entry, tc_init_fixup_match);
+ entry = iptc_next_rule(entry, handle);
+ }
+ }
+}
+
static int
list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
int expanded, int linenumbers, struct xtc_handle *handle)
@@ -1781,6 +1813,8 @@ int do_command4(int argc, char *argv[], char **table,
"can't initialize iptables table `%s': %s",
*table, iptc_strerror(errno));
+ tc_init_fixup(*handle);
+
if (command == CMD_APPEND
|| command == CMD_DELETE
|| command == CMD_CHECK