summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsongyanchao <[email protected]>2024-04-29 08:06:27 +0000
committersongyanchao <[email protected]>2024-05-15 02:06:25 +0000
commit7fa3de16bd8cc266a99279e23baea532a4a3e4c3 (patch)
treea74efe7b558f406d0184b9a57f918909b9b6de2b
parentd77b43cd78605550ee7da332f22f991d02faee3f (diff)
✨ feat(DPISDN-42): Add 'link_db_reverse_match' API to link_db.
Add 'link_db_reverse_match' API to link_db.
-rw-r--r--infra/include/link_db.h10
-rw-r--r--infra/src/link_db.c94
-rw-r--r--infra/test/TestLinkDb.cc149
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)
{