From c61e2e149421b849888bea0239c50607edce35ac Mon Sep 17 00:00:00 2001 From: Alberto Compagno Date: Tue, 7 Apr 2020 11:43:39 +0200 Subject: [HICN-590] Removed andjacency type specific face implementation Changes in the new implementation are: - the adjacency index is replaced with a dpo that allows the single face node to dispatch the packet to the right vlib node. - local and remote address in the face are replaced with a single nat address which is used to perform the nat operation when rewriting an interest or a data (in case of tunnels the nat address will be equal to 0) - the list of next hop in the load balance is no longer a list of dpos but a list of face id (this makes the code easier and increases the number of next hop we supports) Signed-off-by: Alberto Compagno Change-Id: I4ac2b4eb09425bfe1b3ca9f82d7d0ff564297b0d --- hicn-plugin/src/faces/face.c | 377 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 332 insertions(+), 45 deletions(-) (limited to 'hicn-plugin/src/faces/face.c') diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c index f2dcdd151..f8ea61819 100644 --- a/hicn-plugin/src/faces/face.c +++ b/hicn-plugin/src/faces/face.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -14,14 +14,11 @@ */ #include "face.h" -#include "ip/face_ip.h" -#include "ip/face_ip_node.h" -#include "ip/iface_ip_node.h" -#include "ip/dpo_ip.h" -#include "udp/face_udp.h" -#include "udp/face_udp_node.h" -#include "udp/iface_udp_node.h" -#include "udp/dpo_udp.h" +#include "../hicn.h" +#include "../params.h" +#include "../error.h" +/* #include "../mapme.h" */ +/* #include "../mapme_eventmgr.h" */ dpo_id_t *face_dpo_vec; hicn_face_vft_t *face_vft_vec; @@ -33,6 +30,8 @@ dpo_type_t first_type = DPO_FIRST; vlib_combined_counter_main_t *counters; +dpo_type_t hicn_face_type; + const char *HICN_FACE_CTRX_STRING[] = { #define _(a,b,c) c, foreach_hicn_face_counter @@ -56,24 +55,58 @@ 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) +/* 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; + +hicn_face_vec_t * hicn_vec_pool; + +const static char *const hicn_face6_nodes[] = + { + "hicn6-face-output", // this is the name you give your node in VLIB_REGISTER_NODE + "hicn6-iface-output", // this is the name you give your node in VLIB_REGISTER_NODE + NULL, +}; + +const static char *const hicn_face4_nodes[] = + { + "hicn4-face-output", // this is the name you give your node in VLIB_REGISTER_NODE + "hicn4-iface-output", // this is the name you give your node in VLIB_REGISTER_NODE + NULL, +}; + + +const static char *const *const hicn_ip_nodes[DPO_PROTO_NUM] = { - 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; -} + [DPO_PROTO_IP4] = hicn_face4_nodes, + [DPO_PROTO_IP6] = hicn_face6_nodes +}; + +const static dpo_vft_t hicn_face_ip_vft = +{ + .dv_lock = hicn_face_lock, + .dv_unlock = hicn_face_unlock, + .dv_format = format_hicn_face, +}; + // Make this more flexible for future types face void @@ -81,15 +114,77 @@ hicn_face_module_init (vlib_main_t * vm) { pool_validate (hicn_dpoi_face_pool); pool_alloc (hicn_dpoi_face_pool, 1024); - hicn_face_ip_init (vm); - hicn_iface_ip_init (vm); - hicn_face_udp_init (vm); - hicn_iface_udp_init (vm); counters = vec_new (vlib_combined_counter_main_t, HICN_PARAM_FACES_MAX * HICN_N_COUNTER); + + mhash_init (&hicn_face_vec_hashtb, + sizeof (hicn_face_input_faces_t) /* value */ , + sizeof (hicn_face_key_t) /* key */ ); + mhash_init (&hicn_face_hashtb, + sizeof (hicn_face_id_t) /* value */ , + sizeof (hicn_face_key_t) /* key */ ); + + pool_alloc(hicn_vec_pool, 100); + + /* + * How much useful is the following registration? + * So far it seems that we need it only for setting the dpo_type. + */ + hicn_face_type = + dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes); +} + +u8 * +format_hicn_face (u8 * s, va_list * args) +{ + index_t index = va_arg (*args, index_t); + u32 indent = va_arg (*args, u32); + hicn_face_t *face; + + face = hicn_dpoi_get_from_idx (index); + + if (face->flags & HICN_FACE_FLAGS_FACE) + { + hicn_face_id_t face_id = hicn_dpoi_get_index (face); + s = format (s, "%U Face %d: ", format_white_space, indent, face_id); + s = format (s, "nat address %U locks %u, path_label %u", + format_ip46_address, &face->nat_addr, IP46_TYPE_ANY, + face->locks, face->pl_id); + + if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD)) + s = format (s, " (producer)"); + else if ((face->flags & HICN_FACE_FLAGS_APPFACE_CONS)) + s = format (s, " (consumer)"); + + if ((face->flags & HICN_FACE_FLAGS_DELETED)) + s = format (s, " (deleted)"); + + s = format (s, "\n%U%U", + format_white_space, indent + 2, + format_dpo_id, &face->dpo, indent + 3); + } + else + { + hicn_face_id_t face_id = hicn_dpoi_get_index (face); + s = format (s, "%U iFace %d: ", format_white_space, indent, face_id); + s = format (s, "nat address %U locks %u, path_label %u", + format_ip46_address, &face->nat_addr, IP46_TYPE_ANY, + face->locks, face->pl_id); + + if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD)) + s = format (s, " (producer)"); + else if ((face->flags & HICN_FACE_FLAGS_APPFACE_CONS)) + s = format (s, " (consumer)"); + + if ((face->flags & HICN_FACE_FLAGS_DELETED)) + s = format (s, " (deleted)"); + } + + return s; } + u8 * format_hicn_face_all (u8 * s, int n, ...) { @@ -104,46 +199,238 @@ format_hicn_face_all (u8 * s, int n, ...) /* *INDENT-OFF* */ pool_foreach ( face, hicn_dpoi_face_pool, { - hicn_face_vft_t * vft = hicn_face_get_vft(face->shared.face_type); - hicn_face_id_t face_id = hicn_dpoi_get_index(face); - s = format(s, "%U\n", vft->format_face, face_id, indent); + s = format(s, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), indent); }); /* *INDENT-ON* */ return s; } -hicn_face_vft_t * -hicn_face_get_vft (hicn_face_type_t face_type) -{ - int idx = face_type - first_type; - if (idx >= 0) - return &face_vft_vec[idx]; - else - return NULL; +/* 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) { + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); + hicn_face_key_t key; + hicn_face_key_t old_key; + hicn_face_key_t old_key2; + + hicn_face_get_key (&(face->nat_addr), face->sw_if, &(face->dpo), + &key); + hicn_face_input_faces_t *in_faces_vec = + hicn_face_get_vec (&(face->nat_addr), + &hicn_face_vec_hashtb); + if (in_faces_vec != NULL) + { + hicn_face_vec_t *vec = + pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id); + u32 index_face = vec_search (*vec, face_id); + vec_del1 (*vec, index_face); + + if (vec_len (*vec) == 0) + { + pool_put_index (hicn_vec_pool, in_faces_vec->vec_id); + mhash_unset (&hicn_face_vec_hashtb, &key, + (uword *) & old_key); + vec_free (*vec); + } + else + { + /* Check if the face we are deleting is the preferred one. */ + /* If so, repleace with another. */ + if (in_faces_vec->face_id == face_id) + { + in_faces_vec->face_id = (*vec)[0]; + } + } + + mhash_unset (&hicn_face_hashtb, &key, + (uword *) & old_key2); + } + int ret = HICN_ERROR_NONE; if (hicn_dpoi_idx_is_valid (face_id)) { hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); - face->shared.locks--; - if (face->shared.locks == 0) + face->locks--; + if (face->locks == 0) pool_put_index (hicn_dpoi_face_pool, face_id); else - face->shared.flags |= HICN_FACE_FLAGS_DELETED; + face->flags |= HICN_FACE_FLAGS_DELETED; } else ret = HICN_ERROR_FACE_NOT_FOUND; + return ret; } +static void +hicn_iface_to_face(hicn_face_t *face, const dpo_id_t * dpo) +{ + dpo_stack(hicn_face_type, dpo->dpoi_proto, &face->dpo, dpo); + + face->flags &= ~HICN_FACE_FLAGS_IFACE; + face->flags |= HICN_FACE_FLAGS_FACE; +} + +/* + * Utility that adds a new face cache entry. For the moment we assume that + * the ip_adjacency has already been set up. + */ +int +hicn_face_add (const dpo_id_t * dpo_nh, ip46_address_t * nat_address, + int sw_if, hicn_face_id_t * pfaceid, u8 is_app_prod) +{ + // dpo_proto_t dpo_proto; + + hicn_face_flags_t flags = (hicn_face_flags_t) 0; + flags |= HICN_FACE_FLAGS_FACE; + + hicn_face_t *face; + + face = + hicn_face_get_with_dpo (nat_address, sw_if, dpo_nh, + &hicn_face_hashtb); + + if (face != NULL) + { + *pfaceid = hicn_dpoi_get_index (face); + return HICN_ERROR_FACE_ALREADY_CREATED; + } + + face = + hicn_face_get (nat_address, sw_if, + &hicn_face_hashtb); + + dpo_id_t temp_dpo = DPO_INVALID; + hicn_face_key_t key; + hicn_face_get_key (nat_address, sw_if, dpo_nh, &key); + + if (face == NULL) + { + + hicn_iface_add (nat_address, sw_if, pfaceid, dpo_nh->dpoi_proto); + face = hicn_dpoi_get_from_idx (*pfaceid); + + mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, + 0); + + hicn_face_get_key (nat_address, sw_if, &temp_dpo, &key); + mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, + 0); + } + else + { + /* *We found an iface and we convert it to a face */ + *pfaceid = hicn_dpoi_get_index (face); + mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, + 0); + } + + hicn_iface_to_face(face, dpo_nh); + + + hicn_face_input_faces_t *in_faces = + hicn_face_get_vec (nat_address, &hicn_face_vec_hashtb); + + if (in_faces == NULL) + { + hicn_face_input_faces_t in_faces_temp; + hicn_face_vec_t *vec; + pool_get (hicn_vec_pool, vec); + *vec = vec_new (hicn_face_vec_t, 0); + u32 index = vec - hicn_vec_pool; + in_faces_temp.vec_id = index; + vec_add1 (*vec, *pfaceid); + + + // dpo_proto = DPO_PROTO_IP4; + + in_faces_temp.face_id = *pfaceid; + + hicn_face_get_key (nat_address, 0, &temp_dpo, &key); + + mhash_set_mem (&hicn_face_vec_hashtb, &key, + (uword *) & in_faces_temp, 0); + } + else + { + hicn_face_vec_t *vec = + pool_elt_at_index (hicn_vec_pool, in_faces->vec_id); + + /* */ + if (vec_search (*vec, *pfaceid) != ~0) + return HICN_ERROR_FACE_ALREADY_CREATED; + + vec_add1 (*vec, *pfaceid); + + hicn_iface_to_face(face, dpo_nh); + + // 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, + 0); + + /* If the face is an application producer face, we set it as the preferred incoming face. */ + /* This is required to handle the CS separation, and the push api in a lightway */ + if (is_app_prod) + { + in_faces->face_id = *pfaceid; + } + } + + /* retx_t *retx = vlib_process_signal_event_data (vlib_get_main (), */ + /* hicn_mapme_eventmgr_process_node.index, */ + /* HICN_MAPME_EVENT_FACE_ADD, 1, */ + /* sizeof (retx_t)); */ + + /* /\* *INDENT-OFF* *\/ */ + /* *retx = (retx_t) */ + /* { */ + /* .prefix = 0, */ + /* .dpo = (dpo_id_t) */ + /* { */ + /* .dpoi_type = 0, */ + /* .dpoi_proto = dpo_proto, */ + /* .dpoi_next_node = 0, */ + /* .dpoi_index = *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 * -- cgit 1.2.3-korg