1、netlink及相关接口说明
说到驱动和应用层进行数据通信,很多人就会想到使用传统的ioctl,诚然,很多时候应用层调用驱动进行参数配置和参数获取使用的也正是ioctl的方式,但这种方式有一种局限性,那就是只适合于数据量较小且操作不频繁的情况。否则,频繁操作io将大大影响设备的性能,甚至造成设备宕机。
最近在做一个关于wifi诊断需求时,需要记录wifi连接过程中的控制帧和管理帧,以及STA断开及断开原因。由于wifi驱动不断在进行数据帧和控制帧的交互,如果直接在驱动中操作io写文件,wifi性能将收到很大影响。后来相到了使用netlink进行数据传输,将数据传输到应用层进行log的记录。
下面简单介绍下linux下netlink相关的接口,由于我使用的内核版本是linux-lsk-v4.1.25,接口主要介绍该版本接口,代码实例中会进行版本兼容,需要连接其他版本的请自行跟读相关版本源码。
1.1、netlink_kernel_create接口
netlink_kernel_create接口的定义在lnclude/linux/netlink.h中,可以看出他是真身实际上是__netlink_kernel_create,具体我们不需要过多关心,我们先看看他的参数和返回值情况。
static inline struct sock *
netlink_kernel_create(struct net *net, int unit, struct netlink_kernel_cfg *cfg)
{
return __netlink_kernel_create(net, unit, THIS_MODULE, cfg);
}
第一个参数(struct net)是一个网络的namespace,在不同的名字空间里面可以有自己的转发信息库,有自己的一套net_device等等,默认情况下都是使用 init_net这个全局变量。
第二个参数(int unit)实际上是当前使用的实例号,由于Netlink本身是linux的一个部分,linux内核中的很多和应用层的交互也使用过netlink(比如防火墙iptables)。因此部分协议号实际已经被占用,我们只能从之后的协议号中挑选能使用的协议号,否则将造成协议冲突。协议号的定义在include/uapi/linux/netlink.h中,如下。
#define NETLINK_ROUTE 0 /* Routing/device hook */
#define NETLINK_UNUSED 1 /* Unused number */
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
#define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */
#define NETLINK_SOCK_DIAG 4 /* socket monitoring */
#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
#define NETLINK_XFRM 6 /* ipsec */
#define NETLINK_SELINUX 7 /* SELinux event notifications */
#define NETLINK_ISCSI 8 /* Open-iSCSI */
#define NETLINK_AUDIT 9 /* auditing */
#define NETLINK_FIB_LOOKUP 10
#define NETLINK_CONNECTOR 11
#define NETLINK_NETFILTER 12 /* netfilter subsystem */
#define NETLINK_IP6_FW 13
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
#define NETLINK_GENERIC 16
/* leave room for NETLINK_DM (DM Events) */
#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
#define NETLINK_ECRYPTFS 19
#define NETLINK_RDMA 20
#define NETLINK_CRYPTO 21 /* Crypto layer */
#define NETLINK_INET_DIAG NETLINK_SOCK_DIAG
#define