From 4465a1ce74f4a6109bacff3e475a55f3ea1990d7 Mon Sep 17 00:00:00 2001 From: songyanchao Date: Tue, 30 Apr 2024 09:58:10 +0000 Subject: ✨ feat(DPISDN-42): Add 'link_aware_injector' node. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add 'link_aware_injector' node. --- include/internal/adapter_define.h | 2 + infra/include/link_db.h | 3 +- infra/src/link_db.c | 30 +-- infra/test/TestLinkDb.cc | 36 ++-- service/CMakeLists.txt | 2 +- service/include/sc_node_common.h | 2 +- service/src/monit.c | 2 + service/src/node_etherfabric.c | 7 + service/src/node_forwarder.c | 34 +++- service/src/node_link_aware_injector.c | 343 +++++++++++++++++++++++++++++++++ service/src/node_vwire.c | 6 + 11 files changed, 417 insertions(+), 50 deletions(-) create mode 100644 service/src/node_link_aware_injector.c diff --git a/include/internal/adapter_define.h b/include/internal/adapter_define.h index 5e6e131..c103cb3 100644 --- a/include/internal/adapter_define.h +++ b/include/internal/adapter_define.h @@ -14,6 +14,8 @@ enum adapter_type unsigned int nr_max_vwires_get(); unsigned int nr_max_ef_adapters_get(); unsigned int nr_max_tera_adapters_get(); +uint32_t vwire_sid_start_get(); +uint32_t ef_sid_start_get(); int ef_adapter_id_check(uint32_t ef_adapter_id); int vwire_id_check(uint32_t vwire_id); int tera_adapter_id_check(uint32_t tera_adapter_id); diff --git a/infra/include/link_db.h b/infra/include/link_db.h index 198a1ef..3affd77 100644 --- a/infra/include/link_db.h +++ b/infra/include/link_db.h @@ -29,6 +29,7 @@ struct link_db_reverse_result { enum link_db_type type; uint16_t adapter_id; + int match_result; }; struct link_db_ctx; @@ -37,5 +38,5 @@ struct link_db_ctx * link_db_create(enum link_db_type type, uint32_t max_entries int link_db_config_parse(const char * cfgfile, struct link_db_ctx * ctx); void link_db_match(struct link_db_ctx * ctx, struct link_db_match_field match_field[], uint16_t nr_mbufs, uint16_t result[]); -int link_db_reverse_match(struct link_db_ctx * ctx, uint16_t link_id, struct link_db_reverse_result * result); +void link_db_reverse_match(struct link_db_ctx * ctx, uint16_t link_id, struct link_db_reverse_result * result); void link_db_destroy(struct link_db_ctx ** ctx); diff --git a/infra/src/link_db.c b/infra/src/link_db.c index d823e6f..ae42ec5 100644 --- a/infra/src/link_db.c +++ b/infra/src/link_db.c @@ -35,6 +35,8 @@ struct link_db_ctx link_db_match_func match_func; }; +const char * link_db_type_str[LINK_DB_TYPE_MAX] = {"etherfabric", "vwire", "tera", "all"}; + /* Link db ctx item create */ struct link_db_ctx * link_db_create(enum link_db_type type, uint32_t max_entries) { @@ -96,25 +98,9 @@ void link_db_destroy(struct link_db_ctx ** ctx) void link_db_ctx_dump(struct link_db_ctx * ctx) { assert(ctx != NULL); - char str_type[MR_STRING_MAX]; - - switch (ctx->type) - { - case LINK_DB_TYPE_EF: - snprintf(str_type, sizeof(str_type) - 1, "%u(etherfabric)", ctx->type); - break; - case LINK_DB_TYPE_VWIRE: - snprintf(str_type, sizeof(str_type) - 1, "%u(vwire)", ctx->type); - break; - case LINK_DB_TYPE_TERA: - snprintf(str_type, sizeof(str_type) - 1, "%u(tera)", ctx->type); - break; - default: - snprintf(str_type, sizeof(str_type) - 1, "%u(unknow)", ctx->type); - break; - } - MR_INFO("Link db, max entries:%u, nr entries:%u, type:%s", ctx->max_entries, ctx->nr_entries, str_type); + MR_INFO("Link db, max entries:%u, nr entries:%u, type:%s", ctx->max_entries, ctx->nr_entries, + link_db_type_str[ctx->type]); for (int index = 0; index < ctx->nr_entries; index++) { @@ -332,9 +318,10 @@ void link_db_match(struct link_db_ctx * ctx, struct link_db_match_field match_fi } /* Link db reverse match */ -int link_db_reverse_match(struct link_db_ctx * ctx, uint16_t link_id, struct link_db_reverse_result * result) +void link_db_reverse_match(struct link_db_ctx * ctx, uint16_t link_id, struct link_db_reverse_result * result) { assert(ctx != NULL); + result->match_result = RT_ERR; for (int index = 0; index < ctx->nr_entries; index++) { @@ -358,9 +345,10 @@ int link_db_reverse_match(struct link_db_ctx * ctx, uint16_t link_id, struct lin break; } - return RT_SUCCESS; + result->match_result = RT_SUCCESS; + return; } } - return RT_ERR; + return; } diff --git a/infra/test/TestLinkDb.cc b/infra/test/TestLinkDb.cc index eb0f6c2..86bb0d2 100644 --- a/infra/test/TestLinkDb.cc +++ b/infra/test/TestLinkDb.cc @@ -296,14 +296,14 @@ TEST(TestCaseLinkDb, TypeAllReverseMatch) struct link_db_reverse_result reverse_result; - int ret = link_db_reverse_match(all_ctx, result[0], &reverse_result); - ASSERT_EQ(ret, -1); + link_db_reverse_match(all_ctx, result[0], &reverse_result); + ASSERT_EQ(reverse_result.match_result, -1); - ret = link_db_reverse_match(all_ctx, result[1], &reverse_result); - ASSERT_EQ(ret, -1); + link_db_reverse_match(all_ctx, result[1], &reverse_result); + ASSERT_EQ(reverse_result.match_result, -1); - ret = link_db_reverse_match(all_ctx, result[2], &reverse_result); - ASSERT_EQ(ret, 0); + link_db_reverse_match(all_ctx, result[2], &reverse_result); + ASSERT_EQ(reverse_result.match_result, 0); ASSERT_EQ(reverse_result.type, LINK_DB_TYPE_EF); ASSERT_EQ(reverse_result.adapter_id, 16); @@ -318,14 +318,14 @@ TEST(TestCaseLinkDb, TypeAllReverseMatch) ASSERT_EQ(result[1], UINT16_MAX); ASSERT_EQ(result[2], 54321); - ret = link_db_reverse_match(all_ctx, result[0], &reverse_result); - ASSERT_EQ(ret, -1); + link_db_reverse_match(all_ctx, result[0], &reverse_result); + ASSERT_EQ(reverse_result.match_result, -1); - ret = link_db_reverse_match(all_ctx, result[1], &reverse_result); - ASSERT_EQ(ret, -1); + link_db_reverse_match(all_ctx, result[1], &reverse_result); + ASSERT_EQ(reverse_result.match_result, -1); - ret = link_db_reverse_match(all_ctx, result[2], &reverse_result); - ASSERT_EQ(ret, 0); + link_db_reverse_match(all_ctx, result[2], &reverse_result); + ASSERT_EQ(reverse_result.match_result, 0); ASSERT_EQ(reverse_result.type, LINK_DB_TYPE_VWIRE); ASSERT_EQ(reverse_result.adapter_id, 17); @@ -340,14 +340,14 @@ TEST(TestCaseLinkDb, TypeAllReverseMatch) ASSERT_EQ(result[1], UINT16_MAX); ASSERT_EQ(result[2], 6000); - ret = link_db_reverse_match(all_ctx, result[0], &reverse_result); - ASSERT_EQ(ret, -1); + link_db_reverse_match(all_ctx, result[0], &reverse_result); + ASSERT_EQ(reverse_result.match_result, -1); - ret = link_db_reverse_match(all_ctx, result[1], &reverse_result); - ASSERT_EQ(ret, -1); + link_db_reverse_match(all_ctx, result[1], &reverse_result); + ASSERT_EQ(reverse_result.match_result, -1); - ret = link_db_reverse_match(all_ctx, result[2], &reverse_result); - ASSERT_EQ(ret, 0); + link_db_reverse_match(all_ctx, result[2], &reverse_result); + ASSERT_EQ(reverse_result.match_result, 0); ASSERT_EQ(reverse_result.type, LINK_DB_TYPE_TERA); ASSERT_EQ(reverse_result.adapter_id, 18); diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt index 5ca2dcf..22dcb4c 100644 --- a/service/CMakeLists.txt +++ b/service/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(mrzcpd src/core.c src/devmgr.c src/mrb.c src/hwinfo.c src/vdev.c src/node_phydev.c src/node_lb.c src/node_classifier.c src/node_etherfabric.c src/node_tera.c src/node_eth_ingress.c src/node_eth_egress.c src/node_bfd.c src/node_vwire.c src/node_health_check.c src/node_forwarder.c src/node_bridge.c src/pdump.c src/olp.c src/olp_6500.c - src/http_serv.c src/classifier_rule_parser.c src/mpack.c src/dp_trace.c) + src/http_serv.c src/classifier_rule_parser.c src/mpack.c src/dp_trace.c src/node_link_aware_injector.c) target_link_libraries(mrzcpd MESA_prof_load_static libdpdk ${SYSTEMD_LIBRARIES}) target_link_libraries(mrzcpd rt pthread dl infra z elf) diff --git a/service/include/sc_node_common.h b/service/include/sc_node_common.h index 2c34c7c..1f8dc7f 100644 --- a/service/include/sc_node_common.h +++ b/service/include/sc_node_common.h @@ -22,6 +22,7 @@ enum FORWARDER_TYPE_VWIRE, FORWARDER_TYPE_EF, FORWARDER_TYPE_TERA, + FORWARDER_TYPE_LAI, FORWARDER_TYPE_HEALTH_CHECK, FORWARDER_TYPE_MAX }; @@ -119,7 +120,6 @@ static inline int mr_is_local_addr(struct mr_dev_desc * dev_desc, struct mr_gene (x[0] == 0xFF && x[1] == 0x02 && x[2] == 0x00 && x[3] == 0x00 && x[4] == 0x00 && x[5] == 0x00 && x[6] == 0x00 && \ x[7] == 0x00 && x[8] == 0x00 && x[9] == 0x00 && x[10] == 0x00 && x[11] == 0x01 && x[12] == 0xFF) - static inline cJSON * create_uint64_array(const uint64_t * value, unsigned int nr_value) { struct cJSON * uint64_array = cJSON_CreateArray(); diff --git a/service/src/monit.c b/service/src/monit.c index d758c64..08263fd 100644 --- a/service/src/monit.c +++ b/service/src/monit.c @@ -224,6 +224,7 @@ extern cJSON * tera_egress_node_monit_loop(struct sc_main * sc); extern cJSON * devmgr_monit_loop(struct sc_main * sc); extern cJSON * dp_trace_monit_loop(struct sc_main * sc); extern cJSON * phydev_rx_node_monit_loop(struct sc_main * sc); +extern cJSON * lai_node_monit_loop(struct sc_main * sc); static cJSON * monit_root(struct sc_main * sc) { @@ -249,6 +250,7 @@ static cJSON * monit_root(struct sc_main * sc) cJSON_AddItemToObject(j_root, "bfd", bfd_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "classifier", classifier_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "forwarder", forwarder_node_monit_loop(sc)); + cJSON_AddItemToObject(j_root, "link-aware-injector", lai_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "vwire-egress", vwire_egress_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "lb", lb_node_monit_loop(sc)); cJSON_AddItemToObject(j_root, "ef-egress", ef_egress_node_monit_loop(sc)); diff --git a/service/src/node_etherfabric.c b/service/src/node_etherfabric.c index e0c32e3..00adade 100644 --- a/service/src/node_etherfabric.c +++ b/service/src/node_etherfabric.c @@ -140,6 +140,13 @@ unsigned int nr_max_ef_adapters_get() return nr_max_ef_adapters; } +/* Etherfabric start sid get */ +uint32_t ef_sid_start_get() +{ + struct node_ef_main * ef_main = node_ef_main_get(); + return ef_main->sid_start; +} + /* Set the pkt offset */ const static int ef_encap_len = sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr) + sizeof(struct rte_udp_hdr) + sizeof(struct g_vxlan_hdr); diff --git a/service/src/node_forwarder.c b/service/src/node_forwarder.c index ba5aee3..87a3124 100644 --- a/service/src/node_forwarder.c +++ b/service/src/node_forwarder.c @@ -16,6 +16,7 @@ enum FORWARDER_VWIRE_EGRESS, FORWARDER_EF_EGRESS, FORWARDER_TERA_EGRESS, + FORWARDER_LAI, FORWARDER_NEXT_MAX }; @@ -39,6 +40,7 @@ struct forwarder_stats volatile uint64_t to_vwire_egress; volatile uint64_t to_ef_egress; volatile uint64_t to_tera_egress; + volatile uint64_t to_lai; volatile uint64_t drop_reason[FORWARDER_DROP_RSN_MAX]; } __rte_cache_aligned; @@ -96,7 +98,12 @@ void forwarder_table_inserter(uint16_t sid, uint16_t type) forwarder_main->forwarder_table[sid] = FORWARDER_TERA_EGRESS; len += snprintf(str_forwarder + len, sizeof(str_forwarder) - len, ", next_services=tera egress"); break; + case FORWARDER_TYPE_LAI: + forwarder_main->forwarder_table[sid] = FORWARDER_LAI; + len += snprintf(str_forwarder + len, sizeof(str_forwarder) - len, ", next_services=link aware injector"); + break; } + forwarder_main->nr_rules++; MR_INFO("%s", str_forwarder); } @@ -236,6 +243,7 @@ static __rte_always_inline uint16_t forwarder_node_process(struct rte_graph * gr graph_stats->to_vwire_egress += next_node_index_counters[FORWARDER_VWIRE_EGRESS]; graph_stats->to_ef_egress += next_node_index_counters[FORWARDER_EF_EGRESS]; graph_stats->to_tera_egress += next_node_index_counters[FORWARDER_TERA_EGRESS]; + graph_stats->to_lai += next_node_index_counters[FORWARDER_LAI]; for (uint16_t i = 0; i < FORWARDER_DROP_RSN_MAX; i++) { @@ -264,6 +272,7 @@ static struct rte_node_register forwarder_node_base = { [FORWARDER_VWIRE_EGRESS] = "vwire_egress", [FORWARDER_EF_EGRESS] = "ef_egress", [FORWARDER_TERA_EGRESS] = "tera_egress", + [FORWARDER_LAI] = "link_aware_injector", }, }; @@ -281,6 +290,7 @@ cJSON * forwarder_node_monit_loop(struct sc_main * sc) uint64_t to_vwire_egress[nr_graphs]; uint64_t to_ef_egress[nr_graphs]; uint64_t to_tera_egress[nr_graphs]; + uint64_t to_lai[nr_graphs]; uint64_t drop_reason[nr_graphs][FORWARDER_DROP_RSN_MAX]; for (uint32_t graph_id = 0; graph_id < nr_graphs; graph_id++) @@ -294,6 +304,7 @@ cJSON * forwarder_node_monit_loop(struct sc_main * sc) to_vwire_egress[graph_id] = 0; to_ef_egress[graph_id] = 0; to_tera_egress[graph_id] = 0; + to_lai[graph_id] = 0; memset(drop_reason[graph_id], 0, sizeof(drop_reason[graph_id])); continue; @@ -305,6 +316,7 @@ cJSON * forwarder_node_monit_loop(struct sc_main * sc) to_vwire_egress[graph_id] = stats->to_vwire_egress; to_ef_egress[graph_id] = stats->to_ef_egress; to_tera_egress[graph_id] = stats->to_tera_egress; + to_lai[graph_id] = stats->to_lai; for (int i = 0; i < FORWARDER_DROP_RSN_MAX; i++) { @@ -330,6 +342,9 @@ cJSON * forwarder_node_monit_loop(struct sc_main * sc) cJSON * json_to_tera_egress = create_uint64_array(to_tera_egress, nr_graphs); cJSON_AddItemToObject(json_root, "forwarder, to_tera_egress", json_to_tera_egress); + cJSON * json_to_lai = create_uint64_array(to_lai, nr_graphs); + cJSON_AddItemToObject(json_root, "forwarder, to_link_aware_injector", json_to_lai); + for (int i = 0; i < FORWARDER_DROP_RSN_MAX; i++) { char str_title[MR_STRING_MAX]; @@ -353,31 +368,34 @@ cJSON * forwarder_table_monit_loop(struct sc_main * sc) if (forwarder_main->forwarder_table[index] == 0) continue; - cJSON * item_obj = cJSON_CreateObject(); + char str_info[MR_STRING_MAX] = {}; + int len = snprintf(str_info, sizeof(str_info), "Sid:%u, ", index); - cJSON_AddNumberToObject(item_obj, "Sid", index); switch (forwarder_main->forwarder_table[index]) { case FORWARDER_NEXT_LB: - cJSON_AddStringToObject(item_obj, "Next Services", "LB"); + len += snprintf(str_info + len, sizeof(str_info) - len, "Next Services: LB"); break; case FORWARDER_VWIRE_EGRESS: - cJSON_AddStringToObject(item_obj, "Next Services", "Vwire"); + len += snprintf(str_info + len, sizeof(str_info) - len, "Next Services: Vwire"); break; case FORWARDER_EF_EGRESS: - cJSON_AddStringToObject(item_obj, "Next Services", "Etherfabric"); + len += snprintf(str_info + len, sizeof(str_info) - len, "Next Services: Etherfabric"); break; case FORWARDER_TERA_EGRESS: - cJSON_AddStringToObject(item_obj, "Next Services", "Tera"); + len += snprintf(str_info + len, sizeof(str_info) - len, "Next Services: Tera"); + break; + case FORWARDER_LAI: + len += snprintf(str_info + len, sizeof(str_info) - len, "Next Services: Link Aware Injector"); break; default: - cJSON_AddStringToObject(item_obj, "Next Services", "Unknown"); + len += snprintf(str_info + len, sizeof(str_info) - len, "Next Services: Unknown"); break; } char str_idx[MR_STRING_MAX] = {}; snprintf(str_idx, sizeof(str_idx) - 1, "index:%u", nr_items); - cJSON_AddItemToObject(json_root, str_idx, item_obj); + cJSON_AddStringToObject(json_root, str_idx, str_info); nr_items++; } diff --git a/service/src/node_link_aware_injector.c b/service/src/node_link_aware_injector.c new file mode 100644 index 0000000..1b7f5d4 --- /dev/null +++ b/service/src/node_link_aware_injector.c @@ -0,0 +1,343 @@ +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Link aware injector next node */ +enum +{ + LAI_NEXT_PKT_DROP = 0, + LAI_NEXT_EF_EGRESS, + LAI_NEXT_VWIRE_EGRESS, + LAI_NEXT_MAX +}; + +/* Link aware injector drop reason*/ +enum lai_drop_reason +{ + LAI_DROP_RSN_TLID_MISS = 0, + LAI_DROP_RSN_INVALID_ADAPTER_TYPE, + LAI_DROP_RSN_MAX +}; + +/* Link aware injector drop reason string */ +char * lai_drop_rsn_str[LAI_DROP_RSN_MAX] = {"traffic link id miss", "invalid adapter type"}; + +/* Link aware injector stats struct */ +struct lai_stats +{ + volatile uint64_t total_pkts; + volatile uint64_t pkts_per_batch; + volatile uint64_t to_eth_egress; + volatile uint64_t to_vwire_egress; + volatile uint64_t drop_reason[LAI_DROP_RSN_MAX]; +} __rte_cache_aligned; + +/* Link aware injector main struct */ +struct node_lai_main +{ + uint32_t lai_sid; + uint32_t ef_sid_start; + uint32_t vwire_sid_start; + struct link_db_ctx * link_db_ctx; +}; + +/* Link aware injector node context */ +struct lai_node_ctx +{ + /* Cached next index */ + uint16_t next_index; +}; + +#define LAI_NODE_LAST_NEXT(ctx) (((struct lai_node_ctx *)ctx)->next_index) + +/* Global variable */ +static struct node_lai_main g_lai_main = {}; +static struct lai_stats lai_stats_per_graph[RTE_MAX_LCORE] = {}; + +static inline struct node_lai_main * node_lai_main_get() +{ + return &g_lai_main; +} + +/* Init Link aware injector */ +int lai_init(struct sc_main * sc) +{ + struct node_lai_main * lai_main = node_lai_main_get(); + memset(lai_main, 0, sizeof(struct node_lai_main)); + + /* Get Link aware injector sid */ + MESA_load_profile_uint_def(sc->local_cfgfile, "feature_sids", "lai", &lai_main->lai_sid, 900); + + /* Link db ctx create */ + uint32_t max_entries; + MESA_load_profile_uint_def(sc->local_cfgfile, "limits", "nr_max_link_dbs", &max_entries, 64); + max_entries = max_entries * LINK_DB_TYPE_ALL; + + lai_main->link_db_ctx = link_db_create(LINK_DB_TYPE_EF, max_entries); + if (lai_main->link_db_ctx == NULL) + { + MR_ERROR("In link aware injector node, link db ctx create failed."); + return RT_ERR; + } + + if (link_db_config_parse(sc->local_cfgfile, lai_main->link_db_ctx) == RT_ERR) + { + MR_ERROR("In link aware injector node, link db config parse failed."); + return RT_ERR; + } + + /* Get ef and vwire sid start */ + lai_main->ef_sid_start = ef_sid_start_get(); + lai_main->vwire_sid_start = vwire_sid_start_get(); + + if (lai_main->ef_sid_start == 0) + { + MR_ERROR("In link aware injector node, ef sid start get failed."); + return RT_ERR; + } + else if (lai_main->vwire_sid_start == 0) + { + MR_ERROR("In link aware injector node, vwire sid start get failed."); + return RT_ERR; + } + + /* Inserter sid to forwarder table */ + forwarder_table_inserter(lai_main->lai_sid, FORWARDER_TYPE_LAI); + + MR_INFO("Link aware injector node init success,link aware injector sid:%u, ef sid start: %u, vwire sid start: %u", + lai_main->lai_sid, lai_main->ef_sid_start, lai_main->vwire_sid_start); + + return RT_SUCCESS; +} + +/* Generate and store the trace information */ +static __rte_always_inline void gen_store_trace_info(struct rte_node * node, struct rte_mbuf * mbuf, + uint16_t next_node_index, enum lai_drop_reason drop_reason) +{ + /* Populate the next node infomation */ + char str_record[MR_STRING_MAX]; + int len = snprintf(str_record, sizeof(str_record), "next node:%s", node->nodes[next_node_index]->name); + + /* Populate the drop reason */ + if (next_node_index == LAI_NEXT_PKT_DROP) + { + assert(drop_reason < LAI_DROP_RSN_MAX); + len += snprintf(str_record + len, sizeof(str_record) - len, ", rsn:%s", lai_drop_rsn_str[drop_reason]); + } + + struct mrb_metadata * mrb_meta = mrbuf_cz_data(mbuf, MR_NODE_CTRLZONE_ID); + len += snprintf(str_record + len, sizeof(str_record) - len, ", trf lk id:%u, cur sid:%u", mrb_meta->traffic_link_id, + mrb_meta->cur_sid); + + /* Emit the trace record */ + struct dp_trace_record_meta meta = { + .measurement_type = DP_TRACE_MEASUREMENT_TYPE_TRACE, .appsym = MR_TRACE_APPSYM, .module = node->name}; + dp_trace_record_emit_str(sc_main_get()->trace, mbuf, rte_lcore_id(), &meta, str_record); +} + +/* Link aware injector node process function */ +static __rte_always_inline uint16_t lai_node_process(struct rte_graph * graph, struct rte_node * node, void ** objs, + uint16_t nb_objs) +{ + void ** batch_pkts = objs; + struct rte_mbuf ** mbufs = (struct rte_mbuf **)objs; + + /* prefetch the mbuf and it's content */ + rte_prefetch0(mbufs[0]); + rte_prefetch0(mrbuf_cz_data(mbufs[0], MR_NODE_CTRLZONE_ID)); + + uint16_t last_spec = 0; + uint16_t n_left_from = nb_objs; + uint16_t batch_next_node_index = LAI_NODE_LAST_NEXT(node->ctx); + uint32_t last_traffic_link_id = UINT32_MAX; + enum lai_drop_reason drop_reason = LAI_DROP_RSN_TLID_MISS; + struct lai_stats stats = {}; + struct node_lai_main * lai_main = node_lai_main_get(); + struct link_db_reverse_result result = {.match_result = RT_ERR}; + + while (n_left_from > 0) + { + struct rte_mbuf * mbuf = mbufs[0]; + mbufs += 1; + n_left_from -= 1; + + /* prefetch next mbuf */ + if (n_left_from > 0) + { + rte_prefetch0(mbufs[0]); + rte_prefetch0(mrbuf_cz_data(mbufs[0], MR_NODE_CTRLZONE_ID)); + } + + /* Get metadata */ + uint16_t next_node_index; + struct mrb_metadata * mrb_meta = mrbuf_cz_data(mbuf, MR_NODE_CTRLZONE_ID); + + /* Link db reverse match */ + if (last_traffic_link_id != mrb_meta->traffic_link_id) + { + last_traffic_link_id = mrb_meta->traffic_link_id; + link_db_reverse_match(lai_main->link_db_ctx, last_traffic_link_id, &result); + } + + /* Check the match result */ + if (unlikely(result.match_result != RT_SUCCESS)) + { + drop_reason = LAI_DROP_RSN_TLID_MISS; + stats.drop_reason[drop_reason]++; + next_node_index = LAI_NEXT_PKT_DROP; + goto node_enqueue; + } + + /* Set the next node index */ + if (result.type == LINK_DB_TYPE_EF) + { + mrb_meta->cur_sid = lai_main->ef_sid_start + result.adapter_id; + next_node_index = LAI_NEXT_EF_EGRESS; + stats.to_eth_egress++; + } + else if (result.type == LINK_DB_TYPE_VWIRE) + { + mrb_meta->cur_sid = lai_main->vwire_sid_start + result.adapter_id; + next_node_index = LAI_NEXT_VWIRE_EGRESS; + stats.to_vwire_egress++; + } + else + { + drop_reason = LAI_DROP_RSN_INVALID_ADAPTER_TYPE; + stats.drop_reason[drop_reason]++; + next_node_index = LAI_NEXT_PKT_DROP; + } + + node_enqueue: + + /* Check if tracing is enabled for the current Mbuf */ + if (unlikely(dp_trace_record_can_emit(mbuf, DP_TRACE_MEASUREMENT_TYPE_TRACE))) + { + gen_store_trace_info(node, mbuf, next_node_index, drop_reason); + } + + /* Check if the next index needs to be changed */ + if (unlikely(batch_next_node_index != next_node_index)) + { + /* Enqueue the last packets if the next index has changed */ + rte_node_enqueue(graph, node, batch_next_node_index, batch_pkts, last_spec); + batch_pkts += last_spec; + last_spec = 1; + batch_next_node_index = next_node_index; + } + else + { + /* If the next index hasn't changed, update the last packets */ + last_spec++; + } + } + + /* Process any remaining packets */ + if (likely(last_spec > 0)) + rte_node_enqueue(graph, node, batch_next_node_index, batch_pkts, last_spec); + + /* Update last next index */ + LAI_NODE_LAST_NEXT(node->ctx) = batch_next_node_index; + + /* Update stats */ + struct lai_stats * graph_stats = &lai_stats_per_graph[graph->id]; + graph_stats->total_pkts += nb_objs; + graph_stats->pkts_per_batch = nb_objs; + graph_stats->to_eth_egress += stats.to_eth_egress; + graph_stats->to_vwire_egress += stats.to_vwire_egress; + for (int i = 0; i < LAI_DROP_RSN_MAX; i++) + { + graph_stats->drop_reason[i] += stats.drop_reason[i]; + } + + return nb_objs; +} + +/* Link aware injector node init function */ +static int lai_node_init(const struct rte_graph * graph, struct rte_node * node) +{ + LAI_NODE_LAST_NEXT(node->ctx) = LAI_NEXT_EF_EGRESS; + return 0; +} + +/* Link aware injector node base */ +static struct rte_node_register lai_node_base = { + .process = lai_node_process, + .name = "link_aware_injector", + .init = lai_node_init, + .nb_edges = LAI_NEXT_MAX, + .next_nodes = + { + [LAI_NEXT_PKT_DROP] = "pkt_drop_trap", + [LAI_NEXT_EF_EGRESS] = "ef_egress", + [LAI_NEXT_VWIRE_EGRESS] = "vwire_egress", + }, +}; + +RTE_NODE_REGISTER(lai_node_base); + +cJSON * lai_node_monit_loop(struct sc_main * sc) +{ + cJSON * json_root = cJSON_CreateObject(); + unsigned int nr_graphs = sc->nr_io_thread; + + uint64_t total_pkts[nr_graphs]; + uint64_t pkts_per_batch[nr_graphs]; + uint64_t to_eth_egress[nr_graphs]; + uint64_t to_vwire_egress[nr_graphs]; + uint64_t drop_reason[LAI_DROP_RSN_MAX][nr_graphs]; + + for (uint32_t graph_id = 0; graph_id < nr_graphs; graph_id++) + { + struct lai_stats * stats = &lai_stats_per_graph[graph_id]; + if (stats->total_pkts == 0) + { + total_pkts[graph_id] = 0; + pkts_per_batch[graph_id] = 0; + to_eth_egress[graph_id] = 0; + to_vwire_egress[graph_id] = 0; + for (int i = 0; i < LAI_DROP_RSN_MAX; i++) + { + drop_reason[i][graph_id] = 0; + } + continue; + } + + total_pkts[graph_id] = stats->total_pkts; + pkts_per_batch[graph_id] = stats->pkts_per_batch; + to_eth_egress[graph_id] = stats->to_eth_egress; + to_vwire_egress[graph_id] = stats->to_vwire_egress; + for (int i = 0; i < LAI_DROP_RSN_MAX; i++) + { + drop_reason[i][graph_id] = stats->drop_reason[i]; + } + } + + cJSON * json_total_pkts = create_uint64_array(total_pkts, nr_graphs); + cJSON_AddItemToObject(json_root, "lai, total_pkts", json_total_pkts); + + cJSON * json_pkts_per_batch = create_uint64_array(pkts_per_batch, nr_graphs); + cJSON_AddItemToObject(json_root, "lai, pkts_per_batch", json_pkts_per_batch); + + cJSON * json_to_eth_egress = create_uint64_array(to_eth_egress, nr_graphs); + cJSON_AddItemToObject(json_root, "lai, to_eth_egress", json_to_eth_egress); + + cJSON * json_to_vwire_egress = create_uint64_array(to_vwire_egress, nr_graphs); + cJSON_AddItemToObject(json_root, "lai, to_vwire_egress", json_to_vwire_egress); + for (int i = 0; i < LAI_DROP_RSN_MAX; i++) + { + char str_title[MR_STRING_MAX]; + snprintf(str_title, sizeof(str_title), "lai, %s", lai_drop_rsn_str[i]); + + cJSON * json_drop_reason = create_uint64_array(drop_reason[i], nr_graphs); + cJSON_AddItemToObject(json_root, str_title, json_drop_reason); + } + + return json_root; +} diff --git a/service/src/node_vwire.c b/service/src/node_vwire.c index 4197085..1b57073 100644 --- a/service/src/node_vwire.c +++ b/service/src/node_vwire.c @@ -90,6 +90,12 @@ unsigned int nr_max_vwires_get() return nr_max_vwires; } +/* Get max vwires start sid */ +uint32_t vwire_sid_start_get() +{ + return p_vwire_node_main->sid_start; +} + /* Vwire service id check */ int vwire_id_check(uint32_t vwire_id) { -- cgit v1.2.3