* Initialize a new struct sock.
*
**********************************************************************/
-static int pppoe_create(struct socket *sock)
+static int pppoe_create(struct net *net, struct socket *sock)
{
int error = -ENOMEM;
struct sock *sk;
- sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
+ sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto, 1);
if (!sk)
goto out;
/* socket() handler. Initialize a new struct sock.
*/
-static int pppol2tp_create(struct socket *sock)
+static int pppol2tp_create(struct net *net, struct socket *sock)
{
int error = -ENOMEM;
struct sock *sk;
- sk = sk_alloc(PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1);
+ sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppol2tp_sk_proto, 1);
if (!sk)
goto out;
EXPORT_SYMBOL(pppox_ioctl);
-static int pppox_create(struct socket *sock, int protocol)
+static int pppox_create(struct net *net, struct socket *sock, int protocol)
{
int rc = -EPROTOTYPE;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (protocol < 0 || protocol > PX_MAX_PROTO)
goto out;
!try_module_get(pppox_protos[protocol]->owner))
goto out;
- rc = pppox_protos[protocol]->create(sock);
+ rc = pppox_protos[protocol]->create(net, sock);
module_put(pppox_protos[protocol]->owner);
out:
struct module;
struct pppox_proto {
- int (*create)(struct socket *sock);
+ int (*create)(struct net *net, struct socket *sock);
int (*ioctl)(struct socket *sock, unsigned int cmd,
unsigned long arg);
struct module *owner;
struct poll_table_struct;
struct inode;
+struct net;
#define NPROTO 34 /* should be enough for now.. */
struct net_proto_family {
int family;
- int (*create)(struct socket *sock, int protocol);
+ int (*create)(struct net *net, struct socket *sock, int protocol);
struct module *owner;
};
static void iucv_sock_cleanup_listen(struct sock *parent);
static void iucv_sock_kill(struct sock *sk);
static void iucv_sock_close(struct sock *sk);
-static int iucv_sock_create(struct socket *sock, int proto);
static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
int addr_len);
static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
return skb->cb[sizeof(skb->cb) - 1];
}
-extern struct sock *llc_sk_alloc(int family, gfp_t priority,
+extern struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
struct proto *prot);
extern void llc_sk_free(struct sock *sk);
#include <asm/atomic.h>
#include <net/dst.h>
#include <net/checksum.h>
+#include <net/net_namespace.h>
/*
* This structure really needs to be cleaned up.
SINGLE_DEPTH_NESTING)
#define bh_unlock_sock(__sk) spin_unlock(&((__sk)->sk_lock.slock))
-extern struct sock *sk_alloc(int family,
+extern struct sock *sk_alloc(struct net *net, int family,
gfp_t priority,
struct proto *prot, int zero_it);
extern void sk_free(struct sock *sk);
#endif
memcpy(nsk, osk, osk->sk_prot->obj_size);
+ get_net(nsk->sk_net);
#ifdef CONFIG_SECURITY_NETWORK
nsk->sk_security = sptr;
security_sk_clone(osk, nsk);
* Create a socket. Initialise the socket, blank the addresses
* set the state.
*/
-static int atalk_create(struct socket *sock, int protocol)
+static int atalk_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
int rc = -ESOCKTNOSUPPORT;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
/*
* We permit SOCK_DGRAM and RAW is an extension. It is trivial to do
* and gives you the full ELAP frame. Should be handy for CAP 8)
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
goto out;
rc = -ENOMEM;
- sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
+ sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
if (!sk)
goto out;
rc = 0;
.obj_size = sizeof(struct atm_vcc),
};
-int vcc_create(struct socket *sock, int protocol, int family)
+int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
{
struct sock *sk;
struct atm_vcc *vcc;
sock->sk = NULL;
if (sock->type == SOCK_STREAM)
return -EINVAL;
- sk = sk_alloc(family, GFP_KERNEL, &vcc_proto, 1);
+ sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, 1);
if (!sk)
return -ENOMEM;
sock_init_data(sock, sk);
#include <linux/poll.h> /* for poll_table */
-int vcc_create(struct socket *sock, int protocol, int family);
+int vcc_create(struct net *net, struct socket *sock, int protocol, int family);
int vcc_release(struct socket *sock);
int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
};
-static int pvc_create(struct socket *sock,int protocol)
+static int pvc_create(struct net *net, struct socket *sock,int protocol)
{
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
sock->ops = &pvc_proto_ops;
- return vcc_create(sock, protocol, PF_ATMPVC);
+ return vcc_create(net, sock, protocol, PF_ATMPVC);
}
#include "signaling.h"
#include "addr.h"
-static int svc_create(struct socket *sock,int protocol);
+static int svc_create(struct net *net, struct socket *sock,int protocol);
/*
* Note: since all this is still nicely synchronized with the signaling demon,
lock_sock(sk);
- error = svc_create(newsock,0);
+ error = svc_create(sk->sk_net, newsock,0);
if (error)
goto out;
};
-static int svc_create(struct socket *sock,int protocol)
+static int svc_create(struct net *net, struct socket *sock,int protocol)
{
int error;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
sock->ops = &svc_proto_ops;
- error = vcc_create(sock, protocol, AF_ATMSVC);
+ error = vcc_create(net, sock, protocol, AF_ATMSVC);
if (error) return error;
ATM_SD(sock)->local.sas_family = AF_ATMSVC;
ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
.obj_size = sizeof(struct sock),
};
-static int ax25_create(struct socket *sock, int protocol)
+static int ax25_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
ax25_cb *ax25;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
switch (sock->type) {
case SOCK_DGRAM:
if (protocol == 0 || protocol == PF_AX25)
return -ESOCKTNOSUPPORT;
}
- if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
+ if ((sk = sk_alloc(net, PF_AX25, GFP_ATOMIC, &ax25_proto, 1)) == NULL)
return -ENOMEM;
ax25 = sk->sk_protinfo = ax25_create_cb();
struct sock *sk;
ax25_cb *ax25, *oax25;
- if ((sk = sk_alloc(PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
+ if ((sk = sk_alloc(osk->sk_net, PF_AX25, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
return NULL;
if ((ax25 = ax25_create_cb()) == NULL) {
}
EXPORT_SYMBOL(bt_sock_unregister);
-static int bt_sock_create(struct socket *sock, int proto)
+static int bt_sock_create(struct net *net, struct socket *sock, int proto)
{
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
read_lock(&bt_proto_lock);
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
- err = bt_proto[proto]->create(sock, proto);
+ err = bt_proto[proto]->create(net, sock, proto);
module_put(bt_proto[proto]->owner);
}
.obj_size = sizeof(struct bt_sock)
};
-static int bnep_sock_create(struct socket *sock, int protocol)
+static int bnep_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &bnep_proto, 1);
if (!sk)
return -ENOMEM;
.obj_size = sizeof(struct bt_sock)
};
-static int cmtp_sock_create(struct socket *sock, int protocol)
+static int cmtp_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &cmtp_proto, 1);
if (!sk)
return -ENOMEM;
.obj_size = sizeof(struct hci_pinfo)
};
-static int hci_sock_create(struct socket *sock, int protocol)
+static int hci_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
sock->ops = &hci_sock_ops;
- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, 1);
if (!sk)
return -ENOMEM;
.obj_size = sizeof(struct bt_sock)
};
-static int hidp_sock_create(struct socket *sock, int protocol)
+static int hidp_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
if (sock->type != SOCK_RAW)
return -ESOCKTNOSUPPORT;
- sk = sk_alloc(PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, 1);
if (!sk)
return -ENOMEM;
.obj_size = sizeof(struct l2cap_pinfo)
};
-static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
{
struct sock *sk;
- sk = sk_alloc(PF_BLUETOOTH, prio, &l2cap_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, 1);
if (!sk)
return NULL;
return sk;
}
-static int l2cap_sock_create(struct socket *sock, int protocol)
+static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
sock->ops = &l2cap_sock_ops;
- sk = l2cap_sock_alloc(sock, protocol, GFP_ATOMIC);
+ sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC);
if (!sk)
return -ENOMEM;
goto response;
}
- sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
+ sk = l2cap_sock_alloc(parent->sk_net, NULL, BTPROTO_L2CAP, GFP_ATOMIC);
if (!sk)
goto response;
.obj_size = sizeof(struct rfcomm_pinfo)
};
-static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
{
struct rfcomm_dlc *d;
struct sock *sk;
- sk = sk_alloc(PF_BLUETOOTH, prio, &rfcomm_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, 1);
if (!sk)
return NULL;
return sk;
}
-static int rfcomm_sock_create(struct socket *sock, int protocol)
+static int rfcomm_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
sock->ops = &rfcomm_sock_ops;
- sk = rfcomm_sock_alloc(sock, protocol, GFP_ATOMIC);
+ sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC);
if (!sk)
return -ENOMEM;
goto done;
}
- sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
+ sk = rfcomm_sock_alloc(parent->sk_net, NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
if (!sk)
goto done;
.obj_size = sizeof(struct sco_pinfo)
};
-static struct sock *sco_sock_alloc(struct socket *sock, int proto, gfp_t prio)
+static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio)
{
struct sock *sk;
- sk = sk_alloc(PF_BLUETOOTH, prio, &sco_proto, 1);
+ sk = sk_alloc(net, PF_BLUETOOTH, prio, &sco_proto, 1);
if (!sk)
return NULL;
return sk;
}
-static int sco_sock_create(struct socket *sock, int protocol)
+static int sco_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
sock->ops = &sco_sock_ops;
- sk = sco_sock_alloc(sock, protocol, GFP_ATOMIC);
+ sk = sco_sock_alloc(net, sock, protocol, GFP_ATOMIC);
if (!sk)
return -ENOMEM;
bh_lock_sock(parent);
- sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
+ sk = sco_sock_alloc(parent->sk_net, NULL, BTPROTO_SCO, GFP_ATOMIC);
if (!sk) {
bh_unlock_sock(parent);
goto done;
* @prot: struct proto associated with this new sock instance
* @zero_it: if we should zero the newly allocated sock
*/
-struct sock *sk_alloc(int family, gfp_t priority,
+struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
struct proto *prot, int zero_it)
{
struct sock *sk = NULL;
*/
sk->sk_prot = sk->sk_prot_creator = prot;
sock_lock_init(sk);
+ sk->sk_net = get_net(net);
}
if (security_sk_alloc(sk, family, priority))
__FUNCTION__, atomic_read(&sk->sk_omem_alloc));
security_sk_free(sk);
+ put_net(sk->sk_net);
if (sk->sk_prot_creator->slab != NULL)
kmem_cache_free(sk->sk_prot_creator->slab, sk);
else
struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
{
- struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
+ struct sock *newsk = sk_alloc(sk->sk_net, sk->sk_family, priority, sk->sk_prot, 0);
if (newsk != NULL) {
struct sk_filter *filter;
.obj_size = sizeof(struct dn_sock),
};
-static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp)
+static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp)
{
struct dn_scp *scp;
- struct sock *sk = sk_alloc(PF_DECnet, gfp, &dn_proto, 1);
+ struct sock *sk = sk_alloc(net, PF_DECnet, gfp, &dn_proto, 1);
if (!sk)
goto out;
-static int dn_create(struct socket *sock, int protocol)
+static int dn_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
switch(sock->type) {
case SOCK_SEQPACKET:
if (protocol != DNPROTO_NSP)
}
- if ((sk = dn_alloc_sock(sock, GFP_KERNEL)) == NULL)
+ if ((sk = dn_alloc_sock(net, sock, GFP_KERNEL)) == NULL)
return -ENOBUFS;
sk->sk_protocol = protocol;
cb = DN_SKB_CB(skb);
sk->sk_ack_backlog--;
- newsk = dn_alloc_sock(newsock, sk->sk_allocation);
+ newsk = dn_alloc_sock(sk->sk_net, newsock, sk->sk_allocation);
if (newsk == NULL) {
release_sock(sk);
kfree_skb(skb);
* Create an Econet socket
*/
-static int econet_create(struct socket *sock, int protocol)
+static int econet_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct econet_sock *eo;
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
/* Econet only provides datagram services. */
if (sock->type != SOCK_DGRAM)
return -ESOCKTNOSUPPORT;
sock->state = SS_UNCONNECTED;
err = -ENOBUFS;
- sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
+ sk = sk_alloc(net, PF_ECONET, GFP_KERNEL, &econet_proto, 1);
if (sk == NULL)
goto out;
* Create an inet socket.
*/
-static int inet_create(struct socket *sock, int protocol)
+static int inet_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct list_head *p;
int try_loading_module = 0;
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (sock->type != SOCK_RAW &&
sock->type != SOCK_DGRAM &&
!inet_ehash_secret)
BUG_TRAP(answer_prot->slab != NULL);
err = -ENOBUFS;
- sk = sk_alloc(PF_INET, GFP_KERNEL, answer_prot, 1);
+ sk = sk_alloc(net, PF_INET, GFP_KERNEL, answer_prot, 1);
if (sk == NULL)
goto out;
return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
}
-static int inet6_create(struct socket *sock, int protocol)
+static int inet6_create(struct net *net, struct socket *sock, int protocol)
{
struct inet_sock *inet;
struct ipv6_pinfo *np;
int try_loading_module = 0;
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (sock->type != SOCK_RAW &&
sock->type != SOCK_DGRAM &&
!inet_ehash_secret)
BUG_TRAP(answer_prot->slab != NULL);
err = -ENOBUFS;
- sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
+ sk = sk_alloc(net, PF_INET6, GFP_KERNEL, answer_prot, 1);
if (sk == NULL)
goto out;
.obj_size = sizeof(struct ipx_sock),
};
-static int ipx_create(struct socket *sock, int protocol)
+static int ipx_create(struct net *net, struct socket *sock, int protocol)
{
int rc = -ESOCKTNOSUPPORT;
struct sock *sk;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
/*
* SPX support is not anymore in the kernel sources. If you want to
* ressurrect it, completing it and making it understand shared skbs,
goto out;
rc = -ENOMEM;
- sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1);
+ sk = sk_alloc(net, PF_IPX, GFP_KERNEL, &ipx_proto, 1);
if (!sk)
goto out;
#ifdef IPX_REFCNT_DEBUG
#include <net/irda/af_irda.h>
-static int irda_create(struct socket *sock, int protocol);
+static int irda_create(struct net *net, struct socket *sock, int protocol);
static const struct proto_ops irda_stream_ops;
static const struct proto_ops irda_seqpacket_ops;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
- err = irda_create(newsock, sk->sk_protocol);
+ err = irda_create(sk->sk_net, newsock, sk->sk_protocol);
if (err)
return err;
* Create IrDA socket
*
*/
-static int irda_create(struct socket *sock, int protocol)
+static int irda_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct irda_sock *self;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
/* Check for valid socket type */
switch (sock->type) {
case SOCK_STREAM: /* For TTP connections with SAR disabled */
}
/* Allocate networking socket */
- sk = sk_alloc(PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
+ sk = sk_alloc(net, PF_IRDA, GFP_ATOMIC, &irda_proto, 1);
if (sk == NULL)
return -ENOMEM;
{
struct sock *sk;
- sk = sk_alloc(PF_IUCV, prio, &iucv_proto, 1);
+ sk = sk_alloc(&init_net, PF_IUCV, prio, &iucv_proto, 1);
if (!sk)
return NULL;
}
/* Create an IUCV socket */
-static int iucv_sock_create(struct socket *sock, int protocol)
+static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
.obj_size = sizeof(struct pfkey_sock),
};
-static int pfkey_create(struct socket *sock, int protocol)
+static int pfkey_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (sock->type != SOCK_RAW)
return -EPROTONOSUPPORT;
err = -ENOMEM;
- sk = sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
+ sk = sk_alloc(net, PF_KEY, GFP_KERNEL, &key_proto, 1);
if (sk == NULL)
goto out;
* socket type we have available.
* Returns 0 upon success, negative upon failure.
*/
-static int llc_ui_create(struct socket *sock, int protocol)
+static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
int rc = -ESOCKTNOSUPPORT;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) {
rc = -ENOMEM;
- sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto);
+ sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto);
if (sk) {
rc = 0;
llc_ui_sk_init(sock, sk);
struct llc_addr *saddr,
struct llc_addr *daddr)
{
- struct sock *newsk = llc_sk_alloc(sk->sk_family, GFP_ATOMIC,
+ struct sock *newsk = llc_sk_alloc(sk->sk_net, sk->sk_family, GFP_ATOMIC,
sk->sk_prot);
struct llc_sock *newllc, *llc = llc_sk(sk);
* Allocates a LLC sock and initializes it. Returns the new LLC sock
* or %NULL if there's no memory available for one
*/
-struct sock *llc_sk_alloc(int family, gfp_t priority, struct proto *prot)
+struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority, struct proto *prot)
{
- struct sock *sk = sk_alloc(family, priority, prot, 1);
+ struct sock *sk = sk_alloc(net, family, priority, prot, 1);
if (!sk)
goto out;
.obj_size = sizeof(struct netlink_sock),
};
-static int __netlink_create(struct socket *sock, struct mutex *cb_mutex,
- int protocol)
+static int __netlink_create(struct net *net, struct socket *sock,
+ struct mutex *cb_mutex, int protocol)
{
struct sock *sk;
struct netlink_sock *nlk;
sock->ops = &netlink_ops;
- sk = sk_alloc(PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
+ sk = sk_alloc(net, PF_NETLINK, GFP_KERNEL, &netlink_proto, 1);
if (!sk)
return -ENOMEM;
return 0;
}
-static int netlink_create(struct socket *sock, int protocol)
+static int netlink_create(struct net *net, struct socket *sock, int protocol)
{
struct module *module = NULL;
struct mutex *cb_mutex;
struct netlink_sock *nlk;
int err = 0;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
sock->state = SS_UNCONNECTED;
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
cb_mutex = nl_table[protocol].cb_mutex;
netlink_unlock_table();
- if ((err = __netlink_create(sock, cb_mutex, protocol)) < 0)
+ if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0)
goto out_module;
nlk = nlk_sk(sock->sk);
if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
return NULL;
- if (__netlink_create(sock, cb_mutex, unit) < 0)
+ if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0)
goto out_sock_release;
if (groups < 32)
.obj_size = sizeof(struct nr_sock),
};
-static int nr_create(struct socket *sock, int protocol)
+static int nr_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct nr_sock *nr;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (sock->type != SOCK_SEQPACKET || protocol != 0)
return -ESOCKTNOSUPPORT;
- if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
+ if ((sk = sk_alloc(net, PF_NETROM, GFP_ATOMIC, &nr_proto, 1)) == NULL)
return -ENOMEM;
nr = nr_sk(sk);
if (osk->sk_type != SOCK_SEQPACKET)
return NULL;
- if ((sk = sk_alloc(PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
+ if ((sk = sk_alloc(osk->sk_net, PF_NETROM, GFP_ATOMIC, osk->sk_prot, 1)) == NULL)
return NULL;
nr = nr_sk(sk);
* Create a packet of type SOCK_PACKET.
*/
-static int packet_create(struct socket *sock, int protocol)
+static int packet_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct packet_sock *po;
__be16 proto = (__force __be16)protocol; /* weird, but documented */
int err;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (!capable(CAP_NET_RAW))
return -EPERM;
if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
sock->state = SS_UNCONNECTED;
err = -ENOBUFS;
- sk = sk_alloc(PF_PACKET, GFP_KERNEL, &packet_proto, 1);
+ sk = sk_alloc(net, PF_PACKET, GFP_KERNEL, &packet_proto, 1);
if (sk == NULL)
goto out;
.obj_size = sizeof(struct rose_sock),
};
-static int rose_create(struct socket *sock, int protocol)
+static int rose_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct rose_sock *rose;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (sock->type != SOCK_SEQPACKET || protocol != 0)
return -ESOCKTNOSUPPORT;
- if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
+ if ((sk = sk_alloc(net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
return -ENOMEM;
rose = rose_sk(sk);
if (osk->sk_type != SOCK_SEQPACKET)
return NULL;
- if ((sk = sk_alloc(PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
+ if ((sk = sk_alloc(osk->sk_net, PF_ROSE, GFP_ATOMIC, &rose_proto, 1)) == NULL)
return NULL;
rose = rose_sk(sk);
/*
* create an RxRPC socket
*/
-static int rxrpc_create(struct socket *sock, int protocol)
+static int rxrpc_create(struct net *net, struct socket *sock, int protocol)
{
struct rxrpc_sock *rx;
struct sock *sk;
_enter("%p,%d", sock, protocol);
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
/* we support transport protocol UDP only */
if (protocol != PF_INET)
return -EPROTONOSUPPORT;
sock->ops = &rxrpc_rpc_ops;
sock->state = SS_UNCONNECTED;
- sk = sk_alloc(PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
+ sk = sk_alloc(net, PF_RXRPC, GFP_KERNEL, &rxrpc_proto, 1);
if (!sk)
return -ENOMEM;
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
- newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
+ newsk = sk_alloc(sk->sk_net, PF_INET6, GFP_KERNEL, sk->sk_prot, 1);
if (!newsk)
goto out;
{
struct inet_sock *inet = inet_sk(sk);
struct inet_sock *newinet;
- struct sock *newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot, 1);
+ struct sock *newsk = sk_alloc(sk->sk_net, PF_INET, GFP_KERNEL, sk->sk_prot, 1);
if (!newsk)
goto out;
#include <linux/kmod.h>
#include <linux/audit.h>
#include <linux/wireless.h>
+#include <linux/nsproxy.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
return 0;
}
-static int __sock_create(int family, int type, int protocol,
+static int __sock_create(struct net *net, int family, int type, int protocol,
struct socket **res, int kern)
{
int err;
/* Now protected by module ref count */
rcu_read_unlock();
- err = pf->create(sock, protocol);
+ err = pf->create(net, sock, protocol);
if (err < 0)
goto out_module_put;
int sock_create(int family, int type, int protocol, struct socket **res)
{
- return __sock_create(family, type, protocol, res, 0);
+ return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);
}
int sock_create_kern(int family, int type, int protocol, struct socket **res)
{
- return __sock_create(family, type, protocol, res, 1);
+ return __sock_create(&init_net, family, type, protocol, res, 1);
}
asmlinkage long sys_socket(int family, int type, int protocol)
*
* Returns 0 on success, errno otherwise
*/
-static int tipc_create(struct socket *sock, int protocol)
+static int tipc_create(struct net *net, struct socket *sock, int protocol)
{
struct tipc_sock *tsock;
struct tipc_port *port;
struct sock *sk;
u32 ref;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (unlikely(protocol != 0))
return -EPROTONOSUPPORT;
return -EPROTOTYPE;
}
- sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
+ sk = sk_alloc(net, AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
if (!sk) {
tipc_deleteport(ref);
return -ENOMEM;
}
buf = skb_peek(&sock->sk->sk_receive_queue);
- res = tipc_create(newsock, 0);
+ res = tipc_create(sock->sk->sk_net, newsock, 0);
if (!res) {
struct tipc_sock *new_tsock = tipc_sk(newsock->sk);
struct tipc_portid id;
*/
static struct lock_class_key af_unix_sk_receive_queue_lock_key;
-static struct sock * unix_create1(struct socket *sock)
+static struct sock * unix_create1(struct net *net, struct socket *sock)
{
struct sock *sk = NULL;
struct unix_sock *u;
if (atomic_read(&unix_nr_socks) >= 2*get_max_files())
goto out;
- sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
+ sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, 1);
if (!sk)
goto out;
return sk;
}
-static int unix_create(struct socket *sock, int protocol)
+static int unix_create(struct net *net, struct socket *sock, int protocol)
{
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (protocol && protocol != PF_UNIX)
return -EPROTONOSUPPORT;
return -ESOCKTNOSUPPORT;
}
- return unix_create1(sock) ? 0 : -ENOMEM;
+ return unix_create1(net, sock) ? 0 : -ENOMEM;
}
static int unix_release(struct socket *sock)
err = -ENOMEM;
/* create new sock for complete connection */
- newsk = unix_create1(NULL);
+ newsk = unix_create1(sk->sk_net, NULL);
if (newsk == NULL)
goto out;
.obj_size = sizeof(struct x25_sock),
};
-static struct sock *x25_alloc_socket(void)
+static struct sock *x25_alloc_socket(struct net *net)
{
struct x25_sock *x25;
- struct sock *sk = sk_alloc(AF_X25, GFP_ATOMIC, &x25_proto, 1);
+ struct sock *sk = sk_alloc(net, AF_X25, GFP_ATOMIC, &x25_proto, 1);
if (!sk)
goto out;
return sk;
}
-static int x25_create(struct socket *sock, int protocol)
+static int x25_create(struct net *net, struct socket *sock, int protocol)
{
struct sock *sk;
struct x25_sock *x25;
int rc = -ESOCKTNOSUPPORT;
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
if (sock->type != SOCK_SEQPACKET || protocol)
goto out;
rc = -ENOMEM;
- if ((sk = x25_alloc_socket()) == NULL)
+ if ((sk = x25_alloc_socket(net)) == NULL)
goto out;
x25 = x25_sk(sk);
if (osk->sk_type != SOCK_SEQPACKET)
goto out;
- if ((sk = x25_alloc_socket()) == NULL)
+ if ((sk = x25_alloc_socket(osk->sk_net)) == NULL)
goto out;
x25 = x25_sk(sk);