3

with "u32 match ip sport 80" in Linux tc I can match port 80, but how can I match a port range 10000 - 20000 ?

Supratik
  • 2,154
  • 10
  • 51
  • 66

4 Answers4

5

You can use ematch - extended match - instead of u32 filter, which supports "less than" and "greater than" comparisons. Have a look at the man page.

The following matches packets with source port in the range 70 - 90 (excluding)

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

Danny Sade
  • 51
  • 1
  • 1
4

You can use mask, but it difficult:

 u32 match ip sport 4096 0xf000 = sport 4096-8191
 u32 match ip sport 8192 0xe000 = sport 8192-16383

0xf000/0xe000 is the mask. The word extracted from the packet is bit-wise with this mask before comparison.

value = 0001000000000000
mask  = 1111000000000000

start = 0001000000000000
end   = 0001111111111111

Also you can create many filter for one 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

For your example, your need create several 'tc filter':

first: sport 10000 0xfff0 (10000-10015)
second: sport 10016 0xffe0 (10016-10047)
.............

etc.

10000=10011100010000

0010011100010000
           |
     first not zero
1111111111111111
mask
1111111111110000=0xfff0

[Basically take the first number in the range (in this example 10,000) and convert it to binary ( 0010011100010000 ); then scan this binary number from right to left until you encounter the 1st non 0 bit; then make the bits from the left of that bit all into 1's inclusive, and all the bits to the right of it to zeros. That is how you come out to 0xfff0 as the mask.]

alvosu
  • 8,437
  • 25
  • 22
  • How the mask is created here ? – Supratik Feb 06 '11 at 18:49
  • See my update, but I do not compute all the masks, only the first two – alvosu Feb 06 '11 at 23:13
  • @alvosu Can you please tell what is the logic behind the mask calculation ? – Supratik Feb 07 '11 at 11:43
  • $probe_port LOGIN_AND $MASK compared $PORT – alvosu Feb 07 '11 at 11:58
  • @alvosu I think I am not able to explain here properly. Let me rephrase it once again. sport 10000 0xfff0 represents a port range between 10000-10015, can you please tell me how you have calculated the value "0xfff0" ? – Supratik Feb 07 '11 at 13:43
  • I try, but my English bad – alvosu Feb 07 '11 at 14:20
  • @alvosu thanks for the information, it is really helpful. I also googled and found some links which might help others. "http://sleepyhead.de/howto/?href=network" and "http://mailman.ds9a.nl/pipermail/lartc/2007q4/021739.html" – Supratik Feb 08 '11 at 05:12
2

I made a script to do what @alvosu described for anyone interested.

http://blog.roeften.com/2017/01/mask-calculator.html

Currently it will include more ports on the right of the range.

The fiddle is at http://jsfiddle.net/hp6dfnvg/13/

A messy python implementation as well:

    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
Roeften
  • 136
  • 3
0

I've created this simple script on my blog to create the masks for any port range...

I got tired of googling it just to find the wrong ways to do it... Enjoy!

http://marcelustrojahn.blogspot.com/2011/06/u32-port-masks_14.html site is down :(