<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>libnl: Cache Implementation</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css"/> </head> <body> <!-- Generated by Doxygen 1.7.3 --> <div id="top"> <div id="titlearea"> <table cellspacing="0" cellpadding="0"> <tbody> <tr style="height: 56px;"> <td style="padding-left: 0.5em;"> <div id="projectname">libnl <span id="projectnumber">1.1</span></div> </td> </tr> </tbody> </table> </div> <div id="navrow1" class="tabs"> <ul class="tablist"> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> </ul> </div> </div> <div class="header"> <div class="summary"> <a href="#nested-classes">Data Structures</a> | <a href="#define-members">Defines</a> | <a href="#enum-members">Enumerations</a> </div> <div class="headertitle"> <h1>Cache Implementation</h1> </div> <div class="ingroups"><a class="el" href="group__cache.html">Cache</a></div></div> <div class="contents"> <table class="memberdecls"> <tr><td colspan="2"><h2><a name="nested-classes"></a> Data Structures</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="structnl__msgtype.html">nl_msgtype</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Message type to cache action association. <a href="structnl__msgtype.html#_details">More...</a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="structnl__af__group.html">nl_af_group</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Address family to netlink group association. <a href="structnl__af__group.html#_details">More...</a><br/></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="structnl__parser__param.html">nl_parser_param</a></td></tr> <tr><td class="memItemLeft" align="right" valign="top">struct  </td><td class="memItemRight" valign="bottom"><a class="el" href="structnl__cache__ops.html">nl_cache_ops</a></td></tr> <tr><td class="mdescLeft"> </td><td class="mdescRight">Cache Operations. <a href="structnl__cache__ops.html#_details">More...</a><br/></td></tr> <tr><td colspan="2"><h2><a name="define-members"></a> Defines</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="ga66849a5e1c9a8183d541449b8b758155"></a><!-- doxytag: member="cache_api::NL_ACT_MAX" ref="ga66849a5e1c9a8183d541449b8b758155" args="" --> #define </td><td class="memItemRight" valign="bottom"><b>NL_ACT_MAX</b>   (__NL_ACT_MAX - 1)</td></tr> <tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="gacaf5bba6424e223ad9e0e9ea23451303"></a><!-- doxytag: member="cache_api::END_OF_MSGTYPES_LIST" ref="gacaf5bba6424e223ad9e0e9ea23451303" args="" --> #define </td><td class="memItemRight" valign="bottom"><b>END_OF_MSGTYPES_LIST</b>   { -1, -1, NULL }</td></tr> <tr><td class="memItemLeft" align="right" valign="top"><a class="anchor" id="gaae512508ffeb48dcf4b71867d07277f9"></a><!-- doxytag: member="cache_api::END_OF_GROUP_LIST" ref="gaae512508ffeb48dcf4b71867d07277f9" args="" --> #define </td><td class="memItemRight" valign="bottom"><b>END_OF_GROUP_LIST</b>   AF_UNSPEC, 0</td></tr> <tr><td colspan="2"><h2><a name="enum-members"></a> Enumerations</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">enum  </td><td class="memItemRight" valign="bottom">{ <br/>   <b>NL_ACT_UNSPEC</b>, <b>NL_ACT_NEW</b>, <b>NL_ACT_DEL</b>, <b>NL_ACT_GET</b>, <br/>   <b>NL_ACT_SET</b>, <b>NL_ACT_CHANGE</b>, <b>__NL_ACT_MAX</b> <br/> }</td></tr> </table> <hr/><a name="_details"></a><h2>Detailed Description</h2> <dl class="user"><dt><b>1) Cache Definition</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="keyword">struct </span><a class="code" href="structnl__cache__ops.html" title="Cache Operations.">nl_cache_ops</a> my_cache_ops = { .co_name = <span class="stringliteral">"route/link"</span>, .co_protocol = NETLINK_ROUTE, .co_hdrsize = <span class="keyword">sizeof</span>(<span class="keyword">struct </span>ifinfomsg), .co_obj_ops = &my_obj_ops, }; </pre></div></dd></dl> <dl class="user"><dt><b>2) </b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// The simplest way to fill a cache is by providing a request-update</span> <span class="comment">// function which must trigger a complete dump on the kernel-side of</span> <span class="comment">// whatever the cache covers.</span> <span class="keyword">static</span> <span class="keywordtype">int</span> my_request_update(<span class="keyword">struct</span> nl_cache *cache, <span class="keyword">struct</span> nl_handle *socket) { <span class="comment">// In this example, we request a full dump of the interface table</span> <span class="keywordflow">return</span> <a class="code" href="group__rtnl.html#ga1fcd1a88d7f810c50849f13d97b5fe10" title="Send routing netlink request message.">nl_rtgen_request</a>(socket, RTM_GETLINK, AF_UNSPEC, <a class="code" href="group__msg.html#ga8d4fb2458c013decb6673f41c52c07b1" title="Dump all entries.">NLM_F_DUMP</a>); } <span class="comment">// The resulting netlink messages sent back will be fed into a message</span> <span class="comment">// parser one at a time. The message parser has to extract all relevant</span> <span class="comment">// information from the message and create an object reflecting the</span> <span class="comment">// contents of the message and pass it on to the parser callback function</span> <span class="comment">// provide which will add the object to the cache.</span> <span class="keyword">static</span> <span class="keywordtype">int</span> my_msg_parser(<span class="keyword">struct</span> <a class="code" href="structnl__cache__ops.html" title="Cache Operations.">nl_cache_ops</a> *ops, <span class="keyword">struct</span> <a class="code" href="structsockaddr__nl.html" title="Netlink socket address.">sockaddr_nl</a> *who, <span class="keyword">struct</span> <a class="code" href="structnlmsghdr.html" title="Netlink message header.">nlmsghdr</a> *nlh, <span class="keyword">struct</span> <a class="code" href="structnl__parser__param.html">nl_parser_param</a> *pp) { <span class="keyword">struct </span>my_obj *obj; obj = my_obj_alloc(); obj->ce_msgtype = nlh-><a class="code" href="structnlmsghdr.html#a7232c4e6cb513010e64887b7eebf8823" title="Message type (content type)">nlmsg_type</a>; <span class="comment">// Parse the netlink message and continue creating the object.</span> err = pp->pp_cb((<span class="keyword">struct</span> nl_object *) obj, pp); <span class="keywordflow">if</span> (err < 0) <span class="keywordflow">goto</span> errout; } <span class="keyword">struct </span><a class="code" href="structnl__cache__ops.html" title="Cache Operations.">nl_cache_ops</a> my_cache_ops = { ... .<a class="code" href="structnl__cache__ops.html#a93ec4756f5c0ae7c105cf3b3b1473476" title="Called whenever an update of the cache is required.">co_request_update</a> = my_request_update, .co_msg_parser = my_msg_parser, }; </pre></div></dd></dl> <dl class="user"><dt><b>3) Notification based Updates</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// Caches can be kept up-to-date based on notifications if the kernel</span> <span class="comment">// sends out notifications whenever an object is added/removed/changed.</span> <span class="comment">//</span> <span class="comment">// It is trivial to support this, first a list of groups needs to be</span> <span class="comment">// defined which are required to join in order to receive all necessary</span> <span class="comment">// notifications. The groups are separated by address family to support</span> <span class="comment">// the common situation where a separate group is used for each address</span> <span class="comment">// family. If there is only one group, simply specify AF_UNSPEC.</span> <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structnl__af__group.html" title="Address family to netlink group association.">nl_af_group</a> addr_groups[] = { { AF_INET, RTNLGRP_IPV4_IFADDR }, { AF_INET6, RTNLGRP_IPV6_IFADDR }, { END_OF_GROUP_LIST }, }; <span class="comment">// In order for the caching system to know the meaning of each message</span> <span class="comment">// type it requires a table which maps each supported message type to</span> <span class="comment">// a cache action, e.g. RTM_NEWADDR means address has been added or</span> <span class="comment">// updated, RTM_DELADDR means address has been removed.</span> <span class="keyword">static</span> <span class="keyword">struct </span><a class="code" href="structnl__cache__ops.html" title="Cache Operations.">nl_cache_ops</a> rtnl_addr_ops = { ... .co_msgtypes = { { RTM_NEWADDR, NL_ACT_NEW, <span class="stringliteral">"new"</span> }, { RTM_DELADDR, NL_ACT_DEL, <span class="stringliteral">"del"</span> }, { RTM_GETADDR, NL_ACT_GET, <span class="stringliteral">"get"</span> }, END_OF_MSGTYPES_LIST, }, .co_groups = addr_groups, }; <span class="comment">// It is now possible to keep the cache up-to-date using the cache manager.</span> </pre></div> </dd></dl> </div> <hr class="footer"/><address class="footer"><small>Generated on Mon Mar 21 2011 for libnl by  <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.3 </small></address> </body> </html>