diff options
author | David S. Miller <davem@davemloft.net> | 2018-08-21 15:45:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-21 15:45:45 -0400 |
commit | 78c452fe70681c6e6383916a264e0bf010e98058 (patch) | |
tree | 445afddd040006b43d6d2ad85118b558ded5ca6c | |
parent | b93c1b5ac8643cc08bb74fa8ae21d6c63dfcb23d (diff) | |
parent | 5ffe57da29b3802baeddaa40909682bbb4cb4d48 (diff) |
Merge branch 'net_sched-fixes'
Cong Wang says:
====================
net_sched: pending clean up and bug fixes
This patchset aims to clean up and fixes some bugs in current
merge window, this is why it is targeting -net.
Patch 1-5 are clean up Vlad's patches merged in current merge
window, patch 6 is just a trivial cleanup.
Patch 7 reverts a lockdep warning fix and patch 8 provides a better
fix for it.
Patch 9 fixes a potential deadlock found by me during code review.
Please see each patch for details.
====================
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
30 files changed, 108 insertions, 290 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 139d96c5a023..092c817f8f11 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | |||
@@ -110,16 +110,14 @@ static int bnxt_tc_parse_actions(struct bnxt *bp, | |||
110 | struct tcf_exts *tc_exts) | 110 | struct tcf_exts *tc_exts) |
111 | { | 111 | { |
112 | const struct tc_action *tc_act; | 112 | const struct tc_action *tc_act; |
113 | LIST_HEAD(tc_actions); | 113 | int i, rc; |
114 | int rc; | ||
115 | 114 | ||
116 | if (!tcf_exts_has_actions(tc_exts)) { | 115 | if (!tcf_exts_has_actions(tc_exts)) { |
117 | netdev_info(bp->dev, "no actions"); | 116 | netdev_info(bp->dev, "no actions"); |
118 | return -EINVAL; | 117 | return -EINVAL; |
119 | } | 118 | } |
120 | 119 | ||
121 | tcf_exts_to_list(tc_exts, &tc_actions); | 120 | tcf_exts_for_each_action(i, tc_act, tc_exts) { |
122 | list_for_each_entry(tc_act, &tc_actions, list) { | ||
123 | /* Drop action */ | 121 | /* Drop action */ |
124 | if (is_tcf_gact_shot(tc_act)) { | 122 | if (is_tcf_gact_shot(tc_act)) { |
125 | actions->flags |= BNXT_TC_ACTION_FLAG_DROP; | 123 | actions->flags |= BNXT_TC_ACTION_FLAG_DROP; |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c index 623f73dd7738..c116f96956fe 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | |||
@@ -417,10 +417,9 @@ static void cxgb4_process_flow_actions(struct net_device *in, | |||
417 | struct ch_filter_specification *fs) | 417 | struct ch_filter_specification *fs) |
418 | { | 418 | { |
419 | const struct tc_action *a; | 419 | const struct tc_action *a; |
420 | LIST_HEAD(actions); | 420 | int i; |
421 | 421 | ||
422 | tcf_exts_to_list(cls->exts, &actions); | 422 | tcf_exts_for_each_action(i, a, cls->exts) { |
423 | list_for_each_entry(a, &actions, list) { | ||
424 | if (is_tcf_gact_ok(a)) { | 423 | if (is_tcf_gact_ok(a)) { |
425 | fs->action = FILTER_PASS; | 424 | fs->action = FILTER_PASS; |
426 | } else if (is_tcf_gact_shot(a)) { | 425 | } else if (is_tcf_gact_shot(a)) { |
@@ -591,10 +590,9 @@ static int cxgb4_validate_flow_actions(struct net_device *dev, | |||
591 | bool act_redir = false; | 590 | bool act_redir = false; |
592 | bool act_pedit = false; | 591 | bool act_pedit = false; |
593 | bool act_vlan = false; | 592 | bool act_vlan = false; |
594 | LIST_HEAD(actions); | 593 | int i; |
595 | 594 | ||
596 | tcf_exts_to_list(cls->exts, &actions); | 595 | tcf_exts_for_each_action(i, a, cls->exts) { |
597 | list_for_each_entry(a, &actions, list) { | ||
598 | if (is_tcf_gact_ok(a)) { | 596 | if (is_tcf_gact_ok(a)) { |
599 | /* Do nothing */ | 597 | /* Do nothing */ |
600 | } else if (is_tcf_gact_shot(a)) { | 598 | } else if (is_tcf_gact_shot(a)) { |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c index 18eb2aedd4cb..c7d2b4dc7568 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c | |||
@@ -93,14 +93,13 @@ static int fill_action_fields(struct adapter *adap, | |||
93 | unsigned int num_actions = 0; | 93 | unsigned int num_actions = 0; |
94 | const struct tc_action *a; | 94 | const struct tc_action *a; |
95 | struct tcf_exts *exts; | 95 | struct tcf_exts *exts; |
96 | LIST_HEAD(actions); | 96 | int i; |
97 | 97 | ||
98 | exts = cls->knode.exts; | 98 | exts = cls->knode.exts; |
99 | if (!tcf_exts_has_actions(exts)) | 99 | if (!tcf_exts_has_actions(exts)) |
100 | return -EINVAL; | 100 | return -EINVAL; |
101 | 101 | ||
102 | tcf_exts_to_list(exts, &actions); | 102 | tcf_exts_for_each_action(i, a, exts) { |
103 | list_for_each_entry(a, &actions, list) { | ||
104 | /* Don't allow more than one action per rule. */ | 103 | /* Don't allow more than one action per rule. */ |
105 | if (num_actions) | 104 | if (num_actions) |
106 | return -EINVAL; | 105 | return -EINVAL; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 447098005490..af4c9ae7f432 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -9171,14 +9171,12 @@ static int parse_tc_actions(struct ixgbe_adapter *adapter, | |||
9171 | struct tcf_exts *exts, u64 *action, u8 *queue) | 9171 | struct tcf_exts *exts, u64 *action, u8 *queue) |
9172 | { | 9172 | { |
9173 | const struct tc_action *a; | 9173 | const struct tc_action *a; |
9174 | LIST_HEAD(actions); | 9174 | int i; |
9175 | 9175 | ||
9176 | if (!tcf_exts_has_actions(exts)) | 9176 | if (!tcf_exts_has_actions(exts)) |
9177 | return -EINVAL; | 9177 | return -EINVAL; |
9178 | 9178 | ||
9179 | tcf_exts_to_list(exts, &actions); | 9179 | tcf_exts_for_each_action(i, a, exts) { |
9180 | list_for_each_entry(a, &actions, list) { | ||
9181 | |||
9182 | /* Drop action */ | 9180 | /* Drop action */ |
9183 | if (is_tcf_gact_shot(a)) { | 9181 | if (is_tcf_gact_shot(a)) { |
9184 | *action = IXGBE_FDIR_DROP_QUEUE; | 9182 | *action = IXGBE_FDIR_DROP_QUEUE; |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 9131a1376e7d..9fed54017659 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | |||
@@ -1982,14 +1982,15 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec, | |||
1982 | goto out_ok; | 1982 | goto out_ok; |
1983 | 1983 | ||
1984 | modify_ip_header = false; | 1984 | modify_ip_header = false; |
1985 | tcf_exts_to_list(exts, &actions); | 1985 | tcf_exts_for_each_action(i, a, exts) { |
1986 | list_for_each_entry(a, &actions, list) { | 1986 | int k; |
1987 | |||
1987 | if (!is_tcf_pedit(a)) | 1988 | if (!is_tcf_pedit(a)) |
1988 | continue; | 1989 | continue; |
1989 | 1990 | ||
1990 | nkeys = tcf_pedit_nkeys(a); | 1991 | nkeys = tcf_pedit_nkeys(a); |
1991 | for (i = 0; i < nkeys; i++) { | 1992 | for (k = 0; k < nkeys; k++) { |
1992 | htype = tcf_pedit_htype(a, i); | 1993 | htype = tcf_pedit_htype(a, k); |
1993 | if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 || | 1994 | if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 || |
1994 | htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) { | 1995 | htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) { |
1995 | modify_ip_header = true; | 1996 | modify_ip_header = true; |
@@ -2053,15 +2054,14 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, | |||
2053 | const struct tc_action *a; | 2054 | const struct tc_action *a; |
2054 | LIST_HEAD(actions); | 2055 | LIST_HEAD(actions); |
2055 | u32 action = 0; | 2056 | u32 action = 0; |
2056 | int err; | 2057 | int err, i; |
2057 | 2058 | ||
2058 | if (!tcf_exts_has_actions(exts)) | 2059 | if (!tcf_exts_has_actions(exts)) |
2059 | return -EINVAL; | 2060 | return -EINVAL; |
2060 | 2061 | ||
2061 | attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG; | 2062 | attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG; |
2062 | 2063 | ||
2063 | tcf_exts_to_list(exts, &actions); | 2064 | tcf_exts_for_each_action(i, a, exts) { |
2064 | list_for_each_entry(a, &actions, list) { | ||
2065 | if (is_tcf_gact_shot(a)) { | 2065 | if (is_tcf_gact_shot(a)) { |
2066 | action |= MLX5_FLOW_CONTEXT_ACTION_DROP; | 2066 | action |= MLX5_FLOW_CONTEXT_ACTION_DROP; |
2067 | if (MLX5_CAP_FLOWTABLE(priv->mdev, | 2067 | if (MLX5_CAP_FLOWTABLE(priv->mdev, |
@@ -2666,7 +2666,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, | |||
2666 | LIST_HEAD(actions); | 2666 | LIST_HEAD(actions); |
2667 | bool encap = false; | 2667 | bool encap = false; |
2668 | u32 action = 0; | 2668 | u32 action = 0; |
2669 | int err; | 2669 | int err, i; |
2670 | 2670 | ||
2671 | if (!tcf_exts_has_actions(exts)) | 2671 | if (!tcf_exts_has_actions(exts)) |
2672 | return -EINVAL; | 2672 | return -EINVAL; |
@@ -2674,8 +2674,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts, | |||
2674 | attr->in_rep = rpriv->rep; | 2674 | attr->in_rep = rpriv->rep; |
2675 | attr->in_mdev = priv->mdev; | 2675 | attr->in_mdev = priv->mdev; |
2676 | 2676 | ||
2677 | tcf_exts_to_list(exts, &actions); | 2677 | tcf_exts_for_each_action(i, a, exts) { |
2678 | list_for_each_entry(a, &actions, list) { | ||
2679 | if (is_tcf_gact_shot(a)) { | 2678 | if (is_tcf_gact_shot(a)) { |
2680 | action |= MLX5_FLOW_CONTEXT_ACTION_DROP | | 2679 | action |= MLX5_FLOW_CONTEXT_ACTION_DROP | |
2681 | MLX5_FLOW_CONTEXT_ACTION_COUNT; | 2680 | MLX5_FLOW_CONTEXT_ACTION_COUNT; |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 6070d1591d1e..930700413b1d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c | |||
@@ -1346,8 +1346,7 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1346 | return -ENOMEM; | 1346 | return -ENOMEM; |
1347 | mall_tc_entry->cookie = f->cookie; | 1347 | mall_tc_entry->cookie = f->cookie; |
1348 | 1348 | ||
1349 | tcf_exts_to_list(f->exts, &actions); | 1349 | a = tcf_exts_first_action(f->exts); |
1350 | a = list_first_entry(&actions, struct tc_action, list); | ||
1351 | 1350 | ||
1352 | if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) { | 1351 | if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) { |
1353 | struct mlxsw_sp_port_mall_mirror_tc_entry *mirror; | 1352 | struct mlxsw_sp_port_mall_mirror_tc_entry *mirror; |
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index ebd1b24ebaa5..8d211972c5e9 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c | |||
@@ -21,8 +21,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, | |||
21 | struct netlink_ext_ack *extack) | 21 | struct netlink_ext_ack *extack) |
22 | { | 22 | { |
23 | const struct tc_action *a; | 23 | const struct tc_action *a; |
24 | LIST_HEAD(actions); | 24 | int err, i; |
25 | int err; | ||
26 | 25 | ||
27 | if (!tcf_exts_has_actions(exts)) | 26 | if (!tcf_exts_has_actions(exts)) |
28 | return 0; | 27 | return 0; |
@@ -32,8 +31,7 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, | |||
32 | if (err) | 31 | if (err) |
33 | return err; | 32 | return err; |
34 | 33 | ||
35 | tcf_exts_to_list(exts, &actions); | 34 | tcf_exts_for_each_action(i, a, exts) { |
36 | list_for_each_entry(a, &actions, list) { | ||
37 | if (is_tcf_gact_ok(a)) { | 35 | if (is_tcf_gact_ok(a)) { |
38 | err = mlxsw_sp_acl_rulei_act_terminate(rulei); | 36 | err = mlxsw_sp_acl_rulei_act_terminate(rulei); |
39 | if (err) { | 37 | if (err) { |
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c index 0ba0356ec4e6..9044496803e6 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/action.c +++ b/drivers/net/ethernet/netronome/nfp/flower/action.c | |||
@@ -796,11 +796,10 @@ int nfp_flower_compile_action(struct nfp_app *app, | |||
796 | struct net_device *netdev, | 796 | struct net_device *netdev, |
797 | struct nfp_fl_payload *nfp_flow) | 797 | struct nfp_fl_payload *nfp_flow) |
798 | { | 798 | { |
799 | int act_len, act_cnt, err, tun_out_cnt, out_cnt; | 799 | int act_len, act_cnt, err, tun_out_cnt, out_cnt, i; |
800 | enum nfp_flower_tun_type tun_type; | 800 | enum nfp_flower_tun_type tun_type; |
801 | const struct tc_action *a; | 801 | const struct tc_action *a; |
802 | u32 csum_updated = 0; | 802 | u32 csum_updated = 0; |
803 | LIST_HEAD(actions); | ||
804 | 803 | ||
805 | memset(nfp_flow->action_data, 0, NFP_FL_MAX_A_SIZ); | 804 | memset(nfp_flow->action_data, 0, NFP_FL_MAX_A_SIZ); |
806 | nfp_flow->meta.act_len = 0; | 805 | nfp_flow->meta.act_len = 0; |
@@ -810,8 +809,7 @@ int nfp_flower_compile_action(struct nfp_app *app, | |||
810 | tun_out_cnt = 0; | 809 | tun_out_cnt = 0; |
811 | out_cnt = 0; | 810 | out_cnt = 0; |
812 | 811 | ||
813 | tcf_exts_to_list(flow->exts, &actions); | 812 | tcf_exts_for_each_action(i, a, flow->exts) { |
814 | list_for_each_entry(a, &actions, list) { | ||
815 | err = nfp_flower_loop_action(app, a, flow, nfp_flow, &act_len, | 813 | err = nfp_flower_loop_action(app, a, flow, nfp_flow, &act_len, |
816 | netdev, &tun_type, &tun_out_cnt, | 814 | netdev, &tun_type, &tun_out_cnt, |
817 | &out_cnt, &csum_updated); | 815 | &out_cnt, &csum_updated); |
diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 9673d19308e6..b16ce7d93caf 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c | |||
@@ -2006,18 +2006,16 @@ unlock: | |||
2006 | static int qede_parse_actions(struct qede_dev *edev, | 2006 | static int qede_parse_actions(struct qede_dev *edev, |
2007 | struct tcf_exts *exts) | 2007 | struct tcf_exts *exts) |
2008 | { | 2008 | { |
2009 | int rc = -EINVAL, num_act = 0; | 2009 | int rc = -EINVAL, num_act = 0, i; |
2010 | const struct tc_action *a; | 2010 | const struct tc_action *a; |
2011 | bool is_drop = false; | 2011 | bool is_drop = false; |
2012 | LIST_HEAD(actions); | ||
2013 | 2012 | ||
2014 | if (!tcf_exts_has_actions(exts)) { | 2013 | if (!tcf_exts_has_actions(exts)) { |
2015 | DP_NOTICE(edev, "No tc actions received\n"); | 2014 | DP_NOTICE(edev, "No tc actions received\n"); |
2016 | return rc; | 2015 | return rc; |
2017 | } | 2016 | } |
2018 | 2017 | ||
2019 | tcf_exts_to_list(exts, &actions); | 2018 | tcf_exts_for_each_action(i, a, exts) { |
2020 | list_for_each_entry(a, &actions, list) { | ||
2021 | num_act++; | 2019 | num_act++; |
2022 | 2020 | ||
2023 | if (is_tcf_gact_shot(a)) | 2021 | if (is_tcf_gact_shot(a)) |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index 1a96dd9c1091..531294f4978b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | |||
@@ -61,7 +61,7 @@ static int tc_fill_actions(struct stmmac_tc_entry *entry, | |||
61 | struct stmmac_tc_entry *action_entry = entry; | 61 | struct stmmac_tc_entry *action_entry = entry; |
62 | const struct tc_action *act; | 62 | const struct tc_action *act; |
63 | struct tcf_exts *exts; | 63 | struct tcf_exts *exts; |
64 | LIST_HEAD(actions); | 64 | int i; |
65 | 65 | ||
66 | exts = cls->knode.exts; | 66 | exts = cls->knode.exts; |
67 | if (!tcf_exts_has_actions(exts)) | 67 | if (!tcf_exts_has_actions(exts)) |
@@ -69,8 +69,7 @@ static int tc_fill_actions(struct stmmac_tc_entry *entry, | |||
69 | if (frag) | 69 | if (frag) |
70 | action_entry = frag; | 70 | action_entry = frag; |
71 | 71 | ||
72 | tcf_exts_to_list(exts, &actions); | 72 | tcf_exts_for_each_action(i, act, exts) { |
73 | list_for_each_entry(act, &actions, list) { | ||
74 | /* Accept */ | 73 | /* Accept */ |
75 | if (is_tcf_gact_ok(act)) { | 74 | if (is_tcf_gact_ok(act)) { |
76 | action_entry->val.af = 1; | 75 | action_entry->val.af = 1; |
diff --git a/include/net/act_api.h b/include/net/act_api.h index 1ad5b19e83a9..970303448c90 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h | |||
@@ -23,13 +23,11 @@ struct tc_action { | |||
23 | const struct tc_action_ops *ops; | 23 | const struct tc_action_ops *ops; |
24 | __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ | 24 | __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ |
25 | __u32 order; | 25 | __u32 order; |
26 | struct list_head list; | ||
27 | struct tcf_idrinfo *idrinfo; | 26 | struct tcf_idrinfo *idrinfo; |
28 | 27 | ||
29 | u32 tcfa_index; | 28 | u32 tcfa_index; |
30 | refcount_t tcfa_refcnt; | 29 | refcount_t tcfa_refcnt; |
31 | atomic_t tcfa_bindcnt; | 30 | atomic_t tcfa_bindcnt; |
32 | u32 tcfa_capab; | ||
33 | int tcfa_action; | 31 | int tcfa_action; |
34 | struct tcf_t tcfa_tm; | 32 | struct tcf_t tcfa_tm; |
35 | struct gnet_stats_basic_packed tcfa_bstats; | 33 | struct gnet_stats_basic_packed tcfa_bstats; |
@@ -44,7 +42,6 @@ struct tc_action { | |||
44 | #define tcf_index common.tcfa_index | 42 | #define tcf_index common.tcfa_index |
45 | #define tcf_refcnt common.tcfa_refcnt | 43 | #define tcf_refcnt common.tcfa_refcnt |
46 | #define tcf_bindcnt common.tcfa_bindcnt | 44 | #define tcf_bindcnt common.tcfa_bindcnt |
47 | #define tcf_capab common.tcfa_capab | ||
48 | #define tcf_action common.tcfa_action | 45 | #define tcf_action common.tcfa_action |
49 | #define tcf_tm common.tcfa_tm | 46 | #define tcf_tm common.tcfa_tm |
50 | #define tcf_bstats common.tcfa_bstats | 47 | #define tcf_bstats common.tcfa_bstats |
@@ -102,7 +99,6 @@ struct tc_action_ops { | |||
102 | size_t (*get_fill_size)(const struct tc_action *act); | 99 | size_t (*get_fill_size)(const struct tc_action *act); |
103 | struct net_device *(*get_dev)(const struct tc_action *a); | 100 | struct net_device *(*get_dev)(const struct tc_action *a); |
104 | void (*put_dev)(struct net_device *dev); | 101 | void (*put_dev)(struct net_device *dev); |
105 | int (*delete)(struct net *net, u32 index); | ||
106 | }; | 102 | }; |
107 | 103 | ||
108 | struct tc_action_net { | 104 | struct tc_action_net { |
@@ -148,8 +144,6 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, | |||
148 | const struct tc_action_ops *ops, | 144 | const struct tc_action_ops *ops, |
149 | struct netlink_ext_ack *extack); | 145 | struct netlink_ext_ack *extack); |
150 | int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index); | 146 | int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index); |
151 | bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a, | ||
152 | int bind); | ||
153 | int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, | 147 | int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, |
154 | struct tc_action **a, const struct tc_action_ops *ops, | 148 | struct tc_action **a, const struct tc_action_ops *ops, |
155 | int bind, bool cpustats); | 149 | int bind, bool cpustats); |
@@ -158,7 +152,6 @@ void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a); | |||
158 | void tcf_idr_cleanup(struct tc_action_net *tn, u32 index); | 152 | void tcf_idr_cleanup(struct tc_action_net *tn, u32 index); |
159 | int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, | 153 | int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, |
160 | struct tc_action **a, int bind); | 154 | struct tc_action **a, int bind); |
161 | int tcf_idr_delete_index(struct tc_action_net *tn, u32 index); | ||
162 | int __tcf_idr_release(struct tc_action *a, bool bind, bool strict); | 155 | int __tcf_idr_release(struct tc_action *a, bool bind, bool strict); |
163 | 156 | ||
164 | static inline int tcf_idr_release(struct tc_action *a, bool bind) | 157 | static inline int tcf_idr_release(struct tc_action *a, bool bind) |
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index ef727f71336e..c17d51865469 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h | |||
@@ -298,19 +298,13 @@ static inline void tcf_exts_put_net(struct tcf_exts *exts) | |||
298 | #endif | 298 | #endif |
299 | } | 299 | } |
300 | 300 | ||
301 | static inline void tcf_exts_to_list(const struct tcf_exts *exts, | ||
302 | struct list_head *actions) | ||
303 | { | ||
304 | #ifdef CONFIG_NET_CLS_ACT | 301 | #ifdef CONFIG_NET_CLS_ACT |
305 | int i; | 302 | #define tcf_exts_for_each_action(i, a, exts) \ |
306 | 303 | for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = (exts)->actions[i]); i++) | |
307 | for (i = 0; i < exts->nr_actions; i++) { | 304 | #else |
308 | struct tc_action *a = exts->actions[i]; | 305 | #define tcf_exts_for_each_action(i, a, exts) \ |
309 | 306 | for (; 0; ) | |
310 | list_add_tail(&a->list, actions); | ||
311 | } | ||
312 | #endif | 307 | #endif |
313 | } | ||
314 | 308 | ||
315 | static inline void | 309 | static inline void |
316 | tcf_exts_stats_update(const struct tcf_exts *exts, | 310 | tcf_exts_stats_update(const struct tcf_exts *exts, |
@@ -361,6 +355,15 @@ static inline bool tcf_exts_has_one_action(struct tcf_exts *exts) | |||
361 | #endif | 355 | #endif |
362 | } | 356 | } |
363 | 357 | ||
358 | static inline struct tc_action *tcf_exts_first_action(struct tcf_exts *exts) | ||
359 | { | ||
360 | #ifdef CONFIG_NET_CLS_ACT | ||
361 | return exts->actions[0]; | ||
362 | #else | ||
363 | return NULL; | ||
364 | #endif | ||
365 | } | ||
366 | |||
364 | /** | 367 | /** |
365 | * tcf_exts_exec - execute tc filter extensions | 368 | * tcf_exts_exec - execute tc filter extensions |
366 | * @skb: socket buffer | 369 | * @skb: socket buffer |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 962c4fd338ba..1c45c1d6d241 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
@@ -767,7 +767,6 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev, | |||
767 | const struct tc_action *a; | 767 | const struct tc_action *a; |
768 | struct dsa_port *to_dp; | 768 | struct dsa_port *to_dp; |
769 | int err = -EOPNOTSUPP; | 769 | int err = -EOPNOTSUPP; |
770 | LIST_HEAD(actions); | ||
771 | 770 | ||
772 | if (!ds->ops->port_mirror_add) | 771 | if (!ds->ops->port_mirror_add) |
773 | return err; | 772 | return err; |
@@ -775,8 +774,7 @@ static int dsa_slave_add_cls_matchall(struct net_device *dev, | |||
775 | if (!tcf_exts_has_one_action(cls->exts)) | 774 | if (!tcf_exts_has_one_action(cls->exts)) |
776 | return err; | 775 | return err; |
777 | 776 | ||
778 | tcf_exts_to_list(cls->exts, &actions); | 777 | a = tcf_exts_first_action(cls->exts); |
779 | a = list_first_entry(&actions, struct tc_action, list); | ||
780 | 778 | ||
781 | if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) { | 779 | if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) { |
782 | struct dsa_mall_mirror_tc_entry *mirror; | 780 | struct dsa_mall_mirror_tc_entry *mirror; |
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 229d63c99be2..db83dac1e7f4 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -300,21 +300,17 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb, | |||
300 | } | 300 | } |
301 | EXPORT_SYMBOL(tcf_generic_walker); | 301 | EXPORT_SYMBOL(tcf_generic_walker); |
302 | 302 | ||
303 | static bool __tcf_idr_check(struct tc_action_net *tn, u32 index, | 303 | int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index) |
304 | struct tc_action **a, int bind) | ||
305 | { | 304 | { |
306 | struct tcf_idrinfo *idrinfo = tn->idrinfo; | 305 | struct tcf_idrinfo *idrinfo = tn->idrinfo; |
307 | struct tc_action *p; | 306 | struct tc_action *p; |
308 | 307 | ||
309 | spin_lock(&idrinfo->lock); | 308 | spin_lock(&idrinfo->lock); |
310 | p = idr_find(&idrinfo->action_idr, index); | 309 | p = idr_find(&idrinfo->action_idr, index); |
311 | if (IS_ERR(p)) { | 310 | if (IS_ERR(p)) |
312 | p = NULL; | 311 | p = NULL; |
313 | } else if (p) { | 312 | else if (p) |
314 | refcount_inc(&p->tcfa_refcnt); | 313 | refcount_inc(&p->tcfa_refcnt); |
315 | if (bind) | ||
316 | atomic_inc(&p->tcfa_bindcnt); | ||
317 | } | ||
318 | spin_unlock(&idrinfo->lock); | 314 | spin_unlock(&idrinfo->lock); |
319 | 315 | ||
320 | if (p) { | 316 | if (p) { |
@@ -323,23 +319,10 @@ static bool __tcf_idr_check(struct tc_action_net *tn, u32 index, | |||
323 | } | 319 | } |
324 | return false; | 320 | return false; |
325 | } | 321 | } |
326 | |||
327 | int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index) | ||
328 | { | ||
329 | return __tcf_idr_check(tn, index, a, 0); | ||
330 | } | ||
331 | EXPORT_SYMBOL(tcf_idr_search); | 322 | EXPORT_SYMBOL(tcf_idr_search); |
332 | 323 | ||
333 | bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a, | 324 | static int tcf_idr_delete_index(struct tcf_idrinfo *idrinfo, u32 index) |
334 | int bind) | ||
335 | { | 325 | { |
336 | return __tcf_idr_check(tn, index, a, bind); | ||
337 | } | ||
338 | EXPORT_SYMBOL(tcf_idr_check); | ||
339 | |||
340 | int tcf_idr_delete_index(struct tc_action_net *tn, u32 index) | ||
341 | { | ||
342 | struct tcf_idrinfo *idrinfo = tn->idrinfo; | ||
343 | struct tc_action *p; | 326 | struct tc_action *p; |
344 | int ret = 0; | 327 | int ret = 0; |
345 | 328 | ||
@@ -370,7 +353,6 @@ int tcf_idr_delete_index(struct tc_action_net *tn, u32 index) | |||
370 | spin_unlock(&idrinfo->lock); | 353 | spin_unlock(&idrinfo->lock); |
371 | return ret; | 354 | return ret; |
372 | } | 355 | } |
373 | EXPORT_SYMBOL(tcf_idr_delete_index); | ||
374 | 356 | ||
375 | int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, | 357 | int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, |
376 | struct tc_action **a, const struct tc_action_ops *ops, | 358 | struct tc_action **a, const struct tc_action_ops *ops, |
@@ -409,7 +391,6 @@ int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, | |||
409 | 391 | ||
410 | p->idrinfo = idrinfo; | 392 | p->idrinfo = idrinfo; |
411 | p->ops = ops; | 393 | p->ops = ops; |
412 | INIT_LIST_HEAD(&p->list); | ||
413 | *a = p; | 394 | *a = p; |
414 | return 0; | 395 | return 0; |
415 | err3: | 396 | err3: |
@@ -686,14 +667,18 @@ static int tcf_action_put(struct tc_action *p) | |||
686 | return __tcf_action_put(p, false); | 667 | return __tcf_action_put(p, false); |
687 | } | 668 | } |
688 | 669 | ||
670 | /* Put all actions in this array, skip those NULL's. */ | ||
689 | static void tcf_action_put_many(struct tc_action *actions[]) | 671 | static void tcf_action_put_many(struct tc_action *actions[]) |
690 | { | 672 | { |
691 | int i; | 673 | int i; |
692 | 674 | ||
693 | for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) { | 675 | for (i = 0; i < TCA_ACT_MAX_PRIO; i++) { |
694 | struct tc_action *a = actions[i]; | 676 | struct tc_action *a = actions[i]; |
695 | const struct tc_action_ops *ops = a->ops; | 677 | const struct tc_action_ops *ops; |
696 | 678 | ||
679 | if (!a) | ||
680 | continue; | ||
681 | ops = a->ops; | ||
697 | if (tcf_action_put(a)) | 682 | if (tcf_action_put(a)) |
698 | module_put(ops->owner); | 683 | module_put(ops->owner); |
699 | } | 684 | } |
@@ -1175,41 +1160,38 @@ err_out: | |||
1175 | return err; | 1160 | return err; |
1176 | } | 1161 | } |
1177 | 1162 | ||
1178 | static int tcf_action_delete(struct net *net, struct tc_action *actions[], | 1163 | static int tcf_action_delete(struct net *net, struct tc_action *actions[]) |
1179 | int *acts_deleted, struct netlink_ext_ack *extack) | ||
1180 | { | 1164 | { |
1181 | u32 act_index; | 1165 | int i; |
1182 | int ret, i; | ||
1183 | 1166 | ||
1184 | for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) { | 1167 | for (i = 0; i < TCA_ACT_MAX_PRIO && actions[i]; i++) { |
1185 | struct tc_action *a = actions[i]; | 1168 | struct tc_action *a = actions[i]; |
1186 | const struct tc_action_ops *ops = a->ops; | 1169 | const struct tc_action_ops *ops = a->ops; |
1187 | |||
1188 | /* Actions can be deleted concurrently so we must save their | 1170 | /* Actions can be deleted concurrently so we must save their |
1189 | * type and id to search again after reference is released. | 1171 | * type and id to search again after reference is released. |
1190 | */ | 1172 | */ |
1191 | act_index = a->tcfa_index; | 1173 | struct tcf_idrinfo *idrinfo = a->idrinfo; |
1174 | u32 act_index = a->tcfa_index; | ||
1192 | 1175 | ||
1193 | if (tcf_action_put(a)) { | 1176 | if (tcf_action_put(a)) { |
1194 | /* last reference, action was deleted concurrently */ | 1177 | /* last reference, action was deleted concurrently */ |
1195 | module_put(ops->owner); | 1178 | module_put(ops->owner); |
1196 | } else { | 1179 | } else { |
1180 | int ret; | ||
1181 | |||
1197 | /* now do the delete */ | 1182 | /* now do the delete */ |
1198 | ret = ops->delete(net, act_index); | 1183 | ret = tcf_idr_delete_index(idrinfo, act_index); |
1199 | if (ret < 0) { | 1184 | if (ret < 0) |
1200 | *acts_deleted = i + 1; | ||
1201 | return ret; | 1185 | return ret; |
1202 | } | ||
1203 | } | 1186 | } |
1187 | actions[i] = NULL; | ||
1204 | } | 1188 | } |
1205 | *acts_deleted = i; | ||
1206 | return 0; | 1189 | return 0; |
1207 | } | 1190 | } |
1208 | 1191 | ||
1209 | static int | 1192 | static int |
1210 | tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[], | 1193 | tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[], |
1211 | int *acts_deleted, u32 portid, size_t attr_size, | 1194 | u32 portid, size_t attr_size, struct netlink_ext_ack *extack) |
1212 | struct netlink_ext_ack *extack) | ||
1213 | { | 1195 | { |
1214 | int ret; | 1196 | int ret; |
1215 | struct sk_buff *skb; | 1197 | struct sk_buff *skb; |
@@ -1227,7 +1209,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[], | |||
1227 | } | 1209 | } |
1228 | 1210 | ||
1229 | /* now do the delete */ | 1211 | /* now do the delete */ |
1230 | ret = tcf_action_delete(net, actions, acts_deleted, extack); | 1212 | ret = tcf_action_delete(net, actions); |
1231 | if (ret < 0) { | 1213 | if (ret < 0) { |
1232 | NL_SET_ERR_MSG(extack, "Failed to delete TC action"); | 1214 | NL_SET_ERR_MSG(extack, "Failed to delete TC action"); |
1233 | kfree_skb(skb); | 1215 | kfree_skb(skb); |
@@ -1249,8 +1231,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
1249 | struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; | 1231 | struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; |
1250 | struct tc_action *act; | 1232 | struct tc_action *act; |
1251 | size_t attr_size = 0; | 1233 | size_t attr_size = 0; |
1252 | struct tc_action *actions[TCA_ACT_MAX_PRIO + 1] = {}; | 1234 | struct tc_action *actions[TCA_ACT_MAX_PRIO] = {}; |
1253 | int acts_deleted = 0; | ||
1254 | 1235 | ||
1255 | ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack); | 1236 | ret = nla_parse_nested(tb, TCA_ACT_MAX_PRIO, nla, NULL, extack); |
1256 | if (ret < 0) | 1237 | if (ret < 0) |
@@ -1280,14 +1261,13 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
1280 | if (event == RTM_GETACTION) | 1261 | if (event == RTM_GETACTION) |
1281 | ret = tcf_get_notify(net, portid, n, actions, event, extack); | 1262 | ret = tcf_get_notify(net, portid, n, actions, event, extack); |
1282 | else { /* delete */ | 1263 | else { /* delete */ |
1283 | ret = tcf_del_notify(net, n, actions, &acts_deleted, portid, | 1264 | ret = tcf_del_notify(net, n, actions, portid, attr_size, extack); |
1284 | attr_size, extack); | ||
1285 | if (ret) | 1265 | if (ret) |
1286 | goto err; | 1266 | goto err; |
1287 | return ret; | 1267 | return 0; |
1288 | } | 1268 | } |
1289 | err: | 1269 | err: |
1290 | tcf_action_put_many(&actions[acts_deleted]); | 1270 | tcf_action_put_many(actions); |
1291 | return ret; | 1271 | return ret; |
1292 | } | 1272 | } |
1293 | 1273 | ||
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index d30b23e42436..0c68bc9cf0b4 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c | |||
@@ -395,13 +395,6 @@ static int tcf_bpf_search(struct net *net, struct tc_action **a, u32 index, | |||
395 | return tcf_idr_search(tn, a, index); | 395 | return tcf_idr_search(tn, a, index); |
396 | } | 396 | } |
397 | 397 | ||
398 | static int tcf_bpf_delete(struct net *net, u32 index) | ||
399 | { | ||
400 | struct tc_action_net *tn = net_generic(net, bpf_net_id); | ||
401 | |||
402 | return tcf_idr_delete_index(tn, index); | ||
403 | } | ||
404 | |||
405 | static struct tc_action_ops act_bpf_ops __read_mostly = { | 398 | static struct tc_action_ops act_bpf_ops __read_mostly = { |
406 | .kind = "bpf", | 399 | .kind = "bpf", |
407 | .type = TCA_ACT_BPF, | 400 | .type = TCA_ACT_BPF, |
@@ -412,7 +405,6 @@ static struct tc_action_ops act_bpf_ops __read_mostly = { | |||
412 | .init = tcf_bpf_init, | 405 | .init = tcf_bpf_init, |
413 | .walk = tcf_bpf_walker, | 406 | .walk = tcf_bpf_walker, |
414 | .lookup = tcf_bpf_search, | 407 | .lookup = tcf_bpf_search, |
415 | .delete = tcf_bpf_delete, | ||
416 | .size = sizeof(struct tcf_bpf), | 408 | .size = sizeof(struct tcf_bpf), |
417 | }; | 409 | }; |
418 | 410 | ||
diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index 54c0bf54f2ac..6f0f273f1139 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c | |||
@@ -198,13 +198,6 @@ static int tcf_connmark_search(struct net *net, struct tc_action **a, u32 index, | |||
198 | return tcf_idr_search(tn, a, index); | 198 | return tcf_idr_search(tn, a, index); |
199 | } | 199 | } |
200 | 200 | ||
201 | static int tcf_connmark_delete(struct net *net, u32 index) | ||
202 | { | ||
203 | struct tc_action_net *tn = net_generic(net, connmark_net_id); | ||
204 | |||
205 | return tcf_idr_delete_index(tn, index); | ||
206 | } | ||
207 | |||
208 | static struct tc_action_ops act_connmark_ops = { | 201 | static struct tc_action_ops act_connmark_ops = { |
209 | .kind = "connmark", | 202 | .kind = "connmark", |
210 | .type = TCA_ACT_CONNMARK, | 203 | .type = TCA_ACT_CONNMARK, |
@@ -214,7 +207,6 @@ static struct tc_action_ops act_connmark_ops = { | |||
214 | .init = tcf_connmark_init, | 207 | .init = tcf_connmark_init, |
215 | .walk = tcf_connmark_walker, | 208 | .walk = tcf_connmark_walker, |
216 | .lookup = tcf_connmark_search, | 209 | .lookup = tcf_connmark_search, |
217 | .delete = tcf_connmark_delete, | ||
218 | .size = sizeof(struct tcf_connmark_info), | 210 | .size = sizeof(struct tcf_connmark_info), |
219 | }; | 211 | }; |
220 | 212 | ||
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index e698d3fe2080..b8a67ae3105a 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
@@ -659,13 +659,6 @@ static size_t tcf_csum_get_fill_size(const struct tc_action *act) | |||
659 | return nla_total_size(sizeof(struct tc_csum)); | 659 | return nla_total_size(sizeof(struct tc_csum)); |
660 | } | 660 | } |
661 | 661 | ||
662 | static int tcf_csum_delete(struct net *net, u32 index) | ||
663 | { | ||
664 | struct tc_action_net *tn = net_generic(net, csum_net_id); | ||
665 | |||
666 | return tcf_idr_delete_index(tn, index); | ||
667 | } | ||
668 | |||
669 | static struct tc_action_ops act_csum_ops = { | 662 | static struct tc_action_ops act_csum_ops = { |
670 | .kind = "csum", | 663 | .kind = "csum", |
671 | .type = TCA_ACT_CSUM, | 664 | .type = TCA_ACT_CSUM, |
@@ -677,7 +670,6 @@ static struct tc_action_ops act_csum_ops = { | |||
677 | .walk = tcf_csum_walker, | 670 | .walk = tcf_csum_walker, |
678 | .lookup = tcf_csum_search, | 671 | .lookup = tcf_csum_search, |
679 | .get_fill_size = tcf_csum_get_fill_size, | 672 | .get_fill_size = tcf_csum_get_fill_size, |
680 | .delete = tcf_csum_delete, | ||
681 | .size = sizeof(struct tcf_csum), | 673 | .size = sizeof(struct tcf_csum), |
682 | }; | 674 | }; |
683 | 675 | ||
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index 6a3f25a8ffb3..cd1d9bd32ef9 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
@@ -243,13 +243,6 @@ static size_t tcf_gact_get_fill_size(const struct tc_action *act) | |||
243 | return sz; | 243 | return sz; |
244 | } | 244 | } |
245 | 245 | ||
246 | static int tcf_gact_delete(struct net *net, u32 index) | ||
247 | { | ||
248 | struct tc_action_net *tn = net_generic(net, gact_net_id); | ||
249 | |||
250 | return tcf_idr_delete_index(tn, index); | ||
251 | } | ||
252 | |||
253 | static struct tc_action_ops act_gact_ops = { | 246 | static struct tc_action_ops act_gact_ops = { |
254 | .kind = "gact", | 247 | .kind = "gact", |
255 | .type = TCA_ACT_GACT, | 248 | .type = TCA_ACT_GACT, |
@@ -261,7 +254,6 @@ static struct tc_action_ops act_gact_ops = { | |||
261 | .walk = tcf_gact_walker, | 254 | .walk = tcf_gact_walker, |
262 | .lookup = tcf_gact_search, | 255 | .lookup = tcf_gact_search, |
263 | .get_fill_size = tcf_gact_get_fill_size, | 256 | .get_fill_size = tcf_gact_get_fill_size, |
264 | .delete = tcf_gact_delete, | ||
265 | .size = sizeof(struct tcf_gact), | 257 | .size = sizeof(struct tcf_gact), |
266 | }; | 258 | }; |
267 | 259 | ||
diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index d1081bdf1bdb..196430aefe87 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c | |||
@@ -167,16 +167,16 @@ static struct tcf_meta_ops *find_ife_oplist(u16 metaid) | |||
167 | { | 167 | { |
168 | struct tcf_meta_ops *o; | 168 | struct tcf_meta_ops *o; |
169 | 169 | ||
170 | read_lock_bh(&ife_mod_lock); | 170 | read_lock(&ife_mod_lock); |
171 | list_for_each_entry(o, &ifeoplist, list) { | 171 | list_for_each_entry(o, &ifeoplist, list) { |
172 | if (o->metaid == metaid) { | 172 | if (o->metaid == metaid) { |
173 | if (!try_module_get(o->owner)) | 173 | if (!try_module_get(o->owner)) |
174 | o = NULL; | 174 | o = NULL; |
175 | read_unlock_bh(&ife_mod_lock); | 175 | read_unlock(&ife_mod_lock); |
176 | return o; | 176 | return o; |
177 | } | 177 | } |
178 | } | 178 | } |
179 | read_unlock_bh(&ife_mod_lock); | 179 | read_unlock(&ife_mod_lock); |
180 | 180 | ||
181 | return NULL; | 181 | return NULL; |
182 | } | 182 | } |
@@ -190,12 +190,12 @@ int register_ife_op(struct tcf_meta_ops *mops) | |||
190 | !mops->get || !mops->alloc) | 190 | !mops->get || !mops->alloc) |
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | 192 | ||
193 | write_lock_bh(&ife_mod_lock); | 193 | write_lock(&ife_mod_lock); |
194 | 194 | ||
195 | list_for_each_entry(m, &ifeoplist, list) { | 195 | list_for_each_entry(m, &ifeoplist, list) { |
196 | if (m->metaid == mops->metaid || | 196 | if (m->metaid == mops->metaid || |
197 | (strcmp(mops->name, m->name) == 0)) { | 197 | (strcmp(mops->name, m->name) == 0)) { |
198 | write_unlock_bh(&ife_mod_lock); | 198 | write_unlock(&ife_mod_lock); |
199 | return -EEXIST; | 199 | return -EEXIST; |
200 | } | 200 | } |
201 | } | 201 | } |
@@ -204,7 +204,7 @@ int register_ife_op(struct tcf_meta_ops *mops) | |||
204 | mops->release = ife_release_meta_gen; | 204 | mops->release = ife_release_meta_gen; |
205 | 205 | ||
206 | list_add_tail(&mops->list, &ifeoplist); | 206 | list_add_tail(&mops->list, &ifeoplist); |
207 | write_unlock_bh(&ife_mod_lock); | 207 | write_unlock(&ife_mod_lock); |
208 | return 0; | 208 | return 0; |
209 | } | 209 | } |
210 | EXPORT_SYMBOL_GPL(unregister_ife_op); | 210 | EXPORT_SYMBOL_GPL(unregister_ife_op); |
@@ -214,7 +214,7 @@ int unregister_ife_op(struct tcf_meta_ops *mops) | |||
214 | struct tcf_meta_ops *m; | 214 | struct tcf_meta_ops *m; |
215 | int err = -ENOENT; | 215 | int err = -ENOENT; |
216 | 216 | ||
217 | write_lock_bh(&ife_mod_lock); | 217 | write_lock(&ife_mod_lock); |
218 | list_for_each_entry(m, &ifeoplist, list) { | 218 | list_for_each_entry(m, &ifeoplist, list) { |
219 | if (m->metaid == mops->metaid) { | 219 | if (m->metaid == mops->metaid) { |
220 | list_del(&mops->list); | 220 | list_del(&mops->list); |
@@ -222,7 +222,7 @@ int unregister_ife_op(struct tcf_meta_ops *mops) | |||
222 | break; | 222 | break; |
223 | } | 223 | } |
224 | } | 224 | } |
225 | write_unlock_bh(&ife_mod_lock); | 225 | write_unlock(&ife_mod_lock); |
226 | 226 | ||
227 | return err; | 227 | return err; |
228 | } | 228 | } |
@@ -265,11 +265,8 @@ static const char *ife_meta_id2name(u32 metaid) | |||
265 | #endif | 265 | #endif |
266 | 266 | ||
267 | /* called when adding new meta information | 267 | /* called when adding new meta information |
268 | * under ife->tcf_lock for existing action | ||
269 | */ | 268 | */ |
270 | static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, | 269 | static int load_metaops_and_vet(u32 metaid, void *val, int len, bool rtnl_held) |
271 | void *val, int len, bool exists, | ||
272 | bool rtnl_held) | ||
273 | { | 270 | { |
274 | struct tcf_meta_ops *ops = find_ife_oplist(metaid); | 271 | struct tcf_meta_ops *ops = find_ife_oplist(metaid); |
275 | int ret = 0; | 272 | int ret = 0; |
@@ -277,15 +274,11 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, | |||
277 | if (!ops) { | 274 | if (!ops) { |
278 | ret = -ENOENT; | 275 | ret = -ENOENT; |
279 | #ifdef CONFIG_MODULES | 276 | #ifdef CONFIG_MODULES |
280 | if (exists) | ||
281 | spin_unlock_bh(&ife->tcf_lock); | ||
282 | if (rtnl_held) | 277 | if (rtnl_held) |
283 | rtnl_unlock(); | 278 | rtnl_unlock(); |
284 | request_module("ife-meta-%s", ife_meta_id2name(metaid)); | 279 | request_module("ife-meta-%s", ife_meta_id2name(metaid)); |
285 | if (rtnl_held) | 280 | if (rtnl_held) |
286 | rtnl_lock(); | 281 | rtnl_lock(); |
287 | if (exists) | ||
288 | spin_lock_bh(&ife->tcf_lock); | ||
289 | ops = find_ife_oplist(metaid); | 282 | ops = find_ife_oplist(metaid); |
290 | #endif | 283 | #endif |
291 | } | 284 | } |
@@ -302,24 +295,17 @@ static int load_metaops_and_vet(struct tcf_ife_info *ife, u32 metaid, | |||
302 | } | 295 | } |
303 | 296 | ||
304 | /* called when adding new meta information | 297 | /* called when adding new meta information |
305 | * under ife->tcf_lock for existing action | ||
306 | */ | 298 | */ |
307 | static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, | 299 | static int __add_metainfo(const struct tcf_meta_ops *ops, |
308 | int len, bool atomic) | 300 | struct tcf_ife_info *ife, u32 metaid, void *metaval, |
301 | int len, bool atomic, bool exists) | ||
309 | { | 302 | { |
310 | struct tcf_meta_info *mi = NULL; | 303 | struct tcf_meta_info *mi = NULL; |
311 | struct tcf_meta_ops *ops = find_ife_oplist(metaid); | ||
312 | int ret = 0; | 304 | int ret = 0; |
313 | 305 | ||
314 | if (!ops) | ||
315 | return -ENOENT; | ||
316 | |||
317 | mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL); | 306 | mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL); |
318 | if (!mi) { | 307 | if (!mi) |
319 | /*put back what find_ife_oplist took */ | ||
320 | module_put(ops->owner); | ||
321 | return -ENOMEM; | 308 | return -ENOMEM; |
322 | } | ||
323 | 309 | ||
324 | mi->metaid = metaid; | 310 | mi->metaid = metaid; |
325 | mi->ops = ops; | 311 | mi->ops = ops; |
@@ -327,29 +313,47 @@ static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, | |||
327 | ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL); | 313 | ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL); |
328 | if (ret != 0) { | 314 | if (ret != 0) { |
329 | kfree(mi); | 315 | kfree(mi); |
330 | module_put(ops->owner); | ||
331 | return ret; | 316 | return ret; |
332 | } | 317 | } |
333 | } | 318 | } |
334 | 319 | ||
320 | if (exists) | ||
321 | spin_lock_bh(&ife->tcf_lock); | ||
335 | list_add_tail(&mi->metalist, &ife->metalist); | 322 | list_add_tail(&mi->metalist, &ife->metalist); |
323 | if (exists) | ||
324 | spin_unlock_bh(&ife->tcf_lock); | ||
325 | |||
326 | return ret; | ||
327 | } | ||
328 | |||
329 | static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, | ||
330 | int len, bool exists) | ||
331 | { | ||
332 | const struct tcf_meta_ops *ops = find_ife_oplist(metaid); | ||
333 | int ret; | ||
336 | 334 | ||
335 | if (!ops) | ||
336 | return -ENOENT; | ||
337 | ret = __add_metainfo(ops, ife, metaid, metaval, len, false, exists); | ||
338 | if (ret) | ||
339 | /*put back what find_ife_oplist took */ | ||
340 | module_put(ops->owner); | ||
337 | return ret; | 341 | return ret; |
338 | } | 342 | } |
339 | 343 | ||
340 | static int use_all_metadata(struct tcf_ife_info *ife) | 344 | static int use_all_metadata(struct tcf_ife_info *ife, bool exists) |
341 | { | 345 | { |
342 | struct tcf_meta_ops *o; | 346 | struct tcf_meta_ops *o; |
343 | int rc = 0; | 347 | int rc = 0; |
344 | int installed = 0; | 348 | int installed = 0; |
345 | 349 | ||
346 | read_lock_bh(&ife_mod_lock); | 350 | read_lock(&ife_mod_lock); |
347 | list_for_each_entry(o, &ifeoplist, list) { | 351 | list_for_each_entry(o, &ifeoplist, list) { |
348 | rc = add_metainfo(ife, o->metaid, NULL, 0, true); | 352 | rc = __add_metainfo(o, ife, o->metaid, NULL, 0, true, exists); |
349 | if (rc == 0) | 353 | if (rc == 0) |
350 | installed += 1; | 354 | installed += 1; |
351 | } | 355 | } |
352 | read_unlock_bh(&ife_mod_lock); | 356 | read_unlock(&ife_mod_lock); |
353 | 357 | ||
354 | if (installed) | 358 | if (installed) |
355 | return 0; | 359 | return 0; |
@@ -422,7 +426,6 @@ static void tcf_ife_cleanup(struct tc_action *a) | |||
422 | kfree_rcu(p, rcu); | 426 | kfree_rcu(p, rcu); |
423 | } | 427 | } |
424 | 428 | ||
425 | /* under ife->tcf_lock for existing action */ | ||
426 | static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb, | 429 | static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb, |
427 | bool exists, bool rtnl_held) | 430 | bool exists, bool rtnl_held) |
428 | { | 431 | { |
@@ -436,8 +439,7 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb, | |||
436 | val = nla_data(tb[i]); | 439 | val = nla_data(tb[i]); |
437 | len = nla_len(tb[i]); | 440 | len = nla_len(tb[i]); |
438 | 441 | ||
439 | rc = load_metaops_and_vet(ife, i, val, len, exists, | 442 | rc = load_metaops_and_vet(i, val, len, rtnl_held); |
440 | rtnl_held); | ||
441 | if (rc != 0) | 443 | if (rc != 0) |
442 | return rc; | 444 | return rc; |
443 | 445 | ||
@@ -540,8 +542,6 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, | |||
540 | p->eth_type = ife_type; | 542 | p->eth_type = ife_type; |
541 | } | 543 | } |
542 | 544 | ||
543 | if (exists) | ||
544 | spin_lock_bh(&ife->tcf_lock); | ||
545 | 545 | ||
546 | if (ret == ACT_P_CREATED) | 546 | if (ret == ACT_P_CREATED) |
547 | INIT_LIST_HEAD(&ife->metalist); | 547 | INIT_LIST_HEAD(&ife->metalist); |
@@ -551,10 +551,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, | |||
551 | NULL, NULL); | 551 | NULL, NULL); |
552 | if (err) { | 552 | if (err) { |
553 | metadata_parse_err: | 553 | metadata_parse_err: |
554 | if (exists) | ||
555 | spin_unlock_bh(&ife->tcf_lock); | ||
556 | tcf_idr_release(*a, bind); | 554 | tcf_idr_release(*a, bind); |
557 | |||
558 | kfree(p); | 555 | kfree(p); |
559 | return err; | 556 | return err; |
560 | } | 557 | } |
@@ -569,17 +566,16 @@ metadata_parse_err: | |||
569 | * as we can. You better have at least one else we are | 566 | * as we can. You better have at least one else we are |
570 | * going to bail out | 567 | * going to bail out |
571 | */ | 568 | */ |
572 | err = use_all_metadata(ife); | 569 | err = use_all_metadata(ife, exists); |
573 | if (err) { | 570 | if (err) { |
574 | if (exists) | ||
575 | spin_unlock_bh(&ife->tcf_lock); | ||
576 | tcf_idr_release(*a, bind); | 571 | tcf_idr_release(*a, bind); |
577 | |||
578 | kfree(p); | 572 | kfree(p); |
579 | return err; | 573 | return err; |
580 | } | 574 | } |
581 | } | 575 | } |
582 | 576 | ||
577 | if (exists) | ||
578 | spin_lock_bh(&ife->tcf_lock); | ||
583 | ife->tcf_action = parm->action; | 579 | ife->tcf_action = parm->action; |
584 | /* protected by tcf_lock when modifying existing action */ | 580 | /* protected by tcf_lock when modifying existing action */ |
585 | rcu_swap_protected(ife->params, p, 1); | 581 | rcu_swap_protected(ife->params, p, 1); |
@@ -853,13 +849,6 @@ static int tcf_ife_search(struct net *net, struct tc_action **a, u32 index, | |||
853 | return tcf_idr_search(tn, a, index); | 849 | return tcf_idr_search(tn, a, index); |
854 | } | 850 | } |
855 | 851 | ||
856 | static int tcf_ife_delete(struct net *net, u32 index) | ||
857 | { | ||
858 | struct tc_action_net *tn = net_generic(net, ife_net_id); | ||
859 | |||
860 | return tcf_idr_delete_index(tn, index); | ||
861 | } | ||
862 | |||
863 | static struct tc_action_ops act_ife_ops = { | 852 | static struct tc_action_ops act_ife_ops = { |
864 | .kind = "ife", | 853 | .kind = "ife", |
865 | .type = TCA_ACT_IFE, | 854 | .type = TCA_ACT_IFE, |
@@ -870,7 +859,6 @@ static struct tc_action_ops act_ife_ops = { | |||
870 | .init = tcf_ife_init, | 859 | .init = tcf_ife_init, |
871 | .walk = tcf_ife_walker, | 860 | .walk = tcf_ife_walker, |
872 | .lookup = tcf_ife_search, | 861 | .lookup = tcf_ife_search, |
873 | .delete = tcf_ife_delete, | ||
874 | .size = sizeof(struct tcf_ife_info), | 862 | .size = sizeof(struct tcf_ife_info), |
875 | }; | 863 | }; |
876 | 864 | ||
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 51f235bbeb5b..23273b5303fd 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -337,13 +337,6 @@ static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index, | |||
337 | return tcf_idr_search(tn, a, index); | 337 | return tcf_idr_search(tn, a, index); |
338 | } | 338 | } |
339 | 339 | ||
340 | static int tcf_ipt_delete(struct net *net, u32 index) | ||
341 | { | ||
342 | struct tc_action_net *tn = net_generic(net, ipt_net_id); | ||
343 | |||
344 | return tcf_idr_delete_index(tn, index); | ||
345 | } | ||
346 | |||
347 | static struct tc_action_ops act_ipt_ops = { | 340 | static struct tc_action_ops act_ipt_ops = { |
348 | .kind = "ipt", | 341 | .kind = "ipt", |
349 | .type = TCA_ACT_IPT, | 342 | .type = TCA_ACT_IPT, |
@@ -354,7 +347,6 @@ static struct tc_action_ops act_ipt_ops = { | |||
354 | .init = tcf_ipt_init, | 347 | .init = tcf_ipt_init, |
355 | .walk = tcf_ipt_walker, | 348 | .walk = tcf_ipt_walker, |
356 | .lookup = tcf_ipt_search, | 349 | .lookup = tcf_ipt_search, |
357 | .delete = tcf_ipt_delete, | ||
358 | .size = sizeof(struct tcf_ipt), | 350 | .size = sizeof(struct tcf_ipt), |
359 | }; | 351 | }; |
360 | 352 | ||
@@ -395,13 +387,6 @@ static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index, | |||
395 | return tcf_idr_search(tn, a, index); | 387 | return tcf_idr_search(tn, a, index); |
396 | } | 388 | } |
397 | 389 | ||
398 | static int tcf_xt_delete(struct net *net, u32 index) | ||
399 | { | ||
400 | struct tc_action_net *tn = net_generic(net, xt_net_id); | ||
401 | |||
402 | return tcf_idr_delete_index(tn, index); | ||
403 | } | ||
404 | |||
405 | static struct tc_action_ops act_xt_ops = { | 390 | static struct tc_action_ops act_xt_ops = { |
406 | .kind = "xt", | 391 | .kind = "xt", |
407 | .type = TCA_ACT_XT, | 392 | .type = TCA_ACT_XT, |
@@ -412,7 +397,6 @@ static struct tc_action_ops act_xt_ops = { | |||
412 | .init = tcf_xt_init, | 397 | .init = tcf_xt_init, |
413 | .walk = tcf_xt_walker, | 398 | .walk = tcf_xt_walker, |
414 | .lookup = tcf_xt_search, | 399 | .lookup = tcf_xt_search, |
415 | .delete = tcf_xt_delete, | ||
416 | .size = sizeof(struct tcf_ipt), | 400 | .size = sizeof(struct tcf_ipt), |
417 | }; | 401 | }; |
418 | 402 | ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 38fd20f10f67..8bf66d0a6800 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -395,13 +395,6 @@ static void tcf_mirred_put_dev(struct net_device *dev) | |||
395 | dev_put(dev); | 395 | dev_put(dev); |
396 | } | 396 | } |
397 | 397 | ||
398 | static int tcf_mirred_delete(struct net *net, u32 index) | ||
399 | { | ||
400 | struct tc_action_net *tn = net_generic(net, mirred_net_id); | ||
401 | |||
402 | return tcf_idr_delete_index(tn, index); | ||
403 | } | ||
404 | |||
405 | static struct tc_action_ops act_mirred_ops = { | 398 | static struct tc_action_ops act_mirred_ops = { |
406 | .kind = "mirred", | 399 | .kind = "mirred", |
407 | .type = TCA_ACT_MIRRED, | 400 | .type = TCA_ACT_MIRRED, |
@@ -416,7 +409,6 @@ static struct tc_action_ops act_mirred_ops = { | |||
416 | .size = sizeof(struct tcf_mirred), | 409 | .size = sizeof(struct tcf_mirred), |
417 | .get_dev = tcf_mirred_get_dev, | 410 | .get_dev = tcf_mirred_get_dev, |
418 | .put_dev = tcf_mirred_put_dev, | 411 | .put_dev = tcf_mirred_put_dev, |
419 | .delete = tcf_mirred_delete, | ||
420 | }; | 412 | }; |
421 | 413 | ||
422 | static __net_init int mirred_init_net(struct net *net) | 414 | static __net_init int mirred_init_net(struct net *net) |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 822e903bfc25..4313aa102440 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
@@ -300,13 +300,6 @@ static int tcf_nat_search(struct net *net, struct tc_action **a, u32 index, | |||
300 | return tcf_idr_search(tn, a, index); | 300 | return tcf_idr_search(tn, a, index); |
301 | } | 301 | } |
302 | 302 | ||
303 | static int tcf_nat_delete(struct net *net, u32 index) | ||
304 | { | ||
305 | struct tc_action_net *tn = net_generic(net, nat_net_id); | ||
306 | |||
307 | return tcf_idr_delete_index(tn, index); | ||
308 | } | ||
309 | |||
310 | static struct tc_action_ops act_nat_ops = { | 303 | static struct tc_action_ops act_nat_ops = { |
311 | .kind = "nat", | 304 | .kind = "nat", |
312 | .type = TCA_ACT_NAT, | 305 | .type = TCA_ACT_NAT, |
@@ -316,7 +309,6 @@ static struct tc_action_ops act_nat_ops = { | |||
316 | .init = tcf_nat_init, | 309 | .init = tcf_nat_init, |
317 | .walk = tcf_nat_walker, | 310 | .walk = tcf_nat_walker, |
318 | .lookup = tcf_nat_search, | 311 | .lookup = tcf_nat_search, |
319 | .delete = tcf_nat_delete, | ||
320 | .size = sizeof(struct tcf_nat), | 312 | .size = sizeof(struct tcf_nat), |
321 | }; | 313 | }; |
322 | 314 | ||
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 8a7a7cb94e83..107034070019 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -460,13 +460,6 @@ static int tcf_pedit_search(struct net *net, struct tc_action **a, u32 index, | |||
460 | return tcf_idr_search(tn, a, index); | 460 | return tcf_idr_search(tn, a, index); |
461 | } | 461 | } |
462 | 462 | ||
463 | static int tcf_pedit_delete(struct net *net, u32 index) | ||
464 | { | ||
465 | struct tc_action_net *tn = net_generic(net, pedit_net_id); | ||
466 | |||
467 | return tcf_idr_delete_index(tn, index); | ||
468 | } | ||
469 | |||
470 | static struct tc_action_ops act_pedit_ops = { | 463 | static struct tc_action_ops act_pedit_ops = { |
471 | .kind = "pedit", | 464 | .kind = "pedit", |
472 | .type = TCA_ACT_PEDIT, | 465 | .type = TCA_ACT_PEDIT, |
@@ -477,7 +470,6 @@ static struct tc_action_ops act_pedit_ops = { | |||
477 | .init = tcf_pedit_init, | 470 | .init = tcf_pedit_init, |
478 | .walk = tcf_pedit_walker, | 471 | .walk = tcf_pedit_walker, |
479 | .lookup = tcf_pedit_search, | 472 | .lookup = tcf_pedit_search, |
480 | .delete = tcf_pedit_delete, | ||
481 | .size = sizeof(struct tcf_pedit), | 473 | .size = sizeof(struct tcf_pedit), |
482 | }; | 474 | }; |
483 | 475 | ||
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 06f0742db593..5d8bfa878477 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -320,13 +320,6 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index, | |||
320 | return tcf_idr_search(tn, a, index); | 320 | return tcf_idr_search(tn, a, index); |
321 | } | 321 | } |
322 | 322 | ||
323 | static int tcf_police_delete(struct net *net, u32 index) | ||
324 | { | ||
325 | struct tc_action_net *tn = net_generic(net, police_net_id); | ||
326 | |||
327 | return tcf_idr_delete_index(tn, index); | ||
328 | } | ||
329 | |||
330 | MODULE_AUTHOR("Alexey Kuznetsov"); | 323 | MODULE_AUTHOR("Alexey Kuznetsov"); |
331 | MODULE_DESCRIPTION("Policing actions"); | 324 | MODULE_DESCRIPTION("Policing actions"); |
332 | MODULE_LICENSE("GPL"); | 325 | MODULE_LICENSE("GPL"); |
@@ -340,7 +333,6 @@ static struct tc_action_ops act_police_ops = { | |||
340 | .init = tcf_police_init, | 333 | .init = tcf_police_init, |
341 | .walk = tcf_police_walker, | 334 | .walk = tcf_police_walker, |
342 | .lookup = tcf_police_search, | 335 | .lookup = tcf_police_search, |
343 | .delete = tcf_police_delete, | ||
344 | .size = sizeof(struct tcf_police), | 336 | .size = sizeof(struct tcf_police), |
345 | }; | 337 | }; |
346 | 338 | ||
diff --git a/net/sched/act_sample.c b/net/sched/act_sample.c index 207b4132d1b0..44e9c00657bc 100644 --- a/net/sched/act_sample.c +++ b/net/sched/act_sample.c | |||
@@ -232,13 +232,6 @@ static int tcf_sample_search(struct net *net, struct tc_action **a, u32 index, | |||
232 | return tcf_idr_search(tn, a, index); | 232 | return tcf_idr_search(tn, a, index); |
233 | } | 233 | } |
234 | 234 | ||
235 | static int tcf_sample_delete(struct net *net, u32 index) | ||
236 | { | ||
237 | struct tc_action_net *tn = net_generic(net, sample_net_id); | ||
238 | |||
239 | return tcf_idr_delete_index(tn, index); | ||
240 | } | ||
241 | |||
242 | static struct tc_action_ops act_sample_ops = { | 235 | static struct tc_action_ops act_sample_ops = { |
243 | .kind = "sample", | 236 | .kind = "sample", |
244 | .type = TCA_ACT_SAMPLE, | 237 | .type = TCA_ACT_SAMPLE, |
@@ -249,7 +242,6 @@ static struct tc_action_ops act_sample_ops = { | |||
249 | .cleanup = tcf_sample_cleanup, | 242 | .cleanup = tcf_sample_cleanup, |
250 | .walk = tcf_sample_walker, | 243 | .walk = tcf_sample_walker, |
251 | .lookup = tcf_sample_search, | 244 | .lookup = tcf_sample_search, |
252 | .delete = tcf_sample_delete, | ||
253 | .size = sizeof(struct tcf_sample), | 245 | .size = sizeof(struct tcf_sample), |
254 | }; | 246 | }; |
255 | 247 | ||
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index e616523ba3c1..52400d49f81f 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
@@ -196,13 +196,6 @@ static int tcf_simp_search(struct net *net, struct tc_action **a, u32 index, | |||
196 | return tcf_idr_search(tn, a, index); | 196 | return tcf_idr_search(tn, a, index); |
197 | } | 197 | } |
198 | 198 | ||
199 | static int tcf_simp_delete(struct net *net, u32 index) | ||
200 | { | ||
201 | struct tc_action_net *tn = net_generic(net, simp_net_id); | ||
202 | |||
203 | return tcf_idr_delete_index(tn, index); | ||
204 | } | ||
205 | |||
206 | static struct tc_action_ops act_simp_ops = { | 199 | static struct tc_action_ops act_simp_ops = { |
207 | .kind = "simple", | 200 | .kind = "simple", |
208 | .type = TCA_ACT_SIMP, | 201 | .type = TCA_ACT_SIMP, |
@@ -213,7 +206,6 @@ static struct tc_action_ops act_simp_ops = { | |||
213 | .init = tcf_simp_init, | 206 | .init = tcf_simp_init, |
214 | .walk = tcf_simp_walker, | 207 | .walk = tcf_simp_walker, |
215 | .lookup = tcf_simp_search, | 208 | .lookup = tcf_simp_search, |
216 | .delete = tcf_simp_delete, | ||
217 | .size = sizeof(struct tcf_defact), | 209 | .size = sizeof(struct tcf_defact), |
218 | }; | 210 | }; |
219 | 211 | ||
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 926d7bc4a89d..73e44ce2a883 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
@@ -299,13 +299,6 @@ static int tcf_skbedit_search(struct net *net, struct tc_action **a, u32 index, | |||
299 | return tcf_idr_search(tn, a, index); | 299 | return tcf_idr_search(tn, a, index); |
300 | } | 300 | } |
301 | 301 | ||
302 | static int tcf_skbedit_delete(struct net *net, u32 index) | ||
303 | { | ||
304 | struct tc_action_net *tn = net_generic(net, skbedit_net_id); | ||
305 | |||
306 | return tcf_idr_delete_index(tn, index); | ||
307 | } | ||
308 | |||
309 | static struct tc_action_ops act_skbedit_ops = { | 302 | static struct tc_action_ops act_skbedit_ops = { |
310 | .kind = "skbedit", | 303 | .kind = "skbedit", |
311 | .type = TCA_ACT_SKBEDIT, | 304 | .type = TCA_ACT_SKBEDIT, |
@@ -316,7 +309,6 @@ static struct tc_action_ops act_skbedit_ops = { | |||
316 | .cleanup = tcf_skbedit_cleanup, | 309 | .cleanup = tcf_skbedit_cleanup, |
317 | .walk = tcf_skbedit_walker, | 310 | .walk = tcf_skbedit_walker, |
318 | .lookup = tcf_skbedit_search, | 311 | .lookup = tcf_skbedit_search, |
319 | .delete = tcf_skbedit_delete, | ||
320 | .size = sizeof(struct tcf_skbedit), | 312 | .size = sizeof(struct tcf_skbedit), |
321 | }; | 313 | }; |
322 | 314 | ||
diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index d6a1af0c4171..588077fafd6c 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c | |||
@@ -259,13 +259,6 @@ static int tcf_skbmod_search(struct net *net, struct tc_action **a, u32 index, | |||
259 | return tcf_idr_search(tn, a, index); | 259 | return tcf_idr_search(tn, a, index); |
260 | } | 260 | } |
261 | 261 | ||
262 | static int tcf_skbmod_delete(struct net *net, u32 index) | ||
263 | { | ||
264 | struct tc_action_net *tn = net_generic(net, skbmod_net_id); | ||
265 | |||
266 | return tcf_idr_delete_index(tn, index); | ||
267 | } | ||
268 | |||
269 | static struct tc_action_ops act_skbmod_ops = { | 262 | static struct tc_action_ops act_skbmod_ops = { |
270 | .kind = "skbmod", | 263 | .kind = "skbmod", |
271 | .type = TCA_ACT_SKBMOD, | 264 | .type = TCA_ACT_SKBMOD, |
@@ -276,7 +269,6 @@ static struct tc_action_ops act_skbmod_ops = { | |||
276 | .cleanup = tcf_skbmod_cleanup, | 269 | .cleanup = tcf_skbmod_cleanup, |
277 | .walk = tcf_skbmod_walker, | 270 | .walk = tcf_skbmod_walker, |
278 | .lookup = tcf_skbmod_search, | 271 | .lookup = tcf_skbmod_search, |
279 | .delete = tcf_skbmod_delete, | ||
280 | .size = sizeof(struct tcf_skbmod), | 272 | .size = sizeof(struct tcf_skbmod), |
281 | }; | 273 | }; |
282 | 274 | ||
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index 8f09cf08d8fe..420759153d5f 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c | |||
@@ -548,13 +548,6 @@ static int tunnel_key_search(struct net *net, struct tc_action **a, u32 index, | |||
548 | return tcf_idr_search(tn, a, index); | 548 | return tcf_idr_search(tn, a, index); |
549 | } | 549 | } |
550 | 550 | ||
551 | static int tunnel_key_delete(struct net *net, u32 index) | ||
552 | { | ||
553 | struct tc_action_net *tn = net_generic(net, tunnel_key_net_id); | ||
554 | |||
555 | return tcf_idr_delete_index(tn, index); | ||
556 | } | ||
557 | |||
558 | static struct tc_action_ops act_tunnel_key_ops = { | 551 | static struct tc_action_ops act_tunnel_key_ops = { |
559 | .kind = "tunnel_key", | 552 | .kind = "tunnel_key", |
560 | .type = TCA_ACT_TUNNEL_KEY, | 553 | .type = TCA_ACT_TUNNEL_KEY, |
@@ -565,7 +558,6 @@ static struct tc_action_ops act_tunnel_key_ops = { | |||
565 | .cleanup = tunnel_key_release, | 558 | .cleanup = tunnel_key_release, |
566 | .walk = tunnel_key_walker, | 559 | .walk = tunnel_key_walker, |
567 | .lookup = tunnel_key_search, | 560 | .lookup = tunnel_key_search, |
568 | .delete = tunnel_key_delete, | ||
569 | .size = sizeof(struct tcf_tunnel_key), | 561 | .size = sizeof(struct tcf_tunnel_key), |
570 | }; | 562 | }; |
571 | 563 | ||
diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index 209e70ad2c09..033d273afe50 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c | |||
@@ -296,13 +296,6 @@ static int tcf_vlan_search(struct net *net, struct tc_action **a, u32 index, | |||
296 | return tcf_idr_search(tn, a, index); | 296 | return tcf_idr_search(tn, a, index); |
297 | } | 297 | } |
298 | 298 | ||
299 | static int tcf_vlan_delete(struct net *net, u32 index) | ||
300 | { | ||
301 | struct tc_action_net *tn = net_generic(net, vlan_net_id); | ||
302 | |||
303 | return tcf_idr_delete_index(tn, index); | ||
304 | } | ||
305 | |||
306 | static struct tc_action_ops act_vlan_ops = { | 299 | static struct tc_action_ops act_vlan_ops = { |
307 | .kind = "vlan", | 300 | .kind = "vlan", |
308 | .type = TCA_ACT_VLAN, | 301 | .type = TCA_ACT_VLAN, |
@@ -313,7 +306,6 @@ static struct tc_action_ops act_vlan_ops = { | |||
313 | .cleanup = tcf_vlan_cleanup, | 306 | .cleanup = tcf_vlan_cleanup, |
314 | .walk = tcf_vlan_walker, | 307 | .walk = tcf_vlan_walker, |
315 | .lookup = tcf_vlan_search, | 308 | .lookup = tcf_vlan_search, |
316 | .delete = tcf_vlan_delete, | ||
317 | .size = sizeof(struct tcf_vlan), | 309 | .size = sizeof(struct tcf_vlan), |
318 | }; | 310 | }; |
319 | 311 | ||