运维开发网

在Linux中通用netlink中的策略和属性的概念是什么?

运维开发网 https://www.qedev.com 2020-05-19 12:49 出处:网络
我是netlink编程的新手.我正在编写一个用于创建netlink协议族的通用netlink程序.我在互联网上搜索了很多文档,我发现了“属性和策略”之类的东西
我是netlink编程的新手.我正在编写一个用于创建netlink协议族的通用netlink程序.我在互联网上搜索了很多文档,我发现了“属性和策略”之类的东西

用于定义netlink系列.

我对这些事情感到很困惑.

我在Linux / netlink.h中找到了关于属性的信息

<------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
+---------------------------+- - -+- - - - - - - - - -+- - -+
|        Header             | Pad |    Payload        | Pad | 
|   (struct nlattr)         | ing |                   | ing |
+---------------------------+- - -+- - - - - - - - - -+- - -+
 <-------------------- nlattr->nla_len -------------->

策略是一系列nla_policy结构.

我的问题是:

>标题和属性之间的关系是什么?请解释

“属性”.

>什么是政策,需要什么以及我们为什么要使用数组呢?

我找到了一些关于“它定义属性类型”的政策,

这是什么意思?我的意思是“属性类型的含义是什么?”

这可能是一个无意义的问题,但我完全感到困惑.我一直试图了解这些事情超过三天,请帮助我.

谢谢..

在创建/使用netlink协议时,netlink属性旨在为协议提供一个干净的自我文档布局,以便将来可扩展.这意味着如果您想要使用除当前协议中已存在的数据类型之外的其他数据类型,则代码将兼容而不会破坏已存在的操作.

“属性”是依赖于协议的,并且与特定消息相关

使用所述协议发送.

使用taskstats接口作为示例:

taskstat attributes:

enum {
    TASKSTATS_CMD_ATTR_UNSPEC = 0,
    TASKSTATS_CMD_ATTR_PID,
    TASKSTATS_CMD_ATTR_TGID,
    TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
    TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
    __TASKSTATS_CMD_ATTR_MAX,
};

在这些属性中,您可以通过在UNSPEC和MAX映射之间添加自定义属性来轻松地“扩展”它们,该属性属于所需的特定功能或操作.

内核空间taskstat policy:

static const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
    [TASKSTATS_CMD_ATTR_PID]  = { .type = NLA_U32 },
    [TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
    [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
    [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};

我相信你已经遇到过struct nlattr的定义,这是一个使用NETLINK_GENERIC协议和taskstats接口加载这个struct的字段的例子:

struct nlattr na;
na.nla_type = CTRL_ATTR_FAMILY_NAME;         // defined in Linux/genetlink.h 
na.nla_len = strlen(TASKSTATS_GENL_NAME) + 1 // defined in Linux/taskstats.h

// note: you will need to copy/access nlattr data in the same way the NLMSG_DATA
//       macro operates.

现在在内核方面,在解析这些属性时,将调用关联的函数以及有关如何继续的预期操作.

我不确定你发布的图表是否会让你失望,但是要缩小一点

给你一个更大的视角:

根据内核源码v3.16 include/net/netlink.h

/* ========================================================================
 *         Netlink Messages and Attributes Interface (As Seen On TV)
 * ------------------------------------------------------------------------
 *                          Messages Interface
 * ------------------------------------------------------------------------
 *
 * Message Format:
 *    <--- nlmsg_total_size(payload)  --->
 *    <-- nlmsg_msg_size(payload) ->
 *   +----------+- - -+-------------+- - -+-------- - -
 *   | nlmsghdr | Pad |   Payload   | Pad | nlmsghdr
 *   +----------+- - -+-------------+- - -+-------- - -
 *   nlmsg_data(nlh)---^                   ^
 *   nlmsg_next(nlh)-----------------------+
 *
 * Payload Format:
 *    <---------------------- nlmsg_len(nlh) --------------------->
 *    <------ hdrlen ------>       <- nlmsg_attrlen(nlh, hdrlen) ->
 *   +----------------------+- - -+--------------------------------+
 *   |     Family Header    | Pad |           Attributes           |
 *   +----------------------+- - -+--------------------------------+
 *   nlmsg_attrdata(nlh, hdrlen)---^

在这里,您可以看到您发布的标头和有效负载图表只是更大负载的一部分.该段与消息格式中的struct nlmsghdr一起使用.

现在在策略上,当发送netlink消息时,发送者需要遵守协议

格式.在访问有效负载之前,消息的接收方将使用struct nla_policy来验证属性.

内核使用“族”或标识符来跟踪要与之通信的适当协议接口,无论是标准协议还是自定义,如Generic Netlink所示.

当你问“我们可以避免这种情况吗?”时,如果你通过编写自己的自定义通用netlink协议来扩展netlink,那么这些协议可以很容易地调整和维护,而无需通过和更改/修复与之相关的所有操作或让协议崩溃的扁平化.如果没有关联的长度或类型,您建议如何解析具有不同数据类型的嵌套消息?类型和长度允许在正确的对齐上解析消息并允许进行所需的操作.如果没有为有效负载提供标签的属性类型,您将如何解释它,“有效负载是什么”?没有长度你怎么知道有效载荷“有多大”?可能存在多个具有不同长度的有效载荷,而无需区分它们的大小,因此无法分辨出一个开始和另一个结束的位置.

这是libnl(用于处理netlink套接字的库,强烈推荐)文档attributes的链接.

0

精彩评论

暂无评论...
验证码 换一张
取 消