Skip to content

Commit e1ce69d

Browse files
hdmdaviespcmoore
authored andcommitted
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>
1 parent a5e3449 commit e1ce69d

File tree

4 files changed

+165
-0
lines changed

4 files changed

+165
-0
lines changed

include/net/netlabel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ struct netlbl_lsm_secattr {
225225
* @doi_free: free a CALIPSO DOI
226226
* @doi_getdef: returns a reference to a DOI
227227
* @doi_putdef: releases a reference of a DOI
228+
* @doi_walk: enumerate the DOI list
228229
*
229230
* Description:
230231
* This structure is filled out by the CALIPSO engine and passed
@@ -238,6 +239,9 @@ struct netlbl_calipso_ops {
238239
void (*doi_free)(struct calipso_doi *doi_def);
239240
struct calipso_doi *(*doi_getdef)(u32 doi);
240241
void (*doi_putdef)(struct calipso_doi *doi_def);
242+
int (*doi_walk)(u32 *skip_cnt,
243+
int (*callback)(struct calipso_doi *doi_def, void *arg),
244+
void *cb_arg);
241245
};
242246

243247
/*

net/ipv6/calipso.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,52 @@ static void calipso_doi_putdef(struct calipso_doi *doi_def)
210210
call_rcu(&doi_def->rcu, calipso_doi_free_rcu);
211211
}
212212

213+
/**
214+
* calipso_doi_walk - Iterate through the DOI definitions
215+
* @skip_cnt: skip past this number of DOI definitions, updated
216+
* @callback: callback for each DOI definition
217+
* @cb_arg: argument for the callback function
218+
*
219+
* Description:
220+
* Iterate over the DOI definition list, skipping the first @skip_cnt entries.
221+
* For each entry call @callback, if @callback returns a negative value stop
222+
* 'walking' through the list and return. Updates the value in @skip_cnt upon
223+
* return. Returns zero on success, negative values on failure.
224+
*
225+
*/
226+
static int calipso_doi_walk(u32 *skip_cnt,
227+
int (*callback)(struct calipso_doi *doi_def,
228+
void *arg),
229+
void *cb_arg)
230+
{
231+
int ret_val = -ENOENT;
232+
u32 doi_cnt = 0;
233+
struct calipso_doi *iter_doi;
234+
235+
rcu_read_lock();
236+
list_for_each_entry_rcu(iter_doi, &calipso_doi_list, list)
237+
if (atomic_read(&iter_doi->refcount) > 0) {
238+
if (doi_cnt++ < *skip_cnt)
239+
continue;
240+
ret_val = callback(iter_doi, cb_arg);
241+
if (ret_val < 0) {
242+
doi_cnt--;
243+
goto doi_walk_return;
244+
}
245+
}
246+
247+
doi_walk_return:
248+
rcu_read_unlock();
249+
*skip_cnt = doi_cnt;
250+
return ret_val;
251+
}
252+
213253
static const struct netlbl_calipso_ops ops = {
214254
.doi_add = calipso_doi_add,
215255
.doi_free = calipso_doi_free,
216256
.doi_getdef = calipso_doi_getdef,
217257
.doi_putdef = calipso_doi_putdef,
258+
.doi_walk = calipso_doi_walk,
218259
};
219260

220261
/**

net/netlabel/netlabel_calipso.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@
4646
#include "netlabel_mgmt.h"
4747
#include "netlabel_domainhash.h"
4848

49+
/* Argument struct for calipso_doi_walk() */
50+
struct netlbl_calipso_doiwalk_arg {
51+
struct netlink_callback *nl_cb;
52+
struct sk_buff *skb;
53+
u32 seq;
54+
};
55+
4956
/* NetLabel Generic NETLINK CALIPSO family */
5057
static struct genl_family netlbl_calipso_gnl_family = {
5158
.id = GENL_ID_GENERATE,
@@ -183,6 +190,73 @@ static int netlbl_calipso_list(struct sk_buff *skb, struct genl_info *info)
183190
return ret_val;
184191
}
185192

193+
/**
194+
* netlbl_calipso_listall_cb - calipso_doi_walk() callback for LISTALL
195+
* @doi_def: the CALIPSO DOI definition
196+
* @arg: the netlbl_calipso_doiwalk_arg structure
197+
*
198+
* Description:
199+
* This function is designed to be used as a callback to the
200+
* calipso_doi_walk() function for use in generating a response for a LISTALL
201+
* message. Returns the size of the message on success, negative values on
202+
* failure.
203+
*
204+
*/
205+
static int netlbl_calipso_listall_cb(struct calipso_doi *doi_def, void *arg)
206+
{
207+
int ret_val = -ENOMEM;
208+
struct netlbl_calipso_doiwalk_arg *cb_arg = arg;
209+
void *data;
210+
211+
data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid,
212+
cb_arg->seq, &netlbl_calipso_gnl_family,
213+
NLM_F_MULTI, NLBL_CALIPSO_C_LISTALL);
214+
if (!data)
215+
goto listall_cb_failure;
216+
217+
ret_val = nla_put_u32(cb_arg->skb, NLBL_CALIPSO_A_DOI, doi_def->doi);
218+
if (ret_val != 0)
219+
goto listall_cb_failure;
220+
ret_val = nla_put_u32(cb_arg->skb,
221+
NLBL_CALIPSO_A_MTYPE,
222+
doi_def->type);
223+
if (ret_val != 0)
224+
goto listall_cb_failure;
225+
226+
genlmsg_end(cb_arg->skb, data);
227+
return 0;
228+
229+
listall_cb_failure:
230+
genlmsg_cancel(cb_arg->skb, data);
231+
return ret_val;
232+
}
233+
234+
/**
235+
* netlbl_calipso_listall - Handle a LISTALL message
236+
* @skb: the NETLINK buffer
237+
* @cb: the NETLINK callback
238+
*
239+
* Description:
240+
* Process a user generated LISTALL message and respond accordingly. Returns
241+
* zero on success and negative values on error.
242+
*
243+
*/
244+
static int netlbl_calipso_listall(struct sk_buff *skb,
245+
struct netlink_callback *cb)
246+
{
247+
struct netlbl_calipso_doiwalk_arg cb_arg;
248+
u32 doi_skip = cb->args[0];
249+
250+
cb_arg.nl_cb = cb;
251+
cb_arg.skb = skb;
252+
cb_arg.seq = cb->nlh->nlmsg_seq;
253+
254+
calipso_doi_walk(&doi_skip, netlbl_calipso_listall_cb, &cb_arg);
255+
256+
cb->args[0] = doi_skip;
257+
return skb->len;
258+
}
259+
186260
/* NetLabel Generic NETLINK Command Definitions
187261
*/
188262

