mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-11-01 10:57:47 +00:00
The function looking up the rate was leaking a local variable into the global space Signed-off-by: John Crispin <john@phrozen.org>
177 lines
3.6 KiB
Bash
Executable File
177 lines
3.6 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
|
|
wrapper() {
|
|
echo calling $*
|
|
$*
|
|
}
|
|
|
|
TC() {
|
|
wrapper tc $*
|
|
}
|
|
|
|
IP() {
|
|
wrapper ip $*
|
|
}
|
|
|
|
get_id() {
|
|
addr=$1
|
|
hashval="0x$(echo "$addr" | md5sum | head -c8)"
|
|
mask=0x4ff
|
|
echo $(($hashval & $mask))
|
|
}
|
|
|
|
delclient() {
|
|
local ifb=rateifb$1
|
|
local iface=$1
|
|
local mac=$2
|
|
local id=$3
|
|
|
|
logger "ratelimit: delete old client entries"
|
|
|
|
[ -z "$id" ] && id=$(get_id ${mac//:})
|
|
|
|
TC filter del dev $iface protocol all parent 1: prio 1 u32 match ether dst $mac flowid 1:$id
|
|
TC class del dev $iface parent 1:1 classid 1:$id
|
|
|
|
TC filter del dev $ifb protocol all parent 1: prio 1 u32 match ether src $mac flowid 1:$id
|
|
TC class del dev $ifb parent 1:1 classid 1:$id
|
|
}
|
|
|
|
ingress=0
|
|
egress=0
|
|
|
|
getrate() {
|
|
config_get ssid $1 ssid
|
|
[ "$ssid" == "$2" ] || return
|
|
config_get ingress $1 ingress
|
|
config_get egress $1 egress
|
|
}
|
|
|
|
addclient() {
|
|
local ifb=rateifb$1
|
|
local iface=$1
|
|
local mac=$2
|
|
local ssid=$(cat /tmp/ratelimit.$iface)
|
|
|
|
egress=$3
|
|
ingress=$4
|
|
|
|
logger "ratelimit: adding client"
|
|
|
|
[ "$egress" -eq 0 -o $ingress -eq 0 ] && {
|
|
config_load ratelimit
|
|
config_foreach getrate rate $ssid
|
|
}
|
|
|
|
[ "$egress" -eq 0 -o $ingress -eq 0 ] && {
|
|
logger "ratelimit: no valid rates"
|
|
exit 1
|
|
}
|
|
|
|
local id=$(get_id ${mac//:})
|
|
|
|
logger "ratelimit: add new client entries for $2 $egress $ingress"
|
|
|
|
TC class add dev $iface parent 1:1 classid 1:$id htb rate 1mbit ceil ${egress}mbit burst 2k prio 1
|
|
TC qdisc add dev $iface parent 1:$id handle $id: sfq perturb 10
|
|
TC filter add dev $iface protocol all parent 1: prio 1 u32 match ether dst $mac flowid 1:$id
|
|
|
|
TC class add dev $ifb parent 1:1 classid 1:$id htb rate 1mbit ceil ${ingress}mbit burst 2k prio 1
|
|
TC filter add dev $ifb protocol all parent 1: prio 1 u32 match ether src $mac flowid 1:$id
|
|
}
|
|
|
|
deliface() {
|
|
local ifb=rateifb$1
|
|
local iface=$1
|
|
|
|
[ -d /sys/class/net/$ifb/ ] || return 0
|
|
|
|
logger "ratelimit: deleting old iface settings"
|
|
|
|
IP link set $ifb down
|
|
IP link del $ifb
|
|
|
|
TC qdisc del dev $iface root &2> /dev/null
|
|
|
|
rm -f /tmp/ratelimit.$iface
|
|
[ -f /tmp/run/hostapd-cli-$iface.pid ] && kill "$(cat /tmp/run/hostapd-cli-$iface.pid)"
|
|
}
|
|
|
|
found=0
|
|
find_ssid() {
|
|
local ssid
|
|
config_get ssid $1 ssid
|
|
[ "$ssid" == "$2" ] || return
|
|
found=1
|
|
}
|
|
|
|
addiface() {
|
|
local ifb=rateifb$1
|
|
local iface=$1
|
|
local ssid
|
|
|
|
|
|
[ -f /tmp/ratelimit.$iface -o -d /sys/class/net/$ifb/ ] && {
|
|
return 0
|
|
}
|
|
|
|
echo -n startup > /tmp/ratelimit.$iface
|
|
|
|
sleep 2
|
|
ssid=$(ubus call hostapd.$iface get_status | jsonfilter -e '@.ssid')
|
|
[ -z "$ssid" ] && {
|
|
rm /tmp/ratelimit.$iface
|
|
logger "ratelimit: failed to lookup ssid"
|
|
exit 1
|
|
}
|
|
config_load ratelimit
|
|
config_foreach find_ssid rate $ssid
|
|
[ "$found" -eq 0 ] && {
|
|
rm /tmp/ratelimit.$iface
|
|
exit 0
|
|
}
|
|
logger "ratelimit: adding new iface settings"
|
|
|
|
echo -n $ssid > /tmp/ratelimit.$iface
|
|
|
|
IP link add name $ifb type ifb
|
|
IP link set $ifb up
|
|
|
|
sleep 1
|
|
|
|
TC qdisc add dev $iface root handle 1: htb default 30
|
|
TC class add dev $iface parent 1: classid 1:1 htb rate 1000mbit burst 6k
|
|
TC qdisc add dev $iface ingress
|
|
TC filter add dev $iface parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev $ifb
|
|
|
|
TC qdisc add dev $ifb root handle 1: htb default 10
|
|
TC class add dev $ifb parent 1: classid 1:1 htb rate 100mbit
|
|
hostapd_cli -a /usr/libexec/ratelimit.sh -i $iface -P /tmp/run/hostapd-cli-$iface.pid -B
|
|
|
|
for sta in $(ubus call wifi station | jsonfilter -e '@[*][*].mac'); do
|
|
addclient $iface $sta
|
|
done
|
|
}
|
|
|
|
waitiface() {
|
|
local iface=$1
|
|
|
|
ubus -t 120 wait_for hostapd.$1
|
|
|
|
[ $? -eq 0 ] || exit 0
|
|
|
|
addiface $iface
|
|
}
|
|
|
|
flush() {
|
|
for a in `ls /sys/class/net/ | grep rateifb`; do
|
|
deliface ${a:7}
|
|
done
|
|
}
|
|
|
|
cmd=$1
|
|
shift
|
|
$cmd $@
|