diff options
Diffstat (limited to 'src/access/flwd_access_maat.c')
| -rw-r--r-- | src/access/flwd_access_maat.c | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/src/access/flwd_access_maat.c b/src/access/flwd_access_maat.c new file mode 100644 index 0000000..be30508 --- /dev/null +++ b/src/access/flwd_access_maat.c @@ -0,0 +1,582 @@ +#include "flowood.h" +#include "flowood_fun.h" +#include "flwd_net.h" +#include "MESA_htable.h" +#include "MESA_list_queue.h" +#include "MESA_handle_logger.h" +#include "MESA_list_count.h" +#include "Maat_rule.h" +#include <assert.h> +#include <stdio.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> +#include <assert.h> +#include <arpa/inet.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> +#include <ctype.h> + + +static unsigned int flwd_fetch_policy_id_from_user_region(struct Maat_rule_t *maat_res) +{ + char *policy_section; + + /* �������, �洢���Զ�����, ����ǰ���Ե�IP��ַ�ص���� */ + policy_section = strcasestr(maat_res->service_defined, "IR_STRATEGY="); + if(NULL == policy_section){ + return 0; + } + + policy_section += strlen("IR_STRATEGY="); + + return (unsigned int)atoi(policy_section); +} + + +/* + ���ݵ�ǰ�ͻ��˵�ԴIP, PORT, ɨ�������ĸ����ò���: policy_id. + return value: + > 0: success, policy id. + 0: not hit rule; +*/ +unsigned int flwd_access_maat_scan_rule(int tid, const flwd_tuple5_t *tuple5) +{ + int ret; + struct Maat_rule_t maat_res[1]; /* ��̫���ܶ�����, �����Ƕ�����, ���Ҳֻ��Ҫһ�����, �˴�res��Ϊ1 */ + struct ipaddr client_addr; + scan_status_t mid = NULL; + unsigned int hit_policy_id; + + memset(&maat_res[0], 0, sizeof(maat_res)); + + flwd_tuple5_to_stream_addr(tid, tuple5, &client_addr); + + ret = Maat_scan_addr(flwd_global_val.maat_static_handle, + flwd_global_val.maat_table_info[FLWD_MAAT_TB_IR_POLICY_IP].table_id, /* TODO, SNAT��DNAT���Էֿ�, table_id�ֳ�����!! */ + &client_addr, + maat_res, + 1, + &mid, + tid); + if(ret <= 0){ + return 0; + } + + hit_policy_id = flwd_fetch_policy_id_from_user_region(&maat_res[0]); + + return hit_policy_id; +} + +static void nouse_maat_start_cb(int update_type,void* u_para) +{ + return; +} + +static void nouse_maat_finish_cb(void* u_para) +{ + return; +} + + +struct layer_addr_mac_in_mac +{ + unsigned char outer_dst_mac[6]; /* �����mac��ַ, network order */ + unsigned char outer_src_mac[6]; /* �����mac��ַ, network order */ + unsigned char inner_dst_mac[6]; /* �ڲ�mac��ַ, network order */ + unsigned char inner_src_mac[6]; /* �ڲ�mac��ַ, network order */ +}; + + +/* ascii�ַ�ת16���� */ +static char MESA_ascii_to_hex(char ascii) +{ + char c = 0; + + switch(ascii) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + c = ascii - 0x30; + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + c = 10 + ascii - 0x61; + break; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + c = 10 + ascii - 0x41; + break; + } + + return c; +} + +/* + "000100032202-00e0fc030007,000100032202-00e0fc030007" + copy from sapp. +*/ +static int flwd_mac_in_mac_pton(char *addr_str, struct layer_addr_mac_in_mac *minm) +{ + int i; + char *str_val = addr_str; + unsigned char tmp_bin_val; + + memset(minm, 0, sizeof(struct layer_addr_mac_in_mac)); + + for(i = 0; i < 6; i++){ + tmp_bin_val = 0; /* ������, ������ֵ��䶼�ǻ���� */ + if(isxdigit(*str_val)==0){ + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val) << 4; + str_val++; + + if(isxdigit(*str_val)==0) { + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val); + str_val++; + minm->inner_src_mac[i] = tmp_bin_val; + } + + if(*str_val != '-'){ + printf("MAC string type error!\n"); + return -1; + } + str_val++; + + for(i = 0; i < 6; i++){ + tmp_bin_val = 0; /* ������, ������ֵ��䶼�ǻ���� */ + if(isxdigit(*str_val)==0){ + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val) << 4; + str_val++; + + if(isxdigit(*str_val)==0) { + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val); + str_val++; + minm->inner_dst_mac[i] = tmp_bin_val; + } + + if(*str_val != ','){ + printf("MAC_IN_MAC string type error!\n"); + return -1; + } + str_val++; + + for(i = 0; i < 6; i++){ + tmp_bin_val = 0; /* ������, ������ֵ��䶼�ǻ���� */ + if(isxdigit(*str_val)==0){ + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val) << 4; + str_val++; + + if(isxdigit(*str_val)==0) { + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val); + str_val++; + minm->outer_src_mac[i] = tmp_bin_val; + } + + if(*str_val != '-'){ + printf("MAC_IN_MAC string type error!\n"); + return -1; + } + str_val++; + + for(i = 0; i < 6; i++){ + tmp_bin_val = 0; /* ������, ������ֵ��䶼�ǻ���� */ + if(isxdigit(*str_val)==0){ + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val) << 4; + str_val++; + + if(isxdigit(*str_val)==0) { + printf("MAC string type error!\n"); + return -1; + } + tmp_bin_val |= MESA_ascii_to_hex(*str_val); + str_val++; + minm->outer_dst_mac[i] = tmp_bin_val; + } + + return 0; +} + +/* + region_id=1;dev_id=1;link_id=2;route_dir=0;smac=xxxxxx;dmac=xxxxx; + + ����user_region��ʽʹ��MAC-IN-MAC��ʽ�������ڲ㣬���������. + inner_smac-inner-dmac, outer_smac-outer_dmat, + 000100032202-00e0fc030007,000100032202-00e0fc030007 + +*/ +static int flwd_act_ip_user_region_parse(char *user_region, flwd_active_ip_t *act_ip) +{ + int ret; + struct layer_addr_mac_in_mac minm; + + + /* TODO + flwd_search_fwd_ip_by_gdev_ip(), ͨ��dev_id, region_id�Զ���ѯ. + */ + + +#if FLWD_RUN_IN_CEIEC_TEST + /* ��ʱ���ԣ��ֶ�д���ڲ�mac */ + //char manual_inner_smac[6] = {0x3c, 0x97, 0x0e, 0x18, 0x18, 0x41}; + //char manual_inner_smac[6] = {0xe4, 0x95, 0x6e, 0x20, 0x0d, 0x06}; + char manual_inner_smac[6] = {0x28, 0xd2, 0x44, 0x43, 0x12, 0x34}; /* ��ԾIP��SMAC */ + char manual_inner_dmac[6] = {0xe8, 0x61, 0x1f, 0x13, 0x70, 0x7a}; /* Ŀ�������MAC */ + + //inet_pton(AF_INET, "10.3.127.3", &act_ip->gdev_args.gdev_ip_net_order); + inet_pton(AF_INET, "10.1.1.1", &act_ip->gdev_args.gdev_ip_net_order); + act_ip->gdev_args.link_id = 1; /* TODO, ���ݻ�ԾIP������ȡ, ���ϲ���Ϊ1 */ + act_ip->gdev_args.this_ip_as_sip_route_dir = 1; /* TODO, ���ݻ�ԾIP������ȡ,���ϲ���Ϊ1 */ + memcpy(act_ip->gdev_args.inner_raw_smac, manual_inner_smac, 6); + memcpy(act_ip->gdev_args.inner_raw_dmac, manual_inner_dmac, 6); +#else + ret = flwd_mac_in_mac_pton(user_region, &minm); + if(ret < 0){ + return -1; + } + + memcpy(act_ip->gdev_args.inner_raw_dmac, minm.inner_dst_mac, 6); + memcpy(act_ip->gdev_args.inner_raw_smac, minm.inner_src_mac, 6); + +#endif + + return 0; +} + + +/* + �����ʽ: + ID,addr_type, protocol,ip,port,direction,user_region,location,is_valid,action,service,policy_group,op_time; + + TODO: + ����user_region��ʽ��ǰ���Ƿ���mac-in-mac��ʽ, ����ԭʼMAC��ʽδ��, ��ʹ��gdev_ip=1.1.1.1��GDEVIP������. +*/ +static void flwd_ip_static_pool_cb(int table_id, const char *table_line, void* u_para) +{ + char *stack_buf = strdup(table_line); + char *save_ptr; + char *section; + const char *delim = "\t "; + flwd_active_ip_t act_ip; + int tmp_int; + char for_log_ip_str[128]; + + memset(&act_ip, 0, sizeof(act_ip)); + + /* ID */ + section = strtok_r(stack_buf, delim, &save_ptr); + assert(section); + + /* addr_type */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + tmp_int = atoi(section); + if(4 == tmp_int){ + act_ip.active_ip_net_order.addr_type = FLWD_IP_ADDR_TYPE_V4; + act_ip.active_ip_net_order.addr_len = sizeof(int); + }else if(6 == tmp_int){ + act_ip.active_ip_net_order.addr_type = FLWD_IP_ADDR_TYPE_V6; + act_ip.active_ip_net_order.addr_len = sizeof(struct in6_addr); + }else{ + assert(0); + } + + /* protocol, �ݲ����� */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + + /* ip */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + if(FLWD_IP_ADDR_TYPE_V4 == act_ip.active_ip_net_order.addr_type){ + inet_pton(AF_INET, section, &act_ip.active_ip_net_order.addr_ipv4); + }else{ + inet_pton(AF_INET6, section, &act_ip.active_ip_net_order.addr_ipv6); + } + strncpy(for_log_ip_str, section, 128); + + /* port */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + tmp_int = atoi(section); + if(tmp_int < 0 || tmp_int > 65535){ + assert(0); + } + act_ip.active_ip_net_order.dport = (unsigned short)tmp_int; + + /* direction, ��GDEV�µķ���Ӧ�ö���Ŀ��IP, 0��ʾԴIP��1��ʾĿ��IP��2��ʾ˫�� */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + + /* user region, �洢GDEV�����Ϣ */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + if(flwd_act_ip_user_region_parse(section, &act_ip) < 0){ + goto done; + } + + /* location, */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + +#if FLWD_IP_REGION_BY_LIB + if(FLWD_IP_ADDR_TYPE_V4 == act_ip.active_ip_net_order.addr_type){ + act_ip.ip_region_type = flwd_ipv4_location(ntohl(act_ip.active_ip_net_order.addr_ipv4)); + }else{ + act_ip.ip_region_type = flwd_ipv6_location(&act_ip.active_ip_net_order.addr_ipv6); + } +#else + tmp_int = atoi(section); + if((tmp_int != FLWD_IP_REGION_INLAND) && (tmp_int != FLWD_IP_REGION_OUTLAND)){ + assert(0); + } + + act_ip.ip_region_type = (flwd_ip_region_type_t)tmp_int; +#endif + + /* is_valid */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + act_ip.is_valid = atoi(section); + + /* action, TODO, 20180910, ���ֶ��Ѿ�ɾ��!!! */ + //section = strtok_r(NULL, delim, &save_ptr); + //assert(section); + + /* service */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + + /* policy group id */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + act_ip.policy_group_id = strtoul(section, NULL, 10); + + /* op_time */ + section = strtok_r(NULL, delim, &save_ptr); + //assert(section); + + act_ip.ip_origin_type = FLWD_ACT_IP_STATIC; + flwd_act_ip_update(&act_ip); + + flwd_log(10, "ip_static_pool update callback: recv ip %s, region:%d, policy_id:%u\n", + for_log_ip_str, act_ip.ip_region_type, act_ip.policy_group_id); + +done: + while(strtok_r(NULL, delim, &save_ptr)); + + free(stack_buf); + + return; +} + + +/* + �����ʽ: + ID,addr_type, protocol,ip,port,direction,user_region,location,is_valid,op_time; + + TODO: + ����user_region��ʽʹ��MAC-IN-MAC��ʽ�������ڲ㣬���������. + inner_smac-inner-dmac, outer_smac-outer_dmat, + 000100032202-00e0fc030007,000100032202-00e0fc030007 +*/ +void flwd_ip_dyn_sift_pool_cb(int table_id,const char* table_line,void* u_para) +{ + char *stack_buf = strdup(table_line); + char *save_ptr; + char *section; + const char *delim = "\t "; + flwd_active_ip_t act_ip; + int tmp_int; + char *for_log_ip_str; + + memset(&act_ip, 0, sizeof(act_ip)); + + /* ID */ + section = strtok_r(stack_buf, delim, &save_ptr); + assert(section); + + /* addr_type */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + tmp_int = atoi(section); + if(4 == tmp_int){ + act_ip.active_ip_net_order.addr_type = FLWD_IP_ADDR_TYPE_V4; + act_ip.active_ip_net_order.addr_len = sizeof(int); + }else if(6 == tmp_int){ + act_ip.active_ip_net_order.addr_type = FLWD_IP_ADDR_TYPE_V6; + act_ip.active_ip_net_order.addr_len = sizeof(struct in6_addr); + }else{ + assert(0); + } + + /* protocol, �ݲ����� */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + + /* ip */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + if(FLWD_IP_ADDR_TYPE_V4 == act_ip.active_ip_net_order.addr_type){ + inet_pton(AF_INET, section, &act_ip.active_ip_net_order.addr_ipv4); + }else{ + inet_pton(AF_INET6, section, &act_ip.active_ip_net_order.addr_ipv6); + } + for_log_ip_str = section; + + /* port, ��ַ�ص�PORT�ֶ������� */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + tmp_int = atoi(section); + if(tmp_int < 0 || tmp_int > 65535){ + assert(0); + } + act_ip.active_ip_net_order.dport = (unsigned short)tmp_int; + + /* direction, ��GDEV�µķ���Ӧ�ö���Ŀ��IP, 0��ʾԴIP��1��ʾĿ��IP��2��ʾ˫�� */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + + /* user region, �ݲ����� */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + if(flwd_act_ip_user_region_parse(section, &act_ip) < 0){ + goto done; + } + + /* location, */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); +#if FLWD_IP_REGION_BY_LIB + if(FLWD_IP_ADDR_TYPE_V4 == act_ip.active_ip_net_order.addr_type){ + act_ip.ip_region_type = flwd_ipv4_location(ntohl(act_ip.active_ip_net_order.addr_ipv4)); + }else{ + act_ip.ip_region_type = flwd_ipv6_location(&act_ip.active_ip_net_order.addr_ipv6); + } +#else + tmp_int = atoi(section); + if((tmp_int != FLWD_IP_REGION_INLAND) && (tmp_int != FLWD_IP_REGION_OUTLAND)){ + assert(0); + } + + act_ip.ip_region_type = (flwd_ip_region_type_t)tmp_int; +#endif + + /* is_valid */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + act_ip.is_valid = atoi(section); + + /* op_time */ + section = strtok_r(NULL, delim, &save_ptr); + assert(section); + + act_ip.ip_origin_type = FLWD_ACT_IP_DYNAMIC; + + flwd_act_ip_update(&act_ip); + + flwd_log(10, "ip_dynamic_pool update callback: recv ip %s, region:%d\n", + for_log_ip_str, act_ip.ip_region_type); +done: + while(strtok_r(NULL, delim, &save_ptr)); /* ���strtok���� */ + + free(stack_buf); + + return; +} + + +int flwd_access_maat_init(void) +{ +#if 0 == FLWD_NO_MAAT + int ret; + + ret = flwd_maat_talbe_name_init(); + if(ret < 0){ + return -1; + } + + flwd_global_val.maat_static_handle = flwd_maat_summon(FLWD_CONFIG_FILE, "maat_static"); + if(NULL == flwd_global_val.maat_static_handle){ + return -1; + } + + flwd_global_val.maat_dynamic_handle = flwd_maat_summon(FLWD_CONFIG_FILE, "maat_dynamic"); + if(NULL == flwd_global_val.maat_dynamic_handle){ + return -1; + } + + flwd_maat_table_register(flwd_global_val.maat_static_handle, (int)FLWD_MAAT_TB_IR_POLICY_COMPILE); + flwd_maat_table_register(flwd_global_val.maat_static_handle, (int)FLWD_MAAT_TB_IR_POLICY_GROUP); + flwd_maat_table_register(flwd_global_val.maat_static_handle, (int)FLWD_MAAT_TB_IR_POLICY_IP); + flwd_maat_table_register(flwd_global_val.maat_static_handle, (int)FLWD_MAAT_TB_IR_STATIC_IP_POOL_CB); + flwd_maat_table_register(flwd_global_val.maat_dynamic_handle, (int)FLWD_MAAT_TB_IR_DYN_SIFT_IP_CB); + flwd_maat_table_register(flwd_global_val.maat_dynamic_handle, (int)FLWD_MAAT_TB_IR_DYN_CONN_IP); + + ret = Maat_table_callback_register(flwd_global_val.maat_static_handle, + flwd_global_val.maat_table_info[FLWD_MAAT_TB_IR_STATIC_IP_POOL_CB].table_id, + nouse_maat_start_cb, + flwd_ip_static_pool_cb, + nouse_maat_finish_cb, + flwd_global_val.maat_log_handle); + if(ret < 0){ + flwd_log(30, "Maat_table_callback_register %s error!\n", + flwd_global_val.maat_table_info[FLWD_MAAT_TB_IR_STATIC_IP_POOL_CB].table_name); + return -1; + } + + ret = Maat_table_callback_register(flwd_global_val.maat_dynamic_handle, + flwd_global_val.maat_table_info[FLWD_MAAT_TB_IR_DYN_SIFT_IP_CB].table_id, + nouse_maat_start_cb, + flwd_ip_dyn_sift_pool_cb, + nouse_maat_finish_cb, + flwd_global_val.maat_log_handle); + if(ret < 0){ + flwd_log(30, "Maat_table_callback_register %s error!\n", + flwd_global_val.maat_table_info[FLWD_MAAT_TB_IR_DYN_SIFT_IP_CB].table_name); + return -1; + } + +#endif + + return 0; +} + |
