在 Linux tc 中使用“u32 match ip sport 80”我可以匹配端口 80,但是如何匹配端口范围 10000 - 20000?
答案1
可以使用面膜,但是比较困难:
u32 match ip sport 4096 0xf000 = sport 4096-8191
u32 match ip sport 8192 0xe000 = sport 8192-16383
0xf000/0xe000 是掩码。从数据包中提取的字在比较之前会按位与此掩码匹配。
value = 0001000000000000
mask = 1111000000000000
start = 0001000000000000
end = 0001111111111111
您还可以为一个 classid 创建多个过滤器:
tc filter add dev eth0 parent 1:0 prio 3 protocol ip u32 match ip protocol 6 0xff match ip sport 10000 0xffff classid 1:13
tc filter add dev eth0 parent 1:0 prio 3 protocol ip u32 match ip protocol 6 0xff match ip sport 10001 0xffff classid 1:13
tc filter add dev eth0 parent 1:0 prio 3 protocol ip u32 match ip protocol 6 0xff match ip sport 10002 0xffff classid 1:13
对于您的示例,您需要创建几个“tc 过滤器”:
first: sport 10000 0xfff0 (10000-10015)
second: sport 10016 0xffe0 (10016-10047)
.............
ETC。
10000=10011100010000
0010011100010000
|
first not zero
1111111111111111
mask
1111111111110000=0xfff0
[基本上,取范围内的第一个数字(本例中为 10,000)并将其转换为二进制( 0010011100010000 );然后从右到左扫描这个二进制数,直到遇到第一个非 0 位;然后将该位左侧的位全部设为 1(包括 1),将其右侧的所有位设为 0。这就是您得到 0xfff0 作为掩码的方法。]
答案2
您可以使用 ematch(扩展匹配)代替 u32 过滤器,它支持“小于”和“大于”比较。请查看手册页。
以下匹配源端口在 70 - 90 范围内(不包括)的数据包
tc filter add dev eth0 parent 1: protocol ip prio 1 basic match “cmp(u16 at 0 layer transport gt 70) and cmp(u16 at 0 layer transport lt 90)” flowid 1:3
答案3
我编写了一个脚本来执行@alvosu 为任何感兴趣的人所描述的操作。
http://blog.roeften.com/2017/01/mask-calculator.html
目前它将在范围右侧包含更多端口。
小提琴在http://jsfiddle.net/hp6dfnvg/13/
混乱的 Python 实现如下:
import logging
logging.getLogger().setLevel(logging.DEBUG)
fp = 20001 # From port
tp = 25000 # to port
dev = 'ifb0' # dev to add filter rule to
flow = '1:10' # flow id to set
def find_lsm(p,o=1):
m = o
i = 1
while(True):
if(p & m > 0):
return m,i
m = m << 1
i += 1
l = 0xffff
ms = 2
me = None
cp = fp
i = 0
t = ''
while(True):
cm,s = find_lsm(cp)
if cm >= tp:
break
e = cp | cm - 1
m = l & (l << s -1)
logging.info('Range %i - %i, mask %08x', cp, e, m )
i += 1
t += "tc filter add dev {} parent 1: prio {} protocol ip u32 match ip protocol 17 0xff match ip dport {} 0x{:0>8x} flowid {}\n".format(dev,i,cp,m,flow)
cp += cm
print t
答案4
我在我的博客上创建了这个简单的脚本来为任何端口范围创建掩码......
我已经厌倦了通过谷歌搜索却发现错误的方法...尽情享受吧!
http://marcelustrojahn.blogspot.com/2011/06/u32-port-masks_14.html
网站已关闭 :(