Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0198e09c authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'kernel_socket_netns'



Eric W. Biederman says:

====================
Cleanup the kernel sockets.

Right now the situtation for allocating kernel sockets is a mess.
- sock_create_kern does not take a namespace parameter.
- kernel sockets must not reference count a network namespace and keep
  it alive or else we will have a reference counting loop.
- The way we avoid the reference counting loop with sk_change_net
  and sk_release_kernel are major hacks.

This patchset addresses this mess by fixing sock_create_kern to do
everything necessary to create a kernel socket.  None of the current
users of kernel sockets need the network namespace reference counted.
Either kernel sockets are network namespace aware (and using the current
hacks) or kernel sockets are limited to the initial network namespace
in which case it does not matter.

This patchset starts by addressing tun which should be using normal
userspace sockets like macvtap.

Then sock_create_kern is fixed to take a network namespace.
Then the in kernel status of sockets are passed through to sk_alloc.
Then sk_alloc is fixed to not reference count the network namespace
     of kernel sockets.
Then the callers of sock_create_kern are fixed up to stop using hacks.
Then netlink which uses it's own flavor of sock_create_kern is fixed.

Finally the hacks that are sk_change_net and sk_release_kernel are removed.

When it is all done the code is easier to follow, easier to use, easier
to maintain and shorter by about 70 lines.
====================

Reported-by: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 80ba92fa affb9792
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -244,7 +244,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
	if (!type)
	if (!type)
		goto unlock;
		goto unlock;


	sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto);
	sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto, 0);
	err = -ENOMEM;
	err = -ENOMEM;
	if (!sk2)
	if (!sk2)
		goto unlock;
		goto unlock;
@@ -324,7 +324,7 @@ static int alg_create(struct net *net, struct socket *sock, int protocol,
		return -EPROTONOSUPPORT;
		return -EPROTONOSUPPORT;


	err = -ENOMEM;
	err = -ENOMEM;
	sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto);
	sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto, kern);
	if (!sk)
	if (!sk)
		goto out;
		goto out;


+2 −2
Original line number Original line Diff line number Diff line
@@ -598,7 +598,7 @@ static struct socket *drbd_try_connect(struct drbd_connection *connection)
	memcpy(&peer_in6, &connection->peer_addr, peer_addr_len);
	memcpy(&peer_in6, &connection->peer_addr, peer_addr_len);


	what = "sock_create_kern";
	what = "sock_create_kern";
	err = sock_create_kern(((struct sockaddr *)&src_in6)->sa_family,
	err = sock_create_kern(&init_net, ((struct sockaddr *)&src_in6)->sa_family,
			       SOCK_STREAM, IPPROTO_TCP, &sock);
			       SOCK_STREAM, IPPROTO_TCP, &sock);
	if (err < 0) {
	if (err < 0) {
		sock = NULL;
		sock = NULL;
@@ -693,7 +693,7 @@ static int prepare_listen_socket(struct drbd_connection *connection, struct acce
	memcpy(&my_addr, &connection->my_addr, my_addr_len);
	memcpy(&my_addr, &connection->my_addr, my_addr_len);


	what = "sock_create_kern";
	what = "sock_create_kern";
	err = sock_create_kern(((struct sockaddr *)&my_addr)->sa_family,
	err = sock_create_kern(&init_net, ((struct sockaddr *)&my_addr)->sa_family,
			       SOCK_STREAM, IPPROTO_TCP, &s_listen);
			       SOCK_STREAM, IPPROTO_TCP, &s_listen);
	if (err) {
	if (err) {
		s_listen = NULL;
		s_listen = NULL;
+6 −6
Original line number Original line Diff line number Diff line
@@ -601,14 +601,14 @@ static const struct proto_ops data_sock_ops = {
};
};


static int
static int
data_sock_create(struct net *net, struct socket *sock, int protocol)
data_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
{
{
	struct sock *sk;
	struct sock *sk;


	if (sock->type != SOCK_DGRAM)
	if (sock->type != SOCK_DGRAM)
		return -ESOCKTNOSUPPORT;
		return -ESOCKTNOSUPPORT;


	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto);
	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
	if (!sk)
	if (!sk)
		return -ENOMEM;
		return -ENOMEM;


@@ -756,14 +756,14 @@ static const struct proto_ops base_sock_ops = {




static int
static int
base_sock_create(struct net *net, struct socket *sock, int protocol)
base_sock_create(struct net *net, struct socket *sock, int protocol, int kern)
{
{
	struct sock *sk;
	struct sock *sk;


	if (sock->type != SOCK_RAW)
	if (sock->type != SOCK_RAW)
		return -ESOCKTNOSUPPORT;
		return -ESOCKTNOSUPPORT;


	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto);
	sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto, kern);
	if (!sk)
	if (!sk)
		return -ENOMEM;
		return -ENOMEM;


@@ -785,7 +785,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)


	switch (proto) {
	switch (proto) {
	case ISDN_P_BASE:
	case ISDN_P_BASE:
		err = base_sock_create(net, sock, proto);
		err = base_sock_create(net, sock, proto, kern);
		break;
		break;
	case ISDN_P_TE_S0:
	case ISDN_P_TE_S0:
	case ISDN_P_NT_S0:
	case ISDN_P_NT_S0:
@@ -799,7 +799,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
	case ISDN_P_B_L2DTMF:
	case ISDN_P_B_L2DTMF:
	case ISDN_P_B_L2DSP:
	case ISDN_P_B_L2DSP:
	case ISDN_P_B_L2DSPHDLC:
	case ISDN_P_B_L2DSPHDLC:
		err = data_sock_create(net, sock, proto);
		err = data_sock_create(net, sock, proto, kern);
		break;
		break;
	default:
	default:
		return err;
		return err;
+1 −1
Original line number Original line Diff line number Diff line
@@ -476,7 +476,7 @@ static int macvtap_open(struct inode *inode, struct file *file)


	err = -ENOMEM;
	err = -ENOMEM;
	q = (struct macvtap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
	q = (struct macvtap_queue *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
					     &macvtap_proto);
					     &macvtap_proto, 0);
	if (!q)
	if (!q)
		goto out;
		goto out;


+2 −2
Original line number Original line Diff line number Diff line
@@ -546,11 +546,11 @@ static struct proto pppoe_sk_proto __read_mostly = {
 * Initialize a new struct sock.
 * Initialize a new struct sock.
 *
 *
 **********************************************************************/
 **********************************************************************/
static int pppoe_create(struct net *net, struct socket *sock)
static int pppoe_create(struct net *net, struct socket *sock, int kern)
{
{
	struct sock *sk;
	struct sock *sk;


	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto);
	sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, kern);
	if (!sk)
	if (!sk)
		return -ENOMEM;
		return -ENOMEM;


Loading