# netlink_ipc **Repository Path**: mudash/netlink_ipc ## Basic Information - **Project Name**: netlink_ipc - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-01 - **Last Updated**: 2026-05-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Netlink IPC 实现 本项目实现了一个基于Linux Netlink的内核态与用户态通信框架,允许内核态代码调用用户态注册的函数。 ## 项目结构 ``` netlink_ipc/ ├── include/ # 公共头文件 │ └── netlink_ipc.h # 定义通信协议和数据结构 ├── kernel/ # 内核模块代码 │ └── netlink_ipc_module.c # 内核模块实现 ├── user/ # 用户态程序代码 │ ├── netlink_ipc_user.c # 用户态库实现 │ ├── netlink_ipc_user.h # 用户态库头文件 │ └── test_netlink_ipc.c # 测试程序 ├── build.sh # 构建脚本 ├── test.sh # 测试脚本 └── README.md # 项目说明文件 ``` ## 功能特性 1. **用户态函数注册**:用户态程序可以注册多个函数到内核模块 2. **函数调用支持**:内核模块可以调用已注册的用户态函数 3. **多参数支持**:支持多种数据类型的参数传递(整数、长整数、字符串、字符、浮点数、双精度浮点数) 4. **函数注销**:用户态程序可以注销已注册的函数 5. **同步和异步调用**:支持同步和异步两种调用模式 6. **大载荷支持**:支持16KB的消息载荷,字符串参数支持4KB 7. **调用统计**:通过`/proc/netlink_ipc`文件查看函数调用统计 8. **完整测试**:包含内核态和用户态的测试功能 ## 使用方法 ### 构建项目 ```bash # 构建整个项目(内核模块和用户态程序) ./build.sh # 仅构建内核模块 ./build.sh --kernel # 仅构建用户态程序 ./build.sh --user # 清理构建文件 ./build.sh --clean ``` ### 测试项目 测试脚本需要以root权限运行: ```bash # 执行完整测试(加载模块、运行测试程序、检查结果、卸载模块) sudo ./test.sh # 仅加载内核模块 sudo ./test.sh --load # 仅卸载内核模块 sudo ./test.sh --unload # 仅运行用户态测试程序 sudo ./test.sh --run # 检查内核模块状态 sudo ./test.sh --check ``` ### 查看统计信息 内核模块加载后,可以通过`/proc/netlink_ipc`文件查看函数调用统计: ```bash cat /proc/netlink_ipc ``` 输出示例: ``` Netlink IPC Statistics ====================== Function Name Calls Total(us) Avg(us) Max(us) Min(us) ------------------------------------------------------------ add_func 2 2345 1172 1456 889 print_string_func 1 567 567 567 567 get_time_func 1 234 234 234 234 ------------------------------------------------------------ Total Functions: 3 ====================== ``` ### 开发指南 #### 1. 添加新的用户态函数 在用户态程序中,你可以定义自己的函数并注册到内核。函数必须遵循以下格式: ```c __s64 my_function(struct func_param *params, int param_count) { // 函数实现 // 处理参数并返回结果 return result; } ``` 然后使用`register_user_func`函数注册你的函数: ```c register_user_func(FUNC_ID, "my_function", my_function); ``` #### 2. 内核态调用用户态函数 在内核代码中,你可以使用`kernel_call_user_func`函数调用已注册的用户态函数: ```c struct func_param params[2]; __s64 result; // 设置参数 params[0].type = PARAM_TYPE_INT; params[0].val.i_val = 10; params[1].type = PARAM_TYPE_INT; params[1].val.i_val = 20; // 调用用户态函数(同步模式) kernel_call_user_func(FUNC_ID, params, 2, &result); ``` #### 3. 用户态发起同步调用 用户态程序可以请求内核调用已注册的函数(同步模式): ```c struct func_param params[2]; __s64 result; char data[4096]; __u32 data_len; // 设置参数 params[0].type = PARAM_TYPE_INT; params[0].val.i_val = 10; params[1].type = PARAM_TYPE_INT; params[1].val.i_val = 20; // 同步请求内核调用 int ret = request_kernel_call(FUNC_ID, params, 2, &result, data, &data_len); ``` #### 4. 用户态发起异步调用 用户态程序也可以发起异步调用,通过回调函数接收结果: ```c // 异步回调函数 void my_async_callback(__u64 call_id, __u32 func_id, __s64 result, const char *data, __u32 data_len, void *user_data) { printf("Async call complete! Call ID: %llu, Result: %lld\n", (unsigned long long)call_id, result); } // 发起异步调用 __u64 call_id = request_kernel_call_async(FUNC_ID, params, param_count, my_async_callback, user_data); // 轮询异步响应 while (1) { poll_async_response(100); // 检查是否所有响应都已接收 } // 或者取消异步调用 cancel_async_call(call_id); ``` ## API 参考 ### 用户态库 API | 函数名 | 描述 | |--------|------| | `init_netlink_comm()` | 初始化Netlink通信 | | `cleanup_netlink_comm()` | 清理Netlink通信资源 | | `register_user_func(func_id, name, func_ptr)` | 注册用户态函数到内核 | | `unregister_user_func(func_id)` | 注销已注册的用户态函数 | | `request_kernel_call(func_id, params, count, result, data, len)` | 同步请求内核调用函数 | | `request_kernel_call_async(func_id, params, count, callback, user_data)` | 异步请求内核调用函数 | | `poll_async_response(timeout_ms)` | 轮询异步响应 | | `cancel_async_call(call_id)` | 取消异步调用 | ### 内核模块 API | 函数名 | 描述 | |--------|------| | `kernel_call_user_func(func_id, params, count, result)` | 同步调用用户态函数 | | `kernel_call_user_func_ex(func_id, params, count, result, mode, call_id)` | 扩展的调用函数(支持同步/异步模式) | ## 消息协议 ### 消息类型 | 类型 | 描述 | |------|------| | `MSG_TYPE_REGISTER_FUNC` | 函数注册请求 | | `MSG_TYPE_UNREGISTER_FUNC` | 函数注销请求 | | `MSG_TYPE_CALL_FUNC` | 函数调用请求 | | `MSG_TYPE_CALL_RESP` | 函数调用响应 | | `MSG_TYPE_USER_CALL_REQ` | 用户请求内核调用 | | `MSG_TYPE_USER_CALL_RESP` | 内核调用响应 | | `MSG_TYPE_CALL_ASYNC_RESP` | 异步调用响应 | ### 调用模式 | 模式 | 描述 | |------|------| | `CALL_MODE_SYNC` | 同步调用模式 | | `CALL_MODE_ASYNC` | 异步调用模式 | ## 注意事项 1. **权限要求**:加载/卸载内核模块需要root权限 2. **netlink协议号**:本项目使用的netlink协议号为26(NETLINK_USERSOCK) 3. **载荷大小**:最大支持16KB的消息载荷,单字符串参数最大4KB 4. **错误处理**:代码包含基本的错误处理,但在实际应用中可能需要进一步完善 5. **内核兼容性**:内核模块可能需要根据不同的Linux内核版本进行调整 6. **异步响应**:异步调用的响应需要通过`poll_async_response()`主动轮询 ## 故障排除 1. **内核模块加载失败**: - 检查内核版本是否兼容 - 查看`dmesg`输出以获取详细错误信息 2. **函数注册失败**: - 确保内核模块已正确加载 - 检查函数ID是否已被使用 3. **通信问题**: - 检查netlink协议号是否正确 - 查看系统日志以获取更多信息 4. **异步回调未触发**: - 确保调用了`poll_async_response()`来轮询响应 - 检查call_id是否匹配 - 查看`/proc/netlink_ipc`确认调用是否成功 ## 许可证 本项目基于GPL许可证。