linux/include/linux/genl_magic_func.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef GENL_MAGIC_FUNC_H
   3#define GENL_MAGIC_FUNC_H
   4
   5#include <linux/build_bug.h>
   6#include <linux/genl_magic_struct.h>
   7
   8/*
   9 * Magic: declare tla policy                                            {{{1
  10 * Magic: declare nested policies
  11 *                                                                      {{{2
  12 */
  13#undef GENL_mc_group
  14#define GENL_mc_group(group)
  15
  16#undef GENL_notification
  17#define GENL_notification(op_name, op_num, mcast_group, tla_list)
  18
  19#undef GENL_op
  20#define GENL_op(op_name, op_num, handler, tla_list)
  21
  22#undef GENL_struct
  23#define GENL_struct(tag_name, tag_number, s_name, s_fields)             \
  24        [tag_name] = { .type = NLA_NESTED },
  25
  26static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = {
  27#include GENL_MAGIC_INCLUDE_FILE
  28};
  29
  30#undef GENL_struct
  31#define GENL_struct(tag_name, tag_number, s_name, s_fields)             \
  32static struct nla_policy s_name ## _nl_policy[] __read_mostly =         \
  33{ s_fields };
  34
  35#undef __field
  36#define __field(attr_nr, attr_flag, name, nla_type, _type, __get,       \
  37                 __put, __is_signed)                                    \
  38        [attr_nr] = { .type = nla_type },
  39
  40#undef __array
  41#define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen,      \
  42                __get, __put, __is_signed)                              \
  43        [attr_nr] = { .type = nla_type,                                 \
  44                      .len = maxlen - (nla_type == NLA_NUL_STRING) },
  45
  46#include GENL_MAGIC_INCLUDE_FILE
  47
  48#ifndef __KERNEL__
  49#ifndef pr_info
  50#define pr_info(args...)        fprintf(stderr, args);
  51#endif
  52#endif
  53
  54#ifdef GENL_MAGIC_DEBUG
  55static void dprint_field(const char *dir, int nla_type,
  56                const char *name, void *valp)
  57{
  58        __u64 val = valp ? *(__u32 *)valp : 1;
  59        switch (nla_type) {
  60        case NLA_U8:  val = (__u8)val;
  61        case NLA_U16: val = (__u16)val;
  62        case NLA_U32: val = (__u32)val;
  63                pr_info("%s attr %s: %d 0x%08x\n", dir,
  64                        name, (int)val, (unsigned)val);
  65                break;
  66        case NLA_U64:
  67                val = *(__u64*)valp;
  68                pr_info("%s attr %s: %lld 0x%08llx\n", dir,
  69                        name, (long long)val, (unsigned long long)val);
  70                break;
  71        case NLA_FLAG:
  72                if (val)
  73                        pr_info("%s attr %s: set\n", dir, name);
  74                break;
  75        }
  76}
  77
  78static void dprint_array(const char *dir, int nla_type,
  79                const char *name, const char *val, unsigned len)
  80{
  81        switch (nla_type) {
  82        case NLA_NUL_STRING:
  83                if (len && val[len-1] == '\0')
  84                        len--;
  85                pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
  86                break;
  87        default:
  88                /* we can always show 4 byte,
  89                 * thats what nlattr are aligned to. */
  90                pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
  91                        dir, name, len, val[0], val[1], val[2], val[3]);
  92        }
  93}
  94
  95#define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b);
  96
  97/* Name is a member field name of the struct s.
  98 * If s is NULL (only parsing, no copy requested in *_from_attrs()),
  99 * nla is supposed to point to the attribute containing the information
 100 * corresponding to that struct member. */
 101#define DPRINT_FIELD(dir, nla_type, name, s, nla)                       \
 102        do {                                                            \
 103                if (s)                                                  \
 104                        dprint_field(dir, nla_type, #name, &s->name);   \
 105                else if (nla)                                           \
 106                        dprint_field(dir, nla_type, #name,              \
 107                                (nla_type == NLA_FLAG) ? NULL           \
 108                                                : nla_data(nla));       \
 109        } while (0)
 110
 111#define DPRINT_ARRAY(dir, nla_type, name, s, nla)                       \
 112        do {                                                            \
 113                if (s)                                                  \
 114                        dprint_array(dir, nla_type, #name,              \
 115                                        s->name, s->name ## _len);      \
 116                else if (nla)                                           \
 117                        dprint_array(dir, nla_type, #name,              \
 118                                        nla_data(nla), nla_len(nla));   \
 119        } while (0)
 120#else
 121#define DPRINT_TLA(a, op, b) do {} while (0)
 122#define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0)
 123#define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0)
 124#endif
 125
 126/*
 127 * Magic: provide conversion functions                                  {{{1
 128 * populate struct from attribute table:
 129 *                                                                      {{{2
 130 */
 131
 132/* processing of generic netlink messages is serialized.
 133 * use one static buffer for parsing of nested attributes */
 134static struct nlattr *nested_attr_tb[128];
 135
 136#undef GENL_struct
 137#define GENL_struct(tag_name, tag_number, s_name, s_fields)             \
 138/* *_from_attrs functions are static, but potentially unused */         \
 139static int __ ## s_name ## _from_attrs(struct s_name *s,                \
 140                struct genl_info *info, bool exclude_invariants)        \
 141{                                                                       \
 142        const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1;         \
 143        struct nlattr *tla = info->attrs[tag_number];                   \
 144        struct nlattr **ntb = nested_attr_tb;                           \
 145        struct nlattr *nla;                                             \
 146        int err;                                                        \
 147        BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb));    \
 148        if (!tla)                                                       \
 149                return -ENOMSG;                                         \
 150        DPRINT_TLA(#s_name, "<=-", #tag_name);                          \
 151        err = drbd_nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy);   \
 152        if (err)                                                        \
 153                return err;                                             \
 154                                                                        \
 155        s_fields                                                        \
 156        return 0;                                                       \
 157}                                       __attribute__((unused))         \
 158static int s_name ## _from_attrs(struct s_name *s,                      \
 159                                                struct genl_info *info) \
 160{                                                                       \
 161        return __ ## s_name ## _from_attrs(s, info, false);             \
 162}                                       __attribute__((unused))         \
 163static int s_name ## _from_attrs_for_change(struct s_name *s,           \
 164                                                struct genl_info *info) \
 165{                                                                       \
 166        return __ ## s_name ## _from_attrs(s, info, true);              \
 167}                                       __attribute__((unused))         \
 168
 169#define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...)       \
 170                nla = ntb[attr_nr];                                             \
 171                if (nla) {                                              \
 172                        if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) {         \
 173                                pr_info("<< must not change invariant attr: %s\n", #name);      \
 174                                return -EEXIST;                         \
 175                        }                                               \
 176                        assignment;                                     \
 177                } else if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) {          \
 178                        /* attribute missing from payload, */           \
 179                        /* which was expected */                        \
 180                } else if ((attr_flag) & DRBD_F_REQUIRED) {             \
 181                        pr_info("<< missing attr: %s\n", #name);        \
 182                        return -ENOMSG;                                 \
 183                }
 184
 185#undef __field
 186#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
 187                __is_signed)                                            \
 188        __assign(attr_nr, attr_flag, name, nla_type, type,              \
 189                        if (s)                                          \
 190                                s->name = __get(nla);                   \
 191                        DPRINT_FIELD("<<", nla_type, name, s, nla))
 192
 193/* validate_nla() already checked nla_len <= maxlen appropriately. */
 194#undef __array
 195#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,       \
 196                __get, __put, __is_signed)                              \
 197        __assign(attr_nr, attr_flag, name, nla_type, type,              \
 198                        if (s)                                          \
 199                                s->name ## _len =                       \
 200                                        __get(s->name, nla, maxlen);    \
 201                        DPRINT_ARRAY("<<", nla_type, name, s, nla))
 202
 203#include GENL_MAGIC_INCLUDE_FILE
 204
 205#undef GENL_struct
 206#define GENL_struct(tag_name, tag_number, s_name, s_fields)
 207
 208/*
 209 * Magic: define op number to op name mapping                           {{{1
 210 *                                                                      {{{2
 211 */
 212const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
 213{
 214        switch (cmd) {
 215#undef GENL_op
 216#define GENL_op(op_name, op_num, handler, tla_list)             \
 217        case op_num: return #op_name;
 218#include GENL_MAGIC_INCLUDE_FILE
 219        default:
 220                     return "unknown";
 221        }
 222}
 223
 224#ifdef __KERNEL__
 225#include <linux/stringify.h>
 226/*
 227 * Magic: define genl_ops                                               {{{1
 228 *                                                                      {{{2
 229 */
 230
 231#undef GENL_op
 232#define GENL_op(op_name, op_num, handler, tla_list)             \
 233{                                                               \
 234        handler                                                 \
 235        .cmd = op_name,                                         \
 236},
 237
 238#define ZZZ_genl_ops            CONCAT_(GENL_MAGIC_FAMILY, _genl_ops)
 239static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
 240#include GENL_MAGIC_INCLUDE_FILE
 241};
 242
 243#undef GENL_op
 244#define GENL_op(op_name, op_num, handler, tla_list)
 245
 246/*
 247 * Define the genl_family, multicast groups,                            {{{1
 248 * and provide register/unregister functions.
 249 *                                                                      {{{2
 250 */
 251#define ZZZ_genl_family         CONCAT_(GENL_MAGIC_FAMILY, _genl_family)
 252static struct genl_family ZZZ_genl_family;
 253/*
 254 * Magic: define multicast groups
 255 * Magic: define multicast group registration helper
 256 */
 257#define ZZZ_genl_mcgrps         CONCAT_(GENL_MAGIC_FAMILY, _genl_mcgrps)
 258static const struct genl_multicast_group ZZZ_genl_mcgrps[] = {
 259#undef GENL_mc_group
 260#define GENL_mc_group(group) { .name = #group, },
 261#include GENL_MAGIC_INCLUDE_FILE
 262};
 263
 264enum CONCAT_(GENL_MAGIC_FAMILY, group_ids) {
 265#undef GENL_mc_group
 266#define GENL_mc_group(group) CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group),
 267#include GENL_MAGIC_INCLUDE_FILE
 268};
 269
 270#undef GENL_mc_group
 271#define GENL_mc_group(group)                                            \
 272static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)(       \
 273        struct sk_buff *skb, gfp_t flags)                               \
 274{                                                                       \
 275        unsigned int group_id =                                         \
 276                CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group);           \
 277        return genlmsg_multicast(&ZZZ_genl_family, skb, 0,              \
 278                                 group_id, flags);                      \
 279}
 280
 281#include GENL_MAGIC_INCLUDE_FILE
 282
 283#undef GENL_mc_group
 284#define GENL_mc_group(group)
 285
 286static struct genl_family ZZZ_genl_family __ro_after_init = {
 287        .name = __stringify(GENL_MAGIC_FAMILY),
 288        .version = GENL_MAGIC_VERSION,
 289#ifdef GENL_MAGIC_FAMILY_HDRSZ
 290        .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
 291#endif
 292        .maxattr = ARRAY_SIZE(CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy))-1,
 293        .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy),
 294        .ops = ZZZ_genl_ops,
 295        .n_ops = ARRAY_SIZE(ZZZ_genl_ops),
 296        .mcgrps = ZZZ_genl_mcgrps,
 297        .n_mcgrps = ARRAY_SIZE(ZZZ_genl_mcgrps),
 298        .module = THIS_MODULE,
 299};
 300
 301int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
 302{
 303        return genl_register_family(&ZZZ_genl_family);
 304}
 305
 306void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
 307{
 308        genl_unregister_family(&ZZZ_genl_family);
 309}
 310
 311/*
 312 * Magic: provide conversion functions                                  {{{1
 313 * populate skb from struct.
 314 *                                                                      {{{2
 315 */
 316
 317#undef GENL_op
 318#define GENL_op(op_name, op_num, handler, tla_list)
 319
 320#undef GENL_struct
 321#define GENL_struct(tag_name, tag_number, s_name, s_fields)             \
 322static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s,     \
 323                const bool exclude_sensitive)                           \
 324{                                                                       \
 325        struct nlattr *tla = nla_nest_start(skb, tag_number);           \
 326        if (!tla)                                                       \
 327                goto nla_put_failure;                                   \
 328        DPRINT_TLA(#s_name, "-=>", #tag_name);                          \
 329        s_fields                                                        \
 330        nla_nest_end(skb, tla);                                         \
 331        return 0;                                                       \
 332                                                                        \
 333nla_put_failure:                                                        \
 334        if (tla)                                                        \
 335                nla_nest_cancel(skb, tla);                              \
 336        return -EMSGSIZE;                                               \
 337}                                                                       \
 338static inline int s_name ## _to_priv_skb(struct sk_buff *skb,           \
 339                struct s_name *s)                                       \
 340{                                                                       \
 341        return s_name ## _to_skb(skb, s, 0);                            \
 342}                                                                       \
 343static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb,         \
 344                struct s_name *s)                                       \
 345{                                                                       \
 346        return s_name ## _to_skb(skb, s, 1);                            \
 347}
 348
 349
 350#undef __field
 351#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
 352                __is_signed)                                            \
 353        if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {  \
 354                DPRINT_FIELD(">>", nla_type, name, s, NULL);            \
 355                if (__put(skb, attr_nr, s->name))                       \
 356                        goto nla_put_failure;                           \
 357        }
 358
 359#undef __array
 360#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,       \
 361                __get, __put, __is_signed)                              \
 362        if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {  \
 363                DPRINT_ARRAY(">>",nla_type, name, s, NULL);             \
 364                if (__put(skb, attr_nr, min_t(int, maxlen,              \
 365                        s->name ## _len + (nla_type == NLA_NUL_STRING)),\
 366                                                s->name))               \
 367                        goto nla_put_failure;                           \
 368        }
 369
 370#include GENL_MAGIC_INCLUDE_FILE
 371
 372
 373/* Functions for initializing structs to default values.  */
 374
 375#undef __field
 376#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
 377                __is_signed)
 378#undef __array
 379#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,       \
 380                __get, __put, __is_signed)
 381#undef __u32_field_def
 382#define __u32_field_def(attr_nr, attr_flag, name, default)              \
 383        x->name = default;
 384#undef __s32_field_def
 385#define __s32_field_def(attr_nr, attr_flag, name, default)              \
 386        x->name = default;
 387#undef __flg_field_def
 388#define __flg_field_def(attr_nr, attr_flag, name, default)              \
 389        x->name = default;
 390#undef __str_field_def
 391#define __str_field_def(attr_nr, attr_flag, name, maxlen)               \
 392        memset(x->name, 0, sizeof(x->name));                            \
 393        x->name ## _len = 0;
 394#undef GENL_struct
 395#define GENL_struct(tag_name, tag_number, s_name, s_fields)             \
 396static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
 397static void set_ ## s_name ## _defaults(struct s_name *x) {     \
 398s_fields                                                                \
 399}
 400
 401#include GENL_MAGIC_INCLUDE_FILE
 402
 403#endif /* __KERNEL__ */
 404
 405/* }}}1 */
 406#endif /* GENL_MAGIC_FUNC_H */
 407