{ 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"),
{ }
};
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)
{
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)
{
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);
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;
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)
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)
return;
fw3_ipt_rule_target(r, "reject");
- fw3_ipt_rule_append(r, "delegate_forward");
+ fw3_ipt_rule_append(r, "FORWARD");
}
}
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 */
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);
}
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, ...)
{
}
}
+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)
{
r = fw3_alloc(sizeof(*r));
r->h = h;
+ r->id = 0;
r->argv = fw3_alloc(sizeof(char *));
r->argv[r->argc++] = "fw3";
struct xtables_globals *g;
int i, optc;
+ uint32_t id;
bool inv = false;
char buf[32];
va_list ap;
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)
{
#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"
struct xtables_rule_match *matches;
struct xtables_target *target;
+ int id;
+
int argc;
char **argv;
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);
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)
{
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]);
{
char chain[32];
- snprintf(chain, sizeof(chain), "delegate_output");
+ snprintf(chain, sizeof(chain), "OUTPUT");
if (rule->target == FW3_FLAG_NOTRACK)
{
}
else if (rule->target == FW3_FLAG_MARK)
{
- snprintf(chain, sizeof(chain), "fwmark");
+ snprintf(chain, sizeof(chain), "PREROUTING");
}
else
{
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);
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
int i;
const char *chains[] = {
- "input",
- "output",
- "forward",
+ "input", "INPUT",
+ "output", "OUTPUT",
+ "forward", "FORWARD",
};
#define jump_target(t) \
}
}
- 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);
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)
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))
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)
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);
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)
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");
}
}
}