diff options
Diffstat (limited to 'hicn-plugin/src/faces')
-rw-r--r-- | hicn-plugin/src/faces/dpo_face.h | 329 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face.h | 346 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face_node.c | 5 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face_node.h | 17 | ||||
-rw-r--r-- | hicn-plugin/src/faces/iface_node.c | 5 | ||||
-rw-r--r-- | hicn-plugin/src/faces/iface_node.h | 25 |
6 files changed, 353 insertions, 374 deletions
diff --git a/hicn-plugin/src/faces/dpo_face.h b/hicn-plugin/src/faces/dpo_face.h deleted file mode 100644 index 3bb99ecdb..000000000 --- a/hicn-plugin/src/faces/dpo_face.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * 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: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HICN_DPO_H__ -#define __HICN_DPO_H__ - -#include <vnet/vnet.h> -#include <vnet/ip/ip4_packet.h> -#include <vnet/adj/adj_midchain.h> - -#include "face.h" -#include "../error.h" - -/** - * @brief Initialize the internal structures of the dpo ip face module. - */ -//void hicn_dpo_ip_module_init (void); - - -/** - * @brief Retrieve a vector of faces from the ip4 local address and returns its index. - * - * @param vec: Result of the lookup. If no face exists for the local address vec = NULL - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param local_addr: Ip v4 nat address of the face - * @param sw_if: software interface id of the face - * - * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. - */ -always_inline int -hicn_dpo_face_ip4_lock (hicn_face_id_t * face_id, - u32 * in_faces_vec_id, - u8 * hicnb_flags, - const ip4_address_t * nat_addr) -{ - ip46_address_t ip_address = {0}; - ip46_address_set_ip4(&ip_address, nat_addr); - hicn_face_input_faces_t *in_faces_vec = - hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb); - - if (PREDICT_FALSE (in_faces_vec == NULL)) - return HICN_ERROR_FACE_NOT_FOUND; - - *in_faces_vec_id = in_faces_vec->vec_id; - hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id); - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= - (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *face_id = in_faces_vec->face_id; - - return HICN_ERROR_NONE; -} - -/** - * @brief Retrieve a face from the ip6 local address and returns its dpo. This - * method adds a lock on the face state. - * - * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v6 nat address of the face - * @param sw_if: software interface id of the face - * - * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. - */ -always_inline int -hicn_dpo_face_ip6_lock (hicn_face_id_t * face_id, - u32 * in_faces_vec_id, - u8 * hicnb_flags, - const ip6_address_t * nat_addr) -{ - hicn_face_input_faces_t *in_faces_vec = - hicn_face_get_vec ((ip46_address_t *)nat_addr, &hicn_face_vec_hashtb); - - if (PREDICT_FALSE (in_faces_vec == NULL)) - return HICN_ERROR_FACE_NOT_FOUND; - - *in_faces_vec_id = in_faces_vec->vec_id; - hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id); - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= - (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *face_id = in_faces_vec->face_id; - - return HICN_ERROR_NONE; -} - -/** - * @brief Call back to get the adj of the tunnel - */ -static adj_walk_rc_t -hicn4_iface_adj_walk_cb (adj_index_t ai, - void *ctx) -{ - - hicn_face_t *face = (hicn_face_t *)ctx; - - dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai); - adj_nbr_midchain_stack(ai, &face->dpo); - - return (ADJ_WALK_RC_CONTINUE); -} - -/** - * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local - * address and returns its dpo. This method adds a lock on the face state. - * - * @param dpo: Result of the lookup - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v4 remote address of the face - * @param sw_if: software interface id of the face - * @param node_index: vlib edge index to use in the packet processing - */ -always_inline void -hicn_dpo_iface_ip4_add_and_lock (hicn_face_id_t * index, - u8 * hicnb_flags, - const ip4_address_t * nat_addr, - u32 sw_if, u32 adj_index, u32 node_index) -{ - /*All (complete) faces are indexed by remote addess as well */ - - ip46_address_t ip_address = {0}; - ip46_address_set_ip4(&ip_address, nat_addr); - - /* if the face exists, it adds a lock */ - hicn_face_t *face = - hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index); - - if (face == NULL) - { - hicn_face_id_t idx; - hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index); - - face = hicn_dpoi_get_from_idx(idx); - - face->dpo.dpoi_type = DPO_FIRST; - face->dpo.dpoi_proto = DPO_PROTO_IP4; - face->dpo.dpoi_index = adj_index; - face->dpo.dpoi_next_node = node_index; - - /* if (nat_addr->as_u32 == 0) */ - /* { */ - adj_nbr_walk(face->sw_if, - FIB_PROTOCOL_IP4, - hicn4_iface_adj_walk_cb, - face); - /* } */ - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - - *index = idx; - return; - } - else - { - /* unlock the face. We don't take a lock on each interest we receive */ - hicn_face_id_t face_id = hicn_dpoi_get_index(face); - hicn_face_unlock_with_id(face_id); - } - - /* Code replicated on purpose */ - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= - (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *index = hicn_dpoi_get_index (face); -} - -/** - * @brief Call back to get the adj of the tunnel - */ -static adj_walk_rc_t -hicn6_iface_adj_walk_cb (adj_index_t ai, - void *ctx) -{ - - hicn_face_t *face = (hicn_face_t *)ctx; - - ip_adjacency_t *adj = adj_get(ai); - if ((adj->lookup_next_index == IP_LOOKUP_NEXT_MIDCHAIN) || - (adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST_MIDCHAIN)) - { - dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, adj->ia_nh_proto, ai); - adj_nbr_midchain_stack(ai, &face->dpo); - } - - return (ADJ_WALK_RC_CONTINUE); -} - - -/** - * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local - * address and returns its dpo. This method adds a lock on the face state. - * - * @param dpo: Result of the lookup - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v6 remote address of the face - * @param sw_if: software interface id of the face - * @param node_index: vlib edge index to use in the packet processing - */ -always_inline void -hicn_dpo_iface_ip6_add_and_lock (hicn_face_id_t * index, - u8 * hicnb_flags, - const ip6_address_t * nat_addr, - u32 sw_if, u32 adj_index, u32 node_index) -{ - /*All (complete) faces are indexed by remote addess as well */ - /* if the face exists, it adds a lock */ - hicn_face_t *face = - hicn_face_get ((ip46_address_t *)nat_addr, sw_if, &hicn_face_hashtb, adj_index); - - if (face == NULL) - { - hicn_face_id_t idx; - hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, adj_index); - - face = hicn_dpoi_get_from_idx(idx); - - face->dpo.dpoi_type = DPO_FIRST; - face->dpo.dpoi_proto = DPO_PROTO_IP6; - face->dpo.dpoi_index = adj_index; - face->dpo.dpoi_next_node = node_index; - - //if (ip46_address_is_zero((ip46_address_t *)nat_addr)) - // { - adj_nbr_walk(face->sw_if, - FIB_PROTOCOL_IP6, - hicn6_iface_adj_walk_cb, - face); - // } - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - - *index = idx; - - return; - } - else - { - /* unlock the face. We don't take a lock on each interest we receive */ - hicn_face_id_t face_id = hicn_dpoi_get_index(face); - hicn_face_unlock_with_id(face_id); - } - - /* Code replicated on purpose */ - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= - (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *index = hicn_dpoi_get_index (face); -} - - -/* /\** */ -/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */ -/* * control plane. */ -/* * */ -/* * @param dpo: Data plane object that point to the face created. */ -/* * @param local_addr: Ip v4 local address of the face */ -/* * @param remote_addr: Ip v4 remote address of the face */ -/* * @param sw_if: software interface id of the face */ -/* * @param adj: Ip adjacency corresponding to the remote address in the face */ -/* * @param node_index: vlib edge index to use in the packet processing */ -/* * @param flags: Flags of the face */ -/* * @param face_id: Identifier for the face (dpoi_index) */ -/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */ -/* *\/ */ -/* int hicn_dpo_ip4_create (dpo_id_t * dpo, */ -/* const ip4_address_t * local_addr, */ -/* const ip4_address_t * remote_addr, */ -/* u32 sw_if, */ -/* adj_index_t adj, */ -/* u32 node_index, */ -/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */ - -/* /\** */ -/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */ -/* * control plane. */ -/* * */ -/* * @param dpo: Data plane object that point to the face created. */ -/* * @param local_addr: Ip v6 local address of the face */ -/* * @param remote_addr: Ip v6 remote address of the face */ -/* * @param sw_if: software interface id of the face */ -/* * @param adj: Ip adjacency corresponding to the remote address in the face */ -/* * @param node_index: vlib edge index to use in the packet processing */ -/* * @param flags: Flags of the face */ -/* * @param face_id: Identifier for the face (dpoi_index) */ -/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */ -/* *\/ */ -/* int hicn_dpo_ip6_create (dpo_id_t * dpo, */ -/* const ip6_address_t * local_addr, */ -/* const ip6_address_t * remote_addr, */ -/* u32 sw_if, */ -/* adj_index_t adj, */ -/* u32 node_index, */ -/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */ - -#endif // __HICN_DPO_IP_H__ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h index a9a565a5a..234c3fcc2 100644 --- a/hicn-plugin/src/faces/face.h +++ b/hicn-plugin/src/faces/face.h @@ -23,28 +23,55 @@ #include <vnet/dpo/dpo.h> #include <vnet/adj/adj_types.h> #include <vppinfra/bihash_8_8.h> +#include <vnet/adj/adj_midchain.h> + +#include "../error.h" typedef u8 hicn_face_flags_t; typedef index_t hicn_face_id_t; -//typedef dpo_type_t hicn_face_type_t; /** - * @file + * @file face.h + * + * This file implements a general face type. The purpose of a face is to + * carry the needed information to forward interest and data packets to the + * next node in the network. There are two type of faces: complete faces (in short + * faces), and incomplete faces (in short ifaces). * - * @brief Face + * A face that does not contain the indication of the adjacency is an + * incomplete face (iface), otherwise it is considered to be complete. Ifaces are + * used to forward data back to the previous hICN hop from which we received an + * interest, while faces are used to forward interest packets to the next hicn node. + * Faces and ifaces are created at two different points in time. Faces are created + * when a route is added, while ifaces are created when an interest is received. + * In details, faces and ifaces carry the following information: + * - nat_addr: the ip address to perform src nat or dst nat on interest and data packets, respectively; + * - pl_id: the path label + * - locks: the number of entities using this face. When 0 the face can be deallocated + * - dpo: the dpo that identifies the next node in the vlib graph for processing the vlib + * buffer. The dpo contains the dpo.dpoi_next field that points to the next node + * in the vlib graph and the dpo.dpoi_index which is an index to adj used by the next node + * to perform the l2 rewrite. In case of ifaces, it is likely we don't know the + * adjacency when creting the face. In this case, the next node in the vlib graph + * will be the node that performs a lookup in the fib. Only in case of udp tunnels, + * which are bidirectional tunnel we know that the incoming tunnel is also the outgoing + * one, therefore in this case we store the tunnel in the dpo.dpoi_index fields. For + * all the other tunnels (which are most likely unidirectional), the source address of + * the interest will be used to retrieve the outgoing tunnel when sending the corresponding + * data back. + * - sw_if: the incoming interface of the interest + * - fib_node, fib_entry_index and fib_sibling are information used to be notified of + * changes in the adjacency pointed by the dpo. * - * This file implements a general face type. A face is carried through nodes as a - * dpo. The face state (hicn_face_t) is the object pointed by the - * dpoi_index in the dpo_id_t (see - * https://docs.fd.io/vpp/18.07/d0/d37/dpo_8h_source.html). - * A face state that does not contain the indication of the l2 adjacency is an - * incomplete face (iface), otherwise it is considered to be complete. Each face type - * provide specific node for processing packets in input or output of complete - * and incomplete faces. + * We maintain two hash tables to retrieve faces and ifaces. In particular one hash table which + * index faces and ifaces for nat_address, sw_if and dpo. This is used to retrieve existing faces + * or ifaces when an interest is received and when an new face is created. A second hash table that + * indexes vectors of faces for nat_address and sw_if. This is used to retrieve a list of possible + * incoming faces when a data is received. */ /** - * @brief Structure holding the face state. It containes the fields shared among + * @brief Structure representing a face. It containes the fields shared among * all the types of faces as well it leaves some space for storing additional * information specific to each type. */ @@ -85,8 +112,6 @@ typedef struct __attribute__ ((packed)) hicn_face_s /* Pool of faces */ extern hicn_face_t *hicn_dpoi_face_pool; -//extern dpo_type_t hicn_face_type; - /* Flags */ /* A face is complete and it stores all the information. A iface lacks of the adj index, therefore sending a packet through a iface require a lookup in @@ -127,11 +152,6 @@ STATIC_ASSERT ((HICN_FACE_FLAGS_APPFACE_CONS >> /** * @brief Definition of the virtual functin table for an hICN FACE DPO. - * - * An hICN dpo is a combination of a dpo context (hicn_dpo_ctx or struct that - * extends a hicn_dpo_ctx) and a strategy node. The following virtual function table - * template that glues together the fuction to interact with the context and the - * creating the dpo */ typedef struct hicn_face_vft_s { @@ -176,7 +196,7 @@ extern dpo_type_t first_type; extern vlib_combined_counter_main_t *counters; /** - * @brief Return the face id from the face state + * @brief Return the face id from the face object * * @param Pointer to the face state * @return face id @@ -188,10 +208,11 @@ hicn_dpoi_get_index (hicn_face_t * face_dpoi) } /** - * @brief Return the face from the face id. Face id must be valid. + * @brief Return the face object from the face id. + * This method is robust to invalid face id. * * @param dpoi_index Face identifier - * @return Pointer to the face + * @return Pointer to the face or NULL */ always_inline hicn_face_t * hicn_dpoi_get_from_idx_safe (hicn_face_id_t dpoi_index) @@ -252,7 +273,7 @@ hicn_face_unlock_with_id (hicn_face_id_t face_id) } /** - * @brief Add a lock to the face dpo + * @brief Add a lock to the face through its dpo * * @param dpo Pointer to the face dpo */ @@ -263,7 +284,7 @@ hicn_face_lock (dpo_id_t * dpo) } /** - * @brief Remove a lock to the face dpo. Deallocate the face id locks == 0 + * @brief Remove a lock to the face through its dpo. Deallocate the face id locks == 0 * * @param dpo Pointer to the face dpo */ @@ -302,8 +323,6 @@ u8 *format_hicn_face_all (u8 * s, int n, ...); */ int hicn_face_del (hicn_face_id_t face_id); -/* FACE IP CODE */ - /** * @bried vector of faces used to collect faces having the same local address * @@ -336,11 +355,24 @@ extern mhash_t hicn_face_vec_hashtb; /** - * Key definition for the mhash table. An ip face is uniquely identified by ip - * address and the interface id. The ip address can correspond to the remote ip - * address of the next hicn hop, or to the local address of the receiving - * interface. The former is used to retrieve the incoming face when an interest - * is received, the latter when the arring packet is a data. + * Key definition for the mhash table. An face is uniquely identified by ip + * address, the interface id and a dpo pointing to the next node in the vlib graph. + * The ip address can correspond to the remote ip address of the next hicn hop, + * or to the local address of the receiving interface. The former is used to + * retrieve the incoming face when an interest is received, the latter when + * the arring packet is a data. If the face is a regular face + * In case of iface, the following structure can be filled in different ways: + * - dpo equal to DPO_INVALID when the iface is a regular hICN iface + * - in case of udp_tunnel dpo = + * { + * .dpoi_index = tunnel_id, + * .dpoi_type = DPO_FIRST, //We don't need the type, we leave it invalid + * .dpoi_proto = DPO_PROTO_IP4 or DPO_PROTO_IP6, + * .dpoi_next_node = HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP or + * HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP or + * HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP or + * HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP + * } */ typedef struct __attribute__ ((packed)) hicn_face_key_s { @@ -370,7 +402,7 @@ hicn_face_get_key (const ip46_address_t * addr, } /** - * @brief Get the dpoi from the nat address. Does not add any lock. + * @brief Get the face obj from the nat address. Does not add any lock. * * @param addr Ip v4 address used to create the key for the hash table. * @param sw_if Software interface id used to create the key for the hash table. @@ -402,7 +434,7 @@ hicn_face_get (const ip46_address_t * addr, u32 sw_if, mhash_t * hashtb, index_t } /** - * @brief Get the dpoi from the nat address. Does not add any lock. + * @brief Get the face obj from the nat address and the dpo. Does not add any lock. * * @param addr Ip v4 address used to create the key for the hash table. * @param sw_if Software interface id used to create the key for the hash table. @@ -453,10 +485,10 @@ hicn_face_get_vec (const ip46_address_t * addr, /** * @brief Create a new face ip. API for other modules (e.g., routing) * - * @param local_addr Local ip v4 or v6 address of the face - * @param remote_addr Remote ip v4 or v6 address of the face + * @param dpo_nh dpo contained in the face that points to the next node in + * the vlib graph + * @param nat_addr nat ip v4 or v6 address of the face * @param sw_if interface associated to the face - * @param is_app_face Boolean to set the face as an application face * @param pfaceid Pointer to return the face id * @param is_app_prod if HICN_FACE_FLAGS_APPFACE_PROD the face is a local application face, all other values are ignored * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally @@ -512,6 +544,248 @@ hicn_iface_add (ip46_address_t * nat_address, int sw_if, } } +/**** Helpers to manipulate faces and ifaces from the face/iface input nodes ****/ + +/** + * @brief Retrieve a vector of faces from the ip4 local address and returns its index. + * + * @param vec: Result of the lookup. If no face exists for the local address vec = NULL + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param local_addr: Ip v4 nat address of the face + * @param sw_if: software interface id of the face + * + * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. + */ +always_inline int +hicn_face_ip4_lock (hicn_face_id_t * face_id, + u32 * in_faces_vec_id, + u8 * hicnb_flags, + const ip4_address_t * nat_addr) +{ + ip46_address_t ip_address = {0}; + ip46_address_set_ip4(&ip_address, nat_addr); + hicn_face_input_faces_t *in_faces_vec = + hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb); + + if (PREDICT_FALSE (in_faces_vec == NULL)) + return HICN_ERROR_FACE_NOT_FOUND; + + *in_faces_vec_id = in_faces_vec->vec_id; + hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id); + + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= + (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *face_id = in_faces_vec->face_id; + + return HICN_ERROR_NONE; +} + +/** + * @brief Retrieve a face from the ip6 local address and returns its dpo. This + * method adds a lock on the face state. + * + * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param nat_addr: Ip v6 nat address of the face + * @param sw_if: software interface id of the face + * + * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE. + */ +always_inline int +hicn_face_ip6_lock (hicn_face_id_t * face_id, + u32 * in_faces_vec_id, + u8 * hicnb_flags, + const ip6_address_t * nat_addr) +{ + hicn_face_input_faces_t *in_faces_vec = + hicn_face_get_vec ((ip46_address_t *)nat_addr, &hicn_face_vec_hashtb); + + if (PREDICT_FALSE (in_faces_vec == NULL)) + return HICN_ERROR_FACE_NOT_FOUND; + + *in_faces_vec_id = in_faces_vec->vec_id; + hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id); + + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= + (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *face_id = in_faces_vec->face_id; + + return HICN_ERROR_NONE; +} + +/** + * @brief Call back to get the adj of the tunnel + */ +static adj_walk_rc_t +hicn4_iface_adj_walk_cb (adj_index_t ai, + void *ctx) +{ + + hicn_face_t *face = (hicn_face_t *)ctx; + + dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai); + adj_nbr_midchain_stack(ai, &face->dpo); + + return (ADJ_WALK_RC_CONTINUE); +} + +/** + * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local + * address and returns its dpo. This method adds a lock on the face state. + * + * @param dpo: Result of the lookup + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param nat_addr: Ip v4 remote address of the face + * @param sw_if: software interface id of the face + * @param node_index: vlib edge index to use in the packet processing + */ +always_inline void +hicn_iface_ip4_add_and_lock (hicn_face_id_t * index, + u8 * hicnb_flags, + const ip4_address_t * nat_addr, + u32 sw_if, u32 adj_index, u32 node_index) +{ + /*All (complete) faces are indexed by remote addess as well */ + + ip46_address_t ip_address = {0}; + ip46_address_set_ip4(&ip_address, nat_addr); + + /* if the face exists, it adds a lock */ + hicn_face_t *face = + hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index); + + if (face == NULL) + { + hicn_face_id_t idx; + hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index); + + face = hicn_dpoi_get_from_idx(idx); + + face->dpo.dpoi_type = DPO_FIRST; + face->dpo.dpoi_proto = DPO_PROTO_IP4; + face->dpo.dpoi_index = adj_index; + face->dpo.dpoi_next_node = node_index; + + /* if (nat_addr->as_u32 == 0) */ + /* { */ + adj_nbr_walk(face->sw_if, + FIB_PROTOCOL_IP4, + hicn4_iface_adj_walk_cb, + face); + /* } */ + + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + + *index = idx; + return; + } + else + { + /* unlock the face. We don't take a lock on each interest we receive */ + hicn_face_id_t face_id = hicn_dpoi_get_index(face); + hicn_face_unlock_with_id(face_id); + } + + /* Code replicated on purpose */ + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= + (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *index = hicn_dpoi_get_index (face); +} + +/** + * @brief Call back to get the adj of the tunnel + */ +static adj_walk_rc_t +hicn6_iface_adj_walk_cb (adj_index_t ai, + void *ctx) +{ + + hicn_face_t *face = (hicn_face_t *)ctx; + + ip_adjacency_t *adj = adj_get(ai); + if ((adj->lookup_next_index == IP_LOOKUP_NEXT_MIDCHAIN) || + (adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST_MIDCHAIN)) + { + dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, adj->ia_nh_proto, ai); + adj_nbr_midchain_stack(ai, &face->dpo); + } + + return (ADJ_WALK_RC_CONTINUE); +} + + +/** + * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local + * address and returns its dpo. This method adds a lock on the face state. + * + * @param dpo: Result of the lookup + * @param hicnb_flags: Flags that indicate whether the face is an application + * face or not + * @param nat_addr: Ip v6 remote address of the face + * @param sw_if: software interface id of the face + * @param node_index: vlib edge index to use in the packet processing + */ +always_inline void +hicn_iface_ip6_add_and_lock (hicn_face_id_t * index, + u8 * hicnb_flags, + const ip6_address_t * nat_addr, + u32 sw_if, u32 adj_index, u32 node_index) +{ + /*All (complete) faces are indexed by remote addess as well */ + /* if the face exists, it adds a lock */ + hicn_face_t *face = + hicn_face_get ((ip46_address_t *)nat_addr, sw_if, &hicn_face_hashtb, adj_index); + + if (face == NULL) + { + hicn_face_id_t idx; + hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, adj_index); + + face = hicn_dpoi_get_from_idx(idx); + + face->dpo.dpoi_type = DPO_FIRST; + face->dpo.dpoi_proto = DPO_PROTO_IP6; + face->dpo.dpoi_index = adj_index; + face->dpo.dpoi_next_node = node_index; + + adj_nbr_walk(face->sw_if, + FIB_PROTOCOL_IP6, + hicn6_iface_adj_walk_cb, + face); + + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + + *index = idx; + + return; + } + else + { + /* unlock the face. We don't take a lock on each interest we receive */ + hicn_face_id_t face_id = hicn_dpoi_get_index(face); + hicn_face_unlock_with_id(face_id); + } + + /* Code replicated on purpose */ + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= + (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> + HICN_FACE_FLAGS_APPFACE_PROD_BIT; + + *index = hicn_dpoi_get_index (face); +} #endif // __HICN_FACE_H__ diff --git a/hicn-plugin/src/faces/face_node.c b/hicn-plugin/src/faces/face_node.c index 5b42f0dde..e1fd81ca0 100644 --- a/hicn-plugin/src/faces/face_node.c +++ b/hicn-plugin/src/faces/face_node.c @@ -17,7 +17,6 @@ #include "face.h" #include "face_node.h" -#include "dpo_face.h" #include "../strategy_dpo_manager.h" #include "face.h" #include "../cache_policies/cs_lru.h" @@ -97,8 +96,8 @@ typedef enum #define IP_HEADER_4 ip4_header_t #define IP_HEADER_6 ip6_header_t -#define LOCK_DPO_FACE_IP4 hicn_dpo_face_ip4_lock -#define LOCK_DPO_FACE_IP6 hicn_dpo_face_ip6_lock +#define LOCK_DPO_FACE_IP4 hicn_face_ip4_lock +#define LOCK_DPO_FACE_IP6 hicn_face_ip6_lock #define TRACE_INPUT_PKT_IP4 hicn4_face_input_trace_t #define TRACE_INPUT_PKT_IP6 hicn6_face_input_trace_t diff --git a/hicn-plugin/src/faces/face_node.h b/hicn-plugin/src/faces/face_node.h index 932ee40f5..f5a8bf5ae 100644 --- a/hicn-plugin/src/faces/face_node.h +++ b/hicn-plugin/src/faces/face_node.h @@ -19,6 +19,23 @@ #include <vlib/vlib.h> #include <vnet/vnet.h> +/** + * @file face_node.h + * + * Implements the input and output face nodes. Input face nodes + * process incoming data while output face nodes process outgoing + * interests packets. + * + * Input face nodes follow hicn-face-input nodes and their purpose + * is to retrieve the list of possible incoming faces for each the data packet. + * The following node to the input face nodes is the hicn-data-pcslookup. + * Output face nodes follow the strategy and the hicn-interest-hitpit nodes and + * they perform the src nat on each interest packet. The node following the + * output face nodes depends on the adjacency type. In case of ip, the following + * node is the ip-rewrite, in case of tunnels the next node is the one implementing + * the tunnel encapsulation (udp-encap, mpls, etc). + */ + extern vlib_node_registration_t hicn4_face_input_node; extern vlib_node_registration_t hicn4_face_output_node; extern vlib_node_registration_t hicn6_face_input_node; diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c index d42d0114e..433cf0b02 100644 --- a/hicn-plugin/src/faces/iface_node.c +++ b/hicn-plugin/src/faces/iface_node.c @@ -14,7 +14,6 @@ */ #include "face.h" -#include "dpo_face.h" #include "../strategy_dpo_manager.h" #include "../hicn.h" #include "../infra.h" @@ -96,8 +95,8 @@ typedef enum #define ADDRESSX2_IP6 ip6_address_t *local_address0 = ip6_interface_first_address(&ip6_main, swif0); \ ip6_address_t *local_address1 = ip6_interface_first_address(&ip6_main, swif1); -#define DPO_ADD_LOCK_IFACE_IP4 hicn_dpo_iface_ip4_add_and_lock -#define DPO_ADD_LOCK_IFACE_IP6 hicn_dpo_iface_ip6_add_and_lock +#define DPO_ADD_LOCK_IFACE_IP4 hicn_iface_ip4_add_and_lock +#define DPO_ADD_LOCK_IFACE_IP6 hicn_iface_ip6_add_and_lock //#define VLIB_EDGE_IP4 data_fwd_iface_ip4_vlib_edge //#define VLIB_EDGE_IP6 data_fwd_iface_ip6_vlib_edge diff --git a/hicn-plugin/src/faces/iface_node.h b/hicn-plugin/src/faces/iface_node.h index 761721b2f..1a7c4291b 100644 --- a/hicn-plugin/src/faces/iface_node.h +++ b/hicn-plugin/src/faces/iface_node.h @@ -13,16 +13,35 @@ * limitations under the License. */ -#ifndef __HICN_IFACE_IP_NODE_H__ -#define __HICN_IFACE_IP_NODE_H__ +#ifndef __HICN_IFACE_NODE_H__ +#define __HICN_IFACE_NODE_H__ #include <vlib/vlib.h> #include <vnet/vnet.h> /** + * @file iface_node.h + * + * Implements the input and output iface nodes. Input iface nodes + * process incoming interests while output face nodes process outgoing + * data packets. + * + * Input iface nodes follow ip-lookup nodes and their purpose + * is to create (or retrieve if already existing) the list incoming face + * for each the interest packet. + * The following node to the input iface nodes is the hicn-interest-pcslookup. + * Output iface nodes follow the hicn-data-fwd and the hicn-interest-hitcs nodes and + * they perform the dst nat on each data packet. The node following the + * output face nodes depends on the adjacency type. In case of ip, the following + * node is the ip4/6-lookup, in case of tunnels the next node is the one implementing + * the tunnel encapsulation (udp-encap, mpls, etc). + */ + + +/** * @brief Initialize the ip iface module */ -void hicn_iface_ip_init (vlib_main_t * vm); +void hicn_iface_init (vlib_main_t * vm); #endif // __HICN_IFACE_IP_NODE_H__ |