#include #include #include #include #include #include #include #include #include "../netlink_api/libnetlink_k.h" #include "../../../Common/commuapinl.h" struct netlinkk_cfg g_upmnlcfg; struct commnl_msgtype_process cfgnl_msg_handlers[COMMCFG_NLMSG_MAX_TYPE]; int cfgnl_unicast(struct sk_buff *skb, u32 portid) { int ret = -1; struct nlmsghdr *nlh = NULL; int msgtype = 0; ret = commnl_unicast(g_upmnlcfg.sk, skb, portid); if(ret < 0) { g_upmnlcfg.dfs.send_fail++; g_upmnlcfg.dfs.send_fail_reason = ret; } else { g_upmnlcfg.dfs.send_succ++; } nlh = (struct nlmsghdr *)skb->head; msgtype = nlh->nlmsg_type; if((msgtype > NLMGS_PDELIVERY_MAX_TYPE ) || (msgtype <= PDNL_BASE)) { printk(KERN_ERR "pdeliv_unicast:msg type invalid.\r\n"); } else { //printk(KERN_DEBUG "pdeliv_unicast:msg type %d.\r\n",msgtype); if(ret < 0) { cfgnl_msg_handlers[msgtype].dfs.send_fail++; } else { cfgnl_msg_handlers[msgtype].dfs.send_succ++; } } return(ret); } #if 0 int nl_upm_data_ready(struct sk_buff *skb, struct nlmsghdr *nlh) { void *payload; struct sk_buff *out_skb; void *out_payload; struct nlmsghdr *out_nlh; int payload_len; // with padding, but ok for echo printk(KERN_DEBUG "nl_upm_data_ready() begin.\n"); switch(nlh->nlmsg_type) { case COMMNMSG_POLICYCONF:/**/ payload = nlmsg_data(nlh); payload_len = nlmsg_len(nlh); printk(KERN_INFO "Recievid: %s, From: %d\n", (char *)payload, nlh->nlmsg_pid); out_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); //分配足以存放默认大小的sk_buff if (!out_skb) goto failure; out_nlh = nlmsg_put(out_skb, 0, 0, COMMNMSG_POLICYCONF, payload_len, 0); //填充协议头数据 if (!out_nlh) goto failure; //out_payload = nlmsg_data(out_nlh); //nla_put_u32(out_skb,PDELIVERY_DUMP_PKTNUM_ATTR,g_nlcfg->pkt_delev_num); commnl_unicast(g_upmnlcfg.sk, out_skb, nlh->nlmsg_pid); break; default: printk(KERN_INFO "libnetlink Unknow msgtype recieved!\n"); return 0; } printk(KERN_DEBUG "nl_upm_data_ready() end.\n"); return 0; failure: printk(KERN_INFO " failed in fun dataready!\n"); return 0; } #endif int nl_cfg_data_ready(struct sk_buff *skb, struct nlmsghdr *nlh, struct netlink_ext_ack *extack) { int ret = 0; printk(KERN_DEBUG "nl_cfg_data_ready() nlmsg_type = %d begin.\n",nlh->nlmsg_type); g_upmnlcfg.dfs.rev_total++; if(NULL != cfgnl_msg_handlers[nlh->nlmsg_type].doit) { cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_total++; ret = cfgnl_msg_handlers[nlh->nlmsg_type].doit(skb, nlh,extack); if(ret >= 0) { g_upmnlcfg.dfs.rev_cb_sucess++; cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_cb_sucess++; } else { g_upmnlcfg.dfs.rev_cb_fail++; cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_cb_fail++; } } else { cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_drop_total++; cfgnl_msg_handlers[nlh->nlmsg_type].dfs.rev_drop_nodoit++; g_upmnlcfg.dfs.rev_drop_total++; g_upmnlcfg.dfs.rev_drop_nodoit++; printk(KERN_WARNING "no doit fun register with nlmsg_type = %d .\n",nlh->nlmsg_type); } printk(KERN_DEBUG "nl_cfg_data_ready() nlmsg_type = %d end.\n",nlh->nlmsg_type); return ret; } static void libcfgnl_rcv(struct sk_buff *skb) { printk(KERN_DEBUG "libcfgnl_rcv:\n"); netlink_rcv_skb(skb, &nl_cfg_data_ready); } int cfgrcv_debugfs(struct sk_buff *skb, struct nlmsghdr *nlh,struct netlink_ext_ack *extack) { int ret = 0; NETLINK_DEBUG(g_upmnlcfg.debugfs_prk_enable, "cfgrcv_debugfs, From pid: %d\n", nlh->nlmsg_pid); /* #ifdef NLDEBUG_ACK_COOKIES ret = debugfs_pkt_num_stati(&g_upmnlcfg, nlh,extack); #else ret = debugfs_pkt_num_stati_witisend(&g_upmnlcfg, nlh,cfgnl_msg_handlers); #endif printk("*****************biduichengong***************\n"); return ret; */ switch(nlh->nlmsg_type) { //case COMMNMSG_POLICYCONF:/**/ case NLMSG_PDELIV_DEBUGFS: #ifdef NLDEBUG_ACK_COOKIES ret = debugfs_pkt_num_stati(&g_upmnlcfg, nlh,extack); #else ret = debugfs_pkt_num_stati_witisend(&g_upmnlcfg, nlh,cfgnl_msg_handlers); #endif NETLINK_DEBUG(g_upmnlcfg.debugfs_prk_enable, "*****************biduichengong********%d*******\n", nlh->nlmsg_type); return ret; break; case NK_DEBUGFS_PRK_ONOFF: ret = debugfs_prk_onoff(&g_upmnlcfg, nlh, extack); return ret; break; default: NETLINK_DEBUG(g_upmnlcfg.debugfs_prk_enable, "libnetlink Unknow msgtype recieved!\n"); return 0; } /**************************************************************************************************************/ return 0; } int cfg_msgtype_register( int msgtype,commnl_doit_func doit, commnl_dumpit_func dumpit,commnl_calcit_func calcit) { if(msgtype >= COMMCFG_NLMSG_MAX_TYPE ) { printk(KERN_ERR"netlink.ko-msgtype register invalid msgtype %d,protocl comcfg.\r\n",msgtype); return -1; } commnl_register(cfgnl_msg_handlers, msgtype,doit, dumpit,calcit); printk(KERN_INFO"netlink.ko-msgtype register sucess msgtype %d,protocl comcfg.\r\n",msgtype); return 0; } int cfg_msgtype_unregister(int msgtype) { if(msgtype >= COMMCFG_NLMSG_MAX_TYPE ) { printk(KERN_ERR"commnl_unregister invalid msgtype %d,protocl conncfg.\r\n",msgtype); return -1; } commnl_unregister(cfgnl_msg_handlers,msgtype); printk(KERN_DEBUG"commnl_unregister sucess msgtype %d,protocl comcfg.\r\n",msgtype); return 0; } int __init cfgrcv_init(void) { int ret = -1; printk(KERN_INFO "cfgrcv.ko-initialed!\n"); g_upmnlcfg.msg_processer = &(cfgnl_msg_handlers[0]); g_upmnlcfg.msg_processer_num = COMMCFG_NLMSG_MAX_TYPE; /*init for pdelivery module*/ g_upmnlcfg.groups = 0; g_upmnlcfg.subscriptions = NETLINK_COMMCFG;/*创建配置处理通道*/ g_upmnlcfg.cfg.input = libcfgnl_rcv; ret = libnetlinkk_init_byproto(&g_upmnlcfg); if(ret < 0) { return ret; } /*do msg process register*/ ret = cfg_msgtype_register(COMMNMSG_CFG_DEBUGFS,cfgrcv_debugfs,NULL,NULL); ret = cfg_msgtype_register(NK_DEBUGFS_PRK_ONOFF,cfgrcv_debugfs,NULL,NULL); return ret; } void __exit cfgrcv_exit(void) { printk(KERN_CRIT "nl_upm existing...\n"); libnetlinkk_exit(&g_upmnlcfg); return; } EXPORT_SYMBOL_GPL(cfgnl_unicast); EXPORT_SYMBOL_GPL(cfg_msgtype_register); EXPORT_SYMBOL_GPL(cfg_msgtype_unregister); module_init(cfgrcv_init); module_exit(cfgrcv_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("a simple example for upm(user policy manage) netlink protocal family"); MODULE_AUTHOR("RSLjdkt");