Linux – dealing with fast massive filtering
Welcome to the tutorial guide. The guide will provide a user with guidance and instructions on how to deal with fast massive filtering.
If a user needs thousands of rules because he/she has a lot of clients or computers with different QoS specifications, then a user will note that he/she will note that the kernel spends a lot of time matching all those rules.
By default, all filters reside in one big chain which is matched in descending order of priority. If a user has 1000 rules, then he/she will require 1000 checks. These checks are required in order to determine what to do with a packet.
If a user has 256 chains with four rules then matching will be quicker also, if he/she can divide packets over those 256 chains, so that the right rule will be there.
If a user has 1024 cable modem customers in his/her network, with IP addresses ranging from 1.2.0.0 to 1.2.3.255, and each has to go in another bin, for example ‘lite’, ‘regular’ and ‘premium’. A user will then have 1024 rules like this:
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.0.0 classid 1:1
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.0.1 classid 1:1
…
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.3.254 classid 1:3
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.3.255 classid 1:2
If a user wants to speed up then he can use the last part of the IP address as a hash key and 256 tables will be obtained. The first table will look like as below:
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.0.0 classid 1:1
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.1.0 classid 1:1
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.2.0 classid 1:3
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.3.0 classid 1:2
The next table will start as described below:
# tc filter add dev eth1 parent 1:0 protocol ip prio 100 match ip src \
1.2.0.1 classid 1:1
…
In this way, a user will require only four checks.
Please note that configuration is difficult but it is useful by the time a user has many rules. First a user needs to make a filter root, then he/she has to create a table with 256 entries:
# tc filter add dev eth1 parent 1:0 prio 5 protocol ip u32
# tc filter add dev eth1 parent 1:0 prio 5 handle 2: protocol ip u32 divisor 256
A user can now add some rules to entries in the created table:
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \
match ip src 1.2.0.123 flowid 1:1
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \
match ip src 1.2.1.123 flowid 1:2
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \
match ip src 1.2.3.123 flowid 1:3
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 2:7b: \
match ip src 1.2.4.123 flowid 1:2
This is entry 123, which contains matches for 1.2.0.123, 1.2.1.123, 1.2.2.123, 1.2.3.123, and sends them to 1:1, 1:2, 1:3 and 1:2 respectively. Please note that a user will need to specifiy the hash bucket in hex, 0×7b is 123.
After that a user will then need to create a ‘hashing filter’ that directs traffic to the right entry in the hashing table:
# tc filter add dev eth1 protocol ip parent 1:0 prio 5 u32 ht 800:: \
match ip src 1.2.0.0/16 \
hashkey mask 0×000000ff at 12 \
link 2:
It is good know what are these numbers. The default hash table is called 800:: and all filtering starts there. Then a user can select the source address, which lives as position 12, 13, 14 and 15 in the IP
A user should note that this is difficult but the good thing about it is that it works in practice and performance is good.
If you have followed this tutorial guide then you would have learnt about dealing with fast massive filtering.













