Export interface to define caches

This interface was internal so far which required all code defining
caches to be compiled with the sources available.

In order to simplify the interface, the co_msg_parser prototype was
changed to take the struct nl_parser_param directly instead of a
void *. It used to be void * because the co_msg_parser was directly
passed as the NL_CB_VALID callback function.
This commit is contained in:
Thomas Graf 2007-09-17 13:36:16 +02:00
parent 3d8efba917
commit 3040a1d625
16 changed files with 214 additions and 90 deletions

View file

@ -54,6 +54,7 @@ typedef uint64_t __u64;
#include <netlink/cache.h>
#include <netlink/route/tc.h>
#include <netlink/object-api.h>
#include <netlink/cache-api.h>
#include <netlink-types.h>
struct trans_tbl {

View file

@ -95,27 +95,6 @@ struct nl_cache_mngr
struct nl_parser_param;
enum {
NL_ACT_UNSPEC,
NL_ACT_NEW,
NL_ACT_DEL,
NL_ACT_GET,
NL_ACT_SET,
NL_ACT_CHANGE,
__NL_ACT_MAX,
};
#define NL_ACT_MAX (__NL_ACT_MAX - 1)
#define END_OF_MSGTYPES_LIST { -1, -1, NULL }
struct nl_msgtype
{
int mt_id;
int mt_act;
char * mt_name;
};
struct genl_info
{
struct sockaddr_nl * who;
@ -127,43 +106,6 @@ struct genl_info
#define LOOSE_FLAG_COMPARISON 1
struct nl_af_group
{
int ag_family;
int ag_group;
};
#define END_OF_GROUP_LIST AF_UNSPEC, 0
struct nl_cache_ops
{
char * co_name;
int co_hdrsize;
int co_protocol;
struct nl_af_group * co_groups;
/**
* Called whenever an update of the cache is required. Must send
* a request message to the kernel requesting a complete dump.
*/
int (*co_request_update)(struct nl_cache *, struct nl_handle *);
/**
* Called whenever a message was received that needs to be parsed.
* Must parse the message and call the paser callback function
* (nl_parser_param) provided via the argument.
*/
int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *,
struct nlmsghdr *, void *);
struct nl_object_ops * co_obj_ops;
struct nl_cache_ops *co_next;
struct nl_cache *co_major_cache;
struct genl_ops * co_genl;
struct nl_msgtype co_msgtypes[];
};
#define NL_OBJ_MARK 1
struct nl_object
@ -171,12 +113,6 @@ struct nl_object
NLHDR_COMMON
};
struct nl_parser_param
{
int (*pp_cb)(struct nl_object *, struct nl_parser_param *);
void * pp_arg;
};
struct nl_data
{
size_t d_size;

199
include/netlink/cache-api.h Normal file
View file

@ -0,0 +1,199 @@
/*
* netlink/cache-api.h Caching API
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_CACHE_API_H_
#define NETLINK_CACHE_API_H_
#include <netlink/netlink.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup cache
* @defgroup cache_api Cache Implementation
* @brief
*
* @par 1) Cache Definition
* @code
* struct nl_cache_ops my_cache_ops = {
* .co_name = "route/link",
* .co_protocol = NETLINK_ROUTE,
* .co_hdrsize = sizeof(struct ifinfomsg),
* .co_obj_ops = &my_obj_ops,
* };
* @endcode
*
* @par 2)
* @code
* // The simplest way to fill a cache is by providing a request-update
* // function which must trigger a complete dump on the kernel-side of
* // whatever the cache covers.
* static int my_request_update(struct nl_cache *cache,
* struct nl_handle *socket)
* {
* // In this example, we request a full dump of the interface table
* return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP);
* }
*
* // The resulting netlink messages sent back will be fed into a message
* // parser one at a time. The message parser has to extract all relevant
* // information from the message and create an object reflecting the
* // contents of the message and pass it on to the parser callback function
* // provide which will add the object to the cache.
* static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
* struct nlmsghdr *nlh, struct nl_parser_param *pp)
* {
* struct my_obj *obj;
*
* obj = my_obj_alloc();
* obj->ce_msgtype = nlh->nlmsg_type;
*
* // Parse the netlink message and continue creating the object.
*
* err = pp->pp_cb((struct nl_object *) obj, pp);
* if (err < 0)
* goto errout;
* }
*
* struct nl_cache_ops my_cache_ops = {
* ...
* .co_request_update = my_request_update,
* .co_msg_parser = my_msg_parser,
* };
* @endcode
*
* @par 3) Notification based Updates
* @code
* // Caches can be kept up-to-date based on notifications if the kernel
* // sends out notifications whenever an object is added/removed/changed.
* //
* // It is trivial to support this, first a list of groups needs to be
* // defined which are required to join in order to receive all necessary
* // notifications. The groups are separated by address family to support
* // the common situation where a separate group is used for each address
* // family. If there is only one group, simply specify AF_UNSPEC.
* static struct nl_af_group addr_groups[] = {
* { AF_INET, RTNLGRP_IPV4_IFADDR },
* { AF_INET6, RTNLGRP_IPV6_IFADDR },
* { END_OF_GROUP_LIST },
* };
*
* // In order for the caching system to know the meaning of each message
* // type it requires a table which maps each supported message type to
* // a cache action, e.g. RTM_NEWADDR means address has been added or
* // updated, RTM_DELADDR means address has been removed.
* static struct nl_cache_ops rtnl_addr_ops = {
* ...
* .co_msgtypes = {
* { RTM_NEWADDR, NL_ACT_NEW, "new" },
* { RTM_DELADDR, NL_ACT_DEL, "del" },
* { RTM_GETADDR, NL_ACT_GET, "get" },
* END_OF_MSGTYPES_LIST,
* },
* .co_groups = addr_groups,
* };
*
* // It is now possible to keep the cache up-to-date using the cache manager.
* @endcode
* @{
*/
enum {
NL_ACT_UNSPEC,
NL_ACT_NEW,
NL_ACT_DEL,
NL_ACT_GET,
NL_ACT_SET,
NL_ACT_CHANGE,
__NL_ACT_MAX,
};
#define NL_ACT_MAX (__NL_ACT_MAX - 1)
#define END_OF_MSGTYPES_LIST { -1, -1, NULL }
/**
* Message type to cache action association
*/
struct nl_msgtype
{
/** Netlink message type */
int mt_id;
/** Cache action to take */
int mt_act;
/** Name of operation for human-readable printing */
char * mt_name;
};
/**
* Address family to netlink group association
*/
struct nl_af_group
{
/** Address family */
int ag_family;
/** Netlink group identifier */
int ag_group;
};
#define END_OF_GROUP_LIST AF_UNSPEC, 0
struct nl_parser_param
{
int (*pp_cb)(struct nl_object *, struct nl_parser_param *);
void * pp_arg;
};
/**
* Cache Operations
*/
struct nl_cache_ops
{
char * co_name;
int co_hdrsize;
int co_protocol;
struct nl_af_group * co_groups;
/**
* Called whenever an update of the cache is required. Must send
* a request message to the kernel requesting a complete dump.
*/
int (*co_request_update)(struct nl_cache *, struct nl_handle *);
/**
* Called whenever a message was received that needs to be parsed.
* Must parse the message and call the paser callback function
* (nl_parser_param) provided via the argument.
*/
int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *,
struct nlmsghdr *, struct nl_parser_param *);
struct nl_object_ops * co_obj_ops;
struct nl_cache_ops *co_next;
struct nl_cache *co_major_cache;
struct genl_ops * co_genl;
struct nl_msgtype co_msgtypes[];
};
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View file

