The u32 classifier

The U32 filter is the most advanced filter available in the current implementation. It entirely based on hashing tables, which make it robust when there are many filter rules.

In its simplest form the U32 filter is a list of records, each consisting of two fields: a selector and an action. The selectors, described below, are compared with the currently processed IP packet until the first match occurs, and then the associated action is performed. The simplest type of action would be directing the packet into defined CBQ class.

The command line of tc filter program, used to configure the filter, consists of three parts: filter specification, a selector and an action. The filter specification can be defined as:

tc filter add dev IF [ protocol PROTO ]
[ (preference|priority) PRIO ]
[ parent CBQ ]

The protocol field describes protocol that the filter will be applied to. We will only discuss case of ip protocol. The preference field (priority can be used alternatively) sets the priority of currently defined filter. This is important, since you can have several filters (lists of rules) with different priorities. Each list will be passed in the order the rules were added, then list with lower priority (higher preference number) will be processed. The parent field defines the CBQ tree top (e.g. 1:0), the filter should be attached to.

The options described above apply to all filters, not only U32.

12.1.1. U32 selector

The U32 selector contains definition of the pattern, that will be matched to the currently processed packet. Precisely, it defines which bits are to be matched in the packet header and nothing more, but this simple method is very powerful. Let's take a look at the following examples, taken directly from a pretty complex, real-world filter:

# tc filter add dev eth0 protocol ip parent 1:0 pref 10 u32 \
match u32 00100000 00ff0000 at 0 flowid 1:10

