diff options
author | Huw Davies <huw@codeweavers.com> | 2016-06-27 15:02:48 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2016-06-27 15:02:48 -0400 |
commit | e1ce69df7e6e8cbdca78ae831ecf435b12b4c168 (patch) | |
tree | 390601563496364614c223897c0ded59afbf6b8c /net/ipv6 | |
parent | a5e34490c3160e09814403d040765b0ae0003121 (diff) | |
download | linux-stable-e1ce69df7e6e8cbdca78ae831ecf435b12b4c168.tar.gz linux-stable-e1ce69df7e6e8cbdca78ae831ecf435b12b4c168.tar.bz2 linux-stable-e1ce69df7e6e8cbdca78ae831ecf435b12b4c168.zip |
netlabel: Add support for enumerating the CALIPSO DOI list.
Enumerate the DOI list through the NLBL_CALIPSO_C_LISTALL command.
It takes no attributes.
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/calipso.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index 128cc6945e34..fa17c7a7f4be 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -210,11 +210,52 @@ static void calipso_doi_putdef(struct calipso_doi *doi_def) call_rcu(&doi_def->rcu, calipso_doi_free_rcu); } +/** + * calipso_doi_walk - Iterate through the DOI definitions + * @skip_cnt: skip past this number of DOI definitions, updated + * @callback: callback for each DOI definition + * @cb_arg: argument for the callback function + * + * Description: + * Iterate over the DOI definition list, skipping the first @skip_cnt entries. + * For each entry call @callback, if @callback returns a negative value stop + * 'walking' through the list and return. Updates the value in @skip_cnt upon + * return. Returns zero on success, negative values on failure. + * + */ +static int calipso_doi_walk(u32 *skip_cnt, + int (*callback)(struct calipso_doi *doi_def, + void *arg), + void *cb_arg) +{ + int ret_val = -ENOENT; + u32 doi_cnt = 0; + struct calipso_doi *iter_doi; + + rcu_read_lock(); + list_for_each_entry_rcu(iter_doi, &calipso_doi_list, list) + if (atomic_read(&iter_doi->refcount) > 0) { + if (doi_cnt++ < *skip_cnt) + continue; + ret_val = callback(iter_doi, cb_arg); + if (ret_val < 0) { + doi_cnt--; + goto doi_walk_return; + } + } + +doi_walk_return: + rcu_read_unlock(); + *skip_cnt = doi_cnt; + return ret_val; +} + static const struct netlbl_calipso_ops ops = { .doi_add = calipso_doi_add, .doi_free = calipso_doi_free, .doi_getdef = calipso_doi_getdef, .doi_putdef = calipso_doi_putdef, + .doi_walk = calipso_doi_walk, }; /** |