linux 关于netlink的一个奇怪问题

qq_41121215 2019-07-22 09:18:53
最近在学习netlink,用来实现用户层和内核的通信,在写内核部分代码时,遇到一个奇怪的问题:
每次卸载完模块后,必须修改协议号(NETLINK_TEST),netlink_kernel_create(&init_net,NETLINK_TEST,&cfg);才能成功,不修改协议号,一直创建内核sock失败,
哪位大佬帮帮忙!!!

所用平台Ubuntu16.04+linux内核4.15.0-46-generic

内核代码如下
#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");


makefile如下

ifneq ($(KERNELRELEASE),)

obj-m :=nldrv.o
#obj-m += hello.o

else

KDIR :=/lib/modules/$(shell uname -r)/build

all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order

endif
...全文
78 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
636f6c696e 2019-07-23
  • 打赏
  • 举报
回复
卸载模块没有写析构函数啊,内核没有释放这个协议号
qq_41121215 2019-07-23
  • 打赏
  • 举报
回复
谢谢大佬,我找到问题了,netlinkclose函数里的判断错了
qq_41121215 2019-07-23
  • 打赏
  • 举报
回复
引用 1 楼 636f6c696e的回复:
卸载模块没有写析构函数啊,内核没有释放这个协议号
//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; } 调用自己写的这个函数,行不行?

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