TSG-13837 支持decrypted traffic steering/mirroring,并重构packet_io

This commit is contained in:
luwenpeng
2023-03-14 16:10:44 +08:00
parent 29755f2162
commit 0e85d3c9c5
26 changed files with 1960 additions and 1941 deletions

View File

@@ -150,88 +150,14 @@ struct sf_param
* Private API
******************************************************************************/
static const char *traffic_type_to_string(enum traffic_type traffic_type)
static const char *admin_status_to_string(enum admin_status admin_status)
{
switch (traffic_type)
switch (admin_status)
{
case TRAFFIC_TYPE_NONE:
return "none";
case TRAFFIC_TYPE_RAW:
return "raw";
case TRAFFIC_TYPE_DECRYPTED:
return "decrypted";
default:
return "unknown";
}
}
static const char *forward_type_to_string(enum forward_type forward_type)
{
switch (forward_type)
{
case FORWARD_TYPE_NONE:
return "none";
case FORWARD_TYPE_STEERING:
return "steering";
case FORWARD_TYPE_MIRRORING:
return "mirroring";
default:
return "unknown";
}
}
static const char *session_action_to_string(enum session_action session_action)
{
switch (session_action)
{
case SESSION_ACTION_BYPASS:
return "bypass";
case SESSION_ACTION_FORWARD:
return "forward";
case SESSION_ACTION_BLOCK:
return "block";
default:
return "unknown";
}
}
const char *session_action_reason_to_string(enum session_action_reason session_action_reason)
{
switch (session_action_reason)
{
case ACTION_BYPASS_DUE_DEFAULT:
return "bypass_due_default";
case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT:
return "bypass_due_health_sf_limit";
case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION:
return "bypass_due_unavailable_action";
case ACTION_BYPASS_DUE_FAILURE_ACTION:
return "bypass_due_failure_action";
case ACTION_BYPASS_DUE_INVALID_POLICY:
return "bypass_due_invalid_policy";
case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION:
return "block_due_unavailable_action";
case ACTION_BLOCK_DUE_FAILURE_ACTION:
return "block_due_failure_action";
case ACTION_FORWAED_DUE_SELECTED_AVAILABLE_SF:
return "forward_due_selected_available_sf";
default:
return "unknown";
}
}
static const char *package_method_to_string(enum package_method package_method)
{
switch (package_method)
{
case PACKAGE_METHOD_NONE:
return "none";
case PACKAGE_METHOD_LAYER2_SWITCH:
return "layer2_switch";
case PACKAGE_METHOD_LAYER3_SWITCH:
return "layer3_switch";
case PACKAGE_METHOD_VXLAN_G:
return "vxlan_g";
case ADMMIN_STATUS_ACTIVE:
return "active";
case ADMMIN_STATUS_INACTIVE:
return "inactive";
default:
return "unknown";
}
@@ -380,12 +306,10 @@ static void chaining_param_new_cb(int table_id, const char *key, const char *tab
}
if (strcasecmp(item->valuestring, "raw") == 0)
{
LOG_DEBUG("%s: parse chaining policy: %d, targeted_traffic: raw", LOG_TAG_POLICY, param->policy_id);
param->traffic_type = TRAFFIC_TYPE_RAW;
}
else if (strcasecmp(item->valuestring, "decrypted") == 0)
{
LOG_DEBUG("%s: parse chaining policy: %d, targeted_traffic: decrypted", LOG_TAG_POLICY, param->policy_id);
param->traffic_type = TRAFFIC_TYPE_DECRYPTED;
}
else
@@ -393,6 +317,7 @@ static void chaining_param_new_cb(int table_id, const char *key, const char *tab
LOG_ERROR("%s: unexpected chaining policy: (invalid targeted_traffic param) %s", LOG_TAG_POLICY, table_line);
goto error_out;
}
LOG_DEBUG("%s: parse chaining policy: %d, targeted_traffic: %s", LOG_TAG_POLICY, param->policy_id, traffic_type_to_string(param->traffic_type));
// sff_profiles
item = cJSON_GetObjectItem(json, "sff_profiles");
@@ -525,16 +450,15 @@ static void sff_param_new_cb(int table_id, const char *key, const char *table_li
{
case 1:
param->sff_forward_type = FORWARD_TYPE_STEERING;
LOG_DEBUG("%s: parse sff profile: %d, type: steering", LOG_TAG_POLICY, param->sff_profile_id);
break;
case 2:
param->sff_forward_type = FORWARD_TYPE_MIRRORING;
LOG_DEBUG("%s: parse sff profile: %d, type: mirroring", LOG_TAG_POLICY, param->sff_profile_id);
break;
default:
LOG_ERROR("%s: unexpected sff profile: (invalid type param) %s", LOG_TAG_POLICY, table_line);
goto error_out;
}
LOG_DEBUG("%s: parse sff profile: %d, type: %s", LOG_TAG_POLICY, param->sff_profile_id, forward_type_to_string(param->sff_forward_type));
// load_balance_method
if (0 == strcasecmp(load_balance_method, "hash-int-ip"))
@@ -762,16 +686,15 @@ static void sf_param_new_cb(int table_id, const char *key, const char *table_lin
{
case 1:
param->sf_admin_status = ADMMIN_STATUS_ACTIVE;
LOG_DEBUG("%s: parse sf profile: %d, admin_status: active", LOG_TAG_POLICY, param->sf_profile_id);
break;
case 0:
param->sf_admin_status = ADMMIN_STATUS_INACTIVE;
LOG_DEBUG("%s: parse sf profile: %d, admin_status: inactive", LOG_TAG_POLICY, param->sf_profile_id);
break;
default:
LOG_ERROR("%s: unexpected sf profile: (invalid admin_status param) %s", LOG_TAG_POLICY, table_line);
goto error_out;
}
LOG_DEBUG("%s: parse sf profile: %d, admin_status: %s", LOG_TAG_POLICY, param->sf_profile_id, admin_status_to_string(param->sf_admin_status));
// connectivity
root1 = cJSON_Parse(connectivity);
@@ -804,7 +727,7 @@ static void sf_param_new_cb(int table_id, const char *key, const char *table_lin
LOG_ERROR("%s: unexpected sf profile: (invalid connectivity->method param) %s", LOG_TAG_POLICY, table_line);
goto error_out;
}
LOG_DEBUG("%s: parse sf profile: %d, connectivity->method: %s", LOG_TAG_POLICY, param->sf_profile_id, item->valuestring);
LOG_DEBUG("%s: parse sf profile: %d, connectivity->method: %s", LOG_TAG_POLICY, param->sf_profile_id, package_method_to_string(param->sf_connectivity.method));
if (param->sf_connectivity.method == PACKAGE_METHOD_LAYER2_SWITCH || param->sf_connectivity.method == PACKAGE_METHOD_LAYER3_SWITCH)
{
@@ -979,7 +902,7 @@ static void sf_param_free(struct sf_param *param)
}
// After return must check array elem nums
static void select_sf_by_nearby_and_active(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array)
static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array)
{
char buffer[16];
struct sf_param *sf = NULL;
@@ -1019,14 +942,14 @@ static void select_sf_by_nearby_and_active(struct policy_enforcer *enforcer, str
// return : SESSION_ACTION_BYPASS, not care selected_sf_profile_id
// return : SESSION_ACTION_BLOCK, not care selected_sf_profile_id
// return : SESSION_ACTION_FORWARD, care selected_sf_profile_id
static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array, int *selected_sf_profile_id, enum session_action_reason *sf_action_reason, char *sf_dst_mac, struct session_ctx *s_ctx)
static enum session_action select_sf_by_ldbc(struct policy_enforcer *enforcer, struct session_ctx *s_ctx, struct sff_param *sff_param, struct selected_sf *sf, struct fixed_num_array *array, uint64_t hash)
{
struct thread_ctx *thread = (struct thread_ctx *)s_ctx->ref_thread_ctx;
struct global_metrics *g_metrics = thread->ref_metrics;
struct sf_param *sf = NULL;
struct sf_param *sf_param = NULL;
char buffer[16];
*selected_sf_profile_id = -1;
sf->sf_profile_id = -1;
int sf_profile_id = 0;
int sf_profile_index = 0;
int sf_profile_num = 0;
@@ -1041,28 +964,28 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc
memset(&buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%u", sf_profile_id);
sf = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer);
if (sf == NULL)
sf_param = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer);
if (sf_param == NULL)
{
LOG_ERROR("%s: failed to get sf parameter of profile %d", LOG_TAG_POLICY, sf_profile_id);
fixed_num_array_del_elem(array, sf_profile_id);
continue;
}
health_check_session_id = sf->health_check_session_id;
sf_param_free(sf);
health_check_session_id = sf_param->health_check_session_id;
sf_param_free(sf_param);
memset(sf_dst_mac, 0, 32);
if (health_check_session_get_mac(health_check_session_id, sf_dst_mac) == 0)
memset(sf->sf_dst_mac, 0, 32);
if (health_check_session_get_mac(health_check_session_id, sf->sf_dst_mac) == 0)
{
__atomic_fetch_add(&g_metrics->sf_active_times, 1, __ATOMIC_RELAXED);
ATOMIC_INC(&(g_metrics->sf_status.active));
*selected_sf_profile_id = sf_profile_id;
*sf_action_reason = ACTION_FORWAED_DUE_SELECTED_AVAILABLE_SF;
sf->sf_profile_id = sf_profile_id;
sf->sf_action_reason = ACTION_FORWAED_DUE_SELECTED_SF;
return SESSION_ACTION_FORWARD;
}
else
{
__atomic_fetch_add(&g_metrics->sf_inactive_times, 1, __ATOMIC_RELAXED);
ATOMIC_INC(&(g_metrics->sf_status.inactive));
if (sff_param->sff_exception.fail_action == FAILURE_ACTION_RE_DISPATCH)
{
@@ -1071,7 +994,7 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc
if (sff_param->sff_exception.health_service_func_lt > 0 && sf_profile_num < sff_param->sff_exception.health_service_func_lt)
{
*sf_action_reason = ACTION_BYPASS_DUE_HEALTH_SF_LIMIT;
sf->sf_action_reason = ACTION_BYPASS_DUE_HEALTH_SF_LIMIT;
return SESSION_ACTION_BYPASS;
}
else
@@ -1080,12 +1003,12 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc
{
if (sff_param->sff_exception.unavail_action == UNAVAILABLE_ACTION_BYPASSS)
{
*sf_action_reason = ACTION_BYPASS_DUE_UNAVAILABLE_ACTION;
sf->sf_action_reason = ACTION_BYPASS_DUE_UNAVAILABLE_ACTION;
return SESSION_ACTION_BYPASS;
}
else
{
*sf_action_reason = ACTION_BLOCK_DUE_UNAVAILABLE_ACTION;
sf->sf_action_reason = ACTION_BLOCK_DUE_UNAVAILABLE_ACTION;
return SESSION_ACTION_BLOCK;
}
}
@@ -1097,20 +1020,20 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforc
}
else if (sff_param->sff_exception.fail_action == FAILURE_ACTION_BYPASS)
{
*selected_sf_profile_id = sf_profile_id;
*sf_action_reason = ACTION_BYPASS_DUE_FAILURE_ACTION;
sf->sf_profile_id = sf_profile_id;
sf->sf_action_reason = ACTION_BYPASS_DUE_FAILURE_ACTION;
return SESSION_ACTION_BYPASS;
}
else if (sff_param->sff_exception.fail_action == FAILURE_ACTION_BLOCK)
{
*selected_sf_profile_id = sf_profile_id;
*sf_action_reason = ACTION_BLOCK_DUE_FAILURE_ACTION;
sf->sf_profile_id = sf_profile_id;
sf->sf_action_reason = ACTION_BLOCK_DUE_FAILURE_ACTION;
return SESSION_ACTION_BLOCK;
}
}
};
*sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY;
sf->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY;
return SESSION_ACTION_BYPASS;
}
@@ -1130,10 +1053,228 @@ static void selected_sf_init(struct selected_sf *item)
}
}
static void connectivity_copy(struct connectivity *dst, struct connectivity *src)
{
if (dst && src)
{
dst->method = src->method;
dst->int_vlan_tag = src->int_vlan_tag;
dst->ext_vlan_tag = src->ext_vlan_tag;
memcpy(dst->dest_ip, src->dest_ip, sizeof(dst->dest_ip));
}
}
/******************************************************************************
* Public API
******************************************************************************/
const char *traffic_type_to_string(enum traffic_type traffic_type)
{
switch (traffic_type)
{
case TRAFFIC_TYPE_NONE:
return "none";
case TRAFFIC_TYPE_RAW:
return "raw";
case TRAFFIC_TYPE_DECRYPTED:
return "decrypted";
default:
return "unknown";
}
}
const char *forward_type_to_string(enum forward_type forward_type)
{
switch (forward_type)
{
case FORWARD_TYPE_NONE:
return "none";
case FORWARD_TYPE_STEERING:
return "steering";
case FORWARD_TYPE_MIRRORING:
return "mirroring";
default:
return "unknown";
}
}
const char *session_action_to_string(enum session_action session_action)
{
switch (session_action)
{
case SESSION_ACTION_BYPASS:
return "bypass";
case SESSION_ACTION_FORWARD:
return "forward";
case SESSION_ACTION_BLOCK:
return "block";
default:
return "unknown";
}
}
const char *action_reason_to_string(enum action_reason action_reason)
{
switch (action_reason)
{
case ACTION_BYPASS_DUE_DEFAULT:
return "bypass_due_default";
case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT:
return "bypass_due_health_sf_limit";
case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION:
return "bypass_due_unavailable_action";
case ACTION_BYPASS_DUE_FAILURE_ACTION:
return "bypass_due_failure_action";
case ACTION_BYPASS_DUE_INVALID_POLICY:
return "bypass_due_invalid_policy";
case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION:
return "block_due_unavailable_action";
case ACTION_BLOCK_DUE_FAILURE_ACTION:
return "block_due_failure_action";
case ACTION_FORWAED_DUE_SELECTED_SF:
return "forward_due_selected_sf";
default:
return "unknown";
}
}
const char *package_method_to_string(enum package_method package_method)
{
switch (package_method)
{
case PACKAGE_METHOD_NONE:
return "none";
case PACKAGE_METHOD_LAYER2_SWITCH:
return "layer2_switch";
case PACKAGE_METHOD_LAYER3_SWITCH:
return "layer3_switch";
case PACKAGE_METHOD_VXLAN_G:
return "vxlan_g";
default:
return "unknown";
}
}
// return NULL : error
// return !NULL : success
struct selected_chaining *selected_chaining_create(int chaining_size, uint64_t session_id, char *session_addr)
{
struct selected_chaining *chaining = (struct selected_chaining *)calloc(1, sizeof(struct selected_chaining));
assert(chaining);
chaining->chaining_used = 0;
chaining->chaining_size = chaining_size;
chaining->chaining = (struct selected_sf *)calloc(chaining->chaining_size, sizeof(struct selected_sf));
assert(chaining->chaining);
for (int i = 0; i < chaining->chaining_size; i++)
{
struct selected_sf *item = &(chaining->chaining[i]);
selected_sf_init(item);
}
chaining->session_id = session_id;
chaining->session_addr = session_addr;
return chaining;
}
void selected_chaining_destory(struct selected_chaining *chaining)
{
if (chaining)
{
if (chaining->chaining)
{
free(chaining->chaining);
chaining->chaining = NULL;
}
free(chaining);
chaining = NULL;
}
}
void selected_chaining_dump(struct selected_chaining *chaining)
{
if (chaining == NULL)
{
LOG_DEBUG("%s: selected_chaining: NULL", LOG_TAG_POLICY);
return;
}
LOG_DEBUG("%s: session %lu %s selected_chaining->chaining_size : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, chaining->chaining_size);
LOG_DEBUG("%s: session %lu %s selected_chaining->chaining_used : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, chaining->chaining_used);
for (int i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node = &(chaining->chaining[i]);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->policy_id : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->policy_id);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->traffic_type : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, traffic_type_to_string(node->traffic_type));
// sff
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sff_profile_id : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sff_profile_id);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sff_forward_type : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, forward_type_to_string(node->sff_forward_type));
// sf
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_profile_id : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_profile_id);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_need_skip : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_need_skip);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_action : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, session_action_to_string(node->sf_action));
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_action_reason : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, action_reason_to_string(node->sf_action_reason));
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->package_method : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, package_method_to_string(node->sf_connectivity.method));
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->int_vlan_tag : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_connectivity.int_vlan_tag);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->ext_vlan_tag : %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_connectivity.ext_vlan_tag);
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->dest_ip : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->sf_connectivity.dest_ip);
}
}
void selected_chaining_bref(struct selected_chaining *chaining)
{
if (chaining == NULL)
{
return;
}
char buff[4096] = {0};
int buff_used = 0;
int buff_size = sizeof(buff);
buff_used += snprintf(buff + buff_used, buff_size - buff_used, "chaining_size:%d, chaining_used:%d, {", chaining->chaining_size, chaining->chaining_used);
for (int i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node = &(chaining->chaining[i]);
if (buff_size - buff_used > 0)
{
if (i != 0)
{
buff_used += snprintf(buff + buff_used, buff_size - buff_used, ",");
}
buff_used += snprintf(buff + buff_used, buff_size - buff_used,
"\"node[%d]\":{\"skip\":%d,\"policy_id\":%d,\"sff_profile_id\":%d,\"sf_profile_id\":%d,\"traffic_type\":\"%s\",\"sff_forward_type\":\"%s\",\"sf_action\":\"%s\",\"reason\":\"%s\"}",
i, node->sf_need_skip, node->policy_id, node->sff_profile_id, node->sf_profile_id,
traffic_type_to_string(node->traffic_type), forward_type_to_string(node->sff_forward_type), session_action_to_string(node->sf_action), action_reason_to_string(node->sf_action_reason));
}
}
LOG_INFO("%s: session %lu %s selected_chaining_bref: %s}", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, buff);
}
void selected_chaining_uniq(struct selected_chaining *chaining)
{
if (chaining == NULL)
{
return;
}
// Selected Service Chaining Before Unique : [1,2,3,1,2]
// Selected Service Chaining After Unique : [1,2,3]
for (int i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node_i = &(chaining->chaining[i]);
for (int j = 0; j < i; j++)
{
struct selected_sf *node_j = &(chaining->chaining[j]);
if (node_i->sf_profile_id == node_j->sf_profile_id)
{
node_i->sf_need_skip = 1;
break;
}
}
}
}
// return NULL : error
// return !NULL : success
struct policy_enforcer *policy_enforcer_create(const char *instance, const char *profile, int thread_num, void *logger)
@@ -1261,15 +1402,11 @@ void policy_enforcer_destory(struct policy_enforcer *enforcer)
}
}
int policy_enforce_max_chaining_size(struct policy_enforcer *enforcer)
{
return enforcer->config.max_chaining_size;
}
// return 0 : success
// return -1 : error
int policy_enforcer_register(struct policy_enforcer *enforcer)
{
LOG_INFO("%s: register policy callback ...", LOG_TAG_POLICY);
enforcer->compile_table_id = Maat_table_register(enforcer->maat, "SERVICE_CHAINING_COMPILE");
if (enforcer->compile_table_id < 0)
{
@@ -1320,117 +1457,43 @@ int policy_enforcer_register(struct policy_enforcer *enforcer)
LOG_ERROR("%s: register SERVICE_FUNCTION_PROFILE plugin extension callbacks failed", LOG_TAG_POLICY);
return -1;
}
LOG_INFO("%s: register policy callback success", LOG_TAG_POLICY);
return 0;
}
// return NULL : error
// return !NULL : success
struct selected_chaining *selected_chaining_create(int chaining_size)
int policy_enforce_chaining_size(struct policy_enforcer *enforcer)
{
struct selected_chaining *chaining = (struct selected_chaining *)calloc(1, sizeof(struct selected_chaining));
assert(chaining);
chaining->chaining_used = 0;
chaining->chaining_size = chaining_size;
chaining->chaining = (struct selected_sf *)calloc(chaining->chaining_size, sizeof(struct selected_sf));
assert(chaining->chaining);
for (int i = 0; i < chaining->chaining_size; i++)
{
struct selected_sf *item = &(chaining->chaining[i]);
selected_sf_init(item);
}
return chaining;
return enforcer->config.max_chaining_size;
}
void selected_chaining_destory(struct selected_chaining *chaining)
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct raw_pkt_parser *parser, int policy_id, int dir_is_i2e)
{
if (chaining)
{
if (chaining->chaining)
{
free(chaining->chaining);
chaining->chaining = NULL;
}
free(chaining);
chaining = NULL;
}
}
void selected_chaining_dump(struct selected_chaining *chaining)
{
if (chaining == NULL)
{
LOG_DEBUG("%s: selected_chaining: NULL", LOG_TAG_POLICY);
return;
}
LOG_DEBUG("%s: selected_chaining->chaining_size : %d", LOG_TAG_POLICY, chaining->chaining_size);
LOG_DEBUG("%s: selected_chaining->chaining_used : %d", LOG_TAG_POLICY, chaining->chaining_used);
for (int i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node = &(chaining->chaining[i]);
LOG_DEBUG("%s: selected_chaining->node[%d]->policy_id : %d", LOG_TAG_POLICY, i, node->policy_id);
LOG_DEBUG("%s: selected_chaining->node[%d]->traffic_type : %s", LOG_TAG_POLICY, i, traffic_type_to_string(node->traffic_type));
// sff
LOG_DEBUG("%s: selected_chaining->node[%d]->sff_profile_id : %d", LOG_TAG_POLICY, i, node->sff_profile_id);
LOG_DEBUG("%s: selected_chaining->node[%d]->sff_forward_type : %s", LOG_TAG_POLICY, i, forward_type_to_string(node->sff_forward_type));
// sf
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_profile_id : %d", LOG_TAG_POLICY, i, node->sf_profile_id);
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_need_skip : %d", LOG_TAG_POLICY, i, node->sf_need_skip);
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_action : %s", LOG_TAG_POLICY, i, session_action_to_string(node->sf_action));
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_action_reason : %s", LOG_TAG_POLICY, i, session_action_reason_to_string(node->sf_action_reason));
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->package_method : %s", LOG_TAG_POLICY, i, package_method_to_string(node->sf_connectivity.method));
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->int_vlan_tag : %d", LOG_TAG_POLICY, i, node->sf_connectivity.int_vlan_tag);
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->ext_vlan_tag : %d", LOG_TAG_POLICY, i, node->sf_connectivity.ext_vlan_tag);
LOG_DEBUG("%s: selected_chaining->node[%d]->sf_connectivity->dest_ip : %s", LOG_TAG_POLICY, i, node->sf_connectivity.dest_ip);
}
}
void selected_chaining_bref(struct selected_chaining *chaining)
{
if (chaining == NULL)
{
return;
}
char buff[4096] = {0};
int buff_used = 0;
int buff_size = sizeof(buff);
buff_used += snprintf(buff + buff_used, buff_size - buff_used, "chaining_size:%d, chaining_used:%d, {", chaining->chaining_size, chaining->chaining_used);
for (int i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node = &(chaining->chaining[i]);
if (buff_size - buff_used > 0)
{
buff_used += snprintf(buff + buff_used, buff_size - buff_used, "\"node[%d]\":{\"skip\":%d,\"reason\":\"%s\",\"policy_id\":%d,\"sff_profile_id\":%d,\"sf_profile_id\":%d,\"sff_forward_type\":\"%s\"}, ", i, node->sf_need_skip, session_action_reason_to_string(node->sf_action_reason), node->policy_id, node->sff_profile_id, node->sf_profile_id, forward_type_to_string(node->sff_forward_type));
}
}
LOG_DEBUG("%s: selected_chaining_bref: %s}", LOG_TAG_POLICY, buff);
}
void policy_enforce_select_chaining(struct selected_chaining *chaining, struct policy_enforcer *enforcer, struct raw_pkt_parser *parser, int policy_id, int dir_is_internal, struct session_ctx *s_ctx)
{
struct thread_ctx *thread = (struct thread_ctx *)s_ctx->ref_thread_ctx;
struct global_metrics *g_metrics = thread->ref_metrics;
uint64_t hash_value = 0;
char buffer[16] = {0};
struct sf_param *sf_param = NULL;
struct sff_param *sff_param = NULL;
struct fixed_num_array array = {0};
struct chaining_param *chaining_param = NULL;
struct selected_chaining *chaining = NULL;
snprintf(buffer, sizeof(buffer), "%d", policy_id);
chaining_param = (struct chaining_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->compile_table_id, buffer);
if (chaining_param == NULL)
{
LOG_ERROR("%s: failed to get chaining parameter of policy %d", LOG_TAG_POLICY, policy_id);
LOG_ERROR("%s: session %lu %s failed to get chaining parameter of policy %d", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, policy_id);
return;
}
LOG_DEBUG("%s: enforce chaining policy %d", LOG_TAG_POLICY, policy_id);
if (chaining_param->traffic_type == TRAFFIC_TYPE_RAW)
{
chaining = chainings->chaining_raw;
}
else
{
chaining = chainings->chaining_decrypted;
}
LOG_INFO("%s: session %lu %s enforce %s chaining policy %d", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, traffic_type_to_string(chaining_param->traffic_type), policy_id);
for (int i = 0; i < chaining_param->sff_profile_ids_num && chaining->chaining_used < chaining->chaining_size; i++)
{
@@ -1447,19 +1510,18 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p
sff_param = (struct sff_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sff_table_id, buffer);
if (sff_param == NULL)
{
LOG_ERROR("%s: failed to get sff parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, item->sff_profile_id);
LOG_ERROR("%s: session %lu %s failed to get sff parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, item->sff_profile_id);
item->sf_action = SESSION_ACTION_BYPASS;
item->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY;
chaining->chaining_used++;
continue;
}
item->sff_forward_type = sff_param->sff_forward_type;
LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (before filter nearby and active)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, sff_param->sf_profile_ids_num);
memset(&array, 0, sizeof(array));
fixed_num_array_init(&array);
select_sf_by_nearby_and_active(enforcer, sff_param, &array);
LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (after filter nearby and active)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, fixed_num_array_count_elem(&array));
select_sf_by_nearby_and_adminstatus(enforcer, sff_param, &array);
LOG_DEBUG("%s: session %lu %s select sf from chaining policy %d sff_profile %d, sf_profile_num (before filter: %d -> filter nearby/admin_status: %d)", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, policy_id, item->sff_profile_id, sff_param->sf_profile_ids_num, fixed_num_array_count_elem(&array));
if (fixed_num_array_count_elem(&array) == 0)
{
switch (sff_param->sff_exception.fail_action)
@@ -1485,15 +1547,14 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p
}
break;
}
LOG_DEBUG("%s: chaining policy %d -> sff_profile %d, no sf available after filtering by 'nearby & active', %s", LOG_TAG_POLICY, policy_id, item->sff_profile_id, session_action_reason_to_string(item->sf_action_reason));
LOG_DEBUG("%s: session %lu %s select sf frome chaining policy %d sff_profile %d, no sf available after filtering by 'nearby & admin_status', %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, policy_id, item->sff_profile_id, action_reason_to_string(item->sf_action_reason));
chaining->chaining_used++;
sff_param_free(sff_param);
continue;
}
hash_value = raw_packet_parser_get_hash_value(parser, sff_param->sff_ldbc.method, dir_is_internal);
item->sf_action = select_sf_by_ldbc(hash_value, enforcer, sff_param, &array, &(item->sf_profile_id), &(item->sf_action_reason), item->sf_dst_mac, s_ctx);
LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (after filter ldbc)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, fixed_num_array_count_elem(&array));
hash_value = raw_packet_parser_get_hash_value(parser, sff_param->sff_ldbc.method, dir_is_i2e);
item->sf_action = select_sf_by_ldbc(enforcer, s_ctx, sff_param, item, &array, hash_value);
if (item->sf_action != SESSION_ACTION_FORWARD)
{
chaining->chaining_used++;
@@ -1506,7 +1567,7 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p
sf_param = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer);
if (sf_param == NULL)
{
LOG_ERROR("%s: failed to get sf parameter of selected profile %d, bypass current sff !!!", LOG_TAG_POLICY, item->sf_profile_id);
LOG_ERROR("%s: session %lu %s failed to get sf parameter of profile %d, bypass current sff !!!", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, item->sf_profile_id);
item->sf_action = SESSION_ACTION_BYPASS;
item->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY;
chaining->chaining_used++;
@@ -1514,33 +1575,14 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p
continue;
}
item->sf_connectivity.method = sf_param->sf_connectivity.method;
item->sf_connectivity.int_vlan_tag = sf_param->sf_connectivity.int_vlan_tag;
item->sf_connectivity.ext_vlan_tag = sf_param->sf_connectivity.ext_vlan_tag;
memcpy(item->sf_connectivity.dest_ip, sf_param->sf_connectivity.dest_ip, strlen(sf_param->sf_connectivity.dest_ip));
connectivity_copy(&item->sf_connectivity, &sf_param->sf_connectivity);
memcpy(item->sf_dst_ip, sf_param->sf_connectivity.dest_ip, strlen(sf_param->sf_connectivity.dest_ip));
chaining->chaining_used++;
sf_param_free(sf_param);
sff_param_free(sff_param);
}
// Selected Service Chaining Before Unique : [1,2,3,1,2]
// Selected Service Chaining After Unique : [1,2,3]
for (int i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node_i = &(chaining->chaining[i]);
for (int j = 0; j < i; j++)
{
struct selected_sf *node_j = &(chaining->chaining[j]);
if (node_i->sf_profile_id == node_j->sf_profile_id)
{
node_i->sf_need_skip = 1;
break;
}
}
}
selected_chaining_uniq(chaining);
chaining_param_free(chaining_param);
}