@@ -178,14 +178,11 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
178
178
return ERR_PTR (err );
179
179
}
180
180
181
- static bool tcf_proto_destroy (struct tcf_proto * tp , bool force )
181
+ static void tcf_proto_destroy (struct tcf_proto * tp )
182
182
{
183
- if (tp -> ops -> destroy (tp ,force )) {
184
- module_put (tp -> ops -> owner );
185
- kfree_rcu (tp ,rcu );
186
- return true;
187
- }
188
- return false;
183
+ tp -> ops -> destroy (tp );
184
+ module_put (tp -> ops -> owner );
185
+ kfree_rcu (tp ,rcu );
189
186
}
190
187
191
188
void tcf_destroy_chain (struct tcf_proto __rcu * * fl )
@@ -194,7 +191,7 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl)
194
191
195
192
while ((tp = rtnl_dereference (* fl ))!= NULL ) {
196
193
RCU_INIT_POINTER (* fl ,tp -> next );
197
- tcf_proto_destroy (tp , true );
194
+ tcf_proto_destroy (tp );
198
195
}
199
196
}
200
197
EXPORT_SYMBOL (tcf_destroy_chain );
@@ -361,7 +358,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
361
358
RCU_INIT_POINTER (* back ,next );
362
359
tfilter_notify (net ,skb ,n ,tp ,fh ,
363
360
RTM_DELTFILTER , false);
364
- tcf_proto_destroy (tp , true );
361
+ tcf_proto_destroy (tp );
365
362
err = 0 ;
366
363
gotoerrout ;
367
364
}
@@ -372,24 +369,28 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
372
369
gotoerrout ;
373
370
}
374
371
}else {
372
+ bool last ;
373
+
375
374
switch (n -> nlmsg_type ) {
376
375
case RTM_NEWTFILTER :
377
376
if (n -> nlmsg_flags & NLM_F_EXCL ) {
378
377
if (tp_created )
379
- tcf_proto_destroy (tp , true );
378
+ tcf_proto_destroy (tp );
380
379
err = - EEXIST ;
381
380
gotoerrout ;
382
381
}
383
382
break ;
384
383
case RTM_DELTFILTER :
385
- err = tp -> ops -> delete (tp ,fh );
384
+ err = tp -> ops -> delete (tp ,fh , & last );
386
385
if (err )
387
386
gotoerrout ;
388
387
next = rtnl_dereference (tp -> next );
389
388
tfilter_notify (net ,skb ,n ,tp ,t -> tcm_handle ,
390
389
RTM_DELTFILTER , false);
391
- if (tcf_proto_destroy ( tp , false))
390
+ if (last ) {
392
391
RCU_INIT_POINTER (* back ,next );
392
+ tcf_proto_destroy (tp );
393
+ }
393
394
gotoerrout ;
394
395
case RTM_GETTFILTER :
395
396
err = tfilter_notify (net ,skb ,n ,tp ,fh ,
@@ -411,7 +412,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
411
412
tfilter_notify (net ,skb ,n ,tp ,fh ,RTM_NEWTFILTER , false);
412
413
}else {
413
414
if (tp_created )
414
- tcf_proto_destroy (tp , true );
415
+ tcf_proto_destroy (tp );
415
416
}
416
417
417
418
errout :