diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_api.c | 43 | ||||
-rw-r--r-- | net/sched/act_csum.c | 24 | ||||
-rw-r--r-- | net/sched/act_gact.c | 27 | ||||
-rw-r--r-- | net/sched/act_ipt.c | 39 | ||||
-rw-r--r-- | net/sched/act_mirred.c | 32 | ||||
-rw-r--r-- | net/sched/act_nat.c | 25 | ||||
-rw-r--r-- | net/sched/act_pedit.c | 25 | ||||
-rw-r--r-- | net/sched/act_police.c | 10 | ||||
-rw-r--r-- | net/sched/act_simple.c | 39 | ||||
-rw-r--r-- | net/sched/act_skbedit.c | 29 |
10 files changed, 112 insertions, 181 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 72bdc7166345..4f2b807b3621 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -27,8 +27,11 @@ | |||
27 | #include <net/act_api.h> | 27 | #include <net/act_api.h> |
28 | #include <net/netlink.h> | 28 | #include <net/netlink.h> |
29 | 29 | ||
30 | void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) | 30 | void tcf_hash_destroy(struct tc_action *a) |
31 | { | 31 | { |
32 | struct tcf_common *p = a->priv; | ||
33 | struct tcf_hashinfo *hinfo = a->ops->hinfo; | ||
34 | |||
32 | spin_lock_bh(&hinfo->lock); | 35 | spin_lock_bh(&hinfo->lock); |
33 | hlist_del(&p->tcfc_head); | 36 | hlist_del(&p->tcfc_head); |
34 | spin_unlock_bh(&hinfo->lock); | 37 | spin_unlock_bh(&hinfo->lock); |
@@ -42,9 +45,9 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) | |||
42 | } | 45 | } |
43 | EXPORT_SYMBOL(tcf_hash_destroy); | 46 | EXPORT_SYMBOL(tcf_hash_destroy); |
44 | 47 | ||
45 | int tcf_hash_release(struct tcf_common *p, int bind, | 48 | int tcf_hash_release(struct tc_action *a, int bind) |
46 | struct tcf_hashinfo *hinfo) | ||
47 | { | 49 | { |
50 | struct tcf_common *p = a->priv; | ||
48 | int ret = 0; | 51 | int ret = 0; |
49 | 52 | ||
50 | if (p) { | 53 | if (p) { |
@@ -53,7 +56,7 @@ int tcf_hash_release(struct tcf_common *p, int bind, | |||
53 | 56 | ||
54 | p->tcfc_refcnt--; | 57 | p->tcfc_refcnt--; |
55 | if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) { | 58 | if (p->tcfc_bindcnt <= 0 && p->tcfc_refcnt <= 0) { |
56 | tcf_hash_destroy(p, hinfo); | 59 | tcf_hash_destroy(a); |
57 | ret = 1; | 60 | ret = 1; |
58 | } | 61 | } |
59 | } | 62 | } |
@@ -127,7 +130,8 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a) | |||
127 | for (i = 0; i < (hinfo->hmask + 1); i++) { | 130 | for (i = 0; i < (hinfo->hmask + 1); i++) { |
128 | head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; | 131 | head = &hinfo->htab[tcf_hash(i, hinfo->hmask)]; |
129 | hlist_for_each_entry_safe(p, n, head, tcfc_head) { | 132 | hlist_for_each_entry_safe(p, n, head, tcfc_head) { |
130 | if (ACT_P_DELETED == tcf_hash_release(p, 0, hinfo)) { | 133 | a->priv = p; |
134 | if (ACT_P_DELETED == tcf_hash_release(a, 0)) { | ||
131 | module_put(a->ops->owner); | 135 | module_put(a->ops->owner); |
132 | n_i++; | 136 | n_i++; |
133 | } | 137 | } |
@@ -198,7 +202,7 @@ int tcf_hash_search(struct tc_action *a, u32 index) | |||
198 | } | 202 | } |
199 | EXPORT_SYMBOL(tcf_hash_search); | 203 | EXPORT_SYMBOL(tcf_hash_search); |
200 | 204 | ||
201 | struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind) | 205 | int tcf_hash_check(u32 index, struct tc_action *a, int bind) |
202 | { | 206 | { |
203 | struct tcf_hashinfo *hinfo = a->ops->hinfo; | 207 | struct tcf_hashinfo *hinfo = a->ops->hinfo; |
204 | struct tcf_common *p = NULL; | 208 | struct tcf_common *p = NULL; |
@@ -207,19 +211,30 @@ struct tcf_common *tcf_hash_check(u32 index, struct tc_action *a, int bind) | |||
207 | p->tcfc_bindcnt++; | 211 | p->tcfc_bindcnt++; |
208 | p->tcfc_refcnt++; | 212 | p->tcfc_refcnt++; |
209 | a->priv = p; | 213 | a->priv = p; |
214 | return 1; | ||
210 | } | 215 | } |
211 | return p; | 216 | return 0; |
212 | } | 217 | } |
213 | EXPORT_SYMBOL(tcf_hash_check); | 218 | EXPORT_SYMBOL(tcf_hash_check); |
214 | 219 | ||
215 | struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, | 220 | void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est) |
216 | struct tc_action *a, int size, int bind) | 221 | { |
222 | struct tcf_common *pc = a->priv; | ||
223 | if (est) | ||
224 | gen_kill_estimator(&pc->tcfc_bstats, | ||
225 | &pc->tcfc_rate_est); | ||
226 | kfree_rcu(pc, tcfc_rcu); | ||
227 | } | ||
228 | EXPORT_SYMBOL(tcf_hash_cleanup); | ||
229 | |||
230 | int tcf_hash_create(u32 index, struct nlattr *est, struct tc_action *a, | ||
231 | int size, int bind) | ||
217 | { | 232 | { |
218 | struct tcf_hashinfo *hinfo = a->ops->hinfo; | 233 | struct tcf_hashinfo *hinfo = a->ops->hinfo; |
219 | struct tcf_common *p = kzalloc(size, GFP_KERNEL); | 234 | struct tcf_common *p = kzalloc(size, GFP_KERNEL); |
220 | 235 | ||
221 | if (unlikely(!p)) | 236 | if (unlikely(!p)) |
222 | return ERR_PTR(-ENOMEM); | 237 | return -ENOMEM; |
223 | p->tcfc_refcnt = 1; | 238 | p->tcfc_refcnt = 1; |
224 | if (bind) | 239 | if (bind) |
225 | p->tcfc_bindcnt = 1; | 240 | p->tcfc_bindcnt = 1; |
@@ -234,17 +249,19 @@ struct tcf_common *tcf_hash_create(u32 index, struct nlattr *est, | |||
234 | &p->tcfc_lock, est); | 249 | &p->tcfc_lock, est); |
235 | if (err) { | 250 | if (err) { |
236 | kfree(p); | 251 | kfree(p); |
237 | return ERR_PTR(err); | 252 | return err; |
238 | } | 253 | } |
239 | } | 254 | } |
240 | 255 | ||
241 | a->priv = (void *) p; | 256 | a->priv = (void *) p; |
242 | return p; | 257 | return 0; |
243 | } | 258 | } |
244 | EXPORT_SYMBOL(tcf_hash_create); | 259 | EXPORT_SYMBOL(tcf_hash_create); |
245 | 260 | ||
246 | void tcf_hash_insert(struct tcf_common *p, struct tcf_hashinfo *hinfo) | 261 | void tcf_hash_insert(struct tc_action *a) |
247 | { | 262 | { |
263 | struct tcf_common *p = a->priv; | ||
264 | struct tcf_hashinfo *hinfo = a->ops->hinfo; | ||
248 | unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); | 265 | unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); |
249 | 266 | ||
250 | spin_lock_bh(&hinfo->lock); | 267 | spin_lock_bh(&hinfo->lock); |
diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 2210187c45c2..f0f6e7a625d1 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
@@ -48,7 +48,6 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, | |||
48 | { | 48 | { |
49 | struct nlattr *tb[TCA_CSUM_MAX + 1]; | 49 | struct nlattr *tb[TCA_CSUM_MAX + 1]; |
50 | struct tc_csum *parm; | 50 | struct tc_csum *parm; |
51 | struct tcf_common *pc; | ||
52 | struct tcf_csum *p; | 51 | struct tcf_csum *p; |
53 | int ret = 0, err; | 52 | int ret = 0, err; |
54 | 53 | ||
@@ -63,38 +62,31 @@ static int tcf_csum_init(struct net *n, struct nlattr *nla, struct nlattr *est, | |||
63 | return -EINVAL; | 62 | return -EINVAL; |
64 | parm = nla_data(tb[TCA_CSUM_PARMS]); | 63 | parm = nla_data(tb[TCA_CSUM_PARMS]); |
65 | 64 | ||
66 | pc = tcf_hash_check(parm->index, a, bind); | 65 | if (!tcf_hash_check(parm->index, a, bind)) { |
67 | if (!pc) { | 66 | ret = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); |
68 | pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); | 67 | if (ret) |
69 | if (IS_ERR(pc)) | 68 | return ret; |
70 | return PTR_ERR(pc); | ||
71 | ret = ACT_P_CREATED; | 69 | ret = ACT_P_CREATED; |
72 | } else { | 70 | } else { |
73 | if (bind)/* dont override defaults */ | 71 | if (bind)/* dont override defaults */ |
74 | return 0; | 72 | return 0; |
75 | tcf_hash_release(pc, bind, a->ops->hinfo); | 73 | tcf_hash_release(a, bind); |
76 | if (!ovr) | 74 | if (!ovr) |
77 | return -EEXIST; | 75 | return -EEXIST; |
78 | } | 76 | } |
79 | 77 | ||
80 | p = to_tcf_csum(pc); | 78 | p = to_tcf_csum(a); |
81 | spin_lock_bh(&p->tcf_lock); | 79 | spin_lock_bh(&p->tcf_lock); |
82 | p->tcf_action = parm->action; | 80 | p->tcf_action = parm->action; |
83 | p->update_flags = parm->update_flags; | 81 | p->update_flags = parm->update_flags; |
84 | spin_unlock_bh(&p->tcf_lock); | 82 | spin_unlock_bh(&p->tcf_lock); |
85 | 83 | ||
86 | if (ret == ACT_P_CREATED) | 84 | if (ret == ACT_P_CREATED) |
87 | tcf_hash_insert(pc, a->ops->hinfo); | 85 | tcf_hash_insert(a); |
88 | 86 | ||
89 | return ret; | 87 | return ret; |
90 | } | 88 | } |
91 | 89 | ||
92 | static int tcf_csum_cleanup(struct tc_action *a, int bind) | ||
93 | { | ||
94 | struct tcf_csum *p = a->priv; | ||
95 | return tcf_hash_release(&p->common, bind, &csum_hash_info); | ||
96 | } | ||
97 | |||
98 | /** | 90 | /** |
99 | * tcf_csum_skb_nextlayer - Get next layer pointer | 91 | * tcf_csum_skb_nextlayer - Get next layer pointer |
100 | * @skb: sk_buff to use | 92 | * @skb: sk_buff to use |
@@ -574,7 +566,7 @@ static struct tc_action_ops act_csum_ops = { | |||
574 | .owner = THIS_MODULE, | 566 | .owner = THIS_MODULE, |
575 | .act = tcf_csum, | 567 | .act = tcf_csum, |
576 | .dump = tcf_csum_dump, | 568 | .dump = tcf_csum_dump, |
577 | .cleanup = tcf_csum_cleanup, | 569 | .cleanup = tcf_hash_release, |
578 | .init = tcf_csum_init, | 570 | .init = tcf_csum_init, |
579 | }; | 571 | }; |
580 | 572 | ||
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index a0eed30d5811..af6c0acd9bf1 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
@@ -57,7 +57,6 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, | |||
57 | struct nlattr *tb[TCA_GACT_MAX + 1]; | 57 | struct nlattr *tb[TCA_GACT_MAX + 1]; |
58 | struct tc_gact *parm; | 58 | struct tc_gact *parm; |
59 | struct tcf_gact *gact; | 59 | struct tcf_gact *gact; |
60 | struct tcf_common *pc; | ||
61 | int ret = 0; | 60 | int ret = 0; |
62 | int err; | 61 | int err; |
63 | #ifdef CONFIG_GACT_PROB | 62 | #ifdef CONFIG_GACT_PROB |
@@ -86,21 +85,20 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, | |||
86 | } | 85 | } |
87 | #endif | 86 | #endif |
88 | 87 | ||
89 | pc = tcf_hash_check(parm->index, a, bind); | 88 | if (!tcf_hash_check(parm->index, a, bind)) { |
90 | if (!pc) { | 89 | ret = tcf_hash_create(parm->index, est, a, sizeof(*gact), bind); |
91 | pc = tcf_hash_create(parm->index, est, a, sizeof(*gact), bind); | 90 | if (ret) |
92 | if (IS_ERR(pc)) | 91 | return ret; |
93 | return PTR_ERR(pc); | ||
94 | ret = ACT_P_CREATED; | 92 | ret = ACT_P_CREATED; |
95 | } else { | 93 | } else { |
96 | if (bind)/* dont override defaults */ | 94 | if (bind)/* dont override defaults */ |
97 | return 0; | 95 | return 0; |
98 | tcf_hash_release(pc, bind, a->ops->hinfo); | 96 | tcf_hash_release(a, bind); |
99 | if (!ovr) | 97 | if (!ovr) |
100 | return -EEXIST; | 98 | return -EEXIST; |
101 | } | 99 | } |
102 | 100 | ||
103 | gact = to_gact(pc); | 101 | gact = to_gact(a); |
104 | 102 | ||
105 | spin_lock_bh(&gact->tcf_lock); | 103 | spin_lock_bh(&gact->tcf_lock); |
106 | gact->tcf_action = parm->action; | 104 | gact->tcf_action = parm->action; |
@@ -113,19 +111,10 @@ static int tcf_gact_init(struct net *net, struct nlattr *nla, | |||
113 | #endif | 111 | #endif |
114 | spin_unlock_bh(&gact->tcf_lock); | 112 | spin_unlock_bh(&gact->tcf_lock); |
115 | if (ret == ACT_P_CREATED) | 113 | if (ret == ACT_P_CREATED) |
116 | tcf_hash_insert(pc, a->ops->hinfo); | 114 | tcf_hash_insert(a); |
117 | return ret; | 115 | return ret; |
118 | } | 116 | } |
119 | 117 | ||
120 | static int tcf_gact_cleanup(struct tc_action *a, int bind) | ||
121 | { | ||
122 | struct tcf_gact *gact = a->priv; | ||
123 | |||
124 | if (gact) | ||
125 | return tcf_hash_release(&gact->common, bind, a->ops->hinfo); | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int tcf_gact(struct sk_buff *skb, const struct tc_action *a, | 118 | static int tcf_gact(struct sk_buff *skb, const struct tc_action *a, |
130 | struct tcf_result *res) | 119 | struct tcf_result *res) |
131 | { | 120 | { |
@@ -196,7 +185,7 @@ static struct tc_action_ops act_gact_ops = { | |||
196 | .owner = THIS_MODULE, | 185 | .owner = THIS_MODULE, |
197 | .act = tcf_gact, | 186 | .act = tcf_gact, |
198 | .dump = tcf_gact_dump, | 187 | .dump = tcf_gact_dump, |
199 | .cleanup = tcf_gact_cleanup, | 188 | .cleanup = tcf_hash_release, |
200 | .init = tcf_gact_init, | 189 | .init = tcf_gact_init, |
201 | }; | 190 | }; |
202 | 191 | ||
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 0a6d62174027..f5e69782d400 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -69,8 +69,9 @@ static void ipt_destroy_target(struct xt_entry_target *t) | |||
69 | module_put(par.target->me); | 69 | module_put(par.target->me); |
70 | } | 70 | } |
71 | 71 | ||
72 | static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) | 72 | static int tcf_ipt_release(struct tc_action *a, int bind) |
73 | { | 73 | { |
74 | struct tcf_ipt *ipt = to_ipt(a); | ||
74 | int ret = 0; | 75 | int ret = 0; |
75 | if (ipt) { | 76 | if (ipt) { |
76 | if (bind) | 77 | if (bind) |
@@ -80,7 +81,7 @@ static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) | |||
80 | ipt_destroy_target(ipt->tcfi_t); | 81 | ipt_destroy_target(ipt->tcfi_t); |
81 | kfree(ipt->tcfi_tname); | 82 | kfree(ipt->tcfi_tname); |
82 | kfree(ipt->tcfi_t); | 83 | kfree(ipt->tcfi_t); |
83 | tcf_hash_destroy(&ipt->common, &ipt_hash_info); | 84 | tcf_hash_destroy(a); |
84 | ret = ACT_P_DELETED; | 85 | ret = ACT_P_DELETED; |
85 | } | 86 | } |
86 | } | 87 | } |
@@ -99,7 +100,6 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
99 | { | 100 | { |
100 | struct nlattr *tb[TCA_IPT_MAX + 1]; | 101 | struct nlattr *tb[TCA_IPT_MAX + 1]; |
101 | struct tcf_ipt *ipt; | 102 | struct tcf_ipt *ipt; |
102 | struct tcf_common *pc; | ||
103 | struct xt_entry_target *td, *t; | 103 | struct xt_entry_target *td, *t; |
104 | char *tname; | 104 | char *tname; |
105 | int ret = 0, err; | 105 | int ret = 0, err; |
@@ -125,21 +125,20 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
125 | if (tb[TCA_IPT_INDEX] != NULL) | 125 | if (tb[TCA_IPT_INDEX] != NULL) |
126 | index = nla_get_u32(tb[TCA_IPT_INDEX]); | 126 | index = nla_get_u32(tb[TCA_IPT_INDEX]); |
127 | 127 | ||
128 | pc = tcf_hash_check(index, a, bind); | 128 | if (!tcf_hash_check(index, a, bind) ) { |
129 | if (!pc) { | 129 | ret = tcf_hash_create(index, est, a, sizeof(*ipt), bind); |
130 | pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind); | 130 | if (ret) |
131 | if (IS_ERR(pc)) | 131 | return ret; |
132 | return PTR_ERR(pc); | ||
133 | ret = ACT_P_CREATED; | 132 | ret = ACT_P_CREATED; |
134 | } else { | 133 | } else { |
135 | if (bind)/* dont override defaults */ | 134 | if (bind)/* dont override defaults */ |
136 | return 0; | 135 | return 0; |
137 | tcf_ipt_release(to_ipt(pc), bind); | 136 | tcf_ipt_release(a, bind); |
138 | 137 | ||
139 | if (!ovr) | 138 | if (!ovr) |
140 | return -EEXIST; | 139 | return -EEXIST; |
141 | } | 140 | } |
142 | ipt = to_ipt(pc); | 141 | ipt = to_ipt(a); |
143 | 142 | ||
144 | hook = nla_get_u32(tb[TCA_IPT_HOOK]); | 143 | hook = nla_get_u32(tb[TCA_IPT_HOOK]); |
145 | 144 | ||
@@ -170,7 +169,7 @@ static int tcf_ipt_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
170 | ipt->tcfi_hook = hook; | 169 | ipt->tcfi_hook = hook; |
171 | spin_unlock_bh(&ipt->tcf_lock); | 170 | spin_unlock_bh(&ipt->tcf_lock); |
172 | if (ret == ACT_P_CREATED) | 171 | if (ret == ACT_P_CREATED) |
173 | tcf_hash_insert(pc, a->ops->hinfo); | 172 | tcf_hash_insert(a); |
174 | return ret; | 173 | return ret; |
175 | 174 | ||
176 | err3: | 175 | err3: |
@@ -178,21 +177,11 @@ err3: | |||
178 | err2: | 177 | err2: |
179 | kfree(tname); | 178 | kfree(tname); |
180 | err1: | 179 | err1: |
181 | if (ret == ACT_P_CREATED) { | 180 | if (ret == ACT_P_CREATED) |
182 | if (est) | 181 | tcf_hash_cleanup(a, est); |
183 | gen_kill_estimator(&pc->tcfc_bstats, | ||
184 | &pc->tcfc_rate_est); | ||
185 | kfree_rcu(pc, tcfc_rcu); | ||
186 | } | ||
187 | return err; | 182 | return err; |
188 | } | 183 | } |
189 | 184 | ||
190 | static int tcf_ipt_cleanup(struct tc_action *a, int bind) | ||
191 | { | ||
192 | struct tcf_ipt *ipt = a->priv; | ||
193 | return tcf_ipt_release(ipt, bind); | ||
194 | } | ||
195 | |||
196 | static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a, | 185 | static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a, |
197 | struct tcf_result *res) | 186 | struct tcf_result *res) |
198 | { | 187 | { |
@@ -289,7 +278,7 @@ static struct tc_action_ops act_ipt_ops = { | |||
289 | .owner = THIS_MODULE, | 278 | .owner = THIS_MODULE, |
290 | .act = tcf_ipt, | 279 | .act = tcf_ipt, |
291 | .dump = tcf_ipt_dump, | 280 | .dump = tcf_ipt_dump, |
292 | .cleanup = tcf_ipt_cleanup, | 281 | .cleanup = tcf_ipt_release, |
293 | .init = tcf_ipt_init, | 282 | .init = tcf_ipt_init, |
294 | }; | 283 | }; |
295 | 284 | ||
@@ -300,7 +289,7 @@ static struct tc_action_ops act_xt_ops = { | |||
300 | .owner = THIS_MODULE, | 289 | .owner = THIS_MODULE, |
301 | .act = tcf_ipt, | 290 | .act = tcf_ipt, |
302 | .dump = tcf_ipt_dump, | 291 | .dump = tcf_ipt_dump, |
303 | .cleanup = tcf_ipt_cleanup, | 292 | .cleanup = tcf_ipt_release, |
304 | .init = tcf_ipt_init, | 293 | .init = tcf_ipt_init, |
305 | }; | 294 | }; |
306 | 295 | ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 0b2c6d39d396..3edeecafba2f 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -33,8 +33,9 @@ | |||
33 | static LIST_HEAD(mirred_list); | 33 | static LIST_HEAD(mirred_list); |
34 | static struct tcf_hashinfo mirred_hash_info; | 34 | static struct tcf_hashinfo mirred_hash_info; |
35 | 35 | ||
36 | static int tcf_mirred_release(struct tcf_mirred *m, int bind) | 36 | static int tcf_mirred_release(struct tc_action *a, int bind) |
37 | { | 37 | { |
38 | struct tcf_mirred *m = to_mirred(a); | ||
38 | if (m) { | 39 | if (m) { |
39 | if (bind) | 40 | if (bind) |
40 | m->tcf_bindcnt--; | 41 | m->tcf_bindcnt--; |
@@ -43,7 +44,7 @@ static int tcf_mirred_release(struct tcf_mirred *m, int bind) | |||
43 | list_del(&m->tcfm_list); | 44 | list_del(&m->tcfm_list); |
44 | if (m->tcfm_dev) | 45 | if (m->tcfm_dev) |
45 | dev_put(m->tcfm_dev); | 46 | dev_put(m->tcfm_dev); |
46 | tcf_hash_destroy(&m->common, &mirred_hash_info); | 47 | tcf_hash_destroy(a); |
47 | return 1; | 48 | return 1; |
48 | } | 49 | } |
49 | } | 50 | } |
@@ -61,7 +62,6 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
61 | struct nlattr *tb[TCA_MIRRED_MAX + 1]; | 62 | struct nlattr *tb[TCA_MIRRED_MAX + 1]; |
62 | struct tc_mirred *parm; | 63 | struct tc_mirred *parm; |
63 | struct tcf_mirred *m; | 64 | struct tcf_mirred *m; |
64 | struct tcf_common *pc; | ||
65 | struct net_device *dev; | 65 | struct net_device *dev; |
66 | int ret, ok_push = 0; | 66 | int ret, ok_push = 0; |
67 | 67 | ||
@@ -101,21 +101,20 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
101 | dev = NULL; | 101 | dev = NULL; |
102 | } | 102 | } |
103 | 103 | ||
104 | pc = tcf_hash_check(parm->index, a, bind); | 104 | if (!tcf_hash_check(parm->index, a, bind)) { |
105 | if (!pc) { | ||
106 | if (dev == NULL) | 105 | if (dev == NULL) |
107 | return -EINVAL; | 106 | return -EINVAL; |
108 | pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind); | 107 | ret = tcf_hash_create(parm->index, est, a, sizeof(*m), bind); |
109 | if (IS_ERR(pc)) | 108 | if (ret) |
110 | return PTR_ERR(pc); | 109 | return ret; |
111 | ret = ACT_P_CREATED; | 110 | ret = ACT_P_CREATED; |
112 | } else { | 111 | } else { |
113 | if (!ovr) { | 112 | if (!ovr) { |
114 | tcf_mirred_release(to_mirred(pc), bind); | 113 | tcf_mirred_release(a, bind); |
115 | return -EEXIST; | 114 | return -EEXIST; |
116 | } | 115 | } |
117 | } | 116 | } |
118 | m = to_mirred(pc); | 117 | m = to_mirred(a); |
119 | 118 | ||
120 | spin_lock_bh(&m->tcf_lock); | 119 | spin_lock_bh(&m->tcf_lock); |
121 | m->tcf_action = parm->action; | 120 | m->tcf_action = parm->action; |
@@ -131,21 +130,12 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, | |||
131 | spin_unlock_bh(&m->tcf_lock); | 130 | spin_unlock_bh(&m->tcf_lock); |
132 | if (ret == ACT_P_CREATED) { | 131 | if (ret == ACT_P_CREATED) { |
133 | list_add(&m->tcfm_list, &mirred_list); | 132 | list_add(&m->tcfm_list, &mirred_list); |
134 | tcf_hash_insert(pc, a->ops->hinfo); | 133 | tcf_hash_insert(a); |
135 | } | 134 | } |
136 | 135 | ||
137 | return ret; | 136 | return ret; |
138 | } | 137 | } |
139 | 138 | ||
140 | static int tcf_mirred_cleanup(struct tc_action *a, int bind) | ||
141 | { | ||
142 | struct tcf_mirred *m = a->priv; | ||
143 | |||
144 | if (m) | ||
145 | return tcf_mirred_release(m, bind); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | 139 | static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, |
150 | struct tcf_result *res) | 140 | struct tcf_result *res) |
151 | { | 141 | { |
@@ -259,7 +249,7 @@ static struct tc_action_ops act_mirred_ops = { | |||
259 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE, |
260 | .act = tcf_mirred, | 250 | .act = tcf_mirred, |
261 | .dump = tcf_mirred_dump, | 251 | .dump = tcf_mirred_dump, |
262 | .cleanup = tcf_mirred_cleanup, | 252 | .cleanup = tcf_mirred_release, |
263 | .init = tcf_mirred_init, | 253 | .init = tcf_mirred_init, |
264 | }; | 254 | }; |
265 | 255 | ||
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 81f0404bb335..ce9a3914ed4a 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
@@ -44,7 +44,6 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
44 | struct tc_nat *parm; | 44 | struct tc_nat *parm; |
45 | int ret = 0, err; | 45 | int ret = 0, err; |
46 | struct tcf_nat *p; | 46 | struct tcf_nat *p; |
47 | struct tcf_common *pc; | ||
48 | 47 | ||
49 | if (nla == NULL) | 48 | if (nla == NULL) |
50 | return -EINVAL; | 49 | return -EINVAL; |
@@ -57,20 +56,19 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
57 | return -EINVAL; | 56 | return -EINVAL; |
58 | parm = nla_data(tb[TCA_NAT_PARMS]); | 57 | parm = nla_data(tb[TCA_NAT_PARMS]); |
59 | 58 | ||
60 | pc = tcf_hash_check(parm->index, a, bind); | 59 | if (!tcf_hash_check(parm->index, a, bind)) { |
61 | if (!pc) { | 60 | ret = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); |
62 | pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); | 61 | if (ret) |
63 | if (IS_ERR(pc)) | 62 | return ret; |
64 | return PTR_ERR(pc); | ||
65 | ret = ACT_P_CREATED; | 63 | ret = ACT_P_CREATED; |
66 | } else { | 64 | } else { |
67 | if (bind) | 65 | if (bind) |
68 | return 0; | 66 | return 0; |
69 | tcf_hash_release(pc, bind, a->ops->hinfo); | 67 | tcf_hash_release(a, bind); |
70 | if (!ovr) | 68 | if (!ovr) |
71 | return -EEXIST; | 69 | return -EEXIST; |
72 | } | 70 | } |
73 | p = to_tcf_nat(pc); | 71 | p = to_tcf_nat(a); |
74 | 72 | ||
75 | spin_lock_bh(&p->tcf_lock); | 73 | spin_lock_bh(&p->tcf_lock); |
76 | p->old_addr = parm->old_addr; | 74 | p->old_addr = parm->old_addr; |
@@ -82,18 +80,11 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, | |||
82 | spin_unlock_bh(&p->tcf_lock); | 80 | spin_unlock_bh(&p->tcf_lock); |
83 | 81 | ||
84 | if (ret == ACT_P_CREATED) | 82 | if (ret == ACT_P_CREATED) |
85 | tcf_hash_insert(pc, a->ops->hinfo); | 83 | tcf_hash_insert(a); |
86 | 84 | ||
87 | return ret; | 85 | return ret; |
88 | } | 86 | } |
89 | 87 | ||
90 | static int tcf_nat_cleanup(struct tc_action *a, int bind) | ||
91 | { | ||
92 | struct tcf_nat *p = a->priv; | ||
93 | |||
94 | return tcf_hash_release(&p->common, bind, &nat_hash_info); | ||
95 | } | ||
96 | |||
97 | static int tcf_nat(struct sk_buff *skb, const struct tc_action *a, | 88 | static int tcf_nat(struct sk_buff *skb, const struct tc_action *a, |
98 | struct tcf_result *res) | 89 | struct tcf_result *res) |
99 | { | 90 | { |
@@ -298,7 +289,7 @@ static struct tc_action_ops act_nat_ops = { | |||
298 | .owner = THIS_MODULE, | 289 | .owner = THIS_MODULE, |
299 | .act = tcf_nat, | 290 | .act = tcf_nat, |
300 | .dump = tcf_nat_dump, | 291 | .dump = tcf_nat_dump, |
301 | .cleanup = tcf_nat_cleanup, | 292 | .cleanup = tcf_hash_release, |
302 | .init = tcf_nat_init, | 293 | .init = tcf_nat_init, |
303 | }; | 294 | }; |
304 | 295 | ||
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index be3f0f6875bb..091ced38a376 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -39,7 +39,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
39 | struct tc_pedit *parm; | 39 | struct tc_pedit *parm; |
40 | int ret = 0, err; | 40 | int ret = 0, err; |
41 | struct tcf_pedit *p; | 41 | struct tcf_pedit *p; |
42 | struct tcf_common *pc; | ||
43 | struct tc_pedit_key *keys = NULL; | 42 | struct tc_pedit_key *keys = NULL; |
44 | int ksize; | 43 | int ksize; |
45 | 44 | ||
@@ -57,26 +56,22 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
57 | if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize) | 56 | if (nla_len(tb[TCA_PEDIT_PARMS]) < sizeof(*parm) + ksize) |
58 | return -EINVAL; | 57 | return -EINVAL; |
59 | 58 | ||
60 | pc = tcf_hash_check(parm->index, a, bind); | 59 | if (!tcf_hash_check(parm->index, a, bind)) { |
61 | if (!pc) { | ||
62 | if (!parm->nkeys) | 60 | if (!parm->nkeys) |
63 | return -EINVAL; | 61 | return -EINVAL; |
64 | pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); | 62 | ret = tcf_hash_create(parm->index, est, a, sizeof(*p), bind); |
65 | if (IS_ERR(pc)) | 63 | if (ret) |
66 | return PTR_ERR(pc); | 64 | return ret; |
67 | p = to_pedit(pc); | 65 | p = to_pedit(a); |
68 | keys = kmalloc(ksize, GFP_KERNEL); | 66 | keys = kmalloc(ksize, GFP_KERNEL); |
69 | if (keys == NULL) { | 67 | if (keys == NULL) { |
70 | if (est) | 68 | tcf_hash_cleanup(a, est); |
71 | gen_kill_estimator(&pc->tcfc_bstats, | ||
72 | &pc->tcfc_rate_est); | ||
73 | kfree_rcu(pc, tcfc_rcu); | ||
74 | return -ENOMEM; | 69 | return -ENOMEM; |
75 | } | 70 | } |
76 | ret = ACT_P_CREATED; | 71 | ret = ACT_P_CREATED; |
77 | } else { | 72 | } else { |
78 | p = to_pedit(pc); | 73 | p = to_pedit(a); |
79 | tcf_hash_release(pc, bind, a->ops->hinfo); | 74 | tcf_hash_release(a, bind); |
80 | if (bind) | 75 | if (bind) |
81 | return 0; | 76 | return 0; |
82 | if (!ovr) | 77 | if (!ovr) |
@@ -100,7 +95,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, | |||
100 | memcpy(p->tcfp_keys, parm->keys, ksize); | 95 | memcpy(p->tcfp_keys, parm->keys, ksize); |
101 | spin_unlock_bh(&p->tcf_lock); | 96 | spin_unlock_bh(&p->tcf_lock); |
102 | if (ret == ACT_P_CREATED) | 97 | if (ret == ACT_P_CREATED) |
103 | tcf_hash_insert(pc, a->ops->hinfo); | 98 | tcf_hash_insert(a); |
104 | return ret; | 99 | return ret; |
105 | } | 100 | } |
106 | 101 | ||
@@ -110,7 +105,7 @@ static int tcf_pedit_cleanup(struct tc_action *a, int bind) | |||
110 | 105 | ||
111 | if (p) { | 106 | if (p) { |
112 | struct tc_pedit_key *keys = p->tcfp_keys; | 107 | struct tc_pedit_key *keys = p->tcfp_keys; |
113 | if (tcf_hash_release(&p->common, bind, &pedit_hash_info)) { | 108 | if (tcf_hash_release(a, bind)) { |
114 | kfree(keys); | 109 | kfree(keys); |
115 | return 1; | 110 | return 1; |
116 | } | 111 | } |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 1778209a332f..4695d02bd249 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -253,14 +253,6 @@ failure: | |||
253 | return err; | 253 | return err; |
254 | } | 254 | } |
255 | 255 | ||
256 | static int tcf_act_police_cleanup(struct tc_action *a, int bind) | ||
257 | { | ||
258 | struct tcf_police *p = a->priv; | ||
259 | if (p) | ||
260 | return tcf_hash_release(&p->common, bind, &police_hash_info); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a, | 256 | static int tcf_act_police(struct sk_buff *skb, const struct tc_action *a, |
265 | struct tcf_result *res) | 257 | struct tcf_result *res) |
266 | { | 258 | { |
@@ -362,7 +354,7 @@ static struct tc_action_ops act_police_ops = { | |||
362 | .owner = THIS_MODULE, | 354 | .owner = THIS_MODULE, |
363 | .act = tcf_act_police, | 355 | .act = tcf_act_police, |
364 | .dump = tcf_act_police_dump, | 356 | .dump = tcf_act_police_dump, |
365 | .cleanup = tcf_act_police_cleanup, | 357 | .cleanup = tcf_hash_release, |
366 | .init = tcf_act_police_locate, | 358 | .init = tcf_act_police_locate, |
367 | .walk = tcf_act_police_walker | 359 | .walk = tcf_act_police_walker |
368 | }; | 360 | }; |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 8ef2f1fcbfba..11c2922bb900 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
@@ -47,8 +47,9 @@ static int tcf_simp(struct sk_buff *skb, const struct tc_action *a, | |||
47 | return d->tcf_action; | 47 | return d->tcf_action; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int tcf_simp_release(struct tcf_defact *d, int bind) | 50 | static int tcf_simp_release(struct tc_action *a, int bind) |
51 | { | 51 | { |
52 | struct tcf_defact *d = to_defact(a); | ||
52 | int ret = 0; | 53 | int ret = 0; |
53 | if (d) { | 54 | if (d) { |
54 | if (bind) | 55 | if (bind) |
@@ -56,7 +57,7 @@ static int tcf_simp_release(struct tcf_defact *d, int bind) | |||
56 | d->tcf_refcnt--; | 57 | d->tcf_refcnt--; |
57 | if (d->tcf_bindcnt <= 0 && d->tcf_refcnt <= 0) { | 58 | if (d->tcf_bindcnt <= 0 && d->tcf_refcnt <= 0) { |
58 | kfree(d->tcfd_defdata); | 59 | kfree(d->tcfd_defdata); |
59 | tcf_hash_destroy(&d->common, &simp_hash_info); | 60 | tcf_hash_destroy(a); |
60 | ret = 1; | 61 | ret = 1; |
61 | } | 62 | } |
62 | } | 63 | } |
@@ -94,7 +95,6 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
94 | struct nlattr *tb[TCA_DEF_MAX + 1]; | 95 | struct nlattr *tb[TCA_DEF_MAX + 1]; |
95 | struct tc_defact *parm; | 96 | struct tc_defact *parm; |
96 | struct tcf_defact *d; | 97 | struct tcf_defact *d; |
97 | struct tcf_common *pc; | ||
98 | char *defdata; | 98 | char *defdata; |
99 | int ret = 0, err; | 99 | int ret = 0, err; |
100 | 100 | ||
@@ -114,29 +114,25 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
114 | parm = nla_data(tb[TCA_DEF_PARMS]); | 114 | parm = nla_data(tb[TCA_DEF_PARMS]); |
115 | defdata = nla_data(tb[TCA_DEF_DATA]); | 115 | defdata = nla_data(tb[TCA_DEF_DATA]); |
116 | 116 | ||
117 | pc = tcf_hash_check(parm->index, a, bind); | 117 | if (!tcf_hash_check(parm->index, a, bind)) { |
118 | if (!pc) { | 118 | ret = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); |
119 | pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); | 119 | if (ret) |
120 | if (IS_ERR(pc)) | 120 | return ret; |
121 | return PTR_ERR(pc); | ||
122 | 121 | ||
123 | d = to_defact(pc); | 122 | d = to_defact(a); |
124 | ret = alloc_defdata(d, defdata); | 123 | ret = alloc_defdata(d, defdata); |
125 | if (ret < 0) { | 124 | if (ret < 0) { |
126 | if (est) | 125 | tcf_hash_cleanup(a, est); |
127 | gen_kill_estimator(&pc->tcfc_bstats, | ||
128 | &pc->tcfc_rate_est); | ||
129 | kfree_rcu(pc, tcfc_rcu); | ||
130 | return ret; | 126 | return ret; |
131 | } | 127 | } |
132 | d->tcf_action = parm->action; | 128 | d->tcf_action = parm->action; |
133 | ret = ACT_P_CREATED; | 129 | ret = ACT_P_CREATED; |
134 | } else { | 130 | } else { |
135 | d = to_defact(pc); | 131 | d = to_defact(a); |
136 | 132 | ||
137 | if (bind) | 133 | if (bind) |
138 | return 0; | 134 | return 0; |
139 | tcf_simp_release(d, bind); | 135 | tcf_simp_release(a, bind); |
140 | if (!ovr) | 136 | if (!ovr) |
141 | return -EEXIST; | 137 | return -EEXIST; |
142 | 138 | ||
@@ -144,19 +140,10 @@ static int tcf_simp_init(struct net *net, struct nlattr *nla, | |||
144 | } | 140 | } |
145 | 141 | ||
146 | if (ret == ACT_P_CREATED) | 142 | if (ret == ACT_P_CREATED) |
147 | tcf_hash_insert(pc, a->ops->hinfo); | 143 | tcf_hash_insert(a); |
148 | return ret; | 144 | return ret; |
149 | } | 145 | } |
150 | 146 | ||
151 | static int tcf_simp_cleanup(struct tc_action *a, int bind) | ||
152 | { | ||
153 | struct tcf_defact *d = a->priv; | ||
154 | |||
155 | if (d) | ||
156 | return tcf_simp_release(d, bind); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, | 147 | static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, |
161 | int bind, int ref) | 148 | int bind, int ref) |
162 | { | 149 | { |
@@ -192,7 +179,7 @@ static struct tc_action_ops act_simp_ops = { | |||
192 | .owner = THIS_MODULE, | 179 | .owner = THIS_MODULE, |
193 | .act = tcf_simp, | 180 | .act = tcf_simp, |
194 | .dump = tcf_simp_dump, | 181 | .dump = tcf_simp_dump, |
195 | .cleanup = tcf_simp_cleanup, | 182 | .cleanup = tcf_simp_release, |
196 | .init = tcf_simp_init, | 183 | .init = tcf_simp_init, |
197 | }; | 184 | }; |
198 | 185 | ||
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 98725080b5aa..71fd2d499109 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
@@ -65,7 +65,6 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
65 | struct nlattr *tb[TCA_SKBEDIT_MAX + 1]; | 65 | struct nlattr *tb[TCA_SKBEDIT_MAX + 1]; |
66 | struct tc_skbedit *parm; | 66 | struct tc_skbedit *parm; |
67 | struct tcf_skbedit *d; | 67 | struct tcf_skbedit *d; |
68 | struct tcf_common *pc; | ||
69 | u32 flags = 0, *priority = NULL, *mark = NULL; | 68 | u32 flags = 0, *priority = NULL, *mark = NULL; |
70 | u16 *queue_mapping = NULL; | 69 | u16 *queue_mapping = NULL; |
71 | int ret = 0, err; | 70 | int ret = 0, err; |
@@ -100,19 +99,18 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
100 | 99 | ||
101 | parm = nla_data(tb[TCA_SKBEDIT_PARMS]); | 100 | parm = nla_data(tb[TCA_SKBEDIT_PARMS]); |
102 | 101 | ||
103 | pc = tcf_hash_check(parm->index, a, bind); | 102 | if (!tcf_hash_check(parm->index, a, bind)) { |
104 | if (!pc) { | 103 | ret = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); |
105 | pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind); | 104 | if (ret) |
106 | if (IS_ERR(pc)) | 105 | return ret; |
107 | return PTR_ERR(pc); | ||
108 | 106 | ||
109 | d = to_skbedit(pc); | 107 | d = to_skbedit(a); |
110 | ret = ACT_P_CREATED; | 108 | ret = ACT_P_CREATED; |
111 | } else { | 109 | } else { |
112 | d = to_skbedit(pc); | 110 | d = to_skbedit(a); |
113 | if (bind) | 111 | if (bind) |
114 | return 0; | 112 | return 0; |
115 | tcf_hash_release(pc, bind, a->ops->hinfo); | 113 | tcf_hash_release(a, bind); |
116 | if (!ovr) | 114 | if (!ovr) |
117 | return -EEXIST; | 115 | return -EEXIST; |
118 | } | 116 | } |
@@ -132,19 +130,10 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
132 | spin_unlock_bh(&d->tcf_lock); | 130 | spin_unlock_bh(&d->tcf_lock); |
133 | 131 | ||
134 | if (ret == ACT_P_CREATED) | 132 | if (ret == ACT_P_CREATED) |
135 | tcf_hash_insert(pc, a->ops->hinfo); | 133 | tcf_hash_insert(a); |
136 | return ret; | 134 | return ret; |
137 | } | 135 | } |
138 | 136 | ||
139 | static int tcf_skbedit_cleanup(struct tc_action *a, int bind) | ||
140 | { | ||
141 | struct tcf_skbedit *d = a->priv; | ||
142 | |||
143 | if (d) | ||
144 | return tcf_hash_release(&d->common, bind, &skbedit_hash_info); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a, | 137 | static int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a, |
149 | int bind, int ref) | 138 | int bind, int ref) |
150 | { | 139 | { |
@@ -191,7 +180,7 @@ static struct tc_action_ops act_skbedit_ops = { | |||
191 | .owner = THIS_MODULE, | 180 | .owner = THIS_MODULE, |
192 | .act = tcf_skbedit, | 181 | .act = tcf_skbedit, |
193 | .dump = tcf_skbedit_dump, | 182 | .dump = tcf_skbedit_dump, |
194 | .cleanup = tcf_skbedit_cleanup, | 183 | .cleanup = tcf_hash_release, |
195 | .init = tcf_skbedit_init, | 184 | .init = tcf_skbedit_init, |
196 | }; | 185 | }; |
197 | 186 | ||