diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 54a4be6a7d26..d19e274b9c4a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -346,6 +346,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
346 | struct xfrm_policy *pol, **p; | 346 | struct xfrm_policy *pol, **p; |
347 | struct xfrm_policy *delpol = NULL; | 347 | struct xfrm_policy *delpol = NULL; |
348 | struct xfrm_policy **newpos = NULL; | 348 | struct xfrm_policy **newpos = NULL; |
349 | struct dst_entry *gc_list; | ||
349 | 350 | ||
350 | write_lock_bh(&xfrm_policy_lock); | 351 | write_lock_bh(&xfrm_policy_lock); |
351 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { | 352 | for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) { |
@@ -381,9 +382,36 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
381 | xfrm_pol_hold(policy); | 382 | xfrm_pol_hold(policy); |
382 | write_unlock_bh(&xfrm_policy_lock); | 383 | write_unlock_bh(&xfrm_policy_lock); |
383 | 384 | ||
384 | if (delpol) { | 385 | if (delpol) |
385 | xfrm_policy_kill(delpol); | 386 | xfrm_policy_kill(delpol); |
387 | |||
388 | read_lock_bh(&xfrm_policy_lock); | ||
389 | gc_list = NULL; | ||
390 | for (policy = policy->next; policy; policy = policy->next) { | ||
391 | struct dst_entry *dst; | ||
392 | |||
393 | write_lock(&policy->lock); | ||
394 | dst = policy->bundles; | ||
395 | if (dst) { | ||
396 | struct dst_entry *tail = dst; | ||
397 | while (tail->next) | ||
398 | tail = tail->next; | ||
399 | tail->next = gc_list; | ||
400 | gc_list = dst; | ||
401 | |||
402 | policy->bundles = NULL; | ||
403 | } | ||
404 | write_unlock(&policy->lock); | ||
386 | } | 405 | } |
406 | read_unlock_bh(&xfrm_policy_lock); | ||
407 | |||
408 | while (gc_list) { | ||
409 | struct dst_entry *dst = gc_list; | ||
410 | |||
411 | gc_list = dst->next; | ||
412 | dst_free(dst); | ||
413 | } | ||
414 | |||
387 | return 0; | 415 | return 0; |
388 | } | 416 | } |
389 | EXPORT_SYMBOL(xfrm_policy_insert); | 417 | EXPORT_SYMBOL(xfrm_policy_insert); |