Skip to content

Commit

Permalink
net: sched: implement unlocked action init API
Browse files Browse the repository at this point in the history
Add additional 'rtnl_held' argument to act API init functions. It is
required to implement actions that need to release rtnl lock before loading
kernel module and reacquire if afterwards.

Reviewed-by: Marcelo Ricardo Leitner <[email protected]>
Signed-off-by: Vlad Buslov <[email protected]>
Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
w1ldptr authored and davem330 committed Jul 8, 2018
1 parent 036bb44 commit 789871b
Show file tree
Hide file tree
Showing 19 changed files with 50 additions and 29 deletions.
6 changes: 4 additions & 2 deletions include/net/act_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ struct tc_action_ops {
struct netlink_ext_ack *extack);
int (*init)(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **act, int ovr,
int bind, struct netlink_ext_ack *extack);
int bind, bool rtnl_held,
struct netlink_ext_ack *extack);
int (*walk)(struct net *, struct sk_buff *,
struct netlink_callback *, int,
const struct tc_action_ops *,
Expand Down Expand Up @@ -168,10 +169,11 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
struct nlattr *est, char *name, int ovr, int bind,
struct list_head *actions, size_t *attr_size,
struct netlink_ext_ack *extack);
bool rtnl_held, struct netlink_ext_ack *extack);
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind,
bool rtnl_held,
struct netlink_ext_ack *extack);
int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
Expand Down
18 changes: 11 additions & 7 deletions net/sched/act_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind,
bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action *a;
Expand Down Expand Up @@ -721,9 +722,11 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
a_o = tc_lookup_action_n(act_name);
if (a_o == NULL) {
#ifdef CONFIG_MODULES
rtnl_unlock();
if (rtnl_held)
rtnl_unlock();
request_module("act_%s", act_name);
rtnl_lock();
if (rtnl_held)
rtnl_lock();

a_o = tc_lookup_action_n(act_name);

Expand All @@ -746,9 +749,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
/* backward compatibility for policer */
if (name == NULL)
err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
extack);
rtnl_held, extack);
else
err = a_o->init(net, nla, est, &a, ovr, bind, extack);
err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
extack);
if (err < 0)
goto err_mod;

Expand Down Expand Up @@ -800,7 +804,7 @@ static void cleanup_a(struct list_head *actions, int ovr)
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
struct nlattr *est, char *name, int ovr, int bind,
struct list_head *actions, size_t *attr_size,
struct netlink_ext_ack *extack)
bool rtnl_held, struct netlink_ext_ack *extack)
{
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
struct tc_action *act;
Expand All @@ -814,7 +818,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,

for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
extack);
rtnl_held, extack);
if (IS_ERR(act)) {
err = PTR_ERR(act);
goto err;
Expand Down Expand Up @@ -1173,7 +1177,7 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
LIST_HEAD(actions);

ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions,
&attr_size, extack);
&attr_size, true, extack);
if (ret)
return ret;

Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf *prog,

static int tcf_bpf_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **act,
int replace, int bind, struct netlink_ext_ack *extack)
int replace, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, bpf_net_id);
struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_connmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {

static int tcf_connmark_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind,
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, connmark_net_id);
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_csum.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ static struct tc_action_ops act_csum_ops;

static int tcf_csum_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind, struct netlink_ext_ack *extack)
int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, csum_net_id);
struct tcf_csum_params *params_old, *params_new;
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_gact.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ static const struct nla_policy gact_policy[TCA_GACT_MAX + 1] = {

static int tcf_gact_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, gact_net_id);
struct nlattr *tb[TCA_GACT_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_ife.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb,

static int tcf_ife_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, ife_net_id);
struct nlattr *tb[TCA_IFE_MAX + 1];
Expand Down
6 changes: 4 additions & 2 deletions net/sched/act_ipt.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,17 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,

static int tcf_ipt_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind, struct netlink_ext_ack *extack)
int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
return __tcf_ipt_init(net, ipt_net_id, nla, est, a, &act_ipt_ops, ovr,
bind);
}

static int tcf_xt_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind, struct netlink_ext_ack *extack)
int bind, bool unlocked,
struct netlink_ext_ack *extack)
{
return __tcf_ipt_init(net, xt_net_id, nla, est, a, &act_xt_ops, ovr,
bind);
Expand Down
5 changes: 3 additions & 2 deletions net/sched/act_mirred.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ static unsigned int mirred_net_id;
static struct tc_action_ops act_mirred_ops;

static int tcf_mirred_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind, struct netlink_ext_ack *extack)
struct nlattr *est, struct tc_action **a,
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, mirred_net_id);
struct nlattr *tb[TCA_MIRRED_MAX + 1];
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_nat.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static const struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {

static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est,
struct tc_action **a, int ovr, int bind,
struct netlink_ext_ack *extack)
bool rtnl_held, struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, nat_net_id);
struct nlattr *tb[TCA_NAT_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_pedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ static int tcf_pedit_key_ex_dump(struct sk_buff *skb,

static int tcf_pedit_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, pedit_net_id);
struct nlattr *tb[TCA_PEDIT_MAX + 1];
Expand Down
2 changes: 1 addition & 1 deletion net/sched/act_police.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {

static int tcf_act_police_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind,
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
int ret = 0, err;
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_sample.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ static const struct nla_policy sample_policy[TCA_SAMPLE_MAX + 1] = {

static int tcf_sample_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a, int ovr,
int bind, struct netlink_ext_ack *extack)
int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, sample_net_id);
struct nlattr *tb[TCA_SAMPLE_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {

static int tcf_simp_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, simp_net_id);
struct nlattr *tb[TCA_DEF_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_skbedit.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {

static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, skbedit_net_id);
struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_skbmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ static const struct nla_policy skbmod_policy[TCA_SKBMOD_MAX + 1] = {

static int tcf_skbmod_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, skbmod_net_id);
struct nlattr *tb[TCA_SKBMOD_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_tunnel_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {

static int tunnel_key_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
Expand Down
3 changes: 2 additions & 1 deletion net/sched/act_vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = {

static int tcf_vlan_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
int ovr, int bind, struct netlink_ext_ack *extack)
int ovr, int bind, bool rtnl_held,
struct netlink_ext_ack *extack)
{
struct tc_action_net *tn = net_generic(net, vlan_net_id);
struct nlattr *tb[TCA_VLAN_MAX + 1];
Expand Down
5 changes: 3 additions & 2 deletions net/sched/cls_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,7 +1632,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
if (exts->police && tb[exts->police]) {
act = tcf_action_init_1(net, tp, tb[exts->police],
rate_tlv, "police", ovr,
TCA_ACT_BIND, extack);
TCA_ACT_BIND, true, extack);
if (IS_ERR(act))
return PTR_ERR(act);

Expand All @@ -1645,7 +1645,8 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,

err = tcf_action_init(net, tp, tb[exts->action],
rate_tlv, NULL, ovr, TCA_ACT_BIND,
&actions, &attr_size, extack);
&actions, &attr_size, true,
extack);
if (err)
return err;
list_for_each_entry(act, &actions, list)
Expand Down

0 comments on commit 789871b

Please sign in to comment.