Quagga Source Code Analysis--Kernel communication netlink

Source: Internet
Author: User
Tags message queue semaphore

In the Linux operating system, when the CPU is in the kernel state, it can be divided into the state of the user context and the execution of hardware, software interrupt two. When in the user context, due to the kernel state and the user state of the memory mapping mechanism, not directly to the local variables to the user-State memory area, in the hardware, software interruption, can not directly pass data to the user memory area, code execution is not interruptible. For the traditional interprocess communication mechanism, they cannot be used directly between the kernel state and the user state, for the following table:

Communication methods

Reasons for not being in a kernel state or user state

pipeline (excluding named pipes)

Message Queuing

semaphore

memory share

Sockets

Data cannot be received without blocking in a hard, soft interrupt.

One, the solution of the kernel State and user-state communication mechanism can be divided into two categories:

    1. When you have a user context, you can use the Copy_from_user () and Copy_to_user () functions provided by Linux, but because the two functions may be blocked, they cannot be used during hardware or software outages.
    2. In the case of a hard, software interrupt.

2.1 The kernel thread can be synchronized with the interrupt process through the spinlock spin lock provided by the Linux kernel, because the kernel thread is running in a context-sensitive process, so the socket or message queue can be used in the kernel thread to obtain data from the user space and then pass the data through the critical section to the interrupt process .

2.2 is achieved through the NetLink mechanism. The NetLink socket is based on a process-specific identity that is generally identified as the ID of the process. The most important feature of NetLink communication is the support for the interrupt process, which no longer requires the user to start a kernel thread when the kernel space receives the user space data, but instead calls the user's pre-specified receive function through another soft interrupt. The timeliness of data transmission is ensured by soft interrupts rather than self-booting kernel threads.

Second, NetLink advantages

NetLink has the following advantages over other communication mechanisms:

By customizing a new protocol and joining the Protocol family, NetLink uses the NetLink protocol to complete data exchange through the socket API, and both the IOCTL and proc file systems need to be joined to the appropriate device or file via a program.
NetLink uses the socket cache queue, which is an asynchronous communication mechanism, and the IOCTL is a synchronous communication mechanism, which can affect system performance if the amount of data transferred is large.
NetLink supports multicasting, and modules and processes that belong to a NetLink group can get the multicast message.
NetLink allows the kernel to initiate sessions, while IOCTL and system calls can only be initiated by user-space processes.

Third, the NetLink in Quagga code

RT_LINK.C:

static const struct message nlmsg_str[] = {    {rtm_newroute, ' Rtm_newroute '},    {rtm_delroute, ' Rtm_delroute '},
   {Rtm_getroute, "Rtm_getroute"},    {rtm_newlink,  "Rtm_newlink"},    {rtm_dellink,  "Rtm_dellink"},    {rtm_getlink,  "Rtm_getlink"},    {rtm_newaddr,  "Rtm_newaddr"},    {rtm_deladdr,  "rtm_ Deladdr "},    {rtm_getaddr,  " Rtm_getaddr "},    {0, NULL}};

struct message nimsg_str[] Defines a description of the collection of NetLink message types that need to be used. As well as for the description string, in subsequent debug printing, such as _netlink_route_debug and other functions used.

The kernel registers the handler functions for these messages when the Rtnetlink is initialized:

1 void__init Rtnetlink_init (void)2 {3     if(Register_pernet_subsys (&rtnetlink_net_ops))4Panic"Rtnetlink_init:cannot Initialize rtnetlink\n");5 6Register_netdevice_notifier (&rtnetlink_dev_notifier);7 8 Rtnl_register (Pf_unspec, Rtm_getlink, Rtnl_getlink,9 Rtnl_dump_ifinfo, rtnl_calcit);Ten Rtnl_register (Pf_unspec, Rtm_setlink, rtnl_setlink, NULL, NULL); One Rtnl_register (Pf_unspec, Rtm_newlink, rtnl_newlink, NULL, NULL); A Rtnl_register (Pf_unspec, Rtm_dellink, rtnl_dellink, NULL, NULL); -  - Rtnl_register (pf_unspec, rtm_getaddr, NULL, rtnl_dump_all, NULL); the Rtnl_register (pf_unspec, Rtm_getroute, NULL, rtnl_dump_all, NULL); -  - Rtnl_register (Pf_bridge, Rtm_newneigh, rtnl_fdb_add, NULL, NULL); - Rtnl_register (Pf_bridge, Rtm_delneigh, rtnl_fdb_del, NULL, NULL); + Rtnl_register (Pf_bridge, Rtm_getneigh, NULL, rtnl_fdb_dump, NULL); -  + Rtnl_register (Pf_bridge, Rtm_getlink, NULL, rtnl_bridge_getlink, NULL); A Rtnl_register (Pf_bridge, Rtm_dellink, rtnl_bridge_dellink, NULL, NULL); at Rtnl_register (Pf_bridge, Rtm_setlink, rtnl_bridge_setlink, NULL, NULL); -}

OK, open the kernel path, the following to see how to use the User state:

1, the sock definition of Quagga

1 structNlsock2 {3   intsock;4   intseq;5   structsockaddr_nl SNL;6   Const Char*name;7 };8 9 structSockaddr_nl {Ten__kernel_sa_family_t nl_family;/*Af_netlink*/ OneUnsigned ShortNl_pad;/*Zero*/ A__u32 Nl_pid;/*Port ID*/ -__u32 nl_groups;/*Multicast Groups Mask*/ -};

2. Create socket

1 /*Make sockets for Linux NetLink interface.*/2 Static int3Netlink_socket (structNlsock *NL, unsignedLonggroups, vrf_id_t vrf_id) {4     intret;5     structsockaddr_nl SNL;6     intsock;7     intNamelen;8     intSave_errno;9 Ten     if(Zserv_privs.change (zprivs_raise)) { OneZlog (NULL, Log_err,"Can ' t raise privileges"); A         return-1; -     } -  theSock =Vrf_socket (Af_netlink, Sock_raw, Netlink_route, vrf_id); -     if(Sock <0) { -Zlog (NULL, Log_err,"Can ' t open%s socket:%s", nl->name, - Safe_strerror (errno)); +         return-1; -     } +  Amemset (&AMP;SNL,0,sizeofSNL); atsnl.nl_family =Af_netlink; -Snl.nl_groups =groups; -  -     /*Bind the socket to the NETLINK structure for anything.*/ -ret = bind (sock, (structSOCKADDR *) &AMP;SNL,sizeofSNL); -Save_errno =errno; in     if(Zserv_privs.change (Zprivs_lower)) Zlog (NULL, Log_err,"Can ' t lower privileges"); -  to     if(Ret <0) { +Zlog (NULL, Log_err,"Can ' t bind%s socket to group 0x%x:%s", -Nl->name, snl.nl_groups, Safe_strerror (Save_errno)); the Close (sock); *         return-1; $     }Panax Notoginseng  -     /*multiple NetLink sockets would have different nl_pid*/ theNamelen =sizeofSNL; +ret = getsockname (sock, (structSOCKADDR *) &AMP;SNL, (socklen_t *) &Namelen); A     if(Ret <0|| Namelen! =sizeofSNL) { theZlog (NULL, Log_err,"Can ' t get%s socket name:%s", nl->name, + Safe_strerror (errno)); - Close (sock); $         return-1; $     } -  -NL-&GT;SNL =SNL; theNl->sock =sock; -     returnret;Wuyi}

Quagga Source Code Analysis--Kernel communication netlink

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.