FW3_OPT("output", target, defaults, policy_output),
FW3_OPT("drop_invalid", bool, defaults, drop_invalid),
+ FW3_OPT("tcp_reject_code", reject_code, defaults, tcp_reject_code),
+ FW3_OPT("any_reject_code", reject_code, defaults, any_reject_code),
FW3_OPT("syn_flood", bool, defaults, syn_flood),
FW3_OPT("synflood_protect", bool, defaults, syn_flood),
FW3_OPT("accept_redirects", bool, defaults, accept_redirects),
FW3_OPT("accept_source_route", bool, defaults, accept_source_route),
+ FW3_OPT("auto_helper", bool, defaults, auto_helper),
FW3_OPT("custom_chains", bool, defaults, custom_chains),
FW3_OPT("disable_ipv6", bool, defaults, disable_ipv6),
+ FW3_OPT("flow_offloading", bool, defaults, flow_offloading),
+ FW3_OPT("flow_offloading_hw", bool, defaults, flow_offloading_hw),
FW3_OPT("__flags_v4", int, defaults, flags[0]),
FW3_OPT("__flags_v6", int, defaults, flags[1]),
}
}
+static void
+check_kmod(struct uci_element *e, bool *module, const char *name)
+{
+ FILE *f;
+ char buf[128];
+
+ if (!*module)
+ return;
+
+ snprintf(buf, sizeof(buf), "/sys/module/%s/refcnt", name);
+
+ f = fopen(buf, "r");
+
+ if (f)
+ {
+ fclose(f);
+ return;
+ }
+
+ warn_elem(e, "requires not available kernel module %s, disabling", name);
+ *module = false;
+}
+
+static void
+check_any_reject_code(struct uci_element *e, enum fw3_reject_code *any_reject_code)
+{
+ if (*any_reject_code == FW3_REJECT_CODE_TCP_RESET) {
+ warn_elem(e, "tcp-reset not valid for any_reject_code, defaulting to port-unreach");
+ *any_reject_code = FW3_REJECT_CODE_PORT_UNREACH;
+ }
+}
+
+static const char*
+get_reject_code(enum fw3_family family, enum fw3_reject_code reject_code)
+{
+ switch (reject_code) {
+ case FW3_REJECT_CODE_TCP_RESET:
+ return "tcp-reset";
+ case FW3_REJECT_CODE_PORT_UNREACH:
+ return "port-unreach";
+ case FW3_REJECT_CODE_ADM_PROHIBITED:
+ return family == FW3_FAMILY_V6 ? "adm-prohibited": "admin-prohib";
+ default:
+ return "unknown";
+ }
+}
+
void
fw3_load_defaults(struct fw3_state *state, struct uci_package *p)
{
bool seen = false;
+ defs->tcp_reject_code = FW3_REJECT_CODE_TCP_RESET;
+ defs->any_reject_code = FW3_REJECT_CODE_PORT_UNREACH;
defs->syn_flood_rate.rate = 25;
defs->syn_flood_rate.burst = 50;
defs->tcp_syncookies = true;
defs->tcp_window_scaling = true;
defs->custom_chains = true;
- defs->drop_invalid = true;
+ defs->auto_helper = true;
uci_foreach_element(&p->sections, e)
{
continue;
}
- fw3_parse_options(&state->defaults, fw3_flag_opts, s);
+ if(!fw3_parse_options(&state->defaults, fw3_flag_opts, s))
+ warn_elem(e, "has invalid options");
check_policy(e, &defs->policy_input, "input");
check_policy(e, &defs->policy_output, "output");
check_policy(e, &defs->policy_forward, "forward");
+
+ check_any_reject_code(e, &defs->any_reject_code);
+
+ check_kmod(e, &defs->flow_offloading, "xt_FLOWOFFLOAD");
}
}
continue;
if (c->flag &&
- !hasbit(defs->flags[handle->family == FW3_FAMILY_V6], c->flag))
+ !fw3_hasbit(defs->flags[handle->family == FW3_FAMILY_V6], c->flag))
continue;
fw3_ipt_create_chain(handle, c->format);
for (i = 0; i < ARRAY_SIZE(chains); i += 2)
{
r = fw3_ipt_rule_new(handle);
- fw3_ipt_rule_comment(r, "user chain for %s", chains[i+1]);
+ fw3_ipt_rule_comment(r, "Custom %s rule chain", chains[i+1]);
fw3_ipt_rule_target(r, "%s_rule", chains[i+1]);
fw3_ipt_rule_append(r, chains[i]);
}
}
+ if (defs->flow_offloading)
+ {
+ r = fw3_ipt_rule_new(handle);
+ fw3_ipt_rule_comment(r, "Traffic offloading");
+ fw3_ipt_rule_extra(r, "-m conntrack --ctstate RELATED,ESTABLISHED");
+ fw3_ipt_rule_target(r, "FLOWOFFLOAD");
+ if (defs->flow_offloading_hw)
+ fw3_ipt_rule_addarg(r, false, "--hw", NULL);
+ fw3_ipt_rule_append(r, "FORWARD");
+ }
+
for (i = 0; i < ARRAY_SIZE(chains); i += 2)
{
r = fw3_ipt_rule_new(handle);
r = fw3_ipt_rule_create(handle, &tcp, NULL, NULL, NULL, NULL);
fw3_ipt_rule_target(r, "REJECT");
- fw3_ipt_rule_addarg(r, false, "--reject-with", "tcp-reset");
+ fw3_ipt_rule_addarg(r, false, "--reject-with", get_reject_code(handle->family, defs->tcp_reject_code));
fw3_ipt_rule_append(r, "reject");
r = fw3_ipt_rule_new(handle);
fw3_ipt_rule_target(r, "REJECT");
- fw3_ipt_rule_addarg(r, false, "--reject-with", "port-unreach");
+ fw3_ipt_rule_addarg(r, false, "--reject-with", get_reject_code(handle->family, defs->any_reject_code));
fw3_ipt_rule_append(r, "reject");
break;
if (defs->custom_chains)
{
r = fw3_ipt_rule_new(handle);
- fw3_ipt_rule_comment(r, "user chain for prerouting");
+ fw3_ipt_rule_comment(r, "Custom prerouting rule chain");
fw3_ipt_rule_target(r, "prerouting_rule");
fw3_ipt_rule_append(r, "PREROUTING");
r = fw3_ipt_rule_new(handle);
- fw3_ipt_rule_comment(r, "user chain for postrouting");
+ fw3_ipt_rule_comment(r, "Custom postrouting rule chain");
fw3_ipt_rule_target(r, "postrouting_rule");
fw3_ipt_rule_append(r, "POSTROUTING");
}
snprintf(path, sizeof(path), "/proc/sys/net/ipv4/tcp_%s", name);
- info(" * Set tcp_%s to %s", name, set ? "on" : "off", name);
+ info(" * Set tcp_%s to %s", name, set ? "on" : "off");
if (!(f = fopen(path, "w")))
{