diff options
| author | luwenpeng <[email protected]> | 2023-04-17 18:26:33 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-04-21 18:31:36 +0800 |
| commit | f421e4df5403f977603ab22950f83baa7fc3cffd (patch) | |
| tree | 17ac5bb058e9cfcae9c4887bc4fdac4867458192 /plugin | |
| parent | f741c3c025c91da2803246a8213fd5fe2d069a50 (diff) | |
TSG-14789 TFE扫描service chaining策略,执行Decrypted Traffic Steering
Diffstat (limited to 'plugin')
| -rw-r--r-- | plugin/business/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | plugin/business/chaining-policy/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | plugin/business/chaining-policy/src/chaining_policy.cpp | 204 | ||||
| -rw-r--r-- | plugin/business/chaining-policy/src/chaining_policy.h | 8 |
4 files changed, 217 insertions, 0 deletions
diff --git a/plugin/business/CMakeLists.txt b/plugin/business/CMakeLists.txt index 4e67d00..0cb4670 100644 --- a/plugin/business/CMakeLists.txt +++ b/plugin/business/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(doh) add_subdirectory(tsg-http) add_subdirectory(ssl-policy) add_subdirectory(tcp-policy) +add_subdirectory(chaining-policy)
\ No newline at end of file diff --git a/plugin/business/chaining-policy/CMakeLists.txt b/plugin/business/chaining-policy/CMakeLists.txt new file mode 100644 index 0000000..cee66ac --- /dev/null +++ b/plugin/business/chaining-policy/CMakeLists.txt @@ -0,0 +1,4 @@ +add_library(chaining-policy src/chaining_policy.cpp) +target_link_libraries(chaining-policy PUBLIC common) +target_link_libraries(chaining-policy PUBLIC cjson) +target_link_libraries(chaining-policy PUBLIC maatframe)
\ No newline at end of file diff --git a/plugin/business/chaining-policy/src/chaining_policy.cpp b/plugin/business/chaining-policy/src/chaining_policy.cpp new file mode 100644 index 0000000..8405d99 --- /dev/null +++ b/plugin/business/chaining-policy/src/chaining_policy.cpp @@ -0,0 +1,204 @@ +#include <assert.h> +#include <tfe_cmsg.h> +#include <tfe_utils.h> +#include <tfe_stream.h> +#include <tfe_resource.h> +#include <cjson/cJSON.h> +#include <MESA/maat.h> + +#include "chaining_policy.h" + +enum traffic_type +{ + TRAFFIC_TYPE_NONE = 0, + TRAFFIC_TYPE_RAW = 1, + TRAFFIC_TYPE_DECRYPTED = 2, +}; + +struct chaining_param +{ + uint64_t rule_id; + int ref_cnt; + enum traffic_type type; +}; + +struct chaining_policy_enforcer +{ + struct maat *maat; + int table_id; + void *logger; +}; + +static void chaining_param_new_cb(const char *table_name, int table_id, const char *key, const char *table_line, void **ad, long argl, void *argp) +{ + cJSON *json = NULL; + cJSON *item = NULL; + cJSON *element = NULL; + size_t user_region_offset = 0; + size_t user_region_len = 0; + struct chaining_param *param = NULL; + struct chaining_policy_enforcer *enforcer = (struct chaining_policy_enforcer *)argp; + + if (maat_helper_read_column(table_line, 7, &user_region_offset, &user_region_len) < 0) + { + TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid user region) %s", table_line); + return; + } + + char *json_str = (char *)calloc(user_region_len + 1, sizeof(char)); + memcpy(json_str, table_line + user_region_offset, user_region_len); + json = cJSON_Parse(json_str); + if (json == NULL) + { + TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid json format) %s", table_line); + goto error_out; + } + + param = (struct chaining_param *)calloc(1, sizeof(struct chaining_param)); + param->rule_id = atoll(key); + param->ref_cnt = 1; + + item = cJSON_GetObjectItem(json, "targeted_traffic"); + if (!item || !cJSON_IsString(item)) + { + TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid targeted_traffic param) %s", table_line); + goto error_out; + } + if (strcasecmp(item->valuestring, "raw") == 0) + { + param->type = TRAFFIC_TYPE_RAW; + } + else if (strcasecmp(item->valuestring, "decrypted") == 0) + { + param->type = TRAFFIC_TYPE_DECRYPTED; + } + else + { + TFE_LOG_ERROR(enforcer->logger, "unexpected chaining rule: (invalid targeted_traffic param) %s", table_line); + goto error_out; + } + + *ad = param; + TFE_LOG_INFO(enforcer->logger, "Add chaining rule: %lu", param->rule_id); + + cJSON_Delete(json); + free(json_str); + return; + +error_out: + if (json) + { + cJSON_Delete(json); + json = NULL; + } + + if (json_str) + { + free(json_str); + json_str = NULL; + } + + if (param) + { + free(param); + param = NULL; + } +} + +static void chaining_param_free_cb(int table_id, void **ad, long argl, void *argp) +{ + struct chaining_policy_enforcer *enforcer = (struct chaining_policy_enforcer *)argp; + struct chaining_param *param = (struct chaining_param *)*ad; + if (param == NULL) + { + return; + } + + if ((__sync_sub_and_fetch(¶m->ref_cnt, 1) == 0)) + { + TFE_LOG_INFO(enforcer->logger, "Del chaining policy %lu", param->rule_id); + free(param); + *ad = NULL; + } +} + +static void chaining_param_free(struct chaining_param *param) +{ + chaining_param_free_cb(0, (void **)¶m, 0, NULL); +} + +static void chaining_param_dup_cb(int table_id, void **to, void **from, long argl, void *argp) +{ + struct chaining_param *param = (struct chaining_param *)*from; + if (param) + { + __sync_add_and_fetch(&(param->ref_cnt), 1); + *to = param; + } + else + { + *to = NULL; + } +} + +struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger) +{ + int ret = 0; + struct chaining_policy_enforcer *enforcer = ALLOC(struct chaining_policy_enforcer, 1); + enforcer->maat = (struct maat *)tfe_bussiness_resouce_get(STATIC_MAAT); + enforcer->logger = logger; + enforcer->table_id = maat_get_table_id(enforcer->maat, "SERVICE_CHAINING_COMPILE"); + if (enforcer->table_id < 0) + { + TFE_LOG_ERROR(enforcer->logger, "failed at register table of SERVICE_CHAINING_COMPILE, ret = %d", enforcer->table_id); + goto error_out; + } + + ret = maat_plugin_table_ex_schema_register(enforcer->maat, "SERVICE_CHAINING_COMPILE", + chaining_param_new_cb, + chaining_param_free_cb, + chaining_param_dup_cb, + 0, enforcer); + if (ret < 0) + { + TFE_LOG_ERROR(enforcer->logger, "failed at register callback of SERVICE_CHAINING_COMPILE, ret = %d", ret); + goto error_out; + } + return enforcer; + +error_out: + chaining_policy_enforcer_destory(enforcer); + return NULL; +} + +void chaining_policy_enforcer_destory(struct chaining_policy_enforcer *enforcer) +{ + if (enforcer) + { + free(enforcer); + enforcer = NULL; + } +} + +void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id) +{ + char rule_id_str[16] = {0}; + uint8_t enalbe_decrypted_traffic_steering = 0; + + snprintf(rule_id_str, sizeof(rule_id_str), "%lu", rule_id); + struct chaining_param *param = (struct chaining_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->table_id, rule_id_str); + if (param == NULL) + { + TFE_LOG_INFO(enforcer->logger, "Failed to get chaining parameter of policy %lu.", rule_id); + tfe_cmsg_set(cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering)); + return; + } + + if (param->type == TRAFFIC_TYPE_DECRYPTED) + { + enalbe_decrypted_traffic_steering = 1; + } + + tfe_cmsg_set(cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enalbe_decrypted_traffic_steering, sizeof(enalbe_decrypted_traffic_steering)); + chaining_param_free(param); +}
\ No newline at end of file diff --git a/plugin/business/chaining-policy/src/chaining_policy.h b/plugin/business/chaining-policy/src/chaining_policy.h new file mode 100644 index 0000000..0fcbe81 --- /dev/null +++ b/plugin/business/chaining-policy/src/chaining_policy.h @@ -0,0 +1,8 @@ +#pragma once +#include <tfe_cmsg.h> +#include <MESA/maat.h> + +struct chaining_policy_enforcer; +struct chaining_policy_enforcer *chaining_policy_enforcer_create(void *logger); +void chaining_policy_enforcer_destory(struct chaining_policy_enforcer *enforcer); +void chaining_policy_enforce(struct chaining_policy_enforcer *enforcer, struct tfe_cmsg *cmsg, uint64_t rule_id);
\ No newline at end of file |
