mirror of https://gitee.com/openkylin/linux.git
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: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c9f1d0389b
commit
71ebe5e919
|
@ -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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = {
|
||||||
.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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 =
|
||||||
.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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue