diff options
Diffstat (limited to 'net/sched/sch_htb.c')
| -rw-r--r-- | net/sched/sch_htb.c | 31 | 
1 files changed, 16 insertions, 15 deletions
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 571f1d211f4..79b1876b6cd 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] = {  	[TCA_HTB_INIT]	= { .len = sizeof(struct tc_htb_glob) },  	[TCA_HTB_CTAB]	= { .type = NLA_BINARY, .len = TC_RTAB_SIZE },  	[TCA_HTB_RTAB]	= { .type = NLA_BINARY, .len = TC_RTAB_SIZE }, +	[TCA_HTB_DIRECT_QLEN] = { .type = NLA_U32 },  };  static void htb_work_func(struct work_struct *work) @@ -994,7 +995,7 @@ static void htb_work_func(struct work_struct *work)  static int htb_init(struct Qdisc *sch, struct nlattr *opt)  {  	struct htb_sched *q = qdisc_priv(sch); -	struct nlattr *tb[TCA_HTB_INIT + 1]; +	struct nlattr *tb[TCA_HTB_MAX + 1];  	struct tc_htb_glob *gopt;  	int err;  	int i; @@ -1002,20 +1003,16 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)  	if (!opt)  		return -EINVAL; -	err = nla_parse_nested(tb, TCA_HTB_INIT, opt, htb_policy); +	err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy);  	if (err < 0)  		return err; -	if (tb[TCA_HTB_INIT] == NULL) { -		pr_err("HTB: hey probably you have bad tc tool ?\n"); +	if (!tb[TCA_HTB_INIT])  		return -EINVAL; -	} +  	gopt = nla_data(tb[TCA_HTB_INIT]); -	if (gopt->version != HTB_VER >> 16) { -		pr_err("HTB: need tc/htb version %d (minor is %d), you have %d\n", -		       HTB_VER >> 16, HTB_VER & 0xffff, gopt->version); +	if (gopt->version != HTB_VER >> 16)  		return -EINVAL; -	}  	err = qdisc_class_hash_init(&q->clhash);  	if (err < 0) @@ -1027,10 +1024,13 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)  	INIT_WORK(&q->work, htb_work_func);  	skb_queue_head_init(&q->direct_queue); -	q->direct_qlen = qdisc_dev(sch)->tx_queue_len; -	if (q->direct_qlen < 2)	/* some devices have zero tx_queue_len */ -		q->direct_qlen = 2; - +	if (tb[TCA_HTB_DIRECT_QLEN]) +		q->direct_qlen = nla_get_u32(tb[TCA_HTB_DIRECT_QLEN]); +	else { +		q->direct_qlen = qdisc_dev(sch)->tx_queue_len; +		if (q->direct_qlen < 2)	/* some devices have zero tx_queue_len */ +			q->direct_qlen = 2; +	}  	if ((q->rate2quantum = gopt->rate2quantum) < 1)  		q->rate2quantum = 1;  	q->defcls = gopt->defcls; @@ -1056,7 +1056,8 @@ static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)  	nest = nla_nest_start(skb, TCA_OPTIONS);  	if (nest == NULL)  		goto nla_put_failure; -	if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt)) +	if (nla_put(skb, TCA_HTB_INIT, sizeof(gopt), &gopt) || +	    nla_put_u32(skb, TCA_HTB_DIRECT_QLEN, q->direct_qlen))  		goto nla_put_failure;  	nla_nest_end(skb, nest); @@ -1311,7 +1312,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,  	struct htb_sched *q = qdisc_priv(sch);  	struct htb_class *cl = (struct htb_class *)*arg, *parent;  	struct nlattr *opt = tca[TCA_OPTIONS]; -	struct nlattr *tb[__TCA_HTB_MAX]; +	struct nlattr *tb[TCA_HTB_MAX + 1];  	struct tc_htb_opt *hopt;  	/* extract all subattrs from opt attr */  |