summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2007-09-17 11:36:16 (GMT)
committerThomas Graf <tgraf@suug.ch>2007-09-17 11:36:16 (GMT)
commit3040a1d6254465bed9e44e4d1bf279c2c50cd16a (patch)
tree29f557cdd57a8b3d6a1dd6accbc15845a44f3195
parent3d8efba91778b65a40d50ca0b6ba91d4071564c5 (diff)
downloadlibnl-3040a1d6254465bed9e44e4d1bf279c2c50cd16a.zip
libnl-3040a1d6254465bed9e44e4d1bf279c2c50cd16a.tar.gz
libnl-3040a1d6254465bed9e44e4d1bf279c2c50cd16a.tar.bz2
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.
-rw-r--r--include/netlink-local.h1
-rw-r--r--include/netlink-types.h64
-rw-r--r--include/netlink/cache-api.h199
-rw-r--r--lib/fib_lookup/lookup.c3
-rw-r--r--lib/genl/mngt.c4
-rw-r--r--lib/netfilter/ct.c3
-rw-r--r--lib/netfilter/log.c3
-rw-r--r--lib/route/addr.c3
-rw-r--r--lib/route/class.c3
-rw-r--r--lib/route/classifier.c3
-rw-r--r--lib/route/link.c3
-rw-r--r--lib/route/neigh.c3
-rw-r--r--lib/route/neightbl.c3
-rw-r--r--lib/route/qdisc.c3
-rw-r--r--lib/route/route.c3
-rw-r--r--lib/route/rule.c3
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();