diff options
| author | songyanchao <[email protected]> | 2024-04-29 08:06:27 +0000 |
|---|---|---|
| committer | songyanchao <[email protected]> | 2024-05-15 02:06:25 +0000 |
| commit | 7fa3de16bd8cc266a99279e23baea532a4a3e4c3 (patch) | |
| tree | a74efe7b558f406d0184b9a57f918909b9b6de2b /infra | |
| parent | d77b43cd78605550ee7da332f22f991d02faee3f (diff) | |
✨ feat(DPISDN-42): Add 'link_db_reverse_match' API to link_db.
Add 'link_db_reverse_match' API to link_db.
Diffstat (limited to 'infra')
| -rw-r--r-- | infra/include/link_db.h | 10 | ||||
| -rw-r--r-- | infra/src/link_db.c | 94 | ||||
| -rw-r--r-- | infra/test/TestLinkDb.cc | 149 |
3 files changed, 248 insertions, 5 deletions
diff --git a/infra/include/link_db.h b/infra/include/link_db.h index 348e4c3..198a1ef 100644 --- a/infra/include/link_db.h +++ b/infra/include/link_db.h @@ -7,7 +7,8 @@ enum link_db_type { LINK_DB_TYPE_EF = ADAPTER_TYPE_EF, LINK_DB_TYPE_VWIRE = ADAPTER_TYPE_VWIRE, - LINK_DB_TYPE_TERA = ADAPTER_TYPE_TERA, + LINK_DB_TYPE_TERA = ADAPTER_TYPE_TERA, // Tera adapter not supported yet + LINK_DB_TYPE_ALL = ADAPTER_TYPE_ALL, LINK_DB_TYPE_MAX, }; @@ -24,10 +25,17 @@ struct link_db_match_field }; }; +struct link_db_reverse_result +{ + enum link_db_type type; + uint16_t adapter_id; +}; + struct link_db_ctx; 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_destroy(struct link_db_ctx ** ctx); diff --git a/infra/src/link_db.c b/infra/src/link_db.c index 34b1a55..d823e6f 100644 --- a/infra/src/link_db.c +++ b/infra/src/link_db.c @@ -6,11 +6,13 @@ uint16_t link_db_match_ef(struct link_db_ctx * ctx, struct link_db_match_field * match_field); uint16_t link_db_match_vwire(struct link_db_ctx * ctx, struct link_db_match_field * match_field); uint16_t link_db_match_tera(struct link_db_ctx * ctx, struct link_db_match_field * match_field); +uint16_t link_db_match_all(struct link_db_ctx * ctx, struct link_db_match_field * match_field); typedef uint16_t (*link_db_match_func)(struct link_db_ctx * ctx, struct link_db_match_field * match_field); /* Link db struct */ struct link_db { + enum link_db_type type; uint16_t traffic_link_id; union { struct @@ -36,7 +38,8 @@ struct link_db_ctx /* Link db ctx item create */ struct link_db_ctx * link_db_create(enum link_db_type type, uint32_t max_entries) { - assert((type == LINK_DB_TYPE_EF) || (type == LINK_DB_TYPE_VWIRE) || (type == LINK_DB_TYPE_TERA)); + assert((type == LINK_DB_TYPE_EF) || (type == LINK_DB_TYPE_VWIRE) || (type == LINK_DB_TYPE_TERA) || + (type == LINK_DB_TYPE_ALL)); struct link_db_ctx * link_db_ctx = (struct link_db_ctx *)ZMALLOC(sizeof(struct link_db_ctx)); MR_VERIFY_MALLOC(link_db_ctx); @@ -60,6 +63,15 @@ struct link_db_ctx * link_db_create(enum link_db_type type, uint32_t max_entries { link_db_ctx->match_func = link_db_match_tera; } + else if (type == LINK_DB_TYPE_ALL) + { + link_db_ctx->match_func = link_db_match_all; + } + else + { + link_db_destroy(&link_db_ctx); + return NULL; + } return link_db_ctx; } @@ -137,7 +149,7 @@ int link_db_config_parse(const char * cfgfile, struct link_db_ctx * ctx) uint32_t type; snprintf(str_section, sizeof(str_section) - 1, "link_db:%d", index); int ret = MESA_load_profile_uint_nodef(cfgfile, str_section, "type", &type); - if ((ret < 0) || (type != ctx->type)) + if ((ret < 0) || ((type != ctx->type) && (ctx->type != LINK_DB_TYPE_ALL))) { continue; } @@ -170,10 +182,12 @@ int link_db_config_parse(const char * cfgfile, struct link_db_ctx * ctx) return RT_ERR; } + link_db->type = LINK_DB_TYPE_EF; link_db->ef_link_id = (uint16_t)ef_link_id; link_db->ef_ip_addr = ef_ip_addr; } - else if (type == LINK_DB_TYPE_VWIRE) + + if (type == LINK_DB_TYPE_VWIRE) { uint32_t vwire_id; ret = MESA_load_profile_uint_nodef(cfgfile, str_section, "vwire_id", &vwire_id); @@ -183,9 +197,11 @@ int link_db_config_parse(const char * cfgfile, struct link_db_ctx * ctx) return RT_ERR; } + link_db->type = LINK_DB_TYPE_VWIRE; link_db->vwire_id = vwire_id; } - else if (type == LINK_DB_TYPE_TERA) + + if (type == LINK_DB_TYPE_TERA) { uint32_t tera_adapter_id; ret = MESA_load_profile_uint_nodef(cfgfile, str_section, "tera_adapter_id", &tera_adapter_id); @@ -195,6 +211,7 @@ int link_db_config_parse(const char * cfgfile, struct link_db_ctx * ctx) return RT_ERR; } + link_db->type = LINK_DB_TYPE_TERA; link_db->tera_adapter_id = tera_adapter_id; } @@ -267,6 +284,41 @@ uint16_t link_db_match_tera(struct link_db_ctx * ctx, struct link_db_match_field return UINT16_MAX; } +/* Link db match for all */ +uint16_t link_db_match_all(struct link_db_ctx * ctx, struct link_db_match_field * match_field) +{ + assert(ctx->type == LINK_DB_TYPE_ALL); + + for (int index = 0; index < ctx->nr_entries; index++) + { + struct link_db * link_db = &ctx->link_dbs[index]; + + if (link_db->type == LINK_DB_TYPE_EF) + { + if ((match_field->ef_link_id == link_db->ef_link_id) && (match_field->ef_ip_addr == link_db->ef_ip_addr)) + { + return link_db->traffic_link_id; + } + } + else if (link_db->type == LINK_DB_TYPE_VWIRE) + { + if (match_field->vwire_id == link_db->vwire_id) + { + return link_db->traffic_link_id; + } + } + else if (link_db->type == LINK_DB_TYPE_TERA) + { + if (match_field->tera_adapter_id == link_db->tera_adapter_id) + { + return link_db->traffic_link_id; + } + } + } + + return UINT16_MAX; +} + /* Link db match */ void link_db_match(struct link_db_ctx * ctx, struct link_db_match_field match_fields[], uint16_t nr_fields, uint16_t result[]) @@ -278,3 +330,37 @@ void link_db_match(struct link_db_ctx * ctx, struct link_db_match_field match_fi result[index] = ctx->match_func(ctx, &match_fields[index]); } } + +/* Link db reverse match */ +int link_db_reverse_match(struct link_db_ctx * ctx, uint16_t link_id, struct link_db_reverse_result * result) +{ + assert(ctx != NULL); + + for (int index = 0; index < ctx->nr_entries; index++) + { + struct link_db * link_db = &ctx->link_dbs[index]; + if (link_db->traffic_link_id == link_id) + { + result->type = link_db->type; + + switch (link_db->type) + { + case LINK_DB_TYPE_EF: + result->adapter_id = link_db->ef_link_id; + break; + case LINK_DB_TYPE_VWIRE: + result->adapter_id = link_db->vwire_id; + break; + case LINK_DB_TYPE_TERA: + result->adapter_id = link_db->tera_adapter_id; + break; + default: + break; + } + + return RT_SUCCESS; + } + } + + return RT_ERR; +} diff --git a/infra/test/TestLinkDb.cc b/infra/test/TestLinkDb.cc index 28e7983..eb0f6c2 100644 --- a/infra/test/TestLinkDb.cc +++ b/infra/test/TestLinkDb.cc @@ -207,6 +207,155 @@ TEST(TestCaseLinkDb, TypeEtherfabricVwireAndTera) ASSERT_EQ(tera_ctx, nullptr); } +/* Type all match */ +TEST(TestCaseLinkDb, TypeAll) +{ + struct link_db_ctx * all_ctx = link_db_create(LINK_DB_TYPE_ALL, 32); + ASSERT_TRUE(all_ctx != NULL); + + const std::string filename = "link_db.cfg"; + const std::string content = "[link_db:0]\n type = 0\n traffic_link_id = 12345\n ef_ip_addr = 10.1.1.10\n " + "ef_link_id = 16\n [link_db:1]\n type = 1\n traffic_link_id = 54321\n vwire_id = 17\n " + "[link_db:2]\n type = 2\n traffic_link_id = 6000\n tera_adapter_id = 18\n "; + + writeLinkDbCfg(filename, content); + + ASSERT_EQ(link_db_config_parse(filename.c_str(), all_ctx), 0); + + /* Etherfabric */ + struct link_db_match_field match_field[3]; + match_field[0].ef_link_id = 1; + match_field[0].ef_ip_addr = 0x0a01010a; + match_field[1].ef_link_id = 16; + match_field[1].ef_ip_addr = 0x0a01000a; + match_field[2].ef_link_id = 16; + match_field[2].ef_ip_addr = 0x0a01010a; + + uint16_t result[3]; + link_db_match(all_ctx, match_field, 3, result); + ASSERT_EQ(result[0], UINT16_MAX); + ASSERT_EQ(result[1], UINT16_MAX); + ASSERT_EQ(result[2], 12345); + + /* Vwire */ + memset(match_field, 0, sizeof(match_field)); + match_field[0].vwire_id = 1; + match_field[1].vwire_id = 16; + match_field[2].vwire_id = 17; + + link_db_match(all_ctx, match_field, 3, result); + ASSERT_EQ(result[0], UINT16_MAX); + ASSERT_EQ(result[1], UINT16_MAX); + ASSERT_EQ(result[2], 54321); + + /* Tera */ + memset(match_field, 0, sizeof(match_field)); + match_field[0].tera_adapter_id = 1; + match_field[1].tera_adapter_id = 1; + match_field[2].tera_adapter_id = 18; + + link_db_match(all_ctx, match_field, 3, result); + ASSERT_EQ(result[0], UINT16_MAX); + ASSERT_EQ(result[1], UINT16_MAX); + ASSERT_EQ(result[2], 6000); + + /* Destroy ctx */ + link_db_destroy(&all_ctx); + ASSERT_EQ(all_ctx, nullptr); +} + +/* Type all reverse match */ +TEST(TestCaseLinkDb, TypeAllReverseMatch) +{ + struct link_db_ctx * all_ctx = link_db_create(LINK_DB_TYPE_ALL, 32); + ASSERT_TRUE(all_ctx != NULL); + + const std::string filename = "link_db.cfg"; + const std::string content = "[link_db:0]\n type = 0\n traffic_link_id = 12345\n ef_ip_addr = 10.1.1.10\n " + "ef_link_id = 16\n [link_db:1]\n type = 1\n traffic_link_id = 54321\n vwire_id = 17\n " + "[link_db:2]\n type = 2\n traffic_link_id = 6000\n tera_adapter_id = 18\n "; + + writeLinkDbCfg(filename, content); + + ASSERT_EQ(link_db_config_parse(filename.c_str(), all_ctx), 0); + + /* Etherfabric */ + struct link_db_match_field match_field[3]; + match_field[0].ef_link_id = 1; + match_field[0].ef_ip_addr = 0x0a01010a; + match_field[1].ef_link_id = 16; + match_field[1].ef_ip_addr = 0x0a01000a; + match_field[2].ef_link_id = 16; + match_field[2].ef_ip_addr = 0x0a01010a; + + uint16_t result[3]; + link_db_match(all_ctx, match_field, 3, result); + ASSERT_EQ(result[0], UINT16_MAX); + ASSERT_EQ(result[1], UINT16_MAX); + ASSERT_EQ(result[2], 12345); + + struct link_db_reverse_result reverse_result; + + int ret = link_db_reverse_match(all_ctx, result[0], &reverse_result); + ASSERT_EQ(ret, -1); + + ret = link_db_reverse_match(all_ctx, result[1], &reverse_result); + ASSERT_EQ(ret, -1); + + ret = link_db_reverse_match(all_ctx, result[2], &reverse_result); + ASSERT_EQ(ret, 0); + ASSERT_EQ(reverse_result.type, LINK_DB_TYPE_EF); + ASSERT_EQ(reverse_result.adapter_id, 16); + + /* Vwire */ + memset(match_field, 0, sizeof(match_field)); + match_field[0].vwire_id = 1; + match_field[1].vwire_id = 16; + match_field[2].vwire_id = 17; + + link_db_match(all_ctx, match_field, 3, result); + ASSERT_EQ(result[0], UINT16_MAX); + 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); + + ret = link_db_reverse_match(all_ctx, result[1], &reverse_result); + ASSERT_EQ(ret, -1); + + ret = link_db_reverse_match(all_ctx, result[2], &reverse_result); + ASSERT_EQ(ret, 0); + ASSERT_EQ(reverse_result.type, LINK_DB_TYPE_VWIRE); + ASSERT_EQ(reverse_result.adapter_id, 17); + + /* Tera */ + memset(match_field, 0, sizeof(match_field)); + match_field[0].tera_adapter_id = 1; + match_field[1].tera_adapter_id = 1; + match_field[2].tera_adapter_id = 18; + + link_db_match(all_ctx, match_field, 3, result); + ASSERT_EQ(result[0], UINT16_MAX); + 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); + + ret = link_db_reverse_match(all_ctx, result[1], &reverse_result); + ASSERT_EQ(ret, -1); + + ret = link_db_reverse_match(all_ctx, result[2], &reverse_result); + ASSERT_EQ(ret, 0); + ASSERT_EQ(reverse_result.type, LINK_DB_TYPE_TERA); + ASSERT_EQ(reverse_result.adapter_id, 18); + + /* Destroy ctx */ + link_db_destroy(&all_ctx); + ASSERT_EQ(all_ctx, nullptr); +} + /* Rules number out of max entries */ TEST(TestCaseLinkDb, RulesNumberOutOfMaxEntries) { |
