aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/interest_pcslookup_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src/interest_pcslookup_node.c')
-rw-r--r--hicn-plugin/src/interest_pcslookup_node.c362
1 files changed, 356 insertions, 6 deletions
diff --git a/hicn-plugin/src/interest_pcslookup_node.c b/hicn-plugin/src/interest_pcslookup_node.c
index ab6a31e08..743227c18 100644
--- a/hicn-plugin/src/interest_pcslookup_node.c
+++ b/hicn-plugin/src/interest_pcslookup_node.c
@@ -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),
@@ -208,6 +535,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
*
* Local Variables: eval: (c-set-style "gnu") End: