0001
0002 #ifndef __NET_GENERIC_NETLINK_H
0003 #define __NET_GENERIC_NETLINK_H
0004
0005 #include <linux/genetlink.h>
0006 #include <net/netlink.h>
0007 #include <net/net_namespace.h>
0008
0009 #define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
0010
0011
0012
0013
0014
0015
0016 struct genl_multicast_group {
0017 char name[GENL_NAMSIZ];
0018 u8 flags;
0019 };
0020
0021 struct genl_ops;
0022 struct genl_info;
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 struct genl_family {
0050 int id;
0051 unsigned int hdrsize;
0052 char name[GENL_NAMSIZ];
0053 unsigned int version;
0054 unsigned int maxattr;
0055 unsigned int mcgrp_offset;
0056 u8 netnsok:1;
0057 u8 parallel_ops:1;
0058 u8 n_ops;
0059 u8 n_small_ops;
0060 u8 n_mcgrps;
0061 const struct nla_policy *policy;
0062 int (*pre_doit)(const struct genl_ops *ops,
0063 struct sk_buff *skb,
0064 struct genl_info *info);
0065 void (*post_doit)(const struct genl_ops *ops,
0066 struct sk_buff *skb,
0067 struct genl_info *info);
0068 const struct genl_ops * ops;
0069 const struct genl_small_ops *small_ops;
0070 const struct genl_multicast_group *mcgrps;
0071 struct module *module;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 struct genl_info {
0087 u32 snd_seq;
0088 u32 snd_portid;
0089 struct nlmsghdr * nlhdr;
0090 struct genlmsghdr * genlhdr;
0091 void * userhdr;
0092 struct nlattr ** attrs;
0093 possible_net_t _net;
0094 void * user_ptr[2];
0095 struct netlink_ext_ack *extack;
0096 };
0097
0098 static inline struct net *genl_info_net(struct genl_info *info)
0099 {
0100 return read_pnet(&info->_net);
0101 }
0102
0103 static inline void genl_info_net_set(struct genl_info *info, struct net *net)
0104 {
0105 write_pnet(&info->_net, net);
0106 }
0107
0108 #define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg)
0109
0110 enum genl_validate_flags {
0111 GENL_DONT_VALIDATE_STRICT = BIT(0),
0112 GENL_DONT_VALIDATE_DUMP = BIT(1),
0113 GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2),
0114 };
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 struct genl_small_ops {
0129 int (*doit)(struct sk_buff *skb, struct genl_info *info);
0130 int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
0131 u8 cmd;
0132 u8 internal_flags;
0133 u8 flags;
0134 u8 validate;
0135 };
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 struct genl_ops {
0151 int (*doit)(struct sk_buff *skb,
0152 struct genl_info *info);
0153 int (*start)(struct netlink_callback *cb);
0154 int (*dumpit)(struct sk_buff *skb,
0155 struct netlink_callback *cb);
0156 int (*done)(struct netlink_callback *cb);
0157 const struct nla_policy *policy;
0158 unsigned int maxattr;
0159 u8 cmd;
0160 u8 internal_flags;
0161 u8 flags;
0162 u8 validate;
0163 };
0164
0165
0166
0167
0168
0169
0170
0171 struct genl_dumpit_info {
0172 const struct genl_family *family;
0173 struct genl_ops op;
0174 struct nlattr **attrs;
0175 };
0176
0177 static inline const struct genl_dumpit_info *
0178 genl_dumpit_info(struct netlink_callback *cb)
0179 {
0180 return cb->data;
0181 }
0182
0183 int genl_register_family(struct genl_family *family);
0184 int genl_unregister_family(const struct genl_family *family);
0185 void genl_notify(const struct genl_family *family, struct sk_buff *skb,
0186 struct genl_info *info, u32 group, gfp_t flags);
0187
0188 void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
0189 const struct genl_family *family, int flags, u8 cmd);
0190
0191
0192
0193
0194
0195
0196
0197 static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr)
0198 {
0199 return (struct nlmsghdr *)((char *)user_hdr -
0200 GENL_HDRLEN -
0201 NLMSG_HDRLEN);
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 static inline int genlmsg_parse_deprecated(const struct nlmsghdr *nlh,
0214 const struct genl_family *family,
0215 struct nlattr *tb[], int maxtype,
0216 const struct nla_policy *policy,
0217 struct netlink_ext_ack *extack)
0218 {
0219 return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
0220 policy, NL_VALIDATE_LIBERAL, extack);
0221 }
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232 static inline int genlmsg_parse(const struct nlmsghdr *nlh,
0233 const struct genl_family *family,
0234 struct nlattr *tb[], int maxtype,
0235 const struct nla_policy *policy,
0236 struct netlink_ext_ack *extack)
0237 {
0238 return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
0239 policy, NL_VALIDATE_STRICT, extack);
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250 static inline void genl_dump_check_consistent(struct netlink_callback *cb,
0251 void *user_hdr)
0252 {
0253 nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr));
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266 static inline void *genlmsg_put_reply(struct sk_buff *skb,
0267 struct genl_info *info,
0268 const struct genl_family *family,
0269 int flags, u8 cmd)
0270 {
0271 return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
0272 flags, cmd);
0273 }
0274
0275
0276
0277
0278
0279
0280 static inline void genlmsg_end(struct sk_buff *skb, void *hdr)
0281 {
0282 nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
0283 }
0284
0285
0286
0287
0288
0289
0290 static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
0291 {
0292 if (hdr)
0293 nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
0294 }
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 static inline int genlmsg_multicast_netns(const struct genl_family *family,
0306 struct net *net, struct sk_buff *skb,
0307 u32 portid, unsigned int group, gfp_t flags)
0308 {
0309 if (WARN_ON_ONCE(group >= family->n_mcgrps))
0310 return -EINVAL;
0311 group = family->mcgrp_offset + group;
0312 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323 static inline int genlmsg_multicast(const struct genl_family *family,
0324 struct sk_buff *skb, u32 portid,
0325 unsigned int group, gfp_t flags)
0326 {
0327 return genlmsg_multicast_netns(family, &init_net, skb,
0328 portid, group, flags);
0329 }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 int genlmsg_multicast_allns(const struct genl_family *family,
0342 struct sk_buff *skb, u32 portid,
0343 unsigned int group, gfp_t flags);
0344
0345
0346
0347
0348
0349
0350 static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
0351 {
0352 return nlmsg_unicast(net->genl_sock, skb, portid);
0353 }
0354
0355
0356
0357
0358
0359
0360 static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
0361 {
0362 return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
0363 }
0364
0365
0366
0367
0368
0369 static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
0370 {
0371 return ((unsigned char *) gnlh + GENL_HDRLEN);
0372 }
0373
0374
0375
0376
0377
0378 static inline int genlmsg_len(const struct genlmsghdr *gnlh)
0379 {
0380 struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
0381 NLMSG_HDRLEN);
0382 return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
0383 }
0384
0385
0386
0387
0388
0389 static inline int genlmsg_msg_size(int payload)
0390 {
0391 return GENL_HDRLEN + payload;
0392 }
0393
0394
0395
0396
0397
0398 static inline int genlmsg_total_size(int payload)
0399 {
0400 return NLMSG_ALIGN(genlmsg_msg_size(payload));
0401 }
0402
0403
0404
0405
0406
0407
0408 static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
0409 {
0410 return nlmsg_new(genlmsg_total_size(payload), flags);
0411 }
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425 static inline int genl_set_err(const struct genl_family *family,
0426 struct net *net, u32 portid,
0427 u32 group, int code)
0428 {
0429 if (WARN_ON_ONCE(group >= family->n_mcgrps))
0430 return -EINVAL;
0431 group = family->mcgrp_offset + group;
0432 return netlink_set_err(net->genl_sock, portid, group, code);
0433 }
0434
0435 static inline int genl_has_listeners(const struct genl_family *family,
0436 struct net *net, unsigned int group)
0437 {
0438 if (WARN_ON_ONCE(group >= family->n_mcgrps))
0439 return -EINVAL;
0440 group = family->mcgrp_offset + group;
0441 return netlink_has_listeners(net->genl_sock, group);
0442 }
0443 #endif