@ -69,11 +69,10 @@ static int result_clone(struct nl_object *_dst, struct nl_object *_src)
}
static int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
struct nlmsghdr *n, struct nl_parser_param *pp)
{
struct flnl_result *res;
struct fib_result_nl *fr;
struct nl_parser_param *pp = arg;
struct nl_addr *addr;
int err = -EINVAL;

View file

@ -91,7 +91,7 @@
static NL_LIST_HEAD(genl_ops_list);
static int genl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, void *arg)
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
int i, err;
struct genlmsghdr *ghdr;
@ -129,7 +129,7 @@ found:
if (err < 0)
goto errout;
err = cmd->c_msg_parser(ops, cmd, &info, arg);
err = cmd->c_msg_parser(ops, cmd, &info, pp);
}
errout:
return err;

View file

@ -353,9 +353,8 @@ errout:
}
static int ct_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, void *arg)
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
struct nl_parser_param *pp = arg;
struct nfnl_ct *ct;
int err;

View file

@ -161,9 +161,8 @@ errout:
}
static int log_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, void *arg)
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
struct nl_parser_param *pp = arg;
struct nfnl_log *log;
int err;

View file

@ -184,10 +184,9 @@ static struct nla_policy addr_policy[IFA_MAX+1] = {
};
static int addr_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, void *arg)
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
struct rtnl_addr *addr;
struct nl_parser_param *pp = arg;
struct ifaddrmsg *ifa;
struct nlattr *tb[IFA_MAX+1];
int err = -ENOMEM, peer_prefix = 0;

