前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

netlink 通信(二):关键代码解读

qiguaw 2025-04-27 15:37:50 资源文章 3 ℃ 0 评论

在上一篇文章中,我们给出了示例代码,下边就示例代码中的关键部分做一解读:

1. struct netlink_kernel_cfg 结构体

1. 定义

通常位于内核头文件
/usr/src/linux-5.15-headers-x.x/include/linux/netlink.h :

struct netlink_kernel_cfg {
  unsigned int groups; // 允许的组数
  unsigned int flags; // 标记
  void (*input)(struct sk_buff *skb); // 输入处理回调
  struct mutex *cb_mutex;
  int (*bind)(struct net *net, int group); // 绑定回调
  void (*unbind)(struct net *net, int group); // 解绑回调
  bool (*compare)(struct net *net, struct sock *sk);
};

2. 结构体参数说明

  • groups:类型:unsigned int描述:指定允许的 Netlink 组数。Netlink 组用于多播消息的发送和接收,允许多个用户空间进程订阅同一组的消息。
  • input:类型:指向函数的指针,函数签名为 int (*input)(struct sk_buff *skb)描述:这是一个回调函数,用于处理接收到的 Netlink 消息。当内核接收到来自用户空间的消息时,会调用此函数进行处理。skb 是指向 socket 缓冲区的指针,包含了接收到的数据。
  • bind:类型:指向函数的指针,函数签名为 int (*bind)(struct netlink_sock *sock, struct netlink_kernel_cfg *cfg)描述:这是一个可选的回调函数,用于在绑定 Netlink 套接字时执行特定的操作。可以在此函数中进行额外的初始化或配置。

3. 作用

  • netlink_kernel_cfg 结构体用于配置 Netlink 套接字,包含了允许的组数、输入处理函数和绑定函数等参数。
  • 通过合理配置 netlink_kernel_cfg,可以实现内核与用户空间之间的高效通信,处理网络相关的消息和事件。

2. init_net 全局变量

在 Linux 内核中,init_net 是一个全局变量,表示系统初始化时创建的默认网络命名空间(network namespace)。它是一个 struct net 类型的结构体实例,包含了与网络相关的各种信息和状态。

1. init_net 的作用

  • 默认网络命名空间:init_net 代表了系统启动时的网络命名空间,所有未特别指定命名空间的网络操作都将在这个命名空间中进行。
  • 网络资源管理:它包含了与网络相关的资源和状态,例如网络接口、路由表、套接字等。

2. 在示例中的使用

在之前的示例中,init_net 被用作创建 Netlink 套接字的上下文:

nl_sock = netlink_kernel_create(&init_net, MY_MOD_NETLINK_TOKEN, &cfg);
  • 参数解释:&init_net:传递 init_net 的地址,表示要在默认网络命名空间中创建 Netlink 套接字。MY_MOD_NETLINK_TOKEN:指定 Netlink 套接字的类型。&cfg:传递配置结构体,包含了允许的组数和输入处理函数等。

3. 网络命名空间的概念

  • 命名空间:Linux 的网络命名空间允许将网络资源(如网络接口、路由表等)隔离,使得不同的进程可以在不同的网络环境中运行。
  • init_net:作为默认命名空间,init_net 是所有进程在没有指定其他命名空间时使用的网络环境。

4. 总结

  • init_net 是 Linux 内核中表示默认网络命名空间的全局变量。
  • 在创建 Netlink 套接字时,使用 init_net 作为上下文,确保套接字在默认网络命名空间中运行。
  • 通过网络命名空间,Linux 提供了灵活的网络资源管理和隔离机制。

3. NLMSG_SPACE 与NLMSG_DATA 宏定义

在 Linux 内核中,NLMSG_SPACE 和 NLMSG_DATA 两个宏定义用于处理 Netlink 消息的结构和数据。这两个宏的使用是为了简化 Netlink 消息的管理和访问,确保代码的可读性和正确性。

1. NLMSG_SPACE 宏

  • 定义
#define NLMSG_SPACE(len) ((len) + NLMSG_HDRLEN)
  • 作用:NLMSG_SPACE 用于计算 Netlink 消息所需的总字节数,包括消息头的长度和有效载荷的长度。NLMSG_HDRLEN 是 Netlink 消息头的长度,通常是固定的。
  • 重要性内存分配:在创建 Netlink 消息时,使用 NLMSG_SPACE 可以确保分配足够的内存来存储整个消息,包括头部和数据部分。避免错误:通过使用这个宏,可以避免手动计算消息长度时可能出现的错误,确保消息结构的完整性。

2. NLMSG_DATA 宏

  • 定义
#define NLMSG_DATA(nlh) ((void *)(((char *)nlh) + NLMSG_HDRLEN))
  • 作用:NLMSG_DATA 用于获取指向 Netlink 消息有效载荷的指针。它通过将消息头的指针偏移 NLMSG_HDRLEN 的长度来实现。这个宏返回一个指向有效载荷数据的指针,方便后续的数据处理。
  • 重要性简化访问:使用 NLMSG_DATA 可以简化访问 Netlink 消息有效载荷的过程,避免手动计算偏移量。提高可读性:通过使用宏,代码的可读性提高,其他开发者可以更容易理解消息的结构。

3. 示例

  • 以下是一个简单的示例,展示如何使用这两个宏:
struct nlmsghdr *message;
int msglen = sizeof(my_data);
// 分配内存
message = (struct nlmsghdr *)malloc(NLMSG_SPACE(msglen));
// 设置消息头
message->nlmsg_len = NLMSG_SPACE(msglen);
message->nlmsg_type = MY_NETLINK_TYPE;
// 访问有效载荷
memcpy(NLMSG_DATA(message), &my_data, msglen);

4. 总结

  • NLMSG_SPACE 和 NLMSG_DATA 是用于处理 Netlink 消息的两个重要宏。
  • NLMSG_SPACE 确保分配足够的内存以容纳整个消息,而 NLMSG_DATA 提供了一个方便的方式来访问消息的有效载荷。
  • 这两个宏的使用提高了代码的安全性、可读性和可维护性,减少了出错的可能性。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表