For now, leave the first line alone - all these parameters describe the filter's hash tables. Focus on the selector line, containing match keyword. This selector will match to IP headers, whose second byte will be 0x10 (0010). As you can guess, the 00ff number is the match mask, telling the filter exactly which bits to match. Here it's 0xff, so the byte will match if it's exactly 0x10. The at keyword means that the match is to be started at specified offset (in bytes) -- in this case it's beginning of the packet. Translating all that to human language, the packet will match if its Type of Service field will have `low delay' bits set. Let's analyze another rule:

# tc filter add dev eth0 protocol ip parent 1:0 pref 10 u32 \
match u32 00000016 0000ffff at nexthdr+0 flowid 1:10

The nexthdr option means next header encapsulated in the IP packet, i.e. header of upper-layer protocol. The match will also start here at the beginning of the next header. The match should occur in the second, 32-bit word of the header. In TCP and UDP protocols this field contains packet's destination port. The number is given in big-endian format, i.e. older bits first, so we simply read 0x0016 as 22 decimal, which stands for SSH service if this was TCP. As you guess, this match is ambiguous without a context, and we will discuss this later.

Having understood all the above, we will find the following selector quite easy to read: match c0a80100 ffffff00 at 16. What we got here is a three byte match at 17-th byte, counting from the IP header start. This will match for packets with destination address anywhere in 192.168.1/24 network. After analyzing the examples, we can summarize what we have learned.

12.1.2. General selectors

General selectors define the pattern, mask and offset the pattern will be matched to the packet contents. Using the general selectors you can match virtually any single bit in the IP (or upper layer) header. They are more difficult to write and read, though, than specific selectors that described below. The general selector syntax is:

match [ u32 | u16 | u8 ] PATTERN MASK [ at OFFSET | nexthdr+OFFSET]

One of the keywords u32u16 or u8 specifies length of the pattern in bits. PATTERN and MASK should follow, of length defined by the previous keyword. The OFFSET parameter is the offset, in bytes, to start matching. If nexthdr+ keyword is given, the offset is relative to start of the upper layer header.

Some examples:

# tc filter add dev ppp14 parent 1:0 prio 10 u32 \
match u8 64 0xff at 8 \
flowid 1:4

Packet will match to this rule, if its time to live (TTL) is 64. TTL is the field starting just after 8-th byte of the IP header.

# tc filter add dev ppp14 parent 1:0 prio 10 u32 \
match u8 0x10 0xff at nexthdr+13 \
protocol tcp \
flowid 1:3

FIXME: it has been pointed out that this syntax does not work currently.

Use this to match ACKs on packets smaller than 64 bytes:

## match acks the hard way,
## IP protocol 6,
## IP header length 0x5(32 bit words),
## IP Total length 0x34 (ACK + 12 bytes of TCP options)
## TCP ack set (bit 5, offset 33)
# tc filter add dev ppp14 parent 1:0 protocol ip prio 10 u32 \
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid 1:3

This rule will only match TCP packets with ACK bit set, and no further payload. Here we can see an example of using two selectors, the final result will be logical AND of their results. If we take a look at TCP header diagram, we can see that the ACK bit is second older bit (0x10) in the 14-th byte of the TCP header (at nexthdr+13). As for the second selector, if we'd like to make our life harder, we could write match u8 0x06 0xff at 9 instead of using the specific selectorprotocol tcp, because 6 is the number of TCP protocol, present in 10-th byte of the IP header. On the other hand, in this example we couldn't use any specific selector for the first match - simply because there's no specific selector to match TCP ACK bits.

12.1.3. Specific selectors

The following table contains a list of all specific selectors the author of this section has found in the tc program source code. They simply make your life easier and increase readability of your filter's configuration.

FIXME: table placeholder - the table is in separate file ,,selector.html''

FIXME: it's also still in Polish :-(

FIXME: must be sgml'ized

Some examples:

# tc filter add dev ppp0 parent 1:0 prio 10 u32 \
match ip tos 0x10 0xff \
flowid 1:4

FIXME: tcp dst match does not work as described below:

The above rule will match packets which have the TOS field set to 0x10. The TOS field starts at second byte of the packet and is one byte big, so we could write an equivalent general selector: match u8 0x10 0xff at 1. This gives us hint to the internals of U32 filter -- the specific rules are always translated to general ones, and in this form they are stored in the kernel memory. This leads to another conclusion -- the tcp and udp selectors are exactly the same and this is why you can't use single match tcp dst 53 0xffff selector to match TCP packets sent to given port -- they will also match UDP packets sent to this port. You must remember to also specify the protocol and end up with the following rule:

# tc filter add dev ppp0 parent 1:0 prio 10 u32 \
match tcp dst 53 0xffff \
match ip protocol 0x6 0xff \
flowid 1:2

Advanced filters for (re-)classifying packets

As
explained in the section on classful queueing disciplines, filters are
needed to classify packets into any of the sub-queues. These filters are
called from within the classful qdisc.

Here is an incomplete list of classifiers available:

fw

Bases the decision on how the firewall has
marked the packet. This can be the easy way out if you don't want to
learn tc filter syntax. See the Queueing chapter for details.

u32

Bases the decision on fields within the packet (i.e. source IP address, etc)

route

Bases the decision on which route the packet will be routed by

rsvp, rsvp6

Routes packets based on RSVP. Only useful on networks you control - the Internet does not respect RSVP.

tcindex

Used in the DSMARK qdisc, see the relevant section.

Note that in general there
are many ways in which you can classify packet and that it generally
comes down to preference as to which system you wish to use.

Classifiers in general accept a few arguments in common. They are listed here for convenience:

protocol

The protocol this classifier will accept. Generally you will only be accepting only IP traffic. Required.

parent

The handle this classifier is to be attached to. This handle must be an already existing class. Required.

prio

The priority of this classifier. Lower numbers get tested first.

handle

This handle means different things to different filters.

All the following sections will assume you are trying to shape the traffic going to HostA. They will assume that the root class has been configured on 1: and that the class you want to send
the selected traffic to is 1:1.

12.1. The u32 classifier

The U32 filter is the most advanced
filter available in the current implementation. It entirely based on
hashing tables, which make it robust when there are many filter rules.

In its simplest form the U32 filter is
a list of records, each consisting of two fields: a selector and an
action. The selectors, described below, are compared with the currently
processed IP packet until the first match occurs,
and then the associated action is performed. The simplest type of
action would be directing the packet into defined class.

The command line of tc filter program,
used to configure the filter, consists of three parts: filter
specification, a selector and an action. The filter specification can be
defined as:

tc filter add dev IF [ protocol PROTO ]
[ (preference|priority) PRIO ]
[ parent CBQ ]

The protocol field describes protocol that the filter will be applied to. We will only discuss case of ip protocol. The preference field (priority can be used alternatively) sets the priority of currently defined filter. This is important, since you can have several filters (lists of rules) with different priorities. Each list will be passed in the order the rules were added, then list with lower priority (higher preference number) will be processed. The parent field defines the CBQ tree top (e.g. 1:0), the filter should be attached to.

The options described above apply to all filters, not only U32.

12.1.1. U32 selector

The U32 selector contains definition of the pattern, that will be matched to the currently processed packet. Precisely, it defines which bits are to be matched in the packet header and nothing more, but this simple method is very powerful. Let's take a look at the following examples, taken directly from a pretty complex, real-world filter:

# tc filter add dev eth0 protocol ip parent 1:0 pref 10 u32 \
match u32 00100000 00ff0000 at 0 flowid 1:10

For now, leave the first line alone - all these parameters describe the filter's hash tables. Focus on the selector line, containing match keyword. This selector will match to IP headers, whose second byte will be 0x10 (0010). As you can guess, the 00ff number is the match mask, telling the filter exactly which bits to match. Here it's 0xff, so the byte will match if it's exactly 0x10. The at keyword means that the match is to be started at specified offset (in bytes) -- in this case it's beginning of the packet. Translating all that to human language, the packet will match if its Type of Service field will have `low delay' bits set. Let's analyze another rule:

