next up previous contents
Next: Sending and Receiving messages Up: Netlink sockets Previous: Protocol Registration   Contents

Netlink Socket creation

All socket related calls are handled by the sys_socketcall() in net/socket.c, depending on the type of operation requested say SYS_SOCKET, SYS_BIND, SYS_CONNECT etc, the appropriate function is invoked.

For socket creation, take a look at the code of sys_socketcall()

asmlinkage int sys_socketcall(int call, unsigned long *args)
{
    .
 	case SYS_SOCKET:
            err = sys_socket(a0,a1,a[2]);
            break;
    .
}

In sys_socket in net/socket.c the socket is created and a socket descriptor assigned for future reference. The section of the code is

asmlinkage int sys_socket(int family, int type, int protocol)
{
    .
    retval = sock_create(family, type, protocol, &sock);
    .
    retval = get_fd(sock->inode);
    .
}

The sections of code relevant in sock_create are

int sock_create(int family, int type, int protocol, struct socket **res)
{
    .
    .
    sock = sock_alloc();
    i = net_families[family]->create(sock, protocol);
    .
    .
}

For netlink sockets, as described earlier, netlink_create is called. This function associates the operations of the protocol with the socket.

static int netlink_create(struct socket *sock, int protocol)
{
    .
    .    	
    sock->ops = &netlink_ops;
    .
    .
}

netlink_ops gives the list of function pointers for the various operation associated with the netlink sockets.

struct proto_ops netlink_ops = {
    PF_NETLINK,

    sock_no_dup,
    netlink_release,
    netlink_bind,
    netlink_connect,
    sock_no_socketpair,
    sock_no_accept,
    netlink_getname,
    datagram_poll,
    sock_no_ioctl,
    sock_no_listen,
    sock_no_shutdown,
    sock_no_setsockopt,
    sock_no_getsockopt,
    sock_no_fcntl,
    netlink_sendmsg,
    netlink_recvmsg
};

After the netlink socket is created, the next step is to bind the socket, when a bind is issued from the user level, the sys_bind finction is called in the kernel, this in turn calls the bind function corresponding to the socket created, in our case it will be the netlink_bind that is called.

In netlink_bind, netlink_insert() is called which creates an entry for this netlink socket in the nl_table which is a list of sock structures.

static void netlink_insert(struct sock *sk)
{
    sk->next = nl_table[sk->protocol];
    nl_table[sk->protocol] = sk;
}
So the user code for the creation and binding of the netlink socket can be summarised as
 
	struct sockaddr_nl address;
	sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	bind(sock_fd, (struct sockaddr*)&address, sizeof(address));

where sockaddr_nl is defined in include/linux/netlink.h

struct sockaddr_nl
{
    sa_family_t nl_family;  /* AF_NETLINK   */
    unsigned short  nl_pad;     /* zero     */
    __u32       nl_pid;     /* process pid  */
    __u32       nl_groups;  /* multicast groups mask */
};

the family is AF_NETLINK, nl_groups is used for multicast options and the nl_pid is used to represent the process id, if this given as zero, the kernel gets the current->pid from the task structure and fills it. In the kernel the check for the pid is done and if is zero, netlink_autobind() is called which does the following,

static int netlink_autobind(struct socket *sock)
{
    struct sock *sk = sock->sk; 
    struct sock *osk;
    sk->protinfo.af_netlink.groups = 0;
    sk->protinfo.af_netlink.pid = current->pid;
    .
    .
    netlink_insert(sk);
}


next up previous contents
Next: Sending and Receiving messages Up: Netlink sockets Previous: Protocol Registration   Contents
Gowri Dhandapani
1999-10-03