提交 71ebe5e9 编写于 作者: P Patrick McHardy 提交者: David S. Miller

net_sched: make cls_ops->tcf_chain() optional

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: NPatrick McHardy <kaber@trash.net>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 c9f1d038
...@@ -181,6 +181,9 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) ...@@ -181,6 +181,9 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
if ((cops = q->ops->cl_ops) == NULL) if ((cops = q->ops->cl_ops) == NULL)
return -EINVAL; return -EINVAL;
if (cops->tcf_chain == NULL)
return -EOPNOTSUPP;
/* Do we search for filter, attached to class? */ /* Do we search for filter, attached to class? */
if (TC_H_MIN(parent)) { if (TC_H_MIN(parent)) {
cl = cops->get(q, parent); cl = cops->get(q, parent);
...@@ -433,6 +436,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -433,6 +436,8 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
goto out; goto out;
if ((cops = q->ops->cl_ops) == NULL) if ((cops = q->ops->cl_ops) == NULL)
goto errout; goto errout;
if (cops->tcf_chain == NULL)
goto errout;
if (TC_H_MIN(tcm->tcm_parent)) { if (TC_H_MIN(tcm->tcm_parent)) {
cl = cops->get(q, tcm->tcm_parent); cl = cops->get(q, tcm->tcm_parent);
if (cl == 0) if (cl == 0)
......
...@@ -331,11 +331,6 @@ static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker) ...@@ -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 = { static const struct Qdisc_class_ops red_class_ops = {
.graft = red_graft, .graft = red_graft,
.leaf = red_leaf, .leaf = red_leaf,
...@@ -344,7 +339,6 @@ static const struct Qdisc_class_ops red_class_ops = { ...@@ -344,7 +339,6 @@ static const struct Qdisc_class_ops red_class_ops = {
.change = red_change_class, .change = red_change_class,
.delete = red_delete, .delete = red_delete,
.walk = red_walk, .walk = red_walk,
.tcf_chain = red_find_tcf,
.dump = red_dump_class, .dump = red_dump_class,
}; };
......
...@@ -433,11 +433,6 @@ static void tbf_walk(struct Qdisc *sch, struct qdisc_walker *walker) ...@@ -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 = static const struct Qdisc_class_ops tbf_class_ops =
{ {
.graft = tbf_graft, .graft = tbf_graft,
...@@ -447,7 +442,6 @@ static const struct Qdisc_class_ops tbf_class_ops = ...@@ -447,7 +442,6 @@ static const struct Qdisc_class_ops tbf_class_ops =
.change = tbf_change_class, .change = tbf_change_class,
.delete = tbf_delete, .delete = tbf_delete,
.walk = tbf_walk, .walk = tbf_walk,
.tcf_chain = tbf_find_tcf,
.dump = tbf_dump_class, .dump = tbf_dump_class,
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册