# tc filter add dev eth0 protocol ip parent 1:0 pref 10 u32 \
match u32 00000016 0000ffff at nexthdr+0 flowid 1:10

The nexthdr option means next header encapsulated in the IP packet, i.e. header of upper-layer protocol. The match will also start here at the beginning of the next header. The match should occur in the second, 32-bit word of the header. In TCP and UDP protocols this field contains packet's destination port. The number is given in big-endian format, i.e. older bits first, so we simply read 0x0016 as 22 decimal, which stands for SSH service if this was TCP. As you guess, this match is ambiguous without a context, and we will discuss this later.

Having understood all the above, we will find the following selector quite easy to read: match c0a80100 ffffff00 at 16. What we got here is a three byte match at 17-th byte, counting from the IP header start. This will match for packets with destination address anywhere in 192.168.1/24 network. After analyzing the examples, we can summarize what we have learned.

12.1.2. General selectors

General selectors define the pattern, mask and offset the pattern will be matched to the packet contents. Using the general selectors you can match virtually any single bit in the IP (or upper layer) header. They are more difficult to write and read, though, than specific selectors that described below. The general selector syntax is:

match [ u32 | u16 | u8 ] PATTERN MASK [ at OFFSET | nexthdr+OFFSET]

One of the keywords u32u16 or u8 specifies length of the pattern in bits. PATTERN and MASK should follow, of length defined by the previous keyword. The OFFSET parameter is the offset, in bytes, to start matching. If nexthdr+ keyword is given, the offset is relative to start of the upper layer header.

Some examples:

Packet will match to this rule, if its time to live (TTL) is 64. TTL is the field starting just after 8-th byte of the IP header.

# tc filter add dev ppp14 parent 1:0 prio 10 u32 \
match u8 64 0xff at 8 \
flowid 1:4

The following matches all TCP packets which have the ACK bit set:

# tc filter add dev ppp14 parent 1:0 prio 10 u32 \
match ip protocol 6 0xff \
match u8 0x10 0xff at nexthdr+13 \
flowid 1:3

Use this to match ACKs on packets smaller than 64 bytes:

## match acks the hard way,
## IP protocol 6,
## IP header length 0x5(32 bit words),
## IP Total length 0x34 (ACK + 12 bytes of TCP options)
## TCP ack set (bit 5, offset 33)
# tc filter add dev ppp14 parent 1:0 protocol ip prio 10 u32 \
match ip protocol 6 0xff \
match u8 0x05 0x0f at 0 \
match u16 0x0000 0xffc0 at 2 \
match u8 0x10 0xff at 33 \
flowid 1:3

This rule will only match TCP packets with ACK bit set, and no further payload. Here we can see an example of using two selectors, the final result will be logical AND of their results. If we take a look at TCP header diagram, we can see that the ACK bit is second older bit (0x10) in the 14-th byte of the TCP header (at nexthdr+13). As for the second selector, if we'd like to make our life harder, we could write match u8 0x06 0xff at 9 instead of using the specific selectorprotocol tcp, because 6 is the number of TCP protocol, present in 10-th byte of the IP header. On the other hand, in this example we couldn't use any specific selector for the first match - simply because there's no specific selector to match TCP ACK bits.

The filter below is a modified version of the filter above. The difference is, that it doesn't check the ip header length. Why? Because the filter above does only work on 32 bit systems.

tc filter add dev ppp14 parent 1:0 protocol ip prio 10 u32 \
match ip protocol 6 0xff \
match u8 0x10 0xff at nexthdr+13 \
match u16 0x0000 0xffc0 at 2 \
flowid 1:3

12.1.3. Specific selectors

The following table contains a list of all specific selectors the author of this section has found in the tc program source code. They simply make your life easier and increase readability of your filter's configuration.

FIXME: table placeholder - the table is in separate file ,,selector.html''

FIXME: it's also still in Polish :-(

FIXME: must be sgml'ized

Some examples:

# tc filter add dev ppp0 parent 1:0 prio 10 u32 \
match ip tos 0x10 0xff \
flowid 1:4

FIXME: tcp dport match does not work as described below:

The above rule will match packets which have the TOS field set to 0x10. The TOS field starts at second byte of the packet and is one byte big, so we could write an equivalent general selector: match u8 0x10 0xff at 1. This gives us hint to the internals of U32 filter -- the specific rules are always translated to general ones, and in this form they are stored in the kernel memory. This leads to another conclusion -- the tcp and udp selectors are exactly the same and this is why you can't use single match tcp dport 53 0xffff selector to match TCP packets sent to given port -- they will also match UDP packets sent to this port. You must remember to also specify the protocol and end up with the following rule:

