0001
0002 #include <linux/kernel.h>
0003 #include <net/netlink.h>
0004 #include <linux/drbd_genl_api.h>
0005 #include "drbd_nla.h"
0006
0007 static int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla)
0008 {
0009 struct nlattr *head = nla_data(nla);
0010 int len = nla_len(nla);
0011 int rem;
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 nla_for_each_attr(nla, head, len, rem) {
0022 if (nla->nla_type & DRBD_GENLA_F_MANDATORY) {
0023 nla->nla_type &= ~DRBD_GENLA_F_MANDATORY;
0024 if (nla_type(nla) > maxtype)
0025 return -EOPNOTSUPP;
0026 }
0027 }
0028 return 0;
0029 }
0030
0031 int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
0032 const struct nla_policy *policy)
0033 {
0034 int err;
0035
0036 err = drbd_nla_check_mandatory(maxtype, nla);
0037 if (!err)
0038 err = nla_parse_nested_deprecated(tb, maxtype, nla, policy,
0039 NULL);
0040
0041 return err;
0042 }
0043
0044 struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype)
0045 {
0046 int err;
0047
0048
0049
0050
0051
0052 err = drbd_nla_check_mandatory(maxtype, nla);
0053 if (err)
0054 return ERR_PTR(err);
0055 return nla_find_nested(nla, attrtype);
0056 }