secgateway/Product/modules/object_manager/obj_api.c

483 lines
9.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifdef __KERNEL__
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/device.h>
#include <linux/in.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include "../proc_api/proc_api.h"
#include "../../common/cJSON/cJSON.h"
#include "obj_api.h"
/**
* @def OBJ_DEV_NAME
* @brief
*/
#define OBJ_DEV_NAME ("isg_objs") ///< 设备节点名称
/**
* @def VERSION
* @brief
*/
#define VERSION ("obj0.0.0.2")
/**
* @def SHM_MEM_SIZE
* @brief
*/
#define SHM_MEM_SIZE (1024 * 1024) ///< 1M字节共享内存
/**
* @var typedef {anonOBJECT_DRV} OBJECT_DRV
* @brief
*/
/**
* @var typedef {anonOBJECT_DRV} POBJECT_DRV
* @brief
*/
/**
* @struct {anonOBJECT_DRV}
* @brief
*/
typedef struct {
struct class *dev_class; ///< 设备类,用于自动在 /dev 下创建文件节点
int dev_major; ///< 设备主版本号
atomic_t ref_count; ///< 驱动程序打开计数
unsigned int mem_size; ///< 共享内存大小
unsigned char *mem_buf; ///< 共享内存指针
} OBJECT_DRV, *POBJECT_DRV;
/**
* @var g_obj_device
* @brief
* @see POBJECT_DRV
*/
static POBJECT_DRV g_obj_device = NULL;
DEFINE_RWLOCK(g_obj_lock);
/**
* @var g_obj_data
* @brief
* @see PCMHI_OBJECT
*/
PCMHI_OBJECT g_obj_data = NULL;
/**
* @brief
*
* @param buf
* @param size
*
* @return
* @date 2019/08/07
*/
void obj_upgrade_dev_buffer(unsigned char *buf, unsigned int size)
{
if(buf && size < g_obj_device->mem_size - 1) {
memcpy(g_obj_device->mem_buf, buf, size);
g_obj_device->mem_buf[size] = 0;
} else {
printk(KERN_ERR "Buffer = %p, size = %u\n", buf, size);
}
}
/**
* @brief 根据对象名称获取对象
*
* @param name: 对象名称
* @param type: 对象类型
*
* @return: 对象指针 或 NULL 空指针
* @date 2019/08/07
*/
PCMHI_OBJECT get_object(const char *name, int type)
{
PCMHI_OBJECT obj, tmp;
PSERVER_OBJ_CONTENT req = NULL;
HASH_FIND_STR(g_obj_data, name, obj);
if(!obj) {
return NULL;
}
if(type >= OBJ_TYPE_ADDR && type < OBJ_TYPE_MAX) {
if(obj->type != type) {
return NULL;
}
}
return obj;
}
/**
* @brief 判断当前服务是否在对象中
*
* @param obj: 对象指针
* @param port: 协议端口
* @param proType: 协议类型
*
* @return: 存在0 不存在1
* @date 2019/08/07
*/
int item_belong_server_obj(PCMHI_OBJECT obj, __be16 port, int proType)
{
PSERVER_OBJ_CONTENT req = NULL;
if(!obj) {
return 0;
}
list_for_each_entry(req, &obj->data->content, list) {
if(proType == req->pro_type && port >= req->min_port && port <= req->max_port) {
return 1;
}
}
return 0;
}
/**
* @brief 判断当前时间是否在对象中
*
* @param obj: 对象指针
* @param tm: 时间戳
*
* @return: 存在0 不存在1
* @date 2019/08/07
*/
int item_belong_dt_obj(PCMHI_OBJECT obj, unsigned long tm)
{
PDT_OBJ_CONTENT req = NULL;
if(!obj) {
return 0;
}
list_for_each_entry(req, &obj->data->content, list) {
if(MODE_NONE == req->rep_mode && tm >= req->min_time && tm <= req->max_time) {
return 1;
}
}
return 0;
}
/**
* @brief 判断IPv4地址是否在对象中
*
* @param obj: 对象指针
* @param addr: IPv4地址
*
* @return: 存在0 不存在1
* @date 2019/08/07
*/
int ipv4_belong_addr_obj(PCMHI_OBJECT obj, __be32 addr)
{
}
/**
* @brief 判断IPv6地址是否在对象中
*
* @param obj: 对象指针
* @param addr: IPv6地址
*
* @return: 存在0 不存在1
* @date 2019/08/07
*/
int ipv6_belong_addr_obj(PCMHI_OBJECT obj, unsigned char addr[16])
{
}
/**
* @brief
*
* @return
* @date 2019/08/07
*/
static int obj_proc_init(void)
{
return server_proc_init();
}
/**
* @brief
*
* @return
* @date 2019/08/07
*/
static int obj_proc_uninit(void)
{
return server_proc_uninit();
}
/**
* @brief
*
* @return
* @date 2019/08/07
*/
const char *obj_version(void)
{
return VERSION;
}
/**
* @brief
*
* @return
* @date 2019/08/07
*/
PCMHI_OBJECT new_object(void)
{
PCMHI_OBJECT obj = (PCMHI_OBJECT)kmalloc(sizeof(CMHI_OBJECT), GFP_KERNEL);
if(obj == NULL) {
printk(KERN_ERR "Malloc CMHI_OBJECT Error\n");
} else {
memset(obj, 0, sizeof(CMHI_OBJECT));
rwlock_init(&obj->lock);
atomic_set(&obj->ref_count, 0);
}
return obj;
}
/**
* @brief
*
* @param pObj
*
* @return
* @date 2019/08/07
*/
void free_object(PCMHI_OBJECT pObj)
{
if(pObj) {
kfree(pObj);
}
}
/**
* @brief
*
* @return
* @date 2019/08/07
*/
void object_init(void)
{
PCMHI_OBJECT pObj = create_server_object("list1");
if(!pObj) {
printk(KERN_ERR "%s(%d): Create Object Error\n", __FUNCTION__, __LINE__);
return;
}
HASH_ADD_STR(g_obj_data, name, pObj);
if(add_server_obj_data(pObj, 10000, 20000, IPPROTO_IP) != 0) {
printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__);
return;
}
if(add_server_obj_data(pObj, 80, 80, IPPROTO_TCP) != 0) {
printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__);
return;
}
if(add_server_obj_data(pObj, 443, 443, IPPROTO_UDP) != 0) {
printk(KERN_ERR "%s(%d): Add Server Object error\n", __FUNCTION__, __LINE__);
return;
}
}
/**
* @brief
*
* @return
* @date 2019/08/07
*/
void object_uninit(void)
{
PCMHI_OBJECT obj, tmp;
HASH_ITER(hh, g_obj_data, obj, tmp) {
HASH_DEL(g_obj_data, obj);
cleanup_server_object(obj);
}
}
/**
* @brief
*
* @param inode
* @param filp
*
* @return
* @date 2019/08/07
*/
static int obj_open(struct inode *inode, struct file *filp)
{
// 增加引用计数
atomic_inc(&g_obj_device->ref_count);
return 0;
}
/**
* @brief
*
* @param inode
* @param filp
*
* @return
* @date 2019/08/07
*/
static int obj_release(struct inode *inode, struct file *filp)
{
// 减少引用计数
atomic_dec(&g_obj_device->ref_count);
return 0;
}
/**
* @brief
*
* @param fd
* @param vma
*
* @return
* @date 2019/08/07
*/
int obj_mmap(struct file *fd, struct vm_area_struct *vma)
{
// 重新映射内存页表
int ret = remap_pfn_range(vma, vma->vm_start,
virt_to_phys(g_obj_device->mem_buf) >> PAGE_SHIFT,
g_obj_device->mem_size,
PAGE_SHARED);
return ret;
}
/**
* @var obj_fops
* @brief
*/
static struct file_operations obj_fops = {
.open = obj_open,
.release = obj_release,
.mmap = obj_mmap,
};
/**
* @brief
*
* @return
* @date 2019/08/07
*/
static int object_module_init(void)
{
struct page *p = NULL;
dev_t dev = 0;
printk(KERN_INFO "Hello ISG objects manager version: %s\n", VERSION);
// 自动分配设备版本号
if(alloc_chrdev_region(&dev, 0, 1, OBJ_DEV_NAME) != 0) {
printk(KERN_ERR "Alloc driver dev id error\n");
return -ENODEV;
}
// 分配驱动程序结构内存
g_obj_device = (POBJECT_DRV)kmalloc(sizeof(OBJECT_DRV), GFP_KERNEL);
if(g_obj_device == NULL) {
printk(KERN_ERR "Create isg objects error\n");
return -ENOMEM;
}
memset(g_obj_device, 0, sizeof(OBJECT_DRV));
g_obj_device->dev_major = MAJOR(dev); // 保存驱动版本号
atomic_set(&g_obj_device->ref_count, 0);
// 初始化共享内存
g_obj_device->mem_size = PAGE_ALIGN(SHM_MEM_SIZE);
g_obj_device->mem_buf = (unsigned char *)__get_free_pages(GFP_KERNEL, get_order(g_obj_device->mem_size));
if(g_obj_device->mem_buf == NULL) {
printk(KERN_ERR "Malloc %d pages error\n", get_order(g_obj_device->mem_size));
kfree(g_obj_device);
return -ENOMEM;
}
for(p = virt_to_page(g_obj_device->mem_buf);
p < virt_to_page(g_obj_device->mem_buf + g_obj_device->mem_size);
p++) {
SetPageReserved(virt_to_page(p));
}
memset(g_obj_device->mem_buf, 0, g_obj_device->mem_size);
// 注册字符设备
register_chrdev(g_obj_device->dev_major, OBJ_DEV_NAME, &obj_fops);
// 创建字符设备类
g_obj_device->dev_class = class_create(THIS_MODULE, "obj");
// 创建字符设备节点
device_create(g_obj_device->dev_class, NULL, MKDEV(g_obj_device->dev_major, 0),
NULL, "isg_objs/dev%d", 0);
// 初始化 proc 接口
obj_proc_init();
object_init();
return 0;
}
module_init(object_module_init);
/**
* @brief
*
* @return
* @date 2019/08/07
*/
static void __exit object_module_exit(void)
{
struct page *p = NULL;
printk(KERN_INFO "Bye ISG objects manager version: %s\n", VERSION);
obj_proc_uninit();
object_uninit();
if(atomic_read(&g_obj_device->ref_count) != 0) {
printk(KERN_ERR "Device used, please close it first.\n");
return;
}
if(g_obj_device->mem_buf) {
for(p = virt_to_page(g_obj_device->mem_buf);
p < virt_to_page(g_obj_device->mem_buf + g_obj_device->mem_size);
p++) {
ClearPageReserved(virt_to_page(g_obj_device->mem_buf));
}
free_pages((unsigned long)g_obj_device->mem_buf, get_order(g_obj_device->mem_size));
}
device_destroy(g_obj_device->dev_class, MKDEV(g_obj_device->dev_major, 0));
class_destroy(g_obj_device->dev_class);
unregister_chrdev(g_obj_device->dev_major, OBJ_DEV_NAME);
kfree(g_obj_device);
}
module_exit(object_module_exit);
MODULE_LICENSE("Dual BSD/GPL");
#endif // __KERNEL__