feat(hicn-plugin): interest manifest 27/37027/18
authorMauro Sardara <msardara@cisco.com>
Fri, 26 Aug 2022 15:02:12 +0000 (15:02 +0000)
committerMauro Sardara <msardara@cisco.com>
Thu, 1 Sep 2022 13:20:29 +0000 (13:20 +0000)
Ref: HICN-748

Change-Id: Ie403de53a93094dca997cec379db6f5d3ce8e6be
Signed-off-by: Mauro Sardara <msardara@cisco.com>
25 files changed:
Dockerfile.dev
Makefile
apps/ping/src/ping_client.cc
hicn-light/src/hicn/core/forwarder.c
hicn-plugin/.clang-format
hicn-plugin/src/faces/iface_node.c
hicn-plugin/src/hicn.h
hicn-plugin/src/interest_hitpit_node.c
hicn-plugin/src/interest_pcslookup.h
hicn-plugin/src/interest_pcslookup_node.c
hicn-plugin/src/parser.h
hicn-plugin/src/strategy.h
hicn-plugin/src/strategy_node.c
lib/.clang-format
lib/includes/hicn/interest_manifest.h
lib/includes/hicn/util/bitmap.h
lib/src/packet.c
lib/src/test/test_interest_manifest.cc
libtransport/includes/hicn/transport/core/interest.h
libtransport/src/core/interest.cc
libtransport/src/core/packet.cc
libtransport/src/core/pending_interest.h
libtransport/src/core/portal.h
libtransport/src/protocols/transport_protocol.cc
libtransport/src/test/test_interest.cc

index e8c9097..ad7f997 100644 (file)
@@ -16,7 +16,8 @@ RUN apt update && apt-get install -y \
   sudo \
   curl \
   valgrind \
-  git
+  git \
+  zsh
 
 RUN make deps debug-tools
 
index df5f93b..9a80874 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -264,4 +264,4 @@ endif
 
 .PHONY = wipe-docker
 wipe-docker:
-       $(DOCKER) rm --force $(DEV_CONTAINER)
\ No newline at end of file
+       $(DOCKER) rm --force $(DEV_CONTAINER)
index 6cc6de5..bf95837 100644 (file)
@@ -218,9 +218,11 @@ class Client : interface::Portal::TransportCallback {
     const Name interest_name(config_->name_, (uint32_t)sequence_number_);
     hicn_packet_format_t format;
     if (interest_name.getAddressFamily() == AF_INET) {
-      format = HICN_PACKET_FORMAT_IPV4_TCP;
+      format = signer_ ? HICN_PACKET_FORMAT_IPV4_TCP_AH
+                       : HICN_PACKET_FORMAT_IPV4_TCP;
     } else {
-      format = HICN_PACKET_FORMAT_IPV6_TCP;
+      format = signer_ ? HICN_PACKET_FORMAT_IPV6_TCP_AH
+                       : HICN_PACKET_FORMAT_IPV6_TCP;
     }
 
     size_t additional_header_size = 0;
@@ -251,21 +253,22 @@ class Client : interface::Portal::TransportCallback {
       std::cout << ">>> send interest " << interest->getName() << std::endl;
     }
 
-    if (config_->dump_) {
-      std::cout << "----- interest dump -----" << std::endl;
-      interest->dump();
-      std::cout << "-------------------------" << std::endl;
-    }
-
     if (!config_->quiet_) std::cout << std::endl;
 
     send_timestamps_[sequence_number_] = utils::SteadyTime::now();
     for (uint64_t i = 1; i < seq_offset; i++)
       send_timestamps_[sequence_number_ + i] = utils::SteadyTime::now();
 
-    interest->encodeSuffixes();
     if (signer_) signer_->signPacket(interest.get());
 
+    if (config_->dump_) {
+      std::cout << "----- interest dump -----" << std::endl;
+      interest->dump();
+      std::cout << "-------------------------" << std::endl;
+    }
+
+    interest->encodeSuffixes();
+
     portal_.sendInterest(interest, interest->getLifetime());
 
     sequence_number_ += seq_offset;
index 14f1649..4fe1b6c 100644 (file)
@@ -776,10 +776,10 @@ static void _forwarder_update_interest_stats(forwarder_t *forwarder,
 /**
  * Return the interest manifest from the interest payload
  */
-static interest_manifest_header_t *_forwarder_get_interest_manifest(
-    msgbuf_t *msgbuf) {
+static int _forwarder_get_interest_manifest(
+    msgbuf_t *msgbuf, interest_manifest_header_t **int_manifest_header,
+    size_t *payload_size) {
   uint8_t *payload;
-  size_t payload_size;
 
   hicn_packet_buffer_t *pkbuf = msgbuf_get_pkbuf(msgbuf);
 
@@ -787,21 +787,14 @@ static interest_manifest_header_t *_forwarder_get_interest_manifest(
   HICN_UNUSED(int rc) = hicn_packet_get_payload_type(pkbuf, &payload_type);
   assert(rc == HICN_LIB_ERROR_NONE);
 
-  if (payload_type != HPT_MANIFEST) return NULL;
+  if (payload_type != HPT_MANIFEST) return -1;
 
-  rc = hicn_packet_get_payload(pkbuf, &payload, &payload_size, false);
+  rc = hicn_packet_get_payload(pkbuf, &payload, payload_size, false);
   assert(rc == HICN_LIB_ERROR_NONE);
 
-  interest_manifest_header_t *int_manifest_header =
-      (interest_manifest_header_t *)payload;
-
-  // Deserialize intrest mmanifest
-  interest_manifest_deserialize(int_manifest_header);
+  *int_manifest_header = (interest_manifest_header_t *)payload;
 
-  if (!interest_manifest_is_valid(int_manifest_header, payload_size))
-    return NULL;
-
-  return int_manifest_header;
+  return 0;
 }
 
 // Manifest is split using splitting strategy, then every
@@ -850,6 +843,9 @@ int _forwarder_forward_aggregated_interest(
              BITMAP_SIZE * sizeof(hicn_uword));
 
       size_t suffix_index = 0;  // Position of suffix in initial manifest
+      interest_manifest_header_t *manifest;
+      size_t payload_size;
+      int ret;
       while (suffix_index < total_suffixes) {
         // If more than one sub-manifest,
         // clone original interest manifest and update suffix
@@ -872,9 +868,10 @@ int _forwarder_forward_aggregated_interest(
         size_t first_suffix_index_in_next_submanifest = suffix_index;
 
         // Update manifest bitmap in current msgbuf
-        interest_manifest_header_t *manifest =
-            _forwarder_get_interest_manifest(msgbuf);
-        assert(manifest != NULL);
+
+        ret =
+            _forwarder_get_interest_manifest(msgbuf, &manifest, &payload_size);
+        assert(ret == 0);
         memcpy(manifest->request_bitmap, curr_bitmap,
                BITMAP_SIZE * sizeof(hicn_uword));
         WITH_TRACE({
@@ -974,24 +971,25 @@ static ssize_t forwarder_process_aggregated_interest(
   // `_forwarder_forward_aggregated_interest()`
   pkt_cache_entry_t *entries[BITMAP_SIZE * WORD_WIDTH];
 
-  int pos = 0;  // Position of current suffix in manifest
   int n_suffixes_to_fwd = 0;
-  u32 *suffix = (u32 *)(int_manifest_header + 1);
-  u32 seq = hicn_name_get_suffix(msgbuf_get_name(msgbuf));
 
   hicn_name_t name_copy = HICN_NAME_EMPTY;
   hicn_name_copy(&name_copy, msgbuf_get_name(msgbuf));
 
-  // The fist loop iteration handles the suffix in the header,
-  // the following ones handle the suffiexes in the manifest
-  while (true) {
-    if (!bitmap_is_set_no_check(int_manifest_header->request_bitmap, pos))
-      goto NEXT_SUFFIX;
+  // Suffixes in interest manifest also contains suffix in main name. We can
+  // then just iterate the interest manifest and update the suffix in the name
+  // struct
+  hicn_name_suffix_t *suffix;
+  int pos;
+  interest_manifest_foreach_suffix(int_manifest_header, suffix, pos) {
+    // Update name
+    hicn_name_set_suffix(&name_copy, *suffix);
 
     // Update packet cache
     pkt_cache_on_interest(forwarder->pkt_cache, msgbuf_pool, msgbuf_id,
                           &verdict, &data_msgbuf_id, &entry, &name_copy,
                           forwarder->serve_from_cs);
+
     entries[pos] = entry;
     _forwarder_update_interest_stats(forwarder, verdict, msgbuf,
                                      entry->has_expire_ts, entry->expire_ts);
@@ -1014,14 +1012,6 @@ static ssize_t forwarder_process_aggregated_interest(
       n_suffixes_to_fwd++;
     }
 
-  NEXT_SUFFIX:
-    if (pos++ >= int_manifest_header->n_suffixes) break;
-
-    // Use next segment in manifest
-    seq = *suffix;
-    suffix++;
-    hicn_name_set_suffix(&name_copy, seq);
-
     WITH_DEBUG({
       char buf[MAXSZ_HICN_PREFIX];
       int rc =
@@ -1063,9 +1053,19 @@ static ssize_t forwarder_process_interest(forwarder_t *forwarder,
   assert(msgbuf_get_type(msgbuf) == HICN_PACKET_TYPE_INTEREST);
 
   u32 n_suffixes = 0;
-  interest_manifest_header_t *int_manifest_header =
-      _forwarder_get_interest_manifest(msgbuf);
-  if (int_manifest_header) n_suffixes = int_manifest_header->n_suffixes;
+  interest_manifest_header_t *int_manifest_header;
+  size_t payload_size;
+  int ret = _forwarder_get_interest_manifest(msgbuf, &int_manifest_header,
+                                             &payload_size);
+  if (ret == 0) {
+    // Deserialize intrest manifest
+    interest_manifest_deserialize(int_manifest_header);
+
+    if (!interest_manifest_is_valid(int_manifest_header, payload_size))
+      return -1;
+
+    n_suffixes = int_manifest_header->n_suffixes;
+  }
 
   // Update stats
   forwarder->stats.countInterestsReceived++;
index 351a70e..7814184 100644 (file)
@@ -18,3 +18,4 @@ ForEachMacros:
   - 'vec_foreach_index'
   - 'vec_foreach_index_backwards'
   - 'vlib_foreach_rx_tx'
+  - 'interest_manifest_foreach_suffix'
index 598a68d..edfd2cd 100644 (file)
@@ -63,6 +63,7 @@ typedef struct
 typedef enum
 {
   HICN4_IFACE_INPUT_NEXT_INTEREST,
+  HICN4_IFACE_INPUT_NEXT_INTEREST_MANIFEST,
   HICN4_IFACE_INPUT_NEXT_MAPME,
   HICN4_IFACE_INPUT_NEXT_ERROR_DROP,
   HICN4_IFACE_INPUT_N_NEXT,
@@ -81,6 +82,7 @@ typedef struct
 typedef enum
 {
   HICN6_IFACE_INPUT_NEXT_INTEREST,
+  HICN6_IFACE_INPUT_NEXT_INTEREST_MANIFEST,
   HICN6_IFACE_INPUT_NEXT_MAPME,
   HICN6_IFACE_INPUT_NEXT_ERROR_DROP,
   HICN6_IFACE_INPUT_N_NEXT,
@@ -181,7 +183,7 @@ typedef enum
       IP_HEADER_##ipv *ip_hdr = NULL;                                         \
       hicn_buffer_t *hicnb0;                                                  \
       int ret0 = HICN_ERROR_NONE;                                             \
-      u8 is_icmp0;                                                            \
+      u8 is_icmp0, is_manifest0;                                              \
       /* Prefetch for next iteration. */                                      \
       if (n_left_from > 1)                                                    \
        {                                                                     \
@@ -206,6 +208,7 @@ typedef enum
       ret0 =                                                                  \
        hicn_interest_parse_pkt (b0, vlib_buffer_length_in_chain (vm, b0));   \
       is_icmp0 = (ret0 == HICN_ERROR_PARSER_MAPME_PACKET);                    \
+      is_manifest0 = hicnb0->payload_type == HPT_MANIFEST;                    \
       ret0 = (ret0 == HICN_ERROR_NONE) ||                                     \
             (ret0 == HICN_ERROR_PARSER_MAPME_PACKET);                        \
       if (PREDICT_FALSE (!ret0))                                              \
@@ -215,7 +218,7 @@ typedef enum
       else                                                                    \
        {                                                                     \
          next0 = is_icmp0 * NEXT_MAPME_IP##ipv +                             \
-                 (1 - is_icmp0) * NEXT_INTEREST_IP##ipv;                     \
+                 (1 - is_icmp0) * (NEXT_INTEREST_IP##ipv + is_manifest0);    \
                                                                               \
          next_iface0 = NEXT_DATA_LOOKUP_IP##ipv;                             \
          sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];                    \
@@ -273,7 +276,7 @@ typedef enum
       vlib_buffer_t *b0, *b1;                                                 \
       u32 bi0, bi1, next0, next1;                                             \
       u32 next_iface0, next_iface1, sw_if0 = ~0, sw_if1 = ~0;                 \
-      u8 is_icmp0, is_icmp1;                                                  \
+      u8 is_icmp0, is_icmp1, is_manifest0, is_manifest1;                      \
       IP_HEADER_##ipv *ip_hdr0 = NULL;                                        \
       IP_HEADER_##ipv *ip_hdr1 = NULL;                                        \
       int ret0 = HICN_ERROR_NONE, ret1 = HICN_ERROR_NONE;                     \
@@ -314,6 +317,8 @@ typedef enum
        hicn_interest_parse_pkt (b1, vlib_buffer_length_in_chain (vm, b1));   \
       is_icmp0 = ret0 == HICN_ERROR_PARSER_MAPME_PACKET;                      \
       is_icmp1 = ret1 == HICN_ERROR_PARSER_MAPME_PACKET;                      \
+      is_manifest0 = hicnb0->payload_type == HPT_MANIFEST;                    \
+      is_manifest1 = hicnb1->payload_type == HPT_MANIFEST;                    \
       ret0 = (ret0 == HICN_ERROR_NONE) ||                                     \
             (ret0 == HICN_ERROR_PARSER_MAPME_PACKET);                        \
       ret1 = (ret1 == HICN_ERROR_NONE) ||                                     \
@@ -322,10 +327,10 @@ typedef enum
       if (PREDICT_TRUE (ret0 && ret1))                                        \
        {                                                                     \
          next0 = is_icmp0 * NEXT_MAPME_IP##ipv +                             \
-                 (1 - is_icmp0) * NEXT_INTEREST_IP##ipv;                     \
+                 (1 - is_icmp0) * (NEXT_INTEREST_IP##ipv + is_manifest0);    \
                                                                               \
          next1 = is_icmp1 * NEXT_MAPME_IP##ipv +                             \
-                 (1 - is_icmp1) * NEXT_INTEREST_IP##ipv;                     \
+                 (1 - is_icmp1) * (NEXT_INTEREST_IP##ipv + is_manifest1);    \
                                                                               \
          next_iface0 = NEXT_DATA_LOOKUP_IP##ipv;                             \
          sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];                    \
@@ -562,6 +567,7 @@ VLIB_REGISTER_NODE (hicn4_iface_input_node) =
   .next_nodes =
   {
     [HICN4_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
+    [HICN4_IFACE_INPUT_NEXT_INTEREST_MANIFEST] = "hicn-interest-manifest-pcslookup",
     [HICN4_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
     [HICN4_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
   },
@@ -636,6 +642,7 @@ VLIB_REGISTER_NODE (hicn6_iface_input_node) =
   .next_nodes =
   {
     [HICN6_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
+    [HICN6_IFACE_INPUT_NEXT_INTEREST_MANIFEST] = "hicn-interest-manifest-pcslookup",
     [HICN6_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
     [HICN6_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
   },
index 3d8aa29..af23f3d 100644 (file)
@@ -44,6 +44,8 @@ typedef u8 weight_t;
 #define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
 #endif
 
+#define MAX_OUT_FACES 8
+
 /* The following is stored in the opaque2 field in the vlib_buffer_t */
 typedef struct
 {
index 9715fc5..a84aace 100644 (file)
@@ -151,7 +151,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
                  found =
                    hicn_pcs_entry_pit_search (pcs_entry, hicnb0->face_id);
 
-                 if (found)
+                 if (found && hicnb0->payload_type != HPT_MANIFEST)
                    {
                      // Retransmission
                      strategy_vft0->hicn_select_next_hop (
index 4da9c19..ba0e765 100644 (file)
@@ -58,6 +58,16 @@ typedef enum
   HICN_INTEREST_PCSLOOKUP_N_NEXT,
 } hicn_interest_pcslookup_next_t;
 
+typedef enum
+{
+  HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_FACE4,
+  HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_FACE6,
+  HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_INTEREST_HITPIT,
+  HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_INTEREST_HITCS,
+  HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_ERROR_DROP,
+  HICN_INTEREST_MANIFEST_PCSLOOKUP_N_NEXT,
+} hicn_interest_manifest_pcslookup_next_t;
+
 #endif /* // __HICN_INTEREST_PCSLOOKUP_H__ */
 
 /*
index ab6a31e..743227c 100644 (file)
@@ -23,6 +23,8 @@
 #include "error.h"
 #include "state.h"
 
+#include <hicn/interest_manifest.h>
+
 /**
  * @FILE This node performs a lookup in the PIT and CS for a received interest
  * packet.
@@ -46,12 +48,12 @@ static char *hicn_interest_pcslookup_error_strings[] = {
 vlib_node_registration_t hicn_interest_pcslookup_node;
 
 /*
- * ICN forwarder node for interests: handling of Interests delivered based on
- * ACL. - 1 packet at a time - ipv4/tcp ipv6/tcp
+ * ICN forwarder node for interests.
  */
 static uword
-hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
-                                vlib_frame_t *frame)
+hicn_interest_pcslookup_node_inline (vlib_main_t *vm,
+                                    vlib_node_runtime_t *node,
+                                    vlib_frame_t *frame)
 {
   int ret;
   u32 n_left_from, *from, *to_next;
@@ -97,7 +99,7 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
 
          b0 = vlib_get_buffer (vm, bi0);
 
-         // By default we send the interest to strategy node
+         // By default we send the interest to drop
          next0 = HICN_INTEREST_PCSLOOKUP_NEXT_STRATEGY;
 
          // Update stats
@@ -170,6 +172,320 @@ hicn_interest_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
   return (frame->n_vectors);
 }
 
+/*
+ * ICN forwarder node for interests manifest
+ */
+static uword
+hicn_interest_manifest_pcslookup_node_inline (vlib_main_t *vm,
+                                             vlib_node_runtime_t *node,
+                                             vlib_frame_t *frame)
+{
+  int ret;
+  u32 n_left_from, *from, *to_next;
+  hicn_interest_pcslookup_next_t next_index;
+  hicn_interest_pcslookup_runtime_t *rt;
+  vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
+  vlib_buffer_t *b0;
+  hicn_buffer_t *hicnb0;
+  u32 bi0;
+
+  const hicn_dpo_ctx_t *dpo_ctx;
+  const hicn_strategy_vft_t *strategy;
+
+  u16 outfaces_len;
+
+  // For cloning
+  u32 clones[MAX_OUT_FACES];
+  hicn_face_id_t outfaces[MAX_OUT_FACES];
+  u32 next0 = HICN_INTEREST_PCSLOOKUP_NEXT_ERROR_DROP;
+  hicn_pcs_entry_t *pcs_entry = NULL;
+  interest_manifest_header_t *int_manifest_header = NULL;
+  int pos = 0;
+
+  rt = vlib_node_get_runtime_data (vm, hicn_interest_pcslookup_node.index);
+
+  if (PREDICT_FALSE (rt->pitcs == NULL))
+    {
+      rt->pitcs = &hicn_main.pitcs;
+    }
+  from = vlib_frame_vector_args (frame);
+  n_left_from = frame->n_vectors;
+  next_index = node->cached_next_index;
+  int forward = 0;
+
+  vlib_buffer_t *cloneb;
+
+  // Register now
+  f64 tnow = vlib_time_now (vm);
+
+  while (n_left_from > 0)
+    {
+      u32 n_left_to_next;
+      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+      while (n_left_from > 0 && n_left_to_next > 0)
+       {
+         /* Prefetch for next iteration. */
+         if (n_left_from > 1)
+           {
+             vlib_buffer_t *b1;
+             b1 = vlib_get_buffer (vm, from[1]);
+             CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE);
+           }
+
+         // Dequeue a packet buffer
+         bi0 = from[0];
+         from += 1;
+         n_left_from -= 1;
+
+         b0 = vlib_get_buffer (vm, bi0);
+         hicnb0 = hicn_get_buffer (b0);
+
+         // By default we send the interest to drop node
+         next0 = HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_ERROR_DROP;
+
+         // Update stats
+         stats.pkts_processed++;
+
+         // Do not forward by default
+         forward = 0;
+
+         // Check if the interest is in the PCS already
+         hicn_name_t name;
+         hicn_packet_get_name (&hicn_get_buffer (b0)->pkbuf, &name);
+
+         ASSERT (hicn_buffer_get_payload_type (b0) == HPT_MANIFEST);
+
+         // Process interest manifest
+         u8 *payload;
+         size_t payload_size;
+         hicn_interest_get_payload (&hicn_get_buffer (b0)->pkbuf, &payload,
+                                    &payload_size, 0);
+         int_manifest_header = (interest_manifest_header_t *) (payload);
+
+         // Deserialize interest manifest
+         interest_manifest_deserialize (int_manifest_header);
+
+         hicn_name_suffix_t *suffix;
+         if (interest_manifest_is_valid (int_manifest_header, payload_size))
+           {
+             interest_manifest_foreach_suffix (int_manifest_header, suffix,
+                                               pos)
+               {
+                 name.suffix = *suffix;
+                 ret = hicn_pcs_lookup_one (rt->pitcs, &name, &pcs_entry);
+
+                 if (ret == HICN_ERROR_NONE)
+                   {
+                     // Match in PCS. We need to clone a packet for the
+                     // interest_hic{pit,cs} nodes.
+
+                     next0 = HICN_INTEREST_PCSLOOKUP_NEXT_INTEREST_HITPIT +
+                             hicn_pcs_entry_is_cs (pcs_entry);
+
+                     vlib_buffer_clone (vm, bi0, clones, 1, 0);
+                     cloneb = vlib_get_buffer (vm, clones[0]);
+
+                     ret = hicn_store_internal_state (
+                       cloneb,
+                       hicn_pcs_entry_get_index (rt->pitcs, pcs_entry),
+                       vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+
+                     if (PREDICT_FALSE (ret != HICN_ERROR_NONE))
+                       next0 = HICN_INTEREST_PCSLOOKUP_NEXT_ERROR_DROP;
+
+                     to_next[0] = clones[0];
+                     to_next += 1;
+                     n_left_to_next -= 1;
+
+                     // Distinguish between aggregation or retransmission
+                     ret = hicn_pcs_entry_pit_search (
+                       pcs_entry, hicn_get_buffer (b0)->face_id);
+                     if (!ret)
+                       {
+                         // Aggregated interest. Unset the corresponding
+                         // position in bitmap.
+                         bitmap_unset_no_check (
+                           int_manifest_header->request_bitmap, pos);
+                       }
+                     else
+                       {
+                         // Interest must be forwarded fo face node as it
+                         // contains retransmissions
+                         forward = 1;
+                       }
+
+                     // Maybe trace
+                     if (PREDICT_FALSE (
+                           (node->flags & VLIB_NODE_FLAG_TRACE) &&
+                           (b0->flags & VLIB_BUFFER_IS_TRACED)))
+                       {
+                         hicn_interest_pcslookup_trace_t *t =
+                           vlib_add_trace (vm, node, b0, sizeof (*t));
+                         t->pkt_type = HICN_PACKET_TYPE_INTEREST;
+                         t->sw_if_index =
+                           vnet_buffer (b0)->sw_if_index[VLIB_RX];
+                         t->next_index = next0;
+                       }
+                     /*
+                      * Verify speculative enqueue, maybe switch current
+                      * next frame
+                      */
+                     vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                                      to_next, n_left_to_next,
+                                                      clones[0], next0);
+                   }
+                 else
+                   {
+                     // No match. Create new pcs entry and set interest to be
+                     // forwarded
+                     pcs_entry = hicn_pcs_entry_pit_get (
+                       rt->pitcs, tnow, hicn_buffer_get_lifetime (b0));
+
+                     // Add entry to PCS table
+                     ret = hicn_pcs_pit_insert (rt->pitcs, pcs_entry, &name);
+
+                     // This cannot fail as we just checked if PCS contains
+                     // this entry
+                     assert (ret == HICN_ERROR_NONE);
+
+                     // Store internal state
+                     ret = hicn_store_internal_state (
+                       b0, hicn_pcs_entry_get_index (rt->pitcs, pcs_entry),
+                       vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
+
+                     if (PREDICT_FALSE (ret != HICN_ERROR_NONE))
+                       {
+                         // Remove entry
+                         hicn_pcs_entry_remove_lock (rt->pitcs, pcs_entry);
+                         // We do not drop the packet as it is an interest
+                         // manifest.
+                         continue;
+                       }
+
+                     // Add face
+                     hicn_pcs_entry_pit_add_face (
+                       pcs_entry, hicn_get_buffer (b0)->face_id);
+
+                     forward = 1;
+                   }
+               }
+           }
+         else
+           {
+             next0 = HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_ERROR_DROP;
+           }
+
+         // If interest must be forwarded, let's do it now
+         if (forward)
+           {
+             // Serialize interest manifest again
+             interest_manifest_serialize (int_manifest_header);
+
+             // Get the strategy VFT
+             hicnb0->dpo_ctx_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
+             dpo_ctx = hicn_strategy_dpo_ctx_get (hicnb0->dpo_ctx_id);
+             hicnb0->vft_id = dpo_ctx->dpo_type;
+             strategy = hicn_dpo_get_strategy_vft (hicnb0->vft_id);
+             strategy->hicn_add_interest (hicnb0->dpo_ctx_id);
+
+             // Check we have at least one next hop for the packet
+             ret = strategy->hicn_select_next_hop (hicnb0->dpo_ctx_id,
+                                                   outfaces, &outfaces_len);
+             if (ret == HICN_ERROR_NONE)
+               {
+                 next0 = hicn_buffer_is_v6 (b0) ?
+                                 HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_FACE6 :
+                                 HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_FACE4;
+
+                 // Clone interest if needed
+                 if (outfaces_len > 1)
+                   {
+                     ret =
+                       vlib_buffer_clone (vm, bi0, clones, (u16) outfaces_len,
+                                          CLIB_CACHE_LINE_BYTES * 2);
+                     ASSERT (ret == outfaces_len);
+                   }
+                 else
+                   {
+                     clones[0] = bi0;
+                   }
+
+                 // Send interest to next hops
+                 for (u32 nh = 0; nh < outfaces_len; nh++)
+                   {
+                     vlib_buffer_t *local_b0 =
+                       vlib_get_buffer (vm, clones[nh]);
+
+                     to_next[0] = clones[nh];
+                     to_next += 1;
+                     n_left_to_next -= 1;
+
+                     vnet_buffer (local_b0)->ip.adj_index[VLIB_TX] =
+                       outfaces[nh];
+                     stats.pkts_interest_count++;
+
+                     // Maybe trace
+                     if (PREDICT_FALSE (
+                           (node->flags & VLIB_NODE_FLAG_TRACE) &&
+                           (local_b0->flags & VLIB_BUFFER_IS_TRACED)))
+                       {
+                         hicn_strategy_trace_t *t =
+                           vlib_add_trace (vm, node, local_b0, sizeof (*t));
+                         t->pkt_type = HICN_PACKET_TYPE_DATA;
+                         t->sw_if_index =
+                           vnet_buffer (local_b0)->sw_if_index[VLIB_RX];
+                         t->next_index = next0;
+                         t->dpo_type = hicnb0->vft_id;
+                       }
+
+                     /*
+                      * Fix in case of a wrong speculation. Needed for
+                      * cloning the data in the right frame
+                      */
+                     vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                                      to_next, n_left_to_next,
+                                                      clones[nh], next0);
+                   }
+               }
+             else
+               {
+                 next0 = HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_ERROR_DROP;
+
+                 to_next[0] = bi0;
+                 to_next += 1;
+                 n_left_to_next -= 1;
+
+                 /*
+                  * Fix in case of a wrong speculation. Needed for
+                  * cloning the data in the right frame
+                  */
+                 vlib_validate_buffer_enqueue_x1 (
+                   vm, node, next_index, to_next, n_left_to_next, bi0, next0);
+               }
+           }
+       }
+      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+    }
+
+  u32 pit_int_count = hicn_pcs_get_pit_count (rt->pitcs);
+  u32 pit_cs_count = hicn_pcs_get_cs_count (rt->pitcs);
+
+  vlib_node_increment_counter (vm, hicn_interest_pcslookup_node.index,
+                              HICNFWD_ERROR_PROCESSED, stats.pkts_processed);
+
+  vlib_node_increment_counter (vm, hicn_interest_pcslookup_node.index,
+                              HICNFWD_ERROR_INTERESTS,
+                              stats.pkts_interest_count);
+
+  update_node_counter (vm, hicn_interest_pcslookup_node.index,
+                      HICNFWD_ERROR_INT_COUNT, pit_int_count);
+
+  update_node_counter (vm, hicn_interest_pcslookup_node.index,
+                      HICNFWD_ERROR_CS_COUNT, pit_cs_count);
+
+  return (frame->n_vectors);
+}
+
 /* packet trace format function */
 static u8 *
 hicn_interest_pcslookup_format_trace (u8 *s, va_list *args)
@@ -184,12 +500,23 @@ hicn_interest_pcslookup_format_trace (u8 *s, va_list *args)
   return (s);
 }
 
+VLIB_NODE_FN (hicn_interest_pcslookup_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+  return hicn_interest_pcslookup_node_inline (vm, node, frame);
+}
+
+VLIB_NODE_FN (hicn_interest_manifest_pcslookup_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+  return hicn_interest_manifest_pcslookup_node_inline (vm, node, frame);
+}
+
 /*
  * Node registration for the interest forwarder node
  */
 VLIB_REGISTER_NODE(hicn_interest_pcslookup_node) =
 {
-  .function = hicn_interest_pcslookup_node_fn,
   .name = "hicn-interest-pcslookup",
   .vector_size = sizeof(u32),
   .runtime_data_bytes = sizeof(hicn_interest_pcslookup_runtime_t),
@@ -207,6 +534,29 @@ VLIB_REGISTER_NODE(hicn_interest_pcslookup_node) =
   },
 };
 
+/*
+ * Node registration for the interest manifest forwarder node
+ */
+VLIB_REGISTER_NODE(hicn_interest_manifest_pcslookup_node) =
+{
+  .name = "hicn-interest-manifest-pcslookup",
+  .vector_size = sizeof(u32),
+  .runtime_data_bytes = sizeof(hicn_interest_pcslookup_runtime_t),
+  .format_trace = hicn_interest_pcslookup_format_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+  .n_errors = ARRAY_LEN(hicn_interest_pcslookup_error_strings),
+  .error_strings = hicn_interest_pcslookup_error_strings,
+  .n_next_nodes = HICN_INTEREST_MANIFEST_PCSLOOKUP_N_NEXT,
+  .next_nodes =
+  {
+    [HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_FACE4] = "hicn4-face-output",
+    [HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_FACE6] = "hicn6-face-output",
+    [HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit",
+    [HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs",
+    [HICN_INTEREST_MANIFEST_PCSLOOKUP_NEXT_ERROR_DROP] = "error-drop",
+  },
+};
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
index f9b3e43..e69a977 100644 (file)
  * @file parser.h
  */
 
-#define PARSE(PACKET_TYPE, SIZE)                                              \
-  do                                                                          \
-    {                                                                         \
-      if (pkt == NULL)                                                        \
-       return HICN_ERROR_PARSER_PKT_INVAL;                                   \
-                                                                              \
-      int ret = HICN_ERROR_NONE;                                              \
-                                                                              \
-      u16 *port;                                                              \
-      hicn_lifetime_t *lifetime;                                              \
-      hicn_payload_type_t payload_type;                                       \
-                                                                              \
-      hicn_packet_buffer_t *pkbuf = &hicn_get_buffer (pkt)->pkbuf;            \
-                                                                              \
-      hicn_packet_set_buffer (pkbuf, vlib_buffer_get_current (pkt), (SIZE),   \
-                             (SIZE));                                        \
-      hicn_packet_analyze (&hicn_get_buffer (pkt)->pkbuf);                    \
-                                                                              \
-      /* get source port*/                                                    \
-      port = &hicn_get_buffer (pkt)->port;                                    \
-      hicn_packet_get_src_port (pkbuf, port);                                 \
-      if (PREDICT_FALSE (ret))                                                \
-       {                                                                     \
-         return HICN_ERROR_PARSER_PKT_INVAL;                                 \
-       }                                                                     \
-                                                                              \
-      /* get lifetime*/                                                       \
-      lifetime = &hicn_get_buffer (pkt)->lifetime;                            \
-      hicn_packet_get_lifetime (pkbuf, lifetime);                             \
-                                                                              \
-      if (*lifetime > hicn_main.pit_lifetime_max_ms)                          \
-       *lifetime = hicn_main.pit_lifetime_max_ms;                            \
-                                                                              \
-      /* get payload type */                                                  \
-      hicn_packet_get_payload_type (pkbuf, &payload_type);                    \
-      hicn_get_buffer (pkt)->payload_type = (u16) (payload_type);             \
-      return ret;                                                             \
-    }                                                                         \
-  while (0)
+always_inline int
+parse (vlib_buffer_t *pkt, uword size)
+{
+  if (pkt == NULL)
+    return HICN_ERROR_PARSER_PKT_INVAL;
+
+  int ret = HICN_ERROR_NONE;
+
+  u16 *port;
+  hicn_lifetime_t *lifetime;
+  hicn_payload_type_t payload_type;
+
+  hicn_packet_buffer_t *pkbuf = &hicn_get_buffer (pkt)->pkbuf;
+
+  hicn_packet_set_buffer (pkbuf, vlib_buffer_get_current (pkt), size, size);
+  hicn_packet_analyze (&hicn_get_buffer (pkt)->pkbuf);
+
+  /* get source port*/
+  port = &hicn_get_buffer (pkt)->port;
+  hicn_packet_get_src_port (pkbuf, port);
+  if (PREDICT_FALSE (ret))
+    {
+      return HICN_ERROR_PARSER_PKT_INVAL;
+    }
+
+  /* get lifetime*/
+  lifetime = &hicn_get_buffer (pkt)->lifetime;
+  hicn_packet_get_lifetime (pkbuf, lifetime);
+
+  if (*lifetime > hicn_main.pit_lifetime_max_ms)
+    *lifetime = hicn_main.pit_lifetime_max_ms;
+
+  /* get payload type */
+  hicn_packet_get_payload_type (pkbuf, &payload_type);
+  hicn_get_buffer (pkt)->payload_type = (u16) (payload_type);
+  return ret;
 
 #if 0
       hicn_name_t *name;                                                      \
@@ -81,6 +78,7 @@
          return HICN_ERROR_PARSER_PKT_INVAL;
        }
 #endif
+}
 
 /**
  * @brief Parse a interest packet
@@ -96,7 +94,7 @@
 always_inline int
 hicn_interest_parse_pkt (vlib_buffer_t *pkt, uword size)
 {
-  PARSE (interest, size);
+  return parse (pkt, size);
 }
 
 /**
@@ -113,7 +111,7 @@ hicn_interest_parse_pkt (vlib_buffer_t *pkt, uword size)
 always_inline int
 hicn_data_parse_pkt (vlib_buffer_t *pkt, uword size)
 {
-  PARSE (data, size);
+  return parse (pkt, size);
 }
 
 #endif /* __HICN_PARSER_H__ */
index 85fc1e1..ffc5291 100644 (file)
@@ -85,8 +85,6 @@ const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] = {
   [DPO_PROTO_IP4] = hicn_ip4_nodes,
 };
 
-const static uint32_t MAX_OUT_FACES = 8;
-
 extern vlib_node_registration_t hicn_strategy_node;
 
 #endif /* //__HICN_STRATEGY__ */
index 5f5a107..3158507 100644 (file)
@@ -163,7 +163,6 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
          hicn_name_t name;
          hicn_packet_get_name (&hicnb0->pkbuf, &name);
          ret = hicn_pcs_pit_insert (rt->pitcs, pcs_entry, &name);
-         //&hicnb0->name);
 
          if (PREDICT_FALSE (ret != HICN_ERROR_NONE))
            {
index 351a70e..b4846b6 100644 (file)
@@ -10,11 +10,5 @@ BreakBeforeBinaryOperators: None
 ContinuationIndentWidth: 2
 
 ForEachMacros:
-  - 'clib_bitmap_foreach'
-  - 'pool_foreach'
-  - 'pool_foreach_index'
-  - 'vec_foreach'
-  - 'vec_foreach_backwards'
-  - 'vec_foreach_index'
-  - 'vec_foreach_index_backwards'
-  - 'vlib_foreach_rx_tx'
+  - 'interest_manifest_foreach_suffix'
+
index 2b4cd57..b6122ce 100644 (file)
@@ -44,7 +44,7 @@ typedef struct
   /* This can be 16 bits, but we use 32 bits for alignment */
   uint32_t n_suffixes;
 
-  /* Align to 64 bits */
+  /* First suffix */
   uint32_t padding;
 
   hicn_uword request_bitmap[BITMAP_SIZE];
@@ -102,7 +102,27 @@ interest_manifest_serialize (interest_manifest_header_t *int_manifest_header)
 static inline void
 interest_manifest_deserialize (interest_manifest_header_t *int_manifest_header)
 {
-  _interest_manifest_deserialize (int_manifest_header, hicn_uword_bits);
+  u32 n_suffixes = 0;
+
+  int_manifest_header->n_suffixes =
+    hicn_net_to_host_32 (int_manifest_header->n_suffixes);
+  int_manifest_header->padding =
+    hicn_net_to_host_32 (int_manifest_header->padding);
+
+  for (unsigned i = 0; i < BITMAP_SIZE; i++)
+    {
+      int_manifest_header->request_bitmap[i] =
+       hicn_net_to_host_64 (int_manifest_header->request_bitmap[i]);
+    }
+
+  hicn_name_suffix_t *suffix =
+    (hicn_name_suffix_t *) (int_manifest_header + 1);
+
+  n_suffixes = int_manifest_header->n_suffixes;
+  for (unsigned i = 0; i < n_suffixes; i++)
+    {
+      *(suffix + i) = hicn_net_to_host_32 (*(suffix + i));
+    }
 }
 
 static inline bool
@@ -131,15 +151,6 @@ interest_manifest_is_valid (interest_manifest_header_t *int_manifest_header,
   return true;
 }
 
-static inline void
-interest_manifest_init (interest_manifest_header_t *int_manifest_header)
-{
-  int_manifest_header->n_suffixes = 0;
-  int_manifest_header->padding = 0;
-  memset (int_manifest_header->request_bitmap, 0,
-         sizeof (int_manifest_header->request_bitmap));
-}
-
 static inline void
 interest_manifest_add_suffix (interest_manifest_header_t *int_manifest_header,
                              hicn_name_suffix_t suffix)
@@ -151,6 +162,18 @@ interest_manifest_add_suffix (interest_manifest_header_t *int_manifest_header,
   int_manifest_header->n_suffixes++;
 }
 
+static inline void
+interest_manifest_init (interest_manifest_header_t *int_manifest_header,
+                       u32 fist_suffix)
+{
+  int_manifest_header->n_suffixes = 0;
+  int_manifest_header->padding = 0;
+  memset (int_manifest_header->request_bitmap, 0,
+         sizeof (int_manifest_header->request_bitmap));
+
+  interest_manifest_add_suffix (int_manifest_header, fist_suffix);
+}
+
 static inline void
 interest_manifest_del_suffix (interest_manifest_header_t *int_manifest_header,
                              hicn_uword pos)
@@ -182,13 +205,16 @@ interest_manifest_update_bitmap (const hicn_uword *initial_bitmap,
 
 #define _FIRST(h) (hicn_name_suffix_t *) (h + 1)
 
-#define interest_manifest_foreach_suffix(header, suffix)                      \
+#define interest_manifest_foreach_suffix(header, suffix, pos)                 \
   for (suffix = _FIRST (header) + bitmap_first_set_no_check (                 \
-                                   header->request_bitmap, BITMAP_SIZE);     \
+                                   header->request_bitmap, BITMAP_SIZE),     \
+      pos = 0;                                                                \
        suffix - _FIRST (header) < header->n_suffixes;                         \
-       suffix = _FIRST (header) +                                             \
-               bitmap_next_set_no_check (header->request_bitmap,             \
-                                         suffix - _FIRST (header) + 1,       \
-                                         BITMAP_SIZE))
+       pos = suffix - _FIRST (header) + 1,                                    \
+      suffix = _FIRST (header) +                                              \
+              bitmap_next_set_no_check (header->request_bitmap,              \
+                                        suffix - _FIRST (header) + 1,        \
+                                        BITMAP_SIZE),                        \
+      pos = suffix - _FIRST (header))
 
 #endif /* HICNLIGHT_INTEREST_MANIFEST_H */
index 68541bc..d83c838 100644 (file)
@@ -40,7 +40,7 @@ typedef hicn_uword bitmap_t;
 #define BITMAP_INVALID_INDEX ((uint32_t) (~0))
 
 static inline int
-get_lowest_set_bit_index (hicn_uword w)
+hicn_get_lowest_set_bit_index (hicn_uword w)
 {
   return hicn_uword_bits > 32 ? __builtin_ctzll (w) : __builtin_ctz (w);
 }
@@ -132,7 +132,7 @@ _bitmap_set_no_check (bitmap_t *bitmap, off_t i)
 {
   size_t offset = i / BITMAP_WIDTH (bitmap);
   size_t pos = i % BITMAP_WIDTH (bitmap);
-  bitmap[offset] |= (bitmap_t) 1 << pos;
+  bitmap[offset] |= (hicn_uword) (1) << pos;
   return 0;
 }
 
@@ -178,7 +178,7 @@ _bitmap_unset (bitmap_t *bitmap, off_t i, int check)
     return -1;
   size_t offset = i / BITMAP_WIDTH (bitmap);
   size_t pos = i % BITMAP_WIDTH (bitmap);
-  bitmap[offset] &= ~(1ul << pos);
+  bitmap[offset] &= ~((hicn_uword) (1) << pos);
   return 0;
 }
 
@@ -258,13 +258,13 @@ bitmap_next_set_no_check (const bitmap_t *bitmap, hicn_uword i, size_t length)
       // This will zeroes all bits < i
       tmp = bitmap[pos] & mask;
       if (tmp)
-       return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+       return hicn_get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
 
       for (pos += 1; pos < length; pos++)
        {
          tmp = bitmap[pos];
          if (tmp)
-           return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+           return hicn_get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
        }
     }
 
@@ -291,13 +291,13 @@ bitmap_next_unset_no_check (const bitmap_t *bitmap, hicn_uword i,
       // This will zeroes all bits < i
       tmp = ~bitmap[pos] & mask;
       if (tmp)
-       return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+       return hicn_get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
 
       for (pos += 1; pos < length; pos++)
        {
          tmp = ~bitmap[pos];
          if (tmp)
-           return get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
+           return hicn_get_lowest_set_bit_index (tmp) + pos * WORD_WIDTH;
        }
     }
   return BITMAP_INVALID_INDEX;
index ad86afb..f020e09 100644 (file)
@@ -324,11 +324,12 @@ int
 hicn_packet_get_payload (const hicn_packet_buffer_t *pkbuf, u8 **payload,
                         size_t *payload_size, bool hard_copy)
 {
-  size_t payload_len = hicn_packet_get_len (pkbuf) - pkbuf->payload;
+  *payload_size = hicn_packet_get_len (pkbuf) - pkbuf->payload;
 
   if (hard_copy)
     {
-      memcpy (payload, pkbuf_get_header (pkbuf) + pkbuf->payload, payload_len);
+      memcpy (payload, pkbuf_get_header (pkbuf) + pkbuf->payload,
+             *payload_size);
     }
   else
     {
index 5df06d6..da7531f 100644 (file)
@@ -26,7 +26,7 @@ static constexpr hicn_uword WORD_SIZE = WORD_WIDTH;
 class InterestManifestTest : public ::testing::Test
 {
 protected:
-  static constexpr u32 n_suffixes = 0x00000014;
+  static constexpr u32 n_suffixes = 0x00000014 + 1;
   static constexpr u32 padding = 0x21232425;
   static constexpr hicn_uword bitmap_word = ~0ULL;
   static inline std::vector<uint32_t> values = { 10, 22, 23, 43, 54, 65, 66,
@@ -106,7 +106,7 @@ TEST_F (InterestManifestTest, SerializeDeserialize)
 #endif
 
   auto header = reinterpret_cast<interest_manifest_header_t *> (buffer);
-  interest_manifest_init (header);
+  interest_manifest_init (header, 0);
 
   for (const auto &v : values)
     {
@@ -134,8 +134,15 @@ TEST_F (InterestManifestTest, SerializeDeserialize)
   hicn_name_suffix_t *suffix = (hicn_name_suffix_t *) (header + 1);
   for (unsigned i = 0; i < n_suffixes; i++)
     {
-      EXPECT_THAT (*(suffix + i),
-                  ::testing::Eq (hicn_host_to_net_32 (values[i])));
+      if (i == 0)
+       {
+         EXPECT_THAT (*(suffix + i), ::testing::Eq (hicn_name_suffix_t (0)));
+       }
+      else
+       {
+         EXPECT_THAT (*(suffix + i),
+                      ::testing::Eq (hicn_host_to_net_32 (values[i - 1])));
+       }
     }
 
   // Deserialize manifest
@@ -145,59 +152,73 @@ TEST_F (InterestManifestTest, SerializeDeserialize)
   EXPECT_THAT (header->n_suffixes, ::testing::Eq (n_suffixes));
 
   int i = 0;
-  interest_manifest_foreach_suffix (header, suffix)
-  {
-    EXPECT_THAT (*suffix, ::testing::Eq (values[i]));
-    i++;
-  }
+  int pos;
+  interest_manifest_foreach_suffix (header, suffix, pos)
+    {
+      if (pos == 0)
+       {
+         EXPECT_THAT (*suffix, ::testing::Eq (hicn_name_suffix_t (0)));
+       }
+      else
+       {
+         EXPECT_THAT (*suffix, ::testing::Eq (values[i]));
+         i++;
+       }
+    }
 }
 
 TEST_F (InterestManifestTest, ForEach)
 {
+  int pos;
+  hicn_name_suffix_t *suffix = nullptr;
   auto header = reinterpret_cast<interest_manifest_header_t *> (buffer);
-  header->n_suffixes = n_suffixes;
-  header->padding = padding;
-  memset (header->request_bitmap, 0xff, BITMAP_SIZE * sizeof (hicn_uword));
+  interest_manifest_init (header, 0);
 
-  hicn_name_suffix_t *suffix = (hicn_name_suffix_t *) (header + 1);
-  for (uint32_t i = 0; i < n_suffixes; i++)
+  for (const auto &v : values)
     {
-      *(suffix + i) = values[i];
+      interest_manifest_add_suffix (header, v);
     }
 
-  // Iterate over interest manifest. As bitmap is all 1, we should be able to
-  // iterate over all suffixes.
-  unsigned i = 0;
-  interest_manifest_foreach_suffix (header, suffix)
-  {
-    EXPECT_EQ (*suffix, values[i]);
-    i++;
-  }
+  // Iterate over interest manifest. bBbitmap should be all 1, we should be
+  // able to iterate over all suffixes.
+  interest_manifest_foreach_suffix (header, suffix, pos)
+    {
+      if (pos == 0)
+       {
+         EXPECT_EQ (*suffix, hicn_name_suffix_t (0));
+       }
+      else
+       {
+         EXPECT_EQ (*suffix, values[pos - 1]);
+       }
+    }
 
   std::set<uint32_t> set_values (values.begin (), values.end ());
 
   // Unset few bitmap positions
-  interest_manifest_del_suffix (header, 5);
+  interest_manifest_del_suffix (header, 5 + 1);
   set_values.erase (values[5]);
 
-  interest_manifest_del_suffix (header, 6);
+  interest_manifest_del_suffix (header, 6 + 1);
   set_values.erase (values[6]);
 
-  interest_manifest_del_suffix (header, 12);
+  interest_manifest_del_suffix (header, 12 + 1);
   set_values.erase (values[12]);
 
-  interest_manifest_del_suffix (header, 17);
+  interest_manifest_del_suffix (header, 17 + 1);
   set_values.erase (values[17]);
 
   // Iterate over interest manifest and remove elements in manifest from set.
   // The set should be empty at the end.
-  interest_manifest_foreach_suffix (header, suffix)
-  {
-    std::cout << suffix - _FIRST (header) << std::endl;
-    EXPECT_TRUE (set_values.find (*suffix) != set_values.end ())
-      << "The value was " << *suffix;
-    set_values.erase (*suffix);
-  }
+  interest_manifest_foreach_suffix (header, suffix, pos)
+    {
+      if (pos > 0)
+       {
+         EXPECT_TRUE (set_values.find (*suffix) != set_values.end ())
+           << "The value was " << *suffix;
+         set_values.erase (*suffix);
+       }
+    }
 
   EXPECT_TRUE (set_values.empty ());
 }
\ No newline at end of file
index 716ac6b..4288296 100644 (file)
@@ -92,10 +92,12 @@ class Interest
 
   void appendSuffix(std::uint32_t suffix);
 
-  void decodeSuffixes();
-
   void encodeSuffixes();
 
+  void serializeSuffixes();
+
+  void deserializeSuffixes();
+
   uint32_t *firstSuffix();
 
   uint32_t numberOfSuffixes();
index 777374b..10e1a6d 100644 (file)
@@ -169,31 +169,46 @@ void Interest::encodeSuffixes() {
   // We assume interest does not hold signature for the moment.
   auto int_manifest_header =
       (interest_manifest_header_t *)(writableData() + headerSize());
-  int_manifest_header->n_suffixes = (uint32_t)suffix_set_.size();
+
+  interest_manifest_init(int_manifest_header, name_.getSuffix());
   memset(int_manifest_header->request_bitmap, 0xFFFFFFFF,
          BITMAP_SIZE * sizeof(hicn_uword));
 
   uint32_t *suffix = (uint32_t *)(int_manifest_header + 1);
   for (auto it = suffix_set_.begin(); it != suffix_set_.end(); it++, suffix++) {
-    *suffix = *it;
+    interest_manifest_add_suffix(int_manifest_header, *it);
   }
 
   std::size_t additional_length =
       sizeof(interest_manifest_header_t) +
       int_manifest_header->n_suffixes * sizeof(uint32_t);
 
-  // Serialize interest manifest
-  interest_manifest_serialize(int_manifest_header);
-
   append(additional_length);
   updateLength();
 }
 
-void Interest::decodeSuffixes() {
-  if (!hasManifest()) return;
+void Interest::serializeSuffixes() {
+  if (!hasManifest()) {
+    return;
+  }
 
-  auto header = (interest_manifest_header_t *)(writableData() + headerSize());
-  interest_manifest_deserialize(header);
+  // We assume interest does not hold signature for the moment.
+  auto int_manifest_header =
+      (interest_manifest_header_t *)(writableData() + headerSize());
+  // Serialize interest manifest
+  interest_manifest_serialize(int_manifest_header);
+}
+
+void Interest::deserializeSuffixes() {
+  if (!hasManifest()) {
+    return;
+  }
+
+  // We assume interest does not hold signature for the moment.
+  auto int_manifest_header =
+      (interest_manifest_header_t *)(writableData() + headerSize());
+  // Serialize interest manifest
+  interest_manifest_deserialize(int_manifest_header);
 }
 
 uint32_t *Interest::firstSuffix() {
index 73134ce..e670ecb 100644 (file)
@@ -368,7 +368,7 @@ uint8_t Packet::getTTL() const {
   return hops;
 }
 
-bool Packet::hasAH() const { return _is_ah(hicn_packet_get_format(&pkbuf_)); }
+bool Packet::hasAH() const { return _is_ah(getFormat()); }
 
 utils::MemBuf::Ptr Packet::getSignature() const {
   if (!hasAH()) {
index fb10405..b901e7d 100644 (file)
@@ -57,38 +57,32 @@ class PendingInterest {
   ~PendingInterest() = default;
 
   template <typename Handler>
-  TRANSPORT_ALWAYS_INLINE void startCountdown(uint32_t lifetime, Handler &&cb) {
+  void startCountdown(uint32_t lifetime, Handler &&cb) {
     timer_.expires_from_now(std::chrono::milliseconds(lifetime));
     timer_.async_wait(std::forward<Handler>(cb));
   }
 
-  TRANSPORT_ALWAYS_INLINE void cancelTimer() { timer_.cancel(); }
+  void cancelTimer() { timer_.cancel(); }
 
-  TRANSPORT_ALWAYS_INLINE Interest::Ptr &&getInterest() {
-    return std::move(interest_);
-  }
+  Interest::Ptr &&getInterest() { return std::move(interest_); }
 
-  TRANSPORT_ALWAYS_INLINE void setInterest(const Interest::Ptr &interest) {
-    interest_ = interest;
-  }
+  const Interest::Ptr &getInterestReference() const { return interest_; }
+
+  void setInterest(const Interest::Ptr &interest) { interest_ = interest; }
 
-  TRANSPORT_ALWAYS_INLINE const OnContentObjectCallback &getOnDataCallback()
-      const {
+  const OnContentObjectCallback &getOnDataCallback() const {
     return on_content_object_callback_;
   }
 
-  TRANSPORT_ALWAYS_INLINE void setOnContentObjectCallback(
-      OnContentObjectCallback &&on_content_object) {
+  void setOnContentObjectCallback(OnContentObjectCallback &&on_content_object) {
     PendingInterest::on_content_object_callback_ = std::move(on_content_object);
   }
 
-  TRANSPORT_ALWAYS_INLINE const OnInterestTimeoutCallback &
-  getOnTimeoutCallback() const {
+  const OnInterestTimeoutCallback &getOnTimeoutCallback() const {
     return on_interest_timeout_callback_;
   }
 
-  TRANSPORT_ALWAYS_INLINE void setOnTimeoutCallback(
-      OnInterestTimeoutCallback &&on_interest_timeout) {
+  void setOnTimeoutCallback(OnInterestTimeoutCallback &&on_interest_timeout) {
     PendingInterest::on_interest_timeout_callback_ =
         std::move(on_interest_timeout);
   }
index f238034..d4fbb34 100644 (file)
@@ -319,8 +319,8 @@ class Portal : public ::utils::NonCopyable,
     uint32_t initial_hash = interest->getName().getHash32(false);
     auto hash = initial_hash + interest->getName().getSuffix();
     uint32_t seq = interest->getName().getSuffix();
-    const uint32_t *suffix = interest->firstSuffix();
-    auto n_suffixes = interest->numberOfSuffixes();
+    const uint32_t *suffix = interest->firstSuffix() + 1;
+    auto n_suffixes = interest->numberOfSuffixes() - 1;
     uint32_t counter = 0;
     // Set timers
     do {
@@ -412,9 +412,10 @@ class Portal : public ::utils::NonCopyable,
           UNSET_CALLBACK) {
     DCHECK(std::this_thread::get_id() == worker_.getThreadId());
 
-    io_module_->send(*interest);
     addInterestToPIT(interest, lifetime, std::move(on_content_object_callback),
                      std::move(on_interest_timeout_callback));
+    interest->serializeSuffixes();
+    io_module_->send(*interest);
   }
 
   /**
@@ -541,6 +542,22 @@ class Portal : public ::utils::NonCopyable,
     pending_interest_hash_table_.clear();
   }
 
+  void dumpPIT() {
+    std::vector<Name> sorted_elements;
+    for (const auto &[key, value] : pending_interest_hash_table_) {
+      sorted_elements.push_back(value.getInterestReference()->getName());
+    }
+
+    std::sort(sorted_elements.begin(), sorted_elements.end(),
+              [](const Name &a, const Name &b) {
+                return a.getSuffix() < b.getSuffix();
+              });
+
+    for (auto &elt : sorted_elements) {
+      LOG(INFO) << elt;
+    }
+  }
+
   /**
    * Callback called by the underlying connector upon reception of a packet
    * from the local forwarder.
@@ -620,6 +637,7 @@ class Portal : public ::utils::NonCopyable,
     DLOG_IF(INFO, VLOG_IS_ON(3)) << "processInterest " << interest.getName();
 
     // Save interest in PIT
+    interest.deserializeSuffixes();
     addInterestToPIT(interest.shared_from_this(), interest.getLifetime());
     if (TRANSPORT_EXPECT_TRUE(transport_callback_ != nullptr)) {
       transport_callback_->onInterest(interest);
index b180370..5b262e4 100644 (file)
@@ -159,7 +159,6 @@ void TransportProtocol::sendInterest(
   for (uint32_t i = 0; i < len; i++) {
     interest->appendSuffix(additional_suffixes->at(i));
   }
-  interest->encodeSuffixes();
 
   uint32_t lifetime = default_values::interest_lifetime;
   socket_->getSocketOption(GeneralTransportOptions::INTEREST_LIFETIME,
index ba63b6c..22dc014 100644 (file)
@@ -255,16 +255,13 @@ TEST_F(InterestTest, AppendSuffixesEncodeAndIterate) {
   // Encode them in wire format
   interest.encodeSuffixes();
 
-  // Decode suffixes from wire format
-  interest.decodeSuffixes();
-
   // Iterate over them. They should be in order and without repetitions
 
   auto suffix = interest.firstSuffix();
   auto n_suffixes = interest.numberOfSuffixes();
 
   for (uint32_t i = 0; i < n_suffixes; i++) {
-    EXPECT_EQ(*(suffix + i), (i + 1));
+    EXPECT_EQ(*(suffix + i), i);
   }
 }
 
@@ -282,16 +279,13 @@ TEST_F(InterestTest, AppendSuffixesWithGaps) {
   interest.encodeSuffixes();
   EXPECT_TRUE(interest.hasManifest());
 
-  // Decode suffixes from wire format
-  interest.decodeSuffixes();
-
   // Check first suffix correctness
   auto suffix = interest.firstSuffix();
   EXPECT_NE(suffix, nullptr);
-  EXPECT_EQ(*suffix, 1U);
+  EXPECT_EQ(*suffix, 0U);
 
   // Iterate over them. They should be in order and without repetitions
-  std::vector<uint32_t> expected = {1, 2, 5, 6};
+  std::vector<uint32_t> expected = {interest.getName().getSuffix(), 1, 2, 5, 6};
   EXPECT_EQ(interest.numberOfSuffixes(), expected.size());
 
   for (uint32_t seq : expected) {