From 60b1037916c6e6723f401735a0bd1f55696fddef Mon Sep 17 00:00:00 2001 From: wuhuanzheng Date: Fri, 6 Sep 2019 16:41:04 +0800 Subject: [PATCH] OCT commit --- Platform/build/module.rpdb.Makefile | 6 +- Platform/common/rpdb/dpi_trie_cache.h | 3 +- Platform/modules/rpdb/dpi_trie_cache.c | 109 ++-- Platform/user/rpdb/rpdb.c | 690 ++++++++++++++++++------- 4 files changed, 565 insertions(+), 243 deletions(-) diff --git a/Platform/build/module.rpdb.Makefile b/Platform/build/module.rpdb.Makefile index 8ece21501..e2394d032 100755 --- a/Platform/build/module.rpdb.Makefile +++ b/Platform/build/module.rpdb.Makefile @@ -22,20 +22,20 @@ DEBUG = TRUE PLAT_LINUX ?= TRUE PLAT_ARM64 ?= TRUE -VPATH = ../modules +VPATH = ../modules/rpdb # source code # set the source file, don't used .o because of ... -COMMON_SRCS = ./rpdb/dpi_trie_cache.c +COMMON_SRCS = dpi_trie_cache.c dpi_trie_cache_mod.c # MRS Board Source Files PLAT_LINUX_SRCS = $(COMMON_SRCS) PLAT_ARM64_SRCS = $(COMMON_SRCS) # gcc CFLAGS -PLAT_ARM64_CFLAGS := +PLAT_ARM64_CFLAGS := -I../common/rpdb/ -I../../Common PLAT_LINUX_CFLAGS := $(PLAT_ARM64_CFLAGS) # this line must be at below of thus, because of... diff --git a/Platform/common/rpdb/dpi_trie_cache.h b/Platform/common/rpdb/dpi_trie_cache.h index ce762fe8a..0a162cdac 100644 --- a/Platform/common/rpdb/dpi_trie_cache.h +++ b/Platform/common/rpdb/dpi_trie_cache.h @@ -15,6 +15,7 @@ struct dpi_cache_node { __u16 proto; __u16 port; __u32 appid; + bool ipv4; uint64_t uptime; }; @@ -24,4 +25,4 @@ struct dpi_cache_node { @outp: ɹtrueʧܣfalse */ bool dpi_cache_node_add(struct dpi_cache_node node); -#endif \ No newline at end of file +#endif diff --git a/Platform/modules/rpdb/dpi_trie_cache.c b/Platform/modules/rpdb/dpi_trie_cache.c index 643d61131..6ae7d340f 100644 --- a/Platform/modules/rpdb/dpi_trie_cache.c +++ b/Platform/modules/rpdb/dpi_trie_cache.c @@ -7,31 +7,18 @@ #include #include #include +#include +#include "dpi_trie_cache.h" /* - * 三元组超时时间设置为120s + * 三元组超时时间设置为300s */ -int dpi_cache_node_timeout = 120; +int dpi_cache_node_timeout = 300; -/* - * 三元组数据结构 -*/ -struct dpi_cache_node { - struct list_head list; - - union { - struct in6_addr ip6; - struct in_addr ip4; - - }ip; - - __u16 proto; - __u16 port; - __u32 appid; - uint64_t uptime; -}; +#define IPV4_ADDR (1) +#define IPV6_ADDR (2) /* * 初始化cache链表 @@ -43,7 +30,7 @@ typedef struct pkt_info{ unsigned int srcip; unsigned short sport; unsigned int dstip; - unsigned short dport; + unsigned short port; unsigned short proto; }pkt_info_t; @@ -97,7 +84,6 @@ void dpi_cache_list_init(void) return; } - /* * 三元组hash值计算 */ @@ -107,11 +93,11 @@ int dpi_cache_node_hash(struct dpi_cache_node node) int dip = 0; pkt_info_t info; - info.dport = node.port; + info.port = node.port; info.sport = 0; info.srcip = 0; info.proto = node.proto; - if (node.ip.ip4.s_addr !=0 ) { + if (node.ipv4 == true ) { info.dstip = node.ip.ip4.s_addr; } else { for (i = 0; i < 4; ++i) { @@ -138,7 +124,7 @@ bool dpi_cache_node_compare(struct dpi_cache_node src,struct dpi_cache_node dst, return false; } - if(src.ip.ip4.s_addr != 0){ + if(src.ipv4 == true){ if(src.ip.ip4.s_addr != dst.ip.ip4.s_addr){ return false; } @@ -152,7 +138,8 @@ bool dpi_cache_node_compare(struct dpi_cache_node src,struct dpi_cache_node dst, } if (update_appid){ - dst.appid = src.appid; + if(src.appid != -1) + dst.appid = src.appid; dst.uptime = get_jiffies_64(); } @@ -186,7 +173,7 @@ bool dpi_cache_node_add(struct dpi_cache_node node) { int hash = 0; struct dpi_cache_node *pNode =NULL; - + if (dpi_cache_node_search(node,true)) { return true; } @@ -197,8 +184,9 @@ bool dpi_cache_node_add(struct dpi_cache_node node) } hash = dpi_cache_node_hash(node); + memcpy((char*)pNode,(char*)&node,sizeof(node)); pNode->uptime = get_jiffies_64(); - pNode->appid = node.appid; + //printk("%s,%d,%d,%d,%d\n",__FUNCTION__,__LINE__,pNode->proto,pNode->port,pNode->ipv4); list_add_tail(&pNode->list,&dpi_cache_head[hash]); return true; } @@ -209,40 +197,34 @@ bool dpi_cache_node_add(struct dpi_cache_node node) */ void dpi_cache_list_release(void) { - struct list_head * pList = NULL; - struct dpi_cache_node *pNode = NULL; int i = 0; - for (i = 0; i < TRIPLE_CAHCE_HASH_SIZE; i++){ - list_for_each(pList,&dpi_cache_head[i]){ - pNode = list_entry(pList,struct dpi_cache_node,list); - if(pNode){ - list_del(&pNode->list); - } - + while(!list_empty(&dpi_cache_head[i])) + { + list_del(dpi_cache_head[i].next); } } } - /* *定时器超时,删除超时的节点 */ void dpi_cache_node_timeout_func(void) { struct list_head * pList = NULL; + struct list_head * n = NULL; struct dpi_cache_node *pNode = NULL; + int i = 0; for (i = 0; i < TRIPLE_CAHCE_HASH_SIZE; i++){ - list_for_each(pList,&dpi_cache_head[i]){ + list_for_each_safe(pList,(n),&dpi_cache_head[i]){ pNode = list_entry(pList,struct dpi_cache_node,list); + //printk("%s,%d,%d\n",__FUNCTION__,__LINE__,pNode->port); if(pNode&& (get_jiffies_64() - pNode->uptime >= dpi_cache_node_timeout)){ list_del(&pNode->list); } - - } } } @@ -251,12 +233,10 @@ void dpi_cache_node_timeout_func(void) * 定时器操作 */ struct timer_list gTimer; - void dpi_cache_timer_handler(unsigned long data) { - printk(KERN_INFO"timer pending:%d\n", timer_pending(&gTimer)); + //printk(KERN_INFO"timer pending:%d\n", timer_pending(&gTimer)); dpi_cache_node_timeout_func(); mod_timer(&gTimer, jiffies+msecs_to_jiffies(dpi_cache_node_timeout*1000)); - } int dpi_cache_timer_init(void) { @@ -269,28 +249,55 @@ int dpi_cache_timer_init(void) { printk(KERN_INFO"timer pending:%d\n", timer_pending(&gTimer)); return 0; } - +void test_func(void) +{ + struct dpi_cache_node node1,node2,node3; + node1.proto = 17; + in4_pton("192.168.1.1", strlen("192.168.1.1"), (u8*)&node1.ip.ip4, -1, NULL); + node1.port = 200; + node1.ipv4 = true; + dpi_cache_node_add(node1); + + node2.proto = 17; + in4_pton("192.168.2.1", strlen("192.168.1.1"), (u8*)&node2.ip.ip4, -1, NULL); + node2.port = 200; + node2.ipv4 = true; + dpi_cache_node_add(node2); + + node3.proto = 17; + in6_pton("2a01:198:603:0:396e:4789:8e99:890f", strlen("2a01:198:603:0:396e:4789:8e99:890f"), (u8*)&node3.ip.ip6, -1, NULL); + node3.port = 200; + node3.ipv4 = false; + dpi_cache_node_add(node3); + + return; +} + void dpi_cache_timer_exit(void) { printk(KERN_INFO"%s jiffies:%ld\n", __func__, jiffies); del_timer(&gTimer); } -int dpi_cahce_module_init(void) +static int __init dpi_cahce_module_init(void) { - dpi_cache_timer_init(); dpi_cache_list_init(); - return 1; + dpi_cache_timer_init(); + + //test_func(); + return 0; } -int dpi_cache_module_exit(void) +static void __exit dpi_cache_module_exit(void) { dpi_cache_timer_exit(); dpi_cache_list_release(); - return 1; } + + module_init(dpi_cahce_module_init); -module_exit(dpi_cache_timer_exit); +module_exit(dpi_cache_module_exit); MODULE_LICENSE("GPL"); - +MODULE_DESCRIPTION("rpdb process module"); +MODULE_AUTHOR("wuhuanzheng"); diff --git a/Platform/user/rpdb/rpdb.c b/Platform/user/rpdb/rpdb.c index 7230b1c03..fae8483cc 100644 --- a/Platform/user/rpdb/rpdb.c +++ b/Platform/user/rpdb/rpdb.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -5,25 +7,28 @@ #include #include #include - #include "list.h" - - +#include "rpdb.h" +#if 0 +rm -fr /tmp/nf_conntrack* +cp -fr /proc/net/nf_conntrack /tmp/nf_conntrack +cat /tmp/nf_conntrack |awk -F ' ' '{print $4}'|xargs -I {} echo {} >> /tmp/nf_conntrack_proto; +cat /tmp/nf_conntrack |awk -F ' ' '{print $7}' | awk -F '=' '{print $2}' |xargs -I {} echo {} >> /tmp/nf_conntrack_dip; +cat /tmp/nf_conntrack |awk -F ' ' '{print $9}' | awk -F '=' '{print $2}' |xargs -I {} echo {} >> /tmp/nf_conntrack_dport; +paste /tmp/nf_conntrack_proto /tmp/nf_conntrack_dip /tmp/nf_conntrack_dport | xargs -I {} echo {} >>/tmp/dpi_triple1; +sort -k2n /tmp/dpi_triple1 | uniq > /tmp/dpi_triple +#endif struct rpdb_mark { struct list_head list; union { struct in6_addr ip6; struct in_addr ip4; - }ip; - + bool ipv4; int mark; }; - - - char rt_table[11][128]= { "# reserved values", "#", @@ -40,7 +45,7 @@ char rt_table[11][128]= { #define RT_TABLES_PATH ("/etc/iproute2/rt_tables") #define IPV4_PATTERN "^([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5]).([0-9]|[1-9][0-9]|1[0-9]{1,2}|2[0-4][0-9]|25[0-5])$" -#define IPV6_PATTERN "^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$" +#define IPV6_PATTERN "^\s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?\s*$" #define RPDP_MARK_HASH_DEPTH (1024) static int gRpdbMark = 0; @@ -48,49 +53,54 @@ static int gRpdbMark = 0; /* * mark hash list,save mark */ -struct list_head gRpdbMarkList[RPDP_MARK_HASH_DEPTH] = {0}; +static struct list_head gRpdbMarkList[RPDP_MARK_HASH_DEPTH] = {0}; +static int gRpdbTableIndex = 1; /* 1 - 252 */ +static pthread_mutex_t mutex; +#define IPV4_ADDR (1) +#define IPV6_ADDR (2) +struct rpdb_stat{ + char table_name[256]; + int index; +}; +struct rpdb_stat rpdbstat[256] = {0}; /* popen */ - -void -print_result(FILE *fp) +void print_result(FILE *fp) { - char buf[100]; - - if(!fp) { - return; - } - printf("\n>>>\n"); - memset(buf, 0, sizeof(buf)); - fgets(buf, sizeof(buf) - 1, fp) ; - - - printf("%s", buf); - - - printf("\n<<<\n"); + char buf[100]; + + if(!fp) + { + return; + } + + memset(buf, 0, sizeof(buf)); + fgets(buf, sizeof(buf) - 1, fp); + printf("%s", buf); + return; } int rpdb_popen(char *cmd) { FILE *fp = NULL; + fp = popen(cmd, "r"); + if(!fp) + { + perror("popen"); + exit(EXIT_FAILURE); + } + print_result(fp); + pclose(fp); + return 0; +} - - fp = NULL; - fp = popen(cmd, "r"); - if(!fp) - { - perror("popen"); - exit(EXIT_FAILURE); - } - print_result(fp); - pclose(fp); - sleep(1); - return 0; +int rpdb_system(char *cmd) +{ + return system(cmd); } /* @@ -100,8 +110,11 @@ bool rpdb_init_route() { FILE *fp = NULL; int i = 0; - - system("echo > /etc/iproute2/rt_tables"); + char cmd[256] = {0}; + /* + 初始化多路由表 + */ + rpdb_popen("echo > /etc/iproute2/rt_tables"); fp = fopen(RT_TABLES_PATH,"w"); if (fp) { @@ -117,6 +130,20 @@ bool rpdb_init_route() fclose(fp); + /* + 初始化策略路由规则,ip rule + */ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"%s","ip rule|grep fwmark|awk -F ' ' '{print $7}'|xargs -I {} ip rule del table {}"); + rpdb_system(cmd); + + + /* + flush 路由 + */ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"%s","ip route flush cache"); + rpdb_system(cmd); /* 初始化链表 @@ -126,136 +153,160 @@ bool rpdb_init_route() INIT_LIST_HEAD(&gRpdbMarkList[i]); } + + memset((char*)&rpdbstat,0,256*sizeof(struct rpdb_stat)); + + pthread_mutex_init(&mutex, NULL); + return true; } - -static int gRpdbTableIndex = 1; /* 1 - 252 */ -#define RPDB_TABLE_ADD (0) -#define RPDB_TABLE_DEL (1) -bool rpdb_add_delete_table(const char* gateway,const char *tbl_name,int op) +int rpdb_calc(char *name,int flag) { - char table_name[128] = {0}; - char line_cnt[1024] = {0}; - FILE *fp = NULL; - FILE *fp_tmp = NULL; - bool ret = false; int i = 0; - int cn_num = 0; - if (tbl_name == NULL) - { - memset(table_name,0,sizeof(table_name)); - sprintf(table_name,"table_%s",gateway); - } - else - { - if (strlen(tbl_name) < 1) /* 检查name的合法性*/ - { - memset(table_name,0,sizeof(table_name)); - sprintf(table_name,"%s",tbl_name); - } - else - { - return false; - } - } - - fp = fopen(RT_TABLES_PATH,"ra+"); - if (NULL == fp) - { - return false; - } - else - { - while(!feof(fp)) /* 遍历文件每一行,查找 路由表是否存在 */ - { - memset(line_cnt,0,1024); - fgets(line_cnt,1024,fp); - if(strstr(line_cnt,table_name)) - { - if (op == RPDB_TABLE_ADD) - { - fclose(fp); - return true; - } - } - } - } - + int j = 0; + int flag1 = 0; /* - 向文件最后一行添加 路由表项 + 路由表存在,只修改路由表对应的策略数 */ - if (op == RPDB_TABLE_ADD) + for (i = 0; i < 256; i++) { - if (gRpdbTableIndex > 252) + if (strcmp(name,rpdbstat[i].table_name) == 0) { - return false; - } - - memset(line_cnt,0,1024); - sprintf(line_cnt,"%d %s",gRpdbTableIndex,table_name); - printf("RPDB_TABLE_ADD:%s\n",line_cnt); - fprintf(fp,"%s\n",line_cnt); - fclose(fp); - gRpdbTableIndex++; - return true; - } - - if (op == RPDB_TABLE_DEL) - { - fp = fopen(RT_TABLES_PATH,"r+"); - if (NULL == fp) - { - return false; - } - else - { - fp_tmp = fopen("/tmp/rt_tables","w"); - if (fp_tmp == NULL) return false; - while(!feof(fp)) /* 遍历文件每一行,查找 路由表是否存在 */ + if (flag == RPDB_ROUTE_ADD) { - memset(line_cnt,0,1024); - fgets(line_cnt,1024,fp); - if(!strstr(line_cnt,table_name)) + rpdbstat[i].index++; + } + else if(flag == RPDB_ROUTE_DEL) + { + rpdbstat[i].index--; + } + if(rpdbstat[i].index == 0) + memset(rpdbstat[i].table_name,0,sizeof(rpdbstat[i].table_name)); + flag1 = 1; + break; + } + } + + /* + 路由表不存在,添加路由表name,并赋值策略数 + */ + if (flag1 == 0) + { + for (j = 0; j < 256; j++) + { + + if (flag == RPDB_ROUTE_ADD) + { + if(!rpdbstat[j].table_name[0]) { - fprintf(fp_tmp,"%s",line_cnt); - } + strcpy(rpdbstat[j].table_name,name); + rpdbstat[j].index = 1; + //printf("%s,%d,index:%d,%s\n",__FUNCTION__,__LINE__,rpdbstat[j].index,rpdbstat[j].table_name); + return rpdbstat[j].index; + } } - - fclose(fp); - fclose(fp_tmp); - system("cp -fr /tmp/rt_tables /etc/iproute2/rt_tables"); } - } - return true; + } +int rpdb_get_index(char* name) +{ + int i = 0; + for (i = 0; i < 256; i++) + { + if (strcmp(name,rpdbstat[i].table_name) == 0) + { + return rpdbstat[i].index; + } + } + return 0; +} + +#if 0 +inet_pton(AF_INET6, "2a01:198:603:0:396e:4789:8e99:890f", &ip); +printf("0x%x%x%x%x\n", htonl(ip.s6_addr32[0]),htonl(ip.s6_addr32[1]),htonl(ip.s6_addr32[2]),htonl(ip.s6_addr32[3])); + +inet_pton(AF_INET6, "2a01:198:603:0::", &ip); +printf("0x%x%x%x%x\n", htonl(ip.s6_addr32[0]),htonl(ip.s6_addr32[1]),htonl(ip.s6_addr32[2]),htonl(ip.s6_addr32[3])); +#endif +int is_valid_ipv4(char *ipv4) +{ + struct in_addr addr; + if(ipv4 == NULL) + return 0; + if(inet_pton(AF_INET, ipv4, (void *)&addr) == 1) + { + return 1; + } + return 0; +} + +int is_valid_ipv6(char *ipv6) +{ + struct in6_addr addr6; + if(ipv6 == NULL) + return 0; + if(inet_pton(AF_INET6, ipv6, (void *)&addr6) == 1) + { + return 1; + } + return 0; +} + + /* * 判断ip地址是否合法 */ - +#if 0 int rpdb_ipaddr_match(char *ip_addr,int flag) { regex_t reg; regmatch_t match[1]; int retval = 0; - if (flag == 1) + if (flag == IPV4_ADDR) { retval = regcomp(®, IPV4_PATTERN, REG_EXTENDED | REG_NEWLINE); } - else + else if(flag == IPV6_ADDR) { retval = regcomp(®, IPV6_PATTERN, REG_EXTENDED | REG_NEWLINE); } + else + { + return -1; + } retval = regexec(®,ip_addr, sizeof match / sizeof match[0], match, 0); printf("%s is %s\n", ip_addr, retval == 0 ? "legal" : "illegal"); regfree(®); - return retval; + if (retval == 0) + return 1; + else + return 0; +} +#endif + +/* + 1 - 成功 + 0 - 失败 +*/ + +int rpdb_ipaddr_match(char *ip_addr,int flag) +{ + if (flag == IPV4_ADDR) + { + return is_valid_ipv4(ip_addr); + } + else if (flag == IPV6_ADDR) + { + return is_valid_ipv6(ip_addr); + } + return 0; } @@ -264,7 +315,7 @@ int rpdb_ip_hash(struct rpdb_mark node) int ip_value = 0; int hash = 0; int i = 0; - if (node.ip.ip4.s_addr !=0 ) + if (node.ip.ip4.s_addr != 0 ) { ip_value = node.ip.ip4.s_addr; } @@ -287,14 +338,28 @@ int rpdb_ip_hash(struct rpdb_mark node) bool rpdb_mark_node_compare(struct rpdb_mark node1,struct rpdb_mark node2) { - if (node1.ip.ip4.s_addr == node2.ip.ip4.s_addr) + int i = 0; + if (node1.ipv4 == true) { - return true; + if (node1.ip.ip4.s_addr == node2.ip.ip4.s_addr) + { + return true; + } + else + { + return false; + } } else { - return false; + for (i = 0; i < 4; i++){ + if (node1.ip.ip6.s6_addr32[i] != node2.ip.ip6.s6_addr32[i]){ + return false; + } + } } + + return true; } @@ -309,9 +374,9 @@ struct rpdb_mark * rpdb_mark_search(struct rpdb_mark node) list_for_each(pList,&gRpdbMarkList[hash]) { pNode = list_entry(pList,struct rpdb_mark,list); - printf("%s,%d,%d,%d\n",__FUNCTION__,__LINE__,pNode->ip.ip4.s_addr,pNode->mark); + //printf("%s,%d,%d,%d\n",__FUNCTION__,__LINE__,pNode->ip.ip4.s_addr,pNode->mark); if (rpdb_mark_node_compare(node,*pNode)){ - printf("%s,%d,mark = %d\n",__FUNCTION__,__LINE__,pNode->mark); + //printf("%s,%d,mark = %d\n",__FUNCTION__,__LINE__,pNode->mark); return pNode; } } @@ -344,7 +409,7 @@ int rpdb_mark_hash_add(struct rpdb_mark node) node.mark = ++gRpdbMark; memcpy((char*)pNode,(char*)&node,sizeof(struct rpdb_mark)); - printf("%s,%d,%d,%d\n",__FUNCTION__,__LINE__,pNode->ip.ip4.s_addr,pNode->mark); + //printf("%s,%d,%d,%d\n",__FUNCTION__,__LINE__,pNode->ip.ip4.s_addr,pNode->mark); /* 节点添加到链尾部 */ @@ -357,7 +422,7 @@ int rpdb_mark_hash_add(struct rpdb_mark node) /* * 根据下一跳地址生成mark */ -int rpdb_gen_mark(const char* gateway) +int rpdb_gen_mark(char* gateway) { in_addr_t addr; if (NULL == gateway) @@ -367,19 +432,140 @@ int rpdb_gen_mark(const char* gateway) addr = inet_addr(gateway); struct rpdb_mark node; - node.ip.ip4.s_addr = addr; + node.ipv4 = false; + if(rpdb_ipaddr_match(gateway,IPV4_ADDR) == 1) + { + node.ip.ip4.s_addr = addr; + node.ipv4 = true; + } + else if(rpdb_ipaddr_match(gateway,IPV6_ADDR) == 1) + { + inet_pton(AF_INET6, gateway, (void *)&node.ip.ip6); + node.ipv4 = false; + } + else + { + return -1; + } + return rpdb_mark_hash_add(node); } -/* - * 路由添加接口 -*/ -bool rpdb_add_route(const char* gateway,const char *tbl_name) +int rpdb_add_route(char *gateway,char *table_name) { char cmd[256] = {0}; - int status = 0; - char table_name[128] = {0}; + char cmd1[256] = {0}; + int ret = 0; int mark = 0; + + if(rpdb_ipaddr_match(gateway,IPV6_ADDR) == 1) + { + sprintf(cmd,"ip -6 route add default via %s table %s",gateway,table_name); + sprintf(cmd1,"ip -6 route del default via %s table %s",gateway,table_name); + } + else + { + sprintf(cmd,"ip route add default via %s table %s",gateway,table_name); + sprintf(cmd1,"ip route del default via %s table %s",gateway,table_name); + } + + /*先删除之前可能存在的路由,否则添加路由可能会报错*/ + rpdb_system(cmd1); + + /*添加路由*/ + ret = rpdb_system(cmd); + printf("%s,%d,ret=%d,%s\n",__FUNCTION__,__LINE__,ret,cmd); + if(ret != 0) + { + return -1; + } + mark = rpdb_gen_mark(gateway); + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"ip rule add fwmark %d table %s",mark,table_name); + ret = rpdb_system(cmd); + if (ret != 0) + return -1; + /* + 刷新路由 + */ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"%s","ip route flush cache"); + ret = rpdb_system(cmd); + if (ret != 0) + return -1; + + printf("%s,%d,ret=%d,%s\n",__FUNCTION__,__LINE__,ret,cmd); + return 0; +} + + +int rpdb_del_route(char *gateway,char *table_name) +{ + char cmd[256] = {0}; + int ret = 0; + if (strstr(":",gateway)) + { + sprintf(cmd,"ip -6 route del default via %s table %s",gateway,table_name); + } + else + { + sprintf(cmd,"ip route del default via %s table %s",gateway,table_name); + } + + + ret = rpdb_system(cmd); + if (ret != 0) + return -1; + + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"ip rule del table %s",table_name); + ret = rpdb_system(cmd); + if (ret != 0) + return -1; + + /* + 刷新路由 + */ + memset(cmd,0,sizeof(cmd)); + sprintf(cmd,"%s","ip route flush cache"); + ret = rpdb_system(cmd); + if (ret != 0) + return -1; + + printf("%s,%d,ret=%d,%s\n",__FUNCTION__,__LINE__,ret,cmd); + return 0; +} + +/* + 返回nexthop对应的策略数 +*/ +int rpdb_add_delete_table(char *gateway,char* tbl_name,int op) +{ + char line_cnt[1024] = {0}; + FILE *fp = NULL; + FILE *fp_tmp = NULL; + bool ret = false; + int i = 0; + int cn_num = 0; + int index = 0; + int mark = 0; + char table_name[256] = {0}; + int flag = 0; + + /* + 判断ip地址是否合法 + */ + if((rpdb_ipaddr_match(gateway,IPV6_ADDR) == 0)&& + (rpdb_ipaddr_match(gateway,IPV4_ADDR) == 0)) + { + printf("ipv addr invalid:%s\n",gateway); + return -1; + } + + + /* + 生成路由表名字 + */ if (tbl_name == NULL) { memset(table_name,0,sizeof(table_name)); @@ -387,44 +573,156 @@ bool rpdb_add_route(const char* gateway,const char *tbl_name) } else { - if (strlen(tbl_name) < 1) /* 检查name的合法性*/ + if (strlen(tbl_name) > 1) /* 检查name的合法性*/ { memset(table_name,0,sizeof(table_name)); sprintf(table_name,"%s",tbl_name); } else { - return false; + return -1; + } + } + printf("tbl_name:%s\n",table_name); + mark = rpdb_gen_mark(gateway); + + + index = rpdb_get_index(table_name); + printf("%s,%d,index=%d\n",__FUNCTION__,__LINE__,index); + fp = fopen(RT_TABLES_PATH,"ra+"); + if (NULL == fp) + { + return -1; + } + + + /* + 向文件最后一行添加 路由表项 + */ + if (op == RPDB_ROUTE_ADD) + { + while(!feof(fp)) /* 遍历文件每一行,查找 路由表是否存在 */ + { + memset(line_cnt,0,1024); + fgets(line_cnt,1024,fp); + if(strstr(line_cnt,table_name)) + { + rpdb_calc(table_name,RPDB_ROUTE_ADD); + fclose(fp); + return mark; + } + } + + if (gRpdbTableIndex > 252) + { + return -1; + } + + memset(line_cnt,0,1024); + sprintf(line_cnt,"%d %s",gRpdbTableIndex,table_name); + + fprintf(fp,"%s\n",line_cnt); + fclose(fp); + gRpdbTableIndex++; + + if(0 == rpdb_add_route(gateway,table_name)) + { + rpdb_calc(table_name,RPDB_ROUTE_ADD); + return mark; + } + else + { + /* + 删除路由表 + */ + fp = fopen(RT_TABLES_PATH,"ra+"); + if(NULL == fp) return -1; + fp_tmp = fopen("/tmp/rt_tables","w"); + if (fp_tmp == NULL) return -1; + while(!feof(fp)) /* 遍历文件每一行,查找 路由表是否存在 */ + { + memset(line_cnt,0,1024); + fgets(line_cnt,1024,fp); + if(!strstr(line_cnt,table_name)) + { + fprintf(fp_tmp,"%s",line_cnt); + } + } + + fclose(fp); + fclose(fp_tmp); + system("cp -fr /tmp/rt_tables /etc/iproute2/rt_tables"); + return -1; } } - if (rpdb_add_delete_table(gateway,tbl_name,RPDB_TABLE_ADD) == false) + if (op == RPDB_ROUTE_DEL) { - return false; - } - - if (strstr(":",gateway)) - { - sprintf(cmd,"ip -6 route add default via %s table %s",gateway,table_name); - } - else - { - sprintf(cmd,"ip route add default via %s table %s",gateway,table_name); - } + if(index < 1) + { + return -1; + } + + if(index > 1) + { + rpdb_calc(table_name,RPDB_ROUTE_DEL); + return mark; + } + + fp = fopen(RT_TABLES_PATH,"r+"); + if (NULL == fp) + { + return -1; + } + else + { + fp_tmp = fopen("/tmp/rt_tables","w"); + if (fp_tmp == NULL) return -1; + while(!feof(fp)) /* 遍历文件每一行,查找 路由表是否存在 */ + { + memset(line_cnt,0,1024); + fgets(line_cnt,1024,fp); + if(!strstr(line_cnt,table_name)) + { + fprintf(fp_tmp,"%s",line_cnt); + } + else + { + flag = 1; + /* + 删除路由表之前先把路由删掉 + */ + if(0 == rpdb_del_route(gateway,table_name)) + { + rpdb_calc(table_name,RPDB_ROUTE_DEL); + } + } + } - printf("%s\n",cmd); - rpdb_popen(cmd); + fclose(fp); + fclose(fp_tmp); + system("cp -fr /tmp/rt_tables /etc/iproute2/rt_tables"); + if (flag == 1) + { + return mark; + } + else + { + return -1; + } + } + } +} +/* + * 路由添加接口 +*/ - mark = rpdb_gen_mark(gateway); - memset(cmd,0,sizeof(cmd)); - sprintf(cmd,"ip rule add fwmark %d table %s",mark,table_name); - printf("%s\n",cmd); - rpdb_popen(cmd); - - return 0; +int rpdb_add_del_route(char* gateway,char *tbl_name,int opt) +{ + return rpdb_add_delete_table(gateway,tbl_name,opt); } - +#if 0 int main() { //ipaddr_match("192.168.1.1",1); @@ -432,20 +730,12 @@ int main() //ipaddr_match("192.168.1.300",1); //ipaddr_match("2000:0:0:0:0:0:0:1 ",2); - //ipaddr_match("fe80:0000:0000:0000:0204:61ff:fe9d:ffffff15",2); + rpdb_ipaddr_match("fe80:0000:0000:0000:0204:61ff:fe9d:f5",2); struct rpdb_mark mark_value; struct rpdb_mark mark_value1; in_addr_t addr; rpdb_init_route(); - rpdb_add_delete_table("1.1.2.1",NULL,RPDB_TABLE_ADD); - rpdb_add_delete_table("1.1.2.1",NULL,RPDB_TABLE_ADD); - rpdb_add_delete_table("1.2.2.1",NULL,RPDB_TABLE_ADD); - rpdb_add_delete_table("2.1.2.1",NULL,RPDB_TABLE_ADD); - - rpdb_add_delete_table("2.1.2.1",NULL,RPDB_TABLE_DEL); - //rpdb_add_delete_table("2.1.2.1",NULL,RPDB_TABLE_DEL); - //rpdb_add_delete_table("1.1.2.1",NULL,RPDB_TABLE_DEL); - addr = inet_addr("2006.6.6.6"); + addr = inet_addr("table_2006.6.6.6"); mark_value.ip.ip4.s_addr = addr; rpdb_mark_hash_add(mark_value); rpdb_mark_hash_add(mark_value); @@ -458,11 +748,35 @@ int main() rpdb_mark_hash_add(mark_value1); - - rpdb_add_route("1.2.3.3",NULL); - rpdb_add_route("2.2.4.3",NULL); - rpdb_add_route("3.2.4.3",NULL); - rpdb_add_route("4.2.4.3",NULL); + /* + 192.168.221.2 为有效的下一跳网关地址,添加成功 + */ + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2",NULL,RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2","test_table",RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2",NULL,RPDB_ROUTE_DEL)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2","test_table",RPDB_ROUTE_DEL)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2",NULL,RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2","test_table",RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2",NULL,RPDB_ROUTE_DEL)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2","test_table",RPDB_ROUTE_DEL)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2",NULL,RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2","test_table",RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2",NULL,RPDB_ROUTE_DEL)); + printf("~~~~~~%d\n",rpdb_add_del_route("192.168.221.2","test_table",RPDB_ROUTE_DEL)); + /* + 错误的网关地址 + */ + printf("~~~~~~%d\n",rpdb_add_del_route("172.168.221.2",NULL,RPDB_ROUTE_ADD)); + printf("~~~~~~%d\n",rpdb_add_del_route("112.168.221.2",NULL,RPDB_ROUTE_ADD)); + + + /* + 非法IP地址 + */ + printf("~~~~~~%d\n",rpdb_add_del_route("392.168.221.2",NULL,RPDB_ROUTE_ADD)); + + printf("~~~~~~%d\n",rpdb_add_del_route("2a01:198:603:0:396e:4789:8e99:890f",NULL,RPDB_ROUTE_ADD)); return 0; } +#endif \ No newline at end of file