# tc filter add dev ppp0 parent 1:0 prio 10 u32 \
match tcp dport 53 0xffff \
match ip protocol 0x6 0xff \
flowid 1:2

The u32 classifier的更多相关文章

  1. 使用u32过滤器设置基于mac地址的下载限制

    u32过滤器一般使用ip地址作为匹配规则,但按照其定义,它可以匹配ip包头的任意地址,这里使用mac地址限制局域网的下载速度,避免客户端修改ip后其下载速度得不到控制.tc qdisc del dev ...

  2. Ingress qdisc

    Ingress qdisc All qdiscs discussed so far are egress qdiscs. Each interface however can also have an ...

  3. Android系统启动过程-uBoot+Kernel+Android

    摘要:本文是参考大量网上资源在结合自己查看源代码总结出来的,让自己同时也让大家加深对Android系统启动过程有一个更加深入的了解!再次强调,本文的大多数功劳应归功于那些原创者们,同时一些必要的参考链 ...

  4. 原始启动log&新log

    root@Taiyear:/# U-Boot 1.1.3 (Dec 27 2013 - 09:14:28) SoC:MediaTek MT7620 DRAM:  Memory Testing..655 ...

  5. HTB Linux queuing discipline manual - user guide笔记

    1. Introduction HTB is meant as a more understandable, intuitive and faster replacement for the CBQ ...

  6. iproute2学习笔记

    一.替代arp, ifconfig, route等命令 显示网卡和IP地址 root@openstack:~# ip link list 1: lo: <LOOPBACK,UP,LOWER_UP ...

  7. tiny210V2开发板hdmi输出到10.1寸LCD,无图像

    tiny210V2开发板hdmi输出到10.1寸LCD,无图像... 用tiny210V2开发板的HDMI接口输出到的10.1寸LCD,LCD无任何现象.说明一下我的情况,我的10.1寸屏LCD是HD ...

  8. openwrt procd 运行的一些log

    void procd_inittab(void) { #define LINE_LEN 128 FILE *fp = fopen(tab, "r"); struct init_ac ...

  9. Android USB驱动源码分析(-)

    Android USB驱动中,上层应用协议里最重要的一个文件是android/kernel/drivers/usb/gadget/android.c.这个文件实现USB的上层应用协议. 首先包含了一些 ...

随机推荐

  1. asp.net core StaticFiles中间件修改wwwroot

    new StaticFileOptions() { FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentD ...

  2. POJ 3660

    233333... Description: 就是说呢.牛是的实力室友大小之分的.然后呢.告诉你很多pair 表示任意两头牛之间的实力大小.按实力排序之后.问你一共有多少只牛的排名是确定了的. T_T ...

  3. 第三章 XHTML 表单

    1.表单的主要作用在于在网页上提供一个图形用户界面,以采集和提交用户输入的数据. 2.HTML表单元素和属性可以分为两种类型:定义表单整体结构,使浏览器知道如何处理表单数据的元素:创建输入控件的元素. ...

  4. 一模 (6) day1

    第一题: 题目大意: 一个n的全排列A[i]是单峰的,当且仅当存在某个x使得A[1]<A[2]<...<A[x]>A[x+1]>...>A[n]. 试求 n 的单峰 ...

  5. ubuntu连接Android调试

    从这周开始尝试Android开发,记下点滴. 安装JDK.下载ADT不说,连接手机调试的时候出错,一堆问号??????????.网上一查,属于典型错误.试下来,有几步比较关键,容易忽视: 1.我机器上 ...

  6. FG模型

    一直没搞懂CvBGStatModel和CvFGDStatModel有什么区别.CvBGStatModel模型的创建用cvCreateGaussianBGModel,CvFGDStatModel模型的创 ...

  7. bzoj 2154 莫比乌斯反演求lcm的和

    题目大意: 表格中每一个位置(i,j)填的值是lcm(i,j) , 求n*m的表格值有多大 论文贾志鹏线性筛中过程讲的很好 最后的逆元我利用的是欧拉定理求解的 我这个最后线性扫了一遍,勉强过了,效率不 ...

  8. MainActivity获取fragment控件button监听报空指针错误

    原因是是新版SDK创建项目时默认引入的fragment.xml,我的button是定义在fragment.xml里面的,而findviewbyid却是在main.activity里面调用的,而这样是获 ...

  9. c#读取文本文档实践3-写入到文本本文档

    首先通过File.ReadAllLines()方法读入文本文档中内容并返回字符串数组contents,这样每行数据就成为了这个字符串数组contents的一个元素,再利用split()方法将每一个元素 ...

  10. gsoap框架下的onvif程序流程分析

    SOAP_FMAC5 int SOAP_FMAC6 soap_serve(struct soap *soap) { do { unsigned int k = soap->max_keep_al ...