c - 为什么我没有收到来自内核的消息?
问题描述
我正在尝试使用通用 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;
}
ps:LIST_STATES
是枚举成员,值为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 消息,而不是我发送的消息,我想知道为什么会这样以及我做错了什么。
解决方案
的结果genl_ctrl_resolve()
是双重的:
- 如果 < 0,则为错误代码。
- 如果 >= 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 标头时,请确保使用它:
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);
推荐阅读
- javascript - 如何将 Python Flask 路由上的字符串发送到 JS 函数?
- javascript - 当当前焦点元素从 DOM 中移除时,如何挽救焦点?
- amazon-web-services - 从 s3 复制 csv 时,Redshift 副本不添加整数默认值
- git - git pull 请求中不需要的提交
- c# - 尝试在 C# 代码中从 Cosmos DB 中删除一行
- python - 将字符串和字符串列表提供给 keras 标记器有什么区别?
- python - 在 python 中这种反向变体如何?
- python-3.x - 熊猫 DatetimeIndex 到 matplotlib x-ticks
- swift - 如何遍历 Swift 中每个键具有多个值的字典
- css - 我需要我的文本列左对齐*并且*向左截断