一、struct
1 //#include <net/genetlink.h>
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 idenfitier 协议标识
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 * @netnsok: set to true if the family can handle network
30 * namespaces and should be presented in all of them
31 * @parallel_ops: operations can be called in parallel and aren't
32 * synchronized by the core genetlink code
33 * @pre_doit: called before an operation's doit callback, it may
34 * do additional, common, filtering and return an error
35 * @post_doit: called after an operation's doit callback, it may
36 * undo operations done by pre_doit, for example release locks
37 * @mcast_bind: a socket bound to the given multicast group (which
38 * is given as the offset into the groups array)
39 * @mcast_unbind: a socket was unbound from the given multicast group.
40 * Note that unbind() will not be called symmetrically if the
41 * generic netlink family is removed while there are still open
42 * sockets.
43 * @attrbuf: buffer to store parsed attributes
44 * @family_list: family list
45 * @mcgrps: multicast groups used by this family (private)
46 * @n_mcgrps: number of multicast groups (private)
47 * @mcgrp_offset: starting number of multicast group IDs in this family
48 * @ops: the operations supported by this family (private)
49 * @n_ops: number of operations supported by this family (private)
50 */
51 struct genl_family {
52 unsigned int id;
53 unsigned int hdrsize;
54 char name[GENL_NAMSIZ];
55 unsigned int version;
56 unsigned int maxattr;
57 bool netnsok;
58 bool parallel_ops;
59 int (*pre_doit)(const struct genl_ops *ops,
60 struct sk_buff *skb,
61 struct genl_info *info);
62 void (*post_doit)(const struct genl_ops *ops,
63 struct sk_buff *skb,
64 struct genl_info *info);
65 int (*mcast_bind)(struct net *net, int group);
66 void (*mcast_unbind)(struct net *net, int group);
67 struct nlattr ** attrbuf; /* private */
68 const struct genl_ops * ops; /* private */
69 const struct genl_multicast_group *mcgrps; /* private */
70 unsigned int n_ops; /* private */
71 unsigned int n_mcgrps; /* private */
72 unsigned int mcgrp_offset; /* private */
73 struct list_head family_list; /* private */
74 struct module *module;
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 * @dst_sk: destination socket
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 sock * dst_sk;
99 };
100
101 static inline struct net *genl_info_net(struct genl_info *info)
102 {
103 return read_pnet(&info->_net);
104 }
105
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 /**
112 * struct genl_ops - generic netlink operations
113 * @cmd: command identifier
114 * @internal_flags: flags used by the family
115 * @flags: flags
116 * @policy: attribute validation policy 属性验证策略属性验证策略
117 * @doit: standard command callback 标准命令回调
118 * @start: start callback for dumps
119 * @dumpit: callback for dumpers
120 * @done: completion callback for dumps
121 * @ops_list: operations list
122 */
123 struct genl_ops {
124 const struct nla_policy *policy;
125 int (*doit)(struct sk_buff *skb,
126 struct genl_info *info);
127 int (*start)(struct netlink_callback *cb);
128 int (*dumpit)(struct sk_buff *skb,
129 struct netlink_callback *cb);
130 int (*done)(struct netlink_callback *cb);
131 u8 cmd;
132 u8 internal_flags;
133 u8 flags;
134 };
135
136 int __genl_register_family(struct genl_family *family);
137
138 static inline int genl_register_family(struct genl_family *family)
139 {
140 family->module = THIS_MODULE;
141 return __genl_register_family(family);
142 }
143
144 /**
145 * genl_register_family_with_ops - register a generic netlink family with ops
146 * @family: generic netlink family
147 * @ops: operations to be registered
148 * @n_ops: number of elements to register
149 *
150 * Registers the specified family and operations from the specified table.
151 * Only one family may be registered with the same family name or identifier.
152 *
153 * The family id may equal GENL_ID_GENERATE causing an unique id to
154 * be automatically generated and assigned.
155 *
156 * Either a doit or dumpit callback must be specified for every registered
157 * operation or the function will fail. Only one operation structure per
158 * command identifier may be registered.
159 *
160 * See include/net/genetlink.h for more documenation on the operations
161 * structure.
162 *
163 * Return 0 on success or a negative error code.
164 */
165 static inline int
166 _genl_register_family_with_ops_grps(struct genl_family *family,
167 const struct genl_ops *ops, size_t n_ops,
168 const struct genl_multicast_group *mcgrps,
169 size_t n_mcgrps)
170 {
171 family->module = THIS_MODULE;
172 family->ops = ops;
173 family->n_ops = n_ops;
174 family->mcgrps = mcgrps;
175 family->n_mcgrps = n_mcgrps;
176 return __genl_register_family(family);
177 }
178
179 #define genl_register_family_with_ops(family, ops) \
180 _genl_register_family_with_ops_grps((family), \
181 (ops), ARRAY_SIZE(ops), \
182 NULL, 0)
183 #define genl_register_family_with_ops_groups(family, ops, grps) \
184 _genl_register_family_with_ops_grps((family), \
185 (ops), ARRAY_SIZE(ops), \
186 (grps), ARRAY_SIZE(grps))
187
188 int genl_unregister_family(struct genl_family *family);
189 void genl_notify(struct genl_family *family, struct sk_buff *skb,
190 struct genl_info *info, u32 group, gfp_t flags);
191
192 struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
193 gfp_t flags);
194 void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
195 struct genl_family *family, int flags, u8 cmd);
196
197 /**
198 * genlmsg_nlhdr - Obtain netlink header from user specified header
199 * @user_hdr: user header as returned from genlmsg_put()
200 * @family: generic netlink family
201 *
202 * Returns pointer to netlink header.
203 */
204 static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr,
205 struct genl_family *family)
206 {
207 return (struct nlmsghdr *)((char *)user_hdr -
208 family->hdrsize -
209 GENL_HDRLEN -
210 NLMSG_HDRLEN);
211 }
212
213 /**
214 * genlmsg_parse - parse attributes of a genetlink message
215 * @nlh: netlink message header
216 * @family: genetlink message family
217 * @tb: destination array with maxtype+1 elements
218 * @maxtype: maximum attribute type to be expected
219 * @policy: validation policy
220 * */
221 static inline int genlmsg_parse(const struct nlmsghdr *nlh,
222 const struct genl_family *family,
223 struct nlattr *tb[], int maxtype,
224 const struct nla_policy *policy)
225 {
226 return nlmsg_parse(nlh, family->hdrsize + GENL_HDRLEN, tb, maxtype,
227 policy);
228 }
229
230 /**
231 * genl_dump_check_consistent - check if sequence is consistent and advertise if not
232 * @cb: netlink callback structure that stores the sequence number
233 * @user_hdr: user header as returned from genlmsg_put()
234 * @family: generic netlink family
235 *
236 * Cf. nl_dump_check_consistent(), this just provides a wrapper to make it
237 * simpler to use with generic netlink.
238 */
239 static inline void genl_dump_check_consistent(struct netlink_callback *cb,
240 void *user_hdr,
241 struct genl_family *family)
242 {
243 nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr, family));
244 }
245
246 /**
247 * genlmsg_put_reply - Add generic netlink header to a reply message
248 * @skb: socket buffer holding the message
249 * @info: receiver info
250 * @family: generic netlink family
251 * @flags: netlink message flags
252 * @cmd: generic netlink command
253 *
254 * Returns pointer to user specific header
255 */
256 static inline void *genlmsg_put_reply(struct sk_buff *skb,
257 struct genl_info *info,
258 struct genl_family *family,
259 int flags, u8 cmd)
260 {
261 return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
262 flags, cmd);
263 }
264
265 /**
266 * genlmsg_end - Finalize a generic netlink message
267 * @skb: socket buffer the message is stored in
268 * @hdr: user specific header
269 */
270 static inline void genlmsg_end(struct sk_buff *skb, void *hdr)
271 {
272 nlmsg_end(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
273 }
274
275 /**
276 * genlmsg_cancel - Cancel construction of a generic netlink message
277 * @skb: socket buffer the message is stored in
278 * @hdr: generic netlink message header
279 */
280 static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
281 {
282 if (hdr)
283 nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
284 }
285
286 /**
287 * genlmsg_multicast_netns - multicast a netlink message to a specific netns
288 * @family: the generic netlink family
289 * @net: the net namespace
290 * @skb: netlink message as socket buffer
291 * @portid: own netlink portid to avoid sending to yourself
292 * @group: offset of multicast group in groups array
293 * @flags: allocation flags
294 */
295 static inline int genlmsg_multicast_netns(struct genl_family *family,
296 struct net *net, struct sk_buff *skb,
297 u32 portid, unsigned int group, gfp_t flags)
298 {
299 if (WARN_ON_ONCE(group >= family->n_mcgrps))
300 return -EINVAL;
301 group = family->mcgrp_offset + group;
302 return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
303 }
304
305 /**
306 * genlmsg_multicast - multicast a netlink message to the default netns
307 * @family: the generic netlink family
308 * @skb: netlink message as socket buffer
309 * @portid: own netlink portid to avoid sending to yourself
310 * @group: offset of multicast group in groups array
311 * @flags: allocation flags
312 */
313 static inline int genlmsg_multicast(struct genl_family *family,
314 struct sk_buff *skb, u32 portid,
315 unsigned int group, gfp_t flags)
316 {
317 return genlmsg_multicast_netns(family, &init_net, skb,
318 portid, group, flags);
319 }
320
321 /**
322 * genlmsg_multicast_allns - multicast a netlink message to all net namespaces
323 * @family: the generic netlink family
324 * @skb: netlink message as socket buffer
325 * @portid: own netlink portid to avoid sending to yourself
326 * @group: offset of multicast group in groups array
327 * @flags: allocation flags
328 *
329 * This function must hold the RTNL or rcu_read_lock().
330 */
331 int genlmsg_multicast_allns(struct genl_family *family,
332 struct sk_buff *skb, u32 portid,
333 unsigned int group, gfp_t flags);
334
335 /**
336 * genlmsg_unicast - unicast a netlink message
337 * @skb: netlink message as socket buffer
338 * @portid: netlink portid of the destination socket
339 */
340 static inline int genlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid)
341 {
342 return nlmsg_unicast(net->genl_sock, skb, portid);
343 }
344
345 /**
346 * genlmsg_reply - reply to a request
347 * @skb: netlink message to be sent back
348 * @info: receiver information
349 */
350 static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
351 {
352 return genlmsg_unicast(genl_info_net(info), skb, info->snd_portid);
353 }
354
355 /**
356 * gennlmsg_data - head of message payload
357 * @gnlh: genetlink message header
358 */
359 static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
360 {
361 return ((unsigned char *) gnlh + GENL_HDRLEN);
362 }
363
364 /**
365 * genlmsg_len - length of message payload
366 * @gnlh: genetlink message header
367 */
368 static inline int genlmsg_len(const struct genlmsghdr *gnlh)
369 {
370 struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
371 NLMSG_HDRLEN);
372 return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
373 }
374
375 /**
376 * genlmsg_msg_size - length of genetlink message not including padding
377 * @payload: length of message payload
378 */
379 static inline int genlmsg_msg_size(int payload)
380 {
381 return GENL_HDRLEN + payload;
382 }
383
384 /**
385 * genlmsg_total_size - length of genetlink message including padding
386 * @payload: length of message payload
387 */
388 static inline int genlmsg_total_size(int payload)
389 {
390 return NLMSG_ALIGN(genlmsg_msg_size(payload));
391 }
392
393 /**
394 * genlmsg_new - Allocate a new generic netlink message
395 * @payload: size of the message payload
396 * @flags: the type of memory to allocate.
397 */
398 static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
399 {
400 return nlmsg_new(genlmsg_total_size(payload), flags);
401 }
402
403 /**
404 * genl_set_err - report error to genetlink broadcast listeners
405 * @family: the generic netlink family
406 * @net: the network namespace to report the error to
407 * @portid: the PORTID of a process that we want to skip (if any)
408 * @group: the broadcast group that will notice the error
409 * (this is the offset of the multicast group in the groups array)
410 * @code: error code, must be negative (as usual in kernelspace)
411 *
412 * This function returns the number of broadcast listeners that have set the
413 * NETLINK_RECV_NO_ENOBUFS socket option.
414 */
415 static inline int genl_set_err(struct genl_family *family, struct net *net,
416 u32 portid, u32 group, int code)
417 {
418 if (WARN_ON_ONCE(group >= family->n_mcgrps))
419 return -EINVAL;
420 group = family->mcgrp_offset + group;
421 return netlink_set_err(net->genl_sock, portid, group, code);
422 }
423
424 static inline int genl_has_listeners(struct genl_family *family,
425 struct net *net, unsigned int group)
426 {
427 if (WARN_ON_ONCE(group >= family->n_mcgrps))
428 return -EINVAL;
429 group = family->mcgrp_offset + group;
430 return netlink_has_listeners(net->genl_sock, group);
431 }
432 #endif /* __NET_GENERIC_NETLINK_H */
二、Generic Netlink
netlink socket是一种用于用户态进程和内核态进程之间的通信机制。它通过为内核模块提供一组特殊的API,并为用户程序提供了一组标准的socket接口的方式,实现了全双工的通讯连接。
Netlink的特点:
- 双向传输,异步通信
- 用户空间中使用标准socket API
- 内核空间中使用专门的API
- 支持多播
- 可由内核端发起通信
- 支持32种协议类型
generic netlink支持1023个子协议号,弥补了netlink协议类型较少的缺陷。
支持协议号自动分配。它基于netlink,但是在内核中,generic netlink的接口与netlink并不相同。
1、 Generic Netlink框架概述

