Linux 系统下内核与应用进行数据交换的各种方式,包括内核启动参数、模块参数与 sysfs、sysctl、系统调用、netlink、procfs、seq_file、debugfs 和 relayfs;
包括:路由 daemon(NETLINK_ROUTE),1-wire 子系统(NETLINK_W1),用户态 socket 协议(NETLINK_USERSOCK),防火墙(NETLINK_FIREWALL),socket 监视(NETLINK_INET_DIAG),netfilter 日志(NETLINK_NFLOG),ipsec 安全策略(NETLINK_XFRM),SELinux 事件通知(NETLINK_SELINUX),iSCSI 子系统(NETLINK_ISCSI),进程审计(NETLINK_AUDIT),转发信息表查询(NETLINK_FIB_LOOKUP),netlink connector(NETLINK_CONNECTOR),netfilter 子系统(NETLINK_NETFILTER),IPv6 防火墙(NETLINK_IP6_FW),DECnet 路由信息(NETLINK_DNRTMSG),内核事件向用户态通知(NETLINK_KOBJECT_UEVENT),通用 netlink(NETLINK_GENERIC)
简单记录下netlink编程,以后使用时详细规划,年龄大,脑子不好使了。
static DEFINE_MUTEX(netlink_user_cfg_mutex);
static struct sock *netlink_user;
struct user_obj {
int attribute;
int (*command1)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
int (*command2)(struct sk_buff *, struct nlmsghdr *);
}user_ob[] = {
[0] = { .attribute = 1,.command1 = user_command1,.command2 = user_command2},
[1} = { .attribute = 2,.command1 = user_command1,.command2 = user_command2},
[2} = { .attribute = 3,.command1 = user_command1,.command2 = user_command2},
};
int user_command1(struct sk_buff* skb,struct nlmsghdr nlmsg,struct nlattr **nlattr)
{
return nlmsg_unicast();
}
int user_command2(struct sk_buff* skb,struct nlmsghdr nlmsg)
{
return 0;
}
int netlink_user_rcv_msg(struct sk_buff *skb,struct nlmsghdr *nlh)
{
int type;
struct user_obj *user;
type = nlh->nlmsg_type;
user = &user_ob[type];
return user->command2(skb, nlh);
}
static void netlink_user_input(struct sk_buff *skb)
{
//多个进程都是访问,异步,lock
mutex_lock(&netlink_user_cfg_mutex);
netlink_rcv_skb(skb, &netlink_user_rcv_msg);
mutex_unlock(&netlink_user_cfg_mutex);
}
struct netlink_kernel_cfg netlink_user_cfg={
.input = netlink_user_input;
};
static int __init netlink_user_init(void)
{
/*create netlink socket*/
netlink_user = netlink_kernel_create(&init_net,NETLINK_USER,&netlink_user_cfg);
}
module_init(netlink_user_init);
module_exit(netlink_user_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("leefong chen <leefong88.chen@gmail.com>");
MODULE_DESCRIPTION("netlink userspace configuration API");
#define netlink_command1 1
static int skfd;
int main(int argc,char *argv[])
{
struct sockaddr_nl local;
struct nlmsghdr hdr;
memset(&local, 0, sizeof(local));
local.nl_family = AF_NETLINK;
local.nl_pid = getpid();
local.nl_groups = 0;
hdr.nlmsg_len = NLMSG_LENGTH(0);
hdr.nlmsg_flags = 0;
hdr.nlmsg_type = netlink_command1;
hdr.nlmsg_pid = local.nl_pid;
skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
bind(skfd, (struct sockaddr*)&local, sizeof(local));
sendto(skfd,&hdr,hdr.nlmsg_len,0,NULL,0);
while(1) {
recvfrom(skfd,)
}
return 0;
}
转载于:https://blog.51cto.com/linuxkernel/1341522