Original address: http://bbs.chinaunix.net/thread-1940094-1-1.html Most Linux kernel-state programs need to exchange data with user-space processes, but Linux kernel states cannot provide enough support for traditional methods of synchronizing and communicating between Linux processes. This article summarizes the common IPC, Getsockopt/setsockopt mmap netlink/socket proc/seq copy_from_user/copy_to_user file. After the introduction of the test code before the way, NetLink and proc because Jianggo and Duan brother have written better I posted a link ... Okay, no more nonsense, start.
I. getsockopt/setsockopt Recently looked at Ebtables source code, found that with the kernel of IPC is the use of getsockopt, the implementation is in the kernel with the NF_REGISTER_SOCKOPT function to register a NF_SOCKOPT_OPS structure, such as said: static struct Nf_sockopt_ops NSO = { . PF = pf_inet,//protocol family . Set_optmin = constant,//define minimum SET command word . Set_optmax = constant +n,//define maximum SET command word . Set = Do_nso_set,//define Set handler function . Get_optmin = constant,//define minimum GET command word . Get_optmax = constant +n,//define MAX GET command word . get = Do_nso_get,//define Set handler function }; Copy Code Where the command word cannot be duplicated with the system's existing command word. The Set/get handler function is called directly by the set/getsockopt function of the user space.
From this diagram can be seen, the essence of this method is the call is the Copy_from_user ()/copy_to_user () method to complete the kernel and user communication, which is not efficient, more use in the Transfer Control option information, not suitable for a large number of data transmission. Copy_from_user ()/copy_to_user () I'll explain in the following ... Of course for Linux anything is a file then I think should also be able to define their own ioctl, this in the back of the Copy_xx_user in the block device Setsockopt/getsockopt kernel part of the code: static int recv_msg (struct sock *sk, int cmd, void *user, unsigned int len) { int ret = 0; PRINTK (Kern_info "sockopt:recv_msg () \ n"); /* Switch (CMD) { Case Imp1_set: { Char umsg[64]; memset (umsg, 0, sizeof (char) *64); Copy_from_user (umsg, user, sizeof (char) *64); PRINTK ("Umsg:%s", umsg); } Break } */ if (cmd = = socket_ops_set) { Char umsg[64]; int len = sizeof (char) *64; memset (umsg, 0, Len); ret = Copy_from_user (umsg, user, Len); PRINTK ("recv_msg:umsg =%s. ret =%d\n", umsg, ret); } return 0; } static int send_msg (struct sock *sk, int cmd, void *user, int *len) { int ret = 0; PRINTK (Kern_info "sockopt:send_msg () \ n"); if (cmd = = socket_ops_get) { ret = copy_to_user (user, kmsg, kmsg_len); PRINTK ("send_msg:umsg =%s. Ret =%d. success\n", kmsg, ret); } return 0; } static struct Nf_sockopt_ops Test_sockops = { . PF = Pf_inet, . set_optmin = Socket_ops_set, . Set_optmax = Socket_ops_max, . set = Recv_msg, . get_optmin = Socket_ops_get, . Get_optmax = Socket_ops_max, . get = Send_msg, }; Copy Code Setsockopt/getsockopt User Part code: |
|