summaryrefslogtreecommitdiffstats
path: root/utils/sysrepo-plugins
diff options
context:
space:
mode:
authorMasoud Hemmatpour <mhemmatp@cisco.com>2019-03-08 13:40:22 +0100
committerMasoud Hemmatpour <mhemmatp@cisco.com>2019-03-25 15:45:35 +0100
commitc405a5bb3a2299c34f11431be477a228715e66fa (patch)
tree1dabcddbc14dfb010efb22a1547c30f00a03c98e /utils/sysrepo-plugins
parent558581790763815071e9c77e06047e689faf752f (diff)
[HICN-90] adding hicn-light to sysrepo-plugins
Change-Id: Icd92adb21661d33b0cd40ea8c3dd748f0fa97aaf Signed-off-by: Masoud Hemmatpour <mhemmatp@cisco.com> Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com> Signed-off-by: Masoud Hemmatpour <mhemmatp@cisco.com>
Diffstat (limited to 'utils/sysrepo-plugins')
-rw-r--r--utils/sysrepo-plugins/CMakeLists.txt40
-rw-r--r--utils/sysrepo-plugins/README.md330
-rw-r--r--utils/sysrepo-plugins/cmake/FindHicnLight.cmake39
-rw-r--r--utils/sysrepo-plugins/cmake/FindHicnPlugin.cmake39
-rw-r--r--utils/sysrepo-plugins/cmake/FindSysrepo.cmake46
-rw-r--r--utils/sysrepo-plugins/cmake/FindVPP.cmake178
-rw-r--r--utils/sysrepo-plugins/cmake/Packager.cmake149
-rw-r--r--utils/sysrepo-plugins/cmake/Packaging.cmake31
-rw-r--r--utils/sysrepo-plugins/hicn-light/CMakeLists.txt60
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/CMakeLists.txt60
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/hicn_light.c121
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/hicn_light.h25
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.c31
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.h78
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.c33
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.h44
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/model/tlock.c21
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/model/tlock.h31
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/yang/controler_rpcs_instances.xml73
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/yang/model/hicn.yang546
-rw-r--r--utils/sysrepo-plugins/hicn-light/plugin/yang/startup.xml11
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/CMakeLists.txt65
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c123
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.h25
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/hicn_vpp_comm.c53
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/hicn_vpp_comm.h119
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c597
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.h25
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c1323
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.h90
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/model/tlock.c21
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/model/tlock.h31
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/yang/controler_rpcs_instances.xml76
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/yang/model/hicn.yang536
-rw-r--r--utils/sysrepo-plugins/hicn-plugin/plugin/yang/startup.xml11
35 files changed, 5081 insertions, 0 deletions
diff --git a/utils/sysrepo-plugins/CMakeLists.txt b/utils/sysrepo-plugins/CMakeLists.txt
new file mode 100644
index 000000000..91726161f
--- /dev/null
+++ b/utils/sysrepo-plugins/CMakeLists.txt
@@ -0,0 +1,40 @@
+#
+# 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 3.5 FATAL_ERROR)
+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(hicn-plugin)
+add_subdirectory(hicn-light)
+include(Packaging)
+include(Packager)
+make_packages()
diff --git a/utils/sysrepo-plugins/README.md b/utils/sysrepo-plugins/README.md
new file mode 100644
index 000000000..ca40dcb5f
--- /dev/null
+++ b/utils/sysrepo-plugins/README.md
@@ -0,0 +1,330 @@
+# Sysrepo plugin for hicn-plugin (2019)
+
+These plugins serve as a data management agent. they provide yang models via NETCONF to allow the management of hicn-light and hicn-plugin which runs in VPP instance from out-of-box.
+
+## Software Requirement
+
+- VPP
+
+- sysrepo
+
+- hicn-plugin
+
+- hicn-light
+
+## 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/. 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 path_to_startup_xml -f xml hicn
+fi
+
+
+startup.xml is placed under plugin/yang/. Here you can find the content:
+
+<hicn-conf xmlns="urn:sysrepo:hicn">
+<params>
+ <enable_disable>false</enable_disable>
+ <pit_max_size>-1</pit_max_size>
+ <cs_max_size>-1</cs_max_size>
+ <cs_reserved_app>-1</cs_reserved_app>
+ <pit_dflt_lifetime_sec>-1</pit_dflt_lifetime_sec>
+ <pit_max_lifetime_sec>-1</pit_max_lifetime_sec>
+ <pit_min_lifetime_sec>-1</pit_min_lifetime_sec>
+</params>
+</hicn-conf>
+
+As can be seen, it contains the leaves of the params in hicn-conf node which is used as the startup configuration. This configuration can be changed through the controler by subscribing which changes the target to the running state. hicn yang 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 controler_rpcs_instances.xml under plugin/yang/. Here you can find the content:
+
+<node-params-get xmlns="urn:sysrepo:hicn"/>
+
+<node-stat-get xmlns="urn:sysrepo:hicn"/>
+
+<strategy-get xmlns="urn:sysrepo:hicn">
+ <strategy_id>0</strategy_id>
+</strategy-get>
+
+<strategies-get xmlns="urn:sysrepo:hicn"/>
+
+
+<route-get xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+</route-get>
+
+<route-del xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+</route-del>
+
+<route-nhops-add xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <face_ids0>40</face_ids0>
+ <face_ids1>50</face_ids1>
+ <face_ids2>60</face_ids2>
+ <face_ids3>70</face_ids3>
+ <face_ids4>80</face_ids4>
+ <face_ids5>90</face_ids5>
+ <face_ids6>100</face_ids6>
+ <n_faces>110</n_faces>
+</route-nhops-add>
+
+<route-nhops-del xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <faceid>40</faceid>
+</route-nhops-del>
+
+
+<face-ip-params-get xmlns="urn:sysrepo:hicn">
+ <faceid>10</faceid>
+</face-ip-params-get>
+
+<face-ip-add xmlns="urn:sysrepo:hicn">
+ <nh_addr0>10</nh_addr0>
+ <nh_addr1>20</nh_addr1>
+ <swif>30</swif>
+</face-ip-add>
+
+<face-ip-del xmlns="urn:sysrepo:hicn">
+ <faceid>0</faceid>
+</face-ip-del>
+
+<punting-add xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <swif>40</swif>
+</punting-add>
+
+
+<punting-del xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <swif>40</swif>
+</punting-del>
+
+
+## Run the plugin
+
+Firstly, verify the plugin and binary libraries are located correctly, then run the vpp through (service vpp start). Next, run the sysrepo daemon (sysrepod), for debug mode: sysrepo -d -l 4 which runs with high verbosity. Then, run the sysrepo plugin (sysrepo-plugind), for debug mode: sysrep-plugind -d -l 4 which runs with high verbosity. Now, the hicn sysrepo plugin is loaded. Then, run the netopeer2-server which serves as NETCONF server.
+
+## Connect from netopeer2-cli
+
+In order to connect through the netopeer client run the netopeer2-cli. Then, follow these steps:
+
+connect --host XXX --login XXX
+--> get (you can get the configuration and operational data)
+--> get-config (you can get the configuratoin data)
+--> edit-config --target running --config (you can modify the configuration but it needs an xml configuration input. For example,
+<hicn-conf xmlns="urn:sysrepo:hicn">
+<params>
+ <enable_disable>false</enable_disable>
+ <pit_max_size>-1</pit_max_size>
+ <cs_max_size>-1</cs_max_size>
+ <cs_reserved_app>-1</cs_reserved_app>
+ <pit_dflt_lifetime_sec>-1</pit_dflt_lifetime_sec>
+ <pit_max_lifetime_sec>-1</pit_max_lifetime_sec>
+ <pit_min_lifetime_sec>-1</pit_min_lifetime_sec>
+</params>
+</hicn-conf>
+)
+--> user-rpc (you can call one of the rpc proposed by hicn model but it needs an xml input, you can pick one in controler_rpcs_instances.xml)
+
+## Connect from OpenDayligh (ODL) controller
+
+In order to connect througt the OpenDaylight follow these procedure:
+
+- run karaf distribution (./opendayligh_installation_folder/bin/karaf)
+- install the required feature list in DOL (feature:install odl-netconf-server odl-netconf-connector odl-restconf-all odl-netconf-topology or
+ odl-netconf-clustered-topology)
+- run a rest client program (e.g., postman or RESTClient)
+- mount the remote netopeer2-server to the OpenDaylight by the following REST API:
+
+PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/topology-netconf/node/hicn-node
+
+with the following body
+
+ <node xmlns="urn:TBD:params:xml:ns:yang:network-topology">
+ <node-id>hicn-node</node-id>
+ <host xmlns="urn:opendaylight:netconf-node-topology">Remote_NETCONF_SERVER_IP</host>
+ <port xmlns="urn:opendaylight:netconf-node-topology">830</port>
+ <username xmlns="urn:opendaylight:netconf-node-topology">username</username>
+ <password xmlns="urn:opendaylight:netconf-node-topology">password</password>
+ <tcp-only xmlns="urn:opendaylight:netconf-node-topology">false</tcp-only>
+ <keepalive-delay xmlns="urn:opendaylight:netconf-node-topology">1</keepalive-delay>
+ </node>
+
+Note that the header files must be set to Content-Type: application/xml, Accept: application/xml. There are more options which can be set but for simplicity we keep a short configuration to mount the remote node.
+
+- send the operation through the following REST API:
+
+POST http://localhost:8181/restconf/operations/network-topology:network-topology/topology/topology-netconf/node/hicn-node/yang-ext:mount/ietf-netconf:edit-config
+
+The body can be used the same as edit-config in netopeer2-cli.
+
+## Connect from Network Services Orchestrator (NSO)
+
+To connect NSO to the netopeer2-server, first, you need to write a NED package for your device. The procudeure to create NED for hicn is explaned in the following:
+
+Place hicn.yang model in a folder called hicn-yang-model, and follow these steps:
+
+- ncs-make-package --netconf-ned ./hicn-yang-model ./hicn-nso
+- cd hicn-nso/src; make
+- ncs-setup --ned-package ./hicn-nso --dest ./hicn-nso-project
+- cd hicn-nso-project
+- ncs
+- ncs_cli -C -u admin
+- configure
+- devices authgroups group authhicn default-map remote-name user_name remote-password password
+- devices device hicn address IP_device port 830 authgroup authhicn device-type netconf
+- state admin-state unlocked
+- commit
+- ssh fetch-host-keys
+
+At this point, we are able to connect to the remote device.
+
+
+## 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-plugins/cmake/FindHicnLight.cmake b/utils/sysrepo-plugins/cmake/FindHicnLight.cmake
new file mode 100644
index 000000000..bce3265fa
--- /dev/null
+++ b/utils/sysrepo-plugins/cmake/FindHicnLight.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(HICNLIGHT_SEARCH_PATH_LIST
+ ${HICNLIGHT_HOME}
+ $ENV{HICNLIGHT_HOME}
+ /usr/local
+ /opt
+ /usr
+)
+
+find_path(HICNLIGHT_INCLUDE_DIR hicn/api/api.h
+ HINTS ${HICNLIGHT_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ DOC "Find the hicn plugin includes"
+)
+
+find_library(HICNLIGHT_LIBRARY NAMES libhicn-light-ctrl.so
+ HINTS ${HICNLIGHT_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib
+ DOC "Find the hicn light lib"
+)
+
+set(HICNLIGHT_LIBRARIES ${HICNLIGHT_LIBRARY})
+set(HICNLIGHT_INCLUDE_DIRS ${HICNLIGHT_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Hicnlight HICNLIGHT_LIBRARIES HICNLIGHT_INCLUDE_DIRS)
+
+mark_as_advanced(HICNLIGHT_LIBRARY HICNLIGHT_INCLUDE_DIR)
diff --git a/utils/sysrepo-plugins/cmake/FindHicnPlugin.cmake b/utils/sysrepo-plugins/cmake/FindHicnPlugin.cmake
new file mode 100644
index 000000000..f50ed736e
--- /dev/null
+++ b/utils/sysrepo-plugins/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-plugins/cmake/FindSysrepo.cmake b/utils/sysrepo-plugins/cmake/FindSysrepo.cmake
new file mode 100644
index 000000000..4228ef93a
--- /dev/null
+++ b/utils/sysrepo-plugins/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-plugins/cmake/FindVPP.cmake b/utils/sysrepo-plugins/cmake/FindVPP.cmake
new file mode 100644
index 000000000..62abc29da
--- /dev/null
+++ b/utils/sysrepo-plugins/cmake/FindVPP.cmake
@@ -0,0 +1,178 @@
+# 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_SEARCH_PATH_LIST
+# ${VPP_HOME}
+# $ENV{VPP_HOME}
+ /usr/lib
+ /usr/lib64
+ /usr/local/lib
+ /usr/local/lib64
+ /opt/local/lib
+ /sw/lib
+ /usr/local
+ /opt
+ /usr)
+
+# 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
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ )
+
+ find_path(VLIB_API_INCLUDE_DIR
+ NAMES
+ vlibapi/api.h
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ )
+
+ find_path(VLIBMEMORY_INCLUDE_DIR
+ NAMES
+ vlibmemory/api.h
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ )
+
+ find_path(VPP_MSG_INCLUDE_DIR
+ NAMES
+ vpp/api/vpe_msg_enum.h
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ )
+
+ find_path(VPP_ALL_INCLUDE_DIR
+ NAMES
+ vpp/api/vpe_all_api_h.h
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ )
+
+ find_path(VAPI_INCLUDE_DIR
+ NAMES
+ vapi/interface.api.vapi.h
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES include
+ )
+
+ find_library(VLIBMEMORYCLIENT_LIBRARY
+ NAMES
+ vlibmemoryclient
+ libvlibmemoryclient
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ )
+
+ find_library(SVM_LIBRARY
+ NAMES
+ svm
+ libsvm
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ )
+
+ find_library(VPPINFRA_LIBRARY
+ NAMES
+ vppinfra
+ libvppinfra
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ )
+
+ find_library(VLIB_LIBRARY
+ NAMES
+ vlib
+ libvlib
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ )
+
+ find_library(VATPLUGIN_LIBRARY
+ NAMES
+ vatplugin
+ libvatplugin
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ )
+
+ find_library(VAPI_LIBRARY
+ NAMES
+ vapiclient
+ libvapiclient
+ HINTS
+ ${VPP_SEARCH_PATH_LIST}
+ PATH_SUFFIXES lib lib64
+ )
+
+ 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}
+ )
+
+message(${VAPI_LIBRARY})
+ set(VPP_LIBRARIES
+ ${VLIBMEMORYCLIENT_LIBRARY}
+ ${SVM_LIBRARY}
+ ${VPPINFRA_LIBRARY}
+ ${VLIB_LIBRARY}
+ ${VATPLUGIN_LIBRARY}
+ ${VAPI_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)
diff --git a/utils/sysrepo-plugins/cmake/Packager.cmake b/utils/sysrepo-plugins/cmake/Packager.cmake
new file mode 100644
index 000000000..b19145025
--- /dev/null
+++ b/utils/sysrepo-plugins/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-plugins/cmake/Packaging.cmake b/utils/sysrepo-plugins/cmake/Packaging.cmake
new file mode 100644
index 000000000..f5e8426fb
--- /dev/null
+++ b/utils/sysrepo-plugins/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-plugins/hicn-light/CMakeLists.txt b/utils/sysrepo-plugins/hicn-light/CMakeLists.txt
new file mode 100644
index 000000000..eea06592d
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/CMakeLists.txt
@@ -0,0 +1,60 @@
+#
+# 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-light-plugins)
+
+# Cmake find modules
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
+
+find_package(PkgConfig)
+find_package(HicnLight)
+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()
+
+# plugins sources
+set(PLUGINS_SOURCES
+ plugin/model/hicn_model.c
+ plugin/model/tlock.c
+ plugin/hicn_light_comm.c
+ plugin/hicn_light.c
+)
+
+# build the source code into shared library
+add_library(hicnlight SHARED ${PLUGINS_SOURCES})
+target_include_directories(hicnlight PUBLIC ${HICNLIGHT_INCLUDE_DIRS})
+target_link_libraries(hicnlight ${SYSREPO_LIBRARIES} ${HICNLIGHT_LIBRARIES})
+
+# install the plugin into plugins dir
+install(TARGETS hicnlight DESTINATION ${SR_PLUGINS_DIR} COMPONENT hicn_sysrepo_plugin)
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/CMakeLists.txt b/utils/sysrepo-plugins/hicn-light/plugin/CMakeLists.txt
new file mode 100644
index 000000000..e1d3dd39a
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/CMakeLists.txt
@@ -0,0 +1,60 @@
+#
+# 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-light-plugins)
+
+# Cmake find modules
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
+
+find_package(PkgConfig)
+find_package(HicnLight)
+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()
+
+# plugins sources
+set(PLUGINS_SOURCES
+ model/hicn_model.c
+ model/tlock.c
+ hicn_light_comm.c
+ hicn_light.c
+)
+
+# build the source code into shared library
+add_library(hicnlight SHARED ${PLUGINS_SOURCES})
+target_include_directories(hicnlight PUBLIC ${HICNLIGHT_INCLUDE_DIRS})
+target_link_libraries(hicnlight ${SYSREPO_LIBRARIES} ${HICNLIGHT_LIBRARIES})
+
+# install the plugin into plugins dir
+install(TARGETS hicnlight DESTINATION ${SR_PLUGINS_DIR} COMPONENT hicn_sysrepo_plugin) \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/hicn_light.c b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light.c
new file mode 100644
index 000000000..e5b1bf56d
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light.c
@@ -0,0 +1,121 @@
+/*
+ * 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 <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "hicn_light.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_light();
+ if (SR_ERR_OK != rc) {
+ HICN_LOG_ERR("hicn light connect error , with return %d.", rc);
+ return SR_ERR_INTERNAL;
+ }
+
+ // HICN subscribe
+ 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 light unload plugin ok.");
+ hicn_disconnect_light();
+ HICN_LOG_DBG_MSG("hicn light disconnect 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 hicn light */
+ rc = hicn_connect_light();
+ if (-1 == rc) {
+ fprintf(stderr, "hicn light 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_light();
+ return rc;
+} \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/hicn_light.h b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light.h
new file mode 100644
index 000000000..16f65e5c4
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light.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_LIGHT_H__
+#define __HICN_LIGHT_H__
+
+#include "hicn_light_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_LIGHT_H__ \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.c b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.c
new file mode 100644
index 000000000..a1b4d7ad2
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.c
@@ -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.
+ */
+#include "hicn_light_comm.h"
+
+hc_sock_t * hsocket;
+
+int hicn_connect_light() {
+ hsocket = hc_sock_create();
+ if (!hsocket)
+ HICN_LOG_ERR_MSG("Error creating socket\n");
+ if (hc_sock_connect(hsocket) < 0)
+ HICN_LOG_ERR_MSG("Error connecting to the forwarder\n");
+ return 0;
+}
+
+int hicn_disconnect_light() {
+ hc_sock_free(hsocket);
+ return 0;
+} \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.h b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.h
new file mode 100644
index 000000000..d424ebf3a
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/hicn_light_comm.h
@@ -0,0 +1,78 @@
+/*
+ * 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_LIGHT_COMMM_H__
+#define __HICN_LIGHT_COMMM_H__
+#include <sysrepo.h>
+#include <sysrepo/plugins.h>
+#include <sysrepo/values.h>
+
+
+#include <hicn/api/api.h>
+
+#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
+
+//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_CHECK2(retval, arg1, arg2) \
+ ARG_CHECK(retval, arg1); \
+ ARG_CHECK(retval, arg2)
+
+#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)
+
+int hicn_connect_light();
+int hicn_disconnect_light();
+extern hc_sock_t * hsocket;
+#endif //__HICN_LIGHT_COMMM_H__
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.c b/utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.c
new file mode 100644
index 000000000..0c34325d6
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.c
@@ -0,0 +1,33 @@
+/*
+ * 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 <stdio.h>
+#include <malloc.h>
+#include <sysrepo/xpath.h>
+
+/* Hicn headers */
+
+#include "hicn_model.h"
+#include "tlock.h"
+#include "../hicn_light.h"
+
+
+
+int hicn_subscribe_events(sr_session_ctx_t *session,
+ sr_subscription_ctx_t **subscription) {
+
+ SRP_LOG_INF_MSG("hicn light plugin initialized successfully.");
+ return SR_ERR_OK;
+
+} \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.h b/utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.h
new file mode 100644
index 000000000..59befe68c
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/model/hicn_model.h
@@ -0,0 +1,44 @@
+/*
+ * 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 __IETF_HICN_H__
+#define __IETF_HICN_H__
+
+#include "../hicn_light_comm.h"
+
+
+#define MEM_ALIGN 4096
+
+// Number of locks is equal to number of nodes in hicn-state
+// It is a coarse grain approach later can be changed to fine grained
+// better to initialize the lock by 0
+#define NLOCKS 5
+#define LOCK_INIT 0
+
+
+enum locks_name {lstate, lstrategy, lstrategies, lroute, lface_ip_params};
+
+#define NSTATE_LEAVES 15
+#define NSTRATEGY_LEAVES 1
+#define NSTRATEGIES_LEAVES 2
+#define NROUTE_LEAVES 2
+#define NFACE_IP_PARAMS_LEAVES 3
+
+
+
+int hicn_subscribe_events(sr_session_ctx_t *session,
+ sr_subscription_ctx_t **subscription);
+
+#endif /* __IETF_HICN_H__ */ \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/model/tlock.c b/utils/sysrepo-plugins/hicn-light/plugin/model/tlock.c
new file mode 100644
index 000000000..2f7b11efa
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/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-plugins/hicn-light/plugin/model/tlock.h b/utils/sysrepo-plugins/hicn-light/plugin/model/tlock.h
new file mode 100644
index 000000000..36698115a
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/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 5
+
+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-plugins/hicn-light/plugin/yang/controler_rpcs_instances.xml b/utils/sysrepo-plugins/hicn-light/plugin/yang/controler_rpcs_instances.xml
new file mode 100644
index 000000000..c5d24e4f6
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/yang/controler_rpcs_instances.xml
@@ -0,0 +1,73 @@
+<node-params-get xmlns="urn:sysrepo:hicn"/>
+
+<node-stat-get xmlns="urn:sysrepo:hicn"/>
+
+<strategy-get xmlns="urn:sysrepo:hicn">
+ <strategy_id>0</strategy_id>
+</strategy-get>
+
+<strategies-get xmlns="urn:sysrepo:hicn"/>
+
+
+<route-get xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+</route-get>
+
+<route-del xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+</route-del>
+
+<route-nhops-add xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <face_ids0>40</face_ids0>
+ <face_ids1>50</face_ids1>
+ <face_ids2>60</face_ids2>
+ <face_ids3>70</face_ids3>
+ <face_ids4>80</face_ids4>
+ <face_ids5>90</face_ids5>
+ <face_ids6>100</face_ids6>
+ <n_faces>110</n_faces>
+</route-nhops-add>
+
+<route-nhops-del xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <faceid>40</faceid>
+</route-nhops-del>
+
+
+<face-ip-params-get xmlns="urn:sysrepo:hicn">
+ <faceid>10</faceid>
+</face-ip-params-get>
+
+<face-ip-add xmlns="urn:sysrepo:hicn">
+ <nh_addr0>10</nh_addr0>
+ <nh_addr1>20</nh_addr1>
+ <swif>30</swif>
+</face-ip-add>
+
+<face-ip-del xmlns="urn:sysrepo:hicn">
+ <faceid>0</faceid>
+</face-ip-del>
+
+<punting-add xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <swif>40</swif>
+</punting-add>
+
+
+<punting-del xmlns="urn:sysrepo:hicn">
+ <prefix0>10</prefix0>
+ <prefix1>20</prefix1>
+ <len>30</len>
+ <swif>40</swif>
+</punting-del>
diff --git a/utils/sysrepo-plugins/hicn-light/plugin/yang/model/hicn.yang b/utils/sysrepo-plugins/hicn-light/plugin/yang/model/hicn.yang
new file mode 100644
index 000000000..928e5cdc6
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/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 forwarder.";
+ 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 forwarder.";
+ type uint8;
+ }
+ }
+
+ grouping route-reply {
+
+ leaf faceids {
+ description "Enable / disable ICN forwarder in forwarder.";
+ type uint16;
+
+ }
+
+ leaf strategy_id {
+ description "compile-time plugin features.";
+ type uint32;
+ }
+ }
+
+ grouping strategies-reply {
+ leaf n_strategies {
+ description "Enable / disable ICN forwarder in forwarder.";
+ type uint8;
+ }
+ leaf strategy_id {
+ description "Enable / disable ICN forwarder in forwarder.";
+ type uint32;
+ }
+
+ }
+
+ grouping face-ip-params-reply {
+
+ leaf nh_addr {
+ description "Enable / disable ICN forwarder in forwarder.";
+ 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-forwarder.";
+
+ 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 forwarder.";
+ input {
+ uses params;
+ }
+ }
+
+ rpc node-params-get {
+ description "Operation to get hicn parameter in forwarder.";
+ }
+
+
+ rpc node-stat-get {
+ description "Operation to get hicn status in forwarder.";
+ }
+
+
+ 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-plugins/hicn-light/plugin/yang/startup.xml b/utils/sysrepo-plugins/hicn-light/plugin/yang/startup.xml
new file mode 100644
index 000000000..f88e13ea2
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-light/plugin/yang/startup.xml
@@ -0,0 +1,11 @@
+<hicn-conf xmlns="urn:sysrepo:hicn">
+<params>
+ <enable_disable>false</enable_disable>
+ <pit_max_size>-1</pit_max_size>
+ <cs_max_size>-1</cs_max_size>
+ <cs_reserved_app>-1</cs_reserved_app>
+ <pit_dflt_lifetime_sec>-1</pit_dflt_lifetime_sec>
+ <pit_max_lifetime_sec>-1</pit_max_lifetime_sec>
+ <pit_min_lifetime_sec>-1</pit_min_lifetime_sec>
+</params>
+</hicn-conf> \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-plugin/CMakeLists.txt b/utils/sysrepo-plugins/hicn-plugin/CMakeLists.txt
new file mode 100644
index 000000000..4c3ef6d1a
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-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")
+
+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()
+
+# plugins sources
+set(PLUGINS_SOURCES
+ plugin/ietf/ietf_interface.c
+ plugin/model/hicn_model.c
+ plugin/model/tlock.c
+ plugin/hicn_vpp_comm.c
+ plugin/hicn_plugin.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})
+
+#set_target_properties(hicn
+# PROPERTIES
+# LINKER_LANGUAGE C
+# INSTALL_RPATH ${VPP_HOME}/lib)
+
+# install the plugin into plugins dir
+install(TARGETS hicn DESTINATION ${SR_PLUGINS_DIR} COMPONENT hicn_sysrepo_plugin)
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c
new file mode 100644
index 000000000..262e98553
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c
@@ -0,0 +1,123 @@
+/*
+ * 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 <inttypes.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "hicn_plugin.h"
+#include "model/hicn_model.h"
+#include "ietf/ietf_interface.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 subscribe
+ hicn_subscribe_events(session, &subscription);
+
+ // IETF subscribe
+ ietf_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-plugins/hicn-plugin/plugin/hicn_plugin.h b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.h
new file mode 100644
index 000000000..4e48c8c29
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-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-plugins/hicn-plugin/plugin/hicn_vpp_comm.c b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_vpp_comm.c
new file mode 100644
index 000000000..2add127f2
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_vpp_comm.c
@@ -0,0 +1,53 @@
+/*
+ * 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;
+DEFINE_VAPI_MSG_IDS_HICN_API_JSON;
+
+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-plugins/hicn-plugin/plugin/hicn_vpp_comm.h b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_vpp_comm.h
new file mode 100644
index 000000000..aff8e2ea1
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/hicn_vpp_comm.h
@@ -0,0 +1,119 @@
+/*
+ * 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 <sysrepo.h>
+#include <sysrepo/plugins.h> //for HICN_LOG_DBG
+#include <sysrepo/values.h>
+#include <vapi/vapi.h>
+
+#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
+
+DEFINE_VAPI_MSG_IDS_HICN_API_JSON;
+// ctx vpp connect
+extern vapi_ctx_t g_vapi_ctx_instance;
+
+//Here it is the definition
+
+#define VPP_INTFC_NAME_LEN 64
+#define VPP_MAC_ADDRESS_LEN 8
+#define VPP_IP6_ADDRESS_LEN 16
+#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_CHECK2(retval, arg1, arg2) \
+ ARG_CHECK(retval, arg1); \
+ ARG_CHECK(retval, arg2)
+
+#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();
+
+#endif //__HICN_VPP_COMMM_H__ \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c b/utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c
new file mode 100644
index 000000000..f02605895
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (c) 2016 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 <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <sysrepo.h>
+#include <sysrepo/plugins.h>
+#include <sysrepo/values.h>
+#include <sysrepo/xpath.h>
+#include <vnet/interface.h>
+#include <vnet/vnet.h>
+#include <vnet/ip/ip.h>
+#include <vapi/interface.api.vapi.h>
+
+#include "ietf_interface.h"
+#include "../hicn_vpp_comm.h"
+
+
+
+DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON;
+
+typedef struct hicn_interface_
+{
+ u32 sw_if_index;
+ char interface_name[VPP_INTFC_NAME_LEN];
+ u8 l2_address[VPP_MAC_ADDRESS_LEN];
+ u32 l2_address_length;
+ u64 link_speed;
+ u16 link_mtu;
+ u8 admin_up_down;
+ u8 link_up_down;
+} hicnIntfc;
+
+typedef struct _ietf_sw_interface_dump_ctx
+{
+ u8 last_called;
+ int num_ifs;
+ int capacity;
+ hicnIntfc * intfcArray;
+} ietf_sw_interface_dump_ctx;
+
+static i32 ietf_setInterfaceFlags(u32 sw_if_index, u8 admin_up_down);
+static i32 ietf_interface_name2index(const char *name, u32* if_index);
+static i32 ietf_interface_add_del_addr(u32 sw_if_index, u8 is_add, u8 is_ipv6,
+ u8 del_all, u8 address_length,
+ u8 address[VPP_IP6_ADDRESS_LEN]);
+static int ietf_initSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx);
+static int ietf_freeSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx);
+
+/**
+ * @brief Helper function for converting netmask into prefix length.
+ */
+static uint8_t
+netmask_to_prefix(const char *netmask)
+{
+ in_addr_t n = 0;
+ uint8_t i = 0;
+
+ inet_pton(AF_INET, netmask, &n);
+
+ while (n > 0) {
+ n = n >> 1;
+ i++;
+ }
+
+ return i;
+}
+
+/**
+ * @brief Helper function for converting IPv4/IPv6 address string into binary representation.
+ */
+static int
+ip_addr_str_to_binary(const char *ip_address_str, uint8_t *ip_address_bin, bool is_ipv6)
+{
+ struct in6_addr addr6 = { 0, };
+ struct in_addr addr4 = { 0, };
+ int ret = 0;
+
+ if (is_ipv6) {
+ ret = inet_pton(AF_INET6, ip_address_str, &(addr6));
+ if (1 == ret)
+ {
+ memcpy(ip_address_bin, &addr6, sizeof(addr6));
+ }
+ } else {
+ ret = inet_pton(AF_INET, ip_address_str, &(addr4));
+ if (1 == ret)
+ {
+ memcpy(ip_address_bin, &addr4, sizeof(addr4));
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Enable or disable given interface.
+ */
+static int
+interface_enable_disable(const char *if_name, bool enable)
+{
+ uint32_t if_index = ~0;
+ int rc = 0;
+
+ SRP_LOG_DBG("%s interface '%s'", enable ? "Enabling" : "Disabling", if_name);
+
+ /* get interface index */
+ rc = ietf_interface_name2index(if_name, &if_index);
+ if (0 != rc) {
+ SRP_LOG_ERR("Invalid interface name: %s", if_name);
+ return SR_ERR_INVAL_ARG;
+ }
+
+ /* enable/disable interface */
+ rc = ietf_setInterfaceFlags(if_index, (uint8_t)enable);
+ if (0 != rc) {
+ SRP_LOG_ERR("Error by processing of the sw_interface_set_flags request, rc=%d", rc);
+ return SR_ERR_OPERATION_FAILED;
+ } else {
+ return SR_ERR_OK;
+ }
+}
+
+/**
+ * @brief Callback to be called by any config change of "/ietf-interfaces:interfaces/interface/enabled" leaf.
+ */
+static int
+ietf_interface_enable_disable_cb(sr_session_ctx_t *session, const char *xpath, sr_notif_event_t event, void *private_ctx)
+{
+ char *if_name = NULL;
+ 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;
+ }
+ SRP_LOG_DBG("'%s' modified, event=%d", xpath, event);
+
+ /* 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;
+ }
+
+ /* 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)))) {
+
+ SRP_LOG_DBG("A change detected in '%s', op=%d", new_val ? new_val->xpath : old_val->xpath, op);
+ if_name = sr_xpath_key_value(new_val ? new_val->xpath : old_val->xpath, "interface", "name", &xpath_ctx);
+ switch (op) {
+ case SR_OP_CREATED:
+ case SR_OP_MODIFIED:
+ op_rc = interface_enable_disable(if_name, new_val->data.bool_val);
+ break;
+ case SR_OP_DELETED:
+ op_rc = interface_enable_disable(if_name, false /* !enable */);
+ break;
+ default:
+ break;
+ }
+ sr_xpath_recover(&xpath_ctx);
+ if (SR_ERR_INVAL_ARG == op_rc) {
+ sr_set_error(session, "Invalid interface name.", new_val ? new_val->xpath : old_val->xpath);
+ }
+ sr_free_val(old_val);
+ sr_free_val(new_val);
+ }
+ sr_free_change_iter(iter);
+
+ return op_rc;
+}
+
+/**
+ * @brief Add or remove IPv4/IPv6 address to/from an interface.
+ */
+static int
+interface_ipv46_config_add_remove(const char *if_name, uint8_t *addr, uint8_t prefix, bool is_ipv6, bool add)
+{
+ uint32_t if_index = ~0;
+ int rc = 0;
+
+ SRP_LOG_DBG("%s IP config on interface '%s'.", add ? "Adding" : "Removing", if_name);
+
+ /* get interface index */
+ rc = ietf_interface_name2index(if_name, &if_index);
+ if (0 != rc) {
+ SRP_LOG_ERR("Invalid interface name: %s", if_name);
+ return SR_ERR_INVAL_ARG;
+ }
+
+ /* add del addr */
+ rc = ietf_interface_add_del_addr(if_index, (uint8_t)add, (uint8_t)is_ipv6, 0, prefix, addr);
+ if (0 != rc) {
+ SRP_LOG_ERR("Error by processing of the sw_interface_set_flags request, rc=%d", rc);
+ return SR_ERR_OPERATION_FAILED;
+ } else {
+ return SR_ERR_OK;
+ }
+}
+int ietf_initSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx)
+{
+ if(dctx == NULL)
+ return -1;
+
+ dctx->intfcArray = NULL;
+ dctx->last_called = false;
+ dctx->capacity = 0;
+ dctx->num_ifs = 0;
+ return 0;
+}
+int ietf_freeSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx)
+{
+ if(dctx == NULL)
+ return -1;
+
+ if(dctx->intfcArray != NULL)
+ {
+ free(dctx->intfcArray);
+ }
+
+ return ietf_initSwInterfaceDumpCTX(dctx);
+}
+vapi_error_e
+ietf_sw_interface_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx,
+ vapi_error_e rv, bool is_last,
+ vapi_payload_sw_interface_details * reply)
+{
+ ietf_sw_interface_dump_ctx *dctx = callback_ctx;
+ if (is_last)
+ {
+ dctx->last_called = true;
+ }
+ else
+ {
+ if(dctx->capacity == 0 && dctx->intfcArray == NULL)
+ {
+ dctx->capacity = 10;
+ dctx->intfcArray = (hicnIntfc*)malloc( sizeof(hicnIntfc)*dctx->capacity );
+ }
+ if(dctx->num_ifs >= dctx->capacity-1)
+ {
+
+ dctx->capacity += 10;
+ dctx->intfcArray = (hicnIntfc*)realloc(dctx->intfcArray, sizeof(hicnIntfc)*dctx->capacity );
+ }
+
+ hicnIntfc * thisIntfc = &dctx->intfcArray[dctx->num_ifs];
+
+ thisIntfc->sw_if_index = reply->sw_if_index;
+ memcpy(thisIntfc->interface_name, reply->interface_name, VPP_INTFC_NAME_LEN);
+ thisIntfc->l2_address_length = reply->l2_address_length;
+ memcpy(thisIntfc->l2_address, reply->l2_address, reply->l2_address_length );
+ //thisIntfc->link_speed = reply->link_speed;
+#define ONE_MEGABIT (uint64_t)1000000
+ switch (reply->link_speed << VNET_HW_INTERFACE_FLAG_SPEED_SHIFT)
+ {
+ default:
+ thisIntfc->link_speed = 0;
+ break;
+ }
+
+ thisIntfc->link_mtu = reply->link_mtu;
+ thisIntfc->admin_up_down = reply->admin_up_down;
+ thisIntfc->link_up_down = reply->link_up_down;
+
+ dctx->num_ifs += 1;
+ }
+ return VAPI_OK;
+}
+
+static i32 ietf_interface_name2index(const char *name, u32* if_index)
+{
+ ARG_CHECK2(-1, name, if_index);
+
+ i32 ret = -1;
+ ietf_sw_interface_dump_ctx dctx = {false, 0, 0, 0};
+ vapi_msg_sw_interface_dump *dump;
+ vapi_error_e rv;
+ dctx.last_called = false;
+
+ dump = vapi_alloc_sw_interface_dump(g_vapi_ctx_instance);
+ dump->payload.name_filter_valid = true;
+ memcpy(dump->payload.name_filter, name, sizeof(dump->payload.name_filter));
+
+ while (VAPI_EAGAIN == (rv = vapi_sw_interface_dump(g_vapi_ctx_instance, dump, ietf_sw_interface_dump_cb, &dctx)))
+ ;
+
+ int i = 0;
+ for (; i < dctx.num_ifs; ++i)
+ {
+ if (strcmp(dctx.intfcArray[i].interface_name, name) == 0)
+ {
+ *if_index = dctx.intfcArray[i].sw_if_index;
+ ret = 0;
+ break;
+ }
+ }
+ ietf_freeSwInterfaceDumpCTX(&dctx);
+
+ return ret;
+}
+
+i32 ietf_interface_add_del_addr( u32 sw_if_index, u8 is_add, u8 is_ipv6, u8 del_all,
+ u8 address_length, u8 address[VPP_IP6_ADDRESS_LEN] )
+{
+ i32 ret = -1;
+ vapi_msg_sw_interface_add_del_address *msg = vapi_alloc_sw_interface_add_del_address(g_vapi_ctx_instance);
+ msg->payload.sw_if_index = sw_if_index;
+ msg->payload.is_add = is_add;
+ msg->payload.is_ipv6 = is_ipv6;
+ msg->payload.del_all = del_all;
+ msg->payload.address_length = address_length;
+ memcpy(msg->payload.address, address, VPP_IP6_ADDRESS_LEN);
+ vapi_msg_sw_interface_add_del_address_hton (msg);
+
+ vapi_send (g_vapi_ctx_instance, msg);
+
+ vapi_msg_sw_interface_add_del_address_reply *resp;
+
+ HICN_VPP_VAPI_RECV;
+
+ vapi_msg_sw_interface_add_del_address_reply_hton(resp);
+ ret = resp->payload.retval;
+ vapi_msg_free (g_vapi_ctx_instance, resp);
+ return ret;
+}
+
+i32 ietf_setInterfaceFlags(u32 sw_if_index, u8 admin_up_down)
+{
+ i32 ret = -1;
+ vapi_msg_sw_interface_set_flags *msg = vapi_alloc_sw_interface_set_flags(g_vapi_ctx_instance);
+ msg->payload.sw_if_index = sw_if_index;
+ msg->payload.admin_up_down = admin_up_down;
+ vapi_msg_sw_interface_set_flags_hton (msg);
+
+ vapi_send (g_vapi_ctx_instance, msg);
+
+ vapi_msg_sw_interface_set_flags_reply *resp;
+
+ HICN_VPP_VAPI_RECV;
+
+ vapi_msg_sw_interface_set_flags_reply_ntoh(resp);
+ ret = resp->payload.retval;
+ vapi_msg_free (g_vapi_ctx_instance, resp);
+ return ret;
+}
+
+
+/**
+ * @brief Modify existing IPv4/IPv6 config on an interface.
+ */
+static int
+interface_ipv46_config_modify(sr_session_ctx_t *session, const char *if_name,
+ sr_val_t *old_val, sr_val_t *new_val, bool is_ipv6)
+{
+ sr_xpath_ctx_t xpath_ctx = { 0, };
+ char *addr_str = NULL;
+ uint8_t addr[16] = { 0, };
+ uint8_t prefix = 0;
+ int rc = SR_ERR_OK;
+
+ SRP_LOG_DBG("Updating IP config on interface '%s'.", if_name);
+
+ /* get old config to be deleted */
+ if (SR_UINT8_T == old_val->type) {
+ prefix = old_val->data.uint8_val;
+ } else if (SR_STRING_T == old_val->type) {
+ prefix = netmask_to_prefix(old_val->data.string_val);
+ } else {
+ return SR_ERR_INVAL_ARG;
+ }
+ addr_str = sr_xpath_key_value((char*)old_val->xpath, "address", "ip", &xpath_ctx);
+ ip_addr_str_to_binary(addr_str, addr, is_ipv6);
+ sr_xpath_recover(&xpath_ctx);
+
+ /* delete old IP config */
+ rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, false /* remove */);
+ if (SR_ERR_OK != rc) {
+ SRP_LOG_ERR("Unable to remove old IP address config, rc=%d", rc);
+ return rc;
+ }
+
+ /* update the config with the new value */
+ if (sr_xpath_node_name_eq(new_val->xpath, "prefix-length")) {
+ prefix = new_val->data.uint8_val;
+ } else if (sr_xpath_node_name_eq(new_val->xpath, "netmask")) {
+ prefix = netmask_to_prefix(new_val->data.string_val);
+ }
+
+ /* set new IP config */
+ rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */);
+ if (SR_ERR_OK != rc) {
+ SRP_LOG_ERR("Unable to remove old IP address config, rc=%d", rc);
+ return rc;
+ }
+
+ return rc;
+}
+
+/**
+ * @brief Callback to be called by any config change in subtrees "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address"
+ * or "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address".
+ */
+static int
+ietf_interface_ipv46_address_change_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, };
+ bool is_ipv6 = false, has_addr = false, has_prefix = false;
+ uint8_t addr[16] = { 0, };
+ uint8_t prefix = 0;
+ char *node_name = NULL, *if_name = NULL;
+ 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;
+ }
+ SRP_LOG_DBG("'%s' modified, event=%d", xpath, event);
+
+ /* check whether we are handling ipv4 or ipv6 config */
+ node_name = sr_xpath_node_idx((char*)xpath, 2, &xpath_ctx);
+ if (NULL != node_name && 0 == strcmp(node_name, "ipv6")) {
+ is_ipv6 = true;
+ }
+ sr_xpath_recover(&xpath_ctx);
+
+ /* 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;
+ }
+
+ /* 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)))) {
+
+ SRP_LOG_DBG("A change detected in '%s', op=%d", new_val ? new_val->xpath : old_val->xpath, op);
+ if_name = strdup(sr_xpath_key_value(new_val ? new_val->xpath : old_val->xpath, "interface", "name", &xpath_ctx));
+ sr_xpath_recover(&xpath_ctx);
+
+ switch (op) {
+ case SR_OP_CREATED:
+ if (SR_LIST_T == new_val->type) {
+ /* create on list item - reset state vars */
+ has_addr = has_prefix = false;
+ } else {
+ if (sr_xpath_node_name_eq(new_val->xpath, "ip")) {
+ ip_addr_str_to_binary(new_val->data.string_val, addr, is_ipv6);
+ has_addr = true;
+ } else if (sr_xpath_node_name_eq(new_val->xpath, "prefix-length")) {
+ prefix = new_val->data.uint8_val;
+ has_prefix = true;
+ } else if (sr_xpath_node_name_eq(new_val->xpath, "netmask")) {
+ prefix = netmask_to_prefix(new_val->data.string_val);
+ has_prefix = true;
+ }
+ if (has_addr && has_prefix) {
+ op_rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */);
+ }
+ }
+ break;
+ case SR_OP_MODIFIED:
+ op_rc = interface_ipv46_config_modify(session, if_name, old_val, new_val, is_ipv6);
+ break;
+ case SR_OP_DELETED:
+ if (SR_LIST_T == old_val->type) {
+ /* delete on list item - reset state vars */
+ has_addr = has_prefix = false;
+ } else {
+ if (sr_xpath_node_name_eq(old_val->xpath, "ip")) {
+ ip_addr_str_to_binary(old_val->data.string_val, addr, is_ipv6);
+ has_addr = true;
+ } else if (sr_xpath_node_name_eq(old_val->xpath, "prefix-length")) {
+ prefix = old_val->data.uint8_val;
+ has_prefix = true;
+ } else if (sr_xpath_node_name_eq(old_val->xpath, "netmask")) {
+ prefix = netmask_to_prefix(old_val->data.string_val);
+ has_prefix = true;
+ }
+ if (has_addr && has_prefix) {
+ op_rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, false /* !add */);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (SR_ERR_INVAL_ARG == op_rc) {
+ sr_set_error(session, "Invalid interface name.", new_val ? new_val->xpath : old_val->xpath);
+ }
+ free(if_name);
+ sr_free_val(old_val);
+ sr_free_val(new_val);
+ }
+ sr_free_change_iter(iter);
+
+ return op_rc;
+}
+
+/**
+ * @brief Callback to be called by any config change under "/ietf-interfaces:interfaces-state/interface" path.
+ * Does not provide any functionality, needed just to cover not supported config leaves.
+ */
+static int
+ietf_interface_change_cb(sr_session_ctx_t *session, const char *xpath, sr_notif_event_t event, void *private_ctx)
+{
+ SRP_LOG_DBG("'%s' modified, event=%d", xpath, event);
+
+ return SR_ERR_OK;
+}
+
+
+int ietf_subscribe_events(sr_session_ctx_t *session,
+ sr_subscription_ctx_t **subscription){
+
+ int rc = SR_ERR_OK;
+ SRP_LOG_DBG_MSG("Subscriging ietf.");
+
+ //
+ rc = sr_subtree_change_subscribe(session, "/ietf-interfaces:interfaces/interface", ietf_interface_change_cb,
+ NULL,
+ 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, subscription);
+
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /ietf-interfaces:interfaces/interface\n");
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(session, "/ietf-interfaces:interfaces/interface/enabled", ietf_interface_enable_disable_cb,
+ NULL,
+ 100, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /ietf-interfaces:interfaces/interface/enabled\n");
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(session, "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address", ietf_interface_ipv46_address_change_cb,
+ NULL,
+ 99, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, subscription);
+
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address\n");
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(session, "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address", ietf_interface_ipv46_address_change_cb,
+ NULL,
+ 98, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, subscription);
+
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address\n");
+ goto error;
+ }
+
+ /* rc = sr_dp_get_items_subscribe(session, "/ietf-interfaces:interfaces-state", ietf_interface_state_cb,
+ NULL, SR_SUBSCR_CTX_REUSE,
+ subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /ietf-interfaces:interfaces-state\n");
+ goto error;
+ }*/
+
+
+ SRP_LOG_INF_MSG("ietf initialized successfully.");
+ return SR_ERR_OK;
+
+ error:
+ SRP_LOG_ERR_MSG("Error by initialization of the ietf.");
+ return rc;
+}
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.h b/utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.h
new file mode 100644
index 000000000..dec789853
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018 HUACHENTEL 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 __IETF_INTERFACE_H__
+#define __IETF_INTERFACE_H__
+
+//#include "../sc_model.h"
+
+int ietf_subscribe_events(sr_session_ctx_t *session,
+ sr_subscription_ctx_t **subscription);
+
+
+#endif /* __IETF_INTERFACE_H__ */
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c b/utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
new file mode 100644
index 000000000..340d403fb
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
@@ -0,0 +1,1323 @@
+/*
+ * 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 <stdio.h>
+#include <malloc.h>
+#include <sysrepo/xpath.h>
+#include <inttypes.h>
+/* Hicn headers */
+
+#include <vapi/hicn.api.vapi.h>
+#include <hicn/api/ip_address.h>
+#include "../hicn_plugin.h"
+#include "../hicn_vpp_comm.h"
+#include "hicn_model.h"
+#include "tlock.h"
+
+
+//vapi_ctx_t g_vapi_ctx_instance=NULL;
+
+// 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/n_strategies");
+ vals[0].type = SR_UINT8_T;
+ vals[0].data.uint8_val = hicn_strategies->n_strategies;
+
+ sr_val_set_xpath(&vals[1], "/hicn:hicn-state/strategies/strategy_id");
+ vals[1].type = SR_UINT32_T;
+ vals[1].data.uint32_val = hicn_strategies->strategy_id[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);
+ face_ip_params_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) {
+
+ SRP_LOG_DBG_MSG("hicn node parameter received successfully");
+ 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+
+ 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);
+
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ SRP_LOG_DBG("Pit Max entries: %d",resp->payload.pit_max_size);
+ return SR_ERR_OK;
+ }
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn status received successfully");
+ vapi_msg_hicn_api_node_stats_get *msg;
+ vapi_msg_hicn_api_node_stats_get_reply *resp;
+ enum locks_name state;
+ state=lstate;
+
+ //vapi_msg_id_hicn_api_node_stats_get=103;
+ 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);
+
+ if(resp->payload.retval){
+ SRP_LOG_DBG_MSG("Error updating state");
+ return SR_ERR_OPERATION_FAILED;
+ }
+ Ticket_Lock(state);
+ // hicn_state = (hicn_state_t *) resp->payload;
+ hicn_state->pkts_processed = resp->payload.pkts_processed;
+ hicn_state->pkts_interest_count = resp->payload.pkts_interest_count;
+ hicn_state->pkts_data_count = resp->payload.pkts_data_count;
+ hicn_state->pkts_from_cache_count = resp->payload.pkts_from_cache_count;
+ hicn_state->pkts_no_pit_count = resp->payload.pkts_no_pit_count;
+ hicn_state->pit_expired_count = resp->payload.pit_expired_count;
+ hicn_state->cs_expired_count = resp->payload.cs_expired_count;
+ hicn_state->cs_lru_count = resp->payload.cs_lru_count;
+ hicn_state->pkts_drop_no_buf = resp->payload.pkts_drop_no_buf;
+ hicn_state->interests_aggregated = resp->payload.interests_aggregated;
+ hicn_state->interests_retx = resp->payload.interests_retx;
+ // hicn_state->interests_hash_collision = resp->payload.interests_hash_collision;
+ hicn_state->pit_entries_count = resp->payload.pit_entries_count;
+ hicn_state->cs_entries_count = resp->payload.cs_entries_count;
+ hicn_state->cs_entries_ntw_count = resp->payload.cs_entries_ntw_count;
+ Ticket_Unlock(state);
+
+ 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) {
+
+ SRP_LOG_DBG_MSG("hicn strategy receive successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+ msg->payload.strategy_id = input[0].data.uint32_val;
+
+ vapi_msg_hicn_api_strategy_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_strategy_get_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn strategies received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+ 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);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn route receive successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix[0],temp,4);
+
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix[0],temp,8);
+ memcpy(&msg->payload.prefix[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+
+
+ msg->payload.len = input[2].data.uint8_val;
+
+ vapi_msg_hicn_api_route_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_route_get_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn route nhops add received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+ vapi_msg_hicn_api_route_nhops_add_hton(msg);
+
+
+
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix[0],temp,4);
+
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix[0],temp,8);
+ memcpy(&msg->payload.prefix[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+
+
+
+
+ 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);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn route del received successfully");
+ // 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);
+
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix[0],temp,4);
+
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix[0],temp,8);
+ memcpy(&msg->payload.prefix[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+
+ msg->payload.len = input[2].data.uint8_val;
+
+ vapi_msg_hicn_api_route_del_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_route_del_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn face ip params get received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+ msg->payload.faceid = input[0].data.uint16_val;
+
+ vapi_msg_hicn_api_face_ip_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_face_ip_params_get_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn punting add received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix[0],temp,4);
+
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp =(unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix[0],temp,8);
+ memcpy(&msg->payload.prefix[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+ msg->payload.len = input[2].data.uint8_val;
+ msg->payload.swif = input[3].data.uint32_val;
+
+
+ vapi_msg_hicn_api_punting_add_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_punting_add_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn route nhop del received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix[0],temp,4);
+
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix[0],temp,8);
+ memcpy(&msg->payload.prefix[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+
+ 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);
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn punting del received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+
+
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix[0],temp,4);
+
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix[0],temp,8);
+ memcpy(&msg->payload.prefix[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+
+
+
+
+
+
+ msg->payload.len = input[2].data.uint8_val;
+ msg->payload.swif = input[3].data.uint32_val;
+
+ vapi_msg_hicn_api_punting_del_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_punting_del_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn face ip del received successfully");
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+ msg->payload.faceid = input[0].data.uint16_val;
+
+ vapi_msg_hicn_api_face_ip_del_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_face_ip_del_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG_MSG("Successfully Done");
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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) {
+
+ SRP_LOG_DBG_MSG("hicn face ip add received successfully");
+
+ // 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);
+ SRP_LOG_DBG("msg id:%d",msg->header._vl_msg_id);
+ if(strcmp(input[0].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *) &sa.sin_addr.s_addr;
+ memcpy(&msg->payload.local_addr[0],temp,4);
+
+ }else if(strcmp(input[1].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[1].data.string_val, dst);
+ unsigned char * temp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.local_addr[0],temp,8);
+ memcpy(&msg->payload.local_addr[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+ if(strcmp(input[2].data.string_val,"-1")){
+
+ struct sockaddr_in sa;
+ // store this IP address in sa:
+ inet_pton(AF_INET, input[2].data.string_val, &(sa.sin_addr));
+ unsigned char * temp = (unsigned char *)&sa.sin_addr.s_addr;
+ memcpy(&msg->payload.remote_addr[0],temp,4);
+
+
+ }else if(strcmp(input[3].data.string_val,"-1")){
+
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, input[3].data.string_val, dst);
+ unsigned char * temp =(unsigned char *) ((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.remote_addr[0],temp,8);
+ memcpy(&msg->payload.remote_addr[1],temp+8,8);
+
+ }else{
+ SRP_LOG_DBG_MSG("Invalid local IP address");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+ msg->payload.swif = input[4].data.uint32_val; // This is the idx number of interface
+
+ vapi_msg_hicn_api_face_ip_add_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_face_ip_add_reply_ntoh(resp);
+
+ if(!resp->payload.retval){
+ SRP_LOG_DBG("Successfully Done return faceid: %d",resp->payload.faceid);
+ return SR_ERR_OK;
+ }
+
+ SRP_LOG_DBG_MSG("Operation Failed");
+ return SR_ERR_OPERATION_FAILED;
+}
+
+/**
+ * @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("Subscriging hicn.");
+
+
+ //Initializing the locks
+ for (int i=0; i<NLOCKS; i++)
+ Ticket_init(i,LOCK_INIT);
+
+ //Initializing the buffer
+ rc=init_buffer();
+ if(rc!= SR_ERR_OK){
+ SRP_LOG_DBG_MSG("Problem in initializing the buffers\n"); goto error;
+ }
+
+
+
+ // node state subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:node-params-get", hicn_node_params_get_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription stat-get\n");
+ goto error;
+ }
+
+
+ // node state subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:node-stat-get", hicn_node_stat_get_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription stat-get\n");
+ goto error;
+ }
+
+ // strategies subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:strategy-get", hicn_strategy_get_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription strategy-get\n");
+ goto error;
+ }
+
+ rc = sr_rpc_subscribe(session, "/hicn:strategies-get",
+ hicn_strategies_get_cb, session, SR_SUBSCR_CTX_REUSE, subscription); if (rc
+ != SR_ERR_OK) { SRP_LOG_DBG_MSG("Problem in subscription strategies-get\n"); goto error;
+ }
+
+ // route subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:route-get", hicn_route_get_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription route-get\n");
+ goto error;
+ }
+
+ rc = sr_rpc_subscribe(session, "/hicn:route-del", hicn_route_del_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription route-del\n");
+ goto error;
+ }
+
+
+ // route nhops subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:route-nhops-add",
+ hicn_route_nhops_add_cb, session, SR_SUBSCR_CTX_REUSE, subscription); if (rc
+ != SR_ERR_OK) { SRP_LOG_DBG_MSG("Problem in subscription route-get\n"); goto error;
+ }
+
+ rc = sr_rpc_subscribe(session, "/hicn:route-nhops-del",
+ hicn_route_nhops_del_cb, session, SR_SUBSCR_CTX_REUSE, subscription); if (rc
+ != SR_ERR_OK) { SRP_LOG_DBG_MSG("Problem in subscription route-nhops-del\n"); goto
+ error;
+ }
+
+
+ // face ip subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:face-ip-params-get",
+ hicn_face_ip_params_get_cb, session, SR_SUBSCR_CTX_REUSE, subscription); if
+ (rc != SR_ERR_OK) { SRP_LOG_DBG_MSG("Problem in subscription face-ip-params-get\n");
+ goto error;
+ }
+
+
+ rc = sr_rpc_subscribe(session, "/hicn:face-ip-add", hicn_face_ip_add_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription face-ip-add\n");
+ goto error;
+ }
+
+ rc = sr_rpc_subscribe(session, "/hicn:face-ip-del", hicn_face_ip_del_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription face-ip-del\n");
+ goto error;
+ }
+
+ // punting subscriptions
+
+ rc = sr_rpc_subscribe(session, "/hicn:punting-add", hicn_punting_add_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription); if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription punting-add\n");
+ goto error;
+ }
+
+ rc = sr_rpc_subscribe(session, "/hicn:punting-del", hicn_punting_del_cb,
+ session, SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription punting-del\n");
+ goto error;
+ }
+
+ rc = sr_subtree_change_subscribe(
+ session, "/hicn:hicn-conf", hicn_node_params_set_cb, g_vapi_ctx_instance,
+ 100, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, subscription);
+ if (SR_ERR_OK != rc) {
+ SRP_LOG_DBG_MSG("Problem in subscription /hicn:hicn-conf\n");
+ goto error;
+ }
+
+ // subscribe as hicn state data provider
+ rc = sr_dp_get_items_subscribe(session, "/hicn:hicn-state/states",
+ hicn_state_states_cb, NULL, SR_SUBSCR_CTX_REUSE,
+ subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /hicn:hicn-state/states\n");
+ goto error;
+ }
+
+
+
+ rc = sr_dp_get_items_subscribe(session, "/hicn:hicn-state/strategy",
+ hicn_state_strategy_cb, NULL, SR_SUBSCR_CTX_REUSE,
+ subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /hicn:hicn-state/strategy\n");
+ goto error;
+ }
+
+
+
+ rc = sr_dp_get_items_subscribe(session, "/hicn:hicn-state/strategies",
+ hicn_state_strategies_cb, NULL, SR_SUBSCR_CTX_REUSE,
+ subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /hicn:hicn-state/strategies\n");
+ goto error;
+ }
+
+
+ rc = sr_dp_get_items_subscribe(session, "/hicn:hicn-state/route",
+ hicn_state_route_cb, NULL, SR_SUBSCR_CTX_REUSE,
+ subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /hicn:hicn-state/route\n");
+ goto error;
+ }
+
+
+ rc = sr_dp_get_items_subscribe(session, "/hicn:hicn-state/face-ip-params",
+ hicn_state_face_ip_params_cb, NULL, SR_SUBSCR_CTX_REUSE,
+ subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBG_MSG("Problem in subscription /hicn:hicn-state/face-ip-params\n");
+ goto error;
+ }
+
+
+ SRP_LOG_INF_MSG("hicn plugin initialized successfully.");
+ return SR_ERR_OK;
+
+error:
+ SRP_LOG_ERR_MSG("Error by initialization of the hicn plugin.");
+ sr_plugin_cleanup_cb(session, &g_vapi_ctx_instance);
+ return rc;
+} \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.h b/utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.h
new file mode 100644
index 000000000..1f5acabc5
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.h
@@ -0,0 +1,90 @@
+/*
+ * 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 __IETF_HICN_H__
+#define __IETF_HICN_H__
+
+#include "../hicn_vpp_comm.h"
+
+
+#define MEM_ALIGN 4096
+
+// Number of locks is equal to number of nodes in hicn-state
+// It is a coarse grain approach later can be changed to fine grained
+// better to initialize the lock by 0
+#define NLOCKS 5
+#define LOCK_INIT 0
+
+
+enum locks_name {lstate, lstrategy, lstrategies, lroute, lface_ip_params};
+
+#define NSTATE_LEAVES 15
+#define NSTRATEGY_LEAVES 1
+#define NSTRATEGIES_LEAVES 2
+#define NROUTE_LEAVES 2
+#define NFACE_IP_PARAMS_LEAVES 3
+
+
+typedef struct __attribute__ ((__packed__)) {
+
+ uint64_t pkts_processed;
+ uint64_t pkts_interest_count;
+ uint64_t pkts_data_count;
+ uint64_t pkts_from_cache_count;
+ uint64_t pkts_no_pit_count;
+ uint64_t pit_expired_count;
+ uint64_t cs_expired_count;
+ uint64_t cs_lru_count;
+ uint64_t pkts_drop_no_buf;
+ uint64_t interests_aggregated;
+ uint64_t interests_retx;
+ uint64_t interests_hash_collision;
+ uint64_t pit_entries_count;
+ uint64_t cs_entries_count;
+ uint64_t cs_entries_ntw_count;
+ int32_t retval;
+
+} hicn_state_t;
+
+typedef struct __attribute__ ((__packed__)) {
+ uint8_t description[200];
+ int32_t retval;
+} hicn_strategy_t;
+
+
+typedef struct __attribute__ ((__packed__)) {
+
+ uint8_t n_strategies;
+ uint32_t strategy_id[256];
+ int32_t retval;
+} hicn_strategies_t;
+
+typedef struct __attribute__ ((__packed__)) {
+ uint16_t faceids[1000];
+ uint32_t strategy_id;
+ int32_t retval;
+} hicn_route_t;
+
+typedef struct __attribute__ ((__packed__)) {
+ uint64_t nh_addr[2];
+ uint32_t swif;
+ uint32_t flags;
+ int32_t retval;
+} hicn_face_ip_params_t;
+
+int hicn_subscribe_events(sr_session_ctx_t *session,
+ sr_subscription_ctx_t **subscription);
+
+#endif /* __IETF_HICN_H__ */ \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/model/tlock.c b/utils/sysrepo-plugins/hicn-plugin/plugin/model/tlock.c
new file mode 100644
index 000000000..d870adf75
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-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-plugins/hicn-plugin/plugin/model/tlock.h b/utils/sysrepo-plugins/hicn-plugin/plugin/model/tlock.h
new file mode 100644
index 000000000..36698115a
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-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 5
+
+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-plugins/hicn-plugin/plugin/yang/controler_rpcs_instances.xml b/utils/sysrepo-plugins/hicn-plugin/plugin/yang/controler_rpcs_instances.xml
new file mode 100644
index 000000000..f497f0193
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/yang/controler_rpcs_instances.xml
@@ -0,0 +1,76 @@
+<node-params-get xmlns="urn:sysrepo:hicn"/>
+
+<node-stat-get xmlns="urn:sysrepo:hicn"/>
+
+<strategy-get xmlns="urn:sysrepo:hicn">
+ <strategy_id>0</strategy_id>
+</strategy-get>
+
+<strategies-get xmlns="urn:sysrepo:hicn"/>
+
+
+<route-get xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.1.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+</route-get>
+
+<route-del xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.1.1</ip4>
+ <ip6>-1</ip6>
+ <len>30</len>
+</route-del>
+
+<route-nhops-add xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.1.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <face_ids0>0</face_ids0>
+ <face_ids1>0</face_ids1>
+ <face_ids2>0</face_ids2>
+ <face_ids3>0</face_ids3>
+ <face_ids4>0</face_ids4>
+ <face_ids5>0</face_ids5>
+ <face_ids6>0</face_ids6>
+ <n_faces>1</n_faces>
+</route-nhops-add>
+
+<route-nhops-del xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.1.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <faceid>0</faceid>
+</route-nhops-del>
+
+
+<face-ip-params-get xmlns="urn:sysrepo:hicn">
+ <faceid>10</faceid>
+</face-ip-params-get>
+
+<face-ip-add xmlns="urn:sysrepo:hicn">
+ <lip4>192.168.1.10</lip4>
+ <lip6>-1</lip6>
+ <rip4>192.168.1.1</rip4>
+ <rip6>-1</rip6>
+ <swif>0</swif>
+</face-ip-add>
+
+
+<face-ip-del xmlns="urn:sysrepo:hicn">
+ <faceid>0</faceid>
+</face-ip-del>
+
+<punting-add xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.0.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <swif>0</swif>
+</punting-add>
+
+
+<punting-del xmlns="urn:sysrepo:hicn">
+ <ip4>192.168.0.1</ip4>
+ <ip6>-1</ip6>
+ <len>24</len>
+ <swif>0</swif>
+</punting-del> \ No newline at end of file
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/yang/model/hicn.yang b/utils/sysrepo-plugins/hicn-plugin/plugin/yang/model/hicn.yang
new file mode 100644
index 000000000..eddf31c98
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/yang/model/hicn.yang
@@ -0,0 +1,536 @@
+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 lip4 {
+ description "IP version 4 local address.";
+ type string;
+ }
+
+leaf lip6 {
+ description "IP version 6 local address.";
+ type string;
+ }
+
+leaf rip4 {
+ description "IP version 4 local address.";
+ type string;
+ }
+
+leaf rip6 {
+ description "IP version 6 local address.";
+ type string;
+ }
+
+leaf swif {
+ description "Interface Index.";
+ type uint32;
+ }
+}
+
+grouping route_nhops_add {
+
+leaf ip4 {
+ description "ip4 to be added to the FIB.";
+ type string;
+ }
+
+leaf ip6 {
+ description "ip6 to be added to the FIB.";
+ type string;
+ }
+
+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 ip4 {
+ description "ip4 to be added to the FIB.";
+ type string;
+ }
+
+leaf ip6 {
+ description "ip6 to be added to the FIB.";
+ type string;
+ }
+
+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_del {
+
+leaf ip4 {
+ description "ip4 to be added to the FIB.";
+ type string;
+ }
+
+leaf ip6 {
+ description "ip6 to be added to the FIB.";
+ type string;
+ }
+
+leaf len {
+ description "Length of the prefix.";
+ type uint8;
+ }
+}
+
+
+grouping route_get {
+
+
+leaf ip4 {
+ description "ip4 to be added to the FIB.";
+ type string;
+ }
+
+leaf ip6 {
+ description "ip6 to be added to the FIB.";
+ type string;
+ }
+
+leaf len {
+ description "Length of the prefix.";
+ type uint8;
+ }
+}
+
+grouping punting_add {
+
+leaf ip4 {
+ description "ip4 to be added to the FIB.";
+ type string;
+ }
+
+leaf ip6 {
+ description "ip6 to be added to the FIB.";
+ type string;
+ }
+
+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*/
+ }
+}
+
+}
diff --git a/utils/sysrepo-plugins/hicn-plugin/plugin/yang/startup.xml b/utils/sysrepo-plugins/hicn-plugin/plugin/yang/startup.xml
new file mode 100644
index 000000000..f88e13ea2
--- /dev/null
+++ b/utils/sysrepo-plugins/hicn-plugin/plugin/yang/startup.xml
@@ -0,0 +1,11 @@
+<hicn-conf xmlns="urn:sysrepo:hicn">
+<params>
+ <enable_disable>false</enable_disable>
+ <pit_max_size>-1</pit_max_size>
+ <cs_max_size>-1</cs_max_size>
+ <cs_reserved_app>-1</cs_reserved_app>
+ <pit_dflt_lifetime_sec>-1</pit_dflt_lifetime_sec>
+ <pit_max_lifetime_sec>-1</pit_max_lifetime_sec>
+ <pit_min_lifetime_sec>-1</pit_min_lifetime_sec>
+</params>
+</hicn-conf> \ No newline at end of file