summaryrefslogtreecommitdiff
path: root/net/sched/sch_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r--net/sched/sch_api.c39
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.
*/