diff --git a/src/bm_sim/match_units.cpp b/src/bm_sim/match_units.cpp index ab43c944b..67a6780c8 100644 --- a/src/bm_sim/match_units.cpp +++ b/src/bm_sim/match_units.cpp @@ -986,7 +986,8 @@ MatchUnitGeneric::delete_entry_(entry_handle_t handle) { Entry &entry = entries[handle_]; if (HANDLE_VERSION(handle) != entry.key.version) return MatchErrorCode::EXPIRED_HANDLE; - entry.key.version += 1; + entry.key.version = HANDLE_VERSION(HANDLE_SET((entry.key.version + 1), + handle_)); lookup_structure->delete_entry(entry.key); return this->unset_handle(handle_); diff --git a/tests/test_tables.cpp b/tests/test_tables.cpp index f60fe41aa..055d86faa 100644 --- a/tests/test_tables.cpp +++ b/tests/test_tables.cpp @@ -362,6 +362,23 @@ TYPED_TEST(TableSizeTwo, DeleteEntryHandleUpdate) { ASSERT_EQ(MatchErrorCode::EXPIRED_HANDLE, rc); } +// This test was added for this issue: +// https://github.com/p4lang/behavioral-model/issues/549. +// Removing and entry increments the version field; the handle's version wraps +// around, but the entry's did not. +TYPED_TEST(TableSizeTwo, HandleVersionWrapAround) { + std::string key_ = "\xaa\xaa"; + ByteContainer key("0xaaaa"); + entry_handle_t handle; + MatchErrorCode rc; + for (unsigned int i = 0; i < 257; ++i) { + rc = this->add_entry(key_, &handle); + ASSERT_EQ(MatchErrorCode::SUCCESS, rc); + rc = this->table->delete_entry(handle); + ASSERT_EQ(MatchErrorCode::SUCCESS, rc); + } +} + TYPED_TEST(TableSizeTwo, LookupEntry) { std::string key_ = "\x0a\xba"; ByteContainer key("0x0aba");