aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin/src/strategy_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin/src/strategy_node.c')
-rw-r--r--hicn-plugin/src/strategy_node.c266
1 files changed, 110 insertions, 156 deletions
diff --git a/hicn-plugin/src/strategy_node.c b/hicn-plugin/src/strategy_node.c
index ec57d76e2..add5772a4 100644
--- a/hicn-plugin/src/strategy_node.c
+++ b/hicn-plugin/src/strategy_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 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:
@@ -20,11 +20,11 @@
#include "parser.h"
#include "strategy.h"
#include "strategy_dpo_ctx.h"
-#include "face_db.h"
#include "infra.h"
#include "mgmt.h"
#include "pcs.h"
#include "state.h"
+#include "data_fwd.h"
#include "strategies/strategy_mw.h"
/* Registration struct for a graph node */
@@ -60,97 +60,32 @@ hicn_strategy_format_trace (u8 *s, va_list *args)
return vft->hicn_format_strategy_trace (s, t);
}
-always_inline int
-hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next,
- f64 tnow, u8 *nameptr, u16 namelen, hicn_face_id_t outface,
- int nh_idx, index_t dpo_ctx_id0,
- const hicn_strategy_vft_t *strategy, dpo_type_t dpo_type,
- u8 isv6, vl_api_hicn_api_node_stats_get_reply_t *stats)
+always_inline void
+drop_packet (vlib_main_t *vm, u32 bi0, u32 *n_left_to_next, u32 *next0,
+ u32 **to_next, u32 *next_index, vlib_node_runtime_t *node)
{
- int ret;
- hicn_hash_node_t *nodep;
- hicn_pcs_entry_t *pitp;
- hicn_header_t *hicn0;
- hicn_main_t *sm = &hicn_main;
- hicn_buffer_t *hicnb0 = hicn_get_buffer (b0);
- u32 node_id0 = 0;
- u8 vft_id0 = dpo_type;
- u8 is_cs0 = 0;
- u8 hash_entry_id = 0;
- u8 bucket_is_overflow = 0;
- u32 bucket_id = ~0;
-
- /* Create PIT node and init PIT entry */
- nodep = hicn_hashtb_alloc_node (rt->pitcs->pcs_table);
- if (PREDICT_FALSE (nodep == NULL))
- {
- /* Nothing we can do - no mem */
- *next = HICN_STRATEGY_NEXT_ERROR_DROP;
- return HICN_ERROR_HASHTB_NOMEM;
- }
- pitp = hicn_pit_get_data (nodep);
- hicn_pit_init_data (pitp);
- pitp->shared.create_time = tnow;
-
- hicn0 = vlib_buffer_get_current (b0);
- hicn_lifetime_t imsg_lifetime;
- hicn_type_t type = hicnb0->type;
- hicn_ops_vft[type.l1]->get_lifetime (type, &hicn0->protocol, &imsg_lifetime);
+ vlib_buffer_t *b0 = vlib_get_buffer (vm, bi0);
- if (imsg_lifetime > sm->pit_lifetime_max_ms)
- {
- imsg_lifetime = sm->pit_lifetime_max_ms;
- }
- pitp->shared.expire_time = hicn_pcs_get_exp_time (tnow, imsg_lifetime);
+ *next0 = HICN_STRATEGY_NEXT_ERROR_DROP;
- /* Set up the hash node and insert it */
- hicn_hash_entry_t *hash_entry;
- hicn_hashtb_init_node (rt->pitcs->pcs_table, nodep, nameptr, namelen);
+ (*to_next)[0] = bi0;
+ *to_next += 1;
+ *n_left_to_next -= 1;
- ret = hicn_pcs_pit_insert (rt->pitcs, pitp, nodep, &hash_entry,
- hicnb0->name_hash, &node_id0, &dpo_ctx_id0,
- &vft_id0, &is_cs0, &hash_entry_id, &bucket_id,
- &bucket_is_overflow);
-
- if (ret == HICN_ERROR_NONE)
+ // Maybe trace
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- strategy->hicn_add_interest (vnet_buffer (b0)->ip.adj_index[VLIB_TX],
- hash_entry);
-
- /* Add face */
- hicn_face_db_add_face (hicnb0->face_id, &(pitp->u.pit.faces));
-
- *next = isv6 ? HICN_STRATEGY_NEXT_INTEREST_FACE6 :
- HICN_STRATEGY_NEXT_INTEREST_FACE4;
-
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface;
- stats->pkts_interest_count++;
- pitp->u.pit.pe_txnh = nh_idx;
- }
- else
- {
- /* Interest aggregate in PIT */
- if (ret == HICN_ERROR_HASHTB_EXIST)
- {
- hicn_store_internal_state (b0, hicnb0->name_hash, node_id0,
- dpo_ctx_id0, vft_id0, hash_entry_id,
- bucket_id, bucket_is_overflow);
- // We need to take a lock as the lock is not taken on the hash
- // entry because it is a CS entry (hash_insert function).
- hash_entry->locks++;
- *next = is_cs0 ? HICN_STRATEGY_NEXT_INTEREST_HITCS :
- HICN_STRATEGY_NEXT_INTEREST_HITPIT;
- }
- else
- {
- /* Send the packet to the interest-hitpit node */
- *next = HICN_STRATEGY_NEXT_ERROR_DROP;
- }
- hicn_faces_flush (&(pitp->u.pit.faces));
- hicn_hashtb_free_node (rt->pitcs->pcs_table, nodep);
+ hicn_strategy_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;
+ t->dpo_type = hicn_get_buffer (b0)->vft_id;
+ t->out_face = -1;
}
- return (ret);
+ vlib_validate_buffer_enqueue_x1 (vm, node, *next_index, *to_next,
+ *n_left_to_next, bi0, *next0);
}
/*
@@ -162,11 +97,19 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
vlib_frame_t *frame)
{
+ int ret;
u32 n_left_from, *from, *to_next, n_left_to_next;
hicn_strategy_next_t next_index;
hicn_strategy_runtime_t *rt = NULL;
vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- f64 tnow;
+ vlib_buffer_t *b0;
+ u32 bi0;
+ hicn_face_id_t outfaces[MAX_OUT_FACES];
+ u32 clones[MAX_OUT_FACES];
+ u16 outfaces_len;
+ u32 next0;
+ const hicn_strategy_vft_t *strategy;
+ hicn_buffer_t *hicnb0;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -174,97 +117,108 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
rt = vlib_node_get_runtime_data (vm, hicn_strategy_node.index);
rt->pitcs = &hicn_main.pitcs;
/* Capture time in vpp terms */
- tnow = vlib_time_now (vm);
+ next0 = next_index;
while (n_left_from > 0)
{
-
vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
while (n_left_from > 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;
- hicn_face_id_t outface;
- int nh_idx;
- u32 next0 = next_index;
- int ret;
-
- /* Prefetch for next iteration. */
+ // 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, LOAD);
- CLIB_PREFETCH (&b1->trace_handle, 2 * CLIB_CACHE_LINE_BYTES,
- STORE);
+ CLIB_PREFETCH (b1, 2 * CLIB_CACHE_LINE_BYTES, LOAD);
}
- /* Dequeue a packet buffer */
+
+ // Dequeue a packet buffer
bi0 = from[0];
from += 1;
n_left_from -= 1;
- to_next[0] = bi0;
- to_next += 1;
- n_left_to_next -= 1;
-
b0 = vlib_get_buffer (vm, bi0);
- next0 = HICN_STRATEGY_NEXT_ERROR_DROP;
- hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (
- vnet_buffer (b0)->ip.adj_index[VLIB_TX]);
- const hicn_strategy_vft_t *strategy =
- hicn_dpo_get_strategy_vft (dpo_ctx->dpo_type);
+ // Drop by default
+ next0 = HICN_STRATEGY_NEXT_ERROR_DROP;
- ret = hicn_interest_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
+ // Increment counters
stats.pkts_processed++;
- /* Select next hop */
- /*
- * Double check that the interest has been through
- * the interest-pcslookup node due to misconfiguration in
- * the punting rules.
- */
- if (PREDICT_TRUE (ret == HICN_ERROR_NONE &&
- HICN_IS_NAMEHASH_CACHED (b0) &&
- strategy->hicn_select_next_hop (
- vnet_buffer (b0)->ip.adj_index[VLIB_TX], &nh_idx,
- &outface) == HICN_ERROR_NONE))
+
+ hicnb0 = hicn_get_buffer (b0);
+
+ // Get the strategy VFT
+ strategy = hicn_dpo_get_strategy_vft (hicnb0->vft_id);
+
+ // Check we have at least one next hop for the packet
+ ret = strategy->hicn_select_next_hop (
+ hicnb0->dpo_ctx_id, hicnb0->face_id, outfaces, &outfaces_len);
+
+ if (PREDICT_FALSE (ret != HICN_ERROR_NONE || outfaces_len == 0))
+ {
+ drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
+ &next_index, node);
+ continue;
+ }
+
+ // Set next node
+ next0 = hicn_buffer_is_v6 (b0) ? HICN_STRATEGY_NEXT_INTEREST_FACE6 :
+ HICN_STRATEGY_NEXT_INTEREST_FACE4;
+
+ if (PREDICT_TRUE (ret == HICN_ERROR_NONE))
{
- /*
- * No need to check if parsing was successful
- * here. Already checked in the interest_pcslookup
- * node
- */
- nameptr = (u8 *) (&name);
- hicn_new_interest (rt, b0, &next0, tnow, nameptr, namelen,
- outface, nh_idx,
- vnet_buffer (b0)->ip.adj_index[VLIB_TX],
- strategy, dpo_ctx->dpo_type, isv6, &stats);
+ // 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_INTEREST;
+ t->sw_if_index =
+ vnet_buffer (local_b0)->sw_if_index[VLIB_RX];
+ t->next_index = next0;
+ t->dpo_type = hicnb0->vft_id;
+ t->out_face = outfaces[nh];
+ }
+
+ /*
+ * 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);
+ }
}
- /* Maybe trace */
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ else
{
- hicn_strategy_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;
- t->dpo_type = dpo_ctx->dpo_type;
+ drop_packet (vm, bi0, &n_left_from, &next0, &to_next,
+ &next_index, node);
}
- /*
- * Verify speculative enqueue, maybe switch current
- * next frame
- */
- /*
- * 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);