diff options
Diffstat (limited to 'net/sched/cls_route.c')
-rw-r--r-- | net/sched/cls_route.c | 12 |
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 | ||
280 | static void route4_destroy(struct tcf_proto *tp) | 280 | static 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 | ||
313 | static int route4_delete(struct tcf_proto *tp, unsigned long arg) | 321 | static int route4_delete(struct tcf_proto *tp, unsigned long arg) |