blob: e55ec1597ce795fbb17363541767103c63edb4c5 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Thomas Graf482a8522005-11-10 02:25:56 +01002#ifndef __NET_GENERIC_NETLINK_H
3#define __NET_GENERIC_NETLINK_H
4
5#include <linux/genetlink.h>
6#include <net/netlink.h>
Johannes Berg134e6372009-07-10 09:51:34 +00007#include <net/net_namespace.h>
Thomas Graf482a8522005-11-10 02:25:56 +01008
Thomas Graf58050fc2012-06-28 03:57:45 +00009#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
10
Thomas Graf482a8522005-11-10 02:25:56 +010011/**
Johannes Berg2dbba6f2007-07-18 15:47:52 -070012 * struct genl_multicast_group - generic netlink multicast group
13 * @name: name of the multicast group, names are per-family
Johannes Berg2dbba6f2007-07-18 15:47:52 -070014 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +000015struct genl_multicast_group {
Johannes Berg2dbba6f2007-07-18 15:47:52 -070016 char name[GENL_NAMSIZ];
Johannes Berg2dbba6f2007-07-18 15:47:52 -070017};
18
Johannes Bergff4c92d2010-10-04 21:14:03 +020019struct genl_ops;
20struct genl_info;
21
Johannes Berg2dbba6f2007-07-18 15:47:52 -070022/**
Thomas Graf482a8522005-11-10 02:25:56 +010023 * struct genl_family - generic netlink family
Johannes Berga07ea4d2016-10-24 14:40:02 +020024 * @id: protocol family identifier (private)
Thomas Graf482a8522005-11-10 02:25:56 +010025 * @hdrsize: length of user specific header in bytes
26 * @name: name of family
27 * @version: protocol version
28 * @maxattr: maximum number of attributes supported
Johannes Berg3b0f31f2019-03-21 22:51:02 +010029 * @policy: netlink policy
Johannes Berg134e6372009-07-10 09:51:34 +000030 * @netnsok: set to true if the family can handle network
31 * namespaces and should be presented in all of them
Johannes Bergf555f3d2015-01-16 11:37:12 +010032 * @parallel_ops: operations can be called in parallel and aren't
33 * synchronized by the core genetlink code
Johannes Bergff4c92d2010-10-04 21:14:03 +020034 * @pre_doit: called before an operation's doit callback, it may
35 * do additional, common, filtering and return an error
36 * @post_doit: called after an operation's doit callback, it may
37 * undo operations done by pre_doit, for example release locks
Johannes Berg489111e2016-10-24 14:40:03 +020038 * @mcgrps: multicast groups used by this family
39 * @n_mcgrps: number of multicast groups
Johannes Berg2a94fe42013-11-19 15:19:39 +010040 * @mcgrp_offset: starting number of multicast group IDs in this family
Johannes Berg489111e2016-10-24 14:40:03 +020041 * (private)
42 * @ops: the operations supported by this family
43 * @n_ops: number of operations supported by this family
Jakub Kicinski0b588afd2020-10-02 14:49:53 -070044 * @small_ops: the small-struct operations supported by this family
45 * @n_small_ops: number of small-struct operations supported by this family
Thomas Graf482a8522005-11-10 02:25:56 +010046 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +000047struct genl_family {
David S. Miller98e43212016-11-13 12:14:59 -050048 int id; /* private */
Thomas Graf482a8522005-11-10 02:25:56 +010049 unsigned int hdrsize;
50 char name[GENL_NAMSIZ];
51 unsigned int version;
52 unsigned int maxattr;
Jakub Kicinskie5086732020-10-02 14:49:52 -070053 unsigned int mcgrp_offset; /* private */
54 u8 netnsok:1;
55 u8 parallel_ops:1;
56 u8 n_ops;
Jakub Kicinski0b588afd2020-10-02 14:49:53 -070057 u8 n_small_ops;
Jakub Kicinskie5086732020-10-02 14:49:52 -070058 u8 n_mcgrps;
Johannes Berg3b0f31f2019-03-21 22:51:02 +010059 const struct nla_policy *policy;
Johannes Bergf84f7712013-11-14 17:14:45 +010060 int (*pre_doit)(const struct genl_ops *ops,
Johannes Bergff4c92d2010-10-04 21:14:03 +020061 struct sk_buff *skb,
62 struct genl_info *info);
Johannes Bergf84f7712013-11-14 17:14:45 +010063 void (*post_doit)(const struct genl_ops *ops,
Johannes Bergff4c92d2010-10-04 21:14:03 +020064 struct sk_buff *skb,
65 struct genl_info *info);
Johannes Berg489111e2016-10-24 14:40:03 +020066 const struct genl_ops * ops;
Jakub Kicinski0b588afd2020-10-02 14:49:53 -070067 const struct genl_small_ops *small_ops;
Johannes Berg489111e2016-10-24 14:40:03 +020068 const struct genl_multicast_group *mcgrps;
Pravin B Shelar33c6b1f2013-08-23 12:45:04 -070069 struct module *module;
Thomas Graf482a8522005-11-10 02:25:56 +010070};
71
Thomas Graf482a8522005-11-10 02:25:56 +010072/**
73 * struct genl_info - receiving information
74 * @snd_seq: sending sequence number
Eric W. Biederman15e47302012-09-07 20:12:54 +000075 * @snd_portid: netlink portid of sender
Thomas Graf482a8522005-11-10 02:25:56 +010076 * @nlhdr: netlink message header
77 * @genlhdr: generic netlink message header
78 * @userhdr: user specific header
79 * @attrs: netlink attributes
Johannes Bergff4c92d2010-10-04 21:14:03 +020080 * @_net: network namespace
81 * @user_ptr: user pointers
Johannes Berg7ab606d2017-04-12 14:34:05 +020082 * @extack: extended ACK report struct
Thomas Graf482a8522005-11-10 02:25:56 +010083 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +000084struct genl_info {
Thomas Graf482a8522005-11-10 02:25:56 +010085 u32 snd_seq;
Eric W. Biederman15e47302012-09-07 20:12:54 +000086 u32 snd_portid;
Thomas Graf482a8522005-11-10 02:25:56 +010087 struct nlmsghdr * nlhdr;
88 struct genlmsghdr * genlhdr;
89 void * userhdr;
90 struct nlattr ** attrs;
Eric W. Biederman0c5c9fb2015-03-11 23:06:44 -050091 possible_net_t _net;
Johannes Bergff4c92d2010-10-04 21:14:03 +020092 void * user_ptr[2];
Johannes Berg7ab606d2017-04-12 14:34:05 +020093 struct netlink_ext_ack *extack;
Thomas Graf482a8522005-11-10 02:25:56 +010094};
95
Johannes Berg134e6372009-07-10 09:51:34 +000096static inline struct net *genl_info_net(struct genl_info *info)
97{
Eric Dumazetc2d9ba92010-06-01 06:51:19 +000098 return read_pnet(&info->_net);
Johannes Berg134e6372009-07-10 09:51:34 +000099}
100
101static inline void genl_info_net_set(struct genl_info *info, struct net *net)
102{
Eric Dumazetc2d9ba92010-06-01 06:51:19 +0000103 write_pnet(&info->_net, net);
Johannes Berg134e6372009-07-10 09:51:34 +0000104}
Johannes Berg134e6372009-07-10 09:51:34 +0000105
Johannes Berg7ab606d2017-04-12 14:34:05 +0200106#define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg)
107
Johannes Bergef6243a2019-04-26 14:07:31 +0200108enum genl_validate_flags {
109 GENL_DONT_VALIDATE_STRICT = BIT(0),
110 GENL_DONT_VALIDATE_DUMP = BIT(1),
111 GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2),
112};
113
Thomas Graf482a8522005-11-10 02:25:56 +0100114/**
Jakub Kicinski0b588afd2020-10-02 14:49:53 -0700115 * struct genl_small_ops - generic netlink operations (small version)
116 * @cmd: command identifier
117 * @internal_flags: flags used by the family
118 * @flags: flags
119 * @validate: validation flags from enum genl_validate_flags
120 * @doit: standard command callback
121 * @dumpit: callback for dumpers
122 *
123 * This is a cut-down version of struct genl_ops for users who don't need
124 * most of the ancillary infra and want to save space.
Jiri Pirko1927f412019-10-05 20:04:34 +0200125 */
Jakub Kicinski0b588afd2020-10-02 14:49:53 -0700126struct genl_small_ops {
127 int (*doit)(struct sk_buff *skb, struct genl_info *info);
128 int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
129 u8 cmd;
130 u8 internal_flags;
131 u8 flags;
132 u8 validate;
Jiri Pirko1927f412019-10-05 20:04:34 +0200133};
134
Jiri Pirko1927f412019-10-05 20:04:34 +0200135/**
Thomas Graf482a8522005-11-10 02:25:56 +0100136 * struct genl_ops - generic netlink operations
137 * @cmd: command identifier
Johannes Bergff4c92d2010-10-04 21:14:03 +0200138 * @internal_flags: flags used by the family
Thomas Graf482a8522005-11-10 02:25:56 +0100139 * @flags: flags
Jakub Kicinski48526a02020-10-02 14:49:57 -0700140 * @maxattr: maximum number of attributes supported
141 * @policy: netlink policy (takes precedence over family policy)
Jakub Kicinski3ddf9b42020-09-28 17:53:29 -0700142 * @validate: validation flags from enum genl_validate_flags
Thomas Graf482a8522005-11-10 02:25:56 +0100143 * @doit: standard command callback
Tom Herbertfc9e50f2015-12-15 15:41:37 -0800144 * @start: start callback for dumps
Thomas Graf482a8522005-11-10 02:25:56 +0100145 * @dumpit: callback for dumpers
Jamal Hadi Salima4d13662006-12-01 20:07:42 -0800146 * @done: completion callback for dumps
Thomas Graf482a8522005-11-10 02:25:56 +0100147 */
Eric Dumazetfd2c3ef2009-11-03 03:26:03 +0000148struct genl_ops {
Thomas Graf482a8522005-11-10 02:25:56 +0100149 int (*doit)(struct sk_buff *skb,
150 struct genl_info *info);
Tom Herbertfc9e50f2015-12-15 15:41:37 -0800151 int (*start)(struct netlink_callback *cb);
Thomas Graf482a8522005-11-10 02:25:56 +0100152 int (*dumpit)(struct sk_buff *skb,
153 struct netlink_callback *cb);
Jamal Hadi Salima4d13662006-12-01 20:07:42 -0800154 int (*done)(struct netlink_callback *cb);
Jakub Kicinski48526a02020-10-02 14:49:57 -0700155 const struct nla_policy *policy;
156 unsigned int maxattr;
Johannes Berg3f5ccd02013-11-14 17:14:47 +0100157 u8 cmd;
158 u8 internal_flags;
159 u8 flags;
Johannes Bergef6243a2019-04-26 14:07:31 +0200160 u8 validate;
Thomas Graf482a8522005-11-10 02:25:56 +0100161};
162
Jakub Kicinski0b588afd2020-10-02 14:49:53 -0700163/**
164 * struct genl_info - info that is available during dumpit op call
165 * @family: generic netlink family - for internal genl code usage
166 * @ops: generic netlink ops - for internal genl code usage
167 * @attrs: netlink attributes
168 */
169struct genl_dumpit_info {
170 const struct genl_family *family;
171 struct genl_ops op;
172 struct nlattr **attrs;
173};
174
175static inline const struct genl_dumpit_info *
176genl_dumpit_info(struct netlink_callback *cb)
177{
178 return cb->data;
179}
180
Johannes Berg489111e2016-10-24 14:40:03 +0200181int genl_register_family(struct genl_family *family);
Johannes Berg2ae0f172016-10-24 14:40:04 +0200182int genl_unregister_family(const struct genl_family *family);
183void genl_notify(const struct genl_family *family, struct sk_buff *skb,
Jiri Benc92c14d92015-09-22 18:56:43 +0200184 struct genl_info *info, u32 group, gfp_t flags);
Thomas Graf482a8522005-11-10 02:25:56 +0100185
Eric W. Biederman15e47302012-09-07 20:12:54 +0000186void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
Johannes Berg2ae0f172016-10-24 14:40:04 +0200187 const struct genl_family *family, int flags, u8 cmd);
Thomas Graf482a8522005-11-10 02:25:56 +0100188
189/**
Johannes Berg670dc282011-06-20 13:40:46 +0200190 * genlmsg_nlhdr - Obtain netlink header from user specified header
191 * @user_hdr: user header as returned from genlmsg_put()
Johannes Berg670dc282011-06-20 13:40:46 +0200192 *
193 * Returns pointer to netlink header.
194 */
Michal Kubecek0a833c22017-11-15 13:09:32 +0100195static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr)
Johannes Berg670dc282011-06-20 13:40:46 +0200196{
197 return (struct nlmsghdr *)((char *)user_hdr -
Johannes Berg670dc282011-06-20 13:40:46 +0200198 GENL_HDRLEN -
199 NLMSG_HDRLEN);
200}
201
202/**
Johannes Berg8cb08172019-04-26 14:07:28 +0200203 * genlmsg_parse_deprecated - parse attributes of a genetlink message
Joe Stringer7b1883c2015-01-21 16:42:51 -0800204 * @nlh: netlink message header
205 * @family: genetlink message family
206 * @tb: destination array with maxtype+1 elements
207 * @maxtype: maximum attribute type to be expected
208 * @policy: validation policy
Johannes Bergfceb6432017-04-12 14:34:07 +0200209 * @extack: extended ACK report struct
210 */
Johannes Berg8cb08172019-04-26 14:07:28 +0200211static inline int genlmsg_parse_deprecated(const struct nlmsghdr *nlh,
212 const struct genl_family *family,
213 struct nlattr *tb[], int maxtype,
214 const struct nla_policy *policy,
215 struct netlink_ext_ack *extack)
Joe Stringer7b1883c2015-01-21 16:42:51 -0800216{
Johannes Berg8cb08172019-04-26 14:07:28 +0200217 return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
218 policy, NL_VALIDATE_LIBERAL, extack);
Joe Stringer7b1883c2015-01-21 16:42:51 -0800219}
220
221/**
Johannes Berg3de64402019-04-26 14:07:29 +0200222 * genlmsg_parse - parse attributes of a genetlink message
223 * @nlh: netlink message header
224 * @family: genetlink message family
225 * @tb: destination array with maxtype+1 elements
226 * @maxtype: maximum attribute type to be expected
227 * @policy: validation policy
228 * @extack: extended ACK report struct
229 */
230static inline int genlmsg_parse(const struct nlmsghdr *nlh,
231 const struct genl_family *family,
232 struct nlattr *tb[], int maxtype,
233 const struct nla_policy *policy,
234 struct netlink_ext_ack *extack)
235{
236 return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
237 policy, NL_VALIDATE_STRICT, extack);
238}
239
240/**
Johannes Berg670dc282011-06-20 13:40:46 +0200241 * genl_dump_check_consistent - check if sequence is consistent and advertise if not
242 * @cb: netlink callback structure that stores the sequence number
243 * @user_hdr: user header as returned from genlmsg_put()
Johannes Berg670dc282011-06-20 13:40:46 +0200244 *
245 * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it
246 * simpler to use with generic netlink.
247 */
248static inline void genl_dump_check_consistent(struct netlink_callback *cb,
Michal Kubecek0a833c22017-11-15 13:09:32 +0100249 void *user_hdr)
Johannes Berg670dc282011-06-20 13:40:46 +0200250{
Michal Kubecek0a833c22017-11-15 13:09:32 +0100251 nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr));
Johannes Berg670dc282011-06-20 13:40:46 +0200252}
253
254/**
Thomas Graf17c157c2006-11-14 19:46:02 -0800255 * genlmsg_put_reply - Add generic netlink header to a reply message
256 * @skb: socket buffer holding the message
257 * @info: receiver info
258 * @family: generic netlink family
259 * @flags: netlink message flags
260 * @cmd: generic netlink command
261 *
262 * Returns pointer to user specific header
263 */
264static inline void *genlmsg_put_reply(struct sk_buff *skb,
265 struct genl_info *info,
Johannes Berg2ae0f172016-10-24 14:40:04 +0200266 const struct genl_family *family,
Thomas Graf17c157c2006-11-14 19:46:02 -0800267 int flags, u8 cmd)
268{
Eric W. Biederman15e47302012-09-07 20:12:54 +0000269 return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
Thomas Graf17c157c2006-11-14 19:46:02 -0800270 flags, cmd);
271}
272
273/**
Thomas Graf482a8522005-11-10 02:25:56 +0100274 * genlmsg_end - Finalize a generic netlink message
275 * @skb: socket buffer the message is stored in
276 * @hdr: user specific header
277 */
Johannes Berg053c0952015-01-16 22:09:00 +0100278static inline void genlmsg_end(struct sk_buff *skb, void *hdr)
Thomas Graf482a8522005-11-10 02:25:56 +0100279{
Johannes Berg053c0952015-01-16 22:09:00 +0100280 nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
Thomas Graf482a8522005-11-10 02:25:56 +0100281}
282
283/**
284 * genlmsg_cancel - Cancel construction of a generic netlink message
285 * @skb: socket buffer the message is stored in
286 * @hdr: generic netlink message header
287 */
Thomas Grafbc3ed282008-06-03 16:36:54 -0700288static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
Thomas Graf482a8522005-11-10 02:25:56 +0100289{
Julia Lawall38db9e12011-01-28 05:43:40 +0000290 if (hdr)
291 nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
Thomas Graf482a8522005-11-10 02:25:56 +0100292}
293
294/**
Johannes Berg134e6372009-07-10 09:51:34 +0000295 * genlmsg_multicast_netns - multicast a netlink message to a specific netns
Johannes Berg68eb5502013-11-19 15:19:38 +0100296 * @family: the generic netlink family
Johannes Berg134e6372009-07-10 09:51:34 +0000297 * @net: the net namespace
298 * @skb: netlink message as socket buffer
Eric W. Biederman15e47302012-09-07 20:12:54 +0000299 * @portid: own netlink portid to avoid sending to yourself
Johannes Berg2a94fe42013-11-19 15:19:39 +0100300 * @group: offset of multicast group in groups array
Johannes Berg134e6372009-07-10 09:51:34 +0000301 * @flags: allocation flags
302 */
Johannes Berg2ae0f172016-10-24 14:40:04 +0200303static inline int genlmsg_multicast_netns(const struct genl_family *family,
Johannes Berg68eb5502013-11-19 15:19:38 +0100304 struct net *net, struct sk_buff *skb,
Eric W. Biederman15e47302012-09-07 20:12:54 +0000305 u32 portid, unsigned int group, gfp_t flags)
Johannes Berg134e6372009-07-10 09:51:34 +0000306{
Johannes Berg220815a2013-11-21 18:17:04 +0100307 if (WARN_ON_ONCE(group >= family->n_mcgrps))
Johannes Berg2a94fe42013-11-19 15:19:39 +0100308 return -EINVAL;
309 group = family->mcgrp_offset + group;
Eric W. Biederman15e47302012-09-07 20:12:54 +0000310 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
Johannes Berg134e6372009-07-10 09:51:34 +0000311}
312
313/**
314 * genlmsg_multicast - multicast a netlink message to the default netns
Johannes Berg68eb5502013-11-19 15:19:38 +0100315 * @family: the generic netlink family
Thomas Graf482a8522005-11-10 02:25:56 +0100316 * @skb: netlink message as socket buffer
Eric W. Biederman15e47302012-09-07 20:12:54 +0000317 * @portid: own netlink portid to avoid sending to yourself
Johannes Berg2a94fe42013-11-19 15:19:39 +0100318 * @group: offset of multicast group in groups array
Thomas Grafd387f6a2006-08-15 00:31:06 -0700319 * @flags: allocation flags
Thomas Graf482a8522005-11-10 02:25:56 +0100320 */
Johannes Berg2ae0f172016-10-24 14:40:04 +0200321static inline int genlmsg_multicast(const struct genl_family *family,
Johannes Berg68eb5502013-11-19 15:19:38 +0100322 struct sk_buff *skb, u32 portid,
Thomas Grafd387f6a2006-08-15 00:31:06 -0700323 unsigned int group, gfp_t flags)
Thomas Graf482a8522005-11-10 02:25:56 +0100324{
Johannes Berg68eb5502013-11-19 15:19:38 +0100325 return genlmsg_multicast_netns(family, &init_net, skb,
326 portid, group, flags);
Thomas Graf482a8522005-11-10 02:25:56 +0100327}
328
329/**
Johannes Berg134e6372009-07-10 09:51:34 +0000330 * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
Johannes Berg68eb5502013-11-19 15:19:38 +0100331 * @family: the generic netlink family
Johannes Berg134e6372009-07-10 09:51:34 +0000332 * @skb: netlink message as socket buffer
Eric W. Biederman15e47302012-09-07 20:12:54 +0000333 * @portid: own netlink portid to avoid sending to yourself
Johannes Berg2a94fe42013-11-19 15:19:39 +0100334 * @group: offset of multicast group in groups array
Johannes Berg134e6372009-07-10 09:51:34 +0000335 * @flags: allocation flags
336 *
337 * This function must hold the RTNL or rcu_read_lock().
338 */
Johannes Berg2ae0f172016-10-24 14:40:04 +0200339int genlmsg_multicast_allns(const struct genl_family *family,
Johannes Berg68eb5502013-11-19 15:19:38 +0100340 struct sk_buff *skb, u32 portid,
Johannes Berg134e6372009-07-10 09:51:34 +0000341 unsigned int group, gfp_t flags);
342
343/**
Thomas Graf482a8522005-11-10 02:25:56 +0100344 * genlmsg_unicast - unicast a netlink message
345 * @skb: netlink message as socket buffer
Eric W. Biederman15e47302012-09-07 20:12:54 +0000346 * @portid: netlink portid of the destination socket
Thomas Graf482a8522005-11-10 02:25:56 +0100347 */
Eric W. Biederman15e47302012-09-07 20:12:54 +0000348static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
Thomas Graf482a8522005-11-10 02:25:56 +0100349{
Eric W. Biederman15e47302012-09-07 20:12:54 +0000350 return nlmsg_unicast(net->genl_sock, skb, portid);
Thomas Graf482a8522005-11-10 02:25:56 +0100351}
352
Balbir Singhfb0ba6bd2006-07-14 00:24:39 -0700353/**
Thomas Graf81878d22006-11-14 19:45:27 -0800354 * genlmsg_reply - reply to a request
355 * @skb: netlink message to be sent back
356 * @info: receiver information
357 */
358static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
359{
Eric W. Biederman15e47302012-09-07 20:12:54 +0000360 return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
Thomas Graf81878d22006-11-14 19:45:27 -0800361}
362
363/**
Balbir Singhfb0ba6bd2006-07-14 00:24:39 -0700364 * gennlmsg_data - head of message payload
Justin P. Mattock70f23fd2011-05-10 10:16:21 +0200365 * @gnlh: genetlink message header
Balbir Singhfb0ba6bd2006-07-14 00:24:39 -0700366 */
367static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
368{
369 return ((unsigned char *) gnlh + GENL_HDRLEN);
370}
371
372/**
373 * genlmsg_len - length of message payload
374 * @gnlh: genetlink message header
375 */
376static inline int genlmsg_len(const struct genlmsghdr *gnlh)
377{
378 struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
379 NLMSG_HDRLEN);
380 return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
381}
382
Balbir Singh17db9522006-09-30 23:28:51 -0700383/**
384 * genlmsg_msg_size - length of genetlink message not including padding
385 * @payload: length of message payload
386 */
387static inline int genlmsg_msg_size(int payload)
388{
389 return GENL_HDRLEN + payload;
390}
391
392/**
393 * genlmsg_total_size - length of genetlink message including padding
394 * @payload: length of message payload
395 */
396static inline int genlmsg_total_size(int payload)
397{
398 return NLMSG_ALIGN(genlmsg_msg_size(payload));
399}
400
Thomas Graf3dabc712006-11-14 19:44:52 -0800401/**
402 * genlmsg_new - Allocate a new generic netlink message
403 * @payload: size of the message payload
404 * @flags: the type of memory to allocate.
405 */
406static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
407{
408 return nlmsg_new(genlmsg_total_size(payload), flags);
409}
410
Johannes Berg62b68e92013-11-19 15:19:37 +0100411/**
412 * genl_set_err - report error to genetlink broadcast listeners
Johannes Berg68eb5502013-11-19 15:19:38 +0100413 * @family: the generic netlink family
Johannes Berg62b68e92013-11-19 15:19:37 +0100414 * @net: the network namespace to report the error to
415 * @portid: the PORTID of a process that we want to skip (if any)
416 * @group: the broadcast group that will notice the error
Johannes Berg2a94fe42013-11-19 15:19:39 +0100417 * (this is the offset of the multicast group in the groups array)
Johannes Berg62b68e92013-11-19 15:19:37 +0100418 * @code: error code, must be negative (as usual in kernelspace)
419 *
420 * This function returns the number of broadcast listeners that have set the
421 * NETLINK_RECV_NO_ENOBUFS socket option.
422 */
Johannes Berg2ae0f172016-10-24 14:40:04 +0200423static inline int genl_set_err(const struct genl_family *family,
424 struct net *net, u32 portid,
425 u32 group, int code)
Johannes Berg62b68e92013-11-19 15:19:37 +0100426{
Johannes Berg91398a02013-11-21 18:20:28 +0100427 if (WARN_ON_ONCE(group >= family->n_mcgrps))
428 return -EINVAL;
429 group = family->mcgrp_offset + group;
Johannes Berg62b68e92013-11-19 15:19:37 +0100430 return netlink_set_err(net->genl_sock, portid, group, code);
431}
Thomas Graf3dabc712006-11-14 19:44:52 -0800432
Johannes Berg2ae0f172016-10-24 14:40:04 +0200433static inline int genl_has_listeners(const struct genl_family *family,
Johannes Bergf8403a22014-12-22 18:56:36 +0100434 struct net *net, unsigned int group)
Nicolas Dichtel0d566372014-09-18 10:31:03 +0200435{
436 if (WARN_ON_ONCE(group >= family->n_mcgrps))
437 return -EINVAL;
438 group = family->mcgrp_offset + group;
Johannes Bergf8403a22014-12-22 18:56:36 +0100439 return netlink_has_listeners(net->genl_sock, group);
Nicolas Dichtel0d566372014-09-18 10:31:03 +0200440}
Thomas Graf482a8522005-11-10 02:25:56 +0100441#endif /* __NET_GENERIC_NETLINK_H */