netlink多播

来源:互联网 发布:摄像头改网络编码器 编辑:程序博客网 时间:2024/06/05 07:16
Multicast Communication between Kernel and Applications

In this example, two user-space applications are listening to the same netlink multicast group. The kernel module pops up a message through netlink socket to the multicast group, and all the applications receive it. Here is the user-space code:

#include <sys/socket.h>#include <linux/netlink.h>#define MAX_PAYLOAD 1024  /* maximum payload size*/struct sockaddr_nl src_addr, dest_addr;struct nlmsghdr *nlh = NULL;struct iovec iov;int sock_fd;void main() { sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST); memset(&src_addr, 0, sizeof(local_addr)); src_addr.nl_family = AF_NETLINK; src_addr.nl_pid = getpid();  /* self pid */ /* interested in group 1<<0 */ src_addr.nl_groups = 1;##多播组id
  bind(sock_fd, (struct sockaddr*)&src_addr,      sizeof(src_addr)); memset(&dest_addr, 0, sizeof(dest_addr)); nlh = (struct nlmsghdr *)malloc(                          NLMSG_SPACE(MAX_PAYLOAD)); memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); iov.iov_base = (void *)nlh; iov.iov_len = NLMSG_SPACE(MAX_PAYLOAD); msg.msg_name = (void *)&dest_addr; msg.msg_namelen = sizeof(dest_addr); msg.msg_iov = &iov; msg.msg_iovlen = 1; printf("Waiting for message from kernel\n"); /* Read message from kernel */ recvmsg(fd, &msg, 0); printf(" Received message payload: %s\n",        NLMSG_DATA(nlh)); close(sock_fd);}

And, here is the kernel code:

#define MAX_PAYLOAD 1024struct sock *nl_sk = NULL;void netlink_test() { sturct sk_buff *skb = NULL; struct nlmsghdr *nlh; int err; nl_sk = netlink_kernel_create(NETLINK_TEST,                               nl_data_ready); skb=alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL); nlh = (struct nlmsghdr *)skb->data; nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = 0;  /* from kernel */ nlh->nlmsg_flags = 0; strcpy(NLMSG_DATA(nlh), "Greeting from kernel!"); /* sender is in group 1<<0 */ NETLINK_CB(skb).groups = 1;##多播 NETLINK_CB(skb).pid = 0;  /* from kernel */ NETLINK_CB(skb).dst_pid = 0;  /* multicast 不是目的pid*/ /* to mcast group 1<<0 */ NETLINK_CB(skb).dst_groups = 1;多播组id /*multicast the message to all listening processes*/ netlink_broadcast(nl_sk, skb, 0, 1, GFP_KERNEL); sock_release(nl_sk->socket);}

Assuming the user-space code is compiled into the executable nl_recv, we can run two instances of nl_recv:

./nl_recv &Waiting for message from kernel./nl_recv &Waiting for message from kernel

Then, after we load the kernel module that executes the kernel-space code, both instances of nl_recv should receive the following message:

Received message payload: Greeting from kernel!Received message payload: Greeting from kernel!

Conclusion

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.

Kevin Kaichuan He (hek_u5@yahoo.com) is a principal software engineer at Solustek Corp. He currently is working on embedded system, device driver and networking protocols projects. His previous work experience includes senior software engineer at Cisco Systems and research assistant at CS, Purdue University. In his spare time, he enjoys digital photography, PS2 games and literature.

0 0
原创粉丝点击