@@ -201,6 +275,13 @@ static const struct genl_ops netlbl_calipso_ops[] = {
201275
.doit = netlbl_calipso_list,
202276
.dumpit = NULL,
203277
},
278+
{
279+
.cmd = NLBL_CALIPSO_C_LISTALL,
280+
.flags = 0,
281+
.policy = calipso_genl_policy,
282+
.doit = NULL,
283+
.dumpit = netlbl_calipso_listall,
284+
},
204285
};
205286

206287
/* NetLabel Generic NETLINK Protocol Functions
@@ -316,3 +397,28 @@ void calipso_doi_putdef(struct calipso_doi *doi_def)
316397
if (ops)
317398
ops->doi_putdef(doi_def);
318399
}
400+
401+
/**
402+
* calipso_doi_walk - Iterate through the DOI definitions
403+
* @skip_cnt: skip past this number of DOI definitions, updated
404+
* @callback: callback for each DOI definition
405+
* @cb_arg: argument for the callback function
406+
*
407+
* Description:
408+
* Iterate over the DOI definition list, skipping the first @skip_cnt entries.
409+
* For each entry call @callback, if @callback returns a negative value stop
410+
* 'walking' through the list and return. Updates the value in @skip_cnt upon
411+
* return. Returns zero on success, negative values on failure.
412+
*
413+
*/
414+
int calipso_doi_walk(u32 *skip_cnt,
415+
int (*callback)(struct calipso_doi *doi_def, void *arg),
416+
void *cb_arg)
417+
{
418+
int ret_val = -ENOMSG;
419+
const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
420+
421+
if (ops)
422+
ret_val = ops->doi_walk(skip_cnt, callback, cb_arg);
423+
return ret_val;
424+
}

net/netlabel/netlabel_calipso.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@
6363
*
6464
* If using CALIPSO_MAP_PASS no additional attributes are required.
6565
*
66+
* o LISTALL:
67+
* This message is sent by an application to list the valid DOIs on the
68+
* system. When sent by an application there is no payload and the
69+
* NLM_F_DUMP flag should be set. The kernel should respond with a series of
70+
* the following messages.
71+
*
72+
* Required attributes:
73+
*
74+
* NLBL_CALIPSO_A_DOI
75+
* NLBL_CALIPSO_A_MTYPE
76+
*
6677
*/
6778

6879
/* NetLabel CALIPSO commands */
@@ -105,5 +116,8 @@ int calipso_doi_add(struct calipso_doi *doi_def,
105116
void calipso_doi_free(struct calipso_doi *doi_def);
106117
struct calipso_doi *calipso_doi_getdef(u32 doi);
107118
void calipso_doi_putdef(struct calipso_doi *doi_def);
119+
int calipso_doi_walk(u32 *skip_cnt,
120+
int (*callback)(struct calipso_doi *doi_def, void *arg),
121+
void *cb_arg);
108122

109123
#endif

0 commit comments

Comments
 (0)