aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/cls_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/cls_route.c')
-rw-r--r--net/sched/cls_route.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index bb8a60235d01..08a3b0a6f5ab 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -277,13 +277,20 @@ route4_delete_filter(struct rcu_head *head)
277 kfree(f); 277 kfree(f);
278} 278}
279 279
280static void route4_destroy(struct tcf_proto *tp) 280static bool route4_destroy(struct tcf_proto *tp, bool force)
281{ 281{
282 struct route4_head *head = rtnl_dereference(tp->root); 282 struct route4_head *head = rtnl_dereference(tp->root);
283 int h1, h2; 283 int h1, h2;
284 284
285 if (head == NULL) 285 if (head == NULL)
286 return; 286 return true;
287
288 if (!force) {
289 for (h1 = 0; h1 <= 256; h1++) {
290 if (rcu_access_pointer(head->table[h1]))
291 return false;
292 }
293 }
287 294
288 for (h1 = 0; h1 <= 256; h1++) { 295 for (h1 = 0; h1 <= 256; h1++) {
289 struct route4_bucket *b; 296 struct route4_bucket *b;
@@ -308,6 +315,7 @@ static void route4_destroy(struct tcf_proto *tp)
308 } 315 }
309 RCU_INIT_POINTER(tp->root, NULL); 316 RCU_INIT_POINTER(tp->root, NULL);
310 kfree_rcu(head, rcu); 317 kfree_rcu(head, rcu);
318 return true;
311} 319}
312 320
313static int route4_delete(struct tcf_proto *tp, unsigned long arg) 321static int route4_delete(struct tcf_proto *tp, unsigned long arg)