diff options
author | Luca Muscariello <lumuscar@cisco.com> | 2022-03-30 22:29:28 +0200 |
---|---|---|
committer | Mauro Sardara <msardara@cisco.com> | 2022-03-31 19:51:47 +0200 |
commit | c46e5df56b67bb8ea7a068d39324c640084ead2b (patch) | |
tree | eddeb17785938e09bc42eec98ee09b8a28846de6 /hicn-plugin | |
parent | 18fa668f25d3cc5463417ce7df6637e31578e898 (diff) |
feat: boostrap hicn 22.02
The current patch provides several new features, improvements,
bug fixes and also complete rewrite of entire components.
- lib
The hicn packet parser has been improved with a new packet
format fully based on UDP. The TCP header is still temporarily
supported but the UDP header will replace completely the new hicn
packet format. Improvements have been made to make sure every
packet parsing operation is made via this library. The current
new header can be used as header between the payload and the
UDP header or as trailer in the UDP surplus area to be tested
when UDP options will start to be used.
- hicn-light
The portable packet forwarder has been completely rewritten from
scratch with the twofold objective to improve performance and
code size but also to drop dependencies such as libparc which is
now removed by the current implementation.
- hicn control
the control library is the agent that is used to program the
packet forwarders via their binary API. This component has
benefited from significant improvements in terms of interaction
model which is now event driven and more robust to failures.
- VPP plugin has been updated to support VPP 22.02
- transport
Major improvement have been made to the RTC protocol, to the
support of IO modules and to the security sub system. Signed
manifests are the default data authenticity and integrity framework.
Confidentiality can be enabled by sharing the encryption key to the
prod/cons layer. The library has been tested with group key based
applications such as broadcast/multicast and real-time on-line
meetings with trusted server keys or MLS.
- testing
Unit testing has been introduced using GoogleTest. One third of
the code base is covered by unit testing with priority on
critical features. Functional testing has also been introduce
using Docker, linux bridging and Robot Framework to define
test with Less Code techniques to facilitate the extension
of the coverage.
Co-authored-by: Mauro Sardara <msardara@cisco.com>
Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Co-authored-by: Michele Papalini <micpapal@cisco.com>
Co-authored-by: Angelo Mantellini <manangel@cisco.com>
Co-authored-by: Jacques Samain <jsamain@cisco.com>
Co-authored-by: Olivier Roques <oroques+fdio@cisco.com>
Co-authored-by: Enrico Loparco <eloparco@cisco.com>
Co-authored-by: Giulio Grassi <gigrassi@cisco.com>
Change-Id: I75d0ef70f86d921e3ef503c99271216ff583c215
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'hicn-plugin')
103 files changed, 2446 insertions, 1508 deletions
diff --git a/hicn-plugin/CMakeLists.txt b/hicn-plugin/CMakeLists.txt index 9f5553857..965fa5263 100644 --- a/hicn-plugin/CMakeLists.txt +++ b/hicn-plugin/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2019 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: @@ -11,32 +11,51 @@ # See the License for the specific language governing permissions and # limitations under the License. +############################################################## +# Project and cmake version +############################################################## cmake_minimum_required(VERSION 3.10 FATAL_ERROR) - project(hicn-plugin) -include(GNUInstallDirs) +############################################################## +# Cmake modules +############################################################## set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} - "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules/" - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/" + ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules/ ) -include(BuildMacros) - -set (CMAKE_CXX_STANDARD 11) -set (CMAKE_C_STANDARD 11) -# Check for memfd_create syscall -include(CheckSymbolExists) -CHECK_SYMBOL_EXISTS ( "__NR_memfd_create" "sys/syscall.h" HAVE_MEMFD_CREATE ) -if ( HAVE_MEMFD_CREATE ) - add_definitions ( -DHAVE_MEMFD_CREATE ) +if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + include(CommonSetup) endif() + +############################################################## +# Libs and Bins names +############################################################## set(HICN_PLUGIN hicn-plugin CACHE INTERNAL "" FORCE) +set(HICNPLUGIN hicn_plugin CACHE INTERNAL "" FORCE) +set(HICN_API_TEST_PLUGIN hicn_api_test_plugin CACHE INTERNAL "" FORCE) +set(HICNPLUGIN_SHARED ${HICNPLUGIN}.shared CACHE INTERNAL "" FORCE) +set(HICN_API_TEST_PLUGIN_SHARED ${HICN_API_TEST_PLUGIN}.shared CACHE INTERNAL "" FORCE) -include (Packaging) -add_subdirectory(src) +############################################################## +# Packaging and versioning +############################################################## +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/packaging.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/../versions.cmake) + +############################################################## +# C Standard +############################################################## +set (CMAKE_C_STANDARD 11) + + +############################################################## +# Subdirectories +############################################################## +add_subdirectory(includes/vpp_plugins/hicn) +add_subdirectory(src) add_subdirectory(vapi) diff --git a/hicn-plugin/cmake/Modules/Packaging.cmake b/hicn-plugin/cmake/Modules/Packaging.cmake deleted file mode 100644 index c0176e78f..000000000 --- a/hicn-plugin/cmake/Modules/Packaging.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (c) 2017-2019 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. - -###################### -# Packages section -###################### - -set(${HICN_PLUGIN}_DESCRIPTION - "A high-performance Hybrid ICN forwarder as a plugin to VPP." - CACHE STRING "Description for deb/rpm package." -) - -set(${HICN_PLUGIN}_DEB_DEPENDENCIES - "vpp (>= stable_version-release), vpp (<< next_version-release), vpp-plugin-core (>= stable_version-release), vpp-plugin-core (<< next_version-release)" - CACHE STRING "Dependencies for deb/rpm package." -) - -set(${HICN_PLUGIN}-dev_DEB_DEPENDENCIES - "vpp-dev (>= stable_version-release), vpp-dev (<< next_version-release), libvppinfra-dev (>= stable_version-release), libvppinfra-dev (<< next_version-release)" - CACHE STRING "Dependencies for deb/rpm package." -) - -set(${HICN_PLUGIN}_RPM_DEPENDENCIES - "vpp >= stable_version-release, vpp < next_version-release, vpp-plugins >= stable_version-release, vpp-plugins < next_version-release" - CACHE STRING "Dependencies for deb/rpm package." -) - -set(${HICN_PLUGIN}-dev_RPM_DEPENDENCIES - "vpp-devel >= stable_version-release, vpp-devel < next_version-release" - CACHE STRING "Dependencies for deb/rpm package." -) - -set(${HICN_PLUGIN}_DEB_PACKAGE_CONTROL_EXTRA - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/postinst" - CACHE STRING "Control scripts conffiles, postinst, postrm, prerm." -) - -set(${HICN_PLUGIN}_RPM_POST_INSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/post" - CACHE STRING "Install script that will be copied in the %post section" -) - -set(${HICN_PLUGIN}_RPM_POST_UNINSTALL_SCRIPT_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/scripts/postun" - CACHE STRING "Uninstall script that will be copied in the %postun section" -)
\ No newline at end of file diff --git a/hicn-plugin/cmake/packaging.cmake b/hicn-plugin/cmake/packaging.cmake new file mode 100644 index 000000000..276fc0b95 --- /dev/null +++ b/hicn-plugin/cmake/packaging.cmake @@ -0,0 +1,69 @@ +# 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: +# +# 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. + +###################### +# Packages section +###################### + +############################################################## +# Get VPP version +############################################################## +list(GET VPP_DEFAULT_VERSION 0 VPP_VERSION) + +set(${HICN_PLUGIN}_DESCRIPTION + "A high-performance Hybrid ICN forwarder as a plugin to VPP." + CACHE STRING "Description for deb/rpm package." +) + +string(REGEX REPLACE "([0-9]+).([0-9]+)(.[0-9]+)?" "\\1\\2" VER_NO_DOTS ${VPP_DEFAULT_VERSION}) + +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/scripts/postinst +"#!/bin/bash + +######################################################### +# Complete VPP config file with hicn configuration +######################################################### + +if [ -e /etc/vpp/startup.conf ]; then + RESULTS=$(sed -n '/hicn[ ]*{/p' /etc/vpp/startup.conf | wc -l) + if [[ $RESULTS = 0 ]]; then + printf '\n hicn { + ## Set PIT size. Default is 131072 entries + # pit-size 500000 + # + ## Set CS size. Default is 4096 + # cs-size 50000 + # + ## Set maximum PIT entries lifetime in milliseconds. Assigned to a PIT entry in case an interest carries a bigger lifetime + # pit-lifetime-max 20 + # + ## Percentage of CS to reserve for application producer faces + # cs-reserved-app 20\n}' >> /etc/vpp/startup.conf + fi; +fi; +") + +set(${HICN_PLUGIN}_DEB_DEPENDENCIES + "${LIBHICN_COMPONENT} (= stable_version), vpp (>= ${VPP_VERSION}), vpp-plugin-core (>= ${VPP_VERSION})" + CACHE STRING "Dependencies for deb/rpm package." +) + +set(${HICN_PLUGIN}-dev_DEB_DEPENDENCIES + "${LIBHICN_COMPONENT}-dev (= stable_version), vpp-dev (>= ${VPP_VERSION}), libvppinfra-dev (>= ${VPP_VERSION})" + CACHE STRING "Dependencies for deb/rpm package." +) + +set(${HICN_PLUGIN}_DEB_PACKAGE_CONTROL_EXTRA + "${CMAKE_CURRENT_BINARY_DIR}/scripts/postinst" + CACHE STRING "Control scripts conffiles, postinst, postrm, prerm." +) diff --git a/hicn-plugin/includes/vpp_plugins/hicn/CMakeLists.txt b/hicn-plugin/includes/vpp_plugins/hicn/CMakeLists.txt new file mode 100644 index 000000000..9b463e525 --- /dev/null +++ b/hicn-plugin/includes/vpp_plugins/hicn/CMakeLists.txt @@ -0,0 +1,29 @@ +# 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: +# +# 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. + +include(GNUInstallDirs) + +set(HICNPLUGIN_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + CACHE INTERNAL + "" FORCE +) + +set(HICNPLUGIN_TO_INSTALL_HEADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/error.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_all_api_h.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_msg_enum.h "" + CACHE INTERNAL + "" FORCE +)
\ No newline at end of file diff --git a/hicn-plugin/src/error.h b/hicn-plugin/includes/vpp_plugins/hicn/error.h index b33a1b50d..a8a941a79 100644 --- a/hicn-plugin/src/error.h +++ b/hicn-plugin/includes/vpp_plugins/hicn/error.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: @@ -83,7 +83,9 @@ _ (STRATEGY_NOT_FOUND, -179, "Strategy not found") \ _ (UDP_TUNNEL_NOT_FOUND, -180, "Udp tunnel not found") \ _ (UDP_TUNNEL_SRC_DST_TYPE, -181, \ - "Src and dst addresses have different type (ipv4 and ipv6)") + "Src and dst addresses have different type (ipv4 and ipv6)") \ + _ (MAPME_NEXT_HOP_ADDED, -182, "Next hop added to mapme") \ + _ (MAPME_NEXT_HOP_NOT_ADDED, -183, "Next hop added to mapme") typedef enum { @@ -97,7 +99,7 @@ extern const char *HICN_ERROR_STRING[]; #define get_error_string(errno) \ (char *) (errno ? HICN_ERROR_STRING[(-errno) - 127] : \ - HICN_ERROR_STRING[errno]) + HICN_ERROR_STRING[errno]) #endif /* //__HICN_ERROR_H__ */ diff --git a/hicn-plugin/src/hicn_all_api_h.h b/hicn-plugin/includes/vpp_plugins/hicn/hicn_all_api_h.h index 1263ea4a2..13769dd58 100644 --- a/hicn-plugin/src/hicn_all_api_h.h +++ b/hicn-plugin/includes/vpp_plugins/hicn/hicn_all_api_h.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: @@ -13,7 +13,7 @@ * limitations under the License. */ -#include <hicn/hicn.api.h> +#include <vpp_plugins/hicn/hicn.api.h> /* * fd.io coding-style-patch-verification: ON diff --git a/hicn-plugin/src/hicn_api.h b/hicn-plugin/includes/vpp_plugins/hicn/hicn_api.h index e32b785b6..ac45fbf17 100644 --- a/hicn-plugin/src/hicn_api.h +++ b/hicn-plugin/includes/vpp_plugins/hicn/hicn_api.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,7 @@ /* define message structures */ #define vl_typedefs -#include <hicn/hicn_all_api_h.h> +#include <vpp_plugins/hicn/hicn_all_api_h.h> #undef vl_typedefs #endif /* // __HICN_API_H___ */ diff --git a/hicn-plugin/src/hicn_msg_enum.h b/hicn-plugin/includes/vpp_plugins/hicn/hicn_msg_enum.h index fcf2a1e87..903fbf8c0 100644 --- a/hicn-plugin/src/hicn_msg_enum.h +++ b/hicn-plugin/includes/vpp_plugins/hicn/hicn_msg_enum.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: @@ -24,7 +24,7 @@ #define vl_msg_id(n, h) n, typedef enum { -#include <hicn/hicn_all_api_h.h> +#include <vpp_plugins/hicn/hicn_all_api_h.h> /* We'll want to know how many messages IDs we need... */ VL_MSG_FIRST_AVAILABLE, } vl_msg_id_t; diff --git a/hicn-plugin/scripts/post b/hicn-plugin/scripts/post deleted file mode 100644 index dd0a9fbf5..000000000 --- a/hicn-plugin/scripts/post +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -if [ -e /etc/vpp/startup.conf ]; then - RESULTS=$(sed -n '/hicn[ ]*{/p' /etc/vpp/startup.conf | wc -l) - if [[ $RESULTS = 0 ]]; then - printf '\n hicn { - ## Set PIT size. Default is 131Â 072 entries - # pit-size 500000 - # - ## Set CS size. Default is 4096 - # cs-size 50000 - # - ## Set maximum PIT entries lifetime in milliseconds. Assigned to a PIT entry in case an interest carries a bigger lifetime - # pit-lifetime-max 20 - # - ## Percentage of CS to reserve for application producer faces - # cs-reserved-app 20\n}' >> /etc/vpp/startup.conf - fi; -fi; -ln -s /usr/lib64/vpp_plugins/hicn_plugin.so /usr/lib/vpp_plugins/hicn_plugin.so
\ No newline at end of file diff --git a/hicn-plugin/scripts/postinst b/hicn-plugin/scripts/postinst deleted file mode 100644 index d6d48509c..000000000 --- a/hicn-plugin/scripts/postinst +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -if [ -e /etc/vpp/startup.conf ]; then - RESULTS=$(sed -n '/hicn[ ]*{/p' /etc/vpp/startup.conf | wc -l) - if [[ $RESULTS = 0 ]]; then - printf '\n hicn { - ## Set PIT size. Default is 131Â 072 entries - # pit-size 500000 - # - ## Set CS size. Default is 4096 - # cs-size 50000 - # - ## Set maximum PIT entries lifetime in milliseconds. Assigned to a PIT entry in case an interest carries a bigger lifetime - # pit-lifetime-max 20 - # - ## Percentage of CS to reserve for application producer faces - # cs-reserved-app 20\n}' >> /etc/vpp/startup.conf - fi; -fi;
\ No newline at end of file diff --git a/hicn-plugin/scripts/postun b/hicn-plugin/scripts/postun deleted file mode 100644 index c319f014e..000000000 --- a/hicn-plugin/scripts/postun +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -if [ -L /usr/lib/vpp_plugins/hicn_plugin.so ]; then - rm /usr/lib/vpp_plugins/hicn_plugin.so -fi;
\ No newline at end of file diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt index 124d9b5cb..2141ec596 100644 --- a/hicn-plugin/src/CMakeLists.txt +++ b/hicn-plugin/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2017-2020 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: @@ -11,290 +11,234 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Dependencies -find_package(Vpp REQUIRED) - -include_directories(${HICN_INCLUDE_DIRS} ${VPP_INCLUDE_DIR}) - -set(LIBHICN_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/mapme.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/name.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/ops.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/protocol/ah.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/protocol/icmp.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/protocol/ipv4.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/protocol/ipv6.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/src/protocol/tcp.c -) - -set(LIBHICN_HEADER_FILES_SRC - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/hicn.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/base.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/common.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/error.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/header.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/name.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/ops.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/mapme.h -) - -set(LIBHICN_HEADER_FILES_PROTOCOL - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/ah.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/icmp.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/icmprd.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/ipv4.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/ipv6.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/tcp.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/protocol/udp.h -) +############################################################## +# Dependencies and third party libs +############################################################## +find_package(Vpp ${VPP_DEFAULT_VERSION} EXACT REQUIRED) + +if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + find_package(Libhicn ${CURRENT_VERSION} REQUIRED NO_MODULE) + list(APPEND HICN_LIBRARIES hicn::hicn.${LIBTYPE}) +else() + set(LIBHICN_LIBRARIES ${LIBHICN_SHARED}) + list(APPEND DEPENDENCIES + ${LIBHICN_LIBRARIES} + ) +endif() -set(LIBHICN_HEADER_FILES_UTIL - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/util/ip_address.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/util/token.h - ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/includes/hicn/util/types.h -) +############################################################## +# Source/Header files +############################################################## set(HICN_PLUGIN_SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/hicn.c - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.c - ${CMAKE_CURRENT_SOURCE_DIR}/cli.c - ${CMAKE_CURRENT_SOURCE_DIR}/hashtb.c - ${CMAKE_CURRENT_SOURCE_DIR}/mgmt.c - ${CMAKE_CURRENT_SOURCE_DIR}/pcs.c - ${CMAKE_CURRENT_SOURCE_DIR}/route.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_ctx.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_manager.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategy_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/interest_pcslookup_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitpit_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitcs_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/data_input_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/data_fwd_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/error.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_cli.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/face.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_app_cli.c - ${CMAKE_CURRENT_SOURCE_DIR}/pg.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw_cli.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rr.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rr.c - ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_lru.c - ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.c - ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_decap_node.c - ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.c + ${CMAKE_CURRENT_SOURCE_DIR}/hicn.c + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.c + ${CMAKE_CURRENT_SOURCE_DIR}/cli.c + ${CMAKE_CURRENT_SOURCE_DIR}/hashtb.c + ${CMAKE_CURRENT_SOURCE_DIR}/infra.c + ${CMAKE_CURRENT_SOURCE_DIR}/mgmt.c + ${CMAKE_CURRENT_SOURCE_DIR}/pcs.c + ${CMAKE_CURRENT_SOURCE_DIR}/route.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_ctx.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_manager.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/interest_pcslookup_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitpit_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitcs_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/data_input_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/data_fwd_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/error.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_cli.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/face.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_app_cli.c + ${CMAKE_CURRENT_SOURCE_DIR}/pg.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw_cli.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rr.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rr.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rp.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rp.c + ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_lru.c + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.c + ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_decap_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.c ) set(HICN_PLUGIN_HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_all_api_h.h - ${CMAKE_CURRENT_SOURCE_DIR}/hashtb.h - ${CMAKE_CURRENT_SOURCE_DIR}/mgmt.h - ${CMAKE_CURRENT_SOURCE_DIR}/params.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcs.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn.h - ${CMAKE_CURRENT_SOURCE_DIR}/state.h - ${CMAKE_CURRENT_SOURCE_DIR}/infra.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_msg_enum.h - ${CMAKE_CURRENT_SOURCE_DIR}/parser.h - ${CMAKE_CURRENT_SOURCE_DIR}/route.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_ctx.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_manager.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategy.h - ${CMAKE_CURRENT_SOURCE_DIR}/interest_pcslookup.h - ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitpit.h - ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitcs.h - ${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup.h - ${CMAKE_CURRENT_SOURCE_DIR}/data_fwd.h - ${CMAKE_CURRENT_SOURCE_DIR}/error.h - ${CMAKE_CURRENT_SOURCE_DIR}/face_db.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/face.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/inlines.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_dpo.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.h - ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.h - ${CMAKE_CURRENT_SOURCE_DIR}/pg.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rr.h - ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rr.h - ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_policy.h - ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_lru.h - ${CMAKE_CURRENT_SOURCE_DIR}/mapme.h - ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack.h - ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl.h - ${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.h - ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_all_api_h.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_logging.h + ${CMAKE_CURRENT_SOURCE_DIR}/hashtb.h + ${CMAKE_CURRENT_SOURCE_DIR}/mgmt.h + ${CMAKE_CURRENT_SOURCE_DIR}/params.h + ${CMAKE_CURRENT_SOURCE_DIR}/pcs.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn.h + ${CMAKE_CURRENT_SOURCE_DIR}/state.h + ${CMAKE_CURRENT_SOURCE_DIR}/infra.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_msg_enum.h + ${CMAKE_CURRENT_SOURCE_DIR}/parser.h + ${CMAKE_CURRENT_SOURCE_DIR}/route.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_ctx.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_manager.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategy.h + ${CMAKE_CURRENT_SOURCE_DIR}/interest_pcslookup.h + ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitpit.h + ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitcs.h + ${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup.h + ${CMAKE_CURRENT_SOURCE_DIR}/data_fwd.h + ${CMAKE_CURRENT_SOURCE_DIR}/error.h + ${CMAKE_CURRENT_SOURCE_DIR}/face_db.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/face.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/inlines.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_dpo.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.h + ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.h + ${CMAKE_CURRENT_SOURCE_DIR}/pg.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rr.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rr.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_rp.h + ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_rp.h + ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_policy.h + ${CMAKE_CURRENT_SOURCE_DIR}/cache_policies/cs_lru.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl.h + ${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.h + ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.h ) set(HICN_API_TEST_SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api_test.c - ${CMAKE_CURRENT_SOURCE_DIR}/error.c) + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api_test.c + ${CMAKE_CURRENT_SOURCE_DIR}/error.c +) set(HICN_API_HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_msg_enum.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_all_api_h.h - ${CMAKE_CURRENT_SOURCE_DIR}/hicn_api.h - ${CMAKE_CURRENT_SOURCE_DIR}/error.h) + ${HICNPLUGIN_TO_INSTALL_HEADER_FILES} +) set(HICN_API_GENERATED_FILES - ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h - ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_types.h - ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_enum.h + ${PROJECT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h + ${PROJECT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_types.h + ${PROJECT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_enum.h ) set(HICN_VAPI_GENERATED_FILES - ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.h - ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.hpp) + ${PROJECT_BINARY_DIR}/vapi/hicn.api.vapi.h + ${PROJECT_BINARY_DIR}/vapi/hicn.api.vapi.hpp +) -set(HICN_VPP_STARTUP_CONF_FILE - ${CMAKE_BINARY_DIR}/startup.conf) +############################################################## +# Assume VPP is installed in standard location +############################################################## if (NOT VPP_HOME) - set(VPP_HOME /usr) + set(VPP_HOME /usr) endif() -if (NOT CMAKE_BUILD_TYPE) - set (CMAKE_BUILD_TYPE "Release") -endif (NOT CMAKE_BUILD_TYPE) - -SET(HICN_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} CACHE STRING "hicn_install_prefix") - -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/hicn) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vapi) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn) -include(Packager) -extract_version() - -# These files are missing from vpp binary distribution -execute_process( - COMMAND - bash -c - "if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ]; then - curl https://raw.githubusercontent.com/FDio/vpp/stable/2106/src/vpp-api/vapi/vapi_json_parser.py -o ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py; - fi; - if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ]; then - curl https://raw.githubusercontent.com/FDio/vpp/stable/2106/src/vpp-api/vapi/vapi_c_gen.py -o ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py; - fi; - if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py ]; then - curl https://raw.githubusercontent.com/FDio/vpp/stable/2106/src/vpp-api/vapi/vapi_cpp_gen.py -o ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py; - fi; - if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_types.api ]; then - curl https://raw.githubusercontent.com/FDio/vpp/stable/2106/src/vnet/ip/ip_types.api -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_types.api; - fi; - if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib/fib_entry_track.h ]; then - curl https://raw.githubusercontent.com/FDio/vpp/stable/2106/src/vnet/fib/fib_entry_track.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib/fib_entry_track.h; - fi; - if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp/udp_encap.h ]; then - curl https://raw.githubusercontent.com/FDio/vpp/stable/2106/src/vnet/udp/udp_encap.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp/udp_encap.h; - fi; - - chmod +x ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py" +############################################################## +# RPath +############################################################## +SET(HICN_INSTALL_PREFIX + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} ) -execute_process( - COMMAND ${VPP_HOME}/bin/vppapigen --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h --outputdir ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/ - COMMAND ${VPP_HOME}/bin/vppapigen JSON --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json --outputdir ${CMAKE_CURRENT_BINARY_DIR}/vapi/ -) -execute_process( - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json -) - -include_directories(SYSTEM) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHICN_VPP_PLUGIN=1") -add_library(hicn_plugin SHARED - ${LIBHICN_FILES} - ${HICN_PLUGIN_SOURCE_FILES} - ${HICN_API_GENERATED_FILES} - ${HICN_VAPI_GENERATED_FILES}) -file(COPY ${HICN_API_HEADER_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins) - -file(COPY ${LIBHICN_HEADER_FILES_SRC} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn) -file(COPY ${LIBHICN_HEADER_FILES_PROTOCOL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn/protocol) -file(COPY ${LIBHICN_HEADER_FILES_UTIL} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/hicn/util) - -add_library(hicn_api_test_plugin SHARED - ${HICN_API_TEST_SOURCE_FILES} - ${HICN_API_GENERATED_FILES}) +############################################################## +# Compiler Options +############################################################## +set(COMPILER_OPTIONS + ${DEFAULT_COMPILER_OPTIONS} + ${MARCH_COMPILER_OPTIONS} + PRIVATE "-Wno-address-of-packed-member" +) -set(VPP_INSTALL_PLUGIN ${HICN_INSTALL_PREFIX}/vpp_plugins) -set(VPP_INSTALL_API_TEST_PLUGIN ${HICN_INSTALL_PREFIX}/vpp_api_test_plugins CACHE STRING "vpp_install_api_test_plugin") -set(VPP_STARTUP_CONF /etc/vpp/) -set_target_properties(hicn_plugin - PROPERTIES - LINKER_LANGUAGE C - INSTALL_RPATH ${VPP_INSTALL_PLUGIN} - COMPILE_FLAGS "-march=native -Wno-address-of-packed-member" - PREFIX "") -set_target_properties(hicn_api_test_plugin - PROPERTIES - LINKER_LANGUAGE C - COMPILE_FLAGS "-march=native -Wno-address-of-packed-member" - PREFIX "") +############################################################## +# Compiler Definitions +############################################################## +set(COMPILE_DEFINITIONS + "-DHICN_VPP_PLUGIN=1" +) if (${CMAKE_BUILD_TYPE} MATCHES "Debug") - target_compile_definitions(hicn_plugin PRIVATE "CLIB_DEBUG") - target_compile_definitions(hicn_api_test_plugin PRIVATE "CLIB_DEBUG") + list(APPEND COMPILE_DEFINITIONS + "-DHICN_DDEBUG" + "-DCLIB_DEBUG" + ) endif() -message (STATUS "hicn-plugin variable ${HICN_PLUGIN}") -install(DIRECTORY - DESTINATION ${VPP_INSTALL_PLUGIN} - COMPONENT ${HICN_PLUGIN}) -install(TARGETS hicn_plugin - DESTINATION - ${VPP_INSTALL_PLUGIN} - COMPONENT ${HICN_PLUGIN}) +############################################################## +# VPP API Generation +############################################################## +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/vapi) +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/vpp_plugins/hicn) -install(DIRECTORY - DESTINATION ${VPP_INSTALL_API_TEST_PLUGIN} - COMPONENT ${HICN_PLUGIN}) -install(TARGETS hicn_api_test_plugin - DESTINATION ${VPP_INSTALL_API_TEST_PLUGIN} - COMPONENT ${HICN_PLUGIN}) +execute_process( + COMMAND ${VPP_HOME}/bin/vppapigen --includedir ${VPP_HOME}/include --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${PROJECT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h --outputdir ${PROJECT_BINARY_DIR}/vpp_plugins/hicn/ + COMMAND ${VPP_HOME}/bin/vppapigen JSON --includedir ${VPP_HOME}/include --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${PROJECT_BINARY_DIR}/vapi/hicn.api.json --outputdir ${PROJECT_BINARY_DIR}/vapi/ +) +execute_process( + COMMAND ${VPP_HOME}/bin/vapi_c_gen.py ${PROJECT_BINARY_DIR}/vapi/hicn.api.json + COMMAND ${VPP_HOME}/bin/vapi_cpp_gen.py ${PROJECT_BINARY_DIR}/vapi/hicn.api.json +) -install(FILES ${HICN_API_HEADER_FILES} ${HICN_API_GENERATED_FILES} - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn - COMPONENT ${HICN_PLUGIN}-dev) -install(FILES ${HICN_API_GENERATED_FILES} - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vpp_plugins/hicn - COMPONENT ${HICN_PLUGIN}-dev) +############################################################## +# Include directories +############################################################## +set(HICN_PLUGIN_INCLUDE_DIRS_INTERNAL + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${VPP_INCLUDE_DIR} + PUBLIC + $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}> + $<BUILD_INTERFACE:${HICNPLUGIN_INCLUDE_DIRS}> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) + -install(FILES ${HICN_VAPI_GENERATED_FILES} - DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/vapi - COMPONENT ${HICN_PLUGIN}-dev) +############################################################## +# Build hicn plugins for VPP +############################################################## +build_module(${HICNPLUGIN} + SOURCES ${HICN_PLUGIN_SOURCE_FILES} + INSTALL_HEADERS ${HICN_API_HEADER_FILES} ${HICN_API_GENERATED_FILES} + LINK_LIBRARIES PRIVATE ${LIBHICN_LIBRARIES} + DEPENDS ${DEPENDENCIES} + COMPONENT ${HICN_PLUGIN} + INCLUDE_DIRS ${HICN_PLUGIN_INCLUDE_DIRS_INTERNAL} + HEADER_ROOT_DIR "vpp_plugins" + LIBRARY_ROOT_DIR "vpp_plugins" + DEFINITIONS PUBLIC ${COMPILE_DEFINITIONS} + COMPILE_OPTIONS ${COMPILER_OPTIONS} + INSTALL_RPATH "${VPP_INSTALL_PLUGIN}:${HICN_INSTALL_PREFIX}:${VPP_HOME}/lib" +) -#Set variables for other project depending on hicn-plugin -set(HICNPLUGIN_INCLUDE_DIRS - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins - ${VPP_INCLUDE_DIRS} - CACHE INTERNAL "" FORCE) -set(HICNPLUGIN_LIBRARIES ${VPP_LIBRARIES} CACHE INTERNAL "" FORCE) +build_module(${HICN_API_TEST_PLUGIN} + SOURCES ${HICN_API_TEST_SOURCE_FILES} + INSTALL_HEADERS ${HICN_VAPI_GENERATED_FILES} + COMPONENT ${HICN_PLUGIN} + INCLUDE_DIRS ${HICN_PLUGIN_INCLUDE_DIRS_INTERNAL} + HEADER_ROOT_DIR "vapi" + LIBRARY_ROOT_DIR "vpp_api_test_plugins" + DEFINITIONS PUBLIC ${COMPILE_DEFINITIONS} + COMPILE_OPTIONS ${COMPILER_OPTIONS} + INSTALL_RPATH "${VPP_INSTALL_PLUGIN}:${HICN_INSTALL_PREFIX}:${VPP_HOME}/lib" +) diff --git a/hicn-plugin/src/cache_policies/cs_lru.c b/hicn-plugin/src/cache_policies/cs_lru.c index 408a6cb49..e65f487e1 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.c +++ b/hicn-plugin/src/cache_policies/cs_lru.c @@ -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/cache_policies/cs_lru.h b/hicn-plugin/src/cache_policies/cs_lru.h index c939b45df..35b82ff2c 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.h +++ b/hicn-plugin/src/cache_policies/cs_lru.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: diff --git a/hicn-plugin/src/cache_policies/cs_policy.h b/hicn-plugin/src/cache_policies/cs_policy.h index 505138943..73f3de107 100644 --- a/hicn-plugin/src/cache_policies/cs_policy.h +++ b/hicn-plugin/src/cache_policies/cs_policy.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: diff --git a/hicn-plugin/src/cli.c b/hicn-plugin/src/cli.c index 8ecbf7a95..cd45607ca 100644 --- a/hicn-plugin/src/cli.c +++ b/hicn-plugin/src/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: @@ -22,6 +22,9 @@ #include <vnet/ip/ip6_packet.h> // ip46_address_t #include <vnet/ip/format.h> #include <vnet/fib/fib_types.h> +#include <vnet/pg/pg.h> + +#include <vpp_plugins/hicn/hicn_api.h> #include "hicn.h" #include "infra.h" @@ -33,7 +36,6 @@ #include "error.h" #include "faces/face.h" #include "route.h" -#include "hicn_api.h" static vl_api_hicn_api_node_params_set_t node_ctl_params = { .pit_max_size = -1, @@ -65,8 +67,8 @@ hicn_cli_node_ctl_start_set_command_fn (vlib_main_t *vm, get_error_string (ret)); return (ret == HICN_ERROR_NONE) ? - 0 : - clib_error_return (0, get_error_string (ret)); + 0 : + clib_error_return (0, get_error_string (ret)); } /* @@ -91,7 +93,7 @@ hicn_cli_node_ctl_stop_set_command_fn (vlib_main_t *vm, { return (0); } - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + if (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { return clib_error_return (0, "%s '%U'", get_error_string (HICN_ERROR_CLI_INVAL), @@ -103,8 +105,8 @@ hicn_cli_node_ctl_stop_set_command_fn (vlib_main_t *vm, node_ctl_params.pit_max_lifetime_sec, node_ctl_params.cs_max_size, ~0); return (ret == HICN_ERROR_NONE) ? - 0 : - clib_error_return (0, get_error_string (ret)); + 0 : + clib_error_return (0, get_error_string (ret)); } #define DFLTD_RANGE_OK(val, min, max) \ @@ -201,8 +203,8 @@ hicn_cli_node_ctl_param_set_command_fn (vlib_main_t *vm, "compilation time for better performances\n"); return (rv == HICN_ERROR_NONE) ? - 0 : - clib_error_return (0, "%s '%U'", get_error_string (rv), + 0 : + clib_error_return (0, "%s '%U'", get_error_string (rv), format_unformat_error, line_input); } @@ -213,7 +215,7 @@ static clib_error_t * hicn_cli_show_command_fn (vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd) { - int face_p = 0, fib_p = 0, all_p, internal_p = 0, strategies_p = 0, + int face_p = 0, fib_p = 0, all_p = 0, internal_p = 0, strategies_p = 0, ret = HICN_ERROR_NONE; /* Get a line of input. */ @@ -348,8 +350,8 @@ done: hicn_main.pitcs.pcs_table->ht_overflow_buckets_used); } return (ret == HICN_ERROR_NONE) ? - 0 : - clib_error_return (0, "%s\n", get_error_string (ret)); + 0 : + clib_error_return (0, "%s\n", get_error_string (ret)); } /* @@ -408,8 +410,8 @@ hicn_cli_strategy_set_command_fn (vlib_main_t *vm, rv = hicn_route_set_strategy (&prefix, strategy_id); cl_err = (rv == HICN_ERROR_NONE) ? - NULL : - clib_error_return (0, get_error_string (rv)); + NULL : + clib_error_return (0, get_error_string (rv)); done: return (cl_err); @@ -727,12 +729,25 @@ hicn_enable_command_fn (vlib_main_t *vm, unformat_input_t *main_input, goto done; } } - rv = hicn_route_enable (&pfx); + hicn_face_id_t *vec_faces = NULL; + rv = hicn_route_enable (&pfx, &vec_faces); + + if (vec_faces != NULL) + { + hicn_face_id_t *face_id; + u8 *str = 0; + vec_foreach (face_id, vec_faces) + { + str = format (str, " %d", *face_id); + } + vec_free (vec_faces); + vlib_cli_output (vm, "Faces for this prefix: %s", str); + } done: cl_err = (rv == HICN_ERROR_NONE) ? - NULL : - clib_error_return (0, get_error_string (rv)); + NULL : + clib_error_return (0, get_error_string (rv)); return cl_err; } @@ -776,8 +791,8 @@ hicn_disable_command_fn (vlib_main_t *vm, unformat_input_t *main_input, done: cl_err = (rv == HICN_ERROR_NONE) ? - NULL : - clib_error_return (0, get_error_string (rv)); + NULL : + clib_error_return (0, get_error_string (rv)); return cl_err; } diff --git a/hicn-plugin/src/data_fwd.h b/hicn-plugin/src/data_fwd.h index 96d8399e4..b21fa0a2f 100644 --- a/hicn-plugin/src/data_fwd.h +++ b/hicn-plugin/src/data_fwd.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: diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c index fe79b33fa..6acb5915b 100644 --- a/hicn-plugin/src/data_fwd_node.c +++ b/hicn-plugin/src/data_fwd_node.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: @@ -428,9 +428,9 @@ hicn_satisfy_faces (vlib_main_t *vm, u32 bi0, hicn_pcs_entry_t *pitp, clones += 2; next0 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT : - HICN_DATA_FWD_NEXT_IFACE4_OUT; + HICN_DATA_FWD_NEXT_IFACE4_OUT; next1 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT : - HICN_DATA_FWD_NEXT_IFACE4_OUT; + HICN_DATA_FWD_NEXT_IFACE4_OUT; vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0; vnet_buffer (h1)->ip.adj_index[VLIB_TX] = face1; @@ -481,7 +481,7 @@ hicn_satisfy_faces (vlib_main_t *vm, u32 bi0, hicn_pcs_entry_t *pitp, clones += 1; next0 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT : - HICN_DATA_FWD_NEXT_IFACE4_OUT; + HICN_DATA_FWD_NEXT_IFACE4_OUT; vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0; stats->pkts_data_count++; @@ -548,10 +548,7 @@ clone_data_to_cs (vlib_main_t *vm, hicn_pit_cs_t *pitcs, * the PIT part of the union as we update the CS part, so don't * expect the PIT part to be valid after this point. */ - hicn_buffer_t *hicnb0 = hicn_get_buffer (b0); - hicn_pit_to_cs (vm, pitcs, pitp, hash_entry, nodep, dpo_vft, hicn_dpo_id, - hicnb->face_id, - hicnb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP); + hicn_pit_to_cs (vm, pitcs, pitp, hash_entry, nodep, dpo_vft, hicn_dpo_id); pitp->shared.create_time = tnow; diff --git a/hicn-plugin/src/data_input_node.c b/hicn-plugin/src/data_input_node.c index c94443a6b..46fda1080 100644 --- a/hicn-plugin/src/data_input_node.c +++ b/hicn-plugin/src/data_input_node.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-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: @@ -75,6 +75,23 @@ format_hicn_data_input_trace (u8 *s, va_list *args) return s; } +static void +hicn_data_input_set_adj_index (vlib_buffer_t *b, + const ip46_address_t *dst_addr, + const hicn_dpo_ctx_t *dpo_ctx) +{ + for (u8 pos = 0; pos < dpo_ctx->entry_count; pos++) + { + hicn_face_t *face = hicn_dpoi_get_from_idx (dpo_ctx->next_hops[pos]); + assert (face); + if (ip46_address_cmp (&(face->nat_addr), dst_addr) == 0) + { + vnet_buffer (b)->ip.adj_index[VLIB_RX] = face->dpo.dpoi_index; + break; + } + } +} + static uword hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) @@ -100,6 +117,7 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, ip_lookup_next_t next0, next1; ip6_header_t *ip0, *ip1; ip6_address_t *src_addr0, *src_addr1; + ip46_address_t dst_addr0, dst_addr1; const dpo_id_t *dpo0, *dpo1; const load_balance_t *lb0, *lb1; @@ -128,6 +146,9 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, src_addr0 = &ip0->src_address; src_addr1 = &ip1->src_address; + ip46_address_set_ip6 (&dst_addr0, &ip0->dst_address); + ip46_address_set_ip6 (&dst_addr0, &ip1->dst_address); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p1); @@ -150,14 +171,22 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, dpo1 = load_balance_get_bucket_i (lb1, 0); if (dpo_is_hicn (dpo0)) - next0 = HICN_DATA_INPUT_IP6_NEXT_FACE; + { + next0 = (ip_lookup_next_t) HICN_DATA_INPUT_IP6_NEXT_FACE; + hicn_data_input_set_adj_index ( + p0, &dst_addr0, hicn_strategy_dpo_ctx_get (dpo0->dpoi_index)); + } else - next0 = HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; + next0 = (ip_lookup_next_t) HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; if (dpo_is_hicn (dpo1)) - next1 = HICN_DATA_INPUT_IP6_NEXT_FACE; + { + next1 = (ip_lookup_next_t) HICN_DATA_INPUT_IP6_NEXT_FACE; + hicn_data_input_set_adj_index ( + p1, &dst_addr1, hicn_strategy_dpo_ctx_get (dpo1->dpoi_index)); + } else - next1 = HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; + next1 = (ip_lookup_next_t) HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && (p0->flags & VLIB_BUFFER_IS_TRACED)) @@ -235,6 +264,7 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, ip_lookup_next_t next0; load_balance_t *lb0; ip6_address_t *src_addr0; + ip46_address_t dst_addr0; const dpo_id_t *dpo0; pi0 = from[0]; @@ -243,6 +273,7 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, p0 = vlib_get_buffer (vm, pi0); ip0 = vlib_buffer_get_current (p0); src_addr0 = &ip0->src_address; + ip46_address_set_ip6 (&dst_addr0, &ip0->dst_address); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); lbi0 = ip6_fib_table_fwding_lookup (vnet_buffer (p0)->ip.fib_index, src_addr0); @@ -255,9 +286,13 @@ hicn_data_input_ip6_fn (vlib_main_t *vm, vlib_node_runtime_t *node, dpo0 = load_balance_get_bucket_i (lb0, 0); if (dpo_is_hicn (dpo0)) - next0 = HICN_DATA_INPUT_IP6_NEXT_FACE; + { + next0 = (ip_lookup_next_t) HICN_DATA_INPUT_IP6_NEXT_FACE; + hicn_data_input_set_adj_index ( + p0, &dst_addr0, hicn_strategy_dpo_ctx_get (dpo0->dpoi_index)); + } else - next0 = HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; + next0 = (ip_lookup_next_t) HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && (p0->flags & VLIB_BUFFER_IS_TRACED)) @@ -312,7 +347,7 @@ VLIB_REGISTER_NODE (hicn_data_input_ip6) = { VNET_FEATURE_INIT (hicn_data_input_ip6_arc, static) = { .arc_name = "ip6-local", .node_name = "hicn-data-input-ip6", - .runs_before = VNET_FEATURES ("ip6-local-end-of-arc"), + .runs_before = VNET_FEATURES ("ip6-local-end-of-arc") }; always_inline uword @@ -337,9 +372,8 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, { ip4_header_t *ip0, *ip1, *ip2, *ip3; const load_balance_t *lb0, *lb1, *lb2, *lb3; - ip4_fib_mtrie_t *mtrie0, *mtrie1, *mtrie2, *mtrie3; - ip4_fib_mtrie_leaf_t leaf0, leaf1, leaf2, leaf3; ip4_address_t *src_addr0, *src_addr1, *src_addr2, *src_addr3; + ip46_address_t dst_addr0, dst_addr1, dst_addr2, dst_addr3; u32 lb_index0, lb_index1, lb_index2, lb_index3; const dpo_id_t *dpo0, *dpo1, *dpo2, *dpo3; @@ -367,35 +401,21 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, src_addr2 = &ip2->src_address; src_addr3 = &ip3->src_address; + ip46_address_set_ip4 (&dst_addr0, &ip0->dst_address); + ip46_address_set_ip4 (&dst_addr1, &ip1->dst_address); + ip46_address_set_ip4 (&dst_addr2, &ip2->dst_address); + ip46_address_set_ip4 (&dst_addr3, &ip3->dst_address); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[0]); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[1]); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[2]); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[3]); - mtrie0 = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie; - mtrie1 = &ip4_fib_get (vnet_buffer (b[1])->ip.fib_index)->mtrie; - mtrie2 = &ip4_fib_get (vnet_buffer (b[2])->ip.fib_index)->mtrie; - mtrie3 = &ip4_fib_get (vnet_buffer (b[3])->ip.fib_index)->mtrie; - - leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, src_addr0); - leaf1 = ip4_fib_mtrie_lookup_step_one (mtrie1, src_addr1); - leaf2 = ip4_fib_mtrie_lookup_step_one (mtrie2, src_addr2); - leaf3 = ip4_fib_mtrie_lookup_step_one (mtrie3, src_addr3); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 2); - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 2); - leaf2 = ip4_fib_mtrie_lookup_step (mtrie2, leaf2, src_addr2, 2); - leaf3 = ip4_fib_mtrie_lookup_step (mtrie3, leaf3, src_addr3, 2); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 3); - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 3); - leaf2 = ip4_fib_mtrie_lookup_step (mtrie2, leaf2, src_addr2, 3); - leaf3 = ip4_fib_mtrie_lookup_step (mtrie3, leaf3, src_addr3, 3); - - lb_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); - lb_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1); - lb_index2 = ip4_fib_mtrie_leaf_get_adj_index (leaf2); - lb_index3 = ip4_fib_mtrie_leaf_get_adj_index (leaf3); + ip4_fib_forwarding_lookup_x4 ( + vnet_buffer (b[0])->ip.fib_index, vnet_buffer (b[1])->ip.fib_index, + vnet_buffer (b[2])->ip.fib_index, vnet_buffer (b[3])->ip.fib_index, + src_addr0, src_addr1, src_addr2, src_addr3, &lb_index0, &lb_index1, + &lb_index2, &lb_index3); ASSERT (lb_index0 && lb_index1 && lb_index2 && lb_index3); lb0 = load_balance_get (lb_index0); @@ -418,22 +438,38 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, dpo3 = load_balance_get_bucket_i (lb3, 0); if (dpo_is_hicn (dpo0)) - next[0] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[0] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[0], &dst_addr0, hicn_strategy_dpo_ctx_get (dpo0->dpoi_index)); + } else next[0] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; if (dpo_is_hicn (dpo1)) - next[1] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[1] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[1], &dst_addr1, hicn_strategy_dpo_ctx_get (dpo1->dpoi_index)); + } else next[1] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; if (dpo_is_hicn (dpo2)) - next[2] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[2] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[2], &dst_addr2, hicn_strategy_dpo_ctx_get (dpo2->dpoi_index)); + } else next[2] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; if (dpo_is_hicn (dpo3)) - next[3] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[3] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[3], &dst_addr3, hicn_strategy_dpo_ctx_get (dpo3->dpoi_index)); + } else next[3] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; @@ -495,9 +531,8 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, { ip4_header_t *ip0, *ip1; const load_balance_t *lb0, *lb1; - ip4_fib_mtrie_t *mtrie0, *mtrie1; - ip4_fib_mtrie_leaf_t leaf0, leaf1; ip4_address_t *src_addr0, *src_addr1; + ip46_address_t dst_addr0, dst_addr1; u32 lb_index0, lb_index1; flow_hash_config_t flow_hash_config0, flow_hash_config1; u32 hash_c0, hash_c1; @@ -518,23 +553,15 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, src_addr0 = &ip0->src_address; src_addr1 = &ip1->src_address; + ip46_address_set_ip4 (&dst_addr0, &ip0->dst_address); + ip46_address_set_ip4 (&dst_addr1, &ip1->dst_address); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[0]); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[1]); - mtrie0 = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie; - mtrie1 = &ip4_fib_get (vnet_buffer (b[1])->ip.fib_index)->mtrie; - - leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, src_addr0); - leaf1 = ip4_fib_mtrie_lookup_step_one (mtrie1, src_addr1); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 2); - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 2); - - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 3); - leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 3); - - lb_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); - lb_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1); + ip4_fib_forwarding_lookup_x2 ( + vnet_buffer (b[0])->ip.fib_index, vnet_buffer (b[1])->ip.fib_index, + src_addr0, src_addr1, &lb_index0, &lb_index1); ASSERT (lb_index0 && lb_index1); lb0 = load_balance_get (lb_index0); @@ -549,12 +576,20 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, dpo1 = load_balance_get_bucket_i (lb1, 0); if (dpo_is_hicn (dpo0)) - next[0] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[0] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[0], &dst_addr0, hicn_strategy_dpo_ctx_get (dpo0->dpoi_index)); + } else next[0] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; if (dpo_is_hicn (dpo1)) - next[1] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[1] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[1], &dst_addr1, hicn_strategy_dpo_ctx_get (dpo1->dpoi_index)); + } else next[1] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; @@ -592,21 +627,18 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, { ip4_header_t *ip0; const load_balance_t *lb0; - ip4_fib_mtrie_t *mtrie0; - ip4_fib_mtrie_leaf_t leaf0; ip4_address_t *src_addr0; + ip46_address_t dst_addr0; u32 lbi0; const dpo_id_t *dpo0; ip0 = vlib_buffer_get_current (b[0]); src_addr0 = &ip0->src_address; + ip46_address_set_ip4 (&dst_addr0, &ip0->dst_address); ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[0]); - mtrie0 = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie; - leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, src_addr0); - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 2); - leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 3); - lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); + lbi0 = ip4_fib_forwarding_lookup (vnet_buffer (b[0])->ip.fib_index, + src_addr0); ASSERT (lbi0); lb0 = load_balance_get (lbi0); @@ -617,7 +649,11 @@ hicn_data_input_ip4_fn (vlib_main_t *vm, vlib_node_runtime_t *node, dpo0 = load_balance_get_bucket_i (lb0, 0); if (dpo_is_hicn (dpo0)) - next[0] = HICN_DATA_INPUT_IP4_NEXT_FACE; + { + next[0] = (ip_lookup_next_t) HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + hicn_data_input_set_adj_index ( + b[0], &dst_addr0, hicn_strategy_dpo_ctx_get (dpo0->dpoi_index)); + } else next[0] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; diff --git a/hicn-plugin/src/data_pcslookup.h b/hicn-plugin/src/data_pcslookup.h index b548497b6..32fca952a 100644 --- a/hicn-plugin/src/data_pcslookup.h +++ b/hicn-plugin/src/data_pcslookup.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/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c index 073d06c96..69278c306 100644 --- a/hicn-plugin/src/data_pcslookup_node.c +++ b/hicn-plugin/src/data_pcslookup_node.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: @@ -74,7 +74,7 @@ hicn_data_pcslookup_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, u32 node_id0 = 0; index_t dpo_ctx_id0 = 0; int ret0; - u8 vft_id0; + u8 vft_id0 = 0; u8 is_cs0; u8 hash_entry_id = 0; u8 bucket_is_overflown = 0; diff --git a/hicn-plugin/src/error.c b/hicn-plugin/src/error.c index 4c6986999..a64066d67 100644 --- a/hicn-plugin/src/error.c +++ b/hicn-plugin/src/error.c @@ -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: @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "error.h" +#include <vpp_plugins/hicn/error.h> const char *HICN_ERROR_STRING[] = { #define _(a, b, c) c, diff --git a/hicn-plugin/src/face_db.h b/hicn-plugin/src/face_db.h index 1bc061721..37a2af9ca 100644 --- a/hicn-plugin/src/face_db.h +++ b/hicn-plugin/src/face_db.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: @@ -78,8 +78,8 @@ hicn_face_db_get_dpo_face (u32 index, hicn_face_db_t *face_db) ASSERT (index < face_db->n_faces); return index < HICN_FACE_DB_INLINE_FACES ? - (face_db->inline_faces[index]) : - (pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket) + (face_db->inline_faces[index]) : + (pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket) ->faces[(index - HICN_FACE_DB_INLINE_FACES) & (HICN_PIT_N_HOP_BUCKET - 1)]); } @@ -106,8 +106,8 @@ hicn_face_db_add_face (hicn_face_id_t face_id, hicn_face_db_t *face_db) hicn_face_id_t *element = face_db->n_faces < HICN_FACE_DB_INLINE_FACES ? - &(face_db->inline_faces[face_db->n_faces]) : - &(faces_bkt->faces[(face_db->n_faces - HICN_FACE_DB_INLINE_FACES) & + &(face_db->inline_faces[face_db->n_faces]) : + &(faces_bkt->faces[(face_db->n_faces - HICN_FACE_DB_INLINE_FACES) & (HICN_PIT_N_HOP_BUCKET - 1)]); *element = face_id; 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..b3488c462 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: @@ -114,8 +114,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 +175,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..1e569b82b 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 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: @@ -30,7 +30,7 @@ hicn_face_prod_state_t *face_state_vec; 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); @@ -49,6 +49,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 */ @@ -119,7 +120,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 +140,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)) { @@ -268,15 +270,21 @@ hicn_face_prod_add (fib_prefix_t *prefix, u32 sw_if, u32 *cs_reserved, fib_table_entry_path_add2 (fib_index, prefix, FIB_SOURCE_CLI, 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; + hicn_route_enable (prefix, &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); *faceid = hicn_dpoi_get_index (face); @@ -289,6 +297,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 +313,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_CLI); + 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; } diff --git a/hicn-plugin/src/faces/app/face_prod.h b/hicn-plugin/src/faces/app/face_prod.h index 4acf89dfc..51373d541 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 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; diff --git a/hicn-plugin/src/faces/app/face_prod_node.c b/hicn-plugin/src/faces/app/face_prod_node.c index c4c9edc32..5d2b54040 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 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,7 +24,6 @@ */ #include "face_prod.h" -#include "../../hicn_api.h" #include "../../mgmt.h" static __clib_unused char *face_prod_input_error_strings[] = { @@ -114,7 +113,7 @@ hicn_face_prod_next_from_data_hdr (vlib_node_runtime_t *node, vlib_buffer_t *b, } return match_res ? HICN_FACE_PROD_NEXT_DATA_IP4 + (v == 0x60) : - HICN_FACE_PROD_NEXT_ERROR_DROP; + HICN_FACE_PROD_NEXT_ERROR_DROP; } static_always_inline void @@ -151,6 +150,7 @@ 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; @@ -190,11 +190,30 @@ 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); + 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; + 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]]; + vnet_buffer (b0)->ip.adj_index[VLIB_RX] = + face_state_vec[vnet_buffer (b0)->sw_if_index[VLIB_RX]].adj_index; + vnet_buffer (b1)->ip.adj_index[VLIB_RX] = + face_state_vec[vnet_buffer (b1)->sw_if_index[VLIB_RX]].adj_index; + vnet_buffer (b2)->ip.adj_index[VLIB_RX] = + face_state_vec[vnet_buffer (b2)->sw_if_index[VLIB_RX]].adj_index; + vnet_buffer (b3)->ip.adj_index[VLIB_RX] = + face_state_vec[vnet_buffer (b3)->sw_if_index[VLIB_RX]].adj_index; + next0 = hicn_face_prod_next_from_data_hdr (node, b0, &prod_face0->prefix); next1 = @@ -226,6 +245,7 @@ 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; + hicn_buffer_t *hicnb0; u32 bi0, swif; hicn_face_prod_state_t *prod_face = NULL; u32 next0; @@ -245,11 +265,15 @@ 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); + hicnb0 = hicn_get_buffer (b0); + hicnb0->flags = HICN_FACE_FLAGS_DEFAULT; swif = vnet_buffer (b0)->sw_if_index[VLIB_RX]; prod_face = &face_state_vec[swif]; next0 = hicn_face_prod_next_from_data_hdr (node, b0, &prod_face->prefix); + vnet_buffer (b0)->ip.adj_index[VLIB_RX] = + face_state_vec[swif].adj_index; stats.pkts_data_count++; /* trace */ diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c index d62054365..854fd81d3 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 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: @@ -57,11 +57,8 @@ 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 @@ -163,14 +160,9 @@ hicn_face_module_init (vlib_main_t *vm) counters = vec_new (vlib_combined_counter_main_t, HICN_PARAM_FACES_MAX * HICN_N_COUNTER); - mhash_init (&hicn_face_vec_hashtb, - sizeof (hicn_face_input_faces_t) /* value */, - sizeof (hicn_face_key_t) /* key */); mhash_init (&hicn_face_hashtb, sizeof (hicn_face_id_t) /* value */, sizeof (hicn_face_key_t) /* key */); - pool_alloc (hicn_vec_pool, 100); - /* * How much useful is the following registration? * So far it seems that we need it only for setting the dpo_type. @@ -182,7 +174,7 @@ 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); } u8 * @@ -256,46 +248,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 @@ -320,7 +277,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); @@ -375,8 +332,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); @@ -395,52 +351,6 @@ hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address, int sw_if, 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..39505c942 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,11 @@ #include <vppinfra/bihash_8_8.h> #include <vnet/adj/adj_midchain.h> -#include "../error.h" +#include <vpp_plugins/hicn/error.h> + +#include "../udp_tunnels/udp_tunnel.h" +#include "../hicn_logging.h" + typedef u8 hicn_face_flags_t; typedef index_t hicn_face_id_t; @@ -66,12 +70,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. */ /** @@ -129,14 +129,17 @@ extern hicn_face_t *hicn_dpoi_face_pool; #define HICN_FACE_FLAGS_APPFACE_CONS \ 0x08 /* Currently only IP face can be appface */ #define HICN_FACE_FLAGS_DELETED 0x10 +#define HICN_FACE_FLAGS_UDP 0x20 #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 +#define HICN_BUFFER_FLAGS_DEFAULT 0x00 +#define HICN_BUFFER_FLAGS_NEW_FACE 0x02 +#define HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL 0x04 +#define HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL 0x08 STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_PROD_BIT) == HICN_FACE_FLAGS_APPFACE_PROD, @@ -148,16 +151,6 @@ STATIC_ASSERT ((1 << HICN_FACE_FLAGS_APPFACE_CONS_BIT) == "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 +250,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 +276,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 +338,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 +360,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 +431,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 +461,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 +471,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 @@ -526,7 +498,7 @@ int hicn_face_add (const dpo_id_t *dpo_nh, ip46_address_t *nat_address, */ 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_face_id_t *pfaceid, u32 adj_index, u8 flags) { hicn_face_t *face; pool_get (hicn_dpoi_face_pool, face); @@ -534,16 +506,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->dpo.dpoi_next_node = 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,79 +535,6 @@ 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. - */ -always_inline int -hicn_face_ip4_lock (hicn_face_id_t *face_id, u32 *in_faces_vec_id, - u8 *hicnb_flags, const ip4_address_t *nat_addr) -{ - ip46_address_t ip_address = { 0 }; - ip46_address_set_ip4 (&ip_address, nat_addr); - hicn_face_input_faces_t *in_faces_vec = - hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb); - - if (PREDICT_FALSE (in_faces_vec == NULL)) - return HICN_ERROR_FACE_NOT_FOUND; - - *in_faces_vec_id = in_faces_vec->vec_id; - hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id); - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *face_id = in_faces_vec->face_id; - - return HICN_ERROR_NONE; -} - -/** - * @brief Retrieve a face from the ip6 local address and returns its dpo. This - * method adds a lock on the face state. - * - * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL - * @param hicnb_flags: Flags that indicate whether the face is an application - * face or not - * @param nat_addr: Ip v6 nat address of the face - * @param sw_if: software interface id of the face - * - * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise - * HICN_ERROR_NONE. - */ -always_inline int -hicn_face_ip6_lock (hicn_face_id_t *face_id, u32 *in_faces_vec_id, - u8 *hicnb_flags, const ip6_address_t *nat_addr) -{ - hicn_face_input_faces_t *in_faces_vec = - hicn_face_get_vec ((ip46_address_t *) nat_addr, &hicn_face_vec_hashtb); - - if (PREDICT_FALSE (in_faces_vec == NULL)) - return HICN_ERROR_FACE_NOT_FOUND; - - *in_faces_vec_id = in_faces_vec->vec_id; - hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id); - - *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; - *hicnb_flags |= (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >> - HICN_FACE_FLAGS_APPFACE_PROD_BIT; - - *face_id = in_faces_vec->face_id; - - return HICN_ERROR_NONE; -} - -/** * @brief Call back to get the adj of the tunnel */ static adj_walk_rc_t @@ -658,11 +560,12 @@ 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) { + int ret = HICN_ERROR_NONE; /*All (complete) faces are indexed by remote addess as well */ ip46_address_t ip_address = { 0 }; @@ -675,12 +578,30 @@ hicn_iface_ip4_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags, if (face == NULL) { hicn_face_id_t idx; - hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index); + u8 face_flags = 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; + if (*hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && + adj_index != ADJ_INDEX_INVALID) + { + face->dpo.dpoi_type = dpo_type_udp_ip6; + face->dpo.dpoi_proto = DPO_PROTO_IP6; + } + else if (*hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && + adj_index != ADJ_INDEX_INVALID) + { + face->dpo.dpoi_type = dpo_type_udp_ip4; + face->dpo.dpoi_proto = DPO_PROTO_IP4; + } + else + { + 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; @@ -691,15 +612,17 @@ 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; + return ret; } 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); + ret = HICN_ERROR_FACE_ALREADY_CREATED; } /* Code replicated on purpose */ @@ -708,6 +631,8 @@ hicn_iface_ip4_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags, HICN_FACE_FLAGS_APPFACE_PROD_BIT; *index = hicn_dpoi_get_index (face); + + return ret; } /** @@ -723,7 +648,8 @@ 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); } @@ -741,11 +667,13 @@ 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) { + int ret = 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 ((ip46_address_t *) nat_addr, sw_if, @@ -754,13 +682,30 @@ hicn_iface_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags, if (face == NULL) { hicn_face_id_t idx; - hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, - adj_index); + u8 face_flags = 0; + + hicn_iface_add ((ip46_address_t *) nat_addr, 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_IP6; + if (*hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL && + adj_index != ADJ_INDEX_INVALID) + { + face->dpo.dpoi_type = dpo_type_udp_ip6; + face->dpo.dpoi_proto = DPO_PROTO_IP6; + } + else if (*hicnb_flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL && + adj_index != ADJ_INDEX_INVALID) + { + face->dpo.dpoi_type = dpo_type_udp_ip4; + face->dpo.dpoi_proto = DPO_PROTO_IP4; + } + else + { + 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; @@ -768,16 +713,18 @@ hicn_iface_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags, face); *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT; + *hicnb_flags |= HICN_BUFFER_FLAGS_NEW_FACE; *index = idx; - return; + return ret; } 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); + ret = HICN_ERROR_FACE_ALREADY_CREATED; } /* Code replicated on purpose */ @@ -786,6 +733,8 @@ hicn_iface_ip6_add_and_lock (hicn_face_id_t *index, u8 *hicnb_flags, HICN_FACE_FLAGS_APPFACE_PROD_BIT; *index = hicn_dpoi_get_index (face); + + return ret; } #endif // __HICN_FACE_H__ diff --git a/hicn-plugin/src/faces/face_cli.c b/hicn-plugin/src/faces/face_cli.c index a4092e6f4..20acefc5b 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 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/face_node.c b/hicn-plugin/src/faces/face_node.c index 5fe682bd0..dc9bfffd0 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 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: @@ -95,9 +95,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 +108,12 @@ typedef enum do \ { \ vlib_buffer_t *b0; \ - u32 bi0; \ + u32 bi0, sw_if0; \ u32 next0 = NEXT_ERROR_DROP_IP##ipv; \ IP_HEADER_##ipv *ip_hdr = NULL; \ hicn_buffer_t *hicnb0; \ - int ret; \ + int from_tunnel0; \ + int ret0; \ /* Prefetch for next iteration. */ \ if (n_left_from > 1) \ { \ @@ -138,23 +136,26 @@ typedef enum \ u8 is_icmp = ip_hdr->protocol == IPPROTO_ICMPV##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##_add_and_lock ( \ + &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 */ \ + ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \ + \ next0 = \ is_icmp * NEXT_MAPME_IP##ipv + (1 - is_icmp) * NEXT_DATA_IP##ipv; \ \ - ret = LOCK_DPO_FACE_IP##ipv (&(hicnb0->face_id), \ - &(hicnb0->in_faces_vec_id), \ - &hicnb0->flags, &(ip_hdr->dst_address)); \ - \ - if (PREDICT_FALSE (ret != HICN_ERROR_NONE)) \ - next0 = NEXT_ERROR_DROP_IP##ipv; \ - 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; \ - } \ + 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))) \ @@ -178,13 +179,14 @@ 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; \ 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. */ \ { \ @@ -216,41 +218,47 @@ typedef enum u8 is_icmp0 = ip_hdr0->protocol == IPPROTO_ICMPV##ipv; \ u8 is_icmp1 = ip_hdr1->protocol == IPPROTO_ICMPV##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##_add_and_lock ( \ + &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 */ \ + ASSERT (ret0 == HICN_ERROR_FACE_ALREADY_CREATED); \ + \ + 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##_add_and_lock ( \ + &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 */ \ + ASSERT (ret1 == HICN_ERROR_FACE_ALREADY_CREATED); \ + \ 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)); \ + 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; \ \ - 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 \ - { \ - 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 (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; \ - } \ + 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))) \ @@ -437,6 +445,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,6 +454,7 @@ 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, @@ -546,7 +556,9 @@ hicn_face_rewrite_interest (vlib_main_t *vm, vlib_buffer_t *b0, if (ret == HICN_LIB_ERROR_REWRITE_CKSUM_REQUIRED) { - ensure_offload_flags (b0, ip46_address_is_ip4 (&face->nat_addr)); + u8 is_v4 = ip46_address_is_ip4 (&face->nat_addr) && + !ip6_address_is_loopback (&face->nat_addr.ip6); + ensure_offload_flags (b0, is_v4); } ASSERT (face->flags & HICN_FACE_FLAGS_FACE); @@ -593,8 +605,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 +627,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; \ @@ -650,9 +663,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 +692,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 +708,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; \ @@ -797,7 +814,8 @@ VLIB_REGISTER_NODE (hicn4_face_output_node) = { .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", + .next_nodes = { [HICN4_FACE_OUTPUT_NEXT_ERROR_DROP] = "error-drop", + [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" } }; @@ -867,7 +885,8 @@ VLIB_REGISTER_NODE (hicn6_face_output_node) = { .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", + .next_nodes = { [HICN6_FACE_OUTPUT_NEXT_ERROR_DROP] = "error-drop", + [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" } }; 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..84205af9b 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 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: @@ -107,8 +107,8 @@ typedef enum 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 DPO_ADD_LOCK_FACE_IP4 hicn_face_ip4_add_and_lock +#define DPO_ADD_LOCK_FACE_IP6 hicn_face_ip6_add_and_lock //#define VLIB_EDGE_IP4 data_fwd_iface_ip4_vlib_edge //#define VLIB_EDGE_IP6 data_fwd_iface_ip6_vlib_edge @@ -144,6 +144,7 @@ typedef struct typedef enum { + HICN4_IFACE_OUTPUT_NEXT_DROP, HICN4_IFACE_OUTPUT_NEXT_LOOKUP, HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP, HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP, @@ -161,6 +162,7 @@ typedef struct typedef enum { + HICN6_IFACE_OUTPUT_NEXT_DROP, HICN6_IFACE_OUTPUT_NEXT_LOOKUP, HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP, HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP, @@ -188,7 +190,7 @@ typedef enum do \ { \ vlib_buffer_t *b0; \ - u32 bi0, next0, next_iface0; \ + u32 bi0, next0, next_iface0, sw_if0; \ IP_HEADER_##ipv *ip_hdr = NULL; \ hicn_buffer_t *hicnb0; \ /* Prefetch for next iteration. */ \ @@ -219,15 +221,23 @@ typedef enum is_icmp * NEXT_MAPME_IP##ipv + (1 - is_icmp) * 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) \ - next_iface0 = NEXT_UDP_ENCAP_IP4; \ - else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \ - next_iface0 = NEXT_UDP_ENCAP_IP6; \ + 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; \ + } \ \ - DPO_ADD_LOCK_IFACE_IP##ipv ( \ - &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr->src_address), \ - vnet_buffer (b0)->sw_if_index[VLIB_RX], \ + 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) && \ @@ -236,7 +246,7 @@ typedef enum 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->sw_if_index = sw_if0; \ t->next_index = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ @@ -257,7 +267,7 @@ typedef enum do \ { \ vlib_buffer_t *b0, *b1; \ - u32 bi0, bi1, next0, next1, next_iface0, next_iface1; \ + u32 bi0, bi1, next0, next1, next_iface0, next_iface1, sw_if0, sw_if1; \ IP_HEADER_##ipv *ip_hdr0 = NULL; \ IP_HEADER_##ipv *ip_hdr1 = NULL; \ hicn_buffer_t *hicnb0, *hicnb1; \ @@ -300,27 +310,43 @@ typedef enum (1 - is_icmp1) * 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) \ - next_iface0 = NEXT_UDP_ENCAP_IP4; \ - else if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \ - next_iface0 = NEXT_UDP_ENCAP_IP6; \ + 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; \ + } \ \ 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) \ - next_iface1 = NEXT_UDP_ENCAP_IP4; \ - else if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \ - next_iface1 = NEXT_UDP_ENCAP_IP6; \ + 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; \ + } \ \ - DPO_ADD_LOCK_IFACE_IP##ipv ( \ - &(hicnb0->face_id), &hicnb0->flags, &(ip_hdr0->src_address), \ - vnet_buffer (b0)->sw_if_index[VLIB_RX], \ + 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_IFACE_IP##ipv ( \ - &(hicnb1->face_id), &hicnb1->flags, &(ip_hdr1->src_address), \ - vnet_buffer (b1)->sw_if_index[VLIB_RX], \ + 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); \ \ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \ @@ -329,7 +355,7 @@ typedef enum 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->sw_if_index = sw_if0; \ t->next_index = next0; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b0), \ sizeof (t->packet_data)); \ @@ -341,7 +367,7 @@ 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->sw_if_index = sw_if1; \ t->next_index = next1; \ clib_memcpy_fast (t->packet_data, vlib_buffer_get_current (b1), \ sizeof (t->packet_data)); \ @@ -588,7 +614,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 +635,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)) \ { \ @@ -646,7 +673,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 +701,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)) \ { \ @@ -738,7 +767,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,7 +821,8 @@ 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" }, }; @@ -807,7 +837,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 +890,10 @@ 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" }, }; /* diff --git a/hicn-plugin/src/faces/iface_node.h b/hicn-plugin/src/faces/iface_node.h index acb3cab0f..3fa6bb484 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: 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 diff --git a/hicn-plugin/src/hashtb.c b/hicn-plugin/src/hashtb.c index a74353239..eb7da81f2 100644 --- a/hicn-plugin/src/hashtb.c +++ b/hicn-plugin/src/hashtb.c @@ -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: @@ -187,7 +187,7 @@ hicn_hashtb_alloc (hicn_hashtb_h *ph, u32 max_elems, size_t app_data_size) } pool_get_aligned (h->ht_nodes, nodep, 8); // alloc node 0 - nodep = nodep; /* Silence 'not used' warning */ + (void) nodep; /* Silence 'not used' warning */ h->ht_node_count = max_elems; h->ht_nodes_used = 1; @@ -206,7 +206,7 @@ hicn_hashtb_alloc (hicn_hashtb_h *ph, u32 max_elems, size_t app_data_size) } /* 'Hide' the zero-th node so we can use zero as an 'empty' value */ pool_get_aligned (h->ht_overflow_buckets, bucket, 8); - bucket = bucket; /* Silence 'not used' warning */ + (void) bucket; /* Silence 'not used' warning */ h->ht_overflow_bucket_count = count; h->ht_overflow_buckets_used = 1; diff --git a/hicn-plugin/src/hashtb.h b/hicn-plugin/src/hashtb.h index 3965ec65d..4b787e2d7 100644 --- a/hicn-plugin/src/hashtb.h +++ b/hicn-plugin/src/hashtb.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/hicn.api b/hicn-plugin/src/hicn.api index 9643f2098..44382c743 100644 --- a/hicn-plugin/src/hicn.api +++ b/hicn-plugin/src/hicn.api @@ -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: @@ -437,8 +437,14 @@ define hicn_api_enable_disable_reply /* Arbitrary context, so client can match reply to request */ u32 context; -/* Return value, zero means all OK */ + /* Return value, zero means all OK */ i32 retval; + + /* Number of faces created */ + u8 nfaces; + + /* IDs of new faces */ + u32 faceids[16]; }; define hicn_api_register_prod_app diff --git a/hicn-plugin/src/hicn.c b/hicn-plugin/src/hicn.c index 9bec91455..1131d4339 100644 --- a/hicn-plugin/src/hicn.c +++ b/hicn-plugin/src/hicn.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: @@ -149,8 +149,8 @@ hicn_infra_plugin_enable_disable (int enable_disable, int pit_size_req, // check if CS is bugger tha PIT or bigger than the available // vlib_buffers uword cs_buffers = (n_buffers > HICN_PARAM_CS_MIN_MBUF) ? - n_buffers - HICN_PARAM_CS_MIN_MBUF : - 0; + n_buffers - HICN_PARAM_CS_MIN_MBUF : + 0; if (cs_size_req > (pit_size_req / 2) || cs_size_req > cs_buffers) { diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h index 4ff4f6ae6..aaf16c917 100644 --- a/hicn-plugin/src/hicn.h +++ b/hicn-plugin/src/hicn.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: @@ -61,10 +61,8 @@ typedef u8 weight_t; * 2*CLIB_CACHE_LINE_BYTES. */ /* This flag is used to mark packets whose lenght is less that * 2*CLIB_CACHE_LINE_BYTES. */ -#define HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL 0x02 -#define HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL 0x04 -#define HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL 0x08 -#define HICN_BUFFER_FLAGS_FROM_CS 0x10 +#define HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL 0x02 +#define HICN_BUFFER_FLAGS_FROM_CS 0x10 /* The following is stored in the opaque2 field in the vlib_buffer_t */ typedef struct @@ -83,7 +81,6 @@ typedef struct u8 vft_id; /* " */ hicn_face_id_t face_id; /* ingress iface, sizeof(u32) */ - u32 in_faces_vec_id; /* vector of possible input face for a data packet */ hicn_type_t type; } hicn_buffer_t; diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c index b72675f63..85279eb0b 100644 --- a/hicn-plugin/src/hicn_api.c +++ b/hicn-plugin/src/hicn_api.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: @@ -40,12 +40,12 @@ #include "route.h" /* define message IDs */ -#include <hicn/hicn.api_enum.h> -#include <hicn/hicn.api_types.h> +#include <vpp_plugins/hicn/hicn.api_enum.h> +#include <vpp_plugins/hicn/hicn.api_types.h> /* define generated endian-swappers */ #define vl_endianfun -#include <hicn/hicn_all_api_h.h> +#include <vpp_plugins/hicn/hicn_all_api_h.h> #undef vl_endianfun #define REPLY_MSG_ID_BASE sm->msg_id_base @@ -79,8 +79,8 @@ vl_api_hicn_api_node_params_set_t_handler ( f64 pit_max_lifetime_sec = mp->pit_max_lifetime_sec; pit_max_lifetime_sec = pit_max_lifetime_sec == -1 ? - HICN_PARAM_PIT_LIFETIME_DFLT_MAX_MS / SEC_MS : - pit_max_lifetime_sec; + HICN_PARAM_PIT_LIFETIME_DFLT_MAX_MS / SEC_MS : + pit_max_lifetime_sec; int cs_max_size = clib_net_to_host_i32 (mp->cs_max_size); cs_max_size = cs_max_size == -1 ? HICN_PARAM_CS_ENTRIES_DFLT : cs_max_size; @@ -159,7 +159,7 @@ send_face_details (hicn_face_t *face, vl_api_hicn_face_t *mp) { sbuf = format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface); - strcpy ((char *) (mp->if_name), (char *) sbuf); + strcpy_s ((char *) (mp->if_name), sizeof (mp->if_name), (char *) sbuf); } } @@ -567,17 +567,34 @@ vl_api_hicn_api_enable_disable_t_handler (vl_api_hicn_api_enable_disable_t *mp) fib_prefix_t prefix; ip_prefix_decode (&mp->prefix, &prefix); + hicn_face_id_t *vec_faces = NULL; + switch (clib_net_to_host_u32 (mp->enable_disable)) { case HICN_ENABLE: - rv = hicn_route_enable (&prefix); + HICN_DEBUG ("Calling hicn enable from API."); + rv = hicn_route_enable (&prefix, &vec_faces); break; case HICN_DISABLE: + HICN_DEBUG ("Calling hicn disable from API."); rv = hicn_route_disable (&prefix); break; } - REPLY_MACRO (VL_API_HICN_API_ENABLE_DISABLE_REPLY /* , rmp, mp, rv */); + REPLY_MACRO2 (VL_API_HICN_API_ENABLE_DISABLE_REPLY, ({ + rmp->nfaces = 0; + if (vec_faces != NULL) + { + hicn_face_id_t *face; + vec_foreach (face, vec_faces) + { + rmp->faceids[rmp->nfaces++] = + clib_host_to_net_u32 (*face); + } + + vec_free (vec_faces); + } + })); } /*********************************** UDP TUNNELS @@ -632,7 +649,7 @@ done: /************************************************************************************/ -#include <hicn/hicn.api.c> +#include <vpp_plugins/hicn/hicn.api.c> /* Set up the API message handling tables */ clib_error_t * diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c index 04e216e38..fbba5ffc3 100644 --- a/hicn-plugin/src/hicn_api_test.c +++ b/hicn-plugin/src/hicn_api_test.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: @@ -31,11 +31,11 @@ #include <vpp/api/vpe.api_types.h> -#include <hicn/hicn_api.h> -#include "error.h" +#include <vpp_plugins/hicn/hicn_api.h> +#include <vpp_plugins/hicn/error.h> /* Declare message IDs */ -#include "hicn_msg_enum.h" +#include <vpp_plugins/hicn/hicn_msg_enum.h> /* SUPPORTING FUNCTIONS NOT LOADED BY VPP_API_TEST */ uword @@ -1000,8 +1000,8 @@ api_hicn_api_enable_disable (vat_main_t *vam) } prefix.fp_proto = ip46_address_is_ip4 (&(prefix.fp_addr)) ? - FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6; + FIB_PROTOCOL_IP4 : + FIB_PROTOCOL_IP6; // Construct the API message M (HICN_API_ENABLE_DISABLE, mp); @@ -1053,8 +1053,8 @@ api_hicn_api_register_prod_app (vat_main_t *vam) } prefix.fp_proto = ip46_address_is_ip4 (&(prefix.fp_addr)) ? - FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6; + FIB_PROTOCOL_IP4 : + FIB_PROTOCOL_IP6; /* Construct the API message */ M (HICN_API_REGISTER_PROD_APP, mp); ip_prefix_encode (&prefix, &mp->prefix); @@ -1310,7 +1310,7 @@ vl_api_hicn_api_udp_tunnel_add_del_reply_t_handler ( fformat (vam->ofp, "udp-encap %d\n", uei); } -#include <hicn/hicn.api_test.c> +#include <vpp_plugins/hicn/hicn.api_test.c> /* * fd.io coding-style-patch-verification: ON diff --git a/hicn-plugin/src/hicn_logging.h b/hicn-plugin/src/hicn_logging.h new file mode 100644 index 000000000..a960a7212 --- /dev/null +++ b/hicn-plugin/src/hicn_logging.h @@ -0,0 +1,32 @@ +/* + * 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_DEBUG_H__ +#define __HICN_DEBUG_H__ + +#ifdef HICN_DDEBUG +#define HICN_DEBUG(...) \ + do \ + { \ + clib_warning (__VA_ARGS__); \ + } \ + while (0) +#else +#define HICN_DEBUG(...) +#endif /* HICN_DEBUG */ + +#define HICN_ERROR(...) clib_error_return (0, __VA_ARGS__) + +#endif /* __HICN_DEBUG_H__ */
\ No newline at end of file diff --git a/hicn-plugin/src/infra.c b/hicn-plugin/src/infra.c new file mode 100644 index 000000000..e0dba5efd --- /dev/null +++ b/hicn-plugin/src/infra.c @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#include "infra.h" + +/** + * @file infra.c + * + */ + +/* PIT and CS size */ +u32 hicn_infra_pit_size; +u32 hicn_infra_cs_size; diff --git a/hicn-plugin/src/infra.h b/hicn-plugin/src/infra.h index 900ecedde..c942ad581 100644 --- a/hicn-plugin/src/infra.h +++ b/hicn-plugin/src/infra.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: @@ -57,8 +57,8 @@ extern hicn_main_t hicn_main; extern int hicn_infra_fwdr_initialized; /* PIT and CS size */ -u32 hicn_infra_pit_size; -u32 hicn_infra_cs_size; +extern u32 hicn_infra_pit_size; +extern u32 hicn_infra_cs_size; /** * @brief Enable and disable the hicn plugin diff --git a/hicn-plugin/src/interest_hitcs.h b/hicn-plugin/src/interest_hitcs.h index 05a790688..0df987778 100644 --- a/hicn-plugin/src/interest_hitcs.h +++ b/hicn-plugin/src/interest_hitcs.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: diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c index e29b173a9..947b4cb68 100644 --- a/hicn-plugin/src/interest_hitcs_node.c +++ b/hicn-plugin/src/interest_hitcs_node.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: @@ -189,7 +189,7 @@ hicn_interest_hitcs_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, * the data through it */ next0 = isv6 ? HICN_INTEREST_HITCS_NEXT_IFACE6_OUT : - HICN_INTEREST_HITCS_NEXT_IFACE4_OUT; + HICN_INTEREST_HITCS_NEXT_IFACE4_OUT; vnet_buffer (b0)->ip.adj_index[VLIB_TX] = hicnb0->face_id; clone_from_cs (vm, &pitp->u.cs.cs_pkt_buf, b0, isv6); diff --git a/hicn-plugin/src/interest_hitpit.h b/hicn-plugin/src/interest_hitpit.h index 44cf2c879..18ef94aa7 100644 --- a/hicn-plugin/src/interest_hitpit.h +++ b/hicn-plugin/src/interest_hitpit.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: diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c index 837eddca7..33dc782cd 100644 --- a/hicn-plugin/src/interest_hitpit_node.c +++ b/hicn-plugin/src/interest_hitpit_node.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: @@ -88,7 +88,8 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, u8 dpo_ctx_id0; u8 found = 0; int nh_idx; - hicn_face_id_t outface; + hicn_face_id_t outfaces[MAX_OUT_FACES]; + u32 outfaces_len; hicn_hash_entry_t *hash_entry0; hicn_buffer_t *hicnb0; int ret; @@ -171,23 +172,77 @@ hicn_interest_hitpit_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, if (found) { - strategy_vft0->hicn_select_next_hop (dpo_ctx_id0, - &nh_idx, &outface); + strategy_vft0->hicn_select_next_hop ( + dpo_ctx_id0, &nh_idx, outfaces, &outfaces_len); /* Retransmission */ /* * Prepare the packet for the * forwarding */ - next0 = isv6 ? HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT : - HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT; - vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface; - - /* - * Update the egress face in - * the PIT - */ - pitp->u.pit.pe_txnh = nh_idx; - stats.interests_retx++; + if (outfaces_len == 1) + { + next0 = isv6 ? + HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT : + HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT; + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = + outfaces[0]; + + /* + * Update the egress face in + * the PIT + */ + pitp->u.pit.pe_txnh = nh_idx; + stats.interests_retx++; + } + else + { + // restore pointers + to_next -= 1; + n_left_to_next += 1; + u32 clones[outfaces_len]; + int ret = + vlib_buffer_clone (vm, bi0, clones, outfaces_len, + CLIB_CACHE_LINE_BYTES * 2); + ASSERT (ret == outfaces_len); + for (u32 nh = 0; nh < outfaces_len; nh++) + { + vlib_buffer_t *local_b0 = + vlib_get_buffer (vm, clones[nh]); + to_next[0] = clones[nh]; + to_next += 1; + n_left_to_next -= 1; + + next0 = + isv6 ? HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT : + HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT; + vnet_buffer (local_b0)->ip.adj_index[VLIB_TX] = + outfaces[nh]; + stats.interests_retx++; + + /* Maybe trace */ + if (PREDICT_FALSE ( + (node->flags & VLIB_NODE_FLAG_TRACE) && + (local_b0->flags & VLIB_BUFFER_IS_TRACED))) + { + hicn_interest_hitpit_trace_t *t = + vlib_add_trace (vm, node, local_b0, + sizeof (*t)); + t->pkt_type = HICN_PKT_TYPE_INTEREST; + t->sw_if_index = vnet_buffer (local_b0) + ->sw_if_index[VLIB_RX]; + t->next_index = next0; + } + + /* + * Verify speculative enqueue, maybe switch + * current next frame + */ + vlib_validate_buffer_enqueue_x1 ( + vm, node, next_index, to_next, n_left_to_next, + clones[nh], next0); + } + continue; + } } else { diff --git a/hicn-plugin/src/interest_pcslookup.h b/hicn-plugin/src/interest_pcslookup.h index 87d093e91..4da9c1939 100644 --- a/hicn-plugin/src/interest_pcslookup.h +++ b/hicn-plugin/src/interest_pcslookup.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/interest_pcslookup_node.c b/hicn-plugin/src/interest_pcslookup_node.c index d3f6c7bca..ff0da12d7 100644 --- a/hicn-plugin/src/interest_pcslookup_node.c +++ b/hicn-plugin/src/interest_pcslookup_node.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: diff --git a/hicn-plugin/src/mapme.h b/hicn-plugin/src/mapme.h index 63bd42610..1d46ea9f3 100644 --- a/hicn-plugin/src/mapme.h +++ b/hicn-plugin/src/mapme.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: @@ -21,9 +21,9 @@ #include <hicn/mapme.h> #include "hicn.h" -#include "route.h" #include "strategy_dpo_ctx.h" #include "strategy_dpo_manager.h" // dpo_is_hicn +#include "udp_tunnels/udp_tunnel.h" /** * @file @@ -63,7 +63,6 @@ typedef struct hicn_mapme_conf_s bool remove_dpo; // FIXME used ? vlib_main_t *vm; - vlib_log_class_t log_class; } hicn_mapme_main_t; /** @@ -100,65 +99,33 @@ STATIC_ASSERT (sizeof (hicn_mapme_tfib_t) <= sizeof (hicn_dpo_ctx_t), #define TFIB(dpo_ctx) ((hicn_mapme_tfib_t *) (dpo_ctx)) -static_always_inline int -hicn_mapme_nh_set (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) -{ - hicn_dpo_ctx_t *strategy_ctx = (hicn_dpo_ctx_t *) tfib; - const fib_prefix_t *prefix = - fib_entry_get_prefix (strategy_ctx->fib_entry_index); - - u32 n_entries = tfib->entry_count; - /* Remove all the existing next hops and set the new one */ - for (int i = 0; i < n_entries; i++) - { - hicn_face_t *face = hicn_dpoi_get_from_idx (strategy_ctx->next_hops[0]); - ip_adjacency_t *adj = adj_get (face->dpo.dpoi_index); - ip_nh_del_helper (face->dpo.dpoi_proto, prefix, - &adj->sub_type.nbr.next_hop, face->sw_if); - } - hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); - ip_nh_add_helper (face->dpo.dpoi_proto, prefix, &face->nat_addr, - face->sw_if); - return 0; -} - /** - * @brief Add a next hop iif it is not already a next hops + * @brief Check whether a face is already included in the TFIB. + * + * NOTE: linear scan on a contiguous small array should be the most efficient. */ static_always_inline int -hicn_mapme_nh_add (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) +hicn_mapme_tfib_has (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) { - for (u8 pos = 0; pos < tfib->entry_count; pos++) - if (tfib->next_hops[pos] == face_id) - return 0; - - /* Add the next hop in the vrf 0 which will add it to the entry in the hICN - * vrf */ - hicn_dpo_ctx_t *strategy_ctx = (hicn_dpo_ctx_t *) tfib; - const fib_prefix_t *prefix = - fib_entry_get_prefix (strategy_ctx->fib_entry_index); - hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); - ip_nh_add_helper (face->dpo.dpoi_proto, prefix, &face->nat_addr, - face->sw_if); - + u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count; + for (u8 pos2 = pos; pos2 < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos2++) + if (tfib->next_hops[pos2] == face_id) + return 1; return 0; } /** * Add a 'previous' hop to the TFIB - * - * XXX we should have the for look in the reverse order for simpler code. */ static_always_inline int hicn_mapme_tfib_add (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) { - u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count; + // Don't add if it already exists + // (eg. an old IU received on a face on which we are retransmitting) + if (hicn_mapme_tfib_has (tfib, face_id)) + return 0; - // XXX don 't add if it already exist - // eg.an old IU received on a face on which we are retransmitting - for (u8 pos2 = pos; pos2 < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos2++) - if (tfib->next_hops[pos2] == face_id) - return 0; + u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count; // Make sure we have enough room if (pos <= tfib->entry_count) @@ -190,7 +157,6 @@ hicn_mapme_tfib_clear (hicn_mapme_tfib_t *tfib) { hicn_face_unlock_with_id (tfib->next_hops[pos]); tfib->next_hops[pos] = invalid; - break; } tfib->tfib_entry_count = 0; @@ -358,10 +324,6 @@ hicn_mapme_get_dpo_face_node (hicn_face_id_t face_id) } } -#define DEBUG(...) // vlib_log_debug(mapme_main.log_class, __VA_ARGS__) -#define WARN(...) // vlib_log_warn(mapme_main.log_class, __VA_ARGS__) -#define ERROR(...) // vlib_log_err(mapme_main.log_class, __VA_ARGS__) - #endif /* __HICN_MAPME__ */ /* diff --git a/hicn-plugin/src/mapme_ack.h b/hicn-plugin/src/mapme_ack.h index 821baf203..72ed7a0c4 100644 --- a/hicn-plugin/src/mapme_ack.h +++ b/hicn-plugin/src/mapme_ack.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: @@ -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. * */ diff --git a/hicn-plugin/src/mapme_ack_node.c b/hicn-plugin/src/mapme_ack_node.c index fad344b73..ea4834665 100644 --- a/hicn-plugin/src/mapme_ack_node.c +++ b/hicn-plugin/src/mapme_ack_node.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: @@ -14,6 +14,7 @@ */ #include <vnet/ip/ip6_packet.h> +#include <vlib/log.h> #include "hicn.h" #include "mapme.h" @@ -69,7 +70,8 @@ hicn_mapme_process_ack (vlib_main_t *vm, vlib_buffer_t *b, dpo = fib_epm_lookup (&(prefix.name), prefix.len); if (!dpo) { - DEBUG ("Ignored ACK for non-existing FIB entry. Ignored."); + HICN_ERROR ("Ignored ACK for non-existing FIB entry %U. Ignored.", + format_ip_prefix, &prefix); return true; } @@ -80,7 +82,7 @@ hicn_mapme_process_ack (vlib_main_t *vm, vlib_buffer_t *b, if (tfib == NULL) { - WARN ("Unable to get strategy ctx."); + HICN_ERROR ("Unable to get strategy ctx."); return false; } @@ -92,7 +94,7 @@ hicn_mapme_process_ack (vlib_main_t *vm, vlib_buffer_t *b, */ if (params.seq < fib_seq) { - DEBUG ("Ignored ACK for low seq"); + HICN_ERROR ("MAPME: Ignored ACK for low seq"); return true; } diff --git a/hicn-plugin/src/mapme_ctrl.h b/hicn-plugin/src/mapme_ctrl.h index a40a969b0..76382c6d2 100644 --- a/hicn-plugin/src/mapme_ctrl.h +++ b/hicn-plugin/src/mapme_ctrl.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: @@ -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. * */ diff --git a/hicn-plugin/src/mapme_ctrl_node.c b/hicn-plugin/src/mapme_ctrl_node.c index 613958d9c..5314c49a0 100644 --- a/hicn-plugin/src/mapme_ctrl_node.c +++ b/hicn-plugin/src/mapme_ctrl_node.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: @@ -18,6 +18,7 @@ */ #include <vnet/ip/ip6_packet.h> #include <vnet/dpo/load_balance.h> +#include <vlib/log.h> #include "hicn.h" #include "mapme.h" @@ -30,6 +31,7 @@ #include "strategy_dpo_ctx.h" #include "error.h" #include "state.h" +#include "route.h" extern hicn_mapme_main_t mapme_main; @@ -47,6 +49,110 @@ static char *hicn_mapme_ctrl_error_strings[] = { #undef _ }; +static_always_inline int +hicn_mapme_nh_set (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) +{ + hicn_dpo_ctx_t *strategy_ctx = (hicn_dpo_ctx_t *) tfib; + const fib_prefix_t *prefix = + fib_entry_get_prefix (strategy_ctx->fib_entry_index); + + int ret = 0; + + if ((tfib->entry_count == 1) && (tfib->next_hops[0] == face_id)) + return ret; + + u32 n_entries = tfib->entry_count; + /* Remove all the existing next hops and set the new one */ + for (int i = 0; i < n_entries; i++) + { + hicn_face_t *face = hicn_dpoi_get_from_idx (strategy_ctx->next_hops[0]); + if (dpo_is_adj (&face->dpo)) + { + ip_adjacency_t *adj = adj_get (face->dpo.dpoi_index); + ip_nh_adj_add_del_helper (prefix->fp_proto, prefix, + &adj->sub_type.nbr.next_hop, face->sw_if, + 0); + } + else if (face->dpo.dpoi_type == dpo_type_udp_ip4 || + face->dpo.dpoi_type == dpo_type_udp_ip6) + { + ip_nh_udp_tunnel_add_del_helper (prefix->fp_proto, prefix, + face->dpo.dpoi_index, + face->dpo.dpoi_proto, 0); + } + else + { + continue; + } + } + + ret = HICN_ERROR_MAPME_NEXT_HOP_ADDED; + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); + if (face->dpo.dpoi_type == dpo_type_udp_ip4 || + face->dpo.dpoi_type == dpo_type_udp_ip6) + { + ip_nh_udp_tunnel_add_del_helper (prefix->fp_proto, prefix, + face->dpo.dpoi_index, + face->dpo.dpoi_proto, 1); + } + else if (dpo_is_adj (&face->dpo)) + { + ip_nh_adj_add_del_helper (prefix->fp_proto, prefix, &face->nat_addr, + face->sw_if, 1); + } + else + { + ret = HICN_ERROR_MAPME_NEXT_HOP_NOT_ADDED; + } + + return ret; +} + +/** + * @brief Check whether a face is already included in the FIB nexthops. + * + * NOTE: linear scan on a contiguous small array should be the most efficient. + */ +static_always_inline int +hicn_mapme_nh_has (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) +{ + for (u8 pos = 0; pos < tfib->entry_count; pos++) + if (tfib->next_hops[pos] == face_id) + return 1; + return 0; +} + +/** + * @brief Add a next hop iif it is not already a next hops + */ +static_always_inline int +hicn_mapme_nh_add (hicn_mapme_tfib_t *tfib, hicn_face_id_t face_id) +{ + if (hicn_mapme_nh_has (tfib, face_id)) + return 0; + + /* Add the next hop in the vrf 0 which will add it to the entry in the hICN + * vrf */ + hicn_dpo_ctx_t *strategy_ctx = (hicn_dpo_ctx_t *) tfib; + const fib_prefix_t *prefix = + fib_entry_get_prefix (strategy_ctx->fib_entry_index); + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); + if (face->dpo.dpoi_type == dpo_type_udp_ip4 || + face->dpo.dpoi_type == dpo_type_udp_ip6) + { + ip_nh_udp_tunnel_add_del_helper ((fib_protocol_t) face->dpo.dpoi_proto, + prefix, face->dpo.dpoi_index, + face->dpo.dpoi_proto, 1); + } + else + { + ip_nh_adj_add_del_helper ((fib_protocol_t) face->dpo.dpoi_proto, prefix, + &face->nat_addr, face->sw_if, 1); + } + + return 0; +} + /* * @brief Process incoming control messages (Interest Update) * @param vm vlib main data structure @@ -97,7 +203,7 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, * Destroying the face has led to removing all corresponding FIB * entries. In that case, we need to correctly restore the FIB entries. */ - DEBUG ("Re-creating FIB entry with next hop on connection") + HICN_DEBUG ("Re-creating FIB entry with next hop on connection") #error "not implemented" #else // ERROR("Received IU for non-existing FIB entry"); @@ -109,7 +215,7 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, if (!dpo_is_hicn ((dpo))) { /* We have an IP DPO */ - WARN ("Not implemented yet."); + HICN_ERROR ("Not implemented yet."); return false; } #endif @@ -119,7 +225,7 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, if (tfib == NULL) { - WARN ("Unable to get strategy ctx."); + HICN_ERROR ("Unable to get strategy ctx."); return false; } @@ -127,7 +233,7 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, if (params.seq > fib_seq) { - DEBUG ( + HICN_DEBUG ( "Higher sequence number than FIB %d > %d, updating seq and next hops", params.seq, fib_seq); @@ -139,25 +245,29 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, /* Remove ingress face from TFIB in case it was present */ hicn_mapme_tfib_del (tfib, in_face_id); + HICN_DEBUG ("Locks on face %d: %d", in_face_id, + hicn_dpoi_get_from_idx (in_face_id)->locks); + /* Move next hops to TFIB... but in_face... */ for (u8 pos = 0; pos < tfib->entry_count; pos++) { - hicn_face_t *face = hicn_dpoi_get_from_idx (tfib->next_hops[pos]); - hicn_face_t *in_face = hicn_dpoi_get_from_idx (in_face_id); - if (dpo_is_adj (&face->dpo)) - { - ip_adjacency_t *adj = adj_get (dpo->dpoi_index); - if (ip46_address_cmp (&(adj->sub_type.nbr.next_hop), - &(in_face->nat_addr)) == 0) - break; - } - DEBUG ("Adding nexthop to the tfib, dpo index in_face %d, dpo index " - "tfib %d", - in_face_id, tfib->next_hops[pos]); + if (tfib->next_hops[pos] == in_face_id) + continue; + HICN_DEBUG ( + "Adding nexthop to the tfib, dpo index in_face %d, dpo index " + "tfib %d", + in_face_id, tfib->next_hops[pos]); hicn_mapme_tfib_add (tfib, tfib->next_hops[pos]); } - hicn_mapme_nh_set (tfib, in_face_id); + int ret = hicn_mapme_nh_set (tfib, in_face_id); + HICN_DEBUG ("Locks on face %d: %d", in_face_id, + hicn_dpoi_get_from_idx (in_face_id)->locks); + if (ret == HICN_ERROR_MAPME_NEXT_HOP_ADDED && + hicn_get_buffer (b)->flags & HICN_BUFFER_FLAGS_NEW_FACE) + { + hicn_face_unlock_with_id (in_face_id); + } /* We transmit both the prefix and the full dpo (type will be needed to * pick the right transmit node */ @@ -168,15 +278,22 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, } else if (params.seq == fib_seq) { - DEBUG ("Same sequence number than FIB %d > %d, adding next hop", - params.seq, fib_seq); + HICN_DEBUG ("Same sequence number than FIB %d > %d, adding next hop", + params.seq, fib_seq); - /* Remove ingress face from TFIB in case it was present */ - hicn_mapme_tfib_del (tfib, in_face_id); + /** + * Add nh BEFORE removing the face from the tfib, as if the last lock is + * held by the tfib, deleting it first would also delete the face, + * resulting in a undefined behavior after (Debug mode -> SIGABRT, + * Release Mode -> Corrupted memory / SIGSEGV). + **/ /* Add ingress face to next hops */ hicn_mapme_nh_add (tfib, in_face_id); + /* Remove ingress face from TFIB in case it was present */ + hicn_mapme_tfib_del (tfib, in_face_id); + /* Multipath, multihoming, multiple producers or duplicate interest */ retx_t *retx = vlib_process_signal_event_data ( vm, hicn_mapme_eventmgr_process_node.index, @@ -187,8 +304,17 @@ hicn_mapme_process_ctrl (vlib_main_t *vm, vlib_buffer_t *b, { /* * face is propagating outdated information, we can just consider it as a - * prevHops + * prevHops, unless it is the current nexthop. */ + if (hicn_mapme_nh_has (tfib, in_face_id)) + { + HICN_DEBUG ("Ignored seq %d < fib_seq %d from current nexthop", + params.seq, fib_seq); + return true; + } + HICN_DEBUG ("Received seq %d < fib_seq %d, sending backwards", + params.seq, fib_seq); + hicn_mapme_tfib_add (tfib, in_face_id); retx_t *retx = vlib_process_signal_event_data ( diff --git a/hicn-plugin/src/mapme_eventmgr.c b/hicn-plugin/src/mapme_eventmgr.c index 49a9b5c57..c7ae4ecd7 100644 --- a/hicn-plugin/src/mapme_eventmgr.c +++ b/hicn-plugin/src/mapme_eventmgr.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: @@ -24,6 +24,11 @@ #define DEFAULT_TIMEOUT 1.0 /* s */ +/** + * @brief This is a process node reacting to face events. + */ +vlib_node_registration_t hicn_mapme_eventmgr_process_node; + hicn_mapme_main_t mapme_main; hicn_prefix_t *retx_pool; @@ -33,7 +38,6 @@ void hicn_mapme_init (vlib_main_t *vm) { mapme_main.vm = vm; - mapme_main.log_class = vlib_log_register_class ("hicn_mapme", 0); } /* borrowed from vnet/fib/ip4_fib.c */ @@ -77,7 +81,6 @@ hicn_mapme_process_fib_entry (vlib_main_t *vm, hicn_face_id_t face, const dpo_id_t *load_balance_dpo_id; load_balance_t *lb; dpo_id_t *dpo_id; - fib_entry_t *fib_entry; load_balance_dpo_id = fib_entry_contribute_ip_forwarding (*fib_entry_index); @@ -92,12 +95,14 @@ hicn_mapme_process_fib_entry (vlib_main_t *vm, hicn_face_id_t face, { /* un-const */ dpo_id = (dpo_id_t *) load_balance_get_bucket_i (lb, i); - if (dpo_is_hicn (dpo_id)) { +#ifdef HICN_DDEBUG + fib_entry_t *fib_entry; fib_entry = fib_entry_get (*fib_entry_index); - vlib_cli_output (vm, "set face pending %U", format_fib_prefix, - &fib_entry->fe_prefix); + HICN_DEBUG ("set face pending %U", format_fib_prefix, + &fib_entry->fe_prefix); +#endif } } } @@ -107,16 +112,10 @@ hicn_mapme_process_ip4_fib (vlib_main_t *vm, hicn_face_id_t face) { ip4_main_t *im4 = &ip4_main; fib_table_t *fib_table; - int table_id = -1, fib_index = ~0; pool_foreach (fib_table, im4->fibs) { - ip4_fib_t *fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index); - - if (table_id >= 0 && table_id != (int) fib->table_id) - continue; - if (fib_index != ~0 && fib_index != (int) fib->index) - continue; + ip4_fib_t *fib = pool_elt_at_index (ip4_fibs, fib_table->ft_index); fib_node_index_t *fib_entry_index; ip4_fib_show_walk_ctx_t ctx = { @@ -241,8 +240,8 @@ hicn_mapme_send_message (vlib_main_t *vm, const hicn_prefix_t *prefix, size_t n; /* This should be retrieved from face information */ - DEBUG ("Retransmission for prefix %U seq=%d", format_ip46_address, - &prefix->name, IP46_TYPE_ANY, params->seq); + HICN_DEBUG ("Retransmission for prefix %U seq=%d", format_ip46_address, + &prefix->name, IP46_TYPE_ANY, params->seq); char *node_name = hicn_mapme_get_dpo_face_node (face); if (!node_name) @@ -257,7 +256,7 @@ hicn_mapme_send_message (vlib_main_t *vm, const hicn_prefix_t *prefix, u8 *buffer = get_packet_buffer ( vm, node_index, face, (ip46_address_t *) prefix, (params->protocol == IPPROTO_IPV6) ? HICN_TYPE_IPV6_ICMP : - HICN_TYPE_IPV4_ICMP); + HICN_TYPE_IPV4_ICMP); n = hicn_mapme_create_packet (buffer, prefix, params); if (n <= 0) { @@ -275,7 +274,7 @@ hicn_mapme_send_updates (vlib_main_t *vm, hicn_prefix_t *prefix, dpo_id_t dpo, hicn_mapme_tfib_t *tfib = TFIB (hicn_strategy_dpo_ctx_get (dpo.dpoi_index)); if (!tfib) { - DEBUG ("NULL TFIB entry id=%d", dpo.dpoi_index); + HICN_ERROR ("NULL TFIB entry id=%d", dpo.dpoi_index); return; } @@ -337,7 +336,7 @@ hicn_mapme_eventmgr_process (vlib_main_t *vm, vlib_node_runtime_t *rt, * Also, we only run a timer when there are pending retransmissions. */ timeout = (due_time > current_time) ? due_time - current_time : - DEFAULT_TIMEOUT; + DEFAULT_TIMEOUT; due_time = current_time + timeout; } else @@ -493,8 +492,8 @@ hicn_mapme_eventmgr_process (vlib_main_t *vm, vlib_node_runtime_t *rt, TFIB (hicn_strategy_dpo_ctx_get (retx->dpo.dpoi_index)); if (!tfib) { - DEBUG ("NULL TFIB entry for dpoi_index=%d", - retx->dpo.dpoi_index); + HICN_ERROR ("NULL TFIB entry for dpoi_index=%d", + retx->dpo.dpoi_index); continue; } diff --git a/hicn-plugin/src/mapme_eventmgr.h b/hicn-plugin/src/mapme_eventmgr.h index 2100a6f90..559ba2e75 100644 --- a/hicn-plugin/src/mapme_eventmgr.h +++ b/hicn-plugin/src/mapme_eventmgr.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: @@ -39,8 +39,7 @@ typedef struct /** * @brief This is a process node reacting to face events. */ -// not static ! -vlib_node_registration_t hicn_mapme_eventmgr_process_node; +extern vlib_node_registration_t hicn_mapme_eventmgr_process_node; /** * @brief Initialize MAP-Me on forwarder diff --git a/hicn-plugin/src/mgmt.c b/hicn-plugin/src/mgmt.c index b820a378f..6e9ce9fd8 100644 --- a/hicn-plugin/src/mgmt.c +++ b/hicn-plugin/src/mgmt.c @@ -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: @@ -21,7 +21,7 @@ #include "mgmt.h" /* define message IDs */ -#include "hicn_msg_enum.h" +#include <vpp_plugins/hicn/hicn_msg_enum.h> /* shared routine betweeen API and CLI, leveraging API message structure */ int @@ -46,7 +46,8 @@ hicn_mgmt_node_stats_get (vl_api_hicn_api_node_stats_get_reply_t *rmp) vlib_error_main_t *em; vlib_node_t *n; - foreach_vlib_main() { + foreach_vlib_main () + { em = &this_vlib_main->error_main; n = vlib_get_node (this_vlib_main, hicn_interest_pcslookup_node.index); u32 node_cntr_base_idx = n->error_heap_index; diff --git a/hicn-plugin/src/mgmt.h b/hicn-plugin/src/mgmt.h index 8eaa18fa8..03e73999f 100644 --- a/hicn-plugin/src/mgmt.h +++ b/hicn-plugin/src/mgmt.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: @@ -18,7 +18,7 @@ #include <vppinfra/error.h> #include "faces/face.h" -#include "hicn_api.h" +#include <vpp_plugins/hicn/hicn_api.h> /** * @file mgmt.h diff --git a/hicn-plugin/src/params.h b/hicn-plugin/src/params.h index 7c7850d30..324429abe 100644 --- a/hicn-plugin/src/params.h +++ b/hicn-plugin/src/params.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: @@ -60,9 +60,9 @@ STATIC_ASSERT ((HICN_PARAM_FACES_MAX & (HICN_PARAM_FACES_MAX - 1)) == 0, // HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4 must be a power of two #define HICN_PARAM_PIT_ENTRY_PHOPS_MAX 20 -STATIC_ASSERT ((ceil (log2 ((HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4)))) == - (floor (log2 ((HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4)))), - "HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4 must be a power of two"); +// STATIC_ASSERT ((ceil (log2 ((HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4)))) == +// (floor (log2 ((HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4)))), +// "HICN_PARAM_PIT_ENTRY_PHOPS_MAX - 4 must be a power of two"); STATIC_ASSERT ( (HICN_PARAM_PIT_ENTRY_PHOPS_MAX <= HICN_PARAM_FACES_MAX), @@ -113,7 +113,7 @@ STATIC_ASSERT ( #define IPV6_DEFAULT_VERSION 6 #define IPV6_DEFAULT_TRAFFIC_CLASS 0 #define IPV6_DEFAULT_FLOW_LABEL 0 -#define HCIN_IP6_VERSION_TRAFFIC_FLOW \ +#define HICN_IP6_VERSION_TRAFFIC_FLOW \ (IPV6_DEFAULT_VERSION << 28) | (IPV6_DEFAULT_TRAFFIC_CLASS << 20) | \ (IPV6_DEFAULT_FLOW_LABEL & 0xfffff) #define HICN_IP6_PROTOCOL IP_PROTOCOL_TCP diff --git a/hicn-plugin/src/parser.h b/hicn-plugin/src/parser.h index 5c75ce3bd..0e60c526f 100644 --- a/hicn-plugin/src/parser.h +++ b/hicn-plugin/src/parser.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: @@ -59,10 +59,13 @@ hicn_interest_parse_pkt (vlib_buffer_t *pkt, hicn_name_t *name, u16 *namelen, u8 next_proto_offset = 6 + (1 - *isv6) * 3; // in the ipv6 header the next header field is at byte 6 // in the ipv4 header the protocol field is at byte 9 - hicn_type_t type = (hicn_type_t){ { .l4 = IPPROTO_NONE, - .l3 = IPPROTO_NONE, - .l2 = ip_pkt[next_proto_offset], - .l1 = ip_proto } }; + hicn_type_t type = + (hicn_type_t){ { .l4 = IPPROTO_NONE, + .l3 = ip_pkt[next_proto_offset] == IPPROTO_UDP ? + IPPROTO_ENCAP : + IPPROTO_NONE, + .l2 = ip_pkt[next_proto_offset], + .l1 = ip_proto } }; hicn_get_buffer (pkt)->type = type; hicn_ops_vft[type.l1]->get_interest_name (type, &pkt_hdr->protocol, name); @@ -97,10 +100,13 @@ hicn_data_parse_pkt (vlib_buffer_t *pkt, hicn_name_t *name, u16 *namelen, * header the protocol field is at byte 9 */ u8 next_proto_offset = 6 + (1 - *isv6) * 3; - hicn_type_t type = (hicn_type_t){ { .l4 = IPPROTO_NONE, - .l3 = IPPROTO_NONE, - .l2 = ip_pkt[next_proto_offset], - .l1 = ip_proto } }; + hicn_type_t type = + (hicn_type_t){ { .l4 = IPPROTO_NONE, + .l3 = ip_pkt[next_proto_offset] == IPPROTO_UDP ? + IPPROTO_ENCAP : + IPPROTO_NONE, + .l2 = ip_pkt[next_proto_offset], + .l1 = ip_proto } }; hicn_get_buffer (pkt)->type = type; hicn_ops_vft[type.l1]->get_data_name (type, &pkt_hdr->protocol, name); *namelen = (1 - (*isv6)) * HICN_V4_NAME_LEN + (*isv6) * HICN_V6_NAME_LEN; diff --git a/hicn-plugin/src/pcs.c b/hicn-plugin/src/pcs.c index d9e0baf6f..d6e4fd954 100644 --- a/hicn-plugin/src/pcs.c +++ b/hicn-plugin/src/pcs.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: diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h index 083efa901..b98b72a53 100644 --- a/hicn-plugin/src/pcs.h +++ b/hicn-plugin/src/pcs.h @@ -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: @@ -91,7 +91,7 @@ typedef struct __attribute__ ((packed)) hicn_pit_entry_s } hicn_pit_entry_t; -#define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 36 +#define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 32 /* * CS entry, unioned with a PIT entry below @@ -105,17 +105,17 @@ typedef struct __attribute__ ((packed)) hicn_cs_entry_s /* 20B + 4B = 24B */ u32 cs_pkt_buf; - /* Ingress face */ - /* 24B + 4B = 28B */ - hicn_face_id_t cs_rxface; + // /* Ingress face */ + // /* 24B + 4B = 28B */ + // hicn_face_id_t cs_rxface; /* Linkage for LRU, in the form of hashtable node indexes */ - /* 28B + 8B = 36B */ + /* 24B + 8B = 32B */ u32 cs_lru_prev; u32 cs_lru_next; /* Reserved for implementing cache policy different than LRU */ - /* 36B + (64 - 36)B = 64B */ + /* 32B + (64 - 32)B = 64B */ u8 opaque[HICN_CS_ENTRY_OPAQUE_SIZE]; } __attribute__ ((packed)) hicn_cs_entry_t; @@ -167,8 +167,7 @@ always_inline void hicn_pit_to_cs (vlib_main_t *vm, hicn_pit_cs_t *pitcs, hicn_hash_entry_t *hash_entry, hicn_hash_node_t *node, const hicn_dpo_vft_t *dpo_vft, - dpo_id_t *hicn_dpo_id, - hicn_face_id_t inface_id, u8 is_appface); + dpo_id_t *hicn_dpo_id); always_inline void hicn_pcs_cs_update (vlib_main_t *vm, hicn_pit_cs_t *pitcs, hicn_pcs_entry_t *old_entry, @@ -193,7 +192,7 @@ always_inline int hicn_pcs_cs_insert_update ( vlib_main_t *vm, hicn_pit_cs_t *pitcs, hicn_pcs_entry_t *entry, hicn_hash_node_t *node, hicn_hash_entry_t **hash_entry, u64 hashval, u32 *node_id, index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs, u8 *hash_entry_id, - u32 *bucket_id, u8 *bucket_is_overflow, hicn_face_id_t inface); + u32 *bucket_id, u8 *bucket_is_overflow); always_inline int hicn_pcs_pit_insert (hicn_pit_cs_t *pitcs, hicn_pcs_entry_t *entry, @@ -352,7 +351,6 @@ hicn_pcs_delete_internal (hicn_pit_cs_t *pitcs, hicn_pcs_entry_t **pcs_entryp, else { pitcs->pcs_pit_dealloc++; - hicn_strategy_dpo_ctx_unlock (hicn_dpo_id); /* Flush faces */ hicn_faces_flush (&(pcs->u.pit.faces)); @@ -370,7 +368,7 @@ always_inline void hicn_pit_to_cs (vlib_main_t *vm, hicn_pit_cs_t *pitcs, hicn_pcs_entry_t *pcs_entry, hicn_hash_entry_t *hash_entry, hicn_hash_node_t *node, const hicn_dpo_vft_t *dpo_vft, - dpo_id_t *hicn_dpo_id, hicn_face_id_t inface_id, u8 is_appface) + dpo_id_t *hicn_dpo_id) { /* @@ -378,7 +376,6 @@ hicn_pit_to_cs (vlib_main_t *vm, hicn_pit_cs_t *pitcs, * hash entry. */ pitcs->pcs_pit_count--; - hicn_strategy_dpo_ctx_unlock (hicn_dpo_id); /* Flush faces */ hicn_faces_flush (&(pcs_entry->u.pit.faces)); @@ -386,8 +383,6 @@ hicn_pit_to_cs (vlib_main_t *vm, hicn_pit_cs_t *pitcs, node->hn_flags |= HICN_HASH_NODE_CS_FLAGS; pcs_entry->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG; - pcs_entry->u.cs.cs_rxface = inface_id; - /* Update the CS according to the policy */ hicn_cs_policy_t *policy_state; hicn_cs_policy_vft_t *policy_vft; @@ -432,40 +427,8 @@ hicn_pcs_cs_update (vlib_main_t *vm, hicn_pit_cs_t *pitcs, policy_state = &pitcs->policy_state; policy_vft = &pitcs->policy_vft; - if (entry->u.cs.cs_rxface != old_entry->u.cs.cs_rxface) - { - /* Dequeue content from the old queue */ - policy_vft->hicn_cs_dequeue (pitcs, node, old_entry, policy_state); - - old_entry->u.cs.cs_rxface = entry->u.cs.cs_rxface; - policy_state = &pitcs->policy_state; - policy_vft = &pitcs->policy_vft; - - policy_vft->hicn_cs_insert (pitcs, node, old_entry, policy_state); - - if (policy_state->count > policy_state->max) - { - hicn_hash_node_t *node; - hicn_pcs_entry_t *pcs_entry; - hicn_hash_entry_t *hash_entry; - policy_vft->hicn_cs_delete_get (pitcs, policy_state, &node, - &pcs_entry, &hash_entry); - - /* - * We don't have to decrease the lock (therefore we cannot - * use hicn_pcs_cs_delete function) - */ - policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state); - - hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm); - - /* Update the global CS counter */ - pitcs->pcs_cs_count--; - } - } - else - /* Update the CS LRU, moving this item to the head */ - policy_vft->hicn_cs_update (pitcs, node, old_entry, policy_state); + /* Update the CS LRU, moving this item to the head */ + policy_vft->hicn_cs_update (pitcs, node, old_entry, policy_state); } always_inline void @@ -565,13 +528,12 @@ hicn_pcs_cs_insert_update (vlib_main_t *vm, hicn_pit_cs_t *pitcs, hicn_hash_entry_t **hash_entry, u64 hashval, u32 *node_id, index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs, u8 *hash_entry_id, u32 *bucket_id, - u8 *bucket_is_overflow, hicn_face_id_t inface) + u8 *bucket_is_overflow) { int ret; ASSERT (entry == hicn_hashtb_node_data (node)); - entry->u.cs.cs_rxface = inface; ret = hicn_pcs_cs_insert (vm, pitcs, entry, node, hash_entry, hashval, node_id, dpo_ctx_id, vft_id, is_cs, hash_entry_id, bucket_id, bucket_is_overflow); diff --git a/hicn-plugin/src/pg.c b/hicn-plugin/src/pg.c index 2f98e9c16..b77e8fcac 100644 --- a/hicn-plugin/src/pg.c +++ b/hicn-plugin/src/pg.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: @@ -203,11 +203,11 @@ hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, iface = (hpgm->index_ifaces % hpgm->n_ifaces); /* Rewrite and send */ isv6_0 ? - hicn_rewrite_interestv6 ( + hicn_rewrite_interestv6 ( vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number, hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface) : - hicn_rewrite_interestv4 ( + hicn_rewrite_interestv4 ( vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number, hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface); @@ -216,7 +216,7 @@ hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, hpgm->index++; next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP : - HICNPG_INTEREST_NEXT_V4_LOOKUP; + HICNPG_INTEREST_NEXT_V4_LOOKUP; } if (hicn_interest_parse_pkt (b1, &name1, &namelen1, &hicn1, &isv6_1) == HICN_ERROR_NONE) @@ -229,11 +229,11 @@ hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, iface = (hpgm->index_ifaces % hpgm->n_ifaces); /* Rewrite and send */ isv6_1 ? - hicn_rewrite_interestv6 ( + hicn_rewrite_interestv6 ( vm, b1, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number, hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface) : - hicn_rewrite_interestv4 ( + hicn_rewrite_interestv4 ( vm, b1, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number, hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface); @@ -242,7 +242,7 @@ hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, hpgm->index++; next1 = isv6_1 ? HICNPG_INTEREST_NEXT_V6_LOOKUP : - HICNPG_INTEREST_NEXT_V4_LOOKUP; + HICNPG_INTEREST_NEXT_V4_LOOKUP; } /* Send pkt to next node */ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0; @@ -320,11 +320,11 @@ hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, /* Rewrite and send */ isv6_0 ? - hicn_rewrite_interestv6 ( + hicn_rewrite_interestv6 ( vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number, hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface) : - hicn_rewrite_interestv4 ( + hicn_rewrite_interestv4 ( vm, b0, (hpgm->index / hpgm->n_flows) % hpgm->max_seq_number, hpgm->interest_lifetime, hpgm->index % hpgm->n_flows, iface); @@ -333,7 +333,7 @@ hicnpg_client_interest_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, hpgm->index++; next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP : - HICNPG_INTEREST_NEXT_V4_LOOKUP; + HICNPG_INTEREST_NEXT_V4_LOOKUP; } /* Send pkt to ip lookup */ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0; @@ -386,12 +386,12 @@ hicn_rewrite_interestv4 (vlib_main_t *vm, vlib_buffer_t *b0, u32 seq_number, .ip4 = hicnpg_main.pgen_clt_src_addr.ip4, }; hicn_name_t dst_name = { - .ip4.prefix_as_ip4 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip4, - .ip4.suffix = seq_number, + .prefix.ip4 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip4, + .suffix = seq_number, }; src_addr.ip4.as_u32 += clib_host_to_net_u32 (iface); - dst_name.ip4.prefix_as_ip4.as_u32 += clib_net_to_host_u32 (next_flow); + dst_name.prefix.ip4.as_u32 += clib_net_to_host_u32 (next_flow); /* Update locator and name */ hicn_type_t type = hicn_get_buffer (b0)->type; @@ -432,11 +432,11 @@ hicn_rewrite_interestv6 (vlib_main_t *vm, vlib_buffer_t *b0, u32 seq_number, .ip6 = hicnpg_main.pgen_clt_src_addr.ip6, }; hicn_name_t dst_name = { - .ip6.prefix_as_ip6 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip6, - .ip6.suffix = seq_number, + .prefix.ip6 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip6, + .suffix = seq_number, }; src_addr.ip6.as_u32[3] += clib_host_to_net_u32 (iface); - dst_name.ip6.prefix_as_ip6.as_u32[3] += clib_net_to_host_u32 (next_flow); + dst_name.prefix.ip6.as_u32[3] += clib_net_to_host_u32 (next_flow); /* Update locator and name */ hicn_type_t type = hicn_get_buffer (b0)->type; @@ -1011,10 +1011,10 @@ hicnpg_node_server_fn (vlib_main_t *vm, vlib_node_runtime_t *node, rb = vlib_get_buffer (vm, hpgsm->pgen_svr_buffer_idx); isv6_0 ? convert_interest_to_data_v6 (vm, b0, rb, bi0) : - convert_interest_to_data_v4 (vm, b0, rb, bi0); + convert_interest_to_data_v4 (vm, b0, rb, bi0); next0 = isv6_0 ? HICNPG_SERVER_NEXT_V6_LOOKUP : - HICNPG_SERVER_NEXT_V4_LOOKUP; + HICNPG_SERVER_NEXT_V4_LOOKUP; } if (match1) @@ -1029,10 +1029,10 @@ hicnpg_node_server_fn (vlib_main_t *vm, vlib_node_runtime_t *node, rb = vlib_get_buffer (vm, hpgsm->pgen_svr_buffer_idx); isv6_1 ? convert_interest_to_data_v6 (vm, b1, rb, bi1) : - convert_interest_to_data_v4 (vm, b1, rb, bi1); + convert_interest_to_data_v4 (vm, b1, rb, bi1); next1 = isv6_1 ? HICNPG_SERVER_NEXT_V6_LOOKUP : - HICNPG_SERVER_NEXT_V4_LOOKUP; + HICNPG_SERVER_NEXT_V4_LOOKUP; } pkts_processed += 2; @@ -1107,10 +1107,10 @@ hicnpg_node_server_fn (vlib_main_t *vm, vlib_node_runtime_t *node, rb = vlib_get_buffer (vm, hpgsm->pgen_svr_buffer_idx); isv6_0 ? convert_interest_to_data_v6 (vm, b0, rb, bi0) : - convert_interest_to_data_v4 (vm, b0, rb, bi0); + convert_interest_to_data_v4 (vm, b0, rb, bi0); next0 = isv6_0 ? HICNPG_SERVER_NEXT_V6_LOOKUP : - HICNPG_SERVER_NEXT_V4_LOOKUP; + HICNPG_SERVER_NEXT_V4_LOOKUP; } if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && (b0->flags & VLIB_BUFFER_IS_TRACED))) diff --git a/hicn-plugin/src/pg.h b/hicn-plugin/src/pg.h index 059b076fb..7855248e6 100644 --- a/hicn-plugin/src/pg.h +++ b/hicn-plugin/src/pg.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: diff --git a/hicn-plugin/src/route.c b/hicn-plugin/src/route.c index 34a94936e..a84891b9a 100644 --- a/hicn-plugin/src/route.c +++ b/hicn-plugin/src/route.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: @@ -33,6 +33,7 @@ #include "strategies/dpo_mw.h" #include "infra.h" #include "udp_tunnels/udp_tunnel.h" +#include "mapme.h" #define FIB_SOURCE_HICN 0x04 // Right after the FIB_SOURCE_INTERFACE priority @@ -105,94 +106,76 @@ int hicn_route_set_strategy (fib_prefix_t *prefix, u8 strategy_id) { const dpo_id_t *hicn_dpo_id; - dpo_id_t new_dpo_id = DPO_INVALID; int ret; - hicn_dpo_ctx_t *old_hicn_dpo_ctx; - const hicn_dpo_vft_t *new_dpo_vft; - index_t new_hicn_dpo_idx; + hicn_dpo_ctx_t *hicn_dpo_ctx; u32 fib_index; ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index); if (ret == HICN_ERROR_NONE) { - old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index); + hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index); + const hicn_dpo_vft_t *dpo_vft = hicn_dpo_get_vft_from_id (strategy_id); - new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id); - - if (new_dpo_vft == NULL || old_hicn_dpo_ctx == NULL) + if (hicn_dpo_ctx == NULL || dpo_vft == NULL) return HICN_ERROR_STRATEGY_NOT_FOUND; - /* Create a new dpo for the new strategy */ - new_dpo_vft->hicn_dpo_create ( - hicn_dpo_id->dpoi_proto, old_hicn_dpo_ctx->next_hops, - old_hicn_dpo_ctx->entry_count, &new_hicn_dpo_idx); - - /* the value we got when we registered */ - dpo_set (&new_dpo_id, new_dpo_vft->hicn_dpo_get_type (), - (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 : - DPO_PROTO_IP6), - new_hicn_dpo_idx); - - /* Here is where we create the "via" like route */ - /* - * For the moment we use the global one the prefix you want - * to match Neale suggested -- FIB_SOURCE_HICN the client - * that is adding them -- no easy explanation at this time… - */ - fib_node_index_t new_fib_node_index = - fib_table_entry_special_dpo_update (fib_index, prefix, hicn_fib_src, - FIB_ENTRY_FLAG_EXCLUSIVE, - &new_dpo_id); - - dpo_unlock (&new_dpo_id); - ret = (new_fib_node_index != FIB_NODE_INDEX_INVALID) ? - HICN_ERROR_NONE : - HICN_ERROR_ROUTE_NOT_UPDATED; + dpo_vft->hicn_dpo_update_type (hicn_dpo_ctx); } // Remember to remove the lock from the table when removing the entry return ret; } -int -ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx, - ip46_address_t *nh, u32 sw_if) +static int +ip_nh_add_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx, + ip46_address_t *nh, u32 sw_if, u32 udp_encap_id, + dpo_proto_t proto, u8 is_add) { fib_route_path_t *rpaths = NULL, rpath; u32 fib_index = fib_table_find (fib_proto, 0); - clib_memset (&rpath, 0, sizeof (rpath)); + + if (nh) + { + rpath.frp_addr = *nh; + rpath.frp_sw_if_index = sw_if; + } + else if (udp_encap_id != ~0) + { + rpath.frp_udp_encap_id = udp_encap_id; + rpath.frp_flags |= FIB_ROUTE_PATH_UDP_ENCAP; + } + rpath.frp_weight = 1; - rpath.frp_sw_if_index = sw_if; - rpath.frp_addr = *nh; - rpath.frp_proto = ip46_address_is_ip4 (nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6; + rpath.frp_proto = proto; vec_add1 (rpaths, rpath); - fib_table_entry_path_add2 (fib_index, rpfx, FIB_SOURCE_CLI, - FIB_ENTRY_FLAG_NONE, rpaths); + if (is_add) + fib_table_entry_path_add2 (fib_index, rpfx, FIB_SOURCE_API, + FIB_ENTRY_FLAG_NONE, rpaths); + else + fib_table_entry_path_remove2 (fib_index, rpfx, FIB_SOURCE_API, rpaths); + return 0; } int -ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx, - ip46_address_t *nh, u32 sw_if) +ip_nh_adj_add_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx, + ip46_address_t *nh, u32 sw_if, u8 is_add) { - fib_route_path_t *rpaths = NULL, rpath; - - u32 fib_index = fib_table_find (fib_proto, 0); - - clib_memset (&rpath, 0, sizeof (rpath)); - rpath.frp_weight = 1; - rpath.frp_sw_if_index = sw_if; - rpath.frp_addr = *nh; - rpath.frp_proto = ip46_address_is_ip4 (nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6; - - vec_add1 (rpaths, rpath); + return ip_nh_add_del_helper ( + fib_proto, rpfx, nh, sw_if, ~0, + ip46_address_is_ip4 (nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6, is_add); +} - fib_table_entry_path_remove2 (fib_index, rpfx, FIB_SOURCE_CLI, rpaths); - return 0; +int +ip_nh_udp_tunnel_add_del_helper (fib_protocol_t fib_proto, + const fib_prefix_t *rpfx, u32 uei, + dpo_proto_t proto, u8 is_add) +{ + return ip_nh_add_del_helper (fib_proto, rpfx, NULL, ~0, uei, proto, is_add); } static ip46_address_t * @@ -234,13 +217,14 @@ get_address (ip46_address_t *nh, u32 sw_if, fib_protocol_t proto) } static void -sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry) +sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry, hicn_face_id_t **pvec_faces) { + hicn_face_id_t *vec_faces = NULL; const dpo_id_t *dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index); + const fib_entry_t *_fib_entry = fib_entry_get (fib_entry->fib_entry_index); const load_balance_t *lb0 = load_balance_get (dpo_loadbalance->dpoi_index); index_t hicn_fib_entry_index = hicn_strategy_dpo_ctx_get_index (fib_entry); - hicn_face_id_t *vec_faces = 0; dpo_id_t temp = DPO_INVALID; const dpo_id_t *former_dpo = &temp; @@ -287,32 +271,31 @@ sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry) nh = get_address (&(adj->sub_type.nbr.next_hop), sw_if, fib_entry->proto); ADD_FACE (nh); + HICN_DEBUG ("Added new HICN face: %d because of route prefix %U", + face_id, format_ip_prefix, &_fib_entry->fe_prefix); } else if (dpo->dpoi_type == dpo_type_udp_ip4 || dpo->dpoi_type == dpo_type_udp_ip6) { - u8 proto = dpo->dpoi_type == dpo_type_udp_ip4 ? FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6; + dpo_proto_t proto = + dpo->dpoi_type == dpo_type_udp_ip4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6; ip46_address_t _nh = { 0 }; nh = &_nh; - switch (dpo->dpoi_proto) + switch (_fib_entry->fe_prefix.fp_proto) { case FIB_PROTOCOL_IP6: - case FIB_PROTOCOL_IP4: - /** - * Independently of the type of tunnel, encapsulated packet - * can be either v6 or v4, so we need to create 2 faces for each - * version. Tunneled hicn packet MUST have locator set to the - * loopback address, so ::1 for IPv6 and 127.0.0.1 for IPv4. - */ ip46_address_set_ip6 (nh, &localhost6); ADD_FACE (nh); + break; + case FIB_PROTOCOL_IP4: ip46_address_set_ip4 (nh, &localhost4); ADD_FACE (nh); break; default: continue; } + HICN_DEBUG ("Added new UDP face: %d because of route prefix %s", + face_id, format_ip_prefix, &_fib_entry->fe_prefix); udp_tunnel_add_existing (dpo->dpoi_index, proto); } } @@ -345,7 +328,8 @@ sync_hicn_fib_entry (hicn_dpo_ctx_t *fib_entry) /* Remove the lock added by hicn_face_add */ hicn_face_unlock_with_id (*face_id); } - vec_free (vec_faces); + + *pvec_faces = vec_faces; } static void @@ -380,7 +364,7 @@ disable_data_receiving_rm_fib_entry (vnet_main_t *vnm, vnet_sw_interface_t *si, } int -hicn_route_enable (fib_prefix_t *prefix) +hicn_route_enable (fib_prefix_t *prefix, hicn_face_id_t **pvec_faces) { int ret = HICN_ERROR_NONE; @@ -413,10 +397,14 @@ hicn_route_enable (fib_prefix_t *prefix) if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID) { + HICN_DEBUG ( + "No route found for %U. Creating DPO and tracking fib prefix.", + format_ip_prefix, prefix); dpo_id_t dpo = DPO_INVALID; index_t dpo_idx; default_dpo.hicn_dpo_create (prefix->fp_proto, 0, NEXT_HOP_INVALID, &dpo_idx); + HICN_DEBUG ("Created new DPO_MW_CTX_T: %d.", dpo_idx); /* the value we got when we registered */ /* @@ -425,8 +413,14 @@ hicn_route_enable (fib_prefix_t *prefix) */ dpo_set (&dpo, default_dpo.hicn_dpo_get_type (), (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 : - DPO_PROTO_IP6), + DPO_PROTO_IP6), dpo_idx); + HICN_DEBUG ( + "dpo_set called with parameters: type=%d, proto=%s, index=%d", + default_dpo.hicn_dpo_get_type (), + ip46_address_is_ip4 (&prefix->fp_addr) ? "DPO_PROTO_IP4" : + "DPO_PROTO_IP6", + dpo_idx); hicn_dpo_ctx_t *fib_entry = hicn_strategy_dpo_ctx_get (dpo_idx); @@ -448,7 +442,8 @@ hicn_route_enable (fib_prefix_t *prefix) fib_hicn_index, prefix, hicn_fib_src, (FIB_ENTRY_FLAG_EXCLUSIVE | FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT), &dpo); - sync_hicn_fib_entry (fib_entry); + HICN_DEBUG ("Calling sync_hicn_fib_entry"); + sync_hicn_fib_entry (fib_entry, pvec_faces); /* We added a route, therefore add one lock to the table */ fib_table_lock (fib_index, prefix->fp_proto, hicn_fib_src); @@ -470,6 +465,8 @@ hicn_route_enable (fib_prefix_t *prefix) } else { + HICN_DEBUG ("Found a route for %U. Updating DPO.", format_ip_prefix, + &prefix); const dpo_id_t *load_balance_dpo_id; const dpo_id_t *strategy_dpo_id; @@ -481,6 +478,7 @@ hicn_route_enable (fib_prefix_t *prefix) if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE) { ret = HICN_ERROR_ROUTE_NO_LD; + HICN_ERROR ("DPO is not a load balance."); goto done; } else @@ -493,19 +491,22 @@ hicn_route_enable (fib_prefix_t *prefix) if (!dpo_is_hicn (strategy_dpo_id)) { ret = HICN_ERROR_ROUTE_DPO_NO_HICN; + HICN_ERROR ("DPO is not hicn."); goto done; } if (lb->lb_n_buckets > 1) { ret = HICN_ERROR_ROUTE_MLT_LD; + HICN_ERROR ("Too many load balance buckets."); goto done; } hicn_dpo_ctx_t *hicn_fib_entry = hicn_strategy_dpo_ctx_get (strategy_dpo_id->dpoi_index); - sync_hicn_fib_entry (hicn_fib_entry); + HICN_DEBUG ("Calling sync_hicn_fib_entry"); + sync_hicn_fib_entry (hicn_fib_entry, pvec_faces); } } @@ -527,6 +528,7 @@ hicn_route_disable (fib_prefix_t *prefix) if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID) { + HICN_ERROR ("Route %U not found", format_ip_prefix, prefix); return HICN_ERROR_ROUTE_NOT_FOUND; } else @@ -542,6 +544,8 @@ hicn_route_disable (fib_prefix_t *prefix) /* The dpo is not a load balance dpo as expected */ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE) { + HICN_ERROR ("DPO for route %U is not a load balance.", + format_ip_prefix, prefix); ret = HICN_ERROR_ROUTE_NO_LD; goto done; } @@ -554,12 +558,16 @@ hicn_route_disable (fib_prefix_t *prefix) if (!dpo_is_hicn (strategy_dpo_id)) { + HICN_ERROR ("ERROR: DPO for route %U is not a hicn.", + format_ip_prefix, prefix); ret = HICN_ERROR_ROUTE_DPO_NO_HICN; goto done; } if (lb->lb_n_buckets > 1) { + HICN_ERROR ("DPO for route %U contains multiple next hops.", + format_ip_prefix, prefix); ret = HICN_ERROR_ROUTE_MLT_LD; goto done; } @@ -567,17 +575,37 @@ hicn_route_disable (fib_prefix_t *prefix) hicn_fib_entry = hicn_strategy_dpo_ctx_get (strategy_dpo_id->dpoi_index); + HICN_DEBUG ("Found from hicn_strategy_dpo_ctx_get with index %d: %p", + strategy_dpo_id->dpoi_index, hicn_fib_entry); + + if (PREDICT_FALSE (!hicn_fib_entry)) + { + HICN_ERROR ( + "hicn_strategy_dpo_ctx_get for index %d returned NULL", + strategy_dpo_id->dpoi_index); + ret = HICN_ERROR_ROUTE_DPO_NO_HICN; + goto done; + } + for (int i = 0; i < hicn_fib_entry->entry_count; i++) { hicn_strategy_dpo_ctx_del_nh (hicn_fib_entry->next_hops[i], hicn_fib_entry); } + + hicn_mapme_tfib_clear ((hicn_mapme_tfib_t *) hicn_fib_entry); } + HICN_DEBUG ( + "Calling fib_entry_untrack and fib_table_entry_special_remove " + "for route %U.", + format_ip_prefix, prefix); + fib_entry_untrack (hicn_fib_entry->fib_entry_index, hicn_fib_entry->fib_sibling); fib_table_entry_special_remove (fib_hicn_index, prefix, hicn_fib_src); + fib_node_unlock (&hicn_fib_entry->fib_node); /* Disable the feature to punt data packet every time we enable a new * hicn route */ @@ -618,7 +646,11 @@ hicn_fib_back_walk_notify (fib_node_t *node, fib_node_back_walk_ctx_t *ctx) hicn_dpo_ctx_t *fib_entry = hicn_ctx_from_fib_node (node); - sync_hicn_fib_entry (fib_entry); + hicn_face_id_t *vec_faces = NULL; + HICN_DEBUG ("Calling sync_hicn_fib_entry from hicn_fib_back_walk_notify"); + sync_hicn_fib_entry (fib_entry, &vec_faces); + if (vec_faces != NULL) + vec_free (vec_faces); return (FIB_NODE_BACK_WALK_CONTINUE); } @@ -661,7 +693,8 @@ enable_data_on_existing_hicn (fib_node_index_t fei, void *ctx) goto done; } - enable_disable_data_receiving (strategy_dpo_id->dpoi_proto, sw_if, 1); + enable_disable_data_receiving ( + (fib_protocol_t) strategy_dpo_id->dpoi_proto, sw_if, 1); } done: @@ -673,18 +706,18 @@ set_table_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add) { if (!is_add) - return HICN_ERROR_NONE; + return NULL; - int rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, HICN_FIB_TABLE, 1); + int rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, HICN_FIB_TABLE); if (!rv) { - rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, HICN_FIB_TABLE, 1); + rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, HICN_FIB_TABLE); if (rv) { /* An error occurred. Bind the interface back to the default fib */ - ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, 0, 1); + ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, 0); } } @@ -707,10 +740,11 @@ set_table_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add) } return rv ? clib_error_return (0, "unable to add hicn table to interface") : - 0; + 0; } -VNET_SW_INTERFACE_ADD_DEL_FUNCTION (set_table_interface_add_del); +VNET_SW_INTERFACE_ADD_DEL_FUNCTION_PRIO (set_table_interface_add_del, + VNET_ITF_FUNC_PRIORITY_HIGH); void hicn_route_init () @@ -720,7 +754,8 @@ hicn_route_init () hicn_fib_src = fib_source_allocate ("hicn", FIB_SOURCE_HICN, FIB_SOURCE_BH_API); - hicn_fib_node_type = fib_node_register_new_type (&hicn_fib_vft); + hicn_fib_node_type = + fib_node_register_new_type ("hicn_route_fib_node", &hicn_fib_vft); ip_table_create (FIB_PROTOCOL_IP4, HICN_FIB_TABLE, 1, (const u8 *) "hicn4"); ip_table_create (FIB_PROTOCOL_IP6, HICN_FIB_TABLE, 1, (const u8 *) "hicn6"); diff --git a/hicn-plugin/src/route.h b/hicn-plugin/src/route.h index 19b18b8c6..072926498 100644 --- a/hicn-plugin/src/route.h +++ b/hicn-plugin/src/route.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: @@ -73,28 +73,31 @@ int hicn_route_get_dpo (const fib_prefix_t *prefix, const dpo_id_t **hicn_dpo, int hicn_route_set_strategy (fib_prefix_t *prefix, u32 strategy_id); /** - * @Brief Helper to add a nex hop in the vrf 0. If there are no entries in the - * vrf 0 that matches with the prefix (epm), a new one is created. + * @Brief Helper to add an adj nex hop in the vrf 0. If there are no entries in + * the vrf 0 that matches with the prefix (epm), a new one is created. * * @param fib_proto FIB_PROTOCOL_IP6 or FIB_PROTOCOL_IP4 (mpls not supported) - * @param pfx Prefix for which to add a next hop + * @param rpfx Prefix for which to add a next hop * @param nh Next hop to add * @param sw_if Software interface index to add in the next hop */ -int ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t *pfx, - ip46_address_t *nh, u32 sw_if); +int ip_nh_adj_add_del_helper (fib_protocol_t fib_proto, + const fib_prefix_t *rpfx, ip46_address_t *nh, + u32 sw_if, u8 is_add); /** - * @Brief Helper to remove a nex hop in the vrf 0. If there are no entries in - * the vrf 0 nothing happens. + * @Brief Helper to add an udp-tunnel nex hop in the vrf 0. If there are no + * entries in the vrf 0 that matches with the prefix (epm), a new one is + * created. * * @param fib_proto FIB_PROTOCOL_IP6 or FIB_PROTOCOL_IP4 (mpls not supported) - * @param pfx Prefix for which to remove a next hop - * @param nh Next hop to remove - * @param sw_if Software interface index in the next hop definition + * @param rpfx Prefix for which to add a next hop + * @param uei The UDP ENCAP ID + * @param sw_if The */ -int ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx, - ip46_address_t *nh, u32 sw_if); +int ip_nh_udp_tunnel_add_del_helper (fib_protocol_t fib_proto, + const fib_prefix_t *rpfx, u32 uei, + dpo_proto_t proto, u8 is_add); /** * @Brief Enable an hICN for an ip prefix @@ -106,7 +109,7 @@ int ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t *rpfx, * loadbalancer in the vrf HICN already contains a dpo which is not an hICN one * HICN_ERROR_ROUTE_MLT_LD if there are more than a dpo in the vpp loadbalancer */ -int hicn_route_enable (fib_prefix_t *prefix); +int hicn_route_enable (fib_prefix_t *prefix, hicn_face_id_t **vec_faces); /** * @Brief Disable an hICN for an ip prefix. If hICN wasn't enable on the prefix diff --git a/hicn-plugin/src/state.h b/hicn-plugin/src/state.h index 561aef2db..39953722d 100644 --- a/hicn-plugin/src/state.h +++ b/hicn-plugin/src/state.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: diff --git a/hicn-plugin/src/strategies/dpo_mw.c b/hicn-plugin/src/strategies/dpo_mw.c index 70ef7d7c9..1a7d2e495 100644 --- a/hicn-plugin/src/strategies/dpo_mw.c +++ b/hicn-plugin/src/strategies/dpo_mw.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: @@ -28,6 +28,7 @@ static const hicn_dpo_vft_t hicn_dpo_mw_vft = { .hicn_dpo_get_type = &hicn_dpo_strategy_mw_get_type, .hicn_dpo_module_init = &hicn_dpo_strategy_mw_module_init, .hicn_dpo_create = &hicn_strategy_mw_ctx_create, + .hicn_dpo_update_type = &hicn_strategy_mw_update_ctx_type, .hicn_dpo_add_update_nh = &hicn_strategy_mw_ctx_add_nh, .hicn_dpo_del_nh = &hicn_strategy_mw_ctx_del_nh, .hicn_dpo_format = &hicn_strategy_mw_format_ctx @@ -117,8 +118,22 @@ hicn_strategy_mw_ctx_create (fib_protocol_t proto, *dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx); - init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw, proto); + HICN_DEBUG ("Successful hicn_strategy_dpo_ctx_alloc with index %d", + *dpo_idx); + init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw, + (dpo_proto_t) proto); + + memset (hicn_strategy_mw_ctx->weight, 0, HICN_PARAM_FIB_ENTRY_NHOPS_MAX); +} + +void +hicn_strategy_mw_update_ctx_type (hicn_dpo_ctx_t *hicn_strategy_ctx) +{ + hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx; + hicn_strategy_mw_ctx = (hicn_strategy_mw_ctx_t *) hicn_strategy_ctx->data; + + hicn_strategy_ctx->dpo_type = hicn_dpo_type_mw; memset (hicn_strategy_mw_ctx->weight, 0, HICN_PARAM_FIB_ENTRY_NHOPS_MAX); } diff --git a/hicn-plugin/src/strategies/dpo_mw.h b/hicn-plugin/src/strategies/dpo_mw.h index 1a174631a..d2807d1a5 100644 --- a/hicn-plugin/src/strategies/dpo_mw.h +++ b/hicn-plugin/src/strategies/dpo_mw.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: @@ -72,6 +72,13 @@ void hicn_strategy_mw_ctx_create (fib_protocol_t proto, index_t *dpo_idx); /** + * @brief Update existing ctx setting it to mw + * + * @param hicn_strategy_ctx pointer to the ctx to update + */ +void hicn_strategy_mw_update_ctx_type (hicn_dpo_ctx_t *hicn_strategy_ctx); + +/** * @brief Add or update a next hop in the dpo ctx. * * This function is meant to be used in the control plane and not in the data diff --git a/hicn-plugin/src/strategies/dpo_rp.c b/hicn-plugin/src/strategies/dpo_rp.c new file mode 100644 index 000000000..7f527cdb6 --- /dev/null +++ b/hicn-plugin/src/strategies/dpo_rp.c @@ -0,0 +1,155 @@ +/* + * 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. + */ + +#include "dpo_rp.h" +#include "strategy_rp.h" +#include "../strategy_dpo_manager.h" +#include "../strategy_dpo_ctx.h" + +/** + * @brief DPO type value for the rp_strategy + */ +static dpo_type_t hicn_dpo_type_rp; + +static const hicn_dpo_vft_t hicn_dpo_rp_vft = { + .hicn_dpo_is_type = &hicn_dpo_is_type_strategy_rp, + .hicn_dpo_get_type = &hicn_dpo_strategy_rp_get_type, + .hicn_dpo_module_init = &hicn_dpo_strategy_rp_module_init, + .hicn_dpo_create = &hicn_strategy_rp_ctx_create, + .hicn_dpo_update_type = &hicn_strategy_rp_update_ctx_type, + .hicn_dpo_add_update_nh = &hicn_strategy_rp_ctx_add_nh, + .hicn_dpo_del_nh = &hicn_strategy_rp_ctx_del_nh, + .hicn_dpo_format = &hicn_strategy_rp_format_ctx +}; + +int +hicn_dpo_is_type_strategy_rp (const dpo_id_t *dpo) +{ + return dpo->dpoi_type == hicn_dpo_type_rp; +} + +void +hicn_dpo_strategy_rp_module_init (void) +{ + /* + * Register our type of dpo + */ + hicn_dpo_type_rp = hicn_dpo_register_new_type ( + hicn_nodes_strategy, &hicn_dpo_rp_vft, hicn_rp_strategy_get_vft (), + &dpo_strategy_rp_ctx_vft); +} + +dpo_type_t +hicn_dpo_strategy_rp_get_type (void) +{ + return hicn_dpo_type_rp; +} + +////////////////////////////////////////////////////////////////////////////////////////////////// + +u8 * +hicn_strategy_rp_format_ctx (u8 *s, int n, ...) +{ + va_list args; + va_start (args, n); + s = format_hicn_strategy_rp_ctx (s, &args); + return s; +} + +u8 * +format_hicn_strategy_rp_ctx (u8 *s, va_list *ap) +{ + int i = 0; + index_t index = va_arg (*ap, index_t); + hicn_dpo_ctx_t *dpo_ctx = NULL; + u32 indent = va_arg (*ap, u32); + + dpo_ctx = hicn_strategy_dpo_ctx_get (index); + if (dpo_ctx == NULL) + return s; + + for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++) + { + u8 *buf = NULL; + if (i < dpo_ctx->entry_count) + buf = format (NULL, "FIB"); + else if (i >= HICN_PARAM_FIB_ENTRY_NHOPS_MAX - dpo_ctx->tfib_entry_count) + buf = format (NULL, "TFIB"); + else + continue; + + s = format (s, "\n"); + s = format (s, "%U ", format_hicn_face, dpo_ctx->next_hops[i], indent); + s = format (s, " %s", buf); + } + + return (s); +} + +void +hicn_strategy_rp_ctx_create (fib_protocol_t proto, + const hicn_face_id_t *next_hop, int nh_len, + index_t *dpo_idx) +{ + hicn_dpo_ctx_t *hicn_strategy_ctx; + + /* Allocate a hicn_dpo_ctx on the vpp pool and initialize it */ + hicn_strategy_ctx = hicn_strategy_dpo_ctx_alloc (); + + *dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx); + + init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rp, + (dpo_proto_t) proto); +} + +void +hicn_strategy_rp_update_ctx_type (hicn_dpo_ctx_t *hicn_strategy_ctx) +{ + hicn_strategy_ctx->dpo_type = hicn_dpo_type_rp; + // don't care to reset data, it is not used +} + +int +hicn_strategy_rp_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx) +{ + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + u8 pos = 0; + + if (hicn_strategy_dpo_ctx == NULL) + { + return HICN_ERROR_STRATEGY_NOT_FOUND; + } + + hicn_strategy_dpo_ctx_add_nh (nh, hicn_strategy_dpo_ctx, &pos); + // nothing else to initialize in this strategy + return HICN_ERROR_NONE; +} + +int +hicn_strategy_rp_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx) +{ + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + // No need to change the current_nhop. It will be updated at the next + // selection. + return hicn_strategy_dpo_ctx_del_nh (face_id, hicn_strategy_dpo_ctx); +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/hicn-plugin/src/strategies/dpo_rp.h b/hicn-plugin/src/strategies/dpo_rp.h new file mode 100644 index 000000000..4fe645add --- /dev/null +++ b/hicn-plugin/src/strategies/dpo_rp.h @@ -0,0 +1,152 @@ +/* + * 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_DPO_RP_H__ +#define __HICN_DPO_RP_H__ + +#include <vnet/dpo/dpo.h> +#include "../strategy_dpo_ctx.h" + +/** + * @file dpo_rp.h + * + * This file implements the strategy vtf (see strategy.h) and + * the dpo vft (see strategy_dpo_manager.h) for the strategy + * replication. + */ + +typedef struct hicn_strategy_rp_ctx_s +{ +} hicn_strategy_rp_ctx_t; + +/** + * @brief Format the dpo ctx for a human-readable string + * + * @param s String to which to append the formatted dpo ctx + * @param ap List of parameters for the formatting + * + * @result The string with the formatted dpo ctx + */ +u8 *format_hicn_strategy_rp_ctx (u8 *s, va_list *ap); + +const static dpo_vft_t dpo_strategy_rp_ctx_vft = { + .dv_lock = hicn_strategy_dpo_ctx_lock, + .dv_unlock = hicn_strategy_dpo_ctx_unlock, + .dv_format = format_hicn_strategy_rp_ctx, +}; + +/** + * @brief Retrieve an hicn_strategy_rp_ctx object + * + * @param indext Index of the hicn_dpo_ctx to retrieve + * @return The hicn_dpo_ctx object or NULL + */ +hicn_dpo_ctx_t *hicn_strategy_rp_ctx_get (index_t index); + +/** + * @brief Create a new replication ctx + * + * @param proto The protocol to which the dpo is meant for (see vpp docs) + * @param next_hop A list of next hops to be inserted in the dpo ctx + * @param nh_len Size of the list + * @param dpo_idx index_t that will hold the index of the created dpo ctx + * @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL + */ +void hicn_strategy_rp_ctx_create (fib_protocol_t proto, + const hicn_face_id_t *next_hop, int nh_len, + index_t *dpo_idx); + +/** + * @brief Update existing ctx setting it to rp + * + * @param hicn_strategy_ctx pointer to the ctx to update + */ +void hicn_strategy_rp_update_ctx_type (hicn_dpo_ctx_t *hicn_strategy_ctx); + +/** + * @brief Add or update a next hop in the dpo ctx. + * + * This function is meant to be used in the control plane and not in the data + * plane, as it is not optimized for the latter. + * + * @param nh Next hop to insert in the dpo ctx + * @param dpo_idx Index of the dpo ctx to update with the new or updated next + * hop + * @return HICN_ERROR_NONE if the update or insert was fine, + * otherwise HICN_ERROR_DPO_CTX_NOT_FOUND + */ +int hicn_strategy_rp_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx); + +/** + * @brief Delete a next hop in the dpo ctx. + * + * @param face_id Face identifier of the next hop + * @param dpo_idx Index of the dpo ctx to update with the new or updated next + * hop + * @return HICN_ERROR_NONE if the update or insert was fine, + * otherwise HICN_ERROR_DPO_CTS_NOT_FOUND + */ +int hicn_strategy_rp_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx); + +/** + * @brief Prefetch a dpo + * + * @param dpo_idx Index of the dpo ctx to prefetch + */ +void hicn_strategy_rp_ctx_prefetch (index_t dpo_idx); + +/** + * @brief Return true if the dpo is of type strategy rp + * + * @param dpo Dpo to check the type + */ +int hicn_dpo_is_type_strategy_rp (const dpo_id_t *dpo); + +/** + * @brief Initialize the Replication strategy + */ +void hicn_dpo_strategy_rp_module_init (void); + +/** + * @brief Return the dpo type for the Replication strategy + */ +dpo_type_t hicn_dpo_strategy_rp_get_type (void); + +/** + * @brief Format the dpo ctx for the strategy Replication + * + * @param s String to append the formatted dpo ctx + * @param ap List of arguments to format + */ +u8 *format_hicn_dpo_strategy_rp (u8 *s, va_list *ap); + +/** + * @brief Format the dpo ctx for the strategy Replication. To + * call from other functions + * + * @param s String to append the formatted dpo ctx + * @param ... List of arguments to format + */ +u8 *hicn_strategy_rp_format_ctx (u8 *s, int n, ...); + +#endif // __HICN_DPO_RP_H__ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/hicn-plugin/src/strategies/dpo_rr.c b/hicn-plugin/src/strategies/dpo_rr.c index 3fe506bd1..86b68186b 100644 --- a/hicn-plugin/src/strategies/dpo_rr.c +++ b/hicn-plugin/src/strategies/dpo_rr.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: @@ -28,6 +28,7 @@ static const hicn_dpo_vft_t hicn_dpo_rr_vft = { .hicn_dpo_get_type = &hicn_dpo_strategy_rr_get_type, .hicn_dpo_module_init = &hicn_dpo_strategy_rr_module_init, .hicn_dpo_create = &hicn_strategy_rr_ctx_create, + .hicn_dpo_update_type = &hicn_strategy_rr_update_ctx_type, .hicn_dpo_add_update_nh = &hicn_strategy_rr_ctx_add_nh, .hicn_dpo_del_nh = &hicn_strategy_rr_ctx_del_nh, .hicn_dpo_format = &hicn_strategy_rr_format_ctx @@ -117,11 +118,22 @@ hicn_strategy_rr_ctx_create (fib_protocol_t proto, *dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx); - init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr, proto); + init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr, + (dpo_proto_t) proto); hicn_strategy_rr_ctx->current_nhop = 0; } +void +hicn_strategy_rr_update_ctx_type (hicn_dpo_ctx_t *hicn_strategy_ctx) +{ + hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx; + hicn_strategy_rr_ctx = (hicn_strategy_rr_ctx_t *) hicn_strategy_ctx->data; + + hicn_strategy_ctx->dpo_type = hicn_dpo_type_rr; + hicn_strategy_rr_ctx->current_nhop = 0; +} + int hicn_strategy_rr_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx) { diff --git a/hicn-plugin/src/strategies/dpo_rr.h b/hicn-plugin/src/strategies/dpo_rr.h index e68e2917d..72ec7b5df 100644 --- a/hicn-plugin/src/strategies/dpo_rr.h +++ b/hicn-plugin/src/strategies/dpo_rr.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: @@ -74,6 +74,13 @@ void hicn_strategy_rr_ctx_create (fib_protocol_t proto, index_t *dpo_idx); /** + * @brief Update existing ctx setting it to rr + * + * @param hicn_strategy_ctx pointer to the ctx to update + */ +void hicn_strategy_rr_update_ctx_type (hicn_dpo_ctx_t *hicn_strategy_ctx); + +/** * @brief Add or update a next hop in the dpo ctx. * * This function is meant to be used in the control plane and not in the data diff --git a/hicn-plugin/src/strategies/strategy_mw.c b/hicn-plugin/src/strategies/strategy_mw.c index 9409ec856..990e64a5d 100644 --- a/hicn-plugin/src/strategies/strategy_mw.c +++ b/hicn-plugin/src/strategies/strategy_mw.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: @@ -25,7 +25,7 @@ void hicn_receive_data_mw (index_t dpo_idx, int nh_idx); void hicn_add_interest_mw (index_t dpo_idx, hicn_hash_entry_t *pit_entry); void hicn_on_interest_timeout_mw (index_t dpo_idx); u32 hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, - hicn_face_id_t *outface); + hicn_face_id_t *outfaces, uint32_t *len); u32 get_strategy_node_index_mw (void); u8 *hicn_strategy_format_trace_mw (u8 *s, hicn_strategy_trace_t *t); u8 *hicn_strategy_format_mw (u8 *s, va_list *ap); @@ -51,12 +51,16 @@ hicn_mw_strategy_get_vft (void) /* DPO should be give in input as it containes all the information to calculate * the next hops*/ u32 -hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, hicn_face_id_t *outface) +hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, + hicn_face_id_t *outfaces, uint32_t *len) { hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); if (dpo_ctx == NULL) - return HICN_ERROR_STRATEGY_NOT_FOUND; + { + *len = 0; + return HICN_ERROR_STRATEGY_NOT_FOUND; + } hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = (hicn_strategy_mw_ctx_t *) dpo_ctx->data; @@ -71,7 +75,8 @@ hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, hicn_face_id_t *outface) } } - *outface = dpo_ctx->next_hops[next_hop_index]; + outfaces[0] = dpo_ctx->next_hops[next_hop_index]; + *len = 1; return HICN_ERROR_NONE; } @@ -84,7 +89,6 @@ hicn_add_interest_mw (index_t dpo_ctx_idx, hicn_hash_entry_t *hash_entry) .dpoi_proto = 0, .dpoi_next_node = 0, .dpoi_index = dpo_ctx_idx }; - hicn_strategy_dpo_ctx_lock (&hicn_dpo_id); hash_entry->vft_id = hicn_dpo_get_vft_id (&hicn_dpo_id); } diff --git a/hicn-plugin/src/strategies/strategy_mw.h b/hicn-plugin/src/strategies/strategy_mw.h index 9e0078b23..186e8c5ab 100644 --- a/hicn-plugin/src/strategies/strategy_mw.h +++ b/hicn-plugin/src/strategies/strategy_mw.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: diff --git a/hicn-plugin/src/strategies/strategy_mw_cli.c b/hicn-plugin/src/strategies/strategy_mw_cli.c index 6b56e9fd5..4ace68423 100644 --- a/hicn-plugin/src/strategies/strategy_mw_cli.c +++ b/hicn-plugin/src/strategies/strategy_mw_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: @@ -76,7 +76,7 @@ hicn_mw_strategy_cli_set_weight_command_fn (vlib_main_t *vm, } prefix.fp_proto = ip46_address_is_ip4 (&prefix.fp_addr) ? FIB_PROTOCOL_IP4 : - FIB_PROTOCOL_IP6; + FIB_PROTOCOL_IP6; ret = hicn_route_get_dpo (&prefix, &hicn_dpo_id, &fib_index); if (ret == HICN_ERROR_NONE) diff --git a/hicn-plugin/src/strategies/strategy_rp.c b/hicn-plugin/src/strategies/strategy_rp.c new file mode 100644 index 000000000..748cd69b1 --- /dev/null +++ b/hicn-plugin/src/strategies/strategy_rp.c @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#include "dpo_rp.h" +#include "../strategy.h" +#include "../strategy_dpo_ctx.h" +#include "../faces/face.h" +#include "../hashtb.h" +#include "../strategy_dpo_manager.h" + +/* Simple strategy that forwards intertests to all next hops */ +/* It does not require to exend the hicn_dpo */ +void hicn_receive_data_rp (index_t dpo_idx, int nh_idx); +void hicn_add_interest_rp (index_t dpo_idx, hicn_hash_entry_t *pit_entry); +void hicn_on_interest_timeout_rp (index_t dpo_idx); +u32 hicn_select_next_hop_rp (index_t dpo_idx, int *nh_idx, + hicn_face_id_t *outfaces, uint32_t *len); +u8 *hicn_strategy_format_trace_rp (u8 *s, hicn_strategy_trace_t *t); +u8 *hicn_strategy_format_rp (u8 *s, va_list *ap); + +static hicn_strategy_vft_t hicn_strategy_rp_vft = { + .hicn_receive_data = &hicn_receive_data_rp, + .hicn_add_interest = &hicn_add_interest_rp, + .hicn_on_interest_timeout = &hicn_on_interest_timeout_rp, + .hicn_select_next_hop = &hicn_select_next_hop_rp, + .hicn_format_strategy_trace = &hicn_strategy_format_trace_rp, + .hicn_format_strategy = &hicn_strategy_format_rp +}; + +/* + * Return the vft of the strategy. + */ +hicn_strategy_vft_t * +hicn_rp_strategy_get_vft (void) +{ + return &hicn_strategy_rp_vft; +} + +/* DPO should be give in input as it containes all the information to calculate + * the next hops*/ +u32 +hicn_select_next_hop_rp (index_t dpo_idx, int *nh_idx, + hicn_face_id_t *outfaces, uint32_t *len) +{ + hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + + if (dpo_ctx == NULL || dpo_ctx->entry_count == 0) + { + *len = 0; + return HICN_ERROR_STRATEGY_NOT_FOUND; + } + + int i = 0; + while (i < MAX_OUT_FACES && i < dpo_ctx->entry_count) + { + outfaces[i] = dpo_ctx->next_hops[i]; + i++; + } + *len = i; + + return HICN_ERROR_NONE; +} + +void +hicn_add_interest_rp (index_t dpo_ctx_idx, hicn_hash_entry_t *hash_entry) +{ + /* Nothing to do */ +} + +void +hicn_on_interest_timeout_rp (index_t dpo_idx) +{ + /* Nothing to do in the rp strategy when we receive an interest */ +} + +void +hicn_receive_data_rp (index_t dpo_idx, int nh_idx) +{ + /* nothing to do */ +} + +/* packet trace format function */ +u8 * +hicn_strategy_format_trace_rp (u8 *s, hicn_strategy_trace_t *t) +{ + s = format (s, "Strategy_rp: pkt: %d, sw_if_index %d, next index %d", + (int) t->pkt_type, t->sw_if_index, t->next_index); + return (s); +} + +u8 * +hicn_strategy_format_rp (u8 *s, va_list *ap) +{ + + u32 indent = va_arg (*ap, u32); + s = format (s, "Replication: send to all the next hops \n", indent); + return (s); +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/hicn-plugin/src/strategies/strategy_rp.h b/hicn-plugin/src/strategies/strategy_rp.h new file mode 100644 index 000000000..c308497cc --- /dev/null +++ b/hicn-plugin/src/strategies/strategy_rp.h @@ -0,0 +1,41 @@ +/* + * 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_STRATEGY_RP_H__ +#define __HICN_STRATEGY_RP_H__ + +#include "../strategy.h" + +/** + * @file strategy_rp.h + * + * This file implements the replication strategy. In this + * strategy all the next hops are used to send an intertest. + */ + +/** + * @brief Return the vft for the Replication strategy + */ +hicn_strategy_vft_t *hicn_rp_strategy_get_vft (void); + +#endif // __HICN_STRATEGY_RP_H__ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/hicn-plugin/src/strategies/strategy_rr.c b/hicn-plugin/src/strategies/strategy_rr.c index 9995191b7..192cf5fc3 100644 --- a/hicn-plugin/src/strategies/strategy_rr.c +++ b/hicn-plugin/src/strategies/strategy_rr.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: @@ -26,7 +26,7 @@ void hicn_receive_data_rr (index_t dpo_idx, int nh_idx); void hicn_add_interest_rr (index_t dpo_idx, hicn_hash_entry_t *pit_entry); void hicn_on_interest_timeout_rr (index_t dpo_idx); u32 hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, - hicn_face_id_t *outface); + hicn_face_id_t *outfaces, uint32_t *len); u8 *hicn_strategy_format_trace_rr (u8 *s, hicn_strategy_trace_t *t); u8 *hicn_strategy_format_rr (u8 *s, va_list *ap); @@ -51,17 +51,22 @@ hicn_rr_strategy_get_vft (void) /* DPO should be give in input as it containes all the information to calculate * the next hops*/ u32 -hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, hicn_face_id_t *outface) +hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, + hicn_face_id_t *outfaces, uint32_t *len) { hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); if (dpo_ctx == NULL) - return HICN_ERROR_STRATEGY_NOT_FOUND; + { + *len = 0; + return HICN_ERROR_STRATEGY_NOT_FOUND; + } hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = (hicn_strategy_rr_ctx_t *) dpo_ctx->data; - *outface = dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop]; + outfaces[0] = dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop]; + *len = 1; hicn_strategy_rr_ctx->current_nhop = (hicn_strategy_rr_ctx->current_nhop + 1) % dpo_ctx->entry_count; @@ -77,7 +82,6 @@ hicn_add_interest_rr (index_t dpo_ctx_idx, hicn_hash_entry_t *hash_entry) .dpoi_proto = 0, .dpoi_next_node = 0, .dpoi_index = dpo_ctx_idx }; - hicn_strategy_dpo_ctx_lock (&hicn_dpo_id); hash_entry->vft_id = hicn_dpo_get_vft_id (&hicn_dpo_id); } diff --git a/hicn-plugin/src/strategies/strategy_rr.h b/hicn-plugin/src/strategies/strategy_rr.h index 4dfe76b43..fb7520180 100644 --- a/hicn-plugin/src/strategies/strategy_rr.h +++ b/hicn-plugin/src/strategies/strategy_rr.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/strategy.h b/hicn-plugin/src/strategy.h index 28af55f01..efc6e464e 100644 --- a/hicn-plugin/src/strategy.h +++ b/hicn-plugin/src/strategy.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: @@ -53,7 +53,7 @@ typedef struct hicn_strategy_vft_s void (*hicn_on_interest_timeout) (index_t dpo_idx); void (*hicn_add_interest) (index_t dpo_idx, hicn_hash_entry_t *pit_entry); u32 (*hicn_select_next_hop) (index_t dpo_idx, int *nh_idx, - hicn_face_id_t *outface); + hicn_face_id_t *outfaces, uint32_t *len); u8 *(*hicn_format_strategy_trace) (u8 *, hicn_strategy_trace_t *); u8 *(*hicn_format_strategy) (u8 *s, va_list *ap); /**< Format an hICN dpo*/ @@ -86,6 +86,8 @@ const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] = { [DPO_PROTO_IP4] = hicn_ip4_nodes, }; +const static uint32_t MAX_OUT_FACES = 8; + extern vlib_node_registration_t hicn_strategy_node; #endif /* //__HICN_STRATEGY__ */ diff --git a/hicn-plugin/src/strategy_dpo_ctx.c b/hicn-plugin/src/strategy_dpo_ctx.c index edfe75aa8..2279ecc75 100644 --- a/hicn-plugin/src/strategy_dpo_ctx.c +++ b/hicn-plugin/src/strategy_dpo_ctx.c @@ -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,7 +21,7 @@ hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_pool; void hicn_strategy_init_dpo_ctx_pool () { - pool_init_fixed (hicn_strategy_dpo_ctx_pool, 256); + // pool_init_fixed (hicn_strategy_dpo_ctx_pool, 256); } void @@ -29,9 +29,16 @@ hicn_strategy_dpo_ctx_lock (dpo_id_t *dpo) { hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo->dpoi_index); - if (dpo_ctx != NULL) + if (PREDICT_TRUE (dpo_ctx != NULL)) { dpo_ctx->locks++; + HICN_DEBUG ("Locking DPO CTX with index %d. Lock now: %d", + dpo->dpoi_index, dpo_ctx->locks); + } + else + { + HICN_ERROR ("Trying to lock NULL spo_ctx with index %d", + dpo->dpoi_index); } } @@ -41,15 +48,23 @@ hicn_strategy_dpo_ctx_unlock (dpo_id_t *dpo) hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = (hicn_dpo_ctx_t *) hicn_strategy_dpo_ctx_get (dpo->dpoi_index); - if (hicn_strategy_dpo_ctx != NULL) + if (PREDICT_TRUE (hicn_strategy_dpo_ctx != NULL)) { hicn_strategy_dpo_ctx->locks--; + HICN_DEBUG ("Unlcking DPO CTX with index %d. Lock now: %d", + dpo->dpoi_index, hicn_strategy_dpo_ctx->locks); if (0 == hicn_strategy_dpo_ctx->locks) { + HICN_DEBUG ("Releasing DPO CTX %d", dpo->dpoi_index); pool_put (hicn_strategy_dpo_ctx_pool, hicn_strategy_dpo_ctx); } } + else + { + HICN_ERROR ("Trying to unlock NULL spo_ctx with index %d", + dpo->dpoi_index); + } } u8 * @@ -90,8 +105,11 @@ hicn_strategy_dpo_ctx_get (index_t index) hicn_dpo_ctx_t * hicn_strategy_dpo_ctx_alloc () { + HICN_DEBUG ("Allocating new DPO CTX"); hicn_dpo_ctx_t *dpo_ctx; - pool_get (hicn_strategy_dpo_ctx_pool, dpo_ctx); + pool_get_aligned (hicn_strategy_dpo_ctx_pool, dpo_ctx, + 2 * CLIB_CACHE_LINE_BYTES); + dpo_ctx->locks = 0; return dpo_ctx; } diff --git a/hicn-plugin/src/strategy_dpo_ctx.h b/hicn-plugin/src/strategy_dpo_ctx.h index fe63a4258..cb8ca4051 100644 --- a/hicn-plugin/src/strategy_dpo_ctx.h +++ b/hicn-plugin/src/strategy_dpo_ctx.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: @@ -108,7 +108,7 @@ init_dpo_ctx (hicn_dpo_ctx_t *dpo_ctx, const hicn_face_id_t *next_hop, dpo_ctx->seq = INIT_SEQ; dpo_ctx->dpo_type = dpo_type; - dpo_ctx->proto = proto; + dpo_ctx->proto = (fib_protocol_t) proto; for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && i < nh_len; i++) { diff --git a/hicn-plugin/src/strategy_dpo_manager.c b/hicn-plugin/src/strategy_dpo_manager.c index 3c441ccac..6c5767bc9 100644 --- a/hicn-plugin/src/strategy_dpo_manager.c +++ b/hicn-plugin/src/strategy_dpo_manager.c @@ -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: @@ -19,6 +19,7 @@ #include "strategy_dpo_ctx.h" #include "strategies/dpo_mw.h" #include "strategies/dpo_rr.h" +#include "strategies/dpo_rp.h" #include "strategy.h" #include "faces/face.h" @@ -98,11 +99,13 @@ hicn_dpos_init (void) hicn_strategy_init_dpo_ctx_pool (); hicn_dpo_strategy_mw_module_init (); hicn_dpo_strategy_rr_module_init (); + hicn_dpo_strategy_rp_module_init (); default_dpo.hicn_dpo_is_type = &hicn_dpo_is_type_strategy_mw; default_dpo.hicn_dpo_get_type = &hicn_dpo_strategy_mw_get_type; default_dpo.hicn_dpo_module_init = &hicn_dpo_strategy_mw_module_init; default_dpo.hicn_dpo_create = &hicn_strategy_mw_ctx_create; + default_dpo.hicn_dpo_update_type = &hicn_strategy_mw_update_ctx_type; default_dpo.hicn_dpo_add_update_nh = &hicn_strategy_mw_ctx_add_nh; default_dpo.hicn_dpo_del_nh = &hicn_strategy_mw_ctx_del_nh; default_dpo.hicn_dpo_format = &hicn_strategy_mw_format_ctx; @@ -128,12 +131,12 @@ format_hicn_strategy_list (u8 *s, int n, ...) return (s); } -u8 +int hicn_dpo_strategy_id_is_valid (int strategy_id) { return vec_len (strategies_id) > strategy_id ? - HICN_ERROR_NONE : - HICN_ERROR_DPO_MGR_ID_NOT_VALID; + HICN_ERROR_NONE : + HICN_ERROR_DPO_MGR_ID_NOT_VALID; } int diff --git a/hicn-plugin/src/strategy_dpo_manager.h b/hicn-plugin/src/strategy_dpo_manager.h index 7a2ce3fee..b8a0c9e92 100644 --- a/hicn-plugin/src/strategy_dpo_manager.h +++ b/hicn-plugin/src/strategy_dpo_manager.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: @@ -53,6 +53,8 @@ typedef struct hicn_dpo_vft_s void (*hicn_dpo_create) ( fib_protocol_t proto, const hicn_face_id_t *nh, int nh_len, index_t *dpo_idx); /**< Create the context of the hICN dpo */ + void (*hicn_dpo_update_type) ( + hicn_dpo_ctx_t *hicn_strategy_ctx); /**change dpo type */ int (*hicn_dpo_add_update_nh) ( hicn_face_id_t nh, index_t dpo_idx); /**< Add a next hop to the hICN dpo context */ @@ -171,7 +173,7 @@ u8 *format_hicn_strategy_list (u8 *s, int n, ...); * * @result HICN_ERROR_NONE is the id is valid, otherwise EINVAL */ -u8 hicn_dpo_strategy_id_is_valid (int strategy_id); +int hicn_dpo_strategy_id_is_valid (int strategy_id); /** * @brief Return the number of available strategies. This number can be used to diff --git a/hicn-plugin/src/strategy_node.c b/hicn-plugin/src/strategy_node.c index ec57d76e2..66d9c2dbb 100644 --- a/hicn-plugin/src/strategy_node.c +++ b/hicn-plugin/src/strategy_node.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: @@ -25,6 +25,7 @@ #include "mgmt.h" #include "pcs.h" #include "state.h" +#include "data_fwd.h" #include "strategies/strategy_mw.h" /* Registration struct for a graph node */ @@ -65,7 +66,8 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next, f64 tnow, u8 *nameptr, u16 namelen, hicn_face_id_t outface, int nh_idx, index_t dpo_ctx_id0, const hicn_strategy_vft_t *strategy, dpo_type_t dpo_type, - u8 isv6, vl_api_hicn_api_node_stats_get_reply_t *stats) + u8 isv6, vl_api_hicn_api_node_stats_get_reply_t *stats, + u8 is_replication) { int ret; hicn_hash_node_t *nodep; @@ -80,6 +82,17 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next, u8 bucket_is_overflow = 0; u32 bucket_id = ~0; + if (is_replication) + { + // an entry for this message alredy exists in the PIT so just send it + *next = isv6 ? HICN_STRATEGY_NEXT_INTEREST_FACE6 : + HICN_STRATEGY_NEXT_INTEREST_FACE4; + + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface; + stats->pkts_interest_count++; + return HICN_ERROR_NONE; + } + /* Create PIT node and init PIT entry */ nodep = hicn_hashtb_alloc_node (rt->pitcs->pcs_table); if (PREDICT_FALSE (nodep == NULL)) @@ -101,6 +114,7 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next, { imsg_lifetime = sm->pit_lifetime_max_ms; } + pitp->shared.expire_time = hicn_pcs_get_exp_time (tnow, imsg_lifetime); /* Set up the hash node and insert it */ @@ -121,7 +135,7 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next, hicn_face_db_add_face (hicnb0->face_id, &(pitp->u.pit.faces)); *next = isv6 ? HICN_STRATEGY_NEXT_INTEREST_FACE6 : - HICN_STRATEGY_NEXT_INTEREST_FACE4; + HICN_STRATEGY_NEXT_INTEREST_FACE4; vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface; stats->pkts_interest_count++; @@ -137,9 +151,15 @@ hicn_new_interest (hicn_strategy_runtime_t *rt, vlib_buffer_t *b0, u32 *next, bucket_id, bucket_is_overflow); // We need to take a lock as the lock is not taken on the hash // entry because it is a CS entry (hash_insert function). - hash_entry->locks++; - *next = is_cs0 ? HICN_STRATEGY_NEXT_INTEREST_HITCS : - HICN_STRATEGY_NEXT_INTEREST_HITPIT; + if (is_cs0) + { + hash_entry->locks++; + *next = HICN_STRATEGY_NEXT_INTEREST_HITCS; + } + else + { + *next = HICN_STRATEGY_NEXT_INTEREST_HITPIT; + } } else { @@ -189,7 +209,8 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node, hicn_header_t *hicn0; vlib_buffer_t *b0; u32 bi0; - hicn_face_id_t outface; + hicn_face_id_t outfaces[MAX_OUT_FACES]; + u32 outfaces_len; int nh_idx; u32 next0 = next_index; int ret; @@ -207,15 +228,23 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node, bi0 = from[0]; from += 1; n_left_from -= 1; - to_next[0] = bi0; - to_next += 1; - n_left_to_next -= 1; b0 = vlib_get_buffer (vm, bi0); next0 = HICN_STRATEGY_NEXT_ERROR_DROP; hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get ( vnet_buffer (b0)->ip.adj_index[VLIB_TX]); + + if (PREDICT_FALSE (!dpo_ctx)) + { + to_next[0] = bi0; + to_next += 1; + n_left_to_next -= 1; + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + continue; + } + const hicn_strategy_vft_t *strategy = hicn_dpo_get_strategy_vft (dpo_ctx->dpo_type); @@ -231,7 +260,7 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node, HICN_IS_NAMEHASH_CACHED (b0) && strategy->hicn_select_next_hop ( vnet_buffer (b0)->ip.adj_index[VLIB_TX], &nh_idx, - &outface) == HICN_ERROR_NONE)) + outfaces, &outfaces_len) == HICN_ERROR_NONE)) { /* * No need to check if parsing was successful @@ -239,32 +268,72 @@ hicn_strategy_fn (vlib_main_t *vm, vlib_node_runtime_t *node, * node */ nameptr = (u8 *) (&name); - hicn_new_interest (rt, b0, &next0, tnow, nameptr, namelen, - outface, nh_idx, - vnet_buffer (b0)->ip.adj_index[VLIB_TX], - strategy, dpo_ctx->dpo_type, isv6, &stats); + u32 clones[outfaces_len]; + if (outfaces_len > 1) + { + int ret = vlib_buffer_clone (vm, bi0, clones, outfaces_len, + CLIB_CACHE_LINE_BYTES * 2); + ASSERT (ret == outfaces_len); + } + else + { + clones[0] = bi0; + } + + for (u32 nh = 0; nh < outfaces_len; nh++) + { + vlib_buffer_t *local_b0 = vlib_get_buffer (vm, clones[nh]); + + to_next[0] = clones[nh]; + to_next += 1; + n_left_to_next -= 1; + + if (nh == 0) + { + // send first interest + hicn_new_interest ( + rt, local_b0, &next0, tnow, nameptr, namelen, + outfaces[nh], nh_idx, + vnet_buffer (local_b0)->ip.adj_index[VLIB_TX], + strategy, dpo_ctx->dpo_type, isv6, &stats, 0); + } + else + { + // send duplicated interests, avoid aggregation/drop + hicn_new_interest ( + rt, local_b0, &next0, tnow, nameptr, namelen, + outfaces[nh], nh_idx, + vnet_buffer (local_b0)->ip.adj_index[VLIB_TX], + strategy, dpo_ctx->dpo_type, isv6, &stats, 1); + } + + /* Maybe trace */ + if (PREDICT_FALSE ( + (node->flags & VLIB_NODE_FLAG_TRACE) && + (local_b0->flags & VLIB_BUFFER_IS_TRACED))) + { + hicn_strategy_trace_t *t = + vlib_add_trace (vm, node, local_b0, sizeof (*t)); + t->pkt_type = HICN_PKT_TYPE_CONTENT; + t->sw_if_index = + vnet_buffer (local_b0)->sw_if_index[VLIB_RX]; + t->next_index = next0; + t->dpo_type = dpo_ctx->dpo_type; + } + + /* + * Verify speculative enqueue, maybe switch current + * next frame + */ + /* + * Fix in case of a wrong speculation. Needed for + * cloning the data in the right frame + */ + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, + to_next, n_left_to_next, + clones[nh], next0); + } } - /* Maybe trace */ - if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && - (b0->flags & VLIB_BUFFER_IS_TRACED))) - { - hicn_strategy_trace_t *t = - vlib_add_trace (vm, node, b0, sizeof (*t)); - t->pkt_type = HICN_PKT_TYPE_CONTENT; - t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - t->next_index = next0; - t->dpo_type = dpo_ctx->dpo_type; - } - /* - * Verify speculative enqueue, maybe switch current - * next frame - */ - /* - * Fix in case of a wrong speculation. Needed for - * cloning the data in the right frame - */ - vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, - n_left_to_next, bi0, next0); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); diff --git a/hicn-plugin/src/udp_tunnels/udp_decap.h b/hicn-plugin/src/udp_tunnels/udp_decap.h index 9ddb8a73b..7dc13f272 100644 --- a/hicn-plugin/src/udp_tunnels/udp_decap.h +++ b/hicn-plugin/src/udp_tunnels/udp_decap.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/udp_tunnels/udp_decap_node.c b/hicn-plugin/src/udp_tunnels/udp_decap_node.c index 06eb8da71..2ac1b1ecb 100644 --- a/hicn-plugin/src/udp_tunnels/udp_decap_node.c +++ b/hicn-plugin/src/udp_tunnels/udp_decap_node.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-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: @@ -223,7 +223,7 @@ udp4_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip4_header_t *) outer_ptr0)->dst_address); udp0 = (udp_header_t *) (outer_ptr0 + sizeof (ip4_header_t)); next0 = v0 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4 : - UDP4_DECAP_NEXT_LOOKUP_IP6; + UDP4_DECAP_NEXT_LOOKUP_IP6; ip46_address_set_ip4 (&src1, &((ip4_header_t *) outer_ptr1)->src_address); @@ -231,7 +231,7 @@ udp4_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip4_header_t *) outer_ptr1)->dst_address); udp1 = (udp_header_t *) (outer_ptr1 + sizeof (ip4_header_t)); next1 = v1 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4 : - UDP4_DECAP_NEXT_LOOKUP_IP6; + UDP4_DECAP_NEXT_LOOKUP_IP6; ip46_address_set_ip4 (&src2, &((ip4_header_t *) outer_ptr2)->src_address); @@ -239,7 +239,7 @@ udp4_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip4_header_t *) outer_ptr2)->dst_address); udp2 = (udp_header_t *) (outer_ptr2 + sizeof (ip4_header_t)); next2 = v2 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4 : - UDP4_DECAP_NEXT_LOOKUP_IP6; + UDP4_DECAP_NEXT_LOOKUP_IP6; ip46_address_set_ip4 (&src3, &((ip4_header_t *) outer_ptr3)->src_address); @@ -247,7 +247,7 @@ udp4_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip4_header_t *) outer_ptr3)->dst_address); udp3 = (udp_header_t *) (outer_ptr3 + sizeof (ip4_header_t)); next3 = v3 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4 : - UDP4_DECAP_NEXT_LOOKUP_IP6; + UDP4_DECAP_NEXT_LOOKUP_IP6; hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3; hicnb0 = hicn_get_buffer (b0); @@ -257,34 +257,39 @@ udp4_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, /* Udp encap-decap tunnels have dst and src addresses and port * swapped */ - vnet_buffer (b0)->ip.adj_index[VLIB_RX] = - udp_tunnel_get (&dst0, &src0, udp0->dst_port, udp0->src_port); - vnet_buffer (b1)->ip.adj_index[VLIB_RX] = - udp_tunnel_get (&dst1, &src1, udp1->dst_port, udp1->src_port); - vnet_buffer (b2)->ip.adj_index[VLIB_RX] = - udp_tunnel_get (&dst2, &src2, udp2->dst_port, udp2->src_port); - vnet_buffer (b3)->ip.adj_index[VLIB_RX] = - udp_tunnel_get (&dst3, &src3, udp3->dst_port, udp3->src_port); - - if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) - hicnb0->flags |= - (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); - - if (vnet_buffer (b1)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) - hicnb1->flags |= - (outer_v1 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); - - if (vnet_buffer (b2)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) - hicnb2->flags |= - (outer_v2 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); - - if (vnet_buffer (b3)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) - hicnb3->flags |= - (outer_v3 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get_create ( + &dst0, &src0, udp0->dst_port, udp0->src_port); + vnet_buffer (b1)->ip.adj_index[VLIB_RX] = udp_tunnel_get_create ( + &dst1, &src1, udp1->dst_port, udp1->src_port); + vnet_buffer (b2)->ip.adj_index[VLIB_RX] = udp_tunnel_get_create ( + &dst2, &src2, udp2->dst_port, udp2->src_port); + vnet_buffer (b3)->ip.adj_index[VLIB_RX] = udp_tunnel_get_create ( + &dst3, &src3, udp3->dst_port, udp3->src_port); + + ASSERT (vnet_buffer (b0)->ip.adj_index[VLIB_RX] != + UDP_TUNNEL_INVALID); + ASSERT (vnet_buffer (b1)->ip.adj_index[VLIB_RX] != + UDP_TUNNEL_INVALID); + ASSERT (vnet_buffer (b2)->ip.adj_index[VLIB_RX] != + UDP_TUNNEL_INVALID); + ASSERT (vnet_buffer (b3)->ip.adj_index[VLIB_RX] != + UDP_TUNNEL_INVALID); + + hicnb0->flags = + (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + + hicnb1->flags = + (outer_v1 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + + hicnb2->flags = + (outer_v2 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + + hicnb3->flags = + (outer_v3 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); udp_decap_trace_buffer (vm, node, 1, b0); udp_decap_trace_buffer (vm, node, 1, b1); @@ -346,17 +351,19 @@ udp4_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip4_header_t *) outer_ptr0)->dst_address); udp0 = (udp_header_t *) (outer_ptr0 + sizeof (ip4_header_t)); next0 = v0 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4 : - UDP4_DECAP_NEXT_LOOKUP_IP6; + UDP4_DECAP_NEXT_LOOKUP_IP6; hicn_buffer_t *hicnb0 = hicn_get_buffer (b0); - vnet_buffer (b0)->ip.adj_index[VLIB_RX] = - udp_tunnel_get (&dst0, &src0, udp0->dst_port, udp0->src_port); + vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get_create ( + &dst0, &src0, udp0->dst_port, udp0->src_port); - if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) - hicnb0->flags |= - (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + ASSERT (vnet_buffer (b0)->ip.adj_index[VLIB_RX] != + UDP_TUNNEL_INVALID); + + hicnb0->flags |= + (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); udp_decap_trace_buffer (vm, node, 1, b0); @@ -488,7 +495,7 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip6_header_t *) outer_ptr0)->dst_address); udp0 = (udp_header_t *) (outer_ptr0 + sizeof (ip6_header_t)); next0 = v0 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : - UDP6_DECAP_NEXT_LOOKUP_IP6; + UDP6_DECAP_NEXT_LOOKUP_IP6; ip46_address_set_ip6 (&src1, &((ip6_header_t *) outer_ptr1)->src_address); @@ -496,7 +503,7 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip6_header_t *) outer_ptr1)->dst_address); udp1 = (udp_header_t *) (outer_ptr1 + sizeof (ip6_header_t)); next1 = v1 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : - UDP6_DECAP_NEXT_LOOKUP_IP6; + UDP6_DECAP_NEXT_LOOKUP_IP6; ip46_address_set_ip6 (&src2, &((ip6_header_t *) outer_ptr2)->src_address); @@ -504,7 +511,7 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip6_header_t *) outer_ptr2)->dst_address); udp2 = (udp_header_t *) (outer_ptr2 + sizeof (ip6_header_t)); next2 = v2 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : - UDP6_DECAP_NEXT_LOOKUP_IP6; + UDP6_DECAP_NEXT_LOOKUP_IP6; ip46_address_set_ip6 (&src3, &((ip6_header_t *) outer_ptr3)->src_address); @@ -512,7 +519,7 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip6_header_t *) outer_ptr3)->dst_address); udp3 = (udp_header_t *) (outer_ptr3 + sizeof (ip6_header_t)); next3 = v3 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : - UDP6_DECAP_NEXT_LOOKUP_IP6; + UDP6_DECAP_NEXT_LOOKUP_IP6; hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3; hicnb0 = hicn_get_buffer (b0); @@ -534,22 +541,22 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) hicnb0->flags |= (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); if (vnet_buffer (b1)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) hicnb1->flags |= (outer_v1 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); if (vnet_buffer (b2)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) hicnb2->flags |= (outer_v2 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); if (vnet_buffer (b3)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) hicnb3->flags |= (outer_v3 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); udp_decap_trace_buffer (vm, node, 0, b0); udp_decap_trace_buffer (vm, node, 0, b1); @@ -610,7 +617,7 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, &((ip6_header_t *) outer_ptr0)->dst_address); udp0 = (udp_header_t *) (outer_ptr0 + sizeof (ip6_header_t)); next0 = v0 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : - UDP6_DECAP_NEXT_LOOKUP_IP6; + UDP6_DECAP_NEXT_LOOKUP_IP6; hicn_buffer_t *hicnb0 = hicn_get_buffer (b0); @@ -620,7 +627,7 @@ udp6_decap_node_fn (vlib_main_t *vm, vlib_node_runtime_t *node, if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] != UDP_TUNNEL_INVALID) hicnb0->flags |= (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : - HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); + HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL); udp_decap_trace_buffer (vm, node, 0, b0); diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.c b/hicn-plugin/src/udp_tunnels/udp_tunnel.c index 8ea2cb503..d03d6a74e 100644 --- a/hicn-plugin/src/udp_tunnels/udp_tunnel.c +++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-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: @@ -156,6 +156,27 @@ udp_tunnel_get (const ip46_address_t *src_ip, const ip46_address_t *dst_ip, return ret == 0 ? (u32) value.value : UDP_TUNNEL_INVALID; } +u32 +udp_tunnel_get_create (const ip46_address_t *src_ip, + const ip46_address_t *dst_ip, u16 src_port, + u16 dst_port) +{ + u32 ret = udp_tunnel_get (src_ip, dst_ip, src_port, dst_port); + if (ret == UDP_TUNNEL_INVALID) + { + fib_protocol_t proto = + ip46_address_is_ip4 (src_ip) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + + index_t fib_index = fib_table_find (proto, HICN_FIB_TABLE); + + ret = udp_tunnel_add ( + proto, fib_index, src_ip, dst_ip, clib_net_to_host_u16 (src_port), + clib_net_to_host_u16 (dst_port), UDP_ENCAP_FIXUP_NONE); + } + + return ret; +} + void udp_tunnel_init () { @@ -255,8 +276,8 @@ udp_tunnel_command_fn (vlib_main_t *vm, unformat_input_t *main_input, int ret = udp_tunnel_del (fproto, fib_index, &src_ip, &dst_ip, src_port, dst_port, UDP_ENCAP_FIXUP_NONE); error = (ret == HICN_ERROR_NONE) ? - 0 : - clib_error_return (0, "%s\n", get_error_string (ret)); + 0 : + clib_error_return (0, "%s\n", get_error_string (ret)); } else { diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.h b/hicn-plugin/src/udp_tunnels/udp_tunnel.h index 2e57b7857..376adf5fa 100644 --- a/hicn-plugin/src/udp_tunnels/udp_tunnel.h +++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.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: @@ -70,6 +70,19 @@ u32 udp_tunnel_get (const ip46_address_t *src_ip, const ip46_address_t *dst_ip, u16 src_port, u16 dst_port); /** + * @brief Get udp tunnel UEI. Creates the tunnel if does not exist already. + * + * @param src_ip source address of the tunnel + * @param dst_ip destination address of the tunnel + * @param src_port source port + * @param src_port destination port + * @return id of the udp tunnel/encap + */ +u32 udp_tunnel_get_create (const ip46_address_t *src_ip, + const ip46_address_t *dst_ip, u16 src_port, + u16 dst_port); + +/** * @brief Delete a udp tunnel * * @param proto FIB_PROTOCOL_IP4 or FIB_PROTOCOL_IP6 diff --git a/hicn-plugin/src/utils.h b/hicn-plugin/src/utils.h index 847f2f388..7a3492732 100644 --- a/hicn-plugin/src/utils.h +++ b/hicn-plugin/src/utils.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/vapi/CMakeLists.txt b/hicn-plugin/vapi/CMakeLists.txt index 6c176b9f3..2005cdaf7 100644 --- a/hicn-plugin/vapi/CMakeLists.txt +++ b/hicn-plugin/vapi/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2019 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: @@ -11,51 +11,102 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.10 FATAL_ERROR) - -set(SAFE_VAPI safe_vapi CACHE INTERNAL "" FORCE) +############################################################## +# Libs and Bins names +############################################################## +set(SAFE_VAPI safevapi CACHE INTERNAL "" FORCE) set(SAFE_VAPI_SHARED ${SAFE_VAPI}.shared CACHE INTERNAL "" FORCE) -set(SAFE_VAPI_STATIC ${SAFE_VAPI}.static CACHE INTERNAL "" FORCE) +set(SAFE_VAPI_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/includes CACHE INTERNAL "" FORCE) +set(SAFE_VAPI_LIBRARIES ${SAFE_VAPI_SHARED} CACHE INTERNAL "" FORCE) + + +############################################################## +# Dependencies and third party libs +############################################################## +find_package(Vpp ${VPP_DEFAULT_VERSION} EXACT REQUIRED) -# Dependencies -find_package(Vpp REQUIRED) +############################################################## +# Check if building as subproject or as root project +############################################################## +if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + include(CommonSetup) + find_package(HicnPlugin ${CURRENT_VERSION} EXACT REQUIRED) +else() + list(APPEND DEPENDENCIES + ${HICNPLUGIN} + ) +endif() + +############################################################## +# Sources +############################################################## list(APPEND HEADER_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/vapi/vapi_safe.h + ${CMAKE_CURRENT_SOURCE_DIR}/includes/vapi/vapi_safe.h ) list(APPEND SOURCE_FILES - ${CMAKE_CURRENT_SOURCE_DIR}/vapi_safe.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/vapi_safe.c ) + +############################################################## +# Compiler Options +############################################################## +set(COMPILER_OPTIONS + ${DEFAULT_COMPILER_OPTIONS} + ${MARCH_COMPILER_OPTIONS} +) + + +############################################################## +# Libraries to link +############################################################## set (LIBRARIES - ${VPP_LIBRARY_VAPICLIENT}) + ${VPP_LIBRARY_VAPICLIENT} +) + +############################################################## +# Include directories +############################################################## list (APPEND INCLUDE_DIRS - ${VPP_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/include) + PUBLIC + $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}> + $<BUILD_INTERFACE:${HICNPLUGIN_INCLUDE_DIRS}> + $<BUILD_INTERFACE:${VPP_INCLUDE_DIR}> + $<BUILD_INTERFACE:${SAFE_VAPI_INCLUDE_DIRS}> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) -build_library(${SAFE_VAPI} - SHARED STATIC - SOURCES ${SOURCE_FILES} ${HEADER_FILES} - INSTALL_HEADERS ${HEADER_FILES} - LINK_LIBRARIES ${LIBRARIES} - COMPONENT ${HICN_PLUGIN} - INCLUDE_DIRS ${INCLUDE_DIRS} - HEADER_ROOT_DIR / - DEFINITIONS ${COMPILER_DEFINITIONS} - ) -set(SAFE_VAPI_INCLUDE_DIRS - ${CMAKE_CURRENT_SOURCE_DIR}/include - "" CACHE INTERNAL - "" FORCE +############################################################## +# Build library +############################################################## +build_library(${SAFE_VAPI} + SHARED + SOURCES ${SOURCE_FILES} ${HEADER_FILES} + INSTALL_HEADERS ${HEADER_FILES} + LINK_LIBRARIES PRIVATE ${LIBRARIES} + COMPONENT ${HICN_PLUGIN} + INCLUDE_DIRS ${INCLUDE_DIRS} + HEADER_ROOT_DIR "" + DEFINITIONS PUBLIC ${COMPILER_DEFINITIONS} + DEPENDS ${HICNPLUGIN}.shared + VERSION ${CURRENT_VERSION} + EXPORT_NAME "libsafevapi" + COMPILE_OPTIONS ${COMPILER_OPTIONS} ) -set(SAFE_VAPI_LIBRARIES - ${SAFE_VAPI_SHARED} - "" CACHE INTERNAL - "" FORCE -) +############################################################## +# Create cmake configuration +############################################################## +create_cmake_config ( + "libsafevapi" + INCLUDE_DIRS ${SAFE_VAPI_INCLUDE_DIRS} + VERSION ${CURRENT_VERSION} + COMPONENT ${HICN_PLUGIN} + NAMESPACE hicn +) diff --git a/hicn-plugin/vapi/include/vapi/vapi_safe.h b/hicn-plugin/vapi/include/vapi/vapi_safe.h deleted file mode 100644 index df1114cde..000000000 --- a/hicn-plugin/vapi/include/vapi/vapi_safe.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef VAPI_SAFE -#include <vapi/vapi.h> -#include <pthread.h> - -extern pthread_mutex_t *mutex; - -vapi_error_e vapi_connect_safe(vapi_ctx_t * vapi_ctx_ret, int async); - -vapi_error_e vapi_disconnect_safe(); -void vapi_lock(); - -void vapi_unlock(); - -#define VAPI_SAFE (NAME, res, ...) \ - vapi_lock(); \ - res = ## NAME (__ARGS__); \ - vapi_unlock(); - -#endif //VAPI_SAFE diff --git a/hicn-plugin/vapi/includes/vapi/vapi_safe.h b/hicn-plugin/vapi/includes/vapi/vapi_safe.h new file mode 100644 index 000000000..423034730 --- /dev/null +++ b/hicn-plugin/vapi/includes/vapi/vapi_safe.h @@ -0,0 +1,33 @@ +/* + * 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 __VAPI_SAFE__ +#define __VAPI_SAFE__ + +#include <vapi/vapi.h> +#include <pthread.h> + +#include <vapi/hicn.api.vapi.h> +#include <vapi/interface.api.vapi.h> +#include <vapi/ip.api.vapi.h> +#include <vapi/memif.api.vapi.h> +#include <vapi/udp.api.vapi.h> + +vapi_error_e vapi_connect_safe (vapi_ctx_t *vapi_ctx_ret, int async); +vapi_error_e vapi_disconnect_safe (); +void vapi_lock (); +void vapi_unlock (); + +#endif diff --git a/hicn-plugin/vapi/libsafevapi-config.cmake.in b/hicn-plugin/vapi/libsafevapi-config.cmake.in new file mode 100644 index 000000000..feb278c1f --- /dev/null +++ b/hicn-plugin/vapi/libsafevapi-config.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +set(Libsafevapi_VERSION_MAJOR "@VERSION_MAJOR@") +set(Libsafevapi_VERSION_MINOR "@VERSION_MINOR@") +set(Libsafevapi_VERSION_PATCH "@VERSION_PATCH@") + +set_and_check(Libsafe_vapi_INCLUDE_DIRS "@PACKAGE_Libsafevapi_INCLUDE_DIRS@") +include("${CMAKE_CURRENT_LIST_DIR}/libsafevapi-targets.cmake") diff --git a/hicn-plugin/vapi/src/vapi_safe.c b/hicn-plugin/vapi/src/vapi_safe.c new file mode 100644 index 000000000..a91793674 --- /dev/null +++ b/hicn-plugin/vapi/src/vapi_safe.c @@ -0,0 +1,98 @@ +/* + * 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. + */ + +#include <vapi/vapi_safe.h> +#include <stdlib.h> +#include <stdio.h> + +#define APP_NAME "hicn_plugin" +#define MAX_OUTSTANDING_REQUESTS 4 +#define RESPONSE_QUEUE_SIZE 2 + +DEFINE_VAPI_MSG_IDS_HICN_API_JSON +DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON +DEFINE_VAPI_MSG_IDS_IP_API_JSON +DEFINE_VAPI_MSG_IDS_UDP_API_JSON +DEFINE_VAPI_MSG_IDS_MEMIF_API_JSON + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +vapi_ctx_t g_vapi_ctx_instance = NULL; +u32 count = 0; + +vapi_error_e +vapi_connect_safe (vapi_ctx_t *vapi_ctx_ret, int async) +{ + vapi_error_e rv = VAPI_OK; + + vapi_lock (); + + if (!g_vapi_ctx_instance) + { + rv = vapi_ctx_alloc (&g_vapi_ctx_instance); + if (rv != VAPI_OK) + goto err; + } + + if (!count) + { + rv = vapi_connect (g_vapi_ctx_instance, APP_NAME, NULL, + MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, + async ? VAPI_MODE_NONBLOCKING : VAPI_MODE_BLOCKING, + true); + + if (rv != VAPI_OK) + goto err; + } + + count++; + *vapi_ctx_ret = g_vapi_ctx_instance; + + vapi_unlock (); + return rv; + +err: + vapi_unlock (); + return VAPI_ENOMEM; +} + +vapi_error_e +vapi_disconnect_safe () +{ + vapi_error_e rv = VAPI_OK; + + vapi_lock (); + count--; + if (count == 0) + { + rv = vapi_disconnect (g_vapi_ctx_instance); + vapi_ctx_free (g_vapi_ctx_instance); + g_vapi_ctx_instance = NULL; + } + vapi_unlock (); + + return rv; +} + +void +vapi_lock () +{ + pthread_mutex_lock (&mutex); +} + +void +vapi_unlock () +{ + pthread_mutex_unlock (&mutex); +} diff --git a/hicn-plugin/vapi/vapi_safe.c b/hicn-plugin/vapi/vapi_safe.c deleted file mode 100644 index e9353497f..000000000 --- a/hicn-plugin/vapi/vapi_safe.c +++ /dev/null @@ -1,73 +0,0 @@ -#include <vapi/vapi_safe.h> -#include <stdlib.h> -#include <stdio.h> - -#define APP_NAME "hicn_plugin" -#define MAX_OUTSTANDING_REQUESTS 4 -#define RESPONSE_QUEUE_SIZE 2 - -pthread_mutex_t *mutex = NULL; -vapi_ctx_t g_vapi_ctx_instance = NULL; -u32 count = 0; -int lock = 0; - -vapi_error_e vapi_connect_safe(vapi_ctx_t *vapi_ctx_ret, int async) { - vapi_error_e rv = VAPI_OK; - - while (!__sync_bool_compare_and_swap(&lock, 0, 1)); - - if (!g_vapi_ctx_instance && !mutex) - { - rv = vapi_ctx_alloc(&g_vapi_ctx_instance); - if (rv != VAPI_OK) - goto err; - - mutex = malloc(sizeof(pthread_mutex_t)); - if (!mutex) - goto err_mutex_alloc; - - if (pthread_mutex_init(mutex, NULL) != 0) { - printf("Mutex init failed\n"); - goto err_mutex_init; - } - } - - if (!count) - { - rv = vapi_connect(g_vapi_ctx_instance, APP_NAME, NULL, - MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, - async ? VAPI_MODE_NONBLOCKING : VAPI_MODE_BLOCKING, true); - - if (rv != VAPI_OK) - goto err; - - count++; - } - - *vapi_ctx_ret = g_vapi_ctx_instance; - - while (!__sync_bool_compare_and_swap(&lock, 1, 0)); - return rv; - - err_mutex_init: - free(mutex); - err_mutex_alloc: - err: - while (!__sync_bool_compare_and_swap(&lock, 1, 0)); - return VAPI_ENOMEM; -} - -vapi_error_e vapi_disconnect_safe() { - pthread_mutex_lock(mutex); - vapi_error_e rv = VAPI_OK; - pthread_mutex_unlock(mutex); - return rv; -} - -void vapi_lock() { - pthread_mutex_lock(mutex); -} - -void vapi_unlock() { - pthread_mutex_unlock(mutex); -} |