From efaa7522f58c0d8269081f2107e5fb6dc0afe9b9 Mon Sep 17 00:00:00 2001 From: Masoud Hemmatpour Date: Wed, 13 Feb 2019 15:46:22 +0100 Subject: [HICN-5] hicn sysrepo plugin initial Change-Id: I4713465c39abd00fac709cfc908b9384ea75532f Signed-off-by: Masoud Hemmatpour Signed-off-by: Luca Muscariello Signed-off-by: Masoud Hemmatpour Signed-off-by: Luca Muscariello Signed-off-by: Masoud Hemmatpour --- scripts/build-sysrepo.sh | 142 +++ utils/sysrepo-plugin/CMakeLists.txt | 39 + utils/sysrepo-plugin/README.md | 278 ++++++ utils/sysrepo-plugin/cmake/FindHicnPlugin.cmake | 39 + utils/sysrepo-plugin/cmake/FindSysrepo.cmake | 46 + utils/sysrepo-plugin/cmake/FindVPP.cmake | 187 ++++ utils/sysrepo-plugin/cmake/Packager.cmake | 149 +++ utils/sysrepo-plugin/cmake/Packaging.cmake | 31 + utils/sysrepo-plugin/plugin/CMakeLists.txt | 65 ++ utils/sysrepo-plugin/plugin/hicn_plugin.c | 120 +++ utils/sysrepo-plugin/plugin/hicn_plugin.h | 25 + utils/sysrepo-plugin/plugin/hicn_vpp_comm.c | 52 + utils/sysrepo-plugin/plugin/hicn_vpp_comm.h | 110 +++ utils/sysrepo-plugin/plugin/model/hicn_model.c | 1004 ++++++++++++++++++++ utils/sysrepo-plugin/plugin/model/hicn_model.h | 90 ++ utils/sysrepo-plugin/plugin/model/state.h | 68 ++ utils/sysrepo-plugin/plugin/model/tlock.c | 21 + utils/sysrepo-plugin/plugin/model/tlock.h | 31 + .../plugin/yang/hicn_netconf_client.xml | 84 ++ utils/sysrepo-plugin/plugin/yang/model/hicn.yang | 546 +++++++++++ utils/sysrepo-plugin/plugin/yang/startup.xml | 11 + 21 files changed, 3138 insertions(+) create mode 100644 scripts/build-sysrepo.sh create mode 100644 utils/sysrepo-plugin/CMakeLists.txt create mode 100644 utils/sysrepo-plugin/README.md create mode 100644 utils/sysrepo-plugin/cmake/FindHicnPlugin.cmake create mode 100644 utils/sysrepo-plugin/cmake/FindSysrepo.cmake create mode 100644 utils/sysrepo-plugin/cmake/FindVPP.cmake create mode 100644 utils/sysrepo-plugin/cmake/Packager.cmake create mode 100644 utils/sysrepo-plugin/cmake/Packaging.cmake create mode 100644 utils/sysrepo-plugin/plugin/CMakeLists.txt create mode 100644 utils/sysrepo-plugin/plugin/hicn_plugin.c create mode 100644 utils/sysrepo-plugin/plugin/hicn_plugin.h create mode 100644 utils/sysrepo-plugin/plugin/hicn_vpp_comm.c create mode 100644 utils/sysrepo-plugin/plugin/hicn_vpp_comm.h create mode 100644 utils/sysrepo-plugin/plugin/model/hicn_model.c create mode 100644 utils/sysrepo-plugin/plugin/model/hicn_model.h create mode 100644 utils/sysrepo-plugin/plugin/model/state.h create mode 100644 utils/sysrepo-plugin/plugin/model/tlock.c create mode 100644 utils/sysrepo-plugin/plugin/model/tlock.h create mode 100644 utils/sysrepo-plugin/plugin/yang/hicn_netconf_client.xml create mode 100644 utils/sysrepo-plugin/plugin/yang/model/hicn.yang create mode 100644 utils/sysrepo-plugin/plugin/yang/startup.xml diff --git a/scripts/build-sysrepo.sh b/scripts/build-sysrepo.sh new file mode 100644 index 000000000..652322ba1 --- /dev/null +++ b/scripts/build-sysrepo.sh @@ -0,0 +1,142 @@ +# 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. + +#!/bin/bash +set -euxo pipefail + +SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P ) +APT_PATH=`which apt-get` || true +apt_get=${APT_PATH:-"/usr/local/bin/apt-get"} + + +PACKAGECLOUD_RELEASE_REPO_DEB="https://packagecloud.io/install/repositories/fdio/release/script.deb.sh" +PACKAGECLOUD_RELEASE_REPO_RPM="https://packagecloud.io/install/repositories/fdio/release/script.rpm.sh" + +VPP_GIT_REPO="https://git.fd.io/vpp" +VPP_BRANCH="stable/1901" + +VPP_VERSION_DEB="19.01-release" +VPP_VERSION_RPM="19.01-release.x86_64" + +BUILD_TOOLS_UBUNTU="build-essential doxygen" +LIBSSL_LIBEVENT_UBUNTU="libevent-dev libssl-dev" +DEPS_UBUNTU="hicn-plugin vpp-dev=${VPP_VERSION_DEB} vpp-lib=${VPP_VERSION_DEB}" + +# BUILD_TOOLS_GROUP_CENTOS="'Development Tools'" +DEPS_CENTOS="vpp-devel-${VPP_VERSION_RPM} vpp-lib-${VPP_VERSION_RPM} libparc-devel asio-devel centos-release-scl devtoolset-7" +LATEST_EPEL_REPO="http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm" + +install_cmake() { + if ! grep -q "8.8.8.8" /etc/resolv.conf; then + echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf + fi + + cat /etc/resolv.conf + + CMAKE_INSTALL_SCRIPT_URL="https://cmake.org/files/v3.8/cmake-3.8.0-Linux-x86_64.sh" + CMAKE_INSTALL_SCRIPT="/tmp/install_cmake.sh" + curl ${CMAKE_INSTALL_SCRIPT_URL} > ${CMAKE_INSTALL_SCRIPT} + + + sudo mkdir -p /opt/cmake + sudo bash ${CMAKE_INSTALL_SCRIPT} --skip-license --prefix=/opt/cmake + export PATH=/opt/cmake/bin:${PATH} +} + +# Parameters: +# $1 = Distribution id +# $2 = Distribution codename +# +setup_fdio_repo() { + DISTRIB_ID=${1} + + if [ "${DISTRIB_ID}" == "ubuntu" ]; then + curl -s ${PACKAGECLOUD_RELEASE_REPO_DEB} | sudo bash + elif [ "${DISTRIB_ID}" == "centos" ]; then + curl -s ${PACKAGECLOUD_RELEASE_REPO_RPM} | sudo bash + curl ${LATEST_EPEL_REPO} > epel-release-latest-7.noarch.rpm + rpm -ivh epel-release-latest-7.noarch.rpm || true + rm epel-release-latest-7.noarch.rpm + else + echo "Distribution ${DISTRIB_ID} is not supported" + exit -1 + fi +} + + setup() { + # Figure out what system we are running on + if [ -f /etc/os-release ]; then + . /etc/os-release + else + echo "ERROR: System configuration not recognized. Build failed" + exit -1 + fi + + DISTRIB_ID=${ID} + + echo DISTRIBUTION: ${PRETTY_NAME} + echo ARCHITECTURE: $(uname -m) + + install_cmake + setup_fdio_repo ${DISTRIB_ID} + + if [ "${DISTRIB_ID}" == "ubuntu" ]; then + sudo ${apt_get} update || true + fi + + # Install dependencies + if [ ${DISTRIB_ID} == "ubuntu" ]; then + echo ${BUILD_TOOLS_UBUNTU} ${DEPS_UBUNTU} | xargs sudo ${apt_get} install -y --allow-unauthenticated --no-install-recommends + curl -OL https://github.com/muscariello/build-scripts/raw/master/deb/libyang_0.16-r2_amd64.deb + curl -OL https://github.com/muscariello/build-scripts/raw/master/deb/sysrepo_0.7.7_amd64.deb + sudo ${apt_get} clean && sudo ${apt_get} update + sudo ${apt_get} install -y --allow-unauthenticated --no-install-recommends ./libyang_0.16-r2_amd64.deb ./sysrepo_0.7.7_amd64.deb + elif [ ${DISTRIB_ID} == "centos" ]; then + echo "not supported yet" + fi + + # do nothing but check compiler version + c++ --version +} + +# Parameters: +# $1 = Package name +# +build_package() { + setup + + echo "*******************************************************************" + echo "********************* STARTING PACKAGE BUILD **********************" + echo "*******************************************************************" + + mkdir -p build && pushd build + + rm -rf * +# cp ${SCRIPT_PATH}/../cmake/Modules/Packager.cmake ${SCRIPT_PATH}/../utils/sysrepo-plugin/cmake/ + cmake -DCMAKE_INSTALL_PREFIX=/usr ${SCRIPT_PATH}/../utils/sysrepo-plugin/ \ + -DSR_PLUGINS_DIR=/usr/lib/x86_64-linux-gnu/sysrepo/plugins + make package + + find . -not -name '*.deb' -not -name '*.rpm' -print0 | xargs -0 rm -rf -- || true + rm *Unspecified* || true + + popd + + echo "*******************************************************************" + echo "***************** BUILD COMPLETED SUCCESSFULLY *******************" + echo "*******************************************************************" +} + +build_package + +exit 0 diff --git a/utils/sysrepo-plugin/CMakeLists.txt b/utils/sysrepo-plugin/CMakeLists.txt new file mode 100644 index 000000000..c062c010c --- /dev/null +++ b/utils/sysrepo-plugin/CMakeLists.txt @@ -0,0 +1,39 @@ +# +# Copyright (c) 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. +# + +cmake_minimum_required(VERSION 2.8) +project(hicn_sysrepo_plugin) + +include(GNUInstallDirs) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +# set default build type if not specified by user +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE debug) +endif() +string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) + +# set compiler options +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=gnu99") +set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2") +set(CMAKE_C_FLAGS_DEBUG "-g -O0") + +# add subdirectories +add_subdirectory(plugin) +include(Packaging) +include(Packager) +make_packages() diff --git a/utils/sysrepo-plugin/README.md b/utils/sysrepo-plugin/README.md new file mode 100644 index 000000000..87394e975 --- /dev/null +++ b/utils/sysrepo-plugin/README.md @@ -0,0 +1,278 @@ +# hICN plugin for sysrepo (2019) + +This plugin serves as a data management agent that runs on the same host as a +VPP instance. It provides yang models via NETCONF to allow the management of +hicn-plugin that runs in VPP instance from out-of-box. + +## Software Requirement + +- VPP + +- hicn-plugin + +- sysrepo + +## hICN yang model + +You can install the yang model using the following bash script: + +EXIT_CODE=0 +command -v sysrepoctl > /dev/null +if [ $? != 0 ]; then + echo "Could not find command \"sysrepoctl\"." + exit ${EXIT_CODE} +else +sysrepoctl --install --yang=path_to_hicn_yang_model +fi + +hicn.yang can be found under `plugin/yang/model/hicn.yang`. It consists of two +container nodes: *hicn-conf* and *hicn-state*. One is used to hold the +configuration data (i.e., *hicn-conf*) and one for providing the state +data (i.e., *hicn-state*). The *hicn-conf* has one node, *params*, which +contains the hICN configuration parameters. Controler can configure these parameters +through the edit-config RPC call. This node can be used to enable and to initialize +the hicn-plugin in VPP instance. Hicn-state container is used to provide the state +data to the controler. It consists of *state*, *strategy*, *strategies*, *route*, +and *face-ip-params* nodes with the coresponding leaves. In hicn model variety of +RPCs are provided to allow controler to communicate with hicn-plugin as well as +update the state data in *hicn-state*. Here you can find the schematic view of +the described hicn model: + + +module: hicn + +--rw hicn-conf + | +--rw params + | +--rw enable_disable? boolean + | +--rw pit_max_size? int32 + | +--rw cs_max_size? int32 + | +--rw cs_reserved_app? int32 + | +--rw pit_dflt_lifetime_sec? float + | +--rw pit_max_lifetime_sec? float + | +--rw pit_min_lifetime_sec? float + +--ro hicn-state + +--ro states + | +--ro pkts_processed? uint64 + | +--ro pkts_interest_count? uint64 + | +--ro pkts_data_count? uint64 + | +--ro pkts_from_cache_count? uint64 + | +--ro pkts_no_pit_count? uint64 + | +--ro pit_expired_count? uint64 + | +--ro cs_expired_count? uint64 + | +--ro cs_lru_count? uint64 + | +--ro pkts_drop_no_buf? uint64 + | +--ro interests_aggregated? uint64 + | +--ro interests_retx? uint64 + | +--ro interests_hash_collision? uint64 + | +--ro pit_entries_count? uint64 + | +--ro cs_entries_count? uint64 + | +--ro cs_entries_ntw_count? uint64 + +--ro strategy + | +--ro description? uint8 + +--ro route + | +--ro faceids? uint16 + | +--ro strategy_id? uint32 + +--ro strategies + | +--ro n_strategies? uint8 + | +--ro strategy_id? uint32 + +--ro face-ip-params + +--ro nh_addr? uint64 + +--ro swif? uint32 + +--ro flags? uint32 + + +To setup the startup configuration you can use the following script: + +EXIT_CODE=0 +command -v sysrepocfg > /dev/null +if [ $? != 0 ]; then + echo "Could not find command \"sysrepocfg\"." + exit ${EXIT_CODE} +else +sysrepocfg -d startup -i startup.xml -f xml hicn +fi + + +*startup.xml* is placed under `plugin/yang/startup.xml`. Here you can find the content: + + + + false + -1 + -1 + -1 + -1 + -1 + -1 + + + +As can be seen, it contains the params leaves in *hicn-conf* node which is +used as the startup configuration when the yang model is loaded to the sysrepo. +This configuration can be changed through the controler by subscribing which +changes the target to the running state. + +hicn model provides a list of RPCs which allows controler to communicate directly +with the hicn-plugin. This RPCs may also cause the modification in state data. +Here you can find the list of RPCs: + + rpcs: + +---x node-params-set + | +---w input + | +---w enable_disable? boolean + | +---w pit_max_size? int32 + | +---w cs_max_size? int32 + | +---w cs_reserved_app? int32 + | +---w pit_dflt_lifetime_sec? float + | +---w pit_max_lifetime_sec? float + | +---w pit_min_lifetime_sec? float + +---x node-params-get + +---x node-stat-get + +---x strategy-get + | +---w input + | +---w strategy_id? uint32 + +---x strategies-get + +---x route-get + | +---w input + | +---w prefix0? uint64 + | +---w prefix1? uint64 + | +---w len? uint8 + +---x route-del + | +---w input + | +---w prefix0? uint64 + | +---w prefix1? uint64 + | +---w len? uint8 + +---x route-nhops-add + | +---w input + | +---w prefix0? uint64 + | +---w prefix1? uint64 + | +---w len? uint8 + | +---w face_ids0? uint32 + | +---w face_ids1? uint32 + | +---w face_ids2? uint32 + | +---w face_ids3? uint32 + | +---w face_ids4? uint32 + | +---w face_ids5? uint32 + | +---w face_ids6? uint32 + | +---w n_faces? uint8 + +---x route-nhops-del + | +---w input + | +---w prefix0? uint64 + | +---w prefix1? uint64 + | +---w len? uint8 + | +---w faceid? uint16 + +---x face-ip-params-get + | +---w input + | +---w faceid? uint16 + +---x face-ip-add + | +---w input + | +---w nh_addr0? uint64 + | +---w nh_addr1? uint64 + | +---w swif? uint32 + +---x face-ip-del + | +---w input + | +---w faceid? uint16 + +---x punting-add + | +---w input + | +---w prefix0? uint64 + | +---w prefix1? uint64 + | +---w len? uint8 + | +---w swif? uint32 + +---x punting-del + +---w input + +---w prefix0? uint64 + +---w prefix1? uint64 + +---w len? uint8 + +---w swif? uint32 + + +In order to run different RPCs from controler you can use the examples in the +*hicn_netconf_client.xml* under `plugin/yang/model`. Here you can find the content: + + + true + -1 + -1 + -1 + -1 + -1 + -1 + + + + + + + + + 0 + + + + + + + 10 + 20 + 30 + + + + 10 + 20 + 30 + + + + 10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90 + 100 + 110 + + + + 10 + 20 + 30 + 40 + + + + + 10 + + + + 10 + 20 + 30 + + + + 0 + + + + 10 + 20 + 30 + 40 + + + + + 10 + 20 + 30 + 40 + + +## Release note + +The current version is compatible with the 19.01 VPP stable and sysrepo 0.7.7. \ No newline at end of file diff --git a/utils/sysrepo-plugin/cmake/FindHicnPlugin.cmake b/utils/sysrepo-plugin/cmake/FindHicnPlugin.cmake new file mode 100644 index 000000000..f50ed736e --- /dev/null +++ b/utils/sysrepo-plugin/cmake/FindHicnPlugin.cmake @@ -0,0 +1,39 @@ +#sed 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. + +set(HICNPLUGIN_SEARCH_PATH_LIST + ${HICNPLUGIN_HOME} + $ENV{HICNPLUGIN_HOME} + /usr/local + /opt + /usr +) + +find_path(HICNPLUGIN_INCLUDE_DIR vapi/hicn.api.vapi.h + HINTS ${HICNPLUGIN_SEARCH_PATH_LIST} + PATH_SUFFIXES include + DOC "Find the hicn plugin includes" +) + +find_library(HICNPLUGIN_LIBRARY NAMES vpp_plugins/hicn_plugin.so + HINTS ${HICNPLUGIN_SEARCH_PATH_LIST} + PATH_SUFFIXES lib + DOC "Find the hicn plugin plugin" +) + +set(HICNPLUGIN_LIBRARIES ${HICNPLUGIN_LIBRARY}) +set(HICNPLUGIN_INCLUDE_DIRS ${HICNPLUGIN_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(HicnPlugin DEFAULT_MSG HICNPLUGIN_LIBRARIES HICNPLUGIN_INCLUDE_DIRS) + +mark_as_advanced(HICNPLUGIN_LIBRARY HICNPLUGIN_INCLUDE_DIR) \ No newline at end of file diff --git a/utils/sysrepo-plugin/cmake/FindSysrepo.cmake b/utils/sysrepo-plugin/cmake/FindSysrepo.cmake new file mode 100644 index 000000000..4228ef93a --- /dev/null +++ b/utils/sysrepo-plugin/cmake/FindSysrepo.cmake @@ -0,0 +1,46 @@ +# Copyright (c) 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. + +set(SYSREPO_SEARCH_PATH_LIST + ${SYSREPO_HOME} + $ENV{SYSREPO_HOME} + /usr/local + /opt + /usr +) + +find_path(SYSREPO_INCLUDE_DIR sysrepo/values.h + HINTS ${SYSREPO_SEARCH_PATH_LIST} + PATH_SUFFIXES include + DOC "Find the sysrepo includes" +) + +find_path(SYSREPO_INCLUDE_MAIN_DIR sysrepo.h + HINTS ${SYSREPO_SEARCH_PATH_LIST} + PATH_SUFFIXES include + DOC "Find the sysrepo includes" +) + +find_library(SYSREPO_LIBRARY NAMES libsysrepo.so + HINTS ${SYSREPO_SEARCH_PATH_LIST} + PATH_SUFFIXES lib + DOC "Find the sysrepo library" +) + +set(SYSREPO_LIBRARIES ${SYSREPO_LIBRARY}) +set(SYSREPO_INCLUDE_DIRS ${SYSREPO_INCLUDE_DIR} ${SYSREPO_INCLUDE_MAIN_DIR}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Sysrepo DEFAULT_MSG SYSREPO_LIBRARIES SYSREPO_INCLUDE_DIRS) + +mark_as_advanced(SYSREPO_LIBRARY SYSREPO_INCLUDE_DIR SYSREPO_INCLUDE_MAIN_DIR) \ No newline at end of file diff --git a/utils/sysrepo-plugin/cmake/FindVPP.cmake b/utils/sysrepo-plugin/cmake/FindVPP.cmake new file mode 100644 index 000000000..64534d3aa --- /dev/null +++ b/utils/sysrepo-plugin/cmake/FindVPP.cmake @@ -0,0 +1,187 @@ +# Copyright (c) 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. + +if (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) + # in cache already + set(VPP_FOUND TRUE) +else (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) + + set(VPP_INCLUDE_PATH + /usr/include + /usr/local/include + /opt/local/include + /sw/include + ) + + set(VPP_LIBRARY_PATH + /usr/lib + /usr/lib64 + /usr/local/lib + /usr/local/lib64 + /opt/local/lib + /sw/lib + ) + + find_path(VNET_INCLUDE_DIR + NAMES + vnet/vnet.h + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_path(VLIB_API_INCLUDE_DIR + NAMES + vlibapi/api.h + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_path(VLIBMEMORY_INCLUDE_DIR + NAMES + vlibmemory/api.h + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_path(VPP_MSG_INCLUDE_DIR + NAMES + vpp/api/vpe_msg_enum.h + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_path(VPP_ALL_INCLUDE_DIR + NAMES + vpp/api/vpe_all_api_h.h + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_path(VAPI_INCLUDE_DIR + NAMES + vapi/interface.api.vapi.h + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + + find_library(VLIBMEMORYCLIENT_LIBRARY + NAMES + vlibmemoryclient + libvlibmemoryclient + PATHS + ${VPP_LIBARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + find_library(SVM_LIBRARY + NAMES + svm + libsvm + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + find_library(VPPINFRA_LIBRARY + NAMES + vppinfra + libvppinfra + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + find_library(VLIB_LIBRARY + NAMES + vlib + libvlib + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + find_library(VATPLUGIN_LIBRARY + NAMES + vatplugin + libvatplugin + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + find_library(VAPI_LIBRARY + NAMES + vapiclient + libvapiclient + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + find_library(VOM_LIBRARY + NAMES + vom + libvom + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + + if (VPP_INCLUDE_DIR AND VPP_LIBRARY) + set(VPP_FOUND TRUE) + else (VPP_INCLUDE_DIR AND VPP_LIBRARY) + set(VPP_FOUND FALSE) + endif (VPP_INCLUDE_DIR AND VPP_LIBRARY) + + set(VPP_INCLUDE_DIRS + ${VNET_INCLUDE_DIR} + ${VLIB_API_INCLUDE_DIR} + ${VLIB_MEMORY_INCLUDE_DIR} + ${VPP_MSG_INCLUDE_DIR} + ${VPP_ALL_INCLUDE_DIR} + ${VAPI_INCLUDE_DIR} + ) + + set(VPP_LIBRARIES + ${VLIBMEMORYCLIENT_LIBRARY} + ${SVM_LIBRARY} + ${VPPINFRA_LIBRARY} + ${VLIB_LIBRARY} + ${VATPLUGIN_LIBRARY} + ${VAPI_LIBRARY} + ${VOM_LIBRARY} + ) + + # show the VPP_INCLUDE_DIRS and VPP_LIBRARIES variables only in the advanced view + mark_as_advanced(VPP_INCLUDE_DIRS VPP_LIBRARIES) + +endif (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) \ No newline at end of file diff --git a/utils/sysrepo-plugin/cmake/Packager.cmake b/utils/sysrepo-plugin/cmake/Packager.cmake new file mode 100644 index 000000000..b19145025 --- /dev/null +++ b/utils/sysrepo-plugin/cmake/Packager.cmake @@ -0,0 +1,149 @@ +# 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. + +############# +# RPM/DEB/TGZ Packaging utils +# + +set(CONTACT "hicn-dev@lists.fd.io" CACHE STRING "Contact") +set(PACKAGE_MAINTAINER "ICN Team" CACHE STRING "Maintainer") +set(PACKAGE_VENDOR "fd.io" CACHE STRING "Vendor") + +# macro(set) + +macro(make_packages) + if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # parse /etc/os-release + file(READ "/etc/os-release" os_version) + string(REPLACE "\n" ";" os_version ${os_version}) + foreach(_ver ${os_version}) + string(REPLACE "=" ";" _ver ${_ver}) + list(GET _ver 0 _name) + list(GET _ver 1 _value) + set(OS_${_name} ${_value}) + endforeach() + + # extract version from git + execute_process( + COMMAND git describe --long --match v* + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE VER + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (NOT VER) + set(VER "v1.0-1-gcafe") + endif() + + string(REGEX REPLACE "v(.*)-([0-9]+)-(g[0-9a-f]+)" "\\1;\\2;\\3" VER ${VER}) + list(GET VER 0 tag) + string(REPLACE "-" "~" tag ${tag}) + list(GET VER 1 commit_num) + list(GET VER 2 commit_name) + + if (NOT DEFINED ENV{BUILD_NUMBER}) + set(bld "b1") + else() + set(bld "b$ENV{BUILD_NUMBER}") + endif() + + message("Build number is: ${bld}") + + #define DEB and RPM version numbers + if(${commit_num} EQUAL 0) + set(deb_ver "${tag}") + set(rpm_ver "${tag}") + else() + set(deb_ver "${tag}-${commit_num}-release") + set(rpm_ver "${tag}-${commit_num}-release") + endif() + + get_cmake_property(components COMPONENTS) + + if(OS_ID_LIKE MATCHES "debian") + set(CPACK_GENERATOR "DEB") + set(type "DEBIAN") + + execute_process( + COMMAND dpkg --print-architecture + OUTPUT_VARIABLE arch + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + set(CPACK_PACKAGE_VERSION "${deb_ver}") + foreach(lc ${components}) + if (${lc} MATCHES ".*Unspecified.*") + continue() + endif() + + string(TOUPPER ${lc} uc) + set(CPACK_${type}_${uc}_FILE_NAME "${lc}_${deb_ver}_${arch}.deb") + + set(DEB_DEPS) + if (NOT ${${lc}_DEB_DEPENDENCIES} STREQUAL "") + string(REPLACE "stable_version" ${tag} DEB_DEPS ${${lc}_DEB_DEPENDENCIES}) + endif() + + set(CPACK_${type}_${uc}_PACKAGE_DEPENDS "${DEB_DEPS}") + set(CPACK_${type}_${uc}_PACKAGE_NAME "${lc}") + set(CPACK_COMPONENT_${uc}_DESCRIPTION "${${lc}_DESCRIPTION}") + endforeach() + elseif(OS_ID_LIKE MATCHES "rhel") + set(CPACK_GENERATOR "RPM") + set(type "RPM") + + execute_process( + COMMAND uname -m + OUTPUT_VARIABLE arch + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + set(CPACK_PACKAGE_VERSION "${rpm_ver}") + foreach(lc ${components}) + if (${lc} MATCHES ".*Unspecified.*") + continue() + endif() + + string(TOUPPER ${lc} uc) + set(CPACK_${type}_${uc}_DESCRIPTION "${${lc}_DESCRIPTION}") + + set(RPM_DEPS) + if (NOT ${${lc}_DEB_DEPENDENCIES} STREQUAL "") + string(REPLACE "stable_version" ${tag} RPM_DEPS ${${lc}_RPM_DEPENDENCIES}) + endif() + + set(CPACK_${type}_${uc}_PACKAGE_REQUIRES "${RPM_DEPS}") + + if(${lc} MATCHES ".*-dev") + set(package_name ${lc}el) + else() + set(package_name ${lc}) + endif() + + set(CPACK_RPM_${uc}_PACKAGE_NAME "${package_name}") + set(CPACK_${type}_${uc}_FILE_NAME "${package_name}-${rpm_ver}.${arch}.rpm") + endforeach() + endif() + + if(CPACK_GENERATOR) + set(CPACK_PACKAGE_NAME ${ARG_NAME}) + set(CPACK_STRIP_FILES OFF) + set(CPACK_PACKAGE_VENDOR "${PACKAGE_VENDOR}") + set(CPACK_COMPONENTS_IGNORE_GROUPS 1) + set(CPACK_${CPACK_GENERATOR}_COMPONENT_INSTALL ON) + set(CPACK_${type}_PACKAGE_MAINTAINER "HICN Team") + set(CPACK_${type}_PACKAGE_RELEASE 1) + include(CPack) + endif() + endif() +endmacro() diff --git a/utils/sysrepo-plugin/cmake/Packaging.cmake b/utils/sysrepo-plugin/cmake/Packaging.cmake new file mode 100644 index 000000000..f5e8426fb --- /dev/null +++ b/utils/sysrepo-plugin/cmake/Packaging.cmake @@ -0,0 +1,31 @@ +# 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_sysrepo_plugin_DESCRIPTION + "A Plugin to enable hICN VPP in sysrepo." + CACHE STRING "Description for deb/rpm package." +) + +set(hicn_sysrepo_plugin_DEB_DEPENDENCIES + "hicn-plugin (= stable_version-release), vpp (= stable_version-release), vpp-plugins (= stable_version-release)" + CACHE STRING "Dependencies for deb/rpm package." +) + +set(hicn_sysrepo_plugin_RPM_DEPENDENCIES +"hicn-plugin (= stable_version-release), vpp (= stable_version-release), vpp-plugins (= stable_version-release)" +CACHE STRING "Dependencies for deb/rpm package." +) diff --git a/utils/sysrepo-plugin/plugin/CMakeLists.txt b/utils/sysrepo-plugin/plugin/CMakeLists.txt new file mode 100644 index 000000000..6641dc705 --- /dev/null +++ b/utils/sysrepo-plugin/plugin/CMakeLists.txt @@ -0,0 +1,65 @@ +# +# Copyright (c) 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. +# + +# set compiler options +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=gnu99") +set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2") +set(CMAKE_C_FLAGS_DEBUG "-g -O0") +set (CMAKE_INSTALL_LIBDIR "/usr/lib") + +cmake_minimum_required(VERSION 2.8) +project(sysrepo-vpp-plugins) + +# Cmake find modules +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake") + +find_package(VPP) +find_package(PkgConfig) +find_package(HicnPlugin) +find_package(Sysrepo) + +#pkg_check_modules(SYSREPO libsysrepo) + +# get sysrepo plugins directory from pkgconfig +if (NOT SR_PLUGINS_DIR) + if (PKG_CONFIG_FOUND) + execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} "--variable=SR_PLUGINS_DIR" "libsysrepo" OUTPUT_VARIABLE SR_PLUGINS_DIR) + string(STRIP ${SR_PLUGINS_DIR} SR_PLUGINS_DIR) + endif() +endif() +if (NOT SR_PLUGINS_DIR) + message(FATAL_ERROR "Cannot get sysrepo plugins directory due to missing pkg-config, set SR_PLUGINS_DIR manually.") +endif() + +#target_include_directories(vpinc PUBLIC ${VPP_INCLUDE_DIRS} ${HICNPLUGIN_INCLUDE_DIRS}) +#target_link_libraries(vplib ${VPP_LIBRARIES} ${HICNPLUGIN_LIBRARIES}) + +# plugins sources +set(PLUGINS_SOURCES + hicn_plugin.c + model/hicn_model.c + model/tlock.c + hicn_vpp_comm.h + hicn_vpp_comm.c +) + +# build the source code into shared library +add_library(hicn SHARED ${PLUGINS_SOURCES}) +target_include_directories(hicn PUBLIC ${VPP_INCLUDE_DIRS} ${HICNPLUGIN_INCLUDE_DIRS}) +target_link_libraries(hicn ${SYSREPO_LIBRARIES} ${VPP_LIBRARIES} ${HICNPLUGIN_LIBRARIES}) + +# install the plugin into plugins dir +install(TARGETS hicn DESTINATION ${SR_PLUGINS_DIR} COMPONENT hicn_sysrepo_plugin) \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/hicn_plugin.c b/utils/sysrepo-plugin/plugin/hicn_plugin.c new file mode 100644 index 000000000..73991af99 --- /dev/null +++ b/utils/sysrepo-plugin/plugin/hicn_plugin.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 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. + */ +#include +#include +#include +#include +#include + +#include "hicn_plugin.h" +#include "model/hicn_model.h" + + + +sr_subscription_ctx_t *subscription = NULL; +volatile int exit_application = 0; + +int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx) { + HICN_INVOKE_BEGIN; + sr_subscription_ctx_t *subscription = NULL; + int rc = SR_ERR_OK; + rc = hicn_connect_vpp(); + if (SR_ERR_OK != rc) { + HICN_LOG_ERR("vpp connect error , with return %d.", rc); + return SR_ERR_INTERNAL; + } + + // HICN interface + hicn_subscribe_events(session, &subscription); + + /* set subscription as our private context */ + *private_ctx = subscription; + HICN_INVOKE_END; + return SR_ERR_OK; +} + +void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx) { + HICN_INVOKE_BEGIN; + + /* subscription was set as our private context */ + sr_unsubscribe(session, private_ctx); + HICN_LOG_DBG_MSG("hicn pligin unload plugin ok."); + hicn_disconnect_vpp(); + HICN_LOG_DBG_MSG("hicn plugin disconnect vpp ok."); + HICN_INVOKE_END; +} + +static void sigint_handler(int signum) { exit_application = 1; } +int subscribe_all_module_events(sr_session_ctx_t *session) { + sr_plugin_init_cb(session, (void **)&subscription); + return 0; +} + +int main(int argc, char **argv) { + sr_conn_ctx_t *connection = NULL; + sr_session_ctx_t *session = NULL; + int rc = SR_ERR_OK; + + /* connect to vpp */ + rc = hicn_connect_vpp(); + if (-1 == rc) { + fprintf(stderr, "vpp connect error"); + return -1; + } + + /* connect to sysrepo */ + rc = sr_connect("cpe_application", SR_CONN_DEFAULT, &connection); + if (SR_ERR_OK != rc) { + fprintf(stderr, "Error by sr_connect: %s\n", sr_strerror(rc)); + goto cleanup; + } + + /* start session */ + rc = sr_session_start(connection, SR_DS_STARTUP, SR_SESS_DEFAULT, &session); + if (SR_ERR_OK != rc) { + fprintf(stderr, "Error by sr_session_start: %s\n", sr_strerror(rc)); + goto cleanup; + } + + /* subscribe all module events */ + rc = subscribe_all_module_events(session); + if (SR_ERR_OK != rc) { + fprintf(stderr, "Error by subscribe module events: %s\n", sr_strerror(rc)); + goto cleanup; + } + + /* loop until ctrl-c is pressed / SIGINT is received */ + signal(SIGINT, sigint_handler); + signal(SIGPIPE, SIG_IGN); + + while (!exit_application) { + sleep(2); + } + + printf("Application exit requested, exiting.\n"); + +cleanup: + if (NULL != subscription) { + sr_unsubscribe(session, subscription); + } + if (NULL != session) { + sr_session_stop(session); + } + if (NULL != connection) { + sr_disconnect(connection); + } + hicn_disconnect_vpp(); + return rc; +} \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/hicn_plugin.h b/utils/sysrepo-plugin/plugin/hicn_plugin.h new file mode 100644 index 000000000..4e48c8c29 --- /dev/null +++ b/utils/sysrepo-plugin/plugin/hicn_plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 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. + */ + +#ifndef __HICN_PLUGIN_H__ +#define __HICN_PLUGIN_H__ + +#include "hicn_vpp_comm.h" + +// functions that sysrepo-plugin need +int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx); +void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx); + +#endif //__HICN_PLUGIN_H__ \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/hicn_vpp_comm.c b/utils/sysrepo-plugin/plugin/hicn_vpp_comm.c new file mode 100644 index 000000000..9d5518b4f --- /dev/null +++ b/utils/sysrepo-plugin/plugin/hicn_vpp_comm.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 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. + */ +#include "hicn_vpp_comm.h" + + + + +#define APP_NAME "hicn_plugin" +#define MAX_OUTSTANDING_REQUESTS 4 +#define RESPONSE_QUEUE_SIZE 2 +vapi_ctx_t g_vapi_ctx_instance = NULL; + +int hicn_connect_vpp() { + HICN_INVOKE_BEGIN; + if (g_vapi_ctx_instance == NULL) { + vapi_error_e rv = vapi_ctx_alloc(&g_vapi_ctx_instance); + rv = vapi_connect(g_vapi_ctx_instance, APP_NAME, NULL, + MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, + VAPI_MODE_BLOCKING, true); + if (rv != VAPI_OK) { + HICN_LOG_ERR("*connect %s faild,with return %d", APP_NAME, rv); + vapi_ctx_free(g_vapi_ctx_instance); + return -1; + } + HICN_LOG_DBG("*connected %s ok", APP_NAME); + } else { + HICN_LOG_DBG("connection %s keeping", APP_NAME); + } + HICN_INVOKE_END; + return 0; +} + +int hicn_disconnect_vpp() { + if (NULL != g_vapi_ctx_instance) { + vapi_disconnect(g_vapi_ctx_instance); + vapi_ctx_free(g_vapi_ctx_instance); + g_vapi_ctx_instance = NULL; + } + return 0; +} \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/hicn_vpp_comm.h b/utils/sysrepo-plugin/plugin/hicn_vpp_comm.h new file mode 100644 index 000000000..bc8937f02 --- /dev/null +++ b/utils/sysrepo-plugin/plugin/hicn_vpp_comm.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 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. + */ + +#ifndef __HICN_VPP_COMMM_H__ +#define __HICN_VPP_COMMM_H__ +#include +#include //for HICN_LOG_DBG +#include +#include + +#ifndef HICN_THIS_FUNC +#ifdef __FUNCTION__ +#define HICN_THIS_FUNC __FUNCTION__ +#else +#define HICN_THIS_FUNC __func__ +#endif +#endif + +#ifndef _NOLOG +#define HICN_LOG_DBG SRP_LOG_DBG +#define HICN_LOG_ERR SRP_LOG_ERR +#define HICN_LOG_DBG_MSG SRP_LOG_DBG_MSG +#define HICN_LOG_ERR_MSG SRP_LOG_ERR_MSG +#else +#define HICN_LOG_DBG // printf +#define HICN_LOG_DBG // SRP_LOG_DBG +#define HICN_LOG_ERR // SRP_LOG_ERR +#define HICN_LOG_DBG_MSG // SRP_LOG_DBG_MSG +#define HICN_LOG_ERR_MSG // SRP_LOG_ERR_MSG +#endif + +//DEFINE_VAPI_MSG_IDS_VPE_API_JSON + + + +//Here it is the definition + + +#define HICN_INVOKE_BEGIN HICN_LOG_DBG("inovke %s bein.", HICN_THIS_FUNC); +#define HICN_INVOKE_END \ + HICN_LOG_DBG("inovke %s end,with return OK.", HICN_THIS_FUNC); +#define HICN_INVOKE_ENDX(...) \ + HICN_LOG_DBG("inovke %s end,with %s.", HICN_THIS_FUNC, ##__VA_ARGS__) + +#define ARG_CHECK(retval, arg) \ + do { \ + if (NULL == (arg)) { \ + HICN_LOG_ERR_MSG(#arg ":NULL pointer passed."); \ + return (retval); \ + } \ + } while (0) + +#define ARG_CHECK5(retval, arg1, arg2, arg3, arg4, arg5) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2); \ + ARG_CHECK(retval, arg3); \ + ARG_CHECK(retval, arg4); \ + ARG_CHECK(retval, arg5) + + + +/** + * when use tihs must fist DEFINE_VAPI_MSG_IDS_VXLAN_API_JSON + */ +#define HICN_VPP_VAPI_RECV \ + do { \ + size_t size; \ + int recv_vapimsgid = -1; \ + vapi_recv(g_vapi_ctx_instance, (void *)&resp, &size, 0, 0); \ + recv_vapimsgid = vapi_lookup_vapi_msg_id_t( \ + g_vapi_ctx_instance, ntohs(resp->header._vl_msg_id)); \ + if (recv_vapimsgid <= vapi_msg_id_get_next_index_reply || \ + recv_vapimsgid >= vapi_get_message_count()) { \ + HICN_LOG_DBG("***recv error msgid[%d] not in [0-%d) ,try again!***\n", \ + recv_vapimsgid, vapi_get_message_count()); \ + } else { \ + HICN_LOG_DBG("recv msgid [%d]\n", recv_vapimsgid); \ + break; \ + } \ + } while (1); + +#define HICN_REGISTER_RPC_EVT_HANDLER(rpc_evt_handle) \ + do { \ + sr_error_t rc = rpc_evt_handle(session, &subscription); \ + if (SR_ERR_OK != rc) { \ + HICN_LOG_ERR("load plugin failed: %s", sr_strerror(rc)); \ + sr_unsubscribe(session, subscription); \ + HICN_INVOKE_ENDX(sr_strerror(rc)); \ + return rc; \ + } \ + } while (0); + + +int hicn_connect_vpp(); +int hicn_disconnect_vpp(); +extern vapi_ctx_t g_vapi_ctx_instance; +DEFINE_VAPI_MSG_IDS_HICN_API_JSON; +#endif //__HICN_VPP_COMMM_H__ \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/model/hicn_model.c b/utils/sysrepo-plugin/plugin/model/hicn_model.c new file mode 100644 index 000000000..790fb4cbf --- /dev/null +++ b/utils/sysrepo-plugin/plugin/model/hicn_model.c @@ -0,0 +1,1004 @@ +/* + * Copyright (c) 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. + */ +#include +#include +#include + +/* Hicn headers */ + +#include +#include "../hicn_plugin.h" +#include "../hicn_vpp_comm.h" +#include "hicn_model.h" +#include "state.h" +#include "tlock.h" + + +vapi_ctx_t g_vapi_ctx_instance; + +// Shared local variables between state and RPCs + +volatile hicn_state_t * hicn_state = NULL; +volatile hicn_strategy_t * hicn_strategy = NULL; +volatile hicn_strategies_t * hicn_strategies =NULL; +volatile hicn_route_t * hicn_route = NULL; +volatile hicn_face_ip_params_t * hicn_face_ip_params = NULL; + +static int init_buffer(void){ + + hicn_state = memalign(MEM_ALIGN, sizeof(hicn_state_t) ); + memset((hicn_state_t *)hicn_state, 0 , sizeof(hicn_state_t) ); + hicn_strategy = memalign(MEM_ALIGN, sizeof(hicn_strategy_t) ); + memset((hicn_strategy_t *) hicn_strategy, 0 , sizeof(hicn_strategy_t) ); + hicn_strategies = memalign(MEM_ALIGN, sizeof(hicn_strategies_t) ); + memset((hicn_strategies_t *) hicn_strategies, 0 , sizeof(hicn_strategies_t) ); + hicn_route = memalign(MEM_ALIGN, sizeof(hicn_route_t) ); + memset((hicn_route_t *) hicn_route, 0 , sizeof(hicn_route_t) ); + hicn_face_ip_params = memalign(MEM_ALIGN, sizeof(hicn_face_ip_params_t) ); + memset((hicn_face_ip_params_t *) hicn_face_ip_params, 0 , sizeof(hicn_face_ip_params_t) ); + int retval=-1; + ARG_CHECK5(retval, hicn_state, hicn_strategy, hicn_strategies, hicn_route, hicn_face_ip_params); + retval=0; + return retval; +} + + static inline void state_update(sr_val_t * vals ){ + sr_val_set_xpath(&vals[0], "/hicn:hicn-state/states/pkts_processed"); + vals[0].type = SR_UINT64_T; + vals[0].data.uint64_val = hicn_state->pkts_processed; + + sr_val_set_xpath(&vals[1], "/hicn:hicn-state/states/pkts_interest_count"); + vals[1].type = SR_UINT64_T; + vals[1].data.uint64_val = hicn_state->pkts_interest_count; + + sr_val_set_xpath(&vals[2], "/hicn:hicn-state/states/pkts_data_count"); + vals[2].type = SR_UINT64_T; + vals[2].data.uint64_val = hicn_state->pkts_data_count; + + sr_val_set_xpath(&vals[3], "/hicn:hicn-state/states/pkts_from_cache_count"); + vals[3].type = SR_UINT64_T; + vals[3].data.uint64_val = hicn_state->pkts_from_cache_count; + + sr_val_set_xpath(&vals[4], "/hicn:hicn-state/states/pkts_no_pit_count"); + vals[4].type = SR_UINT64_T; + vals[4].data.uint64_val = hicn_state->pkts_no_pit_count; + + sr_val_set_xpath(&vals[5], "/hicn:hicn-state/states/pit_expired_count"); + vals[5].type = SR_UINT64_T; + vals[5].data.uint64_val = hicn_state->pit_expired_count; + + sr_val_set_xpath(&vals[6], "/hicn:hicn-state/states/cs_expired_count"); + vals[6].type = SR_UINT64_T; + vals[6].data.uint64_val = hicn_state->cs_expired_count; + + sr_val_set_xpath(&vals[7], "/hicn:hicn-state/states/cs_lru_count"); + vals[7].type = SR_UINT64_T; + vals[7].data.uint64_val = hicn_state->cs_lru_count; + + sr_val_set_xpath(&vals[8], "/hicn:hicn-state/states/pkts_drop_no_buf"); + vals[8].type = SR_UINT64_T; + vals[8].data.uint64_val = hicn_state->pkts_drop_no_buf; + + sr_val_set_xpath(&vals[9], "/hicn:hicn-state/states/interests_aggregated"); + vals[9].type = SR_UINT64_T; + vals[9].data.uint64_val = hicn_state->interests_aggregated; + + sr_val_set_xpath(&vals[10], "/hicn:hicn-state/states/interests_retx"); + vals[10].type = SR_UINT64_T; + vals[10].data.uint64_val = hicn_state->interests_retx; + + sr_val_set_xpath(&vals[11], + "/hicn:hicn-state/states/interests_hash_collision"); + vals[11].type = SR_UINT64_T; + vals[11].data.uint64_val = hicn_state->interests_hash_collision; + + sr_val_set_xpath(&vals[12], "/hicn:hicn-state/states/pit_entries_count"); + vals[12].type = SR_UINT64_T; + vals[12].data.uint64_val = hicn_state->pit_entries_count; + + sr_val_set_xpath(&vals[13], "/hicn:hicn-state/states/cs_entries_count"); + vals[13].type = SR_UINT64_T; + vals[13].data.uint64_val = hicn_state->cs_entries_count; + + sr_val_set_xpath(&vals[14], "/hicn:hicn-state/states/cs_entries_ntw_count"); + vals[14].type = SR_UINT64_T; + vals[14].data.uint64_val = hicn_state->cs_entries_ntw_count; +} + + +static inline void strategy_update(sr_val_t * vals ){ + sr_val_set_xpath(&vals[0], "/hicn:hicn-state/strategy/description"); + vals[0].type = SR_UINT8_T; + vals[0].data.uint8_val = hicn_strategy->description[0]; +} + +static inline void strategies_update(sr_val_t * vals ){ + sr_val_set_xpath(&vals[0], "/hicn:hicn-state/strategies/description"); + vals[0].type = SR_UINT8_T; + vals[0].data.uint8_val = hicn_strategy->description[0]; +} + +static inline void route_update(sr_val_t * vals ){ + sr_val_set_xpath(&vals[0], "/hicn:hicn-state/route/faceids"); + vals[0].type = SR_UINT16_T; + vals[0].data.uint16_val = hicn_route->faceids[0]; + + sr_val_set_xpath(&vals[1], "/hicn:hicn-state/route/strategy_id"); + vals[1].type = SR_UINT32_T; + vals[1].data.uint32_val = hicn_route->strategy_id; +} + +static inline void face_ip_params_update(sr_val_t * vals ){ + sr_val_set_xpath(&vals[0], "/hicn:hicn-state/face-ip-params/nh_addr"); + vals[0].type = SR_UINT64_T; + vals[0].data.uint64_val = hicn_face_ip_params->nh_addr[0]; + + sr_val_set_xpath(&vals[1], "/hicn:hicn-state/face-ip-params/swif"); + vals[1].type = SR_UINT32_T; + vals[1].data.uint32_val = hicn_face_ip_params->swif; + + sr_val_set_xpath(&vals[2], "/hicn:hicn-state/face-ip-params/flags"); + vals[2].type = SR_UINT32_T; + vals[2].data.uint32_val = hicn_face_ip_params->flags; +} + + +static int hicn_state_states_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) { + sr_val_t *vals; + int rc; + enum locks_name state; + state=lstate; + SRP_LOG_DBG("Requesting state data for '%s'", xpath); + + if (!sr_xpath_node_name_eq(xpath, "states")) { + *values = NULL; + *values_cnt = 0; + return SR_ERR_OK; + } + + rc = sr_new_values(NSTATE_LEAVES, &vals); + if (SR_ERR_OK != rc) { + return rc; + } + + SRP_LOG_DBG("Requesting state data for '%s'", xpath); + Ticket_Lock(state); + state_update(vals); + Ticket_Unlock(state); + + *values = vals; + *values_cnt = NSTATE_LEAVES; + + pthread_t state_tid; + rc = pthread_create((pthread_t *)&state_tid, NULL, state_thread, NULL); + if (rc != 0) { + SRP_LOG_DBG_MSG("Error making hicn state thread"); + return SR_ERR_OPERATION_FAILED; + } + + return SR_ERR_OK; +} + +static int hicn_state_strategy_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) { + sr_val_t *vals; + int rc; + enum locks_name strategy; + strategy=lstrategy; + + if (!sr_xpath_node_name_eq(xpath, "strategy")) { + *values = NULL; + *values_cnt = 0; + return SR_ERR_OK; + } + + + rc = sr_new_values(NSTRATEGY_LEAVES, &vals); + if (SR_ERR_OK != rc) { + return rc; + } + + SRP_LOG_DBG("Requesting state data for '%s'", xpath); + Ticket_Lock(strategy); + strategy_update(vals); + Ticket_Unlock(strategy); + + *values = vals; + *values_cnt = NSTRATEGY_LEAVES; + return SR_ERR_OK; + + } + +static int hicn_state_strategies_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) { + sr_val_t *vals; + int rc; + enum locks_name strategies; + strategies=lstrategies; + + + + if (! sr_xpath_node_name_eq(xpath, "strategies")) { + SRP_LOG_DBG_MSG("Requesting state is not for strategies"); + *values = NULL; + *values_cnt = 0; + return SR_ERR_OK; + } + + + rc = sr_new_values(NSTRATEGIES_LEAVES, &vals); + if (SR_ERR_OK != rc) { + return rc; + } + + SRP_LOG_DBG("Requesting state data for '%s'", xpath); + Ticket_Lock(strategies); + strategies_update(vals); + Ticket_Unlock(strategies); + + *values = vals; + *values_cnt = NSTRATEGIES_LEAVES; + return SR_ERR_OK; + + } + + +static int hicn_state_route_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) { + sr_val_t *vals; + int rc; + enum locks_name route; + route=lroute; + + + if (! sr_xpath_node_name_eq(xpath, "route")) { + SRP_LOG_DBG_MSG("Requesting state is not for route"); + *values = NULL; + *values_cnt = 0; + return SR_ERR_OK; + } + + rc = sr_new_values(NROUTE_LEAVES, &vals); + if (SR_ERR_OK != rc) { + return rc; + } + + SRP_LOG_DBG("Requesting state data for '%s'", xpath); + Ticket_Lock(route); + route_update(vals); + Ticket_Unlock(route); + + *values = vals; + *values_cnt = NROUTE_LEAVES; + return SR_ERR_OK; + + } + + + static int hicn_state_face_ip_params_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) { + sr_val_t *vals; + int rc; + enum locks_name face_ip_params; + face_ip_params=lface_ip_params; + + + + if (! sr_xpath_node_name_eq(xpath, "face-ip-params")) { + SRP_LOG_DBG_MSG("Requesting state is not for face-ip-params"); + *values = NULL; + *values_cnt = 0; + return SR_ERR_OK; + } + + rc = sr_new_values(NFACE_IP_PARAMS_LEAVES, &vals); + if (SR_ERR_OK != rc) { + return rc; + } + + SRP_LOG_DBG("Requesting state data for '%s'", xpath); + Ticket_Lock(face_ip_params); + route_update(vals); + Ticket_Unlock(face_ip_params); + + *values = vals; + *values_cnt = NFACE_IP_PARAMS_LEAVES; + return SR_ERR_OK; + + } + + +static int params_send(vapi_msg_hicn_api_node_params_set *msg, + vapi_msg_hicn_api_node_params_set_reply *resp) { + vapi_msg_hicn_api_node_params_set_hton(msg); + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + HICN_VPP_VAPI_RECV; + SRP_LOG_DBG_MSG("state data are updated successfully"); + return SR_ERR_OK; +} + +/** + * @brief Callback to be called by any config change of "/hicn:/" leaf. + */ +static int hicn_node_params_set_cb(sr_session_ctx_t *session, const char *xpath, + sr_notif_event_t event, void *private_ctx) { + sr_change_iter_t *iter = NULL; + sr_change_oper_t op = SR_OP_CREATED; + sr_val_t *old_val = NULL; + sr_val_t *new_val = NULL; + sr_xpath_ctx_t xpath_ctx = { + 0, + }; + int rc = SR_ERR_OK, op_rc = SR_ERR_OK; + // no-op for apply, we only care about SR_EV_ENABLED, SR_EV_VERIFY, + // SR_EV_ABORT + if (SR_EV_APPLY == event) { + return SR_ERR_OK; + } + + // get changes iterator + rc = sr_get_changes_iter(session, xpath, &iter); + if (SR_ERR_OK != rc) { + SRP_LOG_ERR("Unable to retrieve change iterator: %s", sr_strerror(rc)); + return rc; + } + + vapi_msg_hicn_api_node_params_set *msg; + vapi_msg_hicn_api_node_params_set_reply *resp = NULL; + msg = vapi_alloc_hicn_api_node_params_set(g_vapi_ctx_instance); + // iterate over all changes + while ((SR_ERR_OK == op_rc || event == SR_EV_ABORT) && + (SR_ERR_OK == + (rc = sr_get_change_next(session, iter, &op, &old_val, &new_val)))) { + if (!strcmp(new_val->xpath, "/hicn:hicn-conf/params/enable_disable")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.bool_val); + msg->payload.enable_disable = new_val->data.bool_val; + } else if (!strcmp(new_val->xpath, "/hicn:hicn-conf/params/pit_max_size")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.int32_val); + msg->payload.pit_max_size = new_val->data.int32_val; + } else if (!strcmp(new_val->xpath, "/hicn:hicn-conf/params/cs_max_size")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.int32_val); + msg->payload.cs_max_size = new_val->data.int32_val; + } else if (!strcmp(new_val->xpath, + "/hicn:hicn-conf/params/cs_reserved_app")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.int32_val); + msg->payload.cs_reserved_app = new_val->data.int32_val; + } else if (!strcmp(new_val->xpath, + "/hicn:hicn-conf/params/pit_dflt_lifetime_sec")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.decimal64_val); + msg->payload.pit_dflt_lifetime_sec = new_val->data.decimal64_val; + } else if (!strcmp(new_val->xpath, + "/hicn:hicn-conf/params/pit_min_lifetime_sec")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.decimal64_val); + msg->payload.pit_min_lifetime_sec = new_val->data.decimal64_val; + } else if (!strcmp(new_val->xpath, + "/hicn:hicn-conf/params/pit_max_lifetime_sec")) { + SRP_LOG_DBG("A change detected in '%s', op=%d", + new_val ? new_val->xpath : old_val->xpath, + new_val->data.decimal64_val); + msg->payload.pit_max_lifetime_sec = new_val->data.decimal64_val; + } + + switch (op) { + case SR_OP_CREATED: + case SR_OP_MODIFIED: + op_rc = SR_ERR_OK; // OK + break; + case SR_OP_DELETED: + op_rc = SR_ERR_OPERATION_FAILED; // ERROR + break; + default: + break; + } + sr_xpath_recover(&xpath_ctx); + if (SR_ERR_INVAL_ARG == op_rc) { + sr_set_error(session, "You are not allowed to change the schema.", + new_val ? new_val->xpath : old_val->xpath); + } + sr_free_val(old_val); + sr_free_val(new_val); + } + + params_send(msg, resp); + + sr_free_change_iter(iter); + SRP_LOG_DBG_MSG("Configuration applied successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get hicn param in vpp. + */ +static int hicn_node_params_get_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + vapi_msg_hicn_api_node_params_get *msg; + vapi_msg_hicn_api_node_params_get_reply *resp; + + msg = vapi_alloc_hicn_api_node_params_get(g_vapi_ctx_instance); + vapi_msg_hicn_api_node_params_get_hton(msg); + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_node_params_get_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn parameter receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get hicn stat in vpp. + */ +static int hicn_node_stat_get_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + vapi_msg_hicn_api_node_stats_get *msg; + vapi_msg_hicn_api_node_stats_get_reply *resp; + + msg = vapi_alloc_hicn_api_node_stats_get(g_vapi_ctx_instance); + vapi_msg_hicn_api_node_stats_get_hton(msg); + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_node_stats_get_reply_ntoh(resp); + + Ticket_Lock(0); + hicn_state = (hicn_state_t *) resp; + Ticket_Unlock(0); + + + SRP_LOG_DBG_MSG("hicn status receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get hicn strategy in vpp. + */ +static int hicn_strategy_get_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_strategy_get *msg; + vapi_msg_hicn_api_strategy_get_reply *resp; + + msg = vapi_alloc_hicn_api_strategy_get(g_vapi_ctx_instance); + vapi_msg_hicn_api_strategy_get_hton(msg); + + msg->payload.strategy_id = input[0].data.uint32_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_strategy_get_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get hicn strategies in vpp. + */ +static int hicn_strategies_get_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_strategies_get *msg; + vapi_msg_hicn_api_strategies_get_reply *resp; + + msg = vapi_alloc_hicn_api_strategies_get(g_vapi_ctx_instance); + vapi_msg_hicn_api_strategies_get_hton(msg); + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_strategies_get_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get hicn route in vpp. + */ +static int hicn_route_get_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_route_get *msg; + vapi_msg_hicn_api_route_get_reply *resp; + + msg = vapi_alloc_hicn_api_route_get(g_vapi_ctx_instance); + vapi_msg_hicn_api_route_get_hton(msg); + + msg->payload.prefix[0] = input[0].data.uint64_val; + msg->payload.prefix[1] = input[1].data.uint64_val; + msg->payload.len = input[2].data.uint8_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_route_get_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to add hicn route nhops in vpp. + */ +static int hicn_route_nhops_add_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_route_nhops_add *msg; + vapi_msg_hicn_api_route_nhops_add_reply *resp; + + msg = vapi_alloc_hicn_api_route_nhops_add(g_vapi_ctx_instance); + vapi_msg_hicn_api_route_nhops_add_hton(msg); + + msg->payload.prefix[0] = input[0].data.uint64_val; + msg->payload.prefix[1] = input[1].data.uint64_val; + msg->payload.len = input[2].data.uint8_val; + msg->payload.face_ids[0] = input[3].data.uint32_val; + msg->payload.face_ids[1] = input[4].data.uint32_val; + msg->payload.face_ids[2] = input[5].data.uint32_val; + msg->payload.face_ids[3] = input[6].data.uint32_val; + msg->payload.face_ids[4] = input[7].data.uint32_val; + msg->payload.face_ids[5] = input[8].data.uint32_val; + msg->payload.face_ids[6] = input[9].data.uint32_val; + + msg->payload.n_faces = input[10].data.uint8_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_route_nhops_add_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to del hicn route in vpp. + */ +static int hicn_route_del_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_route_del *msg; + vapi_msg_hicn_api_route_del_reply *resp; + + msg = vapi_alloc_hicn_api_route_del(g_vapi_ctx_instance); + vapi_msg_hicn_api_route_del_hton(msg); + + msg->payload.prefix[0] = input[0].data.uint64_val; + msg->payload.prefix[1] = input[1].data.uint64_val; + msg->payload.len = input[2].data.uint8_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_route_del_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get face ip params in hicn in vpp. + */ +static int hicn_face_ip_params_get_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_face_ip_params_get *msg; + vapi_msg_hicn_api_face_ip_params_get_reply *resp; + + msg = vapi_alloc_hicn_api_face_ip_params_get(g_vapi_ctx_instance); + vapi_msg_hicn_api_face_ip_params_get_hton(msg); + + msg->payload.faceid = input[0].data.uint16_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_face_ip_params_get_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to get face ip params in hicn in vpp. + */ +static int hicn_punting_add_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_punting_add *msg; + vapi_msg_hicn_api_punting_add_reply *resp; + + msg = vapi_alloc_hicn_api_punting_add(g_vapi_ctx_instance); + vapi_msg_hicn_api_punting_add_hton(msg); + + msg->payload.prefix[0] = input[0].data.uint64_val; + msg->payload.prefix[1] = input[1].data.uint64_val; + msg->payload.len = input[2].data.uint8_val; + msg->payload.swif = input[3].data.uint32_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_punting_add_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to del hicn route nhops in vpp. + */ +static int hicn_route_nhops_del_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_route_nhop_del *msg; + vapi_msg_hicn_api_route_nhop_del_reply *resp; + + msg = vapi_alloc_hicn_api_route_nhop_del(g_vapi_ctx_instance); + vapi_msg_hicn_api_route_nhop_del_hton(msg); + + msg->payload.prefix[0] = input[0].data.uint64_val; + msg->payload.prefix[1] = input[1].data.uint64_val; + msg->payload.len = input[2].data.uint8_val; + msg->payload.faceid = input[3].data.uint16_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_route_nhop_del_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to del hicn punting in vpp. + */ +static int hicn_punting_del_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_punting_del *msg; + vapi_msg_hicn_api_punting_del_reply *resp; + + msg = vapi_alloc_hicn_api_punting_del(g_vapi_ctx_instance); + vapi_msg_hicn_api_punting_del_hton(msg); + + msg->payload.prefix[0] = input[0].data.uint64_val; + msg->payload.prefix[1] = input[1].data.uint64_val; + msg->payload.len = input[2].data.uint8_val; + msg->payload.swif = input[3].data.uint32_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_punting_del_reply_ntoh(resp); + + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to del hicn face ip in vpp. + */ +static int hicn_face_ip_del_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_face_ip_del *msg; + vapi_msg_hicn_api_face_ip_del_reply *resp; + + msg = vapi_alloc_hicn_api_face_ip_del(g_vapi_ctx_instance); + vapi_msg_hicn_api_face_ip_del_hton(msg); + + msg->payload.faceid = input[0].data.uint16_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_face_ip_del_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief API to del hicn face ip in vpp. + */ +static int hicn_face_ip_add_cb(const char *xpath, const sr_val_t *input, + const size_t input_cnt, sr_val_t **output, + size_t *output_cnt, void *private_ctx) { + // allocate memory msg and resp + vapi_msg_hicn_api_face_ip_add *msg; + vapi_msg_hicn_api_face_ip_add_reply *resp; + + msg = vapi_alloc_hicn_api_face_ip_add(g_vapi_ctx_instance); + vapi_msg_hicn_api_face_ip_add_hton(msg); + + msg->payload.nh_addr[0] = input[0].data.uint64_val; + msg->payload.nh_addr[1] = input[1].data.uint64_val; + msg->payload.swif = input[2].data.uint32_val; + + if (VAPI_OK != vapi_send(g_vapi_ctx_instance, msg)) { + SRP_LOG_DBG_MSG("Sending msg to VPP failed"); + return SR_ERR_OPERATION_FAILED; + } + + HICN_VPP_VAPI_RECV; + + vapi_msg_hicn_api_face_ip_add_reply_ntoh(resp); + + SRP_LOG_DBG_MSG("hicn strategy receive successfully"); + return SR_ERR_OK; +} + +/** + * @brief Helper function for subscribing all hicn APIs. + */ +int hicn_subscribe_events(sr_session_ctx_t *session, + sr_subscription_ctx_t **subscription) { + int rc = SR_ERR_OK; + SRP_LOG_DBG_MSG("Initializing hicn-interfaces plugin."); + + + //Initializing the locks + for (int i=0; ipayload.pkts_processed; + + // values = val; + //values_cnt = 1; + sr_free_val(val); + + */ + SRP_LOG_DBG_MSG("hicn status receive successfully"); + + return NULL; +} + +#endif /* __IETF_HICN_H__ */ \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/model/tlock.c b/utils/sysrepo-plugin/plugin/model/tlock.c new file mode 100644 index 000000000..d870adf75 --- /dev/null +++ b/utils/sysrepo-plugin/plugin/model/tlock.c @@ -0,0 +1,21 @@ +#include"tlock.h" + + +void Ticket_init ( int Lock_Number , long int init ){ + +//__atomic_store( &En[Lock_Number] , &init , __ATOMIC_SEQ_CST ); +//__atomic_store( &De[Lock_Number] , &init , __ATOMIC_SEQ_CST ); +En[Lock_Number]=init; +De[Lock_Number]=init; +} + +void Ticket_Lock(int Lock_Number ){ + + int my_ticket = __sync_fetch_and_add(&En[Lock_Number] , 1 ); + while ( my_ticket != De[ Lock_Number ] ) {}; + +} + +void Ticket_Unlock(int Lock_Number ){ +De[Lock_Number]++; +} diff --git a/utils/sysrepo-plugin/plugin/model/tlock.h b/utils/sysrepo-plugin/plugin/model/tlock.h new file mode 100644 index 000000000..c7333117b --- /dev/null +++ b/utils/sysrepo-plugin/plugin/model/tlock.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 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. + */ + + +#ifndef __TLOCK_H__ +#define __TLOCK_H__ + + +// limit on the number of locks: it shoud be matched with the number of hicn-state leaves +#define MAX_LOCK_SIZE 4 + +volatile long int En[MAX_LOCK_SIZE] , De[MAX_LOCK_SIZE] ; // For Ticket Algorithm + + +void Ticket_init ( int Lock_Number , long int init ); +void Ticket_Lock(int Lock_Number ); +void Ticket_Unlock(int Lock_Number ); + +#endif /* __IETF_HICN_H__ */ \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/yang/hicn_netconf_client.xml b/utils/sysrepo-plugin/plugin/yang/hicn_netconf_client.xml new file mode 100644 index 000000000..ae3a96a0c --- /dev/null +++ b/utils/sysrepo-plugin/plugin/yang/hicn_netconf_client.xml @@ -0,0 +1,84 @@ + + true + -1 + -1 + -1 + -1 + -1 + -1 + + + + + + + + + 0 + + + + + + + 10 + 20 + 30 + + + + 10 + 20 + 30 + + + + 10 + 20 + 30 + 40 + 50 + 60 + 70 + 80 + 90 + 100 + 110 + + + + 10 + 20 + 30 + 40 + + + + + 10 + + + + 10 + 20 + 30 + + + + 0 + + + + 10 + 20 + 30 + 40 + + + + + 10 + 20 + 30 + 40 + diff --git a/utils/sysrepo-plugin/plugin/yang/model/hicn.yang b/utils/sysrepo-plugin/plugin/yang/model/hicn.yang new file mode 100644 index 000000000..1bab9771b --- /dev/null +++ b/utils/sysrepo-plugin/plugin/yang/model/hicn.yang @@ -0,0 +1,546 @@ +module hicn { + namespace "urn:sysrepo:hicn"; + prefix hcn; + + revision 2019-02-06 { + description "Initial revision."; + } + + +/* new data types and grouping definition to forward the remote request toward hicn controler--to-->hicn */ + + typedef float { + type decimal64 { + fraction-digits 2; + } + } + + + grouping params { + + leaf enable_disable { + description "Enable / disable ICN forwarder in VPP."; + type boolean; + default false; + } + + leaf pit_max_size { + description "PIT maximum size, otherwise -1 to assign default value."; + type int32; + default -1; + } + + leaf cs_max_size { + description "CS maximum size, otherwise -1 to assign default value."; + type int32; + default -1; + } + + leaf cs_reserved_app { + description "Portion of CS reserved to application, otherwise -1 to assign default value."; + type int32; + default -1; + } + + leaf pit_dflt_lifetime_sec { + description "Default PIT entry lifetime, otherwise -1 to assign default value."; + type float; + default -1; + } + + leaf pit_max_lifetime_sec { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value."; + type float; + default -1; + } + + leaf pit_min_lifetime_sec { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type float; + default -1; + } +} + + grouping face_ip_add { + + leaf nh_addr0 { + description "IP local address."; + type uint64; + } + + leaf nh_addr1 { + description "IP local address."; + type uint64; + } + + leaf swif { + description "IPv4 local port number."; + type uint32; + } + } + + grouping route_nhops_add { + + leaf prefix0 { + description "Prefix0 to be added to the FIB."; + type uint64; + } + + leaf prefix1 { + description "Prefix1 to be added to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + + leaf face_ids0 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf face_ids1 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf face_ids2 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf face_ids3 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf face_ids4 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf face_ids5 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf face_ids6 { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint32; + } + + leaf n_faces { + description "Number of face to add."; + type uint8; + } + } + + + grouping route_nhops_del { + + leaf prefix0 { + description "Prefix0 to be added to the FIB."; + type uint64; + } + + leaf prefix1 { + description "Prefix1 to be added to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + + leaf faceid { + description "A Face ID to the next hop forwarder for the specified prefix."; + type uint16; + } + + } + + + grouping route_add { + + leaf prefix0 { + description "Prefix0 to be added to the FIB."; + type uint64; + } + + leaf prefix1 { + description "Prefix1 to be added to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + } + + + grouping route_del { + + leaf prefix0 { + description "Prefix0 to be added to the FIB."; + type uint64; + } + + leaf prefix1 { + description "Prefix1 to be added to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + } + + + grouping route_get { + + + leaf prefix0 { + description "Prefix0 to be added to the FIB."; + type uint64; + } + + leaf prefix1 { + description "Prefix1 to be added to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + } + + grouping punting_add { + + leaf prefix0 { + description "Prefix to be added to the FIB."; + type uint64; + } + + leaf prefix1 { + description "Prefix to be added to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + + leaf swif { + description "Interface id."; + type uint32; + } + } + + grouping register_prod_app { + + leaf-list prefix { + description "Prefix to be matched to the FIB."; + type uint64; + } + + leaf len { + description "Length of the prefix."; + type uint8; + } + + leaf swif { + description "Interface id."; + type uint32; + } + + leaf cs_reserved { + description "CS memory reserved -- in number of packets."; + type uint32; + } + + } + +/* new data types and grouping definition to backward the remote response hicn--to-->controler */ + + + grouping states-reply { + + leaf pkts_processed { + description "ICN packets processed."; + type uint64; + } + + leaf pkts_interest_count { + description "PIT maximum size, otherwise -1 to assign default value."; + type uint64; + } + + leaf pkts_data_count { + description "CS maximum size, otherwise -1 to assign default value."; + type uint64; + } + + leaf pkts_from_cache_count { + description "Portion of CS reserved to application, otherwise -1 to assign default value."; + type uint64; + } + + leaf pkts_no_pit_count { + description "Default PIT entry lifetime, otherwise -1 to assign default value."; + type uint64; + } + + leaf pit_expired_count { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value."; + type uint64; + } + + leaf cs_expired_count { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf cs_lru_count { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf pkts_drop_no_buf { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf interests_aggregated { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf interests_retx { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf interests_hash_collision { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf pit_entries_count { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf cs_entries_count { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + + leaf cs_entries_ntw_count { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint64; + } + +} + + + + grouping strategy-reply { + + leaf description { + description "Enable / disable ICN forwarder in VPP."; + type uint8; + } + } + + grouping route-reply { + + leaf faceids { + description "Enable / disable ICN forwarder in VPP."; + type uint16; + + } + + leaf strategy_id { + description "compile-time plugin features."; + type uint32; + } + } + + grouping strategies-reply { + leaf n_strategies { + description "Enable / disable ICN forwarder in VPP."; + type uint8; + } + leaf strategy_id { + description "Enable / disable ICN forwarder in VPP."; + type uint32; + } + + } + + grouping face-ip-params-reply { + + leaf nh_addr { + description "Enable / disable ICN forwarder in VPP."; + type uint64; + } + + leaf swif { + description "compile-time plugin features."; + type uint32; + } + + leaf flags { + description "compile-time plugin features."; + type uint32; + } + + } + + +/* Hicn configuration */ + + container hicn-conf { + config true; + description "config data container for the hicn-vpp."; + + container params{ + uses params; + } + } + + +/* Hicn operational data */ + + container hicn-state { + config false; + description "operational data container for the hicn."; + + container states{ + uses states-reply; + } + container strategy{ + uses strategy-reply; + } + container route{ + uses route-reply; + } + container strategies{ + uses strategies-reply; + } + container face-ip-params{ + uses face-ip-params-reply; + } + } + +/* RPC Definitions */ + + + rpc node-params-set { + description "Operation to set hicn params in vpp."; + input { + uses params; + } + } + + rpc node-params-get { + description "Operation to get hicn parameter in vpp."; + } + + + rpc node-stat-get { + description "Operation to get hicn status in vpp."; + } + + + rpc strategy-get { + description "Operation to get hicn strategy."; + input { + leaf strategy_id { + description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value ."; + type uint32; + } + } + } + + rpc strategies-get { + description "Operation to get hicn strategies."; + } + + rpc route-get { + description "Operation to get hicn route."; + input { + uses route_get; + } + } + + rpc route-del { + description "Operation to del hicn route."; + input { + uses route_del; + } + } + + rpc route-nhops-add { + description "Operation to add hicn route nhops."; + input { + uses route_nhops_add; + } + } + + rpc route-nhops-del { + description "Operation to add hicn face ip punt."; + input { + uses route_nhops_del; + } + } + + rpc face-ip-params-get { + description "Operation to del hicn route."; + input { + leaf faceid { + description "Face to be retrieved ."; + type uint16; + } + } + } + + rpc face-ip-add { + description "Operation to add hicn face ip."; + input { + uses face_ip_add; + } + } + + rpc face-ip-del { + description "Operation to del hicn face ip."; + input { + leaf faceid { + description "Face to be deleted ."; + type uint16; + } + } + } + + rpc punting-add { + description "Operation to add hicn punt."; + input { + uses punting_add; + } + } + + rpc punting-del { + description "Operation to del hicn punt."; + input { + uses punting_add; /* It uses the same payload as the add*/ + } + } + +} \ No newline at end of file diff --git a/utils/sysrepo-plugin/plugin/yang/startup.xml b/utils/sysrepo-plugin/plugin/yang/startup.xml new file mode 100644 index 000000000..f88e13ea2 --- /dev/null +++ b/utils/sysrepo-plugin/plugin/yang/startup.xml @@ -0,0 +1,11 @@ + + + false + -1 + -1 + -1 + -1 + -1 + -1 + + \ No newline at end of file -- cgit 1.2.3-korg