1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef GENL_MAGIC_STRUCT_H 3#define GENL_MAGIC_STRUCT_H 4 5#ifndef GENL_MAGIC_FAMILY 6# error "you need to define GENL_MAGIC_FAMILY before inclusion" 7#endif 8 9#ifndef GENL_MAGIC_VERSION 10# error "you need to define GENL_MAGIC_VERSION before inclusion" 11#endif 12 13#ifndef GENL_MAGIC_INCLUDE_FILE 14# error "you need to define GENL_MAGIC_INCLUDE_FILE before inclusion" 15#endif 16 17#include <linux/args.h> 18#include <linux/genetlink.h> 19#include <linux/types.h> 20 21extern int CONCATENATE(GENL_MAGIC_FAMILY, _genl_register)(void); 22extern void CONCATENATE(GENL_MAGIC_FAMILY, _genl_unregister)(void); 23 24/* 25 * Extension of genl attribute validation policies {{{2 26 */ 27 28/* 29 * @DRBD_GENLA_F_MANDATORY: By default, netlink ignores attributes it does not 30 * know about. This flag can be set in nlattr->nla_type to indicate that this 31 * attribute must not be ignored. 32 * 33 * We check and remove this flag in drbd_nla_check_mandatory() before 34 * validating the attribute types and lengths via nla_parse_nested(). 35 */ 36#define DRBD_GENLA_F_MANDATORY (1 << 14) 37 38/* 39 * Flags specific to drbd and not visible at the netlink layer, used in 40 * <struct>_from_attrs and <struct>_to_skb: 41 * 42 * @DRBD_F_REQUIRED: Attribute is required; a request without this attribute is 43 * invalid. 44 * 45 * @DRBD_F_SENSITIVE: Attribute includes sensitive information and must not be 46 * included in unpriviledged get requests or broadcasts. 47 * 48 * @DRBD_F_INVARIANT: Attribute is set when an object is initially created, but 49 * cannot subsequently be changed. 50 */ 51#define DRBD_F_REQUIRED (1 << 0) 52#define DRBD_F_SENSITIVE (1 << 1) 53#define DRBD_F_INVARIANT (1 << 2) 54 55#define __nla_type(x) ((__u16)((x) & NLA_TYPE_MASK & ~DRBD_GENLA_F_MANDATORY)) 56 57/* }}}1 58 * MAGIC 59 * multi-include macro expansion magic starts here 60 */ 61 62/* MAGIC helpers {{{2 */ 63 64static inline int nla_put_u64_0pad(struct sk_buff *skb, int attrtype, u64 value) 65{ 66 return nla_put_64bit(skb, attrtype, sizeof(u64), &value, 0); 67} 68 69/* possible field types */ 70#define __flg_field(attr_nr, attr_flag, name) \ 71 __field(attr_nr, attr_flag, name, NLA_U8, char, \ 72 nla_get_u8, nla_put_u8, false) 73#define __u8_field(attr_nr, attr_flag, name) \ 74 __field(attr_nr, attr_flag, name, NLA_U8, unsigned char, \ 75 nla_get_u8, nla_put_u8, false) 76#define __u16_field(attr_nr, attr_flag, name) \ 77 __field(attr_nr, attr_flag, name, NLA_U16, __u16, \ 78 nla_get_u16, nla_put_u16, false) 79#define __u32_field(attr_nr, attr_flag, name) \ 80 __field(attr_nr, attr_flag, name, NLA_U32, __u32, \ 81 nla_get_u32, nla_put_u32, false) 82#define __s32_field(attr_nr, attr_flag, name) \ 83 __field(attr_nr, attr_flag, name, NLA_U32, __s32, \ 84 nla_get_u32, nla_put_u32, true) 85#define __u64_field(attr_nr, attr_flag, name) \ 86 __field(attr_nr, attr_flag, name, NLA_U64, __u64, \ 87 nla_get_u64, nla_put_u64_0pad, false) 88#define __str_field(attr_nr, attr_flag, name, maxlen) \ 89 __array(attr_nr, attr_flag, name, NLA_NUL_STRING, char, maxlen, \ 90 nla_strscpy, nla_put, false) 91#define __bin_field(attr_nr, attr_flag, name, maxlen) \ 92 __array(attr_nr, attr_flag, name, NLA_BINARY, char, maxlen, \ 93 nla_memcpy, nla_put, false) 94 95/* fields with default values */ 96#define __flg_field_def(attr_nr, attr_flag, name, default) \ 97 __flg_field(attr_nr, attr_flag, name) 98#define __u32_field_def(attr_nr, attr_flag, name, default) \ 99 __u32_field(attr_nr, attr_flag, name) 100#define __s32_field_def(attr_nr, attr_flag, name, default) \ 101 __s32_field(attr_nr, attr_flag, name) 102#define __str_field_def(attr_nr, attr_flag, name, maxlen) \ 103 __str_field(attr_nr, attr_flag, name, maxlen) 104 105#define GENL_op_init(args...) args 106#define GENL_doit(handler) \ 107 .doit = handler, \ 108 .flags = GENL_ADMIN_PERM, 109#define GENL_dumpit(handler) \ 110 .dumpit = handler, \ 111 .flags = GENL_ADMIN_PERM, 112 113/* }}}1 114 * Magic: define the enum symbols for genl_ops 115 * Magic: define the enum symbols for top level attributes 116 * Magic: define the enum symbols for nested attributes 117 * {{{2 118 */ 119 120#undef GENL_struct 121#define GENL_struct(tag_name, tag_number, s_name, s_fields) 122 123#undef GENL_mc_group 124#define GENL_mc_group(group) 125 126#undef GENL_notification 127#define GENL_notification(op_name, op_num, mcast_group, tla_list) \ 128 op_name = op_num, 129 130#undef GENL_op 131#define GENL_op(op_name, op_num, handler, tla_list) \ 132 op_name = op_num, 133 134enum { 135#include GENL_MAGIC_INCLUDE_FILE 136}; 137 138#undef GENL_notification 139#define GENL_notification(op_name, op_num, mcast_group, tla_list) 140 141#undef GENL_op 142#define GENL_op(op_name, op_num, handler, attr_list) 143 144#undef GENL_struct 145#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 146 tag_name = tag_number, 147 148enum { 149#include GENL_MAGIC_INCLUDE_FILE 150}; 151 152#undef GENL_struct 153#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 154enum { \ 155 s_fields \ 156}; 157 158#undef __field 159#define __field(attr_nr, attr_flag, name, nla_type, type, \ 160 __get, __put, __is_signed) \ 161 T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)), 162 163#undef __array 164#define __array(attr_nr, attr_flag, name, nla_type, type, \ 165 maxlen, __get, __put, __is_signed) \ 166 T_ ## name = (__u16)(attr_nr | ((attr_flag) & DRBD_GENLA_F_MANDATORY)), 167 168#include GENL_MAGIC_INCLUDE_FILE 169 170/* }}}1 171 * Magic: compile time assert unique numbers for operations 172 * Magic: -"- unique numbers for top level attributes 173 * Magic: -"- unique numbers for nested attributes 174 * {{{2 175 */ 176 177#undef GENL_struct 178#define GENL_struct(tag_name, tag_number, s_name, s_fields) 179 180#undef GENL_op 181#define GENL_op(op_name, op_num, handler, attr_list) \ 182 case op_name: 183 184#undef GENL_notification 185#define GENL_notification(op_name, op_num, mcast_group, tla_list) \ 186 case op_name: 187 188static inline void ct_assert_unique_operations(void) 189{ 190 switch (0) { 191#include GENL_MAGIC_INCLUDE_FILE 192 case 0: 193 ; 194 } 195} 196 197#undef GENL_op 198#define GENL_op(op_name, op_num, handler, attr_list) 199 200#undef GENL_notification 201#define GENL_notification(op_name, op_num, mcast_group, tla_list) 202 203#undef GENL_struct 204#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 205 case tag_number: 206 207static inline void ct_assert_unique_top_level_attributes(void) 208{ 209 switch (0) { 210#include GENL_MAGIC_INCLUDE_FILE 211 case 0: 212 ; 213 } 214} 215 216#undef GENL_struct 217#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 218static inline void ct_assert_unique_ ## s_name ## _attributes(void) \ 219{ \ 220 switch (0) { \ 221 s_fields \ 222 case 0: \ 223 ; \ 224 } \ 225} 226 227#undef __field 228#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ 229 __is_signed) \ 230 case attr_nr: 231 232#undef __array 233#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ 234 __get, __put, __is_signed) \ 235 case attr_nr: 236 237#include GENL_MAGIC_INCLUDE_FILE 238 239/* }}}1 240 * Magic: declare structs 241 * struct <name> { 242 * fields 243 * }; 244 * {{{2 245 */ 246 247#undef GENL_struct 248#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 249struct s_name { s_fields }; 250 251#undef __field 252#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ 253 __is_signed) \ 254 type name; 255 256#undef __array 257#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ 258 __get, __put, __is_signed) \ 259 type name[maxlen]; \ 260 __u32 name ## _len; 261 262#include GENL_MAGIC_INCLUDE_FILE 263 264#undef GENL_struct 265#define GENL_struct(tag_name, tag_number, s_name, s_fields) \ 266enum { \ 267 s_fields \ 268}; 269 270#undef __field 271#define __field(attr_nr, attr_flag, name, nla_type, type, __get, __put, \ 272 is_signed) \ 273 F_ ## name ## _IS_SIGNED = is_signed, 274 275#undef __array 276#define __array(attr_nr, attr_flag, name, nla_type, type, maxlen, \ 277 __get, __put, is_signed) \ 278 F_ ## name ## _IS_SIGNED = is_signed, 279 280#include GENL_MAGIC_INCLUDE_FILE 281 282/* }}}1 */ 283#endif /* GENL_MAGIC_STRUCT_H */ 284