[ip6] update Ip6::Prefix comparison (#7813)

This commit updates `Ip6::Prefix` comparison (overload of `<`
operator). If the two prefixes have same length N, then the bytes are
compared directly (as two big-endian N-bit numbers). If the two
prefix have different lengths, the shorter prefix is padded by `0`
bit up to the longer prefix length N before the bytes are compared
(as big-endian N-bit numbers). If all bytes are equal, the prefix
with shorter length is considered smaller.

This commit also updates `test_ip_address` unit test to validate
the new comparison behavior.
This commit is contained in:
Abtin Keshavarzian
2022-06-16 21:28:08 -07:00
committed by GitHub
parent 16ddb157d0
commit 481a064f03
3 changed files with 55 additions and 6 deletions
+8 -4
View File
@@ -77,13 +77,17 @@ bool Prefix::IsEqual(const uint8_t *aPrefixBytes, uint8_t aPrefixLength) const
bool Prefix::operator<(const Prefix &aOther) const
{
bool isSmaller;
uint8_t minLength;
uint8_t matchedLength;
VerifyOrExit(GetLength() == aOther.GetLength(), isSmaller = GetLength() < aOther.GetLength());
minLength = OT_MIN(GetLength(), aOther.GetLength());
matchedLength = MatchLength(GetBytes(), aOther.GetBytes(), SizeForLength(minLength));
matchedLength = MatchLength(GetBytes(), aOther.GetBytes(), GetBytesSize());
VerifyOrExit(matchedLength < GetLength(), isSmaller = false);
if (matchedLength >= minLength)
{
isSmaller = (GetLength() < aOther.GetLength());
ExitNow();
}
isSmaller = GetBytes()[matchedLength / CHAR_BIT] < aOther.GetBytes()[matchedLength / CHAR_BIT];
+4 -2
View File
@@ -266,8 +266,10 @@ public:
/**
* This method overloads operator `<` to compare two prefixes.
*
* A prefix with shorter length is considered smaller than the one with longer length. If the prefix lengths are
* equal, then the prefix bytes are compared directly.
* If the two prefixes have the same length N, then the bytes are compared directly (as two big-endian N-bit
* numbers). If the two prefix have different lengths, the shorter prefix is padded by `0` bit up to the longer
* prefix length N before the bytes are compared (as big-endian N-bit numbers). If all bytes are equal, the prefix
* with shorter length is considered smaller.
*
* @param[in] aOther The other prefix to compare against.
*
+43
View File
@@ -274,6 +274,17 @@ void TestIp6AddressSetPrefix(void)
}
}
ot::Ip6::Prefix PrefixFrom(const char *aAddressString, uint8_t aPrefixLength)
{
ot::Ip6::Prefix prefix;
ot::Ip6::Address address;
SuccessOrQuit(address.FromString(aAddressString));
prefix.Set(address.GetBytes(), aPrefixLength);
return prefix;
}
void TestIp6Prefix(void)
{
const uint8_t kPrefixes[][OT_IP6_ADDRESS_SIZE] = {
@@ -351,6 +362,38 @@ void TestIp6Prefix(void)
}
}
}
{
struct TestCase
{
ot::Ip6::Prefix mPrefixA;
ot::Ip6::Prefix mPrefixB;
};
TestCase kTestCases[] = {
{PrefixFrom("fd00::", 16), PrefixFrom("fd01::", 16)},
{PrefixFrom("fc00::", 16), PrefixFrom("fd00::", 16)},
{PrefixFrom("fd00::", 15), PrefixFrom("fd00::", 16)},
{PrefixFrom("fd00::", 16), PrefixFrom("fd00:0::", 32)},
{PrefixFrom("2001:0:0:0::", 64), PrefixFrom("fd00::", 8)},
{PrefixFrom("2001:dba::", 32), PrefixFrom("fd12:3456:1234:abcd::", 64)},
{PrefixFrom("910b:1000:0::", 48), PrefixFrom("910b:2000::", 32)},
{PrefixFrom("::", 0), PrefixFrom("fd00::", 8)},
{PrefixFrom("::", 0), PrefixFrom("::", 16)},
{PrefixFrom("fd00:2:2::", 33), PrefixFrom("fd00:2:2::", 35)},
{PrefixFrom("1:2:3:ffff::", 62), PrefixFrom("1:2:3:ffff::", 63)},
};
printf("\nCompare Prefixes:\n");
for (const TestCase &testCase : kTestCases)
{
printf(" %26s < %s\n", testCase.mPrefixA.ToString().AsCString(),
testCase.mPrefixB.ToString().AsCString());
VerifyOrQuit(testCase.mPrefixA < testCase.mPrefixB);
VerifyOrQuit(!(testCase.mPrefixB < testCase.mPrefixA));
}
}
}
void TestIp4Ip6Translation(void)