[OpenWrt-Devel,v2] firewall3: make reject types selectable by user

Message ID 1531384562-8917-1-git-send-email-alin.nastac@technicolor.com
State Accepted
Delegated to: Jo-Philipp Wich
Headers show
Series
  • [OpenWrt-Devel,v2] firewall3: make reject types selectable by user
Related show

Commit Message

Alin Nastac July 12, 2018, 8:36 a.m.
From: Alin Nastac <alin.nastac@gmail.com>

RFC 6092 recommends in section 3.3.1 that an IPv6 CPE must respond to
unsolicited inbound SYNs with an ICMPv6 Destination Unreachable error
code 1 (Communication with destination administratively prohibited).

Signed-off-by: Alin Nastac <alin.nastac@gmail.com>
---
 defaults.c | 34 ++++++++++++++++++++++++++++++++--
 options.c  | 13 +++++++++++++
 options.h  | 12 ++++++++++++
 3 files changed, 57 insertions(+), 2 deletions(-)

Patch

diff --git a/defaults.c b/defaults.c
index 11fbf0d..f42eed6 100644
--- a/defaults.c
+++ b/defaults.c
@@ -41,6 +41,8 @@  const struct fw3_option fw3_flag_opts[] = {
 	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),
@@ -102,6 +104,30 @@  check_offloading(struct uci_element *e, bool *offloading)
 	*offloading = 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)
 {
@@ -111,6 +137,8 @@  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;
@@ -138,6 +166,8 @@  fw3_load_defaults(struct fw3_state *state, struct uci_package *p)
 		check_policy(e, &defs->policy_output, "output");
 		check_policy(e, &defs->policy_forward, "forward");
 
+		check_any_reject_code(e, &defs->any_reject_code);
+
 		check_offloading(e, &defs->flow_offloading);
 	}
 }
@@ -278,12 +308,12 @@  fw3_print_default_head_rules(struct fw3_ipt_handle *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;
diff --git a/options.c b/options.c
index 087aa63..c85bafd 100644
--- a/options.c
+++ b/options.c
@@ -86,6 +86,12 @@  const char *fw3_flag_names[__FW3_FLAG_MAX] = {
 	"DROP",
 };
 
+const char *fw3_reject_code_names[__FW3_REJECT_CODE_MAX] = {
+	"tcp-reset",
+	"port-unreach",
+	"adm-prohibited",
+};
+
 const char *fw3_limit_units[__FW3_LIMIT_UNIT_MAX] = {
 	"second",
 	"minute",
@@ -170,6 +176,13 @@  fw3_parse_target(void *ptr, const char *val, bool is_list)
 }
 
 bool
+fw3_parse_reject_code(void *ptr, const char *val, bool is_list)
+{
+	return parse_enum(ptr, val, &fw3_reject_code_names[FW3_REJECT_CODE_TCP_RESET],
+	                  FW3_REJECT_CODE_TCP_RESET, FW3_REJECT_CODE_ADM_PROHIBITED);
+}
+
+bool
 fw3_parse_limit(void *ptr, const char *val, bool is_list)
 {
 	struct fw3_limit *limit = ptr;
diff --git a/options.h b/options.h
index 08fecf6..0b73a84 100644
--- a/options.h
+++ b/options.h
@@ -88,6 +88,15 @@  enum fw3_flag
 	__FW3_FLAG_MAX
 };
 
+enum fw3_reject_code
+{
+	FW3_REJECT_CODE_TCP_RESET      = 0,
+	FW3_REJECT_CODE_PORT_UNREACH   = 1,
+	FW3_REJECT_CODE_ADM_PROHIBITED = 2,
+
+	__FW3_REJECT_CODE_MAX
+};
+
 extern const char *fw3_flag_names[__FW3_FLAG_MAX];
 
 
@@ -276,6 +285,8 @@  struct fw3_defaults
 	enum fw3_flag policy_forward;
 
 	bool drop_invalid;
+	enum fw3_reject_code tcp_reject_code;
+	enum fw3_reject_code any_reject_code;
 
 	bool syn_flood;
 	struct fw3_limit syn_flood_rate;
@@ -580,6 +591,7 @@  bool fw3_parse_bool(void *ptr, const char *val, bool is_list);
 bool fw3_parse_int(void *ptr, const char *val, bool is_list);
 bool fw3_parse_string(void *ptr, const char *val, bool is_list);
 bool fw3_parse_target(void *ptr, const char *val, bool is_list);
+bool fw3_parse_reject_code(void *ptr, const char *val, bool is_list);
 bool fw3_parse_limit(void *ptr, const char *val, bool is_list);
 bool fw3_parse_device(void *ptr, const char *val, bool is_list);
 bool fw3_parse_address(void *ptr, const char *val, bool is_list);