summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-04-17 18:26:33 +0800
committerluwenpeng <[email protected]>2023-04-21 18:31:36 +0800
commitf421e4df5403f977603ab22950f83baa7fc3cffd (patch)
tree17ac5bb058e9cfcae9c4887bc4fdac4867458192 /plugin
parentf741c3c025c91da2803246a8213fd5fe2d069a50 (diff)
TSG-14789 TFE扫描service chaining策略,执行Decrypted Traffic Steering
Diffstat (limited to 'plugin')
-rw-r--r--plugin/business/CMakeLists.txt1
-rw-r--r--plugin/business/chaining-policy/CMakeLists.txt4
-rw-r--r--plugin/business/chaining-policy/src/chaining_policy.cpp204
-rw-r--r--plugin/business/chaining-policy/src/chaining_policy.h8
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(&param->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 **)&param, 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