summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h10
-rw-r--r--net/xfrm/xfrm_user.c15
2 files changed, 20 insertions, 5 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 786371365f2b..61b7504fc2ba 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1001,7 +1001,15 @@ static inline int xfrm_policy_id2dir(u32 index)
static inline int xfrm_aevent_is_on(void)
{
- return netlink_has_listeners(xfrm_nl,XFRMNLGRP_AEVENTS);
+ struct sock *nlsk;
+ int ret = 0;
+
+ rcu_read_lock();
+ nlsk = rcu_dereference(xfrm_nl);
+ if (nlsk)
+ ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
+ rcu_read_unlock();
+ return ret;
}
static inline void xfrm_aevent_doreplay(struct xfrm_state *x)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 4a7120a7e10f..81d1005830f4 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1947,12 +1947,15 @@ static struct xfrm_mgr netlink_mgr = {
static int __init xfrm_user_init(void)
{
+ struct sock *nlsk;
+
printk(KERN_INFO "Initializing IPsec netlink socket\n");
- xfrm_nl = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
- xfrm_netlink_rcv, THIS_MODULE);
- if (xfrm_nl == NULL)
+ nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
+ xfrm_netlink_rcv, THIS_MODULE);
+ if (nlsk == NULL)
return -ENOMEM;
+ rcu_assign_pointer(xfrm_nl, nlsk);
xfrm_register_km(&netlink_mgr);
@@ -1961,8 +1964,12 @@ static int __init xfrm_user_init(void)
static void __exit xfrm_user_exit(void)
{
+ struct sock *nlsk = xfrm_nl;
+
xfrm_unregister_km(&netlink_mgr);
- sock_release(xfrm_nl->sk_socket);
+ rcu_assign_pointer(xfrm_nl, NULL);
+ synchronize_rcu();
+ sock_release(nlsk->sk_socket);
}
module_init(xfrm_user_init);