RE: iptables CLASSIFY and MARK not working?

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Ok, I ran into a different issue with using the tc filters which
basically puts me right back to using the iptables classify target --
which means that I am running right back into the same problem I was on
before. 

As a refresher, the problem is that the classify target, while matching
in the postrouting chain of the mangle table, is not actually directing
the traffic through the correct TC class. 

Now, I took a look through the iptables classify target code in iptables
and in the Linux kernel. From what I have deciphered thus far, it does
not appear likely that there is a bug in the code in iptables. In fact,
it is a very small amount of code. Essentially, the iptables code runs
through its normal hooks and simply does a sscanf on the --set-class
option to convert the string into numbers. Then it uses the TC_H_MAKE
macro in the packet scheduler code to create a scheduler handle (by
shifting the major node number left 16 bits and ORing in the minor node
number). This 32-bit handle is then stored in the socket buffer priority
field (skb->priority) for use in the scheduler. That's the end of the
iptables code.

At this point, it is up to the scheduler algorithms to handle the
placement of the packets into the correct class. 


// From hfsc_classify()

if (TC_H_MAJ(skb->priority ^ sch->handle) == 0 &&
  (cl = hfsc_find_class(skb->priority, sch)) != NULL)
 if (cl->level == 0)
   return cl;

// filter code cut out


// From htb_classify()

/* allow to select class by setting skb->priority to valid classid;
   note that nfmark can be used too by attaching filter fw with no
   rules in it */
if (skb->priority == sch->handle)
        return HTB_DIRECT;  /* X:0 (direct flow) selected */
if ((cl = htb_find(skb->priority,sch)) != NULL && cl->level == 0)
        return cl;

// filter code cut out


// From cbq_classify()

/*
 *  Step 1. If skb->priority points to one of our classes, use it.
 */
if (TC_H_MAJ(prio^sch->handle) == 0 &&
    (cl = cbq_class_lookup(q, prio)) != NULL)
  return cl;

// filter code cut out



So, it would appear that we are doing essentially this logic:

If the priority field is set such that it contains a major node number
(a handle) that is equal to the handle for the current qdisc, then we
try to find a class that matches the priority field. If the find
function does not find a class, we fall back on the filter code to pick
a class. If the find function does find a class, we check to make sure
the class is a leaf node (HTB and HFSC). If it is a leaf node, we return
a pointer to the class. On CBQ, we just return a pointer to the class
without a leaf node check. 

This logic seems pretty straight forward. So, if this is failing, there
can only be a couple of reasons:

1) The skb->priority field is blank when this function starts 
2) The skb->priority field contains an invalid class id. 
3) The skb->priority field does not reference the handle we are inside
of
4) The handle and class specified in the skb->priority field is not a
leaf node
5) The code elsewhere in tc is messed up.

Now, I have double checked my rules to verify that the class IDs match
up:

Chain POSTROUTING (policy ACCEPT 15224 packets, 1809K bytes)
 pkts bytes target     prot opt in     out     source
destination
   27  1792 CLASSIFY   all  --  *      br1     0.0.0.0/0
0.0.0.0/0           MARK match 0x1f8 CLASSIFY set 1:504
   11  4569 CLASSIFY   all  --  *      br1     0.0.0.0/0
0.0.0.0/0           MARK match 0x1f9 CLASSIFY set 1:505
    0     0 CLASSIFY   all  --  *      br1     0.0.0.0/0
0.0.0.0/0           MARK match 0x1fa CLASSIFY set 1:506
   19  2172 CLASSIFY   all  --  *      wivl4   0.0.0.0/0
0.0.0.0/0           MARK match 0x1f8 CLASSIFY set 5:504
   10   640 CLASSIFY   all  --  *      wivl4   0.0.0.0/0
0.0.0.0/0           MARK match 0x1f9 CLASSIFY set 5:505
    0     0 CLASSIFY   all  --  *      wivl4   0.0.0.0/0
0.0.0.0/0           MARK match 0x1fa CLASSIFY set 5:506
 3960  252K CLASSIFY   all  --  *      br1     0.0.0.0/0
0.0.0.0/0           MARK match 0x1fe CLASSIFY set 1:510
    8  4485 CLASSIFY   all  --  *      br1     0.0.0.0/0
0.0.0.0/0           MARK match 0x1ff CLASSIFY set 1:511
    0     0 CLASSIFY   all  --  *      br1     0.0.0.0/0
