diff options
Diffstat (limited to 'hicn-plugin/src/faces')
-rw-r--r-- | hicn-plugin/src/faces/app/address_mgr.c | 7 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/address_mgr.h | 2 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_app_cli.c | 13 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_cons.c | 10 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_cons.h | 2 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_prod.c | 83 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_prod.h | 8 | ||||
-rw-r--r-- | hicn-plugin/src/faces/app/face_prod_node.c | 155 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face.c | 131 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face.h | 395 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face_cli.c | 14 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face_flags.h | 40 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face_node.c | 387 | ||||
-rw-r--r-- | hicn-plugin/src/faces/face_node.h | 2 | ||||
-rw-r--r-- | hicn-plugin/src/faces/iface_node.c | 405 | ||||
-rw-r--r-- | hicn-plugin/src/faces/iface_node.h | 22 | ||||
-rw-r--r-- | hicn-plugin/src/faces/inlines.h | 23 |
17 files changed, 929 insertions, 770 deletions
diff --git a/hicn-plugin/src/faces/app/address_mgr.c b/hicn-plugin/src/faces/app/address_mgr.c index b5d8ce7cb..44729fd69 100644 --- a/hicn-plugin/src/faces/app/address_mgr.c +++ b/hicn-plugin/src/faces/app/address_mgr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Copyright (c) 2021 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,7 +14,7 @@ */ /* - * Copyright (c) 2017-2019 by cisco systems inc. All rights reserved. + * Copyright (c) 2021 by cisco systems inc. All rights reserved. * */ @@ -31,10 +31,11 @@ #include <vnet/interface.h> //appif_flags #include <vnet/interface_funcs.h> //vnet_sw_interface_set_flags +#include <vpp_plugins/hicn/error.h> + #include "address_mgr.h" #include "../../hicn.h" #include "../../infra.h" -#include "../../error.h" #include "../face.h" #include "../../strategy_dpo_ctx.h" #include "../../route.h" diff --git a/hicn-plugin/src/faces/app/address_mgr.h b/hicn-plugin/src/faces/app/address_mgr.h index bd834f063..32545f8ca 100644 --- a/hicn-plugin/src/faces/app/address_mgr.h +++ b/hicn-plugin/src/faces/app/address_mgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 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: diff --git a/hicn-plugin/src/faces/app/face_app_cli.c b/hicn-plugin/src/faces/app/face_app_cli.c index ccdee4450..50e6ae71b 100644 --- a/hicn-plugin/src/faces/app/face_app_cli.c +++ b/hicn-plugin/src/faces/app/face_app_cli.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Copyright (c) 2021 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: @@ -17,8 +17,9 @@ #include <vnet/dpo/dpo.h> #include <vlib/vlib.h> #include <vnet/ip/ip6_packet.h> +#include <vnet/ip/format.h> -//#include "../face_dpo.h" +#include "../../params.h" #include "../face.h" #include "face_prod.h" #include "face_cons.h" @@ -114,8 +115,8 @@ hicn_face_app_cli_set_command_fn (vlib_main_t *vm, if (prod) { prefix.fp_proto = ip46_address_is_ip4 (&prefix.fp_addr) ? - FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6; + FIB_PROTOCOL_IP4 : + FIB_PROTOCOL_IP6; rv = hicn_face_prod_add (&prefix, sw_if, &cs_reserved, &prod_addr, &face_id1); if (rv == HICN_ERROR_NONE) @@ -175,8 +176,8 @@ hicn_face_app_cli_set_command_fn (vlib_main_t *vm, break; } return (rv == HICN_ERROR_NONE) ? - 0 : - clib_error_return (0, "%s\n", get_error_string (rv)); + 0 : + clib_error_return (0, "%s\n", get_error_string (rv)); } /* cli declaration for 'cfg face' */ diff --git a/hicn-plugin/src/faces/app/face_cons.c b/hicn-plugin/src/faces/app/face_cons.c index 53b955775..edb03387d 100644 --- a/hicn-plugin/src/faces/app/face_cons.c +++ b/hicn-plugin/src/faces/app/face_cons.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Copyright (c) 2021 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: @@ -69,10 +69,10 @@ hicn_face_cons_add (ip4_address_t *nh_addr4, ip6_address_t *nh_addr6, u32 swif, 0 /* is_del */); ip46_address_t nh_addr = to_ip46 (0, (u8 *) nh_addr6); - index_t adj_index = adj_nbr_find (FIB_PROTOCOL_IP6, VNET_LINK_IP6, &nh_addr, swif); + index_t adj_index = + adj_nbr_find (FIB_PROTOCOL_IP6, VNET_LINK_IP6, &nh_addr, swif); - hicn_iface_add ((ip46_address_t *) nh_addr6, swif, faceid2, DPO_PROTO_IP6, - adj_index); + hicn_iface_add ((ip46_address_t *) nh_addr6, swif, faceid2, adj_index, 0); hicn_face_t *face = hicn_dpoi_get_from_idx (*faceid2); face->flags |= HICN_FACE_FLAGS_APPFACE_CONS; @@ -90,7 +90,7 @@ hicn_face_cons_del (hicn_face_id_t face_id) if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS) { - return hicn_face_del (face_id); + return hicn_face_unlock_with_id (face_id); } else { diff --git a/hicn-plugin/src/faces/app/face_cons.h b/hicn-plugin/src/faces/app/face_cons.h index 3ff246f4f..9df6f773f 100644 --- a/hicn-plugin/src/faces/app/face_cons.h +++ b/hicn-plugin/src/faces/app/face_cons.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2021 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: diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c index 16b6e6158..5d0fa727b 100644 --- a/hicn-plugin/src/faces/app/face_prod.c +++ b/hicn-plugin/src/faces/app/face_prod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -17,6 +17,7 @@ #include <vlib/vlib.h> #include <vnet/vnet.h> #include <vnet/interface_funcs.h> +#include <vppinfra/pool.h> #include "face_prod.h" #include "address_mgr.h" @@ -24,17 +25,15 @@ #include "../../route.h" #include "../../cache_policies/cs_lru.h" +#define INITIAL_POOL_SIZE 16 hicn_face_prod_state_t *face_state_vec; /* used to check if an interface is already in the vector */ u32 *face_state_pool; static int -hicn_app_state_create (u32 swif, fib_prefix_t *prefix) +hicn_app_state_create (u32 swif, index_t adj_index, fib_prefix_t *prefix) { - /* Make sure that the pool is not empty */ - pool_validate_index (face_state_pool, 0); - u32 *swif_app; u8 found = 0; @@ -49,6 +48,7 @@ hicn_app_state_create (u32 swif, fib_prefix_t *prefix) /* Create the appif and store in the vector */ vec_validate (face_state_vec, swif); + face_state_vec[swif].adj_index = adj_index; clib_memcpy (&(face_state_vec[swif].prefix), prefix, sizeof (fib_prefix_t)); /* Set as busy the element in the vector */ @@ -73,9 +73,6 @@ hicn_app_state_create (u32 swif, fib_prefix_t *prefix) static int hicn_app_state_del (u32 swif) { - /* Make sure that the pool is not empty */ - pool_validate_index (face_state_pool, 0); - u32 *temp; u32 *swif_app = NULL; u8 found = 0; @@ -119,7 +116,7 @@ hicn_face_prod_add (fib_prefix_t *prefix, u32 sw_if, u32 *cs_reserved, hicn_main_t *hm = &hicn_main; - ip46_address_t local_app_ip; + ip46_address_t local_app_ip = { .as_u64 = { 0, 0 } }; CLIB_UNUSED (ip46_address_t remote_app_ip); u32 if_flags = 0; @@ -139,10 +136,11 @@ hicn_face_prod_add (fib_prefix_t *prefix, u32 sw_if, u32 *cs_reserved, if_flags |= VNET_SW_INTERFACE_FLAG_ADMIN_UP; vnet_sw_interface_set_flags (vnm, sw_if, if_flags); +#ifdef HICN_DDEBUG u8 *s0; s0 = format (0, "Prefix %U", format_fib_prefix, prefix); - - vlib_cli_output (vm, "Received request for %s, swif %d\n", s0, sw_if); + HICN_DEBUG ("Received request for %s, swif %d\n", s0, sw_if); +#endif if (ip46_address_is_zero (&prefix->fp_addr)) { @@ -265,18 +263,26 @@ hicn_face_prod_add (fib_prefix_t *prefix, u32 sw_if, u32 *cs_reserved, } u32 fib_index = fib_table_find (prefix->fp_proto, 0); - fib_table_entry_path_add2 (fib_index, prefix, FIB_SOURCE_CLI, + fib_table_entry_path_add2 (fib_index, prefix, FIB_SOURCE_API, FIB_ENTRY_FLAG_NONE, rpaths); - hicn_route_enable (prefix); - hicn_app_state_create (sw_if, prefix); + HICN_DEBUG ("Calling hicn enable for producer face"); + + hicn_face_id_t *vec_faces = NULL; + fib_node_index_t hicn_fib_node_index; + hicn_route_enable (prefix, &hicn_fib_node_index, &vec_faces); + if (vec_faces != NULL) + vec_free (vec_faces); + + adj_index = + adj_nbr_find (isv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4, + isv6 ? VNET_LINK_IP6 : VNET_LINK_IP4, prod_addr, sw_if); + + hicn_app_state_create (sw_if, adj_index, prefix); } - adj_index = - adj_nbr_find (isv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4, - isv6 ? VNET_LINK_IP6 : VNET_LINK_IP4, prod_addr, sw_if); - face = hicn_face_get (&local_app_ip, sw_if, &hicn_face_hashtb, - adj_index); // HICN_FACE_FLAGS_APPFACE_PROD); + face = hicn_face_get (&local_app_ip, sw_if, &hicn_face_hashtb, adj_index); + assert (face); *faceid = hicn_dpoi_get_index (face); @@ -289,6 +295,7 @@ hicn_face_prod_add (fib_prefix_t *prefix, u32 sw_if, u32 *cs_reserved, /* Cleanup in case of something went wrong. */ if (ret) { + HICN_ERROR ("Somethig went wrong while adding producer face. Cleanup."); hicn_app_state_del (sw_if); } return ret; @@ -304,17 +311,32 @@ 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); - - // int ret = hicn_face_del (face_id); - return hicn_app_state_del (face->sw_if); - // ret == HICN_ERROR_NONE ? hicn_app_state_del (face->sw_if) : ret; + /* Remove the face from the hicn fib */ + fib_prefix_t *prefix = &(face_state_vec[face->sw_if].prefix); + HICN_DEBUG ("Calling hicn_route_disable from hicn_face_prod_del"); + int ret = hicn_route_disable (prefix); + if (ret) + { + vlib_main_t *vm = vlib_get_main (); + vlib_cli_output (vm, "Error disabling route: %s", + get_error_string (ret)); + } + /* Also remove it from main fib, as we sre the owners of this prefix */ + u32 fib_index = fib_table_find (prefix->fp_proto, 0); + fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API); + ret = hicn_app_state_del (face->sw_if); + if (ret) + { + vlib_main_t *vm = vlib_get_main (); + vlib_cli_output (vm, "Error deelting app state: %s", + get_error_string (ret)); + } } else { + vlib_main_t *vm = vlib_get_main (); + vlib_cli_output (vm, "APPFACE not found.", + get_error_string (HICN_ERROR_APPFACE_NOT_FOUND)); return HICN_ERROR_APPFACE_NOT_FOUND; } @@ -332,6 +354,13 @@ format_hicn_face_prod (u8 *s, va_list *args) return s; } +void +hicn_face_prod_init () +{ + /* Make sure that the pool is not empty */ + pool_alloc (face_state_pool, INITIAL_POOL_SIZE); +} + VNET_FEATURE_INIT (hicn_prod_app_input_ip6, static) = { .arc_name = "ip6-unicast", .node_name = "hicn-face-prod-input", diff --git a/hicn-plugin/src/faces/app/face_prod.h b/hicn-plugin/src/faces/app/face_prod.h index 4acf89dfc..46bdf7c24 100644 --- a/hicn-plugin/src/faces/app/face_prod.h +++ b/hicn-plugin/src/faces/app/face_prod.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -50,6 +50,7 @@ typedef struct { fib_prefix_t prefix; + index_t adj_index; } hicn_face_prod_state_t; extern hicn_face_prod_state_t *face_state_vec; @@ -95,6 +96,11 @@ int hicn_face_prod_set_lru_max (hicn_face_id_t face_id, u32 *requested_size); */ u8 *format_hicn_face_prod (u8 *s, va_list *args); +/** + * @brief Init the producer face module + */ +void hicn_face_prod_init (); + #endif /* _FACE_PROD_H_ */ /* diff --git a/hicn-plugin/src/faces/app/face_prod_node.c b/hicn-plugin/src/faces/app/face_prod_node.c index c4c9edc32..93e80d1ac 100644 --- a/hicn-plugin/src/faces/app/face_prod_node.c +++ b/hicn-plugin/src/faces/app/face_prod_node.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -24,8 +24,8 @@ */ #include "face_prod.h" -#include "../../hicn_api.h" #include "../../mgmt.h" +#include "../../parser.h" static __clib_unused char *face_prod_input_error_strings[] = { #define _(sym, string) string, @@ -43,12 +43,12 @@ typedef struct { u32 next_index; u32 sw_if_index; + hicn_error_t error; } hicn_face_prod_input_trace_t; typedef enum { - HICN_FACE_PROD_NEXT_DATA_IP4, - HICN_FACE_PROD_NEXT_DATA_IP6, + HICN_FACE_PROD_NEXT_PCS, HICN_FACE_PROD_NEXT_ERROR_DROP, HICN_FACE_PROD_N_NEXT, } hicn_face_prod_next_t; @@ -66,11 +66,14 @@ format_face_prod_input_trace (u8 *s, va_list *args) s = format (s, "prod-face: sw_if_index %d next-index %d", t->sw_if_index, t->next_index); + + if (t->error != HICN_ERROR_NONE) + s = format (s, " error %s", get_error_string (t->error)); return s; } static_always_inline int -match_ip4_name (u32 *name, fib_prefix_t *prefix) +match_ip4_name (u32 *name, const fib_prefix_t *prefix) { u32 xor = 0; @@ -80,7 +83,7 @@ match_ip4_name (u32 *name, fib_prefix_t *prefix) } static_always_inline int -match_ip6_name (u8 *name, fib_prefix_t *prefix) +match_ip6_name (u8 *name, const fib_prefix_t *prefix) { union { @@ -97,24 +100,42 @@ match_ip6_name (u8 *name, fib_prefix_t *prefix) } static_always_inline u32 -hicn_face_prod_next_from_data_hdr (vlib_node_runtime_t *node, vlib_buffer_t *b, - fib_prefix_t *prefix) +hicn_face_prod_next_from_data_hdr (vlib_main_t *vm, vlib_buffer_t *b) { - u8 *ptr = vlib_buffer_get_current (b); - u8 v = *ptr & 0xf0; + u8 is_v6; int match_res = 1; + int ret = 0; + hicn_name_t name; + hicn_face_prod_state_t *prod_face = NULL; + + // 1 - ensure the packet is hicn and its format is correct + ret = hicn_data_parse_pkt (b, vlib_buffer_length_in_chain (vm, b)); + if (PREDICT_FALSE (ret)) + { + return HICN_FACE_PROD_NEXT_ERROR_DROP; + } - if (PREDICT_TRUE (v == 0x40 && ip46_address_is_ip4 (&prefix->fp_addr))) + // 2 - make sure the packet refers to a valid producer app state and + // retrieve app state information + prod_face = &face_state_vec[vnet_buffer (b)->sw_if_index[VLIB_RX]]; + vnet_buffer (b)->ip.adj_index[VLIB_RX] = prod_face->adj_index; + + // 3 - make sure the address in the packet belongs to the producer prefix + // of this face + const fib_prefix_t *prefix = &prod_face->prefix; + is_v6 = hicn_buffer_is_v6 (b); + hicn_packet_get_name (&hicn_get_buffer (b)->pkbuf, &name); + if (PREDICT_TRUE (!is_v6 && ip46_address_is_ip4 (&prefix->fp_addr))) { - match_res = match_ip4_name ((u32 *) &(ptr[12]), prefix); + match_res = match_ip4_name (&name.prefix.v4.as_u32, prefix); } - else if (PREDICT_TRUE (v == 0x60 && !ip46_address_is_ip4 (&prefix->fp_addr))) + else if (PREDICT_TRUE (is_v6 && !ip46_address_is_ip4 (&prefix->fp_addr))) { - match_res = match_ip6_name (&(ptr[8]), prefix); + match_res = match_ip6_name (name.prefix.v6.as_u8, prefix); } - return match_res ? HICN_FACE_PROD_NEXT_DATA_IP4 + (v == 0x60) : - HICN_FACE_PROD_NEXT_ERROR_DROP; + // 4 - if match found, forward data to next hicn node + return match_res ? HICN_FACE_PROD_NEXT_PCS : HICN_FACE_PROD_NEXT_ERROR_DROP; } static_always_inline void @@ -138,6 +159,7 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, u32 n_left_from, *from, *to_next; hicn_face_prod_next_t next_index; vl_api_hicn_api_node_stats_get_reply_t stats = { 0 }; + u32 thread_index = vm->thread_index; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -151,23 +173,30 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, while (n_left_from >= 8 && n_left_to_next >= 4) { vlib_buffer_t *b0, *b1, *b2, *b3; + hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3; u32 bi0, bi1, bi2, bi3; - hicn_face_prod_state_t *prod_face0 = NULL; - hicn_face_prod_state_t *prod_face1 = NULL; - hicn_face_prod_state_t *prod_face2 = NULL; - hicn_face_prod_state_t *prod_face3 = NULL; u32 next0, next1, next2, next3; + // Prefetch next iteration { vlib_buffer_t *b4, *b5, *b6, *b7; b4 = vlib_get_buffer (vm, from[4]); b5 = vlib_get_buffer (vm, from[5]); b6 = vlib_get_buffer (vm, from[6]); b7 = vlib_get_buffer (vm, from[7]); - CLIB_PREFETCH (b4, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (b5, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (b6, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (b7, CLIB_CACHE_LINE_BYTES, STORE); + CLIB_PREFETCH (b4, 2 * CLIB_CACHE_LINE_BYTES, WRITE); + CLIB_PREFETCH (b5, 2 * CLIB_CACHE_LINE_BYTES, WRITE); + CLIB_PREFETCH (b6, 2 * CLIB_CACHE_LINE_BYTES, WRITE); + CLIB_PREFETCH (b7, 2 * CLIB_CACHE_LINE_BYTES, WRITE); + + CLIB_PREFETCH (vlib_buffer_get_current (b4), + 2 * CLIB_CACHE_LINE_BYTES, WRITE); + CLIB_PREFETCH (vlib_buffer_get_current (b5), + 2 * CLIB_CACHE_LINE_BYTES, WRITE); + CLIB_PREFETCH (vlib_buffer_get_current (b6), + 2 * CLIB_CACHE_LINE_BYTES, WRITE); + CLIB_PREFETCH (vlib_buffer_get_current (b7), + 2 * CLIB_CACHE_LINE_BYTES, WRITE); } bi0 = from[0]; @@ -190,22 +219,49 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, b2 = vlib_get_buffer (vm, bi2); b3 = vlib_get_buffer (vm, bi3); - prod_face0 = &face_state_vec[vnet_buffer (b0)->sw_if_index[VLIB_RX]]; - prod_face1 = &face_state_vec[vnet_buffer (b1)->sw_if_index[VLIB_RX]]; - prod_face2 = &face_state_vec[vnet_buffer (b2)->sw_if_index[VLIB_RX]]; - prod_face3 = &face_state_vec[vnet_buffer (b3)->sw_if_index[VLIB_RX]]; - - next0 = - hicn_face_prod_next_from_data_hdr (node, b0, &prod_face0->prefix); - next1 = - hicn_face_prod_next_from_data_hdr (node, b1, &prod_face1->prefix); - next2 = - hicn_face_prod_next_from_data_hdr (node, b2, &prod_face2->prefix); - next3 = - hicn_face_prod_next_from_data_hdr (node, b3, &prod_face3->prefix); + hicnb0 = hicn_get_buffer (b0); + hicnb1 = hicn_get_buffer (b1); + hicnb2 = hicn_get_buffer (b2); + hicnb3 = hicn_get_buffer (b3); + + hicnb0->flags = HICN_FACE_FLAGS_DEFAULT; + hicnb1->flags = HICN_FACE_FLAGS_DEFAULT; + hicnb2->flags = HICN_FACE_FLAGS_DEFAULT; + hicnb3->flags = HICN_FACE_FLAGS_DEFAULT; + + // parse packets and get next node + next0 = hicn_face_prod_next_from_data_hdr (vm, b0); + next1 = hicn_face_prod_next_from_data_hdr (vm, b1); + next2 = hicn_face_prod_next_from_data_hdr (vm, b2); + next3 = hicn_face_prod_next_from_data_hdr (vm, b3); stats.pkts_data_count += 4; - /* trace */ + // counters + vlib_increment_combined_counter ( + &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, + HICN_FACE_COUNTERS_DATA_RX, 1, + vlib_buffer_length_in_chain (vm, b0)); + stats.pkts_data_count += 1; + + vlib_increment_combined_counter ( + &counters[hicnb1->face_id * HICN_N_COUNTER], thread_index, + HICN_FACE_COUNTERS_DATA_RX, 1, + vlib_buffer_length_in_chain (vm, b0)); + stats.pkts_data_count += 1; + + vlib_increment_combined_counter ( + &counters[hicnb2->face_id * HICN_N_COUNTER], thread_index, + HICN_FACE_COUNTERS_DATA_RX, 1, + vlib_buffer_length_in_chain (vm, b0)); + stats.pkts_data_count += 1; + + vlib_increment_combined_counter ( + &counters[hicnb3->face_id * HICN_N_COUNTER], thread_index, + HICN_FACE_COUNTERS_DATA_RX, 1, + vlib_buffer_length_in_chain (vm, b0)); + stats.pkts_data_count += 1; + + // trace hicn_face_prod_trace_buffer ( vm, node, vnet_buffer (b0)->sw_if_index[VLIB_RX], b0, next0); hicn_face_prod_trace_buffer ( @@ -215,7 +271,7 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, hicn_face_prod_trace_buffer ( vm, node, vnet_buffer (b3)->sw_if_index[VLIB_RX], b3, next3); - /* enqueue */ + // enqueue vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next, n_left_to_next, bi0, bi1, bi2, bi3, next0, next1, next2, next3); @@ -226,8 +282,8 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, while (n_left_from > 0 && n_left_to_next > 0) { vlib_buffer_t *b0; - u32 bi0, swif; - hicn_face_prod_state_t *prod_face = NULL; + hicn_buffer_t *hicnb0; + u32 bi0; u32 next0; if (n_left_from > 1) @@ -245,13 +301,19 @@ hicn_face_prod_input_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, n_left_to_next -= 1; b0 = vlib_get_buffer (vm, bi0); - swif = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - prod_face = &face_state_vec[swif]; + hicnb0 = hicn_get_buffer (b0); + hicnb0->flags = HICN_FACE_FLAGS_DEFAULT; - next0 = - hicn_face_prod_next_from_data_hdr (node, b0, &prod_face->prefix); + next0 = hicn_face_prod_next_from_data_hdr (vm, b0); stats.pkts_data_count++; + // counters + vlib_increment_combined_counter ( + &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, + HICN_FACE_COUNTERS_DATA_RX, 1, + vlib_buffer_length_in_chain (vm, b0)); + stats.pkts_data_count += 1; + /* trace */ hicn_face_prod_trace_buffer ( vm, node, vnet_buffer (b0)->sw_if_index[VLIB_RX], b0, next0); @@ -286,8 +348,7 @@ VLIB_REGISTER_NODE(hicn_face_prod_input_node) = .n_next_nodes = HICN_FACE_PROD_N_NEXT, .next_nodes = { - [HICN_FACE_PROD_NEXT_DATA_IP4] = "hicn4-face-input", - [HICN_FACE_PROD_NEXT_DATA_IP6] = "hicn6-face-input", + [HICN_FACE_PROD_NEXT_PCS] = "hicn-data-pcslookup", [HICN_FACE_PROD_NEXT_ERROR_DROP] = "error-drop", }, }; diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c index d62054365..ce3001ac7 100644 --- a/hicn-plugin/src/faces/face.c +++ b/hicn-plugin/src/faces/face.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -15,6 +15,7 @@ #include <vnet/fib/fib_entry_track.h> #include "face.h" +#include "app/face_prod.h" #include "../hicn.h" #include "../params.h" #include "../error.h" @@ -57,24 +58,17 @@ face_show (u8 *s, int face_id, u32 indent) return (s); } -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 + "hicn6-face-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 + "hicn4-face-output", // this is the name you give your node in + // VLIB_REGISTER_NODE NULL, }; @@ -158,19 +152,13 @@ static const fib_node_vft_t hicn_face_fib_node_vft = { void hicn_face_module_init (vlib_main_t *vm) { - pool_validate (hicn_dpoi_face_pool); pool_alloc (hicn_dpoi_face_pool, 1024); 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. @@ -182,7 +170,12 @@ hicn_face_module_init (vlib_main_t *vm) * corresponding to a face is updated */ hicn_face_fib_node_type = - fib_node_register_new_type (&hicn_face_fib_node_vft); + fib_node_register_new_type ("hicn_face_fib_node", &hicn_face_fib_node_vft); + + /* + * Init producer face module + */ + hicn_face_prod_init (); } u8 * @@ -256,46 +249,11 @@ format_hicn_face_all (u8 *s, int n, ...) 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->locks--; if (face->locks == 0) pool_put_index (hicn_dpoi_face_pool, face_id); else @@ -308,10 +266,12 @@ hicn_face_del (hicn_face_id_t face_id) } static void -hicn_iface_to_face (hicn_face_t *face, const dpo_id_t *dpo) +hicn_iface_to_face (hicn_face_t *face, const dpo_id_t *dpo, + dpo_proto_t dpo_proto) { - dpo_stack (hicn_face_type, dpo->dpoi_proto, &face->dpo, dpo); + dpo_stack (hicn_face_type, dpo_proto, &face->dpo, dpo); + face->dpo.dpoi_proto = dpo_proto; face->flags &= ~HICN_FACE_FLAGS_IFACE; face->flags |= HICN_FACE_FLAGS_FACE; @@ -320,7 +280,7 @@ hicn_iface_to_face (hicn_face_t *face, const dpo_id_t *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 || + if (dpo->dpoi_type != DPO_ADJACENCY_MIDCHAIN && dpo->dpoi_type != DPO_ADJACENCY_MCAST_MIDCHAIN) { ip_adjacency_t *adj = adj_get (dpo->dpoi_index); @@ -347,12 +307,9 @@ hicn_iface_to_face (hicn_face_t *face, const dpo_id_t *dpo) */ 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) + hicn_face_id_t *pfaceid, 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 = @@ -374,9 +331,7 @@ hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address, int sw_if, if (face == NULL) { - - hicn_iface_add (nat_address, sw_if, pfaceid, dpo_nh->dpoi_proto, - dpo_nh->dpoi_index); + hicn_iface_add (nat_address, sw_if, pfaceid, dpo_nh->dpoi_index, 0); face = hicn_dpoi_get_from_idx (*pfaceid); mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, 0); @@ -391,56 +346,10 @@ hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address, int sw_if, mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, 0); } - hicn_iface_to_face (face, dpo_nh); + hicn_iface_to_face (face, dpo_nh, dpo_proto); temp_dpo.dpoi_index = ~0; - 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_id_t, 0); - u32 index = vec - hicn_vec_pool; - in_faces_temp.vec_id = index; - vec_add1 (*vec, *pfaceid); - - 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); - - 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)); diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h index cb706eeca..43900dd4e 100644 --- a/hicn-plugin/src/faces/face.h +++ b/hicn-plugin/src/faces/face.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2020 Cisco and/or its affiliates. + * Copyright (c) 2021 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: @@ -25,7 +25,12 @@ #include <vppinfra/bihash_8_8.h> #include <vnet/adj/adj_midchain.h> -#include "../error.h" +#include <vpp_plugins/hicn/error.h> + +#include "face_flags.h" +#include "../hicn_buffer_flags.h" +#include "../hicn_logging.h" + typedef u8 hicn_face_flags_t; typedef index_t hicn_face_id_t; @@ -66,12 +71,8 @@ typedef index_t hicn_face_id_t; * - fib_node, fib_entry_index and fib_sibling are information used to be * notified of changes in the adjacency pointed by the dpo. * - * 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. + * We maintain one hash tables to retrieve faces and ifaces, which indexes + * faces and ifaces for nat_address, sw_if and dpo. */ /** @@ -86,7 +87,7 @@ typedef struct __attribute__ ((packed)) hicn_face_s hicn_face_flags_t flags; /* Align the upcoming fields */ - u8 align; + u8 iface_next; /* Path label (2B) */ u16 pl_id; @@ -117,47 +118,8 @@ typedef struct __attribute__ ((packed)) hicn_face_s /* Pool of faces */ extern hicn_face_t *hicn_dpoi_face_pool; -/* 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 - the FIB. */ -#define HICN_FACE_FLAGS_DEFAULT 0x00 -#define HICN_FACE_FLAGS_FACE 0x01 -#define HICN_FACE_FLAGS_IFACE 0x02 -#define HICN_FACE_FLAGS_APPFACE_PROD \ - 0x04 /* Currently only IP face can be appface */ -#define HICN_FACE_FLAGS_APPFACE_CONS \ - 0x08 /* Currently only IP face can be appface */ -#define HICN_FACE_FLAGS_DELETED 0x10 - #define HICN_FACE_NULL (hicn_face_id_t) ~0 -#define HICN_FACE_FLAGS_APPFACE_PROD_BIT 2 -#define HICN_FACE_FLAGS_APPFACE_CONS_BIT 3 - -#define HICN_BUFFER_FLAGS_DEFAULT 0x00 -#define HICN_BUFFER_FLAGS_FACE_IS_APP 0x01 - -STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_PROD_BIT) == - HICN_FACE_FLAGS_APPFACE_PROD, - "HICN_FACE_FLAGS_APPFACE_PROD_BIT and " - "HICN_FACE_FLAGS_APPFACE_PROD must correspond"); - -STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_CONS_BIT) == - HICN_FACE_FLAGS_APPFACE_CONS, - "HICN_FACE_FLAGS_APPFACE_CONS_BIT and " - "HICN_FACE_FLAGS_APPFACE_CONS must correspond"); - -STATIC_ASSERT ( - (HICN_FACE_FLAGS_APPFACE_PROD >> HICN_FACE_FLAGS_APPFACE_PROD_BIT) == - HICN_BUFFER_FLAGS_FACE_IS_APP, - "hicn buffer app flag does not correspond to HICN_FACE_FLAGS_APPFACE_PROD"); - -STATIC_ASSERT ( - (HICN_FACE_FLAGS_APPFACE_CONS >> HICN_FACE_FLAGS_APPFACE_CONS_BIT) == - HICN_BUFFER_FLAGS_FACE_IS_APP, - "hicn buffer app flag does not correspond to HICN_FACE_FLAGS_APPFACE_PROD"); - /** * @brief Definition of the virtual functin table for an hICN FACE DPO. */ @@ -257,6 +219,15 @@ hicn_dpoi_idx_is_valid (hicn_face_id_t face_id) } /** + * @brief Delete a face + * + * @param face_id Id of the face to delete + * @return HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise + * HICN_ERROR_NONE + */ +int hicn_face_del (hicn_face_id_t face_id); + +/** * @brief Add a lock to the face dpo * * @param dpo Pointer to the face dpo @@ -274,12 +245,24 @@ hicn_face_lock_with_id (hicn_face_id_t face_id) * * @param dpo Pointer to the face dpo */ -always_inline void +always_inline int hicn_face_unlock_with_id (hicn_face_id_t face_id) { hicn_face_t *face; face = hicn_dpoi_get_from_idx (face_id); - face->locks--; + + if (face->locks > 0) + { + face->locks--; + + if (face->locks == 0) + { + HICN_DEBUG ("Deleting face %d", face_id); + return hicn_face_del (face_id); + } + } + + return HICN_ERROR_NONE; } /** @@ -324,15 +307,6 @@ u8 *format_hicn_face (u8 *s, va_list *args); u8 *format_hicn_face_all (u8 *s, int n, ...); /** - * @brief Delete a face - * - * @param face_id Id of the face to delete - * @return HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise - * HICN_ERROR_NONE - */ -int hicn_face_del (hicn_face_id_t face_id); - -/** * @bried vector of faces used to collect faces having the same local address * */ @@ -355,17 +329,6 @@ typedef struct hicn_input_faces_s_ } hicn_face_input_faces_t; /** - * Pool containing the vector of possible incoming faces. - */ -extern hicn_face_vec_t *hicn_vec_pool; - -/** - * Hash tables that indexes a face by remote address. For fast lookup when an - * interest arrives. - */ -extern mhash_t hicn_face_vec_hashtb; - -/** * 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 @@ -437,7 +400,7 @@ hicn_face_get (const ip46_address_t *addr, u32 sw_if, mhash_t *hashtb, hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb, &key); - if (dpoi_index != NULL) + if (dpoi_index != NULL && hicn_dpoi_idx_is_valid (*dpoi_index)) { hicn_face_lock_with_id (*dpoi_index); return hicn_dpoi_get_from_idx (*dpoi_index); @@ -467,7 +430,7 @@ hicn_face_get_with_dpo (const ip46_address_t *addr, u32 sw_if, hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb, &key); - if (dpoi_index != NULL) + if (dpoi_index != NULL && hicn_dpoi_idx_is_valid (*dpoi_index)) { hicn_face_lock_with_id (*dpoi_index); return hicn_dpoi_get_from_idx (*dpoi_index); @@ -477,28 +440,6 @@ hicn_face_get_with_dpo (const ip46_address_t *addr, u32 sw_if, } /** - * @brief Get the vector of faces from the ip v4 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_input_faces_t * -hicn_face_get_vec (const ip46_address_t *addr, mhash_t *hashtb) -{ - hicn_face_key_t key; - - dpo_id_t dpo = DPO_INVALID; - - hicn_face_get_key (addr, 0, &dpo, &key); - return (hicn_face_input_faces_t *) mhash_get (hashtb, &key); -} - -/** * @brief Create a new face ip. API for other modules (e.g., routing) * * @param dpo_nh dpo contained in the face that points to the next node in @@ -512,7 +453,7 @@ hicn_face_get_vec (const ip46_address_t *addr, mhash_t *hashtb) * reachable ip address, otherwise HICN_ERROR_NONE */ 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); + int sw_if, hicn_face_id_t *pfaceid, dpo_proto_t dpo_proto); /** * @brief Create a new incomplete face ip. (Meant to be used by the data plane) @@ -525,8 +466,8 @@ int hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address, * reachable ip address, otherwise HICN_ERROR_NONE */ always_inline void -hicn_iface_add (ip46_address_t *nat_address, int sw_if, - hicn_face_id_t *pfaceid, dpo_proto_t proto, u32 adj_index) +hicn_iface_add (const ip46_address_t *nat_address, int sw_if, + hicn_face_id_t *pfaceid, u32 adj_index, u8 flags) { hicn_face_t *face; pool_get (hicn_dpoi_face_pool, face); @@ -534,16 +475,19 @@ hicn_iface_add (ip46_address_t *nat_address, int sw_if, clib_memcpy (&(face->nat_addr), nat_address, sizeof (ip46_address_t)); face->sw_if = sw_if; - face->dpo.dpoi_type = DPO_FIRST; - face->dpo.dpoi_proto = DPO_PROTO_NONE; + face->dpo = (dpo_id_t) DPO_INVALID; face->dpo.dpoi_index = adj_index; - face->dpo.dpoi_next_node = 0; + + hicn_face_key_t key; + hicn_face_get_key (nat_address, sw_if, &face->dpo, &key); + + face->iface_next = 1; + face->pl_id = pl_index++; face->flags = HICN_FACE_FLAGS_IFACE; + face->flags |= flags; face->locks = 1; - hicn_face_key_t key; - hicn_face_get_key (nat_address, sw_if, &face->dpo, &key); *pfaceid = hicn_dpoi_get_index (face); mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, 0); @@ -560,91 +504,46 @@ hicn_iface_add (ip46_address_t *nat_address, int sw_if, * ****/ /** - * @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. + * @brief Call back to get the adj of the tunnel */ -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) +static adj_walk_rc_t +hicn4_iface_adj_walk_cb (adj_index_t ai, void *ctx) { - 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; + hicn_face_t *face = (hicn_face_t *) ctx; - *face_id = in_faces_vec->face_id; + dpo_set (&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai); + adj_nbr_midchain_stack (ai, &face->dpo); - return HICN_ERROR_NONE; + return (ADJ_WALK_RC_CONTINUE); } -/** - * @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_ip4_find (hicn_face_id_t *index, u8 *hicnb_flags, + const ip4_address_t *nat_addr, u32 sw_if, u32 adj_index, + u32 node_index) { - 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; + int ret = HICN_ERROR_FACE_NOT_FOUND; + hicn_face_id_t face_id; - return HICN_ERROR_NONE; -} + /*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 ((const ip46_address_t *) nat_addr, sw_if, + &hicn_face_hashtb, adj_index); -/** - * @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) -{ + if (face != NULL) + { + /* unlock the face. We don't take a lock on each interest we receive */ + face_id = hicn_dpoi_get_index (face); + hicn_face_unlock_with_id (face_id); - hicn_face_t *face = (hicn_face_t *) ctx; + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *index = face_id; - dpo_set (&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai); - adj_nbr_midchain_stack (ai, &face->dpo); + ret = HICN_ERROR_FACE_ALREADY_CREATED; + } - return (ADJ_WALK_RC_CONTINUE); + return ret; } /** @@ -658,31 +557,34 @@ hicn4_iface_adj_walk_cb (adj_index_t ai, void *ctx) * @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) +always_inline int +hicn_face_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); + int ret = HICN_ERROR_NONE; + hicn_face_t *face = NULL; - /* if the face exists, it adds a lock */ - hicn_face_t *face = - hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index); + ret = hicn_face_ip4_find (index, hicnb_flags, nat_addr, sw_if, adj_index, + node_index); - if (face == NULL) + if (ret == HICN_ERROR_FACE_NOT_FOUND) { + ip46_address_t ip_address = { 0 }; + ip46_address_set_ip4 (&ip_address, nat_addr); + hicn_face_id_t idx; - hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index); + u8 face_flags = *hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL ? + HICN_FACE_FLAGS_UDP4 : + *hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL ? + HICN_FACE_FLAGS_UDP6 : + 0; + + hicn_iface_add (&ip_address, sw_if, &idx, adj_index, face_flags); 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; + face->iface_next = node_index; /* if (nat_addr->as_u32 == 0) */ /* { */ @@ -691,23 +593,12 @@ hicn_iface_ip4_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags, /* } */ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= HICN_BUFFER_FLAGS_NEW_FACE; *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); + return ret; } /** @@ -723,13 +614,39 @@ hicn6_iface_adj_walk_cb (adj_index_t ai, void *ctx) 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); + dpo_set (&face->dpo, DPO_ADJACENCY_MIDCHAIN, + (dpo_proto_t) adj->ia_nh_proto, ai); adj_nbr_midchain_stack (ai, &face->dpo); } return (ADJ_WALK_RC_CONTINUE); } +always_inline int +hicn_face_ip6_find (hicn_face_id_t *index, u8 *hicnb_flags, + const ip6_address_t *nat_addr, u32 sw_if, u32 adj_index, + u32 node_index) +{ + int ret = HICN_ERROR_FACE_NOT_FOUND; + hicn_face_id_t face_id; + + hicn_face_t *face = hicn_face_get ((const ip46_address_t *) nat_addr, sw_if, + &hicn_face_hashtb, adj_index); + + if (face != NULL) + { + /* unlock the face. We don't take a lock on each interest we receive */ + face_id = hicn_dpoi_get_index (face); + hicn_face_unlock_with_id (face_id); + *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *index = face_id; + + ret = HICN_ERROR_FACE_ALREADY_CREATED; + } + + return ret; +} + /** * @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. @@ -741,51 +658,59 @@ hicn6_iface_adj_walk_cb (adj_index_t ai, void *ctx) * @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) +always_inline int +hicn_face_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); + int ret = HICN_ERROR_NONE; + hicn_face_t *face = NULL; - if (face == NULL) + ret = hicn_face_ip6_find (index, hicnb_flags, nat_addr, sw_if, adj_index, + node_index); + + if (ret == HICN_ERROR_FACE_NOT_FOUND) { + ip46_address_t ip_address = { 0 }; + ip46_address_set_ip6 (&ip_address, nat_addr); hicn_face_id_t idx; - hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, - adj_index); + u8 face_flags = *hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL ? + HICN_FACE_FLAGS_UDP4 : + *hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL ? + HICN_FACE_FLAGS_UDP6 : + 0; - face = hicn_dpoi_get_from_idx (idx); + hicn_iface_add ((const ip46_address_t *) nat_addr, sw_if, &idx, + adj_index, face_flags); - 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; + face = hicn_dpoi_get_from_idx (idx); + face->iface_next = node_index; adj_nbr_walk (face->sw_if, FIB_PROTOCOL_IP6, hicn6_iface_adj_walk_cb, face); - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - + *hicnb_flags = HICN_BUFFER_FLAGS_NEW_FACE; *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; + return ret; +} + +/** + * @brief Check if a face is an application face + * + * @param face_id: The id of the face + * @return 1 if application face, 0 otherwise + */ +always_inline int +hicn_face_is_local (hicn_face_id_t face_id) +{ + hicn_face_t *face; + face = hicn_dpoi_get_from_idx (face_id); + ASSERT (face != NULL); - *index = hicn_dpoi_get_index (face); + return face->flags & HICN_FACE_FLAGS_APPFACE_PROD || + face->flags & HICN_FACE_FLAGS_APPFACE_CONS; } #endif // __HICN_FACE_H__ diff --git a/hicn-plugin/src/faces/face_cli.c b/hicn-plugin/src/faces/face_cli.c index a4092e6f4..1c1501478 100644 --- a/hicn-plugin/src/faces/face_cli.c +++ b/hicn-plugin/src/faces/face_cli.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -82,12 +82,12 @@ hicn_face_cli_show_command_fn (vlib_main_t *vm, unformat_input_t *main_input, HICN_FACE_CTRX_STRING[i]); if (n) - _vec_len (n) = 0; + vec_set_len (n, 0); n = format (n, "packets"); s = format (s, "%U%-16v%16Ld", format_white_space, 30 - strlen (HICN_FACE_CTRX_STRING[i]), n, v.packets); - _vec_len (n) = 0; + vec_set_len (n, 0); n = format (n, "bytes"); s = format (s, "\n%U%-16v%16Ld\n", format_white_space, indent + 30, n, v.bytes); @@ -120,13 +120,13 @@ hicn_face_cli_show_command_fn (vlib_main_t *vm, unformat_input_t *main_input, HICN_FACE_CTRX_STRING[i]); if (n) - _vec_len (n) = 0; + vec_set_len (n, 0); n = format (n, "packets"); s = format (s, "%U%-16v%16Ld", format_white_space, 30 - strlen (HICN_FACE_CTRX_STRING[i]), n, v.packets); - _vec_len (n) = 0; + vec_set_len (n, 0); n = format (n, "bytes"); s = format (s, "\n%U%-16v%16Ld\n", format_white_space, @@ -158,13 +158,13 @@ hicn_face_cli_show_command_fn (vlib_main_t *vm, unformat_input_t *main_input, HICN_FACE_CTRX_STRING[i]); if (n) - _vec_len (n) = 0; + vec_set_len (n, 0); n = format (n, "packets"); s = format (s, "%U%-16v%16Ld", format_white_space, 30 - strlen (HICN_FACE_CTRX_STRING[i]), n, v.packets); - _vec_len (n) = 0; + vec_set_len (n, 0); n = format (n, "bytes"); s = format (s, "\n%U%-16v%16Ld\n", format_white_space, indent + 30, n, v.bytes); diff --git a/hicn-plugin/src/faces/face_flags.h b/hicn-plugin/src/faces/face_flags.h new file mode 100644 index 000000000..880d3b558 --- /dev/null +++ b/hicn-plugin/src/faces/face_flags.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 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_FACE_FLAGS_H__ +#define __HICN_FACE_FLAGS_H__ + +/* 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 + the FIB. */ +#define foreach_face_flag \ + _ (0, FACE, "face") \ + _ (1, IFACE, "iface") \ + _ (2, APPFACE_PROD, "face is producer face") \ + _ (3, APPFACE_CONS, "face is consumer face") \ + _ (4, DELETED, "face is deleted") \ + _ (5, UDP4, "face is udp4") \ + _ (6, UDP6, "face is udp6") + +enum +{ + HICN_FACE_FLAGS_DEFAULT = 0, +#define _(a, b, c) HICN_FACE_FLAGS_##b = (1 << a), + foreach_face_flag +#undef _ +}; + +#endif /* __HICN_FACE_FLAGS_H__ */
\ No newline at end of file diff --git a/hicn-plugin/src/faces/face_node.c b/hicn-plugin/src/faces/face_node.c index 5fe682bd0..2cfb9c7dc 100644 --- a/hicn-plugin/src/faces/face_node.c +++ b/hicn-plugin/src/faces/face_node.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -23,6 +23,10 @@ #include "../cache_policies/cs_lru.h" #include "../infra.h" #include "../hicn.h" +#include "../parser.h" + +#include <hicn/error.h> +#include <hicn/util/ip_address.h> /** * @File @@ -56,6 +60,7 @@ typedef struct u32 next_index; u32 sw_if_index; u8 pkt_type; + hicn_error_t error; u8 packet_data[60]; } hicn4_face_input_trace_t; @@ -73,6 +78,7 @@ typedef struct u32 next_index; u32 sw_if_index; u8 pkt_type; + hicn_error_t error; u8 packet_data[60]; } hicn6_face_input_trace_t; @@ -86,8 +92,9 @@ typedef enum #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 + +#define NEXT_DATA_IP4 HICN4_FACE_INPUT_NEXT_DATA +#define NEXT_DATA_IP6 HICN6_FACE_INPUT_NEXT_DATA #define NEXT_ERROR_DROP_IP4 HICN4_FACE_INPUT_NEXT_ERROR_DROP #define NEXT_ERROR_DROP_IP6 HICN6_FACE_INPUT_NEXT_ERROR_DROP @@ -95,9 +102,6 @@ typedef enum #define IP_HEADER_4 ip4_header_t #define IP_HEADER_6 ip6_header_t -#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 @@ -111,11 +115,13 @@ typedef enum do \ { \ vlib_buffer_t *b0; \ - u32 bi0; \ + u32 bi0, sw_if0; \ u32 next0 = NEXT_ERROR_DROP_IP##ipv; \ + u8 is_mapme0; \ IP_HEADER_##ipv *ip_hdr = NULL; \ hicn_buffer_t *hicnb0; \ - int ret; \ + int from_tunnel0; \ + int ret0 = HICN_ERROR_NONE; \ /* Prefetch for next iteration. */ \ if (n_left_from > 1) \ { \ @@ -136,33 +142,53 @@ typedef enum hicnb0 = hicn_get_buffer (b0); \ ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current (b0); \ \ - u8 is_icmp = ip_hdr->protocol == IPPROTO_ICMPV##ipv; \ - \ - next0 = \ - is_icmp * NEXT_MAPME_IP##ipv + (1 - is_icmp) * NEXT_DATA_IP##ipv; \ + /* Parse packet and cache useful info in opaque2 */ \ + ret0 = hicn_data_parse_pkt (b0, vlib_buffer_length_in_chain (vm, b0)); \ + is_mapme0 = hicn_packet_get_type (&hicn_get_buffer (b0)->pkbuf) == \ + HICN_PACKET_TYPE_MAPME; \ \ - ret = LOCK_DPO_FACE_IP##ipv (&(hicnb0->face_id), \ - &(hicnb0->in_faces_vec_id), \ - &hicnb0->flags, &(ip_hdr->dst_address)); \ + ret0 = (ret0 == HICN_ERROR_NONE) || \ + (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \ \ - if (PREDICT_FALSE (ret != HICN_ERROR_NONE)) \ - next0 = NEXT_ERROR_DROP_IP##ipv; \ + /* If parsing is ok, send packet to next node */ \ + if (PREDICT_FALSE (!ret0)) \ + { \ + next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + } \ else \ { \ - vlib_increment_combined_counter ( \ - &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, \ - HICN_FACE_COUNTERS_DATA_RX, 1, \ - vlib_buffer_length_in_chain (vm, b0)); \ - stats.pkts_data_count += 1; \ + next0 = is_mapme0 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme0) * NEXT_DATA_IP##ipv; \ + from_tunnel0 = \ + (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \ + hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \ + sw_if0 = \ + (from_tunnel0) * ~0 + \ + (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + ret0 = hicn_face_ip##ipv##_find ( \ + &hicnb0->face_id, &hicnb0->flags, &ip_hdr->dst_address, sw_if0, \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX], \ + /* Should not be used */ ~0); \ + /* Make sure the face is not created here */ \ + if (PREDICT_FALSE (ret0 == HICN_ERROR_FACE_NOT_FOUND)) \ + { \ + next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + } \ } \ \ + vlib_increment_combined_counter ( \ + &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, \ + HICN_FACE_COUNTERS_DATA_RX, 1, vlib_buffer_length_in_chain (vm, b0)); \ + stats.pkts_data_count += 1; \ + \ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \ (b0->flags & VLIB_BUFFER_IS_TRACED))) \ { \ TRACE_INPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + t->error = ret0; \ t->next_index = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ @@ -178,13 +204,15 @@ typedef enum do \ { \ vlib_buffer_t *b0, *b1; \ - u32 bi0, bi1; \ + u32 bi0, bi1, sw_if0, sw_if1; \ u32 next0 = NEXT_ERROR_DROP_IP##ipv; \ u32 next1 = NEXT_ERROR_DROP_IP##ipv; \ + u8 is_mapme0, is_mapme1; \ IP_HEADER_##ipv *ip_hdr0 = NULL; \ IP_HEADER_##ipv *ip_hdr1 = NULL; \ hicn_buffer_t *hicnb0; \ hicn_buffer_t *hicnb1; \ + int from_tunnel0, from_tunnel1; \ int ret0, ret1; \ /* Prefetch for next iteration. */ \ { \ @@ -213,52 +241,129 @@ typedef enum ip_hdr0 = (IP_HEADER_##ipv *) vlib_buffer_get_current (b0); \ ip_hdr1 = (IP_HEADER_##ipv *) vlib_buffer_get_current (b1); \ \ - u8 is_icmp0 = ip_hdr0->protocol == IPPROTO_ICMPV##ipv; \ - u8 is_icmp1 = ip_hdr1->protocol == IPPROTO_ICMPV##ipv; \ - \ - next0 = \ - is_icmp0 * NEXT_MAPME_IP##ipv + (1 - is_icmp0) * NEXT_DATA_IP##ipv; \ - \ - next1 = \ - is_icmp1 * NEXT_MAPME_IP##ipv + (1 - is_icmp1) * NEXT_DATA_IP##ipv; \ - \ - ret0 = LOCK_DPO_FACE_IP##ipv (&(hicnb0->face_id), \ - &(hicnb0->in_faces_vec_id), \ - &hicnb0->flags, &(ip_hdr0->dst_address)); \ - \ - ret1 = LOCK_DPO_FACE_IP##ipv (&(hicnb1->face_id), \ - &(hicnb1->in_faces_vec_id), \ - &hicnb1->flags, &(ip_hdr1->dst_address)); \ - \ - if (PREDICT_FALSE (ret0 != HICN_ERROR_NONE)) \ - next0 = NEXT_ERROR_DROP_IP##ipv; \ - else \ + /* Parse packet and cache useful info in opaque2 */ \ + ret0 = hicn_data_parse_pkt (b0, vlib_buffer_length_in_chain (vm, b0)); \ + ret1 = hicn_data_parse_pkt (b1, vlib_buffer_length_in_chain (vm, b1)); \ + is_mapme0 = hicn_packet_get_type (&hicn_get_buffer (b0)->pkbuf) == \ + HICN_PACKET_TYPE_MAPME; \ + is_mapme1 = hicn_packet_get_type (&hicn_get_buffer (b1)->pkbuf) == \ + HICN_PACKET_TYPE_MAPME; \ + ret0 = (ret0 == HICN_ERROR_NONE) || \ + (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \ + ret1 = (ret1 == HICN_ERROR_NONE) || \ + (ret1 == HICN_ERROR_PARSER_MAPME_PACKET); \ + if (PREDICT_TRUE (ret0 && ret1)) \ { \ - vlib_increment_combined_counter ( \ - &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, \ - HICN_FACE_COUNTERS_DATA_RX, 1, \ - vlib_buffer_length_in_chain (vm, b0)); \ - stats.pkts_data_count += 1; \ + next0 = is_mapme0 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme0) * NEXT_DATA_IP##ipv; \ + \ + next1 = is_mapme1 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme1) * NEXT_DATA_IP##ipv; \ + \ + from_tunnel0 = \ + (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \ + hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \ + sw_if0 = \ + (from_tunnel0) * ~0 + \ + (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + ret0 = hicn_face_ip##ipv##_find ( \ + &hicnb0->face_id, &hicnb0->flags, &ip_hdr0->dst_address, sw_if0, \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX], \ + /* Should not be used */ ~0); \ + /* Make sure the face is not created here */ \ + if (PREDICT_FALSE (ret0 == HICN_ERROR_FACE_NOT_FOUND)) \ + { \ + next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + } \ + \ + from_tunnel1 = \ + (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \ + hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \ + sw_if1 = \ + (from_tunnel1) * ~0 + \ + (1 - from_tunnel1) * vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ + ret1 = hicn_face_ip##ipv##_find ( \ + &hicnb1->face_id, &hicnb1->flags, &ip_hdr1->dst_address, sw_if1, \ + vnet_buffer (b1)->ip.adj_index[VLIB_RX], \ + /* Should not be used */ ~0); \ + /* Make sure the face is not created here */ \ + if (PREDICT_FALSE (ret1 == HICN_ERROR_FACE_NOT_FOUND)) \ + { \ + next1 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + } \ + } \ + else if (ret0 && !ret1) \ + { \ + next1 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + from_tunnel0 = \ + (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \ + hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \ + sw_if0 = \ + (from_tunnel0) * ~0 + \ + (1 - from_tunnel0) * vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + ret0 = hicn_face_ip##ipv##_find ( \ + &hicnb0->face_id, &hicnb0->flags, &ip_hdr0->dst_address, sw_if0, \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX], \ + /* Should not be used */ ~0); \ + /* Make sure the face is not created here */ \ + if (PREDICT_FALSE (ret0 == HICN_ERROR_FACE_NOT_FOUND)) \ + { \ + next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + } \ + else \ + { \ + next0 = is_mapme0 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme0) * NEXT_DATA_IP##ipv; \ + } \ + } \ + else if (!ret0 && ret1) \ + { \ + next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + from_tunnel1 = \ + (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL || \ + hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) > 0; \ + sw_if1 = \ + (from_tunnel1) * ~0 + \ + (1 - from_tunnel1) * vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ + ret1 = hicn_face_ip##ipv##_find ( \ + &hicnb1->face_id, &hicnb1->flags, &ip_hdr1->dst_address, sw_if1, \ + vnet_buffer (b1)->ip.adj_index[VLIB_RX], \ + /* Should not be used */ ~0); \ + /* Make sure the face is not created here */ \ + if (PREDICT_FALSE (ret1 == HICN_ERROR_FACE_NOT_FOUND)) \ + { \ + next1 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + } \ + else \ + { \ + next1 = is_mapme1 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme1) * NEXT_DATA_IP##ipv; \ + } \ } \ - \ - if (PREDICT_FALSE (ret1 != HICN_ERROR_NONE)) \ - next1 = NEXT_ERROR_DROP_IP##ipv; \ else \ { \ - vlib_increment_combined_counter ( \ - &counters[hicnb1->face_id * HICN_N_COUNTER], thread_index, \ - HICN_FACE_COUNTERS_DATA_RX, 1, \ - vlib_buffer_length_in_chain (vm, b1)); \ - stats.pkts_data_count += 1; \ + next0 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ + next1 = HICN##ipv##_FACE_INPUT_NEXT_ERROR_DROP; \ } \ \ + vlib_increment_combined_counter ( \ + &counters[hicnb0->face_id * HICN_N_COUNTER], thread_index, \ + HICN_FACE_COUNTERS_DATA_RX, 1, vlib_buffer_length_in_chain (vm, b0)); \ + stats.pkts_data_count += 1; \ + \ + vlib_increment_combined_counter ( \ + &counters[hicnb1->face_id * HICN_N_COUNTER], thread_index, \ + HICN_FACE_COUNTERS_DATA_RX, 1, vlib_buffer_length_in_chain (vm, b1)); \ + stats.pkts_data_count += 1; \ + \ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \ (b0->flags & VLIB_BUFFER_IS_TRACED))) \ { \ TRACE_INPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + t->error = ret0; \ t->next_index = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ @@ -269,8 +374,9 @@ typedef enum { \ TRACE_INPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b1, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ + t->error = ret1; \ t->next_index = next1; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \ sizeof (t->packet_data)); \ @@ -437,6 +543,7 @@ VLIB_REGISTER_NODE(hicn6_face_input_node) = typedef enum { + HICN4_FACE_OUTPUT_NEXT_ERROR_DROP, HICN4_FACE_OUTPUT_NEXT_ECHO_REPLY, HICN4_FACE_OUTPUT_NEXT_UDP4_ENCAP, HICN4_FACE_OUTPUT_NEXT_UDP6_ENCAP, @@ -445,86 +552,13 @@ typedef enum typedef enum { + HICN6_FACE_OUTPUT_NEXT_ERROR_DROP, HICN6_FACE_OUTPUT_NEXT_ECHO_REPLY, HICN6_FACE_OUTPUT_NEXT_UDP4_ENCAP, HICN6_FACE_OUTPUT_NEXT_UDP6_ENCAP, HICN6_FACE_OUTPUT_N_NEXT, } hicn6_face_output_next_t; -/* static_always_inline void */ -/* hicn_reply_probe_v4 (vlib_buffer_t * b, hicn_face_t * face) */ -/* { */ -/* hicn_header_t *h0 = vlib_buffer_get_current (b); */ -/* hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data); */ -/* h0->v4.ip.saddr = h0->v4.ip.daddr; */ -/* h0->v4.ip.daddr = face_ip->local_addr.ip4; */ -/* vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if; */ - -/* u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t) + - * sizeof(u16)); */ -/* u16 dst_port = *dst_port_ptr; */ -/* u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip4_header_t)); */ - -/* *dst_port_ptr = *src_port_ptr; */ -/* *src_port_ptr = dst_port; */ - -/* hicn_type_t type = hicn_get_buffer (b)->type; */ -/* hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0); */ -/* } */ - -/* static_always_inline void */ -/* hicn_reply_probe_v6 (vlib_buffer_t * b, hicn_face_t * face) */ -/* { */ -/* hicn_header_t *h0 = vlib_buffer_get_current (b); */ -/* hicn_face_ip_t * face_ip = (hicn_face_ip_t *)(&face->data); */ -/* h0->v6.ip.saddr = h0->v6.ip.daddr; */ -/* h0->v6.ip.daddr = face_ip->local_addr.ip6; */ -/* vnet_buffer (b)->sw_if_index[VLIB_RX] = face->shared.sw_if; */ - -/* u16 * dst_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t) + - * sizeof(u16)); */ -/* u16 dst_port = *dst_port_ptr; */ -/* u16 * src_port_ptr = (u16 *)(((u8*)h0) + sizeof(ip6_header_t)); */ - -/* *dst_port_ptr = *src_port_ptr; */ -/* *src_port_ptr = dst_port; */ - -/* hicn_type_t type = hicn_get_buffer (b)->type; */ -/* hicn_ops_vft[type.l1]->set_lifetime (type, &h0->protocol, 0); */ - -/* } */ - -/* static_always_inline u32 */ -/* hicn_face_match_probe (vlib_buffer_t * b, hicn_face_t * face, u32 * next) */ -/* { */ - -/* u8 *ptr = vlib_buffer_get_current (b); */ -/* u8 v = *ptr & 0xf0; */ -/* u8 res = 0; */ - -/* if ( v == 0x40 ) */ -/* { */ -/* u16 * dst_port = (u16 *)(ptr + sizeof(ip4_header_t) + sizeof(u16)); */ -/* if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT)) */ -/* { */ -/* hicn_reply_probe_v6(b, face); */ -/* *next = HICN4_FACE_NEXT_ECHO_REPLY; */ -/* res = 1; */ -/* } */ -/* } */ -/* else if ( v == 0x60 ) */ -/* { */ -/* u16 * dst_port = (u16 *)(ptr + sizeof(ip6_header_t) + sizeof(u16)); */ -/* if (*dst_port == clib_net_to_host_u16(DEFAULT_PROBING_PORT)) */ -/* { */ -/* hicn_reply_probe_v6(b, face); */ -/* *next = HICN6_FACE_NEXT_ECHO_REPLY; */ -/* res = 1; */ -/* } */ -/* } */ -/* return res; */ -/* } */ - static inline void hicn_face_rewrite_interest (vlib_main_t *vm, vlib_buffer_t *b0, hicn_face_t *face, u32 *next) @@ -534,19 +568,20 @@ hicn_face_rewrite_interest (vlib_main_t *vm, vlib_buffer_t *b0, * hicn_face_match_probe(b0, face, next)) */ /* return; */ - hicn_header_t *hicn = vlib_buffer_get_current (b0); + hicn_packet_buffer_t *pkbuf = &hicn_get_buffer (b0)->pkbuf; - // hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; + u8 is_v4 = ip46_address_is_ip4 (&face->nat_addr) && + !ip6_address_is_loopback (&face->nat_addr.ip6); - ip46_address_t temp_addr; - ip46_address_reset (&temp_addr); - hicn_type_t type = hicn_get_buffer (b0)->type; - int ret = hicn_ops_vft[type.l1]->rewrite_interest ( - type, &hicn->protocol, &face->nat_addr, &temp_addr); + // hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; + hicn_ip_address_t temp_addr; + ip46_address_reset (&(temp_addr.as_ip46)); + hicn_ip_address_t *face_nat_addr = (hicn_ip_address_t *) &face->nat_addr; + int ret = hicn_interest_rewrite (pkbuf, face_nat_addr, &temp_addr); if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED) { - ensure_offload_flags (b0, ip46_address_is_ip4 (&face->nat_addr)); + ensure_offload_flags (b0, is_v4); } ASSERT (face->flags & HICN_FACE_FLAGS_FACE); @@ -571,6 +606,7 @@ static char *hicn6_face_output_error_strings[] = { typedef struct { u32 next_index; + u32 next_node; u32 sw_if_index; u8 pkt_type; u8 packet_data[60]; @@ -580,6 +616,7 @@ typedef struct typedef struct { u32 next_index; + u32 next_node; u32 sw_if_index; u8 pkt_type; u8 packet_data[60]; @@ -593,8 +630,8 @@ typedef struct { \ vlib_buffer_t *b0; \ u32 bi0; \ - u32 next0 = ~0; \ - hicn_face_t *face; \ + u32 next0 = HICN##ipv##_FACE_OUTPUT_NEXT_ERROR_DROP; \ + hicn_face_t *face = NULL; \ \ /* Prefetch for next iteration. */ \ if (n_left_from > 1) \ @@ -615,9 +652,10 @@ typedef struct b0 = vlib_get_buffer (vm, bi0); \ \ hicn_face_id_t face_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \ - face = hicn_dpoi_get_from_idx (face_id); \ + if (PREDICT_TRUE (hicn_dpoi_idx_is_valid (face_id))) \ + face = hicn_dpoi_get_from_idx (face_id); \ \ - if (PREDICT_TRUE (face != NULL)) \ + if (PREDICT_TRUE (face != NULL) && face->flags & HICN_FACE_FLAGS_FACE) \ { \ hicn_face_rewrite_interest (vm, b0, face, &next0); \ stats.pkts_interest_count += 1; \ @@ -632,9 +670,10 @@ typedef struct { \ TRACE_OUTPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ - t->next_index = next0; \ + t->next_index = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \ + t->next_node = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ } \ @@ -650,9 +689,9 @@ typedef struct { \ vlib_buffer_t *b0, *b1; \ u32 bi0, bi1; \ - u32 next0 = ~0; \ - u32 next1 = ~0; \ - hicn_face_t *face0, *face1; \ + u32 next0 = HICN##ipv##_FACE_OUTPUT_NEXT_ERROR_DROP; \ + u32 next1 = HICN##ipv##_FACE_OUTPUT_NEXT_ERROR_DROP; \ + hicn_face_t *face0 = NULL, *face1 = NULL; \ \ /* Prefetch for next iteration. */ \ { \ @@ -679,10 +718,13 @@ typedef struct \ hicn_face_id_t face_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \ hicn_face_id_t face_id1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \ - face0 = hicn_dpoi_get_from_idx (face_id0); \ - face1 = hicn_dpoi_get_from_idx (face_id1); \ + if (PREDICT_TRUE (hicn_dpoi_idx_is_valid (face_id0))) \ + face0 = hicn_dpoi_get_from_idx (face_id0); \ + if (PREDICT_TRUE (hicn_dpoi_idx_is_valid (face_id1))) \ + face1 = hicn_dpoi_get_from_idx (face_id1); \ \ - if (PREDICT_TRUE (face0 != NULL)) \ + if (PREDICT_TRUE (face0 != NULL) && \ + face0->flags & HICN_FACE_FLAGS_FACE) \ { \ hicn_face_rewrite_interest (vm, b0, face0, &next0); \ stats.pkts_interest_count += 1; \ @@ -692,7 +734,8 @@ typedef struct vlib_buffer_length_in_chain (vm, b0)); \ } \ \ - if (PREDICT_TRUE (face1 != NULL)) \ + if (PREDICT_TRUE (face1 != NULL) && \ + face1->flags & HICN_FACE_FLAGS_FACE) \ { \ hicn_face_rewrite_interest (vm, b1, face1, &next1); \ stats.pkts_interest_count += 1; \ @@ -707,9 +750,10 @@ typedef struct { \ TRACE_OUTPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ - t->next_index = next0; \ + t->next_index = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \ + t->next_node = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ } \ @@ -719,13 +763,13 @@ typedef struct { \ TRACE_OUTPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b1, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ - t->next_index = next1; \ + t->next_index = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \ + t->next_node = next1; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \ sizeof (t->packet_data)); \ } \ - \ /* Verify speculative enqueue, maybe switch current next frame */ \ vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, \ n_left_to_next, bi0, bi1, next0, \ @@ -778,8 +822,10 @@ hicn4_face_output_format_trace (u8 *s, va_list *args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); hicn4_face_output_trace_t *t = va_arg (*args, hicn4_face_output_trace_t *); - s = format (s, "FACE_IP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U", - (int) t->pkt_type, t->sw_if_index, t->next_index, + s = format (s, + "FACE_IP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d, next " + "node: %d\n%U", + (int) t->pkt_type, t->sw_if_index, t->next_index, t->next_node, format_ip4_header, t->packet_data, sizeof (t->packet_data)); return (s); } @@ -795,11 +841,7 @@ VLIB_REGISTER_NODE (hicn4_face_output_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN (hicn4_face_output_error_strings), .error_strings = hicn4_face_output_error_strings, - .n_next_nodes = HICN4_FACE_OUTPUT_N_NEXT, - /* Reusing the list of nodes from lookup to be compatible with arp */ - .next_nodes = { [HICN4_FACE_OUTPUT_NEXT_ECHO_REPLY] = "hicn4-face-input", - [HICN4_FACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap", - [HICN4_FACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" } + .sibling_of = "ip4-lookup", }; static uword @@ -847,8 +889,10 @@ hicn6_face_output_format_trace (u8 *s, va_list *args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); hicn6_face_output_trace_t *t = va_arg (*args, hicn6_face_output_trace_t *); - s = format (s, "FACE_IP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U", - (int) t->pkt_type, t->sw_if_index, t->next_index, + s = format (s, + "FACE_IP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d, next " + "node: %d\n%U", + (int) t->pkt_type, t->sw_if_index, t->next_index, t->next_node, format_ip6_header, t->packet_data, sizeof (t->packet_data)); return (s); } @@ -864,12 +908,7 @@ VLIB_REGISTER_NODE (hicn6_face_output_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN (hicn6_face_output_error_strings), .error_strings = hicn6_face_output_error_strings, - .n_next_nodes = HICN6_FACE_OUTPUT_N_NEXT, - /* Reusing the list of nodes from lookup to be compatible with neighbour - discovery */ - .next_nodes = { [HICN6_FACE_OUTPUT_NEXT_ECHO_REPLY] = "hicn6-face-input", - [HICN6_FACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap", - [HICN6_FACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" } + .sibling_of = "ip6-lookup", }; /* diff --git a/hicn-plugin/src/faces/face_node.h b/hicn-plugin/src/faces/face_node.h index 3b38e71b3..70daa1393 100644 --- a/hicn-plugin/src/faces/face_node.h +++ b/hicn-plugin/src/faces/face_node.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Cisco and/or its affiliates. + * Copyright (c) 2021 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: diff --git a/hicn-plugin/src/faces/iface_node.c b/hicn-plugin/src/faces/iface_node.c index bf9c56515..8b74c6c25 100644 --- a/hicn-plugin/src/faces/iface_node.c +++ b/hicn-plugin/src/faces/iface_node.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2022 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: @@ -19,6 +19,11 @@ #include "../hicn.h" #include "../infra.h" #include "../cache_policies/cs_lru.h" +#include "../parser.h" +#include "iface_node.h" + +#include <hicn/error.h> +#include <hicn/util/ip_address.h> /** * @File @@ -52,12 +57,14 @@ typedef struct u32 next_index; u32 sw_if_index; u8 pkt_type; + hicn_error_t error; u8 packet_data[60]; } hicn4_iface_input_trace_t; typedef enum { HICN4_IFACE_INPUT_NEXT_INTEREST, + HICN4_IFACE_INPUT_NEXT_INTEREST_MANIFEST, HICN4_IFACE_INPUT_NEXT_MAPME, HICN4_IFACE_INPUT_NEXT_ERROR_DROP, HICN4_IFACE_INPUT_N_NEXT, @@ -69,12 +76,14 @@ typedef struct u32 next_index; u32 sw_if_index; u8 pkt_type; + hicn_error_t error; u8 packet_data[60]; } hicn6_iface_input_trace_t; typedef enum { HICN6_IFACE_INPUT_NEXT_INTEREST, + HICN6_IFACE_INPUT_NEXT_INTEREST_MANIFEST, HICN6_IFACE_INPUT_NEXT_MAPME, HICN6_IFACE_INPUT_NEXT_ERROR_DROP, HICN6_IFACE_INPUT_N_NEXT, @@ -86,32 +95,8 @@ typedef enum #define NEXT_INTEREST_IP4 HICN4_IFACE_INPUT_NEXT_INTEREST #define NEXT_INTEREST_IP6 HICN6_IFACE_INPUT_NEXT_INTEREST -#define ADDRESS_IP4 \ - ip_interface_address_t *ia = 0; \ - ip4_address_t *local_address = \ - ip4_interface_first_address (&ip4_main, swif, &ia) -#define ADDRESS_IP6 \ - ip6_address_t *local_address = ip6_interface_first_address (&ip6_main, swif) - -#define ADDRESSX2_IP4 \ - ip_interface_address_t *ia0, *ia1; \ - ia0 = ia1 = 0; \ - ip4_address_t *local_address0 = \ - ip4_interface_first_address (&ip4_main, swif0, &ia0); \ - ip4_address_t *local_address1 = \ - ip4_interface_first_address (&ip4_main, swif1, &ia1); - -#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_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 +#define DPO_ADD_LOCK_FACE_IP4 hicn_face_ip4_add_and_lock +#define DPO_ADD_LOCK_FACE_IP6 hicn_face_ip6_add_and_lock #define IP_HEADER_4 ip4_header_t #define IP_HEADER_6 ip6_header_t @@ -142,14 +127,6 @@ typedef struct u8 packet_data[60]; } hicn4_iface_output_trace_t; -typedef enum -{ - HICN4_IFACE_OUTPUT_NEXT_LOOKUP, - HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP, - HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP, - HICN4_IFACE_OUTPUT_N_NEXT, -} hicn4_iface_output_next_t; - /* Trace context struct */ typedef struct { @@ -159,14 +136,6 @@ typedef struct u8 packet_data[60]; } hicn6_iface_output_trace_t; -typedef enum -{ - HICN6_IFACE_OUTPUT_NEXT_LOOKUP, - HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP, - HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP, - HICN6_IFACE_OUTPUT_N_NEXT, -} hicn6_iface_output_next_t; - //#define ERROR_OUTPUT_IP4 HICN4_IFACE_OUTPUT_NEXT_ERROR_DROP //#define ERROR_OUTPUT_IP6 HICN6_IFACE_OUTPUT_NEXT_ERROR_DROP @@ -176,6 +145,9 @@ typedef enum #define NEXT_UDP_ENCAP_IP4 HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP #define NEXT_UDP_ENCAP_IP6 HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP +#define NEXT_PG4 HICN4_IFACE_OUTPUT_NEXT_PG +#define NEXT_PG6 HICN6_IFACE_OUTPUT_NEXT_PG + #define HICN_REWRITE_DATA_IP4 hicn_rewrite_iface_data4 #define HICN_REWRITE_DATA_IP6 hicn_rewrite_iface_data6 @@ -188,9 +160,11 @@ typedef enum do \ { \ vlib_buffer_t *b0; \ - u32 bi0, next0, next_iface0; \ + u32 bi0, next0, next_iface0, sw_if0 = ~0; \ IP_HEADER_##ipv *ip_hdr = NULL; \ hicn_buffer_t *hicnb0; \ + int ret0 = HICN_ERROR_NONE; \ + u8 is_mapme0, is_manifest0; \ /* Prefetch for next iteration. */ \ if (n_left_from > 1) \ { \ @@ -211,33 +185,58 @@ typedef enum hicnb0 = hicn_get_buffer (b0); \ ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current (b0); \ \ - stats.pkts_interest_count += 1; \ - \ - u8 is_icmp = ip_hdr->protocol == IPPROTO_ICMPV##ipv; \ - \ - next0 = \ - is_icmp * NEXT_MAPME_IP##ipv + (1 - is_icmp) * NEXT_INTEREST_IP##ipv; \ - \ - next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \ - \ - if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \ - next_iface0 = NEXT_UDP_ENCAP_IP4; \ - else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \ - next_iface0 = NEXT_UDP_ENCAP_IP6; \ - \ - DPO_ADD_LOCK_IFACE_IP##ipv ( \ - &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr->src_address), \ - vnet_buffer (b0)->sw_if_index[VLIB_RX], \ - vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \ + /* Parse packet and cache useful info in opaque2 */ \ + ret0 = \ + hicn_interest_parse_pkt (b0, vlib_buffer_length_in_chain (vm, b0)); \ + is_mapme0 = hicn_packet_get_type (&hicn_get_buffer (b0)->pkbuf) == \ + HICN_PACKET_TYPE_MAPME; \ + is_manifest0 = hicnb0->payload_type == HPT_MANIFEST; \ + ret0 = (ret0 == HICN_ERROR_NONE) || \ + (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \ + if (PREDICT_FALSE (!ret0)) \ + { \ + next0 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \ + } \ + else \ + { \ + next0 = is_mapme0 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme0) * (NEXT_INTEREST_IP##ipv + is_manifest0); \ + \ + next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \ + sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + \ + if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \ + { \ + next_iface0 = NEXT_UDP_ENCAP_IP4; \ + sw_if0 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX] != \ + ADJ_INDEX_INVALID) \ + { \ + next_iface0 = NEXT_UDP_ENCAP_IP6; \ + sw_if0 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \ + { \ + next_iface0 = NEXT_PG##ipv; \ + } \ + \ + DPO_ADD_LOCK_FACE_IP##ipv ( \ + &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr->src_address), \ + sw_if0, vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \ + } \ \ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \ (b0->flags & VLIB_BUFFER_IS_TRACED))) \ { \ TRACE_INPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ - t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ + t->sw_if_index = sw_if0; \ t->next_index = next0; \ + t->error = ret0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ } \ @@ -257,9 +256,12 @@ typedef enum do \ { \ vlib_buffer_t *b0, *b1; \ - u32 bi0, bi1, next0, next1, next_iface0, next_iface1; \ + u32 bi0, bi1, next0, next1; \ + u32 next_iface0, next_iface1, sw_if0 = ~0, sw_if1 = ~0; \ + u8 is_mapme0, is_mapme1, is_manifest0, is_manifest1; \ IP_HEADER_##ipv *ip_hdr0 = NULL; \ IP_HEADER_##ipv *ip_hdr1 = NULL; \ + int ret0 = HICN_ERROR_NONE, ret1 = HICN_ERROR_NONE; \ hicn_buffer_t *hicnb0, *hicnb1; \ \ /* Prefetch for next iteration. */ \ @@ -290,47 +292,155 @@ typedef enum \ stats.pkts_interest_count += 2; \ \ - u8 is_icmp0 = ip_hdr0->protocol == IPPROTO_ICMPV##ipv; \ - u8 is_icmp1 = ip_hdr1->protocol == IPPROTO_ICMPV##ipv; \ - \ - next0 = is_icmp0 * NEXT_MAPME_IP##ipv + \ - (1 - is_icmp0) * NEXT_INTEREST_IP##ipv; \ - \ - next1 = is_icmp1 * NEXT_MAPME_IP##ipv + \ - (1 - is_icmp1) * NEXT_INTEREST_IP##ipv; \ - \ - next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \ - \ - if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \ - next_iface0 = NEXT_UDP_ENCAP_IP4; \ - else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \ - next_iface0 = NEXT_UDP_ENCAP_IP6; \ - \ - next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \ - \ - if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \ - next_iface1 = NEXT_UDP_ENCAP_IP4; \ - else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \ - next_iface1 = NEXT_UDP_ENCAP_IP6; \ - \ - DPO_ADD_LOCK_IFACE_IP##ipv ( \ - &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), \ - vnet_buffer (b0)->sw_if_index[VLIB_RX], \ - vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \ - \ - DPO_ADD_LOCK_IFACE_IP##ipv ( \ - &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), \ - vnet_buffer (b1)->sw_if_index[VLIB_RX], \ - vnet_buffer (b1)->ip.adj_index[VLIB_RX], next_iface1); \ + /* Parse packet and cache useful info in opaque2 */ \ + ret0 = \ + hicn_interest_parse_pkt (b0, vlib_buffer_length_in_chain (vm, b0)); \ + ret1 = \ + hicn_interest_parse_pkt (b1, vlib_buffer_length_in_chain (vm, b1)); \ + is_mapme0 = hicn_packet_get_type (&hicn_get_buffer (b0)->pkbuf) == \ + HICN_PACKET_TYPE_MAPME; \ + is_mapme1 = hicn_packet_get_type (&hicn_get_buffer (b1)->pkbuf) == \ + HICN_PACKET_TYPE_MAPME; \ + is_manifest0 = hicnb0->payload_type == HPT_MANIFEST; \ + is_manifest1 = hicnb1->payload_type == HPT_MANIFEST; \ + ret0 = (ret0 == HICN_ERROR_NONE) || \ + (ret0 == HICN_ERROR_PARSER_MAPME_PACKET); \ + ret1 = (ret1 == HICN_ERROR_NONE) || \ + (ret1 == HICN_ERROR_PARSER_MAPME_PACKET); \ + \ + if (PREDICT_TRUE (ret0 && ret1)) \ + { \ + next0 = is_mapme0 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme0) * (NEXT_INTEREST_IP##ipv + is_manifest0); \ + \ + next1 = is_mapme1 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme1) * (NEXT_INTEREST_IP##ipv + is_manifest1); \ + \ + next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \ + sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + \ + if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \ + { \ + next_iface0 = NEXT_UDP_ENCAP_IP4; \ + sw_if0 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX] != \ + ADJ_INDEX_INVALID) \ + { \ + next_iface0 = NEXT_UDP_ENCAP_IP6; \ + sw_if0 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \ + { \ + next_iface0 = NEXT_PG##ipv; \ + } \ + \ + next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \ + sw_if1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ + \ + if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \ + vnet_buffer (b1)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \ + { \ + next_iface1 = NEXT_UDP_ENCAP_IP4; \ + sw_if1 = ~0; \ + } \ + else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \ + vnet_buffer (b1)->ip.adj_index[VLIB_RX] != \ + ADJ_INDEX_INVALID) \ + { \ + next_iface1 = NEXT_UDP_ENCAP_IP6; \ + sw_if1 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \ + { \ + next_iface1 = NEXT_PG##ipv; \ + } \ + \ + DPO_ADD_LOCK_FACE_IP##ipv ( \ + &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), \ + sw_if0, vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \ + \ + DPO_ADD_LOCK_FACE_IP##ipv ( \ + &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), \ + sw_if1, vnet_buffer (b1)->ip.adj_index[VLIB_RX], next_iface1); \ + } \ + else if (ret0 && !ret1) \ + { \ + next1 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \ + next0 = is_mapme0 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme0) * NEXT_INTEREST_IP##ipv; \ + next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \ + sw_if0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + \ + if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \ + { \ + next_iface0 = NEXT_UDP_ENCAP_IP4; \ + sw_if0 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \ + vnet_buffer (b0)->ip.adj_index[VLIB_RX] != \ + ADJ_INDEX_INVALID) \ + { \ + next_iface0 = NEXT_UDP_ENCAP_IP6; \ + sw_if0 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \ + { \ + next_iface0 = NEXT_PG##ipv; \ + } \ + \ + DPO_ADD_LOCK_FACE_IP##ipv ( \ + &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), \ + sw_if0, vnet_buffer (b0)->ip.adj_index[VLIB_RX], next_iface0); \ + } \ + else if (!ret0 && ret1) \ + { \ + next0 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \ + next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \ + sw_if1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ + next1 = is_mapme1 * NEXT_MAPME_IP##ipv + \ + (1 - is_mapme1) * NEXT_INTEREST_IP##ipv; \ + \ + if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && \ + vnet_buffer (b1)->ip.adj_index[VLIB_RX] != ADJ_INDEX_INVALID) \ + { \ + next_iface1 = NEXT_UDP_ENCAP_IP4; \ + sw_if1 = ~0; \ + } \ + else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && \ + vnet_buffer (b1)->ip.adj_index[VLIB_RX] != \ + ADJ_INDEX_INVALID) \ + { \ + next_iface1 = NEXT_UDP_ENCAP_IP6; \ + sw_if1 = ~0; \ + } \ + else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_PG) \ + { \ + next_iface1 = NEXT_PG##ipv; \ + } \ + \ + DPO_ADD_LOCK_FACE_IP##ipv ( \ + &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), \ + sw_if1, vnet_buffer (b1)->ip.adj_index[VLIB_RX], next_iface1); \ + } \ + else \ + { \ + next0 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \ + next1 = HICN##ipv##_IFACE_INPUT_NEXT_ERROR_DROP; \ + } \ \ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \ (b0->flags & VLIB_BUFFER_IS_TRACED))) \ { \ TRACE_INPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ - t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ + t->sw_if_index = sw_if0; \ t->next_index = next0; \ + t->error = ret0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ } \ @@ -340,9 +450,10 @@ typedef enum { \ TRACE_INPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b1, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ - t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ + t->sw_if_index = sw_if1; \ t->next_index = next1; \ + t->error = ret1; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \ sizeof (t->packet_data)); \ } \ @@ -409,9 +520,17 @@ hicn4_iface_input_format_trace (u8 *s, va_list *args) CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); hicn4_iface_input_trace_t *t = va_arg (*args, hicn4_iface_input_trace_t *); - s = format (s, "IFACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U", - (int) t->pkt_type, t->sw_if_index, t->next_index, - format_ip4_header, t->packet_data, sizeof (t->packet_data)); + s = format (s, "IFACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d", + (int) t->pkt_type, t->sw_if_index, t->next_index); + + if (t->error) + { + s = format (s, " drop reason: %s", get_error_string (t->error)); + } + + s = format (s, "\n%U", format_ip4_header, t->packet_data, + sizeof (t->packet_data)); + return (s); } @@ -432,6 +551,7 @@ VLIB_REGISTER_NODE (hicn4_iface_input_node) = .next_nodes = { [HICN4_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup", + [HICN4_IFACE_INPUT_NEXT_INTEREST_MANIFEST] = "hicn-interest-manifest-pcslookup", [HICN4_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl", [HICN4_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop", }, @@ -506,6 +626,7 @@ VLIB_REGISTER_NODE (hicn6_iface_input_node) = .next_nodes = { [HICN6_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup", + [HICN6_IFACE_INPUT_NEXT_INTEREST_MANIFEST] = "hicn-interest-manifest-pcslookup", [HICN6_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl", [HICN6_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop", }, @@ -518,6 +639,7 @@ hicn_rewrite_iface_data4 (vlib_main_t *vm, vlib_buffer_t *b0, const hicn_face_t *iface, u32 *next) { ip4_header_t *ip0; + int ret = HICN_ERROR_NONE; /* Get the pointer to the old ip and tcp header */ ip0 = vlib_buffer_get_current (b0); @@ -529,17 +651,21 @@ hicn_rewrite_iface_data4 (vlib_main_t *vm, vlib_buffer_t *b0, ip0->ttl = 254; // FIXME TTL vnet_buffer (b0)->ip.adj_index[VLIB_TX] = iface->dpo.dpoi_index; - *next = iface->dpo.dpoi_next_node; - hicn_header_t *hicn = vlib_buffer_get_current (b0); + *next = iface->iface_next; + + hicn_packet_buffer_t *pkbuf = &hicn_get_buffer (b0)->pkbuf; + + hicn_ip_address_t temp_addr; + ip46_address_reset (&(temp_addr.as_ip46)); + + hicn_ip_address_t *iface_nat_addr = (hicn_ip_address_t *) &(iface->nat_addr); - ip46_address_t temp_addr; - ip46_address_reset (&temp_addr); - hicn_type_t type = hicn_get_buffer (b0)->type; u8 flags = hicn_get_buffer (b0)->flags; u8 reset_pl = flags & HICN_BUFFER_FLAGS_FROM_CS; - int ret = hicn_ops_vft[type.l1]->rewrite_data ( - type, &hicn->protocol, &(iface->nat_addr), &(temp_addr), iface->pl_id, - reset_pl); + + ret = hicn_data_rewrite (pkbuf, iface_nat_addr, &(temp_addr), iface->pl_id, + reset_pl); + if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED) { ensure_offload_flags (b0, 1 /* is_v4 */); @@ -551,6 +677,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, const hicn_face_t *iface, u32 *next) { ip6_header_t *ip0; + int ret = HICN_ERROR_NONE; /* Get the pointer to the old ip and tcp header */ /* Copy the previous ip and tcp header to the new portion of memory */ @@ -563,18 +690,19 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, ip0->hop_limit = HICN_IP6_HOP_LIMIT; vnet_buffer (b0)->ip.adj_index[VLIB_TX] = iface->dpo.dpoi_index; - *next = iface->dpo.dpoi_next_node; + *next = iface->iface_next; - hicn_header_t *hicn = vlib_buffer_get_current (b0); + hicn_packet_buffer_t *pkbuf = &hicn_get_buffer (b0)->pkbuf; - ip46_address_t temp_addr; - ip46_address_reset (&temp_addr); - hicn_type_t type = hicn_get_buffer (b0)->type; + hicn_ip_address_t temp_addr; + ip46_address_reset (&(temp_addr.as_ip46)); + + hicn_ip_address_t *iface_nat_addr = (hicn_ip_address_t *) &(iface->nat_addr); u8 flags = hicn_get_buffer (b0)->flags; u8 reset_pl = flags & HICN_BUFFER_FLAGS_FROM_CS; - int ret = hicn_ops_vft[type.l1]->rewrite_data ( - type, &hicn->protocol, &(iface->nat_addr), &(temp_addr), iface->pl_id, - reset_pl); + + ret = hicn_data_rewrite (pkbuf, iface_nat_addr, &(temp_addr), iface->pl_id, + reset_pl); if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED) { @@ -588,7 +716,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, vlib_buffer_t *b0; \ u32 bi0; \ u32 next0 = next_index; \ - hicn_face_t *face; \ + hicn_face_t *face = NULL; \ \ /* Prefetch for next iteration. */ \ if (n_left_from > 1) \ @@ -609,7 +737,8 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, b0 = vlib_get_buffer (vm, bi0); \ \ hicn_face_id_t face_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \ - face = hicn_dpoi_get_from_idx (face_id); \ + if (PREDICT_TRUE (hicn_dpoi_idx_is_valid (face_id))) \ + face = hicn_dpoi_get_from_idx (face_id); \ \ if (PREDICT_TRUE (face != NULL)) \ { \ @@ -626,7 +755,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, { \ TRACE_OUTPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ t->next_index = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ @@ -646,7 +775,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, u32 bi0, bi1; \ u32 next0 = next_index; \ u32 next1 = next_index; \ - hicn_face_t *face0, *face1; \ + hicn_face_t *face0 = NULL, *face1 = NULL; \ \ /* Prefetch for next iteration. */ \ { \ @@ -674,8 +803,10 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, \ hicn_face_id_t face_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \ hicn_face_id_t face_id1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \ - face0 = hicn_dpoi_get_from_idx (face_id0); \ - face1 = hicn_dpoi_get_from_idx (face_id1); \ + if (PREDICT_TRUE (hicn_dpoi_idx_is_valid (face_id0))) \ + face0 = hicn_dpoi_get_from_idx (face_id0); \ + if (PREDICT_TRUE (hicn_dpoi_idx_is_valid (face_id1))) \ + face1 = hicn_dpoi_get_from_idx (face_id1); \ \ if (PREDICT_TRUE (face0 != NULL)) \ { \ @@ -702,7 +833,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, { \ TRACE_OUTPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b0, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \ t->next_index = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ @@ -714,7 +845,7 @@ hicn_rewrite_iface_data6 (vlib_main_t *vm, vlib_buffer_t *b0, { \ TRACE_OUTPUT_PKT_IP##ipv *t = \ vlib_add_trace (vm, node, b1, sizeof (*t)); \ - t->pkt_type = HICN_PKT_TYPE_INTEREST; \ + t->pkt_type = HICN_PACKET_TYPE_INTEREST; \ t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \ t->next_index = next1; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \ @@ -738,7 +869,7 @@ hicn4_iface_output_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; - next_index = node->cached_next_index; + next_index = HICN4_IFACE_OUTPUT_NEXT_DROP; while (n_left_from > 0) { @@ -792,9 +923,11 @@ VLIB_REGISTER_NODE (hicn4_iface_output_node) = { .error_strings = hicn4_iface_output_error_strings, .n_next_nodes = HICN4_IFACE_OUTPUT_N_NEXT, /* edit / add dispositions here */ - .next_nodes = { [HICN4_IFACE_OUTPUT_NEXT_LOOKUP] = "ip4-lookup", + .next_nodes = { [HICN4_IFACE_OUTPUT_NEXT_DROP] = "error-drop", + [HICN4_IFACE_OUTPUT_NEXT_LOOKUP] = "ip4-lookup", [HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap", - [HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" }, + [HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap", + [HICN4_IFACE_OUTPUT_NEXT_PG] = "hicnpg-data" }, }; static uword @@ -807,7 +940,7 @@ hicn6_iface_output_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; - next_index = node->cached_next_index; + next_index = HICN6_IFACE_OUTPUT_NEXT_DROP; while (n_left_from > 0) { @@ -860,11 +993,11 @@ VLIB_REGISTER_NODE (hicn6_iface_output_node) = { .error_strings = hicn6_iface_output_error_strings, .n_next_nodes = HICN6_IFACE_OUTPUT_N_NEXT, /* edit / add dispositions here */ - .next_nodes = { [HICN6_IFACE_OUTPUT_NEXT_LOOKUP] = "ip6-lookup", + .next_nodes = { [HICN6_IFACE_OUTPUT_NEXT_DROP] = "error-drop", + [HICN6_IFACE_OUTPUT_NEXT_LOOKUP] = "ip6-lookup", [HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP] = "udp4-encap", - [HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap" - - }, + [HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP] = "udp6-encap", + [HICN6_IFACE_OUTPUT_NEXT_PG] = "hicnpg-data" }, }; /* diff --git a/hicn-plugin/src/faces/iface_node.h b/hicn-plugin/src/faces/iface_node.h index acb3cab0f..d580c9e31 100644 --- a/hicn-plugin/src/faces/iface_node.h +++ b/hicn-plugin/src/faces/iface_node.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Cisco and/or its affiliates. + * Copyright (c) 2021 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: @@ -37,6 +37,26 @@ * one implementing the tunnel encapsulation (udp-encap, mpls, etc). */ +typedef enum +{ + HICN4_IFACE_OUTPUT_NEXT_DROP, + HICN4_IFACE_OUTPUT_NEXT_LOOKUP, + HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP, + HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP, + HICN4_IFACE_OUTPUT_NEXT_PG, + HICN4_IFACE_OUTPUT_N_NEXT, +} hicn4_iface_output_next_t; + +typedef enum +{ + HICN6_IFACE_OUTPUT_NEXT_DROP, + HICN6_IFACE_OUTPUT_NEXT_LOOKUP, + HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP, + HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP, + HICN6_IFACE_OUTPUT_NEXT_PG, + HICN6_IFACE_OUTPUT_N_NEXT, +} hicn6_iface_output_next_t; + /** * @brief Initialize the ip iface module */ diff --git a/hicn-plugin/src/faces/inlines.h b/hicn-plugin/src/faces/inlines.h index 95a1c2ad2..ad9e26b62 100644 --- a/hicn-plugin/src/faces/inlines.h +++ b/hicn-plugin/src/faces/inlines.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Cisco and/or its affiliates. + * Copyright (c) 2021 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: @@ -21,24 +21,19 @@ always_inline void ensure_offload_flags (vlib_buffer_t *b, int is_v4) { - vnet_buffer_offload_flags_set(b, VNET_BUFFER_OFFLOAD_F_TCP_CKSUM); - vnet_buffer_offload_flags_set(b, is_v4 * VNET_BUFFER_OFFLOAD_F_IP_CKSUM); + vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_TCP_CKSUM); + vnet_buffer_offload_flags_set (b, is_v4 * VNET_BUFFER_OFFLOAD_F_IP_CKSUM); size_t l3_header_size = is_v4 * sizeof (ip4_header_t) + (!is_v4) * sizeof (ip6_header_t); /* Make sure l3_hdr_offset and l4_hdr_offset are set */ - if (!(b->flags & VNET_BUFFER_F_L3_HDR_OFFSET_VALID)) - { - b->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID; - vnet_buffer (b)->l3_hdr_offset = b->current_data; - } - if (!(b->flags & VNET_BUFFER_F_L4_HDR_OFFSET_VALID)) - { - b->flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID; - vnet_buffer (b)->l4_hdr_offset = - vnet_buffer (b)->l3_hdr_offset + l3_header_size; - } + b->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID; + vnet_buffer (b)->l3_hdr_offset = b->current_data; + + b->flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID; + vnet_buffer (b)->l4_hdr_offset = + vnet_buffer (b)->l3_hdr_offset + l3_header_size; } #endif /* __HICN_FACE_INLINES_H__ */
\ No newline at end of file |