diff options
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 42 |
1 files changed, 10 insertions, 32 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 1d5c7bf29938..c08fbd11ceff 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -39,8 +39,6 @@ | |||
| 39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) | 39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) |
| 40 | #define XFRM_MAX_QUEUE_LEN 100 | 40 | #define XFRM_MAX_QUEUE_LEN 100 |
| 41 | 41 | ||
| 42 | static struct dst_entry *xfrm_policy_sk_bundles; | ||
| 43 | |||
| 44 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); | 42 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); |
| 45 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] | 43 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] |
| 46 | __read_mostly; | 44 | __read_mostly; |
| @@ -661,7 +659,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
| 661 | hlist_add_head(&policy->bydst, chain); | 659 | hlist_add_head(&policy->bydst, chain); |
| 662 | xfrm_pol_hold(policy); | 660 | xfrm_pol_hold(policy); |
| 663 | net->xfrm.policy_count[dir]++; | 661 | net->xfrm.policy_count[dir]++; |
| 664 | atomic_inc(&flow_cache_genid); | 662 | atomic_inc(&net->xfrm.flow_cache_genid); |
| 665 | 663 | ||
| 666 | /* After previous checking, family can either be AF_INET or AF_INET6 */ | 664 | /* After previous checking, family can either be AF_INET or AF_INET6 */ |
| 667 | if (policy->family == AF_INET) | 665 | if (policy->family == AF_INET) |
| @@ -1844,7 +1842,7 @@ purge_queue: | |||
| 1844 | xfrm_pol_put(pol); | 1842 | xfrm_pol_put(pol); |
| 1845 | } | 1843 | } |
| 1846 | 1844 | ||
| 1847 | static int xdst_queue_output(struct sk_buff *skb) | 1845 | static int xdst_queue_output(struct sock *sk, struct sk_buff *skb) |
| 1848 | { | 1846 | { |
| 1849 | unsigned long sched_next; | 1847 | unsigned long sched_next; |
| 1850 | struct dst_entry *dst = skb_dst(skb); | 1848 | struct dst_entry *dst = skb_dst(skb); |
| @@ -2109,13 +2107,6 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
| 2109 | goto no_transform; | 2107 | goto no_transform; |
| 2110 | } | 2108 | } |
| 2111 | 2109 | ||
| 2112 | dst_hold(&xdst->u.dst); | ||
| 2113 | |||
| 2114 | spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); | ||
| 2115 | xdst->u.dst.next = xfrm_policy_sk_bundles; | ||
| 2116 | xfrm_policy_sk_bundles = &xdst->u.dst; | ||
| 2117 | spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); | ||
| 2118 | |||
| 2119 | route = xdst->route; | 2110 | route = xdst->route; |
| 2120 | } | 2111 | } |
| 2121 | } | 2112 | } |
| @@ -2549,33 +2540,15 @@ static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst) | |||
| 2549 | return dst; | 2540 | return dst; |
| 2550 | } | 2541 | } |
| 2551 | 2542 | ||
| 2552 | static void __xfrm_garbage_collect(struct net *net) | ||
| 2553 | { | ||
| 2554 | struct dst_entry *head, *next; | ||
| 2555 | |||
| 2556 | spin_lock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); | ||
| 2557 | head = xfrm_policy_sk_bundles; | ||
| 2558 | xfrm_policy_sk_bundles = NULL; | ||
| 2559 | spin_unlock_bh(&net->xfrm.xfrm_policy_sk_bundle_lock); | ||
| 2560 | |||
| 2561 | while (head) { | ||
| 2562 | next = head->next; | ||
| 2563 | dst_free(head); | ||
| 2564 | head = next; | ||
| 2565 | } | ||
| 2566 | } | ||
| 2567 | |||
| 2568 | void xfrm_garbage_collect(struct net *net) | 2543 | void xfrm_garbage_collect(struct net *net) |
| 2569 | { | 2544 | { |
| 2570 | flow_cache_flush(); | 2545 | flow_cache_flush(net); |
| 2571 | __xfrm_garbage_collect(net); | ||
| 2572 | } | 2546 | } |
| 2573 | EXPORT_SYMBOL(xfrm_garbage_collect); | 2547 | EXPORT_SYMBOL(xfrm_garbage_collect); |
| 2574 | 2548 | ||
| 2575 | static void xfrm_garbage_collect_deferred(struct net *net) | 2549 | static void xfrm_garbage_collect_deferred(struct net *net) |
| 2576 | { | 2550 | { |
| 2577 | flow_cache_flush_deferred(); | 2551 | flow_cache_flush_deferred(net); |
| 2578 | __xfrm_garbage_collect(net); | ||
| 2579 | } | 2552 | } |
| 2580 | 2553 | ||
| 2581 | static void xfrm_init_pmtu(struct dst_entry *dst) | 2554 | static void xfrm_init_pmtu(struct dst_entry *dst) |
| @@ -2940,15 +2913,19 @@ static int __net_init xfrm_net_init(struct net *net) | |||
| 2940 | rv = xfrm_sysctl_init(net); | 2913 | rv = xfrm_sysctl_init(net); |
| 2941 | if (rv < 0) | 2914 | if (rv < 0) |
| 2942 | goto out_sysctl; | 2915 | goto out_sysctl; |
| 2916 | rv = flow_cache_init(net); | ||
| 2917 | if (rv < 0) | ||
| 2918 | goto out; | ||
| 2943 | 2919 | ||
| 2944 | /* Initialize the per-net locks here */ | 2920 | /* Initialize the per-net locks here */ |
| 2945 | spin_lock_init(&net->xfrm.xfrm_state_lock); | 2921 | spin_lock_init(&net->xfrm.xfrm_state_lock); |
| 2946 | rwlock_init(&net->xfrm.xfrm_policy_lock); | 2922 | rwlock_init(&net->xfrm.xfrm_policy_lock); |
| 2947 | spin_lock_init(&net->xfrm.xfrm_policy_sk_bundle_lock); | ||
| 2948 | mutex_init(&net->xfrm.xfrm_cfg_mutex); | 2923 | mutex_init(&net->xfrm.xfrm_cfg_mutex); |
| 2949 | 2924 | ||
| 2950 | return 0; | 2925 | return 0; |
| 2951 | 2926 | ||
| 2927 | out: | ||
| 2928 | xfrm_sysctl_fini(net); | ||
| 2952 | out_sysctl: | 2929 | out_sysctl: |
| 2953 | xfrm_policy_fini(net); | 2930 | xfrm_policy_fini(net); |
| 2954 | out_policy: | 2931 | out_policy: |
| @@ -2961,6 +2938,7 @@ out_statistics: | |||
| 2961 | 2938 | ||
| 2962 | static void __net_exit xfrm_net_exit(struct net *net) | 2939 | static void __net_exit xfrm_net_exit(struct net *net) |
| 2963 | { | 2940 | { |
| 2941 | flow_cache_fini(net); | ||
| 2964 | xfrm_sysctl_fini(net); | 2942 | xfrm_sysctl_fini(net); |
| 2965 | xfrm_policy_fini(net); | 2943 | xfrm_policy_fini(net); |
| 2966 | xfrm_state_fini(net); | 2944 | xfrm_state_fini(net); |
