TSG-13684 tsg-service-chaining-engine使用VLAN封装Packet并执行Traffic Mirroring

This commit is contained in:
luwenpeng
2023-10-18 10:08:10 +08:00
parent 18561bc4fe
commit 0753e8018c
57 changed files with 1784 additions and 1175 deletions

View File

@@ -7,7 +7,7 @@
#include "global_metrics.h"
#include "health_check.h"
#include "raw_packet.h"
#include "data_packet.h"
#include "policy.h"
#include "utils.h"
#include "log.h"
@@ -800,24 +800,24 @@ static void sf_param_new_cb(const char *table_name, int table_id, const char *ke
}
if (0 == strcasecmp(item->valuestring, "layer2_switch"))
{
param->sf_connectivity.method = PACKAGE_METHOD_LAYER2_SWITCH;
param->sf_connectivity.method = ENCAPSULATE_METHOD_LAYER2_SWITCH;
}
else if (0 == strcasecmp(item->valuestring, "layer3_switch"))
{
param->sf_connectivity.method = PACKAGE_METHOD_LAYER3_SWITCH;
param->sf_connectivity.method = ENCAPSULATE_METHOD_LAYER3_SWITCH;
}
else if (0 == strcasecmp(item->valuestring, "vxlan_g"))
{
param->sf_connectivity.method = PACKAGE_METHOD_VXLAN_G;
param->sf_connectivity.method = ENCAPSULATE_METHOD_VXLAN_G;
}
else
{
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, package_method_to_string(param->sf_connectivity.method));
LOG_DEBUG("%s: parse sf profile: %d, connectivity->method: %s", LOG_TAG_POLICY, param->sf_profile_id, encapsulate_method_to_string(param->sf_connectivity.method));
if (param->sf_connectivity.method == PACKAGE_METHOD_LAYER2_SWITCH || param->sf_connectivity.method == PACKAGE_METHOD_LAYER3_SWITCH)
if (param->sf_connectivity.method == ENCAPSULATE_METHOD_LAYER2_SWITCH || param->sf_connectivity.method == ENCAPSULATE_METHOD_LAYER3_SWITCH)
{
item = cJSON_GetObjectItem(root1, "int_vlan_tag");
if (!item || !cJSON_IsNumber(item))
@@ -837,7 +837,7 @@ static void sf_param_new_cb(const char *table_name, int table_id, const char *ke
param->sf_connectivity.ext_vlan_tag = item->valueint;
LOG_DEBUG("%s: parse sf profile: %d, connectivity->ext_vlan_tag: %d", LOG_TAG_POLICY, param->sf_profile_id, item->valueint);
}
else if (param->sf_connectivity.method == PACKAGE_METHOD_VXLAN_G)
else if (param->sf_connectivity.method == ENCAPSULATE_METHOD_VXLAN_G)
{
item = cJSON_GetObjectItem(root1, "dest_ip");
if (!item || !cJSON_IsString(item))
@@ -885,8 +885,8 @@ static void sf_param_new_cb(const char *table_name, int table_id, const char *ke
}
LOG_DEBUG("%s: parse sf profile: %d, health_check->method: %s", LOG_TAG_POLICY, param->sf_profile_id, item->valuestring);
if ((param->sf_health_check.method == HEALTH_CHECK_METHOD_BFD && param->sf_connectivity.method == PACKAGE_METHOD_VXLAN_G) ||
(param->sf_health_check.method == HEALTH_CHECK_METHOD_NONE && param->sf_connectivity.method == PACKAGE_METHOD_VXLAN_G))
if ((param->sf_health_check.method == HEALTH_CHECK_METHOD_BFD && param->sf_connectivity.method == ENCAPSULATE_METHOD_VXLAN_G) ||
(param->sf_health_check.method == HEALTH_CHECK_METHOD_NONE && param->sf_connectivity.method == ENCAPSULATE_METHOD_VXLAN_G))
{
memcpy(param->sf_health_check.address, param->sf_connectivity.dest_ip, strlen(param->sf_connectivity.dest_ip));
}
@@ -923,7 +923,10 @@ static void sf_param_new_cb(const char *table_name, int table_id, const char *ke
param->sf_health_check.retires = item->valueint;
LOG_DEBUG("%s: parse sf profile: %d, health_check->retires: %d", LOG_TAG_POLICY, param->sf_profile_id, item->valueint);
}
param->health_check_session_id = health_check_session_add(param->sf_profile_id, param->sf_vsys_id, &param->sf_health_check);
if (param->sf_connectivity.method != ENCAPSULATE_METHOD_LAYER2_SWITCH)
{
param->health_check_session_id = health_check_session_add(param->sf_profile_id, param->sf_vsys_id, &param->sf_health_check);
}
*ad = param;
LOG_INFO("%s: Add sf profile: %d", LOG_TAG_POLICY, param->sf_profile_id);
@@ -969,7 +972,10 @@ static void sf_param_free_cb(int table_id, void **ad, long argl, void *argp)
if ((__sync_sub_and_fetch(&param->sf_ref_cnt, 1) == 0))
{
health_check_session_del(param->health_check_session_id, param->sf_profile_id);
if (param->sf_connectivity.method != ENCAPSULATE_METHOD_LAYER2_SWITCH)
{
health_check_session_del(param->health_check_session_id, param->sf_profile_id);
}
LOG_INFO("%s: Del sf profile: %d", LOG_TAG_POLICY, param->sf_profile_id);
free(param);
param = NULL;
@@ -998,7 +1004,7 @@ static void sf_param_free(struct sf_param *param)
}
// 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 fixed_num_array *array)
static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer, struct sff_param *sff_param, struct mutable_array *array)
{
char buffer[16];
struct sf_param *sf = NULL;
@@ -1022,7 +1028,7 @@ static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
fixed_num_array_add_elem(array, sff_param->sf_profile_ids[i]);
mutable_array_add_elem(array, sff_param->sf_profile_ids[i]);
}
}
}
@@ -1032,7 +1038,7 @@ static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
fixed_num_array_add_elem(array, sff_param->sf_profile_ids[i]);
mutable_array_add_elem(array, sff_param->sf_profile_ids[i]);
}
}
}
@@ -1041,7 +1047,7 @@ static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer
{
if (sf->sf_admin_status == ADMMIN_STATUS_ACTIVE)
{
fixed_num_array_add_elem(array, sff_param->sf_profile_ids[i]);
mutable_array_add_elem(array, sff_param->sf_profile_ids[i]);
}
}
sf_param_free(sf);
@@ -1051,7 +1057,7 @@ static void select_sf_by_nearby_and_adminstatus(struct policy_enforcer *enforcer
// 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 fixed_num_array *array, uint64_t hash)
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;
@@ -1063,13 +1069,14 @@ static enum session_action select_sf_by_ldbc(struct policy_enforcer *enforcer, s
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 = fixed_num_array_count_elem(array);
sf_profile_num = mutable_array_count_elem(array);
while (sf_profile_num)
{
sf_profile_index = (int)(hash % sf_profile_num);
sf_profile_id = fixed_num_array_index_elem(array, sf_profile_index);
sf_profile_id = mutable_array_index_elem(array, sf_profile_index);
memset(&buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%u", sf_profile_id);
@@ -1077,13 +1084,26 @@ static enum session_action select_sf_by_ldbc(struct policy_enforcer *enforcer, s
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);
mutable_array_del_elem(array, sf_profile_id);
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)
{
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;
}
// 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));
@@ -1098,8 +1118,8 @@ static enum session_action select_sf_by_ldbc(struct policy_enforcer *enforcer, s
if (sff_param->sff_exception.fail_action == FAILURE_ACTION_RE_DISPATCH)
{
fixed_num_array_del_elem(array, sf_profile_id);
sf_profile_num = fixed_num_array_count_elem(array);
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)
{
@@ -1248,17 +1268,17 @@ const char *action_reason_to_string(enum action_reason action_reason)
}
}
const char *package_method_to_string(enum package_method package_method)
const char *encapsulate_method_to_string(enum encapsulate_method encap_method)
{
switch (package_method)
switch (encap_method)
{
case PACKAGE_METHOD_NONE:
case ENCAPSULATE_METHOD_NONE:
return "none";
case PACKAGE_METHOD_LAYER2_SWITCH:
case ENCAPSULATE_METHOD_LAYER2_SWITCH:
return "layer2_switch";
case PACKAGE_METHOD_LAYER3_SWITCH:
case ENCAPSULATE_METHOD_LAYER3_SWITCH:
return "layer3_switch";
case PACKAGE_METHOD_VXLAN_G:
case ENCAPSULATE_METHOD_VXLAN_G:
return "vxlan_g";
default:
return "unknown";
@@ -1315,20 +1335,20 @@ void selected_chaining_dump(struct selected_chaining *chaining)
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]->rule_id : %lu", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->rule_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));
LOG_DEBUG("%s: session %lu %s selected_chaining->node[%d]->rule_id : %lu", LOG_TAG_POLICY, chaining->session_id, chaining->session_addr, i, node->rule_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));
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);
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->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);
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);
}
}
@@ -1585,13 +1605,13 @@ int policy_enforce_chaining_size(struct policy_enforcer *enforcer)
return enforcer->config.max_chaining_size;
}
void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct selected_chainings *chainings, struct session_ctx *s_ctx, struct raw_pkt_parser *parser, uint64_t rule_id, int dir_is_i2e)
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 fixed_num_array array = {0};
struct mutable_array array = {0};
struct chaining_param *chaining_param = NULL;
struct selected_chaining *chaining = NULL;
@@ -1638,10 +1658,10 @@ void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct se
item->sff_forward_type = sff_param->sff_forward_type;
memset(&array, 0, sizeof(array));
fixed_num_array_init(&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, fixed_num_array_count_elem(&array));
if (fixed_num_array_count_elem(&array) == 0)
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)
{
@@ -1672,7 +1692,7 @@ void policy_enforce_select_chainings(struct policy_enforcer *enforcer, struct se
continue;
}
hash_value = raw_packet_parser_get_hash_value(parser, sff_param->sff_ldbc.method, dir_is_i2e);
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)
{