图1 Generic Netlink模型框架
图1表示了Generic Netlink框架。Kernel socket API向用户空间和内核空间分别提供接口。
Netlink子系统(1)是所有genl通信的基础。
Netlink子系统中收到的所有Generic类型的netlink数据都被送到genl总线(2)上;从内核发出的数据也经由genl总线送至netlink子系统,再打包送至用户空间。
Generic Netlink控制器(4)作为内核的一部分,负责动态地分配genl通道(即genl family id),并管理genl任务。
genl控制器是一个特殊的genl内核用户,它负责监听genl bus上的通信通道。
genl通信建立在一系列的通信通道的基础上,每个genl family对应多个通道,这些通道由genl控制器动态分配。
2、netlink消息结构

图2 Generic Netlink消息结构
其中family头对于Genetlink来说就是Generic消息头genlmsghdr,接下来是可选的用户特定消息头,最后才是可选的有效载荷,即一个个消息属性实例。
Genetlink消息是命令驱动式的,即每一条消息的genlmsghdr中都指明了当前消息的cmd消息命令,这些消息cmd命令由用户自行定义。
内核在接收到用户的genl消息后,首先会对命令cmd做判断,找到对应的消息处理结构(可能会执行attr有效性检查),然后才会去调用消息处理回调函数从消息载荷区中读取并处理其所需要的的attr属性载荷。
3、Generic Netlink相关结构体
3.1、Generic Netlink消息头结构:struct genlmsghdr
1 struct genlmsghdr {
2 __u8 cmd;
3 __u8 version;
4 __u16 reserved;
5 };
Generic Netlink消息头比较简单,仅包含了两个字段。
cmd表示消息命令,对于用户自己定义的每个子协议类型都需要定义特定的消息命令集,这里该字段表示当前消息的消息命令;
version字段表示版本控制(可以在在不破坏向后兼容性的情况下修改消息的格式),可以不使用该字段;
reserved字段保留。
3.2、struct genl_family
Generic Netlink Family结构:struct genl_family,内核中完成注册。Generic Netlink按照family进行管理,用户需注册自己定义的genl_family结构,同时内核使用一个哈希表family_ht对已经注册的genl family进行管理。
1 struct genl_family {
2 unsigned int id;
3 unsigned int hdrsize;
4 char name[GENL_NAMSIZ];
5 unsigned int version;
6 unsigned int maxattr;
7 bool netnsok;
8 bool parallel_ops;
9 int (*pre_doit)(const struct genl_ops *ops,
10 struct sk_buff *skb,
11 struct genl_info *info);
12 void (*post_doit)(const struct genl_ops *ops,
13 struct sk_buff *skb,
14 struct genl_info *info);
15 int (*mcast_bind)(struct net *net, int group);
16 void (*mcast_unbind)(struct net *net, int group);
17 struct nlattr ** attrbuf; /* private */
18 const struct genl_ops * ops; /* private */
19 const struct genl_multicast_group *mcgrps; /* private */
20 unsigned int n_ops; /* private */
21 unsigned int n_mcgrps; /* private */
22 unsigned int mcgrp_offset; /* private */
23 struct list_head family_list; /* private */
24 struct module *module;
25 };
各字段的含义如下:
id:genl family的ID号,一般由内核进行分配,取值范围为GENL_MIN_ID~GENL_MAX_ID(16~1023),其中GENL_ID_CTRL为控制器的family ID,不可另行分配,该familyID全局唯一并且在family_ht中的位置也由该值确定;
hdrsize:用户私有报头的长度,即可选的user msg header长度,若没有则为0;
name:genl family的名称,必须是独一无二且用户层已知的(用户通过它来向控制查找family id);
version:版本号;
maxattr:消息属性attr最大的类型数(即该genl family所支持的最大attr属性类型的种类个数);
netnsok:指示当前簇是否能够处理网络命名空间;
pre_doit:调用genl_ops结构中处理消息函数doit()前调用的钩子函数,一般用于执行一些前置的当前簇通用化处理,例如对临界区加锁等;
post_doit:调用genl_ops结构中处理消息函数doit()后调用的钩子函数,一般执行pre_doit函数相反的操作;
mcast_bind/mcast_unbind:在绑定/解绑定socket到一个特定的genl netlink组播组中调用(目前内核中没有相关使用);
attrbuf:保存拷贝的attr属性缓存;
ops/n_ops:保存genl family命令处理结构即命令的个数,后面详细描述;
family_list:链表结构,用于将当前当前簇链入全局family_ht散列表中;
mcgrps/n_mcgrps:保存当前簇使用的组播组及组播地址的个数;
3.3、Generic Netlink Family命令处理结构:struct genl_ops(内核中完成注册)
1 struct genl_ops {
2 const struct nla_policy *policy;
3 int (*doit)(struct sk_buff *skb,
4 struct genl_info *info);
5 int (*dumpit)(struct sk_buff *skb,
6 struct netlink_callback *cb);
7 int (*done)(struct netlink_callback *cb);
8 u8 cmd;
9 u8 internal_flags;
10 u8 flags;
11 };
cmd: 命令名。用于识别各genl_ops
internal_flags:簇私有标识,用于进行一些分支处理,可以不使用
flag: 各种设置属性,以“或”连接。在需要admin特权级别时,使用GENL_ADMIN_PERM有以下四种类型(在genetlink.h中定义)
1 #define GENL_ADMIN_PERM 0x01 /* 当设置该标识时表示本命令操作需要具有CAP_NET_ADMIN权限 */
2 #define GENL_CMD_CAP_DO 0x02 /* 当genl_ops结构中实现了doit()回调函数则设置该标识 */
3 #define GENL_CMD_CAP_DUMP 0x04 /* 当genl_ops结构中实现了dumpit()回调函数则设置该标识 */
4 #define GENL_CMD_CAP_HASPOL 0x08 /* 当genl_ops结构中定义了属性有效性策略(nla_policy)则设置该标识 */
policy:定义了attr规则。如果此指针非空,genl在触发事件处理程序之前,会使用这个字段来对帧中的attr做校验(见nlmsg_parse函数)。该字段可以为空,表示在触发事件处理程序之前,不做校验。
policy是一个struct nla_policy的数组。struct nla_policy结构体表示如下:
1 struct nla_policy{
2 u16 type;
3 u16 len;
4 };
NLA_UNSPEC--未定义
NLA_U8, NLA_U16, NLA_U32, NLA_U64为8bits, 16bits, 32bits, 64bits的无符号整型
NLA_STRING--字符串
NLA_NUL_STRING--空终止符字符串
NLA_NESTED--attr流
len字段的意思是:
如果在type字段配置的是字符串有关的值,要把len设置为字符串的最大长度(不包含结尾的'\0')。
如果type字段未设置或被设置为NLA_UNSPEC,那么这里要设置为attr的payload部分的长度。
doit:这是一个回调函数。在generic netlink收到数据时触发,运行在进程上下文。
doit传入两个参数,skb为触发此回调函数的socket buffer。第二个参数是一个genl_info结构体,定义如下:
1 struct genl_info {
2 u32 snd_seq;
3 u32 snd_portid;
4 struct nlmsghdr * nlhdr;
5 struct genlmsghdr * genlhdr;
6 void * userhdr;
7 struct nlattr ** attrs;
8 possible_net_t _net;
9 void * user_ptr[2];
10 struct sock * dst_sk;
11 };
内核在接收到用户的genetlink消息后,会对消息解析并封装成genl_info结构,便于命令回校函数进行处理,其中各字段含义如下:
snd_seq:消息的发送序号(不强制使用);
snd_portid:消息发送端socket所绑定的ID;
nlhdr:netlink消息头;
genlhdr:generic netlink消息头;
userhdr:用户私有报头;
attrs:netlink属性,包含了消息的实际载荷;
dst_sk:目的socket;
在完成了操作以后,如果 执行正确,返回0;否则,返回一个负数。负数的返回值会触发NLMSG_ERROR消息。当genl_ops的flag标志被添加了 NLMSG_ERROR时,即使doit返回0,也会触发NLMSG_ERROR消息。dumpit:这是一个回调函数,当genl_ops的flag标志被添加了NLM_F_DUMP以后,每次收到genl消息即会回触发这个函数。 dumpit与doit的区别是:dumpit的第一个参数skb不会携带从客户端发来的数据。相反地,开发者应该在skb中填入需要传给客户端的数据, 然后,并skb的数据长度(可以用skb->len)return。skb中携带的数据会被自动送到客户端。只要dumpit的返回值大于 0,dumpit函数就会再次被调用,并被要求在skb中填入数据。当服务端没有数据要传给客户端时,dumpit要返回0。如果函数中出错,要求返回一 个负值。关于doit和dumpit的触发过程,可以查看源码中的genl_rcv_msg函数。
4、注册
1 int __genl_register_family(struct genl_family *family); 2 3 static inline int genl_register_family(struct genl_family *family) 4 { 5 family->module = THIS_MODULE; 6 return __genl_register_family(family); 7 } 8 9 /** 10 * genl_register_family_with_ops - register a generic netlink family with ops 11 * @family: generic netlink family 12 * @ops: operations to be registered 13 * @n_ops: number of elements to register 14 * 15 * Registers the specified family and operations from the specified table. 16 * Only one family may be registered with the same family name or identifier. 17 * 18 * The family id may equal GENL_ID_GENERATE causing an unique id to 19 * be automatically generated and assigned. 20 * 21 * Either a doit or dumpit callback must be specified for every registered 22 * operation or the function will fail. Only one operation structure per 23 * command identifier may be registered. 24 * 25 * See include/net/genetlink.h for more documenation on the operations 26 * structure. 27 * 28 * Return 0 on success or a negative error code. 29 */ 30 static inline int 31 _genl_register_family_with_ops_grps(struct genl_family *family, 32 const struct genl_ops *ops, size_t n_ops, 33 const struct genl_multicast_group *mcgrps, 34 size_t n_mcgrps) 35 { 36 family->module = THIS_MODULE; 37 family->ops = ops; 38 family->n_ops = n_ops; 39 family->mcgrps = mcgrps; 40 family->n_mcgrps = n_mcgrps; 41 return __genl_register_family(family); 42 } 43 44 #define genl_register_family_with_ops(family, ops) \ 45 _genl_register_family_with_ops_grps((family), \ 46 (ops), ARRAY_SIZE(ops), \ 47 NULL, 0) 48 #define genl_register_family_with_ops_groups(family, ops, grps) \ 49 _genl_register_family_with_ops_grps((family), \ 50 (ops), ARRAY_SIZE(ops), \ 51 (grps), ARRAY_SIZE(grps))
退出
1 int genl_unregister_family(struct genl_family *family);
浙公网安备 33010602011771号