Hi.
I need some help with tc filters in regards to packets marked by nft.
I use 3 rules inside the mangle_postrouting chain to mark udp packets based on their payload length destined for a local ip (192.168.4.10) connected to the lan side of my openwrt vm.
nft add rule inet fw4 mangle_postrouting ip daddr 192.168.4.10 udp dport 55585 udp length \{ 1-100 \} counter meta mark set 1
nft add rule inet fw4 mangle_postrouting ip daddr 192.168.4.10 udp dport 55585 udp length \{ 101-200 \} counter meta mark set 2
nft add rule inet fw4 mangle_postrouting ip daddr 192.168.4.10 udp dport 55585 udp length \{ 201-1000 \} counter meta mark set 3
and then using 3 filters on tc, I feed those marked packets into 3 different flowids each one running the netem qdisc where I can monitor the stats with tc -s and redirect them into their own IFBs where I can monitor the streams with tcpdump
tc qdisc add dev br0 root handle 1: prio
tc filter add dev br0 protocol ip parent 1: prio 1 handle 1 fw flowid 1:1 action mirred egress redirect dev smallD
tc filter add dev br0 protocol ip parent 1: prio 2 handle 2 fw flowid 1:2 action mirred egress redirect dev mediumD
tc filter add dev br0 protocol ip parent 1: prio 3 handle 3 fw flowid 1:3 action mirred egress redirect dev largeD
and this works well enough, I can verify the packets on each IFB are the correct length. While watching the numbers on
watch -tn 0.2 'tc -s qdisc show dev br0'
The problem I am facing is when trying to do this in the opposite direction. I want to do the same with packets coming out of 192.168.4.10 destined for my application server upstream. So tweaking the nft rules by swapping daddr and dport with saddr and sport and then using the ingress qdisc for br0 with no success. I also tried creating a veth pair and first passing the traffic through it and tried different qdiscs on either side, including ingress and prio also with no success.
My thinking at this point was that nft is marking the packets too late for the tc filtering so I tried using different nft rules such as
table netdev filter {
chain ingress {
type filter hook ingress devices = { eth1 } priority -149; policy accept;
ip saddr 192.168.4.10 udp sport 55585 udp length { 1-100 } counter meta mark set 1
ip saddr 192.168.4.10 udp sport 55585 udp length { 101-200 } counter meta mark set 2
ip saddr 192.168.4.10 udp sport 55585 udp length { 201-1000 } counter meta mark set 3
}
}
also with no success. I tried most of the chains that OpenWRT creates by default in the inet fw4 table, also with no success.
I did verify everytime for sanity by tcpdumping eth1 and indeed the traffic flow in both directions show up with all the different lengths.
So the outcome I am hoping to achieve is to split the stream of traffic with the saddr of 192.168.4.10 and sport of 55585 into its own prio flowid and/or IFB. Any help would be really appreciated.