From acb769291a746f50d0d967aaec71049b76c50d5b Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 17 Oct 2025 12:16:48 +0200 Subject: [PATCH] exception-policy: add 'reject-both' option Allow rejecting both sides of a connection. Has the same support as regular reject (which is essentially rejectsrc). Ticket: #5974. --- etc/schema.json | 4 ++++ src/app-layer.c | 2 ++ src/decode.c | 4 ++++ src/stream-tcp.c | 8 ++++++++ src/util-exception-policy-types.h | 5 +++-- src/util-exception-policy.c | 15 +++++++++++++-- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/etc/schema.json b/etc/schema.json index b84b0b1f35..d23edbfb8b 100644 --- a/etc/schema.json +++ b/etc/schema.json @@ -8753,6 +8753,10 @@ "reject": { "type": "integer", "minimum": 0 + }, + "reject_both": { + "type": "integer", + "minimum": 0 } } } diff --git a/src/app-layer.c b/src/app-layer.c index d9049a5480..34efd1b8d6 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -115,6 +115,7 @@ ExceptionPolicyStatsSetts app_layer_error_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -125,6 +126,7 @@ ExceptionPolicyStatsSetts app_layer_error_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ true, /* EXCEPTION_POLICY_DROP_FLOW */ true, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, }; // clang-format on diff --git a/src/decode.c b/src/decode.c index bae2b25dc9..9c480cc36a 100644 --- a/src/decode.c +++ b/src/decode.c @@ -93,6 +93,7 @@ ExceptionPolicyStatsSetts defrag_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -103,6 +104,7 @@ ExceptionPolicyStatsSetts defrag_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ true, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, }; // clang-format on @@ -119,6 +121,7 @@ ExceptionPolicyStatsSetts flow_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -129,6 +132,7 @@ ExceptionPolicyStatsSetts flow_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ true, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, }; // clang-format on diff --git a/src/stream-tcp.c b/src/stream-tcp.c index b626a23a96..9a72e22c16 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -102,6 +102,7 @@ ExceptionPolicyStatsSetts stream_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -112,6 +113,7 @@ ExceptionPolicyStatsSetts stream_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ true, /* EXCEPTION_POLICY_DROP_FLOW */ true, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, }; // clang-format on @@ -128,6 +130,7 @@ ExceptionPolicyStatsSetts stream_reassembly_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -138,6 +141,7 @@ ExceptionPolicyStatsSetts stream_reassembly_memcap_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ true, /* EXCEPTION_POLICY_DROP_FLOW */ true, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, }; // clang-format on @@ -154,6 +158,7 @@ ExceptionPolicyStatsSetts stream_midstream_enabled_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ false, + /* EXCEPTION_POLICY_REJECT_BOTH */ false, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -164,6 +169,7 @@ ExceptionPolicyStatsSetts stream_midstream_enabled_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ false, + /* EXCEPTION_POLICY_REJECT_BOTH */ false, }, }; // clang-format on @@ -180,6 +186,7 @@ ExceptionPolicyStatsSetts stream_midstream_disabled_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ false, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, .valid_settings_ips = { /* EXCEPTION_POLICY_NOT_SET */ false, @@ -190,6 +197,7 @@ ExceptionPolicyStatsSetts stream_midstream_disabled_eps_stats = { /* EXCEPTION_POLICY_DROP_PACKET */ false, /* EXCEPTION_POLICY_DROP_FLOW */ true, /* EXCEPTION_POLICY_REJECT */ true, + /* EXCEPTION_POLICY_REJECT_BOTH */ true, }, }; // clang-format on diff --git a/src/util-exception-policy-types.h b/src/util-exception-policy-types.h index 7df6d0d82c..a3a5308416 100644 --- a/src/util-exception-policy-types.h +++ b/src/util-exception-policy-types.h @@ -30,10 +30,11 @@ enum ExceptionPolicy { EXCEPTION_POLICY_BYPASS_FLOW, EXCEPTION_POLICY_DROP_PACKET, EXCEPTION_POLICY_DROP_FLOW, - EXCEPTION_POLICY_REJECT, + EXCEPTION_POLICY_REJECT, /**< reject src */ + EXCEPTION_POLICY_REJECT_BOTH /**< reject both src and dest */ }; -#define EXCEPTION_POLICY_MAX (EXCEPTION_POLICY_REJECT + 1) +#define EXCEPTION_POLICY_MAX (EXCEPTION_POLICY_REJECT_BOTH + 1) /* Max length = possible exception policy scenarios + counter names * + exception policy type. E.g.: diff --git a/src/util-exception-policy.c b/src/util-exception-policy.c index f6d06add1a..d18aa52706 100644 --- a/src/util-exception-policy.c +++ b/src/util-exception-policy.c @@ -47,6 +47,8 @@ const char *ExceptionPolicyEnumToString(enum ExceptionPolicy policy, bool is_jso return "reject"; case EXCEPTION_POLICY_BYPASS_FLOW: return "bypass"; + case EXCEPTION_POLICY_REJECT_BOTH: + return "reject_both"; case EXCEPTION_POLICY_DROP_FLOW: return is_json ? "drop_flow" : "drop-flow"; case EXCEPTION_POLICY_DROP_PACKET: @@ -145,8 +147,14 @@ void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDro case EXCEPTION_POLICY_NOT_SET: break; case EXCEPTION_POLICY_REJECT: - SCLogDebug("EXCEPTION_POLICY_REJECT"); - PacketDrop(p, ACTION_REJECT, drop_reason); + case EXCEPTION_POLICY_REJECT_BOTH: + if (policy == EXCEPTION_POLICY_REJECT) { + SCLogDebug("EXCEPTION_POLICY_REJECT"); + PacketDrop(p, ACTION_REJECT, drop_reason); + } else { + SCLogDebug("EXCEPTION_POLICY_REJECT_BOTH"); + PacketDrop(p, ACTION_REJECT_BOTH, drop_reason); + } if (!EngineModeIsIPS()) { break; } @@ -204,6 +212,7 @@ static enum ExceptionPolicy PickPacketAction(const char *option, enum ExceptionP case EXCEPTION_POLICY_PASS_PACKET: break; case EXCEPTION_POLICY_REJECT: + case EXCEPTION_POLICY_REJECT_BOTH: break; case EXCEPTION_POLICY_NOT_SET: break; @@ -229,6 +238,8 @@ static enum ExceptionPolicy ExceptionPolicyConfigValueParse( policy = EXCEPTION_POLICY_PASS_PACKET; } else if (strcmp(value_str, "reject") == 0) { policy = EXCEPTION_POLICY_REJECT; + } else if (strcmp(value_str, "reject-both") == 0) { + policy = EXCEPTION_POLICY_REJECT_BOTH; } else if (strcmp(value_str, "ignore") == 0) { // TODO name? policy = EXCEPTION_POLICY_NOT_SET; } else if (strcmp(value_str, "auto") == 0) {