Commit 8d7c6945 authored by Patrick McHardy's avatar Patrick McHardy

[PKT_SCHED]: act_api.c: drop rtnl for loading modules

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent c2e2849f
......@@ -291,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);
......@@ -740,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);
......
......@@ -130,22 +130,30 @@ 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 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;
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))
......@@ -294,6 +302,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;
}
......
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