Hi, I''m trying to police ingress traffic based on port numbers and IP addresses. The u32 match based on IP addresses seems to work without issues and I''m am able to police incoming packets. However, the same isn''t working with u32 matches based on TCP port numbers. For port numbers, I added exactly one ''u32 match'' rule: common for both: # tc qdisc add dev eth0 handle ffff: ingress And then: # tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match ip src \ 0.0.0.0/0 police rate 128kbit burst 10k drop flowid :1 The rule above works, but the same with a port match does not: # tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match tcp dport 0xXYZ 0xFFFF police rate 128kbit burst 10k drop flowid :1 Is there anything I am missing? TIA, -- Shuveb Hussain. When you lose, be patient. When you achieve, be even more patient.
Shuveb Hussain wrote:> Hi, > > I''m trying to police ingress traffic based on port numbers and IP > addresses. The u32 match based on IP addresses seems to work without > issues and I''m am able to police incoming packets. However, the same > isn''t working with u32 matches based on TCP port numbers. For port > numbers, I added exactly one ''u32 match'' rule: > > common for both: > # tc qdisc add dev eth0 handle ffff: ingress > > And then: > > # tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match ip > src \ > 0.0.0.0/0 police rate 128kbit burst 10k drop flowid :1 > > The rule above works, but the same with a port match does not: > > # tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match > tcp dport 0xXYZ 0xFFFF police rate 128kbit burst 10k drop flowid :1 > > Is there anything I am missing?I''ve never managed to find a way to use the word tcp in a filter without getting an illegal match - I know it''s in the help. If you want to match tcp use the ip protocol match tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match ip dport 0xXYZ 0xFFFF match ip protocol 0x06 0xff police ..... Andy.
Hi,>> Hi, >> >> I''m trying to police ingress traffic based on port numbers and IP >> addresses. The u32 match based on IP addresses seems to work without >> issues and I''m am able to police incoming packets. However, the same >> isn''t working with u32 matches based on TCP port numbers. For port >> numbers, I added exactly one ''u32 match'' rule: >> >> common for both: >> # tc qdisc add dev eth0 handle ffff: ingress >> >> And then: >> >> # tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match ip >> src \ >> 0.0.0.0/0 police rate 128kbit burst 10k drop flowid :1 >> >> The rule above works, but the same with a port match does not: >> >> # tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match >> tcp dport 0xXYZ 0xFFFF police rate 128kbit burst 10k drop flowid :1 >> >> Is there anything I am missing?>I''ve never managed to find a way to use the word tcp in a filter without >getting an illegal match - I know it''s in the help.The reason it does not work is that the keywords that refer to the L4 protocols (such as tcp) are supposed to be used when: 1) the u32 filter is inserted into a u32 hash table AND 2) you jump to the above hash table from a u32 filter configured with the "offset" option. (unfortunately the U32 classifier is not well documented)>If you want to match tcp use the ip protocol match > >tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match >ip dport 0xXYZ 0xFFFF match ip protocol 0x06 0xff police .....You should invert the order of the two "match" conditions: first you make sure it is TCP, and then you test the destination port number. This filter works in most cases, but not always: it does not take into account the IP options. IP packets with options in the IP header will not match. The reason is that "ip dport" is equivalent to "offset 22" from the beginning of the IP header. Regards /Christian [http://benve.info]
Christian Benvenuti wrote:>> I''ve never managed to find a way to use the word tcp in a filter without >> getting an illegal match - I know it''s in the help. > > The reason it does not work is that the keywords that refer to the L4 > protocols (such as tcp) are supposed to be used when: > 1) the u32 filter is inserted into a u32 hash table > AND > 2) you jump to the above hash table from a u32 filter configured with > the "offset" option. > > (unfortunately the U32 classifier is not well documented)Ahh thanks I''ll have to try some hashing tests. Last time I tried I found that going above 512 buckets didn''t work so I gave up and still haven''t looked into turning things up (I assume that''s possible)> >> If you want to match tcp use the ip protocol match >> >> tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match >> ip dport 0xXYZ 0xFFFF match ip protocol 0x06 0xff police ..... > > You should invert the order of the two "match" conditions: first you make > sure it is TCP, and then you test the destination port number. >Hmm - does that really matter - I did it that way because, judging by filter counters the first match that fails stops further matching. It depends on what you match and your traffic patterns, but it seemed like it would be more efficient.> This filter works in most cases, but not always: it does not take into > account the IP options. IP packets with options in the IP header will > not match. > The reason is that "ip dport" is equivalent to "offset 22" from the > beginning of the IP header.I wonder how many packets there are like that in the wild - I don''t have much traffic to test. It''s possible to make a fall through counter by making a match and not specifying a class/flowid, though ISTR seeing a patch recently that made me think that won''t work anymore. Andy.
Hi,>>> If you want to match tcp use the ip protocol match >>> >>> tc filter add dev eth0 parent ffff: protocol ip prio 50 u32 match >>> ip dport 0xXYZ 0xFFFF match ip protocol 0x06 0xff police ..... >> >> You should invert the order of the two "match" conditions: first you make >> sure it is TCP, and then you test the destination port number. > >Hmm - does that really matter - I did it that way because, judging by >filter counters the first match that fails stops further matching. It >depends on what you match and your traffic patterns, but it seemed like >it would be more efficient.When performances are critical it can make sense to test the destination port number first, you are right. However, since at offset 22 there is the TCP destination port number only when the transport protocol is TCP (otherwise there is something else), it would not be a bad idea to first test the transport layer protocol. This is just my personal preference. I am sure many people prefer your solution. One more reason why I _personally_ would prefer to test the protocol first is that when you test dport first you also change the way the filter''s statistics are updated. Here is an example. # TCP DST PORT = 5000 --> Class 1:12 tc filter add dev eth1 parent 1:0 prio 3 protocol ip \ u32 \ match ip protocol 6 0xFF \ match ip dport 5000 0xFFFF \ flowid 1:12 The u32 classifier can return the number of successes for each match condition: # tc -s -d filter list dev eth1 filter parent 1: protocol ip pref 3 u32 fh 800::801 order 2049 key ht 800 bkt 0 flowid 1:12 (rule hit 0 success 0) match 00060000/00ff0000 at 8 (success 0 ) <-------Partial counters match 00001388/0000ffff at 20 (success 0 ) <-------" ">From the output above I can tell:1) how many TCP packets have been tested by the filter (1st match) 2) how many TCP packets matched dport (2nd match) 3) how many packets matched both 1) and 2). (In the simple example above 2) and 3) are the same) If you invert the order of the match conditions, you can only tell: 1) how many packets matched the filter (i.e., both the protocol and dport) You can not trust all the partial counters.>> This filter works in most cases, but not always: it does not take into >> account the IP options. IP packets with options in the IP header will >> not match. >> The reason is that "ip dport" is equivalent to "offset 22" from the >> beginning of the IP header. > >I wonder how many packets there are like that in the wild - I don''t have > much traffic to test. It''s possible to make a fall through counter by >making a match and not specifying a class/flowid, though ISTR seeing a >patch recently that made me think that won''t work anymore.ISTR? An easy workaround (for detecting the packets with options) consists of adding another match condition that first tests the IHL field of the IP header and makes sure there are no option (i.e., IHL=5). Another workaround consists of tagging the packets with iptables. The percentage of IP packets with options is small. However, the choice here is between a configuration that is always correct (and therefore easier to troubleshoot) and one that is not always correct. For example, an ISP should not take the 2nd option into consideration. Regards /Christian [http://benve.info]