内核态到用户态通信
(一) netlink简介
netlink
套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC
),也是网络应用程序与内核通信的最常用的接口。
(二) netlink使用
下面首先通过一个实际问题来说明netlink的使用方法
1、要解决的问题
- 环境
硬件:路由器
, 操作系统:openwrt
,芯片:mt7628
- 问题
解决无线驱动接口的状态消息发送到用户态程序
2、无线驱动中使用netlink
在加入该代码的文件必须包含内核部分封装netlink的源文件
/* 封装netlink在内核态发送消息到用户态的代码 */
enum {
ACTION_DOWN = 0, /* 初始默认APCLI状态为down */
ACTION_UP
};
/* 在下述apcli_status.h文件中实现 */
extern int send_netlink_data(char *data, u_int data_len);
static VOID ApCliCtrlSendNetlinkMsg(
IN PRTMP_ADAPTER pAd,
IN USHORT ifIndex,
IN ULONG action)
{
NlAPCliStatusMsg nlData;
memset(&nlData, 0, sizeof(nlData));
nlData.msg_type = action;
nlData.band_type = WIRELESS_BAND_2G;
nlData.ssid_len = pAd->ApCfg.ApCliTab[ifIndex].SsidLen;
memcpy(nlData.ssid, pAd->ApCfg.ApCliTab[ifIndex].Ssid, MAX_LEN_OF_SSID);
send_netlink_data((char *)&nlData, sizeof(nlData));
DBGPRINT(RT_DEBUG_TRACE, ("(%s) 2.4G %s, send netlink msg.\n", __FUNCTION__, action == ACTION_DOWN? "down" : "up"));
}
在相应的地方调用上述函数发送消息
ApCliCtrlSendNetlinkMsg(pAd, ifIndex, ACTION_UP);
3、内核封装netlink
无线驱动使用netlink时,需要包含如下两个文件
/*************************************************************************
File name: apcli_status.c
Description:
The module supports reporting status to application layer
*************************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <linux/apcli_status.h>
#define DEBUG_APCLI_STATUS 0
#if DEBUG_APCLI_STATUS
#define DEBUG_PRINT(fmt ,args...) printk("[%s |%d]" fmt, __func__, __LINE__, ##args)
#else
#define DEBUG_PRINT(fmt, argx...)
#endif
static int pid = 0;
static struct sock *nl_sk = NULL;
static DEFINE_MUTEX(apcli_status_mutex);
int send_netlink_data(char *data, u_int data_len)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
int ret =