16ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru/* 26ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * netlink/cache-api.h Caching API 36ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 46ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * This library is free software; you can redistribute it and/or 56ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * modify it under the terms of the GNU Lesser General Public 66ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * License as published by the Free Software Foundation version 2.1 76ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * of the License. 86ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 96ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 106ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 116ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 126ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#ifndef NETLINK_CACHE_API_H_ 136ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#define NETLINK_CACHE_API_H_ 146ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 156ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#include <netlink/netlink.h> 166ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 176ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#ifdef __cplusplus 186ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queruextern "C" { 196ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#endif 206ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 216ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru/** 226ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @ingroup cache 236ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @defgroup cache_api Cache Implementation 246ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @brief 256ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 266ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @par 1) Cache Definition 276ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @code 286ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * struct nl_cache_ops my_cache_ops = { 296ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_name = "route/link", 306ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_protocol = NETLINK_ROUTE, 316ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_hdrsize = sizeof(struct ifinfomsg), 326ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_obj_ops = &my_obj_ops, 336ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * }; 346ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @endcode 356ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 366ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @par 2) 376ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @code 386ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // The simplest way to fill a cache is by providing a request-update 396ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // function which must trigger a complete dump on the kernel-side of 406ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // whatever the cache covers. 416ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * static int my_request_update(struct nl_cache *cache, 426ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * struct nl_sock *socket) 436ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { 446ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // In this example, we request a full dump of the interface table 456ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP); 466ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * } 476ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 486ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // The resulting netlink messages sent back will be fed into a message 496ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // parser one at a time. The message parser has to extract all relevant 506ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // information from the message and create an object reflecting the 516ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // contents of the message and pass it on to the parser callback function 526ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // provide which will add the object to the cache. 536ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who, 546ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * struct nlmsghdr *nlh, struct nl_parser_param *pp) 556ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { 566ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * struct my_obj *obj; 576ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 586ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * obj = my_obj_alloc(); 596ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * obj->ce_msgtype = nlh->nlmsg_type; 606ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 616ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // Parse the netlink message and continue creating the object. 626ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 636ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * err = pp->pp_cb((struct nl_object *) obj, pp); 646ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * if (err < 0) 656ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * goto errout; 666ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * } 676ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 686ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * struct nl_cache_ops my_cache_ops = { 696ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * ... 706ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_request_update = my_request_update, 716ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_msg_parser = my_msg_parser, 726ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * }; 736ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @endcode 746ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 756ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @par 3) Notification based Updates 766ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @code 776ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // Caches can be kept up-to-date based on notifications if the kernel 786ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // sends out notifications whenever an object is added/removed/changed. 796ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // 806ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // It is trivial to support this, first a list of groups needs to be 816ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // defined which are required to join in order to receive all necessary 826ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // notifications. The groups are separated by address family to support 836ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // the common situation where a separate group is used for each address 846ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // family. If there is only one group, simply specify AF_UNSPEC. 856ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * static struct nl_af_group addr_groups[] = { 866ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { AF_INET, RTNLGRP_IPV4_IFADDR }, 876ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { AF_INET6, RTNLGRP_IPV6_IFADDR }, 886ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { END_OF_GROUP_LIST }, 896ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * }; 906ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 916ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // In order for the caching system to know the meaning of each message 926ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // type it requires a table which maps each supported message type to 936ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // a cache action, e.g. RTM_NEWADDR means address has been added or 946ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // updated, RTM_DELADDR means address has been removed. 956ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * static struct nl_cache_ops rtnl_addr_ops = { 966ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * ... 976ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_msgtypes = { 986ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { RTM_NEWADDR, NL_ACT_NEW, "new" }, 996ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { RTM_DELADDR, NL_ACT_DEL, "del" }, 1006ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * { RTM_GETADDR, NL_ACT_GET, "get" }, 1016ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * END_OF_MSGTYPES_LIST, 1026ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * }, 1036ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * .co_groups = addr_groups, 1046ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * }; 1056ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * 1066ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * // It is now possible to keep the cache up-to-date using the cache manager. 1076ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @endcode 1086ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * @{ 1096ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 1106ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1116ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queruenum { 1126ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru NL_ACT_UNSPEC, 1136ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru NL_ACT_NEW, 1146ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru NL_ACT_DEL, 1156ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru NL_ACT_GET, 1166ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru NL_ACT_SET, 1176ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru NL_ACT_CHANGE, 1186ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru __NL_ACT_MAX, 1196ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru}; 1206ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1216ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#define NL_ACT_MAX (__NL_ACT_MAX - 1) 1226ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1236ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#define END_OF_MSGTYPES_LIST { -1, -1, NULL } 1246ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1256ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru/** 1266ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Message type to cache action association 1276ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 1286ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Querustruct nl_msgtype 1296ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru{ 1306ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** Netlink message type */ 1316ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int mt_id; 1326ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1336ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** Cache action to take */ 1346ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int mt_act; 1356ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1366ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** Name of operation for human-readable printing */ 1376ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru char * mt_name; 1386ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru}; 1396ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1406ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru/** 1416ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Address family to netlink group association 1426ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 1436ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Querustruct nl_af_group 1446ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru{ 1456ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** Address family */ 1466ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int ag_family; 1476ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1486ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** Netlink group identifier */ 1496ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int ag_group; 1506ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru}; 1516ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1526ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#define END_OF_GROUP_LIST AF_UNSPEC, 0 1536ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1546ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Querustruct nl_parser_param 1556ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru{ 1566ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int (*pp_cb)(struct nl_object *, struct nl_parser_param *); 1576ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru void * pp_arg; 1586ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru}; 1596ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1606ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru/** 1616ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Cache Operations 1626ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 1636ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Querustruct nl_cache_ops 1646ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru{ 1656ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru char * co_name; 1666ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1676ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int co_hdrsize; 1686ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int co_protocol; 1696ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct nl_af_group * co_groups; 1706ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1716ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** 1726ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Called whenever an update of the cache is required. Must send 1736ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * a request message to the kernel requesting a complete dump. 1746ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 1756ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int (*co_request_update)(struct nl_cache *, struct nl_sock *); 1766ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1776ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru /** 1786ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Called whenever a message was received that needs to be parsed. 1796ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * Must parse the message and call the paser callback function 1806ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru * (nl_parser_param) provided via the argument. 1816ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru */ 1826ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *, 1836ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct nlmsghdr *, struct nl_parser_param *); 1846ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1856ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct nl_object_ops * co_obj_ops; 1866ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1876ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct nl_cache_ops *co_next; 1886ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct nl_cache *co_major_cache; 1896ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct genl_ops * co_genl; 1906ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru struct nl_msgtype co_msgtypes[]; 1916ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru}; 1926ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1936ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru/** @} */ 1946ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1956ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#ifdef __cplusplus 1966ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru} 1976ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#endif 1986ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru 1996ccf7349d61f73ac26a0675d735d903ab919c658Jean-Baptiste Queru#endif 200