example code: my_nl_cache_exclude_non_matching(...)
Pedro Francisco
pedrogfrancisco at gmail.com
Tue Mar 30 20:02:38 EDT 2010
For the sake of completeness, since I couldn't use
* cache_subset() nor
* tricks with nl_cache_move() nor
* other tricks with callbacks
in order to get a subset of a cache which only had the interfaces which
matched a filter (see my previous mail: the interfaces' addresses at the second
cache would appear as "none"), I created the
void my_nl_cache_exclude_non_matching(struct nl_cache *target, struct
rtnl_addr* filter)
my_nl_cache_exclude_non_matching(...) strips all the interfaces from a cache
which don't verify a certain condition. It doesn't create a copy of the cache,
it strips of the cache which is provided as parameter those rtnl_addr not
matching the filter.
In the event anyone else has the same problem, here it is. I hope it is
useful.
It's available together with example code on http://pastebin.com/pmYFTPUQ or
below:
#include <stdio.h>
#include <assert.h>
#include <netlink/route/link.h>
#include <netlink/route/addr.h>
void my_nl_cache_exclude_non_matching(struct nl_cache *target, struct
rtnl_addr* filter);
/* too much information */
//int nl_debug = 1;
//#define VERBOSE_ERRORS 1
int main(int argc, char *argv[])
{
struct nl_handle *nlh = NULL;
struct nl_cache *link_cache = NULL;
struct nl_cache *addr_cache = NULL;
struct nl_cache *filtered_cache = NULL;
struct rtnl_addr *addr = NULL;
struct nl_dump_params params;
int err = 1;
nlh = nl_handle_alloc();
if (!nlh)
return -1;
addr = rtnl_addr_alloc();
if (!addr)
return -1;
if (nl_connect(nlh, NETLINK_ROUTE) < 0)
assert(0);
link_cache = rtnl_link_alloc_cache(nlh);
if (!link_cache)
assert(0);
nl_cache_mngt_provide(link_cache);
addr_cache = rtnl_addr_alloc_cache(nlh);
if (!addr_cache)
assert(0);
filtered_cache = rtnl_addr_alloc_cache(nlh);
if (!filtered_cache)
assert(0);
// leave just eth0: set the filter `addr'
rtnl_addr_set_ifindex(addr, if_nametoindex("eth0"));
params.dp_type = NL_DUMP_BRIEF;
params.dp_prefix = 30;
params.dp_print_index = 1;
params.dp_dump_msgtype = 1;
params.dp_cb = NULL;
params.dp_nl_cb = NULL;
params.dp_data = NULL;
params.dp_fd = stdout;
params.dp_buf = NULL;
params.dp_buflen = 0;
printf("--------------------------------------\n");
printf("original addr_cache dump-to-screen:\n");
nl_cache_dump (addr_cache, ¶ms);
printf("--------------------------------------\n\n\n");
perror(nl_geterror());
printf("--------------------------------------\n");
printf("after my_nl_cache_exclude_non_matching:\n");
my_nl_cache_exclude_non_matching(filtered_cache, addr);
nl_cache_dump (filtered_cache, ¶ms);
printf("--------------------------------------\n");
perror(nl_geterror());
err = 0;
/* lots of free missing:
nl_cache_free(filtered_cache);
nl_cache_free(addr_cache);
nl_cache_free(link_cache);
nl_close(nlh);
rtnl_addr_put(addr); */
errout:
return err;
}
void my_nl_cache_exclude_non_matching(struct nl_cache *target, struct
rtnl_addr* filter)
{
void my_cb_mark_matches(struct nl_object *obj, void *userdata)
{
nl_object_mark(obj);
}
void my_cb_exclude_non_matching(struct nl_object *obj, void *userdata)
{
if (nl_object_is_marked(obj) == 0)
nl_cache_remove(obj);
else
nl_object_unmark(obj);
}
nl_cache_foreach_filter(target, (struct nl_object* ) filter,
my_cb_mark_matches, NULL);
nl_cache_foreach(target, my_cb_exclude_non_matching, NULL);
}
--
Pedro
More information about the libnl
mailing list