static int __init netlink_init(void) { int i = 10; struct completion cmp1; nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST,1,NULL,NULL,THIS_MODULE); if(nl_sk == NULL) { printk(KERN_ERR"%s:my netlink:create netlink socket error\n",__FUNCTION__); return 1; } printk("my netlink:create netlink socket ok\n"); while(i--) { init_completion(&cmp1); wait_for_completion_timeout(&cmp1,3*HZ); sendnlmsg("I am from kernel!"); } return 0; }
void nl_data_ready(struct sk_buff *__skb) { struct sk_buff *skb; struct nlmsghdr *nlh; char str[100]; // struct completion cmpl; int i=10; skb = skb_get (__skb); if(skb->len >= NLMSG_SPACE(0)){ nlh = nlmsg_hdr(skb); memcpy(str, NLMSG_DATA(nlh), sizeof(str)); printk("Message received:%s\n",str) ; pid = nlh->nlmsg_pid; while(i--){ //init_completion(&cmpl); //wait_for_completion_timeout(&cmpl,3 * HZ); sendnlmsg(); break; } flag = 1; kfree_skb(skb); } }
/* * Accpet the commands from user space to set the rules */ void nl_data_ready(struct sk_buff *__skb) { struct sk_buff *skb; struct nlmsghdr *nlh; char str[100]; //struct completion cmpl; int i=10; int interval = 0; char command[6] ={'\0'},ipaddr[60]={'\0'}; struct in6_addr recvaddr; printk("nl_data_ready......in\n"); skb = skb_get (__skb); if(skb->len >= NLMSG_SPACE(0)) { nlh = nlmsg_hdr(skb); memcpy(str, NLMSG_DATA(nlh), sizeof(str)); printk("Message received:%s\n",str) ; sscanf(str, "cmd=%s ip=%s interval=%d", command, ipaddr,&interval); memcpy(&recvaddr,ipaddr,sizeof(recvaddr)); //convert ipaddr to struct in6_addr // the comand format // ADD>x:x:x:x // DEL>x:x:x:x if(strcmp(command,"ADD")==0) { add_rule(&ipaddrs, &recvaddr); } else if(strcmp(command,"DEL")==0) { del_rule(&ipaddrs, &recvaddr); } pid = nlh->nlmsg_pid; //the source process id sendnlmsg("command executed."); kfree_skb(skb); } }