Commit af06ea11 authored by David S. Miller's avatar David S. Miller

Merge bk://212.42.230.204/net-2.6-sched

into nuts.davemloft.net:/disk1/BK/tgraf-2.6
parents 453269c5 437293de
......@@ -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);
......@@ -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);
......
......@@ -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;
......@@ -656,8 +655,15 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
#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;
......
......@@ -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 ||
......
......@@ -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 ||
......
......@@ -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);
......
......@@ -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 ||
......
......@@ -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 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
}
}
/* 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 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
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 ||
......
......@@ -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]);
......
......@@ -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] &&
......
......@@ -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]))
......
......@@ -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)) )
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)) )
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;
......
......@@ -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]) {
......
......@@ -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;
......
......@@ -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)
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment