perf: 优化策略扫描

This commit is contained in:
luwenpeng
2023-11-03 10:02:50 +08:00
parent 0753e8018c
commit 3627addb85
5 changed files with 1456 additions and 332 deletions

View File

@@ -12,6 +12,7 @@
#include "utils.h"
#include "log.h"
#include "sce.h"
#include "utarray.h"
/******************************************************************************
* Struct policy_enforcer
@@ -165,7 +166,7 @@ struct sf_param
};
/******************************************************************************
* Private API
* Private API -- Utils
******************************************************************************/
static const char *effective_type_to_string(enum effective_type type)
@@ -310,6 +311,10 @@ static void policy_enforcer_config(const char *profile, struct policy_config *co
LOG_DEBUG("%s: MAAT->max_chaining_size : %d", LOG_TAG_POLICY, config->max_chaining_size);
}
/******************************************************************************
* Private API -- MAAT Callback
******************************************************************************/
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)
{
int iter = 0;
@@ -1003,199 +1008,261 @@ static void sf_param_free(struct sf_param *param)
sf_param_free_cb(0, (void **)&param, 0, NULL);
}
// After return must check array elem nums
static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct mutable_array *array)
/******************************************************************************
* Private API -- Selected SF
******************************************************************************/
static void selected_sf_init(struct selected_sf *selected_sf)
{
char buffer[16];
struct sf_param *sf = NULL;
if (selected_sf)
{
memset(selected_sf, 0, sizeof(struct selected_sf));
selected_sf->rule_vsys_id = 0;
selected_sf->rule_id = 0;
selected_sf->traffic_type = TRAFFIC_TYPE_NONE;
selected_sf->sff_profile_id = -1;
selected_sf->sff_forward_type = FORWARD_TYPE_NONE;
selected_sf->sf_profile_id = -1;
selected_sf->sf_action = SESSION_ACTION_BYPASS;
selected_sf->sf_action_desc = ACTION_BYPASS_DUE_DEFAULT;
}
}
static void selected_sf_set_info(struct selected_sf *selected_sf, struct sf_param *sf_param)
{
selected_sf->sf_vsys_id = sf_param->sf_vsys_id;
selected_sf->sf_profile_id = sf_param->sf_profile_id;
selected_sf->sf_connectivity = sf_param->sf_connectivity;
if (selected_sf->sf_connectivity.method == ENCAPSULATE_METHOD_VXLAN_G)
{
selected_sf->sf_dst_ip = inet_addr(selected_sf->sf_connectivity.dest_ip);
}
}
static void selected_sf_set_action(struct selected_sf *selected_sf, enum action_desc action_desc)
{
selected_sf->sf_action_desc = action_desc;
switch (action_desc)
{
case ACTION_BYPASS_DUE_DEFAULT:
case ACTION_BYPASS_DUE_INVALID_POLICY:
case ACTION_BYPASS_DUE_FAILURE_ACTION:
case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION:
case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT:
selected_sf->sf_action = SESSION_ACTION_BYPASS;
break;
case ACTION_BLOCK_DUE_FAILURE_ACTION:
case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION:
selected_sf->sf_action = SESSION_ACTION_BLOCK;
break;
case ACTION_FORWAED_DUE_SELECTED_SF:
selected_sf->sf_action = SESSION_ACTION_FORWARD;
break;
}
}
// return 1 : current sf can be selected
// return 0 : current sf can't be selected
static int select_sf_by_admin_status(struct sf_param *sf)
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
return 1;
}
else
{
return 0;
}
}
// return 1 : current sf can be selected
// return 0 : current sf can't be selected
static int select_sf_by_device_group(struct policy_enforcer *enforcer, struct sf_param *sf)
{
if (strcasecmp(enforcer->config.device_group, sf->sf_effective_range.value) == 0)
{
return 1;
}
else
{
return 0;
}
}
// return 1 : current sf can be selected
// return 0 : current sf can't be selected
static int select_sf_by_data_center(struct policy_enforcer *enforcer, struct sf_param *sf)
{
if (strcasecmp(enforcer->config.data_center, sf->sf_effective_range.value) == 0)
{
return 1;
}
else
{
return 0;
}
}
// return 1 : current sf can be selected
// return 0 : current sf can't be selected
static int select_sf_by_localization(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct sf_param *sf)
{
if (sff_param->sff_ldbc.localiza == LDBC_LOCALIZATION_NEARBY)
{
if (sf->sf_effective_range.type == EFFECTIVE_TYPE_DEVICE_GROUP)
{
return select_sf_by_device_group(enforcer, sf);
}
else
{
return select_sf_by_data_center(enforcer, sf);
}
}
else
{
return 1;
}
}
// return 1 : current sf can be selected
// return 0 : current sf can't be selected
static int handle_fail_action(struct exception *sff_exception, struct selected_sf *selected_sf, int sf_num)
{
if (sff_exception->fail_action == FAILURE_ACTION_RE_DISPATCH)
{
if (sff_exception->health_service_func_lt > 0 && sf_num < sff_exception->health_service_func_lt)
{
selected_sf_set_action(selected_sf, ACTION_BYPASS_DUE_HEALTH_SF_LIMIT);
return 1;
}
else
{
if (sf_num == 0)
{
if (sff_exception->unavail_action == UNAVAILABLE_ACTION_BYPASSS)
{
selected_sf_set_action(selected_sf, ACTION_BYPASS_DUE_UNAVAILABLE_ACTION);
return 1;
}
else
{
selected_sf_set_action(selected_sf, ACTION_BLOCK_DUE_UNAVAILABLE_ACTION);
return 1;
}
}
else
{
return 0;
}
}
}
else if (sff_exception->fail_action == FAILURE_ACTION_BYPASS)
{
selected_sf_set_action(selected_sf, ACTION_BYPASS_DUE_FAILURE_ACTION);
return 1;
}
else if (sff_exception->fail_action == FAILURE_ACTION_BLOCK)
{
selected_sf_set_action(selected_sf, ACTION_BLOCK_DUE_FAILURE_ACTION);
return 1;
}
else
{
return 0;
}
}
static void select_sf_by_ldbc(struct sff_param *sff_param, struct selected_sf *selected_sf, struct session_ctx *s_ctx, UT_array *sf_array, uint64_t hash)
{
struct thread_metrics *thread_metrics = &s_ctx->ref_thread_ctx->thread_metrics;
while (utarray_len(sf_array))
{
unsigned int sf_index = (unsigned int)(hash % utarray_len(sf_array));
struct sf_param *sf_param = (struct sf_param *)utarray_eltptr(sf_array, sf_index);
if (sf_param->sf_connectivity.method == ENCAPSULATE_METHOD_LAYER2_SWITCH)
{
LOG_INFO("%s: session %lu %s select sf by ldbc, sf_profile_id %d to be selected", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, sf_param->sf_profile_id);
selected_sf_set_action(selected_sf, ACTION_FORWAED_DUE_SELECTED_SF);
selected_sf_set_info(selected_sf, sf_param);
return;
}
memset(selected_sf->sf_dst_mac, 0, sizeof(selected_sf->sf_dst_mac));
if (health_check_session_get_mac(sf_param->health_check_session_id, selected_sf->sf_dst_mac) == 0)
{
ATOMIC_INC(&(thread_metrics->sf_status.active));
LOG_INFO("%s: session %lu %s select sf by ldbc, sf_profile_id %d to be selected", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, sf_param->sf_profile_id);
selected_sf_set_action(selected_sf, ACTION_FORWAED_DUE_SELECTED_SF);
selected_sf_set_info(selected_sf, sf_param);
return;
}
else
{
ATOMIC_INC(&(thread_metrics->sf_status.inactive));
if (handle_fail_action(&sff_param->sff_exception, selected_sf, utarray_len(sf_array) - 1) == 0)
{
LOG_INFO("%s: session %lu %s select sf by re-dispatch, sf_profile_id %d to be excluded", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, sf_param->sf_profile_id);
utarray_erase(sf_array, sf_index, 1);
continue;
}
else
{
LOG_INFO("%s: session %lu %s select sf by fail-action, sf_profile_id %d to be selected", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, sf_param->sf_profile_id);
selected_sf_set_info(selected_sf, sf_param);
return;
}
}
}
handle_fail_action(&sff_param->sff_exception, selected_sf, 0);
}
static void select_sf_from_sff(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct selected_sf *selected_sf, struct session_ctx *s_ctx, uint64_t packet_hash)
{
UT_array *sf_array;
UT_icd sf_icd = {sizeof(struct sf_param), NULL, NULL, NULL};
utarray_new(sf_array, &sf_icd);
for (int i = 0; i < sff_param->sf_profile_ids_num; i++)
{
memset(&buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%u", sff_param->sf_profile_ids[i]);
sf = (struct sf_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->sf_table_id, buffer, strlen(buffer));
char profile_id[16] = {0};
snprintf(profile_id, sizeof(profile_id), "%u", sff_param->sf_profile_ids[i]);
struct sf_param *sf = (struct sf_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->sf_table_id, profile_id, strlen(profile_id));
if (sf == NULL)
{
LOG_ERROR("%s: failed to get sf parameter of profile %d", LOG_TAG_POLICY, sff_param->sf_profile_ids[i]);
continue;
}
if (sff_param->sff_ldbc.localiza == LDBC_LOCALIZATION_NEARBY)
if (select_sf_by_admin_status(sf) == 0)
{
if (sf->sf_effective_range.type == EFFECTIVE_TYPE_DEVICE_GROUP)
{
if (strcasecmp(enforcer->config.device_group, sf->sf_effective_range.value) == 0)
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
mutable_array_add_elem(array, sff_param->sf_profile_ids[i]);
}
}
}
else
{
if (strcasecmp(enforcer->config.data_center, sf->sf_effective_range.value) == 0)
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
mutable_array_add_elem(array, sff_param->sf_profile_ids[i]);
}
}
}
}
else
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
mutable_array_add_elem(array, sff_param->sf_profile_ids[i]);
}
}
sf_param_free(sf);
}
}
// 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(struct policy_enforcer *enforcer, struct session_ctx *s_ctx, struct sff_param *sff_param, struct selected_sf *sf, struct mutable_array *array, uint64_t hash)
{
struct thread_ctx *thread = (struct thread_ctx *)s_ctx->ref_thread_ctx;
struct thread_metrics *thread_metrics = &thread->thread_metrics;
struct sf_param *sf_param = NULL;
char buffer[16];
sf->sf_profile_id = -1;
int sf_profile_id = 0;
int sf_profile_index = 0;
int sf_profile_num = 0;
uint64_t health_check_session_id = 0;
enum encapsulate_method encap_method;
sf_profile_num = mutable_array_count_elem(array);
while (sf_profile_num)
{
sf_profile_index = (int)(hash % sf_profile_num);
sf_profile_id = mutable_array_index_elem(array, sf_profile_index);
memset(&buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%u", sf_profile_id);
sf_param = (struct sf_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->sf_table_id, buffer, strlen(buffer));
if (sf_param == NULL)
{
LOG_ERROR("%s: failed to get sf parameter of profile %d", LOG_TAG_POLICY, sf_profile_id);
mutable_array_del_elem(array, sf_profile_id);
LOG_INFO("%s: session %lu %s select sf by admin-status, sf_profile_id %d to be excluded", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, sf->sf_profile_id);
sf_param_free(sf);
continue;
}
health_check_session_id = sf_param->health_check_session_id;
encap_method = sf_param->sf_connectivity.method;
sf_param_free(sf_param);
memset(sf->sf_dst_mac, 0, sizeof(sf->sf_dst_mac));
// VLAN encapsulation not require health check
if (encap_method == ENCAPSULATE_METHOD_LAYER2_SWITCH)
if (select_sf_by_localization(enforcer, sff_param, sf) == 0)
{
ATOMIC_INC(&(thread_metrics->sf_status.active));
sf->sf_profile_id = sf_profile_id;
sf->sf_action_reason = ACTION_FORWAED_DUE_SELECTED_SF;
return SESSION_ACTION_FORWARD;
LOG_INFO("%s: session %lu %s select sf by localization, sf_profile_id %d to be excluded", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, sf->sf_profile_id);
sf_param_free(sf);
continue;
}
// VXLAN encapsulation require health check
if (health_check_session_get_mac(health_check_session_id, sf->sf_dst_mac) == 0)
{
ATOMIC_INC(&(thread_metrics->sf_status.active));
sf->sf_profile_id = sf_profile_id;
sf->sf_action_reason = ACTION_FORWAED_DUE_SELECTED_SF;
return SESSION_ACTION_FORWARD;
}
else
{
ATOMIC_INC(&(thread_metrics->sf_status.inactive));
if (sff_param->sff_exception.fail_action == FAILURE_ACTION_RE_DISPATCH)
{
mutable_array_del_elem(array, sf_profile_id);
sf_profile_num = mutable_array_count_elem(array);
if (sff_param->sff_exception.health_service_func_lt > 0 && sf_profile_num < sff_param->sff_exception.health_service_func_lt)
{
sf->sf_action_reason = ACTION_BYPASS_DUE_HEALTH_SF_LIMIT;
return SESSION_ACTION_BYPASS;
}
else
{
if (sf_profile_num == 0)
{
if (sff_param->sff_exception.unavail_action == UNAVAILABLE_ACTION_BYPASSS)
{
sf->sf_action_reason = ACTION_BYPASS_DUE_UNAVAILABLE_ACTION;
return SESSION_ACTION_BYPASS;
}
else
{
sf->sf_action_reason = ACTION_BLOCK_DUE_UNAVAILABLE_ACTION;
return SESSION_ACTION_BLOCK;
}
}
else
{
continue;
}
}
}
else if (sff_param->sff_exception.fail_action == FAILURE_ACTION_BYPASS)
{
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)
{
sf->sf_profile_id = sf_profile_id;
sf->sf_action_reason = ACTION_BLOCK_DUE_FAILURE_ACTION;
return SESSION_ACTION_BLOCK;
}
}
};
sf->sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY;
return SESSION_ACTION_BYPASS;
}
static void selected_sf_init(struct selected_sf *item)
{
if (item)
{
memset(item, 0, sizeof(struct selected_sf));
item->rule_vsys_id = 0;
item->rule_id = 0;
item->traffic_type = TRAFFIC_TYPE_NONE;
item->sff_profile_id = -1;
item->sff_forward_type = FORWARD_TYPE_NONE;
item->sf_need_skip = 0;
item->sf_profile_id = -1;
item->sf_action = SESSION_ACTION_BYPASS;
item->sf_action_reason = ACTION_BYPASS_DUE_DEFAULT;
utarray_push_back(sf_array, sf);
sf_param_free(sf);
}
}
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));
}
select_sf_by_ldbc(sff_param, selected_sf, s_ctx, sf_array, packet_hash);
utarray_free(sf_array);
}
/******************************************************************************
* Public API
* Public API -- Utils
******************************************************************************/
const char *traffic_type_to_string(enum traffic_type traffic_type)
@@ -1228,41 +1295,26 @@ const char *forward_type_to_string(enum forward_type forward_type)
}
}
const char *session_action_to_string(enum session_action session_action)
const char *action_desc_to_string(enum action_desc action_desc)
{
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)
switch (action_desc)
{
case ACTION_BYPASS_DUE_DEFAULT:
return "bypass_due_default";
return "bypass(default)";
case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT:
return "bypass_due_health_sf_limit";
return "bypass(health_sf_limit)";
case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION:
return "bypass_due_unavailable_action";
return "bypass(unavailable_action)";
case ACTION_BYPASS_DUE_FAILURE_ACTION:
return "bypass_due_failure_action";
return "bypass(failure_action)";
case ACTION_BYPASS_DUE_INVALID_POLICY:
return "bypass_due_invalid_policy";
return "bypass(invalid_policy)";
case ACTION_BLOCK_DUE_UNAVAILABLE_ACTION:
return "block_due_unavailable_action";
return "block(unavailable_action)";
case ACTION_BLOCK_DUE_FAILURE_ACTION:
return "block_due_failure_action";
return "block(failure_action)";
case ACTION_FORWAED_DUE_SELECTED_SF:
return "forward_due_selected_sf";
return "forward(selected_sf)";
default:
return "unknown";
}
@@ -1285,6 +1337,10 @@ const char *encapsulate_method_to_string(enum encapsulate_method encap_method)
}
}
/******************************************************************************
* Public API -- Selected Chaining
******************************************************************************/
// return NULL : error
// return !NULL : success
struct selected_chaining *selected_chaining_create(int chaining_size, uint64_t session_id, char *session_addr)
@@ -1342,9 +1398,7 @@ void selected_chaining_dump(struct selected_chaining *chaining)
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_action_desc : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, action_desc_to_string(node->sf_action_desc));
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->sf_connectivity->encapsulate_method : %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, encapsulate_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);
@@ -1373,9 +1427,9 @@ void selected_chaining_bref(struct selected_chaining *chaining)
buff_used += snprintf(buff + buff_used, buff_size - buff_used, ",");
}
buff_used += snprintf(buff + buff_used, buff_size - buff_used,
"\"node[%d]\":{\"skip\":%d,\"rule_id\":%lu,\"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->rule_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));
"\"node[%d]\":{\"policy\":\"%lu->%d->%d\",\"action\":\"%s->%s->%s\"}",
i, node->rule_id, node->sff_profile_id, node->sf_profile_id,
traffic_type_to_string(node->traffic_type), forward_type_to_string(node->sff_forward_type), action_desc_to_string(node->sf_action_desc));
}
}
LOG_INFO("%s: session %lu %s selected_chaining_bref: %s}", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, buff);
@@ -1390,21 +1444,44 @@ void selected_chaining_uniq(struct selected_chaining *chaining)
// 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++)
int i = 0;
int j = 0;
int k = 0;
int is_exist = 0;
for (i = 0; i < chaining->chaining_used; i++)
{
struct selected_sf *node_i = &(chaining->chaining[i]);
for (int j = 0; j < i; j++)
is_exist = 0;
for (j = 0; j < i; j++)
{
struct selected_sf *node_j = &(chaining->chaining[j]);
if (node_i->sf_profile_id == node_j->sf_profile_id)
if (chaining->chaining[i].sf_profile_id == chaining->chaining[j].sf_profile_id && chaining->chaining[i].sf_action == chaining->chaining[j].sf_action)
{
node_i->sf_need_skip = 1;
is_exist = 1;
break;
}
}
if (is_exist == 0)
{
if (i != k)
{
memcpy(&(chaining->chaining[k]), &(chaining->chaining[i]), sizeof(struct selected_sf));
}
k++;
}
}
chaining->chaining_used = k;
// Selected Service Chaining After Unique : [1,2,3,1,2] -> [1,2,3,0,0]
for (i = chaining->chaining_used; i < chaining->chaining_size; i++)
{
selected_sf_init(&(chaining->chaining[i]));
}
}
/******************************************************************************
* Public API -- Policy Enforcer
******************************************************************************/
// return NULL : error
// return !NULL : success
struct policy_enforcer *policy_enforcer_create(const char *instance, const char *profile, int thread_num, void *logger)
@@ -1607,16 +1684,11 @@ int policy_enforce_chaining_size(struct policy_enforcer *enforcer)
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct data_packet *data_pkt, uint64_t rule_id, int dir_is_i2e)
{
uint64_t hash_value = 0;
char buffer[16] = {0};
struct sf_param *sf_param = NULL;
struct sff_param *sff_param = NULL;
struct mutable_array array = {0};
struct chaining_param *chaining_param = NULL;
struct selected_chaining *chaining = NULL;
snprintf(buffer, sizeof(buffer), "%lu", rule_id);
chaining_param = (struct chaining_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->compile_table_id, buffer, strlen(buffer));
struct chaining_param *chaining_param = (struct chaining_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->compile_table_id, buffer, strlen(buffer));
if (chaining_param == NULL)
{
LOG_ERROR("%s: session %lu %s failed to get chaining parameter of policy %lu", LOG_TAG_POLICY, s_ctx->session_id, s_ctx->session_addr, rule_id);
@@ -1631,95 +1703,44 @@ void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct se
{
chaining = chainings->chaining_decrypted;
}
LOG_INFO("%s: session %lu %s enforce %s chaining rule %lu", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, traffic_type_to_string(chaining_param->traffic_type), rule_id);
LOG_INFO("%s: session %lu %s enforce %s chaining: rule_id %lu", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, traffic_type_to_string(chaining_param->traffic_type), rule_id);
for (int i = 0; i < chaining_param->sff_profile_ids_num && chaining->chaining_used < chaining->chaining_size; i++)
{
struct selected_sf *item = &(chaining->chaining[chaining->chaining_used]);
selected_sf_init(item);
item->rule_id = rule_id;
item->rule_vsys_id = chaining_param->vsys_id;
item->traffic_type = chaining_param->traffic_type;
item->sff_profile_id = chaining_param->sff_profile_ids[i];
item->sf_index = chaining->chaining_used;
struct selected_sf *selected_sf = &(chaining->chaining[chaining->chaining_used]);
selected_sf_init(selected_sf);
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%u", item->sff_profile_id);
sff_param = (struct sff_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->sff_table_id, buffer, strlen(buffer));
snprintf(buffer, sizeof(buffer), "%u", chaining_param->sff_profile_ids[i]);
struct sff_param *sff_param = (struct sff_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->sff_table_id, buffer, strlen(buffer));
if (sff_param == NULL)
{
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;
memset(&array, 0, sizeof(array));
mutable_array_init(&array);
select_sf_by_nearby_and_adminstatus(enforcer, sff_param, &array);
LOG_DEBUG("%s: session %lu %s select sf from chaining rule %lu sff_profile %d, sf_profile_num (before filter: %d -> filter nearby/admin_status: %d)", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, rule_id, item->sff_profile_id, sff_param->sf_profile_ids_num, mutable_array_count_elem(&array));
if (mutable_array_count_elem(&array) == 0)
{
switch (sff_param->sff_exception.fail_action)
{
case FAILURE_ACTION_BYPASS:
item->sf_action = SESSION_ACTION_BYPASS;
item->sf_action_reason = ACTION_BYPASS_DUE_FAILURE_ACTION;
break;
case FAILURE_ACTION_BLOCK:
item->sf_action = SESSION_ACTION_BLOCK;
item->sf_action_reason = ACTION_BLOCK_DUE_FAILURE_ACTION;
break;
case FAILURE_ACTION_RE_DISPATCH:
if (sff_param->sff_exception.unavail_action == UNAVAILABLE_ACTION_BYPASSS)
{
item->sf_action = SESSION_ACTION_BYPASS;
item->sf_action_reason = ACTION_BYPASS_DUE_UNAVAILABLE_ACTION;
}
else // UNAVAILABLE_ACTION_BLOCK
{
item->sf_action = SESSION_ACTION_BLOCK;
item->sf_action_reason = ACTION_BLOCK_DUE_UNAVAILABLE_ACTION;
}
break;
}
LOG_DEBUG("%s: session %lu %s rule_id %lu sff_profile_id %d, no sf available after filtering by 'nearby & admin_status', %s", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, rule_id, item->sff_profile_id, action_reason_to_string(item->sf_action_reason));
chaining->chaining_used++;
sff_param_free(sff_param);
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, chaining_param->sff_profile_ids[i]);
continue;
}
hash_value = data_packet_get_hash(data_pkt, 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++;
sff_param_free(sff_param);
continue;
}
// sc info
selected_sf->rule_id = rule_id;
selected_sf->rule_vsys_id = chaining_param->vsys_id;
selected_sf->traffic_type = chaining_param->traffic_type;
memset(&buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%u", item->sf_profile_id);
sf_param = (struct sf_param *)maat_plugin_table_get_ex_data(enforcer->maat, enforcer->sf_table_id, buffer, strlen(buffer));
if (sf_param == NULL)
{
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++;
sff_param_free(sff_param);
continue;
}
// sff info
selected_sf->sff_profile_id = chaining_param->sff_profile_ids[i];
selected_sf->sff_forward_type = sff_param->sff_forward_type;
// sf_index
selected_sf->sf_index = chaining->chaining_used;
uint64_t packet_hash = data_packet_get_hash(data_pkt, sff_param->sff_ldbc.method, dir_is_i2e);
select_sf_from_sff(enforcer, sff_param, selected_sf, s_ctx, packet_hash);
LOG_INFO("%s: session %lu %s enforce chaining [%d/%d]: policy: %lu->%d->%d, action: %s->%s->%s",
LOG_TAG_POLICY, chaining->session_id, chaining->session_addr,
selected_sf->sf_index, chaining->chaining_size,
selected_sf->rule_id, selected_sf->sff_profile_id, selected_sf->sf_profile_id,
traffic_type_to_string(chaining_param->traffic_type), forward_type_to_string(selected_sf->sff_forward_type), action_desc_to_string(selected_sf->sf_action_desc));
item->sf_vsys_id = sf_param->sf_vsys_id;
connectivity_copy(&item->sf_connectivity, &sf_param->sf_connectivity);
item->sf_dst_ip = inet_addr(sf_param->sf_connectivity.dest_ip);
chaining->chaining_used++;
sf_param_free(sf_param);
sff_param_free(sff_param);
}