netfilter
firewalling, NAT, and packet mangling for linux
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Cache Implementation
Collaboration diagram for Cache Implementation:

Data Structures

struct  nl_msgtype
 Message type to cache action association. More...
 
struct  nl_af_group
 Address family to netlink group association. More...
 
struct  nl_parser_param
 
struct  nl_cache_ops
 Cache Operations. More...
 

Macros

#define NL_ACT_MAX   (__NL_ACT_MAX - 1)
 
#define END_OF_MSGTYPES_LIST   { -1, -1, NULL }
 
#define END_OF_GROUP_LIST   AF_UNSPEC, 0
 

Enumerations

enum  {
  NL_ACT_UNSPEC,
  NL_ACT_NEW,
  NL_ACT_DEL,
  NL_ACT_GET,
  NL_ACT_SET,
  NL_ACT_CHANGE,
  __NL_ACT_MAX
}
 

Detailed Description

1) Cache Definition
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,
};
2)
// 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_sock *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,
};
3) Notification based Updates
// 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 },
};
// 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 = {
...
{ RTM_NEWADDR, NL_ACT_NEW, "new" },
{ RTM_DELADDR, NL_ACT_DEL, "del" },
{ RTM_GETADDR, NL_ACT_GET, "get" },
},
.co_groups = addr_groups,
};
// It is now possible to keep the cache up-to-date using the cache manager.

Macro Definition Documentation

#define END_OF_GROUP_LIST   AF_UNSPEC, 0
#define END_OF_MSGTYPES_LIST   { -1, -1, NULL }
#define NL_ACT_MAX   (__NL_ACT_MAX - 1)

Enumeration Type Documentation

anonymous enum
Enumerator
NL_ACT_UNSPEC 
NL_ACT_NEW 
NL_ACT_DEL 
NL_ACT_GET 
NL_ACT_SET 
NL_ACT_CHANGE 
__NL_ACT_MAX