aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2022-09-16 13:56:34 +0200
committerJordan Augé <jordan.auge+fdio@cisco.com>2022-09-23 15:18:44 +0200
commitadbdfdf7489e1909f29e2dd02edb7d15c258ed19 (patch)
treee12231bddf4d19be089af34d131760e58ddba62f
parentb498b1d3fe2684e0233986551fa581a07148e22b (diff)
fix(hicn-light): fix routing issues
Ref: HICN-786 Change-Id: I541c87d2d810907489ca4f59b3d7740a18c108fb Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
-rw-r--r--.dockerignore2
-rw-r--r--Makefile2
-rw-r--r--ctrl/libhicnctrl/src/modules/hicn_light/route.c8
-rw-r--r--hicn-light/src/hicn/config/commands.c13
-rw-r--r--hicn-light/src/hicn/core/fib.c83
-rw-r--r--hicn-light/src/hicn/test/test-fib.cc8
-rw-r--r--lib/includes/hicn/name.h1
-rw-r--r--lib/src/name.c84
-rw-r--r--lib/src/test/CMakeLists.txt1
-rw-r--r--lib/src/test/test_ip_address.cc73
-rw-r--r--lib/src/test/test_name.cc61
-rw-r--r--lib/src/util/ip_address.c9
-rw-r--r--libtransport/src/core/prefix.cc2
13 files changed, 287 insertions, 60 deletions
diff --git a/.dockerignore b/.dockerignore
index 486e001fb..f6a0b57c5 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -10,3 +10,5 @@ ci/Dockerfile*
**/.gitignore
**/info.txt
./install*
+.git
+**/debug*
diff --git a/Makefile b/Makefile
index 712a3392c..bc4d63774 100644
--- a/Makefile
+++ b/Makefile
@@ -92,7 +92,7 @@ vpp-dep:
VERSION_PATH=$(VERSIONFILE) sudo -E $(SHELL) scripts/install-vpp.sh
.PHONY = dep
-dep: vpp-dep commit-template
+dep: vpp-dep #commit-template
ifeq ($(shell uname),Darwin)
brew install $(MACOS_DEPENDS)
else ifeq ($(filter ubuntu debian,$(OS_ID)),$(OS_ID))
diff --git a/ctrl/libhicnctrl/src/modules/hicn_light/route.c b/ctrl/libhicnctrl/src/modules/hicn_light/route.c
index 1adfe4f36..22cf6fbc5 100644
--- a/ctrl/libhicnctrl/src/modules/hicn_light/route.c
+++ b/ctrl/libhicnctrl/src/modules/hicn_light/route.c
@@ -33,22 +33,22 @@ static int hicnlight_route_parse(const uint8_t *buffer, size_t size,
cmd_route_list_item_t *item = (cmd_route_list_item_t *)buffer;
if (!IS_VALID_NAME(item->face_name)) {
- ERROR("[hc_connection_parse] Invalid face_name received");
+ ERROR("[hc_route_parse] Invalid face_name received");
return -1;
}
if (!IS_VALID_ID(item->face_id)) {
- ERROR("[hc_connection_parse] Invalid face_id received");
+ ERROR("[hc_route_parse] Invalid face_id received");
return -1;
}
if (!IS_VALID_FAMILY(item->family)) {
- ERROR("[hc_listener_parse] Invalid family received");
+ ERROR("[hc_route_parse] Invalid family received");
return -1;
}
if (!IS_VALID_ADDRESS(item->remote_addr)) {
- ERROR("[hc_connection_parse] Invalid address received");
+ ERROR("[hc_route_parse] Invalid address received");
return -1;
}
diff --git a/hicn-light/src/hicn/config/commands.c b/hicn-light/src/hicn/config/commands.c
index 08c43ba24..6aa76ac7b 100644
--- a/hicn-light/src/hicn/config/commands.c
+++ b/hicn-light/src/hicn/config/commands.c
@@ -780,13 +780,14 @@ NACK:
return (uint8_t *)msg;
}
-static inline void fill_route_command(const fib_entry_t *entry,
- cmd_route_list_item_t *cmd) {
+static inline off_t fill_route_command(const fib_entry_t *entry,
+ cmd_route_list_item_t *cmd) {
const nexthops_t *nexthops = fib_entry_get_nexthops(entry);
assert(nexthops_get_len(nexthops) == nexthops_get_curlen(nexthops));
size_t num_nexthops = nexthops_get_len(nexthops);
+ off_t pos = 0;
- if (num_nexthops == 0) return;
+ if (num_nexthops == 0) return 0;
const hicn_prefix_t *prefix = fib_entry_get_prefix(entry);
const hicn_ip_address_t *address = hicn_prefix_get_ip_address(prefix);
@@ -799,8 +800,10 @@ static inline void fill_route_command(const fib_entry_t *entry,
cmd->len = hicn_prefix_get_len(prefix);
cmd->cost = DEFAULT_COST;
+ pos++;
cmd++;
});
+ return pos;
}
uint8_t *configuration_on_route_list(forwarder_t *forwarder, uint8_t *packet,
@@ -831,7 +834,9 @@ uint8_t *configuration_on_route_list(forwarder_t *forwarder, uint8_t *packet,
if (!msg) goto NACK;
cmd_route_list_item_t *payload = &msg->payload;
- fib_foreach_entry(fib, entry, { fill_route_command(entry, payload); });
+ off_t pos = 0;
+ fib_foreach_entry(fib, entry,
+ { pos += fill_route_command(entry, payload + pos); });
*reply_size = sizeof(msg->header) + n * sizeof(msg->payload);
return (uint8_t *)msg;
diff --git a/hicn-light/src/hicn/core/fib.c b/hicn-light/src/hicn/core/fib.c
index 64dd3fe7d..66e6ae339 100644
--- a/hicn-light/src/hicn/core/fib.c
+++ b/hicn-light/src/hicn/core/fib.c
@@ -124,14 +124,28 @@ fib_node_t *fib_search(const fib_t *fib, const hicn_prefix_t *prefix,
uint32_t curr_len;
uint32_t match_len;
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ INFO("FIB SEARCH: %s prefix len %d", buf, prefix_len);
+
fib_node_t *parent = NULL;
fib_node_t *gparent = NULL;
fib_node_t *curr = fib->root;
while (curr) {
const hicn_prefix_t *curr_prefix = fib_entry_get_prefix(curr->entry);
+
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, curr_prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ INFO(" >> current %s", buf);
+
curr_len = hicn_prefix_get_len(curr_prefix);
match_len = hicn_prefix_lpm(prefix, curr_prefix);
+ INFO("curr len %d match len %d", curr_len, match_len);
+
// XXX >= vs == for the second stop condition
// curr_len >= prefix_len l >= L
// L is a prefix of l
@@ -177,14 +191,30 @@ fib_node_t *_fib_insert(fib_t *fib, fib_entry_t *entry, fib_node_t *parent,
const hicn_prefix_t *parent_prefix = fib_entry_get_prefix(parent->entry);
uint32_t parent_prefix_len = hicn_prefix_get_len(parent_prefix);
uint8_t next_bit = hicn_prefix_get_bit(prefix, parent_prefix_len);
+ INFO("parent prefix len %d next bit %d", parent_prefix_len, next_bit);
parent->child[next_bit] = new_node;
}
if (child) {
- const hicn_prefix_t *curr_prefix = fib_entry_get_prefix(entry);
- uint32_t match_len = hicn_prefix_lpm(prefix, curr_prefix);
- uint8_t next_bit = hicn_prefix_get_bit(curr_prefix, match_len);
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc;
+
+ const hicn_prefix_t *child_prefix = fib_entry_get_prefix(child->entry);
+ INFO("prefix lengths %d==127 %d==128", hicn_prefix_get_len(prefix),
+ hicn_prefix_get_len(child_prefix));
+ INFO("LPM BETWEEN");
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ INFO("prefix %s", buf);
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, child_prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ INFO("child prefix %s", buf);
+ uint32_t match_len = hicn_prefix_lpm(prefix, child_prefix);
+ uint8_t next_bit = hicn_prefix_get_bit(child_prefix, match_len);
new_node->child[next_bit] = child;
+ INFO("child match len %d next bit %d", match_len, next_bit);
}
if (is_used) fib->size++;
@@ -291,12 +321,14 @@ void fib_add(fib_t *fib, fib_entry_t *entry) {
/* Case 1 */
if (!curr) {
+ INFO("Case 1");
_fib_insert(fib, entry, search.parent, NULL, true);
- return;
+ goto END;
}
/* Case 2 */
if (search.prefix_len == search.match_len && prefix_len == search.match_len) {
+ INFO("Case 2");
if (!curr->is_used) {
curr->is_used = true;
if (curr->entry) fib_entry_free(curr->entry);
@@ -308,24 +340,56 @@ void fib_add(fib_t *fib, fib_entry_t *entry) {
{ fib_entry_nexthops_add(curr->entry, nexthop); });
fib_entry_free(entry);
}
- return;
+ goto END;
}
/* Case 3 */
if (prefix_len == search.match_len) {
+ INFO("Case 3");
_fib_insert(fib, entry, search.parent, curr, true);
- return;
+ goto END;
}
/* Case 4 */
+ char buf[MAXSZ_HICN_PREFIX];
+ int rc;
+
+ INFO("Case 4 : match len = %d", search.match_len);
hicn_prefix_t inner_prefix; /* dup'ed in fib_entry_create */
hicn_prefix_copy(&inner_prefix, prefix);
+
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, &inner_prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ INFO("inner prefix before truncate %s", buf);
+ INFO("last bit should be 1: %d", hicn_prefix_get_bit(&inner_prefix, 127));
+
+ INFO("truncate to length = %d", search.match_len);
hicn_prefix_truncate(&inner_prefix, search.match_len);
+ INFO("last bit should be 0: %d", hicn_prefix_get_bit(&inner_prefix, 127));
+
+ rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, &inner_prefix);
+ if (rc < 0 || rc >= MAXSZ_HICN_PREFIX)
+ snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)");
+ INFO("inner prefix after truncate %s", buf);
+
fib_entry_t *inner_entry = fib_entry_create(
&inner_prefix, STRATEGY_TYPE_UNDEFINED, NULL, fib->forwarder);
+
+ INFO("inner prefix len=%d", hicn_prefix_get_len(&inner_prefix));
+ // debug
+ const hicn_prefix_t *parent_prefix = fib_entry_get_prefix(inner_entry);
+ INFO("inner prefix len=%d", hicn_prefix_get_len(parent_prefix));
+
+ INFO("insert inner");
fib_node_t *new_node =
_fib_insert(fib, inner_entry, search.parent, curr, false);
+ INFO("insert new node");
+ fib_dump(fib);
_fib_insert(fib, entry, new_node, NULL, true);
+
+END:
+ fib_dump(fib);
}
/*
@@ -345,7 +409,7 @@ fib_entry_t *fib_contains(const fib_t *fib, const hicn_prefix_t *prefix) {
fib_node_t *curr = fib_search(fib, prefix, &search);
if (!curr) return NULL;
- if (search.prefix_len != prefix_len) return NULL;
+ if (search.match_len != prefix_len) return NULL;
return curr->is_used ? curr->entry : NULL;
}
@@ -539,8 +603,6 @@ fib_entry_t *fib_match_prefix(const fib_t *fib, const hicn_prefix_t *prefix) {
assert(fib);
assert(prefix);
- uint32_t prefix_len = hicn_prefix_get_len(prefix);
-
fib_search_t search;
fib_node_t *curr = fib_search(fib, prefix, &search);
@@ -549,7 +611,8 @@ fib_entry_t *fib_match_prefix(const fib_t *fib, const hicn_prefix_t *prefix) {
if (!search.parent) return NULL;
return search.parent->entry;
}
- if ((search.prefix_len <= prefix_len) && curr->is_used) return curr->entry;
+ if ((search.prefix_len == search.match_len) && curr->is_used)
+ return curr->entry;
if (search.parent) return search.parent->entry;
return NULL;
}
diff --git a/hicn-light/src/hicn/test/test-fib.cc b/hicn-light/src/hicn/test/test-fib.cc
index 5db47415f..125515e41 100644
--- a/hicn-light/src/hicn/test/test-fib.cc
+++ b/hicn-light/src/hicn/test/test-fib.cc
@@ -83,3 +83,11 @@ TEST_F(FibTest, FibAddOne) {
/* Check that free indices and bitmaps are correctly updated */
}
+
+#if 0
+22-09-2022 13:07:57 fib_entry_on_event: b002::/64
+22-09-2022 13:08:01 fib_entry_on_event: b002::abcd:0:0:0/128
+22-09-2022 13:08:01 fib_entry_on_event: b002::2/128
+22-09-2022 13:08:01 fib_entry_on_event: b002::abcd:0:0:1/128
+22-09-2022 13:08:01 fib_entry_on_event: b002::3/128
+#endif
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<<pos - 1)
* */
- buffer[offset] &= 1 << (pos - 1);
+ uint8_t mask = 0xFF ^ ((1 << (8 - pos)) - 1);
+ buffer[offset] &= mask;
+
/* ... then fully clear remaining bytes */
for (uint8_t i = offset + 1; i < HICN_PREFIX_MAX_LEN; i++)
buffer[i] = 0;
@@ -454,13 +460,19 @@ 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)
+_hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos)
{
- assert (pos <= hicn_prefix_get_len (prefix));
const hicn_ip_address_t *address = hicn_prefix_get_ip_address (prefix);
return hicn_ip_address_get_bit (address, pos);
}
+uint8_t
+hicn_prefix_get_bit (const hicn_prefix_t *prefix, uint8_t pos)
+{
+ assert (pos <= hicn_prefix_get_len (prefix));
+ return _hicn_prefix_get_bit (prefix, pos);
+}
+
int
hicn_prefix_get_ip_prefix (const hicn_prefix_t *prefix,
hicn_ip_prefix_t *ip_prefix)
diff --git a/lib/src/test/CMakeLists.txt b/lib/src/test/CMakeLists.txt
index d828c8dd8..8cf4359d2 100644
--- a/lib/src/test/CMakeLists.txt
+++ b/lib/src/test/CMakeLists.txt
@@ -24,6 +24,7 @@ list(APPEND TESTS_SRC
test_validation.cc
test_bitmap.cc
test_interest_manifest.cc
+ test_ip_address.cc
test_khash.cc
test_pool.cc
test_ring.cc
diff --git a/lib/src/test/test_ip_address.cc b/lib/src/test/test_ip_address.cc
new file mode 100644
index 000000000..1a7efb603
--- /dev/null
+++ b/lib/src/test/test_ip_address.cc
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C"
+{
+#define WITH_TESTS
+#include <hicn/util/ip_address.h>
+}
+
+#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
diff --git a/libtransport/src/core/prefix.cc b/libtransport/src/core/prefix.cc
index d54dc909a..8c5b153bc 100644
--- a/libtransport/src/core/prefix.cc
+++ b/libtransport/src/core/prefix.cc
@@ -263,7 +263,7 @@ Name Prefix::mapName(const core::Name &content_name) const {
}
Prefix &Prefix::setNetwork(const std::string &network) {
- if (!hicn_ip_address_pton(network.c_str(), &hicn_ip_prefix_.address)) {
+ if (hicn_ip_address_pton(network.c_str(), &hicn_ip_prefix_.address) < 0) {
throw errors::RuntimeException("The network name is not valid.");
}