linux/drivers/block/drbd/drbd_nla.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include <net/netlink.h>
   3#include <linux/drbd_genl_api.h>
   4#include "drbd_nla.h"
   5
   6static int drbd_nla_check_mandatory(int maxtype, struct nlattr *nla)
   7{
   8        struct nlattr *head = nla_data(nla);
   9        int len = nla_len(nla);
  10        int rem;
  11
  12        /*
  13         * validate_nla (called from nla_parse_nested) ignores attributes
  14         * beyond maxtype, and does not understand the DRBD_GENLA_F_MANDATORY flag.
  15         * In order to have it validate attributes with the DRBD_GENLA_F_MANDATORY
  16         * flag set also, check and remove that flag before calling
  17         * nla_parse_nested.
  18         */
  19
  20        nla_for_each_attr(nla, head, len, rem) {
  21                if (nla->nla_type & DRBD_GENLA_F_MANDATORY) {
  22                        nla->nla_type &= ~DRBD_GENLA_F_MANDATORY;
  23                        if (nla_type(nla) > maxtype)
  24                                return -EOPNOTSUPP;
  25                }
  26        }
  27        return 0;
  28}
  29
  30int drbd_nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
  31                          const struct nla_policy *policy)
  32{
  33        int err;
  34
  35        err = drbd_nla_check_mandatory(maxtype, nla);
  36        if (!err)
  37                err = nla_parse_nested(tb, maxtype, nla, policy);
  38
  39        return err;
  40}
  41
  42struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype)
  43{
  44        int err;
  45        /*
  46         * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and
  47         * we don't know about that attribute, reject all the nested
  48         * attributes.
  49         */
  50        err = drbd_nla_check_mandatory(maxtype, nla);
  51        if (err)
  52                return ERR_PTR(err);
  53        return nla_find_nested(nla, attrtype);
  54}
  55