diff options
author | Vlad Buslov <vladbu@mellanox.com> | 2019-08-26 15:45:03 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-08-26 23:17:43 +0200 |
commit | 9838b20a7fb28c69fa66ac8e68d967ffe1d0ecad (patch) | |
tree | 9ed88766141671e1bd7f930d7b53746a18d11c37 /net/sched/cls_api.c | |
parent | net: sched: conditionally obtain rtnl lock in cls hw offloads API (diff) | |
download | linux-9838b20a7fb28c69fa66ac8e68d967ffe1d0ecad.tar.xz linux-9838b20a7fb28c69fa66ac8e68d967ffe1d0ecad.zip |
net: sched: take rtnl lock in tc_setup_flow_action()
In order to allow using new flow_action infrastructure from unlocked
classifiers, modify tc_setup_flow_action() to accept new 'rtnl_held'
argument. Take rtnl lock before accessing tc_action data. This is necessary
to protect from concurrent action replace.
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r-- | net/sched/cls_api.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 3c103cf9fd0d..8751bb8a682f 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -3266,14 +3266,17 @@ int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp, EXPORT_SYMBOL(tc_setup_cb_reoffload); int tc_setup_flow_action(struct flow_action *flow_action, - const struct tcf_exts *exts) + const struct tcf_exts *exts, bool rtnl_held) { const struct tc_action *act; - int i, j, k; + int i, j, k, err = 0; if (!exts) return 0; + if (!rtnl_held) + rtnl_lock(); + j = 0; tcf_exts_for_each_action(i, act, exts) { struct flow_action_entry *entry; @@ -3318,6 +3321,7 @@ int tc_setup_flow_action(struct flow_action *flow_action, entry->vlan.prio = tcf_vlan_push_prio(act); break; default: + err = -EOPNOTSUPP; goto err_out; } } else if (is_tcf_tunnel_set(act)) { @@ -3335,6 +3339,7 @@ int tc_setup_flow_action(struct flow_action *flow_action, entry->id = FLOW_ACTION_ADD; break; default: + err = -EOPNOTSUPP; goto err_out; } entry->mangle.htype = tcf_pedit_htype(act, k); @@ -3393,15 +3398,19 @@ int tc_setup_flow_action(struct flow_action *flow_action, entry->id = FLOW_ACTION_PTYPE; entry->ptype = tcf_skbedit_ptype(act); } else { + err = -EOPNOTSUPP; goto err_out; } if (!is_tcf_pedit(act)) j++; } - return 0; + err_out: - return -EOPNOTSUPP; + if (!rtnl_held) + rtnl_unlock(); + + return err; } EXPORT_SYMBOL(tc_setup_flow_action); |