0.0.0.0/0           MARK match 0x200 CLASSIFY set 1:512
 3899  235K CLASSIFY   all  --  *      wivl4   0.0.0.0/0
0.0.0.0/0           MARK match 0x1fe CLASSIFY set 5:510
   20  1064 CLASSIFY   all  --  *      wivl4   0.0.0.0/0
0.0.0.0/0           MARK match 0x1ff CLASSIFY set 5:511
    0     0 CLASSIFY   all  --  *      wivl4   0.0.0.0/0
0.0.0.0/0           MARK match 0x200 CLASSIFY set 5:512


wireless-r1 ~ # tc -s class show dev wivl4
class hfsc 5: root
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 1

class hfsc 5:505 parent 5: sc m1 160000bit d 2.0s m2 0bit ul m1
160000bit d 2.0s m2 0bit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0

class hfsc 5:1 parent 5: sc m1 0bit d 2.6ms m2 30000Kbit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0

class hfsc 5:504 parent 5: sc m1 400000bit d 30.0ms m2 128000bit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0

class hfsc 5:2 parent 5: ls m1 60000Kbit d 2.0s m2 60000Kbit ul m1
60000Kbit d 2.0s m2 60000Kbit
 Sent 566530 bytes 8797 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 8797 work 566530 bytes level 0

class hfsc 5:3 parent 5: ls m1 10000Kbit d 2.0s m2 10000Kbit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0

class hfsc 5:510 parent 5: sc m1 400000bit d 30.0ms m2 128000bit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0

class hfsc 5:511 parent 5: sc m1 2560Kbit d 2.0s m2 480000bit ul m1
2560Kbit d 2.0s m2 1920Kbit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0

class hfsc 5:512 parent 5: ls m1 960000bit d 2.0s m2 960000bit
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0
 period 0 level 0


You'll notice that the iptables rules show matches for class 5:510,
5:511, and others; yet, the only class taking traffic here is 5:2. 

Now, this proves that options 2 & 3 above are not the case. That leaves:

1) The skb->priority field is blank when this function starts
4) The handle and class specified in the skb->priority field is not a
leaf node
5) The code elsewhere in tc is messed up.

As for option #4, we can show that there are no children for the class
by also taking a look at the qdiscs for the interface:

qdisc hfsc 5: default 2
 Sent 593904 bytes 9198 pkt (dropped 0, overlimits 0 requeues 0)
 rate 0bit 0pps backlog 0b 0p requeues 0


Well, there is only 1 qdisc. Since there are no other classes listed
that say they are a child of 5:510 or 5:511, then obviously 5:510 must
be a leaf node. Thus, option #4 is negated. 

Does anyone have any clues on this?

Thanks.

Eliot Gable
Certified Wireless Network Administrator (CWNA)
Certified Wireless Security Professional (CWSP)
Cisco Certified Network Associate (CCNA)
CompTIA Security+ Certified
CompTIA Network+ Certified
Network and System Engineer
Great Lakes Internet, Inc.
112 North Howard
Croswell, MI 48422
(810) 679-3395
(877) 558-8324
 
Now offering Broadband Wireless Internet access in Croswell, Lexington,
Brown City, Yale, Worth Township, and Sandusky. Call for details.

-----Original Message-----
From: Jody Shumaker [mailto:jody.shumaker@xxxxxxxxx] 
Sent: Tuesday, May 23, 2006 12:33 AM
To: Eliot, Wireless and Server Administrator, Great Lakes Internet
Cc: Andreas Unterkircher; lartc@xxxxxxxxxxxxxxx
Subject: Re:  iptables CLASSIFY and MARK not working?

On 5/22/06, Eliot, Wireless and Server Administrator, Great Lakes
Internet <support8@xxxxxxxxxxxxxx> wrote:
> You were exactly right here. Moving to the filters instead of the
> iptables classify solved the issue. As for performance, I have not yet
> benchmarked it to determine if the filters are fast enough for the
> number of users I need this to support.
>
>

And makes me wonder if its a bug or a design choice that iptables
classify doesn't handle this. If the performance isn't acceptable, you
might want to look into that. Or look into tc filters and hashing
which can improve performance depending on the filters.

- Jody
_______________________________________________
LARTC mailing list
LARTC@xxxxxxxxxxxxxxx
http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc


[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux