Skip to content

Commit a594d31

Browse files
mint570SRAVANI KANASANI
authored andcommitted
Add IPv6 src IP as new ternary key field for table ipv6_tunnel_termination_table
Signed-off-by: SRAVANI KANASANI <[email protected]>
1 parent 942830f commit a594d31

9 files changed

Lines changed: 417 additions & 167 deletions

orchagent/p4orch/p4orch_util.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,11 @@ std::string KeyGenerator::generateTunnelKey(const std::string &tunnel_id)
205205
}
206206

207207
std::string KeyGenerator::generateIpv6TunnelTermKey(
208-
const swss::IpAddress &dst_ipv6_ip,
209-
const swss::IpAddress &dst_ipv6_mask,
210-
const std::string& vrf_id) {
211-
std::map<std::string, std::string> fv_map = {
208+
const swss::IpAddress& src_ipv6_ip, const swss::IpAddress& src_ipv6_mask,
209+
const swss::IpAddress& dst_ipv6_ip, const swss::IpAddress& dst_ipv6_mask) {
210+
std::map<std::string, std::string> fv_map = {
211+
{p4orch::kDecapSrcIpv6Ip, src_ipv6_ip.to_string()},
212+
{p4orch::kDecapSrcIpv6Mask, src_ipv6_mask.to_string()},
212213
{p4orch::kDecapDstIpv6Ip, dst_ipv6_ip.to_string()},
213214
{p4orch::kDecapDstIpv6Mask, dst_ipv6_mask.to_string()}};
214215
return generateKey(fv_map);

orchagent/p4orch/p4orch_util.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ constexpr char *kMirrorAsIpv4Erspan = "mirror_as_ipv4_erspan";
9090
constexpr char *kL3AdmitAction = "admit_to_l3";
9191
constexpr char *kTunnelAction = "mark_for_p2p_tunnel_encap";
9292
constexpr char* kIpv6TunnelTermAction = "mark_for_tunnel_decap_and_set_vrf";
93+
constexpr char* kDecapSrcIpv6 = "src_ipv6";
9394
constexpr char* kDecapDstIpv6 = "dst_ipv6";
95+
constexpr char* kDecapSrcIpv6Ip = "src_ipv6_ip";
96+
constexpr char* kDecapSrcIpv6Mask = "src_ipv6_mask";
9497
constexpr char* kDecapDstIpv6Ip = "dst_ipv6_ip";
9598
constexpr char* kDecapDstIpv6Mask = "dst_ipv6_mask";
9699

@@ -301,6 +304,8 @@ struct P4AclRuleAppDbEntry
301304
struct Ipv6TunnelTermAppDbEntry
302305
{
303306
// Match
307+
swss::IpAddress src_ipv6_ip;
308+
swss::IpAddress src_ipv6_mask;
304309
swss::IpAddress dst_ipv6_ip;
305310
swss::IpAddress dst_ipv6_mask;
306311
// Action
@@ -379,9 +384,9 @@ class KeyGenerator
379384

380385
static std::string generateTunnelKey(const std::string &tunnel_id);
381386

382-
static std::string generateIpv6TunnelTermKey(const swss::IpAddress &dst_ipv6_ip,
383-
const swss::IpAddress &dst_ipv6_mask,
384-
const std::string& vrf_id);
387+
static std::string generateIpv6TunnelTermKey(const swss::IpAddress& src_ipv6_ip,
388+
const swss::IpAddress& src_ipv6_mask,
389+
const swss::IpAddress& dst_ipv6_ip, const swss::IpAddress& dst_ipv6_mask);
385390

386391
static std::string generateExtTableKey(const std::string &table_name, const std::string &table_key);
387392

orchagent/p4orch/tests/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \
4848
$(P4ORCH_DIR)/wcmp_manager.cpp \
4949
$(P4ORCH_DIR)/mirror_session_manager.cpp \
5050
$(P4ORCH_DIR)/l3_admit_manager.cpp \
51+
$(P4ORCH_DIR)/l3_multicast_manager.cpp \
5152
$(P4ORCH_DIR)/tunnel_decap_group_manager.cpp \
5253
$(P4ORCH_DIR)/ext_tables_manager.cpp \
5354
$(top_srcdir)/tests/mock_tests/fake_response_publisher.cpp \
@@ -67,6 +68,7 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \
6768
p4orch_util_test.cpp \
6869
return_code_test.cpp \
6970
route_manager_test.cpp \
71+
l3_multicast_manager_test.cpp \
7072
gre_tunnel_manager_test.cpp \
7173
next_hop_manager_test.cpp \
7274
wcmp_manager_test.cpp \

orchagent/p4orch/tests/p4orch_util_test.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ TEST(P4OrchUtilTest, KeyGeneratorTest)
4343

4444
auto ipv6_tunnel_term_key =
4545
KeyGenerator::generateIpv6TunnelTermKey(
46-
swss::IpAddress("::1"), swss::IpAddress("::1"), "vrf_id");
47-
EXPECT_EQ(
48-
"dst_ipv6_ip=::1:dst_ipv6_mask=::1", ipv6_tunnel_term_key);
46+
swss::IpAddress("::1"), swss::IpAddress("::1"), swss::IpAddress("::2"),
47+
swss::IpAddress("::2"));
48+
EXPECT_EQ("dst_ipv6_ip=::2:dst_ipv6_mask=::2:src_ipv6_ip=::1:src_ipv6_mask=::1",
49+
ipv6_tunnel_term_key);
4950
}
5051

5152
TEST(P4OrchUtilTest, ParseP4RTKeyTest)

orchagent/p4orch/tests/tunnel_decap_group_manager_test.cpp

Lines changed: 277 additions & 109 deletions
Large diffs are not rendered by default.

orchagent/p4orch/tunnel_decap_group_manager.cpp

Lines changed: 85 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ std::vector<sai_attribute_t> prepareSaiAttrs(
7070
attr.value.s32 = SAI_TUNNEL_TERM_TABLE_ENTRY_TYPE_MP2MP;
7171
attrs.push_back(attr);
7272

73+
// Match on source IP.
74+
attr.id = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_SRC_IP;
75+
swss::copy(attr.value.ipaddr, ipv6_tunnel_term_entry.src_ipv6_ip);
76+
attrs.push_back(attr);
77+
// Match on source MASK.
78+
attr.id = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_SRC_IP_MASK;
79+
swss::copy(attr.value.ipaddr, ipv6_tunnel_term_entry.src_ipv6_mask);
80+
attrs.push_back(attr);
7381
// Match on destination IP.
7482
attr.id = SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP;
7583
swss::copy(attr.value.ipaddr, ipv6_tunnel_term_entry.dst_ipv6_ip);
@@ -135,14 +143,24 @@ ReturnCode TunnelDecapGroupManager::validateIpv6TunnelTermAppDbEntry(
135143
<< "Invalid action " << QuotedVar(app_db_entry.action_str)
136144
<< " of Ipv6 tunnel termination table entry";
137145
}
146+
if (app_db_entry.src_ipv6_ip.isV4()) {
147+
return ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
148+
<< QuotedVar(prependParamField("src_ipv6_ip"))
149+
<< " field is not IPv6";
150+
}
151+
if (app_db_entry.src_ipv6_mask.isV4()) {
152+
return ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
153+
<< QuotedVar(prependParamField("src_ipv6_mask"))
154+
<< " field is not IPv6";
155+
}
138156
if (app_db_entry.dst_ipv6_ip.isV4()) {
139157
return ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
140158
<< QuotedVar(prependParamField("dst_ipv6_ip"))
141159
<< " field is not IPv6";
142160
}
143161
if (app_db_entry.dst_ipv6_mask.isV4()) {
144162
return ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
145-
<< QuotedVar(prependParamField("dst_ipv6_ip"))
163+
<< QuotedVar(prependParamField("dst_ipv6_mask"))
146164
<< " field is not IPv6";
147165
}
148166
return ReturnCode();
@@ -152,11 +170,11 @@ ReturnCode TunnelDecapGroupManager::validateIpv6TunnelTermAppDbEntry(
152170
const Ipv6TunnelTermAppDbEntry& app_db_entry,
153171
const std::string& operation) {
154172
SWSS_LOG_ENTER();
155-
156-
Ipv6TunnelTermTableEntry entry =
157-
Ipv6TunnelTermTableEntry(app_db_entry.dst_ipv6_ip,
158-
app_db_entry.dst_ipv6_mask, app_db_entry.vrf_id);
159-
173+
Ipv6TunnelTermTableEntry entry = Ipv6TunnelTermTableEntry(
174+
app_db_entry.src_ipv6_ip, app_db_entry.src_ipv6_mask,
175+
app_db_entry.dst_ipv6_ip, app_db_entry.dst_ipv6_mask,
176+
app_db_entry.vrf_id);
177+
160178
if (operation == SET_COMMAND) {
161179
RETURN_IF_ERROR(validateIpv6TunnelTermAppDbEntry(app_db_entry));
162180
if (getIpv6TunnelTermEntry(entry.ipv6_tunnel_term_key) == nullptr) {
@@ -174,6 +192,8 @@ ReturnCode TunnelDecapGroupManager::validateIpv6TunnelTermAppDbEntry(
174192
return ReturnCode(StatusCode::SWSS_RC_NOT_FOUND)
175193
<< "No VRF found with id " << QuotedVar(entry.vrf_id) << " for "
176194
<< "Ipv6 tunnel termination table entry that matches on "
195+
<< QuotedVar(entry.src_ipv6_ip.to_string()) << "&"
196+
<< QuotedVar(entry.src_ipv6_mask.to_string()) << " and "
177197
<< QuotedVar(entry.dst_ipv6_ip.to_string()) << "&"
178198
<< QuotedVar(entry.dst_ipv6_mask.to_string());
179199
}
@@ -211,12 +231,17 @@ ReturnCode TunnelDecapGroupManager::validateIpv6TunnelTermAppDbEntry(
211231
}
212232

213233
Ipv6TunnelTermTableEntry::Ipv6TunnelTermTableEntry(
234+
const swss::IpAddress& src_ipv6_ip, const swss::IpAddress& src_ipv6_mask,
214235
const swss::IpAddress& dst_ipv6_ip, const swss::IpAddress& dst_ipv6_mask,
215236
const std::string& vrf_id)
216-
: dst_ipv6_ip(dst_ipv6_ip), dst_ipv6_mask(dst_ipv6_mask), vrf_id(vrf_id) {
217-
SWSS_LOG_ENTER();
237+
: src_ipv6_ip(src_ipv6_ip),
238+
src_ipv6_mask(src_ipv6_mask),
239+
dst_ipv6_ip(dst_ipv6_ip),
240+
dst_ipv6_mask(dst_ipv6_mask),
241+
vrf_id(vrf_id) {
242+
SWSS_LOG_ENTER();
218243
ipv6_tunnel_term_key = KeyGenerator::generateIpv6TunnelTermKey(
219-
dst_ipv6_ip, dst_ipv6_mask, vrf_id);
244+
src_ipv6_ip, src_ipv6_mask, dst_ipv6_ip, dst_ipv6_mask);
220245
}
221246

222247
ReturnCode TunnelDecapGroupManager::getSaiObject(const std::string& json_key,
@@ -269,10 +294,9 @@ ReturnCode TunnelDecapGroupManager::drain() {
269294
auto& app_db_entry = *app_db_entry_or;
270295

271296
const std::string ipv6_tunnel_term_entry_key =
272-
KeyGenerator::generateIpv6TunnelTermKey(app_db_entry.dst_ipv6_ip,
273-
app_db_entry.dst_ipv6_mask,
274-
app_db_entry.vrf_id);
275-
297+
KeyGenerator::generateIpv6TunnelTermKey(
298+
app_db_entry.src_ipv6_ip, app_db_entry.src_ipv6_mask,
299+
app_db_entry.dst_ipv6_ip, app_db_entry.dst_ipv6_mask);
276300
bool update =
277301
(getIpv6TunnelTermEntry(ipv6_tunnel_term_entry_key) != nullptr);
278302

@@ -334,11 +358,25 @@ TunnelDecapGroupManager::deserializeIpv6TunnelTermAppDbEntry(
334358
Ipv6TunnelTermAppDbEntry app_db_entry = {};
335359

336360
// Default IP and mask.
361+
app_db_entry.src_ipv6_ip = swss::IpAddress("0:0:0:0:0:0:0:0");
362+
app_db_entry.src_ipv6_mask = swss::IpAddress("0:0:0:0:0:0:0:0");
337363
app_db_entry.dst_ipv6_ip = swss::IpAddress("0:0:0:0:0:0:0:0");
338364
app_db_entry.dst_ipv6_mask = swss::IpAddress("0:0:0:0:0:0:0:0");
339365

340366
try {
341367
nlohmann::json j = nlohmann::json::parse(key);
368+
if (j.find(prependMatchField(p4orch::kDecapSrcIpv6)) != j.end()) {
369+
std::string src_ipv6 = j[prependMatchField(p4orch::kDecapSrcIpv6)];
370+
const auto& src_ip_and_mask =
371+
swss::tokenize(src_ipv6, p4orch::kDataMaskDelimiter);
372+
if (src_ip_and_mask.size() != 2) {
373+
return ReturnCode(StatusCode::SWSS_RC_INVALID_PARAM)
374+
<< "Invalid Ipv6 tunnel termination table entry: "
375+
<< "should be in the format of <value> & <mask>.";
376+
}
377+
app_db_entry.src_ipv6_ip = swss::IpAddress(trim(src_ip_and_mask[0]));
378+
app_db_entry.src_ipv6_mask = swss::IpAddress(trim(src_ip_and_mask[1]));
379+
}
342380
if (j.find(prependMatchField(p4orch::kDecapDstIpv6)) != j.end()) {
343381
std::string ipv6 = j[prependMatchField(p4orch::kDecapDstIpv6)];
344382
const auto& ip_and_mask =
@@ -388,10 +426,11 @@ std::vector<ReturnCode> TunnelDecapGroupManager::createIpv6TunnelTermEntries(
388426

389427
for (size_t i = 0; i < ipv6_tunnel_term_entries.size(); ++i) {
390428
statuses[i] = StatusCode::SWSS_RC_NOT_EXECUTED;
391-
entries.push_back(
392-
Ipv6TunnelTermTableEntry(ipv6_tunnel_term_entries[i].dst_ipv6_ip,
393-
ipv6_tunnel_term_entries[i].dst_ipv6_mask,
394-
ipv6_tunnel_term_entries[i].vrf_id));
429+
entries.push_back( Ipv6TunnelTermTableEntry(ipv6_tunnel_term_entries[i].src_ipv6_ip,
430+
ipv6_tunnel_term_entries[i].src_ipv6_mask,
431+
ipv6_tunnel_term_entries[i].dst_ipv6_ip,
432+
ipv6_tunnel_term_entries[i].dst_ipv6_mask,
433+
ipv6_tunnel_term_entries[i].vrf_id));
395434

396435
entries[i].vrf_oid =
397436
m_vrfOrch->getVRFid(ipv6_tunnel_term_entries[i].vrf_id);
@@ -451,10 +490,11 @@ std::vector<ReturnCode> TunnelDecapGroupManager::removeIpv6TunnelTermEntries(
451490

452491
const std::string ipv6_tunnel_term_entry_key =
453492
KeyGenerator::generateIpv6TunnelTermKey(
493+
ipv6_tunnel_term_entries[i].src_ipv6_ip,
494+
ipv6_tunnel_term_entries[i].src_ipv6_mask,
454495
ipv6_tunnel_term_entries[i].dst_ipv6_ip,
455-
ipv6_tunnel_term_entries[i].dst_ipv6_mask,
456-
ipv6_tunnel_term_entries[i].vrf_id);
457-
496+
ipv6_tunnel_term_entries[i].dst_ipv6_mask);
497+
458498
// getIpv6TunnelTermEntry() may return a nullptr.
459499
// For entry deletion operations validateIpv6TunnelTermAppDbEntry() checks
460500
// if the getIpv6TunnelTermEntry() function returns nullptr.
@@ -563,9 +603,9 @@ std::string TunnelDecapGroupManager::verifyState(
563603
auto& app_db_entry = *app_db_entry_or;
564604

565605
const std::string ipv6_tunnel_term_entry_key =
566-
KeyGenerator::generateIpv6TunnelTermKey(app_db_entry.dst_ipv6_ip,
567-
app_db_entry.dst_ipv6_mask,
568-
app_db_entry.vrf_id);
606+
KeyGenerator::generateIpv6TunnelTermKey(
607+
app_db_entry.src_ipv6_ip, app_db_entry.src_ipv6_mask,
608+
app_db_entry.dst_ipv6_ip, app_db_entry.dst_ipv6_mask);
569609
auto* ipv6_tunnel_term_entry =
570610
getIpv6TunnelTermEntry(ipv6_tunnel_term_entry_key);
571611
if (ipv6_tunnel_term_entry == nullptr) {
@@ -591,9 +631,10 @@ std::string TunnelDecapGroupManager::verifyStateCache(
591631
const Ipv6TunnelTermAppDbEntry& app_db_entry,
592632
const Ipv6TunnelTermTableEntry* ipv6_tunnel_term_entry) {
593633
const std::string ipv6_tunnel_term_entry_key =
594-
KeyGenerator::generateIpv6TunnelTermKey(app_db_entry.dst_ipv6_ip,
595-
app_db_entry.dst_ipv6_mask,
596-
app_db_entry.vrf_id);
634+
KeyGenerator::generateIpv6TunnelTermKey(
635+
app_db_entry.src_ipv6_ip, app_db_entry.src_ipv6_mask,
636+
app_db_entry.dst_ipv6_ip, app_db_entry.dst_ipv6_mask);
637+
597638
ReturnCode status =
598639
validateIpv6TunnelTermAppDbEntry(app_db_entry, SET_COMMAND);
599640
if (!status.ok()) {
@@ -621,6 +662,24 @@ std::string TunnelDecapGroupManager::verifyStateCache(
621662
<< " in Tunnel Decap Group manager.";
622663
return msg.str();
623664
}
665+
if (app_db_entry.src_ipv6_ip != ipv6_tunnel_term_entry->src_ipv6_ip) {
666+
std::stringstream msg;
667+
msg << "Ipv6 tunnel termination table entry with src_ipv6_ip "
668+
<< QuotedVar(app_db_entry.src_ipv6_ip.to_string())
669+
<< " does not match internal cache "
670+
<< QuotedVar(ipv6_tunnel_term_entry->src_ipv6_ip.to_string())
671+
<< " in Tunnel Decap Group manager.";
672+
return msg.str();
673+
}
674+
if (app_db_entry.src_ipv6_mask != ipv6_tunnel_term_entry->src_ipv6_mask) {
675+
std::stringstream msg;
676+
msg << "Ipv6 tunnel termination table entry with src_ipv6_mask "
677+
<< QuotedVar(app_db_entry.src_ipv6_mask.to_string())
678+
<< " does not match internal cache "
679+
<< QuotedVar(ipv6_tunnel_term_entry->src_ipv6_mask.to_string())
680+
<< " in Tunnel Decap Group manager.";
681+
return msg.str();
682+
}
624683
if (app_db_entry.dst_ipv6_ip != ipv6_tunnel_term_entry->dst_ipv6_ip) {
625684
std::stringstream msg;
626685
msg << "Ipv6 tunnel termination table entry with dst_ipv6_ip "

orchagent/p4orch/tunnel_decap_group_manager.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ extern "C" {
1818
// Ipv6TunnelTermTableEntry holds TunnelDecapGroupManager's internal cache of
1919
// tunnel termination table entry. Example:
2020
// P4RT:FIXED_IPV6_TUNNEL_TERMINATION_TABLE:{"match/dst_ipv6_64bit":
21-
// "2607:f8b0:c145:9300:: & ffff:ffff:ffff:ff00::"}
21+
// "2607:f8b0:c145:9300:: & ffff:ffff:ffff:ff00::",
22+
// "match/src_ipv6_64bit":"2607:f8b0:c145:9300:: & ffff:ffff:ffff:ff00::"}
2223
// "action" = "mark_for_tunnel_decap_and_set_vrf",
2324
// "param/vrf_id" = "b4-traffic",
2425
// "controller_metadata" = "..."
@@ -29,6 +30,8 @@ struct Ipv6TunnelTermTableEntry {
2930

3031
// Fields from P4 table.
3132
// Match
33+
swss::IpAddress src_ipv6_ip;
34+
swss::IpAddress src_ipv6_mask;
3235
swss::IpAddress dst_ipv6_ip;
3336
swss::IpAddress dst_ipv6_mask;
3437
// Action
@@ -39,9 +42,11 @@ struct Ipv6TunnelTermTableEntry {
3942
// SAI OID of the vrf_id for SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_VR_ID
4043
sai_object_id_t vrf_oid = SAI_NULL_OBJECT_ID;
4144

42-
Ipv6TunnelTermTableEntry(const swss::IpAddress& dst_ipv6_ip,
43-
const swss::IpAddress& dst_ipv6_mask,
44-
const std::string& vrf_id);
45+
Ipv6TunnelTermTableEntry(const swss::IpAddress& src_ipv6_ip,
46+
const swss::IpAddress& src_ipv6_mask,
47+
const swss::IpAddress& dst_ipv6_ip,
48+
const swss::IpAddress& dst_ipv6_mask,
49+
const std::string& vrf_id);
4550
};
4651
// LINT.ThenChange(tunnel_decap_group_manager.cpp:verify_state_cache)
4752

tests/mock_tests/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FLEX_CTR_DIR = $(top_srcdir)/orchagent/flex_counter
1+
FLEX_CTR_DIR = $(top_srcdir)/orchagent/flex_counter
22
DEBUG_CTR_DIR = $(top_srcdir)/orchagent/debug_counter
33
P4_ORCH_DIR = $(top_srcdir)/orchagent/p4orch
44
DASH_ORCH_DIR = $(top_srcdir)/orchagent/dash
@@ -195,6 +195,7 @@ tests_SOURCES += $(P4_ORCH_DIR)/p4orch.cpp \
195195
$(P4_ORCH_DIR)/mirror_session_manager.cpp \
196196
$(P4_ORCH_DIR)/gre_tunnel_manager.cpp \
197197
$(P4_ORCH_DIR)/l3_admit_manager.cpp \
198+
$(P4_ORCH_DIR)/l3_multicast_manager.cpp \
198199
$(P4_ORCH_DIR)/tunnel_decap_group_manager.cpp\
199200
$(P4_ORCH_DIR)/ext_tables_manager.cpp \
200201
$(P4_ORCH_DIR)/tests/mock_sai_switch.cpp

0 commit comments

Comments
 (0)