summaryrefslogtreecommitdiff
path: root/src/access/flwd_access_maat.c
diff options
context:
space:
mode:
authorlijia <[email protected]>2018-10-24 09:36:45 +0800
committerlijia <[email protected]>2018-10-24 09:36:45 +0800
commit86a43b4d325ddc850fa9dc4711670880f35b11e8 (patch)
tree8356a056ac9bfb8cf14fcf57f113dd306b4277d1 /src/access/flwd_access_maat.c
create new project.
Diffstat (limited to 'src/access/flwd_access_maat.c')
-rw-r--r--src/access/flwd_access_maat.c582
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;
+}
+