From 65e71b94e3ccddae7ed754242dd8d2ad7a3a0cb4 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Thu, 16 Jan 2020 21:36:39 +0100 Subject: [PATCH] luci-app-firewall: support 'limit' and 'limit_burst' options Signed-off-by: Jo-Philipp Wich (backported from commit 28f4a9fcedda504adac3426195749c45b8893836) --- .../resources/view/firewall/forwards.js | 36 ++++++++++++++++ .../resources/view/firewall/rules.js | 36 ++++++++++++++++ .../resources/view/firewall/snats.js | 41 ++++++++++++++++++- 3 files changed, 111 insertions(+), 2 deletions(-) diff --git a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/forwards.js b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/forwards.js index 030b78b2d..f8b9e19e1 100644 --- a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/forwards.js +++ b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/forwards.js @@ -315,6 +315,42 @@ return L.view.extend({ return true; }; + o = s.taboption('advanced', form.Value, 'limit', _('Limit matching'), + _('Limits traffic matching to the specified rate.')); + o.modalonly = true; + o.rmempty = true; + o.placeholder = _('unlimited'); + o.value('10/second'); + o.value('60/minute'); + o.value('3/hour'); + o.value('500/day'); + o.validate = function(section_id, value) { + if (value == '') + return true; + + var m = String(value).toLowerCase().match(/^(?:0x[0-9a-f]{1,8}|[0-9]{1,10})\/([a-z]+)$/), + u = ['second', 'minute', 'hour', 'day'], + i = 0; + + if (m) + for (i = 0; i < u.length; i++) + if (u[i].indexOf(m[1]) == 0) + break; + + if (!m || i >= u.length) + return _('Invalid limit value'); + + return true; + }; + + o = s.taboption('advanced', form.Value, 'limit_burst', _('Limit burst'), + _('Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number.')); + o.modalonly = true; + o.rmempty = true; + o.placeholder = '5'; + o.datatype = 'uinteger'; + o.depends({ limit: null, '!reverse': true }); + o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'), _('Passes additional arguments to iptables. Use with care!')); o.modalonly = true; diff --git a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/rules.js b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/rules.js index 9d8d8d155..a5b27ccf3 100644 --- a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/rules.js +++ b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/rules.js @@ -555,6 +555,42 @@ return L.view.extend({ return true; }; + o = s.taboption('advanced', form.Value, 'limit', _('Limit matching'), + _('Limits traffic matching to the specified rate.')); + o.modalonly = true; + o.rmempty = true; + o.placeholder = _('unlimited'); + o.value('10/second'); + o.value('60/minute'); + o.value('3/hour'); + o.value('500/day'); + o.validate = function(section_id, value) { + if (value == '') + return true; + + var m = String(value).toLowerCase().match(/^(?:0x[0-9a-f]{1,8}|[0-9]{1,10})\/([a-z]+)$/), + u = ['second', 'minute', 'hour', 'day'], + i = 0; + + if (m) + for (i = 0; i < u.length; i++) + if (u[i].indexOf(m[1]) == 0) + break; + + if (!m || i >= u.length) + return _('Invalid limit value'); + + return true; + }; + + o = s.taboption('advanced', form.Value, 'limit_burst', _('Limit burst'), + _('Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number.')); + o.modalonly = true; + o.rmempty = true; + o.placeholder = '5'; + o.datatype = 'uinteger'; + o.depends({ limit: null, '!reverse': true }); + o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'), _('Passes additional arguments to iptables. Use with care!')); o.modalonly = true; diff --git a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/snats.js b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/snats.js index 48fd98ff2..b46791587 100644 --- a/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/snats.js +++ b/applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/snats.js @@ -81,10 +81,11 @@ function snat_proto_txt(s) { var m = uci.get('firewall', s, 'mark'), p = uci.get('firewall', s, 'proto'); - return fmt(_('Match %{protocol?%{family} %{protocol} traffic:any %{family} traffic} %{mark?with firewall mark %{mark}}'), { + return fmt(_('Match %{protocol?%{family} %{protocol} traffic:any %{family} traffic} %{mark?with firewall mark %{mark}} %{limit?limited to %{limit}}'), { protocol: (p && p != 'all' && p != 'any' && p != '*') ? fwtool.fmt_proto(uci.get('firewall', s, 'proto')) : null, family: fwtool.fmt_family('ipv4'), - mark: m ? E('var', {}, fwtool.fmt_neg(m)) : null + mark: m ? E('var', {}, fwtool.fmt_neg(m)) : null, + limit: fwtool.fmt_limit(uci.get('firewall', s, 'limit'), uci.get('firewall', s, 'limit_burst')) }); } @@ -328,6 +329,42 @@ return L.view.extend({ return true; }; + o = s.taboption('advanced', form.Value, 'limit', _('Limit matching'), + _('Limits traffic matching to the specified rate.')); + o.modalonly = true; + o.rmempty = true; + o.placeholder = _('unlimited'); + o.value('10/second'); + o.value('60/minute'); + o.value('3/hour'); + o.value('500/day'); + o.validate = function(section_id, value) { + if (value == '') + return true; + + var m = String(value).toLowerCase().match(/^(?:0x[0-9a-f]{1,8}|[0-9]{1,10})\/([a-z]+)$/), + u = ['second', 'minute', 'hour', 'day'], + i = 0; + + if (m) + for (i = 0; i < u.length; i++) + if (u[i].indexOf(m[1]) == 0) + break; + + if (!m || i >= u.length) + return _('Invalid limit value'); + + return true; + }; + + o = s.taboption('advanced', form.Value, 'limit_burst', _('Limit burst'), + _('Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number.')); + o.modalonly = true; + o.rmempty = true; + o.placeholder = '5'; + o.datatype = 'uinteger'; + o.depends({ limit: null, '!reverse': true }); + o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'), _('Passes additional arguments to iptables. Use with care!')); o.modalonly = true; -- 2.25.1