next up previous
Next: Classify Up: QoS Support in Linux Previous: Dump_class


Filters are used to classify packets based on certain properties of the packet, e.g., TOS byte in the IP header, IP addresses, port numbers etc. It is invoked when the enqueue function of a queuing discipline is invoked. Queuing disciplines use filters to assign the incoming packets to one of its classes.

Filters can be maintained per class or per queuing discipline based on the design of the queuing discipline. As already mentioned in the previous section, filters are maintained in filter lists. The filter list is specified as a struct tcf_proto, in include/net/pkt_cls.h.

struct tcf_proto
 /* Fast access part */
 struct tcf_proto        *next;
 void                    *root;
 int                     (*classify)(struct sk_buff*, struct tcf_proto*, 
                         struct tcf_result *);
 u32                     protocol;

 /* All the rest */
 u32                     prio;
 u32                     classid;
 struct Qdisc            *q;
 void                    *data;
 struct tcf_proto_ops    *ops;

This structure is used to represent filter lists and is maintained by the classes and queuing disciplines. As an example, the cbq_class structure in net/sched/sch_cbq.c maintains the filter list by using the tcf_proto structure. The tcf_chain function on classes, described in the previous section, is used to return the anchor to a filter list, which can be used to traverse the filter list. Filter lists are ordered by priority, in ascending order. Also, the entries are keyed by the protocol for which they apply, e.g., IP, UDP etc. Filters for the same protocol on the same filter list must have different priority values. The protocol numbers are used in skb->protocol and they are defined in include/linux/if_ether.h.

Filters may also have an internal structure: it may control internal elements, which are referenced by a handle. These handles are 32-bit long, but are not divided into major and minor numbers like class IDs. Handle 0 refers to the filter itself. Like classes, filters also have an internal ID, which can be obtained with the help of a get function. The basic structure of filters is shown in Figure 4.

Figure 4: Structure of Filters

When the enqueue function of a queuing discipline is invoked, the tc_classify function in include/net/pkt_cls.h is invoked to classify the packet.

extern __inline__ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
struct tcf_result *res)
 int err = 0;
 u32 protocol = skb->protocol;
 for ( ; tp; tp = tp->next) {
   if ((tp->protocol == protocol || 
     tp->protocol == __constant_htons(ETH_P_ALL)) 
     && (err = tp->classify(skb, tp, res)) >= >0)
        return err;
 return -1;
As seen above in this function, the protocol to which the packet belongs to is determined from skb->protocol. Once this is obtained, the filters corresponding to this protocol are all applied in the order of priority. Within each filter all the internal elements are traversed in an attempt to classify the packet. Once the packet is classified, as already mentioned, the enqueue function of the queuing discipline owned by the class is invoked. This process of obtaining a match for the packet is shown in Figure 5.

Figure 5: Matching a filter

Let us now discuss the functions that can be performed on the filters. The functions are defined in the tc_proto_ops structure in include/net/pkt_cls.h.

next up previous
Next: Classify Up: QoS Support in Linux Previous: Dump_class
Saravanan Radhakrishnan