Linux 内核函数 `nlmsg_unicast()` 的作用与使用详解

ChatGPT4o 使用 ChatGPT 4o 回答

问题:

nlmsg_unicast()函数的作用是什么?

回答:

nlmsg_unicast() 是 Linux 内核中的一个函数,用于通过 netlink 套接字将消息发送到单个用户空间进程。Netlink 是一种进程间通信(IPC)机制,主要用于内核与用户空间之间的通信。

以下是 nlmsg_unicast() 函数的一些关键点:

作用

nlmsg_unicast() 函数的主要作用是将构建好的 netlink 消息发送到指定的用户空间进程。

函数原型

int nlmsg_unicast(struct net *net, struct sk_buff *skb, u32 portid);

参数

  • struct net *net: 指向网络命名空间的指针。
  • struct sk_buff *skb: 指向要发送的 socket 缓冲区(sk_buff)的指针。这个缓冲区包含了要发送的 netlink 消息。
  • u32 portid: 目标用户空间进程的 netlink 端口 ID(通常是进程 ID)。

返回值

  • 成功时返回 0。
  • 失败时返回负数的错误码。

使用示例

以下是一个简单的使用示例,展示了如何使用 nlmsg_unicast() 发送 netlink 消息:

#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <net/netlink.h>
#include <net/sock.h>

void send_netlink_message(struct net *net, u32 portid, const char *message)
{
    struct sk_buff *skb;
    struct nlmsghdr *nlh;
    int msg_size = strlen(message) + 1;
    int res;

    // 分配新的 sk_buff
    skb = nlmsg_new(msg_size, GFP_KERNEL);
    if (!skb) {
        pr_err("Failed to allocate new skb\n");
        return;
    }

    // 初始化 netlink 消息头
    nlh = nlmsg_put(skb, 0, 0, NLMSG_DONE, msg_size, 0);
    if (!nlh) {
        pr_err("Failed to put nlmsg\n");
        nlmsg_free(skb);
        return;
    }

    // 复制消息到 netlink 消息负载
    strncpy(nlmsg_data(nlh), message, msg_size);

    // 发送消息
    res = nlmsg_unicast(net, skb, portid);
    if (res < 0) {
        pr_err("Failed to send netlink message: %d\n", res);
    }
}

在这个示例中,send_netlink_message 函数创建一个新的 netlink 消息并通过 nlmsg_unicast() 发送到指定的用户空间进程。

注意事项

  • 在调用 nlmsg_unicast() 之前,确保 skb 已正确初始化并包含有效的 netlink 消息。
  • portid 必须是目标用户空间进程的有效 netlink 端口 ID。
  • 处理错误返回值,以确保消息发送成功。

通过 nlmsg_unicast(),内核模块可以方便地与用户空间进程进行通信,传递各种信息和数据。