Szymon Stefanek
2007-11-20 17:43:13 UTC
Hi all! :)
I see that this is partially covered in the mailing list archive
but at the moment I can't find a straight & working answer.
I have an imq device with dynamically attacched classes/qdiscs/filters.
There is a hashing filter that maps the last octet of an user's IP address
to a class (and associated qdisc). The "empty" filter looks like this:
filter parent 1: protocol ip pref 5 u32
filter parent 1: protocol ip pref 5 u32 fh 2: ht divisor 256
filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt
0 link 2: (rule hit 0 success 0)
match 00000000/00000000 at 12 (success 0 )
hash mask 000000ff at 16
I'm adding the hash entries dynamically, as users get attacched to the system
(this is a dynamic PPPoE access concentrator).
tc filter add dev imq0 protocol ip parent 1:0 prio 5 u32 ht
2:<LASTIPOCTETHEX>: match ip dst <IPADDRESS> flowid 1:<CLASSID>
<IPADDRESS> is the address of the newly attacched user, <CLASSID> is
a dynamically assigned unique identifier and <LASTIPOCTETHEX> is the
last octet of the user's IP address.
This works and I get a tc tree like this:
filter parent 1: protocol ip pref 5 u32
filter parent 1: protocol ip pref 5 u32 fh 2: ht divisor 256
filter parent 1: protocol ip pref 5 u32 fh 2:1:800 order 2048 key ht 2 bkt 1
flowid 1:4098 (rule hit 0 success 0)
match 0a050001/ffffffff at 16 (success 0 )
filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt
0 link 2: (rule hit 0 success 0)
match 00000000/00000000 at 12 (success 0 )
hash mask 000000ff at 16
Nice.
If another user gets added to the same hash bucket I get something like:
filter parent 1: protocol ip pref 5 u32
filter parent 1: protocol ip pref 5 u32 fh 2: ht divisor 256
filter parent 1: protocol ip pref 5 u32 fh 2:1:800 order 2048 key ht 2 bkt 1
flowid 1:4098 (rule hit 0 success 0)
match 0a050001/ffffffff at 16 (success 0 )
filter parent 1: protocol ip pref 5 u32 fh 2:1:801 order 2048 key ht 2 bkt 1
flowid 1:4099 (rule hit 0 success 0)
match 0a060001/ffffffff at 16 (success 0 )
filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt
0 link 2: (rule hit 0 success 0)
match 00000000/00000000 at 12 (success 0 )
hash mask 000000ff at 16
Now when the users go away I want to _programmatically_ remove the associated
filter entries. This doesn't work unless I manually specify the filter handle
(handle 2:1:801). The problem is that I actually don't know the filter
handle since its last part is assigned automatically by tc. I would need
to relaunch tc with the show option, capture its output and parse it...
this is an overkill. If I try to delete handle 2:1: (just like in the add
command) then ALL the rules with handle 2:1:* get deleted (and this is
obviously not what I want).
Trying to add filters with completly specified handle (like fh 2:1:4098)
doesn't work unless the last part is EXACTLY what tc would set automatically
(this is 800, 801 etc...). But since I have multiple unsynchronized processes
that do the adding job then I don't know which handles have been already
used and thus can't guess what which handle to add next. Synchronizing
the processes and sharing a database would be again a very huge overkill.
Trying to assign an unique filter id by using pref creates a mess since it
adds three filters at once for every preference value. And removing doesn't
work either with tc complaining about "No such file or directory".
I have read somewhere that deleting a qdisc will also delete the filters
attacched to it but this doesn't seem to work: the qdisc is deleted
but the filter in the hash bucket is not.
So finally, can I programmatically remove a filter without knowing exactly its
handle ? How ? Is there another way to match filters ? Maybe on flowid... ?
Add/remove by using direct syscalls ?
I see that this is partially covered in the mailing list archive
but at the moment I can't find a straight & working answer.
I have an imq device with dynamically attacched classes/qdiscs/filters.
There is a hashing filter that maps the last octet of an user's IP address
to a class (and associated qdisc). The "empty" filter looks like this:
filter parent 1: protocol ip pref 5 u32
filter parent 1: protocol ip pref 5 u32 fh 2: ht divisor 256
filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt
0 link 2: (rule hit 0 success 0)
match 00000000/00000000 at 12 (success 0 )
hash mask 000000ff at 16
I'm adding the hash entries dynamically, as users get attacched to the system
(this is a dynamic PPPoE access concentrator).
tc filter add dev imq0 protocol ip parent 1:0 prio 5 u32 ht
2:<LASTIPOCTETHEX>: match ip dst <IPADDRESS> flowid 1:<CLASSID>
<IPADDRESS> is the address of the newly attacched user, <CLASSID> is
a dynamically assigned unique identifier and <LASTIPOCTETHEX> is the
last octet of the user's IP address.
This works and I get a tc tree like this:
filter parent 1: protocol ip pref 5 u32
filter parent 1: protocol ip pref 5 u32 fh 2: ht divisor 256
filter parent 1: protocol ip pref 5 u32 fh 2:1:800 order 2048 key ht 2 bkt 1
flowid 1:4098 (rule hit 0 success 0)
match 0a050001/ffffffff at 16 (success 0 )
filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt
0 link 2: (rule hit 0 success 0)
match 00000000/00000000 at 12 (success 0 )
hash mask 000000ff at 16
Nice.
If another user gets added to the same hash bucket I get something like:
filter parent 1: protocol ip pref 5 u32
filter parent 1: protocol ip pref 5 u32 fh 2: ht divisor 256
filter parent 1: protocol ip pref 5 u32 fh 2:1:800 order 2048 key ht 2 bkt 1
flowid 1:4098 (rule hit 0 success 0)
match 0a050001/ffffffff at 16 (success 0 )
filter parent 1: protocol ip pref 5 u32 fh 2:1:801 order 2048 key ht 2 bkt 1
flowid 1:4099 (rule hit 0 success 0)
match 0a060001/ffffffff at 16 (success 0 )
filter parent 1: protocol ip pref 5 u32 fh 800: ht divisor 1
filter parent 1: protocol ip pref 5 u32 fh 800::800 order 2048 key ht 800 bkt
0 link 2: (rule hit 0 success 0)
match 00000000/00000000 at 12 (success 0 )
hash mask 000000ff at 16
Now when the users go away I want to _programmatically_ remove the associated
filter entries. This doesn't work unless I manually specify the filter handle
(handle 2:1:801). The problem is that I actually don't know the filter
handle since its last part is assigned automatically by tc. I would need
to relaunch tc with the show option, capture its output and parse it...
this is an overkill. If I try to delete handle 2:1: (just like in the add
command) then ALL the rules with handle 2:1:* get deleted (and this is
obviously not what I want).
Trying to add filters with completly specified handle (like fh 2:1:4098)
doesn't work unless the last part is EXACTLY what tc would set automatically
(this is 800, 801 etc...). But since I have multiple unsynchronized processes
that do the adding job then I don't know which handles have been already
used and thus can't guess what which handle to add next. Synchronizing
the processes and sharing a database would be again a very huge overkill.
Trying to assign an unique filter id by using pref creates a mess since it
adds three filters at once for every preference value. And removing doesn't
work either with tc complaining about "No such file or directory".
I have read somewhere that deleting a qdisc will also delete the filters
attacched to it but this doesn't seem to work: the qdisc is deleted
but the filter in the hash bucket is not.
So finally, can I programmatically remove a filter without knowing exactly its
handle ? How ? Is there another way to match filters ? Maybe on flowid... ?
Add/remove by using direct syscalls ?
--
Szymon Stefanek
Szymon Stefanek