Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 12: Networks


Inode and socket are linked by allocating one directly after the other in memory by means of the follow-
ing auxiliary structure:

include/net/sock.h
struct socket_alloc {
struct socket socket;
struct inode vfs_inode;
};

The kernel provides two macros that perform the necessary pointer arithmetic to move from an inode
to the associated socket instance (SOCKET_I) and vice versa (SOCK_INODE). To simplify the situation,
whenever a socket is attached to a file,sock_attach_fdsets theprivate_dataelement ofstruct file
so that it points to thesocketinstance. Thesock_mmapexample shown above makes use of this.

12.10.3 The socketcallSystem Call


In addition to the read and write operations of the file functions that enter the kernel by means of the sys-
tem calls of the virtual filesystem where they are redirected to function pointers of thesocket_file_ops
structure, it is also necessary to carry out other tasks with sockets that cannot be forced into the file
scheme. These include, for example, creating a socket andbindandlistencalls.

For this purpose, Linux provides thesocketcallsystem call, which is implemented insys_socketcall
and to which I have made frequent reference.

It is remarkable that there is just one system call for all 17 socket operations. This results in very different
lists of arguments depending on the task in hand. The first parameter of the system call is therefore
a numeric constant to select the desired call. Possible values are, for example,SYS_SOCKET,SYS_BIND,
SYS_ACCEPT,andSYS_RECV. The routines of the standard library use the same names but are all redirected
internally tosocketcallwith the corresponding constant. The fact that there is only a single system call
is primarily for historical reasons.

The task ofsys_socketcallis not especially difficult — it simply acts as a dispatcher to forward the
system call to other functions, each of which implements a ‘‘small‘‘ system call to which the parameters
are passed:

net/socket.c
asmlinkage long sys_socketcall(int call, unsigned long __user *args)
{
unsigned long a[6];
unsigned long a0,a1;
int err;

if(call<1||call>SYS_RECVMSG)
return -EINVAL;

/* copy_from_user should be SMP safe. */
if (copy_from_user(a, args, nargs[call]))
return -EFAULT;
...
a0=a[0];
a1=a[1];
Free download pdf