【问题标题】:Error trying to send an abstract data through libnl and generic netlink尝试通过 libnl 和通用 netlink 发送抽象数据时出错
【发布时间】:2023-04-08 13:55:01
【问题描述】:

当我运行以下代码时,我正在尝试使用 libnl 和通用 netlink 发送抽象数据:

struct nl_msg *msg;
struct nl_data *abstract;
int err = -1;

if ((msg = nlmsg_alloc()) == NULL)
    return err;

if ((genlmsg_put(msg, ctrl->pid, NL_AUTO_SEQ, ctrl->genl_family, 
        0, NLM_F_REQUEST, CREATE_STATE, KLUA_VERSION) == NULL))
    return err;

if ((err = nla_put_string(msg, STATE_NAME, cmd->name)))
    return err;

if ((err = nl_send_auto(ctrl->sock, msg)) < 0)
    return err;

nlmsg_free(msg);

内核很好地接收到消息。但是,如果我为此更改此代码:

struct nl_msg *msg;
struct nl_data *abstract;
int err = -1;

if ((msg = nlmsg_alloc()) == NULL)
    return err;

if ((abstract = nl_data_alloc(cmd, sizeof(struct klua_nl_state))) == NULL)
    return err;

if ((genlmsg_put(msg, ctrl->pid, NL_AUTO_SEQ, ctrl->genl_family, 
        0, NLM_F_REQUEST, CREATE_STATE, KLUA_VERSION) == NULL))
    return err;
    
nla_put_data(msg, TEST_ATTR, abstract);

if ((err = nl_send_auto(ctrl->sock, msg)) < 0)
    return err;

nlmsg_free(msg);

顺便说一下,我的TEST_ATTR定义为:

[TEST_ATTR] = {.type = NLA_UNSPEC}

如果我只更改消息的有效负载,为什么内核没有收到我的消息? 如何通过通用 netlink 和 libnl 发送抽象数据?

【问题讨论】:

  • 是否有需要(重新)计算的 CRC(或类似的)?
  • 我已经成功了,但是内核仍然没有收到消息,顺便说一下,我知道消息正在发送,因为我激活了libnl的调试功能并且消息正在发送成功,问题出在接收部分。

标签: c netlink


【解决方案1】:

从 Linux 5.2 开始,内核的属性验证器函数 (validate_nla()) 包含一个 conditional,它实质上禁止使用 NLA_UNSPEC

我不确定是否可以禁用该验证。 validate_nla()hardcodesvalidate的主要用户为NL_VALIDATE_STRICT,其中contains NL_VALIDATE_UNSPEC

但无论如何,我建议您不要使用NLA_UNSPEC 在没有适当序列化的情况下发送 C 结构。这是一场等待发生的灾难。 C 有一个叫做“data structure padding;”的陷阱它的要点是允许 C 编译器在任何结构的成员之间引入垃圾。因此,当你声明这个时:

struct test {
    __u16 a;
    __u32 b;
};

技术上允许编译器在实现过程中将其更改为类似

struct test {
    __u16 a;
    unsigned char garbage[2];
    __u32 b;
};

看到问题了吗?如果您的内核模块和用户空间客户端是由不同的编译器生成的,或者由相同的编译器生成但标志略有不同,甚至是由同一编译器的版本略有不同,则结构可能不同,内核无论您的代码看起来多么正确,都会收到垃圾。

使用Nested Attributes 而不是NLA_UNSPEC。他们会为您处理对齐。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2018-02-04
    • 2013-06-02
    相关资源
    最近更新 更多