aboutsummaryrefslogtreecommitdiff
path: root/net/nft-qos/files
diff options
context:
space:
mode:
authorTong Zhang <ztong0001@gmail.com>2020-08-14 07:21:33 -0400
committerTong Zhang <ztong0001@gmail.com>2020-08-19 09:39:57 -0400
commit0483b8dc88fbcf900cc60b0d00116ebe2a495a3c (patch)
tree608b05fb679242e99d42426fe10e63ee2cc42cfd /net/nft-qos/files
parent9c1670ed61675aa5181121af280c3715502ae16c (diff)
nft-qos: support mac address based speed limit
This patch makes it possible to configure and limit per-client internet speed based on MAC address and it can work with SQM. This feature is what OpenWRT currently lacks. This patch is largely based on static.sh and the configuration file is similar to original nft-qos. New configuration options and examples are listed below config default 'default' option limit_mac_enable '1' config client option drunit 'kbytes' option urunit 'kbytes' option hostname 'tv-box' option macaddr 'AB:CD:EF:01:23:45' option drate '1000' option urate '50' config client option drunit 'kbytes' option urunit 'kbytes' option hostname 'my-pc' option macaddr 'AB:CD:EF:01:23:46' option drate '3000' option urate '2000' limit_mac_enable - enable rate limit based on MAC address drunit - download rate unit urunit - upload rate unit macaddr - client MAC address drate - download rate urate - upload rate Signed-off-by: Tong Zhang <ztong0001@gmail.com>
Diffstat (limited to 'net/nft-qos/files')
-rw-r--r--net/nft-qos/files/lib/core.sh11
-rw-r--r--net/nft-qos/files/lib/mac.sh79
-rw-r--r--net/nft-qos/files/nft-qos.config12
-rwxr-xr-xnet/nft-qos/files/nft-qos.init5
4 files changed, 107 insertions, 0 deletions
diff --git a/net/nft-qos/files/lib/core.sh b/net/nft-qos/files/lib/core.sh
index d3c9d641f..8b51122bb 100644
--- a/net/nft-qos/files/lib/core.sh
+++ b/net/nft-qos/files/lib/core.sh
@@ -34,6 +34,17 @@ qosdef_append_rule_ip_limit() { # <ipaddr> <operator> <unit> <rate>
"\t\tip $operator $ipaddr limit rate over $rate $unit/second drop\n"
}
+# qosdef_append_rule_{MATCH}_{STATEMENT}
+qosdef_append_rule_mac_limit() { # <macaddr> <operator> <unit> <rate>
+ local macaddr=$1
+ local operator=$2
+ local unit=$3
+ local rate=$4
+
+ qosdef_appendx \
+ "\t\tether $operator $macaddr limit rate over $rate $unit/second drop\n"
+}
+
# qosdef_append_rule_{MATCH}_{POLICY}
qosdef_append_rule_ip_policy() { # <operator> <ipaddr> <policy>
qosdef_appendx "\t\tip $1 $2 $3\n"
diff --git a/net/nft-qos/files/lib/mac.sh b/net/nft-qos/files/lib/mac.sh
new file mode 100644
index 000000000..ed1070414
--- /dev/null
+++ b/net/nft-qos/files/lib/mac.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+# based on static.sh
+# Copyright (C) 2020 Tong Zhang<ztong0001@gmail.com>
+#
+
+. /lib/nft-qos/core.sh
+
+qosdef_validate_mac() {
+ uci_load_validate nft-qos default "$1" "$2" \
+ 'limit_mac_enable:bool:0'
+}
+
+# append rule for mac qos
+qosdef_append_rule_mac() { # <section> <operator>
+ local macaddr unit rate
+ local operator=$2
+
+ config_get macaddr $1 macaddr
+ if [ "$operator" = "saddr" ]; then
+ config_get unit $1 urunit
+ config_get rate $1 urate
+ else
+ config_get unit $1 drunit
+ config_get rate $1 drate
+ fi
+
+ [ -z "$macaddr" ] && return
+
+ qosdef_append_rule_mac_limit $macaddr $operator $unit $rate
+}
+
+# append chain for mac qos
+qosdef_append_chain_mac() { # <hook> <name> <section>
+ local hook=$1 name=$2
+ local config=$3 operator
+
+ case "$name" in
+ download) operator="daddr";;
+ upload) operator="saddr";;
+ esac
+
+ qosdef_appendx "\tchain $name {\n"
+ qosdef_append_chain_def filter $hook 0 accept
+ config_foreach qosdef_append_rule_mac $config $operator
+ qosdef_appendx "\t}\n"
+}
+
+qosdef_flush_mac() {
+ if [ -n "$NFT_QOS_HAS_BRIDGE" ]; then
+ qosdef_flush_table bridge nft-qos-mac
+ else
+ qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-mac
+ fi
+}
+
+# limit rate by mac address init
+qosdef_init_mac() {
+ local hook_ul="prerouting" hook_dl="postrouting"
+
+ [ "$2" = 0 ] || {
+ logger -t nft-qos-mac "validation failed"
+ return 1
+ }
+
+ [ $limit_mac_enable -eq 0 ] && return 1
+
+ table_name=$NFT_QOS_INET_FAMILY
+ if [ -z "$NFT_QOS_HAS_BRIDGE" ]; then
+ hook_ul="postrouting"
+ hook_dl="prerouting"
+ else
+ table_name="bridge"
+ fi
+
+ qosdef_appendx "table $table_name nft-qos-mac {\n"
+ qosdef_append_chain_mac $hook_ul upload client
+ qosdef_append_chain_mac $hook_dl download client
+ qosdef_appendx "}\n"
+}
diff --git a/net/nft-qos/files/nft-qos.config b/net/nft-qos/files/nft-qos.config
index 82e3b3928..ea1f4a7ba 100644
--- a/net/nft-qos/files/nft-qos.config
+++ b/net/nft-qos/files/nft-qos.config
@@ -51,6 +51,9 @@ config default default
# list limit_whitelist '192.168.1.0/24'
# list limit_whitelist 'ABCD:CDEF::1/64'
+ # Option for Mac address based traffic control
+ option limit_mac_enable '0'
+
# Options for Traffic Priority
option priority_enable '0'
option priority_netdev 'lan'
@@ -73,6 +76,15 @@ config default default
# option ipaddr 'ABCD:FFED::1/64'
# option rate '1024'
#
+# For MAC address based traffic control Samples :
+#
+#config client
+# option drunit 'kbytes'
+# option urunit 'kbytes'
+# option hostname 'tvbox'
+# option macaddr '00:00:00:00:00:00'
+# option drate '300'
+# option urate '30'
#
# Traffic Priority Samples :
#
diff --git a/net/nft-qos/files/nft-qos.init b/net/nft-qos/files/nft-qos.init
index 7a56ec7c6..dcd487fa5 100755
--- a/net/nft-qos/files/nft-qos.init
+++ b/net/nft-qos/files/nft-qos.init
@@ -7,6 +7,7 @@
. /lib/nft-qos/monitor.sh
. /lib/nft-qos/dynamic.sh
. /lib/nft-qos/static.sh
+. /lib/nft-qos/mac.sh
. /lib/nft-qos/priority.sh
START=99
@@ -19,6 +20,7 @@ service_triggers() {
qosdef_validate_dynamic
qosdef_validate_static
qosdef_validate_priority
+ qosdef_validate_mac
procd_close_validate
}
@@ -26,6 +28,7 @@ start_service() {
config_load nft-qos
qosdef_init_env
+ qosdef_flush_mac
qosdef_flush_static
qosdef_flush_dynamic
qosdef_remove_priority
@@ -34,6 +37,7 @@ start_service() {
qosdef_init_monitor
qosdef_validate_dynamic default qosdef_init_dynamic
qosdef_validate_static default qosdef_init_static
+ qosdef_validate_mac default qosdef_init_mac
qosdef_validate_priority default qosdef_init_priority
qosdef_init_done
qosdef_start
@@ -42,6 +46,7 @@ start_service() {
stop_service() {
qosdef_flush_dynamic
qosdef_flush_static
+ qosdef_flush_mac
qosdef_remove_priority
qosdef_clean_cache
}