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