diff options
author | David S. Miller <davem@nuts.davemloft.net> | 2005-01-13 04:26:52 -0800 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2005-01-13 04:26:52 -0800 |
commit | af06ea11b1e55ad590633ec89322848eaf4d2242 (patch) | |
tree | 278c70fac134b38646ec385d204f397c0fe9dbfa /net | |
parent | 453269c56af16eabea712fdbc304cd290a78a2fb (diff) | |
parent | 437293de63d8979bd9288a29352899e72fff581a (diff) | |
download | history-af06ea11b1e55ad590633ec89322848eaf4d2242.tar.gz |
Merge bk://212.42.230.204/net-2.6-sched
into nuts.davemloft.net:/disk1/BK/tgraf-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/act_api.c | 42 | ||||
-rw-r--r-- | net/sched/cls_api.c | 53 | ||||
-rw-r--r-- | net/sched/cls_u32.c | 16 | ||||
-rw-r--r-- | net/sched/gact.c | 3 | ||||
-rw-r--r-- | net/sched/ipt.c | 3 | ||||
-rw-r--r-- | net/sched/mirred.c | 7 | ||||
-rw-r--r-- | net/sched/pedit.c | 3 | ||||
-rw-r--r-- | net/sched/police.c | 10 | ||||
-rw-r--r-- | net/sched/sch_atm.c | 4 | ||||
-rw-r--r-- | net/sched/sch_cbq.c | 5 | ||||
-rw-r--r-- | net/sched/sch_dsmark.c | 3 | ||||
-rw-r--r-- | net/sched/sch_gred.c | 15 | ||||
-rw-r--r-- | net/sched/sch_hfsc.c | 3 | ||||
-rw-r--r-- | net/sched/sch_htb.c | 4 | ||||
-rw-r--r-- | net/sched/sch_red.c | 2 | ||||
-rw-r--r-- | net/sched/sch_tbf.c | 2 |
16 files changed, 98 insertions, 77 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index d4842643928a0f..338e259484aa48 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -279,8 +279,7 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, *err = -EINVAL; if (name == NULL) { - if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) + if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) goto err_out; kind = tb[TCA_ACT_KIND-1]; if (kind == NULL) @@ -292,16 +291,28 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, goto err_out; } - *err = -ENOENT; a_o = tc_lookup_action_n(act_name); -#ifdef CONFIG_KMOD if (a_o == NULL) { +#ifdef CONFIG_KMOD + rtnl_unlock(); request_module(act_name); + rtnl_lock(); + a_o = tc_lookup_action_n(act_name); - } + + /* We dropped the RTNL semaphore in order to + * perform the module load. So, even if we + * succeeded in loading the module we have to + * tell the caller to replay the request. We + * indicate this using -EAGAIN. + */ + if (a_o != NULL) { + *err = -EAGAIN; + goto err_mod; + } #endif - if (a_o == NULL) goto err_out; + } *err = -ENOMEM; a = kmalloc(sizeof(*a), GFP_KERNEL); @@ -344,8 +355,7 @@ struct tc_action *tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *head = NULL, *act, *act_prev = NULL; int i; - if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) { + if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) { *err = -EINVAL; return head; } @@ -467,7 +477,7 @@ tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err) int index; *err = -EINVAL; - if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) + if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) return NULL; if (tb[TCA_ACT_INDEX - 1] == NULL || @@ -552,7 +562,7 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) b = (unsigned char *)skb->tail; - if (rtattr_parse(tb, TCA_ACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) + if (rtattr_parse_nested(tb, TCA_ACT_MAX, rta) < 0) goto err_out; kind = tb[TCA_ACT_KIND-1]; @@ -599,8 +609,7 @@ tca_action_gd(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int event) struct rtattr *tb[TCA_ACT_MAX_PRIO+1]; struct tc_action *head = NULL, *act, *act_prev = NULL; - if (rtattr_parse(tb, TCA_ACT_MAX_PRIO, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) + if (rtattr_parse_nested(tb, TCA_ACT_MAX_PRIO, rta) < 0) return -EINVAL; if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { @@ -743,7 +752,10 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) */ if (n->nlmsg_flags&NLM_F_REPLACE) ovr = 1; +replay: ret = tcf_action_add(tca[TCA_ACT_TAB-1], n, pid, ovr); + if (ret == -EAGAIN) + goto replay; break; case RTM_DELACTION: ret = tca_action_gd(tca[TCA_ACT_TAB-1], n, pid, RTM_DELACTION); @@ -871,11 +883,5 @@ subsys_initcall(tc_action_init); EXPORT_SYMBOL(tcf_register_action); EXPORT_SYMBOL(tcf_unregister_action); -EXPORT_SYMBOL(tcf_action_init_1); -EXPORT_SYMBOL(tcf_action_init); -EXPORT_SYMBOL(tcf_action_destroy); EXPORT_SYMBOL(tcf_action_exec); -EXPORT_SYMBOL(tcf_action_copy_stats); -EXPORT_SYMBOL(tcf_action_dump); EXPORT_SYMBOL(tcf_action_dump_1); -EXPORT_SYMBOL(tcf_action_dump_old); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index c2e298468d27c8..47cdb71d6b3a00 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -130,22 +130,31 @@ static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp) static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) { - struct rtattr **tca = arg; - struct tcmsg *t = NLMSG_DATA(n); - u32 protocol = TC_H_MIN(t->tcm_info); - u32 prio = TC_H_MAJ(t->tcm_info); - u32 nprio = prio; - u32 parent = t->tcm_parent; + struct rtattr **tca; + struct tcmsg *t; + u32 protocol; + u32 prio; + u32 nprio; + u32 parent; struct net_device *dev; struct Qdisc *q; struct tcf_proto **back, **chain; - struct tcf_proto *tp = NULL; + struct tcf_proto *tp; struct tcf_proto_ops *tp_ops; struct Qdisc_class_ops *cops; - unsigned long cl = 0; + unsigned long cl; unsigned long fh; int err; +replay: + tca = arg; + t = NLMSG_DATA(n); + protocol = TC_H_MIN(t->tcm_info); + prio = TC_H_MAJ(t->tcm_info); + nprio = prio; + parent = t->tcm_parent; + cl = 0; + if (prio == 0) { /* If no priority is given, user wants we allocated it. */ if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE)) @@ -211,20 +220,29 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) err = -ENOBUFS; if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL) goto errout; + err = -EINVAL; tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]); + if (tp_ops == NULL) { #ifdef CONFIG_KMOD - if (tp_ops==NULL && tca[TCA_KIND-1] != NULL) { struct rtattr *kind = tca[TCA_KIND-1]; char name[IFNAMSIZ]; - if (rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { + if (kind != NULL && + rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) { + rtnl_unlock(); request_module("cls_%s", name); + rtnl_lock(); tp_ops = tcf_proto_lookup_ops(kind); + /* We dropped the RTNL semaphore in order to + * perform the module load. So, even if we + * succeeded in loading the module we have to + * replay the request. We indicate this using + * -EAGAIN. + */ + if (tp_ops != NULL) + err = -EAGAIN; } - } #endif - if (tp_ops == NULL) { - err = -EINVAL; kfree(tp); goto errout; } @@ -294,6 +312,9 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) errout: if (cl) cops->put(q, cl); + if (err == -EAGAIN) + /* Replay the request. */ + goto replay; return err; } @@ -468,7 +489,7 @@ tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, int err; struct tc_action *act; - if (map->police && tb[map->police-1] && rate_tlv) { + if (map->police && tb[map->police-1]) { act = tcf_action_init_1(tb[map->police-1], rate_tlv, "police", TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err); if (act == NULL) @@ -476,7 +497,7 @@ tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, act->type = TCA_OLD_COMPAT; exts->action = act; - } else if (map->action && tb[map->action-1] && rate_tlv) { + } else if (map->action && tb[map->action-1]) { act = tcf_action_init(tb[map->action-1], rate_tlv, NULL, TCA_ACT_NOREPLACE, TCA_ACT_BIND, &err); if (act == NULL) @@ -485,7 +506,7 @@ tcf_exts_validate(struct tcf_proto *tp, struct rtattr **tb, exts->action = act; } #elif defined CONFIG_NET_CLS_POLICE - if (map->police && tb[map->police-1] && rate_tlv) { + if (map->police && tb[map->police-1]) { struct tcf_police *p; p = tcf_police_locate(tb[map->police-1], rate_tlv); diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 1b1224b1747e36..8b870402bc96a2 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -549,7 +549,6 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, struct tc_u_hnode *ht; struct tc_u_knode *n; struct tc_u32_sel *s; - struct tc_u32_mark *mark; struct rtattr *opt = tca[TCA_OPTIONS-1]; struct rtattr *tb[TCA_U32_MAX]; u32 htid; @@ -654,15 +653,22 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, n->fshift = i; } -#ifdef CONFIG_CLS_U32_MARK +#ifdef CONFIG_CLS_U32_MARK if (tb[TCA_U32_MARK-1]) { - if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark)) + struct tc_u32_mark *mark; + + if (RTA_PAYLOAD(tb[TCA_U32_MARK-1]) < sizeof(struct tc_u32_mark)) { +#ifdef CONFIG_CLS_U32_PERF + kfree(n->pf); +#endif + kfree(n); return -EINVAL; + } mark = RTA_DATA(tb[TCA_U32_MARK-1]); memcpy(&n->mark, mark, sizeof(struct tc_u32_mark)); n->mark.success = 0; - } -#endif + } +#endif err = u32_set_parms(tp, base, ht, n, tb, tca[TCA_RATE-1]); if (err == 0) { diff --git a/net/sched/gact.c b/net/sched/gact.c index b83c1a6a7f318d..e0a64086d749f4 100644 --- a/net/sched/gact.c +++ b/net/sched/gact.c @@ -79,8 +79,7 @@ static int tcf_gact_init(struct rtattr *rta, struct rtattr *est, struct tcf_gact *p; int ret = 0; - if (rta == NULL || - rtattr_parse(tb, TCA_GACT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) + if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0) return -EINVAL; if (tb[TCA_GACT_PARMS - 1] == NULL || diff --git a/net/sched/ipt.c b/net/sched/ipt.c index cd309e49f231c0..e6881990801c1f 100644 --- a/net/sched/ipt.c +++ b/net/sched/ipt.c @@ -122,8 +122,7 @@ tcf_ipt_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, u32 hook = 0; u32 index = 0; - if (rta == NULL || - rtattr_parse(tb, TCA_IPT_MAX, RTA_DATA(rta), RTA_PAYLOAD(rta)) < 0) + if (rta == NULL || rtattr_parse_nested(tb, TCA_IPT_MAX, rta) < 0) return -EINVAL; if (tb[TCA_IPT_HOOK-1] == NULL || diff --git a/net/sched/mirred.c b/net/sched/mirred.c index 4ff3fd740fa329..4402bd53be2928 100644 --- a/net/sched/mirred.c +++ b/net/sched/mirred.c @@ -84,8 +84,7 @@ tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, int ret = 0; int ok_push = 0; - if (rta == NULL || rtattr_parse(tb, TCA_MIRRED_MAX, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) + if (rta == NULL || rtattr_parse_nested(tb, TCA_MIRRED_MAX, rta) < 0) return -EINVAL; if (tb[TCA_MIRRED_PARMS-1] == NULL || @@ -127,7 +126,7 @@ tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, } } - spin_lock(&p->lock); + spin_lock_bh(&p->lock); p->action = parm->action; p->eaction = parm->eaction; if (parm->ifindex) { @@ -138,7 +137,7 @@ tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, dev_hold(dev); p->ok_push = ok_push; } - spin_unlock(&p->lock); + spin_unlock_bh(&p->lock); if (ret == ACT_P_CREATED) tcf_hash_insert(p); diff --git a/net/sched/pedit.c b/net/sched/pedit.c index e4943c59202901..e1b4bedace58d9 100644 --- a/net/sched/pedit.c +++ b/net/sched/pedit.c @@ -63,8 +63,7 @@ tcf_pedit_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a, struct tc_pedit_key *keys = NULL; int ksize; - if (rta == NULL || rtattr_parse(tb, TCA_PEDIT_MAX, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) + if (rta == NULL || rtattr_parse_nested(tb, TCA_PEDIT_MAX, rta) < 0) return -EINVAL; if (tb[TCA_PEDIT_PARMS - 1] == NULL || diff --git a/net/sched/police.c b/net/sched/police.c index 7efd037f49023d..4edaf7e748fdbf 100644 --- a/net/sched/police.c +++ b/net/sched/police.c @@ -171,8 +171,7 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est, struct tcf_police *p; struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; - if (rta == NULL || rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) + if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) return -EINVAL; if (tb[TCA_POLICE_TBF-1] == NULL || @@ -225,7 +224,7 @@ override: } } /* No failure allowed after this point */ - spin_lock(&p->lock); + spin_lock_bh(&p->lock); if (R_tab != NULL) { qdisc_put_rtab(p->R_tab); p->R_tab = R_tab; @@ -255,7 +254,7 @@ override: gen_replace_estimator(&p->bstats, &p->rate_est, p->stats_lock, est); #endif - spin_unlock(&p->lock); + spin_unlock_bh(&p->lock); if (ret != ACT_P_CREATED) return ret; @@ -417,8 +416,7 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) struct rtattr *tb[TCA_POLICE_MAX]; struct tc_police *parm; - if (rtattr_parse(tb, TCA_POLICE_MAX, RTA_DATA(rta), - RTA_PAYLOAD(rta)) < 0) + if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) return NULL; if (tb[TCA_POLICE_TBF-1] == NULL || diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 711143443182ea..427b6fe7bfac08 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -255,8 +255,8 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, * later.) */ if (flow) return -EBUSY; - if (opt == NULL || rtattr_parse(tb,TCA_ATM_MAX,RTA_DATA(opt), - RTA_PAYLOAD(opt))) return -EINVAL; + if (opt == NULL || rtattr_parse_nested(tb, TCA_ATM_MAX, opt)) + return -EINVAL; if (!tb[TCA_ATM_FD-1] || RTA_PAYLOAD(tb[TCA_ATM_FD-1]) < sizeof(fd)) return -EINVAL; fd = *(int *) RTA_DATA(tb[TCA_ATM_FD-1]); diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 74ca4ee720e4c2..b4c1c1f15dc2dd 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1439,7 +1439,7 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt) struct rtattr *tb[TCA_CBQ_MAX]; struct tc_ratespec *r; - if (rtattr_parse(tb, TCA_CBQ_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0 || + if (rtattr_parse_nested(tb, TCA_CBQ_MAX, opt) < 0 || tb[TCA_CBQ_RTAB-1] == NULL || tb[TCA_CBQ_RATE-1] == NULL || RTA_PAYLOAD(tb[TCA_CBQ_RATE-1]) < sizeof(struct tc_ratespec)) return -EINVAL; @@ -1824,8 +1824,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t struct cbq_class *parent; struct qdisc_rate_table *rtab = NULL; - if (opt==NULL || - rtattr_parse(tb, TCA_CBQ_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt))) + if (opt==NULL || rtattr_parse_nested(tb, TCA_CBQ_MAX, opt)) return -EINVAL; if (tb[TCA_CBQ_OVL_STRATEGY-1] && diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 19f4e4fa7f4844..8a3db9d95bab23 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -125,8 +125,7 @@ static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, "arg 0x%lx\n",sch,p,classid,parent,*arg); if (*arg > p->indices) return -ENOENT; - if (!opt || rtattr_parse(tb, TCA_DSMARK_MAX, RTA_DATA(opt), - RTA_PAYLOAD(opt))) + if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt)) return -EINVAL; if (tb[TCA_DSMARK_MASK-1]) { if (!RTA_PAYLOAD(tb[TCA_DSMARK_MASK-1])) diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index decd7ba297e797..25c171c3271542 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -332,13 +332,11 @@ static int gred_change(struct Qdisc *sch, struct rtattr *opt) struct rtattr *tb2[TCA_GRED_DPS]; int i; - if (opt == NULL || - rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ) - return -EINVAL; + if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt)) + return -EINVAL; if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) { - rtattr_parse(tb2, TCA_GRED_DPS, RTA_DATA(opt), - RTA_PAYLOAD(opt)); + rtattr_parse_nested(tb2, TCA_GRED_DPS, opt); if (tb2[TCA_GRED_DPS-1] == 0) return -EINVAL; @@ -475,12 +473,11 @@ static int gred_init(struct Qdisc *sch, struct rtattr *opt) struct rtattr *tb[TCA_GRED_STAB]; struct rtattr *tb2[TCA_GRED_DPS]; - if (opt == NULL || - rtattr_parse(tb, TCA_GRED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ) - return -EINVAL; + if (opt == NULL || rtattr_parse_nested(tb, TCA_GRED_STAB, opt)) + return -EINVAL; if (tb[TCA_GRED_PARMS-1] == 0 && tb[TCA_GRED_STAB-1] == 0) { - rtattr_parse(tb2, TCA_GRED_DPS, RTA_DATA(opt),RTA_PAYLOAD(opt)); + rtattr_parse_nested(tb2, TCA_GRED_DPS, opt); if (tb2[TCA_GRED_DPS-1] == 0) return -EINVAL; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index c6288dedc660e1..d09e0b0cb5f99c 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1046,8 +1046,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct tc_service_curve *rsc = NULL, *fsc = NULL, *usc = NULL; u64 cur_time; - if (opt == NULL || - rtattr_parse(tb, TCA_HFSC_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt))) + if (opt == NULL || rtattr_parse_nested(tb, TCA_HFSC_MAX, opt)) return -EINVAL; if (tb[TCA_HFSC_RSC-1]) { diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 25fa2c06f139cb..116028554ae454 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1267,7 +1267,7 @@ static int htb_init(struct Qdisc *sch, struct rtattr *opt) printk(KERN_INFO "HTB init, kernel part version %d.%d\n", HTB_VER >> 16,HTB_VER & 0xffff); #endif - if (!opt || rtattr_parse(tb, TCA_HTB_INIT, RTA_DATA(opt), RTA_PAYLOAD(opt)) || + if (!opt || rtattr_parse_nested(tb, TCA_HTB_INIT, opt) || tb[TCA_HTB_INIT-1] == NULL || RTA_PAYLOAD(tb[TCA_HTB_INIT-1]) < sizeof(*gopt)) { printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n"); @@ -1559,7 +1559,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, struct tc_htb_opt *hopt; /* extract all subattrs from opt attr */ - if (!opt || rtattr_parse(tb, TCA_HTB_RTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) || + if (!opt || rtattr_parse_nested(tb, TCA_HTB_RTAB, opt) || tb[TCA_HTB_PARMS-1] == NULL || RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt)) goto failure; diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 4ea63bc58a2826..664d0e47374fd1 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c @@ -364,7 +364,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt) struct tc_red_qopt *ctl; if (opt == NULL || - rtattr_parse(tb, TCA_RED_STAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) || + rtattr_parse_nested(tb, TCA_RED_STAB, opt) || tb[TCA_RED_PARMS-1] == 0 || tb[TCA_RED_STAB-1] == 0 || RTA_PAYLOAD(tb[TCA_RED_PARMS-1]) < sizeof(*ctl) || RTA_PAYLOAD(tb[TCA_RED_STAB-1]) < 256) diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 2c3f14a8492df1..cb9711ea8c6cac 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -310,7 +310,7 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt) struct Qdisc *child = NULL; int max_size,n; - if (rtattr_parse(tb, TCA_TBF_PTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) || + if (rtattr_parse_nested(tb, TCA_TBF_PTAB, opt) || tb[TCA_TBF_PARMS-1] == NULL || RTA_PAYLOAD(tb[TCA_TBF_PARMS-1]) < sizeof(*qopt)) goto done; |