diff options
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 277 | 
1 files changed, 259 insertions, 18 deletions
| diff --git a/net/socket.c b/net/socket.c index 3c176a12fe48..8255f5bda0aa 100644 --- a/net/socket.c +++ b/net/socket.c @@ -384,6 +384,18 @@ static struct file_system_type sock_fs_type = {   *	but we take care of internal coherence yet.   */ +/** + *	sock_alloc_file - Bind a &socket to a &file + *	@sock: socket + *	@flags: file status flags + *	@dname: protocol name + * + *	Returns the &file bound with @sock, implicitly storing it + *	in sock->file. If dname is %NULL, sets to "". + *	On failure the return is a ERR pointer (see linux/err.h). + *	This function uses GFP_KERNEL internally. + */ +  struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname)  {  	struct file *file; @@ -424,6 +436,14 @@ static int sock_map_fd(struct socket *sock, int flags)  	return PTR_ERR(newfile);  } +/** + *	sock_from_file - Return the &socket bounded to @file. + *	@file: file + *	@err: pointer to an error code return + * + *	On failure returns %NULL and assigns -ENOTSOCK to @err. + */ +  struct socket *sock_from_file(struct file *file, int *err)  {  	if (file->f_op == &socket_file_ops) @@ -532,11 +552,11 @@ static const struct inode_operations sockfs_inode_ops = {  };  /** - *	sock_alloc	-	allocate a socket + *	sock_alloc - allocate a socket   *   *	Allocate a new inode and socket object. The two are bound together   *	and initialised. The socket is then returned. If we are out of inodes - *	NULL is returned. + *	NULL is returned. This functions uses GFP_KERNEL internally.   */  struct socket *sock_alloc(void) @@ -561,7 +581,7 @@ struct socket *sock_alloc(void)  EXPORT_SYMBOL(sock_alloc);  /** - *	sock_release	-	close a socket + *	sock_release - close a socket   *	@sock: socket to close   *   *	The socket is released from the protocol stack if it has a release @@ -617,6 +637,15 @@ void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags)  }  EXPORT_SYMBOL(__sock_tx_timestamp); +/** + *	sock_sendmsg - send a message through @sock + *	@sock: socket + *	@msg: message to send + * + *	Sends @msg through @sock, passing through LSM. + *	Returns the number of bytes sent, or an error code. + */ +  static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)  {  	int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg)); @@ -633,6 +662,18 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg)  }  EXPORT_SYMBOL(sock_sendmsg); +/** + *	kernel_sendmsg - send a message through @sock (kernel-space) + *	@sock: socket + *	@msg: message header + *	@vec: kernel vec + *	@num: vec array length + *	@size: total message data size + * + *	Builds the message data with @vec and sends it through @sock. + *	Returns the number of bytes sent, or an error code. + */ +  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,  		   struct kvec *vec, size_t num, size_t size)  { @@ -641,6 +682,19 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,  }  EXPORT_SYMBOL(kernel_sendmsg); +/** + *	kernel_sendmsg_locked - send a message through @sock (kernel-space) + *	@sk: sock + *	@msg: message header + *	@vec: output s/g array + *	@num: output s/g array length + *	@size: total message data size + * + *	Builds the message data with @vec and sends it through @sock. + *	Returns the number of bytes sent, or an error code. + *	Caller must hold @sk. + */ +  int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg,  			  struct kvec *vec, size_t num, size_t size)  { @@ -811,6 +865,16 @@ void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,  }  EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); +/** + *	sock_recvmsg - receive a message from @sock + *	@sock: socket + *	@msg: message to receive + *	@flags: message flags + * + *	Receives @msg from @sock, passing through LSM. Returns the total number + *	of bytes received, or an error. + */ +  static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg,  				     int flags)  { @@ -826,20 +890,21 @@ int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags)  EXPORT_SYMBOL(sock_recvmsg);  /** - * kernel_recvmsg - Receive a message from a socket (kernel space) - * @sock:       The socket to receive the message from - * @msg:        Received message - * @vec:        Input s/g array for message data - * @num:        Size of input s/g array - * @size:       Number of bytes to read - * @flags:      Message flags (MSG_DONTWAIT, etc...) + *	kernel_recvmsg - Receive a message from a socket (kernel space) + *	@sock: The socket to receive the message from + *	@msg: Received message + *	@vec: Input s/g array for message data + *	@num: Size of input s/g array + *	@size: Number of bytes to read + *	@flags: Message flags (MSG_DONTWAIT, etc...)   * - * On return the msg structure contains the scatter/gather array passed in the - * vec argument. The array is modified so that it consists of the unfilled - * portion of the original array. + *	On return the msg structure contains the scatter/gather array passed in the + *	vec argument. The array is modified so that it consists of the unfilled + *	portion of the original array.   * - * The returned value is the total number of bytes received, or an error. + *	The returned value is the total number of bytes received, or an error.   */ +  int kernel_recvmsg(struct socket *sock, struct msghdr *msg,  		   struct kvec *vec, size_t num, size_t size, int flags)  { @@ -1005,6 +1070,13 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,   *	what to do with it - that's up to the protocol still.   */ +/** + *	get_net_ns - increment the refcount of the network namespace + *	@ns: common namespace (net) + * + *	Returns the net's common namespace. + */ +  struct ns_common *get_net_ns(struct ns_common *ns)  {  	return &get_net(container_of(ns, struct net, ns))->ns; @@ -1099,6 +1171,19 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)  	return err;  } +/** + *	sock_create_lite - creates a socket + *	@family: protocol family (AF_INET, ...) + *	@type: communication type (SOCK_STREAM, ...) + *	@protocol: protocol (0, ...) + *	@res: new socket + * + *	Creates a new socket and assigns it to @res, passing through LSM. + *	The new socket initialization is not complete, see kernel_accept(). + *	Returns 0 or an error. On failure @res is set to %NULL. + *	This function internally uses GFP_KERNEL. + */ +  int sock_create_lite(int family, int type, int protocol, struct socket **res)  {  	int err; @@ -1224,6 +1309,21 @@ call_kill:  }  EXPORT_SYMBOL(sock_wake_async); +/** + *	__sock_create - creates a socket + *	@net: net namespace + *	@family: protocol family (AF_INET, ...) + *	@type: communication type (SOCK_STREAM, ...) + *	@protocol: protocol (0, ...) + *	@res: new socket + *	@kern: boolean for kernel space sockets + * + *	Creates a new socket and assigns it to @res, passing through LSM. + *	Returns 0 or an error. On failure @res is set to %NULL. @kern must + *	be set to true if the socket resides in kernel space. + *	This function internally uses GFP_KERNEL. + */ +  int __sock_create(struct net *net, int family, int type, int protocol,  			 struct socket **res, int kern)  { @@ -1333,12 +1433,35 @@ out_release:  }  EXPORT_SYMBOL(__sock_create); +/** + *	sock_create - creates a socket + *	@family: protocol family (AF_INET, ...) + *	@type: communication type (SOCK_STREAM, ...) + *	@protocol: protocol (0, ...) + *	@res: new socket + * + *	A wrapper around __sock_create(). + *	Returns 0 or an error. This function internally uses GFP_KERNEL. + */ +  int sock_create(int family, int type, int protocol, struct socket **res)  {  	return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0);  }  EXPORT_SYMBOL(sock_create); +/** + *	sock_create_kern - creates a socket (kernel space) + *	@net: net namespace + *	@family: protocol family (AF_INET, ...) + *	@type: communication type (SOCK_STREAM, ...) + *	@protocol: protocol (0, ...) + *	@res: new socket + * + *	A wrapper around __sock_create(). + *	Returns 0 or an error. This function internally uses GFP_KERNEL. + */ +  int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res)  {  	return __sock_create(net, family, type, protocol, res, 1); @@ -3322,18 +3445,46 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd,  }  #endif +/** + *	kernel_bind - bind an address to a socket (kernel space) + *	@sock: socket + *	@addr: address + *	@addrlen: length of address + * + *	Returns 0 or an error. + */ +  int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen)  {  	return sock->ops->bind(sock, addr, addrlen);  }  EXPORT_SYMBOL(kernel_bind); +/** + *	kernel_listen - move socket to listening state (kernel space) + *	@sock: socket + *	@backlog: pending connections queue size + * + *	Returns 0 or an error. + */ +  int kernel_listen(struct socket *sock, int backlog)  {  	return sock->ops->listen(sock, backlog);  }  EXPORT_SYMBOL(kernel_listen); +/** + *	kernel_accept - accept a connection (kernel space) + *	@sock: listening socket + *	@newsock: new connected socket + *	@flags: flags + * + *	@flags must be SOCK_CLOEXEC, SOCK_NONBLOCK or 0. + *	If it fails, @newsock is guaranteed to be %NULL. + *	Returns 0 or an error. + */ +  int kernel_accept(struct socket *sock, struct socket **newsock, int flags)  {  	struct sock *sk = sock->sk; @@ -3359,6 +3510,19 @@ done:  }  EXPORT_SYMBOL(kernel_accept); +/** + *	kernel_connect - connect a socket (kernel space) + *	@sock: socket + *	@addr: address + *	@addrlen: address length + *	@flags: flags (O_NONBLOCK, ...) + * + *	For datagram sockets, @addr is the addres to which datagrams are sent + *	by default, and the only address from which datagrams are received. + *	For stream sockets, attempts to connect to @addr. + *	Returns 0 or an error code. + */ +  int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,  		   int flags)  { @@ -3366,18 +3530,48 @@ int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen,  }  EXPORT_SYMBOL(kernel_connect); +/** + *	kernel_getsockname - get the address which the socket is bound (kernel space) + *	@sock: socket + *	@addr: address holder + * + * 	Fills the @addr pointer with the address which the socket is bound. + *	Returns 0 or an error code. + */ +  int kernel_getsockname(struct socket *sock, struct sockaddr *addr)  {  	return sock->ops->getname(sock, addr, 0);  }  EXPORT_SYMBOL(kernel_getsockname); +/** + *	kernel_peername - get the address which the socket is connected (kernel space) + *	@sock: socket + *	@addr: address holder + * + * 	Fills the @addr pointer with the address which the socket is connected. + *	Returns 0 or an error code. + */ +  int kernel_getpeername(struct socket *sock, struct sockaddr *addr)  {  	return sock->ops->getname(sock, addr, 1);  }  EXPORT_SYMBOL(kernel_getpeername); +/** + *	kernel_getsockopt - get a socket option (kernel space) + *	@sock: socket + *	@level: API level (SOL_SOCKET, ...) + *	@optname: option tag + *	@optval: option value + *	@optlen: option length + * + *	Assigns the option length to @optlen. + *	Returns 0 or an error. + */ +  int kernel_getsockopt(struct socket *sock, int level, int optname,  			char *optval, int *optlen)  { @@ -3400,6 +3594,17 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,  }  EXPORT_SYMBOL(kernel_getsockopt); +/** + *	kernel_setsockopt - set a socket option (kernel space) + *	@sock: socket + *	@level: API level (SOL_SOCKET, ...) + *	@optname: option tag + *	@optval: option value + *	@optlen: option length + * + *	Returns 0 or an error. + */ +  int kernel_setsockopt(struct socket *sock, int level, int optname,  			char *optval, unsigned int optlen)  { @@ -3420,6 +3625,17 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,  }  EXPORT_SYMBOL(kernel_setsockopt); +/** + *	kernel_sendpage - send a &page through a socket (kernel space) + *	@sock: socket + *	@page: page + *	@offset: page offset + *	@size: total size in bytes + *	@flags: flags (MSG_DONTWAIT, ...) + * + *	Returns the total amount sent in bytes or an error. + */ +  int kernel_sendpage(struct socket *sock, struct page *page, int offset,  		    size_t size, int flags)  { @@ -3430,6 +3646,18 @@ int kernel_sendpage(struct socket *sock, struct page *page, int offset,  }  EXPORT_SYMBOL(kernel_sendpage); +/** + *	kernel_sendpage_locked - send a &page through the locked sock (kernel space) + *	@sk: sock + *	@page: page + *	@offset: page offset + *	@size: total size in bytes + *	@flags: flags (MSG_DONTWAIT, ...) + * + *	Returns the total amount sent in bytes or an error. + *	Caller must hold @sk. + */ +  int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,  			   size_t size, int flags)  { @@ -3443,17 +3671,30 @@ int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset,  }  EXPORT_SYMBOL(kernel_sendpage_locked); +/** + *	kernel_shutdown - shut down part of a full-duplex connection (kernel space) + *	@sock: socket + *	@how: connection part + * + *	Returns 0 or an error. + */ +  int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how)  {  	return sock->ops->shutdown(sock, how);  }  EXPORT_SYMBOL(kernel_sock_shutdown); -/* This routine returns the IP overhead imposed by a socket i.e. - * the length of the underlying IP header, depending on whether - * this is an IPv4 or IPv6 socket and the length from IP options turned - * on at the socket. Assumes that the caller has a lock on the socket. +/** + *	kernel_sock_ip_overhead - returns the IP overhead imposed by a socket + *	@sk: socket + * + *	This routine returns the IP overhead imposed by a socket i.e. + *	the length of the underlying IP header, depending on whether + *	this is an IPv4 or IPv6 socket and the length from IP options turned + *	on at the socket. Assumes that the caller has a lock on the socket.   */ +  u32 kernel_sock_ip_overhead(struct sock *sk)  {  	struct inet_sock *inet; | 
