【问题标题】:Why am I not receiving my messages from kernel?为什么我没有收到来自内核的消息?
【发布时间】:2020-07-11 20:33:41
【问题描述】:

我正在尝试使用通用 netlink 和 libnl 将消息从内核发送到用户空间,执行此操作的代码部分实现如下:

int struct my_callback(struct sk_buff *skb, struct genl_info *info)
{
    struct sk_buff *obuff;
    void *msg_head;

    if ((obuff = genlmsg_new(0, GFP_KERNEL)) == NULL) { // I've tried to change the len to NLMSG_GOODSIZE but not worked
        pr_err("Failed allocating message to an reply\n");
        return 0;
    }

    if ((msg_head = genlmsg_put_reply(obuff, info, &lunatik_family, 0, LIST_STATES)) == NULL) {
        pr_err("Failed to put generic netlink header\n");
        return 0;
    }

    //I've tried to put a genlmsg_end(obuff, msg_head); but didn't work as well

    if (genlmsg_reply(obuff, info) < 0) {
        pr_err("Failed to send message to user space\n");
        return 0;
    }
    pr_info("Message sent to user-space\n");
    return 0;
}

P.s:LIST_STATES 是 enum 的成员,值为 3

而我的用户空间代码基本上是:

static int req_handler(struct nl_msg *msg, void *arg)
{
    struct nlmsghdr *nlhdr;
    struct genlmsghdr *genlhdr;
    
    nlhdr = nlmsg_hdr(msg);
    genlhdr = genlmsg_hdr(nlhdr);

    printf("Received a message from kernel: %d\n", genlhdr->cmd);

    return NL_OK;
}


int socket_init(struct nl_sock *sock)
{
    int err = -1;

    if ((sock = nl_socket_alloc()) == NULL)
        return err;

    if ((err = genl_connect(sock)))
        return err;

    if ((err = genl_ctrl_resolve(sock, LUNATIK_FAMILY)) < 0)
        return err;

    // I've tried to use NL_CB_VALID, but when I use it I receive no message at all
    nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, req_handler, NULL);
    return 0;
}

我在 dmesg 上的输出是:

消息发送到用户空间

我在用户空间的输出是:

收到来自内核的消息:0

我应该收到 3 而不是 0,我注意到我只收到 ACK 消息,而不是我发送的消息,我想知道为什么会发生这种情况以及我做错了什么。

【问题讨论】:

标签: c linux-kernel kernel netlink


【解决方案1】:

genl_ctrl_resolve() 的结果是双重的:

  • 如果
  • 如果 >= 0,则为家庭身份证号。

您正在丢弃您的家庭身份证号码。而不是

if ((err = genl_ctrl_resolve(sock, LUNATIK_FAMILY)) < 0)
    return err;

,做

if ((lunatik_family = genl_ctrl_resolve(sock, LUNATIK_FAMILY)) < 0)
    return lunatik_family;

稍后,当您设置 Netlink Header 时,请务必使用它:

if (!genlmsg_put(..., ..., ..., lunatik_family, ..., ..., LIST_STATES, ...))
    /* handle error */

还有一件事:nl_socket_modify_cb() 也返回一个错误代码。而不是

nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, req_handler, NULL);
return 0;

return nl_socket_modify_cb(sock, NL_CB_MSG_IN, NL_CB_CUSTOM, req_handler, NULL);

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 2021-09-05
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    相关资源
    最近更新 更多