aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin
diff options
context:
space:
mode:
Diffstat (limited to 'hicn-plugin')
-rw-r--r--hicn-plugin/src/CMakeLists.txt45
-rw-r--r--hicn-plugin/src/cache_policies/cs_lru.h9
-rw-r--r--hicn-plugin/src/cache_policies/cs_policy.h16
-rw-r--r--hicn-plugin/src/cli.c237
-rw-r--r--hicn-plugin/src/data_fwd.h28
-rw-r--r--hicn-plugin/src/data_fwd_node.c60
-rw-r--r--hicn-plugin/src/data_input_node.c4
-rw-r--r--hicn-plugin/src/data_pcslookup.h12
-rw-r--r--hicn-plugin/src/data_pcslookup_node.c26
-rw-r--r--hicn-plugin/src/data_push_node.c326
-rw-r--r--hicn-plugin/src/error.h14
-rw-r--r--hicn-plugin/src/face_db.h30
-rw-r--r--hicn-plugin/src/faces/app/address_mgr.c20
-rw-r--r--hicn-plugin/src/faces/app/face_app_cli.c7
-rw-r--r--hicn-plugin/src/faces/app/face_cons.c18
-rw-r--r--hicn-plugin/src/faces/app/face_prod.c183
-rw-r--r--hicn-plugin/src/faces/app/face_prod.h13
-rw-r--r--hicn-plugin/src/faces/app/face_prod_node.c6
-rw-r--r--hicn-plugin/src/faces/face.c423
-rw-r--r--hicn-plugin/src/faces/face.h629
-rw-r--r--hicn-plugin/src/faces/face_cli.c20
-rw-r--r--hicn-plugin/src/faces/face_node.c (renamed from hicn-plugin/src/faces/ip/face_ip_node.c)469
-rw-r--r--hicn-plugin/src/faces/face_node.h52
-rw-r--r--hicn-plugin/src/faces/iface_node.c (renamed from hicn-plugin/src/faces/ip/iface_ip_node.c)434
-rw-r--r--hicn-plugin/src/faces/iface_node.h54
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.c90
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.h288
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.c571
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.h310
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_cli.c208
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_node.h40
-rw-r--r--hicn-plugin/src/faces/udp/dpo_udp.c157
-rw-r--r--hicn-plugin/src/faces/udp/dpo_udp.h289
-rw-r--r--hicn-plugin/src/faces/udp/face_udp.c449
-rw-r--r--hicn-plugin/src/faces/udp/face_udp.h356
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_cli.c164
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_node.c1030
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_node.h35
-rw-r--r--hicn-plugin/src/faces/udp/iface_udp_node.c987
-rw-r--r--hicn-plugin/src/faces/udp/iface_udp_node.h36
-rw-r--r--hicn-plugin/src/hashtb.h73
-rw-r--r--hicn-plugin/src/hicn.api295
-rw-r--r--hicn-plugin/src/hicn.c51
-rw-r--r--hicn-plugin/src/hicn.h15
-rw-r--r--hicn-plugin/src/hicn_api.c475
-rw-r--r--hicn-plugin/src/hicn_api.h8
-rw-r--r--hicn-plugin/src/hicn_api_test.c659
-rw-r--r--hicn-plugin/src/hicn_msg_enum.h3
-rw-r--r--hicn-plugin/src/infra.h19
-rw-r--r--hicn-plugin/src/interest_hitcs.h16
-rw-r--r--hicn-plugin/src/interest_hitcs_node.c14
-rw-r--r--hicn-plugin/src/interest_hitpit.h15
-rw-r--r--hicn-plugin/src/interest_hitpit_node.c17
-rw-r--r--hicn-plugin/src/interest_pcslookup.h11
-rw-r--r--hicn-plugin/src/mapme.h125
-rw-r--r--hicn-plugin/src/mapme_ack.h5
-rw-r--r--hicn-plugin/src/mapme_ack_node.c13
-rw-r--r--hicn-plugin/src/mapme_ctrl.h44
-rw-r--r--hicn-plugin/src/mapme_ctrl_node.c82
-rw-r--r--hicn-plugin/src/mapme_eventmgr.c20
-rw-r--r--hicn-plugin/src/mapme_eventmgr.h10
-rw-r--r--hicn-plugin/src/mgmt.h5
-rw-r--r--hicn-plugin/src/params.h10
-rw-r--r--hicn-plugin/src/parser.h21
-rw-r--r--hicn-plugin/src/pcs.c3
-rw-r--r--hicn-plugin/src/pcs.h136
-rw-r--r--hicn-plugin/src/pg.h2
-rw-r--r--hicn-plugin/src/route.c784
-rw-r--r--hicn-plugin/src/route.h98
-rw-r--r--hicn-plugin/src/state.h51
-rw-r--r--hicn-plugin/src/strategies/dpo_mw.c26
-rw-r--r--hicn-plugin/src/strategies/dpo_mw.h12
-rw-r--r--hicn-plugin/src/strategies/dpo_rr.c25
-rw-r--r--hicn-plugin/src/strategies/dpo_rr.h15
-rw-r--r--hicn-plugin/src/strategies/strategy_mw.c22
-rw-r--r--hicn-plugin/src/strategies/strategy_mw.h7
-rw-r--r--hicn-plugin/src/strategies/strategy_mw_cli.c4
-rw-r--r--hicn-plugin/src/strategies/strategy_rr.c17
-rw-r--r--hicn-plugin/src/strategies/strategy_rr.h7
-rw-r--r--hicn-plugin/src/strategy.h32
-rw-r--r--hicn-plugin/src/strategy_dpo_ctx.c17
-rw-r--r--hicn-plugin/src/strategy_dpo_ctx.h64
-rw-r--r--hicn-plugin/src/strategy_dpo_manager.h55
-rw-r--r--hicn-plugin/src/strategy_node.c19
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_decap.h (renamed from hicn-plugin/src/faces/ip/iface_ip_node.h)29
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_decap_node.c623
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_tunnel.c281
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_tunnel.h114
-rw-r--r--hicn-plugin/src/utils.h21
89 files changed, 4487 insertions, 8128 deletions
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt
index 6852b95bb..ebe8f8713 100644
--- a/hicn-plugin/src/CMakeLists.txt
+++ b/hicn-plugin/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# 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:
@@ -75,20 +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/ip/face_ip.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip_cli.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/iface_ip_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/dpo_ip.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp_cli.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/iface_udp_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/dpo_udp.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.c
${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
@@ -104,6 +95,8 @@ set(HICN_PLUGIN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack_node.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl_node.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_decap_node.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.c
)
set(HICN_PLUGIN_HEADER_FILES
@@ -130,14 +123,9 @@ set(HICN_PLUGIN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/error.h
${CMAKE_CURRENT_SOURCE_DIR}/face_db.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/face.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/iface_ip_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/dpo_ip.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/iface_udp_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/dpo_udp.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_dpo.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.h
@@ -152,6 +140,7 @@ set(HICN_PLUGIN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack.h
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl.h
${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.h
)
set(HICN_API_TEST_SOURCE_FILES
@@ -165,7 +154,10 @@ set(HICN_API_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/error.h)
set(HICN_API_GENERATED_FILES
- ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h)
+ ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h
+ ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_types.h
+ ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_enum.h
+)
set(HICN_VAPI_GENERATED_FILES
${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.h
@@ -194,6 +186,8 @@ endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/hicn)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vapi)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp)
# These files are missing from vpp binary distribution
execute_process(
@@ -214,11 +208,18 @@ execute_process(
if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_format_fns.h ]; then
curl https://raw.githubusercontent.com/FDio/vpp/master/src/vnet/ip/ip_format_fns.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_format_fns.h;
fi;
+ if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib/fib_entry_track.h ]; then
+ curl https://raw.githubusercontent.com/FDio/vpp/master/src/vnet/fib/fib_entry_track.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib/fib_entry_track.h;
+ fi;
+ if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp/udp_encap.h ]; then
+ curl https://raw.githubusercontent.com/FDio/vpp/master/src/vnet/udp/udp_encap.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp/udp_encap.h;
+ fi;
+
chmod +x ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py"
)
add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_types.h ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_enum.h ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json
COMMAND ${VPP_HOME}/bin/vppapigen ARGS --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h --outputdir ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/
COMMAND ${VPP_HOME}/bin/vppapigen ARGS JSON --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json --outputdir ${CMAKE_CURRENT_BINARY_DIR}/vapi/
)
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/cli.c b/hicn-plugin/src/cli.c
index 15ea90c96..a555d7143 100644
--- a/hicn-plugin/src/cli.c
+++ b/hicn-plugin/src/cli.c
@@ -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:
@@ -39,7 +39,6 @@ static vl_api_hicn_api_node_params_set_t node_ctl_params = {
.pit_max_size = -1,
.pit_max_lifetime_sec = -1.0f,
.cs_max_size = -1,
- .cs_reserved_app = -1,
};
typedef enum
@@ -63,7 +62,7 @@ hicn_cli_node_ctl_start_set_command_fn (vlib_main_t * vm,
node_ctl_params.
pit_max_lifetime_sec,
node_ctl_params.cs_max_size,
- node_ctl_params.cs_reserved_app);
+ ~0);
vlib_cli_output (vm, "hicn: fwdr initialize => %s\n",
get_error_string (ret));
@@ -107,7 +106,7 @@ hicn_cli_node_ctl_stop_set_command_fn (vlib_main_t * vm,
node_ctl_params.
pit_max_lifetime_sec,
node_ctl_params.cs_max_size,
- node_ctl_params.cs_reserved_app);
+ ~0);
return (ret == HICN_ERROR_NONE) ? 0 : clib_error_return (0,
get_error_string
@@ -135,7 +134,6 @@ hicn_cli_node_ctl_param_set_command_fn (vlib_main_t * vm,
int table_size;
f64 lifetime;
- int cs_reserved_app;
if (hicn_main.is_enabled)
{
@@ -193,15 +191,6 @@ hicn_cli_node_ctl_param_set_command_fn (vlib_main_t * vm,
}
node_ctl_params.cs_max_size = table_size;
}
- else if (unformat (line_input, "app %d", &cs_reserved_app))
- {
- if (!DFLTD_RANGE_OK (cs_reserved_app, 0, 100))
- {
- rv = HICN_ERROR_CS_CONFIG_SIZE_OOB;
- break;
- }
- node_ctl_params.cs_reserved_app = cs_reserved_app;
- }
else
{
rv = HICN_ERROR_CLI_INVAL;
@@ -278,8 +267,7 @@ hicn_cli_show_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
{
if (node_ctl_params.pit_max_size == -1 &&
node_ctl_params.pit_max_lifetime_sec == -1 &&
- node_ctl_params.cs_max_size == -1 &&
- node_ctl_params.cs_reserved_app == -1)
+ node_ctl_params.cs_max_size == -1)
{
ret = HICN_ERROR_FWD_NOT_ENABLED;
goto done;
@@ -302,11 +290,6 @@ hicn_cli_show_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
vlib_cli_output (vm, " CS:: max entries:%d\n",
node_ctl_params.cs_max_size);
}
- if (node_ctl_params.cs_reserved_app != -1)
- {
- vlib_cli_output (vm, " CS:: reserved to app:%d\n",
- node_ctl_params.cs_reserved_app);
- }
goto done;
}
/* Globals */
@@ -314,16 +297,11 @@ hicn_cli_show_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
"Forwarder: %sabled\n"
" PIT:: max entries:%d,"
" lifetime default: max:%05.3f\n"
- " CS:: max entries:%d, network entries:%d, app entries:%d (allocated %d, free %d)\n",
+ " CS:: max entries:%d\n",
hicn_main.is_enabled ? "en" : "dis",
hicn_infra_pit_size,
((f64) hicn_main.pit_lifetime_max_ms) / SEC_MS,
- hicn_infra_cs_size,
- hicn_infra_cs_size - hicn_main.pitcs.pcs_app_max,
- hicn_main.pitcs.pcs_app_max,
- hicn_main.pitcs.pcs_app_count,
- hicn_main.pitcs.pcs_app_max -
- hicn_main.pitcs.pcs_app_count);
+ hicn_infra_cs_size);
vl_api_hicn_api_node_stats_get_reply_t rm = { 0, }
, *rmp = &rm;
@@ -388,17 +366,16 @@ done:
* cli handler for 'fib'
*/
static clib_error_t *
-hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
+hicn_cli_strategy_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
{
clib_error_t *cl_err = 0;
int rv = HICN_ERROR_NONE;
int addpfx = -1;
ip46_address_t address;
- hicn_face_id_t faceid = HICN_FACE_NULL;
u32 strategy_id;
- u8 plen = 0;
+ u32 plen = 0;
fib_prefix_t prefix;
/* Get a line of input. */
@@ -409,15 +386,7 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
}
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
- if (addpfx == -1 && unformat (line_input, "add"))
- {
- addpfx = 1;
- }
- else if (addpfx == -1 && unformat (line_input, "delete"))
- {
- addpfx = 0;
- }
- else if (unformat (line_input, "set strategy %d", &strategy_id))
+ if (unformat (line_input, "set %d", &strategy_id))
{
addpfx = 2;
}
@@ -426,9 +395,6 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
&address, IP46_TYPE_ANY, &plen))
{;
}
- else if (addpfx <= 1 && unformat (line_input, "face %u", &faceid))
- {;
- }
else
{
cl_err = clib_error_return (0, "%s '%U'",
@@ -441,63 +407,18 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
fib_prefix_from_ip46_addr (&address, &prefix);
prefix.fp_len = plen;
/* Check parse */
- if (addpfx <= 1
- && ((ip46_address_is_zero (&prefix.fp_addr))
- || faceid == HICN_FACE_NULL))
- {
- cl_err =
- clib_error_return (0, "Please specify prefix and a valid faceid...");
- goto done;
- }
- /* Check parse */
- if ((ip46_address_is_zero (&prefix.fp_addr))
- || (addpfx == 2 && hicn_dpo_strategy_id_is_valid (strategy_id)))
+ if (hicn_dpo_strategy_id_is_valid (strategy_id) == HICN_ERROR_DPO_MGR_ID_NOT_VALID)
{
cl_err = clib_error_return (0,
- "Please specify prefix and strategy_id...");
+ "Please specify a valid strategy...");
goto done;
}
- if (addpfx == 0)
- {
- if (ip46_address_is_zero (&prefix.fp_addr))
- {
- cl_err = clib_error_return (0, "Please specify prefix");
- goto done;
- }
- if (faceid == HICN_FACE_NULL)
- {
- rv = hicn_route_del (&prefix);
- }
- else
- {
- rv = hicn_route_del_nhop (&prefix, faceid);
- }
- cl_err =
- (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
- get_error_string
- (rv));
- }
- else if (addpfx == 1)
- {
- rv = hicn_route_add (&faceid, 1, &prefix);
- if (rv == HICN_ERROR_ROUTE_ALREADY_EXISTS)
- {
- rv = hicn_route_add_nhops (&faceid, 1, &prefix);
- }
- cl_err =
- (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
- get_error_string
- (rv));
- }
- else if (addpfx == 2)
- {
- rv = hicn_route_set_strategy (&prefix, strategy_id);
- cl_err =
- (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
- get_error_string
- (rv));
- }
+ rv = hicn_route_set_strategy (&prefix, strategy_id);
+ cl_err =
+ (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
+ get_error_string
+ (rv));
done:
return (cl_err);
@@ -783,6 +704,98 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t * vm,
return cl_err;
}
+static clib_error_t *
+hicn_enable_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *cl_err = 0;
+
+ int rv = HICN_ERROR_NONE;
+ fib_prefix_t pfx;
+
+ /* Get a line of input. */
+ unformat_input_t _line_input, *line_input = &_line_input;
+ if (!unformat_user (main_input, unformat_line_input, line_input))
+ {
+ return (0);
+ }
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U/%d",
+ unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP4;
+ }
+ else if (unformat (line_input, "%U/%d",
+ unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP6;
+ }
+ else
+ {
+ cl_err = clib_error_return (0, "%s '%U'",
+ get_error_string (HICN_ERROR_CLI_INVAL),
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+ rv = hicn_route_enable(&pfx);
+ done:
+
+ cl_err =
+ (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
+ get_error_string
+ (rv));
+ return cl_err;
+}
+
+static clib_error_t *
+hicn_disable_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *cl_err = 0;
+
+ int rv = HICN_ERROR_NONE;
+ fib_prefix_t pfx;
+
+ /* Get a line of input. */
+ unformat_input_t _line_input, *line_input = &_line_input;
+ if (!unformat_user (main_input, unformat_line_input, line_input))
+ {
+ return (0);
+ }
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U/%d",
+ unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP4;
+ }
+ else if (unformat (line_input, "%U/%d",
+ unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP6;
+ }
+ else
+ {
+ cl_err = clib_error_return (0, "%s '%U'",
+ get_error_string (HICN_ERROR_CLI_INVAL),
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = hicn_route_disable (&pfx);
+
+ done:
+ cl_err =
+ (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
+ get_error_string
+ (rv));
+ return cl_err;
+}
+
+
/* cli declaration for 'control start' */
/* *INDENT-OFF* */
VLIB_CLI_COMMAND(hicn_cli_node_ctl_start_set_command, static)=
@@ -818,13 +831,12 @@ VLIB_CLI_COMMAND(hicn_cli_node_ctl_command, static)=
};
/* cli declaration for 'fib' */
-VLIB_CLI_COMMAND(hicn_cli_fib_set_command, static)=
-{
- .path = "hicn fib",
- .short_help = "hicn fib {{add | delete } prefix <prefix> face <facei_d> }"
- " | set strategy <strategy_id> prefix <prefix>",
- .function = hicn_cli_fib_set_command_fn,
-};
+VLIB_CLI_COMMAND(hicn_cli_strategy_set_command, static)=
+ {
+ .path = "hicn strategy",
+ .short_help = "hicn strategy set <strategy_id> prefix <prefix>",
+ .function = hicn_cli_strategy_set_command_fn,
+ };
/* cli declaration for 'show' */
VLIB_CLI_COMMAND(hicn_cli_show_command, static)=
@@ -853,6 +865,25 @@ VLIB_CLI_COMMAND(hicn_cli_pgen_server_set_command, static)=
.long_help = "Run hicn in packet-gen server mode\n",
.function = hicn_cli_pgen_server_set_command_fn,
};
+
+/* cli declaration for 'hicn pgen client' */
+VLIB_CLI_COMMAND(hicn_enable_command, static)=
+ {
+ .path = "hicn enable",
+ .short_help = "hicn enable <prefix>",
+ .long_help = "Enable hicn for the give prefix\n",
+ .function = hicn_enable_command_fn,
+ };
+
+/* cli declaration for 'hicn pgen client' */
+VLIB_CLI_COMMAND(hicn_disable_command, static)=
+ {
+ .path = "hicn disable",
+ .short_help = "hicn disable <prefix>",
+ .long_help = "Disable hicn for the give prefix\n",
+ .function = hicn_disable_command_fn,
+ };
+
/* *INDENT-ON* */
/*
diff --git a/hicn-plugin/src/data_fwd.h b/hicn-plugin/src/data_fwd.h
index 55434a024..d95f564c3 100644
--- a/hicn-plugin/src/data_fwd.h
+++ b/hicn-plugin/src/data_fwd.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,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,13 +54,14 @@ 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,
HICN_DATA_FWD_N_NEXT,
} 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 1bb064fcf..c65b62454 100644
--- a/hicn-plugin/src/data_fwd_node.c
+++ b/hicn-plugin/src/data_fwd_node.c
@@ -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:
@@ -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,
@@ -434,7 +401,7 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
{
vlib_buffer_t *h0, *h1;
u32 hi0, hi1;
- dpo_id_t *face0, *face1;
+ hicn_face_id_t face0, face1;
/* Prefetch for next iteration. */
{
@@ -458,10 +425,13 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
n_left_from -= 2;
clones += 2;
- next0 = face0->dpoi_next_node;
- next1 = face1->dpoi_next_node;
- vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0->dpoi_index;
- vnet_buffer (h1)->ip.adj_index[VLIB_TX] = face1->dpoi_index;
+ next0 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT :
+ HICN_DATA_FWD_NEXT_IFACE4_OUT;
+ next1 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT :
+ HICN_DATA_FWD_NEXT_IFACE4_OUT;
+
+ vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0;
+ vnet_buffer (h1)->ip.adj_index[VLIB_TX] = face1;
stats->pkts_data_count += 2;
@@ -499,7 +469,7 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
{
vlib_buffer_t *h0;
u32 hi0;
- dpo_id_t *face0;
+ hicn_face_id_t face0;
face0 = hicn_face_db_get_dpo_face (i++, &pitp->u.pit.faces);
@@ -511,8 +481,9 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
n_left_from -= 1;
clones += 1;
- next0 = face0->dpoi_next_node;
- vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0->dpoi_index;
+ next0 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT :
+ HICN_DATA_FWD_NEXT_IFACE4_OUT;
+ vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0;
stats->pkts_data_count++;
@@ -584,7 +555,7 @@ clone_data_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
*/
hicn_buffer_t *hicnb0 = hicn_get_buffer (b0);
hicn_pit_to_cs (vm, pitcs, pitp, hash_entry, nodep, dpo_vft, hicn_dpo_id,
- &hicnb->face_dpo_id,
+ hicnb->face_id,
hicnb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP);
pitp->shared.create_time = tnow;
@@ -635,7 +606,8 @@ 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_input_node.c b/hicn-plugin/src/data_input_node.c
index b8c19757c..8d20f54a6 100644
--- a/hicn-plugin/src/data_input_node.c
+++ b/hicn-plugin/src/data_input_node.c
@@ -310,7 +310,7 @@ VLIB_REGISTER_NODE(hicn_data_input_ip6) =
.n_next_nodes = HICN_DATA_INPUT_IP6_N_NEXT,
.next_nodes =
{
- [HICN_DATA_INPUT_IP6_NEXT_FACE] = "hicn-face-ip6-input",
+ [HICN_DATA_INPUT_IP6_NEXT_FACE] = "hicn6-face-input",
[HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL] = "ip6-local-end-of-arc"
},
};
@@ -681,7 +681,7 @@ VLIB_REGISTER_NODE(hicn_data_input_ip4) =
.n_next_nodes = HICN_DATA_INPUT_IP4_N_NEXT,
.next_nodes =
{
- [HICN_DATA_INPUT_IP4_NEXT_FACE] = "hicn-face-ip4-input",
+ [HICN_DATA_INPUT_IP4_NEXT_FACE] = "hicn4-face-input",
[HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL] = "ip4-local-end-of-arc"
},
};
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 fc19362f9..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_dpo_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 2124e63c5..59ebce61c 100644
--- a/hicn-plugin/src/error.h
+++ b/hicn-plugin/src/error.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:
@@ -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") \
@@ -69,8 +76,9 @@
_(APPFACE_PROD_PREFIX_NULL, -176, "Prefix must not be null for producer face") \
_(STRATEGY_NH_NOT_FOUND, -177, "Next hop not found") \
_(MW_STRATEGY_SET, -178, "Error while setting weight for next hop") \
- _(STRATEGY_NOT_FOUND, -179, "Strategy not found")
-
+ _(STRATEGY_NOT_FOUND, -179, "Strategy not found") \
+ _(UDP_TUNNEL_NOT_FOUND, -180, "Udp tunnel not found") \
+ _(UDP_TUNNEL_SRC_DST_TYPE, -181, "Src and dst addresses have different type (ipv4 and ipv6)")
typedef enum
{
diff --git a/hicn-plugin/src/face_db.h b/hicn-plugin/src/face_db.h
index 17c28959a..4dd8b2f32 100644
--- a/hicn-plugin/src/face_db.h
+++ b/hicn-plugin/src/face_db.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,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
@@ -28,7 +28,7 @@
*/
/* Must be power of two */
-#define HICN_FACE_DB_INLINE_FACES 4
+#define HICN_FACE_DB_INLINE_FACES 8
#define HICN_PIT_BITMAP_SIZE_BYTE HICN_PARAM_FACES_MAX/8
#define HICN_PIT_N_HOP_BITMAP_SIZE HICN_PARAM_FACES_MAX
@@ -38,7 +38,7 @@
typedef struct hicn_face_bucket_s
{
/* Array of indexes of virtual faces */
- dpo_id_t faces[HICN_PIT_N_HOP_BUCKET];
+ hicn_face_id_t faces[HICN_PIT_N_HOP_BUCKET];
/* Used to check if interests are retransmission */
u8 bitmap[HICN_PIT_BITMAP_SIZE_BYTE];
@@ -60,7 +60,7 @@ typedef struct __attribute__ ((packed)) hicn_face_db_s
/* 24B + 32B (8*4) = 56B */
/* Array of indexes of virtual faces */
- dpo_id_t inline_faces[HICN_FACE_DB_INLINE_FACES];
+ hicn_face_id_t inline_faces[HICN_FACE_DB_INLINE_FACES];
/* 56B + 4B = 60B */
u32 next_bucket;
@@ -71,13 +71,13 @@ typedef struct __attribute__ ((packed)) hicn_face_db_s
} hicn_face_db_t;
-always_inline dpo_id_t *
+always_inline hicn_face_id_t
hicn_face_db_get_dpo_face (u32 index, hicn_face_db_t * face_db)
{
ASSERT (index < face_db->n_faces);
- return index < HICN_FACE_DB_INLINE_FACES ? &(face_db->inline_faces[index]) :
- &(pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket)->faces
+ return index < HICN_FACE_DB_INLINE_FACES ? (face_db->inline_faces[index]) :
+ (pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket)->faces
[(index - HICN_FACE_DB_INLINE_FACES) & (HICN_PIT_N_HOP_BUCKET - 1)]);
}
@@ -94,23 +94,23 @@ hicn_face_db_get_bucket (u32 bucket_index)
}
always_inline void
-hicn_face_db_add_face_dpo (dpo_id_t * dpo, hicn_face_db_t * face_db)
+hicn_face_db_add_face (hicn_face_id_t face_id, hicn_face_db_t * face_db)
{
- ASSERT (dpo->dpoi_index != ~0);
+ //ASSERT (dpo->dpoi_index != ~0);
hicn_face_bucket_t *faces_bkt =
pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket);
- dpo_id_t *face =
+ hicn_face_id_t *element =
face_db->n_faces <
HICN_FACE_DB_INLINE_FACES ? &(face_db->inline_faces[face_db->n_faces]) :
&(faces_bkt->faces
[(face_db->n_faces -
HICN_FACE_DB_INLINE_FACES) & (HICN_PIT_N_HOP_BUCKET - 1)]);
- clib_memcpy (face, dpo, sizeof (dpo_id_t));
+ *element = face_id;
- u32 bitmap_index = dpo->dpoi_index % HICN_PIT_N_HOP_BITMAP_SIZE;
+ u32 bitmap_index = face_id % HICN_PIT_N_HOP_BITMAP_SIZE;
u32 position_array = bitmap_index / 8;
u8 bit_index = (u8) (bitmap_index - position_array * 8);
@@ -119,11 +119,11 @@ hicn_face_db_add_face_dpo (dpo_id_t * dpo, hicn_face_db_t * face_db)
}
always_inline u8
-hicn_face_search (dpo_id_t * dpo, hicn_face_db_t * face_db)
+hicn_face_search (hicn_face_id_t index, hicn_face_db_t * face_db)
{
hicn_face_bucket_t *faces_bkt =
pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket);
- u32 bitmap_index = dpo->dpoi_index % HICN_PIT_N_HOP_BITMAP_SIZE;
+ u32 bitmap_index = index % HICN_PIT_N_HOP_BITMAP_SIZE;
u32 position_array = bitmap_index / 8;
u8 bit_index = bitmap_index - position_array * 8;
diff --git a/hicn-plugin/src/faces/app/address_mgr.c b/hicn-plugin/src/faces/app/address_mgr.c
index 1674379c4..2d5894ab8 100644
--- a/hicn-plugin/src/faces/app/address_mgr.c
+++ b/hicn-plugin/src/faces/app/address_mgr.c
@@ -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:
@@ -36,7 +36,6 @@
#include "../../infra.h"
#include "../../error.h"
#include "../face.h"
-#include "../ip/face_ip.h"
#include "../../strategy_dpo_ctx.h"
#include "../../route.h"
@@ -134,26 +133,25 @@ get_two_ip6_addresses (ip6_address_t * appif_addr, ip6_address_t * nh_addr)
fib_pfx.fp_proto = FIB_PROTOCOL_IP6;
fib_pfx.fp_len = ADDR_MGR_IP6_LEN;
+
+ fib_index = fib_table_find (fib_pfx.fp_proto, 0);
+
/* At this point the face exists in the face table */
do
{
/* Check if the route already exist in the fib */
fib_pfx.fp_addr = to_ip46 ( /* is_v6 */ 1, appif_addr->as_u8);
- fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
+
fib_entry_index = fib_table_lookup_exact_match (fib_index, &fib_pfx);
- fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
+ //fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
if (fib_entry_index != FIB_NODE_INDEX_INVALID)
{
fib_pfx.fp_addr = to_ip46 ( /* is_v6 */ 0, nh_addr->as_u8);
- fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
+
fib_entry_index =
fib_table_lookup_exact_match (fib_index, &fib_pfx);
- fib_table_unlock (fib_index, fib_pfx.fp_proto,
- FIB_SOURCE_PRIORITY_HI);
+ // fib_table_unlock (fib_index, fib_pfx.fp_proto,
+ // FIB_SOURCE_PRIORITY_HI);
}
if (fib_entry_index != FIB_NODE_INDEX_INVALID)
{
diff --git a/hicn-plugin/src/faces/app/face_app_cli.c b/hicn-plugin/src/faces/app/face_app_cli.c
index 1e8eb6a5b..1aa27adc7 100644
--- a/hicn-plugin/src/faces/app/face_app_cli.c
+++ b/hicn-plugin/src/faces/app/face_app_cli.c
@@ -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,8 +18,7 @@
#include <vlib/vlib.h>
#include <vnet/ip/ip6_packet.h>
-#include "../ip/face_ip.h"
-#include "../ip/dpo_ip.h"
+//#include "../face_dpo.h"
#include "../face.h"
#include "face_prod.h"
#include "face_cons.h"
@@ -164,7 +163,7 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm,
{
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id1);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS)
rv = hicn_face_cons_del (face_id1);
else
rv = hicn_face_prod_del (face_id1);
diff --git a/hicn-plugin/src/faces/app/face_cons.c b/hicn-plugin/src/faces/app/face_cons.c
index e51201c21..d44ba1a2b 100644
--- a/hicn-plugin/src/faces/app/face_cons.c
+++ b/hicn-plugin/src/faces/app/face_cons.c
@@ -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:
@@ -57,10 +57,12 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6,
ip46_address_t nh_addr = to_ip46 (0, (u8 *) nh_addr4);
- hicn_iface_ip_add (&if_ip, &nh_addr, swif, faceid1);
+ index_t adj_index = adj_nbr_find(FIB_PROTOCOL_IP4, VNET_LINK_IP4, &nh_addr, swif);
+
+ hicn_iface_add (&nh_addr, swif, faceid1, DPO_PROTO_IP4, adj_index);
hicn_face_t *face = hicn_dpoi_get_from_idx (*faceid1);
- face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS;
+ face->flags |= HICN_FACE_FLAGS_APPFACE_CONS;
get_two_ip6_addresses (&(if_ip.ip6), nh_addr6);
ip6_add_del_interface_address (vm,
@@ -68,10 +70,12 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6,
&(if_ip.ip6),
ADDR_MGR_IP6_CONS_LEN, 0 /* is_del */ );
- hicn_iface_ip_add (&if_ip, (ip46_address_t *) nh_addr6, swif, faceid2);
+ adj_index = adj_nbr_find(FIB_PROTOCOL_IP6, VNET_LINK_IP6, &nh_addr, swif);
+
+ hicn_iface_add ((ip46_address_t *) nh_addr6, swif, faceid2, DPO_PROTO_IP6, adj_index);
face = hicn_dpoi_get_from_idx (*faceid2);
- face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS;
+ face->flags |= HICN_FACE_FLAGS_APPFACE_CONS;
return HICN_ERROR_NONE;
}
@@ -84,9 +88,9 @@ hicn_face_cons_del (hicn_face_id_t face_id)
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS)
{
- return hicn_face_ip_del (face_id);
+ return hicn_face_del (face_id);
}
else
{
diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c
index ae59719ce..645154325 100644
--- a/hicn-plugin/src/faces/app/face_prod.c
+++ b/hicn-plugin/src/faces/app/face_prod.c
@@ -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:
@@ -98,10 +98,11 @@ hicn_app_state_del (u32 swif)
);
/* *INDENT-ON* */
- prefix = &(face_state_vec[swif].prefix);
if (!found)
return HICN_ERROR_APPFACE_NOT_FOUND;
+ prefix = &(face_state_vec[swif].prefix);
+
int ret = HICN_ERROR_NONE;
if (ip46_address_is_ip4 (&prefix->fp_addr))
{
@@ -132,7 +133,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
hicn_main_t *hm = &hicn_main;
ip46_address_t local_app_ip;
- ip46_address_t remote_app_ip;
+ CLIB_UNUSED(ip46_address_t remote_app_ip);
u32 if_flags = 0;
if (!hm->is_enabled)
@@ -160,28 +161,20 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
{
return HICN_ERROR_APPFACE_PROD_PREFIX_NULL;
}
+
+ u8 isv6 = ip46_address_is_ip4(prod_addr);
+ index_t adj_index = adj_nbr_find(isv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4, isv6 ? VNET_LINK_IP6 : VNET_LINK_IP4, prod_addr, sw_if);
+
/*
* Check if a producer face is already existing for the same prefix
* and sw_if
*/
- if (ip46_address_is_ip4 (&prefix->fp_addr))
- {
- face =
- hicn_face_ip4_get (&(prefix->fp_addr.ip4), sw_if,
- &hicn_face_ip_remote_hashtb);
- }
- else
- {
- face =
- hicn_face_ip6_get (&(prefix->fp_addr.ip6), sw_if,
- &hicn_face_ip_remote_hashtb);
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
- }
+ face = hicn_face_get (&(prefix->fp_addr), sw_if,
+ &hicn_face_hashtb, adj_index);
if (face != NULL)
{
- if (!(face->shared.flags & HICN_FACE_FLAGS_DELETED))
+ if (!(face->flags & HICN_FACE_FLAGS_DELETED))
return HICN_ERROR_FACE_ALREADY_CREATED;
/*
@@ -189,19 +182,17 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
* producer's prefix.
*/
/* It should never happens, this is a safety check. */
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS)
return HICN_ERROR_FACE_ALREADY_CREATED;
/* If the face exists but is marked as deleted, undelete it */
- if (face->shared.flags & HICN_FACE_FLAGS_DELETED)
+ if (face->flags & HICN_FACE_FLAGS_DELETED)
{
/*
* remove the deleted flag and retrieve the face
* local addr
*/
- face->shared.flags &= HICN_FACE_FLAGS_DELETED;
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- local_app_ip = prod_face->ip_face.local_addr;
+ face->flags &= HICN_FACE_FLAGS_DELETED;
}
}
else
@@ -222,9 +213,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
local_app_ip = to_ip46 ( /* isv6 */ 0, local_app_ip4.as_u8);
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_FLAGS_APPFACE_PROD);
+ vnet_build_rewrite_for_sw_interface(vnm, sw_if, VNET_LINK_IP4, &remote_app_ip4);
}
else
{
@@ -242,41 +231,29 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
0 /* is_del */ );
local_app_ip = to_ip46 ( /* isv6 */ 1, local_app_ip6.as_u8);
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_FLAGS_APPFACE_PROD);
}
-
- face = hicn_dpoi_get_from_idx (*faceid);
-
- face->shared.flags |= HICN_FACE_FLAGS_APPFACE_PROD;
-
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
-
- /*
- * For the moment we keep them here although it would be good
- * to create a different face for appface
- */
- prod_face->policy_vft.hicn_cs_insert = hicn_cs_lru.hicn_cs_insert;
- prod_face->policy_vft.hicn_cs_update = hicn_cs_lru.hicn_cs_update;
- prod_face->policy_vft.hicn_cs_dequeue = hicn_cs_lru.hicn_cs_dequeue;
- prod_face->policy_vft.hicn_cs_delete_get =
- hicn_cs_lru.hicn_cs_delete_get;
- prod_face->policy_vft.hicn_cs_trim = hicn_cs_lru.hicn_cs_trim;
- prod_face->policy_vft.hicn_cs_flush = hicn_cs_lru.hicn_cs_flush;
-
}
- if (ret == HICN_ERROR_NONE
- && hicn_face_prod_set_lru_max (*faceid, cs_reserved) == HICN_ERROR_NONE)
+ if (ret == HICN_ERROR_NONE)
+ // && hicn_face_prod_set_lru_max (*faceid, cs_reserved) == HICN_ERROR_NONE)
{
+ fib_route_path_t rpath = {0};
+ fib_route_path_t * rpaths = NULL;
+
if (ip46_address_is_ip4(&(prefix->fp_addr)))
{
ip4_address_t mask;
ip4_preflen_to_mask (prefix->fp_len, &mask);
prefix->fp_addr.ip4.as_u32 = prefix->fp_addr.ip4.as_u32 & mask.as_u32;
prefix->fp_proto = FIB_PROTOCOL_IP4;
+
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = ~0;
+ rpath.frp_addr.ip4.as_u32 = remote_app_ip.ip4.as_u32;
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_proto = DPO_PROTO_IP4;
+
+ vec_add1 (rpaths, rpath);
}
else
{
@@ -287,21 +264,42 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
prefix->fp_addr.ip6.as_u64[1] =
prefix->fp_addr.ip6.as_u64[1] & mask.as_u64[1];
prefix->fp_proto = FIB_PROTOCOL_IP6;
+
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = ~0;
+ rpath.frp_addr.ip6.as_u64[0] = remote_app_ip.ip6.as_u64[0];
+ rpath.frp_addr.ip6.as_u64[1] = remote_app_ip.ip6.as_u64[1];
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_proto = DPO_PROTO_IP6;
+
+ vec_add1 (rpaths, rpath);
}
+ u32 fib_index = fib_table_find (prefix->fp_proto, 0);
+ fib_table_entry_path_add2 (fib_index,
+ prefix,
+ FIB_SOURCE_CLI,
+ FIB_ENTRY_FLAG_NONE, rpaths);
+
+ hicn_route_enable(prefix);
hicn_app_state_create (sw_if, prefix);
- ret = hicn_route_add (faceid, 1, prefix);
}
+ adj_index = adj_nbr_find(isv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4, isv6 ? VNET_LINK_IP6 : VNET_LINK_IP4, prod_addr, sw_if);
+ face = hicn_face_get(&local_app_ip, sw_if, &hicn_face_hashtb, adj_index);//HICN_FACE_FLAGS_APPFACE_PROD);
+
+ *faceid = hicn_dpoi_get_index (face);
+
+ face->flags |= HICN_FACE_FLAGS_APPFACE_PROD;
+
+ hicn_face_unlock_with_id(*faceid);
+
*prod_addr = local_app_ip;
/* Cleanup in case of something went wrong. */
if (ret)
{
hicn_app_state_del (sw_if);
-
- if (*faceid != HICN_FACE_NULL)
- hicn_face_ip_del (*faceid);
}
return ret;
}
@@ -314,88 +312,33 @@ hicn_face_prod_del (hicn_face_id_t face_id)
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_PROD)
{
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- /* Free the CS reserved for the face */
- hicn_main.pitcs.pcs_app_count -= prod_face->policy.max;
- prod_face->policy.max = 0;
-
/* Remove the face from the fib */
- hicn_route_del_nhop (&(face_state_vec[face->shared.sw_if].prefix),
- face_id);
+ hicn_route_disable(&(face_state_vec[face->sw_if].prefix));
+ //hicn_route_del_nhop (&(face_state_vec[face->sw_if].prefix),
+ // face_id);
- /*
- * Delete the content in the CS before deleting the face.
- * Mandatory to prevent hitting the CS and not having the lru list
- * due to a early deletion of the face.
- */
- vlib_main_t *vm = vlib_get_main ();
- prod_face->policy_vft.hicn_cs_flush (vm, &(hicn_main.pitcs),
- &(prod_face->policy));
-
- int ret = hicn_face_ip_del (face_id);
- return ret ==
- HICN_ERROR_NONE ? hicn_app_state_del (face->shared.sw_if) : ret;
+ //int ret = hicn_face_del (face_id);
+ return hicn_app_state_del (face->sw_if);
+ //ret == HICN_ERROR_NONE ? hicn_app_state_del (face->sw_if) : ret;
}
else
{
return HICN_ERROR_APPFACE_NOT_FOUND;
}
-}
-
-int
-hicn_face_prod_set_lru_max (hicn_face_id_t face_id, u32 * requested_size)
-{
- int ret = HICN_ERROR_NONE;
- vlib_main_t *vm = vlib_get_main ();
- hicn_face_t *face;
- hicn_face_prod_t *face_prod;
-
- if (!hicn_infra_fwdr_initialized)
- {
- ret = HICN_ERROR_FWD_NOT_ENABLED;
- vlib_cli_output (vm, "hicn: %s\n", get_error_string (ret));
- return ret;
- }
- face = hicn_dpoi_get_from_idx (face_id);
- face_prod = (hicn_face_prod_t *) face->data;
-
- if (face == NULL)
- return HICN_ERROR_FACE_NOT_FOUND;
-
- if (*requested_size > HICN_PARAM_FACE_MAX_CS_RESERVED)
- *requested_size = HICN_PARAM_FACE_MAX_CS_RESERVED;
- uint32_t available =
- hicn_main.pitcs.pcs_app_max - hicn_main.pitcs.pcs_app_count;
-
- if (*requested_size > available)
- *requested_size = available;
-
- face_prod->policy.max = *requested_size;
- face_prod->policy.count = 0;
- face_prod->policy.head = face_prod->policy.tail = 0;
-
- hicn_main.pitcs.pcs_app_count += *requested_size;
-
- return ret;
+ return HICN_ERROR_NONE;
}
u8 *
format_hicn_face_prod (u8 * s, va_list * args)
{
- index_t index = va_arg (*args, index_t);
+ CLIB_UNUSED (index_t index) = va_arg (*args, index_t);
CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
- hicn_face_t *face;
- hicn_face_prod_t *prod_face;
-
- face = hicn_dpoi_get_from_idx (index);
- prod_face = (hicn_face_prod_t *) face->data;
s =
- format (s, " (producer face: CS size %d, data cached %d)",
- prod_face->policy.max, prod_face->policy.count);
+ format (s, " (producer)");
return s;
}
diff --git a/hicn-plugin/src/faces/app/face_prod.h b/hicn-plugin/src/faces/app/face_prod.h
index 33e2a4199..4cb2e3fbf 100644
--- a/hicn-plugin/src/faces/app/face_prod.h
+++ b/hicn-plugin/src/faces/app/face_prod.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:
@@ -17,7 +17,7 @@
#define _FACE_PRODUCER_H_
#include "../../cache_policies/cs_policy.h"
-#include "../ip/face_ip.h"
+#include "../face.h"
/**
* @file
@@ -56,15 +56,6 @@ extern hicn_face_prod_state_t *face_state_vec;
#define DEFAULT_PROBING_PORT 3784
-typedef struct __attribute__ ((packed)) hicn_face_prod_t_
-{
- hicn_face_ip_t ip_face;
-
- hicn_cs_policy_t policy;
- hicn_cs_policy_vft_t policy_vft;
-
-} hicn_face_prod_t;
-
/**
* @brief Add a new producer application face
*
diff --git a/hicn-plugin/src/faces/app/face_prod_node.c b/hicn-plugin/src/faces/app/face_prod_node.c
index 0ef25fe94..80c3e124c 100644
--- a/hicn-plugin/src/faces/app/face_prod_node.c
+++ b/hicn-plugin/src/faces/app/face_prod_node.c
@@ -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:
@@ -300,8 +300,8 @@ VLIB_REGISTER_NODE(hicn_face_prod_input_node) =
.n_next_nodes = HICN_FACE_PROD_N_NEXT,
.next_nodes =
{
- [HICN_FACE_PROD_NEXT_DATA_IP4] = "hicn-face-ip4-input",
- [HICN_FACE_PROD_NEXT_DATA_IP6] = "hicn-face-ip6-input",
+ [HICN_FACE_PROD_NEXT_DATA_IP4] = "hicn4-face-input",
+ [HICN_FACE_PROD_NEXT_DATA_IP6] = "hicn6-face-input",
[HICN_FACE_PROD_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c
index f2dcdd151..1abbf8887 100644
--- a/hicn-plugin/src/faces/face.c
+++ b/hicn-plugin/src/faces/face.c
@@ -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:
@@ -12,16 +12,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <vnet/fib/fib_entry_track.h>
#include "face.h"
-#include "ip/face_ip.h"
-#include "ip/face_ip_node.h"
-#include "ip/iface_ip_node.h"
-#include "ip/dpo_ip.h"
-#include "udp/face_udp.h"
-#include "udp/face_udp_node.h"
-#include "udp/iface_udp_node.h"
-#include "udp/dpo_udp.h"
+#include "../hicn.h"
+#include "../params.h"
+#include "../error.h"
+#include "../mapme.h"
+#include "../mapme_eventmgr.h"
dpo_id_t *face_dpo_vec;
hicn_face_vft_t *face_vft_vec;
@@ -33,6 +31,10 @@ dpo_type_t first_type = DPO_FIRST;
vlib_combined_counter_main_t *counters;
+dpo_type_t hicn_face_type;
+
+fib_node_type_t hicn_face_fib_node_type;
+
const char *HICN_FACE_CTRX_STRING[] = {
#define _(a,b,c) c,
foreach_hicn_face_counter
@@ -56,40 +58,189 @@ face_show (u8 * s, int face_id, u32 indent)
}
-void
-register_face_type (hicn_face_type_t face_type, hicn_face_vft_t * vft,
- char *name)
+mhash_t hicn_face_vec_hashtb;
+mhash_t hicn_face_hashtb;
+
+hicn_face_vec_t * hicn_vec_pool;
+
+const static char *const hicn_face6_nodes[] =
+ {
+ "hicn6-face-output", // this is the name you give your node in VLIB_REGISTER_NODE
+ "hicn6-iface-output", // this is the name you give your node in VLIB_REGISTER_NODE
+ NULL,
+};
+
+const static char *const hicn_face4_nodes[] =
+ {
+ "hicn4-face-output", // this is the name you give your node in VLIB_REGISTER_NODE
+ "hicn4-iface-output", // this is the name you give your node in VLIB_REGISTER_NODE
+ NULL,
+};
+
+
+const static char *const *const hicn_face_nodes[DPO_PROTO_NUM] =
+{
+ [DPO_PROTO_IP4] = hicn_face4_nodes,
+ [DPO_PROTO_IP6] = hicn_face6_nodes
+};
+
+const static dpo_vft_t hicn_face_dpo_vft =
+{
+ .dv_lock = hicn_face_lock,
+ .dv_unlock = hicn_face_unlock,
+ .dv_format = format_hicn_face,
+};
+
+static fib_node_t *
+hicn_face_node_get (fib_node_index_t index)
{
- if (first_type == DPO_FIRST)
- first_type = face_type;
-
- int idx = face_type - first_type;
- ASSERT (idx >= 0);
- vec_validate (face_vft_vec, idx);
- vec_validate (face_type_names_vec, idx);
-
- /* Copy the null char as well */
- char *name_str = (char *) malloc ((strlen (name) + 1) * sizeof (char));
- strcpy (name_str, name);
- face_vft_vec[idx] = *vft;
- face_type_names_vec[idx] = name_str;
+ hicn_face_t * face;
+
+ face = hicn_dpoi_get_from_idx(index);
+
+ return (&face->fib_node);
+}
+
+static void
+hicn_face_last_lock_gone (fib_node_t *node)
+{
+}
+
+static hicn_face_t *
+hicn_face_from_fib_node (fib_node_t * node)
+{
+ return ((hicn_face_t *) (((char *) node) -
+ STRUCT_OFFSET_OF (hicn_face_t, fib_node)));
+}
+
+static fib_node_back_walk_rc_t
+hicn_face_back_walk_notify (fib_node_t *node,
+ fib_node_back_walk_ctx_t *ctx)
+{
+
+ hicn_face_t *face = hicn_face_from_fib_node (node);
+
+ const dpo_id_t * dpo_loadbalance = fib_entry_contribute_ip_forwarding (face->fib_entry_index);
+ const load_balance_t *lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
+
+ const dpo_id_t *dpo = load_balance_get_bucket_i(lb0,0);
+
+ dpo_stack(hicn_face_type, face->dpo.dpoi_proto, &face->dpo, dpo);
+ /* if (dpo_is_adj(dpo)) */
+ /* { */
+ /* ip_adjacency_t * adj = adj_get (dpo->dpoi_index); */
+
+ /* if (dpo->dpoi_type == DPO_ADJACENCY_MIDCHAIN || */
+ /* dpo->dpoi_type == DPO_ADJACENCY_MCAST_MIDCHAIN) */
+ /* { */
+ /* adj_nbr_midchain_stack(dpo->dpoi_index, &face->dpo); */
+ /* } */
+ /* else */
+ /* { */
+ /* dpo_stack(hicn_face_type, face->dpo.dpoi_proto, &face->dpo, dpo); */
+ /* } */
+ /* } */
+
+ return (FIB_NODE_BACK_WALK_CONTINUE);
}
+static void
+hicn_face_show_memory (void)
+{
+}
+
+
+static const fib_node_vft_t hicn_face_fib_node_vft =
+ {
+ .fnv_get = hicn_face_node_get,
+ .fnv_last_lock = hicn_face_last_lock_gone,
+ .fnv_back_walk = hicn_face_back_walk_notify,
+ .fnv_mem_show = hicn_face_show_memory,
+ };
+
// Make this more flexible for future types face
void
hicn_face_module_init (vlib_main_t * vm)
{
pool_validate (hicn_dpoi_face_pool);
pool_alloc (hicn_dpoi_face_pool, 1024);
- hicn_face_ip_init (vm);
- hicn_iface_ip_init (vm);
- hicn_face_udp_init (vm);
- hicn_iface_udp_init (vm);
counters =
vec_new (vlib_combined_counter_main_t,
HICN_PARAM_FACES_MAX * HICN_N_COUNTER);
+
+ mhash_init (&hicn_face_vec_hashtb,
+ sizeof (hicn_face_input_faces_t) /* value */ ,
+ sizeof (hicn_face_key_t) /* key */ );
+ mhash_init (&hicn_face_hashtb,
+ sizeof (hicn_face_id_t) /* value */ ,
+ sizeof (hicn_face_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.
+ */
+ hicn_face_type =
+ dpo_register_new_type (&hicn_face_dpo_vft, hicn_face_nodes);
+
+ /*
+ * We register a new node type to get informed when the adjacency corresponding
+ * to a face is updated
+ */
+ hicn_face_fib_node_type = fib_node_register_new_type(&hicn_face_fib_node_vft);
+}
+
+u8 *
+format_hicn_face (u8 * s, va_list * args)
+{
+ index_t index = va_arg (*args, index_t);
+ u32 indent = va_arg (*args, u32);
+ hicn_face_t *face;
+
+ face = hicn_dpoi_get_from_idx (index);
+
+ if (face->flags & HICN_FACE_FLAGS_FACE)
+ {
+ hicn_face_id_t face_id = hicn_dpoi_get_index (face);
+ s = format (s, "%U Face %d: ", format_white_space, indent, face_id);
+ s = format (s, "nat address %U locks %u, path_label %u",
+ format_ip46_address, &face->nat_addr, IP46_TYPE_ANY,
+ face->locks, face->pl_id);
+
+ if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD))
+ s = format (s, " (producer)");
+ else if ((face->flags & HICN_FACE_FLAGS_APPFACE_CONS))
+ s = format (s, " (consumer)");
+
+ if ((face->flags & HICN_FACE_FLAGS_DELETED))
+ s = format (s, " (deleted)");
+
+ s = format (s, "\n%U%U",
+ format_white_space, indent + 2,
+ format_dpo_id, &face->dpo, indent + 3);
+ }
+ else
+ {
+ hicn_face_id_t face_id = hicn_dpoi_get_index (face);
+ s = format (s, "%U iFace %d: ", format_white_space, indent, face_id);
+ s = format (s, "nat address %U locks %u, path_label %u",
+ format_ip46_address, &face->nat_addr, IP46_TYPE_ANY,
+ face->locks, face->pl_id);
+
+ if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD))
+ s = format (s, " (producer)");
+ else if ((face->flags & HICN_FACE_FLAGS_APPFACE_CONS))
+ s = format (s, " (consumer)");
+
+ if ((face->flags & HICN_FACE_FLAGS_DELETED))
+ s = format (s, " (deleted)");
+ }
+
+ return s;
}
+
u8 *
format_hicn_face_all (u8 * s, int n, ...)
{
@@ -104,46 +255,226 @@ format_hicn_face_all (u8 * s, int n, ...)
/* *INDENT-OFF* */
pool_foreach ( face, hicn_dpoi_face_pool,
{
- hicn_face_vft_t * vft = hicn_face_get_vft(face->shared.face_type);
- hicn_face_id_t face_id = hicn_dpoi_get_index(face);
- s = format(s, "%U\n", vft->format_face, face_id, indent);
+ s = format(s, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), indent);
});
/* *INDENT-ON* */
return s;
}
-hicn_face_vft_t *
-hicn_face_get_vft (hicn_face_type_t face_type)
-{
- int idx = face_type - first_type;
- if (idx >= 0)
- return &face_vft_vec[idx];
- else
- return NULL;
-
-}
-
int
hicn_face_del (hicn_face_id_t face_id)
{
+ hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
+ hicn_face_key_t key;
+ hicn_face_key_t old_key;
+ hicn_face_key_t old_key2;
+
+ hicn_face_get_key (&(face->nat_addr), face->sw_if, &(face->dpo),
+ &key);
+ hicn_face_input_faces_t *in_faces_vec =
+ hicn_face_get_vec (&(face->nat_addr),
+ &hicn_face_vec_hashtb);
+ if (in_faces_vec != NULL)
+ {
+ hicn_face_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_vec_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];
+ }
+ }
+
+ mhash_unset (&hicn_face_hashtb, &key,
+ (uword *) & old_key2);
+ }
+
int ret = HICN_ERROR_NONE;
if (hicn_dpoi_idx_is_valid (face_id))
{
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- face->shared.locks--;
- if (face->shared.locks == 0)
+ face->locks--;
+ if (face->locks == 0)
pool_put_index (hicn_dpoi_face_pool, face_id);
else
- face->shared.flags |= HICN_FACE_FLAGS_DELETED;
+ face->flags |= HICN_FACE_FLAGS_DELETED;
}
else
ret = HICN_ERROR_FACE_NOT_FOUND;
+
return ret;
}
+static void
+hicn_iface_to_face(hicn_face_t *face, const dpo_id_t * dpo)
+{
+ dpo_stack(hicn_face_type, dpo->dpoi_proto, &face->dpo, dpo);
+
+ face->flags &= ~HICN_FACE_FLAGS_IFACE;
+ face->flags |= HICN_FACE_FLAGS_FACE;
+
+ if (dpo_is_adj(dpo))
+ {
+ fib_node_init (&face->fib_node, hicn_face_fib_node_type);
+ fib_node_lock (&face->fib_node);
+
+ if (dpo->dpoi_type != DPO_ADJACENCY_MIDCHAIN ||
+ dpo->dpoi_type != DPO_ADJACENCY_MCAST_MIDCHAIN)
+ {
+ ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
+ ip46_address_t * nh = &(adj->sub_type.nbr.next_hop);
+ fib_prefix_t prefix;
+
+ if (!ip46_address_is_zero(nh))
+ {
+ fib_prefix_from_ip46_addr(nh, &prefix);
+
+ u32 fib_index = fib_table_find(prefix.fp_proto, HICN_FIB_TABLE);
+
+ face->fib_entry_index = fib_entry_track (fib_index,
+ &prefix,
+ hicn_face_fib_node_type,
+ hicn_dpoi_get_index(face), &face->fib_sibling);
+ }
+ }
+ }
+}
+
+/*
+ * 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_add (const dpo_id_t * dpo_nh, ip46_address_t * nat_address,
+ int sw_if, hicn_face_id_t * pfaceid, u8 is_app_prod)
+{
+
+ hicn_face_flags_t flags = (hicn_face_flags_t) 0;
+ flags |= HICN_FACE_FLAGS_FACE;
+
+ hicn_face_t *face;
+
+ face =
+ hicn_face_get_with_dpo (nat_address, sw_if, dpo_nh,
+ &hicn_face_hashtb);
+
+ if (face != NULL)
+ {
+ *pfaceid = hicn_dpoi_get_index (face);
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+ }
+
+ face =
+ hicn_face_get (nat_address, sw_if,
+ &hicn_face_hashtb, dpo_nh->dpoi_index);
+
+ dpo_id_t temp_dpo = DPO_INVALID;
+ temp_dpo.dpoi_index = dpo_nh->dpoi_index;
+ hicn_face_key_t key;
+ hicn_face_get_key (nat_address, sw_if, dpo_nh, &key);
+
+ if (face == NULL)
+ {
+
+ hicn_iface_add (nat_address, sw_if, pfaceid, dpo_nh->dpoi_proto, dpo_nh->dpoi_index);
+ face = hicn_dpoi_get_from_idx (*pfaceid);
+
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid,
+ 0);
+
+ hicn_face_get_key (nat_address, sw_if, &temp_dpo, &key);
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid,
+ 0);
+ }
+ else
+ {
+ /* We found an iface and we convert it to a face */
+ *pfaceid = hicn_dpoi_get_index (face);
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid,
+ 0);
+ }
+
+ hicn_iface_to_face(face, dpo_nh);
+
+ temp_dpo.dpoi_index = ~0;
+
+ hicn_face_input_faces_t *in_faces =
+ hicn_face_get_vec (nat_address, &hicn_face_vec_hashtb);
+
+ if (in_faces == NULL)
+ {
+ hicn_face_input_faces_t in_faces_temp;
+ hicn_face_vec_t *vec;
+ pool_get (hicn_vec_pool, vec);
+ *vec = vec_new (hicn_face_vec_t, 0);
+ u32 index = vec - hicn_vec_pool;
+ in_faces_temp.vec_id = index;
+ vec_add1 (*vec, *pfaceid);
+
+ in_faces_temp.face_id = *pfaceid;
+
+ hicn_face_get_key (nat_address, 0, &temp_dpo, &key);
+
+ mhash_set_mem (&hicn_face_vec_hashtb, &key,
+ (uword *) & in_faces_temp, 0);
+ }
+ else
+ {
+ hicn_face_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;
+
+ vec_add1 (*vec, *pfaceid);
+
+ hicn_iface_to_face(face, dpo_nh);
+
+ hicn_face_get_key (nat_address, 0, &temp_dpo, &key);
+
+ mhash_set_mem (&hicn_face_vec_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 (),
+ hicn_mapme_eventmgr_process_node.index,
+ HICN_MAPME_EVENT_FACE_ADD, 1,
+ sizeof (retx_t));
+
+ /* *INDENT-OFF* */
+ *retx = (retx_t) {
+ .face_id = *pfaceid,
+ };
+ /* *INDENT-ON* */
+
+ return HICN_ERROR_NONE;
+}
+
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h
index b758ece06..234c3fcc2 100644
--- a/hicn-plugin/src/faces/face.h
+++ b/hicn-plugin/src/faces/face.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:
@@ -16,35 +16,66 @@
#ifndef __HICN_FACE_H__
#define __HICN_FACE_H__
+#include <vnet/fib/fib_node.h>
#include <vnet/vnet.h>
#include <vlib/vlib.h>
+#include <vnet/ip/ip46_address.h>
#include <vnet/dpo/dpo.h>
#include <vnet/adj/adj_types.h>
-#include "../hicn.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 Fields shared among all the different types of faces
+ * @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.
*/
-typedef struct __attribute__ ((packed)) hicn_face_shared_s
+typedef struct __attribute__ ((packed)) hicn_face_s
{
/* Flags to idenfity if the face is incomplete (iface), complete (face) */
/* And a network or application face (1B) */
@@ -59,34 +90,24 @@ typedef struct __attribute__ ((packed)) hicn_face_shared_s
/* Number of dpo holding a reference to the dpoi (4B) */
u32 locks;
- /* Adjacency for the neighbor (4B) */
- adj_index_t adj;
+ /* Dpo for the adjacency (8B) */
+ union {
+ dpo_id_t dpo;
+ u64 align_dpo;
+ };
+
+ /* Local address of the interface sw_if */
+ ip46_address_t nat_addr;
/* local interface for the local ip address */
u32 sw_if;
- /* Face id corresponding to the global face pool (4B) */
- union
- {
- hicn_face_type_t face_type;
- u32 int_face_type; //To force the face_type_t to be 4B
- };
+ fib_node_t fib_node;
-} hicn_face_shared_t;
+ fib_node_index_t fib_entry_index;
-/**
- * @brief Structure holding the face state. 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.
- */
-typedef struct __attribute__ ((packed)) hicn_face_s
-{
- /* Additional space to fill with face_type specific information */
- u8 data[2 * CLIB_CACHE_LINE_BYTES - sizeof (hicn_face_shared_t)];
- hicn_face_shared_t shared;
-}
-
-hicn_face_t;
+ u32 fib_sibling;
+} hicn_face_t;
/* Pool of faces */
extern hicn_face_t *hicn_dpoi_face_pool;
@@ -107,6 +128,10 @@ extern hicn_face_t *hicn_dpoi_face_pool;
#define HICN_FACE_FLAGS_APPFACE_PROD_BIT 2
#define HICN_FACE_FLAGS_APPFACE_CONS_BIT 3
+
+#define HICN_BUFFER_FLAGS_DEFAULT 0x00
+#define HICN_BUFFER_FLAGS_FACE_IS_APP 0x01
+
STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_PROD_BIT) ==
HICN_FACE_FLAGS_APPFACE_PROD,
"HICN_FACE_FLAGS_APPFACE_PROD_BIT and HICN_FACE_FLAGS_APPFACE_PROD must correspond");
@@ -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
{
@@ -155,6 +175,8 @@ typedef enum
HICN_N_COUNTER
} hicn_face_counters_t;
+extern mhash_t hicn_face_hashtb;
+
extern const char *HICN_FACE_CTRX_STRING[];
#define get_face_counter_string(ctrxno) (char *)(HICN_FACE_CTRX_STRING[ctrxno])
@@ -174,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
@@ -186,6 +208,22 @@ hicn_dpoi_get_index (hicn_face_t * face_dpoi)
}
/**
+ * @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 or NULL
+ */
+always_inline hicn_face_t *
+hicn_dpoi_get_from_idx_safe (hicn_face_id_t dpoi_index)
+{
+ if (!pool_is_free_index(hicn_dpoi_face_pool, dpoi_index))
+ return (hicn_face_t *) pool_elt_at_index (hicn_dpoi_face_pool, dpoi_index);
+ else
+ return NULL;
+}
+
+/**
* @brief Return the face from the face id. Face id must be valid.
*
* @param dpoi_index Face identifier
@@ -207,17 +245,18 @@ hicn_dpoi_idx_is_valid (hicn_face_id_t face_id)
&& !pool_is_free_index (hicn_dpoi_face_pool, face_id);
}
+
/**
* @brief Add a lock to the face dpo
*
* @param dpo Pointer to the face dpo
*/
always_inline void
-hicn_face_lock (dpo_id_t * dpo)
+hicn_face_lock_with_id (hicn_face_id_t face_id)
{
hicn_face_t *face;
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
- face->shared.locks++;
+ face = hicn_dpoi_get_from_idx (face_id);
+ face->locks++;
}
/**
@@ -226,20 +265,46 @@ hicn_face_lock (dpo_id_t * dpo)
* @param dpo Pointer to the face dpo
*/
always_inline void
-hicn_face_unlock (dpo_id_t * dpo)
+hicn_face_unlock_with_id (hicn_face_id_t face_id)
{
hicn_face_t *face;
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
- face->shared.locks--;
+ face = hicn_dpoi_get_from_idx (face_id);
+ face->locks--;
+}
+
+/**
+ * @brief Add a lock to the face through its dpo
+ *
+ * @param dpo Pointer to the face dpo
+ */
+always_inline void
+hicn_face_lock (dpo_id_t * dpo)
+{
+ hicn_face_lock_with_id(dpo->dpoi_index);
}
/**
+ * @brief Remove a lock to the face through its dpo. Deallocate the face id locks == 0
+ *
+ * @param dpo Pointer to the face dpo
+ */
+always_inline void
+hicn_face_unlock (dpo_id_t * dpo)
+{
+ hicn_face_unlock_with_id (dpo->dpoi_index);
+}
+
+
+/**
* @brief Init the internal structures of the face module
*
* Must be called before processing any packet
*/
void hicn_face_module_init (vlib_main_t * vm);
+u8 * format_hicn_face (u8 * s, va_list * args);
+
+
/**
* @brief Format all the existing faces
*
@@ -259,21 +324,469 @@ u8 *format_hicn_face_all (u8 * s, int n, ...);
int hicn_face_del (hicn_face_id_t face_id);
/**
- * @brief Return the virtual function table corresponding to the face type
+ * @bried vector of faces used to collect faces having the same local address
+ *
+ */
+typedef hicn_face_id_t *hicn_face_vec_t;
+
+typedef struct hicn_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_input_faces_t;
+
+/**
+ * Pool containing the vector of possible incoming faces.
+ */
+extern hicn_face_vec_t *hicn_vec_pool;
+
+/**
+ * Hash tables that indexes a face by remote address. For fast lookup when an
+ * interest arrives.
+ */
+extern mhash_t hicn_face_vec_hashtb;
+
+
+/**
+ * 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
+{
+ ip46_address_t addr;
+ union {
+ dpo_id_t dpo;
+ u64 align_dpo;
+ };
+ u32 sw_if;
+} hicn_face_key_t;
+
+/**
+ * @brief Create the key object for the mhash. Fill in the key object with the
+ * expected values.
+ *
+ * @param addr nat address of the face
+ * @param sw_if interface associated to the face
+ * @param key Pointer to an allocated hicn_face_ip_key_t object
+ */
+always_inline void
+hicn_face_get_key (const ip46_address_t * addr,
+ u32 sw_if, const dpo_id_t * dpo, hicn_face_key_t * key)
+{
+ key->dpo = *dpo;
+ key->addr = *addr;
+ key->sw_if = sw_if;
+}
+
+/**
+ * @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.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
+ *
+ * @result Pointer to the face.
+ */
+always_inline hicn_face_t *
+hicn_face_get (const ip46_address_t * addr, u32 sw_if, mhash_t * hashtb, index_t adj_index)
+{
+ hicn_face_key_t key;
+
+ dpo_id_t dpo = DPO_INVALID;
+
+ dpo.dpoi_index = adj_index;
+
+ hicn_face_get_key (addr, sw_if, &dpo, &key);
+
+ hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
+ &key);
+
+ if ( dpoi_index != NULL)
+ {
+ hicn_face_lock_with_id(*dpoi_index);
+ return hicn_dpoi_get_from_idx (*dpoi_index);
+ }
+
+ return NULL;
+}
+
+/**
+ * @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.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
*
- * @param face_type Type of the face
- * @return NULL if the face type does not exist
+ * @result Pointer to the face.
*/
-hicn_face_vft_t *hicn_face_get_vft (hicn_face_type_t face_type);
+always_inline hicn_face_t *
+hicn_face_get_with_dpo (const ip46_address_t * addr, u32 sw_if, const dpo_id_t * dpo, mhash_t * hashtb)
+{
+ hicn_face_key_t key;
+
+ hicn_face_get_key (addr, sw_if, dpo, &key);
+
+ hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
+ &key);
+
+ if ( dpoi_index != NULL)
+ {
+ hicn_face_lock_with_id(*dpoi_index);
+ return hicn_dpoi_get_from_idx (*dpoi_index);
+ }
+
+ return NULL;
+}
/**
- * @brief Register a new face type
+ * @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.
*
- * @param face_type Type of the face
- * @param vft Virtual Function table for the new face type
+ * @result Pointer to the face.
*/
-void register_face_type (hicn_face_type_t face_type, hicn_face_vft_t * vft,
- char *name);
+always_inline hicn_face_input_faces_t *
+hicn_face_get_vec (const ip46_address_t * addr,
+ mhash_t * hashtb)
+{
+ hicn_face_key_t key;
+
+ dpo_id_t dpo = DPO_INVALID;
+
+ hicn_face_get_key (addr, 0, &dpo, &key);
+ return (hicn_face_input_faces_t *) mhash_get (hashtb, &key);
+}
+
+/**
+ * @brief Create a new face ip. API for other modules (e.g., routing)
+ *
+ * @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 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_add (const dpo_id_t * dpo_nh,
+ ip46_address_t * nat_address,
+ int sw_if,
+ hicn_face_id_t * pfaceid,
+ u8 is_app_prod);
+
+/**
+ * @brief Create a new incomplete face ip. (Meant to be used by the data plane)
+ *
+ * @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 sw_if interface associated to the face
+ * @param pfaceid Pointer to return the face id
+ * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
+ * reachable ip address, otherwise HICN_ERROR_NONE
+ */
+always_inline void
+hicn_iface_add (ip46_address_t * nat_address, int sw_if,
+ hicn_face_id_t * pfaceid, dpo_proto_t proto,
+ u32 adj_index)
+{
+ hicn_face_t *face;
+ pool_get (hicn_dpoi_face_pool, face);
+
+ clib_memcpy (&(face->nat_addr), nat_address,
+ sizeof (ip46_address_t));
+ face->sw_if = sw_if;
+
+ face->dpo.dpoi_type = DPO_FIRST;
+ face->dpo.dpoi_proto = DPO_PROTO_NONE;
+ face->dpo.dpoi_index = adj_index;
+ face->dpo.dpoi_next_node = 0;
+ face->pl_id = (u16) 0;
+ face->flags = HICN_FACE_FLAGS_IFACE;
+ face->locks = 1;
+
+ hicn_face_key_t key;
+ hicn_face_get_key (nat_address, sw_if, &face->dpo, &key);
+ *pfaceid = hicn_dpoi_get_index (face);
+
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, 0);
+
+ for (int i = 0; i < HICN_N_COUNTER; i++)
+ {
+ vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
+ i);
+ vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
+ }
+}
+
+/**** 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_cli.c b/hicn-plugin/src/faces/face_cli.c
index b0ed7ddae..e9e516cc6 100644
--- a/hicn-plugin/src/faces/face_cli.c
+++ b/hicn-plugin/src/faces/face_cli.c
@@ -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:
@@ -74,8 +74,7 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
(HICN_ERROR_FACE_NOT_FOUND));
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- hicn_face_vft_t *vft = hicn_face_get_vft (face->shared.face_type);
- vlib_cli_output (vm, "%U\n", vft->format_face, face_id, 0 /*indent */ );
+ vlib_cli_output (vm, "%U\n", format_hicn_face, face_id, 0 /*indent */ );
u32 indent = 3;
@@ -107,16 +106,14 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
if (found != ~0)
{
hicn_face_t *face;
- dpo_type_t type = (dpo_type_t) (found + first_type);
- hicn_face_vft_t *vft = hicn_face_get_vft (type);
/* *INDENT-OFF* */
pool_foreach(face, hicn_dpoi_face_pool,
{
- if (!((face->shared.flags & HICN_FACE_FLAGS_DELETED) && !deleted))
+ if (!((face->flags & HICN_FACE_FLAGS_DELETED) && !deleted))
{
- if ((face->shared.face_type == type) && (face->shared.flags))
+ if (face->flags)
{
- vlib_cli_output(vm, "%U\n", vft->format_face, hicn_dpoi_get_index(face), 0);
+ vlib_cli_output(vm, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), 0);
u8 * s = 0;
u32 indent = 3;
@@ -147,10 +144,9 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
/* *INDENT-OFF* */
pool_foreach(face, hicn_dpoi_face_pool,
{
- if (!((face->shared.flags & HICN_FACE_FLAGS_DELETED) && !deleted))
+ if (!((face->flags & HICN_FACE_FLAGS_DELETED) && !deleted))
{
- hicn_face_vft_t * vft = hicn_face_get_vft(face->shared.face_type);
- vlib_cli_output(vm, "%U\n", vft->format_face, hicn_dpoi_get_index(face), 0);
+ vlib_cli_output(vm, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), 0);
u32 indent = 3;
u8 * s = 0;
@@ -184,7 +180,7 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (hicn_face_cli_show_command, static) =
{
.path = "hicn face show",
- .short_help = "hicn face show [<face_id>| type <ip/udp>]",
+ .short_help = "hicn face show [<face_id>]",
.function = hicn_face_cli_show_command_fn,
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.c b/hicn-plugin/src/faces/face_node.c
index 0eeeab6fb..e1fd81ca0 100644
--- a/hicn-plugin/src/faces/ip/face_ip_node.c
+++ b/hicn-plugin/src/faces/face_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 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:
@@ -15,15 +15,13 @@
#include <vnet/adj/adj.h>
-#include "face_ip.h"
-#include "face_ip_node.h"
-#include "dpo_ip.h"
-#include "../app/face_prod.h"
-#include "../../strategy_dpo_manager.h"
-#include "../face.h"
-#include "../../cache_policies/cs_lru.h"
-#include "../../infra.h"
-#include "../../hicn.h"
+#include "face.h"
+#include "face_node.h"
+#include "../strategy_dpo_manager.h"
+#include "face.h"
+#include "../cache_policies/cs_lru.h"
+#include "../infra.h"
+#include "../hicn.h"
/**
* @File
@@ -31,21 +29,21 @@
* Definition of the nodes for ip incomplete faces.
*/
-vlib_node_registration_t hicn_face_ip4_input_node;
-vlib_node_registration_t hicn_face_ip4_output_node;
-vlib_node_registration_t hicn_face_ip6_input_node;
-vlib_node_registration_t hicn_face_ip6_output_node;
+vlib_node_registration_t hicn4_face_input_node;
+vlib_node_registration_t hicn4_face_output_node;
+vlib_node_registration_t hicn6_face_input_node;
+vlib_node_registration_t hicn6_face_output_node;
#define ip_v4 4
#define ip_v6 6
-static char *hicn_face_ip4_input_error_strings[] = {
+static char *hicn4_face_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
};
-static char *hicn_face_ip6_input_error_strings[] = {
+static char *hicn6_face_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
@@ -59,15 +57,15 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip4_input_trace_t;
+hicn4_face_input_trace_t;
typedef enum
{
- HICN_FACE_IP4_INPUT_NEXT_DATA,
- HICN_FACE_IP4_INPUT_NEXT_MAPME,
- HICN_FACE_IP4_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_IP4_INPUT_N_NEXT,
-} hicn_face_ip4_input_next_t;
+ HICN4_FACE_INPUT_NEXT_DATA,
+ HICN4_FACE_INPUT_NEXT_MAPME,
+ HICN4_FACE_INPUT_NEXT_ERROR_DROP,
+ HICN4_FACE_INPUT_N_NEXT,
+} hicn4_face_input_next_t;
/* Trace context struct */
typedef struct
@@ -77,35 +75,35 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip6_input_trace_t;
+hicn6_face_input_trace_t;
typedef enum
{
- HICN_FACE_IP6_INPUT_NEXT_DATA,
- HICN_FACE_IP6_INPUT_NEXT_MAPME,
- HICN_FACE_IP6_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_IP6_INPUT_N_NEXT,
-} hicn_face_ip6_input_next_t;
+ HICN6_FACE_INPUT_NEXT_DATA,
+ HICN6_FACE_INPUT_NEXT_MAPME,
+ HICN6_FACE_INPUT_NEXT_ERROR_DROP,
+ HICN6_FACE_INPUT_N_NEXT,
+} hicn6_face_input_next_t;
-#define NEXT_MAPME_IP4 HICN_FACE_IP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_IP6 HICN_FACE_IP6_INPUT_NEXT_MAPME
-#define NEXT_DATA_IP4 HICN_FACE_IP4_INPUT_NEXT_DATA
-#define NEXT_DATA_IP6 HICN_FACE_IP6_INPUT_NEXT_DATA
+#define NEXT_MAPME_IP4 HICN4_FACE_INPUT_NEXT_MAPME
+#define NEXT_MAPME_IP6 HICN6_FACE_INPUT_NEXT_MAPME
+#define NEXT_DATA_IP4 HICN4_FACE_INPUT_NEXT_DATA
+#define NEXT_DATA_IP6 HICN6_FACE_INPUT_NEXT_DATA
-#define NEXT_ERROR_DROP_IP4 HICN_FACE_IP4_INPUT_NEXT_ERROR_DROP
-#define NEXT_ERROR_DROP_IP6 HICN_FACE_IP6_INPUT_NEXT_ERROR_DROP
+#define NEXT_ERROR_DROP_IP4 HICN4_FACE_INPUT_NEXT_ERROR_DROP
+#define NEXT_ERROR_DROP_IP6 HICN6_FACE_INPUT_NEXT_ERROR_DROP
#define IP_HEADER_4 ip4_header_t
#define IP_HEADER_6 ip6_header_t
-#define LOCK_FROM_LOCAL_IP4 hicn_dpo_ip4_lock_from_local
-#define LOCK_FROM_LOCAL_IP6 hicn_dpo_ip6_lock_from_local
+#define LOCK_DPO_FACE_IP4 hicn_face_ip4_lock
+#define LOCK_DPO_FACE_IP6 hicn_face_ip6_lock
-#define TRACE_INPUT_PKT_IP4 hicn_face_ip4_input_trace_t
-#define TRACE_INPUT_PKT_IP6 hicn_face_ip6_input_trace_t
+#define TRACE_INPUT_PKT_IP4 hicn4_face_input_trace_t
+#define TRACE_INPUT_PKT_IP6 hicn6_face_input_trace_t
/*
- * NOTE: Both hicn_face_ip4_input_node_fn and hicn_face_ip6_input_node_fn
+ * NOTE: Both hicn4_face_input_node_fn and hicn6_face_input_node_fn
* present a similar codebase. Macro are hard to debug, although the
* followind code is pretty straighforward and most of the complexity is in
* functions that can be easily debug.
@@ -143,19 +141,18 @@ typedef enum
next0 = is_icmp*NEXT_MAPME_IP##ipv + \
(1-is_icmp)*NEXT_DATA_IP##ipv; \
\
- ret = LOCK_FROM_LOCAL_IP##ipv \
- (&(hicnb0->face_dpo_id), \
+ ret = LOCK_DPO_FACE_IP##ipv \
+ (&(hicnb0->face_id), \
&(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
- &(ip_hdr->dst_address), \
- vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
+ &(ip_hdr->dst_address)); \
\
if ( PREDICT_FALSE(ret != HICN_ERROR_NONE) ) \
next0 = NEXT_ERROR_DROP_IP##ipv; \
else \
{ \
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
+ &counters[hicnb0->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_DATA_RX, \
1, \
@@ -232,26 +229,24 @@ typedef enum
(1-is_icmp1)*NEXT_DATA_IP##ipv; \
\
\
- ret0 = LOCK_FROM_LOCAL_IP##ipv \
- (&(hicnb0->face_dpo_id), \
+ ret0 = LOCK_DPO_FACE_IP##ipv \
+ (&(hicnb0->face_id), \
&(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
- &(ip_hdr0->dst_address), \
- vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
+ &(ip_hdr0->dst_address)); \
\
- ret1 = LOCK_FROM_LOCAL_IP##ipv \
- (&(hicnb1->face_dpo_id), \
+ ret1 = LOCK_DPO_FACE_IP##ipv \
+ (&(hicnb1->face_id), \
&(hicnb1->in_faces_vec_id), \
&hicnb1->flags, \
- &(ip_hdr1->dst_address), \
- vnet_buffer (b1)->sw_if_index[VLIB_RX]); \
+ &(ip_hdr1->dst_address)); \
\
if ( PREDICT_FALSE(ret0 != HICN_ERROR_NONE) ) \
next0 = NEXT_ERROR_DROP_IP##ipv; \
else \
{ \
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
+ &counters[hicnb0->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_DATA_RX, \
1, \
@@ -264,7 +259,7 @@ typedef enum
else \
{ \
vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
+ &counters[hicnb1->face_id \
* HICN_N_COUNTER], thread_index,\
HICN_FACE_COUNTERS_DATA_RX, \
1, \
@@ -307,8 +302,8 @@ typedef enum
static uword
-hicn_face_ip4_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+hicn4_face_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -345,12 +340,12 @@ hicn_face_ip4_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip4_input_format_trace (u8 * s, va_list * args)
+hicn4_face_input_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_face_ip4_input_trace_t *t =
- va_arg (*args, hicn_face_ip4_input_trace_t *);
+ hicn4_face_input_trace_t *t =
+ va_arg (*args, hicn4_face_input_trace_t *);
s = format (s, "FACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
(int) t->pkt_type, t->sw_if_index, t->next_index,
@@ -363,32 +358,32 @@ hicn_face_ip4_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip4_input_node) =
+VLIB_REGISTER_NODE(hicn4_face_input_node) =
{
- .function = hicn_face_ip4_input_node_fn,
- .name = "hicn-face-ip4-input",
+ .function = hicn4_face_input_node_fn,
+ .name = "hicn4-face-input",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip4_input_format_trace,
+ .format_trace = hicn4_face_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip4_input_error_strings),
- .error_strings = hicn_face_ip4_input_error_strings,
- .n_next_nodes = HICN_FACE_IP4_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN(hicn4_face_input_error_strings),
+ .error_strings = hicn4_face_input_error_strings,
+ .n_next_nodes = HICN4_FACE_INPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_FACE_IP4_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_IP4_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_IP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN4_FACE_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
+ [HICN4_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
+ [HICN4_FACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
/**
* @brief IPv6 face input node function
- * @see hicn_face_ip4_input_node_fn
+ * @see hicn6_face_input_node_fn
*/
static uword
-hicn_face_ip6_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+hicn6_face_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -426,12 +421,12 @@ hicn_face_ip6_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip6_input_format_trace (u8 * s, va_list * args)
+hicn6_face_input_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_face_ip6_input_trace_t *t =
- va_arg (*args, hicn_face_ip6_input_trace_t *);
+ hicn6_face_input_trace_t *t =
+ va_arg (*args, hicn6_face_input_trace_t *);
s = format (s, "FACE_IP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
(int) t->pkt_type, t->sw_if_index, t->next_index,
@@ -443,22 +438,22 @@ hicn_face_ip6_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip6_input_node) =
+VLIB_REGISTER_NODE(hicn6_face_input_node) =
{
- .function = hicn_face_ip6_input_node_fn,
- .name = "hicn-face-ip6-input",
+ .function = hicn6_face_input_node_fn,
+ .name = "hicn6-face-input",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip6_input_format_trace,
+ .format_trace = hicn6_face_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip6_input_error_strings),
- .error_strings = hicn_face_ip6_input_error_strings,
- .n_next_nodes = HICN_FACE_IP6_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN(hicn6_face_input_error_strings),
+ .error_strings = hicn6_face_input_error_strings,
+ .n_next_nodes = HICN6_FACE_INPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_FACE_IP6_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_IP6_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_IP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN6_FACE_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
+ [HICN6_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
+ [HICN6_FACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
@@ -467,87 +462,91 @@ VLIB_REGISTER_NODE(hicn_face_ip6_input_node) =
typedef enum
{
- HICN_FACE_IP4_NEXT_ECHO_REPLY = IP4_LOOKUP_N_NEXT,
- HICN_FACE_IP4_N_NEXT,
-} hicn_face_ip4_next_t;
+ HICN4_FACE_OUTPUT_NEXT_ECHO_REPLY,
+ HICN4_FACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN4_FACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN4_FACE_OUTPUT_N_NEXT,
+} hicn4_face_output_next_t;
typedef enum
{
- HICN_FACE_IP6_NEXT_ECHO_REPLY = IP6_LOOKUP_N_NEXT,
- HICN_FACE_IP6_N_NEXT,
-} hicn_face_ip6_next_t;
-
-static_always_inline void
-hicn_reply_probe_v4 (vlib_buffer_t * b, hicn_face_t * face)
-{
- hicn_header_t *h0 = vlib_buffer_get_current (b);
- hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data);
- h0->v4.ip.saddr = h0->v4.ip.daddr;
- h0->v4.ip.daddr = face_ip->local_addr.ip4;
- vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if;
-
- u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t) + sizeof(u16));
- u16 dst_port = *dst_port_ptr;
- u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t));
-
- *dst_port_ptr = *src_port_ptr;
- *src_port_ptr = dst_port;
-
- hicn_type_t type = hicn_get_buffer (b)->type;
- hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0);
-}
-
-static_always_inline void
-hicn_reply_probe_v6 (vlib_buffer_t * b, hicn_face_t * face)
-{
- hicn_header_t *h0 = vlib_buffer_get_current (b);
- hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data);
- h0->v6.ip.saddr = h0->v6.ip.daddr;
- h0->v6.ip.daddr = face_ip->local_addr.ip6;
- vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if;
-
- u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t) + sizeof(u16));
- u16 dst_port = *dst_port_ptr;
- u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t));
-
- *dst_port_ptr = *src_port_ptr;
- *src_port_ptr = dst_port;
-
- hicn_type_t type = hicn_get_buffer (b)->type;
- hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0);
-
-}
-
-static_always_inline u32
-hicn_face_match_probe (vlib_buffer_t * b, hicn_face_t * face, u32 * next)
-{
-
- u8 *ptr = vlib_buffer_get_current (b);
- u8 v = *ptr & 0xf0;
- u8 res = 0;
-
- if ( v == 0x40 )
- {
- u16 * dst_port = (u16 *)(ptr + sizeof(ip4_header_t) + sizeof(u16));
- if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT))
- {
- hicn_reply_probe_v6(b, face);
- *next = HICN_FACE_IP4_NEXT_ECHO_REPLY;
- res = 1;
- }
- }
- else if ( v == 0x60 )
- {
- u16 * dst_port = (u16 *)(ptr + sizeof(ip6_header_t) + sizeof(u16));
- if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT))
- {
- hicn_reply_probe_v6(b, face);
- *next = HICN_FACE_IP6_NEXT_ECHO_REPLY;
- res = 1;
- }
- }
- return res;
-}
+ HICN6_FACE_OUTPUT_NEXT_ECHO_REPLY,
+ HICN6_FACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN6_FACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN6_FACE_OUTPUT_N_NEXT,
+} hicn6_face_output_next_t;
+
+/* static_always_inline void */
+/* hicn_reply_probe_v4 (vlib_buffer_t * b, hicn_face_t * face) */
+/* { */
+/* hicn_header_t *h0 = vlib_buffer_get_current (b); */
+/* hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data); */
+/* h0->v4.ip.saddr = h0->v4.ip.daddr; */
+/* h0->v4.ip.daddr = face_ip->local_addr.ip4; */
+/* vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if; */
+
+/* u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t) + sizeof(u16)); */
+/* u16 dst_port = *dst_port_ptr; */
+/* u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t)); */
+
+/* *dst_port_ptr = *src_port_ptr; */
+/* *src_port_ptr = dst_port; */
+
+/* hicn_type_t type = hicn_get_buffer (b)->type; */
+/* hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0); */
+/* } */
+
+/* static_always_inline void */
+/* hicn_reply_probe_v6 (vlib_buffer_t * b, hicn_face_t * face) */
+/* { */
+/* hicn_header_t *h0 = vlib_buffer_get_current (b); */
+/* hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data); */
+/* h0->v6.ip.saddr = h0->v6.ip.daddr; */
+/* h0->v6.ip.daddr = face_ip->local_addr.ip6; */
+/* vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if; */
+
+/* u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t) + sizeof(u16)); */
+/* u16 dst_port = *dst_port_ptr; */
+/* u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t)); */
+
+/* *dst_port_ptr = *src_port_ptr; */
+/* *src_port_ptr = dst_port; */
+
+/* hicn_type_t type = hicn_get_buffer (b)->type; */
+/* hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0); */
+
+/* } */
+
+/* static_always_inline u32 */
+/* hicn_face_match_probe (vlib_buffer_t * b, hicn_face_t * face, u32 * next) */
+/* { */
+
+/* u8 *ptr = vlib_buffer_get_current (b); */
+/* u8 v = *ptr & 0xf0; */
+/* u8 res = 0; */
+
+/* if ( v == 0x40 ) */
+/* { */
+/* u16 * dst_port = (u16 *)(ptr + sizeof(ip4_header_t) + sizeof(u16)); */
+/* if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT)) */
+/* { */
+/* hicn_reply_probe_v6(b, face); */
+/* *next = HICN4_FACE_NEXT_ECHO_REPLY; */
+/* res = 1; */
+/* } */
+/* } */
+/* else if ( v == 0x60 ) */
+/* { */
+/* u16 * dst_port = (u16 *)(ptr + sizeof(ip6_header_t) + sizeof(u16)); */
+/* if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT)) */
+/* { */
+/* hicn_reply_probe_v6(b, face); */
+/* *next = HICN6_FACE_NEXT_ECHO_REPLY; */
+/* res = 1; */
+/* } */
+/* } */
+/* return res; */
+/* } */
static inline void
@@ -555,68 +554,37 @@ hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0,
hicn_face_t * face, u32 * next)
{
- if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) && hicn_face_match_probe(b0, face, next))
- return;
+ /* if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD) && hicn_face_match_probe(b0, face, next)) */
+ /* return; */
hicn_header_t *hicn = vlib_buffer_get_current (b0);
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ //hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
hicn_type_t type = hicn_get_buffer (b0)->type;
hicn_ops_vft[type.l1]->rewrite_interest (type, &hicn->protocol,
- &ip_face->local_addr, &temp_addr);
-
- int is_iface = 0;
- ip_adjacency_t *adj;
- if (PREDICT_FALSE (face->shared.adj == ~0))
- is_iface = 1;
- else
- adj = adj_get (face->shared.adj);
-
- /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
- * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
- * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
- */
- if (PREDICT_FALSE
- (is_iface || adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- fib_prefix_from_ip46_addr (&ip_face->remote_addr, &fib_pfx);
- fib_pfx.fp_len = ip46_address_is_ip4(&ip_face->remote_addr)? 32 : 128;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+ &face->nat_addr, &temp_addr);
- face->shared.adj = fib_entry_get_adj (fib_entry_index);
- face->shared.flags &= ~HICN_FACE_FLAGS_IFACE;
- face->shared.flags |= HICN_FACE_FLAGS_FACE;
-
- adj = adj_get (face->shared.adj);
-
- hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &ip_face->remote_addr, &temp_addr,
- 0);
- }
+ if (ip46_address_is_ip4(&face->nat_addr))
+ b0->flags |= VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
- *next = adj->lookup_next_index;
+ b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
+ ASSERT(face->flags & HICN_FACE_FLAGS_FACE);
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->dpo.dpoi_index;
+ *next = face->dpo.dpoi_next_node;
}
-static char *hicn_face_ip4_output_error_strings[] = {
+static char *hicn4_face_output_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
};
-static char *hicn_face_ip6_output_error_strings[] = {
+static char *hicn6_face_output_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
@@ -631,7 +599,7 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip4_output_trace_t;
+hicn4_face_output_trace_t;
/* Trace context struct */
typedef struct
@@ -641,16 +609,16 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip6_output_trace_t;
+hicn6_face_output_trace_t;
-#define TRACE_OUTPUT_PKT_IP4 hicn_face_ip4_output_trace_t
-#define TRACE_OUTPUT_PKT_IP6 hicn_face_ip6_output_trace_t
+#define TRACE_OUTPUT_PKT_IP4 hicn4_face_output_trace_t
+#define TRACE_OUTPUT_PKT_IP6 hicn6_face_output_trace_t
#define face_output_x1(ipv) \
do { \
vlib_buffer_t *b0; \
u32 bi0; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
+ u32 next0 = ~0; \
hicn_face_t * face; \
\
/* Prefetch for next iteration. */ \
@@ -712,8 +680,8 @@ hicn_face_ip6_output_trace_t;
do { \
vlib_buffer_t *b0, *b1; \
u32 bi0, bi1; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
- u32 next1 = IP_LOOKUP_NEXT_DROP; \
+ u32 next0 = ~0; \
+ u32 next1 = ~0; \
hicn_face_t *face0, *face1; \
\
/* Prefetch for next iteration. */ \
@@ -807,7 +775,7 @@ hicn_face_ip6_output_trace_t;
static uword
-hicn_face_ip4_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+hicn4_face_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -846,12 +814,12 @@ hicn_face_ip4_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip4_output_format_trace (u8 * s, va_list * args)
+hicn4_face_output_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_face_ip4_output_trace_t *t =
- va_arg (*args, hicn_face_ip4_output_trace_t *);
+ hicn4_face_output_trace_t *t =
+ va_arg (*args, hicn4_face_output_trace_t *);
s =
format (s, "FACE_IP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -864,38 +832,29 @@ hicn_face_ip4_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip4_output_node) =
+VLIB_REGISTER_NODE(hicn4_face_output_node) =
{
- .function = hicn_face_ip4_output_node_fn,
- .name = "hicn-face-ip4-output",
+ .function = hicn4_face_output_node_fn,
+ .name = "hicn4-face-output",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip4_output_format_trace,
+ .format_trace = hicn4_face_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip4_output_error_strings),
- .error_strings = hicn_face_ip4_output_error_strings,
- .n_next_nodes = HICN_FACE_IP4_N_NEXT,
+ .n_errors = ARRAY_LEN(hicn4_face_output_error_strings),
+ .error_strings = hicn4_face_output_error_strings,
+ .n_next_nodes = HICN4_FACE_OUTPUT_N_NEXT,
/* Reusing the list of nodes from lookup to be compatible with arp */
.next_nodes =
{
- [IP_LOOKUP_NEXT_DROP] = "ip4-drop",
- [IP_LOOKUP_NEXT_PUNT] = "ip4-punt",
- [IP_LOOKUP_NEXT_LOCAL] = "ip4-local",
- [IP_LOOKUP_NEXT_ARP] = "ip4-arp",
- [IP_LOOKUP_NEXT_GLEAN] = "ip4-glean",
- [IP_LOOKUP_NEXT_REWRITE] = "ip4-rewrite",
- [IP_LOOKUP_NEXT_MCAST] = "ip4-rewrite-mcast",
- [IP_LOOKUP_NEXT_BCAST] = "ip4-rewrite-bcast",
- [IP_LOOKUP_NEXT_MIDCHAIN] = "ip4-midchain",
- [IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip4-mcast-midchain",
- [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [HICN_FACE_IP4_NEXT_ECHO_REPLY] = "hicn-face-ip4-input",
+ [HICN4_FACE_OUTPUT_NEXT_ECHO_REPLY] = "hicn4-face-input",
+ [HICN4_FACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
+ [HICN4_FACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap"
}
};
/* *INDENT-ON* */
static uword
-hicn_face_ip6_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+hicn6_face_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -934,12 +893,12 @@ hicn_face_ip6_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip6_output_format_trace (u8 * s, va_list * args)
+hicn6_face_output_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_face_ip6_output_trace_t *t =
- va_arg (*args, hicn_face_ip6_output_trace_t *);
+ hicn6_face_output_trace_t *t =
+ va_arg (*args, hicn6_face_output_trace_t *);
s =
format (s, "FACE_IP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -952,34 +911,22 @@ hicn_face_ip6_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip6_output_node) =
+VLIB_REGISTER_NODE(hicn6_face_output_node) =
{
- .function = hicn_face_ip6_output_node_fn,
- .name = "hicn-face-ip6-output",
+ .function = hicn6_face_output_node_fn,
+ .name = "hicn6-face-output",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip6_output_format_trace,
+ .format_trace = hicn6_face_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip6_output_error_strings),
- .error_strings = hicn_face_ip6_output_error_strings,
- .n_next_nodes = HICN_FACE_IP6_N_NEXT,
+ .n_errors = ARRAY_LEN(hicn6_face_output_error_strings),
+ .error_strings = hicn6_face_output_error_strings,
+ .n_next_nodes = HICN6_FACE_OUTPUT_N_NEXT,
/* Reusing the list of nodes from lookup to be compatible with neighbour discovery */
.next_nodes =
{
- [IP_LOOKUP_NEXT_DROP] = "ip6-drop",
- [IP_LOOKUP_NEXT_PUNT] = "ip6-punt",
- [IP_LOOKUP_NEXT_LOCAL] = "ip6-local",
- [IP_LOOKUP_NEXT_ARP] = "ip6-discover-neighbor",
- [IP_LOOKUP_NEXT_GLEAN] = "ip6-glean",
- [IP_LOOKUP_NEXT_REWRITE] = "ip6-rewrite",
- [IP_LOOKUP_NEXT_BCAST] = "ip6-rewrite-bcast",
- [IP_LOOKUP_NEXT_MCAST] = "ip6-rewrite-mcast",
- [IP_LOOKUP_NEXT_MIDCHAIN] = "ip6-midchain",
- [IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip6-mcast-midchain",
- [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip6-icmp-error",
- [IP6_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",
- [IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",
- [IP6_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",
- [HICN_FACE_IP6_NEXT_ECHO_REPLY] = "hicn-face-ip6-input"
+ [HICN6_FACE_OUTPUT_NEXT_ECHO_REPLY] = "hicn6-face-input",
+ [HICN6_FACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
+ [HICN6_FACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap"
}
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/face_node.h b/hicn-plugin/src/faces/face_node.h
new file mode 100644
index 000000000..f5a8bf5ae
--- /dev/null
+++ b/hicn-plugin/src/faces/face_node.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 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_FACE_NODE_H__
+#define __HICN_FACE_NODE_H__
+
+#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;
+extern vlib_node_registration_t hicn6_face_output_node;
+
+#endif // __HICN_FACE_NODE_H__
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/hicn-plugin/src/faces/ip/iface_ip_node.c b/hicn-plugin/src/faces/iface_node.c
index 8adef50d9..433cf0b02 100644
--- a/hicn-plugin/src/faces/ip/iface_ip_node.c
+++ b/hicn-plugin/src/faces/iface_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 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:
@@ -13,13 +13,11 @@
* limitations under the License.
*/
-#include "face_ip.h"
-#include "dpo_ip.h"
-#include "../../strategy_dpo_manager.h"
-#include "../face.h"
-#include "../../hicn.h"
-#include "../../infra.h"
-#include "../../cache_policies/cs_lru.h"
+#include "face.h"
+#include "../strategy_dpo_manager.h"
+#include "../hicn.h"
+#include "../infra.h"
+#include "../cache_policies/cs_lru.h"
/**
* @File
@@ -27,43 +25,21 @@
* Definition of the nodes for ip incomplete faces.
*/
-vlib_node_registration_t hicn_iface_ip4_input_node;
-vlib_node_registration_t hicn_iface_ip4_output_node;
-vlib_node_registration_t hicn_iface_ip6_input_node;
-vlib_node_registration_t hicn_iface_ip6_output_node;
+vlib_node_registration_t hicn4_iface_input_node;
+vlib_node_registration_t hicn4_iface_output_node;
+vlib_node_registration_t hicn6_iface_input_node;
+vlib_node_registration_t hicn6_iface_output_node;
u32 data_fwd_iface_ip4_vlib_edge;
u32 data_fwd_iface_ip6_vlib_edge;
-void
-hicn_iface_ip_init (vlib_main_t * vm)
-{
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_ip4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_ip6_output_node.index);
-
- data_fwd_iface_ip4_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_ip4_output_node.index);
-
- data_fwd_iface_ip6_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_ip6_output_node.index);
-
- ASSERT (temp_index4 == data_fwd_iface_ip4_vlib_edge);
- ASSERT (temp_index6 == data_fwd_iface_ip6_vlib_edge);
-}
-
-static char *hicn_iface_ip4_input_error_strings[] = {
+static char *hicn4_iface_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
};
-static char *hicn_iface_ip6_input_error_strings[] = {
+static char *hicn6_iface_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
@@ -76,15 +52,15 @@ typedef struct
u32 sw_if_index;
u8 pkt_type;
u8 packet_data[60];
-} hicn_iface_ip4_input_trace_t;
+} hicn4_iface_input_trace_t;
typedef enum
{
- HICN_IFACE_IP4_INPUT_NEXT_INTEREST,
- HICN_IFACE_IP4_INPUT_NEXT_MAPME,
- HICN_IFACE_IP4_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP4_INPUT_N_NEXT,
-} hicn_iface_ip4_input_next_t;
+ HICN4_IFACE_INPUT_NEXT_INTEREST,
+ HICN4_IFACE_INPUT_NEXT_MAPME,
+ HICN4_IFACE_INPUT_NEXT_ERROR_DROP,
+ HICN4_IFACE_INPUT_N_NEXT,
+} hicn4_iface_input_next_t;
/* Trace context struct */
typedef struct
@@ -93,21 +69,21 @@ typedef struct
u32 sw_if_index;
u8 pkt_type;
u8 packet_data[60];
-} hicn_iface_ip6_input_trace_t;
+} hicn6_iface_input_trace_t;
typedef enum
{
- HICN_IFACE_IP6_INPUT_NEXT_INTEREST,
- HICN_IFACE_IP6_INPUT_NEXT_MAPME,
- HICN_IFACE_IP6_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP6_INPUT_N_NEXT,
-} hicn_iface_ip6_input_next_t;
+ HICN6_IFACE_INPUT_NEXT_INTEREST,
+ HICN6_IFACE_INPUT_NEXT_MAPME,
+ HICN6_IFACE_INPUT_NEXT_ERROR_DROP,
+ HICN6_IFACE_INPUT_N_NEXT,
+} hicn6_iface_input_next_t;
-#define NEXT_MAPME_IP4 HICN_IFACE_IP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_IP6 HICN_IFACE_IP6_INPUT_NEXT_MAPME
+#define NEXT_MAPME_IP4 HICN4_IFACE_INPUT_NEXT_MAPME
+#define NEXT_MAPME_IP6 HICN6_IFACE_INPUT_NEXT_MAPME
-#define NEXT_INTEREST_IP4 HICN_IFACE_IP6_INPUT_NEXT_INTEREST
-#define NEXT_INTEREST_IP6 HICN_IFACE_IP6_INPUT_NEXT_INTEREST
+#define NEXT_INTEREST_IP4 HICN4_IFACE_INPUT_NEXT_INTEREST
+#define NEXT_INTEREST_IP6 HICN6_IFACE_INPUT_NEXT_INTEREST
#define ADDRESS_IP4 ip_interface_address_t *ia = 0;ip4_address_t *local_address = ip4_interface_first_address(&ip4_main, swif, &ia)
#define ADDRESS_IP6 ip6_address_t *local_address = ip6_interface_first_address(&ip6_main, swif)
@@ -119,25 +95,90 @@ 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_IP4 hicn_dpo_ip4_add_and_lock_from_remote
-#define DPO_ADD_LOCK_IP6 hicn_dpo_ip6_add_and_lock_from_remote
+#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
+//#define VLIB_EDGE_IP4 data_fwd_iface_ip4_vlib_edge
+//#define VLIB_EDGE_IP6 data_fwd_iface_ip6_vlib_edge
#define IP_HEADER_4 ip4_header_t
#define IP_HEADER_6 ip6_header_t
-#define TRACE_INPUT_PKT_IP4 hicn_iface_ip4_input_trace_t
-#define TRACE_INPUT_PKT_IP6 hicn_iface_ip6_input_trace_t
+#define TRACE_INPUT_PKT_IP4 hicn4_iface_input_trace_t
+#define TRACE_INPUT_PKT_IP6 hicn6_iface_input_trace_t
+
+// NODE OUTPUT
+
+static char *hicn4_iface_output_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnfwd_error
+#undef _
+};
+
+static char *hicn6_iface_output_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnfwd_error
+#undef _
+};
+
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u8 packet_data[60];
+} hicn4_iface_output_trace_t;
+
+typedef enum
+{
+ HICN4_IFACE_OUTPUT_NEXT_LOOKUP,
+ HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN4_IFACE_OUTPUT_N_NEXT,
+} hicn4_iface_output_next_t;
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u8 packet_data[60];
+} hicn6_iface_output_trace_t;
+
+typedef enum
+{
+ HICN6_IFACE_OUTPUT_NEXT_LOOKUP,
+ HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN6_IFACE_OUTPUT_N_NEXT,
+} hicn6_iface_output_next_t;
+
+//#define ERROR_OUTPUT_IP4 HICN4_IFACE_OUTPUT_NEXT_ERROR_DROP
+//#define ERROR_OUTPUT_IP6 HICN6_IFACE_OUTPUT_NEXT_ERROR_DROP
+
+#define NEXT_DATA_LOOKUP_IP4 HICN4_IFACE_OUTPUT_NEXT_LOOKUP
+#define NEXT_DATA_LOOKUP_IP6 HICN6_IFACE_OUTPUT_NEXT_LOOKUP
+
+#define NEXT_UDP_ENCAP_IP4 HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP
+#define NEXT_UDP_ENCAP_IP6 HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP
+
+#define HICN_REWRITE_DATA_IP4 hicn_rewrite_iface_data4
+#define HICN_REWRITE_DATA_IP6 hicn_rewrite_iface_data6
+
+#define TRACE_OUTPUT_PKT_IP4 hicn4_iface_output_trace_t
+#define TRACE_OUTPUT_PKT_IP6 hicn6_iface_output_trace_t
+
+// NODES IMPLEMENTATIONS
#define iface_input_x1(ipv) \
do { \
vlib_buffer_t *b0; \
- u32 bi0, next0; \
+ u32 bi0, next0, next_iface0; \
IP_HEADER_##ipv * ip_hdr = NULL; \
hicn_buffer_t * hicnb0; \
- u32 swif; \
/* Prefetch for next iteration. */ \
if (n_left_from > 1) \
{ \
@@ -165,17 +206,20 @@ typedef enum
next0 = is_icmp*NEXT_MAPME_IP##ipv + \
(1-is_icmp)*NEXT_INTEREST_IP##ipv; \
\
- swif = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
\
- ADDRESS_IP##ipv; \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ else if(hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
\
- DPO_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &hicnb0->flags, \
- local_address, \
- &(ip_hdr->src_address), \
- vnet_buffer(b0)->sw_if_index[VLIB_RX], \
- VLIB_EDGE_IP##ipv); \
+ DPO_ADD_LOCK_IFACE_IP##ipv \
+ (&(hicnb0->face_id), \
+ &hicnb0->flags, \
+ &(ip_hdr->src_address), \
+ vnet_buffer(b0)->sw_if_index[VLIB_RX], \
+ vnet_buffer(b0)->ip.adj_index[VLIB_RX], \
+ next_iface0); \
\
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
(b0->flags & VLIB_BUFFER_IS_TRACED))) \
@@ -192,11 +236,11 @@ typedef enum
} \
\
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index, \
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
+ &counters[hicnb0->face_id \
+ * HICN_N_COUNTER], thread_index, \
+ HICN_FACE_COUNTERS_INTEREST_RX, \
+ 1, \
+ vlib_buffer_length_in_chain(vm, b0)); \
\
/* Verify speculative enqueue, maybe switch current next frame */ \
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, \
@@ -208,11 +252,10 @@ typedef enum
#define iface_input_x2(ipv) \
do { \
vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1, next0, next1; \
+ u32 bi0, bi1, next0, next1, next_iface0, next_iface1; \
IP_HEADER_##ipv * ip_hdr0 = NULL; \
IP_HEADER_##ipv * ip_hdr1 = NULL; \
hicn_buffer_t *hicnb0, *hicnb1; \
- u32 swif0, swif1; \
\
/* Prefetch for next iteration. */ \
vlib_buffer_t *b2, *b3; \
@@ -251,26 +294,35 @@ typedef enum
next1 = is_icmp1*NEXT_MAPME_IP##ipv + \
(1-is_icmp1)*NEXT_INTEREST_IP##ipv; \
\
- swif0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- swif1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ else if(hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
\
- ADDRESSX2_IP##ipv; \
+ next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \
\
- DPO_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
+ if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \
+ next_iface1 = NEXT_UDP_ENCAP_IP4; \
+ else if(hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \
+ next_iface1 = NEXT_UDP_ENCAP_IP6; \
+ \
+ DPO_ADD_LOCK_IFACE_IP##ipv \
+ (&(hicnb0->face_id), \
&hicnb0->flags, \
- local_address0, \
&(ip_hdr0->src_address), \
vnet_buffer(b0)->sw_if_index[VLIB_RX], \
- VLIB_EDGE_IP##ipv); \
+ vnet_buffer(b0)->ip.adj_index[VLIB_RX], \
+ next_iface0); \
\
- DPO_ADD_LOCK_IP##ipv \
- (&(hicnb1->face_dpo_id), \
+ DPO_ADD_LOCK_IFACE_IP##ipv \
+ (&(hicnb1->face_id), \
&hicnb1->flags, \
- local_address1, \
&(ip_hdr1->src_address), \
vnet_buffer(b1)->sw_if_index[VLIB_RX], \
- VLIB_EDGE_IP##ipv); \
+ vnet_buffer(b1)->ip.adj_index[VLIB_RX], \
+ next_iface1); \
\
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
(b0->flags & VLIB_BUFFER_IS_TRACED))) \
@@ -299,14 +351,14 @@ typedef enum
} \
\
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
+ &counters[hicnb0->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_INTEREST_RX, \
1, \
vlib_buffer_length_in_chain(vm, b0)); \
\
vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
+ &counters[hicnb1->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_INTEREST_RX, \
1, \
@@ -319,7 +371,7 @@ typedef enum
}while(0)
static uword
-hicn_iface_ip4_input_node_fn (vlib_main_t * vm,
+hicn4_iface_input_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -359,12 +411,12 @@ hicn_iface_ip4_input_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip4_input_format_trace (u8 * s, va_list * args)
+hicn4_iface_input_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_iface_ip4_input_trace_t *t =
- va_arg (*args, hicn_iface_ip4_input_trace_t *);
+ hicn4_iface_input_trace_t *t =
+ va_arg (*args, hicn4_iface_input_trace_t *);
s =
format (s, "IFACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -377,28 +429,28 @@ hicn_iface_ip4_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip4_input_node) =
+VLIB_REGISTER_NODE (hicn4_iface_input_node) =
{
- .function = hicn_iface_ip4_input_node_fn,
- .name = "hicn-iface-ip4-input",
+ .function = hicn4_iface_input_node_fn,
+ .name = "hicn4-iface-input",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip4_input_format_trace,
+ .format_trace = hicn4_iface_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip4_input_error_strings),
- .error_strings = hicn_iface_ip4_input_error_strings,
- .n_next_nodes = HICN_IFACE_IP4_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn4_iface_input_error_strings),
+ .error_strings = hicn4_iface_input_error_strings,
+ .n_next_nodes = HICN4_IFACE_INPUT_N_NEXT,
/* edit / add dispositions*/
.next_nodes =
{
- [HICN_IFACE_IP4_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_IP4_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_IP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN4_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
+ [HICN4_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
+ [HICN4_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
static uword
-hicn_iface_ip6_input_node_fn (vlib_main_t * vm,
+hicn6_iface_input_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -439,12 +491,12 @@ hicn_iface_ip6_input_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip6_input_format_trace (u8 * s, va_list * args)
+hicn6_iface_input_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_iface_ip6_input_trace_t *t =
- va_arg (*args, hicn_iface_ip6_input_trace_t *);
+ hicn6_iface_input_trace_t *t =
+ va_arg (*args, hicn6_iface_input_trace_t *);
s =
format (s, "IFACE_IP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -457,22 +509,22 @@ hicn_iface_ip6_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip6_input_node) =
+VLIB_REGISTER_NODE (hicn6_iface_input_node) =
{
- .function = hicn_iface_ip6_input_node_fn,
- .name = "hicn-iface-ip6-input",
+ .function = hicn6_iface_input_node_fn,
+ .name = "hicn6-iface-input",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip6_input_format_trace,
+ .format_trace = hicn6_iface_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip6_input_error_strings),
- .error_strings = hicn_iface_ip6_input_error_strings,
- .n_next_nodes = HICN_IFACE_IP6_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn6_iface_input_error_strings),
+ .error_strings = hicn6_iface_input_error_strings,
+ .n_next_nodes = HICN6_IFACE_INPUT_N_NEXT,
/* edit / add dispositions*/
.next_nodes =
{
- [HICN_IFACE_IP6_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_IP6_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_IP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN6_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
+ [HICN6_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
+ [HICN6_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
@@ -482,7 +534,7 @@ VLIB_REGISTER_NODE (hicn_iface_ip6_input_node) =
static inline void
hicn_rewrite_iface_data4 (vlib_main_t * vm, vlib_buffer_t * b0,
- const hicn_face_t * iface)
+ const hicn_face_t * iface, u32 * next)
{
ip4_header_t *ip0;
@@ -495,21 +547,21 @@ hicn_rewrite_iface_data4 (vlib_main_t * vm, vlib_buffer_t * b0,
ip0->length = clib_host_to_net_u16 (sval);
ip0->ttl = 254; // FIXME TTL
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ~0;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = iface->dpo.dpoi_index;
+ *next = iface->dpo.dpoi_next_node;
hicn_header_t *hicn = vlib_buffer_get_current (b0);
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
- hicn_face_ip_t *iface_ip = (hicn_face_ip_t *) iface->data;
hicn_type_t type = hicn_get_buffer (b0)->type;
hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &(iface_ip->remote_addr), &(temp_addr),
- iface->shared.pl_id);
+ &(iface->nat_addr), &(temp_addr),
+ iface->pl_id);
}
static inline void
hicn_rewrite_iface_data6 (vlib_main_t * vm, vlib_buffer_t * b0,
- const hicn_face_t * iface)
+ const hicn_face_t * iface, u32 * next)
{
ip6_header_t *ip0;
@@ -523,80 +575,24 @@ hicn_rewrite_iface_data6 (vlib_main_t * vm, vlib_buffer_t * b0,
ip0->payload_length = clib_host_to_net_u16 (sval);
ip0->hop_limit = HICN_IP6_HOP_LIMIT;
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ~0;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = iface->dpo.dpoi_index;
+ *next = iface->dpo.dpoi_next_node;
+
hicn_header_t *hicn = vlib_buffer_get_current (b0);
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
- hicn_face_ip_t *iface_ip = (hicn_face_ip_t *) iface->data;
hicn_type_t type = hicn_get_buffer (b0)->type;
hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &(iface_ip->remote_addr), &(temp_addr),
- iface->shared.pl_id);
+ &(iface->nat_addr), &(temp_addr),
+ iface->pl_id);
}
-static char *hicn_iface_ip4_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_iface_ip6_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-} hicn_iface_ip4_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_IP4_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_IP4_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP4_OUTPUT_N_NEXT,
-} hicn_iface_ip4_output_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-} hicn_iface_ip6_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_IP6_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_IP6_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP6_OUTPUT_N_NEXT,
-} hicn_iface_ip6_output_next_t;
-
-#define ERROR_OUTPUT_IP4 HICN_IFACE_IP4_OUTPUT_NEXT_ERROR_DROP
-#define ERROR_OUTPUT_IP6 HICN_IFACE_IP6_OUTPUT_NEXT_ERROR_DROP
-
-#define NEXT_DATA_LOOKUP_IP4 HICN_IFACE_IP4_OUTPUT_NEXT_LOOKUP
-#define NEXT_DATA_LOOKUP_IP6 HICN_IFACE_IP6_OUTPUT_NEXT_LOOKUP
-
-#define HICN_REWRITE_DATA_IP4 hicn_rewrite_iface_data4
-#define HICN_REWRITE_DATA_IP6 hicn_rewrite_iface_data6
-
-#define TRACE_OUTPUT_PKT_IP4 hicn_iface_ip4_output_trace_t
-#define TRACE_OUTPUT_PKT_IP6 hicn_iface_ip6_output_trace_t
-
#define iface_output_x1(ipv) \
do { \
vlib_buffer_t *b0; \
u32 bi0; \
- u32 next0 = ERROR_OUTPUT_IP##ipv; \
+ u32 next0 = next_index; \
hicn_face_t * face; \
\
/* Prefetch for next iteration. */ \
@@ -624,8 +620,7 @@ typedef enum
if (PREDICT_TRUE(face != NULL)) \
{ \
HICN_REWRITE_DATA_IP##ipv \
- (vm, b0, face); \
- next0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ (vm, b0, face, &next0); \
stats.pkts_data_count += 1; \
vlib_increment_combined_counter ( \
&counters[face_id * HICN_N_COUNTER], \
@@ -660,8 +655,8 @@ typedef enum
do { \
vlib_buffer_t *b0, *b1; \
u32 bi0, bi1; \
- u32 next0 = ERROR_OUTPUT_IP##ipv; \
- u32 next1 = ERROR_OUTPUT_IP##ipv; \
+ u32 next0 = next_index; \
+ u32 next1 = next_index; \
hicn_face_t *face0, *face1; \
\
/* Prefetch for next iteration. */ \
@@ -698,8 +693,7 @@ typedef enum
if (PREDICT_TRUE(face0 != NULL)) \
{ \
HICN_REWRITE_DATA_IP##ipv \
- (vm, b0, face0); \
- next0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ (vm, b0, face0, &next0); \
stats.pkts_data_count += 1; \
vlib_increment_combined_counter ( \
&counters[face_id0 * HICN_N_COUNTER], \
@@ -712,8 +706,7 @@ typedef enum
if (PREDICT_TRUE(face1 != NULL)) \
{ \
HICN_REWRITE_DATA_IP##ipv \
- (vm, b1, face1); \
- next1 = NEXT_DATA_LOOKUP_IP##ipv; \
+ (vm, b1, face1, &next1); \
stats.pkts_data_count += 1; \
vlib_increment_combined_counter ( \
&counters[face_id1 * HICN_N_COUNTER], \
@@ -759,7 +752,7 @@ typedef enum
static uword
-hicn_iface_ip4_output_node_fn (vlib_main_t * vm,
+hicn4_iface_output_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -797,12 +790,12 @@ hicn_iface_ip4_output_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip4_output_format_trace (u8 * s, va_list * args)
+hicn4_iface_output_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_iface_ip4_output_trace_t *t =
- va_arg (*args, hicn_iface_ip4_output_trace_t *);
+ hicn4_iface_output_trace_t *t =
+ va_arg (*args, hicn4_iface_output_trace_t *);
s =
format (s, "IFACE_IP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -815,28 +808,29 @@ hicn_iface_ip4_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip4_output_node) =
+VLIB_REGISTER_NODE (hicn4_iface_output_node) =
{
- .function = hicn_iface_ip4_output_node_fn,
- .name = "hicn-iface-ip4-output",
+ .function = hicn4_iface_output_node_fn,
+ .name = "hicn4-iface-output",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip4_output_format_trace,
+ .format_trace = hicn4_iface_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip4_output_error_strings),
- .error_strings = hicn_iface_ip4_output_error_strings,
- .n_next_nodes = HICN_IFACE_IP4_OUTPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn4_iface_output_error_strings),
+ .error_strings = hicn4_iface_output_error_strings,
+ .n_next_nodes = HICN4_IFACE_OUTPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_IFACE_IP4_OUTPUT_NEXT_LOOKUP] = "ip4-lookup",
- [HICN_IFACE_IP4_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN4_IFACE_OUTPUT_NEXT_LOOKUP] = "ip4-lookup",
+ [HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
+ [HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap"
},
};
/* *INDENT-ON* */
static uword
-hicn_iface_ip6_output_node_fn (vlib_main_t * vm,
+hicn6_iface_output_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -873,12 +867,12 @@ hicn_iface_ip6_output_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip6_output_format_trace (u8 * s, va_list * args)
+hicn6_iface_output_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_iface_ip6_output_trace_t *t =
- va_arg (*args, hicn_iface_ip6_output_trace_t *);
+ hicn6_iface_output_trace_t *t =
+ va_arg (*args, hicn6_iface_output_trace_t *);
s =
format (s, "IFACE_IP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -891,21 +885,23 @@ hicn_iface_ip6_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip6_output_node) =
+VLIB_REGISTER_NODE (hicn6_iface_output_node) =
{
- .function = hicn_iface_ip6_output_node_fn,
- .name = "hicn-iface-ip6-output",
+ .function = hicn6_iface_output_node_fn,
+ .name = "hicn6-iface-output",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip6_output_format_trace,
+ .format_trace = hicn6_iface_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip6_output_error_strings),
- .error_strings = hicn_iface_ip6_output_error_strings,
- .n_next_nodes = HICN_IFACE_IP6_OUTPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn6_iface_output_error_strings),
+ .error_strings = hicn6_iface_output_error_strings,
+ .n_next_nodes = HICN6_IFACE_OUTPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_IFACE_IP6_OUTPUT_NEXT_LOOKUP] = "ip6-lookup",
- [HICN_IFACE_IP6_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN6_IFACE_OUTPUT_NEXT_LOOKUP] = "ip6-lookup",
+ [HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap",
+ [HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap"
+
},
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/iface_node.h b/hicn-plugin/src/faces/iface_node.h
new file mode 100644
index 000000000..1a7c4291b
--- /dev/null
+++ b/hicn-plugin/src/faces/iface_node.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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_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_init (vlib_main_t * vm);
+
+#endif // __HICN_IFACE_IP_NODE_H__
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.c b/hicn-plugin/src/faces/ip/dpo_ip.c
deleted file mode 100644
index d05fec1a0..000000000
--- a/hicn-plugin/src/faces/ip/dpo_ip.c
+++ /dev/null
@@ -1,90 +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 "dpo_ip.h"
-
-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",
- "hicn-iface-ip4-input",
- "hicn-iface-ip4-output",
- NULL,
-};
-
-const static char *const hicn_face_ip6dpoi_nodes[] = {
- "hicn-face-ip6-input",
- "hicn-face-ip6-output",
- "hicn-iface-ip6-input",
- "hicn-iface-ip6-output",
- NULL,
-};
-
-const static char *const *const hicn_ip_nodes[DPO_PROTO_NUM] = {
- [DPO_PROTO_IP4] = hicn_face_ip4dpoi_nodes,
- [DPO_PROTO_IP6] = hicn_face_ip6dpoi_nodes
-};
-
-const static dpo_vft_t hicn_face_ip_vft = {
- .dv_lock = hicn_face_lock,
- .dv_unlock = hicn_face_unlock,
- .dv_format = format_hicn_face_ip,
-};
-
-/* Must be executed after all the strategy nodes are created */
-void
-hicn_dpo_ip_module_init (void)
-{
- mhash_init (&hicn_face_ip_local_hashtb,
- 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.
- */
- hicn_face_ip_type =
- dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes);
-}
-
-void
-hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node)
-{
- hicn_face_id_t face_dpoi_id = hicn_dpoi_get_index (face);
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- dpo_set (dpo, face->shared.face_type,
- ip46_address_is_ip4 (&ip_face->local_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6, face_dpoi_id);
- dpo->dpoi_next_node = dpoi_next_node;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.h b/hicn-plugin/src/faces/ip/dpo_ip.h
deleted file mode 100644
index c893c8be4..000000000
--- a/hicn-plugin/src/faces/ip/dpo_ip.h
+++ /dev/null
@@ -1,288 +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.
- */
-
-#ifndef __HICN_DPO_IP_H__
-#define __HICN_DPO_IP_H__
-
-#include <vnet/vnet.h>
-#include <vnet/ip/ip4_packet.h>
-
-#include "face_ip.h"
-#include "../face.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 local 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_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)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- 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 (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;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, in_faces_vec->face_id);
- dpo->dpoi_next_node = ~0;
- dpo_unlock (dpo);
-
- 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 local_addr: Ip v6 local 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_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)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- 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 (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;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, in_faces_vec->face_id);
- dpo->dpoi_next_node = ~0;
- dpo_unlock (dpo);
-
- return HICN_ERROR_NONE;
-}
-
-
-/**
- * @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 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 node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_ip4_add_and_lock_from_remote (dpo_id_t * dpo,
- u8 * hicnb_flags,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u32 sw_if, u32 node_index)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- /*All (complete) faces are indexed by remote addess as well */
- hicn_face_t *face =
- hicn_face_ip4_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- if (face == NULL)
- {
- hicn_face_id_t dpoi_index;
- ip46_address_t local_addr46 = to_ip46 (0, (u8 *) local_addr);
- ip46_address_t remote_addr46 = to_ip46 (0, (u8 *) remote_addr);
- hicn_iface_ip_add (&local_addr46, &remote_addr46, sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
-
- /* Code replicated on purpose */
- *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->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-/**
- * @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 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 node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_ip6_add_and_lock_from_remote (dpo_id_t * dpo,
- u8 * hicnb_flags,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u32 sw_if, u32 node_index)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- /*All (complete) faces are indexed by remote addess as well */
- hicn_face_t *face =
- hicn_face_ip6_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- if (face == NULL)
- {
- hicn_face_id_t dpoi_index;
- hicn_iface_ip_add ((ip46_address_t *) local_addr,
- (ip46_address_t *) remote_addr, sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
- /* Code replicated on purpose */
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |=
- (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- index_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (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 a dpo from an ip face
- *
- * @param face Face from which to create the dpo
- * @param dpoi_next_node Edge index that connects a node to the iface or face nodes
- * @return the dpo
- */
-void hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node);
-
-#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/ip/face_ip.c b/hicn-plugin/src/faces/ip/face_ip.c
deleted file mode 100644
index a2fe069ed..000000000
--- a/hicn-plugin/src/faces/ip/face_ip.c
+++ /dev/null
@@ -1,571 +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 <vnet/adj/adj_midchain.h>
-#include <vnet/adj/adj.h>
-
-#include "face_ip.h"
-#include "face_ip_node.h"
-#include "dpo_ip.h"
-#include "../../strategy_dpo_manager.h"
-#include "../face.h"
-#include "../../cache_policies/cs_lru.h"
-#include "../../infra.h"
-#include "../../hicn.h"
-#include "../app/face_prod.h"
-#include "../app/face_cons.h"
-
-#include "../../mapme.h" // HICN_MAPME_EVENT_*
-#include "../../mapme_eventmgr.h" // hicn_mapme_eventmgr_process_node
-
-extern vlib_node_registration_t hicn_mapme_eventmgr_process_node;
-
-u32 strategy_face_ip4_vlib_edge;
-u32 strategy_face_ip6_vlib_edge;
-
-void
-hicn_face_ip_init (vlib_main_t * vm)
-{
- int strategy_nodes_n = hicn_strategy_get_all_available ();
-
- /* Default Strategy has index 0 and it always exists */
- strategy_face_ip4_vlib_edge = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip4_output_node.index);
-
- strategy_face_ip6_vlib_edge = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip6_output_node.index);
- /*
- * Create and edge between al the other strategy nodes and the
- * ip_encap nodes.
- */
- for (int i = 1; i < strategy_nodes_n; i++)
- {
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip6_output_node.index);
- ASSERT (temp_index4 == strategy_face_ip4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_ip6_vlib_edge);
- }
-
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_ip4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_ip6_output_node.index);
-
- ASSERT (temp_index4 == strategy_face_ip4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_ip6_vlib_edge);
-
-
- hicn_dpo_ip_module_init ();
-
- register_face_type (hicn_face_ip_type, &ip_vft, "ip");
-}
-
-int
-hicn_face_ip_del (hicn_face_id_t face_id)
-{
- hicn_face_t *face = hicn_dpoi_get_from_idx (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);
- 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);
-
- 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,
- const struct ip_adjacency_t_ *adj,
- vlib_buffer_t * b0, const void *data)
-{
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
-};
-
-/**
- * @brief Build a rewrite string for the face.
- */
-static u8 *
-face_build_rewrite_i (void)
-{
- /*
- * 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;
-
- 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);
-
- if (*adj == ADJ_INDEX_INVALID)
- {
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_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_MIDCHAIN)
- {
- 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);
- }
- }
-
- return HICN_ERROR_NONE;
-}
-
-/*
- * 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;
-
- /* 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;
-
- hicn_face_t *face;
- if (ip46_address_is_ip4 (local_addr))
- {
- face =
- hicn_face_ip4_get (&(remote_addr->ip4), sw_if,
- &hicn_face_ip_remote_hashtb);
-
- /* 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);
- face = hicn_dpoi_get_from_idx (*pfaceid);
- }
- else
- {
- *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);
-
- 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 (&(remote_addr->ip6), sw_if,
- &hicn_face_ip_remote_hashtb);
-
- /* If remote matches the face is a iface */
- if (face == NULL)
- {
- hicn_iface_ip_add (local_addr, remote_addr, sw_if, pfaceid);
- face = hicn_dpoi_get_from_idx (*pfaceid);
- }
- else
- {
- *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);
-
- 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 (),
- hicn_mapme_eventmgr_process_node.index,
- HICN_MAPME_EVENT_FACE_ADD, 1,
- sizeof (retx_t));
-
- /* *INDENT-OFF* */
- *retx = (retx_t)
- {
- .prefix = 0,
- .dpo = (dpo_id_t)
- {
- .dpoi_type = hicn_face_ip_type,
- .dpoi_proto = dpo_proto,
- .dpoi_next_node = 0,
- .dpoi_index = *pfaceid,
- }
- };
- /* *INDENT-ON* */
-
- return HICN_ERROR_NONE;
-}
-
-u8 *
-format_hicn_face_ip (u8 * s, va_list * args)
-{
- index_t index = va_arg (*args, index_t);
- CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
- hicn_face_t *face;
- hicn_face_ip_t *ip_face;
- ip_adjacency_t *adj;
- vnet_main_t *vnm = vnet_get_main ();
-
- face = hicn_dpoi_get_from_idx (index);
- ip_face = (hicn_face_ip_t *) face->data;
-
- if (face->shared.flags & HICN_FACE_FLAGS_FACE)
- {
- ASSERT (face->shared.adj != (adj_index_t) ~ 0);
- adj = adj_get (face->shared.adj);
-
- hicn_face_id_t face_id = hicn_dpoi_get_index (face);
- s = format (s, "%U Face %d: ", format_white_space, indent, face_id);
- s = format (s, "type IP local %U ",
- format_ip46_address, &ip_face->local_addr, IP46_TYPE_ANY);
- s =
- format (s, "remote %U ", format_ip46_address, &ip_face->remote_addr,
- IP46_TYPE_ANY);
- s = format (s, "%U", format_vnet_link, adj->ia_link);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm, sw_int);
-
-
- if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD))
- s = format (s, " %U", format_hicn_face_prod, face_id, 0);
- else if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS))
- s = format (s, " %U", format_hicn_face_cons, face_id, 0);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- else
- {
- hicn_face_id_t face_id = hicn_dpoi_get_index (face);
- s = format (s, "%U iFace %d: ", format_white_space, indent, face_id);
- s = format (s, "type IP local %U remote %U",
- format_ip46_address, &ip_face->local_addr, IP46_TYPE_ANY,
- format_ip46_address, &ip_face->remote_addr, IP46_TYPE_ANY);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm, sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD))
- s = format (s, " %U", format_hicn_face_prod, face_id, 0);
- else if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS))
- s = format (s, " %U", format_hicn_face_cons, face_id, 0);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
-
- return s;
-}
-
-void
-hicn_face_ip_get_dpo (hicn_face_t * face, dpo_id_t * dpo)
-{
-
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- return hicn_dpo_ip_create_from_face (face, dpo,
- ip46_address_is_ip4
- (&face_ip->remote_addr) ?
- strategy_face_ip4_vlib_edge :
- strategy_face_ip6_vlib_edge);
-}
-
-hicn_face_vft_t ip_vft = {
- .format_face = format_hicn_face_ip,
- .hicn_face_del = hicn_face_ip_del,
- .hicn_face_get_dpo = hicn_face_ip_get_dpo,
-};
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip.h b/hicn-plugin/src/faces/ip/face_ip.h
deleted file mode 100644
index 74f3a83dc..000000000
--- a/hicn-plugin/src/faces/ip/face_ip.h
+++ /dev/null
@@ -1,310 +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.
- */
-
-#ifndef __HICN_FACE_IP_H__
-#define __HICN_FACE_IP_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include "../face.h"
-#include "../../cache_policies/cs_policy.h"
-
-/**
- * @file
- *
- * @brief IP face
- *
- * A face is carried through nodes as a dpo. The face state 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)
- */
-typedef struct hicn_ip_face_t_
-{
- /**
- * The headers to paint, in packet painting order
- */
- /* Local address of the interface sw_if */
- ip46_address_t local_addr;
-
- /* Remote address of neighbor */
- ip46_address_t remote_addr;
-
-} 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
- * data arrives.
- */
-extern mhash_t hicn_face_ip_local_hashtb;
-
-/**
- * Hash tables that indexes a face by remote address. For fast lookup when an
- * interest arrives.
- */
-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
- * interface. The former is used to retrieve the incoming face when an interest
- * is received, the latter when the arring packet is a data.
- */
-typedef struct hicn_face_ip_key_s
-{
- ip46_address_t addr;
- u32 sw_if;
-} hicn_face_ip_key_t;
-
-
-extern hicn_face_type_t hicn_face_ip_type;
-extern hicn_face_vft_t ip_vft;
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param addr Local or remote ip v6 address of the face
- * @param sw_if interface associated to the face
- * @param key Pointer to an allocated hicn_face_ip_key_t object
- */
-always_inline void
-hicn_face_ip6_get_key (const ip6_address_t * addr,
- u32 sw_if, hicn_face_ip_key_t * key)
-{
- key->addr.ip6 = *addr;
- key->sw_if = sw_if;
-}
-
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param addr Local or remote ip v4 address of the face
- * @param sw_if interface associated to the face
- * @param key Pointer to an allocated hicn_face_ip_key_t object
- */
-always_inline void
-hicn_face_ip4_get_key (const ip4_address_t * addr,
- u32 sw_if, hicn_face_ip_key_t * key)
-{
- ip46_address_set_ip4 (&(key->addr), addr);
- key->sw_if = sw_if;
-}
-
-/**
- * @brief Get the dpoi 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_t *
-hicn_face_ip4_get (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);
-
- hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-/**
- * @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.
- * @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_t *
-hicn_face_ip6_get (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);
-
- hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-/**
- * @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 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, u8 is_app_prod);
-
-/**
- * @brief Create a new incomplete face ip. (Meant to be used by the data plane)
- *
- * @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 sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-always_inline void
-hicn_iface_ip_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr,
- int sw_if, hicn_face_id_t * pfaceid)
-{
- hicn_face_t *face;
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) (face->data);
-
- clib_memcpy (&(ip_face->local_addr.ip6), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(ip_face->remote_addr.ip6), remote_addr,
- sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_ip_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 1;
-
- hicn_face_ip_key_t key;
- hicn_face_ip6_get_key (&(remote_addr->ip6), sw_if, &key);
- *pfaceid = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_ip_remote_hashtb, &key, (uword *) pfaceid, 0);
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-}
-
-/**
- * @brief Delete an ip face
- *
- * @param face_id Id of the face to delete
- * @return HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise
- * HICN_ERROR_NONE
- */
-int hicn_face_ip_del (hicn_face_id_t face_id);
-
-/**
- * @brief Format a IP face
- *
- * @param s Pointer to a previous string. If null it will be initialize
- * @param args Array storing input values. Expected u32 face_id and u32 indent
- * @return String with the formatted face
- */
-u8 *format_hicn_face_ip (u8 * s, va_list * args);
-
-/**
- * @brief Create a dpo from an ip face
- *
- * @param face Face from which to create the dpo
- * @return the dpo
- */
-void hicn_face_ip_get_dpo (hicn_face_t * face, dpo_id_t * dpo);
-
-#endif // __HICN_FACE_IP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip_cli.c b/hicn-plugin/src/faces/ip/face_ip_cli.c
deleted file mode 100644
index 4c4986f97..000000000
--- a/hicn-plugin/src/faces/ip/face_ip_cli.c
+++ /dev/null
@@ -1,208 +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 <vnet/vnet.h>
-#include <vnet/dpo/dpo.h>
-#include <vlib/vlib.h>
-
-#include "face_ip.h"
-#include "dpo_ip.h"
-#include "../face.h"
-
-#define HICN_FACE_NONE 0
-#define HICN_FACE_DELETE 1
-#define HICN_FACE_ADD 2
-
-static clib_error_t *
-hicn_face_ip_cli_set_command_fn (vlib_main_t * vm,
- unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- ip46_address_t local_addr;
- ip46_address_t remote_addr;
- hicn_face_id_t face_id = HICN_FACE_NULL;
- int ret = HICN_ERROR_NONE;
- int sw_if;
- int face_op = HICN_FACE_NONE;
-
- ip46_address_reset (&local_addr);
- /* Get a line of input. */
- unformat_input_t _line_input, *line_input = &_line_input;
- if (!unformat_user (main_input, unformat_line_input, line_input))
- {
- return (0);
- }
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "del"))
- {
- if (unformat (line_input, "id %d", &face_id))
- face_op = HICN_FACE_DELETE;
- else
- {
- return clib_error_return (0, "missing face id");
- }
- }
- else if (unformat (line_input, "add"))
- {
- face_op = HICN_FACE_ADD;
- if (unformat (line_input, "local %U",
- unformat_ip46_address, &local_addr, IP46_TYPE_ANY));
-
- if (unformat (line_input, "remote %U intfc %U",
- unformat_ip46_address, &remote_addr,
- IP46_TYPE_ANY, unformat_vnet_sw_interface, vnm,
- &sw_if));
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string
- (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
-
- if (face_id != HICN_FACE_NULL)
- {
-
- if (!hicn_dpoi_idx_is_valid (face_id))
- {
- return clib_error_return (0, "%s, face_id %d not valid",
- get_error_string (ret), face_id);
- }
- }
-
- int rv;
- switch (face_op)
- {
- case HICN_FACE_ADD:
-
- /* Check for presence of next hop address */
- if ((remote_addr.as_u64[0] == (u64) 0)
- && (remote_addr.as_u64[1] == (u64) 0))
- {
- return clib_error_return (0, "next hop address not specified");
- }
-
- if (ip46_address_is_zero (&local_addr))
- {
- if (!vnet_sw_interface_is_valid (vnm, sw_if))
- return clib_error_return (0, "interface not valid");
-
- if (ip46_address_is_ip4 (&remote_addr))
- {
- ip_interface_address_t *interface_address;
- ip4_address_t *addr =
- ip4_interface_address_matching_destination (&ip4_main,
- &remote_addr.ip4,
- sw_if,
- &interface_address);
-
- if (addr == NULL)
- addr = ip4_interface_first_address (&ip4_main,
- sw_if,
- &interface_address);
-
- if (addr == NULL)
- return clib_error_return (0,
- "no valid ip address on interface %d",
- sw_if);
-
- ip46_address_set_ip4 (&local_addr, addr);
- }
- else
- {
- ip_interface_address_t *interface_address;
- ip6_interface_address_matching_destination (&ip6_main,
- &remote_addr.ip6,
- sw_if,
- &interface_address);
-
- ip6_address_t *addr = NULL;
- if (interface_address != NULL)
- addr =
- (ip6_address_t *)
- ip_interface_address_get_address (&ip6_main.lookup_main,
- interface_address);
-
- if (addr == NULL)
- addr = ip6_interface_first_address (&ip6_main, sw_if);
-
- if (addr == NULL)
- return clib_error_return (0,
- "no valid ip address on interface %d",
- sw_if);
-
- ip46_address_set_ip6 (&local_addr, addr);
- }
- }
-
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &face_id, 0);
-
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face id: %d", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- case HICN_FACE_DELETE:
- rv = hicn_face_ip_del (face_id);
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face %d deleted", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- default:
- return clib_error_return (0, "Operation (%d) not implemented", face_op);
- break;
- }
- return (rv == HICN_ERROR_NONE) ? 0 : clib_error_return (0, "%s\n",
- get_error_string
- (rv));
-}
-
-/* cli declaration for 'cfg face' */
-/* *INDENT-OFF* */
-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>}",
- .function = hicn_face_ip_cli_set_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.h b/hicn-plugin/src/faces/ip/face_ip_node.h
deleted file mode 100644
index 000395a04..000000000
--- a/hicn-plugin/src/faces/ip/face_ip_node.h
+++ /dev/null
@@ -1,40 +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.
- */
-
-#ifndef __HICN_FACE_IP_NODE_H__
-#define __HICN_FACE_IP_NODE_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-
-extern vlib_node_registration_t hicn_face_ip4_input_node;
-extern vlib_node_registration_t hicn_face_ip4_output_node;
-extern vlib_node_registration_t hicn_face_ip6_input_node;
-extern vlib_node_registration_t hicn_face_ip6_output_node;
-
-/**
- * @brief Initialize the ip face module
- */
-void hicn_face_ip_init (vlib_main_t * vm);
-
-#endif // __HICN_FACE_IP_NODE_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/dpo_udp.c b/hicn-plugin/src/faces/udp/dpo_udp.c
deleted file mode 100644
index 987d52bb7..000000000
--- a/hicn-plugin/src/faces/udp/dpo_udp.c
+++ /dev/null
@@ -1,157 +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 "dpo_udp.h"
-
-#include <vnet/ip/format.h>
-#include <vnet/adj/adj.h>
-#include <vnet/vnet.h>
-#include <vlib/vlib.h>
-
-const static char *const hicn_face_ip4udp_nodes[] = {
- "hicn-face-encap-udp4",
- "hicn-face-decap-udp4",
- "hicn-iface-decap-udp4",
- "hicn-iface-encap-udp4",
- NULL,
-};
-
-const static char *const hicn_face_ip6udp_nodes[] = {
- "hicn-face-encap-udp6",
- "hicn-face-decap-udp6",
- "hicn-iface-decap-udp6",
- "hicn-iface-encap-udp6",
- NULL,
-};
-
-const static char *const *const hicn_ipudp_nodes[DPO_PROTO_NUM] = {
- [DPO_PROTO_IP4] = hicn_face_ip4udp_nodes,
- [DPO_PROTO_IP6] = hicn_face_ip6udp_nodes
-};
-
-
-const static dpo_vft_t hicn_dpoi_udp_vft = {
- .dv_lock = hicn_face_lock,
- .dv_unlock = hicn_face_unlock,
- .dv_format = format_hicn_face_udp,
-};
-
-/* Must be executed after all the strategy nodes are created */
-void
-hicn_dpo_udp_module_init (void)
-{
- mhash_init (&hicn_face_udp_hashtb, sizeof (hicn_face_id_t) /* value */ ,
- sizeof (hicn_face_udp_key_t) /* key */ );
-
- /*
- * How much useful is the following registration?
- * So far it seems that we need it only for setting the dpo_type.
- */
- hicn_face_udp_type =
- dpo_register_new_type (&hicn_dpoi_udp_vft, hicn_ipudp_nodes);
-}
-
-
-/* Here udp ports are in host order, move them to network order to do the lookup */
-int
-hicn_dpo_udp4_create (dpo_id_t * dpo,
- const ip4_address_t * src_ip,
- const ip4_address_t * dst_ip,
- u16 src_port, u16 dst_port,
- u32 sw_if,
- adj_index_t ip_adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- u16 net_src_port = clib_host_to_net_u16 (src_port);
- u16 net_dst_port = clib_host_to_net_u16 (dst_port);
- hicn_face_t *face =
- hicn_face_udp4_get (src_ip, dst_ip, net_src_port, net_dst_port);
-
- u8 hicnb_flags;
- /* ip_csum_t sum0; */
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- hicn_dpo_udp4_add_and_lock (dpo, src_ip, dst_ip, net_src_port, net_dst_port,
- node_index, &hicnb_flags, sw_if);
-
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- udp_face->hdrs.ip4.ip.checksum =
- ip4_header_checksum (&(udp_face->hdrs.ip4.ip));
-
- face->shared.flags = flags;
- face->shared.adj = ip_adj;
- *face_id = hicn_dpoi_get_index (face);
-
- return HICN_ERROR_NONE;
-}
-
-
-int
-hicn_dpo_udp6_create (dpo_id_t * dpo,
- const ip6_address_t * src_ip,
- const ip6_address_t * dst_ip,
- u16 src_port, u16 dst_port,
- u32 sw_if,
- adj_index_t ip_adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- u16 net_src_port = clib_host_to_net_u16 (src_port);
- u16 net_dst_port = clib_host_to_net_u16 (dst_port);
- hicn_face_t *face =
- hicn_face_udp6_get (src_ip, dst_ip, net_src_port, net_dst_port);
- u8 hicnb_flags;
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- hicn_dpo_udp6_add_and_lock (dpo, src_ip, dst_ip, net_src_port, net_dst_port,
- node_index, &hicnb_flags, sw_if);
-
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
-
- face->shared.flags = flags;
- face->shared.adj = ip_adj;
- *face_id = hicn_dpoi_get_index (face);
-
- return HICN_ERROR_NONE;
-}
-
-void
-hicn_dpo_udp_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node)
-{
- hicn_face_id_t face_dpoi_id = hicn_dpoi_get_index (face);
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- u8 version =
- (face_udp->hdrs.ip4.ip.ip_version_and_header_length & 0xf0) >> 4;
- dpo_set (dpo, face->shared.face_type,
- version == 4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6, face_dpoi_id);
- dpo->dpoi_next_node = dpoi_next_node;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/dpo_udp.h b/hicn-plugin/src/faces/udp/dpo_udp.h
deleted file mode 100644
index 98abf3d29..000000000
--- a/hicn-plugin/src/faces/udp/dpo_udp.h
+++ /dev/null
@@ -1,289 +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.
- */
-
-#ifndef __HICN_DPO_UDP_H__
-#define __HICN_DPO_UDP_H__
-
-#include <vnet/adj/adj_types.h>
-#include <vnet/ip/ip4_packet.h>
-#include <vnet/ip/ip6_packet.h>
-
-#include "face_udp.h"
-#include "../face.h"
-#include "../../error.h"
-
-extern u32 strategy_face_udp4_vlib_edge;
-extern u32 strategy_face_udp6_vlib_edge;
-
-
-/**
- * @brief Initialize the internal structures of the dpo udp face module.
- */
-void hicn_dpo_udp_module_init (void);
-
-/**
- * @brief Create a udp 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: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @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_udp4_create (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
-
-/**
- * @brief Retrieve a face using the face identifier, i.e., the quadruplet (local_addr, remote_addr,
- * local_port, remote_port). This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not in the hicn_buffer. (Currently only IP faces can be appface)
- *
- * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
- */
-always_inline int
-hicn_dpo_udp4_lock (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port, u8 * hicnb_flags)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp4_get (local_addr, remote_addr, local_port, remote_port);
-
- if (PREDICT_FALSE (face == NULL))
- return HICN_ERROR_FACE_NOT_FOUND;
-
- index_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = strategy_face_udp4_vlib_edge;
- dpo_unlock (dpo);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- return HICN_ERROR_NONE;
-}
-
-/**
- * @brief Retrieve, or create if it doesn't exist, a face from the face
- * identifier (local_addr, remote_addr, local_port, remote_port) and returns its
- * dpo. This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not. (Currently only IP faces can be appface)
- * @param node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_udp4_add_and_lock (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 node_index, u8 * hicnb_flags, u32 sw_if)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp4_get (local_addr, remote_addr, local_port, remote_port);
-
- if (face == NULL)
- {
-
- hicn_face_id_t dpoi_index;
- hicn_iface_udp4_add (local_addr, remote_addr, local_port, remote_port,
- sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-/**
- * @brief Create a udp 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: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @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_udp6_create (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
-
-
-/**
- * @brief Retrieve a face using the face identifier, i.e., the quadruplet (local_addr, remote_addr,
- * local_port, remote_port). This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not. (Currently only IP faces can be appface)
- *
- * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
- */
-always_inline int
-hicn_dpo_udp6_lock (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port, u8 * hicnb_flags)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp6_get (local_addr, remote_addr, local_port, remote_port);
-
-
- if (PREDICT_FALSE (face == NULL))
- return HICN_ERROR_FACE_NOT_FOUND;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = strategy_face_udp6_vlib_edge;
- dpo_unlock (dpo);
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- return HICN_ERROR_NONE;
-}
-
-/**
- * @brief Retrieve, or create if it doesn't exist, a face from the face
- * identifier (local_addr, remote_addr, local_port, remote_port) and returns its
- * dpo. This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not. (Currently only IP faces can be appface)
- * @param node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_udp6_add_and_lock (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 node_index, u8 * hicnb_flags, u32 sw_if)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp6_get (local_addr, remote_addr, local_port, remote_port);
-
- if (face == NULL)
- {
- hicn_face_id_t dpoi_index;
- hicn_iface_udp6_add (local_addr, remote_addr, local_port, remote_port,
- sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-/**
- * @brief Create a dpo from a udp face
- *
- * @param face Face from which to create the dpo
- * @return the dpo
- */
-void hicn_dpo_udp_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node);
-
-#endif // __HICN_DPO_UDP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp.c b/hicn-plugin/src/faces/udp/face_udp.c
deleted file mode 100644
index e610cbd14..000000000
--- a/hicn-plugin/src/faces/udp/face_udp.c
+++ /dev/null
@@ -1,449 +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 "face_udp.h"
-#include "face_udp_node.h"
-#include "dpo_udp.h"
-#include "../face.h"
-#include "../../infra.h"
-#include "../../strategy.h"
-#include "../../strategy_dpo_manager.h"
-#include "../../hicn.h"
-
-#include "../../mapme.h" // HICN_MAPME_EVENT_*
-#include "../../mapme_eventmgr.h" // hicn_mapme_eventmgr_process_node
-extern vlib_node_registration_t hicn_mapme_eventmgr_process_node;
-
-mhash_t hicn_face_udp_hashtb;
-
-dpo_type_t hicn_face_udp_type;
-
-ip4_header_t ip4_header_skl = {
- .ip_version_and_header_length = IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS,
- .tos = 0x00,
- .length = (u16) 0,
- .fragment_id = (u16) 0,
- .flags_and_fragment_offset = (u16) 0,
- .ttl = 254,
- .protocol = IP_PROTOCOL_UDP,
- .checksum = 0,
- .src_address = {{0}},
- .dst_address = {{0}},
-};
-
-ip6_header_t ip6_header_skl = {
-#if CLIB_ARCH_IS_BIG_ENDIAN
- .ip_version_traffic_class_and_flow_label = 0x60000000,
-#else
- .ip_version_traffic_class_and_flow_label = 0x00000060,
-#endif
- .payload_length = (u16) 0,
- .protocol = IP_PROTOCOL_UDP,
- .hop_limit = 254,
- .src_address = {{0}},
- .dst_address = {{0}}
-};
-
-u32 strategy_face_udp4_vlib_edge;
-u32 strategy_face_udp6_vlib_edge;
-
-/*
- * Separated from the hicn_face_udp_init because it cannot be called by the
- * init macro due to dependencies with other modules not yet initialied
- */
-void
-hicn_face_udp_init_internal ()
-{
- ip4_header_t *ip4_hdr = &ip4_header_skl;
- ip4_header_skl.checksum = ip4_header_checksum (ip4_hdr);
-}
-
-void
-hicn_face_udp_init (vlib_main_t * vm)
-{
- int strategy_nodes_n = hicn_strategy_get_all_available ();
-
- /* Default Strategy has index 0 and it always exists */
- strategy_face_udp4_vlib_edge = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_udp4_output_node.
- index);
- strategy_face_udp6_vlib_edge =
- vlib_node_add_next (vm, hicn_strategy_node.index,
- hicn_face_udp6_output_node.index);
-
- /*
- * Create and edge between al the other strategy nodes and the
- * udp_output nodes.
- */
- for (int i = 1; i < strategy_nodes_n; i++)
- {
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_udp4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_udp6_output_node.index);
- ASSERT (temp_index4 == strategy_face_udp4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_udp6_vlib_edge);
- }
-
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_udp4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_udp6_output_node.index);
-
- ASSERT (temp_index4 == strategy_face_udp4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_udp6_vlib_edge);
-
- hicn_dpo_udp_module_init ();
-
- register_face_type (hicn_face_udp_type, &udp_vft, "udp");;
-}
-
-int
-hicn_face_udp_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr, u16 local_port,
- u16 remote_port, u32 swif, hicn_face_id_t * pfaceid)
-{
- adj_index_t ip_adj;
- int ret = HICN_ERROR_NONE;
- dpo_proto_t dpo_proto;
-
- hicn_face_flags_t flags = (hicn_face_flags_t) 0;
- flags |= HICN_FACE_FLAGS_FACE;
-
-
- if (ip46_address_is_ip4 (local_addr) && ip46_address_is_ip4 (remote_addr))
- {
- 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;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- ip_adj = fib_entry_get_adj (fib_entry_index);
-
- if (ip_adj == ~0)
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
-
- hicn_face_t *face =
- hicn_face_udp4_get (&local_addr->ip4, &remote_addr->ip4, local_port,
- remote_port);
-
- if (face == NULL)
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip4.ip), &ip4_header_skl,
- sizeof (ip4_header_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.src_address), &(local_addr->ip4),
- sizeof (ip4_address_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.dst_address), &(remote_addr->ip4),
- sizeof (ip4_address_t));
-
- udp_face->hdrs.ip4.udp.src_port = local_port;
- udp_face->hdrs.ip4.udp.dst_port = remote_port;
-
- ip_csum_t csum = udp_face->hdrs.ip4.ip.checksum;
- csum = ip_csum_sub_even (csum, ip4_header_skl.src_address.as_u32);
- csum = ip_csum_sub_even (csum, ip4_header_skl.dst_address.as_u32);
- csum =
- ip_csum_add_even (csum, udp_face->hdrs.ip4.ip.src_address.as_u32);
- csum =
- ip_csum_add_even (csum, udp_face->hdrs.ip4.ip.dst_address.as_u32);
- udp_face->hdrs.ip4.ip.checksum = ip_csum_fold (csum);
-
- face->shared.adj = ip_adj;
- face->shared.sw_if = swif;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = flags;
- face->shared.locks = 0;
-
- hicn_face_udp_key_t key;
- hicn_face_udp4_get_key (&local_addr->ip4, &remote_addr->ip4, local_port,
- remote_port, &key);
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- *pfaceid = hicn_dpoi_get_index (face);
- dpo_proto = DPO_PROTO_IP4;
- fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
- }
- else if (!ip46_address_is_ip4 (local_addr)
- && !ip46_address_is_ip4 (remote_addr))
- {
- 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;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- ip_adj = fib_entry_get_adj (fib_entry_index);
-
- if (ip_adj == ~0)
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
-
- hicn_face_t *face =
- hicn_face_udp6_get (&local_addr->ip6, &remote_addr->ip6, local_port,
- remote_port);
-
- if (face == NULL)
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip6.ip), &ip6_header_skl,
- sizeof (ip6_header_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.src_address), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.dst_address), remote_addr,
- sizeof (ip6_address_t));
-
- udp_face->hdrs.ip6.udp.src_port = local_port;
- udp_face->hdrs.ip6.udp.dst_port = remote_port;
-
- face->shared.adj = ip_adj;
- face->shared.sw_if = swif;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = flags;
- face->shared.locks = 0;
-
- hicn_face_udp_key_t key;
- hicn_face_udp6_get_key (&local_addr->ip6, &remote_addr->ip6, local_port,
- remote_port, &key);
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- *pfaceid = hicn_dpoi_get_index (face);
- dpo_proto = DPO_PROTO_IP6;
- fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
- }
- else
- {
- return HICN_ERROR_IPS_ADDR_TYPE_NONUNIFORM;
- }
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-
- retx_t *retx = vlib_process_signal_event_data (vlib_get_main (),
- hicn_mapme_eventmgr_process_node.
- index,
- HICN_MAPME_EVENT_FACE_ADD, 1,
- sizeof (retx_t));
- /* *INDENT-OFF* */
- *retx = (retx_t)
- {
- .prefix = 0,
- .dpo = (dpo_id_t)
- {
- .dpoi_type = hicn_face_udp_type,
- .dpoi_proto = dpo_proto,
- .dpoi_next_node = 0,
- .dpoi_index = *pfaceid,
- }
- };
- /* *INDENT-ON* */
-
- //Take a lock on the face which will be removed when the face is deleted
- hicn_face_lock (&(retx->dpo));
-
- return ret;
-}
-
-int
-hicn_face_udp_del (u32 faceid)
-{
- hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- hicn_face_udp_key_t key;
- hicn_face_udp_key_t old_key;
-
- if (face_udp->hdrs.ip4.ip.ip_version_and_header_length ==
- IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS)
- {
- hicn_face_udp4_get_key (&face_udp->hdrs.ip4.ip.src_address,
- &face_udp->hdrs.ip4.ip.dst_address,
- face_udp->hdrs.ip4.udp.src_port,
- face_udp->hdrs.ip4.udp.dst_port, &key);
- mhash_unset (&hicn_face_udp_hashtb, &key, (uword *) & old_key);
- }
- else
- {
- hicn_face_udp6_get_key (&face_udp->hdrs.ip6.ip.src_address,
- &face_udp->hdrs.ip6.ip.dst_address,
- face_udp->hdrs.ip6.udp.src_port,
- face_udp->hdrs.ip6.udp.dst_port, &key);
- mhash_unset (&hicn_face_udp_hashtb, &key, (uword *) & old_key);
- }
- return hicn_face_del (faceid);
-}
-
-u8 *
-format_hicn_face_udp (u8 * s, va_list * args)
-{
- hicn_face_id_t face_id = va_arg (*args, index_t);
- CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
- hicn_face_t *face;
- hicn_face_udp_t *udp_face;
- ip_adjacency_t *adj;
- u8 ipv = IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS;
- vnet_main_t *vnm = vnet_get_main ();
-
-
- face = hicn_dpoi_get_from_idx (face_id);
- udp_face = (hicn_face_udp_t *) (face->data);
-
- if (face->shared.flags & HICN_FACE_FLAGS_FACE)
- {
- ASSERT (face->shared.adj != (adj_index_t) ~ 0);
- adj = adj_get (face->shared.adj);
-
- s = format (s, "%U Face %d: ", format_white_space, indent, face_id);
- if (udp_face->hdrs.ip4.ip.ip_version_and_header_length == ipv)
- {
- s = format (s, "type UDP local %U|%u ",
- format_ip4_address, &udp_face->hdrs.ip4.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.src_port));
- s =
- format (s, "remote %U|%u ", format_ip4_address,
- &udp_face->hdrs.ip4.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.dst_port));
- s = format (s, "%U", format_vnet_link, adj->ia_link);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- else
- {
- s = format (s, "type UDP local %U|%u ",
- format_ip6_address, &udp_face->hdrs.ip6.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.src_port));
- s =
- format (s, "remote %U|%u ", format_ip6_address,
- &udp_face->hdrs.ip6.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.dst_port));
- s = format (s, "%U", format_vnet_link, adj->ia_link);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- }
- else
- {
- s = format (s, "%U iFace %d: ", format_white_space, indent, face_id);
- if (udp_face->hdrs.ip4.ip.ip_version_and_header_length == ipv)
- {
- s = format (s, "type UDP local %U|%u",
- format_ip4_address, &udp_face->hdrs.ip4.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.src_port));
- s =
- format (s, " local %U|%u", format_ip4_address,
- &udp_face->hdrs.ip4.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.dst_port));
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- else
- {
- s = format (s, "type UDP local %U|%u",
- format_ip6_address, &udp_face->hdrs.ip6.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.src_port));
- s =
- format (s, " remote %U|%u", format_ip6_address,
- &udp_face->hdrs.ip6.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.dst_port));
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- }
-
- return s;
-}
-
-void
-hicn_face_udp_get_dpo (hicn_face_t * face, dpo_id_t * dpo)
-{
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- u8 version =
- (face_udp->hdrs.ip4.ip.ip_version_and_header_length & 0xf0) >> 4;
- return hicn_dpo_udp_create_from_face (face, dpo,
- version ==
- (u8) 4 ? strategy_face_udp4_vlib_edge
- : strategy_face_udp6_vlib_edge);
-}
-
-hicn_face_vft_t udp_vft = {
- .format_face = format_hicn_face_udp,
- .hicn_face_del = hicn_face_udp_del,
- .hicn_face_get_dpo = hicn_face_udp_get_dpo,
-};
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp.h b/hicn-plugin/src/faces/udp/face_udp.h
deleted file mode 100644
index 5dfc76e22..000000000
--- a/hicn-plugin/src/faces/udp/face_udp.h
+++ /dev/null
@@ -1,356 +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.
- */
-
-#ifndef __HICN_FACE_UDP_H__
-#define __HICN_FACE_UDP_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include <vnet/ip/ip6_packet.h>
-#include <vnet/udp/udp_packet.h>
-
-#include "../face.h"
-
-/**
- * @file
- * @brief UDP face
- *
- * This file containes the definition of UDP faces.
- * UDP faces encap and decap an hicn packet into a UDP tunnel.
- * Src and dst address in interest and data packets are not considered and
- * should be set to 0 (not checked in the forwarder).
- */
-
-/* Pre-instantiated ip header to fast fill an newly encapsulated packet */
-extern ip4_header_t ip4_header_skl;
-extern ip6_header_t ip6_header_skl;
-
-#define INVALID_UDP_DPO_INDEX ~0
-
-/**
- * @brief UDP face representation. The following is stored in the data field of
- * an hicn_face_t object (see hicn_face.h). A UDP face is identifies by the
- * quadruplet (src addr, dst addr, src port, dst port).
- */
-typedef struct hicn_face_udp_t_
-{
- /**
- * The headers to paint, in packet painting order
- */
- union
- {
- struct
- {
- ip4_header_t ip;
- udp_header_t udp;
- } __attribute__ ((packed)) ip4;
- struct
- {
- ip6_header_t ip;
- udp_header_t udp;
- } __attribute__ ((packed)) ip6;
- } __attribute__ ((packed)) hdrs;
-} hicn_face_udp_t;
-
-/* Hast table mapping the udp key with the face id (dpoi_index pointing to and
- element in the face pool defined in hicn_face.h)*/
-extern mhash_t hicn_face_udp_hashtb;
-
-/**
- * @brief Hash table key.
- */
-typedef struct hicn_face_udp_key_s
-{
- ip46_address_t local_addr;
- ip46_address_t remote_addr;
- u16 local_port;
- u16 remote_port;
-} hicn_face_udp_key_t;
-
-/* DPO type for the udp face */
-extern dpo_type_t hicn_face_udp_type;
-
-/* VFT table for the udp face. Mainly used to format the face in the right way */
-extern hicn_face_vft_t udp_vft;
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param local_addr Local address of the UDP tunnel
- * @param remote_addr Remote address of the UDP tunnel
- * @param local_port Local port of the UDP tunnel
- * @param remote_port Remote port of the UDP tunnel
- * @param key Pointer to an allocated hicn_face_udp_key_t object
- */
-always_inline void
-hicn_face_udp4_get_key (const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- hicn_face_udp_key_t * key)
-{
-
- ip46_address_set_ip4 (&(key->local_addr), local_addr);
- ip46_address_set_ip4 (&(key->remote_addr), remote_addr);
- key->local_port = local_port;
- key->remote_port = remote_port;
-}
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param local_addr Local address of the UDP tunnel
- * @param remote_addr Remote address of the UDP tunnel
- * @param local_port Local port of the UDP tunnel
- * @param remote_port Remote port of the UDP tunnel
- * @param key Pointer to an allocated hicn_face_udp_key_t object
- */
-always_inline void
-hicn_face_udp6_get_key (const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- hicn_face_udp_key_t * key)
-{
- key->local_addr.ip6 = *local_addr;
- key->remote_addr.ip6 = *remote_addr;
- key->local_port = local_port;
- key->remote_port = remote_port;
-}
-
-/**
- * @brief Get the dpoi from the quadruplet that identifies the face. Does not add any lock.
- *
- * @param local_addr Local address of the UDP tunnel
- * @param remote_addr Remote address of the UDP tunnel
- * @param local_port Local port of the UDP tunnel
- * @param remote_port Remote port of the UDP tunnel
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_t *
-hicn_face_udp4_get (const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port)
-{
- hicn_face_udp_key_t key;
-
- hicn_face_udp4_get_key (local_addr, remote_addr, local_port, remote_port,
- &key);
-
- hicn_face_id_t *dpoi_index =
- (hicn_face_id_t *) mhash_get (&hicn_face_udp_hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-/**
- * @brief Get the dpoi from the quadruplet that identifies the face. Does not add any lock.
- *
- * @param local_addr Local address of the UDP tunnel (network order)
- * @param remote_addr Remote address of the UDP tunnel (network order)
- * @param local_port Local port of the UDP tunnel (network order)
- * @param remote_port Remote port of the UDP tunnel (network order)
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_t *
-hicn_face_udp6_get (const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port)
-{
- hicn_face_udp_key_t key;
-
- hicn_face_udp6_get_key (local_addr, remote_addr, local_port, remote_port,
- &key);
-
- hicn_face_id_t *dpoi_index =
- (hicn_face_id_t *) mhash_get (&hicn_face_udp_hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-
-/**
- * @brief Initialize the udp face module
- */
-void hicn_face_udp_init (vlib_main_t * vm);
-
-/**
- * @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 (network order)
- * @param remote_addr Remote ip v4 or v6 address of the face (network order)
- * @param local_port Local udp port of the face (network order)
- * @param remote_port Remote udp port of the face (network order)
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @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_udp_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr, u16 local_port,
- u16 remote_port, u32 swif, hicn_face_id_t * pfaceid);
-
-/**
- * @brief Create a new incomplete face udp. (Meant to be used by the data plane)
- *
- * @param local_addr Local ip v6 address of the face
- * @param remote_addr Remote ip v6 address of the face
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-always_inline void
-hicn_iface_udp6_add (const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr, u16 local_port,
- u16 remote_port, int sw_if, hicn_face_id_t * pfaceid)
-{
- hicn_face_t *face;
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip6.ip), &ip6_header_skl,
- sizeof (ip6_header_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.src_address), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.dst_address), remote_addr,
- sizeof (ip6_address_t));
-
- udp_face->hdrs.ip6.udp.src_port = local_port;
- udp_face->hdrs.ip6.udp.dst_port = remote_port;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 0;
- face->shared.sw_if = sw_if;
-
- hicn_face_udp_key_t key;
- hicn_face_udp6_get_key (local_addr, remote_addr, local_port,
- remote_port, &key);
- *pfaceid = hicn_dpoi_get_index (face);
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-}
-
-/**
- * @brief Create a new incomplete face udp. (Meant to be used by the data plane)
- *
- * @param local_addr Local ip v4 address of the face
- * @param remote_addr Remote ip v4 address of the face
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-always_inline void
-hicn_iface_udp4_add (const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr, u16 local_port,
- u16 remote_port, int sw_if, hicn_face_id_t * pfaceid)
-{
- hicn_face_t *face;
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip4.ip), &ip4_header_skl,
- sizeof (ip4_header_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.src_address), local_addr,
- sizeof (ip4_address_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.dst_address), remote_addr,
- sizeof (ip4_address_t));
-
- udp_face->hdrs.ip4.udp.src_port = local_port;
- udp_face->hdrs.ip4.udp.dst_port = remote_port;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 1;
- face->shared.sw_if = sw_if;
-
- hicn_face_udp_key_t key;
- hicn_face_udp4_get_key (local_addr, remote_addr, local_port,
- remote_port, &key);
- *pfaceid = hicn_dpoi_get_index (face);
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-}
-
-/**
- * @brief Delete an ip face
- *
- * @param face_id Id of the face to delete
- * @return HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise
- * HICN_ERROR_NONE
- */
-int hicn_face_udp_del (hicn_face_id_t faceid);
-
-/**
- * @brief Format a UDP face
- *
- * @param s Pointer to a previous string. If null it will be initialize
- * @param args Array storing input values. Expected u32 indent and u32 face_id
- * @return String with the formatted face
- */
-u8 *format_hicn_face_udp (u8 * s, va_list * args);
-
-/**
- * @brief Create a dpo from a udp face
- *
- * @param face Face from which to create the dpo
- * @return the dpo
- */
-void hicn_face_udp_get_dpo (hicn_face_t * face, dpo_id_t * dpo);
-
-/**
- * @brief Init some internal structures
- */
-void hicn_face_udp_init_internal (void);
-
-#endif // __HICN_FACE_UDP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp_cli.c b/hicn-plugin/src/faces/udp/face_udp_cli.c
deleted file mode 100644
index 7bb172ce8..000000000
--- a/hicn-plugin/src/faces/udp/face_udp_cli.c
+++ /dev/null
@@ -1,164 +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 "face_udp.h"
-#include "dpo_udp.h"
-
-#include <vnet/vnet.h>
-#include <vnet/dpo/dpo.h>
-#include <vlib/vlib.h>
-#include <vnet/ip/format.h>
-
-#define HICN_FACE_NONE 0
-#define HICN_FACE_DELETE 1
-#define HICN_FACE_ADD 2
-
-
-static clib_error_t *
-hicn_face_udp_cli_set_command_fn (vlib_main_t * vm,
- unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- ip46_address_t src_addr;
- u32 src_port = 0;
- ip46_address_t dst_addr;
- u32 dst_port = 0;
- hicn_face_id_t face_id = HICN_FACE_NULL;
- int ret = HICN_ERROR_NONE;
- int sw_if;
- int face_op = HICN_FACE_NONE;
-
- ip46_address_reset (&src_addr);
- ip46_address_reset (&dst_addr);
- /* Get a line of input. */
- unformat_input_t _line_input, *line_input = &_line_input;
- if (!unformat_user (main_input, unformat_line_input, line_input))
- {
- return (0);
- }
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "del"))
- {
- if (unformat (line_input, "id %d", &face_id))
- face_op = HICN_FACE_DELETE;
- else
- {
- return clib_error_return (0, "missing face id");
- }
- }
- else if (unformat (line_input, "add"))
- {
- face_op = HICN_FACE_ADD;
- if (unformat
- (line_input, "src_addr %U port %u dst_addr %U port %u intfc %U",
- unformat_ip46_address, &src_addr, IP46_TYPE_ANY, &src_port,
- unformat_ip46_address, &dst_addr, IP46_TYPE_ANY, &dst_port,
- unformat_vnet_sw_interface, vnm, &sw_if));
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string
- (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
-
- if (face_id != HICN_FACE_NULL)
- {
- if (!hicn_dpoi_idx_is_valid (face_id))
- {
- return clib_error_return (0, "%s, face_id %d not valid",
- get_error_string (ret), face_id);
- }
- }
-
- int rv;
- switch (face_op)
- {
- case HICN_FACE_ADD:
-
- /* Check for presence of next hop address */
- if (((dst_addr.as_u64[0] == (u64) 0) && (dst_addr.as_u64[1] == (u64) 0))
- || dst_port == 0)
- {
- return clib_error_return (0, "dst address and port not specified");
- }
-
- if (((src_addr.as_u64[0] == (u64) 0) && (src_addr.as_u64[1] == (u64) 0))
- || src_port == 0)
- {
- return clib_error_return (0, "src address not specified");
- }
-
- rv =
- hicn_face_udp_add (&src_addr, &dst_addr,
- clib_host_to_net_u16 (src_port),
- clib_host_to_net_u16 (dst_port), sw_if, &face_id);
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face id: %d", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- case HICN_FACE_DELETE:
- rv = hicn_face_udp_del (face_id);
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face %d deleted", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- default:
- return clib_error_return (0, "Operation (%d) not implemented", face_op);
- break;
- }
- return (rv == HICN_ERROR_NONE) ? 0 : clib_error_return (0, "%s\n",
- get_error_string
- (rv));
-}
-
-/* cli declaration for 'cfg face' */
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (hicn_face_udp_cli_set_command, static) =
-{
- .path = "hicn face udp",
- .short_help = "hicn face udp {add src_addr <src_address> port <src_port > dst_addr <dst_address> port <dst_port>} intfc <interface> | {del id <face_id>}",
- .function = hicn_face_udp_cli_set_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp_node.c b/hicn-plugin/src/faces/udp/face_udp_node.c
deleted file mode 100644
index c82336659..000000000
--- a/hicn-plugin/src/faces/udp/face_udp_node.c
+++ /dev/null
@@ -1,1030 +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 <vnet/ip/ip_packet.h>
-
-#include "face_udp.h"
-#include "face_udp_node.h"
-#include "dpo_udp.h"
-#include "../face.h"
-#include "../../strategy.h"
-#include "../../strategy_dpo_manager.h"
-#include "../../hicn.h"
-
-/**
- * @File
- *
- * Definition of the nodes for udp faces.
- */
-
-vlib_node_registration_t hicn_face_udp4_input_node;
-vlib_node_registration_t hicn_face_udp6_input_node;
-vlib_node_registration_t hicn_face_udp4_output_node;
-vlib_node_registration_t hicn_face_udp6_output_node;
-
-static char *hicn_face_udp4_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_face_udp6_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp4_input_trace_t;
-
-typedef enum
-{
- HICN_FACE_UDP4_INPUT_NEXT_DATA,
- HICN_FACE_UDP4_INPUT_NEXT_MAPME,
- HICN_FACE_UDP4_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_UDP4_INPUT_N_NEXT,
-} hicn_face_udp4_input_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp6_input_trace_t;
-
-typedef enum
-{
- HICN_FACE_UDP6_INPUT_NEXT_DATA,
- HICN_FACE_UDP6_INPUT_NEXT_MAPME,
- HICN_FACE_UDP6_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_UDP6_INPUT_N_NEXT,
-} hicn_face_udp6_input_next_t;
-
-#define ERROR_INPUT_UDP4 HICN_FACE_UDP4_INPUT_NEXT_ERROR_DROP
-#define ERROR_INPUT_UDP6 HICN_FACE_UDP6_INPUT_NEXT_ERROR_DROP
-
-#define NEXT_MAPME_UDP4 HICN_FACE_UDP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_UDP6 HICN_FACE_UDP6_INPUT_NEXT_MAPME
-#define NEXT_DATA_UDP4 HICN_FACE_UDP4_INPUT_NEXT_DATA
-#define NEXT_DATA_UDP6 HICN_FACE_UDP6_INPUT_NEXT_DATA
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define HICN_DPO_UDP_LOCK_IP4 hicn_dpo_udp4_lock
-#define HICN_DPO_UDP_LOCK_IP6 hicn_dpo_udp6_lock
-
-#define TRACE_INPUT_PKT_UDP4 hicn_face_udp4_input_trace_t
-#define TRACE_INPUT_PKT_UDP6 hicn_face_udp6_input_trace_t
-
-#define SIZE_HICN_HEADER4 sizeof(ip4_header_t) + sizeof(udp_header_t)
-#define SIZE_HICN_HEADER6 sizeof(ip6_header_t) + sizeof(udp_header_t)
-
-
-#define face_input_x1(ipv) \
- do { \
- int ret; \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr = NULL; \
- u8 * inner_ip_hdr = NULL; \
- udp_header_t * udp_hdr = NULL; \
- hicn_buffer_t * hicnb0; \
- /* Prefetch for next iteration. */ \
- if (n_left_from > 1) \
- { \
- vlib_buffer_t *b1; \
- b1 = vlib_get_buffer (vm, from[1]); \
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- udp_hdr = (udp_header_t *) (ip_hdr + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- \
- inner_ip_hdr = (u8 *)(udp_hdr + 1); \
- u8 is_v6 = hicn_is_v6((hicn_header_t *)inner_ip_hdr); \
- u8 is_icmp = is_v6*(inner_ip_hdr[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6)*(inner_ip_hdr[9] == IPPROTO_ICMPV4); \
- \
- ret = HICN_DPO_UDP_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr->dst_address), \
- &(ip_hdr->src_address), \
- (udp_hdr->dst_port), \
- (udp_hdr->src_port), \
- &hicnb0->flags); \
- \
- if ( PREDICT_FALSE(ret != HICN_ERROR_NONE) ) \
- { \
- next0 = ERROR_INPUT_UDP##ipv; \
- } \
- else \
- { \
- next0 = is_icmp*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp)*NEXT_DATA_UDP##ipv; \
- stats.pkts_data_count += 1; \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index, \
- HICN_FACE_COUNTERS_DATA_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_CONTENT; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0), \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, next0); \
- }while(0) \
-
-#define face_input_x2(ipv) \
- do { \
- int ret0, ret1; \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0 = ERROR_INPUT_UDP##ipv; \
- u32 next1 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr0 = NULL; \
- IP_HEADER_##ipv * ip_hdr1 = NULL; \
- u8 * inner_ip_hdr0 = NULL; \
- u8 * inner_ip_hdr1 = NULL; \
- udp_header_t * udp_hdr0 = NULL; \
- udp_header_t * udp_hdr1 = NULL; \
- hicn_buffer_t *hicnb0, *hicnb1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- ip_hdr0 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- ip_hdr1 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b1); \
- udp_hdr0 = (udp_header_t *) (ip_hdr0 + 1); \
- udp_hdr1 = (udp_header_t *) (ip_hdr1 + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- hicnb1 = hicn_get_buffer(b1); \
- \
- inner_ip_hdr0 = (u8 *)(udp_hdr0 + 1); \
- u8 is_v6_0 = hicn_is_v6((hicn_header_t *)inner_ip_hdr0); \
- u8 is_icmp0 = is_v6_0*(inner_ip_hdr0[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_0)*(inner_ip_hdr0[9] == IPPROTO_ICMPV4); \
- \
- inner_ip_hdr1 = (u8 *)(udp_hdr1 + 1); \
- u8 is_v6_1 = hicn_is_v6((hicn_header_t *)inner_ip_hdr1); \
- u8 is_icmp1 = is_v6_1*(inner_ip_hdr1[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_1)*(inner_ip_hdr1[9] == IPPROTO_ICMPV4); \
- \
- ret0 = HICN_DPO_UDP_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr0->dst_address), \
- &(ip_hdr0->src_address), \
- (udp_hdr0->dst_port), \
- (udp_hdr0->src_port), \
- &hicnb0->flags); \
- \
- ret1 = HICN_DPO_UDP_LOCK_IP##ipv \
- (&(hicnb1->face_dpo_id), \
- &(ip_hdr1->dst_address), \
- &(ip_hdr1->src_address), \
- (udp_hdr1->dst_port), \
- (udp_hdr1->src_port), \
- &hicnb1->flags); \
- \
- if ( PREDICT_FALSE(ret0 != HICN_ERROR_NONE) ) \
- { \
- next0 = ERROR_INPUT_UDP##ipv; \
- } \
- else \
- { \
- stats.pkts_data_count += 1; \
- next0 = is_icmp0*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp0)*NEXT_DATA_UDP##ipv; \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index, \
- HICN_FACE_COUNTERS_DATA_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if ( PREDICT_FALSE(ret1 != HICN_ERROR_NONE) ) \
- { \
- next1 = ERROR_INPUT_UDP##ipv; \
- } \
- else \
- { \
- stats.pkts_data_count += 1; \
- next1 = is_icmp1*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp1)*NEXT_DATA_UDP##ipv; \
- \
- vlib_buffer_advance(b1, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_DATA_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_CONTENT; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0), \
- sizeof (t->packet_data)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_CONTENT; \
- t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
- t->next_index = next1; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b1), \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, bi1, next0, next1); \
- }while(0) \
-
-static uword
-hicn_face_udp4_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_input_x2 (4);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_input_x1 (4);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp4_input_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_face_udp4_input_trace_t *t =
- va_arg (*args, hicn_face_udp4_input_trace_t *);
-
- s =
- format (s, "FACE_UDP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp4_input_node) =
-{
- .function = hicn_face_udp4_input_node_fn,
- .name = "hicn-face-udp4-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp4_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp4_input_error_strings),
- .error_strings = hicn_face_udp4_input_error_strings,
- .n_next_nodes = HICN_FACE_UDP4_INPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_FACE_UDP4_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_UDP4_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_UDP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-
-static uword
-hicn_face_udp6_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_input_x2 (6);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_input_x1 (6);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_PROCESSED, stats.pkts_processed);
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp6_input_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_face_udp6_input_trace_t *t =
- va_arg (*args, hicn_face_udp6_input_trace_t *);
-
- s =
- format (s, "FACE_UDP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp6_input_node) =
-{
- .function = hicn_face_udp6_input_node_fn,
- .name = "hicn-face-udp6-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp6_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp6_input_error_strings),
- .error_strings = hicn_face_udp6_input_error_strings,
- .n_next_nodes = HICN_FACE_UDP6_INPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_FACE_UDP6_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_UDP6_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_UDP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-/******* Face Output *******/
-
-always_inline void
-hicn_face_udp4_encap (vlib_main_t * vm,
- vlib_buffer_t * outer_b0,
- hicn_face_t * face, u32 * next)
-{
- u16 old_l0 = 0, new_l0;
- ip_csum_t sum0;
- ip4_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* ip */
- ip0 = vlib_buffer_get_current (outer_b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip4.ip), sizeof (ip4_header_t) +
- sizeof (udp_header_t));
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
-
- new_l0 =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, outer_b0) -
- sizeof (*ip0));
- udp0->length = new_l0;
-
- old_l0 = ip0->length;
- ip0->length =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, outer_b0));
-
- sum0 = ip0->checksum;
-
- //old_l0 always 0, see the rewrite setup
- new_l0 = ip0->length;
-
- sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
- length /* changed member */ );
- ip0->checksum = sum0;
-
- int is_iface = 0;
- ip_adjacency_t *adj;
- if (PREDICT_FALSE (face->shared.adj == ~0))
- is_iface = 1;
- else
- adj = adj_get (face->shared.adj);
-
- /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
- * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
- * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
- */
- if (PREDICT_FALSE
- (is_iface || adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- ip46_address_t ip46 =
- to_ip46 (0, (u8 *) & (face_udp->hdrs.ip4.ip.dst_address));
- fib_prefix_from_ip46_addr (&ip46, &fib_pfx);
- fib_pfx.fp_len = 32;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- face->shared.adj = fib_entry_get_adj (fib_entry_index);
- face->shared.flags &= ~HICN_FACE_FLAGS_IFACE;
- face->shared.flags |= HICN_FACE_FLAGS_FACE;
-
- adj = adj_get (face->shared.adj);
- }
-
- vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
- *next = adj->lookup_next_index;
-}
-
-always_inline void
-hicn_face_udp6_encap (vlib_main_t * vm,
- vlib_buffer_t * outer_b0,
- hicn_face_t * face, u32 * next)
-{
- int bogus0;
- u16 new_l0;
- ip6_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* ip */
- ip0 = vlib_buffer_get_current (outer_b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip6.ip), sizeof (ip6_header_t) +
- sizeof (udp_header_t));
- new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, outer_b0)
- - sizeof (*ip0));
- ip0->payload_length = new_l0;
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
- udp0->length = new_l0;
-
- udp0->checksum =
- ip6_tcp_udp_icmp_compute_checksum (vm, outer_b0, ip0, &bogus0);
-
- ASSERT (bogus0 == 0);
-
- if (udp0->checksum == 0)
- udp0->checksum = 0xffff;
-
- int is_iface = 0;
- ip_adjacency_t *adj;
- if (PREDICT_FALSE (face->shared.adj == ~0))
- is_iface = 1;
- else
- adj = adj_get (face->shared.adj);
-
- /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
- * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
- * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
- */
- if (PREDICT_FALSE (is_iface || adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- ip46_address_t ip46 =
- to_ip46 (1, (u8 *) & (face_udp->hdrs.ip6.ip.dst_address));
- fib_prefix_from_ip46_addr (&ip46, &fib_pfx);
- fib_pfx.fp_len = 128;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- face->shared.adj = fib_entry_get_adj (fib_entry_index);
- face->shared.flags &= ~HICN_FACE_FLAGS_IFACE;
- face->shared.flags |= HICN_FACE_FLAGS_FACE;
-
- adj = adj_get (face->shared.adj);
- }
-
- vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
-
- *next = adj->lookup_next_index;
-}
-
-static char *hicn_face_udp4_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_face_udp6_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp4_output_trace_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp6_output_trace_t;
-
-#define HICN_FACE_UDP_ENCAP_IP4 hicn_face_udp4_encap
-#define HICN_FACE_UDP_ENCAP_IP6 hicn_face_udp6_encap
-
-#define TRACE_OUTPUT_PKT_UDP4 hicn_face_udp4_output_trace_t
-#define TRACE_OUTPUT_PKT_UDP6 hicn_face_udp6_output_trace_t
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define face_output_x1(ipv) \
- do { \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
- hicn_face_t * face; \
- \
- /* Prefetch for next iteration. */ \
- if (n_left_from > 1) \
- { \
- vlib_buffer_t *b1; \
- b1 = vlib_get_buffer (vm, from[1]); \
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- hicn_face_id_t face_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- face = \
- hicn_dpoi_get_from_idx(face_id); \
- \
- if (PREDICT_TRUE(face != NULL)) \
- { \
- /* Adjust vlib buffer. Create space for the udp tunnel. */ \
- vlib_buffer_advance(b0, -(sizeof (IP_HEADER_##ipv) + \
- sizeof (udp_header_t))); \
- \
- \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face, &next0); \
- stats.pkts_interest_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_INTEREST_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0));\
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, next0); \
- } while(0) \
-
-
-#define face_output_x2(ipv) \
- do { \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
- u32 next1 = IP_LOOKUP_NEXT_DROP; \
- hicn_face_t *face0, *face1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- \
- hicn_face_id_t face_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- hicn_face_id_t face_id1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \
- face0 = \
- hicn_dpoi_get_from_idx(vnet_buffer (b0)->ip.adj_index[VLIB_TX]); \
- face1 = \
- hicn_dpoi_get_from_idx(vnet_buffer (b1)->ip.adj_index[VLIB_TX]); \
- \
- if (PREDICT_TRUE(face0 != NULL)) \
- { \
- /* Adjust vlib buffer. Create space for the udp tunnel. */ \
- vlib_buffer_advance(b0, -(sizeof (IP_HEADER_##ipv) + \
- sizeof (udp_header_t))); \
- \
- \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face0, &next0); \
- stats.pkts_interest_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id0 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_INTEREST_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_TRUE(face1 != NULL)) \
- { \
- /* Adjust vlib buffer. Create space for the udp tunnel. */ \
- vlib_buffer_advance(b1, -(sizeof (IP_HEADER_##ipv) + \
- sizeof (udp_header_t))); \
- \
- \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b1, face1, &next1); \
- stats.pkts_interest_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id1 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_INTEREST_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
- t->next_index = next1; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b1) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, bi1, next0, next1); \
- } while(0) \
-
-
-static uword
-hicn_face_udp4_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_output_x2 (4);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_output_x1 (4);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp4_output_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_face_udp4_output_trace_t *t =
- va_arg (*args, hicn_face_udp4_output_trace_t *);
-
- s =
- format (s, "FACE_UDP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/* *INDENT-OFF* */
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp4_output_node) =
-{
- .function = hicn_face_udp4_output_node_fn,
- .name = "hicn-face-udp4-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp4_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp4_output_error_strings),
- .error_strings = hicn_face_udp4_output_error_strings,
- .n_next_nodes = IP4_LOOKUP_N_NEXT,
- /* Reusing the list of nodes from lookup to be compatible with arp */
- .next_nodes = IP4_LOOKUP_NEXT_NODES,
-};
-/* *INDENT-ON* */
-
-/* *INDENT-ON* */
-
-static uword
-hicn_face_udp6_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_output_x2 (6);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_output_x1 (6);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp6_output_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_face_udp6_output_trace_t *t =
- va_arg (*args, hicn_face_udp6_output_trace_t *);
-
- s =
- format (s, "FACE_UDP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%u",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/* *INDENT-OFF* */
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp6_output_node) =
-{
- .function = hicn_face_udp6_output_node_fn,
- .name = "hicn-face-udp6-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp6_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp6_output_error_strings),
- .error_strings = hicn_face_udp6_output_error_strings,
- .n_next_nodes = IP6_LOOKUP_N_NEXT,
- /* Reusing the list of nodes from lookup to be compatible with neighbour discovery */
- .next_nodes = IP6_LOOKUP_NEXT_NODES,
-};
-/* *INDENT-ON* */
-
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp_node.h b/hicn-plugin/src/faces/udp/face_udp_node.h
deleted file mode 100644
index c759312c8..000000000
--- a/hicn-plugin/src/faces/udp/face_udp_node.h
+++ /dev/null
@@ -1,35 +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.
- */
-
-#ifndef __HICN_FACE_UDP_NODE_H__
-#define __HICN_FACE_UDP_NODE_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-
-extern vlib_node_registration_t hicn_face_udp4_input_node;
-extern vlib_node_registration_t hicn_face_udp6_input_node;
-extern vlib_node_registration_t hicn_face_udp4_output_node;
-extern vlib_node_registration_t hicn_face_udp6_output_node;
-
-#endif // __HICN_FACE_UDP_NODE_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/iface_udp_node.c b/hicn-plugin/src/faces/udp/iface_udp_node.c
deleted file mode 100644
index 1fdd68f0b..000000000
--- a/hicn-plugin/src/faces/udp/iface_udp_node.c
+++ /dev/null
@@ -1,987 +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 "iface_udp_node.h"
-#include "dpo_udp.h"
-#include "../face.h"
-
-#include "../../infra.h"
-#include "../../hicn.h"
-
-/**
- * @File
- *
- * Definition of the nodes for udp incomplete faces.
- */
-
-vlib_node_registration_t hicn_iface_udp4_input_node;
-vlib_node_registration_t hicn_iface_udp6_input_node;
-vlib_node_registration_t hicn_iface_udp4_output_node;
-vlib_node_registration_t hicn_iface_udp6_output_node;
-
-u32 data_fwd_face_udp4_vlib_edge;
-u32 data_fwd_face_udp6_vlib_edge;
-
-void
-hicn_iface_udp_init (vlib_main_t * vm)
-{
- data_fwd_face_udp4_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_udp4_output_node.index);
-
- data_fwd_face_udp6_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_udp6_output_node.index);
-
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_udp4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_udp6_output_node.index);
-
- ASSERT (temp_index4 == data_fwd_face_udp4_vlib_edge);
- ASSERT (temp_index6 == data_fwd_face_udp6_vlib_edge);
-}
-
-static char *hicn_iface_udp4_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_iface_udp6_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-u32
-get_face_udp4_output_node (void)
-{
- return data_fwd_face_udp4_vlib_edge;
-}
-
-u32
-get_face_udp6_output_node (void)
-{
- return data_fwd_face_udp6_vlib_edge;
-}
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp4_input_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP4_INPUT_NEXT_INTEREST,
- HICN_IFACE_UDP4_INPUT_NEXT_MAPME,
- HICN_IFACE_UDP4_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP4_INPUT_N_NEXT,
-} hicn_iface_udp4_input_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp6_input_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP6_INPUT_NEXT_INTEREST,
- HICN_IFACE_UDP6_INPUT_NEXT_MAPME,
- HICN_IFACE_UDP6_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP6_INPUT_N_NEXT,
-} hicn_iface_udp6_input_next_t;
-
-#define ERROR_INPUT_UDP4 HICN_IFACE_UDP4_INPUT_NEXT_ERROR_DROP
-#define ERROR_INPUT_UDP6 HICN_IFACE_UDP6_INPUT_NEXT_ERROR_DROP
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define NEXT_MAPME_UDP4 HICN_IFACE_UDP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_UDP6 HICN_IFACE_UDP6_INPUT_NEXT_MAPME
-
-#define NEXT_INTEREST_UDP4 HICN_IFACE_UDP4_INPUT_NEXT_INTEREST
-#define NEXT_INTEREST_UDP6 HICN_IFACE_UDP6_INPUT_NEXT_INTEREST
-
-#define HICN_IFACE_UDP_ADD_LOCK_IP4 hicn_dpo_udp4_add_and_lock
-#define HICN_IFACE_UDP_ADD_LOCK_IP6 hicn_dpo_udp6_add_and_lock
-
-#define GET_FACE_UDP4 get_face_udp4_output_node
-#define GET_FACE_UDP6 get_face_udp6_output_node
-
-#define TRACE_INPUT_PKT_UDP4 hicn_iface_udp4_input_trace_t
-#define TRACE_INPUT_PKT_UDP6 hicn_iface_udp6_input_trace_t
-
-#define iface_input_x1(ipv) \
- do { \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr = NULL; \
- u8 * inner_ip_hdr = NULL; \
- udp_header_t * udp_hdr = NULL; \
- hicn_buffer_t * hicnb0; \
- /* Prefetch for next iteration. */ \
- if (n_left_from > 1) \
- { \
- vlib_buffer_t *b1; \
- b1 = vlib_get_buffer (vm, from[1]); \
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- udp_hdr = (udp_header_t *) (ip_hdr + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- \
- stats.pkts_interest_count += 1; \
- \
- inner_ip_hdr = (u8 *)(udp_hdr + 1); \
- u8 is_v6 = hicn_is_v6((hicn_header_t *)inner_ip_hdr); \
- u8 is_icmp = is_v6*(inner_ip_hdr[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6)*(inner_ip_hdr[9] == IPPROTO_ICMPV4); \
- \
- next0 = is_icmp*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp)*NEXT_INTEREST_UDP##ipv; \
- \
- HICN_IFACE_UDP_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr->dst_address), \
- &(ip_hdr->src_address), \
- udp_hdr->dst_port, \
- udp_hdr->src_port, \
- GET_FACE_UDP##ipv \
- (), \
- &hicnb0->flags, \
- vnet_buffer(b0)->sw_if_index[VLIB_RX]); \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0), \
- sizeof (t->packet_data)); \
- } \
- \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, next0); \
- }while(0)
-
-
-#define iface_input_x2(ipv) \
- do { \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0, next1 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr0 = NULL, *ip_hdr1 = NULL; \
- u8 * inner_ip_hdr0 = NULL, *inner_ip_hdr1 = NULL; \
- udp_header_t * udp_hdr0 = NULL, *udp_hdr1 = NULL; \
- hicn_buffer_t * hicnb0, *hicnb1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- ip_hdr0 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- ip_hdr1 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b1); \
- udp_hdr0 = (udp_header_t *) (ip_hdr0 + 1); \
- udp_hdr1 = (udp_header_t *) (ip_hdr1 + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- hicnb1 = hicn_get_buffer(b1); \
- \
- stats.pkts_interest_count += 2; \
- \
- inner_ip_hdr0 = (u8 *)(udp_hdr0 + 1); \
- inner_ip_hdr1 = (u8 *)(udp_hdr1 + 1); \
- u8 is_v6_0 = hicn_is_v6((hicn_header_t *)inner_ip_hdr0); \
- u8 is_v6_1 = hicn_is_v6((hicn_header_t *)inner_ip_hdr1); \
- u8 is_icmp0 = is_v6_0*(inner_ip_hdr0[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_0)*(inner_ip_hdr0[9] == IPPROTO_ICMPV4); \
- u8 is_icmp1 = is_v6_1*(inner_ip_hdr1[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_1)*(inner_ip_hdr1[9] == IPPROTO_ICMPV4); \
- \
- next0 = is_icmp0*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp0)*NEXT_INTEREST_UDP##ipv; \
- next1 = is_icmp1*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp1)*NEXT_INTEREST_UDP##ipv; \
- \
- HICN_IFACE_UDP_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr0->dst_address), \
- &(ip_hdr0->src_address), \
- udp_hdr0->dst_port, \
- udp_hdr0->src_port, \
- GET_FACE_UDP##ipv \
- (), \
- &hicnb0->flags, \
- vnet_buffer(b0)->sw_if_index[VLIB_RX]); \
- \
- \
- HICN_IFACE_UDP_ADD_LOCK_IP##ipv \
- (&(hicnb1->face_dpo_id), \
- &(ip_hdr1->dst_address), \
- &(ip_hdr1->src_address), \
- udp_hdr1->dst_port, \
- udp_hdr1->src_port, \
- GET_FACE_UDP##ipv \
- (), \
- &hicnb1->flags, \
- vnet_buffer(b1)->sw_if_index[VLIB_RX]); \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- \
- vlib_buffer_advance(b1, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0), \
- sizeof (t->packet_data)); \
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
- t->next_index = next1; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b1), \
- sizeof (t->packet_data)); \
- } \
- \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- \
- vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, bi1, next0, next1); \
- }while(0)
-
-
-static uword
-hicn_iface_udp4_input_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- iface_input_x2 (4);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_input_x1 (4);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp4_input_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_iface_udp4_input_trace_t *t =
- va_arg (*args, hicn_iface_udp4_input_trace_t *);
-
- s =
- format (s, "IFACE_UDP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp4_input_node) =
-
-{
- .function = hicn_iface_udp4_input_node_fn,
- .name = "hicn-iface-udp4-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp4_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp4_input_error_strings),
- .error_strings = hicn_iface_udp4_input_error_strings,
- .n_next_nodes = HICN_IFACE_UDP4_INPUT_N_NEXT,
- .next_nodes =
- {
- [HICN_IFACE_UDP4_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_UDP4_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_UDP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-
-static uword
-hicn_iface_udp6_input_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- iface_input_x2 (6);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_input_x1 (6);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp6_input_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_iface_udp6_input_trace_t *t =
- va_arg (*args, hicn_iface_udp6_input_trace_t *);
-
- s =
- format (s, "IFACE_UDP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp6_input_node) =
-{
- .function = hicn_iface_udp6_input_node_fn,
- .name = "hicn-iface-udp6-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp6_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp6_input_error_strings),
- .error_strings = hicn_iface_udp6_input_error_strings,
- .n_next_nodes = HICN_IFACE_UDP6_INPUT_N_NEXT,
- .next_nodes =
- {
- [HICN_IFACE_UDP6_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_UDP6_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_UDP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-/******* Iface Output *******/
-
-always_inline void
-hicn_iface_udp4_encap (vlib_main_t * vm,
- vlib_buffer_t * b0, hicn_face_t * face)
-{
- u16 new_l0 = 0;
- ip4_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* Adjust vlib buffers */
- /* Set the right length on the header buffer */
- /* Move the next buffer current data pointer back to the ip+tcp header (hicn header) */
- word offset = sizeof (ip4_header_t) + sizeof (udp_header_t);
- vlib_buffer_advance (b0, -offset);
-
- /* ip */
- ip0 = vlib_buffer_get_current (b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip4.ip), sizeof (ip4_header_t) +
- sizeof (udp_header_t));
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
-
- new_l0 =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) -
- sizeof (*ip0));
- udp0->length = new_l0;
-
- ip0->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
- ip0->checksum = ip4_header_checksum (ip0);
-}
-
-always_inline void
-hicn_iface_udp6_encap (vlib_main_t * vm,
- vlib_buffer_t * b0, hicn_face_t * face)
-{
- int bogus0;
- u16 new_l0;
- ip6_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* Adjust vlib buffer */
- word offset = sizeof (ip6_header_t) + sizeof (udp_header_t);
- vlib_buffer_advance (b0, -offset);
-
- /* ip */
- ip0 = vlib_buffer_get_current (b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip6.ip), sizeof (ip6_header_t) +
- sizeof (udp_header_t));
-
- new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)
- - sizeof (*ip0));
-
- ip0->payload_length = new_l0;
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
- udp0->length = new_l0;
-
- udp0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0, &bogus0);
-
- ASSERT (bogus0 == 0);
-
- if (udp0->checksum == 0)
- udp0->checksum = 0xffff;
-}
-
-static char *hicn_iface_udp4_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_iface_udp6_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp4_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP4_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_UDP4_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP4_OUTPUT_N_NEXT,
-} hicn_iface_udp4_output_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp6_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP6_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_UDP6_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP6_OUTPUT_N_NEXT,
-} hicn_iface_udp6_output_next_t;
-
-#define ERROR_OUTPUT_UDP4 HICN_IFACE_UDP4_OUTPUT_NEXT_ERROR_DROP
-#define ERROR_OUTPUT_UDP6 HICN_IFACE_UDP6_OUTPUT_NEXT_ERROR_DROP
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define NEXT_LOOKUP_UDP4 HICN_IFACE_UDP4_OUTPUT_NEXT_LOOKUP
-#define NEXT_LOOKUP_UDP6 HICN_IFACE_UDP6_OUTPUT_NEXT_LOOKUP
-
-#define HICN_IFACE_UDP_ADD_LOCK_IP4 hicn_dpo_udp4_add_and_lock
-#define HICN_IFACE_UDP_ADD_LOCK_IP6 hicn_dpo_udp6_add_and_lock
-
-#define HICN_FACE_UDP_ENCAP_IP4 hicn_iface_udp4_encap
-#define HICN_FACE_UDP_ENCAP_IP6 hicn_iface_udp6_encap
-
-#define TRACE_OUTPUT_PKT_UDP4 hicn_iface_udp4_output_trace_t
-#define TRACE_OUTPUT_PKT_UDP6 hicn_iface_udp6_output_trace_t
-
-#define SIZE_HICN_HEADER4 sizeof(ip4_header_t) + sizeof(udp_header_t)
-#define SIZE_HICN_HEADER6 sizeof(ip6_header_t) + sizeof(udp_header_t)
-
-#define iface_output_x1(ipv) \
- do { \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = ERROR_OUTPUT_UDP##ipv; \
- hicn_face_t * face; \
- \
- /* Prefetch for next iteration. */ \
- if (n_left_from > 1) \
- { \
- vlib_buffer_t *b1; \
- b1 = vlib_get_buffer (vm, from[1]); \
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- \
- hicn_face_id_t face_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- face = \
- hicn_dpoi_get_from_idx(face_id); \
- \
- if (PREDICT_TRUE(face != NULL)) \
- { \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face); \
- next0 = NEXT_LOOKUP_UDP##ipv; \
- stats.pkts_data_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_DATA_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, next0); \
- } while(0)
-
-#define iface_output_x2(ipv) \
- do { \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0 = ERROR_OUTPUT_UDP##ipv, next1 = ERROR_OUTPUT_UDP##ipv; \
- hicn_face_t *face0, *face1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue packets buffers */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- \
- hicn_face_id_t face_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- hicn_face_id_t face_id1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \
- face0 = \
- hicn_dpoi_get_from_idx(face_id0); \
- face1 = \
- hicn_dpoi_get_from_idx(face_id1); \
- \
- if (PREDICT_TRUE(face0 != NULL)) \
- { \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face0); \
- next0 = NEXT_LOOKUP_UDP##ipv; \
- stats.pkts_data_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id0 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_DATA_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_TRUE(face1 != NULL)) \
- { \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b1, face1); \
- next1 = NEXT_LOOKUP_UDP##ipv; \
- stats.pkts_data_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id1 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_DATA_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- t->next_index = next0; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b0) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_INTEREST; \
- t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
- t->next_index = next1; \
- clib_memcpy_fast (t->packet_data, \
- vlib_buffer_get_current (b1) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* Verify speculative enqueue, maybe switch current next frame */ \
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index, \
- to_next, n_left_to_next, \
- bi0, bi1, next0, next1); \
- } while(0)
-
-
-static uword
-hicn_iface_udp4_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- iface_output_x2 (4);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_output_x1 (4);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp4_output_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_iface_udp4_output_trace_t *t =
- va_arg (*args, hicn_iface_udp4_output_trace_t *);
-
- s =
- format (s,
- "IFACE_UDP4_OUTPUT: pkt: %d, out face %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp4_output_node) =
-{
- .function = hicn_iface_udp4_output_node_fn,
- .name = "hicn-iface-udp4-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp4_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp4_output_error_strings),
- .error_strings = hicn_iface_udp4_output_error_strings,
- .n_next_nodes = HICN_IFACE_UDP4_OUTPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_IFACE_UDP4_OUTPUT_NEXT_LOOKUP] = "ip4-lookup",
- [HICN_IFACE_UDP4_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-
-static uword
-hicn_iface_udp6_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- iface_output_x2 (6);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_output_x1 (6);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp6_output_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_iface_udp6_output_trace_t *t =
- va_arg (*args, hicn_iface_udp6_output_trace_t *);
-
- s =
- format (s,
- "IFACE_UDP6_OUTPUT: pkt: %d, out face %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp6_output_node) =
-{
- .function = hicn_iface_udp6_output_node_fn,
- .name = "hicn-iface-udp6-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp6_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp6_output_error_strings),
- .error_strings = hicn_iface_udp6_output_error_strings,
- .n_next_nodes = HICN_IFACE_UDP6_OUTPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_IFACE_UDP6_OUTPUT_NEXT_LOOKUP] = "ip6-lookup",
- [HICN_IFACE_UDP6_OUTPUT_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/faces/udp/iface_udp_node.h b/hicn-plugin/src/faces/udp/iface_udp_node.h
deleted file mode 100644
index 957d19217..000000000
--- a/hicn-plugin/src/faces/udp/iface_udp_node.h
+++ /dev/null
@@ -1,36 +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.
- */
-
-#ifndef __HICN_IFACE_UDP_H__
-#define __HICN_IFACE_UDP_H__
-
-#include <vlib/vlib.h>
-
-extern vlib_node_registration_t hicn_iface_udp4_input_node;
-extern vlib_node_registration_t hicn_iface_udp6_input_node;
-extern vlib_node_registration_t hicn_iface_udp4_output_node;
-extern vlib_node_registration_t hicn_iface_udp6_output_node;
-
-void hicn_iface_udp_init (vlib_main_t * vm);
-
-#endif // __HICN_FACE_UDP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
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.api b/hicn-plugin/src/hicn.api
index 01e4da213..9643f2098 100644
--- a/hicn-plugin/src/hicn.api
+++ b/hicn-plugin/src/hicn.api
@@ -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:
@@ -16,43 +16,16 @@
option version = "5.1.0";
import "vnet/ip/ip_types.api";
-enum hicn_face_type
+enum hicn_action_type
{
- IP_FACE = 0,
- UDP_FACE,
+ HICN_DISABLE = 0,
+ HICN_ENABLE,
};
-typedef hicn_face_ip
+typedef hicn_face
{
/* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
-
- /* IPv4 local port number */
- u32 swif;
-
- /* Face flags */
- u32 flags;
-
- /* Name of the interface */
- u8 if_name[30];
-};
-
-typedef hicn_face_udp
-{
- /* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
-
- /* Local port */
- u16 lport;
-
- /* Remote port */
- u16 rport;
+ vl_api_address_t nat_addr;
/* IPv4 local port number */
u32 swif;
@@ -64,12 +37,6 @@ typedef hicn_face_udp
u8 if_name[30];
};
-typedef hicn_face_union
-{
- vl_api_hicn_face_ip_t ip;
- vl_api_hicn_face_udp_t udp;
-};
-
define hicn_api_node_params_set
{
/* Client identifier, set from api_main.my_client_index */
@@ -87,9 +54,6 @@ define hicn_api_node_params_set
/* CS maximum size, otherwise -1 to assign default value */
i32 cs_max_size;
- /* Portion of CS reserved to application, otherwise -1 to assign default value */
- i32 cs_reserved_app;
-
/* Upper bound on PIT entry lifetime, otherwise -1 to assign default value */
f64 pit_max_lifetime_sec;
};
@@ -205,51 +169,6 @@ define hicn_api_node_stats_get_reply
u64 cs_entries_ntw_count;
};
-define hicn_api_face_ip_add
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* IP local address */
- vl_api_hicn_face_ip_t face;
-};
-
-define hicn_api_face_ip_add_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value: new Face ID, ~0 means no Face was created */
- u32 faceid;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_face_ip_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* A Face ID to be deleted */
- u32 faceid;
-};
-
-define hicn_api_face_ip_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
define hicn_api_face_stats_details
{
/* From the request */
@@ -291,7 +210,7 @@ define hicn_api_face_stats_dump
u32 context;
};
-define hicn_api_face_ip_params_get
+define hicn_api_face_params_get
{
/* Client identifier, set from api_main.my_client_index */
u32 client_index;
@@ -303,7 +222,7 @@ define hicn_api_face_ip_params_get
u32 faceid;
};
-define hicn_api_face_ip_params_get_reply
+define hicn_api_face_params_get_reply
{
/* From the request */
u32 context;
@@ -315,10 +234,7 @@ define hicn_api_face_ip_params_get_reply
u32 faceid;
/* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
+ vl_api_address_t nat_addr;
/* VPP interface (index) associated with the face */
u32 swif;
@@ -327,54 +243,6 @@ define hicn_api_face_ip_params_get_reply
u32 flags;
};
-define hicn_api_face_add
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Type of face to add */
- vl_api_hicn_face_type_t type;
-
- /* Face to add */
- vl_api_hicn_face_union_t face;
-};
-
-define hicn_api_face_add_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value: new Face ID, ~0 means no Face was created */
- u32 faceid;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_face_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* A Face ID to be deleted */
- u32 faceid;
-};
-
-define hicn_api_face_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
define hicn_api_faces_details
{
/* From the request */
@@ -386,11 +254,8 @@ define hicn_api_faces_details
/* Id of the face */
u32 faceid;
- /* Type of face to add */
- vl_api_hicn_face_type_t type;
-
/* Face to add */
- vl_api_hicn_face_union_t face;
+ vl_api_hicn_face_t face;
};
define hicn_api_faces_dump
@@ -425,83 +290,8 @@ define hicn_api_face_get_reply
/* Id of the face */
u32 faceid;
- /* Type of face to add */
- vl_api_hicn_face_type_t type;
-
/* Face to add */
- vl_api_hicn_face_union_t face;
-};
-
-define hicn_api_route_nhops_add
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Prefix to be added to the FIB */
- vl_api_prefix_t prefix;
-
- /* A Face ID to the next hop forwarder for the specified prefix */
- u32 face_ids[5];
-
- /* Number of face to add */
- u8 n_faces;
-};
-
-define hicn_api_route_nhops_add_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_route_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Prefix to be added to the FIB */
- vl_api_prefix_t prefix;
-};
-
-define hicn_api_route_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_route_nhop_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Prefix to be added to the FIB */
- vl_api_prefix_t prefix;
-
- /* Specific next-hop to be removed */
- u32 faceid;
-};
-
-define hicn_api_route_nhop_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
+ vl_api_hicn_face_t face;
};
define hicn_api_route_get
@@ -624,6 +414,33 @@ define hicn_api_strategy_get_reply
i32 retval;
};
+define hicn_api_enable_disable
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* Enable or disable enable/disable hICN*/
+ vl_api_hicn_action_type_t enable_disable;
+
+ /* Prefix on which we enable/disable hICN*/
+ vl_api_prefix_t prefix;
+};
+
+define hicn_api_enable_disable_reply
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+/* Return value, zero means all OK */
+ i32 retval;
+};
+
define hicn_api_register_prod_app
{
/* Client identifier, set from api_main.my_client_index */
@@ -717,6 +534,42 @@ autoreply define hicn_api_face_cons_del
u32 faceid;
};
+define hicn_api_udp_tunnel_add_del
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* Source address */
+ vl_api_address_t src_addr;
+
+ /* Destination address */
+ vl_api_address_t dst_addr;
+
+ /* Source port */
+ u16 src_port;
+
+ /* Destination port */
+ u16 dst_port;
+
+ /* Add or remove the tunnel*/
+ u8 is_add;
+};
+
+define hicn_api_udp_tunnel_add_del_reply
+{
+ /* From the request */
+ u32 context;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+
+ /* Udp encap index */
+ u32 uei;
+};
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/hicn-plugin/src/hicn.c b/hicn-plugin/src/hicn.c
index 7c2776869..43a717f80 100644
--- a/hicn-plugin/src/hicn.c
+++ b/hicn-plugin/src/hicn.c
@@ -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:
@@ -16,6 +16,7 @@
#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
#include <vlib/vlib.h>
+#include <vnet/interface.h>
#include "hicn.h"
#include "params.h"
@@ -25,7 +26,7 @@
#include "error.h"
#include "faces/app/address_mgr.h"
#include "face_db.h"
-#include "faces/udp/face_udp.h"
+#include "udp_tunnels/udp_tunnel.h"
#include "route.h"
hicn_main_t hicn_main;
@@ -45,8 +46,7 @@ hicn_face_bucket_t *hicn_face_bucket_pool;
* Init hicn forwarder with configurable PIT, CS sizes
*/
static int
-hicn_infra_fwdr_init (uint32_t shard_pit_size, uint32_t shard_cs_size,
- uint32_t cs_reserved)
+hicn_infra_fwdr_init (uint32_t shard_pit_size, uint32_t shard_cs_size)
{
int ret = 0;
@@ -64,12 +64,7 @@ hicn_infra_fwdr_init (uint32_t shard_pit_size, uint32_t shard_cs_size,
hicn_infra_slow_timer = 1;
ret = hicn_pit_create (&hicn_main.pitcs, hicn_infra_pit_size);
- hicn_pit_set_lru_max (&hicn_main.pitcs,
- hicn_infra_cs_size -
- (hicn_infra_cs_size * cs_reserved / 100));
- hicn_pit_set_lru_app_max (&hicn_main.pitcs,
- hicn_infra_cs_size * cs_reserved / 100);
-
+ hicn_pit_set_lru_max (&hicn_main.pitcs, hicn_infra_cs_size);
done:
if ((ret == HICN_ERROR_NONE) && !hicn_infra_fwdr_initialized)
{
@@ -86,12 +81,13 @@ int
hicn_infra_plugin_enable_disable (int enable_disable,
int pit_size_req,
f64 pit_max_lifetime_sec_req,
- int cs_size_req, int cs_reserved_app)
+ int cs_size_req,
+ vnet_link_t link)
{
int ret = 0;
hicn_main_t *sm = &hicn_main;
- uint32_t pit_size, cs_size, cs_reserved;
+ uint32_t pit_size, cs_size;
/* Notice if we're already enabled... */
if (sm->is_enabled)
@@ -168,18 +164,7 @@ hicn_infra_plugin_enable_disable (int enable_disable,
cs_size = (uint32_t) cs_size_req;
}
- if (cs_reserved_app < 0)
- {
- cs_reserved = HICN_PARAM_CS_RESERVED_APP;
- }
- else
- {
- if (cs_reserved_app >= 100)
- ret = HICN_ERROR_CS_CONFIG_RESERVED_OOB;
- cs_reserved = cs_reserved_app;
- }
-
- ret = hicn_infra_fwdr_init (pit_size, cs_size, cs_reserved);
+ ret = hicn_infra_fwdr_init (pit_size, cs_size);
hicn_face_db_init (pit_size);
@@ -188,8 +173,8 @@ hicn_infra_plugin_enable_disable (int enable_disable,
goto done;
}
sm->is_enabled = 1;
-
- hicn_face_udp_init_internal ();
+ sm->link = link;
+ //hicn_face_udp_init_internal ();
done:
@@ -202,7 +187,9 @@ hicn_configure (vlib_main_t * vm, unformat_input_t * input)
u32 pit_size = HICN_PARAM_PIT_ENTRIES_DFLT;
u32 cs_size = HICN_PARAM_CS_ENTRIES_DFLT;
u64 pit_lifetime_max_sec = HICN_PARAM_PIT_LIFETIME_DFLT_MAX_MS / SEC_MS;
- int cs_reserved = HICN_PARAM_CS_RESERVED_APP;
+
+ vnet_link_t link;
+
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -212,19 +199,17 @@ hicn_configure (vlib_main_t * vm, unformat_input_t * input)
;
else if (unformat (input, "pit-lifetime-max %u", &pit_lifetime_max_sec))
;
- else if (unformat (input, "cs-reserved-app %u", &cs_reserved))
- ;
+ else if (unformat (input, "grab mpls-tunnels"))
+ link = VNET_LINK_MPLS;
else
break;
-// clib_error_return (0,
-// "hICN parameter unknown");
}
unformat_free (input);
hicn_infra_plugin_enable_disable (1, pit_size,
pit_lifetime_max_sec,
- cs_size, cs_reserved);
+ cs_size, link);
return 0;
@@ -258,6 +243,8 @@ hicn_init (vlib_main_t * vm)
/* Init the route module */
hicn_route_init ();
+ udp_tunnel_init ();
+
return error;
}
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index b469a7ed9..3d980bd49 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.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:
@@ -30,6 +30,8 @@
#undef ip_prefix_len
#define ip_prefix_len(_a) (_a)->len
+#include "faces/face.h"
+
#include <netinet/in.h>
#include <vnet/ip/ip.h>
#include <vnet/tcp/tcp_packet.h>
@@ -37,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)
@@ -54,11 +60,11 @@ typedef u8 weight_t;
#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
#endif
-#define HICN_BUFFER_FLAGS_DEFAULT 0x00
-#define HICN_BUFFER_FLAGS_FACE_IS_APP 0x01
/* vlib_buffer cloning utilities impose that current_lentgh is more that 2*CLIB_CACHE_LINE_BYTES. */
/* This flag is used to mark packets whose lenght is less that 2*CLIB_CACHE_LINE_BYTES. */
#define HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL 0x02
+#define HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL 0x04
+#define HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL 0x08
/* The following is stored in the opaque2 field in the vlib_buffer_t */
typedef struct
@@ -76,8 +82,7 @@ typedef struct
u8 dpo_ctx_id; /* used for data path */
u8 vft_id; /* " */
- dpo_id_t face_dpo_id; /* ingress iface, sizeof(dpo_id_t)
- * <= sizeof(u64) */
+ hicn_face_id_t face_id; /* ingress iface, sizeof(u32) */
u32 in_faces_vec_id; /* vector of possible input face for a data packet */
hicn_type_t type;
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index 7a6babeb2..e6050f96c 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -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:
@@ -25,8 +25,8 @@
#include <vnet/ip/ip_types_api.h>
#include <vnet/ip/ip_format_fns.h>
-#include "faces/ip/face_ip.h"
-#include "faces/udp/face_udp.h"
+#include "faces/face.h"
+#include "udp_tunnels/udp_tunnel.h"
#include "infra.h"
#include "parser.h"
#include "mgmt.h"
@@ -59,7 +59,7 @@
*/
always_inline vnet_api_error_t
hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
- vl_api_hicn_api_face_ip_params_get_reply_t
+ vl_api_hicn_api_face_params_get_reply_t
* reply);
@@ -88,14 +88,11 @@ vl_api_hicn_api_node_params_set_t_handler (vl_api_hicn_api_node_params_set_t *
int cs_max_size = clib_net_to_host_i32 (mp->cs_max_size);
cs_max_size = cs_max_size == -1 ? HICN_PARAM_CS_ENTRIES_DFLT : cs_max_size;
- int cs_reserved_app = clib_net_to_host_i32 (mp->cs_reserved_app);
- cs_reserved_app = cs_reserved_app >= 0
- && cs_reserved_app < 100 ? cs_reserved_app : HICN_PARAM_CS_RESERVED_APP;
-
rv = hicn_infra_plugin_enable_disable ((int) (mp->enable_disable),
pit_max_size,
pit_max_lifetime_sec,
- cs_max_size, cs_reserved_app);
+ cs_max_size,
+ ~0);
REPLY_MACRO (VL_API_HICN_API_NODE_PARAMS_SET_REPLY /* , rmp, mp, rv */ );
}
@@ -141,119 +138,11 @@ vl_api_hicn_api_node_stats_get_t_handler (vl_api_hicn_api_node_stats_get_t *
}
-/****** FACE *******/
-static hicn_error_t
-hicn_api_face_ip_add (vl_api_hicn_face_ip_t * mp, hicn_face_id_t * face_id)
-{
- hicn_error_t rv = HICN_ERROR_NONE;
-
- vnet_main_t *vnm = vnet_get_main ();
-
- ip46_address_t local_addr;
- ip46_address_t remote_addr;
- ip_address_decode (&mp->local_addr, &local_addr);
- ip_address_decode (&mp->remote_addr, &remote_addr);
-
- u32 sw_if = clib_net_to_host_u32 (mp->swif);
-
- if (ip46_address_is_zero (&local_addr))
- {
- if (!vnet_sw_interface_is_valid (vnm, sw_if))
- {
- rv = HICN_ERROR_UNSPECIFIED;
- }
-
- if ((rv == HICN_ERROR_NONE) && ip46_address_is_ip4 (&remote_addr))
- {
- ip_interface_address_t *interface_address;
- ip4_address_t *addr =
- ip4_interface_address_matching_destination (&ip4_main,
- &remote_addr.ip4,
- sw_if,
- &interface_address);
- if (addr == NULL)
- addr = ip4_interface_first_address (&ip4_main,
- sw_if, &interface_address);
-
- if (addr == NULL)
- rv = HICN_ERROR_UNSPECIFIED;
- else
- ip46_address_set_ip4 (&local_addr, addr);
- }
- else
- {
- ip_interface_address_t *interface_address;
- ip6_interface_address_matching_destination (&ip6_main,
- &remote_addr.ip6, sw_if,
- &interface_address);
- ip6_address_t *addr = NULL;
- if (rv == HICN_ERROR_NONE && interface_address != NULL)
- {
- addr =
- (ip6_address_t *)
- ip_interface_address_get_address (&ip6_main.lookup_main,
- interface_address);
- }
- else
- {
- addr = ip6_interface_first_address (&ip6_main, sw_if);
- }
-
- if (addr == NULL)
- rv = HICN_ERROR_UNSPECIFIED;
- else
- ip46_address_set_ip6 (&local_addr, addr);
- }
- }
-
- if (rv == HICN_ERROR_NONE)
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, face_id, 0);
-
- return rv;
-}
-
-static void
-vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
-{
- vl_api_hicn_api_face_ip_add_reply_t *rmp;
- hicn_error_t rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
- hicn_face_id_t face_id = HICN_FACE_NULL;
- rv = hicn_api_face_ip_add (&(mp->face), &face_id);
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_ADD_REPLY /* , rmp, mp, rv */ ,(
- {
- rmp->faceid = clib_host_to_net_u32 ((u32) face_id);
- rmp->retval = rv;
- }));
- /* *INDENT-ON* */
-}
-
-static void
-vl_api_hicn_api_face_ip_del_t_handler (vl_api_hicn_api_face_ip_del_t * mp)
-{
- vl_api_hicn_api_face_ip_del_reply_t *rmp;
- int rv = HICN_ERROR_FACE_NOT_FOUND;
-
- hicn_main_t *sm = &hicn_main;
-
- hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
- if (hicn_dpoi_idx_is_valid (faceid))
- {
- rv = hicn_face_ip_del (faceid);
- }
-
- REPLY_MACRO (VL_API_HICN_API_FACE_IP_DEL_REPLY /* , rmp, mp, rv */ );
-
-}
-
static void
- vl_api_hicn_api_face_ip_params_get_t_handler
- (vl_api_hicn_api_face_ip_params_get_t * mp)
+ vl_api_hicn_api_face_params_get_t_handler
+ (vl_api_hicn_api_face_params_get_t * mp)
{
- vl_api_hicn_api_face_ip_params_get_reply_t *rmp;
+ vl_api_hicn_api_face_params_get_reply_t *rmp;
int rv = 0;
hicn_main_t *sm = &hicn_main;
@@ -261,7 +150,7 @@ static void
hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
/* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_PARAMS_GET_REPLY, (
+ REPLY_MACRO2 (VL_API_HICN_API_FACE_PARAMS_GET_REPLY, (
{
rv = hicn_face_api_entry_params_serialize(faceid, rmp);
rmp->retval = clib_host_to_net_u32(rv);
@@ -269,149 +158,16 @@ static void
/* *INDENT-ON* */
}
-static hicn_error_t
-hicn_api_face_udp_add (vl_api_hicn_face_udp_t * mp, hicn_face_id_t * face_id)
-{
- hicn_error_t rv = HICN_ERROR_NONE;
-
- ip46_address_t local_addr = ip46_address_initializer;
- ip46_address_t remote_addr = ip46_address_initializer;
- u16 lport;
- u16 rport;
- u32 sw_if;
- ip_address_decode (&mp->local_addr, &local_addr);
- ip_address_decode (&mp->remote_addr, &remote_addr);
- //Do not byteswap. We store ports in network order
- lport = mp->lport;
- rport = mp->rport;
- sw_if = clib_net_to_host_u32 (mp->swif);
-
- int input_is_ok = !ip46_address_is_zero (&local_addr)
- && !ip46_address_is_zero (&remote_addr)
- &&
- ((ip46_address_is_ip4 (&local_addr) && ip46_address_is_ip4 (&remote_addr))
- || (!ip46_address_is_ip4 (&local_addr)
- && !ip46_address_is_ip4 (&remote_addr))) && lport != 0 && rport != 0;
-
- if (!input_is_ok)
- {
- rv = HICN_ERROR_UNSPECIFIED;
- }
- else
- {
- rv = hicn_face_udp_add (&local_addr,
- &remote_addr, lport, rport, sw_if, face_id);
- }
- return rv;
-}
-
-static void
-vl_api_hicn_api_face_add_t_handler (vl_api_hicn_api_face_add_t * mp)
-{
- vl_api_hicn_api_face_add_reply_t *rmp;
- hicn_error_t rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
- hicn_face_id_t face_id;
- vl_api_hicn_face_type_t face_type = clib_net_to_host_u32 (mp->type);
-
- switch (face_type)
- {
- case IP_FACE:
- rv = hicn_api_face_ip_add (&(mp->face.ip), &face_id);
- break;
- case UDP_FACE:
- rv = hicn_api_face_udp_add (&(mp->face.udp), &face_id);
- break;
- default:
- rv = HICN_ERROR_UNSPECIFIED;
- break;
- }
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_HICN_API_FACE_ADD_REPLY /* , rmp, mp, rv */ ,(
- {
- rmp->faceid = clib_host_to_net_u32 ((u32) face_id);
- rmp->retval = clib_host_to_net_u32 (rv);
- }));
- /* *INDENT-ON* */
-}
-
static void
-vl_api_hicn_api_face_del_t_handler (vl_api_hicn_api_face_del_t * mp)
-{
- vl_api_hicn_api_face_del_reply_t *rmp;
- int rv = HICN_ERROR_FACE_NOT_FOUND;
-
- hicn_main_t *sm = &hicn_main;
-
- hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
- if (hicn_dpoi_idx_is_valid (faceid))
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
- hicn_face_vft_t *vft = hicn_face_get_vft (face->shared.face_type);
- rv = vft->hicn_face_del (faceid);
- }
-
- REPLY_MACRO (VL_API_HICN_API_FACE_DEL_REPLY /* , rmp, mp, rv */ );
-}
-
-static void
-send_face_ip_details (hicn_face_t * face, vl_api_hicn_face_ip_t * mp)
+send_face_details (hicn_face_t * face, vl_api_hicn_face_t * mp)
{
vnet_main_t *vnm = vnet_get_main ();
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY, &mp->local_addr);
- ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY, &mp->remote_addr);
- mp->flags = clib_host_to_net_u32 (face->shared.flags);
- mp->swif = clib_net_to_host_u32 (face->shared.sw_if);
+ ip_address_encode (&face->nat_addr, IP46_TYPE_ANY, &mp->nat_addr);
+ mp->flags = clib_host_to_net_u32 (face->flags);
+ mp->swif = clib_net_to_host_u32 (face->sw_if);
vnet_sw_interface_t *sw_interface =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- u8 *sbuf = 0;
- if (sw_interface != NULL)
- {
- sbuf =
- format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface);
- strcpy ((char *) (mp->if_name), (char *) sbuf);
- }
-}
-
-static void
-send_face_udp_details (hicn_face_t * face, vl_api_hicn_face_udp_t * mp)
-{
- vnet_main_t *vnm = vnet_get_main ();
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- if (face_udp->hdrs.ip4.ip.ip_version_and_header_length == 0x45)
- {
- ip46_address_t src_addr = { 0 };
- ip46_address_t dst_addr = { 0 };
- ip46_address_set_ip4 (&src_addr, &(face_udp->hdrs.ip4.ip.src_address));
- ip46_address_set_ip4 (&dst_addr, &(face_udp->hdrs.ip4.ip.dst_address));
-
- ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr));
- ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr));
- //Do not swap, they are already in network order
- mp->lport = face_udp->hdrs.ip4.udp.src_port;
- mp->rport = face_udp->hdrs.ip4.udp.dst_port;
- }
- else
- {
- ip46_address_t src_addr = { 0 };
- ip46_address_t dst_addr = { 0 };
- ip46_address_set_ip6 (&src_addr, &(face_udp->hdrs.ip6.ip.src_address));
- ip46_address_set_ip6 (&dst_addr, &(face_udp->hdrs.ip6.ip.dst_address));
-
- ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr));
- ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr));
- //Do not swap, they are already in network order
- mp->lport = face_udp->hdrs.ip6.udp.src_port;
- mp->rport = face_udp->hdrs.ip6.udp.dst_port;
- }
- mp->flags = clib_host_to_net_u32 (face->shared.flags);
- mp->swif = clib_net_to_host_u32 (face->shared.sw_if);
- vnet_sw_interface_t *sw_interface =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
+ vnet_get_sw_interface_or_null (vnm, face->sw_if);
u8 *sbuf = 0;
if (sw_interface != NULL)
{
@@ -433,17 +189,7 @@ send_faces_details (vl_api_registration_t * reg,
mp->_vl_msg_id = htons (VL_API_HICN_API_FACES_DETAILS + hm->msg_id_base);
mp->context = context;
- if (face->shared.face_type == hicn_face_ip_type)
- {
- mp->type = clib_host_to_net_u32 (IP_FACE);
- send_face_ip_details (face, &(mp->face.ip));
- }
- else if (face->shared.face_type == hicn_face_udp_type)
- {
- mp->type = clib_host_to_net_u32 (UDP_FACE);
- send_face_udp_details (face, &(mp->face.udp));
- }
-
+ send_face_details (face, &(mp->face));
vl_api_send_msg (reg, (u8 *) mp);
}
@@ -483,16 +229,7 @@ vl_api_hicn_api_face_get_t_handler (vl_api_hicn_api_face_get_t * mp)
if (rv)
{
hicn_face_t * face = hicn_dpoi_get_from_idx(faceid);
- if (face->shared.face_type == hicn_face_ip_type)
- {
- rmp->type = IP_FACE;
- send_face_ip_details(face, &(rmp->face.ip));
- }
- else if (face->shared.face_type == hicn_face_udp_type)
- {
- rmp->type = UDP_FACE;
- send_face_udp_details(face, &(rmp->face.udp));
- }
+ send_face_details(face, &(rmp->face));
rv = HICN_ERROR_NONE;
}
else
@@ -568,77 +305,6 @@ static void
/****** ROUTE *******/
-static void
-vl_api_hicn_api_route_nhops_add_t_handler (vl_api_hicn_api_route_nhops_add_t
- * mp)
-{
- vl_api_hicn_api_route_nhops_add_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
- hicn_face_id_t face_ids[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
-
- hicn_main_t *sm = &hicn_main;
-
- fib_prefix_t prefix;
- ip_prefix_decode (&mp->prefix, &prefix);
-
- u8 n_faces = mp->n_faces;
-
- for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++)
- {
- face_ids[i] = clib_net_to_host_u32 (mp->face_ids[i]);
- }
-
- if ((face_ids == NULL) || (n_faces > HICN_PARAM_FIB_ENTRY_NHOPS_MAX))
- {
- rv = VNET_API_ERROR_INVALID_ARGUMENT;
- }
- if (rv == HICN_ERROR_NONE)
- {
- rv = hicn_route_add (face_ids, n_faces, &prefix);
-
- if (rv == HICN_ERROR_ROUTE_ALREADY_EXISTS)
- {
- rv = hicn_route_add_nhops (face_ids, n_faces, &prefix);
- }
- }
- REPLY_MACRO (VL_API_HICN_API_ROUTE_NHOPS_ADD_REPLY /* , rmp, mp, rv */ );
-}
-
-
-static void vl_api_hicn_api_route_del_t_handler
- (vl_api_hicn_api_route_del_t * mp)
-{
- vl_api_hicn_api_route_del_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
-
- fib_prefix_t prefix;
- ip_prefix_decode (&mp->prefix, &prefix);
-
- rv = hicn_route_del (&prefix);
-
- REPLY_MACRO (VL_API_HICN_API_ROUTE_DEL_REPLY /* , rmp, mp, rv */ );
-}
-
-static void vl_api_hicn_api_route_nhop_del_t_handler
- (vl_api_hicn_api_route_nhop_del_t * mp)
-{
- vl_api_hicn_api_route_nhop_del_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
-
- fib_prefix_t prefix;
- ip_prefix_decode (&mp->prefix, &prefix);
- hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
-
-
- rv = hicn_route_del_nhop (&prefix, faceid);
-
- REPLY_MACRO (VL_API_HICN_API_ROUTE_NHOP_DEL_REPLY /* , rmp, mp, rv */ );
-}
-
static void vl_api_hicn_api_route_get_t_handler
(vl_api_hicn_api_route_get_t * mp)
{
@@ -663,9 +329,7 @@ static void vl_api_hicn_api_route_get_t_handler
hicn_dpo_ctx = hicn_strategy_dpo_ctx_get(hicn_dpo_id->dpoi_index);
for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count; i++)
{
- if (dpo_id_is_valid(&hicn_dpo_ctx->next_hops[i]))
- {
- rmp->faceids[i] =((dpo_id_t *) &hicn_dpo_ctx->next_hops[i])->dpoi_index;}
+ rmp->faceids[i] = hicn_dpo_ctx->next_hops[i];
}
rmp->strategy_id = clib_host_to_net_u32(hicn_dpo_get_vft_id(hicn_dpo_id));}
}));
@@ -699,14 +363,10 @@ send_route_details (vl_api_registration_t * reg,
for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count;
i++)
{
- if (dpo_id_is_valid (&hicn_dpo_ctx->next_hops[i]))
- {
- mp->faceids[i] =
- clib_host_to_net_u32 (((dpo_id_t *) &
- hicn_dpo_ctx->
- next_hops[i])->dpoi_index);
+ mp->faceids[i] =
+ clib_host_to_net_u32 (hicn_dpo_ctx->
+ next_hops[i]);
mp->nfaces++;
- }
}
mp->strategy_id =
clib_host_to_net_u32 (hicn_dpo_get_vft_id (hicn_dpo_id));
@@ -930,6 +590,83 @@ vl_api_hicn_api_face_cons_del_t_handler (vl_api_hicn_api_face_cons_del_t * mp)
REPLY_MACRO (VL_API_HICN_API_FACE_CONS_DEL_REPLY /* , rmp, mp, rv */ );
}
+static void vl_api_hicn_api_enable_disable_t_handler
+(vl_api_hicn_api_enable_disable_t * mp)
+{
+ vl_api_hicn_api_enable_disable_reply_t *rmp;
+ int rv = HICN_ERROR_NONE;
+
+ hicn_main_t *sm = &hicn_main;
+
+ fib_prefix_t prefix;
+ ip_prefix_decode (&mp->prefix, &prefix);
+
+ switch (clib_net_to_host_u32(mp->enable_disable))
+ {
+ case HICN_ENABLE:
+ rv = hicn_route_enable(&prefix);
+ break;
+ case HICN_DISABLE:
+ rv = hicn_route_disable(&prefix);
+ break;
+ }
+
+ REPLY_MACRO (VL_API_HICN_API_ENABLE_DISABLE_REPLY/* , rmp, mp, rv */ );
+}
+
+/*********************************** UDP TUNNELS ************************************/
+
+static void vl_api_hicn_api_udp_tunnel_add_del_t_handler
+(vl_api_hicn_api_udp_tunnel_add_del_t * mp)
+{
+ vl_api_hicn_api_udp_tunnel_add_del_reply_t *rmp;
+ int rv = HICN_ERROR_NONE;
+
+ hicn_main_t *sm = &hicn_main;
+
+ ip46_address_t src_addr;
+ ip46_address_t dst_addr;
+ u16 src_port;
+ u16 dst_port;
+ index_t uei = ~0;
+
+ ip46_type_t type = ip_address_decode (&mp->src_addr, &src_addr);
+ if (type != ip_address_decode (&mp->dst_addr, &dst_addr))
+ {
+ rv = HICN_ERROR_UDP_TUNNEL_SRC_DST_TYPE;
+ goto done;
+ }
+
+ src_port = clib_net_to_host_u16(mp->src_port);
+ dst_port = clib_net_to_host_u16(mp->dst_port);
+
+ fib_protocol_t proto = ip46_address_is_ip4(&src_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+
+ index_t fib_index = fib_table_find (proto, HICN_FIB_TABLE);
+
+ if (mp->is_add)
+ {
+ uei = udp_tunnel_add(proto,
+ fib_index, &src_addr, &dst_addr, src_port, dst_port,
+ UDP_ENCAP_FIXUP_NONE);
+ }
+ else
+ {
+ udp_tunnel_del(proto,
+ fib_index, &src_addr, &dst_addr, src_port, dst_port,
+ UDP_ENCAP_FIXUP_NONE);
+ }
+
+
+ done:
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2 (VL_API_HICN_API_UDP_TUNNEL_ADD_DEL_REPLY, (
+ {
+ rmp->uei = clib_host_to_net_u32(uei);
+ }));
+ /* *INDENT-ON* */
+}
/************************************************************************************/
@@ -955,7 +692,7 @@ hicn_api_plugin_hookup (vlib_main_t * vm)
*/
vnet_api_error_t
hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
- vl_api_hicn_api_face_ip_params_get_reply_t
+ vl_api_hicn_api_face_params_get_reply_t
* reply)
{
int rv = HICN_ERROR_NONE;
@@ -967,15 +704,13 @@ hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
}
hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
- if (face != NULL && face->shared.face_type == hicn_face_ip_type)
+ if (face != NULL)
{
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY,
- &reply->local_addr);
- ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY,
- &reply->remote_addr);
- reply->swif = clib_host_to_net_u32 (face->shared.sw_if);
- reply->flags = clib_host_to_net_u32 (face->shared.flags);
+ ip_address_encode (&face->nat_addr, IP46_TYPE_ANY,
+ &reply->nat_addr);
+
+ reply->swif = clib_host_to_net_u32 (face->sw_if);
+ reply->flags = clib_host_to_net_u32 (face->flags);
reply->faceid = clib_host_to_net_u32 (faceid);
}
else
diff --git a/hicn-plugin/src/hicn_api.h b/hicn-plugin/src/hicn_api.h
index 79b561be4..ec10a6bbd 100644
--- a/hicn-plugin/src/hicn_api.h
+++ b/hicn-plugin/src/hicn_api.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:
@@ -16,7 +16,13 @@
#ifndef __HICN_API_H__
#define __HICN_API_H__
+/**
+ * @file
+ */
+
+
#define HICN_STRATEGY_NULL ~0
+#define HICN_FIB_TABLE 10
/* define message structures */
#define vl_typedefs
diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c
index 08a579914..e4704e8ea 100644
--- a/hicn-plugin/src/hicn_api_test.c
+++ b/hicn-plugin/src/hicn_api_test.c
@@ -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:
@@ -222,11 +222,7 @@ hicn_test_main_t hicn_test_main;
#define foreach_standard_reply_retval_handler \
_(hicn_api_node_params_set_reply) \
-_(hicn_api_face_ip_del_reply) \
-_(hicn_api_face_del_reply) \
-_(hicn_api_route_nhops_add_reply) \
-_(hicn_api_route_del_reply) \
-_(hicn_api_route_nhop_del_reply)
+_(hicn_api_enable_disable_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -253,26 +249,16 @@ foreach_standard_reply_retval_handler;
_(HICN_API_NODE_PARAMS_SET_REPLY, hicn_api_node_params_set_reply) \
_(HICN_API_NODE_PARAMS_GET_REPLY, hicn_api_node_params_get_reply) \
_(HICN_API_NODE_STATS_GET_REPLY, hicn_api_node_stats_get_reply) \
-_(HICN_API_FACE_IP_DEL_REPLY, hicn_api_face_ip_del_reply) \
-_(HICN_API_FACE_IP_ADD_REPLY, hicn_api_face_ip_add_reply) \
-_(HICN_API_FACE_ADD_REPLY, hicn_api_face_add_reply) \
-_(HICN_API_FACE_DEL_REPLY, hicn_api_face_del_reply) \
_(HICN_API_FACE_GET_REPLY, hicn_api_face_get_reply) \
_(HICN_API_FACES_DETAILS, hicn_api_faces_details) \
_(HICN_API_FACE_STATS_DETAILS, hicn_api_face_stats_details) \
-_(HICN_API_ROUTE_NHOPS_ADD_REPLY, hicn_api_route_nhops_add_reply) \
-_(HICN_API_FACE_IP_PARAMS_GET_REPLY, hicn_api_face_ip_params_get_reply) \
+_(HICN_API_FACE_PARAMS_GET_REPLY, hicn_api_face_params_get_reply) \
_(HICN_API_ROUTE_GET_REPLY, hicn_api_route_get_reply) \
_(HICN_API_ROUTES_DETAILS, hicn_api_routes_details) \
-_(HICN_API_ROUTE_DEL_REPLY, hicn_api_route_del_reply) \
-_(HICN_API_ROUTE_NHOP_DEL_REPLY, hicn_api_route_nhop_del_reply) \
_(HICN_API_STRATEGIES_GET_REPLY, hicn_api_strategies_get_reply) \
_(HICN_API_STRATEGY_GET_REPLY, hicn_api_strategy_get_reply) \
-_(HICN_API_REGISTER_PROD_APP_REPLY, hicn_api_register_prod_app_reply) \
-_(HICN_API_FACE_PROD_DEL_REPLY, hicn_api_face_prod_del_reply) \
-_(HICN_API_REGISTER_CONS_APP_REPLY, hicn_api_register_cons_app_reply) \
-_(HICN_API_FACE_CONS_DEL_REPLY, hicn_api_face_cons_del_reply)
-
+_(HICN_API_ENABLE_DISABLE_REPLY, hicn_api_enable_disable_reply) \
+_(HICN_API_UDP_TUNNEL_ADD_DEL_REPLY, hicn_api_udp_tunnel_add_del_reply)
static int
api_hicn_api_node_params_set (vat_main_t * vam)
@@ -309,7 +295,7 @@ api_hicn_api_node_params_set (vat_main_t * vam)
/* Construct the API message */
M (HICN_API_NODE_PARAMS_SET, mp);
- mp->enable_disable = enable_disable;
+ mp->enable_disable = clib_host_to_net_u32(enable_disable);
mp->pit_max_size = clib_host_to_net_i32 (pit_size);
mp->cs_max_size = clib_host_to_net_i32 (cs_size);
mp->pit_max_lifetime_sec = pit_max_lifetime_sec;
@@ -451,263 +437,10 @@ static void
}
static int
-api_hicn_api_face_ip_add (vat_main_t * vam)
+api_hicn_api_face_params_get (vat_main_t * vam)
{
unformat_input_t *input = vam->input;
- ip46_address_t local_addr = { 0 };
- ip46_address_t remote_addr = { 0 };
- int ret = HICN_ERROR_NONE;
- int sw_if = 0;
- vl_api_hicn_api_face_add_t *mp;
-
- /* Parse args required to build the message */
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (input, "local %U", unformat_ip46_address, &local_addr,
- IP46_TYPE_ANY));
- else
- if (unformat
- (input, "remote %U", unformat_ip46_address, &remote_addr,
- IP46_TYPE_ANY));
- else if (unformat (input, "intfc %d", &sw_if));
- else
- {
- break;
- }
- }
-
- /* Check for presence of both addresses */
- if (ip46_address_is_zero (&remote_addr))
- {
- clib_warning ("Incomplete IP face. Please specify remote address");
- return (1);
- }
- /* Construct the API message */
- M (HICN_API_FACE_ADD, mp);
- mp->type = clib_host_to_net_u32 (IP_FACE);
- ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.ip.local_addr);
- ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.ip.remote_addr);
- mp->face.ip.swif = clib_host_to_net_u32 (sw_if);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static void
- vl_api_hicn_api_face_ip_add_reply_t_handler
- (vl_api_hicn_api_face_ip_add_reply_t * rmp)
-{
- vat_main_t *vam = hicn_test_main.vat_main;
- i32 retval = ntohl (rmp->retval);
-
- if (vam->async_mode)
- {
- vam->async_errors += (retval < 0);
- return;
- }
- vam->retval = retval;
- vam->result_ready = 1;
-
- if (vam->retval < 0)
- {
- //vpp_api_test infra will also print out string form of error
- fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
- return;
- }
- fformat (vam->ofp, "New Face ID: %d\n", ntohl (rmp->faceid));
-}
-
-static int
-api_hicn_api_face_udp_add (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- ip46_address_t local_addr = ip46_address_initializer;
- ip46_address_t remote_addr = ip46_address_initializer;
- u32 sport = 0;
- u32 dport = 0;
- int ret = HICN_ERROR_NONE;
- int sw_if = ~0;
- vl_api_hicn_api_face_add_t *mp;
-
- /* Parse args required to build the message */
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (input, "local %U port %u", unformat_ip46_address, &local_addr,
- IP46_TYPE_ANY, &sport));
- else
- if (unformat
- (input, "remote %U port %u", unformat_ip46_address, &remote_addr,
- IP46_TYPE_ANY, &dport));
- else if (unformat (input, "intfc %d", &sw_if));
- else
- {
- break;
- }
- }
-
- /* Check for presence of both addresses */
- if (ip46_address_is_zero (&remote_addr)
- || ip46_address_is_zero (&local_addr) || sport == 0 || dport == 0)
- {
- clib_warning
- ("Incomplete UDP face. Please specify local and remote address and port");
- return (1);
- }
- /* Construct the API message */
- M (HICN_API_FACE_ADD, mp);
- mp->type = clib_host_to_net_u32 (UDP_FACE);
- ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.udp.local_addr);
- ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.udp.remote_addr);
- mp->face.udp.lport = clib_host_to_net_u16 (sport);
- mp->face.udp.rport = clib_host_to_net_u16 (dport);
- mp->face.udp.swif = clib_host_to_net_u32 (sw_if);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_face_add (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- int ret = HICN_ERROR_NONE;
- u32 type = ~0;
-
- /* Parse args required to build the message */
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "type %d", &type));
- else
- {
- break;
- }
- }
-
- vam->input = input;
-
- if (type == IP_FACE)
- ret = api_hicn_api_face_ip_add (vam);
- else if (type == UDP_FACE)
- ret = api_hicn_api_face_udp_add (vam);
-
- return ret;
-}
-
-static void
- vl_api_hicn_api_face_add_reply_t_handler
- (vl_api_hicn_api_face_add_reply_t * rmp)
-{
- vat_main_t *vam = hicn_test_main.vat_main;
- i32 retval = ntohl (rmp->retval);
-
- if (vam->async_mode)
- {
- vam->async_errors += (retval < 0);
- return;
- }
- vam->retval = retval;
- vam->result_ready = 1;
-
- if (vam->retval < 0)
- {
- //vpp_api_test infra will also print out string form of error
- fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
- return;
- }
- fformat (vam->ofp, "New Face ID: %d\n", ntohl (rmp->faceid));
-}
-
-static int
-api_hicn_api_face_ip_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_face_ip_del_t *mp;
- u32 faceid = 0, ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- //Check for presence of face ID
- if (faceid == ~0)
- {
- clib_warning ("Please specify face ID");
- return 1;
- }
- //Construct the API message
- M (HICN_API_FACE_IP_DEL, mp);
- mp->faceid = clib_host_to_net_u32 (faceid);
-
- //send it...
- S (mp);
-
- //Wait for a reply...
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_face_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_face_del_t *mp;
- u32 faceid = 0, ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- //Check for presence of face ID
- if (faceid == ~0)
- {
- clib_warning ("Please specify face ID");
- return 1;
- }
- //Construct the API message
- M (HICN_API_FACE_DEL, mp);
- mp->faceid = clib_host_to_net_u32 (faceid);
-
- //send it...
- S (mp);
-
- //Wait for a reply...
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_face_ip_params_get (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_face_ip_params_get_t *mp;
+ vl_api_hicn_api_face_params_get_t *mp;
u32 faceid = HICN_FACE_NULL, ret;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -728,7 +461,7 @@ api_hicn_api_face_ip_params_get (vat_main_t * vam)
return 1;
}
//Construct the API message
- M (HICN_API_FACE_IP_PARAMS_GET, mp);
+ M (HICN_API_FACE_PARAMS_GET, mp);
mp->faceid = clib_host_to_net_u32 (faceid);
//send it...
@@ -741,14 +474,13 @@ api_hicn_api_face_ip_params_get (vat_main_t * vam)
}
static void
- vl_api_hicn_api_face_ip_params_get_reply_t_handler
- (vl_api_hicn_api_face_ip_params_get_reply_t * rmp)
+ vl_api_hicn_api_face_params_get_reply_t_handler
+ (vl_api_hicn_api_face_params_get_reply_t * rmp)
{
vat_main_t *vam = hicn_test_main.vat_main;
i32 retval = ntohl (rmp->retval);
u8 *sbuf = 0;
- ip46_address_t remote_addr;
- ip46_address_t local_addr;
+ ip46_address_t nat_addr;
if (vam->async_mode)
{
@@ -765,12 +497,10 @@ static void
return;
}
vec_reset_length (sbuf);
- ip_address_decode (&rmp->local_addr, &local_addr);
- ip_address_decode (&rmp->remote_addr, &remote_addr);
+ ip_address_decode (&rmp->nat_addr, &nat_addr);
sbuf =
- format (0, "local_addr %U remote_addr %U", format_ip46_address,
- &local_addr, 0 /*IP46_ANY_TYPE */ , format_ip46_address,
- &remote_addr, 0 /*IP46_ANY_TYPE */ );
+ format (0, "nat_addr %U", format_ip46_address,
+ &nat_addr, 0 /*IP46_ANY_TYPE */);
fformat (vam->ofp, "%s swif %d flags %d\n",
sbuf,
@@ -779,48 +509,23 @@ static void
}
static void
-format_ip_face (vl_api_hicn_face_ip_t * rmp)
+format_face (vl_api_hicn_face_t * rmp)
{
vat_main_t *vam = hicn_test_main.vat_main;
u8 *sbuf = 0;
- ip46_address_t remote_addr;
+ ip46_address_t nat_addr;
ip46_address_t local_addr;
vec_reset_length (sbuf);
- ip_address_decode (&rmp->local_addr, &local_addr);
- ip_address_decode (&rmp->remote_addr, &remote_addr);
- sbuf =
- format (0, "local_addr %U remote_addr %U", format_ip46_address,
- &local_addr, 0 /*IP46_ANY_TYPE */ , format_ip46_address,
- &remote_addr, 0 /*IP46_ANY_TYPE */ );
-
- fformat (vam->ofp, "%s swif %d flags %d name %s\n",
- sbuf,
- clib_net_to_host_u32 (rmp->swif),
- clib_net_to_host_i32 (rmp->flags), rmp->if_name);
-}
-
-static void
-format_udp_face (vl_api_hicn_face_udp_t * rmp)
-{
- vat_main_t *vam = hicn_test_main.vat_main;
- u8 *sbuf = 0;
- ip46_address_t remote_addr;
- ip46_address_t local_addr;
+ ip_address_decode (&rmp->nat_addr, &nat_addr);
- vec_reset_length (sbuf);
- ip_address_decode (&rmp->local_addr, &local_addr);
- ip_address_decode (&rmp->remote_addr, &remote_addr);
- u16 lport = clib_net_to_host_u16 (rmp->lport);
- u16 rport = clib_net_to_host_u16 (rmp->rport);;
sbuf =
- format (0, "local_addr %U port %u remote_addr %U port %u",
- format_ip46_address, &local_addr, 0 /*IP46_ANY_TYPE */ , lport,
- format_ip46_address, &remote_addr, 0 /*IP46_ANY_TYPE */ , rport);
+ format (0, "nat_addr %U", format_ip46_address,
+ &local_addr, 0 /*IP46_ANY_TYPE */);
fformat (vam->ofp, "%s swif %d flags %d name %s\n",
sbuf,
- clib_net_to_host_u16 (rmp->swif),
+ clib_net_to_host_u32 (rmp->swif),
clib_net_to_host_i32 (rmp->flags), rmp->if_name);
}
@@ -841,6 +546,9 @@ api_hicn_api_faces_dump (vat_main_t * vam)
M (HICN_API_FACES_DUMP, mp);
S (mp);
+ if (!hm->ping_id)
+ hm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
+
/* Use a control ping for synchronization */
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
mp_ping->_vl_msg_id = htons (hm->ping_id);
@@ -859,14 +567,7 @@ static void
vl_api_hicn_api_faces_details_t_handler
(vl_api_hicn_api_faces_details_t * mp)
{
- if (mp->type == IP_FACE)
- {
- format_ip_face (&(mp->face.ip));
- }
- else
- {
- format_udp_face (&(mp->face.udp));
- }
+ format_face (&(mp->face));
}
static int
@@ -929,15 +630,7 @@ static void
fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
return;
}
-
- if (rmp->type == IP_FACE)
- {
- format_ip_face (&(rmp->face.ip));
- }
- else
- {
- format_udp_face (&(rmp->face.udp));
- }
+ format_face (&(rmp->face));
}
@@ -959,6 +652,9 @@ api_hicn_api_face_stats_dump (vat_main_t * vam)
M (HICN_API_FACE_STATS_DUMP, mp);
S (mp);
+ if (!hm->ping_id)
+ hm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
+
/* Use a control ping for synchronization */
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
mp_ping->_vl_msg_id = htons (hm->ping_id);
@@ -1061,6 +757,9 @@ api_hicn_api_routes_dump (vat_main_t * vam)
M (HICN_API_ROUTES_DUMP, mp);
S (mp);
+ if (!hm->ping_id)
+ hm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
+
/* Use a control ping for synchronization */
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
mp_ping->_vl_msg_id = htons (hm->ping_id);
@@ -1151,152 +850,6 @@ static void
}
static int
-api_hicn_api_route_nhops_add (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_route_nhops_add_t *mp;
-
- fib_prefix_t prefix;
- u32 faceid = 0;
- int ret;
-
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "add prefix %U/%d", unformat_ip46_address,
- &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
- {;
- }
- else if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- /* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
- || (prefix.fp_len == 0) || (faceid == 0))
- {
- clib_warning ("Please specify prefix and faceid...");
- return 1;
- }
- /* Construct the API message */
- M (HICN_API_ROUTE_NHOPS_ADD, mp);
- ip_prefix_encode (&prefix, &mp->prefix);
-
- if (!ip46_address_is_ip4 (&(prefix.fp_addr)))
- prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6);
-
- mp->face_ids[0] = clib_host_to_net_u32 (faceid);
- mp->n_faces = 1;
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_route_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_route_del_t *mp;
-
- fib_prefix_t prefix;
- int ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "prefix %U/%d", unformat_ip46_address,
- &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
- {;
- }
- else
- {
- break;
- }
- }
-
- /* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
- || (prefix.fp_len == 0))
- {
- clib_warning ("Please specify prefix...");
- return 1;
- }
- /* Construct the API message */
- M (HICN_API_ROUTE_DEL, mp);
- ip_prefix_encode (&prefix, &mp->prefix);
-
- if (!ip46_address_is_ip4 (&(prefix.fp_addr)))
- prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-
-}
-
-static int
-api_hicn_api_route_nhop_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_route_nhop_del_t *mp;
-
- fib_prefix_t prefix;
- int faceid = 0, ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "del prefix %U/%d", unformat_ip46_address,
- &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
- {;
- }
- else if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- /* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
- || (prefix.fp_len == 0) || (faceid == HICN_FACE_NULL))
- {
- clib_warning ("Please specify prefix and faceid...");
- return 1;
- }
- /* Construct the API message */
- M (HICN_API_ROUTE_NHOP_DEL, mp);
- ip_prefix_encode (&prefix, &mp->prefix);
-
- if (!ip46_address_is_ip4 (&(prefix.fp_addr)))
- prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6);
-
- mp->faceid = clib_host_to_net_u32 (faceid);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static int
api_hicn_api_strategies_get (vat_main_t * vam)
{
vl_api_hicn_api_strategies_get_t *mp;
@@ -1415,6 +968,58 @@ static void
}
static int
+api_hicn_api_enable_disable (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_hicn_api_enable_disable_t *mp;
+ int ret;
+
+ fib_prefix_t prefix;
+ vl_api_hicn_action_type_t en_dis = HICN_ENABLE;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "prefix %U/%d", unformat_ip46_address,
+ &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
+ {;
+ }
+ else if (unformat (input, "disable"))
+ {;
+ en_dis = HICN_DISABLE;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Check parse */
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0))
+ {
+ clib_warning ("Please specify a valid prefix...");
+ return 1;
+ }
+
+ prefix.fp_proto = ip46_address_is_ip4 (&(prefix.fp_addr)) ? FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6;
+
+ //Construct the API message
+ M (HICN_API_ENABLE_DISABLE, mp);
+
+ ip_prefix_encode (&prefix, &mp->prefix);
+ mp->enable_disable = en_dis;
+
+ //send it...
+ S (mp);
+
+ //Wait for a reply...
+ W (ret);
+
+ return ret;
+}
+
+static int
api_hicn_api_register_prod_app (vat_main_t * vam)
{
unformat_input_t *input = vam->input;
@@ -1607,12 +1212,104 @@ static void
fformat (vam->ofp,
"ip4 address %U\n"
- "ip6 address :%U\n"
- "appif id :%d\n",
+ "ip6 address :%U\n",
format_ip46_address, IP46_TYPE_ANY, &src_addr4,
format_ip46_address, IP46_TYPE_ANY, &src_addr6);
}
+static int
+api_hicn_api_udp_tunnel_add_del (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_hicn_api_udp_tunnel_add_del_t *mp;
+
+ ip46_address_t src_ip, dst_ip;
+ u32 src_port, dst_port;
+ fib_protocol_t fproto;
+ u8 is_del;
+ int ret;
+
+ is_del = 0;
+ fproto = FIB_PROTOCOL_MAX;
+
+ /* Get a line of input. */
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "add"))
+ is_del = 0;
+ else if (unformat (input, "del"))
+ is_del = 1;
+ else if (unformat (input, "%U %U",
+ unformat_ip4_address,
+ &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
+ fproto = FIB_PROTOCOL_IP4;
+ else if (unformat (input, "%U %U",
+ unformat_ip6_address,
+ &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
+ fproto = FIB_PROTOCOL_IP6;
+ else if (unformat (input, "%d %d", &src_port, &dst_port))
+ ;
+ else
+ {
+ break;
+ }
+ }
+
+
+ if (fproto == FIB_PROTOCOL_MAX)
+ {
+ clib_warning ("Please specify face ID");
+ return 1;
+ }
+
+ /* Construct the API message */
+ M (HICN_API_UDP_TUNNEL_ADD_DEL, mp);
+ ip_address_encode (&src_ip, fproto == FIB_PROTOCOL_IP4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6 ,&mp->src_addr);
+ ip_address_encode (&dst_ip, fproto == FIB_PROTOCOL_IP4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6 ,&mp->dst_addr);
+ mp->src_port = clib_host_to_net_u16(src_port);
+ mp->dst_port = clib_host_to_net_u16(dst_port);
+ mp->is_add = !is_del;
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+
+ return ret;
+}
+
+static void
+vl_api_hicn_api_udp_tunnel_add_del_reply_t_handler
+(vl_api_hicn_api_udp_tunnel_add_del_reply_t * mp)
+{
+ vat_main_t *vam = hicn_test_main.vat_main;
+ i32 retval = ntohl (mp->retval);
+
+ if (vam->async_mode)
+ {
+ vam->async_errors += (retval < 0);
+ return;
+ }
+ vam->retval = retval;
+ vam->result_ready = 1;
+
+ if (vam->retval < 0)
+ {
+ //vpp_api_test infra will also print out string form of error
+ fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
+ return;
+ }
+
+ index_t uei = clib_net_to_host_u32(mp->uei);
+
+ fformat (vam->ofp,
+ "udp-encap %d\n",
+ uei);
+}
+
+
+
#include <hicn/hicn.api_test.c>
/*
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 b859b8e46..ff76de4e4 100644
--- a/hicn-plugin/src/infra.h
+++ b/hicn-plugin/src/infra.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,12 +18,17 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
+#include <vnet/interface.h>
#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
{
@@ -43,6 +48,8 @@ typedef struct hicn_main_s
*/
u64 pit_lifetime_max_ms;
+ vnet_link_t link;
+
} hicn_main_t;
extern hicn_main_t hicn_main;
@@ -67,7 +74,8 @@ int
hicn_infra_plugin_enable_disable (int enable_disable,
int pit_max_size,
f64 pit_max_lifetime_sec_req,
- int cs_max_size, int cs_reserved_app);
+ int cs_max_size,
+ vnet_link_t link);
/* vlib nodes that compose the hICN forwarder */
@@ -80,6 +88,9 @@ extern vlib_node_registration_t hicn_interest_hitcs_node;
extern vlib_node_registration_t hicn_pg_interest_node;
extern vlib_node_registration_t hicn_pg_data_node;
extern vlib_node_registration_t hicn_pg_server_node;
+extern vlib_node_registration_t hicn_data_input_ip6_node;
+extern vlib_node_registration_t hicn_data_input_ip4_node;
+
#endif /* // __HICN_INFRA_H__ */
diff --git a/hicn-plugin/src/interest_hitcs.h b/hicn-plugin/src/interest_hitcs.h
index c69564452..94fa3e6f5 100644
--- a/hicn-plugin/src/interest_hitcs.h
+++ b/hicn-plugin/src/interest_hitcs.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:
@@ -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
*/
@@ -41,9 +51,9 @@ typedef struct
typedef enum
{
HICN_INTEREST_HITCS_NEXT_STRATEGY,
- HICN_INTEREST_HITCS_NEXT_PUSH,
+ HICN_INTEREST_HITCS_NEXT_IFACE4_OUT,
+ HICN_INTEREST_HITCS_NEXT_IFACE6_OUT,
HICN_INTEREST_HITCS_NEXT_ERROR_DROP,
- HICN_INTEREST_HITCS_NEXT_EMPTY,
HICN_INTEREST_HITCS_N_NEXT,
} hicn_interest_hitcs_next_t;
diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c
index d10f15afa..f569fa897 100644
--- a/hicn-plugin/src/interest_hitcs_node.c
+++ b/hicn-plugin/src/interest_hitcs_node.c
@@ -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:
@@ -184,9 +184,9 @@ hicn_interest_hitcs_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
* Retrieve the incoming iface and forward
* the data through it
*/
- next0 = hicnb0->face_dpo_id.dpoi_next_node;
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
- hicnb0->face_dpo_id.dpoi_index;
+ next0 = isv6 ? HICN_INTEREST_HITCS_NEXT_IFACE6_OUT :
+ HICN_INTEREST_HITCS_NEXT_IFACE4_OUT;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = hicnb0->face_id;
clone_from_cs (vm, &pitp->u.cs.cs_pkt_buf, b0, isv6);
@@ -277,9 +277,9 @@ VLIB_REGISTER_NODE(hicn_interest_hitcs_node) =
.next_nodes =
{
[HICN_INTEREST_HITCS_NEXT_STRATEGY] = "hicn-strategy",
- [HICN_INTEREST_HITCS_NEXT_PUSH] = "hicn-data-push",
- [HICN_INTEREST_HITCS_NEXT_ERROR_DROP] = "error-drop",
- [HICN_INTEREST_HITCS_NEXT_EMPTY] = "ip6-lookup"
+ [HICN_INTEREST_HITCS_NEXT_IFACE4_OUT] = "hicn4-iface-output",
+ [HICN_INTEREST_HITCS_NEXT_IFACE6_OUT] = "hicn6-iface-output",
+ [HICN_INTEREST_HITCS_NEXT_ERROR_DROP] = "error-drop"
},
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/interest_hitpit.h b/hicn-plugin/src/interest_hitpit.h
index fc4cfc3ea..ffdc61c8f 100644
--- a/hicn-plugin/src/interest_hitpit.h
+++ b/hicn-plugin/src/interest_hitpit.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:
@@ -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
*/
@@ -42,6 +53,8 @@ typedef enum
{
HICN_INTEREST_HITPIT_NEXT_INTEREST_HITCS,
HICN_INTEREST_HITPIT_NEXT_STRATEGY,
+ HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT,
+ HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT,
HICN_INTEREST_HITPIT_NEXT_ERROR_DROP,
HICN_INTEREST_HITPIT_N_NEXT,
} hicn_interest_hitpit_next_t;
diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c
index a346dcc7e..9ebf183c5 100644
--- a/hicn-plugin/src/interest_hitpit_node.c
+++ b/hicn-plugin/src/interest_hitpit_node.c
@@ -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:
@@ -88,7 +88,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
u8 dpo_ctx_id0;
u8 found = 0;
int nh_idx;
- dpo_id_t *outface;
+ hicn_face_id_t outface;
hicn_hash_entry_t *hash_entry0;
hicn_buffer_t *hicnb0;
int ret;
@@ -166,7 +166,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
*/
found =
- hicn_face_search (&(hicnb0->face_dpo_id),
+ hicn_face_search (hicnb0->face_id,
&(pitp->u.pit.faces));
if (found)
@@ -178,9 +178,10 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
* Prepare the packet for the
* forwarding
*/
- next0 = outface->dpoi_next_node;
+ next0 = isv6 ? HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT :
+ HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT;
vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
- outface->dpoi_index;
+ outface;
/*
* Update the egress face in
@@ -191,8 +192,8 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
- hicn_face_db_add_face_dpo (&hicnb0->face_dpo_id,
- &pitp->u.pit.faces);
+ hicn_face_db_add_face (hicnb0->face_id,
+ &pitp->u.pit.faces);
/* Aggregation */
drop_packet (&next0);
@@ -293,6 +294,8 @@ VLIB_REGISTER_NODE(hicn_interest_hitpit_node) =
{
[HICN_INTEREST_HITPIT_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs",
[HICN_INTEREST_HITPIT_NEXT_STRATEGY] = "hicn-strategy",
+ [HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT] = "hicn4-face-output",
+ [HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT] = "hicn6-face-output",
[HICN_INTEREST_HITPIT_NEXT_ERROR_DROP] = "error-drop",
},
};
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.h b/hicn-plugin/src/mapme.h
index 071590ede..17bd9a766 100644
--- a/hicn-plugin/src/mapme.h
+++ b/hicn-plugin/src/mapme.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,13 +18,34 @@
#include <vnet/dpo/load_balance.h>
#include <vnet/buffer.h>
-//#include <hicn/hicn.h>
#include <hicn/mapme.h>
#include "hicn.h"
+#include "route.h"
#include "strategy_dpo_ctx.h"
#include "strategy_dpo_manager.h" // dpo_is_hicn
+/**
+ * @file
+ *
+ * @brief Mapme
+ *
+ * Mapme implementation follows the "Anchorless mobility through hICN" document
+ * specification. In particular, the implementation is made of:
+ * - two internal nodes: hicn-mapme-ctrl and hicn-mapme-ack. The former processes
+ * IU and the latter IU acknowledgment.
+ * - a process node, mapme-eventmgr-process, that is signaled every time a face is
+ * added or deleted, as well as when a new next hop is added to a fib entry as a
+ * result of a mobility event.
+ *
+ * TFIB implementation is done as an extension of an hICN fib entry. In particular,
+ * the list of next hops hold the list of next hops in the tfib as well (stored at the
+ * end of the list of regualt next hops). Mapme implementation follows the hICN vrf
+ * implementation and consider the vrf 0 (default fib) as the control-plane fib to
+ * update every time a new next hop must be added or removed.
+ */
+
+
#define HICN_MAPME_ALLOW_LOCATORS 1
//#define HICN_MAPME_NOTIFICATIONS 1
@@ -34,6 +55,9 @@
#define INVALID_SEQ 0
+STATIC_ASSERT (sizeof(u32) == sizeof(seq_t),
+ "seq_t is not 4 bytes");
+
typedef struct hicn_mapme_conf_s
{
hicn_mapme_conf_t conf;
@@ -43,6 +67,9 @@ typedef struct hicn_mapme_conf_s
vlib_log_class_t log_class;
} hicn_mapme_main_t;
+/**
+ * @brief List of event to signat to the procesing node (eventmgr)
+ */
#define foreach_hicn_mapme_event \
_(FACE_ADD) \
_(FACE_DEL) \
@@ -72,13 +99,24 @@ typedef hicn_dpo_ctx_t hicn_mapme_tfib_t;
STATIC_ASSERT (sizeof (hicn_mapme_tfib_t) <= sizeof (hicn_dpo_ctx_t),
"hicn_mapme_tfib_t is greater than hicn_dpo_ctx_t");
-#define TFIB(dpo) ((hicn_mapme_tfib_t*)(dpo))
+#define TFIB(dpo_ctx) ((hicn_mapme_tfib_t*)(dpo_ctx))
static_always_inline int
-hicn_mapme_nh_set (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_nh_set (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
- tfib->next_hops[0] = *face_id;
- tfib->entry_count = 1;
+ hicn_dpo_ctx_t * strategy_ctx = (hicn_dpo_ctx_t *)tfib;
+ const fib_prefix_t * prefix = fib_entry_get_prefix(strategy_ctx->fib_entry_index);
+
+ u32 n_entries = tfib->entry_count;
+ /* Remove all the existing next hops and set the new one */
+ for (int i = 0; i < n_entries; i++)
+ {
+ hicn_face_t * face = hicn_dpoi_get_from_idx(strategy_ctx->next_hops[0]);
+ ip_adjacency_t * adj = adj_get (face->dpo.dpoi_index);
+ ip_nh_del_helper(face->dpo.dpoi_proto, prefix, &adj->sub_type.nbr.next_hop, face->sw_if);
+ }
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+ ip_nh_add_helper(face->dpo.dpoi_proto, prefix, &face->nat_addr, face->sw_if);
return 0;
}
@@ -86,12 +124,18 @@ hicn_mapme_nh_set (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
* @brief Add a next hop iif it is not already a next hops
*/
static_always_inline int
-hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
for (u8 pos = 0; pos < tfib->entry_count; pos++)
- if (dpo_cmp (&tfib->next_hops[pos], face_id) == 0)
+ if (tfib->next_hops[pos] == face_id)
return 0;
- tfib->next_hops[tfib->entry_count++] = *face_id;
+
+ /* Add the next hop in the vrf 0 which will add it to the entry in the hICN vrf */
+ hicn_dpo_ctx_t * strategy_ctx = (hicn_dpo_ctx_t *)tfib;
+ const fib_prefix_t * prefix = fib_entry_get_prefix(strategy_ctx->fib_entry_index);
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+ ip_nh_add_helper(face->dpo.dpoi_proto, prefix, &face->nat_addr, face->sw_if);
+
return 0;
}
@@ -101,30 +145,36 @@ hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
* XXX we should have the for look in the reverse order for simpler code.
*/
static_always_inline int
-hicn_mapme_tfib_add (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_tfib_add (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
//XXX don 't add if it already exist
// eg.an old IU received on a face on which we are retransmitting
for (u8 pos2 = pos; pos2 < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos2++)
- if (dpo_cmp (&tfib->next_hops[pos2], face_id) == 0)
+ if (tfib->next_hops[pos2] == face_id)
return 0;
//Make sure we have enough room
if (pos <= tfib->entry_count)
return -1;
- tfib->next_hops[pos - 1] = *face_id;
+ tfib->next_hops[pos - 1] = face_id;
tfib->tfib_entry_count++;
+ /*
+ * Take a lock on the face as if it will be removed from the next_hops a
+ * lock will be removed.
+ */
+ hicn_face_lock_with_id(face_id);
+
return 0;
}
static_always_inline int
hicn_mapme_tfib_clear (hicn_mapme_tfib_t * tfib)
{
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
/*
* We need to do a linear scan of TFIB entries to find the one to
* remove
@@ -133,7 +183,7 @@ hicn_mapme_tfib_clear (hicn_mapme_tfib_t * tfib)
u8 pos = ~0;
for (pos = start_pos; pos < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos++)
{
- hicn_face_unlock (&tfib->next_hops[pos]);
+ hicn_face_unlock_with_id (tfib->next_hops[pos]);
tfib->next_hops[pos] = invalid;
break;
}
@@ -144,9 +194,9 @@ hicn_mapme_tfib_clear (hicn_mapme_tfib_t * tfib)
}
static_always_inline int
-hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
/*
* We need to do a linear scan of TFIB entries to find the one to
* remove
@@ -154,9 +204,9 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
u8 start_pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
u8 pos = ~0;
for (pos = start_pos; pos < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos++)
- if (dpo_cmp (&tfib->next_hops[pos], face_id) == 0)
+ if (tfib->next_hops[pos] == face_id)
{
- hicn_face_unlock (&tfib->next_hops[pos]);
+ hicn_face_unlock_with_id (tfib->next_hops[pos]);
tfib->next_hops[pos] = invalid;
break;
}
@@ -168,8 +218,8 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
/* Likely we won't receive a new IU twice from the same face */
if (PREDICT_TRUE (pos > start_pos))
- memmove (tfib->next_hops + start_pos, tfib->next_hops + start_pos + 1,
- (pos - start_pos) * sizeof (dpo_id_t));
+ memmove (tfib->next_hops + start_pos +1 , tfib->next_hops + start_pos,
+ (pos - start_pos) * sizeof (hicn_face_id_t));
return 0;
}
@@ -287,34 +337,17 @@ hicn_mapme_get_dpo_vlib_edge (dpo_id_t * dpo)
* @brief Returns the next hop node on which we can send an Update packet
*/
always_inline char *
-hicn_mapme_get_dpo_face_node (dpo_id_t * dpo)
+hicn_mapme_get_dpo_face_node (hicn_face_id_t face_id)
{
- if (dpo->dpoi_type == hicn_face_ip_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return "hicn-face-ip4-output";
- case DPO_PROTO_IP6:
- return "hicn-face-ip6-output";
- default:
- return NULL;
- }
- }
- else if (dpo->dpoi_type == hicn_face_udp_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return "hicn-face-udp4-output";
- case DPO_PROTO_IP6:
- return "hicn-face-udp6-output";
- default:
- return NULL;
- }
- }
- else
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+
+ switch (face->dpo.dpoi_proto)
{
+ case DPO_PROTO_IP4:
+ return "hicn4-face-output";
+ case DPO_PROTO_IP6:
+ return "hicn6-face-output";
+ default:
return NULL;
}
}
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_ack_node.c b/hicn-plugin/src/mapme_ack_node.c
index 557fb0ad7..f26895d20 100644
--- a/hicn-plugin/src/mapme_ack_node.c
+++ b/hicn-plugin/src/mapme_ack_node.c
@@ -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:
@@ -48,7 +48,7 @@ static char *hicn_mapme_ack_error_strings[] = {
*/
bool
hicn_mapme_process_ack (vlib_main_t * vm, vlib_buffer_t * b,
- dpo_id_t * in_face)
+ hicn_face_id_t in_face)
{
seq_t fib_seq;
const dpo_id_t *dpo;
@@ -113,8 +113,11 @@ hicn_mapme_process_ack (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
+
return true;
ERR_PARSE:
@@ -159,7 +162,7 @@ hicn_mapme_ack_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_cli_output (vm, "Received IUAck");
hb = hicn_get_buffer (b0);
- hicn_mapme_process_ack (vm, b0, &hb->face_dpo_id);
+ hicn_mapme_process_ack (vm, b0, hb->face_id);
/* Single loop: process 1 packet here */
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
diff --git a/hicn-plugin/src/mapme_ctrl.h b/hicn-plugin/src/mapme_ctrl.h
index e7c1cdf64..9af4beccc 100644
--- a/hicn-plugin/src/mapme_ctrl.h
+++ b/hicn-plugin/src/mapme_ctrl.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:
@@ -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
{
@@ -42,8 +47,6 @@ typedef enum
{
HICN_MAPME_CTRL_NEXT_IP4_OUTPUT,
HICN_MAPME_CTRL_NEXT_IP6_OUTPUT,
- HICN_MAPME_CTRL_NEXT_UDP46_OUTPUT,
- HICN_MAPME_CTRL_NEXT_UDP66_OUTPUT,
HICN_MAPME_CTRL_NEXT_ERROR_DROP,
HICN_MAPME_CTRL_N_NEXT,
} hicn_mapme_ctrl_next_t;
@@ -51,34 +54,17 @@ typedef enum
* @brief Returns the next hop node on which we can send an ACK packet
*/
always_inline hicn_mapme_ctrl_next_t
-hicn_mapme_get_dpo_iface_node (dpo_id_t * dpo)
+hicn_mapme_ctrl_get_iface_node (hicn_face_id_t face_id)
{
- if (dpo->dpoi_type == hicn_face_ip_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return HICN_MAPME_CTRL_NEXT_IP4_OUTPUT;
- case DPO_PROTO_IP6:
- return HICN_MAPME_CTRL_NEXT_IP6_OUTPUT;
- default:
- return HICN_MAPME_CTRL_NEXT_ERROR_DROP;
- }
- }
- else if (dpo->dpoi_type == hicn_face_udp_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return HICN_MAPME_CTRL_NEXT_UDP46_OUTPUT;
- case DPO_PROTO_IP6:
- return HICN_MAPME_CTRL_NEXT_UDP66_OUTPUT;
- default:
- return HICN_MAPME_CTRL_NEXT_ERROR_DROP;
- }
- }
- else
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+
+ switch (face->dpo.dpoi_proto)
{
+ case DPO_PROTO_IP4:
+ return HICN_MAPME_CTRL_NEXT_IP4_OUTPUT;
+ case DPO_PROTO_IP6:
+ return HICN_MAPME_CTRL_NEXT_IP6_OUTPUT;
+ default:
return HICN_MAPME_CTRL_NEXT_ERROR_DROP;
}
}
diff --git a/hicn-plugin/src/mapme_ctrl_node.c b/hicn-plugin/src/mapme_ctrl_node.c
index ed25a31b0..a0be2be1d 100644
--- a/hicn-plugin/src/mapme_ctrl_node.c
+++ b/hicn-plugin/src/mapme_ctrl_node.c
@@ -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:
@@ -48,18 +48,6 @@ static char *hicn_mapme_ctrl_error_strings[] = {
#undef _
};
-/**
- * Preprocess the ingress face so as to make it a candidate next hop, which is
- * what MAP-Me will handle
- */
-static_always_inline void
-preprocess_in_face (hicn_type_t type, dpo_id_t * in, dpo_id_t * out)
-{
- u32 vlib_edge = hicn_mapme_get_dpo_vlib_edge (in);
- *out = *in;
- out->dpoi_next_node = vlib_edge;
-}
-
/*
* @brief Process incoming control messages (Interest Update)
* @param vm vlib main data structure
@@ -74,7 +62,7 @@ preprocess_in_face (hicn_type_t type, dpo_id_t * in, dpo_id_t * out)
*/
static_always_inline bool
hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
- dpo_id_t * in_face)
+ hicn_face_id_t in_face_id)
{
seq_t fib_seq;
const dpo_id_t *dpo;
@@ -153,25 +141,26 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
// in_face and next_hops are face_id_t
/* Remove ingress face from TFIB in case it was present */
- hicn_mapme_tfib_del (tfib, in_face);
+ hicn_mapme_tfib_del (tfib, in_face_id);
/* Move next hops to TFIB... but in_face... */
for (u8 pos = 0; pos < tfib->entry_count; pos++)
{
- if (dpo_cmp (&tfib->next_hops[pos], in_face) == 0)
- {
- tfib->entry_count = 0;
- break;
- }
+ hicn_face_t * face = hicn_dpoi_get_from_idx(tfib->next_hops[pos]);
+ hicn_face_t * in_face = hicn_dpoi_get_from_idx(in_face_id);
+ if (dpo_is_adj(&face->dpo))
+ {
+ ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
+ if (ip46_address_cmp(&(adj->sub_type.nbr.next_hop), &(in_face->nat_addr))== 0)
+ break;
+ }
DEBUG
("Adding nexthop to the tfib, dpo index in_face %d, dpo index tfib %d",
- in_face->dpoi_index, tfib->next_hops[pos].dpoi_index);
- hicn_mapme_tfib_add (tfib, &tfib->next_hops[pos]);
+ in_face_id, tfib->next_hops[pos]);
+ hicn_mapme_tfib_add (tfib, tfib->next_hops[pos]);
}
- /* ... and set ingress face as next_hop */
- in_face->dpoi_next_node = hicn_mapme_get_dpo_vlib_edge (in_face);
- hicn_mapme_nh_set (tfib, in_face);
+ hicn_mapme_nh_set (tfib, in_face_id);
/* We transmit both the prefix and the full dpo (type will be needed to pick the right transmit node */
retx_t *retx = vlib_process_signal_event_data (vm,
@@ -181,8 +170,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
}
else if (params.seq == fib_seq)
@@ -191,10 +182,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
params.seq, fib_seq);
/* Remove ingress face from TFIB in case it was present */
- hicn_mapme_tfib_del (tfib, in_face);
+ hicn_mapme_tfib_del (tfib, in_face_id);
/* Add ingress face to next hops */
- hicn_mapme_nh_add (tfib, in_face);
+ hicn_mapme_nh_add (tfib, in_face_id);
/* Multipath, multihoming, multiple producers or duplicate interest */
retx_t *retx = vlib_process_signal_event_data (vm,
@@ -204,8 +195,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
}
else // params.seq < fib_seq
{
@@ -213,7 +206,7 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
* face is propagating outdated information, we can just consider it as a
* prevHops
*/
- hicn_mapme_tfib_add (tfib, in_face);
+ hicn_mapme_tfib_add (tfib, in_face_id);
retx_t *retx = vlib_process_signal_event_data (vm,
hicn_mapme_eventmgr_process_node.
@@ -222,8 +215,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
}
/* We just raise events, the event_mgr is in charge of forging packet. */
@@ -245,7 +240,7 @@ hicn_mapme_ctrl_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hicn_mapme_ctrl_next_t next_index;
u32 n_left_from, *from, *to_next;
n_left_from = frame->n_vectors;
- dpo_id_t in_face;
+ //hicn_face_id_t in_face;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -273,16 +268,11 @@ hicn_mapme_ctrl_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hb = hicn_get_buffer (b0);
/* This determines the next node on which the ack will be sent back */
- u32 next0 = hicn_mapme_get_dpo_iface_node (&hb->face_dpo_id);
+ u32 next0 = hicn_mapme_ctrl_get_iface_node (hb->face_id);
- /* Preprocessing is needed to precompute in the dpo the next node
- * that will have to be followed by regular interests when being
- * forwarder on a given next hop
- */
- preprocess_in_face (hb->type, &hb->face_dpo_id, &in_face);
- hicn_mapme_process_ctrl (vm, b0, &in_face);
+ hicn_mapme_process_ctrl (vm, b0, hb->face_id);
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = in_face.dpoi_index;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = hb->face_id;
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
n_left_to_next, bi0, next0);
@@ -331,10 +321,8 @@ VLIB_REGISTER_NODE (hicn_mapme_ctrl_node) =
* Manager. This node is only responsible for sending ACK back,
* Acks are like data packets are output on iface's
*/
- [HICN_MAPME_CTRL_NEXT_IP4_OUTPUT] = "hicn-iface-ip4-output",
- [HICN_MAPME_CTRL_NEXT_IP6_OUTPUT] = "hicn-iface-ip6-output",
- [HICN_MAPME_CTRL_NEXT_UDP46_OUTPUT] = "hicn-iface-udp4-output",
- [HICN_MAPME_CTRL_NEXT_UDP66_OUTPUT] = "hicn-iface-udp6-output",
+ [HICN_MAPME_CTRL_NEXT_IP4_OUTPUT] = "hicn4-iface-output",
+ [HICN_MAPME_CTRL_NEXT_IP6_OUTPUT] = "hicn6-iface-output",
[HICN_MAPME_CTRL_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/mapme_eventmgr.c b/hicn-plugin/src/mapme_eventmgr.c
index 5a9e7967e..d8b7562f8 100644
--- a/hicn-plugin/src/mapme_eventmgr.c
+++ b/hicn-plugin/src/mapme_eventmgr.c
@@ -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:
@@ -71,7 +71,7 @@ ip6_fib_table_show_walk (fib_node_index_t fib_entry_index, void *arg)
}
void
-hicn_mapme_process_fib_entry (vlib_main_t * vm, dpo_id_t face,
+hicn_mapme_process_fib_entry (vlib_main_t * vm, hicn_face_id_t face,
const fib_node_index_t * fib_entry_index)
{
const dpo_id_t *load_balance_dpo_id;
@@ -103,7 +103,7 @@ hicn_mapme_process_fib_entry (vlib_main_t * vm, dpo_id_t face,
}
void
-hicn_mapme_process_ip4_fib (vlib_main_t * vm, dpo_id_t face)
+hicn_mapme_process_ip4_fib (vlib_main_t * vm, hicn_face_id_t face)
{
ip4_main_t *im4 = &ip4_main;
fib_table_t *fib_table;
@@ -138,7 +138,7 @@ hicn_mapme_process_ip4_fib (vlib_main_t * vm, dpo_id_t face)
}
void
-hicn_mapme_process_ip6_fib (vlib_main_t * vm, dpo_id_t face)
+hicn_mapme_process_ip6_fib (vlib_main_t * vm, hicn_face_id_t face)
{
/* Walk IPv6 FIB */
ip6_main_t *im6 = &ip6_main;
@@ -182,7 +182,7 @@ hicn_mapme_process_ip6_fib (vlib_main_t * vm, dpo_id_t face)
* Callback called everytime a new face is created (not including app faces)
*/
void
-hicn_mapme_on_face_added (vlib_main_t * vm, dpo_id_t face)
+hicn_mapme_on_face_added (vlib_main_t * vm, hicn_face_id_t face)
{
hicn_mapme_process_ip4_fib (vm, face);
hicn_mapme_process_ip6_fib (vm, face);
@@ -242,7 +242,7 @@ get_packet_buffer (vlib_main_t * vm, u32 node_index, u32 dpoi_index,
static_always_inline bool
hicn_mapme_send_message (vlib_main_t * vm, const hicn_prefix_t * prefix,
- mapme_params_t * params, dpo_id_t * face)
+ mapme_params_t * params, hicn_face_id_t face)
{
size_t n;
@@ -261,7 +261,7 @@ hicn_mapme_send_message (vlib_main_t * vm, const hicn_prefix_t * prefix,
vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) node_name);
u32 node_index = node->index;
- u8 *buffer = get_packet_buffer (vm, node_index, face->dpoi_index,
+ u8 *buffer = get_packet_buffer (vm, node_index, face,
(ip46_address_t *) prefix,
(params->protocol ==
IPPROTO_IPV6) ? HICN_TYPE_IPV6_ICMP :
@@ -302,13 +302,13 @@ hicn_mapme_send_updates (vlib_main_t * vm, hicn_prefix_t * prefix,
pos++)
{
hicn_mapme_send_message (vm, prefix, &params,
- &tfib->next_hops[pos]);
+ tfib->next_hops[pos]);
}
}
else
{
hicn_mapme_send_message (vm, prefix, &params,
- &tfib->next_hops[tfib_last_idx]);
+ tfib->next_hops[tfib_last_idx]);
}
}
@@ -372,7 +372,7 @@ hicn_mapme_eventmgr_process (vlib_main_t * vm,
retx_t *retx_events = event_data;
for (u8 i = 0; i < vec_len (retx_events); i++)
{
- hicn_mapme_on_face_added (vm, retx_events[i].dpo);
+ hicn_mapme_on_face_added (vm, retx_events[i].face_id);
}
idle = 0;
}
diff --git a/hicn-plugin/src/mapme_eventmgr.h b/hicn-plugin/src/mapme_eventmgr.h
index 338915d63..b63d16805 100644
--- a/hicn-plugin/src/mapme_eventmgr.h
+++ b/hicn-plugin/src/mapme_eventmgr.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:
@@ -15,6 +15,13 @@
#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.
@@ -23,6 +30,7 @@ typedef struct
{
hicn_prefix_t prefix;
dpo_id_t dpo;
+ hicn_face_id_t face_id;
u8 rtx_count; // Number of retransmissions since last tfib addition
} retx_t;
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 606d42992..606d50771 100644
--- a/hicn-plugin/src/params.h
+++ b/hicn-plugin/src/params.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,12 @@
#include <math.h>
+/**
+ * @file params.h
+ *
+ */
+
+
/*
* Features
*/
@@ -37,7 +43,7 @@ STATIC_ASSERT ((HICN_PARAM_FACES_MAX & (HICN_PARAM_FACES_MAX - 1)) == 0,
#define HICN_PARAM_HICN_NAME_LEN_MAX 20 //bytes
// Max next - hops supported in a FIB entry
-#define HICN_PARAM_FIB_ENTRY_NHOPS_MAX 5
+#define HICN_PARAM_FIB_ENTRY_NHOPS_MAX 10
// Default and limit on weight, whatever weight means
#define HICN_PARAM_FIB_ENTRY_NHOP_WGHT_DFLT 0x10
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.c b/hicn-plugin/src/pcs.c
index 4355aaeb0..6c44b9d83 100644
--- a/hicn-plugin/src/pcs.c
+++ b/hicn-plugin/src/pcs.c
@@ -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:
@@ -34,7 +34,6 @@ hicn_pit_create (hicn_pit_cs_t * p, u32 num_elems)
(HICN_PARAM_CS_LRU_DEFAULT * HICN_PARAM_CS_RESERVED_APP / 100);
p->policy_state.count = 0;
p->policy_state.head = p->policy_state.tail = 0;
- p->pcs_app_max = HICN_PARAM_CS_LRU_DEFAULT - p->policy_state.max;
p->policy_vft.hicn_cs_insert = hicn_cs_lru.hicn_cs_insert;
p->policy_vft.hicn_cs_update = hicn_cs_lru.hicn_cs_update;
diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h
index fc63bd0a6..a9e1ae5a0 100644
--- a/hicn-plugin/src/pcs.h
+++ b/hicn-plugin/src/pcs.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:
@@ -22,8 +22,17 @@
#include "error.h"
#include "cache_policies/cs_policy.h"
#include "faces/face.h"
-#include "faces/ip/dpo_ip.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,48 +80,41 @@ 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;
} hicn_pit_entry_t;
-#define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 40
+#define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 36
/*
* CS entry, unioned with a PIT entry below
*/
typedef struct __attribute__ ((packed)) hicn_cs_entry_s
{
- /* 22B + 2B = 24B */
+ /* 18B + 2B = 20B */
u16 align;
/* Packet buffer, if held */
- /* 18B + 4B = 22B */
+ /* 20B + 4B = 24B */
u32 cs_pkt_buf;
/* Ingress face */
- /* 24B + 8B = 32B */
- //Fix alignment issues
- union
- {
- dpo_id_t cs_rxface;
- u64 cs_rxface_u64;
- };
+ /* 24B + 4B = 28B */
+ hicn_face_id_t cs_rxface;
/* Linkage for LRU, in the form of hashtable node indexes */
- /* 32B + 8B = 40B */
+ /* 28B + 8B = 36B */
u32 cs_lru_prev;
u32 cs_lru_next;
/* Reserved for implementing cache policy different than LRU */
- /* 40B + (64 - 40)B = 64B */
+ /* 36B + (64 - 36)B = 64B */
u8 opaque[HICN_CS_ENTRY_OPAQUE_SIZE];
@@ -154,10 +155,6 @@ typedef struct hicn_pit_cs_s
/* Total size of PCS */
u32 pcs_size;
- /* Memory reserved for appfaces */
- u32 pcs_app_max;
- u32 pcs_app_count;
-
hicn_cs_policy_t policy_state;
hicn_cs_policy_vft_t policy_vft;
@@ -170,7 +167,7 @@ always_inline void
hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_pcs_entry_t * pcs_entry, hicn_hash_entry_t * hash_entry,
hicn_hash_node_t * node, const hicn_dpo_vft_t * dpo_vft,
- dpo_id_t * hicn_dpo_id, dpo_id_t * inface_id, u8 is_appface);
+ dpo_id_t * hicn_dpo_id, hicn_face_id_t inface_id, u8 is_appface);
always_inline void
hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
@@ -197,7 +194,7 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_hash_entry_t ** hash_entry, u64 hashval,
u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id,
u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id,
- u8 * bucket_is_overflow, dpo_id_t * inface);
+ u8 * bucket_is_overflow, hicn_face_id_t inface);
always_inline int
hicn_pcs_pit_insert (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry,
@@ -285,16 +282,6 @@ hicn_pit_set_lru_max (hicn_pit_cs_t * p, u32 limit)
}
/*
- * Configure CS LRU limit. Zero is accepted, means 'no limit', probably not a
- * good choice.
- */
-static inline void
-hicn_pit_set_lru_app_max (hicn_pit_cs_t * p, u32 limit)
-{
- p->pcs_app_max = limit;
-}
-
-/*
* Accessor for PIT interest counter.
*/
static inline u32
@@ -385,7 +372,7 @@ always_inline void
hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_pcs_entry_t * pcs_entry, hicn_hash_entry_t * hash_entry,
hicn_hash_node_t * node, const hicn_dpo_vft_t * dpo_vft,
- dpo_id_t * hicn_dpo_id, dpo_id_t * inface_id, u8 is_appface)
+ dpo_id_t * hicn_dpo_id, hicn_face_id_t inface_id, u8 is_appface)
{
/*
@@ -401,25 +388,14 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
node->hn_flags |= HICN_HASH_NODE_CS_FLAGS;
pcs_entry->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG;
- pcs_entry->u.cs.cs_rxface = *inface_id;
+ pcs_entry->u.cs.cs_rxface = inface_id;
/* Update the CS according to the policy */
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- if (is_appface)
- {
- dpo_id_t *face_dpo = (dpo_id_t *) & (pcs_entry->u.cs.cs_rxface);
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- else
- {
- policy_state = &pitcs->policy_state;
- policy_vft = &pitcs->policy_vft;
- }
+ policy_state = &pitcs->policy_state;
+ policy_vft = &pitcs->policy_vft;
policy_vft->hicn_cs_insert (pitcs, node, pcs_entry, policy_state);
pitcs->pcs_cs_count++;
@@ -456,42 +432,18 @@ hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- dpo_id_t *face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface);
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
-
- if (dpo_cmp (&entry->u.cs.cs_rxface, &old_entry->u.cs.cs_rxface) != 0)
+ if (entry->u.cs.cs_rxface != old_entry->u.cs.cs_rxface)
{
/* Dequeue content from the old queue */
policy_vft->hicn_cs_dequeue (pitcs, node, old_entry, policy_state);
- dpo_copy (&old_entry->u.cs.cs_rxface, &entry->u.cs.cs_rxface);
- face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface);
+ old_entry->u.cs.cs_rxface = entry->u.cs.cs_rxface;
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
-
policy_vft->hicn_cs_insert (pitcs, node, old_entry, policy_state);
if (policy_state->count > policy_state->max)
@@ -530,20 +482,9 @@ hicn_pcs_cs_delete (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- dpo_id_t *face_dpo = (dpo_id_t *) & ((*pcs_entryp)->u.cs.cs_rxface);
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
policy_vft->hicn_cs_dequeue (pitcs, (*nodep), (*pcs_entryp),
policy_state);
@@ -589,20 +530,9 @@ hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- dpo_id_t *face_dpo = (dpo_id_t *) & (entry->u.cs.cs_rxface);
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
policy_vft->hicn_cs_insert (pitcs, node, entry, policy_state);
pitcs->pcs_cs_count++;
@@ -639,13 +569,13 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_hash_entry_t ** hash_entry, u64 hashval,
u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id,
u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id,
- u8 * bucket_is_overflow, dpo_id_t * inface)
+ u8 * bucket_is_overflow, hicn_face_id_t inface)
{
int ret;
ASSERT (entry == hicn_hashtb_node_data (node));
- entry->u.cs.cs_rxface = *inface;
+ entry->u.cs.cs_rxface = inface;
ret =
hicn_pcs_cs_insert (vm, pitcs, entry, node, hash_entry, hashval, node_id,
dpo_ctx_id, vft_id, is_cs, hash_entry_id, bucket_id,
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.c b/hicn-plugin/src/route.c
index c208dd4c1..3b774cd82 100644
--- a/hicn-plugin/src/route.c
+++ b/hicn-plugin/src/route.c
@@ -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:
@@ -15,9 +15,14 @@
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_entry_track.h>
#include <vnet/ip/ip6_packet.h>
+#include <vnet/ip/ip.h>
#include <vnet/dpo/dpo.h>
+#include <vnet/dpo/drop_dpo.h>
#include <vnet/dpo/load_balance.h>
+#include <vnet/udp/udp.h>
+#include <vnet/udp/udp_encap.h>
#include <vlib/global_funcs.h>
#include "strategy_dpo_ctx.h"
@@ -26,11 +31,18 @@
#include "faces/face.h"
#include "error.h"
#include "strategies/dpo_mw.h"
+#include "infra.h"
+#include "udp_tunnels/udp_tunnel.h"
#define FIB_SOURCE_HICN 0x04 //Right after the FIB_SOURCE_INTERFACE priority
fib_source_t hicn_fib_src;
+fib_node_type_t hicn_fib_node_type;
+
+ip4_address_t localhost4 = {0};
+ip6_address_t localhost6 = {0};
+
int
hicn_route_get_dpo (const fib_prefix_t * prefix,
const dpo_id_t ** hicn_dpo, u32 * fib_index)
@@ -91,134 +103,321 @@ hicn_route_get_dpo (const fib_prefix_t * prefix,
}
int
-hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix)
+hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id)
{
const dpo_id_t *hicn_dpo_id;
- int ret = HICN_ERROR_NONE;
- dpo_id_t faces_dpo_tmp[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
- int n_face_dpo = 0;
- const hicn_dpo_vft_t *dpo_vft;
+ dpo_id_t new_dpo_id = DPO_INVALID;
+ int ret;
+ hicn_dpo_ctx_t *old_hicn_dpo_ctx;
+ const hicn_dpo_vft_t *new_dpo_vft;
+ index_t new_hicn_dpo_idx;
u32 fib_index;
- vlib_main_t *vm = vlib_get_main ();
- hicn_face_vft_t *face_vft = NULL;
- if (face_id == NULL)
+ ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+
+ if (ret == HICN_ERROR_NONE)
{
- return HICN_ERROR_ROUTE_INVAL;
+ old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+
+ new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id);
+
+ if (new_dpo_vft == NULL || old_hicn_dpo_ctx == NULL)
+ return HICN_ERROR_STRATEGY_NOT_FOUND;
+
+ /* Create a new dpo for the new strategy */
+ new_dpo_vft->hicn_dpo_create (hicn_dpo_id->dpoi_proto,
+ old_hicn_dpo_ctx->next_hops,
+ old_hicn_dpo_ctx->entry_count,
+ &new_hicn_dpo_idx);
+
+ /* the value we got when we registered */
+ dpo_set (&new_dpo_id,
+ new_dpo_vft->hicn_dpo_get_type (),
+ (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
+ DPO_PROTO_IP6), new_hicn_dpo_idx);
+
+ /* Here is where we create the "via" like route */
+ /*
+ * For the moment we use the global one the prefix you want
+ * to match Neale suggested -- FIB_SOURCE_HICN the client
+ * that is adding them -- no easy explanation at this time…
+ */
+ fib_node_index_t new_fib_node_index =
+ fib_table_entry_special_dpo_update (fib_index,
+ prefix,
+ hicn_fib_src,
+ FIB_ENTRY_FLAG_EXCLUSIVE,
+ &new_dpo_id);
+
+ dpo_unlock (&new_dpo_id);
+ ret =
+ (new_fib_node_index !=
+ FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
+ HICN_ERROR_ROUTE_NOT_UPDATED;
}
- /*
- * Check is the faces are available, otherwise skip the face
- * id_adjacency existance is not checked. It should be checked before
- * sending a packet out
- */
- for (int i = 0; i < clib_min (HICN_PARAM_FIB_ENTRY_NHOPS_MAX, len); i++)
+ //Remember to remove the lock from the table when removing the entry
+ return ret;
+
+}
+
+int
+ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if)
+{
+ fib_route_path_t *rpaths = NULL, rpath;
+
+ u32 fib_index = fib_table_find(fib_proto, 0);
+
+ clib_memset(&rpath, 0, sizeof(rpath));
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_addr = *nh;
+ rpath.frp_proto = ip46_address_is_ip4(nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
+
+ vec_add1(rpaths, rpath);
+
+ fib_table_entry_path_add2 (fib_index,
+ rpfx,
+ FIB_SOURCE_CLI,
+ FIB_ENTRY_FLAG_NONE, rpaths);
+ return 0;
+}
+
+int
+ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if)
+{
+ fib_route_path_t *rpaths = NULL, rpath;
+
+ u32 fib_index = fib_table_find(fib_proto, 0);
+
+ clib_memset(&rpath, 0, sizeof(rpath));
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_addr = *nh;
+ rpath.frp_proto = ip46_address_is_ip4(nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
+
+ vec_add1(rpaths, rpath);
+
+ fib_table_entry_path_remove2 (fib_index,
+ rpfx,
+ FIB_SOURCE_CLI,
+ rpaths);
+ return 0;
+}
+
+
+static ip46_address_t * get_address(ip46_address_t * nh, u32 sw_if, fib_protocol_t proto)
+{
+ ip46_address_t * local_address = calloc(1, sizeof(ip46_address_t));
+
+ if (proto == FIB_PROTOCOL_IP4)
{
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id[i]);
- face_vft = hicn_face_get_vft (face->shared.face_type);
- dpo_id_t face_dpo = DPO_INVALID;
- face_vft->hicn_face_get_dpo (face, &face_dpo);
+ ip_interface_address_t *interface_address;
+ ip4_address_t *addr =
+ ip4_interface_address_matching_destination (&ip4_main,
+ &nh->ip4,
+ sw_if,
+ &interface_address);
+
+ if (addr == NULL)
+ addr = ip4_interface_first_address (&ip4_main,
+ sw_if,
+ &interface_address);
+ if (addr != NULL)
+ ip46_address_set_ip4 (local_address, addr);
+ }
+ else if (proto == FIB_PROTOCOL_IP6)
+ {
+ ip_interface_address_t *interface_address;
+ ip6_interface_address_matching_destination (&ip6_main,
+ &nh->ip6,
+ sw_if,
+ &interface_address);
+
+ ip6_address_t *addr = NULL;
+ if (interface_address != NULL)
+ addr =
+ (ip6_address_t *)
+ ip_interface_address_get_address (&ip6_main.lookup_main,
+ interface_address);
+
+ if (addr == NULL)
+ addr = ip6_interface_first_address (&ip6_main, sw_if);
+
+ if (addr != NULL)
+ ip46_address_set_ip6 (local_address, addr);
+ }
- if (!dpo_id_is_valid (&face_dpo))
- {
- vlib_cli_output (vm, "Face %d not found, skip...\n", face_id[i]);
- return ret;
- }
+ return local_address;
+}
+
+static void
+sync_hicn_fib_entry(hicn_dpo_ctx_t *fib_entry)
+{
+ const dpo_id_t * dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
+ const load_balance_t *lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
+ index_t hicn_fib_entry_index = hicn_strategy_dpo_ctx_get_index(fib_entry);
+ hicn_face_id_t * vec_faces = 0;
+
+ dpo_id_t temp = DPO_INVALID;
+ const dpo_id_t *former_dpo = &temp;
+ int index = 0;
+ for (int j = 0; j < lb0->lb_n_buckets; j++) {
+ const dpo_id_t * dpo = load_balance_get_bucket_i(lb0,j);
+
+ int dpo_comparison = dpo_cmp(former_dpo, dpo);
+ former_dpo = dpo;
+ /*
+ * Loadbalancing in ip replicate the dpo in multiple buckets
+ * in order to honor the assigned weights.
+ */
+ if (dpo_comparison == 0)
+ continue;
+
+ u32 sw_if = ~0;
+ ip46_address_t * nh = NULL;
+ hicn_face_id_t face_id = HICN_FACE_NULL;
+
+ if (dpo_is_adj(dpo))
+ {
+ ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
+ sw_if = adj->rewrite_header.sw_if_index;
+ nh = get_address (&(adj->sub_type.nbr.next_hop), sw_if, fib_entry->proto);
+ }
+ else if (dpo->dpoi_type == dpo_type_udp_ip4 || dpo->dpoi_type == dpo_type_udp_ip6)
+ {
+ u8 proto = dpo->dpoi_type == dpo_type_udp_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+ nh = calloc (1, sizeof(ip46_address_t));
+ switch (dpo->dpoi_proto)
+ {
+ case FIB_PROTOCOL_IP6:
+ nh = calloc (1, sizeof(ip46_address_t));
+ ip46_address_set_ip6(nh, &localhost6);
+ break;
+ case FIB_PROTOCOL_IP4:
+ nh = calloc (1, sizeof(ip46_address_t));
+ ip46_address_set_ip4(nh, &localhost4);
+ break;
+ default:
+ nh = calloc (1, sizeof(ip46_address_t));
+ }
+ udp_tunnel_add_existing (dpo->dpoi_index, proto);
+ }
+ else //if (dpo_is_drop(dpo))
+ {
+ sw_if = dpo_get_urpf(dpo);
+ nh = calloc (1, sizeof(ip46_address_t));
+ }
+
+ /* Careful, this adds a lock on the face if it exists */
+ hicn_face_add(dpo, nh, sw_if, &face_id, 0);
+
+ vec_validate(vec_faces, index);
+ vec_faces[index] = face_id;
+ index++;
+
+ /* Face creation can realloc load_balance_t? Seem the fib_tracking does so. */
+ dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
+ lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
+ }
+
+ const hicn_dpo_vft_t * strategy_vft = hicn_dpo_get_vft(fib_entry->dpo_type);
+ int i = 0;
+ while (i < fib_entry->entry_count)
+ {
+ u32 idx_nh = vec_search(vec_faces, fib_entry->next_hops[i]);
+ if (idx_nh == ~0)
+ {
+ strategy_vft->hicn_dpo_del_nh(fib_entry->next_hops[i], hicn_fib_entry_index);
+ }
else
- {
- faces_dpo_tmp[n_face_dpo++] = face_dpo;
- }
- }
+ {
+ vec_del1(vec_faces, idx_nh);
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ /* Remove the lock added by hicn_face_add */
+ hicn_face_unlock_with_id (fib_entry->next_hops[i]);
+ i++;
+ }
+ }
- if (ret == HICN_ERROR_NONE)
+ hicn_face_id_t *face_id;
+ vec_foreach(face_id, vec_faces)
{
- for (int i = 0; i < n_face_dpo && (ret == HICN_ERROR_NONE); i++)
- {
- u32 vft_id = hicn_dpo_get_vft_id (hicn_dpo_id);
- dpo_vft = hicn_dpo_get_vft (vft_id);
-
- hicn_face_t *face =
- hicn_dpoi_get_from_idx (faces_dpo_tmp[i].dpoi_index);
- //Disable feature on the interface
- if (prefix->fp_proto == FIB_PROTOCOL_IP4)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- face->shared.sw_if, 1, 0, 0);
- else if (prefix->fp_proto == FIB_PROTOCOL_IP6)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- face->shared.sw_if, 1, 0, 0);
-
- ret = dpo_vft->hicn_dpo_add_update_nh (&faces_dpo_tmp[i],
- hicn_dpo_id->dpoi_index);
- }
+ strategy_vft->hicn_dpo_add_update_nh(*face_id, hicn_fib_entry_index);
+
+ /* Remove the lock added by hicn_face_add */
+ hicn_face_unlock_with_id (*face_id);
+
}
- return ret;
+ vec_free(vec_faces);
}
-/* Add a new route for a name prefix */
-int
-hicn_route_add (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix)
+static void
+enable_disable_data_receiving (fib_protocol_t proto, u32 sw_if, u8 is_enable)
{
- dpo_id_t dpo = DPO_INVALID;
- const dpo_id_t *hicn_dpo_id;
- int ret = HICN_ERROR_NONE;
- dpo_id_t face_dpo_tmp[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
- int n_face_dpo = 0;
- index_t dpo_idx;
- u32 fib_index;
- vlib_main_t *vm = vlib_get_main ();
- hicn_face_vft_t *face_vft = NULL;
+ if (proto == FIB_PROTOCOL_IP4 && sw_if != ~0)
+ vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
+ sw_if, is_enable, 0, 0);
+ else if (proto == FIB_PROTOCOL_IP6 && sw_if != ~0)
+ vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
+ sw_if, is_enable, 0, 0);
- if (face_id == NULL || !hicn_dpoi_idx_is_valid (*face_id))
- {
- return HICN_ERROR_ROUTE_INVAL;
+}
+
+walk_rc_t enable_data_receiving_new_fib_entry (vnet_main_t * vnm,
+ vnet_sw_interface_t * si,
+ void *ctx)
+{
+ fib_protocol_t *proto = (fib_protocol_t *) ctx;
+ enable_disable_data_receiving(*proto, si->sw_if_index, 1);
+
+ return (WALK_CONTINUE);
+}
+
+walk_rc_t disable_data_receiving_rm_fib_entry (vnet_main_t * vnm,
+ vnet_sw_interface_t * si,
+ void *ctx)
+{
+ fib_protocol_t *proto = (fib_protocol_t *) ctx;
+ enable_disable_data_receiving(*proto, si->sw_if_index, 0);
+
+ return (WALK_CONTINUE);
}
+
+int
+hicn_route_enable (fib_prefix_t *prefix) {
+
+ int ret = HICN_ERROR_NONE;
+ fib_node_index_t fib_entry_index;
+
+ /* Check if the route already exist in the fib */
/*
- * Check is the faces are available, otherwise skip the face
- * id_adjacency existance is not checked. It should be checked before
- * sending a packet out
+ * ASSUMPTION: we use table 0 which is the default table and it is
+ * already existing and locked
*/
- for (int i = 0; i < clib_min (HICN_PARAM_FIB_ENTRY_NHOPS_MAX, len); i++)
+ u32 fib_index = fib_table_find(prefix->fp_proto, 0);
+
+ fib_entry_index = fib_table_lookup_exact_match (fib_index, prefix);
+
+ if (fib_entry_index == FIB_NODE_INDEX_INVALID)
{
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id[i]);
- face_vft = hicn_face_get_vft (face->shared.face_type);
- dpo_id_t face_dpo = DPO_INVALID;
- face_vft->hicn_face_get_dpo (face, &face_dpo);
+ fib_entry_index = fib_table_lookup (fib_index, prefix);
- if (!dpo_id_is_valid (&face_dpo))
- {
- vlib_cli_output (vm, "Face %d not found, skip...\n", face_id[i]);
- return ret;
- }
- else
- {
- face_dpo_tmp[n_face_dpo++] = face_dpo;
- }
+ fib_route_path_t * paths = fib_entry_encode(fib_entry_index);
+
+ fib_table_entry_path_add2(fib_index, prefix, FIB_SOURCE_CLI, FIB_ENTRY_FLAG_NONE, paths);
}
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ /* Check if the prefix is already enabled */
+ u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
- if (ret == HICN_ERROR_ROUTE_NOT_FOUND)
- {
- dpo_id_t nhops[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
- for (int i = 0; i < n_face_dpo; i++)
- {
- clib_memcpy (&nhops[i], &face_dpo_tmp[i], sizeof (dpo_id_t));
- hicn_face_t *face =
- hicn_dpoi_get_from_idx (face_dpo_tmp[i].dpoi_index);
- //Disable feature on the interface
- if (prefix->fp_proto == FIB_PROTOCOL_IP4)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- face->shared.sw_if, 1, 0, 0);
- else if (prefix->fp_proto == FIB_PROTOCOL_IP6)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- face->shared.sw_if, 1, 0, 0);
- }
+ fib_node_index_t fib_hicn_entry_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
- default_dpo.hicn_dpo_create (prefix->fp_proto, nhops, n_face_dpo,
- &dpo_idx);
+ if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID)
+ {
+ dpo_id_t dpo = DPO_INVALID;
+ index_t dpo_idx;
+ default_dpo.hicn_dpo_create (prefix->fp_proto, 0, NEXT_HOP_INVALID,
+ &dpo_idx);
/* the value we got when we registered */
/*
@@ -226,9 +425,20 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len,
* object
*/
dpo_set (&dpo,
- default_dpo.hicn_dpo_get_type (),
- (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6), dpo_idx);
+ default_dpo.hicn_dpo_get_type (),
+ (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
+ DPO_PROTO_IP6), dpo_idx);
+
+ hicn_dpo_ctx_t * fib_entry = hicn_strategy_dpo_ctx_get(dpo_idx);
+
+ fib_node_init (&fib_entry->fib_node, hicn_fib_node_type);
+ fib_node_lock (&fib_entry->fib_node);
+
+ fib_entry->fib_entry_index = fib_entry_track (fib_index,
+ prefix,
+ hicn_fib_node_type,
+ dpo_idx, &fib_entry->fib_sibling);
+
/* Here is where we create the "via" like route */
/*
@@ -236,163 +446,317 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len,
* to match Neale suggested -- FIB_SOURCE_HICN the client
* that is adding them -- no easy explanation at this time…
*/
- fib_node_index_t new_fib_node_index =
- fib_table_entry_special_dpo_add (fib_index,
- prefix,
- hicn_fib_src,
- (FIB_ENTRY_FLAG_EXCLUSIVE |
- FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
- &dpo);
+ CLIB_UNUSED (fib_node_index_t new_fib_node_index) =
+ fib_table_entry_special_dpo_add (fib_hicn_index,
+ prefix,
+ hicn_fib_src,
+ (FIB_ENTRY_FLAG_EXCLUSIVE |
+ FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
+ &dpo);
+
+ sync_hicn_fib_entry(fib_entry);
/* We added a route, therefore add one lock to the table */
fib_table_lock (fib_index, prefix->fp_proto, hicn_fib_src);
- dpo_unlock (&dpo);
- ret =
- (new_fib_node_index !=
- FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
- HICN_ERROR_ROUTE_NO_INSERT;
-
- /*
- * TODO: we might want to store the fib index in the face.
- * This will help to update the fib entries when a face is
- * deleted. Fib_index_t is returned from
- * fib_table_entry_special_dpo_add.
+ /* Enable the feature to punt data packet every time we enable a new hicn route
+ * For each enable there must be a disable to defenitely disable the feature
+ *
+ * We cannot enable only the interfaces on which we send out interest because
+ * Data packet might be coming on in different interfaces, as in che case of mpls
+ * tunnels (packets are received from the physical nic, not the mpls tunnel interface).
*/
+ vnet_main_t * vnm = vnet_get_main ();
+ vnet_sw_interface_walk(vnm, enable_data_receiving_new_fib_entry, &(prefix->fp_proto));
+
+ dpo_unlock (&dpo);
}
- else if (ret == HICN_ERROR_NONE)
+ else
{
- ret = hicn_route_add_nhops (face_id, len, prefix);
+ const dpo_id_t *load_balance_dpo_id;
+ const dpo_id_t *strategy_dpo_id;
+
+ /* Route already existing. We need to update the dpo. */
+ load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fib_hicn_entry_index);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
+ {
+ ret = HICN_ERROR_ROUTE_NO_LD;
+ goto done;
+ }
+ else
+ {
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
+
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ goto done;
+ }
+
+ if (lb->lb_n_buckets > 1)
+ {
+ ret = HICN_ERROR_ROUTE_MLT_LD;
+ goto done;
+ }
+
+ hicn_dpo_ctx_t * hicn_fib_entry = hicn_strategy_dpo_ctx_get(strategy_dpo_id->dpoi_index);
+
+ sync_hicn_fib_entry(hicn_fib_entry);
+ }
}
+
+ done:
return ret;
}
int
-hicn_route_del (fib_prefix_t * prefix)
-{
- const dpo_id_t *hicn_dpo_id;
+hicn_route_disable (fib_prefix_t *prefix) {
+
int ret = HICN_ERROR_NONE;
- u32 fib_index;
- /* Remove the fib entry only if the dpo is of type hicn */
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ /* Check if the prefix is already enabled */
+ u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
- if (ret == HICN_ERROR_NONE)
+ fib_node_index_t fib_hicn_entry_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
+
+ if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID)
{
- fib_table_entry_special_remove (HICN_FIB_TABLE, prefix, hicn_fib_src);
+ return HICN_ERROR_ROUTE_NOT_FOUND;
+ }
+ else
+ {
+ const dpo_id_t *load_balance_dpo_id;
+ const dpo_id_t *strategy_dpo_id;
+ hicn_dpo_ctx_t * hicn_fib_entry;
- /*
- * Remove the lock from the table. We keep one lock per route
- */
- fib_table_unlock (fib_index, prefix->fp_proto, hicn_fib_src);
+ /* Route already existing. We need to update the dpo. */
+ load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fib_hicn_entry_index);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
+ {
+ ret = HICN_ERROR_ROUTE_NO_LD;
+ goto done;
+ }
+ else
+ {
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
+
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ goto done;
+ }
+
+ if (lb->lb_n_buckets > 1)
+ {
+ ret = HICN_ERROR_ROUTE_MLT_LD;
+ goto done;
+ }
+
+ hicn_fib_entry = hicn_strategy_dpo_ctx_get(strategy_dpo_id->dpoi_index);
+
+ for (int i = 0; i < hicn_fib_entry->entry_count; i++)
+ {
+ hicn_strategy_dpo_ctx_del_nh(hicn_fib_entry->next_hops[i], hicn_fib_entry);
+ }
+ }
+
+ fib_entry_untrack(hicn_fib_entry->fib_entry_index, hicn_fib_entry->fib_sibling);
+
+ fib_table_entry_special_remove (fib_hicn_index, prefix, hicn_fib_src);
+
+ /* Disable the feature to punt data packet every time we enable a new hicn route */
+ vnet_main_t * vnm = vnet_get_main ();
+ vnet_sw_interface_walk(vnm, disable_data_receiving_rm_fib_entry, &(prefix->fp_proto));
}
- //Remember to remove the lock from the table when removing the entry
+
+ done:
return ret;
}
-int
-hicn_route_del_nhop (fib_prefix_t * prefix, hicn_face_id_t face_id)
+
+static fib_node_t *
+hicn_ctx_node_get (fib_node_index_t index)
{
- const dpo_id_t *hicn_dpo_id;
- int ret;
- u32 vft_id;
- const hicn_dpo_vft_t *dpo_vft;
- u32 fib_index;
+ hicn_dpo_ctx_t * hicn_ctx;
+ hicn_ctx = hicn_strategy_dpo_ctx_get(index);
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ return (&hicn_ctx->fib_node);
+}
- /* Check if the dpo is an hicn_dpo_t */
- if (ret == HICN_ERROR_NONE)
- {
- vft_id = hicn_dpo_get_vft_id (hicn_dpo_id);
- dpo_vft = hicn_dpo_get_vft (vft_id);
+static void
+hicn_fib_last_lock_gone (fib_node_t *node)
+{
+}
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- //Disable feature on the interface
- if (prefix->fp_proto == FIB_PROTOCOL_IP4)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- face->shared.sw_if, 0, 0, 0);
- else if (prefix->fp_proto == FIB_PROTOCOL_IP6)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- face->shared.sw_if, 0, 0, 0);
+static hicn_dpo_ctx_t *
+hicn_ctx_from_fib_node (fib_node_t * node)
+{
+ return ((hicn_dpo_ctx_t *) (((char *) node) -
+ STRUCT_OFFSET_OF (hicn_dpo_ctx_t, fib_node)));
+}
- ret = dpo_vft->hicn_dpo_del_nh (face_id, hicn_dpo_id->dpoi_index);
+static fib_node_back_walk_rc_t
+hicn_fib_back_walk_notify (fib_node_t *node,
+ fib_node_back_walk_ctx_t *ctx)
+{
- hicn_dpo_ctx_t *dpo_ctx =
- hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+ hicn_dpo_ctx_t *fib_entry = hicn_ctx_from_fib_node (node);
+ sync_hicn_fib_entry(fib_entry);
- if (ret == HICN_ERROR_NONE && !dpo_ctx->entry_count)
- ret = hicn_route_del (prefix);
- }
- //Remember to remove the lock from the table when removing the entry
- return ret;
+ return (FIB_NODE_BACK_WALK_CONTINUE);
}
-int
-hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id)
+static void
+hicn_fib_show_memory (void)
{
- const dpo_id_t *hicn_dpo_id;
- dpo_id_t new_dpo_id = DPO_INVALID;
- int ret;
- hicn_dpo_ctx_t *old_hicn_dpo_ctx;
- const hicn_dpo_vft_t *new_dpo_vft;
- index_t new_hicn_dpo_idx;
- u32 fib_index;
+}
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
- if (ret == HICN_ERROR_NONE)
+static const fib_node_vft_t hicn_fib_vft =
+{
+ .fnv_get = hicn_ctx_node_get,
+ .fnv_last_lock = hicn_fib_last_lock_gone,
+ .fnv_back_walk = hicn_fib_back_walk_notify,
+ .fnv_mem_show = hicn_fib_show_memory,
+};
+
+fib_table_walk_rc_t enable_data_on_existing_hicn(fib_node_index_t fei,
+ void *ctx)
+{
+ u32 sw_if = *(u32 *)ctx;
+ const dpo_id_t *load_balance_dpo_id;
+ const dpo_id_t *strategy_dpo_id;
+
+ /* Route already existing. We need to update the dpo. */
+ load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fei);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
{
- old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+ goto done;
+ }
+ else
+ {
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
- new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id);
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
- if (new_dpo_vft == NULL || old_hicn_dpo_ctx == NULL)
- return HICN_ERROR_STRATEGY_NOT_FOUND;
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ goto done;
+ }
- /* Create a new dpo for the new strategy */
- new_dpo_vft->hicn_dpo_create (hicn_dpo_id->dpoi_proto,
- old_hicn_dpo_ctx->next_hops,
- old_hicn_dpo_ctx->entry_count,
- &new_hicn_dpo_idx);
+ enable_disable_data_receiving (strategy_dpo_id->dpoi_proto, sw_if, 1);
+ }
- /* the value we got when we registered */
- dpo_set (&new_dpo_id,
- new_dpo_vft->hicn_dpo_get_type (),
- (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6), new_hicn_dpo_idx);
+ done:
+ return (FIB_TABLE_WALK_CONTINUE);
+}
- /* Here is where we create the "via" like route */
+static clib_error_t *
+set_table_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
+{
+
+ if (!is_add)
+ return HICN_ERROR_NONE;
+
+ vnet_sw_interface_t * sw_int = vnet_get_sw_interface(vnm, sw_if_index);
+ vnet_hw_interface_t * hw_int = vnet_get_hw_interface(vnm, sw_int->hw_if_index);
+
+ char * mpls = "mpls";
+ if (strstr((char *)hw_int->name, mpls) == NULL)
+ return 0;
+
+ int rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, HICN_FIB_TABLE, 1);
+
+ if (!rv)
+ {
+ rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, HICN_FIB_TABLE, 1);
+
+ if (rv)
+ {
+ /* An error occurred. Bind the interface back to the default fib */
+ ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, 0, 1);
+ }
+ }
+
+ u32 fib_index = fib_table_find(FIB_PROTOCOL_IP4,
+ HICN_FIB_TABLE);
+ if (fib_index != ~0)
+ {
/*
- * For the moment we use the global one the prefix you want
- * to match Neale suggested -- FIB_SOURCE_HICN the client
- * that is adding them -- no easy explanation at this time…
+ * Walk the ip4 and ip6 fib tables to discover existing hicn fib entries.
+ * For each of them we need to enable the feature to punt data packets.
*/
- fib_node_index_t new_fib_node_index =
- fib_table_entry_special_dpo_update (fib_index,
- prefix,
- hicn_fib_src,
- FIB_ENTRY_FLAG_EXCLUSIVE,
- &new_dpo_id);
+ fib_table_walk(fib_index,
+ FIB_PROTOCOL_IP4,
+ enable_data_on_existing_hicn,
+ &sw_if_index);
+ }
- dpo_unlock (&new_dpo_id);
- ret =
- (new_fib_node_index !=
- FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
- HICN_ERROR_ROUTE_NOT_UPDATED;
+ fib_index = fib_table_find(FIB_PROTOCOL_IP6,
+ HICN_FIB_TABLE);
+ if (fib_index != ~0)
+ {
+ fib_table_walk(fib_index,
+ FIB_PROTOCOL_IP6,
+ enable_data_on_existing_hicn,
+ &sw_if_index);
}
- //Remember to remove the lock from the table when removing the entry
- return ret;
+ return rv ? clib_error_return (0, "unable to add hicn table to interface") : 0;
}
+VNET_SW_INTERFACE_ADD_DEL_FUNCTION (set_table_interface_add_del);
+
void
hicn_route_init ()
{
+ vnet_main_t * vnm = vnet_get_main ();
+ vlib_main_t * vm = vlib_get_main ();
hicn_fib_src = fib_source_allocate ("hicn",
FIB_SOURCE_HICN, FIB_SOURCE_BH_API);
+
+ hicn_fib_node_type = fib_node_register_new_type(&hicn_fib_vft);
+
+ ip_table_create(FIB_PROTOCOL_IP4, HICN_FIB_TABLE, 1, (const u8 *)"hicn4");
+ ip_table_create(FIB_PROTOCOL_IP6, HICN_FIB_TABLE, 1, (const u8 *)"hicn6");
+
+ u32 sw_if_index;
+ u8 mac_address[6];
+ u8 is_specified = 0;
+ u32 user_instance = 0;
+
+ vnet_create_loopback_interface (&sw_if_index, mac_address,
+ is_specified, user_instance);
+
+ localhost4.as_u8[0] = 127;
+ localhost4.as_u8[3] = 1;
+ u32 length4 = 32, length6 = 128, is_del = 0, flags = 0;
+
+ localhost6.as_u8[15] = 1;
+
+ ip4_add_del_interface_address (vm, sw_if_index, &localhost4, length4, is_del);
+ ip6_add_del_interface_address (vm, sw_if_index, &localhost6, length6, is_del);
+
+ flags |= VNET_SW_INTERFACE_FLAG_ADMIN_UP;
+ vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
}
/*
diff --git a/hicn-plugin/src/route.h b/hicn-plugin/src/route.h
index 5877f31a8..a1ba86b3d 100644
--- a/hicn-plugin/src/route.h
+++ b/hicn-plugin/src/route.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:
@@ -21,36 +21,102 @@
#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.
+ */
+
/*
- * Retrieve the hicn dpo corresponding to a hicn prefix
+ * 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];
+
+/**
+ * @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);
-/*
- * Add a new 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_add (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix);
+hicn_route_set_strategy (fib_prefix_t * prefix, u32 strategy_id);
-/*
- * Add new next hops for a prefix route
+/**
+ * @Brief Helper to add a nex hop in the vrf 0. If there are no entries in the
+ * vrf 0 that matches with the prefix (epm), a new one is created.
+ *
+ * @param fib_proto FIB_PROTOCOL_IP6 or FIB_PROTOCOL_IP4 (mpls not supported)
+ * @param pfx Prefix for which to add a next hop
+ * @param nh Next hop to add
+ * @param sw_if Software interface index to add in the next hop
*/
int
-hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix);
+ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * pfx, ip46_address_t * nh, u32 sw_if);
-/* Remove a route for a name prefix */
-int hicn_route_del (fib_prefix_t * prefix);
+/**
+ * @Brief Helper to remove a nex hop in the vrf 0. If there are no entries in the
+ * vrf 0 nothing happens.
+ *
+ * @param fib_proto FIB_PROTOCOL_IP6 or FIB_PROTOCOL_IP4 (mpls not supported)
+ * @param pfx Prefix for which to remove a next hop
+ * @param nh Next hop to remove
+ * @param sw_if Software interface index in the next hop definition
+ */
+int
+ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if);
-/* Remove a next hop route for a name prefix */
-int hicn_route_del_nhop (fib_prefix_t * prefix, u32 face_id);
+/**
+ * @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);
-/* Remove a next hop route for a name 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_set_strategy (fib_prefix_t * prefix, u32 strategy_id);
+hicn_route_disable (fib_prefix_t *prefix);
+
/* Init route internal strustures */
void
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.c b/hicn-plugin/src/strategies/dpo_mw.c
index eebb572c4..12c77bce8 100644
--- a/hicn-plugin/src/strategies/dpo_mw.c
+++ b/hicn-plugin/src/strategies/dpo_mw.c
@@ -76,8 +76,6 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap)
index_t index = va_arg (*ap, index_t);
hicn_dpo_ctx_t *dpo_ctx = NULL;
hicn_strategy_mw_ctx_t *mw_dpo_ctx = NULL;
- dpo_id_t *next_hop = NULL;
- hicn_face_vft_t *face_vft = NULL;
u32 indent = va_arg (*ap, u32);;
dpo_ctx = hicn_strategy_dpo_ctx_get (index);
@@ -97,24 +95,20 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap)
buf = format (NULL, "TFIB");
else
continue;
- next_hop = &dpo_ctx->next_hops[i];
- face_vft = hicn_face_get_vft (next_hop->dpoi_type);
- if (face_vft != NULL)
- {
- s = format (s, "\n");
- s =
- format (s, "%U ", face_vft->format_face, next_hop->dpoi_index,
- indent);
- s = format (s, "weight %u", mw_dpo_ctx->weight[i]);
- s = format (s, " %s", buf);
- }
+
+ s = format (s, "\n");
+ s =
+ format (s, "%U ", format_hicn_face, dpo_ctx->next_hops[i],
+ indent);
+ s = format (s, "weight %u", mw_dpo_ctx->weight[i]);
+ s = format (s, " %s", buf);
}
return (s);
}
void
-hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_mw_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx)
{
hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx;
@@ -126,13 +120,13 @@ hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
*dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx);
- init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw);
+ init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw, proto);
memset (hicn_strategy_mw_ctx->weight, 0, HICN_PARAM_FIB_ENTRY_NHOPS_MAX);
}
int
-hicn_strategy_mw_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx)
+hicn_strategy_mw_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx)
{
hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
u8 pos = 0;
diff --git a/hicn-plugin/src/strategies/dpo_mw.h b/hicn-plugin/src/strategies/dpo_mw.h
index ccc8d044f..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
@@ -60,7 +68,7 @@ hicn_dpo_ctx_t *hicn_strategy_mw_ctx_get (index_t index);
* @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL
*/
void
-hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_mw_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx);
/**
@@ -75,7 +83,7 @@ hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
* @return HICN_ERROR_NONE if the update or insert was fine,
* otherwise HICN_ERROR_DPO_CTX_NOT_FOUND
*/
-int hicn_strategy_mw_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx);
+int hicn_strategy_mw_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx);
/**
* @brief Delete a next hop in the dpo ctx.
diff --git a/hicn-plugin/src/strategies/dpo_rr.c b/hicn-plugin/src/strategies/dpo_rr.c
index a67b06acb..adb7e1025 100644
--- a/hicn-plugin/src/strategies/dpo_rr.c
+++ b/hicn-plugin/src/strategies/dpo_rr.c
@@ -76,8 +76,6 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
index_t index = va_arg (*ap, index_t);
hicn_dpo_ctx_t *dpo_ctx = NULL;
hicn_strategy_rr_ctx_t *rr_dpo_ctx = NULL;
- dpo_id_t *next_hop = NULL;
- hicn_face_vft_t *face_vft = NULL;
u32 indent = va_arg (*ap, u32);
dpo_ctx = hicn_strategy_dpo_ctx_get (index);
@@ -88,7 +86,7 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
s =
format (s, "hicn-rr, next hop Face %d",
- dpo_ctx->next_hops[rr_dpo_ctx->current_nhop].dpoi_index);
+ dpo_ctx->next_hops[rr_dpo_ctx->current_nhop]);
for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++)
{
@@ -101,23 +99,18 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
else
continue;
- next_hop = &dpo_ctx->next_hops[i];
- face_vft = hicn_face_get_vft (next_hop->dpoi_type);
- if (face_vft != NULL)
- {
- s = format (s, "\n");
- s =
- format (s, "%U ", face_vft->format_face, next_hop->dpoi_index,
- indent);
- s = format (s, " %s", buf);
- }
+ s = format (s, "\n");
+ s =
+ format (s, "%U ", format_hicn_face, dpo_ctx->next_hops[i],
+ indent);
+ s = format (s, " %s", buf);
}
return (s);
}
void
-hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_rr_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx)
{
hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx;
@@ -129,13 +122,13 @@ hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
*dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx);
- init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr);
+ init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr, proto);
hicn_strategy_rr_ctx->current_nhop = 0;
}
int
-hicn_strategy_rr_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx)
+hicn_strategy_rr_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx)
{
hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
u8 pos = 0;
diff --git a/hicn-plugin/src/strategies/dpo_rr.h b/hicn-plugin/src/strategies/dpo_rr.h
index 8afd0dabc..e4e5b5372 100644
--- a/hicn-plugin/src/strategies/dpo_rr.h
+++ b/hicn-plugin/src/strategies/dpo_rr.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,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
*/
@@ -62,7 +71,7 @@ hicn_dpo_ctx_t *hicn_strategy_rr_ctx_get (index_t index);
* @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL
*/
void
-hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_rr_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx);
/**
@@ -77,7 +86,7 @@ hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
* @return HICN_ERROR_NONE if the update or insert was fine,
* otherwise HICN_ERROR_DPO_CTX_NOT_FOUND
*/
-int hicn_strategy_rr_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx);
+int hicn_strategy_rr_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx);
/**
* @brief Delete a next hop in the dpo ctx.
diff --git a/hicn-plugin/src/strategies/strategy_mw.c b/hicn-plugin/src/strategies/strategy_mw.c
index 2422d4fed..fe4d5896a 100644
--- a/hicn-plugin/src/strategies/strategy_mw.c
+++ b/hicn-plugin/src/strategies/strategy_mw.c
@@ -25,7 +25,7 @@ void hicn_receive_data_mw (index_t dpo_idx, int nh_idx);
void hicn_add_interest_mw (index_t dpo_idx, hicn_hash_entry_t * pit_entry);
void hicn_on_interest_timeout_mw (index_t dpo_idx);
u32 hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx,
- dpo_id_t ** outface);
+ hicn_face_id_t* outface);
u32 get_strategy_node_index_mw (void);
u8 *hicn_strategy_format_trace_mw (u8 * s, hicn_strategy_trace_t * t);
u8 *hicn_strategy_format_mw (u8 * s, va_list * ap);
@@ -51,7 +51,7 @@ hicn_mw_strategy_get_vft (void)
/* DPO should be give in input as it containes all the information to calculate the next hops*/
u32
-hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
+hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, hicn_face_id_t* outface)
{
hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
@@ -64,20 +64,14 @@ hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
u8 next_hop_index = 0;
for (int i = 0; i < dpo_ctx->entry_count; i++)
{
- if (dpo_id_is_valid (&dpo_ctx->next_hops[i]))
- {
- if (hicn_strategy_mw_ctx->weight[next_hop_index] <
- hicn_strategy_mw_ctx->weight[i])
- {
- next_hop_index = i;
- }
- }
+ if (hicn_strategy_mw_ctx->weight[next_hop_index] <
+ hicn_strategy_mw_ctx->weight[i])
+ {
+ next_hop_index = i;
+ }
}
- if (!dpo_id_is_valid (&dpo_ctx->next_hops[next_hop_index]))
- return HICN_ERROR_STRATEGY_NH_NOT_FOUND;
-
- *outface = (dpo_id_t *) & dpo_ctx->next_hops[next_hop_index];
+ *outface = dpo_ctx->next_hops[next_hop_index];
return HICN_ERROR_NONE;
}
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_mw_cli.c b/hicn-plugin/src/strategies/strategy_mw_cli.c
index 701f96fa7..636d7effa 100644
--- a/hicn-plugin/src/strategies/strategy_mw_cli.c
+++ b/hicn-plugin/src/strategies/strategy_mw_cli.c
@@ -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:
@@ -97,7 +97,7 @@ hicn_mw_strategy_cli_set_weight_command_fn (vlib_main_t * vm,
(hicn_strategy_mw_ctx_t *) hicn_dpo_ctx;
int idx = ~0;
for (int i = 0; i < hicn_dpo_ctx->entry_count; i++)
- if (hicn_dpo_ctx->next_hops[i].dpoi_index == (index_t) faceid)
+ if (hicn_dpo_ctx->next_hops[i] == faceid)
idx = i;
if (idx == ~0)
diff --git a/hicn-plugin/src/strategies/strategy_rr.c b/hicn-plugin/src/strategies/strategy_rr.c
index cdcca7f2a..4c65ce52a 100644
--- a/hicn-plugin/src/strategies/strategy_rr.c
+++ b/hicn-plugin/src/strategies/strategy_rr.c
@@ -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,7 +26,7 @@ void hicn_receive_data_rr (index_t dpo_idx, int nh_idx);
void hicn_add_interest_rr (index_t dpo_idx, hicn_hash_entry_t * pit_entry);
void hicn_on_interest_timeout_rr (index_t dpo_idx);
u32 hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx,
- dpo_id_t ** outface);
+ hicn_face_id_t* outface);
u8 *hicn_strategy_format_trace_rr (u8 * s, hicn_strategy_trace_t * t);
u8 *hicn_strategy_format_rr (u8 * s, va_list * ap);
@@ -51,7 +51,7 @@ hicn_rr_strategy_get_vft (void)
/* DPO should be give in input as it containes all the information to calculate the next hops*/
u32
-hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
+hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, hicn_face_id_t* outface)
{
hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
@@ -61,15 +61,8 @@ hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx =
(hicn_strategy_rr_ctx_t *) dpo_ctx->data;
- if (dpo_id_is_valid
- (&dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop]))
- {
- *outface =
- (dpo_id_t *) & dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop];
-
- }
- else
- return HICN_ERROR_STRATEGY_NH_NOT_FOUND;
+ *outface =
+ dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop];
hicn_strategy_rr_ctx->current_nhop =
(hicn_strategy_rr_ctx->current_nhop + 1) % dpo_ctx->entry_count;
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 c18ae4eea..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 */
@@ -54,7 +53,7 @@ typedef struct hicn_strategy_vft_s
void (*hicn_on_interest_timeout) (index_t dpo_idx);
void (*hicn_add_interest) (index_t dpo_idx, hicn_hash_entry_t * pit_entry);
u32 (*hicn_select_next_hop) (index_t dpo_idx, int *nh_idx,
- dpo_id_t ** outface);
+ hicn_face_id_t* outface);
u8 *(*hicn_format_strategy_trace) (u8 *, hicn_strategy_trace_t *);
u8 *(*hicn_format_strategy) (u8 * s, va_list * ap);
/**< Format an hICN dpo*/
@@ -64,10 +63,31 @@ typedef enum
{
HICN_STRATEGY_NEXT_INTEREST_HITPIT,
HICN_STRATEGY_NEXT_INTEREST_HITCS,
+ HICN_STRATEGY_NEXT_INTEREST_FACE4,
+ HICN_STRATEGY_NEXT_INTEREST_FACE6,
HICN_STRATEGY_NEXT_ERROR_DROP,
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.c b/hicn-plugin/src/strategy_dpo_ctx.c
index 6ec1407fb..342c78bb5 100644
--- a/hicn-plugin/src/strategy_dpo_ctx.c
+++ b/hicn-plugin/src/strategy_dpo_ctx.c
@@ -97,7 +97,7 @@ hicn_strategy_dpo_ctx_alloc ()
}
int
-hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
+hicn_strategy_dpo_ctx_add_nh (hicn_face_id_t nh, hicn_dpo_ctx_t * dpo_ctx,
u8 * pos)
{
@@ -106,12 +106,12 @@ hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
/* Iterate through the list of faces to find if the face is already a next hop */
for (int i = 0; i < dpo_ctx->entry_count; i++)
{
- if (!memcmp (nh, &dpo_ctx->next_hops[i], sizeof (dpo_id_t)))
+ if (nh == dpo_ctx->next_hops[i])
{
/* If face is marked as deleted, ignore it */
hicn_face_t *face =
- hicn_dpoi_get_from_idx (dpo_ctx->next_hops[i].dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_DELETED)
+ hicn_dpoi_get_from_idx (dpo_ctx->next_hops[i]);
+ if (face->flags & HICN_FACE_FLAGS_DELETED)
{
continue;
}
@@ -125,7 +125,8 @@ hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
return HICN_ERROR_DPO_CTX_NHOPS_NS;
}
- clib_memcpy (&dpo_ctx->next_hops[empty], nh, sizeof (dpo_id_t));
+ dpo_ctx->next_hops[empty] = nh;
+ hicn_face_lock_with_id (nh);
dpo_ctx->entry_count++;
*pos = empty;
@@ -137,13 +138,13 @@ hicn_strategy_dpo_ctx_del_nh (hicn_face_id_t face_id,
hicn_dpo_ctx_t * dpo_ctx)
{
int ret = HICN_ERROR_DPO_CTX_NOT_FOUND;
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
for (int i = 0; i < dpo_ctx->entry_count; i++)
{
- if (dpo_ctx->next_hops[i].dpoi_index == face_id)
+ if (dpo_ctx->next_hops[i] == face_id)
{
- hicn_face_unlock (&dpo_ctx->next_hops[i]);
+ hicn_face_unlock_with_id (dpo_ctx->next_hops[i]);
dpo_ctx->entry_count--;
dpo_ctx->next_hops[i] = dpo_ctx->next_hops[dpo_ctx->entry_count];
dpo_ctx->next_hops[dpo_ctx->entry_count] = invalid;
diff --git a/hicn-plugin/src/strategy_dpo_ctx.h b/hicn-plugin/src/strategy_dpo_ctx.h
index 737071766..214ed88ad 100644
--- a/hicn-plugin/src/strategy_dpo_ctx.h
+++ b/hicn-plugin/src/strategy_dpo_ctx.h
@@ -22,27 +22,30 @@
#include "params.h"
#include "faces/face.h"
-//FIB table for hicn. 0 is the default one used by ip
-#define HICN_FIB_TABLE 0
-
-#define NEXT_HOP_INVALID DPO_INVALID
-
-#define INIT_SEQ 0
-
/**
- * @brief Definition of the general hICN DPO ctx (shared among all the strategies).
+ * @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 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)
+ * 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
+
+#define NEXT_HOP_INVALID ~0
+
+#define INIT_SEQ 0
+
typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
- /* 8B*5 = 40B */
- dpo_id_t next_hops[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
+ /* 4B*10 = 40B */
+ hicn_face_id_t next_hops[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
/* 40B + 4B = 44B */
u32 locks;
/* 44B + 1B = 45B */
@@ -51,17 +54,30 @@ typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s
/* Number of TFIB entries (stored at the end of the next_hops array */
u8 tfib_entry_count;
+ dpo_type_t dpo_type;
+
/* 46B + 2B = 48B */
- u16 padding; /* To align to 8B */
+ u8 padding; /* To align to 8B */
/* 48 + 4B = 52; last sequence number */
- seq_t seq;
+ u32 seq;
- /* 48 + 1B = 53; last sequence number */
- dpo_type_t dpo_type;
+ /* 52 + 12 = 64 */
+ fib_node_t fib_node;
CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
- u8 data[CLIB_CACHE_LINE_BYTES];
+
+ fib_node_index_t fib_entry_index;
+
+ u32 fib_sibling;
+
+ union
+ {
+ u32 padding_proto;
+ fib_protocol_t proto;
+ };
+
+ u8 data[CLIB_CACHE_LINE_BYTES - 12];
} hicn_dpo_ctx_t;
@@ -76,10 +92,10 @@ extern hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_pool;
* @param dpo_type Type of dpo. It identifies the strategy.
*/
always_inline void
-init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const dpo_id_t * next_hop,
- int nh_len, dpo_type_t dpo_type)
+init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const hicn_face_id_t * next_hop,
+ int nh_len, dpo_type_t dpo_type, dpo_proto_t proto)
{
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
dpo_ctx->entry_count = 0;
dpo_ctx->locks = 0;
@@ -89,9 +105,11 @@ init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const dpo_id_t * next_hop,
dpo_ctx->seq = INIT_SEQ;
dpo_ctx->dpo_type = dpo_type;
+ dpo_ctx->proto = proto;
+
for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && i < nh_len; i++)
{
- clib_memcpy (&dpo_ctx->next_hops[i], &next_hop[i], sizeof (dpo_id_t));
+ dpo_ctx->next_hops[i] = next_hop[i];
dpo_ctx->entry_count++;
}
@@ -151,7 +169,7 @@ void hicn_strategy_dpo_ctx_unlock (dpo_id_t * dpo);
* otherwise HICN_ERROR_DPO_CTX_NOT_FOUND
*/
int
-hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
+hicn_strategy_dpo_ctx_add_nh (hicn_face_id_t nh, hicn_dpo_ctx_t * dpo_ctx,
u8 * pos);
/**
diff --git a/hicn-plugin/src/strategy_dpo_manager.h b/hicn-plugin/src/strategy_dpo_manager.h
index 63fcb930b..e96e050d9 100644
--- a/hicn-plugin/src/strategy_dpo_manager.h
+++ b/hicn-plugin/src/strategy_dpo_manager.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,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
*/
@@ -35,8 +51,8 @@ typedef struct hicn_dpo_vft_s
dpo_type_t (*hicn_dpo_get_type) (void);
/**< Return the type of the hICN dpo */
void (*hicn_dpo_module_init) (void); /**< Initialize the hICN dpo */
- void (*hicn_dpo_create) (dpo_proto_t proto, const dpo_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */
- int (*hicn_dpo_add_update_nh) (const dpo_id_t * nh, index_t dpo_idx); /**< Add a next hop to the hICN dpo context */
+ void (*hicn_dpo_create) (fib_protocol_t proto, const hicn_face_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */
+ int (*hicn_dpo_add_update_nh) (hicn_face_id_t nh, index_t dpo_idx); /**< Add a next hop to the hICN dpo context */
int (*hicn_dpo_del_nh) (hicn_face_id_t face_id, index_t dpo_idx);
u8 *(*hicn_dpo_format) (u8 * s, int, ...);
/**< Format an hICN 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[] = {
- "hicn-iface-ip6-input", // this is the name you give your node in VLIB_REGISTER_NODE
- NULL,
-};
-
-const static char *const hicn_ip4_nodes[] = {
- "hicn-iface-ip4-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 27d1e2a03..0659a871a 100644
--- a/hicn-plugin/src/strategy_node.c
+++ b/hicn-plugin/src/strategy_node.c
@@ -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:
@@ -64,7 +64,7 @@ hicn_strategy_format_trace (u8 * s, va_list * args)
always_inline int
hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0,
u32 * next, f64 tnow, u8 * nameptr,
- u16 namelen, dpo_id_t * outface, int nh_idx,
+ u16 namelen, hicn_face_id_t outface, int nh_idx,
index_t dpo_ctx_id0, const hicn_strategy_vft_t * strategy,
dpo_type_t dpo_type, u8 isv6,
vl_api_hicn_api_node_stats_get_reply_t * stats)
@@ -123,15 +123,14 @@ hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0,
hash_entry);
/* Add face */
- hicn_face_db_add_face_dpo (&hicnb0->face_dpo_id, &(pitp->u.pit.faces));
+ hicn_face_db_add_face (hicnb0->face_id, &(pitp->u.pit.faces));
- /* Remove lock on the dpo stored in the vlib_buffer */
- //dpo_unlock (&hicnb0->face_dpo_id);
+ *next = isv6 ? HICN_STRATEGY_NEXT_INTEREST_FACE6 :
+ HICN_STRATEGY_NEXT_INTEREST_FACE4;
- *next = outface->dpoi_next_node;
-
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface->dpoi_index;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface;
stats->pkts_interest_count++;
+ pitp->u.pit.pe_txnh = nh_idx;
}
else
{
@@ -197,7 +196,7 @@ hicn_strategy_fn (vlib_main_t * vm,
hicn_header_t *hicn0;
vlib_buffer_t *b0;
u32 bi0;
- dpo_id_t *outface = NULL;
+ hicn_face_id_t outface;
int nh_idx;
u32 next0 = next_index;
int ret;
@@ -310,6 +309,8 @@ VLIB_REGISTER_NODE (hicn_strategy_node) =
{
[HICN_STRATEGY_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit",
[HICN_STRATEGY_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs",
+ [HICN_STRATEGY_NEXT_INTEREST_FACE4] = "hicn4-face-output",
+ [HICN_STRATEGY_NEXT_INTEREST_FACE6] = "hicn6-face-output",
[HICN_STRATEGY_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/faces/ip/iface_ip_node.h b/hicn-plugin/src/udp_tunnels/udp_decap.h
index 36923f069..9ddb8a73b 100644
--- a/hicn-plugin/src/faces/ip/iface_ip_node.h
+++ b/hicn-plugin/src/udp_tunnels/udp_decap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 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:
@@ -13,23 +13,20 @@
* limitations under the License.
*/
-#ifndef __HICN_IFACE_IP_NODE_H__
-#define __HICN_IFACE_IP_NODE_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
+#ifndef __UDP_DECAP_H__
+#define __UDP_DECAP_H__
/**
- * @brief Initialize the ip iface module
+ * @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.
*/
-void hicn_iface_ip_init (vlib_main_t * vm);
-#endif // __HICN_IFACE_IP_NODE_H__
+extern vlib_node_registration_t udp_decap_node;
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
+#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
new file mode 100644
index 000000000..5603f20f9
--- /dev/null
+++ b/hicn-plugin/src/udp_tunnels/udp_decap_node.c
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 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.
+ */
+#include <vnet/fib/fib_table.h>
+
+#include "udp_tunnel.h"
+#include "../mgmt.h"
+#include "../hicn.h"
+#include "../strategy_dpo_ctx.h"
+
+vlib_node_registration_t udp_decap_node;
+
+static char *udp_decap_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnfwd_error
+#undef _
+};
+
+/* Trace context struct */
+typedef enum
+{
+ UDP4_DECAP_NEXT_LOOKUP_IP4,
+ UDP4_DECAP_NEXT_LOOKUP_IP6,
+ UDP4_DECAP_N_NEXT,
+} udp4_decap_next_t;
+
+typedef enum
+{
+ UDP6_DECAP_NEXT_LOOKUP_IP4,
+ UDP6_DECAP_NEXT_LOOKUP_IP6,
+ UDP6_DECAP_N_NEXT,
+} udp6_decap_next_t;
+
+typedef struct udp4_decap_trace_t_
+{
+ ip4_header_t ip;
+ udp_header_t udp;
+} udp4_decap_trace_t;
+
+typedef struct udp6_decap_trace_t_
+{
+ ip6_header_t ip;
+ udp_header_t udp;
+} udp6_decap_trace_t;
+
+typedef struct udp_decap_trace_t_
+{
+ union
+ {
+ udp4_decap_trace_t udp4;
+ udp6_decap_trace_t udp6;
+ };
+
+ u8 isv6;
+ u8 ishicn;
+} udp_decap_trace_t;
+
+
+static u8 *
+format_udp_decap_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 *);
+ udp_decap_trace_t *t;
+
+ t = va_arg (*args, udp_decap_trace_t *);
+
+ if (t->isv6)
+ {
+ s = format (s, "%U\n %U \n %s",
+ format_ip4_header, &t->udp6.ip, sizeof (t->udp6.ip),
+ format_udp_header, &t->udp6.udp, sizeof (t->udp6.udp),
+ t->ishicn ? "hICN udp tunnel" : "");
+ }
+ else
+ {
+ s = format (s, "%U\n %U \n %s",
+ format_ip4_header, &t->udp4.ip, sizeof (t->udp4.ip),
+ format_udp_header, &t->udp4.udp, sizeof (t->udp4.udp),
+ t->ishicn ? "hICN udp tunnel" : "");
+ }
+ return (s);
+}
+
+static_always_inline void
+udp_decap_trace_buffer (vlib_main_t * vm, vlib_node_runtime_t * node,
+ u8 isv6, vlib_buffer_t * b)
+{
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ udp_decap_trace_t *t =
+ vlib_add_trace (vm, node, b, sizeof (*t));
+ t->isv6 = isv6;
+ hicn_buffer_t *hb = hicn_get_buffer(b);
+
+ if (isv6)
+ {
+ clib_memcpy(&(t->udp6.udp), vlib_buffer_get_current(b) + sizeof(ip6_header_t), sizeof(udp_header_t));
+ clib_memcpy(&(t->udp6.ip), vlib_buffer_get_current(b), sizeof(ip6_header_t));
+ t->ishicn = hb->flags & hb->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL;
+ }
+ else
+ {
+ clib_memcpy(&(t->udp4.udp), vlib_buffer_get_current(b) + sizeof(ip4_header_t), sizeof(udp_header_t));
+ clib_memcpy(&(t->udp4.ip), vlib_buffer_get_current(b), sizeof(ip4_header_t));
+ t->ishicn = hb->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL;
+ }
+ }
+}
+
+static uword
+udp4_decap_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ u32 n_left_from, *from, *to_next, next_index;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ next_index = node->cached_next_index;
+
+ while (n_left_from > 0)
+ {
+ u32 n_left_to_next;
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ /* Dual loop, X2 */
+ while (n_left_from >= 8 && n_left_to_next >= 4)
+ {
+ vlib_buffer_t *b0, *b1, *b2, *b3;
+ u32 bi0, bi1, bi2, bi3;
+ u32 next0, next1, next2, next3;
+
+ {
+ vlib_buffer_t *b4, *b5, *b6, *b7;
+ b4 = vlib_get_buffer (vm, from[4]);
+ b5 = vlib_get_buffer (vm, from[5]);
+ b6 = vlib_get_buffer (vm, from[6]);
+ b7 = vlib_get_buffer (vm, from[7]);
+ CLIB_PREFETCH (b4, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b5, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b6, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b7, CLIB_CACHE_LINE_BYTES, STORE);
+ }
+
+ bi0 = from[0];
+ bi1 = from[1];
+ bi2 = from[2];
+ bi3 = from[3];
+
+ from += 4;
+ n_left_from -= 4;
+ to_next[0] = bi0;
+ to_next[1] = bi1;
+ to_next[2] = bi2;
+ to_next[3] = bi3;
+
+ to_next += 4;
+ n_left_to_next -= 4;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+ b2 = vlib_get_buffer (vm, bi2);
+ b3 = vlib_get_buffer (vm, bi3);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 *ptr1 = vlib_buffer_get_current (b1);
+ u8 *ptr2 = vlib_buffer_get_current (b2);
+ u8 *ptr3 = vlib_buffer_get_current (b3);
+ u8 v0 = *ptr0 & 0xf0;
+ u8 v1 = *ptr1 & 0xf0;
+ u8 v2 = *ptr2 & 0xf0;
+ u8 v3 = *ptr3 & 0xf0;
+
+ u8 advance = sizeof(ip4_header_t) + sizeof(udp_header_t);
+
+ vlib_buffer_advance(b0, -advance);
+ vlib_buffer_advance(b1, -advance);
+ vlib_buffer_advance(b2, -advance);
+ vlib_buffer_advance(b3, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 *outer_ptr1 = vlib_buffer_get_current (b1);
+ u8 *outer_ptr2 = vlib_buffer_get_current (b2);
+ u8 *outer_ptr3 = vlib_buffer_get_current (b3);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+ u8 outer_v1 = *outer_ptr1 & 0xf0;
+ u8 outer_v2 = *outer_ptr2 & 0xf0;
+ u8 outer_v3 = *outer_ptr3 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t src1 = {0};
+ ip46_address_t src2 = {0};
+ ip46_address_t src3 = {0};
+
+ ip46_address_t dst0 = {0};
+ ip46_address_t dst1 = {0};
+ ip46_address_t dst2 = {0};
+ ip46_address_t dst3 = {0};
+
+ udp_header_t * udp0 = NULL;
+ udp_header_t * udp1 = NULL;
+ udp_header_t * udp2 = NULL;
+ udp_header_t * udp3 = NULL;
+
+ ip46_address_set_ip4(&src0, &((ip4_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip4(&dst0, &((ip4_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip4_header_t));
+ next0 = v0 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip4(&src1, &((ip4_header_t *)outer_ptr1)->src_address);
+ ip46_address_set_ip4(&dst1, &((ip4_header_t *)outer_ptr1)->dst_address);
+ udp1 = (udp_header_t *)(outer_ptr1 + sizeof(ip4_header_t));
+ next1 = v1 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip4(&src2, &((ip4_header_t *)outer_ptr2)->src_address);
+ ip46_address_set_ip4(&dst2, &((ip4_header_t *)outer_ptr2)->dst_address);
+ udp2 = (udp_header_t *)(outer_ptr2 + sizeof(ip4_header_t));
+ next2 = v2 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip4(&src3, &((ip4_header_t *)outer_ptr3)->src_address);
+ ip46_address_set_ip4(&dst3, &((ip4_header_t *)outer_ptr3)->dst_address);
+ udp3 = (udp_header_t *)(outer_ptr3 + sizeof(ip4_header_t));
+ next3 = v3 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3;
+ hicnb0 = hicn_get_buffer(b0);
+ hicnb1 = hicn_get_buffer(b1);
+ hicnb2 = hicn_get_buffer(b2);
+ hicnb3 = hicn_get_buffer(b3);
+
+
+ /* Udp encap-decap tunnels have dst and src addresses and port swapped */
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst1, &src1, udp1->dst_port, udp1->src_port);
+ vnet_buffer (b2)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst2, &src2, udp2->dst_port, udp2->src_port);
+ vnet_buffer (b3)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst3, &src3, udp3->dst_port, udp3->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b1)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb1->flags |= (outer_v1 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b2)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb2->flags |= (outer_v2 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b3)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb3->flags |= (outer_v3 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 1, b0);
+ udp_decap_trace_buffer (vm, node, 1, b1);
+ udp_decap_trace_buffer (vm, node, 1, b2);
+ udp_decap_trace_buffer (vm, node, 1, b3);
+
+ vlib_buffer_advance(b0, advance);
+ vlib_buffer_advance(b1, advance);
+ vlib_buffer_advance(b2, advance);
+ vlib_buffer_advance(b3, advance);
+
+ vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, bi2, bi3,
+ next0, next1, next2, next3);
+ }
+
+ /* Dual loop, X1 */
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ vlib_buffer_t *b0;
+ u32 bi0;
+ /* udp_encap_t *udp_tunnel0 = NULL; */
+ u32 next0;
+
+ if (n_left_from > 1)
+ {
+ vlib_buffer_t *b1;
+ b1 = vlib_get_buffer (vm, from[1]);
+ CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE);
+ }
+
+ bi0 = from[0];
+ from += 1;
+ n_left_from -= 1;
+ to_next[0] = bi0;
+ to_next += 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 v0 = *ptr0 & 0xf0;
+
+ u8 advance = sizeof(ip4_header_t) + sizeof(udp_header_t);;
+
+ vlib_buffer_advance(b0, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t dst0 = {0};
+ udp_header_t * udp0 = NULL;
+
+ ip46_address_set_ip4(&src0, &((ip4_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip4(&dst0, &((ip4_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip4_header_t));
+ next0 = v0 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4: UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0 = hicn_get_buffer(b0);
+
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 1, b0);
+
+ vlib_buffer_advance(b0, advance);
+
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
+
+ }
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ return (frame->n_vectors);
+}
+
+
+/*
+ * Node registration for the interest forwarder node
+ */
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE(udp4_decap_node) =
+{
+ .function = udp4_decap_node_fn,
+ .name = "udp4-decap",
+ .vector_size = sizeof(u32),
+ .format_trace = format_udp_decap_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(udp_decap_error_strings),
+ .error_strings = udp_decap_error_strings,
+ .n_next_nodes = UDP4_DECAP_N_NEXT,
+ /* edit / add dispositions here */
+ .next_nodes =
+ {
+ [UDP4_DECAP_NEXT_LOOKUP_IP4] = "ip4-lookup",
+ [UDP4_DECAP_NEXT_LOOKUP_IP6] = "ip6-lookup"
+ },
+};
+/* *INDENT-ON* */
+
+static uword
+udp6_decap_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ u32 n_left_from, *from, *to_next, next_index;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ next_index = node->cached_next_index;
+
+ while (n_left_from > 0)
+ {
+ u32 n_left_to_next;
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ /* Dual loop, X2 */
+ while (n_left_from >= 8 && n_left_to_next >= 4)
+ {
+ vlib_buffer_t *b0, *b1, *b2, *b3;
+ u32 bi0, bi1, bi2, bi3;
+ u32 next0, next1, next2, next3;
+
+ {
+ vlib_buffer_t *b4, *b5, *b6, *b7;
+ b4 = vlib_get_buffer (vm, from[4]);
+ b5 = vlib_get_buffer (vm, from[5]);
+ b6 = vlib_get_buffer (vm, from[6]);
+ b7 = vlib_get_buffer (vm, from[7]);
+ CLIB_PREFETCH (b4, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b5, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b6, CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (b7, CLIB_CACHE_LINE_BYTES, STORE);
+ }
+
+ bi0 = from[0];
+ bi1 = from[1];
+ bi2 = from[2];
+ bi3 = from[3];
+
+ from += 4;
+ n_left_from -= 4;
+ to_next[0] = bi0;
+ to_next[1] = bi1;
+ to_next[2] = bi2;
+ to_next[3] = bi3;
+
+ to_next += 4;
+ n_left_to_next -= 4;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+ b2 = vlib_get_buffer (vm, bi2);
+ b3 = vlib_get_buffer (vm, bi3);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 *ptr1 = vlib_buffer_get_current (b1);
+ u8 *ptr2 = vlib_buffer_get_current (b2);
+ u8 *ptr3 = vlib_buffer_get_current (b3);
+ u8 v0 = *ptr0 & 0xf0;
+ u8 v1 = *ptr1 & 0xf0;
+ u8 v2 = *ptr2 & 0xf0;
+ u8 v3 = *ptr3 & 0xf0;
+
+ u8 advance = sizeof(ip6_header_t) + sizeof(udp_header_t);
+
+ vlib_buffer_advance(b0, -advance);
+ vlib_buffer_advance(b1, -advance);
+ vlib_buffer_advance(b2, -advance);
+ vlib_buffer_advance(b3, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 *outer_ptr1 = vlib_buffer_get_current (b1);
+ u8 *outer_ptr2 = vlib_buffer_get_current (b2);
+ u8 *outer_ptr3 = vlib_buffer_get_current (b3);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+ u8 outer_v1 = *outer_ptr1 & 0xf0;
+ u8 outer_v2 = *outer_ptr2 & 0xf0;
+ u8 outer_v3 = *outer_ptr3 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t src1 = {0};
+ ip46_address_t src2 = {0};
+ ip46_address_t src3 = {0};
+
+ ip46_address_t dst0 = {0};
+ ip46_address_t dst1 = {0};
+ ip46_address_t dst2 = {0};
+ ip46_address_t dst3 = {0};
+
+ udp_header_t * udp0 = NULL;
+ udp_header_t * udp1 = NULL;
+ udp_header_t * udp2 = NULL;
+ udp_header_t * udp3 = NULL;
+
+ ip46_address_set_ip6(&src0, &((ip6_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip6(&dst0, &((ip6_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip6_header_t));
+ next0 = v0 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip6(&src1, &((ip6_header_t *)outer_ptr1)->src_address);
+ ip46_address_set_ip6(&dst1, &((ip6_header_t *)outer_ptr1)->dst_address);
+ udp1 = (udp_header_t *)(outer_ptr1 + sizeof(ip6_header_t));
+ next1 = v1 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip6(&src2, &((ip6_header_t *)outer_ptr2)->src_address);
+ ip46_address_set_ip6(&dst2, &((ip6_header_t *)outer_ptr2)->dst_address);
+ udp2 = (udp_header_t *)(outer_ptr2 + sizeof(ip6_header_t));
+ next2 = v2 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip6(&src3, &((ip6_header_t *)outer_ptr3)->src_address);
+ ip46_address_set_ip6(&dst3, &((ip6_header_t *)outer_ptr3)->dst_address);
+ udp3 = (udp_header_t *)(outer_ptr3 + sizeof(ip6_header_t));
+ next3 = v3 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3;
+ hicnb0 = hicn_get_buffer(b0);
+ hicnb1 = hicn_get_buffer(b1);
+ hicnb2 = hicn_get_buffer(b2);
+ hicnb3 = hicn_get_buffer(b3);
+
+
+ /* Udp encap-decap tunnels have dst and src addresses and port swapped */
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst1, &src1, udp1->dst_port, udp1->src_port);
+ vnet_buffer (b2)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst2, &src2, udp2->dst_port, udp2->src_port);
+ vnet_buffer (b3)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst3, &src3, udp3->dst_port, udp3->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b1)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb1->flags |= (outer_v1 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b2)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb2->flags |= (outer_v2 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b3)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb3->flags |= (outer_v3 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 0, b0);
+ udp_decap_trace_buffer (vm, node, 0, b1);
+ udp_decap_trace_buffer (vm, node, 0, b2);
+ udp_decap_trace_buffer (vm, node, 0, b3);
+
+ vlib_buffer_advance(b0, advance);
+ vlib_buffer_advance(b1, advance);
+ vlib_buffer_advance(b2, advance);
+ vlib_buffer_advance(b3, advance);
+
+ vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, bi2, bi3,
+ next0, next1, next2, next3);
+ }
+
+ /* Dual loop, X1 */
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ vlib_buffer_t *b0;
+ u32 bi0;
+ /* udp_encap_t *udp_tunnel0 = NULL; */
+ u32 next0;
+
+ if (n_left_from > 1)
+ {
+ vlib_buffer_t *b1;
+ b1 = vlib_get_buffer (vm, from[1]);
+ CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE);
+ }
+
+ bi0 = from[0];
+ from += 1;
+ n_left_from -= 1;
+ to_next[0] = bi0;
+ to_next += 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 v0 = *ptr0 & 0xf0;
+
+ u8 advance = sizeof(ip6_header_t) + sizeof(udp_header_t);
+
+ vlib_buffer_advance(b0, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t dst0 = {0};
+ udp_header_t * udp0 = NULL;
+
+ ip46_address_set_ip6(&src0, &((ip6_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip6(&dst0, &((ip6_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip6_header_t));
+ next0 = v0 == 0x40? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0 = hicn_get_buffer(b0);
+
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 0, b0);
+
+ vlib_buffer_advance(b0, advance);
+
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
+
+ }
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ return (frame->n_vectors);
+}
+
+
+/*
+ * Node registration for the interest forwarder node
+ */
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE(udp6_decap_node) =
+{
+ .function = udp6_decap_node_fn,
+ .name = "udp6-decap",
+ .vector_size = sizeof(u32),
+ .format_trace = format_udp_decap_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(udp_decap_error_strings),
+ .error_strings = udp_decap_error_strings,
+ .n_next_nodes = UDP6_DECAP_N_NEXT,
+ /* edit / add dispositions here */
+ .next_nodes =
+ {
+ [UDP6_DECAP_NEXT_LOOKUP_IP4] = "ip4-lookup",
+ [UDP6_DECAP_NEXT_LOOKUP_IP6] = "ip6-lookup"
+ },
+};
+/* *INDENT-ON* */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.c b/hicn-plugin/src/udp_tunnels/udp_tunnel.c
new file mode 100644
index 000000000..872e4cd82
--- /dev/null
+++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 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.
+ */
+#include <vlib/vlib.h>
+#include <vnet/vnet.h>
+#include <vppinfra/bihash_40_8.h>
+#include <vnet/fib/fib_table.h>
+
+#include "../error.h"
+#include "../strategy_dpo_ctx.h"
+#include "udp_tunnel.h"
+
+clib_bihash_40_8_t udp_tunnels_hashtb;
+dpo_type_t dpo_type_udp_ip4;
+dpo_type_t dpo_type_udp_ip6;
+
+u32 udp_tunnel_add (fib_protocol_t proto,
+ index_t fib_index,
+ const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port,
+ udp_encap_fixup_flags_t flags)
+{
+ vlib_main_t *vm = vlib_get_main();
+ clib_bihash_kv_40_8_t kv;
+ clib_memcpy(&kv.key[0], src_ip, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], dst_ip, sizeof(ip46_address_t));
+ kv.key[4] = (clib_host_to_net_u16(src_port) << 16) + clib_host_to_net_u16(dst_port);
+
+ clib_bihash_kv_40_8_t value;
+ int rv = clib_bihash_search_40_8 (&udp_tunnels_hashtb, &kv, &value);
+
+ if (rv != 0)
+ {
+ u32 uei = udp_encap_add_and_lock(proto, fib_index, src_ip, dst_ip, src_port, dst_port, flags);
+ kv.value = uei;
+ clib_bihash_add_del_40_8(&udp_tunnels_hashtb, &kv, 1);
+ value.value = kv.value;
+ if (proto == FIB_PROTOCOL_IP4)
+ {
+ udp_register_dst_port(vm, src_port, udp4_decap_node.index, 1);
+ }
+ else
+ {
+ udp_register_dst_port(vm, src_port, udp6_decap_node.index, 0);
+ }
+ }
+
+ return value.value;
+}
+
+void udp_tunnel_add_existing (index_t uei, dpo_proto_t proto)
+{
+ vlib_main_t *vm = vlib_get_main();
+ udp_encap_t * udp_encap = udp_encap_get(uei);
+ clib_bihash_kv_40_8_t kv;
+
+ ip46_address_t src = {0};
+ ip46_address_t dst = {0};
+ u16 src_port = 0, dst_port = 0;
+
+ switch (proto)
+ {
+ case DPO_PROTO_IP4:
+ ip46_address_set_ip4(&src, &(udp_encap->ue_hdrs.ip4.ue_ip4.src_address));
+ ip46_address_set_ip4(&dst, &(udp_encap->ue_hdrs.ip4.ue_ip4.dst_address));
+ src_port = udp_encap->ue_hdrs.ip4.ue_udp.src_port;
+ dst_port = udp_encap->ue_hdrs.ip4.ue_udp.dst_port;
+ break;
+ case DPO_PROTO_IP6:
+ ip46_address_set_ip6(&src, &(udp_encap->ue_hdrs.ip6.ue_ip6.src_address));
+ ip46_address_set_ip6(&dst, &(udp_encap->ue_hdrs.ip6.ue_ip6.dst_address));
+ src_port = udp_encap->ue_hdrs.ip6.ue_udp.src_port;
+ dst_port = udp_encap->ue_hdrs.ip6.ue_udp.dst_port;
+ break;
+ default:
+ break;
+ }
+
+ clib_memcpy(&kv.key[0], &src, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], &dst, sizeof(ip46_address_t));
+ kv.key[4] = (src_port << 16) + dst_port ;
+ kv.value = uei;
+
+ clib_bihash_add_del_40_8(&udp_tunnels_hashtb, &kv, 1);
+
+ if (proto == DPO_PROTO_IP4)
+ {
+ udp_register_dst_port(vm, clib_net_to_host_u16(src_port), udp4_decap_node.index, 1);
+ }
+ else
+ {
+ udp_register_dst_port(vm, clib_net_to_host_u16(src_port), udp6_decap_node.index, 0);
+ }
+}
+
+int udp_tunnel_del (fib_protocol_t proto,
+ index_t fib_index,
+ const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port,
+ udp_encap_fixup_flags_t flags)
+{
+ clib_bihash_kv_40_8_t kv;
+ clib_memcpy(&kv.key[0], src_ip, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], dst_ip, sizeof(ip46_address_t));
+ kv.key[4] = (clib_host_to_net_u16(src_port) << 16) + clib_host_to_net_u16(dst_port);
+
+ clib_bihash_kv_40_8_t value;
+ int ret = clib_bihash_search_40_8 (&udp_tunnels_hashtb, &kv, &value);
+
+ if (ret == 0)
+ {
+ udp_encap_unlock((u32)value.value);
+ clib_bihash_add_del_40_8(&udp_tunnels_hashtb, &kv, 0);
+ ret = HICN_ERROR_NONE;
+ }
+ else
+ {
+ ret = HICN_ERROR_UDP_TUNNEL_NOT_FOUND;
+ }
+
+ return ret;
+}
+
+u32 udp_tunnel_get(const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port)
+{
+ clib_bihash_kv_40_8_t kv;
+ clib_memcpy(&kv.key[0], src_ip, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], dst_ip, sizeof(ip46_address_t));
+ kv.key[4] = (src_port << 16) + dst_port;
+
+ clib_bihash_kv_40_8_t value;
+ int ret = clib_bihash_search_40_8 (&udp_tunnels_hashtb, &kv, &value);
+
+ return ret == 0 ? (u32)value.value : UDP_TUNNEL_INVALID;
+}
+
+
+void udp_tunnel_init()
+{
+ clib_bihash_init_40_8(&udp_tunnels_hashtb, "udp encap table",
+ 2048, 256 << 20);
+
+ /*
+ * Udp encap does not expose the dpo type when it registers.
+ * In the following we understand what is the dpo type for a udp_encap dpo.
+ */
+ ip46_address_t src = {0};
+ ip46_address_t dst = {0};
+
+ src.ip6.as_u8[15] = 1;
+ dst.ip6.as_u8[15] = 2;
+
+ u32 fib_index = fib_table_find (FIB_PROTOCOL_IP6, HICN_FIB_TABLE);
+ u32 uei = udp_encap_add_and_lock(FIB_PROTOCOL_IP6, fib_index, &src, &dst, 4444, 4444, UDP_ENCAP_FIXUP_NONE);
+
+ dpo_id_t temp = DPO_INVALID;
+ udp_encap_contribute_forwarding(uei, DPO_PROTO_IP6, &temp);
+ dpo_type_udp_ip6 = temp.dpoi_type;
+ udp_encap_unlock(uei);
+
+ dpo_id_t temp2 = DPO_INVALID;
+ fib_index = fib_table_find (FIB_PROTOCOL_IP4, HICN_FIB_TABLE);
+ uei = udp_encap_add_and_lock(FIB_PROTOCOL_IP4, fib_index, &src, &dst, 4444, 4444, UDP_ENCAP_FIXUP_NONE);
+ udp_encap_contribute_forwarding(uei, DPO_PROTO_IP4, &temp2);
+ dpo_type_udp_ip4 = temp2.dpoi_type;
+ udp_encap_unlock(uei);
+}
+
+static clib_error_t *
+udp_tunnel_command_fn (vlib_main_t * vm,
+ unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = NULL;
+ ip46_address_t src_ip = {0}, dst_ip = {0};
+ u32 table_id, src_port, dst_port;
+ fib_protocol_t fproto;
+ u8 is_del;
+ index_t uei;
+
+ is_del = 0;
+ fproto = FIB_PROTOCOL_MAX;
+ uei = ~0;
+ table_id = HICN_FIB_TABLE;
+
+ /* Get a line of input. */
+ if (unformat_user (main_input, unformat_line_input, line_input))
+ {
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "index %d", &uei))
+ ;
+ else if (unformat (line_input, "add"))
+ is_del = 0;
+ else if (unformat (line_input, "del"))
+ is_del = 1;
+ else if (unformat (line_input, "%U %U",
+ unformat_ip4_address,
+ &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
+ fproto = FIB_PROTOCOL_IP4;
+ else if (unformat (line_input, "%U %U",
+ unformat_ip6_address,
+ &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
+ fproto = FIB_PROTOCOL_IP6;
+ else if (unformat (line_input, "%d %d", &src_port, &dst_port))
+ ;
+ else if (unformat (line_input, "table-id %d", &table_id))
+ ;
+ else
+ {
+ error = unformat_parse_error (line_input);
+ goto done;
+ }
+ }
+ }
+
+ index_t fib_index = fib_table_find (fproto, table_id);
+ if (~0 == fib_index)
+ {
+ error = clib_error_return (0, "Nonexistent table id %d", table_id);
+ goto done;
+ }
+
+ if (!is_del && fproto != FIB_PROTOCOL_MAX)
+ {
+ uei = udp_tunnel_add(fproto, fib_index, &src_ip, &dst_ip, src_port, dst_port, UDP_ENCAP_FIXUP_NONE);
+
+ vlib_cli_output (vm, "udp-encap: %d\n", uei);
+ }
+ else if (is_del)
+ {
+ int ret = udp_tunnel_del(fproto, fib_index, &src_ip, &dst_ip, src_port, dst_port, UDP_ENCAP_FIXUP_NONE);
+ error = (ret == HICN_ERROR_NONE) ? 0 : clib_error_return (0, "%s\n",
+ get_error_string
+ (ret));
+ }
+ else
+ {
+ error = clib_error_return (0, "specify some IP addresses");
+ }
+
+ done:
+ unformat_free (line_input);
+ return error;
+
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (udp_tunnel_command, static) =
+ {
+ .path = "udp tunnel",
+ .short_help = "udp tunnel [add/del] src_address dst_address src_port dst_port",
+ .function = udp_tunnel_command_fn,
+ };
+/* *INDENT-ON* */
+
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables: eval: (c-set-style "gnu") End:
+ */
diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.h b/hicn-plugin/src/udp_tunnels/udp_tunnel.h
new file mode 100644
index 000000000..2ec92056c
--- /dev/null
+++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 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 __UDP_TUNNEL__
+#define __UDP_TUNNEL__
+
+#include <vlib/vlib.h>
+#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;
+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,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ 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,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ 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)
{