Use xt_id match to track own rules
authorJo-Philipp Wich <jow@openwrt.org>
Sun, 24 Jan 2016 16:43:30 +0000 (17:43 +0100)
committerJo-Philipp Wich <jow@openwrt.org>
Sun, 24 Jan 2016 16:56:02 +0000 (17:56 +0100)
Instead of relying on the delegate_* chains to isolate own toplevel
rules from user supplied ones, use the xt_id match to attach a magic
value to fw3 rules which allows selective cleanup regardless of the
container chain.

Also add an experimental "fw3 gc" call to garbage collect empty chains.

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
defaults.c
forwards.c
iptables.c
iptables.h
main.c
rules.c
snats.c
zones.c

index 396cbf757356eb236fd5ff905c026890273560b5..ccd320c7d6f11bf85b118ad6557d12610435dd7f 100644 (file)
        { FW3_FAMILY_##f, FW3_TABLE_##tbl, FW3_FLAG_##def, fmt }
 
 static const struct fw3_chain_spec default_chains[] = {
-       C(ANY, FILTER, UNSPEC,        "delegate_input"),
-       C(ANY, FILTER, UNSPEC,        "delegate_output"),
-       C(ANY, FILTER, UNSPEC,        "delegate_forward"),
+       //C(ANY, FILTER, UNSPEC,        "delegate_input"),
+       //C(ANY, FILTER, UNSPEC,        "delegate_output"),
+       //C(ANY, FILTER, UNSPEC,        "delegate_forward"),
        C(ANY, FILTER, UNSPEC,        "reject"),
        C(ANY, FILTER, CUSTOM_CHAINS, "input_rule"),
        C(ANY, FILTER, CUSTOM_CHAINS, "output_rule"),
        C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_rule"),
        C(ANY, FILTER, SYN_FLOOD,     "syn_flood"),
 
-       C(V4,  NAT,    UNSPEC,        "delegate_prerouting"),
-       C(V4,  NAT,    UNSPEC,        "delegate_postrouting"),
+       //C(V4,  NAT,    UNSPEC,        "delegate_prerouting"),
+       //C(V4,  NAT,    UNSPEC,        "delegate_postrouting"),
        C(V4,  NAT,    CUSTOM_CHAINS, "prerouting_rule"),
        C(V4,  NAT,    CUSTOM_CHAINS, "postrouting_rule"),
 
-       C(ANY, MANGLE, UNSPEC,        "mssfix"),
-       C(ANY, MANGLE, UNSPEC,        "fwmark"),
+       //C(ANY, MANGLE, UNSPEC,        "mssfix"),
+       //C(ANY, MANGLE, UNSPEC,        "fwmark"),
 
-       C(ANY, RAW,    UNSPEC,        "delegate_notrack"),
+       //C(ANY, RAW,    UNSPEC,        "delegate_notrack"),
 
        { }
 };
@@ -189,39 +189,39 @@ fw3_print_default_head_rules(struct fw3_ipt_handle *handle,
        struct fw3_device lodev = { .set = true };
        struct fw3_protocol tcp = { .protocol = 6 };
        struct fw3_ipt_rule *r;
-       struct toplevel_rule *tr;
+       //struct toplevel_rule *tr;
 
        const char *chains[] = {
-               "delegate_input", "input",
-               "delegate_output", "output",
-               "delegate_forward", "forwarding",
+               "INPUT", "input",
+               "OUTPUT", "output",
+               "FORWARD", "forwarding",
        };
 
-       struct toplevel_rule rules[] = {
-               { FW3_TABLE_FILTER, "INPUT",       "delegate_input" },
-               { FW3_TABLE_FILTER, "OUTPUT",      "delegate_output" },
-               { FW3_TABLE_FILTER, "FORWARD",     "delegate_forward" },
-
-               { FW3_TABLE_NAT,    "PREROUTING",  "delegate_prerouting" },
-               { FW3_TABLE_NAT,    "POSTROUTING", "delegate_postrouting" },
-
-               { FW3_TABLE_MANGLE, "FORWARD",     "mssfix" },
-               { FW3_TABLE_MANGLE, "PREROUTING",  "fwmark" },
-
-               { FW3_TABLE_RAW,    "PREROUTING",  "delegate_notrack" },
-
-               { 0, NULL },
-       };
-
-       for (tr = rules; tr->chain; tr++)
-       {
-               if (tr->table != handle->table)
-                       continue;
-
-               r = fw3_ipt_rule_new(handle);
-               fw3_ipt_rule_target(r, tr->target);
-               fw3_ipt_rule_replace(r, tr->chain);
-       }
+       //struct toplevel_rule rules[] = {
+       //      { FW3_TABLE_FILTER, "INPUT",       "delegate_input" },
+       //      { FW3_TABLE_FILTER, "OUTPUT",      "delegate_output" },
+       //      { FW3_TABLE_FILTER, "FORWARD",     "delegate_forward" },
+       //
+       //      { FW3_TABLE_NAT,    "PREROUTING",  "delegate_prerouting" },
+       //      { FW3_TABLE_NAT,    "POSTROUTING", "delegate_postrouting" },
+       //
+       //      { FW3_TABLE_MANGLE, "FORWARD",     "mssfix" },
+       //      { FW3_TABLE_MANGLE, "PREROUTING",  "fwmark" },
+       //
+       //      { FW3_TABLE_RAW,    "PREROUTING",  "delegate_notrack" },
+       //
+       //      { 0, NULL },
+       //};
+       //
+       //for (tr = rules; tr->chain; tr++)
+       //{
+       //      if (tr->table != handle->table)
+       //              continue;
+       //
+       //      r = fw3_ipt_rule_new(handle);
+       //      fw3_ipt_rule_target(r, tr->target);
+       //      fw3_ipt_rule_replace(r, tr->chain);
+       //}
 
        switch (handle->table)
        {
@@ -231,11 +231,11 @@ fw3_print_default_head_rules(struct fw3_ipt_handle *handle,
 
                r = fw3_ipt_rule_create(handle, NULL, &lodev, NULL, NULL, NULL);
                fw3_ipt_rule_target(r, "ACCEPT");
-               fw3_ipt_rule_append(r, "delegate_input");
+               fw3_ipt_rule_append(r, "INPUT");
 
                r = fw3_ipt_rule_create(handle, NULL, NULL, &lodev, NULL, NULL);
                fw3_ipt_rule_target(r, "ACCEPT");
-               fw3_ipt_rule_append(r, "delegate_output");
+               fw3_ipt_rule_append(r, "OUTPUT");
 
                if (defs->custom_chains)
                {
@@ -279,7 +279,7 @@ fw3_print_default_head_rules(struct fw3_ipt_handle *handle,
                        r = fw3_ipt_rule_create(handle, &tcp, NULL, NULL, NULL, NULL);
                        fw3_ipt_rule_extra(r, "--syn");
                        fw3_ipt_rule_target(r, "syn_flood");
-                       fw3_ipt_rule_append(r, "delegate_input");
+                       fw3_ipt_rule_append(r, "INPUT");
                }
 
                r = fw3_ipt_rule_create(handle, &tcp, NULL, NULL, NULL, NULL);
@@ -300,12 +300,12 @@ fw3_print_default_head_rules(struct fw3_ipt_handle *handle,
                        r = fw3_ipt_rule_new(handle);
                        fw3_ipt_rule_comment(r, "user chain for prerouting");
                        fw3_ipt_rule_target(r, "prerouting_rule");
-                       fw3_ipt_rule_append(r, "delegate_prerouting");
+                       fw3_ipt_rule_append(r, "PREROUTING");
 
                        r = fw3_ipt_rule_new(handle);
                        fw3_ipt_rule_comment(r, "user chain for postrouting");
                        fw3_ipt_rule_target(r, "postrouting_rule");
-                       fw3_ipt_rule_append(r, "delegate_postrouting");
+                       fw3_ipt_rule_append(r, "POSTROUTING");
                }
                break;
 
@@ -332,7 +332,7 @@ fw3_print_default_tail_rules(struct fw3_ipt_handle *handle,
                        return;
 
                fw3_ipt_rule_target(r, "reject");
-               fw3_ipt_rule_append(r, "delegate_input");
+               fw3_ipt_rule_append(r, "INPUT");
        }
 
        if (defs->policy_output == FW3_FLAG_REJECT)
@@ -343,7 +343,7 @@ fw3_print_default_tail_rules(struct fw3_ipt_handle *handle,
                        return;
 
                fw3_ipt_rule_target(r, "reject");
-               fw3_ipt_rule_append(r, "delegate_output");
+               fw3_ipt_rule_append(r, "OUTPUT");
        }
 
        if (defs->policy_forward == FW3_FLAG_REJECT)
@@ -354,7 +354,7 @@ fw3_print_default_tail_rules(struct fw3_ipt_handle *handle,
                        return;
 
                fw3_ipt_rule_target(r, "reject");
-               fw3_ipt_rule_append(r, "delegate_forward");
+               fw3_ipt_rule_append(r, "FORWARD");
        }
 }
 
@@ -404,6 +404,12 @@ fw3_flush_rules(struct fw3_ipt_handle *handle, struct fw3_state *state,
                fw3_ipt_set_policy(handle, "FORWARD", policy);
        }
 
+       fw3_ipt_delete_id_rules(handle, "INPUT");
+       fw3_ipt_delete_id_rules(handle, "OUTPUT");
+       fw3_ipt_delete_id_rules(handle, "FORWARD");
+       fw3_ipt_delete_id_rules(handle, "PREROUTING");
+       fw3_ipt_delete_id_rules(handle, "POSTROUTING");
+
        for (c = default_chains; c->format; c++)
        {
                /* don't touch user chains on selective stop */
index e27e4ee4c4dabbc9961dd2a4e5261f3e889871d5..24b8e4dc8fd5557c29b241219ff9b2598b1ee949 100644 (file)
@@ -106,7 +106,7 @@ static void
 append_chain(struct fw3_ipt_rule *r, struct fw3_forward *forward)
 {
        if (forward->src.any || !forward->src.set)
-               fw3_ipt_rule_append(r, "delegate_forward");
+               fw3_ipt_rule_append(r, "FORWARD");
        else
                fw3_ipt_rule_append(r, "zone_%s_forward", forward->src.name);
 }
index 0f41fb04fccebabc010ad378420b331ac901b203..a27da142acaa11640ebc5b7111628c1640681d83 100644 (file)
@@ -233,6 +233,96 @@ fw3_ipt_delete_chain(struct fw3_ipt_handle *h, const char *chain)
                iptc_delete_chain(chain, h->handle);
 }
 
+static int
+get_rule_id(const void *base, unsigned int start, unsigned int end)
+{
+       uint32_t id;
+       unsigned int i;
+       const struct xt_entry_match *em;
+
+       for (i = start; i < end; i += em->u.match_size)
+       {
+               em = base + i;
+
+               if (strcmp(em->u.user.name, "id"))
+                       continue;
+
+               memcpy(&id, em->data, sizeof(id));
+
+               if ((id & FW3_ID_MASK) != FW3_ID_MAGIC)
+                       continue;
+
+               return (id & ~FW3_ID_MASK);
+       }
+
+       return -1;
+}
+
+void
+fw3_ipt_delete_id_rules(struct fw3_ipt_handle *h, const char *chain)
+{
+       unsigned int num;
+       const struct ipt_entry *e;
+       bool found;
+       int id;
+
+#ifndef DISABLE_IPV6
+       if (h->family == FW3_FAMILY_V6)
+       {
+               if (!ip6tc_is_chain(chain, h->handle))
+                       return;
+
+               do {
+                       found = false;
+
+                       const struct ip6t_entry *e6;
+                       for (num = 0, e6 = ip6tc_first_rule(chain, h->handle);
+                                e6 != NULL;
+                                num++, e6 = ip6tc_next_rule(e6, h->handle))
+                       {
+                               id = get_rule_id(e6, sizeof(*e6), e6->target_offset);
+
+                               if (id >= 0)
+                               {
+                                       if (fw3_pr_debug)
+                                               debug(h, "-D %s %u\n", chain, num + 1);
+
+                                       ip6tc_delete_num_entry(chain, num, h->handle);
+                                       found = true;
+                                       break;
+                               }
+                       }
+               } while (found);
+       }
+       else
+#endif
+       {
+               if (!iptc_is_chain(chain, h->handle))
+                       return;
+
+               do {
+                       found = false;
+
+                       for (num = 0, e = iptc_first_rule(chain, h->handle);
+                                e != NULL;
+                                num++, e = iptc_next_rule(e, h->handle))
+                       {
+                               id = get_rule_id(e, sizeof(*e), e->target_offset);
+
+                               if (id >= 0)
+                               {
+                                       if (fw3_pr_debug)
+                                               debug(h, "-D %s %u\n", chain, num + 1);
+
+                                       iptc_delete_num_entry(chain, num, h->handle);
+                                       found = true;
+                                       break;
+                               }
+                       }
+               } while (found);
+       }
+}
+
 void
 fw3_ipt_create_chain(struct fw3_ipt_handle *h, const char *fmt, ...)
 {
@@ -290,6 +380,69 @@ fw3_ipt_flush(struct fw3_ipt_handle *h)
        }
 }
 
+static bool
+chain_is_empty(struct fw3_ipt_handle *h, const char *chain)
+{
+#ifndef DISABLE_IPV6
+       if (h->family == FW3_FAMILY_V6)
+               return (!ip6tc_builtin(chain, h->handle) &&
+                       !ip6tc_first_rule(chain, h->handle));
+#endif
+
+       return (!iptc_builtin(chain, h->handle) &&
+               !iptc_first_rule(chain, h->handle));
+}
+
+void
+fw3_ipt_gc(struct fw3_ipt_handle *h)
+{
+       const char *chain;
+       bool found;
+
+#ifndef DISABLE_IPV6
+       if (h->family == FW3_FAMILY_V6)
+       {
+               do {
+                       found = false;
+
+                       for (chain = ip6tc_first_chain(h->handle);
+                                chain != NULL;
+                                chain = ip6tc_next_chain(h->handle))
+                       {
+                               if (!chain_is_empty(h, chain))
+                                       continue;
+
+                               fw3_ipt_delete_chain(h, chain);
+                               found = true;
+                               break;
+                       }
+               } while(found);
+       }
+       else
+#endif
+       {
+               do {
+                       found = false;
+
+                       for (chain = iptc_first_chain(h->handle);
+                                chain != NULL;
+                                chain = iptc_next_chain(h->handle))
+                       {
+                               warn("C=%s\n", chain);
+
+                               if (!chain_is_empty(h, chain))
+                                       continue;
+
+                               warn("D=%s\n", chain);
+
+                               fw3_ipt_delete_chain(h, chain);
+                               found = true;
+                               break;
+                       }
+               } while (found);
+       }
+}
+
 void
 fw3_ipt_commit(struct fw3_ipt_handle *h)
 {
@@ -336,6 +489,7 @@ fw3_ipt_rule_new(struct fw3_ipt_handle *h)
        r = fw3_alloc(sizeof(*r));
 
        r->h = h;
+       r->id = 0;
        r->argv = fw3_alloc(sizeof(char *));
        r->argv[r->argc++] = "fw3";
 
@@ -1315,6 +1469,7 @@ __fw3_ipt_rule_append(struct fw3_ipt_rule *r, bool repl, const char *fmt, ...)
        struct xtables_globals *g;
 
        int i, optc;
+       uint32_t id;
        bool inv = false;
        char buf[32];
        va_list ap;
@@ -1329,6 +1484,24 @@ __fw3_ipt_rule_append(struct fw3_ipt_rule *r, bool repl, const char *fmt, ...)
        optind = 0;
        opterr = 0;
 
+       if (r->id >= 0)
+       {
+               em = find_match(r, "id");
+
+               if (!em)
+               {
+                       warn("fw3_ipt_rule_append(): Can't find match '%s'", "id");
+                       goto free;
+               }
+
+               init_match(r, em, true);
+
+               id = FW3_ID_MAGIC | (r->id & ~FW3_ID_MASK);
+               memcpy(em->m->data, &id, sizeof(id));
+
+               em->mflags = 1;
+       }
+
        while ((optc = getopt_long(r->argc, r->argv, "-:m:j:", g->opts,
                                   NULL)) != -1)
        {
index fabefa8abea870ff0331f29a8da9fb96786aff49..a6d10245a9f68f819babf8e64117dff78749d721 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "options.h"
 
+#define FW3_ID_MAGIC   0x66773300      /* 'f' 'w' '3' */
+#define FW3_ID_MASK            0xffffff00
+
 /* xtables interface */
 #if (XTABLES_VERSION_CODE == 10)
 # include "xtables-10.h"
@@ -68,6 +71,8 @@ struct fw3_ipt_rule {
        struct xtables_rule_match *matches;
        struct xtables_target *target;
 
+       int id;
+
        int argc;
        char **argv;
 
@@ -85,10 +90,14 @@ void fw3_ipt_set_policy(struct fw3_ipt_handle *h, const char *chain,
 void fw3_ipt_flush_chain(struct fw3_ipt_handle *h, const char *chain);
 void fw3_ipt_delete_chain(struct fw3_ipt_handle *h, const char *chain);
 
+void fw3_ipt_delete_id_rules(struct fw3_ipt_handle *h, const char *chain);
+
 void fw3_ipt_create_chain(struct fw3_ipt_handle *h, const char *fmt, ...);
 
 void fw3_ipt_flush(struct fw3_ipt_handle *h);
 
+void fw3_ipt_gc(struct fw3_ipt_handle *h);
+
 void fw3_ipt_commit(struct fw3_ipt_handle *h);
 
 void fw3_ipt_close(struct fw3_ipt_handle *h);
diff --git a/main.c b/main.c
index 71463aec6a3840b547291de8fbae5ece5f9939c3..b95302050286d1d840caea0cc74313da0c46599d 100644 (file)
--- a/main.c
+++ b/main.c
@@ -400,6 +400,35 @@ start:
        return rv;
 }
 
+static int
+gc(void)
+{
+       enum fw3_family family;
+       enum fw3_table table;
+       struct fw3_ipt_handle *handle;
+
+       for (family = FW3_FAMILY_V4; family <= FW3_FAMILY_V6; family++)
+       {
+               if (family == FW3_FAMILY_V6 && cfg_state->defaults.disable_ipv6)
+                       continue;
+
+               for (table = FW3_TABLE_FILTER; table <= FW3_TABLE_RAW; table++)
+               {
+                       if (!fw3_has_table(family == FW3_FAMILY_V6, fw3_flag_names[table]))
+                               continue;
+
+                       if (!(handle = fw3_ipt_open(family, table)))
+                               continue;
+
+                       fw3_ipt_gc(handle);
+                       fw3_ipt_commit(handle);
+                       fw3_ipt_close(handle);
+               }
+       }
+
+       return 0;
+}
+
 static int
 lookup_network(const char *net)
 {
@@ -591,6 +620,14 @@ int main(int argc, char **argv)
                        fw3_unlock();
                }
        }
+       else if (!strcmp(argv[optind], "gc"))
+       {
+               if (fw3_lock())
+               {
+                       rv = gc();
+                       fw3_unlock();
+               }
+       }
        else if (!strcmp(argv[optind], "network") && (optind + 1) < argc)
        {
                rv = lookup_network(argv[optind + 1]);
diff --git a/rules.c b/rules.c
index a5f3fa9328f02eeb76188ba6ddf42c0505269503..756c78dc47c9fa11ab4ff7af282ec0e53b70580c 100644 (file)
--- a/rules.c
+++ b/rules.c
@@ -264,7 +264,7 @@ append_chain(struct fw3_ipt_rule *r, struct fw3_rule *rule)
 {
        char chain[32];
 
-       snprintf(chain, sizeof(chain), "delegate_output");
+       snprintf(chain, sizeof(chain), "OUTPUT");
 
        if (rule->target == FW3_FLAG_NOTRACK)
        {
@@ -272,7 +272,7 @@ append_chain(struct fw3_ipt_rule *r, struct fw3_rule *rule)
        }
        else if (rule->target == FW3_FLAG_MARK)
        {
-               snprintf(chain, sizeof(chain), "fwmark");
+               snprintf(chain, sizeof(chain), "PREROUTING");
        }
        else
        {
@@ -290,16 +290,16 @@ append_chain(struct fw3_ipt_rule *r, struct fw3_rule *rule)
                        else
                        {
                                if (rule->dest.set)
-                                       snprintf(chain, sizeof(chain), "delegate_forward");
+                                       snprintf(chain, sizeof(chain), "FORWARD");
                                else
-                                       snprintf(chain, sizeof(chain), "delegate_input");
+                                       snprintf(chain, sizeof(chain), "INPUT");
                        }
                }
 
                if (rule->dest.set && !rule->src.set)
                {
                        if (rule->dest.any)
-                               snprintf(chain, sizeof(chain), "delegate_output");
+                               snprintf(chain, sizeof(chain), "OUTPUT");
                        else
                                snprintf(chain, sizeof(chain), "zone_%s_output",
                                         rule->dest.name);
diff --git a/snats.c b/snats.c
index 0f7d851bc8e3153512d1a9bc9cbfda4c3918af11..75b0fa046d2949ac90ca0d191b91c62e167d69c3 100644 (file)
--- a/snats.c
+++ b/snats.c
@@ -265,7 +265,7 @@ append_chain(struct fw3_ipt_rule *r, struct fw3_snat *snat)
        if (snat->_src)
                fw3_ipt_rule_append(r, "zone_%s_postrouting", snat->src.name);
        else
-               fw3_ipt_rule_append(r, "delegate_postrouting");
+               fw3_ipt_rule_append(r, "POSTROUTING");
 }
 
 static void
diff --git a/zones.c b/zones.c
index 2ddd7b44443f3b2714e19ffb2f8b8b29320700d2..88133e26b3348fdc9e1ce261ed2b241ef955c166 100644 (file)
--- a/zones.c
+++ b/zones.c
@@ -331,9 +331,9 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
        int i;
 
        const char *chains[] = {
-               "input",
-               "output",
-               "forward",
+               "input", "INPUT",
+               "output", "OUTPUT",
+               "forward", "FORWARD",
        };
 
 #define jump_target(t) \
@@ -362,7 +362,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                        }
                }
 
-               for (i = 0; i < sizeof(chains)/sizeof(chains[0]); i++)
+               for (i = 0; i < sizeof(chains)/sizeof(chains[0]); i += 2)
                {
                        if (*chains[i] == 'o')
                                r = fw3_ipt_rule_create(handle, NULL, NULL, dev, NULL, sub);
@@ -376,7 +376,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                        else
                                fw3_ipt_rule_extra(r, zone->extra_src);
 
-                       fw3_ipt_rule_replace(r, "delegate_%s", chains[i]);
+                       fw3_ipt_rule_replace(r, chains[i + 1]);
                }
        }
        else if (handle->table == FW3_TABLE_NAT)
@@ -386,7 +386,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                        r = fw3_ipt_rule_create(handle, NULL, dev, NULL, sub, NULL);
                        fw3_ipt_rule_target(r, "zone_%s_prerouting", zone->name);
                        fw3_ipt_rule_extra(r, zone->extra_src);
-                       fw3_ipt_rule_replace(r, "delegate_prerouting");
+                       fw3_ipt_rule_replace(r, "PREROUTING");
                }
 
                if (has(zone->flags, handle->family, FW3_FLAG_SNAT))
@@ -394,7 +394,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                        r = fw3_ipt_rule_create(handle, NULL, NULL, dev, NULL, sub);
                        fw3_ipt_rule_target(r, "zone_%s_postrouting", zone->name);
                        fw3_ipt_rule_extra(r, zone->extra_dest);
-                       fw3_ipt_rule_replace(r, "delegate_postrouting");
+                       fw3_ipt_rule_replace(r, "POSTROUTING");
                }
        }
        else if (handle->table == FW3_TABLE_MANGLE)
@@ -412,7 +412,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                                fw3_ipt_rule_comment(r, "%s (mtu_fix logging)", zone->name);
                                fw3_ipt_rule_target(r, "LOG");
                                fw3_ipt_rule_addarg(r, false, "--log-prefix", buf);
-                               fw3_ipt_rule_replace(r, "mssfix");
+                               fw3_ipt_rule_replace(r, "FORWARD");
                        }
 
                        r = fw3_ipt_rule_create(handle, &tcp, NULL, dev, NULL, sub);
@@ -421,7 +421,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                        fw3_ipt_rule_comment(r, "%s (mtu_fix)", zone->name);
                        fw3_ipt_rule_target(r, "TCPMSS");
                        fw3_ipt_rule_addarg(r, false, "--clamp-mss-to-pmtu", NULL);
-                       fw3_ipt_rule_replace(r, "mssfix");
+                       fw3_ipt_rule_replace(r, "FORWARD");
                }
        }
        else if (handle->table == FW3_TABLE_RAW)
@@ -431,7 +431,7 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
                        r = fw3_ipt_rule_create(handle, NULL, dev, NULL, sub, NULL);
                        fw3_ipt_rule_target(r, "zone_%s_notrack", zone->name);
                        fw3_ipt_rule_extra(r, zone->extra_src);
-                       fw3_ipt_rule_replace(r, "delegate_notrack");
+                       fw3_ipt_rule_replace(r, "PREROUTING");
                }
        }
 }