diff options
| -rw-r--r-- | include/net/netns/xfrm.h | 1 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 18 |
2 files changed, 11 insertions, 8 deletions
diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 1ba912749caa..56f8e5585df7 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h | |||
| @@ -43,6 +43,7 @@ struct netns_xfrm { | |||
| 43 | struct work_struct policy_hash_work; | 43 | struct work_struct policy_hash_work; |
| 44 | 44 | ||
| 45 | struct sock *nlsk; | 45 | struct sock *nlsk; |
| 46 | struct sock *nlsk_stash; | ||
| 46 | 47 | ||
| 47 | u32 sysctl_aevent_etime; | 48 | u32 sysctl_aevent_etime; |
| 48 | u32 sysctl_aevent_rseqth; | 49 | u32 sysctl_aevent_rseqth; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index fb42d778d278..1ada6186933c 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -2721,22 +2721,24 @@ static int __net_init xfrm_user_net_init(struct net *net) | |||
| 2721 | xfrm_netlink_rcv, NULL, THIS_MODULE); | 2721 | xfrm_netlink_rcv, NULL, THIS_MODULE); |
| 2722 | if (nlsk == NULL) | 2722 | if (nlsk == NULL) |
| 2723 | return -ENOMEM; | 2723 | return -ENOMEM; |
| 2724 | net->xfrm.nlsk_stash = nlsk; /* Don't set to NULL */ | ||
| 2724 | rcu_assign_pointer(net->xfrm.nlsk, nlsk); | 2725 | rcu_assign_pointer(net->xfrm.nlsk, nlsk); |
| 2725 | return 0; | 2726 | return 0; |
| 2726 | } | 2727 | } |
| 2727 | 2728 | ||
| 2728 | static void __net_exit xfrm_user_net_exit(struct net *net) | 2729 | static void __net_exit xfrm_user_net_exit(struct list_head *net_exit_list) |
| 2729 | { | 2730 | { |
| 2730 | struct sock *nlsk = net->xfrm.nlsk; | 2731 | struct net *net; |
| 2731 | 2732 | list_for_each_entry(net, net_exit_list, exit_list) | |
| 2732 | rcu_assign_pointer(net->xfrm.nlsk, NULL); | 2733 | rcu_assign_pointer(net->xfrm.nlsk, NULL); |
| 2733 | synchronize_rcu(); | 2734 | synchronize_net(); |
| 2734 | netlink_kernel_release(nlsk); | 2735 | list_for_each_entry(net, net_exit_list, exit_list) |
| 2736 | netlink_kernel_release(net->xfrm.nlsk_stash); | ||
| 2735 | } | 2737 | } |
| 2736 | 2738 | ||
| 2737 | static struct pernet_operations xfrm_user_net_ops = { | 2739 | static struct pernet_operations xfrm_user_net_ops = { |
| 2738 | .init = xfrm_user_net_init, | 2740 | .init = xfrm_user_net_init, |
| 2739 | .exit = xfrm_user_net_exit, | 2741 | .exit_batch = xfrm_user_net_exit, |
| 2740 | }; | 2742 | }; |
| 2741 | 2743 | ||
| 2742 | static int __init xfrm_user_init(void) | 2744 | static int __init xfrm_user_init(void) |
