aboutsummaryrefslogtreecommitdiffstats
path: root/hicn-plugin
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2020-04-07 18:27:24 +0200
committerAlberto Compagno <acompagn+fdio@cisco.com>2020-05-04 11:25:34 +0200
commit2fba74798833331fe6312e8a764688a23918c14a (patch)
tree877e24ea293d55a8c31b939bf2abacccdf9f365f /hicn-plugin
parentc61e2e149421b849888bea0239c50607edce35ac (diff)
[HICN-591] Created new command "hicn enable <prefix>" that enable hicn on a given prefix
The changes include: - we use now a different vrf for the hicn routes. The default vrf (fib) contains every route, we sync the route we marked as hicn on the hicn vrf. In the vrf we use a custom dpo to implement the forwarding strategy. Change-Id: I399805eff8a62a5c41bf7b50831986a35bce4f76 Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com>
Diffstat (limited to 'hicn-plugin')
-rw-r--r--hicn-plugin/src/CMakeLists.txt7
-rw-r--r--hicn-plugin/src/cli.c111
-rw-r--r--hicn-plugin/src/data_input_node.c4
-rw-r--r--hicn-plugin/src/error.h3
-rw-r--r--hicn-plugin/src/faces/app/face_prod.c2
-rw-r--r--hicn-plugin/src/faces/face.h11
-rw-r--r--hicn-plugin/src/faces/iface_node.c22
-rw-r--r--hicn-plugin/src/hicn.api34
-rw-r--r--hicn-plugin/src/hicn_api.c263
-rw-r--r--hicn-plugin/src/hicn_api_test.c62
-rw-r--r--hicn-plugin/src/interest_hitcs.h3
-rw-r--r--hicn-plugin/src/interest_hitpit_node.c4
-rw-r--r--hicn-plugin/src/route.c503
-rw-r--r--hicn-plugin/src/route.h8
-rw-r--r--hicn-plugin/src/strategies/dpo_mw.c4
-rw-r--r--hicn-plugin/src/strategies/dpo_mw.h2
-rw-r--r--hicn-plugin/src/strategies/dpo_rr.c4
-rw-r--r--hicn-plugin/src/strategies/dpo_rr.h2
-rw-r--r--hicn-plugin/src/strategy_dpo_ctx.h27
-rw-r--r--hicn-plugin/src/strategy_dpo_manager.h6
20 files changed, 790 insertions, 292 deletions
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt
index 2d8a2c385..f43c3b8aa 100644
--- a/hicn-plugin/src/CMakeLists.txt
+++ b/hicn-plugin/src/CMakeLists.txt
@@ -155,7 +155,8 @@ set(HICN_API_HEADER_FILES
set(HICN_API_GENERATED_FILES
${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}/vpp_plugins/hicn/hicn.api_enum.h
+)
set(HICN_VAPI_GENERATED_FILES
${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.h
@@ -184,6 +185,7 @@ 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)
# These files are missing from vpp binary distribution
execute_process(
@@ -204,6 +206,9 @@ 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;
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"
)
diff --git a/hicn-plugin/src/cli.c b/hicn-plugin/src/cli.c
index 9d9a6d949..b3d03294d 100644
--- a/hicn-plugin/src/cli.c
+++ b/hicn-plugin/src/cli.c
@@ -759,6 +759,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)=
@@ -829,6 +921,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_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/error.h b/hicn-plugin/src/error.h
index 2124e63c5..923b25944 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:
@@ -71,7 +71,6 @@
_(MW_STRATEGY_SET, -178, "Error while setting weight for next hop") \
_(STRATEGY_NOT_FOUND, -179, "Strategy not found")
-
typedef enum
{
#define _(a,b,c) HICN_ERROR_##a = (b),
diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c
index 5aed8c11e..c5b9f93dd 100644
--- a/hicn-plugin/src/faces/app/face_prod.c
+++ b/hicn-plugin/src/faces/app/face_prod.c
@@ -275,6 +275,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
FIB_SOURCE_CLI,
FIB_ENTRY_FLAG_NONE, rpaths);
+ hicn_route_enable(prefix);
hicn_app_state_create (sw_if, prefix);
}
@@ -307,6 +308,7 @@ hicn_face_prod_del (hicn_face_id_t face_id)
if (face->flags & HICN_FACE_FLAGS_APPFACE_PROD)
{
/* Remove the face from the fib */
+ hicn_route_disable(&(face_state_vec[face->sw_if].prefix));
//hicn_route_del_nhop (&(face_state_vec[face->sw_if].prefix),
// face_id);
diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h
index 1c829d2c2..665492a84 100644
--- a/hicn-plugin/src/faces/face.h
+++ b/hicn-plugin/src/faces/face.h
@@ -339,7 +339,7 @@ extern mhash_t hicn_face_vec_hashtb;
* 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_key_s
+typedef struct __attribute__ ((packed)) hicn_face_key_s
{
ip46_address_t addr;
union {
@@ -396,6 +396,15 @@ hicn_face_get (const ip46_address_t * addr, u32 sw_if, mhash_t * hashtb)
return NULL;
}
+/**
+ * @brief Get the dpoi 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_with_dpo (const ip46_address_t * addr, u32 sw_if, const dpo_id_t * dpo, mhash_t * hashtb)
{
diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c
index 5def03417..b952787a4 100644
--- a/hicn-plugin/src/faces/iface_node.c
+++ b/hicn-plugin/src/faces/iface_node.c
@@ -34,28 +34,6 @@ 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,
- hicn4_iface_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn6_iface_output_node.index);
-
- data_fwd_iface_ip4_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn4_iface_output_node.index);
-
- data_fwd_iface_ip6_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn6_iface_output_node.index);
-
- ASSERT (temp_index4 == data_fwd_iface_ip4_vlib_edge);
- ASSERT (temp_index6 == data_fwd_iface_ip6_vlib_edge);
-}
-
static char *hicn4_iface_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api
index d8198d149..0f7231327 100644
--- a/hicn-plugin/src/hicn.api
+++ b/hicn-plugin/src/hicn.api
@@ -16,6 +16,13 @@
option version = "5.1.0";
import "vnet/ip/ip_types.api";
+enum hicn_action_type
+{
+ HICN_DISABLE = 0,
+ HICN_ENABLE,
+};
+
+
typedef hicn_face
{
/* IP local address */
@@ -480,6 +487,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 */
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index 62fa55f47..841f0b604 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -137,114 +137,6 @@ 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_params_get_t_handler
(vl_api_hicn_api_face_params_get_t * mp)
@@ -265,93 +157,6 @@ 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_details (hicn_face_t * face, vl_api_hicn_face_t * mp)
{
@@ -371,50 +176,6 @@ send_face_details (hicn_face_t * face, vl_api_hicn_face_t * mp)
}
}
-/* 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); */
-/* 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_faces_details (vl_api_registration_t * reg,
hicn_face_t * face, u32 context)
@@ -899,6 +660,30 @@ 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 */ );
+}
+
/************************************************************************************/
diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c
index af0f8af94..6a1657edd 100644
--- a/hicn-plugin/src/hicn_api_test.c
+++ b/hicn-plugin/src/hicn_api_test.c
@@ -224,7 +224,8 @@ hicn_test_main_t hicn_test_main;
_(hicn_api_node_params_set_reply) \
_(hicn_api_route_nhops_add_reply) \
_(hicn_api_route_del_reply) \
-_(hicn_api_route_nhop_del_reply)
+_(hicn_api_route_nhop_del_reply) \
+_(hicn_api_enable_disable_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -261,7 +262,8 @@ _(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_STRATEGY_GET_REPLY, hicn_api_strategy_get_reply) \
+_(HICN_API_ENABLE_DISABLE_REPLY, hicn_api_enable_disable_reply)
static int
api_hicn_api_node_params_set (vat_main_t * vam)
@@ -298,7 +300,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;
@@ -1108,6 +1110,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;
@@ -1305,8 +1359,6 @@ static void
format_ip46_address, IP46_TYPE_ANY, &src_addr4,
format_ip46_address, IP46_TYPE_ANY, &src_addr6);
}
-
-
#include <hicn/hicn.api_test.c>
/*
diff --git a/hicn-plugin/src/interest_hitcs.h b/hicn-plugin/src/interest_hitcs.h
index 4164887d0..b568a9290 100644
--- a/hicn-plugin/src/interest_hitcs.h
+++ b/hicn-plugin/src/interest_hitcs.h
@@ -41,10 +41,9 @@ typedef struct
typedef enum
{
HICN_INTEREST_HITCS_NEXT_STRATEGY,
- HICN_INTEREST_HITCS_NEXT_PUSH,
- HICN_INTEREST_HITCS_NEXT_ERROR_DROP,
HICN_INTEREST_HITCS_NEXT_IFACE4_OUT,
HICN_INTEREST_HITCS_NEXT_IFACE6_OUT,
+ HICN_INTEREST_HITCS_NEXT_ERROR_DROP,
HICN_INTEREST_HITCS_N_NEXT,
} hicn_interest_hitcs_next_t;
diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c
index 25a25248c..9ebf183c5 100644
--- a/hicn-plugin/src/interest_hitpit_node.c
+++ b/hicn-plugin/src/interest_hitpit_node.c
@@ -294,8 +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_STRATEGY] = "hicn4-face-output",
- [HICN_INTEREST_HITPIT_NEXT_STRATEGY] = "hicn6-face-output",
+ [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/route.c b/hicn-plugin/src/route.c
index 263bf8c56..3023bf898 100644
--- a/hicn-plugin/src/route.c
+++ b/hicn-plugin/src/route.c
@@ -15,8 +15,11 @@
#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 <vlib/global_funcs.h>
@@ -31,6 +34,8 @@
fib_source_t hicn_fib_src;
+fib_node_type_t hicn_fib_node_type;
+
int
hicn_route_get_dpo (const fib_prefix_t * prefix,
const dpo_id_t ** hicn_dpo, u32 * fib_index)
@@ -380,11 +385,509 @@ hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id)
}
+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)
+ {
+ 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);
+ }
+
+ 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_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);
+ for (int i = 0; i < fib_entry->entry_count; i++)
+ {
+ 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
+ {
+ vec_del1(vec_faces, idx_nh);
+
+ /* Remove the lock added by hicn_face_add */
+ hicn_face_unlock_with_id (fib_entry->next_hops[i]);
+
+ }
+ }
+
+ hicn_face_id_t *face_id;
+ vec_foreach(face_id, vec_faces)
+ {
+ 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);
+
+ }
+ vec_free(vec_faces);
+}
+
+static void
+enable_disable_data_receiving (fib_protocol_t proto, u32 sw_if, u8 is_enable)
+{
+ 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);
+
+}
+
+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 */
+ /*
+ * ASSUMPTION: we use table 0 which is the default table and it is
+ * already existing and locked
+ */
+ 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)
+ {
+ fib_entry_index = fib_table_lookup (fib_index, prefix);
+
+ 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);
+ }
+
+ /* Check if the prefix is already enabled */
+ u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
+
+ 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)
+ {
+ 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 */
+ /*
+ * This should be taken from the name?!? the index of the
+ * 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);
+
+ 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 */
+ /*
+ * 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ā€¦
+ */
+ 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);
+
+ /* 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
+ {
+ 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_disable (fib_prefix_t *prefix) {
+
+ int ret = HICN_ERROR_NONE;
+
+ /* Check if the prefix is already enabled */
+ u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
+
+ 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)
+ {
+ 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;
+
+ /* 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));
+ }
+
+ done:
+ return ret;
+}
+
+
+static fib_node_t *
+hicn_ctx_node_get (fib_node_index_t index)
+{
+ hicn_dpo_ctx_t * hicn_ctx;
+
+ hicn_ctx = hicn_strategy_dpo_ctx_get(index);
+
+ return (&hicn_ctx->fib_node);
+}
+
+static void
+hicn_fib_last_lock_gone (fib_node_t *node)
+{
+}
+
+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)));
+}
+
+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 *fib_entry = hicn_ctx_from_fib_node (node);
+
+ sync_hicn_fib_entry(fib_entry);
+
+ return (FIB_NODE_BACK_WALK_CONTINUE);
+}
+
+static void
+hicn_fib_show_memory (void)
+{
+}
+
+
+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)
+ {
+ 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))
+ {
+ goto done;
+ }
+
+ enable_disable_data_receiving (strategy_dpo_id->dpoi_proto, sw_if, 1);
+ }
+
+ done:
+ return (FIB_TABLE_WALK_CONTINUE);
+}
+
+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;
+
+ 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)
+ {
+ /*
+ * 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_table_walk(fib_index,
+ FIB_PROTOCOL_IP4,
+ enable_data_on_existing_hicn,
+ &sw_if_index);
+ }
+
+ 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);
+ }
+
+ 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 ()
{
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");
}
/*
diff --git a/hicn-plugin/src/route.h b/hicn-plugin/src/route.h
index 5877f31a8..f601d0b22 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:
@@ -52,6 +52,12 @@ int hicn_route_del_nhop (fib_prefix_t * prefix, u32 face_id);
int
hicn_route_set_strategy (fib_prefix_t * prefix, u32 strategy_id);
+int
+hicn_route_enable (fib_prefix_t *prefix);
+
+int
+hicn_route_disable (fib_prefix_t *prefix);
+
/* Init route internal strustures */
void
hicn_route_init();
diff --git a/hicn-plugin/src/strategies/dpo_mw.c b/hicn-plugin/src/strategies/dpo_mw.c
index 2ec699e06..12c77bce8 100644
--- a/hicn-plugin/src/strategies/dpo_mw.c
+++ b/hicn-plugin/src/strategies/dpo_mw.c
@@ -108,7 +108,7 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap)
}
void
-hicn_strategy_mw_ctx_create (dpo_proto_t proto, const hicn_face_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;
@@ -120,7 +120,7 @@ hicn_strategy_mw_ctx_create (dpo_proto_t proto, const hicn_face_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);
}
diff --git a/hicn-plugin/src/strategies/dpo_mw.h b/hicn-plugin/src/strategies/dpo_mw.h
index 45a3f3384..887c7003a 100644
--- a/hicn-plugin/src/strategies/dpo_mw.h
+++ b/hicn-plugin/src/strategies/dpo_mw.h
@@ -60,7 +60,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 hicn_face_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);
/**
diff --git a/hicn-plugin/src/strategies/dpo_rr.c b/hicn-plugin/src/strategies/dpo_rr.c
index 40620bb51..adb7e1025 100644
--- a/hicn-plugin/src/strategies/dpo_rr.c
+++ b/hicn-plugin/src/strategies/dpo_rr.c
@@ -110,7 +110,7 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
}
void
-hicn_strategy_rr_ctx_create (dpo_proto_t proto, const hicn_face_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;
@@ -122,7 +122,7 @@ hicn_strategy_rr_ctx_create (dpo_proto_t proto, const hicn_face_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;
}
diff --git a/hicn-plugin/src/strategies/dpo_rr.h b/hicn-plugin/src/strategies/dpo_rr.h
index cb6e693e3..e80c0302a 100644
--- a/hicn-plugin/src/strategies/dpo_rr.h
+++ b/hicn-plugin/src/strategies/dpo_rr.h
@@ -62,7 +62,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 hicn_face_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);
/**
diff --git a/hicn-plugin/src/strategy_dpo_ctx.h b/hicn-plugin/src/strategy_dpo_ctx.h
index 2a534c4dc..54a339573 100644
--- a/hicn-plugin/src/strategy_dpo_ctx.h
+++ b/hicn-plugin/src/strategy_dpo_ctx.h
@@ -23,7 +23,7 @@
#include "faces/face.h"
//FIB table for hicn. 0 is the default one used by ip
-#define HICN_FIB_TABLE 0
+#define HICN_FIB_TABLE 10
#define NEXT_HOP_INVALID ~0
@@ -51,17 +51,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 */
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;
@@ -77,7 +90,7 @@ extern hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_pool;
*/
always_inline void
init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const hicn_face_id_t * next_hop,
- int nh_len, dpo_type_t dpo_type)
+ int nh_len, dpo_type_t dpo_type, dpo_proto_t proto)
{
hicn_face_id_t invalid = NEXT_HOP_INVALID;
@@ -89,6 +102,8 @@ init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const hicn_face_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++)
{
dpo_ctx->next_hops[i] = next_hop[i];
diff --git a/hicn-plugin/src/strategy_dpo_manager.h b/hicn-plugin/src/strategy_dpo_manager.h
index 8c274d06d..eaec252b7 100644
--- a/hicn-plugin/src/strategy_dpo_manager.h
+++ b/hicn-plugin/src/strategy_dpo_manager.h
@@ -35,7 +35,7 @@ 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 hicn_face_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */
+ 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, ...);
@@ -49,12 +49,12 @@ 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
+ "hicn6-iface-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
+ "hicn4-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE
NULL,
};