From 0c7f490009e8633e015b5cba48b78cc243254953 Mon Sep 17 00:00:00 2001 From: Alberto Compagno Date: Fri, 17 Apr 2020 18:51:54 +0200 Subject: [HICN-592] Updating the vrf 0 (default fib) when a mapme event occurs Updates on the vrf 0 will be reflected on the hicn vrf thanks to the fib entry tracking. Change-Id: I4afd6256593f27172c4b0a613316fb8428fa8e50 Signed-off-by: Alberto Compagno --- hicn-plugin/src/CMakeLists.txt | 14 +-- hicn-plugin/src/faces/face.c | 190 ++++++++++++++++++++++--------------- hicn-plugin/src/faces/face.h | 7 +- hicn-plugin/src/faces/face_node.c | 12 +-- hicn-plugin/src/faces/iface_node.c | 12 +-- hicn-plugin/src/mapme.h | 108 +++++++++++++-------- hicn-plugin/src/mapme_ack_node.c | 13 ++- hicn-plugin/src/mapme_ctrl.h | 6 +- hicn-plugin/src/mapme_ctrl_node.c | 80 +++++++--------- hicn-plugin/src/mapme_eventmgr.c | 20 ++-- hicn-plugin/src/mapme_eventmgr.h | 1 + hicn-plugin/src/route.c | 50 +++++++++- hicn-plugin/src/route.h | 26 +++++ 13 files changed, 337 insertions(+), 202 deletions(-) diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt index f43c3b8aa..2dcc07ca3 100644 --- a/hicn-plugin/src/CMakeLists.txt +++ b/hicn-plugin/src/CMakeLists.txt @@ -94,9 +94,9 @@ set(HICN_PLUGIN_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rr.c ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rr.c ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_lru.c -# ${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}/mapme_ack_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.c ) set(HICN_PLUGIN_HEADER_FILES @@ -136,10 +136,10 @@ set(HICN_PLUGIN_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rr.h ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_policy.h ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_lru.h - # ${CMAKE_CURRENT_SOURCE_DIR}/mapme.h - # ${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}/mapme.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.h ) set(HICN_API_TEST_SOURCE_FILES diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c index f8ea61819..652a4a8e2 100644 --- a/hicn-plugin/src/faces/face.c +++ b/hicn-plugin/src/faces/face.c @@ -12,13 +12,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include "face.h" #include "../hicn.h" #include "../params.h" #include "../error.h" -/* #include "../mapme.h" */ -/* #include "../mapme_eventmgr.h" */ +#include "../mapme.h" +#include "../mapme_eventmgr.h" dpo_id_t *face_dpo_vec; hicn_face_vft_t *face_vft_vec; @@ -32,6 +33,8 @@ 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 @@ -55,25 +58,6 @@ 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) */ -/* { */ -/* 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; */ -/* } */ - mhash_t hicn_face_vec_hashtb; mhash_t hicn_face_hashtb; @@ -94,19 +78,85 @@ const static char *const hicn_face4_nodes[] = }; -const static char *const *const hicn_ip_nodes[DPO_PROTO_NUM] = +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_ip_vft = +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) +{ + 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 @@ -132,7 +182,13 @@ hicn_face_module_init (vlib_main_t * vm) * So far it seems that we need it only for setting the dpo_type. */ hicn_face_type = - dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes); + 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 * @@ -206,19 +262,6 @@ format_hicn_face_all (u8 * s, int n, ...) 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; */ - -/* } */ - -/* FACE IP CODE */ - int hicn_face_del (hicn_face_id_t face_id) { @@ -285,6 +328,32 @@ hicn_iface_to_face(hicn_face_t *face, const dpo_id_t * 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; + + 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); + } + } + + + //adj_child_add(face->dpo.dpoi_index, hicn_face_fib_node_type, hicn_dpoi_get_index(face)); } /* @@ -295,7 +364,6 @@ 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) { - // dpo_proto_t dpo_proto; hicn_face_flags_t flags = (hicn_face_flags_t) 0; flags |= HICN_FACE_FLAGS_FACE; @@ -335,7 +403,7 @@ hicn_face_add (const dpo_id_t * dpo_nh, ip46_address_t * nat_address, } else { - /* *We found an iface and we convert it to a face */ + /* 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); @@ -357,9 +425,6 @@ hicn_face_add (const dpo_id_t * dpo_nh, ip46_address_t * nat_address, in_faces_temp.vec_id = index; vec_add1 (*vec, *pfaceid); - - // dpo_proto = DPO_PROTO_IP4; - in_faces_temp.face_id = *pfaceid; hicn_face_get_key (nat_address, 0, &temp_dpo, &key); @@ -380,8 +445,6 @@ hicn_face_add (const dpo_id_t * dpo_nh, ip46_address_t * nat_address, hicn_iface_to_face(face, dpo_nh); - // dpo_proto = DPO_PROTO_IP4; - hicn_face_get_key (nat_address, 0, &temp_dpo, &key); mhash_set_mem (&hicn_face_vec_hashtb, &key, (uword *) in_faces, @@ -395,41 +458,20 @@ hicn_face_add (const dpo_id_t * dpo_nh, ip46_address_t * nat_address, } } - /* 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)); */ + 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 = 0, */ - /* .dpoi_proto = dpo_proto, */ - /* .dpoi_next_node = 0, */ - /* .dpoi_index = *pfaceid, */ - /* } */ - /* }; */ - /* /\* *INDENT-ON* *\/ */ + /* *INDENT-OFF* */ + *retx = (retx_t) { + .face_id = *pfaceid, + }; + /* *INDENT-ON* */ return HICN_ERROR_NONE; } -/* void */ -/* hicn_face_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); */ -/* } */ - - /* * fd.io coding-style-patch-verification: ON diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h index 665492a84..54f2eab31 100644 --- a/hicn-plugin/src/faces/face.h +++ b/hicn-plugin/src/faces/face.h @@ -16,6 +16,7 @@ #ifndef __HICN_FACE_H__ #define __HICN_FACE_H__ +#include #include #include #include @@ -74,9 +75,11 @@ typedef struct __attribute__ ((packed)) hicn_face_s /* local interface for the local ip address */ u32 sw_if; - /* To align a face to 8 bytes */ - u32 padding; + fib_node_t fib_node; + fib_node_index_t fib_entry_index; + + u32 fib_sibling; } hicn_face_t; /* Pool of faces */ diff --git a/hicn-plugin/src/faces/face_node.c b/hicn-plugin/src/faces/face_node.c index b146e3a6f..a52967dae 100644 --- a/hicn-plugin/src/faces/face_node.c +++ b/hicn-plugin/src/faces/face_node.c @@ -64,7 +64,7 @@ hicn4_face_input_trace_t; typedef enum { HICN4_FACE_INPUT_NEXT_DATA, - //HICN4_FACE_INPUT_NEXT_MAPME, + HICN4_FACE_INPUT_NEXT_MAPME, HICN4_FACE_INPUT_NEXT_ERROR_DROP, HICN4_FACE_INPUT_N_NEXT, } hicn4_face_input_next_t; @@ -82,13 +82,13 @@ hicn6_face_input_trace_t; typedef enum { HICN6_FACE_INPUT_NEXT_DATA, - //HICN6_FACE_INPUT_NEXT_MAPME, + 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 HICN4_FACE_INPUT_NEXT_ERROR_DROP//HICN4_FACE_INPUT_NEXT_MAPME -#define NEXT_MAPME_IP6 HICN6_FACE_INPUT_NEXT_ERROR_DROP//HICN6_FACE_INPUT_NEXT_MAPME +#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 @@ -374,7 +374,7 @@ VLIB_REGISTER_NODE(hicn4_face_input_node) = .next_nodes = { [HICN4_FACE_INPUT_NEXT_DATA] = "hicn-data-pcslookup", - //[HICN4_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack", + [HICN4_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack", [HICN4_FACE_INPUT_NEXT_ERROR_DROP] = "error-drop", }, }; @@ -454,7 +454,7 @@ VLIB_REGISTER_NODE(hicn6_face_input_node) = .next_nodes = { [HICN6_FACE_INPUT_NEXT_DATA] = "hicn-data-pcslookup", - //[HICN6_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack", + [HICN6_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack", [HICN6_FACE_INPUT_NEXT_ERROR_DROP] = "error-drop", }, }; diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c index b952787a4..fbc573088 100644 --- a/hicn-plugin/src/faces/iface_node.c +++ b/hicn-plugin/src/faces/iface_node.c @@ -58,7 +58,7 @@ typedef struct typedef enum { HICN4_IFACE_INPUT_NEXT_INTEREST, - //HICN4_IFACE_INPUT_NEXT_MAPME, + HICN4_IFACE_INPUT_NEXT_MAPME, HICN4_IFACE_INPUT_NEXT_ERROR_DROP, HICN4_IFACE_INPUT_N_NEXT, } hicn4_iface_input_next_t; @@ -75,13 +75,13 @@ typedef struct typedef enum { HICN6_IFACE_INPUT_NEXT_INTEREST, - //HICN6_IFACE_INPUT_NEXT_MAPME, + 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 HICN4_IFACE_INPUT_NEXT_ERROR_DROP//HICN4_IFACE_INPUT_NEXT_MAPME -#define NEXT_MAPME_IP6 HICN6_IFACE_INPUT_NEXT_ERROR_DROP//HICN6_IFACE_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 HICN4_IFACE_INPUT_NEXT_INTEREST #define NEXT_INTEREST_IP6 HICN6_IFACE_INPUT_NEXT_INTEREST @@ -415,7 +415,7 @@ VLIB_REGISTER_NODE (hicn4_iface_input_node) = .next_nodes = { [HICN4_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup", - //[HICN4_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl", + [HICN4_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl", [HICN4_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop", }, }; @@ -495,7 +495,7 @@ VLIB_REGISTER_NODE (hicn6_iface_input_node) = .next_nodes = { [HICN6_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup", - //[HICN6_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl", + [HICN6_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl", [HICN6_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop", }, }; diff --git a/hicn-plugin/src/mapme.h b/hicn-plugin/src/mapme.h index 7ed0af88b..17bd9a766 100644 --- a/hicn-plugin/src/mapme.h +++ b/hicn-plugin/src/mapme.h @@ -18,13 +18,34 @@ #include #include -//#include #include #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 @@ -46,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) \ @@ -75,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; } @@ -94,7 +129,13 @@ 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 (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; } @@ -104,30 +145,36 @@ hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, hicn_face_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 @@ -136,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_with_id (&tfib->next_hops[pos]); + hicn_face_unlock_with_id (tfib->next_hops[pos]); tfib->next_hops[pos] = invalid; break; } @@ -159,7 +206,7 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id) for (pos = start_pos; pos < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos++) if (tfib->next_hops[pos] == face_id) { - hicn_face_unlock_with_id (&tfib->next_hops[pos]); + hicn_face_unlock_with_id (tfib->next_hops[pos]); tfib->next_hops[pos] = invalid; break; } @@ -171,7 +218,7 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, hicn_face_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, + memmove (tfib->next_hops + start_pos +1 , tfib->next_hops + start_pos, (pos - start_pos) * sizeof (hicn_face_id_t)); return 0; @@ -290,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_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 732a74b30..a69dfe1fc 100644 --- a/hicn-plugin/src/mapme_ctrl.h +++ b/hicn-plugin/src/mapme_ctrl.h @@ -42,8 +42,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,11 +49,11 @@ 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 (hicn_face_id_t face_id) +hicn_mapme_ctrl_get_iface_node (hicn_face_id_t face_id) { hicn_face_t * face = hicn_dpoi_get_from_idx(face_id); - switch (dpo->dpoi_proto) + switch (face->dpo.dpoi_proto) { case DPO_PROTO_IP4: return HICN_MAPME_CTRL_NEXT_IP4_OUTPUT; diff --git a/hicn-plugin/src/mapme_ctrl_node.c b/hicn-plugin/src/mapme_ctrl_node.c index 1708f2b2d..a0be2be1d 100644 --- a/hicn-plugin/src/mapme_ctrl_node.c +++ b/hicn-plugin/src/mapme_ctrl_node.c @@ -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, - hicn_face_id_t in_face) + hicn_face_id_t in_face_id) { seq_t fib_seq; const dpo_id_t *dpo; @@ -153,27 +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 (tfib->next_hops[pos] == in_face) - { - 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, 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); - - /* Convert possible iFate into a face TODO!!!*/ - 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, @@ -183,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) @@ -193,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, @@ -206,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 { @@ -215,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. @@ -224,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. */ @@ -247,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; @@ -275,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_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); @@ -333,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, ¶ms, - &tfib->next_hops[pos]); + tfib->next_hops[pos]); } } else { hicn_mapme_send_message (vm, prefix, ¶ms, - &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 8414861b4..84c57b50f 100644 --- a/hicn-plugin/src/mapme_eventmgr.h +++ b/hicn-plugin/src/mapme_eventmgr.h @@ -24,6 +24,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/route.c b/hicn-plugin/src/route.c index 3023bf898..0cefe6bda 100644 --- a/hicn-plugin/src/route.c +++ b/hicn-plugin/src/route.c @@ -385,6 +385,51 @@ hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id) } +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)); @@ -482,7 +527,8 @@ sync_hicn_fib_entry(hicn_dpo_ctx_t *fib_entry) } 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++) + 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) @@ -495,7 +541,7 @@ sync_hicn_fib_entry(hicn_dpo_ctx_t *fib_entry) /* Remove the lock added by hicn_face_add */ hicn_face_unlock_with_id (fib_entry->next_hops[i]); - + i++; } } diff --git a/hicn-plugin/src/route.h b/hicn-plugin/src/route.h index f601d0b22..678a828b5 100644 --- a/hicn-plugin/src/route.h +++ b/hicn-plugin/src/route.h @@ -21,6 +21,7 @@ #include "hicn.h" #include "faces/face.h" +extern fib_source_t hicn_fib_src; /* * Retrieve the hicn dpo corresponding to a hicn prefix */ @@ -52,12 +53,37 @@ int hicn_route_del_nhop (fib_prefix_t * prefix, u32 face_id); int hicn_route_set_strategy (fib_prefix_t * prefix, u32 strategy_id); +/** + * @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 +ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * pfx, ip46_address_t * nh, u32 sw_if); + +/** + * @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); + int hicn_route_enable (fib_prefix_t *prefix); int hicn_route_disable (fib_prefix_t *prefix); + /* Init route internal strustures */ void hicn_route_init(); -- cgit 1.2.3-korg