next up previous contents
Next: NETLINK_ROUTE Family Up: Netlink sockets Previous: Netlink Socket creation   Contents

Sending and Receiving messages

After the socket is created and bound, we can read and write using recvmsg() and sendmsg() functions.
	sendmsg(sock_fd, &msg, 0);

where msg is of struct msghdr defined in /include/linux/socket.h

struct msghdr {
    void    *   msg_name;   /* Socket name          */
    int     msg_namelen;    /* Length of name       */
    struct iovec *  msg_iov;    /* Data blocks          */
    __kernel_size_t msg_iovlen; /* Number of blocks     */
    void    *   msg_control;    /* Per protocol magic (eg BSD file descriptor
								   passing) */
    __kernel_size_t msg_controllen; /* Length of cmsg list */
    unsigned    msg_flags;

This msghdr is filled as follows,

  struct msghdr msg = {
        (void*)&nladdr, sizeof(nladdr),
        &iov,   1,
        NULL,   0,

    memset(&nladdr, 0, sizeof(nladdr));
    nladdr.nl_family = AF_NETLINK;
    nladdr.nl_pid = 0;
    nladdr.nl_groups = 0;

where iov is of type struct iovec.

struct iovec
    void *iov_base;     /* BSD uses caddr_t (1003.1g requires void *) */
    __kernel_size_t iov_len; /* Must be size_t (1003.1g) */

This iovec structure is filled with the data pointer and the length of the data to be passed to the kernel. In netlink_sendmsg the data sent through the iovec is copied into the kernel space as follows,

static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, int len,
               struct scm_cookie *scm)
    memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);

So, the data to be sent to the kernel is filled up, the iovec structure initialised and the packet sent to the kernel. The data from the iovec is copied and processed in the kernel, how the data needs to be filled depends on the kind of operation that we need to perform. Note that the nladdr's pid is set to zero, the significance of which will be explained later.

Gowri Dhandapani