netlink API changes

来源:互联网 发布:如何彻底卸载java mac 编辑:程序博客网 时间:2024/05/01 20:27

Netlink socket is a flexible interface for communication between user-space applications and kernel modules. It provides an easy-to-use socket API to both applications and the kernel. It provides advanced communication features, such as full-duplex, buffered I/O, multicast and asynchronous communication, which are absent in other kernel/user-space IPCs. But the netlink interface in Linux is fast changing,the APIs vary a lot between different kernel versions.Here is the changed interfaces in Linux kernel 2.6.37

netlink_kernel_create

This method is called to create a netlink socket in kernel modules.In ealier version of the kernel this functions is defined as this:

struct sock *

netlink_kernel_create(int unit,

           void (*input)(struct sock *sk, int len));

The parameter unit is, in fact, the netlink protocol type, such as NETLINK_TEST. The function pointer, input, is a callback function invoked 

when a message arrives at this netlink socket. while in 2.6.37 the function is defined as below in /linux/netlink.h

extern struct sock *netlink_kernel_create(struct net *net,

int unit,unsigned int groups,

void (*input)(struct sk_buff *skb),

struct mutex *cb_mutex,

struct module *module);

There are some newly-added parameters:

 

struct net *net:the namespace of network.using &init_net is ok.

unsigned int groups:the group number of the socket.pass NULL to this parameter

struct mutex *cb_mutex:NULL is OK

struct module *module:use the THIS_MODULE macro

 

notice that the prototype of the callback func input has also been changed.

sk_buff in handler function

All network-related queues and buffers in the kernel use a common data structure, struct sk_buff. This is a large struct containing all the control information required for the packet (datagram, cell, whatever). The sk_buff elements are organized as a doubly linked list, in such a way that it is very efficient to move an sk_buff element from the beginning/end of a list to the beginning/end of another list. A queue is defined by struct sk_buff_head, which includes a head and a tail pointer to sk_buff elements. 

All the queuing structures include an sk_buff_head representing the queue. For instance, struct sock includes a receive and send queue. Functions to manage the queues (skb_queue_head(), skb_queue_tail(), skb_dequeue(), skb_dequeue_tail()) operate on an sk_buff_head. In reality, however, the sk_buff_head is included in the doubly linked list of sk_buffs (so it actually forms a ring). 

When a sk_buff is allocated, also its data space is allocated from kernel memory. sk_buff allocation is done with alloc_skb() or dev_alloc_skb(); drivers use dev_alloc_skb();. (free by kfree_skb() and dev_kfree_skb(). 

However, sk_buff provides an additional management layer. The data space is divided into a head area and a data area. This allows kernel functions to reserve space for the header, so that the data doesn't need to be copied around. Typically, therefore, after allocating an sk_buff, header space is reserved using skb_reserve(). skb_pull(int len) – removes data from the start of a buffer (skipping over an existing header) by advancing data to data+len and by decreasing len. 

Sample Code

Below is the sample code I wrote. The user send a greeting message to kernel module and the kernel module print the message,then send a greeting message back to the user app.(Linux kernel version 2.6.37,os openSUSE 11.4)

kernel module:

 

User App:

 

 

原创粉丝点击