Generic Netlink机制


系统中有已经有很多具体的Netlink协议了,不过它们都是针对某个子系统的,功能已经比较固定,如果我们需要扩展新的Netlink协议,那么就需要对内核进行侵入式修改(最起码要扩展MAX_LINKS),为此,Netlink框架还提供了一个通用的Netlink协议: Generic Netlink。通过它,内核模块可以在无需扩充协议的基础上使用Netlink机制。

这篇笔记分析了内核Generic Netlink核心部分的实现,官方参考资料见这里

文件 说明
net/netlink/genetlink.c Generic Netlink协议框架实现文件
include/net/genetlink.h 仅内核态可见的Generic Netlink协议头文件
include/linux/genetlink.h 用户态也可见的Generic Netlink协议头文件

数据结构

genl_family

/**
 * struct genl_family - generic netlink family
 * @id: protocol family idenfitier
 * @hdrsize: length of user specific header in bytes
 * @name: name of family
 * @version: protocol version
 * @maxattr: maximum number of attributes supported
 * @attrbuf: buffer to store parsed attributes
 * @ops_list: list of all assigned operations
 * @family_list: family list
 * @mcast_groups: multicast groups list
 */
struct genl_family
{
   
	unsigned int id;
	unsigned int hdrsize;
	char name[GENL_NAMSIZ]; // 每个family也拥有一个全局唯一的名字
	unsigned int version;
	unsigned int maxattr;
	struct nlattr ** attrbuf;	/* private */
	struct list_head ops_list;	/* private */ // 该family的命令操作集链表
	struct list_head family_list;	/* private */ // 将family对象保存在全局哈希表中
	struct list_head mcast_groups;	/* private */
};
  • id

每个family拥有一个全局唯一的ID,该ID可以由faimily的实现指定(比较难保证唯一性),也可由内核自动分配(推荐做法),可用范围为(GENL_MIN_ID(0x10), GENL_MAX_ID(1023)];

  • hdrsize

每个Generic Netlink消息首部除了标准的genlmsghdr外,family还可以追加自己的首部,只需要通过该字段指定自己追加的首部大小即可;

  • maxattr/attrbuf

maxattr字段记录了该faimily支持的最大属性个数,如果指定了属性个数,Generic Netlink框架会负责分配attrbuf,该区域用于消息接收过程中的属性解析,具体见genl_rcv_msg()。

genl_ops

genl_ops定义一个family支持的命令。如genl_family的定义,每个family可以支持多个命令,这些命令被组织到genl_family.ops_list中。

/**
 * struct genl_ops - generic netlink operations
 * @cmd: command identifier
 * @flags: flags
 * @policy: attribute validation policy
 * @doit: standard command callback
 * @dumpit: callback for dumpers
 * @done: completion callback for dumps
 * @ops_list: operations list
 */
struct genl_ops
{
   
	u8 cmd; // 命令ID,在family内部唯一标识命令
	unsigned int flags;
	const struct nla_policy	*policy; // 属性策略,nlmsg_parse()会根据该策略对属性格式做基本的校验
	int	(*doit)(struct sk_buff *skb, struct genl_info *info);
	int	(*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
	int	(*done)(struct netlink_callback *cb);
	struct list_head ops_list; // 将ops对象放入family->ops_list链表中
};
  • flags

取值来自标准的Netlink消息中的NLM_F_XXX,不过Generic Netlink只用了其中部分标记,这些标记会影响消息的接收流程。

flags 含义
GENL_ADMIN_PERM 0x1 表示该消息的发送需要管理员权限
GENL_CMD_CAP_DO 0x2 表示该操作集指定了doit()回调
GENL_CMD_CAP_DUMP 0x4 表示该操作集指定了dumpit()回调
GENL_CMD_CAP_HASPOL 0x8 表示该操作集指定了属性策略

多播组: genl_multicast_group

/**
 * struct genl_multicast_group - generic netlink multicast group
 * @name: name of the multicast group, names are per-family
 * @id: multicast group ID, assigned by the core, to use with
 *      genlmsg_multicast().
 * @list: list entry for linking
 * @family: pointer to family, need not be set before registering
 */
struct genl_multicast_group
{
   
	struct genl_family	*family;	/* private */
	struct list_head	list;		/* private */
	char name[GENL_NAMSIZ]; // 多播组名字
	u32	id; // 多播组ID,在整个Generic Netlink层面唯一
};

/*
 * Bitmap of multicast groups that are currently in use.
 *
 * To avoid an allocation at boot of just one unsigned long,
 * declare it global instead.
 * Bit 0 is marked as already used since group 0 is invalid.
 */
static unsigned long mc_group_start = 0x1;
static unsigned long *mc_groups = &mc_group_start;
// 按位表示所有多播组需要的unsigned long整数个数
static unsigned long mc_groups_longs = 1;

Generic Netlink框架

     +---------------------+      +---------------------+
     | (3) application "A" |      | (3) application "B" |
     +------+--------------+      +--------------+------+
            |                                    |
            \                                    /
             \                                  /
              |                                |
      +-------+--------------------------------+-------+
      |        :                               :       |   user-space
 =====+        :   (5)  kernel socket API      :       +================
      |        :                               :       |   kernel-space
      +--------+-------------------------------+-------+
               |                               |
         +-----+-------------------------------+----+
         |        (1)  Netlink subsystem            |
         +---------------------+--------------------+
                               |
         +---------------------+--------------------+
         |       (2) Generic Netlink bus            |
         +--+--------------------------+-------+----+
            |                          |       |
    +------
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值