static unsigned long cbq_bind_filter(struct Qdisc *sch, u32 classid)
{
struct cbq_sched_data *q = (struct cbq_sched_data *)sch->data;
struct cbq_class *cl = cbq_class_lookup(q, classid);
if (cl) {
cl->filters++;
return (unsigned long)cl;
}
return 0;
}
As shown in this function, when the cbq_bind_filter function is called, the filter count for the class is incremented. This function is almost similar to the get function on a class. The difference is that a class that is pointed to by filters cannot be deleted without deleting the filters. That is, the queuing discipline explicitly refuses requests to delete a class if the class is in use. This can be seen from the following portion of the code from the cbq_delete function in net/sched/sch_cbq.c
static int cbq_delete(struct Qdisc *sch, unsigned long arg)
{
.
.
if (cl->filters || cl->children || cl == &q->link)
return -EBUSY;
.
.
.
}
However, there is a bug in the dsmark queuing discipline implementation. In this case, the get and bind_tcf functions map to the dsmark_get function, which is incorrect. Thus a class being pointed to by a filter may be deleted, which is not the desired behavior.