1 #ifndef GENL_MAGIC_FUNC_H 2 #define GENL_MAGIC_FUNC_H 3 4 #include <linux/genl_magic_struct.h> 5 6 /* 7 * Extension of genl attribute validation policies {{{1 8 * {{{2 9 */ 10 11 /** 12 * nla_is_required - return true if this attribute is required 13 * @nla: netlink attribute 14 */ 15 static inline int nla_is_required(const struct nlattr *nla) 16 { 17 return nla->nla_type & GENLA_F_REQUIRED; 18 } 19 20 /** 21 * nla_is_mandatory - return true if understanding this attribute is mandatory 22 * @nla: netlink attribute 23 * Note: REQUIRED attributes are implicitly MANDATORY as well 24 */ 25 static inline int nla_is_mandatory(const struct nlattr *nla) 26 { 27 return nla->nla_type & (GENLA_F_MANDATORY | GENLA_F_REQUIRED); 28 } 29 30 /* Functionality to be integrated into nla_parse(), and validate_nla(), 31 * respectively. 32 * 33 * Enforcing the "mandatory" bit is done here, 34 * by rejecting unknown mandatory attributes. 35 * 36 * Part of enforcing the "required" flag would mean to embed it into 37 * nla_policy.type, and extending validate_nla(), which currently does 38 * BUG_ON(pt->type > NLA_TYPE_MAX); we have to work on existing kernels, 39 * so we cannot do that. Thats why enforcing "required" is done in the 40 * generated assignment functions below. */ 41 static int nla_check_unknown(int maxtype, struct nlattr *head, int len) 42 { 43 struct nlattr *nla; 44 int rem; 45 nla_for_each_attr(nla, head, len, rem) { 46 __u16 type = nla_type(nla); 47 if (type > maxtype && nla_is_mandatory(nla)) 48 return -EOPNOTSUPP; 49 } 50 return 0; 51 } 52 53 /* 54 * Magic: declare tla policy {{{1 55 * Magic: declare nested policies 56 * {{{2 57 */ 58 #undef GENL_mc_group 59 #define GENL_mc_group(group) 60 61 #undef GENL_notification 62 #define GENL_notification(op_name, op_num, mcast_group, tla_list) 63 64 #undef GENL_op 65 #define GENL_op(op_name, op_num, handler, tla_list) 66 67 #undef GENL_struct 68 #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 69 [tag_name] = { .type = NLA_NESTED }, 70 71 static struct nla_policy CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy)[] = { 72 #include GENL_MAGIC_INCLUDE_FILE 73 }; 74 75 #undef GENL_struct 76 #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 77 static struct nla_policy s_name ## _nl_policy[] __read_mostly = \ 78 { s_fields }; 79 80 #undef __field 81 #define __field(attr_nr, attr_flag, name, nla_type, _type, __get, \ 82 __put, __is_signed) \ 83 [__nla_type(attr_nr)] = { .type = nla_type }, 84 85 #undef __array 86 #define __array(attr_nr, attr_flag, name, nla_type, _type, maxlen, \ 87 __get, __put, __is_signed) \ 88 [__nla_type(attr_nr)] = { .type = nla_type, \ 89 .len = maxlen - (nla_type == NLA_NUL_STRING) }, 90 91 #include GENL_MAGIC_INCLUDE_FILE 92 93 #ifndef __KERNEL__ 94 #ifndef pr_info 95 #define pr_info(args...) fprintf(stderr, args); 96 #endif 97 #endif 98 99 #ifdef GENL_MAGIC_DEBUG 100 static void dprint_field(const char *dir, int nla_type, 101 const char *name, void *valp) 102 { 103 __u64 val = valp ? *(__u32 *)valp : 1; 104 switch (nla_type) { 105 case NLA_U8: val = (__u8)val; 106 case NLA_U16: val = (__u16)val; 107 case NLA_U32: val = (__u32)val; 108 pr_info("%s attr %s: %d 0x%08x\n", dir, 109 name, (int)val, (unsigned)val); 110 break; 111 case NLA_U64: 112 val = *(__u64*)valp; 113 pr_info("%s attr %s: %lld 0x%08llx\n", dir, 114 name, (long long)val, (unsigned long long)val); 115 break; 116 case NLA_FLAG: 117 if (val) 118 pr_info("%s attr %s: set\n", dir, name); 119 break; 120 } 121 } 122 123 static void dprint_array(const char *dir, int nla_type, 124 const char *name, const char *val, unsigned len) 125 { 126 switch (nla_type) { 127 case NLA_NUL_STRING: 128 if (len && val[len-1] == '\0') 129 len--; 130 pr_info("%s attr %s: [len:%u] '%s'\n", dir, name, len, val); 131 break; 132 default: 133 /* we can always show 4 byte, 134 * thats what nlattr are aligned to. */ 135 pr_info("%s attr %s: [len:%u] %02x%02x%02x%02x ...\n", 136 dir, name, len, val[0], val[1], val[2], val[3]); 137 } 138 } 139 140 #define DPRINT_TLA(a, op, b) pr_info("%s %s %s\n", a, op, b); 141 142 /* Name is a member field name of the struct s. 143 * If s is NULL (only parsing, no copy requested in *_from_attrs()), 144 * nla is supposed to point to the attribute containing the information 145 * corresponding to that struct member. */ 146 #define DPRINT_FIELD(dir, nla_type, name, s, nla) \ 147 do { \ 148 if (s) \ 149 dprint_field(dir, nla_type, #name, &s->name); \ 150 else if (nla) \ 151 dprint_field(dir, nla_type, #name, \ 152 (nla_type == NLA_FLAG) ? NULL \ 153 : nla_data(nla)); \ 154 } while (0) 155 156 #define DPRINT_ARRAY(dir, nla_type, name, s, nla) \ 157 do { \ 158 if (s) \ 159 dprint_array(dir, nla_type, #name, \ 160 s->name, s->name ## _len); \ 161 else if (nla) \ 162 dprint_array(dir, nla_type, #name, \ 163 nla_data(nla), nla_len(nla)); \ 164 } while (0) 165 #else 166 #define DPRINT_TLA(a, op, b) do {} while (0) 167 #define DPRINT_FIELD(dir, nla_type, name, s, nla) do {} while (0) 168 #define DPRINT_ARRAY(dir, nla_type, name, s, nla) do {} while (0) 169 #endif 170 171 /* 172 * Magic: provide conversion functions {{{1 173 * populate struct from attribute table: 174 * {{{2 175 */ 176 177 /* processing of generic netlink messages is serialized. 178 * use one static buffer for parsing of nested attributes */ 179 static struct nlattr *nested_attr_tb[128]; 180 181 #ifndef BUILD_BUG_ON 182 /* Force a compilation error if condition is true */ 183 #define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition)) 184 /* Force a compilation error if condition is true, but also produce a 185 result (of value 0 and type size_t), so the expression can be used 186 e.g. in a structure initializer (or where-ever else comma expressions 187 aren't permitted). */ 188 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) 189 #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); })) 190 #endif 191 192 #undef GENL_struct 193 #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 194 /* *_from_attrs functions are static, but potentially unused */ \ 195 static int __ ## s_name ## _from_attrs(struct s_name *s, \ 196 struct genl_info *info, bool exclude_invariants) \ 197 { \ 198 const int maxtype = ARRAY_SIZE(s_name ## _nl_policy)-1; \ 199 struct nlattr *tla = info->attrs[tag_number]; \ 200 struct nlattr **ntb = nested_attr_tb; \ 201 struct nlattr *nla; \ 202 int err; \ 203 BUILD_BUG_ON(ARRAY_SIZE(s_name ## _nl_policy) > ARRAY_SIZE(nested_attr_tb)); \ 204 if (!tla) \ 205 return -ENOMSG; \ 206 DPRINT_TLA(#s_name, "<=-", #tag_name); \ 207 err = nla_parse_nested(ntb, maxtype, tla, s_name ## _nl_policy); \ 208 if (err) \ 209 return err; \ 210 err = nla_check_unknown(maxtype, nla_data(tla), nla_len(tla)); \ 211 if (err) \ 212 return err; \ 213 \ 214 s_fields \ 215 return 0; \ 216 } __attribute__((unused)) \ 217 static int s_name ## _from_attrs(struct s_name *s, \ 218 struct genl_info *info) \ 219 { \ 220 return __ ## s_name ## _from_attrs(s, info, false); \ 221 } __attribute__((unused)) \ 222 static int s_name ## _from_attrs_for_change(struct s_name *s, \ 223 struct genl_info *info) \ 224 { \ 225 return __ ## s_name ## _from_attrs(s, info, true); \ 226 } __attribute__((unused)) \ 227 228 #define __assign(attr_nr, attr_flag, name, nla_type, type, assignment...) \ 229 nla = ntb[__nla_type(attr_nr)]; \ 230 if (nla) { \ 231 if (exclude_invariants && ((attr_flag) & GENLA_F_INVARIANT)) { \ 232 pr_info("<< must not change invariant attr: %s\n", #name); \ 233 return -EEXIST; \ 234 } \ 235 assignment; \ 236 } else if (exclude_invariants && ((attr_flag) & GENLA_F_INVARIANT)) { \ 237 /* attribute missing from payload, */ \ 238 /* which was expected */ \ 239 } else if ((attr_flag) & GENLA_F_REQUIRED) { \ 240 pr_info("<< missing attr: %s\n", #name); \ 241 return -ENOMSG; \ 242 } 243 244 #undef __field 245 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ 246 __is_signed) \ 247 __assign(attr_nr, attr_flag, name, nla_type, type, \ 248 if (s) \ 249 s->name = __get(nla); \ 250 DPRINT_FIELD("<<", nla_type, name, s, nla)) 251 252 /* validate_nla() already checked nla_len <= maxlen appropriately. */ 253 #undef __array 254 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ 255 __get, __put, __is_signed) \ 256 __assign(attr_nr, attr_flag, name, nla_type, type, \ 257 if (s) \ 258 s->name ## _len = \ 259 __get(s->name, nla, maxlen); \ 260 DPRINT_ARRAY("<<", nla_type, name, s, nla)) 261 262 #include GENL_MAGIC_INCLUDE_FILE 263 264 #undef GENL_struct 265 #define GENL_struct(tag_name, tag_number, s_name, s_fields) 266 267 /* 268 * Magic: define op number to op name mapping {{{1 269 * {{{2 270 */ 271 const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) 272 { 273 switch (cmd) { 274 #undef GENL_op 275 #define GENL_op(op_name, op_num, handler, tla_list) \ 276 case op_num: return #op_name; 277 #include GENL_MAGIC_INCLUDE_FILE 278 default: 279 return "unknown"; 280 } 281 } 282 283 #ifdef __KERNEL__ 284 #include <linux/stringify.h> 285 /* 286 * Magic: define genl_ops {{{1 287 * {{{2 288 */ 289 290 #undef GENL_op 291 #define GENL_op(op_name, op_num, handler, tla_list) \ 292 { \ 293 handler \ 294 .cmd = op_name, \ 295 .policy = CONCAT_(GENL_MAGIC_FAMILY, _tla_nl_policy), \ 296 }, 297 298 #define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops) 299 static struct genl_ops ZZZ_genl_ops[] __read_mostly = { 300 #include GENL_MAGIC_INCLUDE_FILE 301 }; 302 303 #undef GENL_op 304 #define GENL_op(op_name, op_num, handler, tla_list) 305 306 /* 307 * Define the genl_family, multicast groups, {{{1 308 * and provide register/unregister functions. 309 * {{{2 310 */ 311 #define ZZZ_genl_family CONCAT_(GENL_MAGIC_FAMILY, _genl_family) 312 static struct genl_family ZZZ_genl_family __read_mostly = { 313 .id = GENL_ID_GENERATE, 314 .name = __stringify(GENL_MAGIC_FAMILY), 315 .version = GENL_MAGIC_VERSION, 316 #ifdef GENL_MAGIC_FAMILY_HDRSZ 317 .hdrsize = NLA_ALIGN(GENL_MAGIC_FAMILY_HDRSZ), 318 #endif 319 .maxattr = ARRAY_SIZE(drbd_tla_nl_policy)-1, 320 }; 321 322 /* 323 * Magic: define multicast groups 324 * Magic: define multicast group registration helper 325 */ 326 #undef GENL_mc_group 327 #define GENL_mc_group(group) \ 328 static struct genl_multicast_group \ 329 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group) __read_mostly = { \ 330 .name = #group, \ 331 }; \ 332 static int CONCAT_(GENL_MAGIC_FAMILY, _genl_multicast_ ## group)( \ 333 struct sk_buff *skb, gfp_t flags) \ 334 { \ 335 unsigned int group_id = \ 336 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id; \ 337 if (!group_id) \ 338 return -EINVAL; \ 339 return genlmsg_multicast(skb, 0, group_id, flags); \ 340 } 341 342 #include GENL_MAGIC_INCLUDE_FILE 343 344 int CONCAT_(GENL_MAGIC_FAMILY, _genl_register)(void) 345 { 346 int err = genl_register_family_with_ops(&ZZZ_genl_family, 347 ZZZ_genl_ops, ARRAY_SIZE(ZZZ_genl_ops)); 348 if (err) 349 return err; 350 #undef GENL_mc_group 351 #define GENL_mc_group(group) \ 352 err = genl_register_mc_group(&ZZZ_genl_family, \ 353 &CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group)); \ 354 if (err) \ 355 goto fail; \ 356 else \ 357 pr_info("%s: mcg %s: %u\n", #group, \ 358 __stringify(GENL_MAGIC_FAMILY), \ 359 CONCAT_(GENL_MAGIC_FAMILY, _mcg_ ## group).id); 360 361 #include GENL_MAGIC_INCLUDE_FILE 362 363 #undef GENL_mc_group 364 #define GENL_mc_group(group) 365 return 0; 366 fail: 367 genl_unregister_family(&ZZZ_genl_family); 368 return err; 369 } 370 371 void CONCAT_(GENL_MAGIC_FAMILY, _genl_unregister)(void) 372 { 373 genl_unregister_family(&ZZZ_genl_family); 374 } 375 376 /* 377 * Magic: provide conversion functions {{{1 378 * populate skb from struct. 379 * {{{2 380 */ 381 382 #undef GENL_op 383 #define GENL_op(op_name, op_num, handler, tla_list) 384 385 #undef GENL_struct 386 #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 387 static int s_name ## _to_skb(struct sk_buff *skb, struct s_name *s, \ 388 const bool exclude_sensitive) \ 389 { \ 390 struct nlattr *tla = nla_nest_start(skb, tag_number); \ 391 if (!tla) \ 392 goto nla_put_failure; \ 393 DPRINT_TLA(#s_name, "-=>", #tag_name); \ 394 s_fields \ 395 nla_nest_end(skb, tla); \ 396 return 0; \ 397 \ 398 nla_put_failure: \ 399 if (tla) \ 400 nla_nest_cancel(skb, tla); \ 401 return -EMSGSIZE; \ 402 } \ 403 static inline int s_name ## _to_priv_skb(struct sk_buff *skb, \ 404 struct s_name *s) \ 405 { \ 406 return s_name ## _to_skb(skb, s, 0); \ 407 } \ 408 static inline int s_name ## _to_unpriv_skb(struct sk_buff *skb, \ 409 struct s_name *s) \ 410 { \ 411 return s_name ## _to_skb(skb, s, 1); \ 412 } 413 414 415 #undef __field 416 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ 417 __is_signed) \ 418 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \ 419 DPRINT_FIELD(">>", nla_type, name, s, NULL); \ 420 __put(skb, attr_nr, s->name); \ 421 } 422 423 #undef __array 424 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ 425 __get, __put, __is_signed) \ 426 if (!exclude_sensitive || !((attr_flag) & GENLA_F_SENSITIVE)) { \ 427 DPRINT_ARRAY(">>",nla_type, name, s, NULL); \ 428 __put(skb, attr_nr, min_t(int, maxlen, \ 429 s->name ## _len + (nla_type == NLA_NUL_STRING)),\ 430 s->name); \ 431 } 432 433 #include GENL_MAGIC_INCLUDE_FILE 434 435 436 /* Functions for initializing structs to default values. */ 437 438 #undef __field 439 #define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ 440 __is_signed) 441 #undef __array 442 #define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ 443 __get, __put, __is_signed) 444 #undef __u32_field_def 445 #define __u32_field_def(attr_nr, attr_flag, name, default) \ 446 x->name = default; 447 #undef __s32_field_def 448 #define __s32_field_def(attr_nr, attr_flag, name, default) \ 449 x->name = default; 450 #undef __flg_field_def 451 #define __flg_field_def(attr_nr, attr_flag, name, default) \ 452 x->name = default; 453 #undef __str_field_def 454 #define __str_field_def(attr_nr, attr_flag, name, maxlen) \ 455 memset(x->name, 0, sizeof(x->name)); \ 456 x->name ## _len = 0; 457 #undef GENL_struct 458 #define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 459 static void set_ ## s_name ## _defaults(struct s_name *x) __attribute__((unused)); \ 460 static void set_ ## s_name ## _defaults(struct s_name *x) { \ 461 s_fields \ 462 } 463 464 #include GENL_MAGIC_INCLUDE_FILE 465 466 #endif /* __KERNEL__ */ 467 468 /* }}}1 */ 469 #endif /* GENL_MAGIC_FUNC_H */ 470 /* vim: set foldmethod=marker foldlevel=1 nofoldenable : */ 471