универсальный 32-битный фильтр управления трафиком (universal 32bit traffic control filter)
Имя (Name)
u32 - universal 32bit traffic control filter
Синопсис (Synopsis)
tc filter
... [ handle
HANDLE ] u32
OPTION_LIST [ offset
OFFSET ]
[ hashkey
HASHKEY ] [ classid
CLASSID ] [ divisor
uint_value ] [ order
u32_value ] [ ht
HANDLE ] [ sample
SELECTOR [ divisor
uint_value ] ] [ link
HANDLE ] [ indev
ifname ] [ skip_hw
| skip_sw
] [ help
]
HANDLE := { u12_hex_htid:
[u8_hex_hash:
[u12_hex_nodeid] |
0x
u32_hex_value }
OPTION_LIST := [ OPTION_LIST ] OPTION
HASHKEY := [ mask
u32_hex_value ] [ at
4*int_value ]
CLASSID := { root
| none
| [u16_major]:
u16_minor | u32_hex_value
}
OFFSET := [ plus
int_value ] [ at
2*int_value ] [ mask
u16_hex_value ] [ shift
int_value ] [ eat
]
OPTION := { match
SELECTOR | action
ACTION }
SELECTOR := { u32
VAL_MASK_32 | u16
VAL_MASK_16 | u8
VAL_MASK_8 |
ip
IP | ip6
IP6 | { tcp
| udp
} TCPUDP | icmp
ICMP | mark
VAL_MASK_32 | ether
ETHER }
IP := { { src
| dst
} { default
| any
| all
| ip_address [ /
{
prefixlen | netmask } ] } AT | { dsfield
| ihl
| protocol
| precedence
| icmp_type
| icmp_code
} VAL_MASK_8 | {
sport
| dport
} VAL_MASK_16 | nofrag
| firstfrag
| df
|
mf
}
IP6 := { { src
| dst
} { default
| any
| all
| ip6_address
[/prefixlen ] } AT | priority
VAL_MASK_8 | { protocol
|
icmp_type
| icmp_code
} VAL_MASK_8 | flowlabel
VAL_MASK_32 | { sport
| dport
} VAL_MASK_16 }
TCPUDP := { src
| dst
} VAL_MASK_16
ICMP := { type
VAL_MASK_8 | code
VAL_MASK_8 }
ETHER := { src
| dst
} ether_address AT
VAL_MASK_32 := u32_value u32_hex_mask [ AT ]
VAL_MASK_16 := u16_value u16_hex_mask [ AT ]
VAL_MASK_8 := u8_value u8_hex_mask [ AT ]
AT := [ at
[ nexthdr+
] int_value ]
Описание (Description)
The Universal/Ugly 32bit filter allows to match arbitrary
bitfields in the packet. Due to breaking everything down to
values, masks and offsets, It is equally powerful and hard to
use. Luckily many abstracting directives are present which allow
defining rules on a higher level and therefore free the user from
having to fiddle with bits and masks in many cases.
There are two general modes of invocation: The first mode creates
a new filter to delegate packets to different destinations. Apart
from the obvious ones, namely classifying the packet by
specifying a CLASSID or calling an action
, one may link
one
filter to another one (or even a list of them), effectively
organizing filters into a tree-like hierarchy.
Typically filter delegation is done by means of a hash table,
which leads to the second mode of invocation: it merely serves to
set up these hash tables. Filters can select a hash table and
provide a key selector from which a hash is to be computed and
used as key to lookup the table's bucket which contains filters
for further processing. This is useful if a high number of
filters is in use, as the overhead of performing the hash
operation and table lookup becomes negligible in that case. Using
hashtables with u32
basically involves the following pattern:
(1) Creating a new hash table, specifying it's size using the
divisor
parameter and ideally a handle by which the table can
be identified. If the latter is not given, the kernel chooses
one on it's own, which has to be guessed later.
(2) Creating filters which link to the created table in (1) using
the link
parameter and defining the packet data which the
kernel will use to calculate the hashkey
.
(3) Adding filters to buckets in the hash table from (1). In
order to avoid having to know how exactly the kernel creates
the hash key, there is the sample
parameter, which gives
sample data to hash and thereby define the table bucket the
filter should be added to.
In fact, even if not explicitly requested u32
creates a hash
table for every priority
a filter is being added with. The
table's size is 1 though, so it is in fact merely a linked list.