aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin')
-rw-r--r--hicn-plugin/CMakeLists.txt43
-rw-r--r--hicn-plugin/scripts/post3
-rw-r--r--hicn-plugin/scripts/postinst3
-rw-r--r--hicn-plugin/src/data_fwd_node.c5
-rw-r--r--hicn-plugin/src/data_pcslookup_node.c79
-rw-r--r--hicn-plugin/src/faces/app/face_prod.c4
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.c106
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.h117
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.c341
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.h62
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_cli.c4
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_node.c3
-rw-r--r--hicn-plugin/src/hicn.h5
-rw-r--r--hicn-plugin/src/hicn_api.c2
-rw-r--r--hicn-plugin/src/mgmt.c4
-rw-r--r--hicn-plugin/src/pcs.h30
16 files changed, 510 insertions, 301 deletions
diff --git a/hicn-plugin/CMakeLists.txt b/hicn-plugin/CMakeLists.txt
index 0da096e22..8425a5cf3 100644
--- a/hicn-plugin/CMakeLists.txt
+++ b/hicn-plugin/CMakeLists.txt
@@ -55,25 +55,31 @@ set(LIBHICN_FILES
)
set(LIBHICN_HEADER_FILES_SRC
- ../lib/src/hicn.h
- ../lib/src/base.h
- ../lib/src/common.h
- ../lib/src/error.h
- ../lib/src/header.h
- ../lib/src/name.h
- ../lib/src/protocol.h
- ../lib/src/ops.h
- ../lib/src/mapme.h
+ ../lib/includes/hicn/hicn.h
+ ../lib/includes/hicn/base.h
+ ../lib/includes/hicn/common.h
+ ../lib/includes/hicn/error.h
+ ../lib/includes/hicn/header.h
+ ../lib/includes/hicn/name.h
+ ../lib/includes/hicn/protocol.h
+ ../lib/includes/hicn/ops.h
+ ../lib/includes/hicn/mapme.h
)
set(LIBHICN_HEADER_FILES_PROTOCOL
- ../lib/src/protocol/ah.h
- ../lib/src/protocol/icmp.h
- ../lib/src/protocol/icmprd.h
- ../lib/src/protocol/ipv4.h
- ../lib/src/protocol/ipv6.h
- ../lib/src/protocol/tcp.h
- ../lib/src/protocol/udp.h
+ ../lib/includes/hicn/protocol/ah.h
+ ../lib/includes/hicn/protocol/icmp.h
+ ../lib/includes/hicn/protocol/icmprd.h
+ ../lib/includes/hicn/protocol/ipv4.h
+ ../lib/includes/hicn/protocol/ipv6.h
+ ../lib/includes/hicn/protocol/tcp.h
+ ../lib/includes/hicn/protocol/udp.h
+)
+
+set(LIBHICN_HEADER_FILES_UTIL
+ ../lib/includes/hicn/util/ip_address.h
+ ../lib/includes/hicn/util/token.h
+ ../lib/includes/hicn/util/types.h
)
set(HICN_PLUGIN_SOURCE_FILES
@@ -262,6 +268,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins)
file(COPY ${LIBHICN_HEADER_FILES_SRC} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn)
file(COPY ${LIBHICN_HEADER_FILES_PROTOCOL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn/protocol)
+file(COPY ${LIBHICN_HEADER_FILES_UTIL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn/util)
add_library(hicn_api_test_plugin SHARED
${HICN_API_TEST_SOURCE_FILES}
@@ -300,6 +307,10 @@ install(FILES ${HICN_API_HEADER_FILES} ${HICN_API_GENERATED_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn
COMPONENT ${HICN_PLUGIN}-dev)
+install(FILES ${HICN_API_GENERATED_FILES}
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn
+ COMPONENT ${HICN_PLUGIN_DEV})
+
install(FILES ${HICN_VAPI_GENERATED_FILES}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vapi
COMPONENT ${HICN_PLUGIN}-dev)
diff --git a/hicn-plugin/scripts/post b/hicn-plugin/scripts/post
index 3cde599ca..dd0a9fbf5 100644
--- a/hicn-plugin/scripts/post
+++ b/hicn-plugin/scripts/post
@@ -1,7 +1,8 @@
#!/bin/bash
if [ -e /etc/vpp/startup.conf ]; then
- if ! grep -q "hicn" /etc/vpp/startup.conf; then
+ RESULTS=$(sed -n '/hicn[ ]*{/p' /etc/vpp/startup.conf | wc -l)
+ if [[ $RESULTS = 0 ]]; then
printf '\n hicn {
## Set PIT size. Default is 131 072 entries
# pit-size 500000
diff --git a/hicn-plugin/scripts/postinst b/hicn-plugin/scripts/postinst
index 012fc3571..d6d48509c 100644
--- a/hicn-plugin/scripts/postinst
+++ b/hicn-plugin/scripts/postinst
@@ -1,7 +1,8 @@
#!/bin/bash
if [ -e /etc/vpp/startup.conf ]; then
- if ! grep -q "hicn" /etc/vpp/startup.conf; then
+ RESULTS=$(sed -n '/hicn[ ]*{/p' /etc/vpp/startup.conf | wc -l)
+ if [[ $RESULTS = 0 ]]; then
printf '\n hicn {
## Set PIT size. Default is 131 072 entries
# pit-size 500000
diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c
index 53308a49d..ca3baaa0d 100644
--- a/hicn-plugin/src/data_fwd_node.c
+++ b/hicn-plugin/src/data_fwd_node.c
@@ -176,6 +176,7 @@ hicn_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hicn_pcs_delete (pitcs, &pitp, &node0, vm, hash_entry0,
dpo_vft0, &hicn_dpo_id0);
+#if HICN_FEATURE_CS
if (hicnb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP)
{
push_in_cache (vm, bi0, &n_left_to_next, &next0, &to_next,
@@ -186,6 +187,10 @@ hicn_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
&next_index, node);
}
+#else
+ drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
+ &next_index, node);
+#endif
stats.pit_expired_count++;
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
diff --git a/hicn-plugin/src/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c
index aeb8c2276..1ae36202f 100644
--- a/hicn-plugin/src/data_pcslookup_node.c
+++ b/hicn-plugin/src/data_pcslookup_node.c
@@ -14,12 +14,12 @@
*/
#include "data_pcslookup.h"
+#include "infra.h"
#include "mgmt.h"
#include "parser.h"
-#include "infra.h"
+#include "state.h"
#include "strategy.h"
#include "strategy_dpo_manager.h"
-#include "state.h"
/* Stats string values */
static char *hicn_data_pcslookup_error_strings[] = {
@@ -37,10 +37,9 @@ vlib_node_registration_t hicn_data_pcslookup_node;
* hICN node for handling data. It performs a lookup in the PIT.
*/
static uword
-hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+hicn_data_pcslookup_node_fn (vlib_main_t * vm,
+ vlib_node_runtime_t * node, vlib_frame_t * frame)
{
-
u32 n_left_from, *from, *to_next;
hicn_data_pcslookup_next_t next_index;
hicn_data_pcslookup_runtime_t *rt;
@@ -87,7 +86,8 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
{
vlib_buffer_t *b1;
b1 = vlib_get_buffer (vm, from[1]);
- //Prefetch two cache lines-- 128 byte-- so that we load the hicn_buffer_t as well
+ // Prefetch two cache lines-- 128 byte-- so that we load the
+ // hicn_buffer_t as well
CLIB_PREFETCH (b1, 2 * CLIB_CACHE_LINE_BYTES, STORE);
CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES, LOAD);
}
@@ -99,47 +99,35 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
to_next += 1;
n_left_to_next -= 1;
-
b0 = vlib_get_buffer (vm, bi0);
hb0 = hicn_get_buffer (b0);
+ next0 = HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP;
/* Incr packet counter */
stats.pkts_processed += 1;
ret0 = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
-
- if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE))
- {
- next0 =
- isv6 ? HICN_DATA_PCSLOOKUP_NEXT_V6_LOOKUP :
- HICN_DATA_PCSLOOKUP_NEXT_V4_LOOKUP;
- }
nameptr = (u8 *) (&name);
- if (PREDICT_FALSE
- (ret0 != HICN_ERROR_NONE
- || hicn_hashtb_fullhash (nameptr, namelen,
- &name_hash) != HICN_ERROR_NONE))
- {
- next0 = HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP;
- }
- else
+
+ if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE &&
+ hicn_hashtb_fullhash (nameptr, namelen,
+ &name_hash) ==
+ HICN_ERROR_NONE))
{
int res =
hicn_hashtb_lookup_node (rt->pitcs->pcs_table, nameptr,
namelen, name_hash,
- !(hb0->flags &
- HICN_BUFFER_FLAGS_FACE_IS_APP)
- /* take lock */ ,
+ 1 /*is_data. Do not take lock if hit CS */ ,
&node_id0, &dpo_ctx_id0, &vft_id0,
- &is_cs0,
- &hash_entry_id, &bucket_id,
+ &is_cs0, &hash_entry_id, &bucket_id,
&bucket_is_overflown);
stats.pkts_data_count += 1;
- if ((res == HICN_ERROR_HASHTB_HASH_NOT_FOUND
- || (res == HICN_ERROR_NONE && is_cs0))
- && (hb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP))
+#if HICN_FEATURE_CS
+ if ((res == HICN_ERROR_HASHTB_HASH_NOT_FOUND ||
+ (res == HICN_ERROR_NONE && is_cs0)) &&
+ ((hb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP)))
{
next0 = HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA;
}
@@ -153,6 +141,18 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
next0 = HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD + is_cs0;
}
}
+#else
+ if (res == HICN_ERROR_NONE)
+ {
+ /*
+ * In case the result of the lookup
+ * is a CS entry, the packet is
+ * dropped
+ */
+ next0 = HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD + is_cs0;
+ }
+ }
+#endif
hicn_store_internal_state (b0, name_hash, node_id0, dpo_ctx_id0,
vft_id0, hash_entry_id, bucket_id,
@@ -166,9 +166,8 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
* Fix in case of a wrong speculation. Needed to
* clone the data in the right frame
*/
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
/* Maybe trace */
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
@@ -214,24 +213,22 @@ hicn_data_pcslookup_format_trace (u8 * s, va_list * args)
return (s);
}
-
/*
* Node registration for the data forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_data_pcslookup_node) =
+VLIB_REGISTER_NODE(hicn_data_pcslookup_node) =
{
.function = hicn_data_pcslookup_node_fn,
.name = "hicn-data-pcslookup",
- .vector_size = sizeof (u32),
- .runtime_data_bytes = sizeof (hicn_data_pcslookup_runtime_t),
+ .vector_size = sizeof(u32),
+ .runtime_data_bytes = sizeof(hicn_data_pcslookup_runtime_t),
.format_trace = hicn_data_pcslookup_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_data_pcslookup_error_strings),
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(hicn_data_pcslookup_error_strings),
.error_strings = hicn_data_pcslookup_error_strings,
.n_next_nodes = HICN_DATA_PCSLOOKUP_N_NEXT,
- .next_nodes =
- {
+ .next_nodes = {
[HICN_DATA_PCSLOOKUP_NEXT_V4_LOOKUP] = "ip4-lookup",
[HICN_DATA_PCSLOOKUP_NEXT_V6_LOOKUP] = "ip6-lookup",
[HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA] = "hicn-data-push",
diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c
index 7e6117b84..bbcc7fa6e 100644
--- a/hicn-plugin/src/faces/app/face_prod.c
+++ b/hicn-plugin/src/faces/app/face_prod.c
@@ -218,7 +218,7 @@ hicn_face_prod_add (hicn_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
remote_app_ip = to_ip46 ( /* isv6 */ 0, remote_app_ip4.as_u8);
ret =
- hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid);
+ hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, HICN_FACE_FLAGS_APPFACE_PROD);
}
else
{
@@ -238,7 +238,7 @@ hicn_face_prod_add (hicn_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
remote_app_ip = to_ip46 ( /* isv6 */ 1, remote_app_ip6.as_u8);
ret =
- hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid);
+ hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid, HICN_FACE_FLAGS_APPFACE_PROD);
}
face = hicn_dpoi_get_from_idx (*faceid);
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.c b/hicn-plugin/src/faces/ip/dpo_ip.c
index de71f1b01..d05fec1a0 100644
--- a/hicn-plugin/src/faces/ip/dpo_ip.c
+++ b/hicn-plugin/src/faces/ip/dpo_ip.c
@@ -19,6 +19,8 @@ mhash_t hicn_face_ip_local_hashtb;
mhash_t hicn_face_ip_remote_hashtb;
dpo_type_t hicn_face_ip_type;
+hicn_face_ip_vec_t * hicn_vec_pool;
+
const static char *const hicn_face_ip4dpoi_nodes[] = {
"hicn-face-ip4-input",
"hicn-face-ip4-output",
@@ -51,12 +53,14 @@ void
hicn_dpo_ip_module_init (void)
{
mhash_init (&hicn_face_ip_local_hashtb,
- sizeof (hicn_face_id_t) /* value */ ,
+ sizeof (hicn_face_ip_input_faces_t) /* value */ ,
sizeof (hicn_face_ip_key_t) /* key */ );
mhash_init (&hicn_face_ip_remote_hashtb,
sizeof (hicn_face_id_t) /* value */ ,
sizeof (hicn_face_ip_key_t) /* key */ );
+ pool_alloc(hicn_vec_pool, 100);
+
/*
* How much useful is the following registration?
* So far it seems that we need it only for setting the dpo_type.
@@ -65,106 +69,6 @@ hicn_dpo_ip_module_init (void)
dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes);
}
-
-int
-hicn_dpo_ip4_create (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- /* If local matches the dpoi is a face */
- hicn_face_t *face =
- hicn_face_ip4_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
- u8 hicnb_flags;
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face = hicn_face_ip4_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- if (face == NULL)
- {
- hicn_dpo_ip4_add_and_lock_from_remote (dpo, &hicnb_flags, local_addr,
- remote_addr, sw_if, node_index);
- *face_id = (hicn_face_id_t) dpo->dpoi_index;
- face = hicn_dpoi_get_from_idx (*face_id);
- }
- else
- {
- *face_id = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, *face_id);
- dpo->dpoi_next_node = node_index;
- }
-
-
- hicn_face_ip_key_t key;
- hicn_face_ip4_get_key (local_addr, sw_if, &key);
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) face_id, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- ip46_address_set_ip4 (&ip_face->local_addr, local_addr);
- ip46_address_set_ip4 (&ip_face->remote_addr, remote_addr);
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- return HICN_ERROR_NONE;
-}
-
-int
-hicn_dpo_ip6_create (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- /* If local matches the dpoi is a face */
- hicn_face_t *face =
- hicn_face_ip6_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
-
- u8 hicnb_flags;
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face = hicn_face_ip6_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- /* If remote matches the dpoi is a iface */
- if (face == NULL)
- {
- hicn_dpo_ip6_add_and_lock_from_remote (dpo, &hicnb_flags, local_addr,
- remote_addr, sw_if, node_index);
- *face_id = (hicn_face_id_t) dpo->dpoi_index;
- face = hicn_dpoi_get_from_idx (*face_id);
- }
- else
- {
- *face_id = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, *face_id);
- dpo->dpoi_next_node = node_index;
- }
-
- hicn_face_ip_key_t key;
- hicn_face_ip6_get_key (local_addr, sw_if, &key);
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) face_id, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr, sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
-
- return HICN_ERROR_NONE;
-}
-
void
hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
u16 dpoi_next_node)
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.h b/hicn-plugin/src/faces/ip/dpo_ip.h
index 164931a06..d6b4f5f7e 100644
--- a/hicn-plugin/src/faces/ip/dpo_ip.h
+++ b/hicn-plugin/src/faces/ip/dpo_ip.h
@@ -29,10 +29,9 @@ void hicn_dpo_ip_module_init (void);
/**
- * @brief Retrieve a face from the ip4 local address and returns its dpo. This
- * method adds a lock on the face state.
+ * @brief Retrieve a vector of faces from the ip4 local address and returns its index.
*
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
+ * @param vec: Result of the lookup. If no face exists for the local address vec = NULL
* @param hicnb_flags: Flags that indicate whether the face is an application
* face or not
* @param local_addr: Ip v4 local address of the face
@@ -42,22 +41,25 @@ void hicn_dpo_ip_module_init (void);
*/
always_inline int
hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo,
+ u32 * in_faces_vec_id,
u8 * hicnb_flags,
const ip4_address_t * local_addr, u32 sw_if)
{
- hicn_face_t *face =
- hicn_face_ip4_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
+ hicn_face_ip_input_faces_t * in_faces_vec =
+ hicn_face_ip4_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb);
- if (PREDICT_FALSE (face == NULL))
+ if (PREDICT_FALSE (in_faces_vec == NULL))
return HICN_ERROR_FACE_NOT_FOUND;
+ *in_faces_vec_id = in_faces_vec->vec_id;
+ hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
+
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
*hicnb_flags |=
(face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
HICN_FACE_FLAGS_APPFACE_PROD_BIT;
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
+ dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, in_faces_vec->face_id);
dpo->dpoi_next_node = ~0;
dpo_lock (dpo);
@@ -78,22 +80,25 @@ hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo,
*/
always_inline int
hicn_dpo_ip6_lock_from_local (dpo_id_t * dpo,
+ u32 * in_faces_vec_id,
u8 * hicnb_flags,
const ip6_address_t * local_addr, u32 sw_if)
{
- hicn_face_t *face =
- hicn_face_ip6_get (local_addr, sw_if, &hicn_face_ip_local_hashtb);
+ hicn_face_ip_input_faces_t * in_faces_vec =
+ hicn_face_ip6_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb);
- if (PREDICT_FALSE (face == NULL))
+ if (PREDICT_FALSE (in_faces_vec == NULL))
return HICN_ERROR_FACE_NOT_FOUND;
+ *in_faces_vec_id = in_faces_vec->vec_id;
+ hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
+
*hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
*hicnb_flags |=
(face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
HICN_FACE_FLAGS_APPFACE_PROD_BIT;
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, dpoi_index);
+ dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, in_faces_vec->face_id);
dpo->dpoi_next_node = ~0;
dpo_lock (dpo);
@@ -210,49 +215,49 @@ hicn_dpo_ip6_add_and_lock_from_remote (dpo_id_t * dpo,
}
-/**
- * @brief Create an ip face and its corresponding dpo. Meant to be used for the
- * control plane.
- *
- * @param dpo: Data plane object that point to the face created.
- * @param local_addr: Ip v4 local address of the face
- * @param remote_addr: Ip v4 remote address of the face
- * @param sw_if: software interface id of the face
- * @param adj: Ip adjacency corresponding to the remote address in the face
- * @param node_index: vlib edge index to use in the packet processing
- * @param flags: Flags of the face
- * @param face_id: Identifier for the face (dpoi_index)
- * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE
- */
-int hicn_dpo_ip4_create (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
-
-/**
- * @brief Create an ip face and its corresponding dpo. Meant to be used for the
- * control plane.
- *
- * @param dpo: Data plane object that point to the face created.
- * @param local_addr: Ip v6 local address of the face
- * @param remote_addr: Ip v6 remote address of the face
- * @param sw_if: software interface id of the face
- * @param adj: Ip adjacency corresponding to the remote address in the face
- * @param node_index: vlib edge index to use in the packet processing
- * @param flags: Flags of the face
- * @param face_id: Identifier for the face (dpoi_index)
- * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE
- */
-int hicn_dpo_ip6_create (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
+/* /\** */
+/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */
+/* * control plane. */
+/* * */
+/* * @param dpo: Data plane object that point to the face created. */
+/* * @param local_addr: Ip v4 local address of the face */
+/* * @param remote_addr: Ip v4 remote address of the face */
+/* * @param sw_if: software interface id of the face */
+/* * @param adj: Ip adjacency corresponding to the remote address in the face */
+/* * @param node_index: vlib edge index to use in the packet processing */
+/* * @param flags: Flags of the face */
+/* * @param face_id: Identifier for the face (dpoi_index) */
+/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */
+/* *\/ */
+/* int hicn_dpo_ip4_create (dpo_id_t * dpo, */
+/* const ip4_address_t * local_addr, */
+/* const ip4_address_t * remote_addr, */
+/* u32 sw_if, */
+/* adj_index_t adj, */
+/* u32 node_index, */
+/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */
+
+/* /\** */
+/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */
+/* * control plane. */
+/* * */
+/* * @param dpo: Data plane object that point to the face created. */
+/* * @param local_addr: Ip v6 local address of the face */
+/* * @param remote_addr: Ip v6 remote address of the face */
+/* * @param sw_if: software interface id of the face */
+/* * @param adj: Ip adjacency corresponding to the remote address in the face */
+/* * @param node_index: vlib edge index to use in the packet processing */
+/* * @param flags: Flags of the face */
+/* * @param face_id: Identifier for the face (dpoi_index) */
+/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */
+/* *\/ */
+/* int hicn_dpo_ip6_create (dpo_id_t * dpo, */
+/* const ip6_address_t * local_addr, */
+/* const ip6_address_t * remote_addr, */
+/* u32 sw_if, */
+/* adj_index_t adj, */
+/* u32 node_index, */
+/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */
/**
* @brief Create a dpo from an ip face
diff --git a/hicn-plugin/src/faces/ip/face_ip.c b/hicn-plugin/src/faces/ip/face_ip.c
index 6e279583c..23d3900ec 100644
--- a/hicn-plugin/src/faces/ip/face_ip.c
+++ b/hicn-plugin/src/faces/ip/face_ip.c
@@ -12,6 +12,8 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+#include <vnet/adj/adj_midchain.h>
+#include <vnet/adj/adj.h>
#include "face_ip.h"
#include "face_ip_node.h"
@@ -96,62 +98,165 @@ hicn_face_ip_del (hicn_face_id_t face_id)
hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
hicn_face_ip_key_t key;
hicn_face_ip_key_t old_key;
+ hicn_face_ip_key_t old_key2;
if (ip46_address_is_ip4 (&face_ip->local_addr))
{
hicn_face_ip4_get_key (&(face_ip->local_addr.ip4), face->shared.sw_if,
&key);
- mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
- hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4), face->shared.sw_if,
- &key);
- mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key);
+ hicn_face_ip_input_faces_t * in_faces_vec = hicn_face_ip4_get_vec(&(face_ip->local_addr.ip4), face->shared.sw_if,
+ &hicn_face_ip_local_hashtb);
+ if (in_faces_vec != NULL)
+ {
+ hicn_face_ip_vec_t * vec = pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
+ u32 index_face = vec_search(*vec, face_id);
+ vec_del1(*vec, index_face);
+
+ if (vec_len(*vec) == 0)
+ {
+ pool_put_index(hicn_vec_pool, in_faces_vec->vec_id);
+ mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
+ vec_free(*vec);
+ }
+ else
+ {
+ /* Check if the face we are deleting is the preferred one. */
+ /* If so, repleace with another. */
+ if (in_faces_vec->face_id == face_id)
+ {
+ in_faces_vec->face_id = (*vec)[0];
+ }
+ }
+ hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4), face->shared.sw_if,
+ &key);
+ mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key2);
+ }
}
else
{
hicn_face_ip6_get_key (&(face_ip->local_addr.ip6), face->shared.sw_if,
&key);
- mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
- hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6), face->shared.sw_if,
- &key);
- mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key);
+
+ hicn_face_ip_input_faces_t * in_faces_vec = hicn_face_ip6_get_vec(&(face_ip->local_addr.ip6), face->shared.sw_if,
+ &hicn_face_ip_local_hashtb);
+ if (in_faces_vec != NULL)
+ {
+ hicn_face_ip_vec_t * vec = pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
+ u32 index_face = vec_search(*vec, face_id);
+ vec_del1(*vec, index_face);
+
+ if (vec_len(*vec) == 0)
+ {
+ pool_put(hicn_vec_pool, vec);
+ mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key);
+ vec_free(*vec);
+ }
+ else
+ {
+ /* Check if the face we are deleting is the preferred one. */
+ /* If so, repleace with another. */
+ if (in_faces_vec->face_id == face_id)
+ {
+ in_faces_vec->face_id = (*vec)[0];
+ }
+ }
+ hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6), face->shared.sw_if,
+ &key);
+ mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key);
+ }
}
return hicn_face_del (face_id);
}
+/**
+ * @brief Helper for handling midchain adjacencies
+ */
+void face_midchain_fixup_t (vlib_main_t * vm,
+ struct ip_adjacency_t_ * adj,
+ vlib_buffer_t * b0,
+ const void *data) {
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
+};
-/*
- * Utility that adds a new face cache entry. For the moment we assume that
- * the ip_adjacency has already been set up.
+/**
+ * @brief Build a rewrite string for the face.
*/
-int
-hicn_face_ip_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr,
- int sw_if, hicn_face_id_t * pfaceid)
+static u8*
+face_build_rewrite_i (void)
{
- /* fib_protocol_t fib_type; */
- /* vnet_link_t link_type; */
- adj_index_t adj;
- dpo_proto_t dpo_proto;
+ /*
+ * passing the adj code a NULL rewrite means 'i don't have one cos
+ * t'other end is unresolved'. That's not the case here. For the mpls
+ * tunnel there are just no bytes of encap to apply in the adj. We'll impose
+ * the label stack once we choose a path. So return a zero length rewrite.
+ */
+ u8 *rewrite = NULL;
- /* Check if we found at least one ip address */
- if (ip46_address_is_zero (local_addr) || ip46_address_is_zero (remote_addr))
- return HICN_ERROR_FACE_NO_GLOBAL_IP;
+ vec_validate(rewrite, 0);
+ vec_reset_length(rewrite);
+ return (rewrite);
+}
+
+always_inline int
+hicn_face_ip_find_adj (const ip46_address_t * remote_addr,
+ int sw_if, adj_index_t * adj)
+{
fib_prefix_t fib_pfx;
fib_node_index_t fib_entry_index;
fib_prefix_from_ip46_addr (remote_addr, &fib_pfx);
fib_pfx.fp_len = ip46_address_is_ip4(remote_addr)? 32 : 128;
+ vnet_link_t link_type = ip46_address_is_ip4(&fib_pfx.fp_addr)? VNET_LINK_IP4 : VNET_LINK_IP6;
+ *adj = adj_nbr_find(fib_pfx.fp_proto, link_type, &fib_pfx.fp_addr, sw_if);
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PLUGIN_HI);
+ if (*adj == ADJ_INDEX_INVALID)
+ {
+ u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
+ HICN_FIB_TABLE,
+ FIB_SOURCE_PLUGIN_HI);
+
+ fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+
+ if (fib_entry_index == (FIB_NODE_INDEX_INVALID))
+ return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
+
+ *adj = fib_entry_get_adj (fib_entry_index);
+ ip_adjacency_t * temp = NULL;
+ if (*adj != ~0)
+ temp = adj_get(*adj);
+
+ if (temp == NULL || temp->lookup_next_index <= IP_LOOKUP_NEXT_REWRITE)
+ {
+ if(sw_if != ~0)
+ *adj = adj_nbr_add_or_lock(fib_pfx.fp_proto, link_type, remote_addr, sw_if);
+ else
+ return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
+ }
+ else
+ {
+ adj_nbr_midchain_update_rewrite(*adj, &face_midchain_fixup_t, NULL, ADJ_FLAG_NONE, face_build_rewrite_i());
+ adj_midchain_delegate_stack(*adj, fib_index, &fib_pfx);
+ }
+ }
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+ return HICN_ERROR_NONE;
+}
- adj = fib_entry_get_adj (fib_entry_index);
+/*
+ * Utility that adds a new face cache entry. For the moment we assume that
+ * the ip_adjacency has already been set up.
+ */
+int
+hicn_face_ip_add (const ip46_address_t * local_addr,
+ const ip46_address_t * remote_addr,
+ int sw_if, hicn_face_id_t * pfaceid,
+ u8 is_app_prod)
+{
+ dpo_proto_t dpo_proto;
- if (adj == ~0)
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
+ /* Check if we found at least one ip address */
+ if (ip46_address_is_zero (remote_addr))
+ return HICN_ERROR_FACE_NO_GLOBAL_IP;
hicn_face_flags_t flags = (hicn_face_flags_t) 0;
flags |= HICN_FACE_FLAGS_FACE;
@@ -160,17 +265,10 @@ hicn_face_ip_add (const ip46_address_t * local_addr,
if (ip46_address_is_ip4 (local_addr))
{
face =
- hicn_face_ip4_get (&(local_addr->ip4), sw_if,
- &hicn_face_ip_local_hashtb);
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face =
hicn_face_ip4_get (&(remote_addr->ip4), sw_if,
&hicn_face_ip_remote_hashtb);
- /* If remote matches the face is a iface */
+ /* If remote matches the face we need to check if it is an incomplete face */
if (face == NULL)
{
hicn_iface_ip_add (local_addr, remote_addr, sw_if, pfaceid);
@@ -181,31 +279,83 @@ hicn_face_ip_add (const ip46_address_t * local_addr,
*pfaceid = hicn_dpoi_get_index (face);
}
+ if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE))
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
hicn_face_ip_key_t key;
hicn_face_ip4_get_key (&(local_addr->ip4), sw_if, &key);
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) pfaceid, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip4_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP4;
+ hicn_face_ip_input_faces_t * in_faces =
+ hicn_face_ip4_get_vec (&(local_addr->ip4), sw_if,
+ &hicn_face_ip_local_hashtb);
+
+ if (in_faces == NULL)
+ {
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ hicn_face_ip_input_faces_t in_faces_temp;
+ hicn_face_ip_vec_t *vec;
+ pool_get(hicn_vec_pool, vec);
+ *vec = vec_new(hicn_face_ip_vec_t, 0);
+ u32 index = vec - hicn_vec_pool;
+ in_faces_temp.vec_id = index;
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip4_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP4;
+
+ in_faces_temp.face_id = *pfaceid;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) &in_faces_temp, 0);
+ }
+ else
+ {
+ hicn_face_ip_vec_t * vec = pool_elt_at_index(hicn_vec_pool, in_faces->vec_id);
+
+ /* */
+ if (vec_search(*vec, *pfaceid) != ~0)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip4_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP4;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, 0);
+
+ /* If the face is an application producer face, we set it as the preferred incoming face. */
+ /* This is required to handle the CS separation, and the push api in a lightway*/
+ if (is_app_prod)
+ {
+ in_faces->face_id = *pfaceid;
+ }
+ }
}
else
{
face =
- hicn_face_ip6_get (&(local_addr->ip6), sw_if,
- &hicn_face_ip_local_hashtb);
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- face =
hicn_face_ip6_get (&(remote_addr->ip6), sw_if,
&hicn_face_ip_remote_hashtb);
@@ -220,20 +370,79 @@ hicn_face_ip_add (const ip46_address_t * local_addr,
*pfaceid = hicn_dpoi_get_index (face);
}
+ if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE))
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
hicn_face_ip_key_t key;
hicn_face_ip6_get_key (&(local_addr->ip6), sw_if, &key);
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) pfaceid, 0);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP6;
+ hicn_face_ip_input_faces_t * in_faces =
+ hicn_face_ip6_get_vec (&(local_addr->ip6), sw_if,
+ &hicn_face_ip_local_hashtb);
+
+ if (in_faces == NULL)
+ {
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ hicn_face_ip_input_faces_t in_faces_temp;
+ hicn_face_ip_vec_t *vec;
+ pool_get(hicn_vec_pool, vec);
+ vec_alloc(*vec, 1);
+ u32 index = vec - hicn_vec_pool;
+ in_faces_temp.vec_id = index;
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip6_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP6;
+
+ in_faces_temp.face_id = *pfaceid;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) &in_faces_temp, 0);
+ }
+ else
+ {
+ hicn_face_ip_vec_t *vec = pool_elt_at_index(hicn_vec_pool, in_faces->vec_id);
+
+ /* */
+ if (vec_search(*vec, *pfaceid) != ~0)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ adj_index_t adj;
+ int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj);
+ if (ret != HICN_ERROR_NONE)
+ return ret;
+
+ vec_add1(*vec, *pfaceid);
+
+ hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t));
+ clib_memcpy (&ip_face->remote_addr, remote_addr,
+ sizeof (ip6_address_t));
+ face->shared.sw_if = sw_if;
+ face->shared.flags = flags;
+ face->shared.adj = adj;
+
+ dpo_proto = DPO_PROTO_IP6;
+
+ mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, 0);
+
+ /* If the face is an application producer face, we set it as the preferred incoming face. */
+ /* This is required to handle the CS separation, and the push api in a lightway*/
+ if (is_app_prod)
+ {
+ in_faces->face_id = *pfaceid;
+ }
+ }
}
retx_t *retx = vlib_process_signal_event_data (vlib_get_main (),
diff --git a/hicn-plugin/src/faces/ip/face_ip.h b/hicn-plugin/src/faces/ip/face_ip.h
index 852106b70..0491af506 100644
--- a/hicn-plugin/src/faces/ip/face_ip.h
+++ b/hicn-plugin/src/faces/ip/face_ip.h
@@ -43,6 +43,24 @@ typedef struct hicn_ip_face_t_
} hicn_face_ip_t;
+/**
+ * @bried vector of faces used to collect faces having the same local address
+ *
+ */
+typedef hicn_face_id_t * hicn_face_ip_vec_t;
+
+typedef struct hicn_ip_input_faces_s_
+{
+ /* Vector of all possible input faces */
+ u32 vec_id;
+
+ /* Preferred face. If an prod_app face is in the vector it will be the preferred one. */
+ /* It's not possible to have multiple prod_app face in the same vector, they would have */
+ /* the same local address. Every prod_app face is a point-to-point face between the forwarder */
+ /* and the application. */
+ hicn_face_id_t face_id;
+
+} hicn_face_ip_input_faces_t;
/**
* Hash tables that indexes a face by local address. For fast lookup when an
@@ -57,6 +75,11 @@ extern mhash_t hicn_face_ip_local_hashtb;
extern mhash_t hicn_face_ip_remote_hashtb;
/**
+ * Pool containing the vector of possible incoming faces.
+ */
+extern hicn_face_ip_vec_t * hicn_vec_pool;
+
+/**
* Key definition for the mhash table. An ip face is uniquely identified by ip
* address and the interface id. The ip address can correspond to the remote ip
* address of the next hicn hop, or to the local address of the receiving
@@ -129,6 +152,42 @@ hicn_face_ip4_get (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb)
}
/**
+ * @brief Get the vector of faces from the ip v4 address. Does not add any lock.
+ *
+ * @param addr Ip v4 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
+ *
+ * @result Pointer to the face.
+ */
+always_inline hicn_face_ip_input_faces_t *
+hicn_face_ip4_get_vec (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb)
+{
+ hicn_face_ip_key_t key;
+
+ hicn_face_ip4_get_key (addr, sw_if, &key);
+ return (hicn_face_ip_input_faces_t *) mhash_get (hashtb,&key);
+}
+
+/**
+ * @brief Get the vector of faces from the ip v6 address. Does not add any lock.
+ *
+ * @param addr Ip v6 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
+ *
+ * @result Pointer to the face.
+ */
+always_inline hicn_face_ip_input_faces_t *
+hicn_face_ip6_get_vec (const ip6_address_t * addr, u32 sw_if, mhash_t * hashtb)
+{
+ hicn_face_ip_key_t key;
+
+ hicn_face_ip6_get_key (addr, sw_if, &key);
+ return (hicn_face_ip_input_faces_t *) mhash_get (hashtb,&key);
+}
+
+/**
* @brief Get the dpoi from the ip v6 address. Does not add any lock.
*
* @param addr Ip v6 address used to create the key for the hash table.
@@ -158,12 +217,13 @@ hicn_face_ip6_get (const ip6_address_t * addr, u32 sw_if, mhash_t * hashtb)
* @param sw_if interface associated to the face
* @param is_app_face Boolean to set the face as an application face
* @param pfaceid Pointer to return the face id
+ * @param is_app_prod if HICN_FACE_FLAGS_APPFACE_PROD the face is a local application face, all other values are ignored
* @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
* reachable ip address, otherwise HICN_ERROR_NONE
*/
int hicn_face_ip_add (const ip46_address_t * local_addr,
const ip46_address_t * remote_addr,
- int swif, hicn_face_id_t * pfaceid);
+ int swif, hicn_face_id_t * pfaceid, u8 is_app_prod);
/**
* @brief Create a new incomplete face ip. (Meant to be used by the data plane)
diff --git a/hicn-plugin/src/faces/ip/face_ip_cli.c b/hicn-plugin/src/faces/ip/face_ip_cli.c
index 760768be1..4c4986f97 100644
--- a/hicn-plugin/src/faces/ip/face_ip_cli.c
+++ b/hicn-plugin/src/faces/ip/face_ip_cli.c
@@ -158,7 +158,7 @@ hicn_face_ip_cli_set_command_fn (vlib_main_t * vm,
}
}
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &face_id);
+ rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &face_id, 0);
if (rv == HICN_ERROR_NONE)
{
@@ -194,7 +194,7 @@ hicn_face_ip_cli_set_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (hicn_face_ip_cli_set_command, static) =
{
.path = "hicn face ip",
- .short_help = "hicn face ip {add local <src_address> remote <dst_address> intfc <sw_if>} | {del id <face_id>}",
+ .short_help = "hicn face ip {add [local <src_address>] remote <dst_address> intfc <sw_if>} | {del id <face_id>}",
.function = hicn_face_ip_cli_set_command_fn,
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.c b/hicn-plugin/src/faces/ip/face_ip_node.c
index 6592dc065..3f1f6a0d0 100644
--- a/hicn-plugin/src/faces/ip/face_ip_node.c
+++ b/hicn-plugin/src/faces/ip/face_ip_node.c
@@ -144,6 +144,7 @@ typedef enum
\
ret = LOCK_FROM_LOCAL_IP##ipv \
(&(hicnb0->face_dpo_id), \
+ &(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
&(ip_hdr->dst_address), \
vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
@@ -232,12 +233,14 @@ typedef enum
\
ret0 = LOCK_FROM_LOCAL_IP##ipv \
(&(hicnb0->face_dpo_id), \
+ &(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
&(ip_hdr0->dst_address), \
vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
\
ret1 = LOCK_FROM_LOCAL_IP##ipv \
(&(hicnb1->face_dpo_id), \
+ &(hicnb1->in_faces_vec_id), \
&hicnb1->flags, \
&(ip_hdr1->dst_address), \
vnet_buffer (b1)->sw_if_index[VLIB_RX]); \
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index 87628ba53..1b57ce9e2 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.h
@@ -64,8 +64,9 @@ typedef struct
u8 dpo_ctx_id; /* used for data path */
u8 vft_id; /* " */
- dpo_id_t face_dpo_id; /* ingress face ,sizeof(iface_dpo_id)
- * <= sizeof(u64) */
+ dpo_id_t face_dpo_id; /* ingress iface, sizeof(dpo_id_t)
+ * <= sizeof(u64) */
+ u32 in_faces_vec_id; /* vector of possible input face for a data packet */
hicn_type_t type;
} hicn_buffer_t;
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index 9bca748e6..f8933206d 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -249,7 +249,7 @@ vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
}
if (rv == HICN_ERROR_NONE)
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &faceid);
+ rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &faceid, 0);
else
faceid = HICN_FACE_NULL;
diff --git a/hicn-plugin/src/mgmt.c b/hicn-plugin/src/mgmt.c
index b992ba15c..cfeef6cb6 100644
--- a/hicn-plugin/src/mgmt.c
+++ b/hicn-plugin/src/mgmt.c
@@ -66,10 +66,6 @@ hicn_mgmt_node_stats_get (vl_api_hicn_api_node_stats_get_reply_t * rmp)
rmp->pkts_processed +=
clib_host_to_net_u64 (em->counters[node_cntr_base_idx +
HICNFWD_ERROR_PROCESSED]);
- n =
- vlib_get_node (this_vlib_main,
- hicn_data_pcslookup_node.index);
- node_cntr_base_idx = n->error_heap_index;
rmp->pkts_data_count +=
clib_host_to_net_u64 (em->counters[node_cntr_base_idx +
HICNFWD_ERROR_DATAS]);
diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h
index 28f9c3c37..d9c48954e 100644
--- a/hicn-plugin/src/pcs.h
+++ b/hicn-plugin/src/pcs.h
@@ -499,8 +499,16 @@ hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
policy_vft->hicn_cs_delete_get (pitcs, policy_state,
&node, &pcs_entry, &hash_entry);
- hicn_pcs_cs_delete (vm, pitcs, &pcs_entry, &node, hash_entry, NULL,
- NULL);
+ /*
+ * We don't have to decrease the lock (therefore we cannot
+ * use hicn_pcs_cs_delete function)
+ */
+ policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state);
+
+ hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm);
+
+ /* Update the global CS counter */
+ pitcs->pcs_cs_count--;
}
}
else
@@ -541,14 +549,14 @@ hicn_pcs_cs_delete (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
}
/* A data could have been inserted in the CS through a push. In this case locks == 0 */
- if (hash_entry->locks == 0 || hash_entry->locks == 1)
+ hash_entry->locks--;
+ if (hash_entry->locks == 0)
{
hicn_pcs_delete_internal
(pitcs, pcs_entryp, hash_entry, nodep, vm, dpo_vft, hicn_dpo_id);
}
else
{
- hash_entry->locks--;
hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_DELETED;
}
}
@@ -603,8 +611,16 @@ hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
policy_vft->hicn_cs_delete_get (pitcs, policy_state,
&node, &pcs_entry, &hash_entry);
- hicn_pcs_cs_delete (vm, pitcs, &pcs_entry, &node, hash_entry, NULL,
- NULL);
+ /*
+ * We don't have to decrease the lock (therefore we cannot
+ * use hicn_pcs_cs_delete function)
+ */
+ policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state);
+
+ hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm);
+
+ /* Update the global CS counter */
+ pitcs->pcs_cs_count--;
}
}
return ret;
@@ -685,9 +701,9 @@ hicn_pcs_pit_delete (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t ** pcs_entryp,
const hicn_dpo_vft_t * dpo_vft, dpo_id_t * hicn_dpo_id)
{
hash_entry->locks--;
- pitcs->pcs_pit_count--;
if (hash_entry->locks == 0)
{
+ pitcs->pcs_pit_count--;
hicn_pcs_delete_internal
(pitcs, pcs_entryp, hash_entry, node, vm, dpo_vft, hicn_dpo_id);
}