net_sched: make cls_ops->tcf_chain() optional
Patrick McHardy [Fri, 4 Sep 2009 06:41:15 +0000 (06:41 +0000)]
Some qdiscs don't support attaching filters. Handle this centrally in
cls_api and return a proper errno code (EOPNOTSUPP) instead of EINVAL.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

net/sched/cls_api.c
net/sched/sch_red.c
net/sched/sch_tbf.c

index 09cdcdf..bcfbdb4 100644 (file)
@@ -181,6 +181,9 @@ replay:
        if ((cops = q->ops->cl_ops) == NULL)
                return -EINVAL;
 
+       if (cops->tcf_chain == NULL)
+               return -EOPNOTSUPP;
+
        /* Do we search for filter, attached to class? */
        if (TC_H_MIN(parent)) {
                cl = cops->get(q, parent);
@@ -433,6 +436,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
                goto out;
        if ((cops = q->ops->cl_ops) == NULL)
                goto errout;
+       if (cops->tcf_chain == NULL)
+               goto errout;
        if (TC_H_MIN(tcm->tcm_parent)) {
                cl = cops->get(q, tcm->tcm_parent);
                if (cl == 0)
index 2bdf241..c27b802 100644 (file)
@@ -331,11 +331,6 @@ static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
        }
 }
 
-static struct tcf_proto **red_find_tcf(struct Qdisc *sch, unsigned long cl)
-{
-       return NULL;
-}
-
 static const struct Qdisc_class_ops red_class_ops = {
        .graft          =       red_graft,
        .leaf           =       red_leaf,
@@ -344,7 +339,6 @@ static const struct Qdisc_class_ops red_class_ops = {
        .change         =       red_change_class,
        .delete         =       red_delete,
        .walk           =       red_walk,
-       .tcf_chain      =       red_find_tcf,
        .dump           =       red_dump_class,
 };
 
index e22dfe8..2890969 100644 (file)
@@ -433,11 +433,6 @@ static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker)
        }
 }
 
-static struct tcf_proto **tbf_find_tcf(struct Qdisc *sch, unsigned long cl)
-{
-       return NULL;
-}
-
 static const struct Qdisc_class_ops tbf_class_ops =
 {
        .graft          =       tbf_graft,
@@ -447,7 +442,6 @@ static const struct Qdisc_class_ops tbf_class_ops =
        .change         =       tbf_change_class,
        .delete         =       tbf_delete,
        .walk           =       tbf_walk,
-       .tcf_chain      =       tbf_find_tcf,
        .dump           =       tbf_dump_class,
 };