diff options
-rw-r--r-- | include/net/inet_common.h | 2 | ||||
-rw-r--r-- | include/net/sock.h | 2 | ||||
-rw-r--r-- | net/core/sock.c | 8 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 4 | ||||
-rw-r--r-- | net/ipv4/udp_tunnel.c | 8 | ||||
-rw-r--r-- | net/ipv6/ip6_udp_tunnel.c | 6 | ||||
-rw-r--r-- | net/l2tp/l2tp_core.c | 15 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sync.c | 30 |
8 files changed, 30 insertions, 45 deletions
diff --git a/include/net/inet_common.h b/include/net/inet_common.h index 4a92423eefa5..279f83591971 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h | |||
@@ -41,7 +41,7 @@ int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, | |||
41 | 41 | ||
42 | static inline void inet_ctl_sock_destroy(struct sock *sk) | 42 | static inline void inet_ctl_sock_destroy(struct sock *sk) |
43 | { | 43 | { |
44 | sk_release_kernel(sk); | 44 | sock_release(sk->sk_socket); |
45 | } | 45 | } |
46 | 46 | ||
47 | #endif | 47 | #endif |
diff --git a/include/net/sock.h b/include/net/sock.h index d8dcf91732b0..9e6b2c0b4741 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -184,6 +184,7 @@ struct sock_common { | |||
184 | unsigned char skc_reuse:4; | 184 | unsigned char skc_reuse:4; |
185 | unsigned char skc_reuseport:1; | 185 | unsigned char skc_reuseport:1; |
186 | unsigned char skc_ipv6only:1; | 186 | unsigned char skc_ipv6only:1; |
187 | unsigned char skc_net_refcnt:1; | ||
187 | int skc_bound_dev_if; | 188 | int skc_bound_dev_if; |
188 | union { | 189 | union { |
189 | struct hlist_node skc_bind_node; | 190 | struct hlist_node skc_bind_node; |
@@ -323,6 +324,7 @@ struct sock { | |||
323 | #define sk_reuse __sk_common.skc_reuse | 324 | #define sk_reuse __sk_common.skc_reuse |
324 | #define sk_reuseport __sk_common.skc_reuseport | 325 | #define sk_reuseport __sk_common.skc_reuseport |
325 | #define sk_ipv6only __sk_common.skc_ipv6only | 326 | #define sk_ipv6only __sk_common.skc_ipv6only |
327 | #define sk_net_refcnt __sk_common.skc_net_refcnt | ||
326 | #define sk_bound_dev_if __sk_common.skc_bound_dev_if | 328 | #define sk_bound_dev_if __sk_common.skc_bound_dev_if |
327 | #define sk_bind_node __sk_common.skc_bind_node | 329 | #define sk_bind_node __sk_common.skc_bind_node |
328 | #define sk_prot __sk_common.skc_prot | 330 | #define sk_prot __sk_common.skc_prot |
diff --git a/net/core/sock.c b/net/core/sock.c index cbc3789b830c..9e8968e9ebeb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1412,7 +1412,10 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
1412 | */ | 1412 | */ |
1413 | sk->sk_prot = sk->sk_prot_creator = prot; | 1413 | sk->sk_prot = sk->sk_prot_creator = prot; |
1414 | sock_lock_init(sk); | 1414 | sock_lock_init(sk); |
1415 | sock_net_set(sk, get_net(net)); | 1415 | sk->sk_net_refcnt = kern ? 0 : 1; |
1416 | if (likely(sk->sk_net_refcnt)) | ||
1417 | get_net(net); | ||
1418 | sock_net_set(sk, net); | ||
1416 | atomic_set(&sk->sk_wmem_alloc, 1); | 1419 | atomic_set(&sk->sk_wmem_alloc, 1); |
1417 | 1420 | ||
1418 | sock_update_classid(sk); | 1421 | sock_update_classid(sk); |
@@ -1446,7 +1449,8 @@ static void __sk_free(struct sock *sk) | |||
1446 | if (sk->sk_peer_cred) | 1449 | if (sk->sk_peer_cred) |
1447 | put_cred(sk->sk_peer_cred); | 1450 | put_cred(sk->sk_peer_cred); |
1448 | put_pid(sk->sk_peer_pid); | 1451 | put_pid(sk->sk_peer_pid); |
1449 | put_net(sock_net(sk)); | 1452 | if (likely(sk->sk_net_refcnt)) |
1453 | put_net(sock_net(sk)); | ||
1450 | sk_prot_free(sk->sk_prot_creator, sk); | 1454 | sk_prot_free(sk->sk_prot_creator, sk); |
1451 | } | 1455 | } |
1452 | 1456 | ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index e2dd9cb99d61..235d36afece3 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1430,7 +1430,7 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family, | |||
1430 | struct net *net) | 1430 | struct net *net) |
1431 | { | 1431 | { |
1432 | struct socket *sock; | 1432 | struct socket *sock; |
1433 | int rc = sock_create_kern(&init_net, family, type, protocol, &sock); | 1433 | int rc = sock_create_kern(net, family, type, protocol, &sock); |
1434 | 1434 | ||
1435 | if (rc == 0) { | 1435 | if (rc == 0) { |
1436 | *sk = sock->sk; | 1436 | *sk = sock->sk; |
@@ -1440,8 +1440,6 @@ int inet_ctl_sock_create(struct sock **sk, unsigned short family, | |||
1440 | * we do not wish this socket to see incoming packets. | 1440 | * we do not wish this socket to see incoming packets. |
1441 | */ | 1441 | */ |
1442 | (*sk)->sk_prot->unhash(*sk); | 1442 | (*sk)->sk_prot->unhash(*sk); |
1443 | |||
1444 | sk_change_net(*sk, net); | ||
1445 | } | 1443 | } |
1446 | return rc; | 1444 | return rc; |
1447 | } | 1445 | } |
diff --git a/net/ipv4/udp_tunnel.c b/net/ipv4/udp_tunnel.c index 4e2837476967..933ea903f7b8 100644 --- a/net/ipv4/udp_tunnel.c +++ b/net/ipv4/udp_tunnel.c | |||
@@ -15,12 +15,10 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg, | |||
15 | struct socket *sock = NULL; | 15 | struct socket *sock = NULL; |
16 | struct sockaddr_in udp_addr; | 16 | struct sockaddr_in udp_addr; |
17 | 17 | ||
18 | err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &sock); | 18 | err = sock_create_kern(net, AF_INET, SOCK_DGRAM, 0, &sock); |
19 | if (err < 0) | 19 | if (err < 0) |
20 | goto error; | 20 | goto error; |
21 | 21 | ||
22 | sk_change_net(sock->sk, net); | ||
23 | |||
24 | udp_addr.sin_family = AF_INET; | 22 | udp_addr.sin_family = AF_INET; |
25 | udp_addr.sin_addr = cfg->local_ip; | 23 | udp_addr.sin_addr = cfg->local_ip; |
26 | udp_addr.sin_port = cfg->local_udp_port; | 24 | udp_addr.sin_port = cfg->local_udp_port; |
@@ -47,7 +45,7 @@ int udp_sock_create4(struct net *net, struct udp_port_cfg *cfg, | |||
47 | error: | 45 | error: |
48 | if (sock) { | 46 | if (sock) { |
49 | kernel_sock_shutdown(sock, SHUT_RDWR); | 47 | kernel_sock_shutdown(sock, SHUT_RDWR); |
50 | sk_release_kernel(sock->sk); | 48 | sock_release(sock); |
51 | } | 49 | } |
52 | *sockp = NULL; | 50 | *sockp = NULL; |
53 | return err; | 51 | return err; |
@@ -101,7 +99,7 @@ void udp_tunnel_sock_release(struct socket *sock) | |||
101 | { | 99 | { |
102 | rcu_assign_sk_user_data(sock->sk, NULL); | 100 | rcu_assign_sk_user_data(sock->sk, NULL); |
103 | kernel_sock_shutdown(sock, SHUT_RDWR); | 101 | kernel_sock_shutdown(sock, SHUT_RDWR); |
104 | sk_release_kernel(sock->sk); | 102 | sock_release(sock); |
105 | } | 103 | } |
106 | EXPORT_SYMBOL_GPL(udp_tunnel_sock_release); | 104 | EXPORT_SYMBOL_GPL(udp_tunnel_sock_release); |
107 | 105 | ||
diff --git a/net/ipv6/ip6_udp_tunnel.c b/net/ipv6/ip6_udp_tunnel.c index 478576b61214..e1a1136bda7c 100644 --- a/net/ipv6/ip6_udp_tunnel.c +++ b/net/ipv6/ip6_udp_tunnel.c | |||
@@ -19,12 +19,10 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, | |||
19 | int err; | 19 | int err; |
20 | struct socket *sock = NULL; | 20 | struct socket *sock = NULL; |
21 | 21 | ||
22 | err = sock_create_kern(&init_net, AF_INET6, SOCK_DGRAM, 0, &sock); | 22 | err = sock_create_kern(net, AF_INET6, SOCK_DGRAM, 0, &sock); |
23 | if (err < 0) | 23 | if (err < 0) |
24 | goto error; | 24 | goto error; |
25 | 25 | ||
26 | sk_change_net(sock->sk, net); | ||
27 | |||
28 | udp6_addr.sin6_family = AF_INET6; | 26 | udp6_addr.sin6_family = AF_INET6; |
29 | memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6, | 27 | memcpy(&udp6_addr.sin6_addr, &cfg->local_ip6, |
30 | sizeof(udp6_addr.sin6_addr)); | 28 | sizeof(udp6_addr.sin6_addr)); |
@@ -55,7 +53,7 @@ int udp_sock_create6(struct net *net, struct udp_port_cfg *cfg, | |||
55 | error: | 53 | error: |
56 | if (sock) { | 54 | if (sock) { |
57 | kernel_sock_shutdown(sock, SHUT_RDWR); | 55 | kernel_sock_shutdown(sock, SHUT_RDWR); |
58 | sk_release_kernel(sock->sk); | 56 | sock_release(sock); |
59 | } | 57 | } |
60 | *sockp = NULL; | 58 | *sockp = NULL; |
61 | return err; | 59 | return err; |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index ae513a2fe7f3..f6b090df3930 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1334,9 +1334,10 @@ static void l2tp_tunnel_del_work(struct work_struct *work) | |||
1334 | if (sock) | 1334 | if (sock) |
1335 | inet_shutdown(sock, 2); | 1335 | inet_shutdown(sock, 2); |
1336 | } else { | 1336 | } else { |
1337 | if (sock) | 1337 | if (sock) { |
1338 | kernel_sock_shutdown(sock, SHUT_RDWR); | 1338 | kernel_sock_shutdown(sock, SHUT_RDWR); |
1339 | sk_release_kernel(sk); | 1339 | sock_release(sock); |
1340 | } | ||
1340 | } | 1341 | } |
1341 | 1342 | ||
1342 | l2tp_tunnel_sock_put(sk); | 1343 | l2tp_tunnel_sock_put(sk); |
@@ -1399,13 +1400,11 @@ static int l2tp_tunnel_sock_create(struct net *net, | |||
1399 | if (cfg->local_ip6 && cfg->peer_ip6) { | 1400 | if (cfg->local_ip6 && cfg->peer_ip6) { |
1400 | struct sockaddr_l2tpip6 ip6_addr = {0}; | 1401 | struct sockaddr_l2tpip6 ip6_addr = {0}; |
1401 | 1402 | ||
1402 | err = sock_create_kern(&init_net, AF_INET6, SOCK_DGRAM, | 1403 | err = sock_create_kern(net, AF_INET6, SOCK_DGRAM, |
1403 | IPPROTO_L2TP, &sock); | 1404 | IPPROTO_L2TP, &sock); |
1404 | if (err < 0) | 1405 | if (err < 0) |
1405 | goto out; | 1406 | goto out; |
1406 | 1407 | ||
1407 | sk_change_net(sock->sk, net); | ||
1408 | |||
1409 | ip6_addr.l2tp_family = AF_INET6; | 1408 | ip6_addr.l2tp_family = AF_INET6; |
1410 | memcpy(&ip6_addr.l2tp_addr, cfg->local_ip6, | 1409 | memcpy(&ip6_addr.l2tp_addr, cfg->local_ip6, |
1411 | sizeof(ip6_addr.l2tp_addr)); | 1410 | sizeof(ip6_addr.l2tp_addr)); |
@@ -1429,13 +1428,11 @@ static int l2tp_tunnel_sock_create(struct net *net, | |||
1429 | { | 1428 | { |
1430 | struct sockaddr_l2tpip ip_addr = {0}; | 1429 | struct sockaddr_l2tpip ip_addr = {0}; |
1431 | 1430 | ||
1432 | err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, | 1431 | err = sock_create_kern(net, AF_INET, SOCK_DGRAM, |
1433 | IPPROTO_L2TP, &sock); | 1432 | IPPROTO_L2TP, &sock); |
1434 | if (err < 0) | 1433 | if (err < 0) |
1435 | goto out; | 1434 | goto out; |
1436 | 1435 | ||
1437 | sk_change_net(sock->sk, net); | ||
1438 | |||
1439 | ip_addr.l2tp_family = AF_INET; | 1436 | ip_addr.l2tp_family = AF_INET; |
1440 | ip_addr.l2tp_addr = cfg->local_ip; | 1437 | ip_addr.l2tp_addr = cfg->local_ip; |
1441 | ip_addr.l2tp_conn_id = tunnel_id; | 1438 | ip_addr.l2tp_conn_id = tunnel_id; |
@@ -1462,7 +1459,7 @@ out: | |||
1462 | *sockp = sock; | 1459 | *sockp = sock; |
1463 | if ((err < 0) && sock) { | 1460 | if ((err < 0) && sock) { |
1464 | kernel_sock_shutdown(sock, SHUT_RDWR); | 1461 | kernel_sock_shutdown(sock, SHUT_RDWR); |
1465 | sk_release_kernel(sock->sk); | 1462 | sock_release(sock); |
1466 | *sockp = NULL; | 1463 | *sockp = NULL; |
1467 | } | 1464 | } |
1468 | 1465 | ||
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 2e9a5b5d1239..b08ba9538d12 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c | |||
@@ -1457,18 +1457,12 @@ static struct socket *make_send_sock(struct net *net, int id) | |||
1457 | struct socket *sock; | 1457 | struct socket *sock; |
1458 | int result; | 1458 | int result; |
1459 | 1459 | ||
1460 | /* First create a socket move it to right name space later */ | 1460 | /* First create a socket */ |
1461 | result = sock_create_kern(&init_net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); | 1461 | result = sock_create_kern(net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); |
1462 | if (result < 0) { | 1462 | if (result < 0) { |
1463 | pr_err("Error during creation of socket; terminating\n"); | 1463 | pr_err("Error during creation of socket; terminating\n"); |
1464 | return ERR_PTR(result); | 1464 | return ERR_PTR(result); |
1465 | } | 1465 | } |
1466 | /* | ||
1467 | * Kernel sockets that are a part of a namespace, should not | ||
1468 | * hold a reference to a namespace in order to allow to stop it. | ||
1469 | * After sk_change_net should be released using sk_release_kernel. | ||
1470 | */ | ||
1471 | sk_change_net(sock->sk, net); | ||
1472 | result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn); | 1466 | result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn); |
1473 | if (result < 0) { | 1467 | if (result < 0) { |
1474 | pr_err("Error setting outbound mcast interface\n"); | 1468 | pr_err("Error setting outbound mcast interface\n"); |
@@ -1497,7 +1491,7 @@ static struct socket *make_send_sock(struct net *net, int id) | |||
1497 | return sock; | 1491 | return sock; |
1498 | 1492 | ||
1499 | error: | 1493 | error: |
1500 | sk_release_kernel(sock->sk); | 1494 | sock_release(sock); |
1501 | return ERR_PTR(result); | 1495 | return ERR_PTR(result); |
1502 | } | 1496 | } |
1503 | 1497 | ||
@@ -1518,17 +1512,11 @@ static struct socket *make_receive_sock(struct net *net, int id) | |||
1518 | int result; | 1512 | int result; |
1519 | 1513 | ||
1520 | /* First create a socket */ | 1514 | /* First create a socket */ |
1521 | result = sock_create_kern(&init_net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); | 1515 | result = sock_create_kern(net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); |
1522 | if (result < 0) { | 1516 | if (result < 0) { |
1523 | pr_err("Error during creation of socket; terminating\n"); | 1517 | pr_err("Error during creation of socket; terminating\n"); |
1524 | return ERR_PTR(result); | 1518 | return ERR_PTR(result); |
1525 | } | 1519 | } |
1526 | /* | ||
1527 | * Kernel sockets that are a part of a namespace, should not | ||
1528 | * hold a reference to a namespace in order to allow to stop it. | ||
1529 | * After sk_change_net should be released using sk_release_kernel. | ||
1530 | */ | ||
1531 | sk_change_net(sock->sk, net); | ||
1532 | /* it is equivalent to the REUSEADDR option in user-space */ | 1520 | /* it is equivalent to the REUSEADDR option in user-space */ |
1533 | sock->sk->sk_reuse = SK_CAN_REUSE; | 1521 | sock->sk->sk_reuse = SK_CAN_REUSE; |
1534 | result = sysctl_sync_sock_size(ipvs); | 1522 | result = sysctl_sync_sock_size(ipvs); |
@@ -1554,7 +1542,7 @@ static struct socket *make_receive_sock(struct net *net, int id) | |||
1554 | return sock; | 1542 | return sock; |
1555 | 1543 | ||
1556 | error: | 1544 | error: |
1557 | sk_release_kernel(sock->sk); | 1545 | sock_release(sock); |
1558 | return ERR_PTR(result); | 1546 | return ERR_PTR(result); |
1559 | } | 1547 | } |
1560 | 1548 | ||
@@ -1692,7 +1680,7 @@ done: | |||
1692 | ip_vs_sync_buff_release(sb); | 1680 | ip_vs_sync_buff_release(sb); |
1693 | 1681 | ||
1694 | /* release the sending multicast socket */ | 1682 | /* release the sending multicast socket */ |
1695 | sk_release_kernel(tinfo->sock->sk); | 1683 | sock_release(tinfo->sock); |
1696 | kfree(tinfo); | 1684 | kfree(tinfo); |
1697 | 1685 | ||
1698 | return 0; | 1686 | return 0; |
@@ -1729,7 +1717,7 @@ static int sync_thread_backup(void *data) | |||
1729 | } | 1717 | } |
1730 | 1718 | ||
1731 | /* release the sending multicast socket */ | 1719 | /* release the sending multicast socket */ |
1732 | sk_release_kernel(tinfo->sock->sk); | 1720 | sock_release(tinfo->sock); |
1733 | kfree(tinfo->buf); | 1721 | kfree(tinfo->buf); |
1734 | kfree(tinfo); | 1722 | kfree(tinfo); |
1735 | 1723 | ||
@@ -1854,11 +1842,11 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid) | |||
1854 | return 0; | 1842 | return 0; |
1855 | 1843 | ||
1856 | outsocket: | 1844 | outsocket: |
1857 | sk_release_kernel(sock->sk); | 1845 | sock_release(sock); |
1858 | 1846 | ||
1859 | outtinfo: | 1847 | outtinfo: |
1860 | if (tinfo) { | 1848 | if (tinfo) { |
1861 | sk_release_kernel(tinfo->sock->sk); | 1849 | sock_release(tinfo->sock); |
1862 | kfree(tinfo->buf); | 1850 | kfree(tinfo->buf); |
1863 | kfree(tinfo); | 1851 | kfree(tinfo); |
1864 | } | 1852 | } |