View file

@ -28,10 +28,9 @@
static struct nl_cache_ops rtnl_class_ops;
static int class_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
struct nlmsghdr *n, struct nl_parser_param *pp)
{
int err;
struct nl_parser_param *pp = arg;
struct rtnl_class *class;
struct rtnl_class_ops *cops;

View file

@ -36,10 +36,9 @@
static struct nl_cache_ops rtnl_cls_ops;
static int cls_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, void *arg)
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
int err;
struct nl_parser_param *pp = arg;
struct rtnl_cls *cls;
struct rtnl_cls_ops *cops;

View file

@ -199,12 +199,11 @@ static struct nla_policy link_policy[IFLA_MAX+1] = {
};
static int link_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
struct nlmsghdr *n, struct nl_parser_param *pp)
{
struct rtnl_link *link;
struct ifinfomsg *ifi;
struct nlattr *tb[IFLA_MAX+1];
struct nl_parser_param *pp = arg;
int err;
link = rtnl_link_alloc();

View file

@ -252,11 +252,10 @@ static struct nla_policy neigh_policy[NDA_MAX+1] = {
};
static int neigh_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
struct nlmsghdr *n, struct nl_parser_param *pp)
{
struct rtnl_neigh *neigh;
struct nlattr *tb[NDA_MAX + 1];
struct nl_parser_param *pp = arg;
struct ndmsg *nm;
int err;

View file

@ -120,11 +120,10 @@ static struct nla_policy neightbl_policy[NDTA_MAX+1] = {
static int neightbl_msg_parser(struct nl_cache_ops *ops,
struct sockaddr_nl *who, struct nlmsghdr *n,
void *arg)
struct nl_parser_param *pp)
{
struct rtnl_neightbl *ntbl;
struct nlattr *tb[NDTA_MAX + 1];
struct nl_parser_param *pp = arg;
struct rtgenmsg *rtmsg;
int err;

View file

@ -96,10 +96,9 @@
static struct nl_cache_ops rtnl_qdisc_ops;
static int qdisc_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
struct nlmsghdr *n, struct nl_parser_param *pp)
{
int err = -ENOMEM;
struct nl_parser_param *pp = arg;
struct rtnl_qdisc *qdisc;
struct rtnl_qdisc_ops *qops;

View file

@ -57,9 +57,8 @@ static void copy_cacheinfo_into_route(struct rta_cacheinfo *ci,
}
static int route_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *nlh, void *arg)
struct nlmsghdr *nlh, struct nl_parser_param *pp)
{
struct nl_parser_param *pp = arg;
struct rtmsg *rtm;
struct rtnl_route *route;
struct nlattr *tb[RTA_MAX + 1];

View file

@ -80,12 +80,11 @@ static struct nla_policy rule_policy[RTA_MAX+1] = {
};
static int rule_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, void *arg)
struct nlmsghdr *n, struct nl_parser_param *pp)
{
struct rtnl_rule *rule;
struct rtmsg *r;
struct nlattr *tb[RTA_MAX+1];
struct nl_parser_param *pp = arg;
int err = 1;
rule = rtnl_rule_alloc();