知者726 知者726
关注数: 6 粉丝数: 4 发帖数: 118 关注贴吧数: 32
linux 第二次加载netlink模块时,内核创建sock失败 最近在学习netlink,用来实现用户层和内核的通信,在写内核部分代码时,遇到一个奇怪的问题: 每次卸载完模块后,必须修改协议号(NETLINK_TEST),netlink_kernel_create(&init_net,NETLINK_TEST,&cfg);才能成功,不修改协议号,一直创建内核sock失败, 哪位大佬帮帮忙!!!所用平台Ubuntu16.04+linux内核4.15.0-46-generic内核代码如下 [code=c]#include<linux/module.h> #include<linux/netlink.h> #include<linux/skbuff.h> #include<net/sock.h>#define MAX_MSG_LEN 1024 //#define USER_PID 66666 #define NETLINK_TEST 21 //proto number static struct sock* g_sk_nl_k = NULL; static struct nlmsghdr *g_nlh = NULL; //will contain user's pid,data and so on//static int g_nlmsg_pid = USER_PID;//static void revFromApp(struct sk_buff* skb);//send msg to app int sendToApp(char *pmsg){ struct nlmsghdr *nlh = NULL; struct sk_buff *nl_skb_out = NULL; int ret; ret= -1; if(!pmsg){ printk("Msg is null,send msg failed!\n"); return -1; } if(!g_sk_nl_k){ printk("User's pid is'n known,send msg failed!\n"); return -1; } nl_skb_out = nlmsg_new(MAX_MSG_LEN,0);//Allocate a new skb to send a new netlink message to nl_APP //nl_skb_out = alloc_skb(NLMSG_SPACE(MAX_MSG_LEN), GFP_ATOMIC); if(!nl_skb_out){ printk("Allocate new skb failed,send msg failed!\n"); return -1; } nlh = nlmsg_put(nl_skb_out,0,0,0,MAX_MSG_LEN,0); if(nlh == NULL){ printk("nlmsg_put failaure!\n"); nlmsg_free(nl_skb_out); return -1; } NETLINK_CB(nl_skb_out).creds.pid = 0; //NETLINK_CB(nl_skb_out).dst_group = 0; memcpy(NLMSG_DATA(nlh), pmsg, strlen(pmsg)); //ret = nlmsg; ret = netlink_unicast(g_sk_nl_k, nl_skb_out,g_nlh->nlmsg_pid, MSG_DONTWAIT);//USER_PID if(ret < 0){ printk("nlmsg_unicast failaure!\n"); nlmsg_free(nl_skb_out); return -1; } nlmsg_free(nl_skb_out); return 0; }//receive msg from app(only run one time if no loop) static void revFromApp(struct sk_buff* skb){ char * msgFromApp = NULL; char * str0 = "msg from kernel"; //struct nlmsghdr *nlh; turn to gloabe g_nlh=(struct nlmsghdr*)(skb->data); //nlh message from shb's data...(sk_buff:unsigned char *data) //nlh = nlmsg_hdr(skb); msgFromApp = nlmsg_data(g_nlh);//get data from struct nlmsghdr *nlh; //test printk("msg:%s\n",msgFromApp); sendToApp(str0); }struct netlink_kernel_cfg cfg = { .input=revFromApp, };//create socket int netlinkCreate(void){ g_sk_nl_k = netlink_kernel_create(&init_net,NETLINK_TEST,&cfg); if(!g_sk_nl_k){ printk("Error creating socket!\n"); return -1; } return 0; }//close socket void netlinkClose(struct sock* sk_nl_k){ if(!sk_nl_k){ //sock_release(sk_nl_k->sk_socket); netlink_kernel_release(sk_nl_k); //sk_nl_k = NULL; } }//netlink open static int __init netlink_init(void){ int ret = -1; ret = netlinkCreate();//get struct sock* g_sk_nl_k if(ret < 0){ printk("Netlink open failed!\n"); return -1; } printk("Netlink open !\n"); return 0; }//netlink close static void __exit netlink_exit(void){ //netlink_kernel_release(g_sk_nl_k); //printk("Netlink close0!\n"); netlinkClose(g_sk_nl_k); printk("Netlink close1!\n"); }module_init(netlink_init); module_exit(netlink_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("ysx"); [/code]makefile如下 [code=c] ifneq ($(KERNELRELEASE),)obj-m :=nldrv.o #obj-m += hello.oelseKDIR :=/lib/modules/$(shell uname -r)/buildall: make -C $(KDIR) M=$(PWD) modules clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.orderendif [/code]
1 下一页