diff options
author | 2020-04-07 18:27:24 +0200 | |
---|---|---|
committer | 2020-05-04 11:25:34 +0200 | |
commit | 2fba74798833331fe6312e8a764688a23918c14a (patch) | |
tree | 877e24ea293d55a8c31b939bf2abacccdf9f365f /hicn-plugin/src | |
parent | c61e2e149421b849888bea0239c50607edce35ac (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/src')
-rw-r--r-- | hicn-plugin/src/CMakeLists.txt | 7 | ||||
-rw-r--r-- | hicn-plugin/src/cli.c | 111 | ||||
-rw-r--r-- | hicn-plugin/src/data_input_node.c | 4 | ||||
-rw-r--r-- | hicn-plugin/src/error.h | 3 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_prod.c | 2 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face.h | 11 | ||||
-rw-r--r-- | hicn-plugin/src/faces/iface_node.c | 22 | ||||
-rw-r--r-- | hicn-plugin/src/hicn.api | 34 | ||||
-rw-r--r-- | hicn-plugin/src/hicn_api.c | 263 | ||||
-rw-r--r-- | hicn-plugin/src/hicn_api_test.c | 62 | ||||
-rw-r--r-- | hicn-plugin/src/interest_hitcs.h | 3 | ||||
-rw-r--r-- | hicn-plugin/src/interest_hitpit_node.c | 4 | ||||
-rw-r--r-- | hicn-plugin/src/route.c | 503 | ||||
-rw-r--r-- | hicn-plugin/src/route.h | 8 | ||||
-rw-r--r-- | hicn-plugin/src/strategies/dpo_mw.c | 4 | ||||
-rw-r--r-- | hicn-plugin/src/strategies/dpo_mw.h | 2 | ||||
-rw-r--r-- | hicn-plugin/src/strategies/dpo_rr.c | 4 | ||||
-rw-r--r-- | hicn-plugin/src/strategies/dpo_rr.h | 2 | ||||
-rw-r--r-- | hicn-plugin/src/strategy_dpo_ctx.h | 27 | ||||
-rw-r--r-- | hicn-plugin/src/strategy_dpo_manager.h | 6 |
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, }; |