首页 > 其他分享 >Netlink 与 struct genl_family 结构体

Netlink 与 struct genl_family 结构体

时间:2022-10-30 11:35:08浏览次数:46  
标签:netlink struct family ops int Netlink genl

一、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种协议类型
netlink仅支持32种协议类型,这在实际应用中可能并不足够。因此产生了generic netlink(以下简称为genl)。
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 };
其中,type字段表示attr中的数据类型,可被配置为:
       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);

 

标签:netlink,struct,family,ops,int,Netlink,genl
From: https://www.cnblogs.com/ink-white/p/16822559.html

相关文章