aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/data_push_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src/data_push_node.c')
-rw-r--r--hicn-plugin/src/data_push_node.c256
1 files changed, 110 insertions, 146 deletions
diff --git a/hicn-plugin/src/data_push_node.c b/hicn-plugin/src/data_push_node.c
index a4a25e29b..d530173bc 100644
--- a/hicn-plugin/src/data_push_node.c
+++ b/hicn-plugin/src/data_push_node.c
@@ -22,6 +22,7 @@
#include "infra.h"
#include "mgmt.h"
#include "pcs.h"
+#include "state.h"
/*
* Node context data (to be used in all the strategy nodes); we think this is
@@ -42,6 +43,7 @@ static char *hicn_data_push_error_strings[] = {
typedef enum
{
+ HICN_DATA_PUSH_NEXT_FWD,
HICN_DATA_PUSH_NEXT_ERROR_DROP,
HICN_DATA_PUSH_N_NEXT,
} hicn_data_push_next_t;
@@ -60,34 +62,47 @@ vlib_node_registration_t hicn_data_push_node;
always_inline void
prep_buffer_for_cs (vlib_main_t * vm, vlib_buffer_t * b0, u8 isv6)
{
- if (isv6)
+ word buffer_advance = CLIB_CACHE_LINE_BYTES * 2;
+ hicn_buffer_t *hicnb = hicn_get_buffer (b0);
+
+ if (PREDICT_TRUE (b0->next_buffer == 0))
{
- /* Advance the vlib buffer to the beginning of the TCP header */
- vlib_buffer_advance (b0, sizeof (ip6_header_t) + sizeof (tcp_header_t));
b0->total_length_not_including_first_buffer = 0;
+ b0->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
+ }
+
+ /*
+ * Mark the buffer as smaller than TWO_CL. It will be stored as is in the CS, without excluding
+ * the hicn_header. Cloning is not possible, it will be copied.
+ */
+ if (b0->current_length < (buffer_advance + (CLIB_CACHE_LINE_BYTES * 2)))
+ {
+ /* In this case the packet is copied. We don't need to add a reference as no buffer are
+ * chained to it.
+ */
+ hicnb->flags |= HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL;
}
else
{
- /* Advance the vlib buffer to the beginning of the TCP header */
- vlib_buffer_advance (b0, sizeof (ip4_header_t) + sizeof (tcp_header_t));
- b0->total_length_not_including_first_buffer = 0;
+ vlib_buffer_advance (b0, buffer_advance);
}
}
always_inline int
hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt,
- vlib_buffer_t * b0, u32 * next, f64 tnow, u8 * nameptr,
- u16 namelen, u8 isv6)
+ vlib_buffer_t * b0, u32 ** to_forward, u32 * n_to_forward,
+ f64 tnow, u8 * nameptr, u16 namelen, u8 isv6)
{
int ret;
+ u32 bi0 = vlib_get_buffer_index (vm, b0);
hicn_hash_node_t *nodep;
hicn_pcs_entry_t *pitp;
hicn_header_t *hicn0;
hicn_buffer_t *hicnb0 = hicn_get_buffer (b0);
u32 node_id0 = 0;
- u8 dpo_ctx_id0 = 0;
- u8 vft_id0 = 0;
- u8 is_cs0 = 0;
+ u8 dpo_ctx_id0 = ~0;
+ u8 vft_id0 = default_dpo.hicn_dpo_get_type ();
+ u8 is_cs0 = 1;
u8 hash_entry_id = 0;
u32 bucket_id = ~0;
u8 bucket_is_overflow = 0;
@@ -97,10 +112,11 @@ hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt,
nodep = hicn_hashtb_alloc_node (rt->pitcs->pcs_table);
if (PREDICT_FALSE (nodep == NULL))
{
+ vlib_buffer_free_one (vm, bi0);
/* Nothing we can do - no mem */
- *next = HICN_DATA_PUSH_NEXT_ERROR_DROP;
return HICN_ERROR_HASHTB_NOMEM;
}
+
pitp = hicn_pit_get_data (nodep);
hicn_pit_init_data (pitp);
pitp->shared.create_time = tnow;
@@ -117,7 +133,6 @@ hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt,
dmsg_lifetime = HICN_PARAM_CS_LIFETIME_DFLT;
}
pitp->shared.expire_time = hicn_pcs_get_exp_time (tnow, dmsg_lifetime);
- prep_buffer_for_cs (vm, b0, isv6);
/* Store the original packet buffer in the CS node */
pitp->u.cs.cs_pkt_buf = vlib_get_buffer_index (vm, b0);
@@ -138,11 +153,31 @@ hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt,
&vft_id0, &is_cs0, &hash_entry_id, &bucket_id,
&bucket_is_overflow);
- hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_CS_ENTRY;
if (ret != HICN_ERROR_NONE)
{
hicn_hashtb_free_node (rt->pitcs->pcs_table, nodep);
}
+
+ if (ret != HICN_ERROR_HASHTB_NOMEM)
+ {
+ if (!is_cs0)
+ {
+ ASSERT (ret != HICN_ERROR_NONE);
+ hicn_store_internal_state (b0, hicnb0->name_hash, node_id0,
+ dpo_ctx_id0, vft_id0, hash_entry_id,
+ bucket_id, bucket_is_overflow);
+
+ (*to_forward)[0] = bi0;
+ *to_forward += 1;
+ *n_to_forward += 1;
+ }
+ else
+ {
+ hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_CS_ENTRY;
+ prep_buffer_for_cs (vm, b0, isv6);
+ }
+ }
+
return (ret);
}
@@ -161,144 +196,73 @@ hicn_data_push_fn (vlib_main_t * vm,
hicn_data_push_runtime_t *rt;
vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
f64 tnow;
+ u32 *to_forward = NULL, *header = NULL, n_to_forward = 0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
next_index = (hicn_data_push_next_t) node->cached_next_index;
rt = vlib_node_get_runtime_data (vm, hicn_data_push_node.index);
rt->pitcs = &hicn_main.pitcs;
+
+ vec_alloc (to_forward, n_left_from);
+ header = to_forward;
/* Capture time in vpp terms */
tnow = vlib_time_now (vm);
while (n_left_from > 0)
{
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
+ u8 isv6;
+ u8 *nameptr;
+ u16 namelen;
+ hicn_name_t name;
+ hicn_header_t *hicn0;
+ vlib_buffer_t *b0;
+ u32 bi0;
+ int ret0;
+
+ /* Prefetch for next iteration. */
+ if (n_left_from > 1)
{
- u8 isv6_0, isv6_1;
- u8 *nameptr0, *nameptr1;
- u16 namelen0, namelen1;
- hicn_name_t name0, name1;
- hicn_header_t *hicn0, *hicn1;
- vlib_buffer_t *b0, *b1;
- u32 bi0, bi1;
- u32 next0 = next_index, next1 = next_index;
- int ret0, ret1;
-
- /* Prefetch for next iteration. */
- {
- vlib_buffer_t *b2, *b3;
- b2 = vlib_get_buffer (vm, from[2]);
- b3 = vlib_get_buffer (vm, from[3]);
- CLIB_PREFETCH (b2, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b3, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES, STORE);
- }
-
- /* Dequeue a packet buffer */
- bi0 = from[0];
- bi1 = from[1];
- from += 2;
- n_left_from -= 2;
- /* to_next[0] = bi0; */
- /* to_next[1] = bi1; */
- /* to_next += 2; */
- /* n_left_to_next -= 2; */
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
- next0 = next1 = HICN_DATA_PUSH_NEXT_ERROR_DROP;
-
- ret0 = hicn_data_parse_pkt (b0, &name0, &namelen0, &hicn0, &isv6_0);
- ret1 = hicn_data_parse_pkt (b1, &name1, &namelen1, &hicn1, &isv6_1);
-
- nameptr0 = (u8 *) (&name0);
- nameptr1 = (u8 *) (&name1);
- if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE))
- hicn_new_data (vm, rt, b0, &next0, tnow, nameptr0, namelen0,
- isv6_0);
-
- if (PREDICT_TRUE (ret1 == HICN_ERROR_NONE))
- hicn_new_data (vm, rt, b1, &next1, tnow, nameptr1, namelen1,
- isv6_1);
- stats.pkts_data_count += 2;
-
- /* Maybe trace */
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- hicn_data_push_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];;
- t->next_index = next0;
- }
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b1->flags & VLIB_BUFFER_IS_TRACED)))
- {
- hicn_data_push_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
- t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX];;
- t->next_index = next0;
- }
+ vlib_buffer_t *b1;
+ //hicn_buffer_t * hicnb1;
+ b1 = vlib_get_buffer (vm, from[1]);
+ CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES, STORE);
}
+ /* Dequeue a packet buffer */
+ bi0 = from[0];
+ from += 1;
+ n_left_from -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ ret0 = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
+ nameptr = (u8 *) (&name);
+ if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE))
+ hicn_new_data (vm, rt, b0, &to_forward, &n_to_forward, tnow, nameptr,
+ namelen, isv6);
+ stats.pkts_data_count++;
+ }
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
+ to_forward -= n_to_forward;
+ next_index = HICN_DATA_PUSH_NEXT_FWD;
+
+ while (n_to_forward > 0)
+ {
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+ while (n_to_forward > 0 && n_left_to_next > 0)
{
- u8 isv6;
- u8 *nameptr;
- u16 namelen;
- hicn_name_t name;
- hicn_header_t *hicn0;
- vlib_buffer_t *b0;
- u32 bi0;
- u32 next0 = next_index;
- int ret0;
-
- /* Prefetch for next iteration. */
- if (n_left_from > 1)
- {
- vlib_buffer_t *b1;
- //hicn_buffer_t * hicnb1;
- b1 = vlib_get_buffer (vm, from[1]);
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES, STORE);
- }
- /* Dequeue a packet buffer */
- bi0 = from[0];
- from += 1;
- n_left_from -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- next0 = HICN_DATA_PUSH_NEXT_ERROR_DROP;
-
- ret0 = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
- nameptr = (u8 *) (&name);
-
- if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE))
- hicn_new_data (vm, rt, b0, &next0, tnow, nameptr, namelen, isv6);
- stats.pkts_data_count++;
-
- /* Maybe trace */
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- hicn_data_push_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];;
- t->next_index = next0;
- }
+ to_next[0] = to_forward[0];
+ to_forward++;
+ n_to_forward--;
+ to_next++;
+ n_left_to_next--;
}
-
vlib_put_next_frame (vm, node, next_index, n_left_to_next);
}
+ vec_free (header);
+
vlib_node_increment_counter (vm, hicn_data_push_node.index,
HICNFWD_ERROR_CACHED, stats.pkts_data_count);
@@ -326,19 +290,19 @@ hicn_data_push_format_trace (u8 * s, va_list * args)
/* *INDENT-OFF* */
VLIB_REGISTER_NODE(hicn_data_push_node) =
{
- .function = hicn_data_push_fn,
- .name = "hicn-data-push",
- .vector_size = sizeof(u32),
- .runtime_data_bytes = sizeof(hicn_data_push_runtime_t),
- .format_trace = hicn_data_push_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_data_push_error_strings),
- .error_strings = hicn_data_push_error_strings,
- .n_next_nodes = HICN_DATA_PUSH_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes = {
- [HICN_DATA_PUSH_NEXT_ERROR_DROP] = "error-drop",
- },
+ .function = hicn_data_push_fn,
+ .name = "hicn-data-push",
+ .vector_size = sizeof(u32),
+ .runtime_data_bytes = sizeof(hicn_data_push_runtime_t),
+ .format_trace = hicn_data_push_format_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(hicn_data_push_error_strings),
+ .error_strings = hicn_data_push_error_strings,
+ .n_next_nodes = HICN_DATA_PUSH_N_NEXT,
+ .next_nodes = {
+ [HICN_DATA_PUSH_NEXT_FWD] = "hicn-data-fwd",
+ [HICN_DATA_PUSH_NEXT_ERROR_DROP] = "error-drop",
+ },
};
/* *INDENT-ON* */