diff options
Diffstat (limited to 'hicn-plugin/src')
46 files changed, 834 insertions, 895 deletions
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt index 13d3b5c3c..ebe8f8713 100644 --- a/hicn-plugin/src/CMakeLists.txt +++ b/hicn-plugin/src/CMakeLists.txt @@ -75,13 +75,11 @@ set(HICN_PLUGIN_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/data_input_node.c ${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup_node.c ${CMAKE_CURRENT_SOURCE_DIR}/data_fwd_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/data_push_node.c ${CMAKE_CURRENT_SOURCE_DIR}/error.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_cli.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/face.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/dpo_face.h ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.c diff --git a/hicn-plugin/src/cache_policies/cs_lru.h b/hicn-plugin/src/cache_policies/cs_lru.h index 0a58912d6..3bd18060d 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.h +++ b/hicn-plugin/src/cache_policies/cs_lru.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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,6 +20,13 @@ #include "../hashtb.h" #include "cs_policy.h" +/** + * @file cs_lru.h + * + * This file implements the LRU policy for the CS + */ + + extern hicn_cs_policy_vft_t hicn_cs_lru; /* diff --git a/hicn-plugin/src/cache_policies/cs_policy.h b/hicn-plugin/src/cache_policies/cs_policy.h index c1a9a44c9..0bf745915 100644 --- a/hicn-plugin/src/cache_policies/cs_policy.h +++ b/hicn-plugin/src/cache_policies/cs_policy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -18,6 +18,13 @@ #include "../hashtb.h" +/** + * @file cs_policy.h + * + * This file provides the needed structures to implement a CS policy + */ + + /* * Structure */ @@ -41,7 +48,12 @@ struct hicn_cs_policy_s; /** * @brief Definition of the virtual functin table for a cache policy. * - * A cache policy must implement three functions: insert, update, delete, trim. + * A cache policy must implement all the following functions: + * - insert: add a new element + * - update: update the position of an existing element + * - dequeue: remove an element from the list + * - delete_get: return the next element that should be removed trim + * - flush: clean the cs */ typedef struct hicn_cs_policy_vft_s { diff --git a/hicn-plugin/src/data_fwd.h b/hicn-plugin/src/data_fwd.h index ad41e7e39..d95f564c3 100644 --- a/hicn-plugin/src/data_fwd.h +++ b/hicn-plugin/src/data_fwd.h @@ -20,6 +20,27 @@ #include "pcs.h" +/** + * @file data_fwd.h + * + * This is the node encoutered by data packets after the hicn-data-pcslookup. + * This node has two goals: 1) clone/copy the vlib buffer as many time as the number + * of faces stored in the pit entry, 2) store a clone/copy of the vlib buffer in the CS. + * Unless there are memory issue (no more vlib buffer available to perform cloning/copy), + * a single vlib buffer received might results in several vlib buffer sent to the next + * vlib node (hicn4-iface-output or hicn6-iface-output). + * + * It must be noted that cloning is possible only if the lentgh of the data pointed by + * the vlib buffer is at least 256 bytes. This is due to an imposition in the vpp source + * code. In all the other cases the vlib buffer is copied. Cloning is performed by advancing + * the vlib buffer of 256 bytes and a new vlib buffer is created and chained in from of the received + * buffer. Additionally, the 256 bytes removed (advanced) from the received vlib buffer are + * copied in the head vlib buffer. In case of multiple cloning for the same vlib buffer, this + * mechanism allows us to have a different hICN header for each clone (+ the same additional bytes + * due to the vpp restriction on cloning). + */ + + /* Trace context struct */ typedef struct { @@ -33,7 +54,6 @@ typedef enum { HICN_DATA_FWD_NEXT_V4_LOOKUP, HICN_DATA_FWD_NEXT_V6_LOOKUP, - HICN_DATA_FWD_NEXT_PUSH, HICN_DATA_FWD_NEXT_IFACE4_OUT, HICN_DATA_FWD_NEXT_IFACE6_OUT, HICN_DATA_FWD_NEXT_ERROR_DROP, @@ -41,7 +61,7 @@ typedef enum } hicn_data_fwd_next_t; /** - *@brief Create a maximum of 256 clones of buffer and store them + * @brief Create a maximum of 256 clones of buffer and store them * in the supplied array. Unlike the original function in the vlib * library, we don't prevent cloning if n_buffer==1 and if * s->current_length <= head_end_offset + CLIB_CACHE_LINE_BYTES * 2. diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c index 2737d1d62..c65b62454 100644 --- a/hicn-plugin/src/data_fwd_node.c +++ b/hicn-plugin/src/data_fwd_node.c @@ -37,11 +37,6 @@ 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); -always_inline void -push_in_cache (vlib_main_t * vm, u32 bi0, - u32 * n_left_to_next, u32 * next0, u32 ** to_next, - u32 * next_index, vlib_node_runtime_t * node); - always_inline int hicn_satisfy_faces (vlib_main_t * vm, u32 b0, hicn_pcs_entry_t * pitp, u32 * n_left_to_next, @@ -176,21 +171,8 @@ 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, - &next_index, node); - } - else - { - 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) && @@ -348,21 +330,6 @@ drop_packet (vlib_main_t * vm, u32 bi0, *to_next, *n_left_to_next, bi0, *next0); } -always_inline void -push_in_cache (vlib_main_t * vm, u32 bi0, - u32 * n_left_to_next, u32 * next0, u32 ** to_next, - u32 * next_index, vlib_node_runtime_t * node) -{ - *next0 = HICN_DATA_FWD_NEXT_PUSH; - - (*to_next)[0] = bi0; - *to_next += 1; - *n_left_to_next -= 1; - - vlib_validate_buffer_enqueue_x1 (vm, node, *next_index, - *to_next, *n_left_to_next, bi0, *next0); -} - always_inline int hicn_satisfy_faces (vlib_main_t * vm, u32 bi0, hicn_pcs_entry_t * pitp, u32 * n_left_to_next, @@ -639,7 +606,6 @@ VLIB_REGISTER_NODE(hicn_data_fwd_node) = .next_nodes = { [HICN_DATA_FWD_NEXT_V4_LOOKUP] = "ip4-lookup", [HICN_DATA_FWD_NEXT_V6_LOOKUP] = "ip6-lookup", - [HICN_DATA_FWD_NEXT_PUSH] = "hicn-data-push", [HICN_DATA_FWD_NEXT_IFACE4_OUT] = "hicn4-iface-output", [HICN_DATA_FWD_NEXT_IFACE6_OUT] = "hicn6-iface-output", [HICN_DATA_FWD_NEXT_ERROR_DROP] = "error-drop", diff --git a/hicn-plugin/src/data_pcslookup.h b/hicn-plugin/src/data_pcslookup.h index fa75c3ac3..e3050c31c 100644 --- a/hicn-plugin/src/data_pcslookup.h +++ b/hicn-plugin/src/data_pcslookup.h @@ -18,6 +18,15 @@ #include "pcs.h" +/** + * @file data_pcslookup.h + * + * This is the node encoutered by data packets after the hicn6-face-input or + * hicn4-face-input. This node performs a lookup in the pit and content store and + * if there is a hit in the PIT, the vlib buffer is passed to the hicn-data-fwd + * while if there is a hit in the CS or there isn't any hit, the packet is dropped. + */ + /* * Node context data; we think this is per-thread/instance */ @@ -37,9 +46,6 @@ typedef struct typedef enum { - HICN_DATA_PCSLOOKUP_NEXT_V4_LOOKUP, - HICN_DATA_PCSLOOKUP_NEXT_V6_LOOKUP, - HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA, HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD, /* This must be one position * before the error drop!! */ HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP, diff --git a/hicn-plugin/src/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c index cbea07871..99af350b0 100644 --- a/hicn-plugin/src/data_pcslookup_node.c +++ b/hicn-plugin/src/data_pcslookup_node.c @@ -63,7 +63,6 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next > 0) { vlib_buffer_t *b0; - hicn_buffer_t *hb0; u8 isv6; u8 *nameptr; u16 namelen; @@ -100,7 +99,6 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, 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 */ @@ -126,25 +124,7 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, stats.pkts_data_count += 1; -#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; - } - 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; - } - } -#else - if (res == HICN_ERROR_NONE) + if (res == HICN_ERROR_NONE) { /* * In case the result of the lookup @@ -154,7 +134,6 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, 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, @@ -231,9 +210,6 @@ VLIB_REGISTER_NODE(hicn_data_pcslookup_node) = .error_strings = hicn_data_pcslookup_error_strings, .n_next_nodes = HICN_DATA_PCSLOOKUP_N_NEXT, .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", [HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD] = "hicn-data-fwd", [HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP] = "error-drop", }, diff --git a/hicn-plugin/src/data_push_node.c b/hicn-plugin/src/data_push_node.c deleted file mode 100644 index 18c4690b1..000000000 --- a/hicn-plugin/src/data_push_node.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2017-2019 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: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <vlib/vlib.h> -#include <vnet/vnet.h> - -#include "hicn.h" -#include "parser.h" -#include "strategy_dpo_ctx.h" -#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 - * per-thread/instance - */ -typedef struct hicn_data_push_runtime_s -{ - int id; - hicn_pit_cs_t *pitcs; -} hicn_data_push_runtime_t; - -/* Stats string values */ -static char *hicn_data_push_error_strings[] = { -#define _(sym, string) string, - foreach_hicnfwd_error -#undef _ -}; - -typedef enum -{ - HICN_DATA_PUSH_NEXT_FWD, - HICN_DATA_PUSH_NEXT_ERROR_DROP, - HICN_DATA_PUSH_N_NEXT, -} hicn_data_push_next_t; - -/* Trace context struct */ -typedef struct -{ - u32 next_index; - u32 sw_if_index; - u8 pkt_type; -} hicn_data_push_trace_t; - -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) -{ - word buffer_advance = CLIB_CACHE_LINE_BYTES * 2; - hicn_buffer_t *hicnb = hicn_get_buffer (b0); - - if (PREDICT_TRUE (b0->next_buffer == 0)) - { - 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 - { - 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 ** 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 = vlib_buffer_get_current (b0); - hicn_buffer_t *hicnb0 = hicn_get_buffer (b0); - u32 node_id0 = 0; - index_t 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; - hicn_lifetime_t dmsg_lifetime; - - hicnb0 = hicn_get_buffer (b0); - hicn_type_t type = hicnb0->type; - hicn_ops_vft[type.l1]->get_lifetime (type, &hicn0->protocol, - &dmsg_lifetime); - - if (!dmsg_lifetime) - { - vlib_buffer_free_one (vm, bi0); - return HICN_ERROR_NONE; - } - - /* Create PIT node and init PIT entry */ - 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 */ - return HICN_ERROR_HASHTB_NOMEM; - } - - pitp = hicn_pit_get_data (nodep); - hicn_cs_init_data (pitp); - pitp->shared.create_time = tnow; - - if (dmsg_lifetime < HICN_PARAM_CS_LIFETIME_MIN - || dmsg_lifetime > HICN_PARAM_CS_LIFETIME_MAX) - { - dmsg_lifetime = HICN_PARAM_CS_LIFETIME_DFLT; - } - pitp->shared.expire_time = hicn_pcs_get_exp_time (tnow, dmsg_lifetime); - - /* Store the original packet buffer in the CS node */ - pitp->u.cs.cs_pkt_buf = vlib_get_buffer_index (vm, b0); - - /* Set up the hash node and insert it */ - hicn_hashtb_init_node (rt->pitcs->pcs_table, nodep, nameptr, namelen); - - - hicn_hash_entry_t *hash_entry; - ret = - hicn_pcs_cs_insert_update (vm, 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, hicnb0->face_id); - - 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 - { - prep_buffer_for_cs (vm, b0, isv6); - } - } - - return (ret); - -} - -/* - * ICN strategy later node for interests: - 1 packet at a time - ipv4/tcp - * ipv6/tcp - */ -uword -hicn_data_push_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - - u32 n_left_from, *from, *to_next, n_left_to_next; - hicn_data_push_next_t next_index; - 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) - { - 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) - { - 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++; - } - - /* 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 = HICN_DATA_PUSH_NEXT_ERROR_DROP; - } - } - - 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) - { - 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); - - return (frame->n_vectors); -} - -/* packet trace format function */ -always_inline u8 * -hicn_data_push_format_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - hicn_data_push_trace_t *t = va_arg (*args, hicn_data_push_trace_t *); - - s = format (s, "DATA-STORE: pkt: %d, sw_if_index %d, next index %d\n", - (int) t->pkt_type, t->sw_if_index, t->next_index); - - return (s); -} - - -/* - * Node registration for the data forwarder node - */ -/* *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, - .next_nodes = { - [HICN_DATA_PUSH_NEXT_FWD] = "hicn-data-fwd", - [HICN_DATA_PUSH_NEXT_ERROR_DROP] = "error-drop", - }, -}; -/* *INDENT-ON* */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: eval: (c-set-style "gnu") End: - */ diff --git a/hicn-plugin/src/error.h b/hicn-plugin/src/error.h index d35347779..59ebce61c 100644 --- a/hicn-plugin/src/error.h +++ b/hicn-plugin/src/error.h @@ -16,6 +16,13 @@ #ifndef __HICN_ERROR_H__ #define __HICN_ERROR_H__ +/** + * @file error.h + * + * Error codes for the hICN plugin. + */ + + #define foreach_hicn_error \ _(NONE, 0, "Ok") \ _(UNSPECIFIED, -128, "Unspecified Error") \ diff --git a/hicn-plugin/src/face_db.h b/hicn-plugin/src/face_db.h index 9423c59d6..4dd8b2f32 100644 --- a/hicn-plugin/src/face_db.h +++ b/hicn-plugin/src/face_db.h @@ -20,7 +20,7 @@ #include "faces/face.h" /** - * @File + * @file face_db.h * * Define a face db that is store in every pit entry. A face db containes a list * of incoming faces for interest packets that are used to forward data packets diff --git a/hicn-plugin/src/faces/dpo_face.h b/hicn-plugin/src/faces/dpo_face.h deleted file mode 100644 index 3bb99ecdb..000000000 --- a/hicn-plugin/src/faces/dpo_face.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2017-2020 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: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HICN_DPO_H__ -#define __HICN_DPO_H__ - -#include <vnet/vnet.h> -#include <vnet/ip/ip4_packet.h> -#include <vnet/adj/adj_midchain.h> - -#include "face.h" -#include "../error.h" - -/** - * @brief Initialize the internal structures of the dpo ip face module. - */ -//void hicn_dpo_ip_module_init (void); - - -/** - * @brief Retrieve a vector of faces from the ip4 local address and returns its index. - * - * @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 nat address of the face - * @param sw_if: software interface id of the face - * - * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. - */ -always_inline int -hicn_dpo_face_ip4_lock (hicn_face_id_t * face_id, - u32 * in_faces_vec_id, - u8 * hicnb_flags, - const ip4_address_t * nat_addr) -{ - ip46_address_t ip_address = {0}; - ip46_address_set_ip4(&ip_address, nat_addr); - hicn_face_input_faces_t *in_faces_vec = - hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb); - - 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->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *face_id = in_faces_vec->face_id; - - return HICN_ERROR_NONE; -} - -/** - * @brief Retrieve a face from the ip6 local address and returns its dpo. This - * method adds a lock on the face state. - * - * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v6 nat address of the face - * @param sw_if: software interface id of the face - * - * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. - */ -always_inline int -hicn_dpo_face_ip6_lock (hicn_face_id_t * face_id, - u32 * in_faces_vec_id, - u8 * hicnb_flags, - const ip6_address_t * nat_addr) -{ - hicn_face_input_faces_t *in_faces_vec = - hicn_face_get_vec ((ip46_address_t *)nat_addr, &hicn_face_vec_hashtb); - - 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->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *face_id = in_faces_vec->face_id; - - return HICN_ERROR_NONE; -} - -/** - * @brief Call back to get the adj of the tunnel - */ -static adj_walk_rc_t -hicn4_iface_adj_walk_cb (adj_index_t ai, - void *ctx) -{ - - hicn_face_t *face = (hicn_face_t *)ctx; - - dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai); - adj_nbr_midchain_stack(ai, &face->dpo); - - return (ADJ_WALK_RC_CONTINUE); -} - -/** - * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local - * address and returns its dpo. This method adds a lock on the face state. - * - * @param dpo: Result of the lookup - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v4 remote address of the face - * @param sw_if: software interface id of the face - * @param node_index: vlib edge index to use in the packet processing - */ -always_inline void -hicn_dpo_iface_ip4_add_and_lock (hicn_face_id_t * index, - u8 * hicnb_flags, - const ip4_address_t * nat_addr, - u32 sw_if, u32 adj_index, u32 node_index) -{ - /*All (complete) faces are indexed by remote addess as well */ - - ip46_address_t ip_address = {0}; - ip46_address_set_ip4(&ip_address, nat_addr); - - /* if the face exists, it adds a lock */ - hicn_face_t *face = - hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index); - - if (face == NULL) - { - hicn_face_id_t idx; - hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index); - - face = hicn_dpoi_get_from_idx(idx); - - face->dpo.dpoi_type = DPO_FIRST; - face->dpo.dpoi_proto = DPO_PROTO_IP4; - face->dpo.dpoi_index = adj_index; - face->dpo.dpoi_next_node = node_index; - - /* if (nat_addr->as_u32 == 0) */ - /* { */ - adj_nbr_walk(face->sw_if, - FIB_PROTOCOL_IP4, - hicn4_iface_adj_walk_cb, - face); - /* } */ - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - - *index = idx; - return; - } - else - { - /* unlock the face. We don't take a lock on each interest we receive */ - hicn_face_id_t face_id = hicn_dpoi_get_index(face); - hicn_face_unlock_with_id(face_id); - } - - /* Code replicated on purpose */ - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= - (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *index = hicn_dpoi_get_index (face); -} - -/** - * @brief Call back to get the adj of the tunnel - */ -static adj_walk_rc_t -hicn6_iface_adj_walk_cb (adj_index_t ai, - void *ctx) -{ - - hicn_face_t *face = (hicn_face_t *)ctx; - - ip_adjacency_t *adj = adj_get(ai); - if ((adj->lookup_next_index == IP_LOOKUP_NEXT_MIDCHAIN) || - (adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST_MIDCHAIN)) - { - dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, adj->ia_nh_proto, ai); - adj_nbr_midchain_stack(ai, &face->dpo); - } - - return (ADJ_WALK_RC_CONTINUE); -} - - -/** - * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local - * address and returns its dpo. This method adds a lock on the face state. - * - * @param dpo: Result of the lookup - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v6 remote address of the face - * @param sw_if: software interface id of the face - * @param node_index: vlib edge index to use in the packet processing - */ -always_inline void -hicn_dpo_iface_ip6_add_and_lock (hicn_face_id_t * index, - u8 * hicnb_flags, - const ip6_address_t * nat_addr, - u32 sw_if, u32 adj_index, u32 node_index) -{ - /*All (complete) faces are indexed by remote addess as well */ - /* if the face exists, it adds a lock */ - hicn_face_t *face = - hicn_face_get ((ip46_address_t *)nat_addr, sw_if, &hicn_face_hashtb, adj_index); - - if (face == NULL) - { - hicn_face_id_t idx; - hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, adj_index); - - face = hicn_dpoi_get_from_idx(idx); - - face->dpo.dpoi_type = DPO_FIRST; - face->dpo.dpoi_proto = DPO_PROTO_IP6; - face->dpo.dpoi_index = adj_index; - face->dpo.dpoi_next_node = node_index; - - //if (ip46_address_is_zero((ip46_address_t *)nat_addr)) - // { - adj_nbr_walk(face->sw_if, - FIB_PROTOCOL_IP6, - hicn6_iface_adj_walk_cb, - face); - // } - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - - *index = idx; - - return; - } - else - { - /* unlock the face. We don't take a lock on each interest we receive */ - hicn_face_id_t face_id = hicn_dpoi_get_index(face); - hicn_face_unlock_with_id(face_id); - } - - /* Code replicated on purpose */ - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= - (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *index = hicn_dpoi_get_index (face); -} - - -/* /\** */ -/* * @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); */ - -#endif // __HICN_DPO_IP_H__ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h index a9a565a5a..234c3fcc2 100644 --- a/hicn-plugin/src/faces/face.h +++ b/hicn-plugin/src/faces/face.h @@ -23,28 +23,55 @@ #include <vnet/dpo/dpo.h> #include <vnet/adj/adj_types.h> #include <vppinfra/bihash_8_8.h> +#include <vnet/adj/adj_midchain.h> + +#include "../error.h" typedef u8 hicn_face_flags_t; typedef index_t hicn_face_id_t; -//typedef dpo_type_t hicn_face_type_t; /** - * @file + * @file face.h + * + * This file implements a general face type. The purpose of a face is to + * carry the needed information to forward interest and data packets to the + * next node in the network. There are two type of faces: complete faces (in short + * faces), and incomplete faces (in short ifaces). * - * @brief Face + * A face that does not contain the indication of the adjacency is an + * incomplete face (iface), otherwise it is considered to be complete. Ifaces are + * used to forward data back to the previous hICN hop from which we received an + * interest, while faces are used to forward interest packets to the next hicn node. + * Faces and ifaces are created at two different points in time. Faces are created + * when a route is added, while ifaces are created when an interest is received. + * In details, faces and ifaces carry the following information: + * - nat_addr: the ip address to perform src nat or dst nat on interest and data packets, respectively; + * - pl_id: the path label + * - locks: the number of entities using this face. When 0 the face can be deallocated + * - dpo: the dpo that identifies the next node in the vlib graph for processing the vlib + * buffer. The dpo contains the dpo.dpoi_next field that points to the next node + * in the vlib graph and the dpo.dpoi_index which is an index to adj used by the next node + * to perform the l2 rewrite. In case of ifaces, it is likely we don't know the + * adjacency when creting the face. In this case, the next node in the vlib graph + * will be the node that performs a lookup in the fib. Only in case of udp tunnels, + * which are bidirectional tunnel we know that the incoming tunnel is also the outgoing + * one, therefore in this case we store the tunnel in the dpo.dpoi_index fields. For + * all the other tunnels (which are most likely unidirectional), the source address of + * the interest will be used to retrieve the outgoing tunnel when sending the corresponding + * data back. + * - sw_if: the incoming interface of the interest + * - fib_node, fib_entry_index and fib_sibling are information used to be notified of + * changes in the adjacency pointed by the dpo. * - * This file implements a general face type. A face is carried through nodes as a - * dpo. The face state (hicn_face_t) is the object pointed by the - * dpoi_index in the dpo_id_t (see - * https://docs.fd.io/vpp/18.07/d0/d37/dpo_8h_source.html). - * A face state that does not contain the indication of the l2 adjacency is an - * incomplete face (iface), otherwise it is considered to be complete. Each face type - * provide specific node for processing packets in input or output of complete - * and incomplete faces. + * We maintain two hash tables to retrieve faces and ifaces. In particular one hash table which + * index faces and ifaces for nat_address, sw_if and dpo. This is used to retrieve existing faces + * or ifaces when an interest is received and when an new face is created. A second hash table that + * indexes vectors of faces for nat_address and sw_if. This is used to retrieve a list of possible + * incoming faces when a data is received. */ /** - * @brief Structure holding the face state. It containes the fields shared among + * @brief Structure representing a face. It containes the fields shared among * all the types of faces as well it leaves some space for storing additional * information specific to each type. */ @@ -85,8 +112,6 @@ typedef struct __attribute__ ((packed)) hicn_face_s /* Pool of faces */ extern hicn_face_t *hicn_dpoi_face_pool; -//extern dpo_type_t hicn_face_type; - /* Flags */ /* A face is complete and it stores all the information. A iface lacks of the adj index, therefore sending a packet through a iface require a lookup in @@ -127,11 +152,6 @@ STATIC_ASSERT ((HICN_FACE_FLAGS_APPFACE_CONS >> /** * @brief Definition of the virtual functin table for an hICN FACE DPO. - * - * An hICN dpo is a combination of a dpo context (hicn_dpo_ctx or struct that - * extends a hicn_dpo_ctx) and a strategy node. The following virtual function table - * template that glues together the fuction to interact with the context and the - * creating the dpo */ typedef struct hicn_face_vft_s { @@ -176,7 +196,7 @@ extern dpo_type_t first_type; extern vlib_combined_counter_main_t *counters; /** - * @brief Return the face id from the face state + * @brief Return the face id from the face object * * @param Pointer to the face state * @return face id @@ -188,10 +208,11 @@ hicn_dpoi_get_index (hicn_face_t * face_dpoi) } /** - * @brief Return the face from the face id. Face id must be valid. + * @brief Return the face object from the face id. + * This method is robust to invalid face id. * * @param dpoi_index Face identifier - * @return Pointer to the face + * @return Pointer to the face or NULL */ always_inline hicn_face_t * hicn_dpoi_get_from_idx_safe (hicn_face_id_t dpoi_index) @@ -252,7 +273,7 @@ hicn_face_unlock_with_id (hicn_face_id_t face_id) } /** - * @brief Add a lock to the face dpo + * @brief Add a lock to the face through its dpo * * @param dpo Pointer to the face dpo */ @@ -263,7 +284,7 @@ hicn_face_lock (dpo_id_t * dpo) } /** - * @brief Remove a lock to the face dpo. Deallocate the face id locks == 0 + * @brief Remove a lock to the face through its dpo. Deallocate the face id locks == 0 * * @param dpo Pointer to the face dpo */ @@ -302,8 +323,6 @@ u8 *format_hicn_face_all (u8 * s, int n, ...); */ int hicn_face_del (hicn_face_id_t face_id); -/* FACE IP CODE */ - /** * @bried vector of faces used to collect faces having the same local address * @@ -336,11 +355,24 @@ extern mhash_t hicn_face_vec_hashtb; /** - * 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 - * interface. The former is used to retrieve the incoming face when an interest - * is received, the latter when the arring packet is a data. + * Key definition for the mhash table. An face is uniquely identified by ip + * address, the interface id and a dpo pointing to the next node in the vlib graph. + * The ip address can correspond to the remote ip address of the next hicn hop, + * or to the local address of the receiving interface. The former is used to + * retrieve the incoming face when an interest is received, the latter when + * the arring packet is a data. If the face is a regular face + * In case of iface, the following structure can be filled in different ways: + * - dpo equal to DPO_INVALID when the iface is a regular hICN iface + * - in case of udp_tunnel dpo = + * { + * .dpoi_index = tunnel_id, + * .dpoi_type = DPO_FIRST, //We don't need the type, we leave it invalid + * .dpoi_proto = DPO_PROTO_IP4 or DPO_PROTO_IP6, + * .dpoi_next_node = HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP or + * HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP or + * HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP or + * HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP + * } */ typedef struct __attribute__ ((packed)) hicn_face_key_s { @@ -370,7 +402,7 @@ hicn_face_get_key (const ip46_address_t * addr, } /** - * @brief Get the dpoi from the nat address. Does not add any lock. + * @brief Get the face obj from the nat 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. @@ -402,7 +434,7 @@ hicn_face_get (const ip46_address_t * addr, u32 sw_if, mhash_t * hashtb, index_t } /** - * @brief Get the dpoi from the nat address. Does not add any lock. + * @brief Get the face obj from the nat address and the dpo. 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. @@ -453,10 +485,10 @@ hicn_face_get_vec (const ip46_address_t * addr, /** * @brief Create a new face ip. API for other modules (e.g., routing) * - * @param local_addr Local ip v4 or v6 address of the face - * @param remote_addr Remote ip v4 or v6 address of the face + * @param dpo_nh dpo contained in the face that points to the next node in + * the vlib graph + * @param nat_addr nat ip v4 or v6 address of the face * @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 @@ -512,6 +544,248 @@ hicn_iface_add (ip46_address_t * nat_address, int sw_if, } } +/**** Helpers to manipulate faces and ifaces from the face/iface input nodes ****/ + +/** + * @brief Retrieve a vector of faces from the ip4 local address and returns its index. + * + * @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 nat address of the face + * @param sw_if: software interface id of the face + * + * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. + */ +always_inline int +hicn_face_ip4_lock (hicn_face_id_t * face_id, + u32 * in_faces_vec_id, + u8 * hicnb_flags, + const ip4_address_t * nat_addr) +{ + ip46_address_t ip_address = {0}; + ip46_address_set_ip4(&ip_address, nat_addr); + hicn_face_input_faces_t *in_faces_vec = + hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb); + + 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->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *face_id = in_faces_vec->face_id; + + return HICN_ERROR_NONE; +} + +/** + * @brief Retrieve a face from the ip6 local address and returns its dpo. This + * method adds a lock on the face state. + * + * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param nat_addr: Ip v6 nat address of the face + * @param sw_if: software interface id of the face + * + * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. + */ +always_inline int +hicn_face_ip6_lock (hicn_face_id_t * face_id, + u32 * in_faces_vec_id, + u8 * hicnb_flags, + const ip6_address_t * nat_addr) +{ + hicn_face_input_faces_t *in_faces_vec = + hicn_face_get_vec ((ip46_address_t *)nat_addr, &hicn_face_vec_hashtb); + + 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->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *face_id = in_faces_vec->face_id; + + return HICN_ERROR_NONE; +} + +/** + * @brief Call back to get the adj of the tunnel + */ +static adj_walk_rc_t +hicn4_iface_adj_walk_cb (adj_index_t ai, + void *ctx) +{ + + hicn_face_t *face = (hicn_face_t *)ctx; + + dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai); + adj_nbr_midchain_stack(ai, &face->dpo); + + return (ADJ_WALK_RC_CONTINUE); +} + +/** + * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local + * address and returns its dpo. This method adds a lock on the face state. + * + * @param dpo: Result of the lookup + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param nat_addr: Ip v4 remote address of the face + * @param sw_if: software interface id of the face + * @param node_index: vlib edge index to use in the packet processing + */ +always_inline void +hicn_iface_ip4_add_and_lock (hicn_face_id_t * index, + u8 * hicnb_flags, + const ip4_address_t * nat_addr, + u32 sw_if, u32 adj_index, u32 node_index) +{ + /*All (complete) faces are indexed by remote addess as well */ + + ip46_address_t ip_address = {0}; + ip46_address_set_ip4(&ip_address, nat_addr); + + /* if the face exists, it adds a lock */ + hicn_face_t *face = + hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index); + + if (face == NULL) + { + hicn_face_id_t idx; + hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index); + + face = hicn_dpoi_get_from_idx(idx); + + face->dpo.dpoi_type = DPO_FIRST; + face->dpo.dpoi_proto = DPO_PROTO_IP4; + face->dpo.dpoi_index = adj_index; + face->dpo.dpoi_next_node = node_index; + + /* if (nat_addr->as_u32 == 0) */ + /* { */ + adj_nbr_walk(face->sw_if, + FIB_PROTOCOL_IP4, + hicn4_iface_adj_walk_cb, + face); + /* } */ + + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + + *index = idx; + return; + } + else + { + /* unlock the face. We don't take a lock on each interest we receive */ + hicn_face_id_t face_id = hicn_dpoi_get_index(face); + hicn_face_unlock_with_id(face_id); + } + + /* Code replicated on purpose */ + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= + (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *index = hicn_dpoi_get_index (face); +} + +/** + * @brief Call back to get the adj of the tunnel + */ +static adj_walk_rc_t +hicn6_iface_adj_walk_cb (adj_index_t ai, + void *ctx) +{ + + hicn_face_t *face = (hicn_face_t *)ctx; + + ip_adjacency_t *adj = adj_get(ai); + if ((adj->lookup_next_index == IP_LOOKUP_NEXT_MIDCHAIN) || + (adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST_MIDCHAIN)) + { + dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, adj->ia_nh_proto, ai); + adj_nbr_midchain_stack(ai, &face->dpo); + } + + return (ADJ_WALK_RC_CONTINUE); +} + + +/** + * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local + * address and returns its dpo. This method adds a lock on the face state. + * + * @param dpo: Result of the lookup + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param nat_addr: Ip v6 remote address of the face + * @param sw_if: software interface id of the face + * @param node_index: vlib edge index to use in the packet processing + */ +always_inline void +hicn_iface_ip6_add_and_lock (hicn_face_id_t * index, + u8 * hicnb_flags, + const ip6_address_t * nat_addr, + u32 sw_if, u32 adj_index, u32 node_index) +{ + /*All (complete) faces are indexed by remote addess as well */ + /* if the face exists, it adds a lock */ + hicn_face_t *face = + hicn_face_get ((ip46_address_t *)nat_addr, sw_if, &hicn_face_hashtb, adj_index); + + if (face == NULL) + { + hicn_face_id_t idx; + hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, adj_index); + + face = hicn_dpoi_get_from_idx(idx); + + face->dpo.dpoi_type = DPO_FIRST; + face->dpo.dpoi_proto = DPO_PROTO_IP6; + face->dpo.dpoi_index = adj_index; + face->dpo.dpoi_next_node = node_index; + + adj_nbr_walk(face->sw_if, + FIB_PROTOCOL_IP6, + hicn6_iface_adj_walk_cb, + face); + + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + + *index = idx; + + return; + } + else + { + /* unlock the face. We don't take a lock on each interest we receive */ + hicn_face_id_t face_id = hicn_dpoi_get_index(face); + hicn_face_unlock_with_id(face_id); + } + + /* Code replicated on purpose */ + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= + (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *index = hicn_dpoi_get_index (face); +} #endif // __HICN_FACE_H__ diff --git a/hicn-plugin/src/faces/face_node.c b/hicn-plugin/src/faces/face_node.c index 5b42f0dde..e1fd81ca0 100644 --- a/hicn-plugin/src/faces/face_node.c +++ b/hicn-plugin/src/faces/face_node.c @@ -17,7 +17,6 @@ #include "face.h" #include "face_node.h" -#include "dpo_face.h" #include "../strategy_dpo_manager.h" #include "face.h" #include "../cache_policies/cs_lru.h" @@ -97,8 +96,8 @@ typedef enum #define IP_HEADER_4 ip4_header_t #define IP_HEADER_6 ip6_header_t -#define LOCK_DPO_FACE_IP4 hicn_dpo_face_ip4_lock -#define LOCK_DPO_FACE_IP6 hicn_dpo_face_ip6_lock +#define LOCK_DPO_FACE_IP4 hicn_face_ip4_lock +#define LOCK_DPO_FACE_IP6 hicn_face_ip6_lock #define TRACE_INPUT_PKT_IP4 hicn4_face_input_trace_t #define TRACE_INPUT_PKT_IP6 hicn6_face_input_trace_t diff --git a/hicn-plugin/src/faces/face_node.h b/hicn-plugin/src/faces/face_node.h index 932ee40f5..f5a8bf5ae 100644 --- a/hicn-plugin/src/faces/face_node.h +++ b/hicn-plugin/src/faces/face_node.h @@ -19,6 +19,23 @@ #include <vlib/vlib.h> #include <vnet/vnet.h> +/** + * @file face_node.h + * + * Implements the input and output face nodes. Input face nodes + * process incoming data while output face nodes process outgoing + * interests packets. + * + * Input face nodes follow hicn-face-input nodes and their purpose + * is to retrieve the list of possible incoming faces for each the data packet. + * The following node to the input face nodes is the hicn-data-pcslookup. + * Output face nodes follow the strategy and the hicn-interest-hitpit nodes and + * they perform the src nat on each interest packet. The node following the + * output face nodes depends on the adjacency type. In case of ip, the following + * node is the ip-rewrite, in case of tunnels the next node is the one implementing + * the tunnel encapsulation (udp-encap, mpls, etc). + */ + extern vlib_node_registration_t hicn4_face_input_node; extern vlib_node_registration_t hicn4_face_output_node; extern vlib_node_registration_t hicn6_face_input_node; diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c index d42d0114e..433cf0b02 100644 --- a/hicn-plugin/src/faces/iface_node.c +++ b/hicn-plugin/src/faces/iface_node.c @@ -14,7 +14,6 @@ */ #include "face.h" -#include "dpo_face.h" #include "../strategy_dpo_manager.h" #include "../hicn.h" #include "../infra.h" @@ -96,8 +95,8 @@ typedef enum #define ADDRESSX2_IP6 ip6_address_t *local_address0 = ip6_interface_first_address(&ip6_main, swif0); \ ip6_address_t *local_address1 = ip6_interface_first_address(&ip6_main, swif1); -#define DPO_ADD_LOCK_IFACE_IP4 hicn_dpo_iface_ip4_add_and_lock -#define DPO_ADD_LOCK_IFACE_IP6 hicn_dpo_iface_ip6_add_and_lock +#define DPO_ADD_LOCK_IFACE_IP4 hicn_iface_ip4_add_and_lock +#define DPO_ADD_LOCK_IFACE_IP6 hicn_iface_ip6_add_and_lock //#define VLIB_EDGE_IP4 data_fwd_iface_ip4_vlib_edge //#define VLIB_EDGE_IP6 data_fwd_iface_ip6_vlib_edge diff --git a/hicn-plugin/src/faces/iface_node.h b/hicn-plugin/src/faces/iface_node.h index 761721b2f..1a7c4291b 100644 --- a/hicn-plugin/src/faces/iface_node.h +++ b/hicn-plugin/src/faces/iface_node.h @@ -13,16 +13,35 @@ * limitations under the License. */ -#ifndef __HICN_IFACE_IP_NODE_H__ -#define __HICN_IFACE_IP_NODE_H__ +#ifndef __HICN_IFACE_NODE_H__ +#define __HICN_IFACE_NODE_H__ #include <vlib/vlib.h> #include <vnet/vnet.h> /** + * @file iface_node.h + * + * Implements the input and output iface nodes. Input iface nodes + * process incoming interests while output face nodes process outgoing + * data packets. + * + * Input iface nodes follow ip-lookup nodes and their purpose + * is to create (or retrieve if already existing) the list incoming face + * for each the interest packet. + * The following node to the input iface nodes is the hicn-interest-pcslookup. + * Output iface nodes follow the hicn-data-fwd and the hicn-interest-hitcs nodes and + * they perform the dst nat on each data packet. The node following the + * output face nodes depends on the adjacency type. In case of ip, the following + * node is the ip4/6-lookup, in case of tunnels the next node is the one implementing + * the tunnel encapsulation (udp-encap, mpls, etc). + */ + + +/** * @brief Initialize the ip iface module */ -void hicn_iface_ip_init (vlib_main_t * vm); +void hicn_iface_init (vlib_main_t * vm); #endif // __HICN_IFACE_IP_NODE_H__ diff --git a/hicn-plugin/src/hashtb.h b/hicn-plugin/src/hashtb.h index 756f247b7..3c72fda65 100644 --- a/hicn-plugin/src/hashtb.h +++ b/hicn-plugin/src/hashtb.h @@ -24,47 +24,35 @@ #include "parser.h" #include "error.h" -/* Handy abbreviations for success status, and for boolean values */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* +/** + * @file hashtb.h * Lookup is finding a hashtable record whose name matches the name being * looked up. Most of the lookup work is based on the hash value of the two * names. Note that the intel cache line size is 64 bytes, and some platforms - * load in 2 cache lines together. - first step is to match a record at the - * bucket/slot level (htab has an array of htbucket_t/htbc_elmt, where each - * bucket has 7 slots to hold indices for entries.) Matching at this level - * implies - the hashes of the lookup name and the record map to the same - * bucket - the high 32 bits of the hashes (slot bce_hash_msb32s) match. Read - * cost (on the hash table size, i.e. ignoring reading the name being looked - * up): - First step normally requires 1 cache line load to pull in the - * 64-byte htbucket_t with the 7 element slot table holding the hash_msb32s. - * - In the event (hopefully rare for a hash table with appropriate number of - * buckets) that more than 7 elements hash to the same bucket, lookup may - * well need to look not only at the static htbc_elmt_t but at the chain of - * dynamically allocated htbc_elmt_t's linked to the static htbc_elmt_t, - * where each of these holds slot entries for additional elements. - Before - * reaching that point, it is initially required is to read in the hash table - * record fields (ht_bucket_buf, htnode buf, etc) holding pointers to the - * arrays, but these cache lines are common to all lookups so will likely - * already be in the cache. - second step is to match at the record level - * (htnode/htkb level) once a slot-level match happens. Matching at this - * level implies the following match - the hash values (the full 64 bits vs. - * bucket+32 msb, above) With siphash, two names hashing to the same 64-bit - * value is quite rare. - the name which, on the hash table side, is stored - * as a list of htkb_t (key buffers). [In some cases, the full name is not - * compared, and a match is assumed based on hash value match. Read cost: - - * htnode_t, in one cache line, holds hash value and index for the htkb at - * the head of the key buffer list - each key buffer (htkb_t) is cache line - * aligned/sized, and holds 60 bytes of the name and requires a cache line - * read. Simplification is that a fib lookup requires 3 cache lines: - bucket - * - htnode - single key buffer (for cases where a name comparision is done) + * load in 2 cache lines together. + * - first step is to match a record at the bucket/slot level (htab has an + * array of htbucket_t/htbc_elmt, where each bucket has 7 slots to hold indices + * for entries.) Matching at this level implies + * - the hashes of the lookup name and the record map to the same bucket + * - the high 32 bits of the hashes (slot bce_hash_msb32s) match. Read + * cost (on the hash table size, i.e. ignoring reading the name being + * looked up): + * - First step normally requires 1 cache line load to pull in the + * 64-byte htbucket_t with the 7 element slot table holding the + * hash_msb32s. + * - In the event (hopefully rare for a hash table with appropriate + * number of buckets) that more than 7 elements hash to the same bucket, + * lookup may well need to look not only at the static htbc_elmt_t but at + * the chain of dynamically allocated htbc_elmt_t's linked to the static + * htbc_elmt_t, where each of these holds slot entries for additional elements. + * - Before reaching that point, it is initially required to read in the + * hash table record fields (ht_bucket_buf, htnode buf, etc) holding + * pointers to the arrays, but these cache lines are common to all lookups + * so will likely already be in the cache. + * - second step is to match at the record level (htnode/htkb level) once a + * slot-level match happens. Matching at this level implies the following match + * - the hash values (the full 64 bits vs. bucket+32 msb, above). + * - the name which, on the hash table side, is stored as a list of htkb_t (key buffers). * * Some hashtables (for which rare false positives are tolerable) store hash * values but no keys. (In ISM NDN forwarder, this was used for dcm_dpf: data @@ -73,6 +61,15 @@ * are used (or even allocated at hash table creation). */ +/* Handy abbreviations for success status, and for boolean values */ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + #define HICN_HASH_INVALID_IDX ~0 /* * for hicn_hashtb_next_node() iterator, this otherwise illegal context value diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h index 6911cc5a9..3d980bd49 100644 --- a/hicn-plugin/src/hicn.h +++ b/hicn-plugin/src/hicn.h @@ -39,6 +39,10 @@ #include <vnet/ip/ip4_packet.h> #include <vnet/buffer.h> +/** + * @file + */ + /* Helper for avoiding warnings about type-punning */ #define UNION_CAST(x, destType) \ (((union {__typeof__(x) a; destType b;})x).b) diff --git a/hicn-plugin/src/hicn_api.h b/hicn-plugin/src/hicn_api.h index 6eecadf34..ec10a6bbd 100644 --- a/hicn-plugin/src/hicn_api.h +++ b/hicn-plugin/src/hicn_api.h @@ -16,6 +16,11 @@ #ifndef __HICN_API_H__ #define __HICN_API_H__ +/** + * @file + */ + + #define HICN_STRATEGY_NULL ~0 #define HICN_FIB_TABLE 10 diff --git a/hicn-plugin/src/hicn_msg_enum.h b/hicn-plugin/src/hicn_msg_enum.h index 291e6226c..fcf2a1e87 100644 --- a/hicn-plugin/src/hicn_msg_enum.h +++ b/hicn-plugin/src/hicn_msg_enum.h @@ -18,6 +18,9 @@ #include <vppinfra/byte_order.h> +/** + * @file + */ #define vl_msg_id(n, h) n, typedef enum { diff --git a/hicn-plugin/src/infra.h b/hicn-plugin/src/infra.h index 007cf266d..9dc77c9e8 100644 --- a/hicn-plugin/src/infra.h +++ b/hicn-plugin/src/infra.h @@ -22,8 +22,12 @@ #include "pcs.h" /** - * hICN plugin global state: see also - * - fib and pits + * @file infra.h + * + */ + +/** + * @brief hICN plugin global state. */ typedef struct hicn_main_s { diff --git a/hicn-plugin/src/interest_hitcs.h b/hicn-plugin/src/interest_hitcs.h index b568a9290..94fa3e6f5 100644 --- a/hicn-plugin/src/interest_hitcs.h +++ b/hicn-plugin/src/interest_hitcs.h @@ -21,6 +21,16 @@ #include "pcs.h" +/** + * @file interest_hitcs.h + * + * This is the node encoutered by interest packets after the hicn-interest-pcslookup. + * This node satisfies an interest with a data stored in the CS and send the data back + * from the incoming iface of the interest (i.e., the vlib buffer is sent to the + * hicn6-iface-output or hicn4-iface-output node). In case the data is expired, the + * vlib buffer is sent to the hicn-strategy node. + */ + /* * Node context data; we think this is per-thread/instance */ diff --git a/hicn-plugin/src/interest_hitpit.h b/hicn-plugin/src/interest_hitpit.h index f26a25afa..ffdc61c8f 100644 --- a/hicn-plugin/src/interest_hitpit.h +++ b/hicn-plugin/src/interest_hitpit.h @@ -21,6 +21,17 @@ #include "pcs.h" +/** + * @file interest_hitpit.h + * + * This is the node encoutered by interest packets after the hicn-interest-pcslookup. + * This node aggregates an interest in the PIT or forward it in case of a retransmission. + * If the interest must be retransmitted the next vlib node will be on of the + * hicn6-face-output or hicn4-face-output nodes. If the pit entry is expired the next vlib node + * will be the hicn-strategy node, otherwise the vlib buffer is dropped. + */ + + /* * Node context data; we think this is per-thread/instance */ diff --git a/hicn-plugin/src/interest_pcslookup.h b/hicn-plugin/src/interest_pcslookup.h index 5a5a6a7a8..cbc9dde51 100644 --- a/hicn-plugin/src/interest_pcslookup.h +++ b/hicn-plugin/src/interest_pcslookup.h @@ -21,6 +21,17 @@ #include "pcs.h" +/** + * @file interest_pcslookup.h + * + * This is the node encoutered by interest packets after the hicn6-iface-input or + * hicn4-iface-input. This node performs a lookup in the pit and content store and + * if there is a hit in the PIT, the vlib buffer is passed to the hicn-interest-hitcs + * while if there is a hit in the CS the vlib buffer is passed to the + * hicn-interest-hitpit. If there isn't any hit, the vlib buffer is passed to the + * hicn-strategy node. + */ + /* * Node context data; we think this is per-thread/instance */ diff --git a/hicn-plugin/src/mapme_ack.h b/hicn-plugin/src/mapme_ack.h index 98a219982..821baf203 100644 --- a/hicn-plugin/src/mapme_ack.h +++ b/hicn-plugin/src/mapme_ack.h @@ -24,6 +24,11 @@ #include <vlib/vlib.h> #include <vnet/vnet.h> +/** + * @file + * + */ + /* Node context data */ typedef struct hicn_mapme_ack_runtime_s { diff --git a/hicn-plugin/src/mapme_ctrl.h b/hicn-plugin/src/mapme_ctrl.h index a69dfe1fc..9af4beccc 100644 --- a/hicn-plugin/src/mapme_ctrl.h +++ b/hicn-plugin/src/mapme_ctrl.h @@ -24,6 +24,11 @@ #include <vlib/vlib.h> #include <vnet/vnet.h> +/** + * @file mapme_ctrl.h + * + */ + /* Node context data */ typedef struct hicn_mapme_ctrl_runtime_s { diff --git a/hicn-plugin/src/mapme_eventmgr.h b/hicn-plugin/src/mapme_eventmgr.h index 84c57b50f..b63d16805 100644 --- a/hicn-plugin/src/mapme_eventmgr.h +++ b/hicn-plugin/src/mapme_eventmgr.h @@ -16,6 +16,12 @@ #include <vlib/vlib.h> // vlib_node_registration_t (vlib/node.h) #include <hicn/name.h> + +/** + * @file mapme_eventmgr.h + * + */ + /* * Structure carrying all necessary information for managing Special Interest * (re)transmissions. diff --git a/hicn-plugin/src/mgmt.h b/hicn-plugin/src/mgmt.h index 326922a01..6db0fe0c1 100644 --- a/hicn-plugin/src/mgmt.h +++ b/hicn-plugin/src/mgmt.h @@ -20,6 +20,11 @@ #include "faces/face.h" #include "hicn_api.h" +/** + * @file mgmt.h + * + */ + typedef struct icn_stats_s { u32 pkts_processed; diff --git a/hicn-plugin/src/params.h b/hicn-plugin/src/params.h index d8e4dc247..606d50771 100644 --- a/hicn-plugin/src/params.h +++ b/hicn-plugin/src/params.h @@ -18,6 +18,12 @@ #include <math.h> +/** + * @file params.h + * + */ + + /* * Features */ diff --git a/hicn-plugin/src/parser.h b/hicn-plugin/src/parser.h index 0d72780ae..e79d65831 100644 --- a/hicn-plugin/src/parser.h +++ b/hicn-plugin/src/parser.h @@ -21,6 +21,9 @@ #include "hicn.h" #include "error.h" +/** + * @file parser.h + */ /* * Key type codes for header, header tlvs, body tlvs, and child tlvs @@ -33,6 +36,15 @@ enum hicn_pkt_type_e HICN_PKT_TYPE_CONTENT = 1, }; +/** + * @brief Parse an interest packet + * + * @param pkt vlib buffer holding the interest + * @param name return variable that will point to the hicn name + * @param namelen return valiable that will hold the length of the name + * @param pkt_hdrp return valiable that will point to the packet header + * @param isv6 return variable that will be equale to 1 is the header is ipv6 + */ always_inline int hicn_interest_parse_pkt (vlib_buffer_t * pkt, hicn_name_t * name, u16 * namelen, hicn_header_t ** pkt_hdrp, u8 * isv6) @@ -61,6 +73,15 @@ hicn_interest_parse_pkt (vlib_buffer_t * pkt, hicn_name_t * name, return HICN_ERROR_NONE; } +/** + * @brief Parse a data packet + * + * @param pkt vlib buffer holding the interest + * @param name return variable that will point to the hicn name + * @param namelen return valiable that will hold the length of the name + * @param pkt_hdrp return valiable that will point to the packet header + * @param isv6 return variable that will be equale to 1 is the header is ipv6 + */ always_inline int hicn_data_parse_pkt (vlib_buffer_t * pkt, hicn_name_t * name, u16 * namelen, hicn_header_t ** pkt_hdrp, u8 * isv6) diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h index 1d99136a2..a9e1ae5a0 100644 --- a/hicn-plugin/src/pcs.h +++ b/hicn-plugin/src/pcs.h @@ -22,8 +22,17 @@ #include "error.h" #include "cache_policies/cs_policy.h" #include "faces/face.h" -#include "faces/dpo_face.h" -//#include "faces/app/face_prod.h" + +/** + * @file pcs.h + * + * This file implement the PIT and CS which are collapsed in the same + * structure, thereore an entry is either a PIT entry of a CS entry. + * The implementation consist of a hash table where each entry of the + * hash table contains a PIT or CS entry, some counters to maintain the + * status of the PIT/CS and the reference to the eviction policy for + * the CS. The default eviction policy id FIFO. + */ /* The PIT and CS are stored as a union */ #define HICN_PIT_NULL_TYPE 0 @@ -32,7 +41,7 @@ /* * Definitions and Forward refs for the time counters we're trying out. - * Counters are maintained by the background process. + * Counters are maintained by the background process. TODO. */ #define SEC_MS 1000 #define HICN_INFRA_FAST_TIMER_SECS 1 @@ -41,8 +50,7 @@ #define HICN_INFRA_SLOW_TIMER_MSECS (HICN_INFRA_SLOW_TIMER_SECS * SEC_MS) /* - * Max number of incoming (interest) faces supported, for now. Note that - * changing this may change alignment within the PIT struct, so be careful. + * Note that changing this may change alignment within the PIT struct, so be careful. */ typedef struct __attribute__ ((packed)) hicn_pcs_shared_s { @@ -72,13 +80,11 @@ typedef struct __attribute__ ((packed)) hicn_pit_entry_s /* * Egress next hop (containes the egress face) This id refers to the - * nh - */ - /* choosen in the next_hops array of the dpo */ + * position of the choosen face in the next_hops array of the dpo */ /* 18B + 1B = 19B */ u8 pe_txnh; - /* Array of faces */ + /* Array of incoming ifaces */ /* 24B + 32B (8B*4) =56B */ hicn_face_db_t faces; @@ -101,12 +107,6 @@ typedef struct __attribute__ ((packed)) hicn_cs_entry_s /* Ingress face */ /* 24B + 4B = 28B */ hicn_face_id_t cs_rxface; - /* //Fix alignment issues */ - /* union */ - /* { */ - /* dpo_id_t cs_rxface; */ - /* u64 cs_rxface_u64; */ - /* }; */ /* Linkage for LRU, in the form of hashtable node indexes */ /* 28B + 8B = 36B */ diff --git a/hicn-plugin/src/pg.h b/hicn-plugin/src/pg.h index 9ec3eeabc..84a391d43 100644 --- a/hicn-plugin/src/pg.h +++ b/hicn-plugin/src/pg.h @@ -18,7 +18,7 @@ /** - * @File Packet generator for hICN + * @file pg.h * * The packet generator is made of two entities, a client and a server. * The client issues interests at high speed and the server satisfy each diff --git a/hicn-plugin/src/route.h b/hicn-plugin/src/route.h index 4918f275b..a1ba86b3d 100644 --- a/hicn-plugin/src/route.h +++ b/hicn-plugin/src/route.h @@ -21,19 +21,54 @@ #include "hicn.h" #include "faces/face.h" +/** + * @file route.h + * + * hICN uses a specific vrf to install the routes for a prefix has been enabled to + * be hicn. It considers the vrf 0 (the default vrf) as the dominating vrf on + * which every route is stored. Enabling a prefix to be hICN will copy all the routes + * in the vrf 0 for the given prefi, in the vrf HICN. Every modification made on the + * vrf 0 on an hICN enabled prefix is reflected in the vrf hICN (through the use of + * the fib entry tracking functionality). Moreover, we use the lookup in the vrf hICN + * as a way for punting packet that must be processed as hICN. The implementation will + * install a special dpo as a single next hop for the vpp load balancer for each entry + * in the vrf hICN that we enabled. Such dpo will have two purposes: 1) to punt packets + * to the hICN forwarding pipeline, 2) to point to the righe strategy (the dpoi_index will + * be an index to the strategy context while the dpoi_type will be an index to the strategy vft). + * + * Additionally, hICN assign each interface to the vrf hICN; this is required for + * the interest lookup. Vpp performs a lookup in the vrf assigned to the interface, + * therefore if an interface is not assigned to the hICN vrf, the lookup will be done + * on the vrf 0 and the packet won't be processed through the hicn forwarding pipeline. + */ + +/* + * Adding each interface to the vrf hICN has the side effect that to ping you need to + * specify the vrf hICN in the command. + */ + extern fib_source_t hicn_fib_src; extern dpo_type_t udp_encap_dpo_types[FIB_PROTOCOL_MAX]; -/* - * Retrieve the hicn dpo corresponding to a hicn prefix +/** + * @Brief Return the hicn_dpo corresponding to the prefix in teh vrf HICN + * + * @param prefix Prefix for which we want to retrieve the hICN dpo + * @param hicn_dpo return value with the hicn_dpo + * @param fib_index return value with the fib index corresponding to the prefix */ int hicn_route_get_dpo (const fib_prefix_t * prefix, const dpo_id_t ** hicn_dpo, u32 * fib_index); -/* Remove a next hop route for a name prefix */ +/** + * @Brief Set the strategy for a given prefix + * + * @param prefix Prefix for which we set the strategy + * @param stretegy_id Index of the strategy to set + */ int hicn_route_set_strategy (fib_prefix_t * prefix, u32 strategy_id); @@ -61,9 +96,24 @@ ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * pfx, ip46_addre int ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if); +/** + * @Brief Enable an hICN for an ip prefix + * + * @param prefix Prefix for which we enable hICN + * @return HICN_ERROR_NONE if hICN was enabled on the prefix + * HICN_ERROR_ROUTE_NO_LD if the first dpo for the fib entry corresponding to the prefix is not a load_balancer + * HICN_ERROR_ROUTE_DPO_NO_HICN if the loadbalancer in the vrf HICN already contains a dpo which is not an hICN one + * HICN_ERROR_ROUTE_MLT_LD if there are more than a dpo in the vpp loadbalancer + */ int hicn_route_enable (fib_prefix_t *prefix); +/** + * @Brief Disable an hICN for an ip prefix. If hICN wasn't enable on the prefix + * nothing happens and it returns HICN_ERROR_ROUTE_NOT_FOUND + * + * @param prefix Prefix for which we disable hICN + */ int hicn_route_disable (fib_prefix_t *prefix); diff --git a/hicn-plugin/src/state.h b/hicn-plugin/src/state.h index 7e984e6c3..37003d0ae 100644 --- a/hicn-plugin/src/state.h +++ b/hicn-plugin/src/state.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -26,26 +26,26 @@ #include "strategy_dpo_ctx.h" #include "strategy_dpo_manager.h" -always_inline void -hicn_prefetch_pcs_entry (hicn_buffer_t * hicnb, hicn_pit_cs_t * pitcs) -{ - hicn_hash_node_t *node = pool_elt_at_index (pitcs->pcs_table->ht_nodes, - hicnb->node_id); - - hicn_hash_bucket_t *bucket; - if (hicnb->hash_bucket_flags & HICN_HASH_NODE_OVERFLOW_BUCKET) - bucket = - pool_elt_at_index (pitcs->pcs_table->ht_overflow_buckets, - hicnb->bucket_id); - else - bucket = - (hicn_hash_bucket_t *) (pitcs->pcs_table->ht_buckets + - hicnb->bucket_id); +/** + * @file plugin_state + * + * Helper functions to hicn state (hash node, hash entry, strategy vft, dpo vft and dpo context id) + * + */ - CLIB_PREFETCH (node, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (bucket, CLIB_CACHE_LINE_BYTES, STORE); -} +//TODO exploit this state to prefetch hash nodes and entries. +/** + * @brief Retrieve the hicn state + * + * @param hicnb hicn buffer used to retrieve the hicn state + * @param pitcs pointer to PIT/CS + * @param node node in the hash table referring to the buffer + * @param strategy_vft return value pointing to the strategy vft corresponding to the buffer + * @param dpo_vft return value pointing to the dpo vft corresponding to the buffer + * @param dpo_ctx_id return value pointing to the dpo context id corresponding to the buffer + * @param hash_entry entry in the hash table referring to the buffer + */ always_inline void hicn_get_internal_state (hicn_buffer_t * hicnb, hicn_pit_cs_t * pitcs, hicn_hash_node_t ** node, @@ -77,6 +77,19 @@ hicn_get_internal_state (hicn_buffer_t * hicnb, hicn_pit_cs_t * pitcs, * nodes can prefetch the corresponding state (PIT entry, dpo_ctx and the * strategy vft */ +/** + * @brief Store the hicn state in the hicn buffer + * + * @param b vlib buffer holding the hICN packet + * @param name_hash hash of the hICN name + * @param node_id id of the node in the hash table referring to the buffer + * @param dpo_ctx_id id of the dpo context id corresponding to the buffer + * @param vft_id id of the strategy vft corresponding to the buffer + * @param hash_entry_id id of the entry in the hash table referring to the buffer + * @param bucket_id id of the hasth table bucket that holds the hash entry + * @param bucket_is_overflow 1 if the bucket is from the ht_overflow_buckets pool + * 0 if the bucket is from the ht_buckets pool + */ always_inline void hicn_store_internal_state (vlib_buffer_t * b, u64 name_hash, u32 node_id, u8 dpo_ctx_id, u8 vft_id, u8 hash_entry_id, diff --git a/hicn-plugin/src/strategies/dpo_mw.h b/hicn-plugin/src/strategies/dpo_mw.h index 887c7003a..433c415fb 100644 --- a/hicn-plugin/src/strategies/dpo_mw.h +++ b/hicn-plugin/src/strategies/dpo_mw.h @@ -19,6 +19,14 @@ #include <vnet/dpo/dpo.h> #include "../strategy_dpo_ctx.h" +/** + * @file dpo_mw.h + * + * This file implements the strategy vtf (see strategy.h) and + * the dpo vft (see strategy_dpo_manager.h) for the strategy + * maximum weight + */ + #define DEFAULT_WEIGHT 0 typedef struct hicn_strategy_mw_ctx_s diff --git a/hicn-plugin/src/strategies/dpo_rr.h b/hicn-plugin/src/strategies/dpo_rr.h index e80c0302a..e4e5b5372 100644 --- a/hicn-plugin/src/strategies/dpo_rr.h +++ b/hicn-plugin/src/strategies/dpo_rr.h @@ -20,6 +20,15 @@ #include "../strategy_dpo_ctx.h" /** + * @file dpo_rr.h + * + * This file implements the strategy vtf (see strategy.h) and + * the dpo vft (see strategy_dpo_manager.h) for the strategy + * round robin. + */ + + +/** * Context for the Round Robin strategy */ diff --git a/hicn-plugin/src/strategies/strategy_mw.h b/hicn-plugin/src/strategies/strategy_mw.h index f64f1fdc7..9e0078b23 100644 --- a/hicn-plugin/src/strategies/strategy_mw.h +++ b/hicn-plugin/src/strategies/strategy_mw.h @@ -19,6 +19,13 @@ #include "../strategy.h" /** + * @file strategy_mw.h + * + * This file implements the maximum weight strategy. In this + * strategy the choosen next hop is one with the maximum weight. + */ + +/** * @brief Return the vft for the Maximum Weight strategy */ hicn_strategy_vft_t *hicn_mw_strategy_get_vft (void); diff --git a/hicn-plugin/src/strategies/strategy_rr.h b/hicn-plugin/src/strategies/strategy_rr.h index 3936845fe..4dfe76b43 100644 --- a/hicn-plugin/src/strategies/strategy_rr.h +++ b/hicn-plugin/src/strategies/strategy_rr.h @@ -19,6 +19,13 @@ #include "../strategy.h" /** + * @file strategy_rr.h + * + * This file implements the round robin strategy. In this + * strategy the next hop is choosen in a round robin way. + */ + +/** * @brief Return the vft for the Round Robin strategy */ hicn_strategy_vft_t *hicn_rr_strategy_get_vft (void); diff --git a/hicn-plugin/src/strategy.h b/hicn-plugin/src/strategy.h index a63db84d4..d949f38a4 100644 --- a/hicn-plugin/src/strategy.h +++ b/hicn-plugin/src/strategy.h @@ -22,21 +22,20 @@ #include "faces/face.h" /** - * @File + * @file strategy.h * * A strategy is defined as a dpo and a set of function (vft) that will be called * during the packet processing. A strategy is associated to an entry in the fib by * assigning the corresponding dpo to the fib entry. The dpo points to a hICN dpo * context (ctx) which contains the information needed by the strategy to compute * the next hop. Each strategy hash its own dpo type, which means that the dpo_type - * uniquely identify a strategy and its vft. The strategy node will use the dpo_type + * uniquely identifies a strategy and its vft. The strategy node will use the dpo_type * to retrieve the corresponding vft. * Here we provide: * - a template for the callbacks to implement in order to create a new strategy * (hicn_fwd_strategy_t) - * - the base structure for a strategy node - * (list of next vpp nodes, errors, tracing and the main function processing an - * interest and calling hicn_select_next_hop) + * - a default implementation for the strategy node which will call the strategy + * functions while processing the interest packets */ /* Trace context struct */ @@ -70,6 +69,25 @@ typedef enum HICN_STRATEGY_N_NEXT, } hicn_strategy_next_t; +const static char *const hicn_ip6_nodes[] = +{ + "hicn6-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE + NULL, +}; + +const static char *const hicn_ip4_nodes[] = +{ + "hicn4-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE + NULL, +}; + +const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] = +{ + [DPO_PROTO_IP6] = hicn_ip6_nodes, + [DPO_PROTO_IP4] = hicn_ip4_nodes, +}; + + extern vlib_node_registration_t hicn_strategy_node; #endif /* //__HICN_STRATEGY__ */ diff --git a/hicn-plugin/src/strategy_dpo_ctx.h b/hicn-plugin/src/strategy_dpo_ctx.h index 54a339573..214ed88ad 100644 --- a/hicn-plugin/src/strategy_dpo_ctx.h +++ b/hicn-plugin/src/strategy_dpo_ctx.h @@ -22,6 +22,18 @@ #include "params.h" #include "faces/face.h" +/** + * @file strategy_dpo_ctx.h + * + * This file implements the general hICN DPO ctx (shared among all the strategies). + * + * An hICN DPO ctx contains the list of next hops, auxiliaries fields to maintain the dpo, map-me + * specifics (tfib_entry_count and seq), the dpo_type and 64B to let each strategy to store additional + * information. Each next hop is an hicn_face_id_t that refers to an index for an hICN face. The + * dpo_type is used to identify the strategy and to retrieve the vft corresponding to the strategy + * (see strategy.h) and to the dpo ctx (see strategy_dpo_manager.h) + */ + //FIB table for hicn. 0 is the default one used by ip #define HICN_FIB_TABLE 10 @@ -29,15 +41,6 @@ #define INIT_SEQ 0 -/** - * @brief Definition of the general hICN DPO ctx (shared among all the strategies). - * - * An hICN DPO ctx contains the list of next hops, auxiliaries fields to maintain the dpo, map-me - * specifics (tfib_entry_count and seq), the dpo_type and 64B to let each strategy to store additional - * information. Each next hop is a dpo_id_t that refers to an hICN face. The dpo_type is used to - * identify the strategy and to retrieve the vft corresponding to the strategy (see strategy.h) - * and to the dpo ctx (see strategy_dpo_manager.h) - */ typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s { CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); diff --git a/hicn-plugin/src/strategy_dpo_manager.h b/hicn-plugin/src/strategy_dpo_manager.h index eaec252b7..e96e050d9 100644 --- a/hicn-plugin/src/strategy_dpo_manager.h +++ b/hicn-plugin/src/strategy_dpo_manager.h @@ -20,10 +20,26 @@ #include "strategy.h" /** + * @file strategy_dpo_manager.h + * + * This file implements structs and helper functions to manipulate hICN dpo. + * An hICN DPO is a combination of: + * - a hICN DPO ctx (context) that holds the structure containing the + * information to choose the next hop, + * - a dpo vft that specify how to update the hICN DPO ctx when a next hop is + * added, deleted or updated, + * - a strategy containing (see strategy.h): (i) the vpp node that processes Interest packets + * subjected to such strategy, (ii) the definition of the vft that defines + * the hICN strategy functions + * An hICN DPO is places as the sole next hop in the vpp loadbalancer, and it containes + * a list of next hops that will be used by the associated strategy when forwarding + * interest packets. + */ + +/** * @brief Definition of the virtual function table for a hICN DPO. * - * An hICN dpo is a combination of a dpo context (hicn_dpo_ctx or struct that - * extends a hicn_dpo_ctx) and a strategy node. The following virtual function table + * The following virtual function table * template that glues together the fuction to interact with the context and the * creating the dpo */ @@ -48,37 +64,18 @@ typedef struct hicn_dpo_vft_s */ extern hicn_dpo_vft_t default_dpo; -const static char *const hicn_ip6_nodes[] = { - "hicn6-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE - NULL, -}; - -const static char *const hicn_ip4_nodes[] = { - "hicn4-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE - NULL, -}; - -const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] = { - [DPO_PROTO_IP6] = hicn_ip6_nodes, - [DPO_PROTO_IP4] = hicn_ip4_nodes, -}; - /** * @brief Register a new hICN dpo to the manager. * - * An hICN DPO is a combination of: - * - a hICN DPO ctx (context) that holds the structure containing the - * information to choose the next hop, - * - a strategy containing: (i) the vpp node that processes Interest packets - * subjected to such strategy, (ii) the definition of the vft that defines - * the hICN strategy functions - * Registering a hICN DPO allows the plugin to be aware of the new dpo an be - * able to apply it to the FIB entries. + * Registering a hICN DPO allows the plugin to be aware of the new dpo an be + * able to apply it to the FIB entries. * * @param hicn_nodes A list of vpp to which pass an interest that matches with * the FIB entry to which the hICN DPO is applied. This list must contain the * name of the strategy node (or nodes in case of differentiation between IPv4 - * and IPv6). + * and IPv6). Unless really needed otherwise (i.e., different implementation of + * iface input), the list of node to use should be one provided in the strategy.h + * (hicn_nodes_strategy) * @param hicn_dpo_vft The structure holding the virtual function table to * interact with the hICN dpo and its context. * @param hicn_strategy_vft The structure holding the virtual function table diff --git a/hicn-plugin/src/strategy_node.c b/hicn-plugin/src/strategy_node.c index 578ba2c4f..0659a871a 100644 --- a/hicn-plugin/src/strategy_node.c +++ b/hicn-plugin/src/strategy_node.c @@ -130,6 +130,7 @@ hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0, vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface; stats->pkts_interest_count++; + pitp->u.pit.pe_txnh = nh_idx; } else { diff --git a/hicn-plugin/src/udp_tunnels/udp_decap.h b/hicn-plugin/src/udp_tunnels/udp_decap.h index adbec3f03..9ddb8a73b 100644 --- a/hicn-plugin/src/udp_tunnels/udp_decap.h +++ b/hicn-plugin/src/udp_tunnels/udp_decap.h @@ -13,4 +13,20 @@ * limitations under the License. */ +#ifndef __UDP_DECAP_H__ +#define __UDP_DECAP_H__ + +/** + * @file udp_decap.h + * + * Implements the udp decapsulation for udp tunnels + * + * Udp decap nodes follow the ip4/6-local nodes and their purpose + * is to retrieve the udp tunnel for the incoming packet. If a tunnel does + * not exist the packet is dropped. + * The following node to the udp decap nodes are the ip4/6-lookup nodes. + */ + extern vlib_node_registration_t udp_decap_node; + +#endif // __UDP_DECAP_H__ diff --git a/hicn-plugin/src/udp_tunnels/udp_decap_node.c b/hicn-plugin/src/udp_tunnels/udp_decap_node.c index 6a5831c2b..5603f20f9 100644 --- a/hicn-plugin/src/udp_tunnels/udp_decap_node.c +++ b/hicn-plugin/src/udp_tunnels/udp_decap_node.c @@ -19,12 +19,6 @@ #include "../hicn.h" #include "../strategy_dpo_ctx.h" -/** - * @File - * - * Definition of the nodes for ip incomplete faces. - */ - vlib_node_registration_t udp_decap_node; static char *udp_decap_error_strings[] = { diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.h b/hicn-plugin/src/udp_tunnels/udp_tunnel.h index 8f38a47e4..2ec92056c 100644 --- a/hicn-plugin/src/udp_tunnels/udp_tunnel.h +++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.h @@ -20,6 +20,17 @@ #include <vppinfra/error.h> #include <vnet/udp/udp_encap.h> +/** + * @file udp_tunnel.h + * + * This file implements bidirectional udp tunnels. Udp tunnels exploit + * the udp encap functionality in vpp. In particular, a udp tunnel creates + * an udp encap object with the information for encapsulating packets and it + * implements the udp decap node. The udp decap node checks if a udp tunnel exists + * before performing the decapsulation. If the tunnel does not exist the packet + * is dropped. + */ + #define UDP_TUNNEL_INVALID ~0 extern dpo_type_t dpo_type_udp_ip4; @@ -28,7 +39,19 @@ extern dpo_type_t dpo_type_udp_ip6; extern vlib_node_registration_t udp4_decap_node; extern vlib_node_registration_t udp6_decap_node; - +/** + * @brief Create a udp tunnel + * + * @param proto FIB_PROTOCOL_IP4 or FIB_PROTOCOL_IP6 + * @param fib_index fib index to add to the udp encap + * @param src_ip source address of the tunnel + * @param dst_ip destination address of the tunnel + * @param src_port source port + * @param src_port destination port + * @param flags flags for the udp encap + * + * @return return the id of the tunnel + */ u32 udp_tunnel_add (fib_protocol_t proto, index_t fib_index, const ip46_address_t * src_ip, @@ -37,11 +60,35 @@ u32 udp_tunnel_add (fib_protocol_t proto, u16 dst_port, udp_encap_fixup_flags_t flags); +/** + * @brief Retrieve the index of a udp tunnel (same id of the udp encap) + * + * @param src_ip source address of the tunnel + * @param dst_ip destination address of the tunnel + * @param src_port source port + * @param src_port destination port + * + * @return id of the udp tunnel/encap + */ u32 udp_tunnel_get(const ip46_address_t * src_ip, const ip46_address_t * dst_ip, u16 src_port, u16 dst_port); +/** + * @brief Delete a udp tunnel + * + * @param proto FIB_PROTOCOL_IP4 or FIB_PROTOCOL_IP6 + * @param fib_index fib index to add to the udp encap + * @param src_ip source address of the tunnel + * @param dst_ip destination address of the tunnel + * @param src_port source port + * @param src_port destination port + * @param flags flags for the udp encap + * + * @return HICN_ERROR_UDP_TUNNEL_NOT_FOUND if the tunnel was not found + * or HICN_ERROR_NONE if the tunnel has been deleted + */ int udp_tunnel_del (fib_protocol_t proto, index_t fib_index, const ip46_address_t * src_ip, @@ -50,8 +97,18 @@ int udp_tunnel_del (fib_protocol_t proto, u16 dst_port, udp_encap_fixup_flags_t flags); +/** + * @brief Add a udp tunnel from an existing udp encap + * + * @param uei index of the udp encap object + * @param proto DPO_PROTO_IP6 or DPO_PROTO_IP4 + */ void udp_tunnel_add_existing (index_t uei, dpo_proto_t proto); +/** + * @brief Init the udp tunnel module + * + */ void udp_tunnel_init(); #endif diff --git a/hicn-plugin/src/utils.h b/hicn-plugin/src/utils.h index ecad47e9b..689942ab6 100644 --- a/hicn-plugin/src/utils.h +++ b/hicn-plugin/src/utils.h @@ -18,6 +18,17 @@ #include "hicn.h" +/** + * @file + * + * Helpers to print hicn headers + */ + +/** + * @Brief Print the hicn name + * + * @param name hicn name to print + */ always_inline void hicn_print_name6 (hicn_name_t * name) { @@ -29,6 +40,11 @@ hicn_print_name6 (hicn_name_t * name) printf ("%s\n", s0); } +/** + * @Brief Print the ipv6 hicn header (src and dst address and port) + * + * @param hicn0 hICN header to print + */ always_inline void hicn_print6 (hicn_header_t * hicn0) { @@ -43,6 +59,11 @@ hicn_print6 (hicn_header_t * hicn0) vlib_cli_output (vm, "%s\n", s0); } +/** + * @Brief Print the ipv4 hicn header (src and dst address and port) + * + * @param hicn0 hICN header to print + */ always_inline void hicn_print4 (hicn_header_t * hicn0) { |