Thank you for creating this script. After reading through the code, it seems like it could be the best solution for QoS with cake.
But when I tried to use it, I couldn't get it working. Perhaps you could help me with that?
My issues
It seems that the init.d script references the wan interface as "wan", but my wan interface is eth0
.
I tried to change all instances of wan
to eth0
, but I am not sure if all of them are references to the device or a keyword.
And it still didn't work after making that change. The log showed:
RTNETLINK answers: File exists
Error: Exclusivity flag on, cannot modify.
RTNETLINK answers: Invalid argument
We have an error talking to the kernel
Error: Exclusivity flag on, cannot modify.
Error: Exclusivity flag on, cannot modify.
And here are the commands and their outputs when I run them directly:
root@FriendlyWrt:~/cake-qos-simple# ip link add name ifb-wan type ifb
root@FriendlyWrt:~/cake-qos-simple# ip link set ifb-wan up
root@FriendlyWrt:~/cake-qos-simple# tc qdisc add dev eth0 handle ffff: ingress
Error: Exclusivity flag on, cannot modify.
root@FriendlyWrt:~/cake-qos-simple# tc filter add dev eth0 parent ffff: protocol ip matchall action ctinfo dscp 63 128 action mirred egress redirect dev ifb-wan
RTNETLINK answers: Invalid argument
We have an error talking to the kernel
root@FriendlyWrt:~/cake-qos-simple# tc qdisc add dev eth0 root cake bandwidth 10Mbit diffserv4 dual-srchost nonat wash no-ack-filter noatm overhead 0
root@FriendlyWrt:~/cake-qos-simple# tc qdisc add dev ifb-wan root cake bandwidth 10Mbit diffserv4 dual-dsthost nonat nowash ingress no-ack-filter noatm overhead 0
root@FriendlyWrt:~/cake-qos-simple#
Issues I noticed
I also noticed two issues...
The default config causes fw4 syntax errors
This section...
# local MAC addresses to set to bulk (e.g. IoT devices)
define BULK_MACS = {
# XX,
# YY
}
... causes syntax errors in fw4:
# fw4 reload
Section @zone[1] (wan) IPv4 fullcone enabled for zone 'wan'
Section @zone[1] (wan) IPv6 fullcone enabled for zone 'wan'
Section @rule[14] (Allow iperf3 on WAN) is disabled, ignoring section
Section @rule[15] (Allow librespeed) is disabled, ignoring section
Automatically including '/root/cake-qos-simple/cake-qos-simple.nft'
In file included from /dev/stdin:398:1-52:
/root/cake-qos-simple/cake-qos-simple.nft:21:6-6: Error: syntax error, unexpected newline
# XX,
^
In file included from /dev/stdin:398:1-52:
/root/cake-qos-simple/cake-qos-simple.nft:23:1-1: Error: syntax error, unexpected '}'
}
^
Removing the commented out lines also didn't work. It seems like you can't have an empty set in nftables.
Errors in the cake-qos-simple.nft
prevent all other firewall rules from being loaded
I rebooted my router after adding cake-qos-simple and suddenly none of the routing would work anymore.
When I ran nft list ruleset
, I saw that none of the fw4 openwrt rules were loaded.
When I ran fw4 reload
, I saw the above error. After uncommenting the empty set and the rule that uses it, I was able to load all the rules.
This script completely breaking networking is not ideal. Especially when this happens in the default config.
Perhaps there is a way to load the firewall rules in a way that doesn't prevent all other rules from loading? If a syntax error breaks the DSCP tagging that's not great, but still way better than a sudden stop of all routing and firewalling on the next reboot.
This is especially critical since the user might not even notice the issue initially. There was no visible error anywhere about the syntax issues in the .nft
file.
So tracking it back to this is not trivial.
And a few suggestions on how to improve the usability
Add a variable for the wan interface
My suggestion would be to add a WAN_INTERFACE
variable at the top of the script to help users configure the correct interface and then use that throughout the script instead of hardcoding wan
.
Make the init.d script more userfriendly
I found it very confusing that the init.d script didn't output anything. To me that was a sign that everything was ok.
Only later did I realize that there is a logfile and all output ends up in there.
I would suggest to add echos that describe what the next command is going to be so that it's clear which command the error output belongs to.
Something like echo "Creating ifb-wan interface..."
.
Add a help section to the init.d script
To make it easier to know which commands are available, it would be great to see a help when you run the init.d script.
Here is how it looks with QoSify:
# /etc/init.d/qosify
Syntax: /etc/init.d/qosify [command]
Available commands:
start Start the service
stop Stop the service
restart Restart the service
reload Reload configuration files (or restart if service does not implement reload)
enable Enable service autostart
disable Disable service autostart
enabled Check if service is started on boot
running Check if service is running
status Service status
trace Start with syscall trace
info Dump procd service info
Add a way to easily see the status of cake
I'm sorry that I keep comparing this to QoSify, but I think it's currently the main competitor for your script and they really nailed the usability of the package.
You can run...
# qosify-status
===== interface wan: active =====
egress status:
qdisc cake 800c: root refcnt 9 bandwidth 100Mbit diffserv4 dual-srchost nat nowash no-ack-filter split-gso rtt 100ms noatm overhead 42 mpu 84
Sent 10537 bytes 49 pkt (dropped 0, overlimits 1 requeues 0)
backlog 0b 0p requeues 0
memory used: 1408b of 5000000b
capacity estimate: 100Mbit
min/max network layer size: 40 / 751
min/max overhead-adjusted size: 84 / 793
average network hdr offset: 2
Bulk Best Effort Video Voice
thresh 6250Kbit 100Mbit 50Mbit 25Mbit
target 5ms 5ms 5ms 5ms
interval 100ms 100ms 100ms 100ms
pk_delay 9us 20us 0us 0us
av_delay 0us 2us 0us 0us
sp_delay 0us 2us 0us 0us
backlog 0b 0b 0b 0b
pkts 3 46 0 0
bytes 1278 9259 0 0
way_inds 0 0 0 0
way_miss 1 17 0 0
way_cols 0 0 0 0
drops 0 0 0 0
marks 0 0 0 0
ack_drop 0 0 0 0
sp_flows 0 0 0 0
bk_flows 0 1 0 0
un_flows 0 0 0 0
max_len 725 765 0 0
quantum 300 1514 1514 762
[...]
And it shows you alll the important info. It seems like it's mainly the output of tc -s qdisc show dev eth0
.
So it would be easy to add to the init.d script as a status
or info
command. That would make it much easier for beginners to debug and use.
Conclusion
I want to stress once more that I think this solution is awesome and could becom the ideal QoS solution on openwrt. So I hope this feedback is not discouraging. 