From bbfd1f3f8b38ffb2a6a8e08b0e505e82ca08139b Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Thu, 26 Dec 2024 19:26:28 +0100 Subject: [PATCH] Firewall: Automation: Filter - add adaptive timeouts for https://github.com/opnsense/core/issues/8143 --- .../Firewall/forms/dialogFilterRule.xml | 14 +++++++ .../app/models/OPNsense/Firewall/Filter.php | 38 ++++++++++++++++++- .../app/models/OPNsense/Firewall/Filter.xml | 6 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml b/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml index 9ceb276c1..74f5860f1 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml +++ b/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml @@ -161,6 +161,20 @@ State Timeout in seconds (TCP only) true + + rule.adaptivestart + + text + When the number of state entries exceeds this value, adaptive scaling begins. All timeout values are scaled linearly with factor (adaptive.end - number of states) / (adaptive.end - adaptive.start). + true + + + rule.adaptiveend + + text + When reaching this number of state entries, all timeout values become zero, effectively purging all state entries immediately. This value is used to define the scale factor, it should not actually be reached (set a lower state limit). + true + rule.max diff --git a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php index 0b5bd7448..282a7e028 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php +++ b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php @@ -119,7 +119,9 @@ class Filter extends BaseModel )); } if ($rule->statetype == 'none') { - foreach (['statetimeout', 'max', 'max-src-states', 'max-src-nodes'] as $fieldname) { + foreach ([ + 'statetimeout', 'max', 'max-src-states', 'max-src-nodes', 'adaptivestart', 'adaptiveend' + ] as $fieldname) { if (!empty((string)$rule->$fieldname)) { $messages->appendMessage(new Message( gettext("Invalid option when statetype is none."), @@ -134,6 +136,40 @@ class Filter extends BaseModel $rule->statetimeout->__reference )); } + if (empty((string)$rule->max) && ($rule->adaptivestart == '0' || $rule->adaptiveend == '0')) { + $messages->appendMessage(new Message( + gettext('Disabling adaptive timeouts is only supported in combination with a configured maximum number of states for the same rule.'), + $rule->max->__reference + )); + } elseif ($rule->adaptivestart == '0' xor $rule->adaptiveend == '0') { + $messages->appendMessage(new Message( + gettext("Adaptive timeouts must be disabled together."), + $rule->adaptivestart->__reference + )); + } elseif (!empty((string)$rule->adaptivestart) xor !empty((string)$rule->adaptiveend)) { + $messages->appendMessage(new Message( + gettext("The adaptive timouts values must be set together."), + $rule->adaptivestart->__reference + )); + } elseif ( + !empty((string)$rule->max) && + !empty((string)$rule->adaptiveend) && + (int)$rule->max->getCurrentValue() > (int)$rule->adaptiveend->getCurrentValue() + ) { + $messages->appendMessage(new Message( + gettext("The value of adaptive.end must be greater than the Max states value."), + $rule->adaptiveend->__reference + )); + } elseif ( + !empty((string)$rule->adaptivestart) && + !empty((string)$rule->adaptiveend) && + (int)$rule->adaptivestart->getCurrentValue() > (int)$rule->adaptiveend->getCurrentValue() + ) { + $messages->appendMessage(new Message( + gettext("The value of adaptive.end must be greater than adaptive.start value."), + $rule->adaptiveend->__reference + )); + } } } } diff --git a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml index cc6350bd3..bfc8b5ca3 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml @@ -155,6 +155,12 @@ 1 + + 0 + + + 0 +