【发布时间】:2016-06-08 07:15:10
【问题描述】:
我正在尝试使用 netlink 套接字和通用消息类型来实现内核用户通信。到目前为止,我能够将消息从用户空间发送到内核,然后将消息发送回用户空间。问题是在我的用户空间程序中,我总是收到一个错误,即收到了无效/格式错误的消息。在用户空间程序中,我使用 libnl 进行 netlink 通信。
相关的netlink内核代码如下:
enum nl_tdisk_attr {
NL_UNSPEC,
NL_MY_ATTR, //My argument
__NL_MAX
};
#define NL_MAX (__NL_MAX - 1)
enum nl_tdisk_msg_types {
NL_CMD_READ = 0,
NL_CMD_MY_CMD //My command
NL_CMD_MAX
};
//Family definition
static struct genl_family family = {
.id = GENL_ID_GENERATE,
.name = "my-family",
.hdrsize = 0,
.version = 0,
.maxattr = NL_MAX,
};
//Command definition
static struct genl_ops ops[] = {
{
.cmd = NL_CMD_MY_CMD,
.doit = genl_register,
}
};
//...
//When the module is loaded:
genl_register_family_with_ops(&family, ops);
//Now some data should be sent to user space:
struct sk_buff *msg= nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
void *hdr = genlmsg_put(msg, port/*note1*/, 0, &family, 0/*note2*/, NL_CMD_MY_CMD);
nla_put_u32(msg, NL_MY_ATTR, some_value);
genlmsg_end(msg, hdr);
genlmsg_unicast(&init_net, msg, port/*note1*/); //note3
请注意,我删除了错误检查以减少代码量
一些注意事项:
- 注意 1:用户空间程序的端口存储在内核模块内部 - 我 100% 确定它是正确的
- note2:在标志中我也尝试设置 NLM_F_REQUEST 但没有成功
- 注意3:函数
genlmsg_unicast总是返回0,表示消息发送成功。所以我认为内核代码应该没问题。
这里是用户空间代码:
#include <netlink/netlink.h>
#include <netlink/socket.h>
#include <netlink/types.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <netlink/genl/mngt.h>
//...
struct nl_sock *socket = nl_socket_alloc();
//I explicitly set those callbacks to get some debug information
nl_socket_modify_cb(socket, NL_CB_MSG_IN, NL_CB_DEBUG, NULL, NULL);
nl_socket_modify_cb(socket, NL_CB_INVALID, NL_CB_DEBUG, NULL, NULL);
//I also tried to Play around with the buffer size:
nl_socket_set_buffer_size(socket, 65536, 65536);
genl_connect(socket);
familyId = genl_ctrl_resolve(socket, "my-family"); //This works and gives me the correct Family id
nl_recvmsgs_default(socket);
内核一发送消息,我就会在用户空间程序中看到调试信息,但遗憾的是它只是错误消息:
-- Debug: Received Message:
-------------------------- BEGIN NETLINK MESSAGE ---------------------------
[NETLINK HEADER] 16 octets
.nlmsg_len = 308
.type = 23 <0x17>
.flags = 0
.seq = 0
.port = -1765782228
[GENERIC NETLINK HEADER] 4 octets
.cmd = 1
.version = 1
.unused = 0
[PAYLOAD] 4 octets
08 00 02 00 ....
--------------------------- END NETLINK MESSAGE ---------------------------
-- Error: Invalid message: type=0x17 length=24 flags=0 sequence-nr=0 pid=2529185068
如您所见,在“END NETLINK MESSAGE”行之后是来自回调NL_CB_INVALID 的消息,它告诉我收到了无效消息。
所以实际上通信本身是正常的,因为它应该只是收到一个无效的消息,不知道为什么。有人知道我在哪里可以找到更多信息吗?为什么邮件格式不正确... 甚至更好:有人在我的代码中看到错误吗? 或者有谁知道描述这种场景的非常好的网站?
【问题讨论】:
标签: c sockets linux-kernel netlink