linux - netlink 套接字 : kernel freeze 的问题

标签 linux linux-kernel netlink

我正在尝试使用 netlink 套接字在用户空间和内核空间之间交换消息...我从用户空间向内核空间发送消息并且一切正常但是当我尝试从内核空间回复时,系统卡住。特别是我用工作队列安排了一个函数,该函数创建消息并使用 netlink_unicast 函数发送到用户空间......这里是一些内核代码:

void wq_func(struct work_queue *wq)
{
  struct sk_buff *resp = alloc_skb(NLMSG_LENGTH(100), GFP_KERNEL);
  if (!resp)
  {
     printk(KERN_INFO "alloc_skb failed");
     return;
  }

  struct nlmsghdr *nlh = (struct nlmsghdr *)skb_put(resp, NLMSG_LENGTH(100));
  memset(nlh, 0, NLMSG_LENGTH(100));
  nlh->nlmsg_len = NLMSG_LENGTH(100);
  nlh->nlmsg_pid = 0;
  nlh->nlmsg_flags = 0;
  strcpy(NLMSG_DATA(nlh), "From kernel: Yes i'm here!");
  NETLINK_CB(resp).pid = 0;
  NETLINK_CB(resp).dst_group = 0;

  printk(KERN_INFO "Trying to send a netlink message to pid %d", pid);
  int err = netlink_unicast(s, resp, pid, MSG_DONTWAIT);
  if (err < 0)
    printk(KERN_ALERT "Error sending message to user-space");
  kfree_skb(resp);
}
DECLARE_WORK(wq, wq_func);

static void input_nl(struct sk_buff *buff)
{
  printk(KERN_INFO "Received message socket NETLINK_TEST");
  if (buff == NULL)
  {
    printk(KERN_ALERT "NULL sk_buff!");
    return;
  }
  struct nlmsghdr *nlh = (struct nlmsghdr *)buff->data;
  printk(KERN_INFO "Received netlink message from pid %d: %s", nlh->nlmsg_pid,       NLMSG_DATA(nlh));

  pid = nlh->nlmsg_pid;

  schedule_work(&wq);
}

int __init knl_init()
{
  printk(KERN_INFO "knl module loaded");

  s = netlink_kernel_create(&init_net, NETLINK_TEST, 0, input_nl, NULL, THIS_MODULE);

  if (s == NULL)
    return -1;
  return 0;
}

如果我尝试评论对 netlink_unicast 内核的调用不会卡住。从用户空间我可以正确发送消息。我记得同样的代码在过去运行良好,现在我对这个奇怪的错误感到非常惊讶。

有什么想法吗?

谢谢大家!


我尝试在 netlink_unicast 调用之后删除 kfree_skb 调用,一切正常...那么,为什么系统会因该调用而挂起?我应该在哪里释放分配的 sk_buff?

最佳答案

netlink_unicast() 获取 skb 的所有权并自行释放它。

关于linux - netlink 套接字 : kernel freeze 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5884711/

相关文章:

linux - Asterisk 中使用的加密狗拨号方案

linux - 从 crontab 设置自动 rsync 以通过互联网将内容从一台 Linux 机器同步到另一台 Linux 机器的 final方法是什么?

c - obj-y += something/in linux kernel Makefile 是什么意思?

linux - 审核 netlink 响应没有正确的数据包长度

c - 从netlink消息中提取当前路由,附代码

linux - 将 IPv6 添加到 domU guest 中

c - 如何在 C 中对包含 "%"的字符串执行 strcmp?

linux - 从/proc/kcore获取系统调用表中的系统调用地址

linux - 哪个内核版本稳定/推荐用于 linux mint 18.2?

c - 应用程序未收到 iptable 修改的 Netlink 通知