linux/drivers/block/drbd/drbd_nla.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/kernel.h>
   3#include <net/netlink.h>
   4#include <linux/drbd_genl_api.h>
   5#include "drbd_nla.h"
   6
   7static 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
  31int 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_deprecated(tb, maxtype, nla, policy,
  39                                                  NULL);
  40
  41        return err;
  42}
  43
  44struct nlattr *drbd_nla_find_nested(int maxtype, struct nlattr *nla, int attrtype)
  45{
  46        int err;
  47        /*
  48         * If any nested attribute has the DRBD_GENLA_F_MANDATORY flag set and
  49         * we don't know about that attribute, reject all the nested
  50         * attributes.
  51         */
  52        err = drbd_nla_check_mandatory(maxtype, nla);
  53        if (err)
  54                return ERR_PTR(err);
  55        return nla_find_nested(nla, attrtype);
  56}
  57