diff options
-rw-r--r-- | include/netlink-local.h | 1 | ||||
-rw-r--r-- | include/netlink-types.h | 64 | ||||
-rw-r--r-- | include/netlink/cache-api.h | 199 | ||||
-rw-r--r-- | lib/fib_lookup/lookup.c | 3 | ||||
-rw-r--r-- | lib/genl/mngt.c | 4 | ||||
-rw-r--r-- | lib/netfilter/ct.c | 3 | ||||
-rw-r--r-- | lib/netfilter/log.c | 3 | ||||
-rw-r--r-- | lib/route/addr.c | 3 | ||||
-rw-r--r-- | lib/route/class.c | 3 | ||||
-rw-r--r-- | lib/route/classifier.c | 3 | ||||
-rw-r--r-- | lib/route/link.c | 3 | ||||
-rw-r--r-- | lib/route/neigh.c | 3 | ||||
-rw-r--r-- | lib/route/neightbl.c | 3 | ||||
-rw-r--r-- | lib/route/qdisc.c | 3 | ||||
-rw-r--r-- | lib/route/route.c | 3 | ||||
-rw-r--r-- | lib/route/rule.c | 3 |
16 files changed, 214 insertions, 90 deletions
diff --git a/include/netlink-local.h b/include/netlink-local.h index f03b795..a4cc6ce 100644 --- a/include/netlink-local.h +++ b/include/netlink-local.h @@ -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 { diff --git a/include/netlink-types.h b/include/netlink-types.h index 8fea34c..e1145e1 100644 --- a/include/netlink-types.h +++ b/include/netlink-types.h @@ -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; diff --git a/include/netlink/cache-api.h b/include/netlink/cache-api.h new file mode 100644 index 0000000..96699ed --- /dev/null +++ b/include/netlink/cache-api.h @@ -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 diff --git a/lib/fib_lookup/lookup.c b/lib/fib_lookup/lookup.c index 2b0070d..d076ef9 100644 --- a/lib/fib_lookup/lookup.c +++ b/lib/fib_lookup/lookup.c @@ -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; diff --git a/lib/genl/mngt.c b/lib/genl/mngt.c index 846cd7e..d737697 100644 --- a/lib/genl/mngt.c +++ b/lib/genl/mngt.c @@ -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; diff --git a/lib/netfilter/ct.c b/lib/netfilter/ct.c index 24b67fd..195c98f 100644 --- a/lib/netfilter/ct.c +++ b/lib/netfilter/ct.c @@ -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; diff --git a/lib/netfilter/log.c b/lib/netfilter/log.c index ccc90a8..d8b3521 100644 --- a/lib/netfilter/log.c +++ b/lib/netfilter/log.c @@ -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; diff --git a/lib/route/addr.c b/lib/route/addr.c index 1947b5a..b1fa7d0 100644 --- a/lib/route/addr.c +++ b/lib/route/addr.c @@ -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; diff --git a/lib/route/class.c b/lib/route/class.c index 7f2289e..efa8cb4 100644 --- a/lib/route/class.c +++ b/lib/route/class.c @@ -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; diff --git a/lib/route/classifier.c b/lib/route/classifier.c index 7ad4722..a661d9b 100644 --- a/lib/route/classifier.c +++ b/lib/route/classifier.c @@ -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; diff --git a/lib/route/link.c b/lib/route/link.c index 7ecae12..4774a58 100644 --- a/lib/route/link.c +++ b/lib/route/link.c @@ -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(); diff --git a/lib/route/neigh.c b/lib/route/neigh.c index aac4718..5d6bf7a 100644 --- a/lib/route/neigh.c +++ b/lib/route/neigh.c @@ -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; diff --git a/lib/route/neightbl.c b/lib/route/neightbl.c index afd64a6..38c345d 100644 --- a/lib/route/neightbl.c +++ b/lib/route/neightbl.c @@ -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; diff --git a/lib/route/qdisc.c b/lib/route/qdisc.c index 818ca7b..19bf12a 100644 --- a/lib/route/qdisc.c +++ b/lib/route/qdisc.c @@ -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; diff --git a/lib/route/route.c b/lib/route/route.c index 4382e19..1254b36 100644 --- a/lib/route/route.c +++ b/lib/route/route.c @@ -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]; diff --git a/lib/route/rule.c b/lib/route/rule.c index 76e0060..85a431b 100644 --- a/lib/route/rule.c +++ b/lib/route/rule.c @@ -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(); |