diff options
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 95b560f0b253..b855352167b1 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1173,6 +1173,45 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n) } /* + * enable/disable flow on qdisc. + */ +int +tc_qdisc_flow_control(struct net_device *dev, u32 tcm_handle, int enable_flow) +{ + struct Qdisc *q; + int qdisc_len = 0; + struct __qdisc_change_req { + struct nlattr attr; + struct tc_prio_qopt data; + } req = { + .attr = {sizeof(struct __qdisc_change_req), TCA_OPTIONS}, + .data = {3, {1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}, 1} + }; + + /* override flow bit */ + req.data.enable_flow = enable_flow; + + /* look up using tcm handle */ + q = qdisc_lookup(dev, tcm_handle); + + /* call registered change function */ + if (likely(q && q->ops)) { + if (likely(q->ops->change)) { + qdisc_len = q->q.qlen; + if (q->ops->change(q, &req.attr) != 0) + pr_err("%s(): qdisc change failed", __func__); + } else { + WARN_ONCE(1, "%s(): called on queue which does %s", + __func__, "not support change() operation"); + } + } else { + WARN_ONCE(1, "%s(): called on bad queue", __func__); + } + return qdisc_len; +} +EXPORT_SYMBOL(tc_qdisc_flow_control); + +/* * Create/change qdisc. */ |