Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef GENL_MAGIC_FUNC_H
0003 #define GENL_MAGIC_FUNC_H
0004 
0005 #include <linux/build_bug.h>
0006 #include <linux/genl_magic_struct.h>
0007 
0008 /*
0009  * Magic: declare tla policy                        {{{1
0010  * Magic: declare nested policies
0011  *                                  {{{2
0012  */
0013 #undef GENL_mc_group
0014 #define GENL_mc_group(group)
0015 
0016 #undef GENL_notification
0017 #define GENL_notification(op_name, op_num, mcast_group, tla_list)
0018 
0019 #undef GENL_op
0020 #define GENL_op(op_name, op_num, handler, tla_list)
0021 
0022 #undef GENL_struct
0023 #define GENL_struct(tag_name, tag_number, s_name, s_fields)     \
0024     [tag_name] = { .type = NLA_NESTED },
0025 
0026 static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = {
0027 #include GENL_MAGIC_INCLUDE_FILE
0028 };
0029 
0030 #undef GENL_struct
0031 #define GENL_struct(tag_name, tag_number, s_name, s_fields)     \
0032 static struct nla_policy s_name ## _nl_policy[] __read_mostly =     \
0033 { s_fields };
0034 
0035 #undef __field
0036 #define __field(attr_nr, attr_flag, name, nla_type, _type, __get,   \
0037          __put, __is_signed)                    \
0038     [attr_nr] = { .type = nla_type },
0039 
0040 #undef __array
0041 #define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen,  \
0042         __get, __put, __is_signed)              \
0043     [attr_nr] = { .type = nla_type,                 \
0044               .len = maxlen - (nla_type == NLA_NUL_STRING) },
0045 
0046 #include GENL_MAGIC_INCLUDE_FILE
0047 
0048 #ifndef __KERNEL__
0049 #ifndef pr_info
0050 #define pr_info(args...)    fprintf(stderr, args);
0051 #endif
0052 #endif
0053 
0054 #ifdef GENL_MAGIC_DEBUG
0055 static void dprint_field(const char *dir, int nla_type,
0056         const char *name, void *valp)
0057 {
0058     __u64 val = valp ? *(__u32 *)valp : 1;
0059     switch (nla_type) {
0060     case NLA_U8:  val = (__u8)val;
0061     case NLA_U16: val = (__u16)val;
0062     case NLA_U32: val = (__u32)val;
0063         pr_info("%s attr %s: %d 0x%08x\n", dir,
0064             name, (int)val, (unsigned)val);
0065         break;
0066     case NLA_U64:
0067         val = *(__u64*)valp;
0068         pr_info("%s attr %s: %lld 0x%08llx\n", dir,
0069             name, (long long)val, (unsigned long long)val);
0070         break;
0071     case NLA_FLAG:
0072         if (val)
0073             pr_info("%s attr %s: set\n", dir, name);
0074         break;
0075     }
0076 }
0077 
0078 static void dprint_array(const char *dir, int nla_type,
0079         const char *name, const char *val, unsigned len)
0080 {
0081     switch (nla_type) {
0082     case NLA_NUL_STRING:
0083         if (len && val[len-1] == '\0')
0084             len--;
0085         pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val);
0086         break;
0087     default:
0088         /* we can always show 4 byte,
0089          * thats what nlattr are aligned to. */
0090         pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n",
0091             dir, name, len, val[0], val[1], val[2], val[3]);
0092     }
0093 }
0094 
0095 #define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b);
0096 
0097 /* Name is a member field name of the struct s.
0098  * If s is NULL (only parsing, no copy requested in *_from_attrs()),
0099  * nla is supposed to point to the attribute containing the information
0100  * corresponding to that struct member. */
0101 #define DPRINT_FIELD(dir, nla_type, name, s, nla)           \
0102     do {                                \
0103         if (s)                          \
0104             dprint_field(dir, nla_type, #name, &s->name);   \
0105         else if (nla)                       \
0106             dprint_field(dir, nla_type, #name,      \
0107                 (nla_type == NLA_FLAG) ? NULL       \
0108                         : nla_data(nla));   \
0109     } while (0)
0110 
0111 #define DPRINT_ARRAY(dir, nla_type, name, s, nla)           \
0112     do {                                \
0113         if (s)                          \
0114             dprint_array(dir, nla_type, #name,      \
0115                     s->name, s->name ## _len);  \
0116         else if (nla)                       \
0117             dprint_array(dir, nla_type, #name,      \
0118                     nla_data(nla), nla_len(nla));   \
0119     } while (0)
0120 #else
0121 #define DPRINT_TLA(a, op, b) do {} while (0)
0122 #define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0)
0123 #define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0)
0124 #endif
0125 
0126 /*
0127  * Magic: provide conversion functions                  {{{1
0128  * populate struct from attribute table:
0129  *                                  {{{2
0130  */
0131 
0132 /* processing of generic netlink messages is serialized.
0133  * use one static buffer for parsing of nested attributes */
0134 static struct nlattr *nested_attr_tb[128];
0135 
0136 #undef GENL_struct
0137 #define GENL_struct(tag_name, tag_number, s_name, s_fields)     \
0138 /* *_from_attrs functions are static, but potentially unused */     \
0139 static int __ ## s_name ## _from_attrs(struct s_name *s,        \
0140         struct genl_info *info, bool exclude_invariants)    \
0141 {                                   \
0142     const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1;     \
0143     struct nlattr *tla = info->attrs[tag_number];           \
0144     struct nlattr **ntb = nested_attr_tb;               \
0145     struct nlattr *nla;                     \
0146     int err;                            \
0147     BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb));    \
0148     if (!tla)                           \
0149         return -ENOMSG;                     \
0150     DPRINT_TLA(#s_name, "<=-", #tag_name);              \
0151     err = drbd_nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy);   \
0152     if (err)                            \
0153         return err;                     \
0154                                     \
0155     s_fields                            \
0156     return 0;                           \
0157 }                   __attribute__((unused))     \
0158 static int s_name ## _from_attrs(struct s_name *s,          \
0159                         struct genl_info *info) \
0160 {                                   \
0161     return __ ## s_name ## _from_attrs(s, info, false);     \
0162 }                   __attribute__((unused))     \
0163 static int s_name ## _from_attrs_for_change(struct s_name *s,       \
0164                         struct genl_info *info) \
0165 {                                   \
0166     return __ ## s_name ## _from_attrs(s, info, true);      \
0167 }                   __attribute__((unused))     \
0168 
0169 #define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...)   \
0170         nla = ntb[attr_nr];                     \
0171         if (nla) {                      \
0172             if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) {     \
0173                 pr_info("<< must not change invariant attr: %s\n", #name);  \
0174                 return -EEXIST;             \
0175             }                       \
0176             assignment;                 \
0177         } else if (exclude_invariants && !!((attr_flag) & DRBD_F_INVARIANT)) {      \
0178             /* attribute missing from payload, */       \
0179             /* which was expected */            \
0180         } else if ((attr_flag) & DRBD_F_REQUIRED) {     \
0181             pr_info("<< missing attr: %s\n", #name);    \
0182             return -ENOMSG;                 \
0183         }
0184 
0185 #undef __field
0186 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
0187         __is_signed)                        \
0188     __assign(attr_nr, attr_flag, name, nla_type, type,      \
0189             if (s)                      \
0190                 s->name = __get(nla);           \
0191             DPRINT_FIELD("<<", nla_type, name, s, nla))
0192 
0193 /* validate_nla() already checked nla_len <= maxlen appropriately. */
0194 #undef __array
0195 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,   \
0196         __get, __put, __is_signed)              \
0197     __assign(attr_nr, attr_flag, name, nla_type, type,      \
0198             if (s)                      \
0199                 s->name ## _len =           \
0200                     __get(s->name, nla, maxlen);    \
0201             DPRINT_ARRAY("<<", nla_type, name, s, nla))
0202 
0203 #include GENL_MAGIC_INCLUDE_FILE
0204 
0205 #undef GENL_struct
0206 #define GENL_struct(tag_name, tag_number, s_name, s_fields)
0207 
0208 /*
0209  * Magic: define op number to op name mapping               {{{1
0210  *                                  {{{2
0211  */
0212 const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd)
0213 {
0214     switch (cmd) {
0215 #undef GENL_op
0216 #define GENL_op(op_name, op_num, handler, tla_list)     \
0217     case op_num: return #op_name;
0218 #include GENL_MAGIC_INCLUDE_FILE
0219     default:
0220              return "unknown";
0221     }
0222 }
0223 
0224 #ifdef __KERNEL__
0225 #include <linux/stringify.h>
0226 /*
0227  * Magic: define genl_ops                       {{{1
0228  *                                  {{{2
0229  */
0230 
0231 #undef GENL_op
0232 #define GENL_op(op_name, op_num, handler, tla_list)     \
0233 {                               \
0234     handler                         \
0235     .cmd = op_name,                     \
0236 },
0237 
0238 #define ZZZ_genl_ops        CONCAT_(GENL_MAGIC_FAMILY, _genl_ops)
0239 static struct genl_ops ZZZ_genl_ops[] __read_mostly = {
0240 #include GENL_MAGIC_INCLUDE_FILE
0241 };
0242 
0243 #undef GENL_op
0244 #define GENL_op(op_name, op_num, handler, tla_list)
0245 
0246 /*
0247  * Define the genl_family, multicast groups,                {{{1
0248  * and provide register/unregister functions.
0249  *                                  {{{2
0250  */
0251 #define ZZZ_genl_family     CONCAT_(GENL_MAGIC_FAMILY, _genl_family)
0252 static struct genl_family ZZZ_genl_family;
0253 /*
0254  * Magic: define multicast groups
0255  * Magic: define multicast group registration helper
0256  */
0257 #define ZZZ_genl_mcgrps     CONCAT_(GENL_MAGIC_FAMILY, _genl_mcgrps)
0258 static const struct genl_multicast_group ZZZ_genl_mcgrps[] = {
0259 #undef GENL_mc_group
0260 #define GENL_mc_group(group) { .name = #group, },
0261 #include GENL_MAGIC_INCLUDE_FILE
0262 };
0263 
0264 enum CONCAT_(GENL_MAGIC_FAMILY, group_ids) {
0265 #undef GENL_mc_group
0266 #define GENL_mc_group(group) CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group),
0267 #include GENL_MAGIC_INCLUDE_FILE
0268 };
0269 
0270 #undef GENL_mc_group
0271 #define GENL_mc_group(group)                        \
0272 static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)(   \
0273     struct sk_buff *skb, gfp_t flags)               \
0274 {                                   \
0275     unsigned int group_id =                     \
0276         CONCAT_(GENL_MAGIC_FAMILY, _group_ ## group);       \
0277     return genlmsg_multicast(&ZZZ_genl_family, skb, 0,      \
0278                  group_id, flags);          \
0279 }
0280 
0281 #include GENL_MAGIC_INCLUDE_FILE
0282 
0283 #undef GENL_mc_group
0284 #define GENL_mc_group(group)
0285 
0286 static struct genl_family ZZZ_genl_family __ro_after_init = {
0287     .name = __stringify(GENL_MAGIC_FAMILY),
0288     .version = GENL_MAGIC_VERSION,
0289 #ifdef GENL_MAGIC_FAMILY_HDRSZ
0290     .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ),
0291 #endif
0292     .maxattr = ARRAY_SIZE(CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy))-1,
0293     .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy),
0294     .ops = ZZZ_genl_ops,
0295     .n_ops = ARRAY_SIZE(ZZZ_genl_ops),
0296     .mcgrps = ZZZ_genl_mcgrps,
0297     .n_mcgrps = ARRAY_SIZE(ZZZ_genl_mcgrps),
0298     .module = THIS_MODULE,
0299 };
0300 
0301 int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void)
0302 {
0303     return genl_register_family(&ZZZ_genl_family);
0304 }
0305 
0306 void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void)
0307 {
0308     genl_unregister_family(&ZZZ_genl_family);
0309 }
0310 
0311 /*
0312  * Magic: provide conversion functions                  {{{1
0313  * populate skb from struct.
0314  *                                  {{{2
0315  */
0316 
0317 #undef GENL_op
0318 #define GENL_op(op_name, op_num, handler, tla_list)
0319 
0320 #undef GENL_struct
0321 #define GENL_struct(tag_name, tag_number, s_name, s_fields)     \
0322 static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \
0323         const bool exclude_sensitive)               \
0324 {                                   \
0325     struct nlattr *tla = nla_nest_start(skb, tag_number);       \
0326     if (!tla)                           \
0327         goto nla_put_failure;                   \
0328     DPRINT_TLA(#s_name, "-=>", #tag_name);              \
0329     s_fields                            \
0330     nla_nest_end(skb, tla);                     \
0331     return 0;                           \
0332                                     \
0333 nla_put_failure:                            \
0334     if (tla)                            \
0335         nla_nest_cancel(skb, tla);              \
0336         return -EMSGSIZE;                       \
0337 }                                   \
0338 static inline int s_name ## _to_priv_skb(struct sk_buff *skb,       \
0339         struct s_name *s)                   \
0340 {                                   \
0341     return s_name ## _to_skb(skb, s, 0);                \
0342 }                                   \
0343 static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb,     \
0344         struct s_name *s)                   \
0345 {                                   \
0346     return s_name ## _to_skb(skb, s, 1);                \
0347 }
0348 
0349 
0350 #undef __field
0351 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
0352         __is_signed)                        \
0353     if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {  \
0354         DPRINT_FIELD(">>", nla_type, name, s, NULL);        \
0355         if (__put(skb, attr_nr, s->name))           \
0356             goto nla_put_failure;               \
0357     }
0358 
0359 #undef __array
0360 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,   \
0361         __get, __put, __is_signed)              \
0362     if (!exclude_sensitive || !((attr_flag) & DRBD_F_SENSITIVE)) {  \
0363         DPRINT_ARRAY(">>",nla_type, name, s, NULL);     \
0364         if (__put(skb, attr_nr, min_t(int, maxlen,      \
0365             s->name ## _len + (nla_type == NLA_NUL_STRING)),\
0366                         s->name))       \
0367             goto nla_put_failure;               \
0368     }
0369 
0370 #include GENL_MAGIC_INCLUDE_FILE
0371 
0372 
0373 /* Functions for initializing structs to default values.  */
0374 
0375 #undef __field
0376 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \
0377         __is_signed)
0378 #undef __array
0379 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen,   \
0380         __get, __put, __is_signed)
0381 #undef __u32_field_def
0382 #define __u32_field_def(attr_nr, attr_flag, name, default)      \
0383     x->name = default;
0384 #undef __s32_field_def
0385 #define __s32_field_def(attr_nr, attr_flag, name, default)      \
0386     x->name = default;
0387 #undef __flg_field_def
0388 #define __flg_field_def(attr_nr, attr_flag, name, default)      \
0389     x->name = default;
0390 #undef __str_field_def
0391 #define __str_field_def(attr_nr, attr_flag, name, maxlen)       \
0392     memset(x->name, 0, sizeof(x->name));                \
0393     x->name ## _len = 0;
0394 #undef GENL_struct
0395 #define GENL_struct(tag_name, tag_number, s_name, s_fields)     \
0396 static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \
0397 static void set_ ## s_name ## _defaults(struct s_name *x) { \
0398 s_fields                                \
0399 }
0400 
0401 #include GENL_MAGIC_INCLUDE_FILE
0402 
0403 #endif /* __KERNEL__ */
0404 
0405 /* }}}1 */
0406 #endif /* GENL_MAGIC_FUNC_H */