libnl
3.2.3
|
00001 /* 00002 * netlink/cache-api.h Caching API 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 #ifndef NETLINK_CACHE_API_H_ 00013 #define NETLINK_CACHE_API_H_ 00014 00015 #include <netlink/netlink.h> 00016 00017 #ifdef __cplusplus 00018 extern "C" { 00019 #endif 00020 00021 /** 00022 * @ingroup cache 00023 * @defgroup cache_api Cache Implementation 00024 * @brief 00025 * 00026 * @par 1) Cache Definition 00027 * @code 00028 * struct nl_cache_ops my_cache_ops = { 00029 * .co_name = "route/link", 00030 * .co_protocol = NETLINK_ROUTE, 00031 * .co_hdrsize = sizeof(struct ifinfomsg), 00032 * .co_obj_ops = &my_obj_ops, 00033 * }; 00034 * @endcode 00035 * 00036 * @par 2) 00037 * @code 00038 * // The simplest way to fill a cache is by providing a request-update 00039 * // function which must trigger a complete dump on the kernel-side of 00040 * // whatever the cache covers. 00041 * static int my_request_update(struct nl_cache *cache, 00042 * struct nl_sock *socket) 00043 * { 00044 * // In this example, we request a full dump of the interface table 00045 * return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); 00046 * } 00047 * 00048 * // The resulting netlink messages sent back will be fed into a message 00049 * // parser one at a time. The message parser has to extract all relevant 00050 * // information from the message and create an object reflecting the 00051 * // contents of the message and pass it on to the parser callback function 00052 * // provide which will add the object to the cache. 00053 * static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 00054 * struct nlmsghdr *nlh, struct nl_parser_param *pp) 00055 * { 00056 * struct my_obj *obj; 00057 * 00058 * obj = my_obj_alloc(); 00059 * obj->ce_msgtype = nlh->nlmsg_type; 00060 * 00061 * // Parse the netlink message and continue creating the object. 00062 * 00063 * err = pp->pp_cb((struct nl_object *) obj, pp); 00064 * if (err < 0) 00065 * goto errout; 00066 * } 00067 * 00068 * struct nl_cache_ops my_cache_ops = { 00069 * ... 00070 * .co_request_update = my_request_update, 00071 * .co_msg_parser = my_msg_parser, 00072 * }; 00073 * @endcode 00074 * 00075 * @par 3) Notification based Updates 00076 * @code 00077 * // Caches can be kept up-to-date based on notifications if the kernel 00078 * // sends out notifications whenever an object is added/removed/changed. 00079 * // 00080 * // It is trivial to support this, first a list of groups needs to be 00081 * // defined which are required to join in order to receive all necessary 00082 * // notifications. The groups are separated by address family to support 00083 * // the common situation where a separate group is used for each address 00084 * // family. If there is only one group, simply specify AF_UNSPEC. 00085 * static struct nl_af_group addr_groups[] = { 00086 * { AF_INET, RTNLGRP_IPV4_IFADDR }, 00087 * { AF_INET6, RTNLGRP_IPV6_IFADDR }, 00088 * { END_OF_GROUP_LIST }, 00089 * }; 00090 * 00091 * // In order for the caching system to know the meaning of each message 00092 * // type it requires a table which maps each supported message type to 00093 * // a cache action, e.g. RTM_NEWADDR means address has been added or 00094 * // updated, RTM_DELADDR means address has been removed. 00095 * static struct nl_cache_ops rtnl_addr_ops = { 00096 * ... 00097 * .co_msgtypes = { 00098 * { RTM_NEWADDR, NL_ACT_NEW, "new" }, 00099 * { RTM_DELADDR, NL_ACT_DEL, "del" }, 00100 * { RTM_GETADDR, NL_ACT_GET, "get" }, 00101 * END_OF_MSGTYPES_LIST, 00102 * }, 00103 * .co_groups = addr_groups, 00104 * }; 00105 * 00106 * // It is now possible to keep the cache up-to-date using the cache manager. 00107 * @endcode 00108 * @{ 00109 */ 00110 00111 enum { 00112 NL_ACT_UNSPEC, 00113 NL_ACT_NEW, 00114 NL_ACT_DEL, 00115 NL_ACT_GET, 00116 NL_ACT_SET, 00117 NL_ACT_CHANGE, 00118 __NL_ACT_MAX, 00119 }; 00120 00121 #define NL_ACT_MAX (__NL_ACT_MAX - 1) 00122 00123 #define END_OF_MSGTYPES_LIST { -1, -1, NULL } 00124 00125 /** 00126 * Message type to cache action association 00127 */ 00128 struct nl_msgtype 00129 { 00130 /** Netlink message type */ 00131 int mt_id; 00132 00133 /** Cache action to take */ 00134 int mt_act; 00135 00136 /** Name of operation for human-readable printing */ 00137 char * mt_name; 00138 }; 00139 00140 /** 00141 * Address family to netlink group association 00142 */ 00143 struct nl_af_group 00144 { 00145 /** Address family */ 00146 int ag_family; 00147 00148 /** Netlink group identifier */ 00149 int ag_group; 00150 }; 00151 00152 #define END_OF_GROUP_LIST AF_UNSPEC, 0 00153 00154 /** 00155 * Parser parameters 00156 * 00157 * This structure is used to configure what kind of parser to use 00158 * when parsing netlink messages to create objects. 00159 */ 00160 struct nl_parser_param 00161 { 00162 /** Function to parse netlink messages into objects */ 00163 int (*pp_cb)(struct nl_object *, struct nl_parser_param *); 00164 00165 /** Arbitary argument to be passed to the parser */ 00166 void * pp_arg; 00167 }; 00168 00169 /** 00170 * Cache Operations 00171 * 00172 * This structure defines the characterstics of a cache type. It contains 00173 * pointers to functions which implement the specifics of the object type 00174 * the cache can hold. 00175 */ 00176 struct nl_cache_ops 00177 { 00178 /** Name of cache type (must be unique) */ 00179 char * co_name; 00180 00181 /** Size of family specific netlink header */ 00182 int co_hdrsize; 00183 00184 /** Netlink protocol */ 00185 int co_protocol; 00186 00187 /** Group definition */ 00188 struct nl_af_group * co_groups; 00189 00190 /** 00191 * Called whenever an update of the cache is required. Must send 00192 * a request message to the kernel requesting a complete dump. 00193 */ 00194 int (*co_request_update)(struct nl_cache *, struct nl_sock *); 00195 00196 /** 00197 * Called whenever a message was received that needs to be parsed. 00198 * Must parse the message and call the paser callback function 00199 * (nl_parser_param) provided via the argument. 00200 */ 00201 int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *, 00202 struct nlmsghdr *, struct nl_parser_param *); 00203 00204 /** 00205 * Called whenever a notification has been parsed into an object and 00206 * is considered for inclusion into a cache. Must return NL_SKIP if 00207 * the object should not be included in the cache. 00208 */ 00209 int (*co_event_filter)(struct nl_cache *, struct nl_object *obj); 00210 00211 /** Object operations */ 00212 struct nl_object_ops * co_obj_ops; 00213 00214 /** Internal, do not touch! */ 00215 struct nl_cache_ops *co_next; 00216 00217 struct nl_cache *co_major_cache; 00218 struct genl_ops * co_genl; 00219 00220 /* Message type definition */ 00221 struct nl_msgtype co_msgtypes[]; 00222 }; 00223 00224 /** @} */ 00225 00226 #ifdef __cplusplus 00227 } 00228 #endif 00229 00230 #endif