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 : 3 : 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 : 3 : 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 : 3 : if (WARN_ON_ONCE(group >= family->n_mcgrps)) 272 : : return -EINVAL; 273 : 3 : group = family->mcgrp_offset + group; 274 : 3 : 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 : 3 : 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 : 3 : static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) 323 : : { 324 : 3 : 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 */