update 2023-06-22 00:22:29
This commit is contained in:
parent
53383276e6
commit
4b75020669
|
@ -0,0 +1,59 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=nft-qos
|
||||||
|
PKG_VERSION:=1.0.6
|
||||||
|
PKG_RELEASE:=4
|
||||||
|
PKG_LICENSE:=GPL-2.0
|
||||||
|
|
||||||
|
PKG_MAINTAINER:=Rosy Song <rosysong@rosinson.com>
|
||||||
|
|
||||||
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define Package/nft-qos
|
||||||
|
SECTION:=utils
|
||||||
|
CATEGORY:=Base system
|
||||||
|
DEPENDS:=+kmod-nft-netdev +kmod-nft-bridge +nftables
|
||||||
|
TITLE:=QoS scripts over nftables
|
||||||
|
PKGARCH:=all
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/nft-qos/description
|
||||||
|
This package provides implementation for qos over nftables.
|
||||||
|
Currently, static/dynamic qos and traffic shaping are supported.
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/nft-qos/conffiles
|
||||||
|
/etc/config/nft-qos
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Configure
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/nft-qos/install
|
||||||
|
$(INSTALL_DIR) $(1)/lib/nft-qos
|
||||||
|
$(INSTALL_DATA) ./files/lib/* $(1)/lib/nft-qos/
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_CONF) ./files/nft-qos.config $(1)/etc/config/nft-qos
|
||||||
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
|
$(INSTALL_BIN) ./files/nft-qos.init $(1)/etc/init.d/nft-qos
|
||||||
|
$(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp
|
||||||
|
$(INSTALL_BIN) ./files/nft-qos-monitor.hotplug $(1)/etc/hotplug.d/dhcp/00-nft-qos-monitor
|
||||||
|
$(INSTALL_BIN) ./files/nft-qos-dynamic.hotplug $(1)/etc/hotplug.d/dhcp/01-nft-qos-dynamic
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackage,nft-qos))
|
|
@ -0,0 +1,104 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
# for uci_validate_section()
|
||||||
|
. /lib/functions/procd.sh
|
||||||
|
|
||||||
|
NFT_QOS_HAS_BRIDGE=
|
||||||
|
NFT_QOS_INET_FAMILY=ip
|
||||||
|
NFT_QOS_SCRIPT_TEXT=
|
||||||
|
NFT_QOS_SCRIPT_FILE=/tmp/qos.nft
|
||||||
|
|
||||||
|
qosdef_appendx() { # <string to be appended>
|
||||||
|
NFT_QOS_SCRIPT_TEXT="$NFT_QOS_SCRIPT_TEXT""$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_append_chain_def() { # <type> <hook> <priority> <policy>
|
||||||
|
qosdef_appendx "\t\ttype $1 hook $2 priority $3; policy $4;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_append_chain_ingress() { # <type> <device> <priority> <policy>
|
||||||
|
qosdef_appendx "\t\ttype $1 hook ingress device $2 priority $3; policy $4;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# qosdef_append_rule_{MATCH}_{STATEMENT}
|
||||||
|
qosdef_append_rule_ip_limit() { # <ipaddr> <operator> <unit> <rate>
|
||||||
|
local ipaddr=$1
|
||||||
|
local operator=$2
|
||||||
|
local unit=$3
|
||||||
|
local rate=$4
|
||||||
|
|
||||||
|
qosdef_appendx \
|
||||||
|
"\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"
|
||||||
|
}
|
||||||
|
|
||||||
|
_handle_limit_whitelist() { # <value> <chain>
|
||||||
|
local ipaddr=$1
|
||||||
|
local operator
|
||||||
|
|
||||||
|
[ -z "$ipaddr" ] && return
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
download) operator="daddr";;
|
||||||
|
upload) operator="saddr";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
qosdef_append_rule_ip_policy $operator $ipaddr accept
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_append_rule_limit_whitelist() { # <chain>
|
||||||
|
config_list_foreach default limit_whitelist _handle_limit_whitelist $1
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_flush_table() { # <family> <table>
|
||||||
|
nft flush table $1 $2 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_remove_table() { # <family> <table>
|
||||||
|
nft delete table $1 $2 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_init_header() { # add header for nft script
|
||||||
|
qosdef_appendx "#!/usr/sbin/nft -f\n"
|
||||||
|
qosdef_appendx "# Copyright (C) 2018 rosysong@rosinson.com\n"
|
||||||
|
qosdef_appendx "#\n\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_init_env() {
|
||||||
|
# check interface type of lan
|
||||||
|
local lt="$(uci_get "network.lan.type")"
|
||||||
|
[ "$lt" = "bridge" ] && export NFT_QOS_HAS_BRIDGE="y"
|
||||||
|
|
||||||
|
# check if ipv6 support
|
||||||
|
[ -e /proc/sys/net/ipv6 ] && export NFT_QOS_INET_FAMILY="inet"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_clean_cache() {
|
||||||
|
rm -f $NFT_QOS_SCRIPT_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_init_done() {
|
||||||
|
echo -e $NFT_QOS_SCRIPT_TEXT > $NFT_QOS_SCRIPT_FILE 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_start() {
|
||||||
|
nft -f $NFT_QOS_SCRIPT_FILE 2>/dev/null
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
. /lib/nft-qos/core.sh
|
||||||
|
|
||||||
|
qosdef_validate_dynamic() {
|
||||||
|
uci_load_validate nft-qos default "$1" "$2" \
|
||||||
|
'limit_enable:bool:0' \
|
||||||
|
'limit_type:maxlength(8)' \
|
||||||
|
'dynamic_bw_up:uinteger:100' \
|
||||||
|
'dynamic_bw_down:uinteger:100'
|
||||||
|
}
|
||||||
|
|
||||||
|
# return average rate for dhcp leases
|
||||||
|
qosdef_dynamic_rate() { # <bandwidth>
|
||||||
|
local c=0 c6=0
|
||||||
|
|
||||||
|
[ ! -e /tmp/dhcp.leases -a \
|
||||||
|
! -e /var/dhcp6.leases ] && return
|
||||||
|
|
||||||
|
[ -e /tmp/dhcp.leases ] && \
|
||||||
|
c=$(wc -l < /tmp/dhcp.leases 2>/dev/null)
|
||||||
|
[ -e /var/dhcp6.leases ] && \
|
||||||
|
c6=$(wc -l < /var/dhcp6.leases 2>/dev/null)
|
||||||
|
[ $c -eq 0 -a $c6 -eq 0 ] && \
|
||||||
|
{ echo 12500; return; }
|
||||||
|
|
||||||
|
echo $(($1 / ($c + $c6)))
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_append_chain_dym() { # <hook> <name> <bandwidth>
|
||||||
|
local cidr cidr6
|
||||||
|
local operator rate
|
||||||
|
local hook=$1 name=$2 bandwidth=$3
|
||||||
|
|
||||||
|
config_get cidr default 'dynamic_cidr'
|
||||||
|
config_get cidr6 default 'dynamic_cidr6'
|
||||||
|
|
||||||
|
[ -z "$cidr" -a -z "$cidr6" ] && return
|
||||||
|
|
||||||
|
case "$2" in
|
||||||
|
download) operator=daddr;;
|
||||||
|
upload) operator=saddr;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
rate=$(qosdef_dynamic_rate $bandwidth)
|
||||||
|
|
||||||
|
qosdef_appendx "\tchain $name {\n"
|
||||||
|
qosdef_append_chain_def filter $hook 0 accept
|
||||||
|
qosdef_append_rule_limit_whitelist $name
|
||||||
|
[ -n "$cidr" ] && \
|
||||||
|
qosdef_append_rule_ip_limit $cidr $operator kbytes $rate
|
||||||
|
[ -n "$cidr6" ] && \
|
||||||
|
qosdef_append_rule_ip_limit $cidr6 $operator kbytes $rate
|
||||||
|
qosdef_appendx "\t}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_flush_dynamic() {
|
||||||
|
qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-dynamic
|
||||||
|
}
|
||||||
|
|
||||||
|
# init dynamic qos
|
||||||
|
qosdef_init_dynamic() {
|
||||||
|
local hook_ul="prerouting" hook_dl="postrouting"
|
||||||
|
|
||||||
|
[ "$2" = 0 ] || {
|
||||||
|
logger -t nft-qos-dynamic "validation failed"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ $limit_enable -eq 0 -o \
|
||||||
|
"$limit_type" = "static" ] && return 1
|
||||||
|
|
||||||
|
# Transfer mbits/s to mbytes/s
|
||||||
|
# e.g. 100,000 kbits == 12,500 kbytes
|
||||||
|
dynamic_bw_up=$(($dynamic_bw_up * 1000 / 8))
|
||||||
|
dynamic_bw_down=$(($dynamic_bw_down * 1000 / 8))
|
||||||
|
|
||||||
|
[ -z "$NFT_QOS_HAS_BRIDGE" ] && {
|
||||||
|
hook_ul="postrouting"
|
||||||
|
hook_dl="prerouting"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_appendx "table $NFT_QOS_INET_FAMILY nft-qos-dynamic {\n"
|
||||||
|
qosdef_append_chain_dym $hook_ul upload $dynamic_bw_up
|
||||||
|
qosdef_append_chain_dym $hook_dl download $dynamic_bw_down
|
||||||
|
qosdef_appendx "}\n"
|
||||||
|
}
|
|
@ -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"
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
. /lib/nft-qos/core.sh
|
||||||
|
|
||||||
|
qosdef_monitor_get_ip_handle() { # <family> <chain> <ip>
|
||||||
|
echo $(nft -a list chain $1 nft-qos-monitor $2 2>/dev/null | grep $3 | awk '{print $11}')
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_monitor_add() { # <mac> <ip> <hostname>
|
||||||
|
handle_dl=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY download $2)
|
||||||
|
[ -z "$handle_dl" ] && nft add rule $NFT_QOS_INET_FAMILY nft-qos-monitor download ip daddr $2 counter
|
||||||
|
handle_ul=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY upload $2)
|
||||||
|
[ -z "$handle_ul" ] && nft add rule $NFT_QOS_INET_FAMILY nft-qos-monitor upload ip saddr $2 counter
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_monitor_del() { # <mac> <ip> <hostname>
|
||||||
|
local handle_dl handle_ul
|
||||||
|
handle_dl=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY download $2)
|
||||||
|
handle_ul=$(qosdef_monitor_get_ip_handle $NFT_QOS_INET_FAMILY upload $2)
|
||||||
|
[ -n "$handle_dl" ] && nft delete handle $handle_dl
|
||||||
|
[ -n "$handle_ul" ] && nft delete handle $handle_ul
|
||||||
|
}
|
||||||
|
|
||||||
|
# init qos monitor
|
||||||
|
qosdef_init_monitor() {
|
||||||
|
local hook_ul="prerouting" hook_dl="postrouting"
|
||||||
|
|
||||||
|
[ -z "$NFT_QOS_HAS_BRIDGE" ] && {
|
||||||
|
hook_ul="postrouting"
|
||||||
|
hook_dl="prerouting"
|
||||||
|
}
|
||||||
|
|
||||||
|
nft add table $NFT_QOS_INET_FAMILY nft-qos-monitor
|
||||||
|
nft add chain $NFT_QOS_INET_FAMILY nft-qos-monitor upload { type filter hook $hook_ul priority 0\; }
|
||||||
|
nft add chain $NFT_QOS_INET_FAMILY nft-qos-monitor download { type filter hook $hook_dl priority 0\; }
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
. /lib/functions/network.sh
|
||||||
|
. /lib/nft-qos/core.sh
|
||||||
|
|
||||||
|
P1=""; P2=""; P3=""; P4=""; P5=""; P6="";
|
||||||
|
P7=""; P8=""; P9=""; P10=""; P11="";
|
||||||
|
|
||||||
|
qosdef_validate_priority() {
|
||||||
|
uci_load_validate nft-qos default "$1" "$2" \
|
||||||
|
'priority_enable:bool:0' \
|
||||||
|
'priority_netdev:maxlength(8)'
|
||||||
|
}
|
||||||
|
|
||||||
|
_qosdef_handle_protox() { # <priority> <rule>
|
||||||
|
case "$1" in
|
||||||
|
-400) P1="$P1""$2";;
|
||||||
|
-300) P2="$P2""$2";;
|
||||||
|
-225) P3="$P3""$2";;
|
||||||
|
-200) P4="$P4""$2";;
|
||||||
|
-150) P5="$P5""$2";;
|
||||||
|
-100) P6="$P6""$2";;
|
||||||
|
0) P7="$P7""$2";;
|
||||||
|
50) P8="$P8""$2";;
|
||||||
|
100) P9="$P9""$2";;
|
||||||
|
225) P10="$P10""$2";;
|
||||||
|
300) P11="$P11""$2";;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_handle_protox() { # <section>
|
||||||
|
local proto prio srv
|
||||||
|
|
||||||
|
config_get proto $1 'protocol'
|
||||||
|
config_get prio $1 'priority'
|
||||||
|
config_get srv $1 'service'
|
||||||
|
|
||||||
|
[ -z "$proto" -o \
|
||||||
|
-z "$prio" -o \
|
||||||
|
-z "$srv" ] && return
|
||||||
|
|
||||||
|
_qosdef_handle_protox $prio \
|
||||||
|
"\t\t$proto dport { $srv } accept\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_append_rule_protox() { # <section>
|
||||||
|
config_foreach qosdef_handle_protox $1
|
||||||
|
qosdef_appendx \
|
||||||
|
"${P1}${P2}${P3}${P4}${P5}${P6}${P7}${P8}${P9}${P10}${P11}"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_append_chain_priority() { # <name> <section> <device>
|
||||||
|
local name=$1 device=$3
|
||||||
|
|
||||||
|
qosdef_appendx "\tchain $name {\n"
|
||||||
|
qosdef_append_chain_ingress filter $device 0 accept
|
||||||
|
qosdef_append_rule_protox $2
|
||||||
|
qosdef_appendx "\t}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_remove_priority() {
|
||||||
|
qosdef_remove_table netdev nft-qos-priority
|
||||||
|
}
|
||||||
|
|
||||||
|
# init traffic priority
|
||||||
|
qosdef_init_priority() {
|
||||||
|
[ "$2" = 0 ] || {
|
||||||
|
logger -t nft-qos-priority "validation failed"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ $priority_enable -eq 0 ] && return 1
|
||||||
|
|
||||||
|
local ifname
|
||||||
|
network_get_device ifname "$priority_netdev"
|
||||||
|
[ -n "$ifname" ] || {
|
||||||
|
logger -t nft-qos-priority "unable to get ifname for $priority_netdev"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_appendx "table netdev nft-qos-priority {\n"
|
||||||
|
qosdef_append_chain_priority filter priority $ifname
|
||||||
|
qosdef_appendx "}\n"
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
. /lib/nft-qos/core.sh
|
||||||
|
|
||||||
|
qosdef_validate_static() {
|
||||||
|
uci_load_validate nft-qos default "$1" "$2" \
|
||||||
|
'limit_enable:bool:0' \
|
||||||
|
'limit_type:maxlength(8)' \
|
||||||
|
'static_unit_dl:string:kbytes' \
|
||||||
|
'static_unit_ul:string:kbytes' \
|
||||||
|
'static_rate_dl:uinteger:50' \
|
||||||
|
'static_rate_ul:uinteger:50'
|
||||||
|
}
|
||||||
|
|
||||||
|
# append rule for static qos
|
||||||
|
qosdef_append_rule_sta() { # <section> <operator> <default-unit> <default-rate>
|
||||||
|
local ipaddr unit rate
|
||||||
|
local operator=$2
|
||||||
|
|
||||||
|
config_get ipaddr $1 ipaddr
|
||||||
|
config_get unit $1 unit $3
|
||||||
|
config_get rate $1 rate $4
|
||||||
|
|
||||||
|
[ -z "$ipaddr" ] && return
|
||||||
|
|
||||||
|
qosdef_append_rule_ip_limit $ipaddr $operator $unit $rate
|
||||||
|
}
|
||||||
|
|
||||||
|
# append chain for static qos
|
||||||
|
qosdef_append_chain_sta() { # <hook> <name> <section> <unit> <rate>
|
||||||
|
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
|
||||||
|
qosdef_append_rule_limit_whitelist $name
|
||||||
|
config_foreach qosdef_append_rule_sta $config $operator $4 $5
|
||||||
|
qosdef_appendx "\t}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_flush_static() {
|
||||||
|
qosdef_flush_table "$NFT_QOS_INET_FAMILY" nft-qos-static
|
||||||
|
}
|
||||||
|
|
||||||
|
# static limit rate init
|
||||||
|
qosdef_init_static() {
|
||||||
|
local hook_ul="prerouting" hook_dl="postrouting"
|
||||||
|
|
||||||
|
[ "$2" = 0 ] || {
|
||||||
|
logger -t nft-qos-static "validation failed"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[ $limit_enable -eq 0 -o \
|
||||||
|
$limit_type = "dynamic" ] && return 1
|
||||||
|
|
||||||
|
[ -z "$NFT_QOS_HAS_BRIDGE" ] && {
|
||||||
|
hook_ul="postrouting"
|
||||||
|
hook_dl="prerouting"
|
||||||
|
}
|
||||||
|
|
||||||
|
qosdef_appendx "table $NFT_QOS_INET_FAMILY nft-qos-static {\n"
|
||||||
|
qosdef_append_chain_sta $hook_ul upload upload $static_unit_ul $static_rate_ul
|
||||||
|
qosdef_append_chain_sta $hook_dl download download $static_unit_dl $static_rate_dl
|
||||||
|
qosdef_appendx "}\n"
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
export initscript="nft-qos-dynamic"
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
. /lib/nft-qos/core.sh
|
||||||
|
. /lib/nft-qos/dynamic.sh
|
||||||
|
|
||||||
|
NFT_QOS_DYNAMIC_ON=
|
||||||
|
|
||||||
|
qosdef_check_if_dynamic() {
|
||||||
|
[ $limit_enable -eq 1 -a \
|
||||||
|
"$limit_type" = "dynamic" ] && \
|
||||||
|
NFT_QOS_DYNAMIC_ON="y"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
logger -t nft-qos-dynamic "ACTION=$ACTION, MACADDR=$MACADDR, IPADDR=$IPADDR, HOSTNAME=$HOSTNAME"
|
||||||
|
|
||||||
|
case "$ACTION" in
|
||||||
|
add | update | remove)
|
||||||
|
qosdef_validate_dynamic default qosdef_check_if_dynamic
|
||||||
|
[ -z "$NFT_QOS_DYNAMIC_ON" ] && return
|
||||||
|
|
||||||
|
qosdef_init_env
|
||||||
|
qosdef_flush_dynamic
|
||||||
|
|
||||||
|
qosdef_init_header
|
||||||
|
qosdef_validate_dynamic default qosdef_init_dynamic
|
||||||
|
qosdef_init_done
|
||||||
|
qosdef_start
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
export initscript="nft-qos-monitor"
|
||||||
|
|
||||||
|
. /lib/nft-qos/monitor.sh
|
||||||
|
|
||||||
|
logger -t nft-qos-monitor "ACTION=$ACTION, MACADDR=$MACADDR, IPADDR=$IPADDR, HOSTNAME=$HOSTNAME"
|
||||||
|
|
||||||
|
case "$ACTION" in
|
||||||
|
add | update)
|
||||||
|
qosdef_init_env
|
||||||
|
qosdef_init_monitor
|
||||||
|
qosdef_monitor_add $MACADDR $IPADDR $HOSTNAME
|
||||||
|
;;
|
||||||
|
remove)
|
||||||
|
qosdef_init_env
|
||||||
|
qosdef_init_monitor
|
||||||
|
qosdef_monitor_del $MACADDR $IPADDR $HOSTNAME
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -0,0 +1,119 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
# This is the sample for nft-qos configuration file,
|
||||||
|
# which will generate a nftables script in /tmp/qos.nft
|
||||||
|
#
|
||||||
|
|
||||||
|
# Getting Started
|
||||||
|
# Official site :
|
||||||
|
# https://netfilter.org/projects/nftables/index.html
|
||||||
|
# What is nftables :
|
||||||
|
# https://wiki.nftables.org/wiki-nftables/index.php/Main_Page
|
||||||
|
#
|
||||||
|
|
||||||
|
# Basic Operations
|
||||||
|
# Configuring Tables :
|
||||||
|
# https://wiki.nftables.org/wiki-nftables/index.php/Configuring_tables
|
||||||
|
# Configuring Chains :
|
||||||
|
# https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains
|
||||||
|
# Configuring Rules :
|
||||||
|
# https://wiki.nftables.org/wiki-nftables/index.php/Simple_rule_management
|
||||||
|
# Quick Reference (recommended) :
|
||||||
|
# https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes
|
||||||
|
# https://netfilter.org/projects/nftables/manpage.html
|
||||||
|
#
|
||||||
|
|
||||||
|
config default default
|
||||||
|
# Enable Flag for limit rate
|
||||||
|
option limit_enable '1'
|
||||||
|
|
||||||
|
# Options for enable Static QoS (rate limit)
|
||||||
|
option limit_type 'static'
|
||||||
|
# Options for Static QoS (rate limit)
|
||||||
|
option static_unit_dl 'kbytes'
|
||||||
|
option static_unit_ul 'kbytes'
|
||||||
|
option static_rate_dl '50'
|
||||||
|
option static_rate_ul '50'
|
||||||
|
|
||||||
|
# Options for enable Dynamic QoS
|
||||||
|
# This option can not compatible with Static QoS
|
||||||
|
# option limit_type 'dynamic'
|
||||||
|
|
||||||
|
# For Dynamic QoS Samples (unit of bandwidth is Mbps):
|
||||||
|
option dynamic_cidr '192.168.1.0/24'
|
||||||
|
option dynamic_cidr6 'AAAA:BBBB::1/64'
|
||||||
|
option dynamic_bw_up '100'
|
||||||
|
option dynamic_bw_down '100'
|
||||||
|
|
||||||
|
# White list for static/dynamic limit
|
||||||
|
# list limit_whitelist '192.168.1.225'
|
||||||
|
# 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'
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# For Static QoS Rate Limit Samples :
|
||||||
|
#
|
||||||
|
# For Download :
|
||||||
|
#config download
|
||||||
|
# option hostname 'My PC'
|
||||||
|
# option unit 'kbytes'
|
||||||
|
# option ipaddr '192.168.1.224'
|
||||||
|
# option rate '128'
|
||||||
|
#
|
||||||
|
# For Upload :
|
||||||
|
#config upload
|
||||||
|
# option hostname 'office-pc'
|
||||||
|
# option unit 'mbytes'
|
||||||
|
# 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 :
|
||||||
|
#
|
||||||
|
# protocol : tcp, udp, udplite, sctp, dccp, tcp is default
|
||||||
|
# priority : integer between 1-11, 1 is default and the highest
|
||||||
|
# service : you can input a integer or service name,
|
||||||
|
# e.g. '22', '11-22', 'telnet', 'ssh, http, ftp', etc
|
||||||
|
#
|
||||||
|
#config priority
|
||||||
|
# option protocol 'tcp'
|
||||||
|
# option priority '-400'
|
||||||
|
# option service '23'
|
||||||
|
# option comment '?'
|
||||||
|
#
|
||||||
|
#config priority
|
||||||
|
# option protocol 'udp'
|
||||||
|
# option priority '-400'
|
||||||
|
# option service 'https'
|
||||||
|
# option comment '?'
|
||||||
|
#
|
||||||
|
#config priority
|
||||||
|
# option protocol 'dccp'
|
||||||
|
# option priority '0'
|
||||||
|
# option service '22-35'
|
||||||
|
# option comment '?'
|
||||||
|
#
|
||||||
|
#config priority
|
||||||
|
# option protocol 'dccp'
|
||||||
|
# option priority '300'
|
||||||
|
# option service 'ftp,ssh,http'
|
||||||
|
# option comment '?'
|
||||||
|
#
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/sh /etc/rc.common
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 rosysong@rosinson.com
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ -z "${IPKG_INSTROOT}" ]; then
|
||||||
|
. /lib/nft-qos/core.sh
|
||||||
|
. /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
|
||||||
|
fi
|
||||||
|
|
||||||
|
START=99
|
||||||
|
USE_PROCD=1
|
||||||
|
|
||||||
|
service_triggers() {
|
||||||
|
procd_add_reload_trigger nft-qos
|
||||||
|
|
||||||
|
procd_open_validate
|
||||||
|
qosdef_validate_dynamic
|
||||||
|
qosdef_validate_static
|
||||||
|
qosdef_validate_priority
|
||||||
|
qosdef_validate_mac
|
||||||
|
procd_close_validate
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
config_load nft-qos
|
||||||
|
|
||||||
|
qosdef_init_env
|
||||||
|
qosdef_flush_mac
|
||||||
|
qosdef_flush_static
|
||||||
|
qosdef_flush_dynamic
|
||||||
|
qosdef_remove_priority
|
||||||
|
|
||||||
|
qosdef_init_header
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
qosdef_flush_dynamic
|
||||||
|
qosdef_flush_static
|
||||||
|
qosdef_flush_mac
|
||||||
|
qosdef_remove_priority
|
||||||
|
qosdef_clean_cache
|
||||||
|
}
|
Loading…
Reference in New Issue