• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __NET_GENERIC_NETLINK_H
3 #define __NET_GENERIC_NETLINK_H
4 
5 #include <linux/genetlink.h>
6 #include <linux/android_kabi.h>
7 #include <net/netlink.h>
8 #include <net/net_namespace.h>
9 
10 #define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
11 
12 /**
13  * struct genl_multicast_group - generic netlink multicast group
14  * @name: name of the multicast group, names are per-family
15  * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
16  */
17 struct genl_multicast_group {
18 	char			name[GENL_NAMSIZ];
19 	u8			flags;
20 };
21 
22 struct genl_ops;
23 struct genl_info;
24 
25 /**
26  * struct genl_family - generic netlink family
27  * @id: protocol family identifier (private)
28  * @hdrsize: length of user specific header in bytes
29  * @name: name of family
30  * @version: protocol version
31  * @maxattr: maximum number of attributes supported
32  * @policy: netlink policy
33  * @netnsok: set to true if the family can handle network
34  *	namespaces and should be presented in all of them
35  * @parallel_ops: operations can be called in parallel and aren't
36  *	synchronized by the core genetlink code
37  * @pre_doit: called before an operation's doit callback, it may
38  *	do additional, common, filtering and return an error
39  * @post_doit: called after an operation's doit callback, it may
40  *	undo operations done by pre_doit, for example release locks
41  * @mcgrps: multicast groups used by this family
42  * @n_mcgrps: number of multicast groups
43  * @mcgrp_offset: starting number of multicast group IDs in this family
44  *	(private)
45  * @ops: the operations supported by this family
46  * @n_ops: number of operations supported by this family
47  * @small_ops: the small-struct operations supported by this family
48  * @n_small_ops: number of small-struct operations supported by this family
49  */
50 struct genl_family {
51 	int			id;		/* private */
52 	unsigned int		hdrsize;
53 	char			name[GENL_NAMSIZ];
54 	unsigned int		version;
55 	unsigned int		maxattr;
56 	unsigned int		mcgrp_offset;	/* private */
57 	u8			netnsok:1;
58 	u8			parallel_ops:1;
59 	u8			n_ops;
60 	u8			n_small_ops;
61 	u8			n_mcgrps;
62 	const struct nla_policy *policy;
63 	int			(*pre_doit)(const struct genl_ops *ops,
64 					    struct sk_buff *skb,
65 					    struct genl_info *info);
66 	void			(*post_doit)(const struct genl_ops *ops,
67 					     struct sk_buff *skb,
68 					     struct genl_info *info);
69 	const struct genl_ops *	ops;
70 	const struct genl_small_ops *small_ops;
71 	const struct genl_multicast_group *mcgrps;
72 	struct module		*module;
73 
74 	ANDROID_KABI_RESERVE(1);
75 };
76 
77 /**
78  * struct genl_info - receiving information
79  * @snd_seq: sending sequence number
80  * @snd_portid: netlink portid of sender
81  * @nlhdr: netlink message header
82  * @genlhdr: generic netlink message header
83  * @userhdr: user specific header
84  * @attrs: netlink attributes
85  * @_net: network namespace
86  * @user_ptr: user pointers
87  * @extack: extended ACK report struct
88  */
89 struct genl_info {
90 	u32			snd_seq;
91 	u32			snd_portid;
92 	struct nlmsghdr *	nlhdr;
93 	struct genlmsghdr *	genlhdr;
94 	void *			userhdr;
95 	struct nlattr **	attrs;
96 	possible_net_t		_net;
97 	void *			user_ptr[2];
98 	struct netlink_ext_ack *extack;
99 };
100 
genl_info_net(struct genl_info * info)101 static inline struct net *genl_info_net(struct genl_info *info)
102 {
103 	return read_pnet(&info->_net);
104 }
105 
genl_info_net_set(struct genl_info * info,struct net * net)106 static inline void genl_info_net_set(struct genl_info *info, struct net *net)
107 {
108 	write_pnet(&info->_net, net);
109 }
110 
111 #define GENL_SET_ERR_MSG(info, msg) NL_SET_ERR_MSG((info)->extack, msg)
112 
113 enum genl_validate_flags {
114 	GENL_DONT_VALIDATE_STRICT		= BIT(0),
115 	GENL_DONT_VALIDATE_DUMP			= BIT(1),
116 	GENL_DONT_VALIDATE_DUMP_STRICT		= BIT(2),
117 };
118 
119 /**
120  * struct genl_small_ops - generic netlink operations (small version)
121  * @cmd: command identifier
122  * @internal_flags: flags used by the family
123  * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
124  * @validate: validation flags from enum genl_validate_flags
125  * @doit: standard command callback
126  * @dumpit: callback for dumpers
127  *
128  * This is a cut-down version of struct genl_ops for users who don't need
129  * most of the ancillary infra and want to save space.
130  */
131 struct genl_small_ops {
132 	int	(*doit)(struct sk_buff *skb, struct genl_info *info);
133 	int	(*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
134 	u8	cmd;
135 	u8	internal_flags;
136 	u8	flags;
137 	u8	validate;
138 };
139 
140 /**
141  * struct genl_ops - generic netlink operations
142  * @cmd: command identifier
143  * @internal_flags: flags used by the family
144  * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
145  * @maxattr: maximum number of attributes supported
146  * @policy: netlink policy (takes precedence over family policy)
147  * @validate: validation flags from enum genl_validate_flags
148  * @doit: standard command callback
149  * @start: start callback for dumps
150  * @dumpit: callback for dumpers
151  * @done: completion callback for dumps
152  */
153 struct genl_ops {
154 	int		       (*doit)(struct sk_buff *skb,
155 				       struct genl_info *info);
156 	int		       (*start)(struct netlink_callback *cb);
157 	int		       (*dumpit)(struct sk_buff *skb,
158 					 struct netlink_callback *cb);
159 	int		       (*done)(struct netlink_callback *cb);
160 	const struct nla_policy *policy;
161 	unsigned int		maxattr;
162 	u8			cmd;
163 	u8			internal_flags;
164 	u8			flags;
165 	u8			validate;
166 
167 	ANDROID_KABI_RESERVE(1);
168 };
169 
170 /**
171  * struct genl_info - info that is available during dumpit op call
172  * @family: generic netlink family - for internal genl code usage
173  * @ops: generic netlink ops - for internal genl code usage
174  * @attrs: netlink attributes
175  */
176 struct genl_dumpit_info {
177 	const struct genl_family *family;
178 	struct genl_ops op;
179 	struct nlattr **attrs;
180 };
181 
182 static inline const struct genl_dumpit_info *
genl_dumpit_info(struct netlink_callback * cb)183 genl_dumpit_info(struct netlink_callback *cb)
184 {
185 	return cb->data;
186 }
187 
188 int genl_register_family(struct genl_family *family);
189 int genl_unregister_family(const struct genl_family *family);
190 void genl_notify(const struct genl_family *family, struct sk_buff *skb,
191 		 struct genl_info *info, u32 group, gfp_t flags);
192 
193 void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
194 		  const struct genl_family *family, int flags, u8 cmd);
195 
196 /**
197  * genlmsg_nlhdr - Obtain netlink header from user specified header
198  * @user_hdr: user header as returned from genlmsg_put()
199  *
200  * Returns pointer to netlink header.
201  */
genlmsg_nlhdr(void * user_hdr)202 static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr)
203 {
204 	return (struct nlmsghdr *)((char *)user_hdr -
205 				   GENL_HDRLEN -
206 				   NLMSG_HDRLEN);
207 }
208 
209 /**
210  * genlmsg_parse_deprecated - parse attributes of a genetlink message
211  * @nlh: netlink message header
212  * @family: genetlink message family
213  * @tb: destination array with maxtype+1 elements
214  * @maxtype: maximum attribute type to be expected
215  * @policy: validation policy
216  * @extack: extended ACK report struct
217  */
genlmsg_parse_deprecated(const struct nlmsghdr * nlh,const struct genl_family * family,struct nlattr * tb[],int maxtype,const struct nla_policy * policy,struct netlink_ext_ack * extack)218 static inline int genlmsg_parse_deprecated(const struct nlmsghdr *nlh,
219 					   const struct genl_family *family,
220 					   struct nlattr *tb[], int maxtype,
221 					   const struct nla_policy *policy,
222 					   struct netlink_ext_ack *extack)
223 {
224 	return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
225 			     policy, NL_VALIDATE_LIBERAL, extack);
226 }
227 
228 /**
229  * genlmsg_parse - parse attributes of a genetlink message
230  * @nlh: netlink message header
231  * @family: genetlink message family
232  * @tb: destination array with maxtype+1 elements
233  * @maxtype: maximum attribute type to be expected
234  * @policy: validation policy
235  * @extack: extended ACK report struct
236  */
genlmsg_parse(const struct nlmsghdr * nlh,const struct genl_family * family,struct nlattr * tb[],int maxtype,const struct nla_policy * policy,struct netlink_ext_ack * extack)237 static inline int genlmsg_parse(const struct nlmsghdr *nlh,
238 				const struct genl_family *family,
239 				struct nlattr *tb[], int maxtype,
240 				const struct nla_policy *policy,
241 				struct netlink_ext_ack *extack)
242 {
243 	return __nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
244 			     policy, NL_VALIDATE_STRICT, extack);
245 }
246 
247 /**
248  * genl_dump_check_consistent - check if sequence is consistent and advertise if not
249  * @cb: netlink callback structure that stores the sequence number
250  * @user_hdr: user header as returned from genlmsg_put()
251  *
252  * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it
253  * simpler to use with generic netlink.
254  */
genl_dump_check_consistent(struct netlink_callback * cb,void * user_hdr)255 static inline void genl_dump_check_consistent(struct netlink_callback *cb,
256 					      void *user_hdr)
257 {
258 	nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr));
259 }
260 
261 /**
262  * genlmsg_put_reply - Add generic netlink header to a reply message
263  * @skb: socket buffer holding the message
264  * @info: receiver info
265  * @family: generic netlink family
266  * @flags: netlink message flags
267  * @cmd: generic netlink command
268  *
269  * Returns pointer to user specific header
270  */
genlmsg_put_reply(struct sk_buff * skb,struct genl_info * info,const struct genl_family * family,int flags,u8 cmd)271 static inline void *genlmsg_put_reply(struct sk_buff *skb,
272 				      struct genl_info *info,
273 				      const struct genl_family *family,
274 				      int flags, u8 cmd)
275 {
276 	return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
277 			   flags, cmd);
278 }
279 
280 /**
281  * genlmsg_end - Finalize a generic netlink message
282  * @skb: socket buffer the message is stored in
283  * @hdr: user specific header
284  */
genlmsg_end(struct sk_buff * skb,void * hdr)285 static inline void genlmsg_end(struct sk_buff *skb, void *hdr)
286 {
287 	nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
288 }
289 
290 /**
291  * genlmsg_cancel - Cancel construction of a generic netlink message
292  * @skb: socket buffer the message is stored in
293  * @hdr: generic netlink message header
294  */
genlmsg_cancel(struct sk_buff * skb,void * hdr)295 static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
296 {
297 	if (hdr)
298 		nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
299 }
300 
301 /**
302  * genlmsg_multicast_netns - multicast a netlink message to a specific netns
303  * @family: the generic netlink family
304  * @net: the net namespace
305  * @skb: netlink message as socket buffer
306  * @portid: own netlink portid to avoid sending to yourself
307  * @group: offset of multicast group in groups array
308  * @flags: allocation flags
309  */
genlmsg_multicast_netns(const struct genl_family * family,struct net * net,struct sk_buff * skb,u32 portid,unsigned int group,gfp_t flags)310 static inline int genlmsg_multicast_netns(const struct genl_family *family,
311 					  struct net *net, struct sk_buff *skb,
312 					  u32 portid, unsigned int group, gfp_t flags)
313 {
314 	if (WARN_ON_ONCE(group >= family->n_mcgrps))
315 		return -EINVAL;
316 	group = family->mcgrp_offset + group;
317 	return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
318 }
319 
320 /**
321  * genlmsg_multicast - multicast a netlink message to the default netns
322  * @family: the generic netlink family
323  * @skb: netlink message as socket buffer
324  * @portid: own netlink portid to avoid sending to yourself
325  * @group: offset of multicast group in groups array
326  * @flags: allocation flags
327  */
genlmsg_multicast(const struct genl_family * family,struct sk_buff * skb,u32 portid,unsigned int group,gfp_t flags)328 static inline int genlmsg_multicast(const struct genl_family *family,
329 				    struct sk_buff *skb, u32 portid,
330 				    unsigned int group, gfp_t flags)
331 {
332 	return genlmsg_multicast_netns(family, &init_net, skb,
333 				       portid, group, flags);
334 }
335 
336 /**
337  * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
338  * @family: the generic netlink family
339  * @skb: netlink message as socket buffer
340  * @portid: own netlink portid to avoid sending to yourself
341  * @group: offset of multicast group in groups array
342  * @flags: allocation flags
343  *
344  * This function must hold the RTNL or rcu_read_lock().
345  */
346 int genlmsg_multicast_allns(const struct genl_family *family,
347 			    struct sk_buff *skb, u32 portid,
348 			    unsigned int group, gfp_t flags);
349 
350 /**
351  * genlmsg_unicast - unicast a netlink message
352  * @skb: netlink message as socket buffer
353  * @portid: netlink portid of the destination socket
354  */
genlmsg_unicast(struct net * net,struct sk_buff * skb,u32 portid)355 static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
356 {
357 	return nlmsg_unicast(net->genl_sock, skb, portid);
358 }
359 
360 /**
361  * genlmsg_reply - reply to a request
362  * @skb: netlink message to be sent back
363  * @info: receiver information
364  */
genlmsg_reply(struct sk_buff * skb,struct genl_info * info)365 static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
366 {
367 	return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
368 }
369 
370 /**
371  * gennlmsg_data - head of message payload
372  * @gnlh: genetlink message header
373  */
genlmsg_data(const struct genlmsghdr * gnlh)374 static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
375 {
376 	return ((unsigned char *) gnlh + GENL_HDRLEN);
377 }
378 
379 /**
380  * genlmsg_len - length of message payload
381  * @gnlh: genetlink message header
382  */
genlmsg_len(const struct genlmsghdr * gnlh)383 static inline int genlmsg_len(const struct genlmsghdr *gnlh)
384 {
385 	struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
386 							NLMSG_HDRLEN);
387 	return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
388 }
389 
390 /**
391  * genlmsg_msg_size - length of genetlink message not including padding
392  * @payload: length of message payload
393  */
genlmsg_msg_size(int payload)394 static inline int genlmsg_msg_size(int payload)
395 {
396 	return GENL_HDRLEN + payload;
397 }
398 
399 /**
400  * genlmsg_total_size - length of genetlink message including padding
401  * @payload: length of message payload
402  */
genlmsg_total_size(int payload)403 static inline int genlmsg_total_size(int payload)
404 {
405 	return NLMSG_ALIGN(genlmsg_msg_size(payload));
406 }
407 
408 /**
409  * genlmsg_new - Allocate a new generic netlink message
410  * @payload: size of the message payload
411  * @flags: the type of memory to allocate.
412  */
genlmsg_new(size_t payload,gfp_t flags)413 static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
414 {
415 	return nlmsg_new(genlmsg_total_size(payload), flags);
416 }
417 
418 /**
419  * genl_set_err - report error to genetlink broadcast listeners
420  * @family: the generic netlink family
421  * @net: the network namespace to report the error to
422  * @portid: the PORTID of a process that we want to skip (if any)
423  * @group: the broadcast group that will notice the error
424  * 	(this is the offset of the multicast group in the groups array)
425  * @code: error code, must be negative (as usual in kernelspace)
426  *
427  * This function returns the number of broadcast listeners that have set the
428  * NETLINK_RECV_NO_ENOBUFS socket option.
429  */
genl_set_err(const struct genl_family * family,struct net * net,u32 portid,u32 group,int code)430 static inline int genl_set_err(const struct genl_family *family,
431 			       struct net *net, u32 portid,
432 			       u32 group, int code)
433 {
434 	if (WARN_ON_ONCE(group >= family->n_mcgrps))
435 		return -EINVAL;
436 	group = family->mcgrp_offset + group;
437 	return netlink_set_err(net->genl_sock, portid, group, code);
438 }
439 
genl_has_listeners(const struct genl_family * family,struct net * net,unsigned int group)440 static inline int genl_has_listeners(const struct genl_family *family,
441 				     struct net *net, unsigned int group)
442 {
443 	if (WARN_ON_ONCE(group >= family->n_mcgrps))
444 		return -EINVAL;
445 	group = family->mcgrp_offset + group;
446 	return netlink_has_listeners(net->genl_sock, group);
447 }
448 #endif	/* __NET_GENERIC_NETLINK_H */
449