4

Can I attach a tc filter to an HTB class rather than to an HTB qdisc?

For example:

tc class add dev $IF_LAN parent 1:100 classid 1:180 htb rate 19kbit ceil 2000kbit prio 4

where:

 1:100 -> Is an HTB inner class.

This question arises from the fact that I could be able to attach a tc filter to a class without throwing an error but later when I saw the tc statistics I realized that there is no filtering being made.

Thanks in advance.

EDIT: I found in the tc manual tc-filter syntax:

tc  filter  [  add  |  change  | replace ] dev DEV [ parent qdisc-id | root ] protocol prootocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id

(the relevant part is parent qdisc-id)

So, I only can be able to attach a filter to a qdisc or there is a workaround?

Diosney
  • 305
  • 5
  • 12

2 Answers2

3

Should be possible, we use:

/sbin/tc qdisc add dev $DEV root handle 1: htb default 1
/sbin/tc class add dev $DEV parent 1: classid 1:3 htb rate $RATE burst $BURST
/sbin/tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 match ip src $IP flowid 1:3

The third line attaches a filter to the class defined in the second line (classid 1:3 and flowid 1:3).

Christoph Wurm
  • 299
  • 2
  • 12
2

It is possible. I believe tc(8) man is not comprehensive.

Citing from man7.org/tc(8):

tc filters
If tc filters are attached to a class, they are consulted first for relevant instructions. Filters can match on all fields of a packet header, as well as on the firewall mark applied by ipchains or iptables.

Just checked on my Linux 5.0.3-zen1-2-zen laptop and it works.

lang-bash
sudo tc qdisc add dev enp3s0 root handle 1: htb default 10
# inner class
sudo tc class add dev enp3s0 parent 1: classid 1:1 htb rate 100kbps
# leaf classes
sudo tc class add dev enp3s0 parent 1:1 classid 1:10 htb rate 100kbps
sudo tc class add dev enp3s0 parent 1:1 classid 1:20 htb rate 100kbps
sudo tc class add dev enp3s0 parent 1:1 classid 1:30 htb rate 100kbps

sudo tc filter add dev enp3s0 parent 1: protocol ip matchall flowid 1:1
sudo tc filter add dev enp3s0 parent 1:1 u32 match ip dst 192.168.1.6 flowid 1:30

ping -c1 192.168.1.6
ping -c2 192.168.1.1
sudo tc -s -g class show dev enp3s0 
sudo tc -s filter show dev enp3s0 parent 1:
sudo tc -s filter show dev enp3s0 parent 1:1

First filter's parent is qdisc and it sets flowid to inner class 1:1. Second filter's parent is the inner class 1:1 and it does final verdict selecting leaf class 1:30

Output of last 3 commands:

$ sudo tc -s -g class show dev enp3s0 
+---(1:1) htb rate 800Kbit ceil 800Kbit burst 1600b cburst 1600b 
     |    Sent 294 bytes 3 pkt (dropped 0, overlimits 0 requeues 0) 
     |    backlog 0b 0p requeues 0
     |
     +---(1:10) htb prio 0 rate 800Kbit ceil 800Kbit burst 1600b cburst 1600b 
     |          Sent 196 bytes 2 pkt (dropped 0, overlimits 0 requeues 0) 
     |          backlog 0b 0p requeues 0
     |     
     +---(1:20) htb prio 0 rate 800Kbit ceil 800Kbit burst 1600b cburst 1600b 
     |          Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) 
     |          backlog 0b 0p requeues 0
     |     
     +---(1:30) htb prio 0 rate 800Kbit ceil 800Kbit burst 1600b cburst 1600b 
                Sent 98 bytes 1 pkt (dropped 0, overlimits 0 requeues 0) 
                backlog 0b 0p requeues 0


$ sudo tc -s filter show dev enp3s0 parent 1:
filter protocol ip pref 49152 matchall chain 0 
filter protocol ip pref 49152 matchall chain 0 handle 0x1 flowid 1:1 
  not_in_hw
$ sudo tc -s filter show dev enp3s0 parent 1:1
filter protocol all pref 49152 u32 chain 0 
filter protocol all pref 49152 u32 chain 0 fh 800: ht divisor 1 
filter protocol all pref 49152 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:30 not_in_hw  (rule hit 3 success 1)
  match c0a80106/ffffffff at 16 (success 1 ) 

See: resulting qdisc represented as graph

Note: To make filters parented at inner class work, inner class should be referenced (with classid or flowid) by filters from upper level inner class or qdisc, i.e. preserve chain qdisc --filter--> inner class --filter--> leaf class.

Also make sure htb default is set to leaf class.

Daniele Santi
  • 2,479
  • 1
  • 25
  • 22
Dawer
  • 21
  • 1