diff options
-rw-r--r-- | include/uapi/linux/pkt_sched.h | 1 | ||||
-rw-r--r-- | net/sched/sch_htb.c | 31 |
2 files changed, 17 insertions, 15 deletions
diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h index 32aef0a439ef..dbd71b0c7d8c 100644 --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h | |||
@@ -348,6 +348,7 @@ enum { | |||
348 | TCA_HTB_INIT, | 348 | TCA_HTB_INIT, |
349 | TCA_HTB_CTAB, | 349 | TCA_HTB_CTAB, |
350 | TCA_HTB_RTAB, | 350 | TCA_HTB_RTAB, |
351 | TCA_HTB_DIRECT_QLEN, | ||
351 | __TCA_HTB_MAX, | 352 | __TCA_HTB_MAX, |
352 | }; | 353 | }; |
353 | 354 | ||
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 571f1d211f4d..79b1876b6cd2 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -981,6 +981,7 @@ static const struct nla_policy htb_policy[TCA_HTB_MAX + 1] = { | |||
981 | [TCA_HTB_INIT] = { .len = sizeof(struct tc_htb_glob) }, | 981 | [TCA_HTB_INIT] = { .len = sizeof(struct tc_htb_glob) }, |
982 | [TCA_HTB_CTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | 982 | [TCA_HTB_CTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, |
983 | [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, | 983 | [TCA_HTB_RTAB] = { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, |
984 | [TCA_HTB_DIRECT_QLEN] = { .type = NLA_U32 }, | ||
984 | }; | 985 | }; |
985 | 986 | ||
986 | static void htb_work_func(struct work_struct *work) | 987 | static void htb_work_func(struct work_struct *work) |
@@ -994,7 +995,7 @@ static void htb_work_func(struct work_struct *work) | |||
994 | static int htb_init(struct Qdisc *sch, struct nlattr *opt) | 995 | static int htb_init(struct Qdisc *sch, struct nlattr *opt) |
995 | { | 996 | { |
996 | struct htb_sched *q = qdisc_priv(sch); | 997 | struct htb_sched *q = qdisc_priv(sch); |
997 | struct nlattr *tb[TCA_HTB_INIT + 1]; | 998 | struct nlattr *tb[TCA_HTB_MAX + 1]; |
998 | struct tc_htb_glob *gopt; | 999 | struct tc_htb_glob *gopt; |
999 | int err; | 1000 | int err; |
1000 | int i; | 1001 | int i; |
@@ -1002,20 +1003,16 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
1002 | if (!opt) | 1003 | if (!opt) |
1003 | return -EINVAL; | 1004 | return -EINVAL; |
1004 | 1005 | ||
1005 | err = nla_parse_nested(tb, TCA_HTB_INIT, opt, htb_policy); | 1006 | err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy); |
1006 | if (err < 0) | 1007 | if (err < 0) |
1007 | return err; | 1008 | return err; |
1008 | 1009 | ||
1009 | if (tb[TCA_HTB_INIT] == NULL) { | 1010 | if (!tb[TCA_HTB_INIT]) |
1010 | pr_err("HTB: hey probably you have bad tc tool ?\n"); | ||
1011 | return -EINVAL; | 1011 | return -EINVAL; |
1012 | } | 1012 | |
1013 | gopt = nla_data(tb[TCA_HTB_INIT]); | 1013 | gopt = nla_data(tb[TCA_HTB_INIT]); |
1014 | if (gopt->version != HTB_VER >> 16) { | 1014 | if (gopt->version != HTB_VER >> 16) |
1015 | pr_err("HTB: need tc/htb version %d (minor is %d), you have %d\n", | ||
1016 | HTB_VER >> 16, HTB_VER & 0xffff, gopt->version); | ||
1017 | return -EINVAL; | 1015 | return -EINVAL; |
1018 | } | ||
1019 | 1016 | ||
1020 | err = qdisc_class_hash_init(&q->clhash); | 1017 | err = qdisc_class_hash_init(&q->clhash); |
1021 | if (err < 0) | 1018 | if (err < 0) |
@@ -1027,10 +1024,13 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt) | |||
1027 | INIT_WORK(&q->work, htb_work_func); | 1024 | INIT_WORK(&q->work, htb_work_func); |
1028 | skb_queue_head_init(&q->direct_queue); | 1025 | skb_queue_head_init(&q->direct_queue); |
1029 | 1026 | ||
1030 | q->direct_qlen = qdisc_dev(sch)->tx_queue_len; | 1027 | if (tb[TCA_HTB_DIRECT_QLEN]) |
1031 | if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */ | 1028 | q->direct_qlen = nla_get_u32(tb[TCA_HTB_DIRECT_QLEN]); |
1032 | q->direct_qlen = 2; | 1029 | else { |
1033 | 1030 | q->direct_qlen = qdisc_dev(sch)->tx_queue_len; | |
1031 | if (q->direct_qlen < 2) /* some devices have zero tx_queue_len */ | ||
1032 | q->direct_qlen = 2; | ||
1033 | } | ||
1034 | if ((q->rate2quantum = gopt->rate2quantum) < 1) | 1034 | if ((q->rate2quantum = gopt->rate2quantum) < 1) |
1035 | q->rate2quantum = 1; | 1035 | q->rate2quantum = 1; |
1036 | q->defcls = gopt->defcls; | 1036 | q->defcls = gopt->defcls; |
@@ -1056,7 +1056,8 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
1056 | nest = nla_nest_start(skb, TCA_OPTIONS); | 1056 | nest = nla_nest_start(skb, TCA_OPTIONS); |
1057 | if (nest == NULL) | 1057 | if (nest == NULL) |
1058 | goto nla_put_failure; | 1058 | goto nla_put_failure; |
1059 | if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt)) | 1059 | if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt) || |
1060 | nla_put_u32(skb, TCA_HTB_DIRECT_QLEN, q->direct_qlen)) | ||
1060 | goto nla_put_failure; | 1061 | goto nla_put_failure; |
1061 | nla_nest_end(skb, nest); | 1062 | nla_nest_end(skb, nest); |
1062 | 1063 | ||
@@ -1311,7 +1312,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1311 | struct htb_sched *q = qdisc_priv(sch); | 1312 | struct htb_sched *q = qdisc_priv(sch); |
1312 | struct htb_class *cl = (struct htb_class *)*arg, *parent; | 1313 | struct htb_class *cl = (struct htb_class *)*arg, *parent; |
1313 | struct nlattr *opt = tca[TCA_OPTIONS]; | 1314 | struct nlattr *opt = tca[TCA_OPTIONS]; |
1314 | struct nlattr *tb[__TCA_HTB_MAX]; | 1315 | struct nlattr *tb[TCA_HTB_MAX + 1]; |
1315 | struct tc_htb_opt *hopt; | 1316 | struct tc_htb_opt *hopt; |
1316 | 1317 | ||
1317 | /* extract all subattrs from opt attr */ | 1318 | /* extract all subattrs from opt attr */ |