{ FW3_FAMILY_##f, FW3_TABLE_##tbl, FW3_FLAG_##tgt, fmt }
static const struct fw3_chain_spec zone_chains[] = {
- C(ANY, FILTER, UNSPEC, "zone_%s_input"),
- C(ANY, FILTER, UNSPEC, "zone_%s_output"),
- C(ANY, FILTER, UNSPEC, "zone_%s_forward"),
+ C(ANY, FILTER, UNSPEC, "zone_?_input"),
+ C(ANY, FILTER, UNSPEC, "zone_?_output"),
+ C(ANY, FILTER, UNSPEC, "zone_?_forward"),
- C(ANY, FILTER, SRC_ACCEPT, "zone_%s_src_ACCEPT"),
- C(ANY, FILTER, SRC_REJECT, "zone_%s_src_REJECT"),
- C(ANY, FILTER, SRC_DROP, "zone_%s_src_DROP"),
+ C(ANY, FILTER, SRC_ACCEPT, "zone_?_src_ACCEPT"),
+ C(ANY, FILTER, SRC_REJECT, "zone_?_src_REJECT"),
+ C(ANY, FILTER, SRC_DROP, "zone_?_src_DROP"),
- C(ANY, FILTER, ACCEPT, "zone_%s_dest_ACCEPT"),
- C(ANY, FILTER, REJECT, "zone_%s_dest_REJECT"),
- C(ANY, FILTER, DROP, "zone_%s_dest_DROP"),
+ C(ANY, FILTER, ACCEPT, "zone_?_dest_ACCEPT"),
+ C(ANY, FILTER, REJECT, "zone_?_dest_REJECT"),
+ C(ANY, FILTER, DROP, "zone_?_dest_DROP"),
- C(V4, NAT, SNAT, "zone_%s_postrouting"),
- C(V4, NAT, DNAT, "zone_%s_prerouting"),
+ C(V4, NAT, SNAT, "zone_?_postrouting"),
+ C(V4, NAT, DNAT, "zone_?_prerouting"),
- C(ANY, RAW, HELPER, "zone_%s_helper"),
- C(ANY, RAW, NOTRACK, "zone_%s_notrack"),
+ C(ANY, RAW, HELPER, "zone_?_helper"),
+ C(ANY, RAW, NOTRACK, "zone_?_notrack"),
- C(ANY, FILTER, CUSTOM_CHAINS, "input_%s_rule"),
- C(ANY, FILTER, CUSTOM_CHAINS, "output_%s_rule"),
- C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_%s_rule"),
+ C(ANY, FILTER, CUSTOM_CHAINS, "input_?_rule"),
+ C(ANY, FILTER, CUSTOM_CHAINS, "output_?_rule"),
+ C(ANY, FILTER, CUSTOM_CHAINS, "forwarding_?_rule"),
- C(V4, NAT, CUSTOM_CHAINS, "prerouting_%s_rule"),
- C(V4, NAT, CUSTOM_CHAINS, "postrouting_%s_rule"),
+ C(V4, NAT, CUSTOM_CHAINS, "prerouting_?_rule"),
+ C(V4, NAT, CUSTOM_CHAINS, "postrouting_?_rule"),
{ }
};
static void
resolve_networks(struct uci_element *e, struct fw3_zone *zone)
{
- struct fw3_device *net, *tmp;
+ struct fw3_device *net, *dev, *tmp;
list_for_each_entry(net, &zone->networks, list)
{
continue;
}
+ list_for_each_entry(dev, &zone->devices, list)
+ if (!strcmp(dev->name, tmp->name))
+ goto alias;
+
snprintf(tmp->network, sizeof(tmp->network), "%s", net->name);
list_add_tail(&tmp->list, &zone->devices);
+ continue;
+alias:
+ free(tmp);
}
}
}
+static char *
+format_chain(const char *fmt, const char *zonename)
+{
+ static char chain[32];
+ size_t rem;
+ char *p;
+ int len;
+
+ for (p = chain, rem = sizeof(chain); *fmt; fmt++) {
+ if (*fmt == '?') {
+ len = snprintf(p, rem, "%s", zonename);
+
+ if (len < 0 || len >= rem)
+ break;
+
+ rem -= len;
+ p += len;
+ }
+ else {
+ if (rem <= 1)
+ break;
+
+ *p++ = *fmt;
+ rem--;
+ }
+ }
+
+ *p = 0;
+
+ return chain;
+}
+
static void
print_zone_chain(struct fw3_ipt_handle *handle, struct fw3_state *state,
bool reload, struct fw3_zone *zone)
for (c = zone_chains; c->format; c++)
{
- /* don't touch user chains on selective stop */
- if (reload && c->flag == FW3_FLAG_CUSTOM_CHAINS)
- continue;
-
if (!fw3_is_family(c, handle->family))
continue;
!fw3_hasbit(zone->flags[handle->family == FW3_FAMILY_V6], c->flag))
continue;
- fw3_ipt_create_chain(handle, c->format, zone->name);
+ fw3_ipt_create_chain(handle, reload, format_chain(c->format, zone->name));
}
if (zone->custom_chains)
fw3_ipt_rule_target(r, "TCPMSS");
fw3_ipt_rule_addarg(r, false, "--clamp-mss-to-pmtu", NULL);
fw3_ipt_rule_replace(r, "FORWARD");
+
+ r = fw3_ipt_rule_create(handle, &tcp, dev, NULL, sub, NULL);
+ fw3_ipt_rule_addarg(r, false, "--tcp-flags", "SYN,RST");
+ fw3_ipt_rule_addarg(r, false, "SYN", NULL);
+ fw3_ipt_rule_comment(r, "Zone %s MTU fixing", zone->name);
+ fw3_ipt_rule_target(r, "TCPMSS");
+ fw3_ipt_rule_addarg(r, false, "--clamp-mss-to-pmtu", NULL);
+ fw3_ipt_rule_replace(r, "FORWARD");
}
}
else if (handle->table == FW3_TABLE_RAW)
{
struct fw3_zone *z, *tmp;
const struct fw3_chain_spec *c;
- char chain[32];
list_for_each_entry_safe(z, tmp, &state->zones, list)
{
if (!has(z->flags, handle->family, handle->table))
continue;
+ /* first flush all rules ... */
for (c = zone_chains; c->format; c++)
{
/* don't touch user chains on selective stop */
if (c->flag && !has(z->flags, handle->family, c->flag))
continue;
- snprintf(chain, sizeof(chain), c->format, z->name);
- fw3_ipt_flush_chain(handle, chain);
+ fw3_ipt_flush_chain(handle, format_chain(c->format, z->name));
+ }
+
+ /* ... then remove the chains */
+ for (c = zone_chains; c->format; c++)
+ {
+ if (!fw3_is_family(c, handle->family))
+ continue;
+
+ if (c->table != handle->table)
+ continue;
- /* keep certain basic chains that do not depend on any settings to
- avoid purging unrelated user rules pointing to them */
- if (reload && !c->flag)
+ if (c->flag && !has(z->flags, handle->family, c->flag))
continue;
- fw3_ipt_delete_chain(handle, chain);
+ fw3_ipt_delete_chain(handle, reload,
+ format_chain(c->format, z->name));
}
del(z->flags, handle->family, handle->table);