secgateway/Product/modules/usercfgrcv/usercfg_kinit.c

245 lines
6.3 KiB
C
Raw Normal View History

#include <linux/module.h>
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <uapi/linux/netfilter_ipv4.h>
#include <uapi/linux/ip.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
#include "usercfg_kinit.h"
#include "../../../../../Common/commuapinl.h"
#include <linux/rtnetlink.h>
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
#define RTA_ALIGNTO 4U
#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
struct netlinkk_cfg g_upmnlcfg;
struct commnl_msgtype_process cfgnl_msg_handlers[COMMCFG_NLMSG_MAX_TYPE];
/*全局变量,存放免认证规则信息,目前只考虑放一条免认证规则,以结构体形式存放,后期考虑链表存放 */
freeauth_configure_t * kfreeauth;
/*全局变量,存放配置的用户老化时间 */
int *kaging_time = NULL;
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 cfgnl_unicast(struct sk_buff *skb, u32 portid)
{
int ret = -1;
struct nlmsghdr *nlh = NULL;
int msgtype = 0;
/**
* nlmsg_unicast - unicast a netlink message
* @sk: netlink socket to spread message to
* @skb: netlink message as socket buffer
* @portid: netlink portid of the destination socket
*/
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 > COMMCFG_NLMSG_MAX_TYPE)
{
printk(KERN_ERR "cfg_unicast:msg type invalid.\r\n");
}
else
{
printk(KERN_DEBUG "cfg_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);
}
/*免认证规则配置的功能函数,解析出配置信息,存全局变量*/
int usercfg_freeauth(struct sk_buff *skb, struct nlmsghdr *nlh,struct netlink_ext_ack *extack)
{
char *pload;
struct nlattr *rta;
char *load;
/**
* nlmsg_data - head of message payload
* @nlh: netlink message header
*/
pload = nlmsg_data(nlh);
rta = (struct nlattr *)pload;
load = RTA_DATA(rta);
kfreeauth = (freeauth_configure_t *)load;
printk("name:%s sip:%d\n", kfreeauth->name, kfreeauth->sip);
printk("dip:%d dport:%d\n", kfreeauth->dip, kfreeauth->dport);
return 0;
}
/*用户老化时间配置的功能函数,解析出配置信息,存全局变量 */
int usercfg_agingtime(struct sk_buff *skb, struct nlmsghdr *nlh,struct netlink_ext_ack *extack)
{
char *pload;
struct nlattr *rta;
char *load;
pload = nlmsg_data(nlh);
rta = (struct nlattr *)pload;
load = RTA_DATA(rta);
kaging_time = (int *)load;
printk("agingtime: %d\n", *kaging_time);
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;
}
/*函数功能:注册内核态配置接收消息处理函数。 */
/*输入参数: */
/*msgtype:注册的消息类型。*/
/*doit:对应的消息接收处理函数;*/
/*dumpit,calcit:框架预留接口暂未使用。填NULL.*/
/*输出参数: WU */
/*返回值0注册成功< 0,失败*/
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;
}
/*commcfgmsgtype:FREEAUTH_CFG = 0x13, 用户态发送给内核态的免认证规则消息*/
/*AGINGTIME_CFG = 0x14, 用户态发送给内核态的用户老化时间消息 */
int __init usercfgrcv_init(void)
{
int ret = -1;
printk(KERN_INFO "usercfgrcv.ko-initialed\n");
g_upmnlcfg.msg_processer = &(cfgnl_msg_handlers[0]);
g_upmnlcfg.msg_processer_num = COMMCFG_NLMSG_MAX_TYPE;
/*init for usercfg module */
g_upmnlcfg.groups = 0;
g_upmnlcfg.subscriptions = NETLINK_COMMCFG; /*创建配置处理通道 */
g_upmnlcfg.cfg.input = libcfgnl_rcv;
/*函数功能:在内核态创建报文上送通道,上送的 */
/*报文内容从链路层头开始。一个netlink协议号只能创建一个通道。 */
/*输入参数g_nlcfg */
/*输出参数: wu */
/*返回值0通道创建成果< 0,失败 */
ret = libnetlinkk_init_byproto(&g_upmnlcfg);
if(ret < 0)
{
return ret;
}
/*do msg process register */
ret = cfg_msgtype_register(FREEAUTH_CFG, usercfg_freeauth, NULL, NULL);
ret = cfg_msgtype_register(AGINGTIME_CFG, usercfg_agingtime, NULL, NULL);
return ret;
}
void __exit usercfgrcv_exit(void)
{
printk(KERN_CRIT "nl_upm existing...\n");
libnetlinkk_exit(&g_upmnlcfg);
}
EXPORT_SYMBOL_GPL(cfgnl_unicast);
EXPORT_SYMBOL_GPL(cfg_msgtype_register);
module_init(usercfgrcv_init);
module_exit(usercfgrcv_exit);