It becomes rapidly more complex when you have multiple destination networks. One strategy is to create a veth called something like "qosveth" where the other end of the veth is in a different namespace. In that namespace you have a bridge to another veth, whose far end comes back into the main namespace as something like qosreturn... then you route everything from the WAN side to qosveth... and then everything from qosreturn gets routed normally.
It might make sense to try using an IFB... route all stuff from WAN side to an IFB, and then I don't know if it'll seem like that traffic "comes from the IFB" so you can route it again out to the normal routes.
Thanks. This seems like a fun challenge and may be helpful for other users in the same boat.
Any chance you could draw me a sketch of the veth-based solution in terms of how the veths are linked up with br-lan and br-guest?
I tried just working with my existing setup, but having veth-br made a part of both br-lan (192.168.1.1) and br-guest (192.168.2.1), but that failed. It seems a veth end can only be a part of one interface and not more than one interface.
Regarding the IFB-based solution, I got pretty far with that during my earlier attempt:
So that grabs all the br-lan wan/VPN but then I wouldn't know how to also grab the br-guest wan/VPN as well. Assuming the goal would be to create IFB that grabs all br-lan wan/VPN combined with all br-guest wan/VPN.
Or can I just stack the br-guest to the common IFB by repeating the lines for the br-guest? Like this:
ip link add name ifb type ifb
tc qdisc add dev ifb root cake bandwidth 30Mbit diffserv3 triple-isolate nonat nowash no-ack-filter split-gso rtt 100ms noatm overhead 60
tc qdisc add dev br-lan handle ffff: ingress
tc qdisc add dev br-guest handle ffff: ingress
ip link set ifb up
tc filter add dev br-lan parent ffff: protocol ip prio 1 u32 match ip dst 192.168.1.0/24 action pass
tc filter add dev br-lan parent ffff: prio 2 matchall action mirred egress redirect dev ifb
tc filter add dev br-guest parent ffff: protocol ip prio 1 u32 match ip dst 192.168.2.0/24 action pass
tc filter add dev br-guest parent ffff: prio 2 matchall action mirred egress redirect dev ifb
Basically you have a special route rule that says all your traffic coming from WAN first gets routed to qos interface, which is one end of a veth... then that goes into a separate namespace where the other end is a member of a bridge... then it's bridged to another veth... which brings it back into the main namespace.
You'll need a kernel with network namespaces enabled, and the ip-full package to handle setting up the namespaces.
then packets received on qosreturn are routed as normal. Make qosreturn part of the WAN firewall zone, since it's got packets coming in from WAN.
Where you shove the real ethernet/vlan device representing your WAN connection into a namespace, and then in that namespace route everything to the veth that brings packets in to your main namespace... then in the main namespace everything works as normal, except the "wan" is a virtual device that's the second end of a veth.
In this scenario, you'd also need to shove your wireguard connection into the "pre" namespace as well I think.
@jow / @vgaetera does netifd support multiple namespaces? Can this:
be done in LuCi and if so how? If not in LuCi how can it be done using the command line?
@dlakelan any idea how to implement this? Seems elegant. But I can't see much about namespace use in OpenWrt in this way. So I don't know where or who to turn to. This returned no errors:
root@OpenWrt:~# opkg install ip-full
Installing ip-full (5.15.0-2) to root...
Downloading https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/base/ip-full_5.15.0-2_aarch64_cortex-a53.ipk
Installing libelf1 (0.186-1) to root...
Downloading https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/base/libelf1_0.186-1_aarch64_cortex-a53.ipk
Installing libbpf20220308 (2022-03-08-04c465fd-1) to root...
Downloading https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/base/libbpf20220308_2022-03-08-04c465fd-1_aarch64_cortex-a53.ipk
Configuring libelf1.
Configuring libbpf20220308.
Configuring ip-full.
root@OpenWrt:~# ip netns add blue
root@OpenWrt:~#
I think what you will have to do is use a script. Create a veth pair, move one end into the netns, put your WAN ethernet into the netns as well. Bridge them together with a bridge in the netns. Add cake to the veth... then you'll have to run your autorate script in the netns as well. it's not ideal, but it should work.
In my diagram, instead of routing between the wan and veth, just bridge them.
So could I actually bridge WAN + VPN + veth all together? Or would it really have to be routing in that instance?
Would the IFB solution be in any sense inferior? I ask because I imagine setting it up may be easier for me because I don't altogether understand how the routing would be implemented. I mean I know how to use netifd in LuCi. But I'm a bit hazy beyond that.
The VPN is not an Ethernet layer device so I don't think it can be in the bridge meaningfully.
I'm not sure how well the IFB will work. You don't want the VPN traffic to go twice through, so you'll have to do some magic to send just either the encrypted packet, or the unencrypted packet through not both.
I assume you want to shape traffic in the tunnel with prioritization, so just the unencrypted stuff which you can then prioritize differently and / or flow/fair queue
What you want is ingress to WAN that matches non encrypted packets, and ingress to wireguard that matches all packets. Send those all to an IFB. But it won't be classified yet...
tc filter add dev wan parent ffff: protocol ip prio 1 u32 match ip sport 51820 0xffff action pass
tc filter add dev wan parent ffff: prio 2 matchall action mirred egress redirect dev ifb
tc filter add dev vpn parent ffff: matchall action mirred egress redirect dev ifb
The main reason to not just handle everything on an ingress to WAN is that you want to treat some flows differently from others, and to handle fairness etc. If you just want to rate limit you can do ingress on WAN.
It will allow the VPN flows to be treated as separate flows, so at least that. But you won't have any DSCP/classification. So for example if you're interested in making guest traffic lower priority than regular LAN traffic, then you'll need some other magic for that.
potentially any device on the internet could send you packets from that identical port. So I think you're best off to match on something like UDP packets from your VPN provider's IP address coming from that port.
root@OpenWrt:/etc/init.d# cat sqm-wan-vpn
#!/bin/sh /etc/rc.common
# Copyright (C) 2007 OpenWrt.org
exec &> /tmp/sqm.log
START=50
STOP=4
start() {
# apply CAKE on upload (must be besteffort flows nonat nowash to work with the skb->hash preservation)
tc qdisc add dev wan root cake bandwidth 30Mbit besteffort flows nonat nowash no-ack-filter split-gso rtt 100ms noatm overhead 92
# set up ifb that combines vpn and wan flows
ip link add name ifb type ifb
tc qdisc add dev wan handle ffff: ingress
tc qdisc add dev vpn handle ffff: ingress
ip link set ifb up
# filter out packets from WireGuard src IP on wan, else preserve, and combine all vpn flows
tc filter add dev wan parent ffff: protocol ip prio 1 u32 match ip src xx.xx.xx.xx/32 action pass
tc filter add dev wan parent ffff: prio 2 matchall action mirred egress redirect dev ifb
tc filter add dev vpn parent ffff: matchall action mirred egress redirect dev ifb
# apply CAKE on download using the ifb
tc qdisc add dev ifb root cake bandwidth 25Mbit besteffort triple-isolate nat wash ingress no-ack-filter split-gso rtt 100ms noatm overhead 92
}
stop() {
tc qdisc del dev wan ingress
tc qdisc del dev wan root
tc qdisc del dev vpn ingress
tc qdisc del dev ifb root
ip link set ifb down
ip link del ifb
}
@moeller0 this is what I mean - couldn't the LuCi sqm-script be adapted to allow setting up IFB's for those who have wan/vpn like this? If I just use this script does that mean I don't need all the sqm packages? Think I need: kmod-sched-core + tc-tiny?
Maybe this is a fairly generic solution that could be brought in?