diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-06-10 06:57:26 -0400 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2012-11-08 10:57:45 -0500 |
commit | 01b39b50d34733646fe46a582fa60d3b53f6180d (patch) | |
tree | 1602650bce908e1b65b656070be7473948001255 /drivers/block/drbd/drbd_nla.c | |
parent | 7c3063cc6f0e75cdf312f5f318f9a4c02e460397 (diff) |
drbd: Split off netlink mandatory attribute handling into separate file
Duplicate this file in the kernel module and in user space; both sides need it.
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_nla.c')
-rw-r--r-- | drivers/block/drbd/drbd_nla.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/block/drbd/drbd_nla.c b/drivers/block/drbd/drbd_nla.c new file mode 100644 index 000000000000..fa672b6df8d6 --- /dev/null +++ b/drivers/block/drbd/drbd_nla.c | |||
@@ -0,0 +1,55 @@ | |||
1 | #include "drbd_wrappers.h" | ||
2 | #include <linux/kernel.h> | ||
3 | #include <net/netlink.h> | ||
4 | #include <linux/drbd_genl_api.h> | ||
5 | #include "drbd_nla.h" | ||
6 | |||
7 | static int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla) | ||
8 | { | ||
9 | struct nlattr *head = nla_data(nla); | ||
10 | int len = nla_len(nla); | ||
11 | int rem; | ||
12 | |||
13 | /* | ||
14 | * validate_nla (called from nla_parse_nested) ignores attributes | ||
15 | * beyond maxtype, and does not understand the DRBD_GENLA_F_MANDATORY flag. | ||
16 | * In order to have it validate attributes with the DRBD_GENLA_F_MANDATORY | ||
17 | * flag set also, check and remove that flag before calling | ||
18 | * nla_parse_nested. | ||
19 | */ | ||
20 | |||
21 | nla_for_each_attr(nla, head, len, rem) { | ||
22 | if (nla->nla_type & DRBD_GENLA_F_MANDATORY) { | ||
23 | nla->nla_type &= ~DRBD_GENLA_F_MANDATORY; | ||
24 | if (nla_type(nla) > maxtype) | ||
25 | return -EOPNOTSUPP; | ||
26 | } | ||
27 | } | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, | ||
32 | const struct nla_policy *policy) | ||
33 | { | ||
34 | int err; | ||
35 | |||
36 | err = drbd_nla_check_mandatory(maxtype, nla); | ||
37 | if (!err) | ||
38 | err = nla_parse_nested(tb, maxtype, nla, policy); | ||
39 | |||
40 | return err; | ||
41 | } | ||
42 | |||
43 | struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype) | ||
44 | { | ||
45 | int err; | ||
46 | /* | ||
47 | * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and | ||
48 | * we don't know about that attribute, reject all the nested | ||
49 | * attributes. | ||
50 | */ | ||
51 | err = drbd_nla_check_mandatory(maxtype, nla); | ||
52 | if (err) | ||
53 | return ERR_PTR(err); | ||
54 | return nla_find_nested(nla, attrtype); | ||
55 | } | ||