-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ffda-wireless-rate-limiter: add package
This adds a package which can be used to shape traffic on the wireless interfaces interface-wide or per-client. Signed-off-by: David Bauer <[email protected]>
- Loading branch information
1 parent
0bc5c69
commit 1186654
Showing
3 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
include $(TOPDIR)/rules.mk | ||
|
||
PKG_NAME:=ffda-wireless-rate-limiter | ||
PKG_RELEASE:=1 | ||
|
||
PKG_SOURCE_PROTO:=git | ||
PKG_SOURCE_URL=https://github.com/blocktrron/wireless-rate-limiter.git | ||
PKG_SOURCE_DATE:=2024-08-24 | ||
PKG_SOURCE_VERSION:=1fedb08ba7ce347d5c3f7c8ddcac8a5e2f5d14b6 | ||
|
||
PKG_MAINTAINER:=David Bauer <[email protected]> | ||
PKG_LICENSE:=GPL-2.0 | ||
|
||
include $(TOPDIR)/../package/gluon.mk | ||
include $(INCLUDE_DIR)/cmake.mk | ||
|
||
CMAKE_SOURCE_SUBDIR:=src | ||
|
||
define Package/ffda-wireless-rate-limiter | ||
TITLE:=Package to provide diagnostic information using WiFi beacons | ||
DEPENDS:=+libubox +libubus +libblobmsg-json +tc +kmod-sched-core +kmod-ifb +gluon-core | ||
endef | ||
|
||
define Package/ffda-wireless-rate-limiter/description | ||
Package to impose per-interface and per-client rate limits on a wireless interface | ||
endef | ||
|
||
define Package/ffda-wireless-rate-limiter/conffiles | ||
/etc/config/wireless-rate-limiter | ||
endef | ||
|
||
define Package/ffda-wireless-rate-limiter/install | ||
$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/init.d $(1)/etc/config $(1)/lib/wireless-rate-limiter $(1)/lib/gluon/upgrade | ||
|
||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/wireless-rate-limiter $(1)/usr/bin/wireless-rate-limiter | ||
|
||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/openwrt/wireless-rate-limiter/files/wireless-rate-limiter.init $(1)/etc/init.d/wireless-rate-limiter | ||
|
||
$(CP) $(PKG_BUILD_DIR)/openwrt/wireless-rate-limiter/files/wireless-rate-limiter.uci $(1)/etc/config/wireless-rate-limiter | ||
|
||
$(CP) $(PKG_BUILD_DIR)/openwrt/wireless-rate-limiter/files/htb-shared.sh $(1)/lib/wireless-rate-limiter/htb-shared.sh | ||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/openwrt/wireless-rate-limiter/files/htb-client.sh $(1)/lib/wireless-rate-limiter/htb-client.sh | ||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/openwrt/wireless-rate-limiter/files/htb-netdev.sh $(1)/lib/wireless-rate-limiter/htb-netdev.sh | ||
|
||
$(INSTALL_BIN) ./files/wireless-rate-limiter.upgrade.lua $(1)/lib/gluon/upgrade/880-wireless-rate-limiter | ||
endef | ||
|
||
$(eval $(call BuildPackageGluon,ffda-wireless-rate-limiter)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# ffda-wireless-rate-limiter | ||
|
||
This package provides a rate-limiter which can shape traffic per client | ||
and per interface. The limit is user-configurable and defaults can be | ||
applied and updated via the site-config. | ||
|
||
## Examples | ||
### Site | ||
|
||
Below you can see an example of how to configure the rate-limiter | ||
in the site-configuration. | ||
|
||
Each client is shaped to a different rate. | ||
|
||
- On 5 GHz, only the uplink will be shaped. | ||
- On 2.4 GHz, both uplink and downlink will be shaped. Additionally, | ||
all traffic on the 2.4 GHz radios will each be shaped to a maximum | ||
of 10 Mbit/s downlink and 5 Mbit/s uplink. | ||
|
||
When using OWE, the limits are imposed for the unencrypted and OWE network | ||
indepedently. | ||
|
||
```lua | ||
wifi24 = { | ||
channel = 5, -- 2432 MHz | ||
|
||
rate_limit = { | ||
client = { | ||
down = 6000, -- 6 Mbit/s | ||
up = 3000, -- 3 Mbit/s | ||
}, | ||
iface = { | ||
down = 10000, -- 10 Mbit/s | ||
up = 5000, -- 5 Mbit/s | ||
}, | ||
}, | ||
|
||
mesh = { | ||
mcast_rate = 12000, | ||
}, | ||
}, | ||
wifi5 = { | ||
channel = 48, -- 5230 MHz | ||
outdoor_chanlist = '96-116 132-140', | ||
|
||
rate_limit = { | ||
client = { | ||
up = 6000, -- 6 Mbit/s | ||
}, | ||
}, | ||
|
||
mesh = { | ||
mcast_rate = 12000, | ||
}, | ||
}, | ||
``` | ||
|
||
### UCI | ||
|
||
The rate-limiter can also be configured via UCI. The following example is | ||
for a configuration which is equivalent to the site-configuration above. | ||
|
||
```sh | ||
uci set gluon.rate_limit_2g=rate-limit | ||
uci set gluon.rate_limit_2g.client_down=6000 | ||
uci set gluon.rate_limit_2g.client_up=3000 | ||
uci set gluon.rate_limit_2g.iface_down=10000 | ||
uci set gluon.rate_limit_2g.iface_up=5000 | ||
|
||
uci set gluon.rate_limit_5g=rate-limit | ||
uci set gluon.rate_limit_5g.client_up=6000 | ||
uci set gluon.rate_limit_5g.iface_down=10000 | ||
uci set gluon.rate_limit_5g.iface_up=5000 | ||
``` |
106 changes: 106 additions & 0 deletions
106
ffda-wireless-rate-limiter/files/wireless-rate-limiter.upgrade.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#!/usr/bin/lua | ||
|
||
local uci = require('simple-uci').cursor() | ||
local site = require('gluon.site') | ||
local wireless = require('gluon.wireless') | ||
|
||
local function wireless_limits_get() | ||
local output_limits = {} | ||
wireless.foreach_radio(uci, function(radio, index, site_config) | ||
local radio_band = radio.band | ||
local radio_index = radio['.name']:match('^radio(%d+)$') | ||
|
||
local uci_section = 'rate_limit_2g' | ||
if radio_band == '5g' then | ||
uci_section = 'rate_limit_5g' | ||
end | ||
|
||
local limit_table = { | ||
client = { | ||
up = { | ||
['user'] = uci:get('gluon', uci_section, 'client_up'), | ||
['site'] = site_config.rate_limit.client.up(0) | ||
}, | ||
down = { | ||
['user'] = uci:get('gluon', uci_section, 'client_down'), | ||
['site'] = site_config.rate_limit.client.down(0) | ||
} | ||
}, | ||
iface = { | ||
up = { | ||
['user'] = uci:get('gluon', uci_section, 'iface_up'), | ||
['site'] = site_config.rate_limit.up(0) | ||
}, | ||
down = { | ||
['user'] = uci:get('gluon', uci_section, 'iface_down'), | ||
['site'] = site_config.rate_limit.down(0) | ||
} | ||
} | ||
} | ||
|
||
output_limits[radio_band] = { | ||
index = radio_index, | ||
limits = { | ||
client = { | ||
up = limit_table.client.up.user or limit_table.client.up.site, | ||
down = limit_table.client.down.user or limit_table.client.down.site | ||
}, | ||
iface = { | ||
up = limit_table.iface.up.user or limit_table.iface.up.site, | ||
down = limit_table.iface.down.user or limit_table.iface.down.site | ||
} | ||
}, | ||
} | ||
end) | ||
|
||
return output_limits | ||
end | ||
|
||
local function wireless_limits_set(index, limits) | ||
local limit_applied = false | ||
for type_key, type_value in pairs(limits) do | ||
local limit_down = type_value.down | ||
local limit_up = type_value.up | ||
|
||
for _, iface_type in ipairs({'client', 'owe'}) do | ||
local section_name = type_key .. '_limit_' .. iface_type .. index | ||
|
||
uci:delete('wireless-rate-limiter', section_name) | ||
|
||
if limit_down ~= 0 or limit_up ~= 0 then | ||
local section_type = type_key == 'client' and 'limit-client' or 'limit-interface' | ||
uci:section('wireless-rate-limiter', section_type, section_name, { | ||
interface = iface_type .. index, | ||
download = limit_down, | ||
upload = limit_up, | ||
disabled = 0 | ||
}) | ||
|
||
limit_applied = true | ||
end | ||
end | ||
end | ||
|
||
return limit_applied | ||
end | ||
|
||
-- Delete existing config | ||
uci:delete_all('wireless-rate-limiter', 'limit-client') | ||
uci:delete_all('wireless-rate-limiter', 'limit-interface') | ||
|
||
-- Apply config | ||
local limits = wireless_limits_get() | ||
local limits_applied = false | ||
for _, value in pairs(limits) do | ||
if wireless_limits_set(value.index, value.limits) then | ||
limits_applied = true | ||
end | ||
end | ||
|
||
-- Decide daemon necessity | ||
uci:set('wireless-rate-limiter', 'core', 'disabled', limits_applied and 0 or 1) | ||
|
||
-- Save | ||
uci:commit('wireless-rate-limiter') | ||
|
||
return 0 |