From adbdfdf7489e1909f29e2dd02edb7d15c258ed19 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Fri, 16 Sep 2022 13:56:34 +0200 Subject: fix(hicn-light): fix routing issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ref: HICN-786 Change-Id: I541c87d2d810907489ca4f59b3d7740a18c108fb Signed-off-by: Jordan Augé --- lib/includes/hicn/name.h | 1 + lib/src/name.c | 84 +++++++++++++++++++++++------------------ lib/src/test/CMakeLists.txt | 1 + lib/src/test/test_ip_address.cc | 73 +++++++++++++++++++++++++++++++++++ lib/src/test/test_name.cc | 61 ++++++++++++++++++++++++++++++ lib/src/util/ip_address.c | 9 +++-- 6 files changed, 189 insertions(+), 40 deletions(-) create mode 100644 lib/src/test/test_ip_address.cc (limited to 'lib') diff --git a/lib/includes/hicn/name.h b/lib/includes/hicn/name.h index a1b8e1fc1..a4e8e02ad 100644 --- a/lib/includes/hicn/name.h +++ b/lib/includes/hicn/name.h @@ -309,6 +309,7 @@ bool hicn_prefix_equals (const hicn_prefix_t *p1, const hicn_prefix_t *p2); int hicn_prefix_snprintf (char *s, size_t size, const hicn_prefix_t *prefix); +uint8_t _hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos); uint8_t hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos); #define MAXSZ_HICN_PREFIX MAXSZ_IP_PREFIX diff --git a/lib/src/name.c b/lib/src/name.c index 1c933d466..f363eea90 100644 --- a/lib/src/name.c +++ b/lib/src/name.c @@ -251,7 +251,7 @@ int hicn_prefix_create_from_ip_prefix (const hicn_ip_prefix_t *hicn_ip_prefix, hicn_prefix_t *prefix) { - if (hicn_ip_prefix->family != AF_INET || hicn_ip_prefix->family != AF_INET6) + if (hicn_ip_prefix->family != AF_INET && hicn_ip_prefix->family != AF_INET6) return HICN_LIB_ERROR_INVALID_IP_ADDRESS; prefix->name = hicn_ip_prefix->address; prefix->len = (u8) (hicn_ip_prefix->len); @@ -320,6 +320,14 @@ hicn_prefix_is_v4 (const hicn_prefix_t *prefix) * But the bits are in host order... so we cannot use builtin functions to get * the position of the first 1 unless we swap bytes as was done previously, * which is costly and non-essential. + * + * + * Example: + * + * bits | 127 .. 120 | ... | 8 9 10 11 12 13 14 15 | 0 .. 7 | + * diff | | ... | 1 0 1 0 0 0 0 0 | | + * ^ + * bit of interest ----------------+ */ uint64_t @@ -329,40 +337,43 @@ _log2_nbo (uint64_t val) uint64_t result = 0; - if (val & 0xFFFFFFFF00000000) - val = val >> 32; - else - /* The first 32 bits of val are 0 */ - result = result | 32; - - if (val & 0xFFFF0000) - val = val >> 16; - else - result = result | 16; - - if (val & 0xFF00) - val = val >> 8; - else - result = result | 8; + /* Search for the first 1, starting from left */ - /* Val now contains the byte with at last 1 bit set (host bit order) */ - if (val & 0xF0) + /* The first 32 bits of val are 0 */ + if (!(val & 0x00000000FFFFFFFF)) { - val = val >> 4; - result = result | 4; + val = val >> 32; + result = result | 32; } - if (val & 0xC) + if (!(val & 0x0000FFFF)) { - val = val >> 2; - result = result | 2; + val = val >> 16; + result = result | 16; } - if (val & 0x2) + + if (!(val & 0x00FF)) { - val = val >> 1; - result = result | 1; + val = val >> 8; + result = result | 8; } + /* Val now contains the byte with at last 1 bit set (host bit order) */ + if (val & 0xF0) + val = val >> 4; + else + result = result | 4; + + if (val & 0xC) + val = val >> 2; + else + result = result | 2; + + if (val & 0x2) + val = val >> 1; + else + result = result | 1; + return result; } @@ -381,13 +392,6 @@ hicn_prefix_lpm (const hicn_prefix_t *p1, const hicn_prefix_t *p2) /* * As the ip_address_t mimics in*_addr and has network byte order * (and host bit order, we cannot directly use 64-bit operations: - * - * Example: - * - * bits | 7 .. 0 | 15 14 13 12 11 10 9 8 | .. | 127 .. 120 | - * diff | | 1 0 1 0 0 0 0 0 | .. | | - * ^ - * bit of interest ---------+ */ prefix_len += _log2_nbo (diff); break; @@ -416,7 +420,9 @@ hicn_prefix_clear (hicn_prefix_t *prefix, uint8_t start_from) * pos 7 6 5 4 3 2 1 0 (eg. start_from = 19, pos = 3) * mask 0 0 0 0 0 1 1 1 (= 1< + +#include +#include + +extern "C" +{ +#define WITH_TESTS +#include +} + +#define DEFAULT_SIZE 10 + +class IPAddressTest : public ::testing::Test +{ +protected: + IPAddressTest () {} + + virtual ~IPAddressTest () {} +}; + +TEST_F (IPAddressTest, IPAddressGetBit) +{ + hicn_ip_address_t a_0, a_1, a_1_0, a_1_1, a_1_48, a_1_49, a_1_63, a_1_64, + a_1_127; + + hicn_ip_address_pton ("0::0", &a_0); + hicn_ip_address_pton ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &a_1); + + hicn_ip_address_pton ("8000::0", &a_1_0); + hicn_ip_address_pton ("4000::0", &a_1_1); + hicn_ip_address_pton ("0:0:0:8000::0", &a_1_48); + hicn_ip_address_pton ("0:0:0:4000::0", &a_1_49); + hicn_ip_address_pton ("0:0:0:1::0", &a_1_63); + hicn_ip_address_pton ("0::8000:0:0:0", &a_1_64); + hicn_ip_address_pton ("0::1", &a_1_127); + +#if 0 + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_0, i), 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1, i), 1); +#endif + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_0, i), (i == 0) ? 1 : 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_1, i), (i == 1) ? 1 : 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_48, i), (i == 48) ? 1 : 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_49, i), (i == 49) ? 1 : 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_63, i), (i == 63) ? 1 : 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_64, i), (i == 64) ? 1 : 0); + for (unsigned i = 0; i < 128; i++) + EXPECT_EQ (hicn_ip_address_get_bit (&a_1_127, i), (i == 127) ? 1 : 0); +} diff --git a/lib/src/test/test_name.cc b/lib/src/test/test_name.cc index dbeab96cc..cd9ff2d4d 100644 --- a/lib/src/test/test_name.cc +++ b/lib/src/test/test_name.cc @@ -335,3 +335,64 @@ TEST_F (NameTest, NameNToP) rc = strcmp (dst, expected4.str ().c_str ()); EXPECT_EQ (rc, 0); } + +class PrefixTest : public ::testing::Test +{ +protected: + PrefixTest () {} + + virtual ~PrefixTest () {} +}; + +#define HICN_PREFIX(P, STR) \ + hicn_prefix_t P; \ + hicn_ip_prefix_t _##P; \ + EXPECT_EQ (hicn_ip_prefix_pton (STR, &_##P), 0); \ + EXPECT_EQ (hicn_prefix_create_from_ip_prefix (&_##P, &P), 0); + +TEST_F (PrefixTest, PrefixClear) +{ + HICN_PREFIX (hp_all, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"); + + for (unsigned i = 0; i < 127; i++) + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, i), 1); + + hicn_prefix_truncate (&hp_all, 127); + EXPECT_EQ (hicn_prefix_get_len (&hp_all), 127); + + for (unsigned i = 0; i < 126; i++) + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, i), 1) << "bit[" << i << "] != 1"; + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 127), 0); + + hicn_prefix_truncate (&hp_all, 126); + EXPECT_EQ (hicn_prefix_get_len (&hp_all), 126); + + for (unsigned i = 0; i < 125; i++) + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, i), 1); + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 126), 0); + EXPECT_EQ (_hicn_prefix_get_bit (&hp_all, 127), 0); +} + +TEST_F (PrefixTest, PrefixClear2) +{ + HICN_PREFIX (hp_all, "b002::3"); + + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 125), 0); + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 126), 1); + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 127), 1); + + hicn_prefix_truncate (&hp_all, 127); + EXPECT_EQ (hicn_prefix_get_len (&hp_all), 127); + + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 125), 0); + EXPECT_EQ (hicn_prefix_get_bit (&hp_all, 126), 1); + EXPECT_EQ (_hicn_prefix_get_bit (&hp_all, 127), 0); +} + +TEST_F (PrefixTest, PrefixLPM) +{ + HICN_PREFIX (b007, "b007::/64"); + HICN_PREFIX (b009, "b009::/64"); + + EXPECT_EQ (hicn_prefix_lpm (&b007, &b009), (uint32_t) 12); +} diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c index ba7c6475b..3624a6fca 100644 --- a/lib/src/util/ip_address.c +++ b/lib/src/util/ip_address.c @@ -164,7 +164,7 @@ hicn_ip_address_pton (const char *hicn_ip_address_str, if (pton_fd <= 0) return -1; - return 1; + return 0; } int @@ -292,7 +292,7 @@ hicn_ip_prefix_pton (const char *hicn_ip_address_str, goto ERR; free (addr); - return 1; + return 0; ERR: free (addr); return -1; @@ -409,11 +409,12 @@ hicn_ip_prefix_cmp (const hicn_ip_prefix_t *prefix1, return hicn_ip_address_cmp (&prefix1->address, &prefix2->address); } +/* Network byte order + host bit order */ + uint8_t hicn_ip_address_get_bit (const hicn_ip_address_t *address, uint8_t pos) { - u64 quad = address->v6.as_u64[pos / 64]; - return quad & (0x1 << pos % 64); + return (address->v6.as_u8[pos / 8] >> (7 - pos % 8)) & 0x1; } bool -- cgit 1.2.3-korg