From 18561adfde80d6665e24262d70d18f916e2662e5 Mon Sep 17 00:00:00 2001 From: YohanPipereau Date: Mon, 15 Jul 2019 15:37:46 +0200 Subject: vom: migration from scvpp to vom Change-Id: I79609f0bee9b8307da0d9bf704babe8ba06dba4d Signed-off-by: YohanPipereau Co-authored-by: Pavel Kotucek Co-authored-by: Andrej Kozemcak --- Makefile | 80 +- README.md | 2 - samples/ietf-interfaces/create-if.json | 11 + samples/ietf-nat/create-instance.xml | 11 + samples/ietf-nat/create-mapping.xml | 19 + samples/openconfig-interfaces/create-if.json | 13 + .../create-prefix-entry.json | 11 + scripts/Dockerfile | 12 +- scripts/run_test.sh | 1 - src/CMakeLists.txt | 5 +- src/cmake/FindVPP.cmake | 21 + src/plugins/CMakeLists.txt | 31 +- src/plugins/ietf/ietf_interface.c | 570 --------- src/plugins/ietf/ietf_interface.cpp | 613 +++++++++ src/plugins/ietf/ietf_nat.c | 525 -------- src/plugins/ietf/ietf_nat.cpp | 336 +++++ src/plugins/openconfig/openconfig_interfaces.c | 646 ---------- src/plugins/openconfig/openconfig_interfaces.cpp | 309 +++++ src/plugins/openconfig/openconfig_local_routing.c | 548 -------- src/plugins/sc_plugins.c | 157 ++- src/plugins/sc_plugins.h | 18 +- src/plugins/sys_util.cpp | 61 + src/plugins/sys_util.h | 271 ++-- src/plugins/vpp-oper/interface.cpp | 39 + src/plugins/vpp-oper/interface.hpp | 33 + src/plugins/yang/ietf/ietf-ip@2018-02-22.yang | 876 ------------- .../yang/openconfig/openconfig-acl@2018-11-21.yang | 847 ------------- .../openconfig-extensions@2017-04-11.yang | 91 -- .../openconfig-if-aggregate@2018-03-23.yang | 223 ---- .../openconfig-if-ethernet@2018-09-04.yang | 428 ------- .../openconfig/openconfig-if-ip@2018-01-05.yang | 1312 -------------------- .../openconfig/openconfig-if-types@2018-01-05.yang | 98 -- .../openconfig-inet-types@2018-11-21.yang | 343 ----- .../openconfig-local-routing@2017-05-15.yang | 408 ------ .../openconfig-packet-match-types@2018-11-21.yang | 309 ----- .../openconfig-packet-match@2018-11-21.yang | 371 ------ .../openconfig-policy-types@2018-06-05.yang | 220 ---- .../openconfig-vlan-types@2018-02-14.yang | 195 --- .../openconfig/openconfig-vlan@2018-06-05.yang | 438 ------- src/scvpp/CMakeLists.txt | 101 -- src/scvpp/inc/scvpp/comm.h | 245 ---- src/scvpp/inc/scvpp/interface.h | 69 - src/scvpp/inc/scvpp/ip.h | 77 -- src/scvpp/inc/scvpp/nat.h | 61 - src/scvpp/inc/scvpp/v3po.h | 54 - src/scvpp/libscvpp.pc.in | 10 - src/scvpp/src/comm.c | 191 --- src/scvpp/src/interface.c | 182 --- src/scvpp/src/ip.c | 259 ---- src/scvpp/src/nat.c | 294 ----- src/scvpp/src/v3po.c | 89 -- src/scvpp/tests/CMakeLists.txt | 42 - src/scvpp/tests/scvpp_iface_test.c | 130 -- src/scvpp/tests/scvpp_ip_test.c | 184 --- src/scvpp/tests/scvpp_nat_test.c | 173 --- src/scvpp/tests/scvpp_test.c | 109 -- src/scvpp/tests/scvpp_test.h | 31 - 57 files changed, 1774 insertions(+), 11029 deletions(-) create mode 100644 samples/ietf-interfaces/create-if.json create mode 100644 samples/ietf-nat/create-instance.xml create mode 100644 samples/ietf-nat/create-mapping.xml create mode 100644 samples/openconfig-interfaces/create-if.json create mode 100644 samples/openconfig-local-routing/create-prefix-entry.json delete mode 100644 src/plugins/ietf/ietf_interface.c create mode 100644 src/plugins/ietf/ietf_interface.cpp delete mode 100644 src/plugins/ietf/ietf_nat.c create mode 100644 src/plugins/ietf/ietf_nat.cpp delete mode 100644 src/plugins/openconfig/openconfig_interfaces.c create mode 100644 src/plugins/openconfig/openconfig_interfaces.cpp delete mode 100644 src/plugins/openconfig/openconfig_local_routing.c create mode 100644 src/plugins/sys_util.cpp create mode 100644 src/plugins/vpp-oper/interface.cpp create mode 100644 src/plugins/vpp-oper/interface.hpp delete mode 100644 src/plugins/yang/ietf/ietf-ip@2018-02-22.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-acl@2018-11-21.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-extensions@2017-04-11.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-if-aggregate@2018-03-23.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-if-ethernet@2018-09-04.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-if-ip@2018-01-05.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-if-types@2018-01-05.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-inet-types@2018-11-21.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-local-routing@2017-05-15.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-packet-match-types@2018-11-21.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-packet-match@2018-11-21.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-policy-types@2018-06-05.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-vlan-types@2018-02-14.yang delete mode 100644 src/plugins/yang/openconfig/openconfig-vlan@2018-06-05.yang delete mode 100644 src/scvpp/CMakeLists.txt delete mode 100644 src/scvpp/inc/scvpp/comm.h delete mode 100644 src/scvpp/inc/scvpp/interface.h delete mode 100644 src/scvpp/inc/scvpp/ip.h delete mode 100644 src/scvpp/inc/scvpp/nat.h delete mode 100644 src/scvpp/inc/scvpp/v3po.h delete mode 100644 src/scvpp/libscvpp.pc.in delete mode 100644 src/scvpp/src/comm.c delete mode 100644 src/scvpp/src/interface.c delete mode 100644 src/scvpp/src/ip.c delete mode 100644 src/scvpp/src/nat.c delete mode 100644 src/scvpp/src/v3po.c delete mode 100644 src/scvpp/tests/CMakeLists.txt delete mode 100644 src/scvpp/tests/scvpp_iface_test.c delete mode 100644 src/scvpp/tests/scvpp_ip_test.c delete mode 100644 src/scvpp/tests/scvpp_nat_test.c delete mode 100644 src/scvpp/tests/scvpp_test.c delete mode 100644 src/scvpp/tests/scvpp_test.h diff --git a/Makefile b/Makefile index 9a6b237..cc33123 100644 --- a/Makefile +++ b/Makefile @@ -52,14 +52,14 @@ BUILD_DEB = curl build-essential autoconf automake ccache git cmake wget coreuti NETOPEER2_DEB = libssl-dev pkgconf #Dependencies for checkstyle CHECKSTYLE_DEB = indent -#Dependencies for scvpp -SCVPP_DEB = libcmocka-dev #Dependencies for sysrepo (swig required for sysrepo python, lua, java) SYSREPO_DEB = libev-dev libavl-dev bison flex libpcre3-dev libprotobuf-c-dev protobuf-c-compiler #Dependencies of libssh LIBSSH_DEB = zlib1g-dev +#Dependencies of VOM +LIBVOM_DEB = libboost-all-dev #Sum dependencies -DEB_DEPENDS = ${BUILD_DEB} ${NETOPEER2_DEB} ${CHECKSTYLE_DEB} ${SCVPP_DEB} ${SYSREPO_DEB} ${LIBSSH_DEB} +DEB_DEPENDS = ${BUILD_DEB} ${NETOPEER2_DEB} ${CHECKSTYLE_DEB} ${SYSREPO_DEB} ${LIBSSH_DEB} ${LIBVOM_DEB} #Dependencies for automatic test DEB_TEST_DEPENDS = python3-pip python-pip libcurl4-openssl-dev libssh-dev \ @@ -74,12 +74,10 @@ BUILD_RPM = curl autoconf automake ccache cmake3 wget gcc gcc-c++ git NETOPEER2_RPM = openssl-devel #Dependencies for checkstyle CHECKSTYLE_RPM = indent -#Dependencies for scvpp -SCVPP_RPM = libcmocka-devel #Dependencies for sysrepo SYSREPO_RPM = libev-devel bison flex pcre-devel protobuf-c-devel protobuf-c-compiler -RPM_DEPENDS = ${BUILD_RPM} ${NETOPEER2_RPM} ${CHECKSTYLE_RPM} ${SCVPP_RPM} \ +RPM_DEPENDS = ${BUILD_RPM} ${NETOPEER2_RPM} ${CHECKSTYLE_RPM} \ ${SYSREPO_RPM} #Dependencies for automatic test @@ -87,7 +85,7 @@ RPM_TEST_DEPENDS = python36-devel python36-pip python-pip libxml2-devel \ libxslt-devel libtool which cmake3 .PHONY: help install-dep install-dep-extra install-vpp install-models \ - uninstall-models build-scvpp build-plugins build-package docker \ + uninstall-models build-plugins build-package docker \ docker-test test clean distclean _clean_dl _libssh _libyang \ _libnetconf2 _sysrepo _netopeer2 @@ -99,8 +97,6 @@ help: @echo " install-models - install YANG models" @echo " uninstall-models - uninstall YANG models" @echo " install-test-extra - install software extra dependencies from source code for YDK" - @echo " build-scvpp - build scvpp" - @echo " test-scvpp - unit test for scvpp" @echo " build-plugins - build plugins" @echo " test-plugins - integration test for sweetcomb plugins" @echo " build-package - build rpm or deb package" @@ -134,13 +130,13 @@ ifeq ($(filter ubuntu debian,$(OS_ID)),$(OS_ID)) mkdir -p $(BR)/downloads/&&cd $(BR)/downloads/\ &&wget https://git.libssh.org/projects/libssh.git/snapshot/libssh-0.7.7.tar.gz\ &&tar xvf libssh-0.7.7.tar.gz && cd libssh-0.7.7 && mkdir build && cd build\ - &&cmake -DZLIB_LIBRARY=/usr/lib/x86_64-linux-gnu/libz.so -DZLIB_INCLUDE_DIR=/usr/include/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ + &&$(cmake) -DZLIB_LIBRARY=/usr/lib/x86_64-linux-gnu/libz.so -DZLIB_INCLUDE_DIR=/usr/include/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ &&make -j$(nproc) &&sudo make install && sudo ldconfig&&cd ../../; else ifeq ($(OS_ID),centos) mkdir -p $(BR)/downloads/&&cd $(BR)/downloads/\ &&wget https://git.libssh.org/projects/libssh.git/snapshot/libssh-0.7.7.tar.gz\ &&tar xvf libssh-0.7.7.tar.gz && cd libssh-0.7.7 && mkdir build && cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ &&make -j$(nproc) &&sudo make install && sudo ldconfig&&cd ../../; endif @@ -148,7 +144,7 @@ _libyang: @mkdir -p $(BR)/downloads/&&cd $(BR)/downloads/\ &&wget https://github.com/CESNET/libyang/archive/v0.16-r3.tar.gz\ &&tar xvf v0.16-r3.tar.gz && cd libyang-0.16-r3 && mkdir -p build&& cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr \ -DGEN_LANGUAGE_BINDINGS=OFF -DGEN_CPP_BINDINGS=ON \ -DGEN_PYTHON_BINDINGS=OFF -DBUILD_EXAMPLES=OFF \ -DENABLE_BUILD_TESTS=OFF .. \ @@ -159,7 +155,7 @@ _libnetconf2: @mkdir -p $(BR)/downloads/&&cd $(BR)/downloads/\ &&git clone https://github.com/CESNET/libnetconf2.git&&cd libnetconf2\ &&git checkout 7e5f7b05f10cb32a546c42355481c7d87e0409b8&& mkdir -p build&& cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_BUILD_TESTS=OFF\ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DENABLE_BUILD_TESTS=OFF\ -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ &&make -j $(nproc) &&make install&&ldconfig\ &&cd ../../\ @@ -168,7 +164,7 @@ _sysrepo: @mkdir -p $(BR)/downloads/&&cd $(BR)/downloads/\ &&wget https://github.com/sysrepo/sysrepo/archive/v0.7.7.tar.gz\ &&tar xvf v0.7.7.tar.gz && cd sysrepo-0.7.7 && mkdir -p build && cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr \ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr \ -DGEN_LANGUAGE_BINDINGS=OFF -DGEN_CPP_BINDINGS=ON -DGEN_LUA_BINDINGS=OFF \ -DGEN_PYTHON_BINDINGS=OFF -DGEN_JAVA_BINDINGS=OFF -DBUILD_EXAMPLES=OFF \ -DENABLE_TESTS=OFF ..\ @@ -180,16 +176,16 @@ _netopeer2: &&tar xvf v0.7-r1.tar.gz\ && echo "Netopeer2:keystored" \ && cd Netopeer2-0.7-r1/keystored && mkdir -p build && cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ &&make -j$(nproc) && make install && sudo ldconfig\ && echo "Netopeer2:server" \ &&cd ../../server/ && mkdir -p build && cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_BUILD_TESTS=OFF\ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DENABLE_BUILD_TESTS=OFF\ -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ &&make -j$(nproc) && make install && ldconfig\ && echo "Netopeer2:cli" \ &&cd ../../cli && mkdir -p build && cd build\ - &&cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ + &&$(cmake) -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr ..\ &&make -j$(nproc) && make install && sudo ldconfig\ &&cd ../../../ && mv v0.7-r1.tar.gz Netopeer2-0.7-r1.tar.gz\ @@ -235,7 +231,7 @@ install-vpp: @echo "please install vpp as vpp's guide from source if failed" ifeq ($(PKG),deb) # @curl -s https://packagecloud.io/install/repositories/fdio/release/script.deb.sh | sudo bash - @sudo -E apt-get -y --force-yes install vpp libvppinfra* vpp-plugin-* vpp-dev + @sudo -E apt-get -y --force-yes install vpp libvppinfra* vpp-plugin-* vpp-dev vom else ifeq ($(PKG),rpm) # @curl -s https://packagecloud.io/install/repositories/fdio/release/script.rpm.sh | sudo bash ifeq ($(OS_ID),centos) @@ -246,28 +242,40 @@ endif install-test-extra: _clean_dl _libssh _test_python _ydk @cd ../ && rm -rf $(BR)/downloads -build-scvpp: - @mkdir -p $(BR)/build-scvpp/; cd $(BR)/build-scvpp; \ - $(cmake) -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=/usr $(WS_ROOT)/src/scvpp/;\ - make install - @# NEW INSTRUCTIONS TO BUILD-SCVPP MUST BE DECLARED ON A NEW LINE WITH '@' - -test-scvpp: build-scvpp - @cd $(BR)/build-scvpp; make test ARGS="-V" - +#Centos needs to build sysrepo plugin with same toolchain as libvom.so i.e. +#devtoolset-7. build-plugins: +ifeq ($(filter ubuntu debian,$(OS_ID)),$(OS_ID)) + @mkdir -p $(BR)/build-plugins/; cd $(BR)/build-plugins/; \ + $(cmake) -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr $(WS_ROOT)/src/; \ + make install +else ifeq ($(OS_ID),centos) @mkdir -p $(BR)/build-plugins/; cd $(BR)/build-plugins/; \ - $(cmake) -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=/usr $(WS_ROOT)/src/plugins/; \ + $(cmake) -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_PROGRAM_PATH:PATH="/opt/rh/devtoolset-7/root/bin" \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr $(WS_ROOT)/src/; \ make install +endif @# NEW INSTRUCTIONS TO BUILD-PLUGINS MUST BE DECLARED ON A NEW LINE WITH '@' + test-plugins: install-models @test/run_test.py --dir ./test/ build-package: +ifeq ($(filter ubuntu debian,$(OS_ID)),$(OS_ID)) @mkdir -p $(BR)/build-package/; cd $(BR)/build-package/;\ - $(cmake) -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr \ - -DENABLE_TESTS=OFF $(WS_ROOT)/src/; make package; + $(cmake) -DCMAKE_BUILD_TYPE=ReleaseĀ \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr $(WS_ROOT)/src/;\ + make package; +else ifeq ($(OS_ID),centos) + @mkdir -p $(BR)/build-package/; cd $(BR)/build-package/;\ + $(cmake) -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_PROGRAM_PATH:PATH="/opt/rh/devtoolset-7/root/bin" \ + -DCMAKE_INSTALL_PREFIX:PATH=/usr $(WS_ROOT)/src/;\ + make package; +endif @# NEW INSTRUCTIONS TO BUILD-PACKAGE MUST BE DECLARED ON A NEW LINE WITH @# '@' NOT WITH ';' ELSE BUILD-PACKAGE WILL NOT RETURN THE CORRECT @# RETURN CODE FOR JENKINS CI @@ -281,34 +289,24 @@ install-models: sysrepoctl --install --yang=ietf-nat@2017-11-16.yang > /dev/null; \ sysrepoctl -e if-mib -m ietf-interfaces; @cd src/plugins/yang/openconfig; \ - sysrepoctl -S --install --yang=openconfig-local-routing@2017-05-15.yang > /dev/null; \ sysrepoctl -S --install --yang=openconfig-interfaces@2018-08-07.yang > /dev/null; \ - sysrepoctl -S --install --yang=openconfig-if-ip@2018-01-05.yang > /dev/null; \ - sysrepoctl -S --install --yang=openconfig-acl@2018-11-21.yang > /dev/null; uninstall-models: @ sysrepoctl -u -m ietf-ip > /dev/null; \ - sysrepoctl -u -m openconfig-acl > /dev/null; \ - sysrepoctl -u -m openconfig-if-ip > /dev/null; \ - sysrepoctl -u -m openconfig-local-routing > /dev/null; \ - sysrepoctl -u -m openconfig-if-aggregate > /dev/null; \ sysrepoctl -u -m openconfig-interfaces > /dev/null; \ sysrepoctl -u -m ietf-nat > /dev/null; \ sysrepoctl -u -m iana-if-type > /dev/null; \ sysrepoctl -u -m ietf-interfaces > /dev/null; \ - sysrepoctl -u -m openconfig-vlan-types > /dev/null; clean: - @if [ -d $(BR)/build-scvpp ] ; then cd $(BR)/build-scvpp && make clean; fi @if [ -d $(BR)/build-plugins ] ; then cd $(BR)/build-plugins && make clean; fi @if [ -d $(BR)/build-package ] ; then cd $(BR)/build-package && make clean; fi distclean: - @rm -rf $(BR)/build-scvpp @rm -rf $(BR)/build-plugins @rm -rf $(BR)/build-package -docker: +docker: distclean @scripts/docker.sh docker-test: diff --git a/README.md b/README.md index dbbf74c..abf6f87 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ Details of the changes leading up to this version of Sweetcomb can be found unde | ---------------------- | ------------------------------------------- | | build-root | Build output directory | | @ref src/plugins | Sweetcomb bundled plugins directory | -| @ref src/scvpp | Sweetcomb to VPP communication | ## Getting started @@ -37,7 +36,6 @@ Firstly, please follow below steps to install dependencies and build code: make install-dep make install-dep-extra make install-vpp - make build-scvpp make build-plugins ``` diff --git a/samples/ietf-interfaces/create-if.json b/samples/ietf-interfaces/create-if.json new file mode 100644 index 0000000..02c5371 --- /dev/null +++ b/samples/ietf-interfaces/create-if.json @@ -0,0 +1,11 @@ +{ + "ietf-interfaces:interfaces": { + "interface": [ + { + "name": "GigabitEthernet0/8/0", + "type": "iana-if-type:ethernetCsmacd", + "enabled": true + } + ] + } +} diff --git a/samples/ietf-nat/create-instance.xml b/samples/ietf-nat/create-instance.xml new file mode 100644 index 0000000..e14b0dd --- /dev/null +++ b/samples/ietf-nat/create-instance.xml @@ -0,0 +1,11 @@ + + + + 1 + + 5 + + + + + diff --git a/samples/ietf-nat/create-mapping.xml b/samples/ietf-nat/create-mapping.xml new file mode 100644 index 0000000..63cfca8 --- /dev/null +++ b/samples/ietf-nat/create-mapping.xml @@ -0,0 +1,19 @@ + + + + 1 + + 5 + + + + 1 + static + 10.0.0.2/32 + 192.168.1.2/32 + + + + + + diff --git a/samples/openconfig-interfaces/create-if.json b/samples/openconfig-interfaces/create-if.json new file mode 100644 index 0000000..695c03f --- /dev/null +++ b/samples/openconfig-interfaces/create-if.json @@ -0,0 +1,13 @@ +{ + "openconfig-interfaces:interfaces": { + "interface": [ + { + "name": "GigabitEthernet0/8/0", + "config": { + "type": "iana-if-type:ethernetCsmacd", + "enabled": true + } + } + ] + } +} diff --git a/samples/openconfig-local-routing/create-prefix-entry.json b/samples/openconfig-local-routing/create-prefix-entry.json new file mode 100644 index 0000000..372c873 --- /dev/null +++ b/samples/openconfig-local-routing/create-prefix-entry.json @@ -0,0 +1,11 @@ +{ + "openconfig-local-routing:local-routes": { + "static-routes": { + "static": [ + { + "prefix": "8.0.0.0/8" + } + ] + } + } +} diff --git a/scripts/Dockerfile b/scripts/Dockerfile index f45af42..873a19c 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -1,6 +1,6 @@ FROM ubuntu:18.04 -ARG vpp_version=release +ARG vpp_version=master # Layer0: Prepare sweetcomb environement by installing sysrepo, netopeer2 & vpp # Layer1: Install vpp @@ -15,14 +15,12 @@ RUN make install-dep && make install-dep-extra RUN rm -rf /opt/dev/* #Layer1 -RUN apt-get install -y \ - sudo curl \ - inetutils-ping \ - && curl -s https://packagecloud.io/install/repositories/fdio/$vpp_version/script.deb.sh | sudo bash \ - && apt-get -y --force-yes install vpp libvppinfra* vpp-plugin-* vpp-dev +RUN apt-get install -y curl inetutils-ping \ + && curl -s https://packagecloud.io/install/repositories/fdio/$vpp_version/script.deb.sh | bash \ + && apt-get -y --force-yes install vpp libvppinfra* vpp-plugin-* vpp-dev vom #Layer2 COPY . /root/src/sweetcomb WORKDIR /root/src/sweetcomb -RUN make install-dep && make build-scvpp && make build-plugins +RUN make install-dep && make build-plugins diff --git a/scripts/run_test.sh b/scripts/run_test.sh index 76b1ca1..1c50247 100755 --- a/scripts/run_test.sh +++ b/scripts/run_test.sh @@ -42,7 +42,6 @@ docker run -id --privileged --name ${CONTAINER} ${IMAGE_TEST} docker cp . ${CONTAINER}:/root/src/sweetcomb docker exec -it ${CONTAINER} bash -c " cd /root/src/sweetcomb && - make build-scvpp && make build-plugins" if [ "$?" == 0 ]; then echo "Run tests" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 617c647..55d6792 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,7 +15,9 @@ cmake_minimum_required(VERSION 3.0) project(sweetcomb) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") + +# Cmake find modules directory +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # set default build type if not specified by user if(NOT CMAKE_BUILD_TYPE) @@ -24,7 +26,6 @@ endif() string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWER) # add subdirectories -# add_subdirectory(scvpp) add_subdirectory(plugins) include(Packager) diff --git a/src/cmake/FindVPP.cmake b/src/cmake/FindVPP.cmake index afc1520..56ab482 100644 --- a/src/cmake/FindVPP.cmake +++ b/src/cmake/FindVPP.cmake @@ -98,6 +98,15 @@ else (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) ${CMAKE_INSTALL_PREFIX}/include ) + find_path(VOM_INCLUDE_DIR + NAMES + vom/om.hpp + PATHS + ${VPP_INCLUDE_PATH} + ${CMAKE_INCLUDE_PATH} + ${CMAKE_INSTALL_PREFIX}/include + ) + find_library(VLIBMEMORYCLIENT_LIBRARY NAMES vlibmemoryclient @@ -158,6 +167,16 @@ else (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) ${CMAKE_INSTALL_PREFIX}/lib ) + find_library(VOM_LIBRARY + NAMES + vom + libvom + PATHS + ${VPP_LIBRARY_PATH} + ${CMAKE_LIBRARY_PATH} + ${CMAKE_INSTALL_PREFIX}/lib + ) + if (VPP_INCLUDE_DIR AND VPP_LIBRARY) set(VPP_FOUND TRUE) else (VPP_INCLUDE_DIR AND VPP_LIBRARY) @@ -171,6 +190,7 @@ else (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) ${VPP_MSG_INCLUDE_DIR} ${VPP_ALL_INCLUDE_DIR} ${VAPI_INCLUDE_DIR} + ${VOM_INCLUDE_DIR} ) set(VPP_LIBRARIES @@ -180,6 +200,7 @@ else (VPP_LIBRARIES AND VPP_INCLUDE_DIRS) ${VLIB_LIBRARY} ${VATPLUGIN_LIBRARY} ${VAPI_LIBRARY} + ${VOM_LIBRARY} ) # show the VPP_INCLUDE_DIRS and VPP_LIBRARIES variables only in the advanced view diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 6a04143..ae1c58d 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -13,7 +13,6 @@ # limitations under the License. cmake_minimum_required(VERSION 3.0) -project(sysrepo-vpp-plugins) # DEPENDENCIES ############## @@ -26,8 +25,8 @@ find_package(VPP) #use FindVPP.cmake find_package(PkgConfig) #official cmake module pkg_check_modules(SYSREPO REQUIRED libsysrepo) #PkgConfig cmake module maccro -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../scvpp scvpp_out) -include_directories(${CMAKE_CURRENT_LIST_DIR}/../scvpp/inc) +find_package(Boost 1.40 COMPONENTS program_options REQUIRED) +include_directories(${Boost_INCLUDE_DIR}) # get sysrepo plugins directory from pkgconfig if (NOT SR_PLUGINS_DIR) @@ -47,11 +46,11 @@ endif() set(CMAKE_EXPORT_COMPILE_COMMANDS 1) # set compiler and linker flags -set(RIGOROUS_C_FLAGS "-Wlogical-op -Wformat=2") -set(CMAKE_C_FLAGS "-Wall -Wextra -std=gnu99 ${RIGOROUS_C_FLAGS}") -set(CMAKE_C_FLAGS_DEBUG "-Wall -Wextra -std=gnu99 -g -O0 ${RIGOROUS_C_FLAGS}") +set(RIGOROUS_CXX_FLAGS "-Wlogical-op -Wformat=2") +set(CMAKE_CXX_FLAGS "-Wall -Wextra -std=gnu++11 ${RIGOROUS_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Wextra -std=gnu++11 -g -O0 ${RIGOROUS_CXX_FLAGS}") #NDEBUG to skip assert checks -set(CMAKE_C_FLAGS_RELEASE "-Wall -Wextra -std=gnu99 -DNDEBUG -O2 ${RIGOROUS_C_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "-Wall -Wextra -std=gnu++11 -DNDEBUG -O2 ${RIGOROUS_CXX_FLAGS}") # add plugin include directories include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -60,18 +59,22 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) set(PLUGINS_SOURCES sc_init.c sc_plugins.c - ietf/ietf_interface.c - ietf/ietf_nat.c - openconfig/openconfig_interfaces.c - openconfig/openconfig_local_routing.c + sys_util.cpp + vpp-oper/interface.cpp + ietf/ietf_interface.cpp + openconfig/openconfig_interfaces.cpp + ietf/ietf_nat.cpp ) +set_source_files_properties(${PLUGINS_SOURCES} PROPERTIES LANGUAGE CXX) + # build the source code into shared library -add_library(vpp-plugins SHARED ${PLUGINS_SOURCES}) -target_link_libraries(vpp-plugins ${SYSREPO_LIBRARIES} scvpp) +add_library(sweetcomb SHARED ${PLUGINS_SOURCES}) +target_link_libraries(sweetcomb ${SYSREPO_LIBRARIES} ${Boost_LIBRARIES} + ${VOM_LIBRARY}) # INSTALL ######### # install the plugin into plugins dir -install(TARGETS vpp-plugins DESTINATION ${SR_PLUGINS_DIR}) +install(TARGETS sweetcomb DESTINATION ${SR_PLUGINS_DIR}) diff --git a/src/plugins/ietf/ietf_interface.c b/src/plugins/ietf/ietf_interface.c deleted file mode 100644 index b4a2bc7..0000000 --- a/src/plugins/ietf/ietf_interface.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - * 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 -#include - -#include - -#include -#include - -#include - -/** - * @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) -{ - UNUSED(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; - - SRP_LOG_INF("In %s", __FUNCTION__); - - /* 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) { - sr_free_change_iter(iter); - SRP_LOG_ERR("Unable to retrieve change iterator: %s", sr_strerror(rc)); - return rc; - } - - foreach_change (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(if_name, new_val->data.bool_val); - break; - case SR_OP_DELETED: - op_rc = interface_enable(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 Modify existing IPv4/IPv6 config on an interface. - */ -static int -interface_ipv46_config_modify(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 = NULL; - 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 = sr_xpath_key_value((char*)old_val->xpath, "address", "ip", &xpath_ctx); - sr_xpath_recover(&xpath_ctx); - - /* delete old IP config */ - rc = 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 = 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) -{ - UNUSED(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; - char addr[VPP_IP6_ADDRESS_STRING_LEN] = {0}; - uint8_t prefix = 0; - char *node_name = NULL, *if_name = NULL; - int rc = SR_ERR_OK, op_rc = SR_ERR_OK; - - SRP_LOG_INF("In %s", __FUNCTION__); - - /* 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) { - sr_free_change_iter(iter); - SRP_LOG_ERR("Unable to retrieve change iterator: %s", sr_strerror(rc)); - return rc; - } - - foreach_change(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")) { - strncpy(addr, new_val->data.string_val, strlen(new_val->data.string_val)); - 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 = ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */); - } - } - break; - case SR_OP_MODIFIED: - //TODO Why is it using old_val and new_val? - op_rc = interface_ipv46_config_modify(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")) { - strncpy(addr, old_val->data.string_val, strlen(old_val->data.string_val)); - 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 = 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) -{ - UNUSED(session); UNUSED(xpath); UNUSED(event); UNUSED(private_ctx); - - SRP_LOG_INF("In %s", __FUNCTION__); - - return SR_ERR_OK; -} - -/** - * @brief Callback to be called by any request for state data under "/ietf-interfaces:interfaces-state/interface" path. - * Here we reply systematically with all interfaces, it the responsability of - * sysrepo apply a filter not to answer undesired interfaces. - */ -static int -ietf_interface_state_cb(const char *xpath, sr_val_t **values, - size_t *values_cnt, uint64_t request_id, - const char *original_xpath, void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - struct elt* stack; - sw_interface_dump_t *dump; - sr_val_t *val = NULL; - int vc = 5; //number of answer per interfaces - int cnt = 0; //value counter - int rc = SR_ERR_OK; - - SRP_LOG_INF("In %s", __FUNCTION__); - - if (!sr_xpath_node_name_eq(xpath, "interface")) - goto nothing_todo; //no interface field specified - - /* dump interfaces */ - stack = interface_dump_all(); - if (!stack) - goto nothing_todo; //no element returned - - /* allocate array of values to be returned */ - SRP_LOG_DBG("number of interfaces: %d", stack->id+1); - rc = sr_new_values((stack->id + 1)* vc, &val); - if (0 != rc) - goto nothing_todo; - - foreach_stack_elt(stack) { - dump = (sw_interface_dump_t *) data; - - SRP_LOG_DBG("State of interface %s, xpath %s", dump->interface_name, xpath); - //TODO need support for type propvirtual - sr_val_build_xpath(&val[cnt], "%s[name='%s']/type", xpath, dump->interface_name); - sr_val_set_str_data(&val[cnt], SR_IDENTITYREF_T, "iana-if-type:ethernetCsmacd"); - cnt++; - - //Be careful, it needs if-mib feature to work ! - sr_val_build_xpath(&val[cnt], "%s[name='%s']/admin-status", xpath, dump->interface_name); - sr_val_set_str_data(&val[cnt], SR_ENUM_T, dump->link_up_down ? "up" : "down"); - cnt++; - - sr_val_build_xpath(&val[cnt], "%s[name='%s']/oper-status", xpath, dump->interface_name); - sr_val_set_str_data(&val[cnt], SR_ENUM_T, dump->link_up_down ? "up" : "down"); - cnt++; - - sr_val_build_xpath(&val[cnt], "%s[name='%s']/phys-address", xpath, dump->interface_name); - if (dump->l2_address_length > 0) { - sr_val_build_str_data(&val[cnt], SR_STRING_T, - "%02x:%02x:%02x:%02x:%02x:%02x", - dump->l2_address[0], dump->l2_address[1], - dump->l2_address[2], dump->l2_address[3], - dump->l2_address[4], dump->l2_address[5]); - } else { - sr_val_build_str_data(&val[cnt], SR_STRING_T, "%02x:%02x:%02x:%02x:%02x:%02x", 0,0,0,0,0,0); - } - cnt++; - - sr_val_build_xpath(&val[cnt], "%s[name='%s']/speed", xpath, dump->interface_name); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = dump->link_speed; - cnt++; - - free(dump); - } - - *values = val; - *values_cnt = cnt; - - return SR_ERR_OK; - -nothing_todo: - *values = NULL; - *values_cnt = 0; - return rc; -} - -static inline stat_segment_data_t* fetch_stat_index(const char *path) { - stat_segment_data_t *r; - u32 *stats = NULL; - u8 **patterns = NULL; - - patterns = stat_segment_string_vector(patterns, path); - if (!patterns) - return NULL; - - do { - stats = stat_segment_ls(patterns); - if (!stats) - return NULL; - - r = stat_segment_dump(stats); - } while (r == NULL); /* Memory layout has changed */ - - return r; -} - -static inline uint64_t get_counter(stat_segment_data_t *r, int itf_idx) -{ - if (r == NULL) { - SRP_LOG_ERR_MSG("stat segment can not be NULL"); - return 0; - } - - if (r->type != STAT_DIR_TYPE_COUNTER_VECTOR_SIMPLE) { - SRP_LOG_ERR_MSG("Only simple counter"); - return 0; - } - - return r->simple_counter_vec[0][itf_idx]; -} - -static inline uint64_t get_bytes(stat_segment_data_t *r, int itf_idx) -{ - if (r->type != STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED) { - SRP_LOG_ERR_MSG("Only combined counter"); - return 0; - } - - return r->combined_counter_vec[0][itf_idx].bytes; -} - -static inline uint64_t get_packets(stat_segment_data_t *r, int itf_idx) -{ - if (r->type != STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED) { - SRP_LOG_ERR_MSG("Only combined counter"); - return 0; - } - - return r->combined_counter_vec[0][itf_idx].packets; -} - -/** - * @brief Callback to be called by any request for state data under - * "/ietf-interfaces:interfaces-state/interface/statistics" path. - */ -static int -interface_statistics_cb(const char *xpath, sr_val_t **values, - size_t *values_cnt, uint64_t request_id, - const char *original_xpath, void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - sr_val_t *val = NULL; - int vc = 10; - int cnt = 0; //value counter - int rc = SR_ERR_OK; - sr_xpath_ctx_t state = {0}; - char *tmp; - char interface_name[VPP_INTFC_NAME_LEN] = {0}; - uint32_t itf_idx; - stat_segment_data_t *r; - - SRP_LOG_INF("In %s", __FUNCTION__); - - /* Retrieve the interface asked */ - tmp = sr_xpath_key_value((char*) xpath, "interface", "name", &state); - if (!tmp) { - SRP_LOG_ERR_MSG("XPATH interface name not found"); - return SR_ERR_INVAL_ARG; - } - strncpy(interface_name, tmp, VPP_INTFC_NAME_LEN); - sr_xpath_recover(&state); - - /* allocate array of values to be returned */ - rc = sr_new_values(vc, &val); - if (0 != rc) - goto nothing_todo; - - rc = get_interface_id(interface_name, &itf_idx); - if (rc != 0) - goto nothing_todo; - - SRP_LOG_DBG("name:%s index:%d", interface_name, itf_idx); - - r = fetch_stat_index("/if"); - if (!r) - goto nothing_todo; - - for (int i = 0; i < stat_segment_vec_len(r); i++) { - if (strcmp(r[i].name, "/if/rx") == 0) { - sr_val_build_xpath(&val[cnt], "%s/in-octets", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_bytes(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/rx-unicast") == 0) { - sr_val_build_xpath(&val[cnt], "%s/in-unicast-pkts", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_packets(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/rx-broadcast") == 0) { - sr_val_build_xpath(&val[cnt], "%s/in-broadcast-pkts", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_packets(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/rx-multicast") == 0) { - sr_val_build_xpath(&val[cnt], "%s/in-multicast-pkts", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_packets(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/rx-error") == 0) { - sr_val_build_xpath(&val[cnt], "%s/in-errors", xpath, 5); - val[cnt].type = SR_UINT32_T; - //Be carefeul cast uint64 to uint32 - val[cnt].data.uint32_val = get_counter(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/tx") == 0) { - sr_val_build_xpath(&val[cnt], "%s/out-octets", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_bytes(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/tx-unicast") == 0) { - sr_val_build_xpath(&val[cnt], "%s/out-unicast-pkts", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_packets(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/tx-broadcast") == 0) { - sr_val_build_xpath(&val[cnt], "%s/out-broadcast-pkts", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_packets(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/tx-multicast") == 0) { - sr_val_build_xpath(&val[cnt], "%s/out-multicast-pkts", xpath, 5); - val[cnt].type = SR_UINT64_T; - val[cnt].data.uint64_val = get_packets(&r[i], itf_idx); - cnt++; - } else if (strcmp(r[i].name, "/if/tx-error") == 0) { - sr_val_build_xpath(&val[cnt], "%s/out-errors", xpath, 5); - val[cnt].type = SR_UINT32_T; - //Be carefeul cast uint64 to uint32 - val[cnt].data.uint32_val = get_counter(&r[i], itf_idx); - cnt++; - } - } - - *values = val; - *values_cnt = cnt; - - return SR_ERR_OK; - -nothing_todo: - *values = NULL; - *values_cnt = 0; - return rc; -} - - -int -ietf_interface_init(sc_plugin_main_t *pm) -{ - int rc = SR_ERR_OK; - SRP_LOG_DBG_MSG("Initializing ietf-interface plugin."); - - rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface", - ietf_interface_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface/enabled", - ietf_interface_enable_disable_cb, NULL, 100, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_EV_ENABLED, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->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, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->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, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/ietf-interfaces:interfaces-state", - ietf_interface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/ietf-interfaces:interfaces-state/interface/statistics", - interface_statistics_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - SRP_LOG_DBG_MSG("ietf-interface plugin initialized successfully."); - return SR_ERR_OK; - -error: - SRP_LOG_ERR("Error by initialization of ietf-interface plugin. Error : %d", rc); - return rc; -} - -void -ietf_interface_exit(__attribute__((unused)) sc_plugin_main_t *pm) -{ -} - -SC_INIT_FUNCTION(ietf_interface_init); -SC_EXIT_FUNCTION(ietf_interface_exit); diff --git a/src/plugins/ietf/ietf_interface.cpp b/src/plugins/ietf/ietf_interface.cpp new file mode 100644 index 0000000..74fc594 --- /dev/null +++ b/src/plugins/ietf/ietf_interface.cpp @@ -0,0 +1,613 @@ +/* + * 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. + */ + +/* This file implements: + * - creation, configuration, deletion of an interface. + * - adding, modifying, removing a prefix from an interface + * - streaming of an interface statistics + * + * Even physical interfaces must be created before applying configuration to + * them. Else, it results in undefined behavior. (cf RFC 8343) + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "sc_plugins.h" +#include "sys_util.h" + +using namespace std; + +using VOM::interface; +using VOM::OM; +using VOM::HW; +using VOM::l3_binding; +using VOM::rc_t; + +using type_t = VOM::interface::type_t; +using admin_state_t = VOM::interface::admin_state_t; + +class interface_builder { + public: + interface_builder() {} + + shared_ptr build() { + if (m_name.empty() || m_type.empty()) + return nullptr; + return make_shared(m_name, type_t::from_string(m_type), + admin_state_t::from_int(m_state)); + } + + /* Getters */ + string name() { + return m_name; + } + + /* Setters */ + interface_builder& set_name(string n) { + m_name = n; + return *this; + } + + interface_builder& set_type(string t) { + if (t == "iana-if-type:ethernetCsmacd") + m_type = "ETHERNET"; + return *this; + } + + interface_builder& set_state(bool enable) { + m_state = enable; + return *this; + } + + std::string to_string() { + std::ostringstream os; + os << m_name << "," << m_type << "," << m_state; + return os.str(); + } + + private: + string m_name; + string m_type; + bool m_state; +}; + +/* @brief creation of ethernet devices */ +static int +ietf_interface_create_cb(sr_session_ctx_t *session, const char *xpath, + sr_notif_event_t event, void *private_ctx) +{ + UNUSED(private_ctx); + shared_ptr intf; + interface_builder builder; + string if_name; + sr_change_iter_t *iter = nullptr; + sr_xpath_ctx_t xpath_ctx; + sr_val_t *old_val = nullptr; + sr_val_t *new_val = nullptr; + sr_change_oper_t op; + bool create, remove, modify; + int rc; + + SRP_LOG_INF("In %s", __FUNCTION__); + + /* no-op for apply, we only care about SR_EV_{ENABLED,VERIFY,ABORT} */ + if (SR_EV_VERIFY != 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) { + sr_free_change_iter(iter); + SRP_LOG_ERR("Unable to retrieve change iterator: %s", sr_strerror(rc)); + return SR_ERR_OPERATION_FAILED; + } + + foreach_change (session, iter, op, old_val, new_val) { + SRP_LOG_INF("Change xpath: %s", + old_val ? old_val->xpath : new_val->xpath); + switch (op) { + case SR_OP_MODIFIED: + SRP_LOG_INF_MSG("Modified"); + if (sr_xpath_node_name_eq(new_val->xpath, "enabled")) { + string n = sr_xpath_key_value(new_val->xpath, "interface", + "name", &xpath_ctx); + intf = interface::find(n); + if (!intf) { + rc = SR_ERR_OPERATION_FAILED; + goto nothing_todo; + } + intf->set(admin_state_t::from_int(new_val->data.bool_val)); + modify = true; + } + break; + case SR_OP_CREATED: + if (sr_xpath_node_name_eq(new_val->xpath, "name")) { + builder.set_name(new_val->data.string_val); + create = true; + } else if (sr_xpath_node_name_eq(new_val->xpath, "type")) { + builder.set_type(new_val->data.string_val); + } else if (sr_xpath_node_name_eq(new_val->xpath, "enabled")) { + builder.set_state(new_val->data.bool_val); + } + break; + case SR_OP_DELETED: + if (sr_xpath_node_name_eq(old_val->xpath, "name")) { + builder.set_name(old_val->data.string_val); + remove = true; + } + break; + default: + rc = SR_ERR_UNSUPPORTED; + goto nothing_todo; + } + + sr_free_val(old_val); + sr_free_val(new_val); + } + + if (create) { + SRP_LOG_INF("creating interface '%s'", builder.name().c_str()); + intf = builder.build(); + if (nullptr == intf) { + SRP_LOG_ERR_MSG("Interface does not exist"); + rc = SR_ERR_INVAL_ARG; + goto nothing_todo; + } + } + + if (create || modify) { + /* Commit the changes to VOM DB and VPP with interface name as key. + * Work for modifications too, because OM::write() check for existing + * l3 bindings. */ + if ( OM::write(intf->key(), *intf) != rc_t::OK ) { + SRP_LOG_ERR("Fail writing changes to VPP for: %s", + builder.to_string().c_str()); + rc = SR_ERR_OPERATION_FAILED; + goto nothing_todo; + } + + } else if (remove) { + SRP_LOG_INF("deleting interface '%s'", builder.name().c_str()); + OM::remove(builder.name()); + } + + sr_free_change_iter(iter); + + return SR_ERR_OK; + +nothing_todo: + sr_free_val(old_val); + sr_free_val(new_val); + sr_free_change_iter(iter); + return rc; +} + + +static int +ipv46_config_add_remove(const string &if_name, const string &addr, + uint8_t prefix, bool add) +{ + shared_ptr l3; + shared_ptr intf; + rc_t rc = rc_t::OK; + + intf = interface::find(if_name); + if (nullptr == intf) { + SRP_LOG_ERR_MSG("Interface does not exist"); + return SR_ERR_INVAL_ARG; + } + + try { + VOM::route::prefix_t pfx(addr, prefix); + l3 = make_shared(*intf, pfx); + + #define KEY(l3) "l3_" + l3->itf().name() + "_" + l3->prefix().to_string() + if (add) { + /* Commit the changes to VOM DB and VPP */ + if ( OM::write(KEY(l3), *l3) != rc_t::OK ) { + SRP_LOG_ERR_MSG("Fail writing changes to VPP"); + return SR_ERR_OPERATION_FAILED; + } + } else { + /* Remove l3 thanks to its unique identifier */ + OM::remove(KEY(l3)); + } + #undef KEY + + } catch (std::exception &exc) { //catch boost exception from prefix_t + SRP_LOG_ERR("Error: %s", exc.what()); + return SR_ERR_OPERATION_FAILED; + } + + return SR_ERR_OK; +} + +static void +parse_interface_ipv46_address(sr_val_t *val, string &addr, + uint8_t &prefix) +{ + if (val == nullptr) + throw std::runtime_error("Null pointer"); + + if (SR_LIST_T == val->type) { + /* create on list item - reset state vars */ + addr.clear(); + } else { + if (sr_xpath_node_name_eq(val->xpath, "ip")) { + addr = val->data.string_val; + } else if (sr_xpath_node_name_eq(val->xpath, "prefix-length")) { + prefix = val->data.uint8_val; + } else if (sr_xpath_node_name_eq(val->xpath, "netmask")) { + prefix = utils::netmask_to_plen( + boost::asio::ip::address::from_string(val->data.string_val)); + } + } +} + +/** + * @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) +{ + UNUSED(private_ctx); + sr_change_iter_t *iter = nullptr; + sr_change_oper_t op = SR_OP_CREATED; + sr_val_t *old_val = nullptr; + sr_val_t *new_val = nullptr; + sr_xpath_ctx_t xpath_ctx; + string new_addr, old_addr; + string if_name; + uint8_t new_prefix = 0; + uint8_t old_prefix = 0; + int rc = SR_ERR_OK, op_rc = SR_ERR_OK; + bool create = false; + bool del = false; + + SRP_LOG_INF("In %s", __FUNCTION__); + + /* no-op for apply, we only care about SR_EV_{ENABLED,VERIFY,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) { + sr_free_change_iter(iter); + SRP_LOG_ERR("Unable to retrieve change iterator: %s", sr_strerror(rc)); + return rc; + } + + foreach_change(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); + if (if_name.empty()) { + rc = SR_ERR_OPERATION_FAILED; + goto nothing_todo; + } + sr_xpath_recover(&xpath_ctx); + + try { + switch (op) { + case SR_OP_CREATED: + create = true; + parse_interface_ipv46_address(new_val, new_addr, new_prefix); + break; + case SR_OP_MODIFIED: + create = true; + del = true; + parse_interface_ipv46_address(old_val, old_addr, old_prefix); + parse_interface_ipv46_address(new_val, new_addr, new_prefix); + break; + case SR_OP_DELETED: + del = true; + parse_interface_ipv46_address(old_val, old_addr, old_prefix); + break; + default: + break; + } + } catch (std::exception &exc) { + SRP_LOG_ERR("Error: %s", exc.what()); + } + sr_free_val(old_val); + sr_free_val(new_val); + + if (del && !old_addr.empty()) { + op_rc = ipv46_config_add_remove(if_name, old_addr, old_prefix, + false /* del */); + } + + if (create && !new_addr.empty()) { + op_rc = ipv46_config_add_remove(if_name, new_addr, new_prefix, + true /* add */); + } + + } + sr_free_change_iter(iter); + + return op_rc; + +nothing_todo: + sr_free_val(old_val); + sr_free_val(new_val); + sr_free_change_iter(iter); + return rc; +} + +/** + * @brief Callback to be called by any request for state data under "/ietf-interfaces:interfaces-state/interface" path. + * Here we reply systematically with all interfaces, it the responsability of + * sysrepo apply a filter not to answer undesired interfaces. + */ +static int +ietf_interface_state_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) +{ + UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); + vapi_payload_sw_interface_details interface; + shared_ptr dump; + sr_val_t *val = nullptr; + int vc = 6; //number of answer per interfaces + int cnt = 0; //value counter + int interface_num = 0; + int rc = SR_ERR_OK; + + SRP_LOG_INF("In %s", __FUNCTION__); + + if (!sr_xpath_node_name_eq(xpath, "interface")) + goto nothing_todo; //no interface field specified + + dump = make_shared(); + HW::enqueue(dump); + HW::write(); + + interface_num = std::distance((*dump).begin(), (*dump).end()); + + /* allocate array of values to be returned */ + SRP_LOG_DBG("number of interfaces: %d", interface_num + 1); + rc = sr_new_values((interface_num + 1)* vc, &val); + if (0 != rc) + goto nothing_todo; + + for (auto &it : *dump) { + interface = it.get_payload(); + + SRP_LOG_DBG("State of interface %s", interface.interface_name); + + /* it needs if-mib YANG feature to work ! + * admin-state: state as required by configuration */ + sr_val_build_xpath(&val[cnt], "%s[name='%s']/admin-status", xpath, + interface.interface_name); + sr_val_set_str_data(&val[cnt], SR_ENUM_T, + interface.admin_up_down ? "up" : "down"); + cnt++; + + /* oper-state: effective state. can differ from admin-state */ + sr_val_build_xpath(&val[cnt], "%s[name='%s']/oper-status", xpath, + interface.interface_name); + sr_val_set_str_data(&val[cnt], SR_ENUM_T, + interface.link_up_down ? "up" : "down"); + cnt++; + + sr_val_build_xpath(&val[cnt], "%s[name='%s']/phys-address", xpath, + interface.interface_name); + sr_val_build_str_data(&val[cnt], SR_STRING_T, + "%02x:%02x:%02x:%02x:%02x:%02x", + interface.l2_address[0], interface.l2_address[1], + interface.l2_address[2], interface.l2_address[3], + interface.l2_address[4], interface.l2_address[5]); + cnt++; + + sr_val_build_xpath(&val[cnt], "%s[name='%s']/if-index", xpath, + interface.interface_name); + val[cnt].type = SR_INT32_T; + val[cnt].data.int32_val = interface.sw_if_index; + cnt++; + + sr_val_build_xpath(&val[cnt], "%s[name='%s']/speed", xpath, + interface.interface_name); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = interface.link_speed; + cnt++; + + } + + *values = val; + *values_cnt = cnt; + + return SR_ERR_OK; + +nothing_todo: + *values = nullptr; + *values_cnt = 0; + return rc; +} + +/** + * @brief Callback to be called by any request for state data under + * "/ietf-interfaces:interfaces-state/interface/statistics" path. + */ +static int +interface_statistics_cb(const char *xpath, sr_val_t **values, + size_t *values_cnt, uint64_t request_id, + const char *original_xpath, void *private_ctx) +{ + UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); + shared_ptr interface; + interface::stats_t stats; + string intf_name; + sr_val_t *val = NULL; + int vc = 8; + int cnt = 0; //value counter + sr_xpath_ctx_t state; + int rc = SR_ERR_OK; + + SRP_LOG_INF("In %s", __FUNCTION__); + + /* Retrieve the interface asked */ + intf_name = sr_xpath_key_value((char*) xpath, "interface", "name", &state); + if (intf_name.empty()) { + SRP_LOG_ERR_MSG("XPATH interface name not found"); + return SR_ERR_INVAL_ARG; + } + sr_xpath_recover(&state); + + interface = interface::find(intf_name); + if (interface == nullptr) { + SRP_LOG_WRN("interface %s not found in VOM", intf_name.c_str()); + goto nothing_todo; + } + + /* allocate array of values to be returned */ + rc = sr_new_values(vc, &val); + if (0 != rc) + goto nothing_todo; + + stats = interface->get_stats(); + + //if/rx + sr_val_build_xpath(&val[cnt], "%s/in-octets", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_rx.bytes; + cnt++; + + //if/rx-unicast + sr_val_build_xpath(&val[cnt], "%s/in-unicast-pkts", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_rx_unicast.packets; + cnt++; + + //if/rx-broadcast + sr_val_build_xpath(&val[cnt], "%s/in-broadcast-pkts", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_rx_broadcast.packets; + cnt++; + + //if/rx-multicast + sr_val_build_xpath(&val[cnt], "%s/in-multicast-pkts", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_rx_multicast.packets; + cnt++; + + //if/tx + sr_val_build_xpath(&val[cnt], "%s/out-octets", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_tx.bytes; + cnt++; + + //if/tx-unicast + sr_val_build_xpath(&val[cnt], "%s/out-unicast-pkts", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_tx_unicast.packets; + cnt++; + + //if/tx-broadcast + sr_val_build_xpath(&val[cnt], "%s/out-broadcast-pkts", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_tx_broadcast.packets; + cnt++; + + //if/tx-multicast + sr_val_build_xpath(&val[cnt], "%s/out-multicast-pkts", xpath, 5); + val[cnt].type = SR_UINT64_T; + val[cnt].data.uint64_val = stats.m_tx_multicast.packets; + cnt++; + + *values = val; + *values_cnt = cnt; + + return SR_ERR_OK; + +nothing_todo: + *values = NULL; + *values_cnt = 0; + return rc; +} + + +int +ietf_interface_init(sc_plugin_main_t *pm) +{ + int rc = SR_ERR_OK; + SRP_LOG_DBG_MSG("Initializing ietf-interface plugin."); + + rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface", + ietf_interface_create_cb, nullptr, 100, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address", + ietf_interface_ipv46_address_change_cb, nullptr, 99, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + rc = sr_subtree_change_subscribe(pm->session, "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address", + ietf_interface_ipv46_address_change_cb, nullptr, 98, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + rc = sr_dp_get_items_subscribe(pm->session, "/ietf-interfaces:interfaces-state", + ietf_interface_state_cb, nullptr, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + rc = sr_dp_get_items_subscribe(pm->session, "/ietf-interfaces:interfaces-state/interface/statistics", + interface_statistics_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + SRP_LOG_DBG_MSG("ietf-interface plugin initialized successfully."); + return SR_ERR_OK; + +error: + SRP_LOG_ERR("Error by initialization of ietf-interface plugin. Error : %d", rc); + return rc; +} + +void +ietf_interface_exit(__attribute__((unused)) sc_plugin_main_t *pm) +{ +} + +SC_INIT_FUNCTION(ietf_interface_init); +SC_EXIT_FUNCTION(ietf_interface_exit); diff --git a/src/plugins/ietf/ietf_nat.c b/src/plugins/ietf/ietf_nat.c deleted file mode 100644 index 86b700f..0000000 --- a/src/plugins/ietf/ietf_nat.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (c) 2019 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * @brief Wrapper struct for VAPI address range payload. - */ -struct address_range_t { - nat44_add_del_address_range_t payload; //< VAPI payload for address range. - bool last_ip_address_set; //< Variable last_ip_address in payload is set. -}; - -// Check input structure, set VAPI payload and call VAPI function to set -// nat44 address range. -static sr_error_t set_address_range(struct address_range_t *address_r) -{ - sr_error_t rc = SR_ERR_OK; -// char tmp_ip1[VPP_IP4_ADDRESS_STRING_LEN]; -// char tmp_ip2[VPP_IP4_ADDRESS_STRING_LEN]; - - ARG_CHECK(SR_ERR_INVAL_ARG, address_r); - - //if end of IP range not provided, then range size = 1 with only first ip - if (!address_r->last_ip_address_set) { - memcpy(&address_r->payload.last_ip_address[0], - &address_r->payload.first_ip_address[0], - VPP_IP4_ADDRESS_LEN); - } - - if (hardntohlu32(address_r->payload.last_ip_address) < - hardntohlu32(address_r->payload.first_ip_address)) { - SRP_LOG_ERR_MSG("End address less than start address"); - return SR_ERR_INVAL_ARG; - } - -// strncpy(tmp_ip1, sc_ntoa(address_r->payload.first_ip_address), -// VPP_IP4_ADDRESS_STRING_LEN); -// strncpy(tmp_ip2, sc_ntoa(address_r->payload.last_ip_address), -// VPP_IP4_ADDRESS_STRING_LEN); -// SRP_LOG_DBG("Fist ip address: %s, last ip address: %s, twice_nat: %u," -// "is_add: %u", tmp_ip1, tmp_ip2, address_r->payload.twice_nat, -// address_r->payload.is_add); - - int rv = nat44_add_del_addr_range(&address_r->payload); - if (0 != rv) { - SRP_LOG_ERR_MSG("Failed set address range."); - rc = SR_ERR_OPERATION_FAILED; - } - - return rc; -} - -// parse leaf from this xpath: -// /ietf-nat:nat/instances/instance[id='%s']/policy[id='%s']/external-ip-address-pool[pool-id='%s']/ -static int parse_instance_policy_external_ip_address_pool( - const sr_val_t *val, struct address_range_t *address_range) -{ - int rc; - char tmp_str[VPP_IP4_PREFIX_STRING_LEN] = {0}; - uint8_t prefix = 0; - - ARG_CHECK2(SR_ERR_INVAL_ARG, val, address_range); - - if (sr_xpath_node_name_eq(val->xpath, "pool-id")) { - SRP_LOG_WRN("%s not supported.", val->xpath); - } else if(sr_xpath_node_name_eq(val->xpath, "external-ip-pool")) { - rc = prefix2ip4(tmp_str, val->data.string_val, &prefix); - if (0 != rc) { - SRP_LOG_ERR_MSG("Error translate"); - return SR_ERR_INVAL_ARG; - } - - rc = sc_aton(tmp_str, address_range->payload.first_ip_address, - VPP_IP4_ADDRESS_LEN); - if (0 != rc) { - SRP_LOG_ERR_MSG("Failed convert string IP address to int."); - return SR_ERR_INVAL_ARG; - } - - if (prefix < VPP_IP4_HOST_PREFIX_LEN) { - // External IP pool is represented as IPv4 prefix in YANG module. - // VPP support range from first IPv4 address to last IPv4 address, not prefix. - // In this concept the broadcast IPv4 address of this IPv4 prefix, - // represent last IPv4 address for VPP - get_last_ip_address( - (sc_ipv4_addr*) &address_range->payload.last_ip_address[0], - (sc_ipv4_addr*) &address_range->payload.first_ip_address[0], - prefix); - address_range->last_ip_address_set = true; - } - } - - return SR_ERR_OK; -} - -// XPATH: /ietf-nat:nat/instances/instance[id='%s']/policy[id='%s']/external-ip-address-pool[pool-id='%s']/ -static int instances_instance_policy_external_ip_address_pool_cb( - sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event, - void *private_ctx) -{ - UNUSED(private_ctx); - sr_error_t rc = SR_ERR_OK; - sr_change_iter_t *it = NULL; - sr_change_oper_t oper; - sr_val_t *old_val = NULL; - sr_val_t *new_val = NULL; - bool create = false; - bool delete = false; - struct address_range_t new_address_r = {0}; - struct address_range_t old_address_r = {0}; - - ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); - - SRP_LOG_INF("In %s", __FUNCTION__); - - new_address_r.payload.vrf_id = ~0; - old_address_r.payload.vrf_id = ~0; - - SRP_LOG_DBG("'%s' modified, event=%d", xpath, event); - - if (event != SR_EV_APPLY) { - return SR_ERR_OK; - } - - if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) { - // in example he calls even on fale - sr_free_change_iter(it); - return SR_ERR_OK; - } - - foreach_change (ds, it, oper, old_val, new_val) { - - SRP_LOG_DBG("A change detected in '%s', op=%d", - new_val ? new_val->xpath : old_val->xpath, oper); - - switch (oper) { - case SR_OP_CREATED: - create = true; - rc = parse_instance_policy_external_ip_address_pool(new_val, - &new_address_r); - break; - - case SR_OP_MODIFIED: - delete = true; - rc = parse_instance_policy_external_ip_address_pool(old_val, - &old_address_r); - if (SR_ERR_OK != rc) { - break; - } - - create = true; - rc = parse_instance_policy_external_ip_address_pool(new_val, - &new_address_r); - break; - - case SR_OP_MOVED: - break; - - case SR_OP_DELETED: - delete = true; - rc = parse_instance_policy_external_ip_address_pool(old_val, - &old_address_r); - break; - } - - sr_free_val(old_val); - sr_free_val(new_val); - - if (SR_ERR_OK != rc) { - rc = SR_ERR_OPERATION_FAILED; - goto error; - } - } - - if (delete) { - old_address_r.payload.is_add = 0; - rc = set_address_range(&old_address_r); - if (SR_ERR_OK != rc) { - goto error; - } - } - - if (create) { - new_address_r.payload.is_add = 1; - rc = set_address_range(&new_address_r); - if (SR_ERR_OK != rc) { - goto error; - } - } - -error: - sr_free_change_iter(it); - return rc; -} - -enum mapping_type { - STATIC, - DYNAMIC_IMPLICIT, - DYNAMIC_EXPLICIT, - UNKNOWN, -}; - -/** - * @brief Wrapper struct for VAPI static mapping payload. - */ -struct static_mapping_t { - enum mapping_type mtype; //< Mapping type - bool local_ip_address_set; //< Variable are set in payload. - bool external_ip_address_set; //< Variable are set in payload. - bool protocol_set; //< Variable are set in payload. - bool local_port_set; //< Variable are set in payload. - bool external_port_set; //< Variable are set in payload. - bool external_sw_if_index_set; //< Variable are set in payload. - bool vrf_id_set; //< Variable are set in payload. - bool twice_nat_set; //< Variable are set in payload. - nat44_add_del_static_mapping_t payload; //< VAPI payload for static mapping -}; - -// Check input structure, set VAPI payload and call VAPI function to set -// nat44 static mapping. -static sr_error_t set_static_mapping(struct static_mapping_t *mapping) -{ - int rc = 0; -// char tmp_ip1[VPP_IP4_ADDRESS_STRING_LEN]; -// char tmp_ip2[VPP_IP4_ADDRESS_STRING_LEN]; - - ARG_CHECK(SR_ERR_INVAL_ARG, mapping); - - if ((mapping->local_port_set != mapping->external_port_set) || - !mapping->local_ip_address_set || !mapping->external_ip_address_set) { - SRP_LOG_ERR_MSG("NAT44 parameter missing."); - - return SR_ERR_VALIDATION_FAILED; - } - - if (!mapping->local_port_set && !mapping->external_port_set) { - //FIXME!!!!! Compile error -// mapping->payload.flags = NAT_IS_ADDR_ONLY; - } else { - //FIXME!!!!! Compile error -// mapping->payload.flags = NAT_IS_TWICE_NAT; - if (!mapping->protocol_set) { - - SRP_LOG_ERR_MSG("NAT44 protocol missing."); - return SR_ERR_VALIDATION_FAILED; - } - } - - mapping->payload.external_sw_if_index = ~0; - -// strncpy(tmp_ip1, sc_ntoa(mapping->payload.local_ip_address), -// VPP_IP4_ADDRESS_STRING_LEN); -// strncpy(tmp_ip2, sc_ntoa(mapping->payload.external_ip_address), -// VPP_IP4_ADDRESS_STRING_LEN); -// SRP_LOG_DBG("Local ip address: %s, external ip address: %s, addr_only: %u," -// " protocol: %u, local port: %u, external port: %u, twice_nat: %u," -// "is_add: %u", tmp_ip1, tmp_ip2, mapping->payload.addr_only, -// mapping->payload.protocol, mapping->payload.local_port, -// mapping->payload.external_port, mapping->payload.twice_nat, -// mapping->payload.is_add); - - rc = nat44_add_del_static_mapping(&mapping->payload); - if (0 != rc) { - SRP_LOG_ERR_MSG("Failed set static mapping"); - return SR_ERR_OPERATION_FAILED; - } - - return SR_ERR_OK; -} - -// parse leaf from this xpath: -// /ietf-nat:nat/instances/instance[id='%s']/mapping-table/mapping-entry[index='%s']/ -static int parse_instance_mapping_table_mapping_entry( - const sr_val_t *val, - struct static_mapping_t *mapping) -{ - int rc; - char tmp_str[VPP_IP4_PREFIX_STRING_LEN] = {0}; - - ARG_CHECK2(SR_ERR_INVAL_ARG, val, mapping); - - sr_xpath_ctx_t state = {0}; - - if(sr_xpath_node_name_eq(val->xpath, "type")) { - if (!strncmp("static", val->data.string_val, strlen("static"))) { - mapping->mtype = STATIC; - } else if (!strncmp("dynamic-implicit", val->data.string_val, - strlen("dynamic-implicit"))) { - mapping->mtype = DYNAMIC_IMPLICIT; - } else if (!strncmp("dynamic-explicit", val->data.string_val, - strlen("dynamic-explicit"))) { - mapping->mtype = DYNAMIC_EXPLICIT; - } - } else if(sr_xpath_node_name_eq(val->xpath, "transport-protocol")) { - if (SR_UINT8_T != val->type) { - SRP_LOG_ERR("Wrong transport-protocol, type, current type: %d.", - val->type); - return SR_ERR_INVAL_ARG; - } - - mapping->payload.protocol = val->data.uint8_val; - mapping->protocol_set = true; - } else if(sr_xpath_node_name_eq(val->xpath, "internal-src-address")) { - if (SR_STRING_T != val->type) { - SRP_LOG_ERR("Wrong internal-src-address, type, current type: %d.", - val->type); - return SR_ERR_INVAL_ARG; - } - - rc = prefix2ip4(tmp_str, val->data.string_val, NULL); - if (0 != rc) { - SRP_LOG_ERR_MSG("Error translate"); - return SR_ERR_INVAL_ARG; - } - - rc = sc_aton(tmp_str, mapping->payload.local_ip_address, - VPP_IP4_ADDRESS_LEN); - if (0 != rc) { - SRP_LOG_ERR_MSG("Failed convert string IP address to int."); - return SR_ERR_INVAL_ARG; - } - - mapping->local_ip_address_set = true; - } else if(sr_xpath_node_name_eq(val->xpath, "external-src-address")) { - if (SR_STRING_T != val->type) { - SRP_LOG_ERR("Wrong external-src-address, type, current type: %d.", - val->type); - return SR_ERR_INVAL_ARG; - } - - rc = prefix2ip4(tmp_str, val->data.string_val, NULL); - if (0 != rc) { - SRP_LOG_ERR_MSG("Error translate"); - return SR_ERR_INVAL_ARG; - } - - rc = sc_aton(tmp_str, mapping->payload.external_ip_address, - VPP_IP4_ADDRESS_LEN); - if (0 != rc) { - SRP_LOG_ERR_MSG("Failed convert string IP address to int."); - return SR_ERR_INVAL_ARG; - } - - mapping->external_ip_address_set = true; - } else if (sr_xpath_node(val->xpath, "internal-src-port", &state)) { - sr_xpath_recover(&state); - if(sr_xpath_node_name_eq(val->xpath, "start-port-number")) { - mapping->local_port_set = true; - mapping->payload.local_port = val->data.uint16_val; - } - } else if (sr_xpath_node(val->xpath, "external-src-port", &state)) { - sr_xpath_recover(&state); - if(sr_xpath_node_name_eq(val->xpath, "start-port-number")) { - mapping->external_port_set = true; - mapping->payload.external_port = val->data.uint16_val; - } - } - - return SR_ERR_OK; -} - -// XPATH: /ietf-nat:nat/instances/instance[id='%s']/mapping-table/mapping-entry[index='%s']/ -static int instances_instance_mapping_table_mapping_entry_cb( - sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event, - void *private_ctx) -{ - UNUSED(private_ctx); - sr_error_t rc = SR_ERR_OK; - sr_change_iter_t *it = NULL; - sr_change_oper_t oper; - sr_val_t *old_val = NULL; - sr_val_t *new_val = NULL; - bool create = false; - bool delete = false; - struct static_mapping_t new_mapping = {0}; - struct static_mapping_t old_mapping = {0}; - - ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); - - SRP_LOG_INF("In %s", __FUNCTION__); - - new_mapping.mtype = UNKNOWN; - old_mapping.mtype = UNKNOWN; - - SRP_LOG_DBG("'%s' modified, event=%d", xpath, event); - - if (event != SR_EV_APPLY) { - return SR_ERR_OK; - } - - if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) { - // in example he calls even on fale - sr_free_change_iter(it); - return SR_ERR_OK; - } - - foreach_change (ds, it, oper, old_val, new_val) { - - SRP_LOG_DBG("A change detected in '%s', op=%d", - new_val ? new_val->xpath : old_val->xpath, oper); - - switch (oper) { - case SR_OP_CREATED: - create = true; - rc = parse_instance_mapping_table_mapping_entry(new_val, - &new_mapping); - break; - - case SR_OP_MODIFIED: - delete = true; - rc = parse_instance_mapping_table_mapping_entry(old_val, - &old_mapping); - if (SR_ERR_OK != rc) { - break; - } - - create = true; - rc = parse_instance_mapping_table_mapping_entry(new_val, - &new_mapping); - break; - - case SR_OP_MOVED: - break; - - case SR_OP_DELETED: - delete = true; - rc = parse_instance_mapping_table_mapping_entry(old_val, - &old_mapping); - break; - } - - sr_free_val(old_val); - sr_free_val(new_val); - - if (SR_ERR_OK != rc) { - rc = SR_ERR_OPERATION_FAILED; - goto error; - } - } - - if (delete) { - old_mapping.payload.is_add = 0; - if (STATIC == old_mapping.mtype) { - rc = set_static_mapping(&old_mapping); - if (SR_ERR_OK != rc) { - goto error; - } - } - } - - if (create) { - new_mapping.payload.is_add = 1; - if (STATIC == new_mapping.mtype) { - rc = set_static_mapping(&new_mapping); - if (SR_ERR_OK != rc) { - goto error; - } - } - } - -error: - sr_free_change_iter(it); - return rc; -} - -int -ietf_nat_init(sc_plugin_main_t *pm) -{ - int rc = SR_ERR_OK; - SRP_LOG_DBG_MSG("Initializing ietf-nat plugin."); - - rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/policy/external-ip-address-pool", - instances_instance_policy_external_ip_address_pool_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (rc != SR_ERR_OK) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/mapping-table/mapping-entry", - instances_instance_mapping_table_mapping_entry_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (rc != SR_ERR_OK) { - goto error; - } - - SRP_LOG_DBG_MSG("ietf-nat plugin initialized successfully."); - return SR_ERR_OK; - -error: - SRP_LOG_ERR("Error by initialization of ietf-nat plugin. Error : %d", rc); - return rc; -} - -void -ietf_nat_exit(__attribute__((unused)) sc_plugin_main_t *pm) -{ -} - -SC_INIT_FUNCTION(ietf_nat_init); -SC_EXIT_FUNCTION(ietf_nat_exit); diff --git a/src/plugins/ietf/ietf_nat.cpp b/src/plugins/ietf/ietf_nat.cpp new file mode 100644 index 0000000..4242df6 --- /dev/null +++ b/src/plugins/ietf/ietf_nat.cpp @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2019 PANTHEON.tech. + * 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. + */ + +/* + * Instances: + * ========== + * IETF NAT defines NAT instances, it is like databases which carry NAT + * configurations. + * VPP offers a single NAT database, so users should use instance with id=0. + * Thus, enabling/disabling a NAT instance is not supported. + * + * NAT instance capabilities: + * ========================== + * We currently support: + * -"static-mapping" + * + * NAT instance policies: + * ====================== + * + * VOM NAT + * ======== + * -Support NAT44/NAT66 static mapping (IP by IP) without transport protocol (NAT_IS_ADDR_ONLY) + * -Support declaration of an interface as an INSIDE/OUTSIDE interface. + * + * TODO ideas of new features which can be supported + * -Support for internal/external port in VOM and sweetcomb + * -Support for dynamic NAT in VOM and sweetcomb + */ + +#include +#include +#include + +#include +#include + +#include "sc_plugins.h" +#include "sys_util.h" + +using VOM::OM; +using VOM::rc_t; + +/* Just to intercept request trying to create nat instances */ +static int +nat_instance_config_cb(sr_session_ctx_t *ds, const char *xpath, + sr_notif_event_t event, void *private_ctx) +{ + UNUSED(ds); UNUSED(xpath); UNUSED(event); UNUSED(private_ctx); + + SRP_LOG_INF("In %s", __FUNCTION__); + + return SR_ERR_OK; +} + +typedef std::pair nat_pair_t; +typedef std::map nat_table_t; + +static nat_table_t static_mapping_table; + +/* + * Valid pairs for static NAT are: + * (internal_src address, external_src address) + * (inernal_dest address, external_dest address) + * Addresses must be of the same family i.e. no IP4 with IP6. + * + * Invalid pairs are: + * (internal_*, internal_*) , (external_*, external_*) + * (*_src, *_dest), (*_dest, *_src); + */ +class nat_static_builder { +public: + /* Default constructor */ + nat_static_builder() {} + + shared_ptr build() { + + if (m_type != "static") //only static is supported for now + return nullptr; + + if (! m_internal_src.empty() && ! m_external_src.empty() ) { + m_inside = m_internal_src.address(); + m_outside = m_external_src.address(); + } else if (! m_internal_dest.empty() && ! m_external_dest.empty() ) { + m_inside = m_internal_dest.address(); + m_outside = m_external_dest.address(); + } else + return nullptr; + + return make_shared(m_inside, m_outside); + } + + /* Getters */ + boost::asio::ip::address inside () + { return m_inside; } + boost::asio::ip::address outside() + { return m_outside; } + + /* Setters */ + nat_static_builder& set_type(std::string t) + { + m_type = t; + return *this; + } + nat_static_builder& set_internal_src(std::string p) + { + m_internal_src = utils::prefix::make_prefix(p); + return *this; + } + nat_static_builder& set_external_src(std::string p) + { + m_external_src = utils::prefix::make_prefix(p); + return *this; + } + nat_static_builder& set_internal_dest(std::string p) + { + m_internal_dest = utils::prefix::make_prefix(p); + return *this; + } + nat_static_builder& set_external_dest(std::string p) + { + m_external_dest = utils::prefix::make_prefix(p); + return *this; + } + +private: + std::string m_type; + utils::prefix m_internal_src; + utils::prefix m_external_src; + utils::prefix m_internal_dest; + utils::prefix m_external_dest; + boost::asio::ip::address m_inside; + boost::asio::ip::address m_outside; +}; + +/* + * /ietf-nat:nat/instances/instance[id='%s']/mapping-table/mapping-entry[index='%s']/ + */ +static int +nat_mapping_table_config_cb(sr_session_ctx_t *ds, const char *xpath, + sr_notif_event_t event, void *private_ctx) +{ + UNUSED(private_ctx); + nat_static_builder builder; + std::shared_ptr ns = nullptr; + sr_val_t *ol = nullptr; + sr_val_t *ne = nullptr; + sr_change_iter_t *it; + sr_change_oper_t oper; + uint32_t xindex; // mapping entry index from xpath + bool create, remove; + int rc; + + ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); + + if (event != SR_EV_VERIFY) + return SR_ERR_OK; + + SRP_LOG_INF("In %s", __FUNCTION__); + + rc = sr_get_changes_iter(ds, (char *)xpath, &it); + if (rc != SR_ERR_OK) + goto error; + + foreach_change(ds, it, oper, ol, ne) { + + switch (oper) { + case SR_OP_CREATED: + if (sr_xpath_node_name_eq(ne->xpath, "index")) { + xindex = ne->data.uint32_val; + create = true; + } else if (sr_xpath_node_name_eq(ne->xpath, "type")) { + /* For configuration only "static" can be supported */ + builder.set_type(string(ne->data.string_val)); + } else if (sr_xpath_node_name_eq(ne->xpath, "internal-src-address")) { + /* source IP on NAT internal network src address */ + builder.set_internal_src(string(ne->data.string_val)); + } else if (sr_xpath_node_name_eq(ne->xpath, "external-src-address")) { + /* source IP on NAT external network src address */ + builder.set_external_src(string(ne->data.string_val)); + } else if (sr_xpath_node_name_eq(ne->xpath, "internal-dst-address")) { + /* destination IP on NAT internal network src address */ + builder.set_internal_dest(string(ne->data.string_val)); + } else if (sr_xpath_node_name_eq(ne->xpath, "external-dst-address")) { + /* destination IP on NAT internal network src address */ + builder.set_external_dest(string(ne->data.string_val)); + } + break; + + case SR_OP_DELETED: + if (sr_xpath_node_name_eq(ol->xpath, "index")) { + xindex = ol->data.uint32_val; + remove = true; + } + break; + + default: + SRP_LOG_WRN_MSG("Operation not supported"); + rc = SR_ERR_UNSUPPORTED; + goto error; + } + + sr_free_val(ne); + sr_free_val(ol); + } + + sr_free_change_iter(it); + + if (create) { + ns = builder.build(); + if (ns == nullptr) { + SRP_LOG_ERR("Fail building nat %s %s", + builder.inside().to_string().c_str(), + builder.outside().to_string().c_str()); + rc = SR_ERR_INVAL_ARG; + goto error; + } + } + + if (create) { + #define KEY(xindex) to_string(xindex) + if (OM::write(KEY(xindex), *ns) != rc_t::OK) { + SRP_LOG_ERR("Fail writing changes for nat: %s", + ns->to_string().c_str()); + rc = SR_ERR_OPERATION_FAILED; + goto error; + } + static_mapping_table[xindex] = nat_pair_t(builder.inside(), + builder.outside()); + SRP_LOG_INF_MSG("Sucess creating nat static entry"); + } else if (remove) { + OM::remove(KEY(xindex)); + static_mapping_table.erase(xindex); + #undef KEY + } + + return SR_ERR_OK; + +error: + sr_free_val(ol); + sr_free_val(ne); + sr_free_change_iter(it); + return rc; +} + +/* + * /ietf-nat:nat/instances/instance/capabilities + */ +static int +nat_cap_state_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, + uint64_t request_id, const char *original_xpath, + void *private_ctx) +{ + UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); + sr_val_t *val = nullptr; + int vc = 1; //expected number of answer + int cnt = 0; //value counter + int rc; + + SRP_LOG_INF("In %s", __FUNCTION__); + + rc = sr_new_values(vc, &val); + if (0 != rc) { + rc = SR_ERR_NOMEM; + goto nothing_todo; + } + + sr_val_build_xpath(&val[cnt], "%s/static-mapping", xpath); + val[cnt].type = SR_BOOL_T; + val[cnt].data.bool_val = true; + cnt++; + + *values = val; + *values_cnt = cnt; + + return SR_ERR_OK; + +nothing_todo: + *values = NULL; + *values_cnt = 0; + return rc; +} + + +int +ietf_nat_init(sc_plugin_main_t *pm) +{ + int rc = SR_ERR_OK; + SRP_LOG_DBG_MSG("Initializing ietf-nat plugin."); + + rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance", + nat_instance_config_cb, NULL, 1, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (rc != SR_ERR_OK) { + goto error; + } + + rc = sr_subtree_change_subscribe(pm->session, "/ietf-nat:nat/instances/instance/mapping-table/mapping-entry", + nat_mapping_table_config_cb, NULL, 10, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (rc != SR_ERR_OK) { + goto error; + } + + rc = sr_dp_get_items_subscribe(pm->session, "/ietf-nat:nat/instances/instance/capabilities", + nat_cap_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + SRP_LOG_DBG_MSG("ietf-nat plugin initialized successfully."); + return SR_ERR_OK; + +error: + SRP_LOG_ERR("Error by initialization of ietf-nat plugin. Error : %d", rc); + return rc; +} + +void +ietf_nat_exit(__attribute__((unused)) sc_plugin_main_t *pm) +{ +} + +SC_INIT_FUNCTION(ietf_nat_init); +SC_EXIT_FUNCTION(ietf_nat_exit); diff --git a/src/plugins/openconfig/openconfig_interfaces.c b/src/plugins/openconfig/openconfig_interfaces.c deleted file mode 100644 index 67b9a3c..0000000 --- a/src/plugins/openconfig/openconfig_interfaces.c +++ /dev/null @@ -1,646 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include -#include - -#include - -// XPATH: /openconfig-interfaces:interfaces/interface[name='%s']/config/ -static int openconfig_interfaces_interfaces_interface_config_cb( - sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event, - void *private_ctx) -{ - UNUSED(private_ctx); - sr_change_iter_t *it = NULL; - sr_change_oper_t oper; - sr_xpath_ctx_t state = {0}; - sr_val_t *old = NULL; - sr_val_t *new = NULL; - char *tmp = NULL; - char interface_name[XPATH_SIZE] = {0}; - int rc = 0; - - SRP_LOG_INF("In %s", __FUNCTION__); - SRP_LOG_INF("XPATH %s", xpath); - - ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); - - if (event == SR_EV_APPLY) - return SR_ERR_OK; - - if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) { - sr_free_change_iter(it); - return SR_ERR_OK; - } - - foreach_change (ds, it, oper, old, new) { - - SRP_LOG_DBG("xpath: %s", new->xpath); - - tmp = sr_xpath_key_value(new->xpath, "interface", "name", &state); - if (!tmp) { - sr_set_error(ds, "XPATH interface name NOT found", new->xpath); - return SR_ERR_INVAL_ARG; - } - strncpy(interface_name, tmp, XPATH_SIZE); - sr_xpath_recover(&state); - - switch (oper) { - case SR_OP_CREATED: - case SR_OP_MODIFIED: - if (sr_xpath_node_name_eq(new->xpath, "name")) { - //TODO: LEAF: name, type: string - } else if(sr_xpath_node_name_eq(new->xpath, "type")) { - //TODO: LEAF: type, type: identityref - } else if(sr_xpath_node_name_eq(new->xpath, "mtu")) { - //TODO: LEAF: mtu, type: uint16 - } else if(sr_xpath_node_name_eq(new->xpath, - "loopback-mode")) { - //TODO: LEAF: loopback-mode, type: boolean - } else if(sr_xpath_node_name_eq(new->xpath, - "description")) { - //TODO: LEAF: description, type: string - } else if(sr_xpath_node_name_eq(new->xpath, "enabled")) { - rc = interface_enable(interface_name, - new->data.bool_val); - } else if(sr_xpath_node_name_eq(new->xpath, - "oc-vlan:tpid")) { - //TODO: LEAF: oc-vlan:tpid, type: identityref - } - break; - - case SR_OP_MOVED: - break; - - case SR_OP_DELETED: - if (sr_xpath_node_name_eq(old->xpath, "name")) { - //TODO: LEAF: name, type: string - } else if(sr_xpath_node_name_eq(old->xpath, "type")) { - //TODO: LEAF: type, type: identityref - } else if(sr_xpath_node_name_eq(old->xpath, "mtu")) { - //TODO: LEAF: mtu, type: uint16 - } else if(sr_xpath_node_name_eq(old->xpath, - "loopback-mode")) { - //TODO: LEAF: loopback-mode, type: boolean - } else if(sr_xpath_node_name_eq(old->xpath, - "description")) { - //TODO: LEAF: description, type: string - } else if(sr_xpath_node_name_eq(old->xpath, "enabled")) { - rc = interface_enable(interface_name, false); - } else if(sr_xpath_node_name_eq(old->xpath, - "oc-vlan:tpid")) { - //TODO: LEAF: oc-vlan:tpid, type: identityref - } - break; - } - - if (0 != rc) { - sr_xpath_recover(&state); - - sr_free_val(old); - sr_free_val(new); - - sr_free_change_iter(it); - - return SR_ERR_OPERATION_FAILED; - } - - sr_xpath_recover(&state); - - sr_free_val(old); - sr_free_val(new); - } - - sr_free_change_iter(it); - return SR_ERR_OK; -} - -//XPATH : /openconfig-interfaces:interfaces/interface/state -static int -openconfig_interfaces_interfaces_interface_state_cb( - const char *xpath, sr_val_t **values, - size_t *values_cnt, uint64_t request_id, const char *original_xpath, - void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - sw_interface_dump_t reply = {0}; - sr_val_t *vals = NULL; - sr_xpath_ctx_t state = {0}; - char interface_name[VPP_INTFC_NAME_LEN] = {0}; - char xpath_root[XPATH_SIZE]; - int vc = 10; - char *tmp; - int rc; - - SRP_LOG_INF("In %s", __FUNCTION__); - - ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); - - tmp = sr_xpath_key_value((char*) xpath, "interface", "name", &state); - if (!tmp) { - SRP_LOG_ERR_MSG("XPATH interface name not found"); - return SR_ERR_INVAL_ARG; - } - strncpy(interface_name, tmp, VPP_INTFC_NAME_LEN); - sr_xpath_recover(&state); - - snprintf(xpath_root, XPATH_SIZE, - "/openconfig-interfaces:interfaces/interface[name='%s']/state", - interface_name); - - //dump interface interface_name - rc = interface_dump_iface(&reply, interface_name); - if (rc == -SCVPP_NOT_FOUND) { - SRP_LOG_ERR_MSG("interface not found"); - return SR_ERR_NOT_FOUND; - } - - rc = sr_new_values(vc, &vals); - if (SR_ERR_OK != rc) - return rc; - - sr_val_build_xpath(&vals[0], "%s/name", xpath_root); - sr_val_set_str_data(&vals[0], SR_STRING_T, (char *)reply.interface_name); - - sr_val_build_xpath(&vals[1], "%s/type", xpath_root); - sr_val_set_str_data(&vals[1], SR_IDENTITYREF_T, "ianaift:ethernetCsmacd"); - - sr_val_build_xpath(&vals[2], "%s/mtu", xpath_root); - vals[2].type = SR_UINT16_T; - vals[2].data.uint16_val = reply.link_mtu; - - sr_val_build_xpath(&vals[3], "%s/loopback-mode", xpath_root); - vals[3].type = SR_BOOL_T; - if (strncmp((char*)reply.interface_name, "loop", 4) == 0) - vals[3].data.bool_val = 1; - else - vals[3].data.bool_val = 0; - - sr_val_build_xpath(&vals[4], "%s/description", xpath_root); - sr_val_set_str_data(&vals[4], SR_STRING_T, NOT_AVAL); - - sr_val_build_xpath(&vals[5], "%s/enabled", xpath_root); - vals[5].type = SR_BOOL_T; - vals[5].data.bool_val = reply.admin_up_down; - - sr_val_build_xpath(&vals[6], "%s/ifindex", xpath_root); - vals[6].type = SR_UINT32_T; - vals[6].data.uint32_val = reply.sw_if_index; - - sr_val_build_xpath(&vals[7], "%s/admin-status", xpath_root); - sr_val_set_str_data(&vals[7], SR_ENUM_T, - reply.admin_up_down ? "UP" : "DOWN"); - - sr_val_build_xpath(&vals[8], "%s/oper-status", xpath_root); - sr_val_set_str_data(&vals[8], SR_ENUM_T, - reply.link_up_down ? "UP" : "DOWN"); - - //TODO: Openconfig required this value - // sr_val_build_xpath(&vals[9], "%s/last-change", xpath_root); - // sr_val_set_str_data(&vals[9], YANG INPUT TYPE: oc-types:timeticks64); - - sr_val_build_xpath(&vals[9], "%s/logical", xpath_root); - vals[9].type = SR_BOOL_T; - vals[9].data.bool_val = true; //for now, we assume all are logical - - *values = vals; - *values_cnt = vc; - - return SR_ERR_OK; -} - -//TODO: for some arcane reason, this doesn't work -static int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_cb( - const char *xpath, sr_val_t **values, size_t *values_cnt, - uint64_t request_id, const char *original_xpath, void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - char xpath_root[XPATH_SIZE] = {0}; - sr_xpath_ctx_t state = {0}; - sr_val_t *vals = NULL; - char interface_name[VPP_INTFC_NAME_LEN] = {0}; - char subinterface_index[XPATH_SIZE] = {0}; - char address_ip[XPATH_SIZE] = {0}; - u8 prefix_len; - char *tmp = NULL; - int rc, cnt = 0; - - ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); - - SRP_LOG_INF("In %s", __FUNCTION__); - - /* Get XPATH parameters name, index and ip */ - - tmp = sr_xpath_key_value((char*)xpath, "interface", "name", &state); - if (!tmp) { - SRP_LOG_ERR_MSG("XPATH interface name not found"); - return SR_ERR_INVAL_ARG; - } - strncpy(interface_name, tmp, VPP_INTFC_NAME_LEN); - sr_xpath_recover(&state); - - tmp = sr_xpath_key_value((char*)xpath, "subinterface", "index", &state); - if (NULL == tmp) { - SRP_LOG_ERR_MSG("XPATH subinterface index not found."); - return SR_ERR_INVAL_ARG; - } - strncpy(subinterface_index, tmp, XPATH_SIZE); - sr_xpath_recover(&state); - - tmp = sr_xpath_key_value((char*)xpath, "address", "ip", &state); - if (NULL == tmp) { - SRP_LOG_ERR_MSG("XPATH address ip not found."); - return SR_ERR_INVAL_ARG; - } - strncpy(address_ip, tmp, XPATH_SIZE); - sr_xpath_recover(&state); - - snprintf(xpath_root, XPATH_SIZE, "/openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address[ip='%s']/openconfig-if-ip:state", - interface_name, subinterface_index, address_ip); - - rc = ipv46_address_dump(interface_name, address_ip, &prefix_len, false); - if (!rc) { - SRP_LOG_ERR_MSG("ipv46_address_dump failed"); - return SR_ERR_INVAL_ARG; - } - - /* Build answer to state XPATH */ - - rc = sr_new_values(3, &vals); - if (SR_ERR_OK != rc) - return rc; - - sr_val_build_xpath(&vals[cnt], "%s/openconfig-if-ip:ip", xpath_root); - sr_val_set_str_data(&vals[cnt], SR_STRING_T, address_ip); - cnt++; - - sr_val_build_xpath(&vals[cnt], "%s/openconfig-if-ip:prefix-length", xpath_root); - vals[cnt].type = SR_UINT8_T; - vals[cnt].data.uint8_val = prefix_len; - cnt++; - - sr_val_build_xpath(&vals[cnt], "%s/openconfig-if-ip:origin", xpath_root); - sr_val_set_str_data(&vals[cnt], SR_ENUM_T, "STATIC"); - cnt++; - - sr_xpath_recover(&state); - *values = vals; - *values_cnt = cnt; - - return SR_ERR_OK; -} - -/* TODO move to common functions between all plugins */ -static bool -is_subinterface(const char* subif_name, const char* base_name, - const u32 subif_index) -{ - assert(subif_name && base_name); - - const char* dot = strchr(subif_name, '.'); - - if (NULL == dot && 0 == subif_index) - return true; //subif_index == 0 can pass as a "real" interface - - if (dot > subif_name && 0 == strncmp(subif_name, base_name, - dot - subif_name)) { - char * eptr = NULL; - u32 si = strtoul(dot + 1, &eptr, 10); - - if ('\0' == *eptr && subif_index == si) - return true; - } - - return false; -} - -// openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/state -static int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_cb( - const char *xpath, sr_val_t **values, size_t *values_cnt, - uint64_t request_id, const char *original_xpath, void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - sw_interface_dump_t reply = {0}; - char xpath_root[XPATH_SIZE]; - sr_xpath_ctx_t state = {0}; - char *tmp = NULL; - char interface_name[VPP_INTFC_NAME_LEN] = {0}; - char subinterface_index[XPATH_SIZE] = {0}; - u32 sub_id; - sr_val_t *vals = NULL; - int vc = 6; - int val_idx = 0; - int rc; - - ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); - - SRP_LOG_INF("In %s", __FUNCTION__); - - tmp = sr_xpath_key_value((char*)xpath, "interface", "name", &state); - if (!tmp) { - SRP_LOG_ERR_MSG("XPATH interface name not found"); - return SR_ERR_INVAL_ARG; - } - strncpy(interface_name, tmp, VPP_INTFC_NAME_LEN); - sr_xpath_recover(&state); - - tmp = sr_xpath_key_value((char*)xpath, "subinterface", "index", &state); - if (!tmp) { - SRP_LOG_ERR_MSG("subinterface index not found"); - return SR_ERR_INVAL_ARG; - } - strncpy(subinterface_index, tmp, XPATH_SIZE); - sr_xpath_recover(&state); - - snprintf(xpath_root, XPATH_SIZE, - "/openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/state", - interface_name, subinterface_index); - - rc = interface_dump_iface(&reply, interface_name); - if (rc == -SCVPP_NOT_FOUND) { - SRP_LOG_ERR_MSG("interface not found"); - return SR_ERR_NOT_FOUND; - } - - /* Check that requested subinterface index matches reply subid */ - sub_id = atoi(subinterface_index); - if (sub_id != reply.sub_id) { - SRP_LOG_ERR_MSG("subinterface index not found."); - return SR_ERR_NOT_FOUND; - } - - /* Check that interface is a sub interface */ - if (!is_subinterface((char*)reply.interface_name, interface_name, sub_id)) { - SRP_LOG_ERR("%s not a subinterface", interface_name); - return SR_ERR_OPERATION_FAILED; - } - - rc = sr_new_values(vc, &vals); - if (SR_ERR_OK != rc) - return rc; - - sr_val_build_xpath(&vals[val_idx], "%s/index", xpath_root); - vals[val_idx].type = SR_UINT32_T; - vals[val_idx++].data.uint32_val = sub_id; - - sr_val_build_xpath(&vals[val_idx], "%s/description", xpath_root); - sr_val_set_str_data(&vals[val_idx++], SR_STRING_T, NOT_AVAL); - - sr_val_build_xpath(&vals[val_idx], "%s/enabled", xpath_root); - vals[val_idx].type = SR_BOOL_T; - vals[val_idx++].data.bool_val = reply.admin_up_down; - - //TODO: Openconfig required this value - // sr_val_build_xpath(&vals[val_idx], "%s/name", xpath_root); - // sr_val_set_str_data(&vals[val_idx++], SR_STRING_T, YANG INPUT TYPE: string); - - // sr_val_build_xpath(&vals[val_idx], "%s/ifindex", interface_name, sub_id); - // vals[val_idx].type = SR_UINT32_T; - // vals[val_idx++].data.uint32_val = YANG INPUT TYPE: uint32; - - sr_val_build_xpath(&vals[val_idx], "%s/admin-status", xpath_root); - sr_val_set_str_data(&vals[val_idx++], SR_ENUM_T, - reply.admin_up_down ? "UP" : "DOWN"); - - sr_val_build_xpath(&vals[val_idx], "%s/oper-status", xpath_root); - sr_val_set_str_data(&vals[val_idx++], SR_ENUM_T, reply.admin_up_down ? "UP" : "DOWN"); - - //TODO: Openconfig required this value - // sr_val_build_xpath(&vals[val_idx], "/openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/state/last-change", interface_name, sub_id); - // sr_val_set_str_data(&vals[val_idx++], YANG INPUT TYPE: oc-types:timeticks64); - - sr_val_build_xpath(&vals[val_idx], "%s/logical", xpath_root); - vals[val_idx].type = SR_BOOL_T; - vals[val_idx++].data.bool_val = true; //for now, we assume all are logical - - sr_xpath_recover(&state); - - *values = vals; - *values_cnt = vc; - - return SR_ERR_OK; -} - -// openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/oc-ip:ipv4/oc-ip:addresses/oc-ip:address[ip='%s']/oc-ip:config/ -static int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_config_cb( - sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event, - void *private_ctx) -{ - UNUSED(private_ctx); - sr_change_iter_t *it = NULL; - sr_change_oper_t oper; - sr_xpath_ctx_t state = {0}; - sr_val_t *old = NULL; - sr_val_t *new = NULL; - char *tmp = NULL; - char interface_name[VPP_INTFC_NAME_LEN] = {0}; - char subinterface_index[XPATH_SIZE] = {0}; - char address_ip[XPATH_SIZE] = {0}; - char old_address_ip[XPATH_SIZE] = {0}; - u8 prefix_len = 0; - u8 old_prefix_len = 0; - int rc = 0; - bool ip_set = false, prefix_len_set = false; - bool old_ip_set = false, old_prefix_len_set = false; - - ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); - - // if we receive event SR_EV_APPLY - config has changed - - if (event == SR_EV_APPLY) - return SR_ERR_OK; - - if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) { - sr_free_change_iter(it); - return SR_ERR_OK; - } - - foreach_change (ds, it, oper, old, new) { - - SRP_LOG_DBG("xpath: %s", new->xpath); - - tmp = sr_xpath_key_value(new->xpath, "interface", "name", &state); - if (!tmp) { - sr_set_error(ds, "XPATH interface name NOT found", new->xpath); - return SR_ERR_INVAL_ARG; - } - strncpy(interface_name, tmp, VPP_INTFC_NAME_LEN); - sr_xpath_recover(&state); - - tmp = sr_xpath_key_value(new->xpath, "subinterface", "index", &state); - if (!tmp) { - sr_set_error(ds, "XPATH subinterface index NOT found", new->xpath); - return SR_ERR_INVAL_ARG; - } - strncpy(subinterface_index, tmp, XPATH_SIZE); - sr_xpath_recover(&state); - - switch (oper) { - case SR_OP_CREATED: - if (sr_xpath_node_name_eq(new->xpath, "ip")) { - ip_set = true; - strncpy(address_ip, new->data.string_val, XPATH_SIZE); - } else if (sr_xpath_node_name_eq(new->xpath, - "prefix-length")) { - prefix_len_set = true; - prefix_len = new->data.uint8_val; - } - - if (ip_set && prefix_len_set) //add ipv4 - rc = ipv46_config_add_remove(interface_name, address_ip, - prefix_len, false , true); - - break; - - case SR_OP_MODIFIED: - if (sr_xpath_node_name_eq(old->xpath, "ip")) { - old_ip_set = true; - strncpy(old_address_ip, old->data.string_val, - XPATH_SIZE); - } else if (sr_xpath_node_name_eq(old->xpath, - " prefix-length")) { - old_prefix_len_set = true; - old_prefix_len = old->data.uint8_val; - } - - if (sr_xpath_node_name_eq(new->xpath, "ip")) { - ip_set = true; - strncpy(address_ip, new->data.string_val, XPATH_SIZE); - } else if (sr_xpath_node_name_eq(new->xpath, - "prefix-length")) { - prefix_len_set = true; - prefix_len = new->data.uint8_val; - } - - if (old_ip_set && old_prefix_len_set) { - //remove ipv4 - rc = ipv46_config_add_remove(interface_name, old_address_ip, - old_prefix_len, false, false); - if (0 != rc) { - break; - } - } - - if (ip_set && prefix_len_set) { - //add ipv4 - rc = ipv46_config_add_remove(interface_name, address_ip, - prefix_len, false, true); - } - break; - - case SR_OP_MOVED: - break; - - case SR_OP_DELETED: - if (sr_xpath_node_name_eq(old->xpath, "ip")) { - old_ip_set = true; - strncpy(old_address_ip, old->data.string_val, - XPATH_SIZE); - } else if (sr_xpath_node_name_eq(old->xpath, - "prefix-length")) { - old_prefix_len_set = true; - old_prefix_len = old->data.uint8_val; - } - - if (old_ip_set && old_prefix_len_set) { - //remove ipv4 - rc = ipv46_config_add_remove(interface_name, old_address_ip, - old_prefix_len, false, false); - } - break; - } - - if (0 != rc) { - sr_xpath_recover(&state); - - sr_free_val(old); - sr_free_val(new); - - sr_free_change_iter(it); - - return SR_ERR_OPERATION_FAILED; - } - - sr_xpath_recover(&state); - - sr_free_val(old); - sr_free_val(new); - } - - sr_free_change_iter(it); - return SR_ERR_OK; -} - -int -openconfig_interface_init(sc_plugin_main_t *pm) -{ - int rc = SR_ERR_OK; - SRP_LOG_DBG_MSG("Initializing openconfig-interfaces plugin."); - - rc = sr_subtree_change_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/config", - openconfig_interfaces_interfaces_interface_config_cb, NULL, 98, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/state", - openconfig_interfaces_interfaces_interface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/state", - openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->session, - "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:config", - openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_config_cb, - NULL, 100, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, - "/openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:state", - openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_cb, - NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - SRP_LOG_DBG_MSG("openconfig-interfaces plugin initialized successfully."); - return SR_ERR_OK; - -error: - SRP_LOG_ERR("Error by initialization of openconfig-interfaces plugin. Error : %d", rc); - return rc; -} - -void -openconfig_interface_exit(__attribute__((unused)) sc_plugin_main_t *pm) -{ -} - -SC_INIT_FUNCTION(openconfig_interface_init); -SC_EXIT_FUNCTION(openconfig_interface_exit); diff --git a/src/plugins/openconfig/openconfig_interfaces.cpp b/src/plugins/openconfig/openconfig_interfaces.cpp new file mode 100644 index 0000000..40de71c --- /dev/null +++ b/src/plugins/openconfig/openconfig_interfaces.cpp @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include + +#include + +#include + +using VOM::interface; +using VOM::OM; +using VOM::HW; +using VOM::rc_t; + +using type_t = VOM::interface::type_t; +using admin_state_t = VOM::interface::admin_state_t; + +class interface_builder { + public: + interface_builder() {} + + shared_ptr build() { + if (m_name.empty() || m_type.empty()) + return nullptr; + return make_shared(m_name, type_t::from_string(m_type), + admin_state_t::from_int(m_state)); + } + + /* Getters */ + string name() { + return m_name; + } + + /* Setters */ + interface_builder& set_name(string n) { + m_name = n; + return *this; + } + + interface_builder& set_type(string t) { + if (t == "iana-if-type:ethernetCsmacd") + m_type = "ETHERNET"; + return *this; + } + + interface_builder& set_state(bool enable) { + m_state = enable; + return *this; + } + + std::string to_string() { + std::ostringstream os; + os << m_name << "," << m_type << "," << m_state; + return os.str(); + } + + private: + string m_name; + string m_type; + bool m_state; +}; + + +// XPATH: /openconfig-interfaces:interfaces/interface[name='%s']/config/ +static int +oc_interfaces_config_cb(sr_session_ctx_t *ds, const char *xpath, + sr_notif_event_t event, void *private_ctx) +{ + UNUSED(private_ctx); + interface_builder builder; + shared_ptr intf; + string intf_name; + sr_change_iter_t *it = nullptr; + sr_xpath_ctx_t state; + sr_val_t *ol = nullptr; + sr_val_t *ne = nullptr; + sr_change_oper_t oper; + bool create, remove, modify; + int rc; + + SRP_LOG_INF("In %s", __FUNCTION__); + + ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); + + if (event != SR_EV_VERIFY) + return SR_ERR_OK; + + if (sr_get_changes_iter(ds, (char *)xpath, &it) != SR_ERR_OK) { + sr_free_change_iter(it); + return SR_ERR_OK; + } + + foreach_change (ds, it, oper, ol, ne) { + + intf_name = sr_xpath_key_value(ne->xpath, "interface", "name", &state); + if (intf_name.empty()) { + sr_set_error(ds, "XPATH interface name NOT found", ne->xpath); + return SR_ERR_INVAL_ARG; + } + sr_xpath_recover(&state); + + switch (oper) { + case SR_OP_CREATED: + if (sr_xpath_node_name_eq(ne->xpath, "name")) { + builder.set_name(ne->data.string_val); + create = true; + } else if(sr_xpath_node_name_eq(ne->xpath, "type")) { + builder.set_type(ne->data.string_val); + } else if(sr_xpath_node_name_eq(ne->xpath, "enabled")) { + builder.set_state(ne->data.bool_val); + } + break; + + case SR_OP_MODIFIED: + if (sr_xpath_node_name_eq(ne->xpath, "enabled")) { + string n = sr_xpath_key_value(ne->xpath, "interface", + "name", &state); + intf = interface::find(n); + if (!intf) { + rc = SR_ERR_OPERATION_FAILED; + goto nothing_todo; + } + intf->set(admin_state_t::from_int(ne->data.bool_val)); + modify = true; + } + break; + + case SR_OP_DELETED: + if (sr_xpath_node_name_eq(ol->xpath, "name")) { + builder.set_name(ol->data.string_val); + remove = true; + } + break; + + default: + rc = SR_ERR_UNSUPPORTED; + goto nothing_todo; + } + + sr_xpath_recover(&state); + + sr_free_val(ol); + sr_free_val(ne); + } + + if (create) { + SRP_LOG_INF("creating interface '%s'", builder.name().c_str()); + intf = builder.build(); + if (nullptr == intf) { + SRP_LOG_ERR_MSG("Interface does not exist"); + rc = SR_ERR_INVAL_ARG; + goto nothing_todo; + } + } + + if (create || modify) { + if ( OM::write(intf->key(), *intf) != rc_t::OK ) { + SRP_LOG_ERR("Fail writing changes to VPP for: %s", + builder.to_string().c_str()); + rc = SR_ERR_OPERATION_FAILED; + goto nothing_todo; + } + } else if (remove) { + SRP_LOG_INF("deleting interface '%s'", builder.name().c_str()); + OM::remove(builder.name()); + } + + sr_free_change_iter(it); + return SR_ERR_OK; + +nothing_todo: + sr_free_val(ol); + sr_free_val(ne); + sr_free_change_iter(it); + return rc; +} + +//XPATH : /openconfig-interfaces:interfaces/interface/state +static int +oc_interfaces_state_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, + uint64_t request_id, const char *original_xpath, + void *private_ctx) +{ + UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); + vapi_payload_sw_interface_details reply; + shared_ptr dump; + string intf_name; + sr_val_t *vals = nullptr; + sr_xpath_ctx_t state; + char xpath_root[XPATH_SIZE]; + int vc = 7; + int cnt = 0; + int rc; + + SRP_LOG_INF("In %s", __FUNCTION__); + + ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); + + intf_name = sr_xpath_key_value((char*) xpath, "interface", "name", &state); + if (intf_name.empty()) { + SRP_LOG_ERR_MSG("XPATH interface name not found"); + return SR_ERR_INVAL_ARG; + } + sr_xpath_recover(&state); + + snprintf(xpath_root, XPATH_SIZE, + "/openconfig-interfaces:interfaces/interface[name='%s']/state", + intf_name.c_str()); + + rc = sr_new_values(vc, &vals); + if (SR_ERR_OK != rc) + return rc; + + dump = make_shared(intf_name); //dump only specific intf + HW::enqueue(dump); + HW::write(); + + reply = dump->begin()->get_payload(); + + sr_val_build_xpath(&vals[cnt], "%s/name", xpath_root); + sr_val_set_str_data(&vals[cnt], SR_STRING_T, (char *)reply.interface_name); + cnt++; + + //TODO revisit types after V3PO has been implemented + sr_val_build_xpath(&vals[cnt], "%s/type", xpath_root); + sr_val_set_str_data(&vals[cnt], SR_IDENTITYREF_T, "ianaift:ethernetCsmacd"); + cnt++; + + sr_val_build_xpath(&vals[cnt], "%s/mtu", xpath_root); + vals[cnt].type = SR_UINT16_T; + vals[cnt].data.uint16_val = reply.link_mtu; + cnt++; + + sr_val_build_xpath(&vals[cnt], "%s/enabled", xpath_root); + vals[cnt].type = SR_BOOL_T; + vals[cnt].data.bool_val = reply.admin_up_down; + cnt++; + + sr_val_build_xpath(&vals[cnt], "%s/ifindex", xpath_root); + vals[cnt].type = SR_UINT32_T; + vals[cnt].data.uint32_val = reply.sw_if_index; + cnt++; + + sr_val_build_xpath(&vals[cnt], "%s/admin-status", xpath_root); + sr_val_set_str_data(&vals[cnt], SR_ENUM_T, + reply.admin_up_down ? "UP" : "DOWN"); + cnt++; + + sr_val_build_xpath(&vals[cnt], "%s/oper-status", xpath_root); + sr_val_set_str_data(&vals[cnt], SR_ENUM_T, + reply.link_up_down ? "UP" : "DOWN"); + cnt++; + + *values = vals; + *values_cnt = cnt; + + return SR_ERR_OK; +} + +int +openconfig_interface_init(sc_plugin_main_t *pm) +{ + int rc = SR_ERR_OK; + SRP_LOG_DBG_MSG("Initializing openconfig-interfaces plugin."); + + rc = sr_subtree_change_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/config", + oc_interfaces_config_cb, nullptr, 98, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-interfaces:interfaces/interface/state", + oc_interfaces_state_cb, nullptr, SR_SUBSCR_CTX_REUSE, &pm->subscription); + if (SR_ERR_OK != rc) { + goto error; + } + + SRP_LOG_DBG_MSG("openconfig-interfaces plugin initialized successfully."); + return SR_ERR_OK; + +error: + SRP_LOG_ERR("Error by initialization of openconfig-interfaces plugin. Error : %d", rc); + return rc; +} + +void +openconfig_interface_exit(__attribute__((unused)) sc_plugin_main_t *pm) +{ +} + +SC_INIT_FUNCTION(openconfig_interface_init); +SC_EXIT_FUNCTION(openconfig_interface_exit); diff --git a/src/plugins/openconfig/openconfig_local_routing.c b/src/plugins/openconfig/openconfig_local_routing.c deleted file mode 100644 index 2d16da0..0000000 --- a/src/plugins/openconfig/openconfig_local_routing.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include -#include - -#include - -#define HOP_INDEX_SIZE 10 //number of digit in max 32 bit integer - -static inline int -_set_route (const char *prefix, const char *nhop, bool is_add, - const char *iface) -{ - int table = 0; //FIB table ID - int mask; - int rc; - - // Put prefix length in mask and prefix IP in prefix - mask = ip_prefix_split(prefix); - if (mask < 1) { - SRP_LOG_ERR("Prefix length can not be %d", mask); - return SR_ERR_INVAL_ARG; - } - - rc = ipv46_config_add_del_route(prefix, mask, nhop, is_add, table, iface); - if (rc != SCVPP_OK) { - SRP_LOG_ERR("Add/delete route failed for %s %s", prefix, iface); - return SR_ERR_INVAL_ARG; - } - - SRP_LOG_INF("Add/delete route Success for %s %s", prefix, iface); - - return SR_ERR_OK; -} - -#define STR(string) #string - -#define ROOT "/openconfig-local-routing:local-routes/static-routes/static[prefix='%s']/next-hops/next-hop[index='%s']/%s" - -static inline char * _get_ds_elem(sr_session_ctx_t *sess, const char *prefix, - const char *index, const char *sub) -{ - char xpath[XPATH_SIZE] = {0}; - sr_val_t *value = NULL; - int rc; - - snprintf(xpath, XPATH_SIZE, ROOT, prefix, index, sub); - - rc = sr_get_item(sess, xpath, &value); - if (SR_ERR_OK != rc) { - SRP_LOG_DBG("XPATH %s not set", xpath); - return NULL; - } - - return value->data.string_val; -} - -/* @brief add/del route to FIB table 0. - * If you add/delete an entry to FIB, prefix is mandatory and next hop can be: - * - interface only - * - next hop IP - * - both interface and next hop IP - */ -static int set_route(sr_session_ctx_t *sess, const char *index, - const char *interface /* NULLABLE*/, - const char *next_hop /* NULLABLE*/, - const char *prefix, bool is_add) -{ - const char *iface = NULL; - const char *nhop = NULL; - - ARG_CHECK3(SR_ERR_INVAL_ARG, sess, index, prefix); - - if (!interface && !next_hop) - return SR_ERR_INVAL_ARG; - - if (!interface) //fetch interface in datastore, can return NULL - iface = _get_ds_elem(sess, prefix, index, "interface-ref/config/interface"); - else //use interface provided - iface = interface; - - if (!next_hop) //fetch next-hop in datastore , can return NULL - nhop = _get_ds_elem(sess, prefix, index, "config/next-hop"); - else //use next hop IP provided - nhop = next_hop; - - return _set_route(prefix, nhop, is_add, iface); -} - -/* @brief Callback used to add prefix entry for XPATH: - * /openconfig-local-routing:local-routes/static-routes/static/config - */ -static int -oc_prefix_config_cb(sr_session_ctx_t *ds, const char *xpath, - sr_notif_event_t event, void *private_ctx) -{ - UNUSED(ds); UNUSED(xpath); UNUSED(event); UNUSED(private_ctx); - - SRP_LOG_INF("In %s", __FUNCTION__); - - return SR_ERR_OK; -} - -// XPATH: /openconfig-local-routing:local-routes/static-routes/static[prefix='%s']/next-hops/next-hop[index='%s']/config/ -static int oc_next_hop_config_cb(sr_session_ctx_t *ds, const char *xpath, - sr_notif_event_t event, void *private_ctx) -{ - char prefix[VPP_IP4_PREFIX_STRING_LEN] = {0}; - char next_hop[VPP_IP4_ADDRESS_STRING_LEN] = {0}; //IP of next router - char index[HOP_INDEX_SIZE]; //next hop index - bool index_set = false, next_hop_set = false; - sr_change_iter_t *it; - sr_change_oper_t oper; - sr_val_t *old, *new, *tmp; - sr_xpath_ctx_t state = {0}; - int rc = SR_ERR_OK; - UNUSED(private_ctx); - - ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); - - SRP_LOG_INF("In %s", __FUNCTION__); - - if (event == SR_EV_APPLY) //SR_EV_VERIFY already applied the changes - return SR_ERR_OK; - - rc = sr_get_changes_iter(ds, (char *)xpath, &it); - if (rc != SR_ERR_OK) { - sr_free_change_iter(it); - return rc; - } - - foreach_change(ds, it, oper, old, new) { - - rc = get_xpath_key(prefix, new->xpath, "static", "prefix", - VPP_IP4_PREFIX_STRING_LEN, &state); - if (rc != 0) - goto error; - - switch (oper) { - case SR_OP_MODIFIED: - case SR_OP_CREATED: - tmp = new; - break; - case SR_OP_DELETED: - tmp = old; - break; - default: - SRP_LOG_WRN_MSG("Operation not supported"); - break; - } - - if (sr_xpath_node_name_eq(tmp->xpath, "config")) { - SRP_LOG_DBG("xpath: %s", tmp->xpath); - } else if (sr_xpath_node_name_eq(tmp->xpath, "index")) { - strncpy(index, tmp->data.string_val, HOP_INDEX_SIZE); - index_set = true; - } else if(sr_xpath_node_name_eq(tmp->xpath, "next-hop")) { - strncpy(next_hop, tmp->data.string_val, VPP_IP4_ADDRESS_STRING_LEN); - next_hop_set = true; - } else if(sr_xpath_node_name_eq(tmp->xpath, "recurse")) { - //SYSREPO BUG: Just catch it, sysrepo thinks it is mandatory... - } else { //metric, recurse - SRP_LOG_ERR("Unsupported field %s", tmp->xpath); - return SR_ERR_UNSUPPORTED; - } - - if (index_set && next_hop_set) { - if (oper == SR_OP_CREATED) { - rc = set_route(ds, index, NULL, next_hop, prefix, true); - } else if (oper == SR_OP_MODIFIED) { - rc = set_route(ds, index, NULL, next_hop, prefix, false); - rc |= set_route(ds, index, NULL, next_hop, prefix, true); - } else if (oper == SR_OP_DELETED) { - rc = set_route(ds, index, NULL, next_hop, prefix, false); - } - - if (rc != 0) { - SRP_LOG_ERR_MSG("setting route failed"); - goto error; - } - index_set = false; next_hop_set = false; - } - - sr_free_val(old); - sr_free_val(new); - sr_xpath_recover(&state); - } - - sr_free_change_iter(it); - return rc; - -error: - sr_free_val(old); - sr_free_val(new); - sr_xpath_recover(&state); - sr_free_change_iter(it); - return rc; -} - -// XPATH: /openconfig-local-routing:local-routes/static-routes/static[prefix='%s']/next-hops/next-hop[index='%s']/interface-ref/config/ -static int -oc_next_hop_interface_config_cb(sr_session_ctx_t *ds, const char *xpath, - sr_notif_event_t event, void *private_ctx) -{ - char prefix[VPP_IP4_PREFIX_STRING_LEN] = {0}; - char interface[VPP_INTFC_NAME_LEN] = {0}; - char index[HOP_INDEX_SIZE] = {0}; - sr_change_iter_t *it = NULL; - sr_change_oper_t oper; - sr_val_t *old, *new, *tmp; - sr_xpath_ctx_t state = {0}; - bool interface_set = false; - int rc = SR_ERR_OK; - UNUSED(private_ctx); - - SRP_LOG_INF("In %s", __FUNCTION__); - - if (event == SR_EV_APPLY) - return SR_ERR_OK; - - rc = sr_get_changes_iter(ds, (char *)xpath, &it); - if (rc != SR_ERR_OK) { - sr_free_change_iter(it); - return rc; - } - - foreach_change(ds, it, oper, old, new) { - - SRP_LOG_DBG("xpath: %s", new->xpath); - - rc = get_xpath_key(prefix, new->xpath, "static", "prefix", - VPP_IP4_PREFIX_STRING_LEN, &state); - - rc |= get_xpath_key(index, new->xpath, "next-hop", "index", - HOP_INDEX_SIZE, &state); - if (rc) - goto error; - - switch (oper) { - case SR_OP_MODIFIED: - case SR_OP_CREATED: - tmp = new; - break; - case SR_OP_DELETED: - tmp = old; - break; - default: - SRP_LOG_WRN_MSG("Operation not supported"); - break; - } - - if (sr_xpath_node_name_eq(tmp->xpath, "config")) { - SRP_LOG_DBG("xpath: %s", tmp->xpath); - } else if (sr_xpath_node_name_eq(tmp->xpath, "interface")) { - strncpy(interface, tmp->data.string_val, VPP_INTFC_NAME_LEN); - interface_set = true; - } else { //metric, recurse - SRP_LOG_ERR("Unsupported field %s", tmp->xpath); - return SR_ERR_UNSUPPORTED; - } - - if (oper == SR_OP_CREATED && interface_set) { - rc = set_route(ds, index, interface, NULL, prefix, true); - interface_set = false; - } else if (oper == SR_OP_MODIFIED && interface_set) { - rc = set_route(ds, index, interface, NULL, prefix, false); - rc |= set_route(ds, index, interface, NULL, prefix, true); - interface_set = false; - } else if (oper == SR_OP_DELETED && interface_set) { - rc = set_route(ds, index, interface, NULL, prefix, false); - interface_set = false; - } - - if (rc != 0) { - SRP_LOG_ERR_MSG("setting route failed"); - goto error; - } - - sr_free_val(old); - sr_free_val(new); - sr_xpath_recover(&state); - } - - sr_free_change_iter(it); - return SR_ERR_OK; - -error: - sr_free_val(old); - sr_free_val(new); - sr_xpath_recover(&state); - sr_free_change_iter(it); - return rc; -} - -// XPATH: /openconfig-local-routing:local-routes/static-routes/static/state -static int oc_prefix_state_cb( - const char *xpath, sr_val_t **values, size_t *values_cnt, - uint64_t request_id, const char *original_xpath, void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - char prefix[VPP_IP4_PREFIX_STRING_LEN] = {0}; - sr_xpath_ctx_t state = {0}; - sr_val_t *vals = NULL; - fib_dump_t *reply = NULL; - int vc = 1; - int rc = 0; - - ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); - - SRP_LOG_INF("In %s", __FUNCTION__); - - rc = get_xpath_key(prefix, (char *)xpath, "static", "prefix", - VPP_IP4_PREFIX_STRING_LEN, &state); - if (rc != 0) - return SR_ERR_INVAL_ARG; - - rc = ipv4_fib_dump_prefix(prefix, &reply); - if (rc == -SCVPP_NOT_FOUND) { - SRP_LOG_ERR("Prefix %s not found in VPP FIB", prefix); - return SR_ERR_NOT_FOUND; - } - - /* Allocation for number of elements dumped by ipv4_fib_dump_all */ - rc = sr_new_values(vc, &vals); - if (SR_ERR_OK != rc) - return rc; - - sr_val_build_xpath(&vals[0], "%s/prefix", xpath); - sr_val_set_str_data(&vals[0], SR_STRING_T, prefix); - - sr_xpath_recover(&state); - - free(reply); - *values = vals; - *values_cnt = vc; - - return SR_ERR_OK; -} - -// XPATH /openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/state -static int -oc_next_hop_state_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, - uint64_t request_id, const char *original_xpath, - void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - char prefix[VPP_IP4_PREFIX_STRING_LEN] = {0}; - char index[HOP_INDEX_SIZE]; - char next_hop[INET_ADDRSTRLEN] = {0}; - fib_dump_t *reply = NULL; - sr_xpath_ctx_t state = {0}; - sr_val_t *vals = NULL; - int vc = 3; - int rc = 0; - - ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); - - SRP_LOG_INF("In %s", __FUNCTION__); - - /* Get prefix and index key from XPATH */ - rc = get_xpath_key(prefix, (char *)xpath, "static", "prefix", - VPP_IP4_PREFIX_STRING_LEN, &state); - - rc |= get_xpath_key(index, (char*)xpath, "next-hop", "index", - HOP_INDEX_SIZE, &state); - - if (rc != 0) - return SR_ERR_INVAL_ARG; - - rc = ipv4_fib_dump_prefix(prefix, &reply); - if (rc != SCVPP_OK) { - SRP_LOG_ERR("Fail to dump prefix %s", prefix); - return SR_ERR_INVAL_ARG; - } - - rc = sr_new_values(vc, &vals); - if (SR_ERR_OK != rc) - return rc; - - // check next hop index equals next hop id - if (strtoul(index, NULL, 0) != reply->path[0].next_hop_id) { - SRP_LOG_ERR("next hop index is %d for prefix %s", - reply->path[0].next_hop_id, prefix); - SRP_LOG_ERR("before %s, stroul is %lu", index, strtoul(index, NULL, 0)); - return SR_ERR_INVAL_ARG; - } - - sr_val_build_xpath(&vals[0], "%s/index", xpath); - sr_val_set_str_data(&vals[0], SR_STRING_T, index); - - strncpy(next_hop, sc_ntoa(reply->path[0].next_hop), VPP_IP4_ADDRESS_LEN); - sr_val_build_xpath(&vals[1], "%s/next-hop", xpath); - sr_val_set_str_data(&vals[1], SR_STRING_T, (char *)reply->path[0].next_hop); - - sr_val_build_xpath(&vals[2], "%s/metric", xpath); - vals[2].type = SR_UINT32_T; - vals[2].data.uint32_val = reply->path[0].weight; - - free(reply); - sr_xpath_recover(&state); - *values = vals; - *values_cnt = vc; - - return SR_ERR_OK; -} - -// XPATH /openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/state -static int -oc_next_hop_interface_state_cb(const char *xpath, sr_val_t **values, - size_t *values_cnt, uint64_t request_id, - const char *original_xpath, void *private_ctx) -{ - UNUSED(request_id); UNUSED(original_xpath); UNUSED(private_ctx); - sr_xpath_ctx_t state = {0}; - char prefix[VPP_IP4_PREFIX_STRING_LEN] = {0}; - char interface[VPP_INTFC_NAME_LEN] = {0}; - char index[HOP_INDEX_SIZE]; //next hop index - fib_dump_t *reply = NULL; - sr_val_t *vals = NULL; - int vc = 1; - int rc = 0; - - //ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); - - SRP_LOG_INF("In %s", __FUNCTION__); - - ///* Get prefix key from XPATH */ - rc = get_xpath_key(prefix, (char*) xpath, "static", "prefix", - VPP_IP4_PREFIX_STRING_LEN, &state); - - rc |= get_xpath_key(index, (char *)xpath, "next-hop", "index", - HOP_INDEX_SIZE, &state); - - if (rc != 0) - return SR_ERR_INVAL_ARG; - - rc = ipv4_fib_dump_prefix(prefix, &reply); - if (rc != SCVPP_OK) { - SRP_LOG_ERR("Fail to dump prefix %s", prefix); - return SR_ERR_INVAL_ARG; - } - //TODO: check nhop? - - rc = sr_new_values(vc, &vals); - if (SR_ERR_OK != rc) - return rc; - - // check next hop index equals next hop id - if (strtoul(index, NULL, 0) != reply->path[0].next_hop_id) { - SRP_LOG_ERR("next hop index is %d for prefix %s", - reply->path[0].next_hop_id, prefix); - SRP_LOG_ERR("before %s, stroul is %lu", index, strtoul(index, NULL, 0)); - return SR_ERR_INVAL_ARG; - } - - rc = get_interface_name(interface, reply->path[0].sw_if_index); - if (rc != SCVPP_OK) { - SRP_LOG_ERR("No interface name for id %d", reply->path[0].sw_if_index); - return SR_ERR_INVAL_ARG; - } - - sr_val_build_xpath(&vals[0], "%s/interface", xpath); - sr_val_set_str_data(&vals[0], SR_STRING_T, interface); - - free(reply); - sr_xpath_recover(&state); - *values = vals; - *values_cnt = vc; - - return SR_ERR_OK; -} - -int -openconfig_local_routing_init(sc_plugin_main_t *pm) -{ - int rc = SR_ERR_OK; - SRP_LOG_DBG_MSG("Initializing openconfig-local-routing plugin."); - - rc = sr_subtree_change_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/config", - oc_prefix_config_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/config", - oc_next_hop_config_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_subtree_change_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/config", - oc_next_hop_interface_config_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/state", - oc_prefix_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/state", - oc_next_hop_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - rc = sr_dp_get_items_subscribe(pm->session, "/openconfig-local-routing:local-routes/static-routes/static/next-hops/next-hop/interface-ref/state", - oc_next_hop_interface_state_cb, NULL, SR_SUBSCR_CTX_REUSE, &pm->subscription); - if (SR_ERR_OK != rc) { - goto error; - } - - SRP_LOG_DBG_MSG("openconfig-local-routing plugin initialized successfully."); - return SR_ERR_OK; - -error: - SRP_LOG_ERR("Error by initialization of openconfig-local-routing plugin. Error : %d", rc); - return rc; -} - -void -openconfig_local_routing_exit(__attribute__((unused)) sc_plugin_main_t *pm) -{ -} - -SC_INIT_FUNCTION(openconfig_local_routing_init); -SC_EXIT_FUNCTION(openconfig_local_routing_exit); - diff --git a/src/plugins/sc_plugins.c b/src/plugins/sc_plugins.c index 8ed2c12..cb78219 100644 --- a/src/plugins/sc_plugins.c +++ b/src/plugins/sc_plugins.c @@ -1,5 +1,7 @@ /* * Copyright (c) 2018 HUACHENTEL and/or its affiliates. + * 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: @@ -16,33 +18,118 @@ #include "sc_plugins.h" #include +#include +#include + +#include +#include -#include +static int vpp_pid_start; sc_plugin_main_t sc_plugin_main; +using namespace VOM; + +#define _DIRENT_NAME 256 +#define CMDLINE_MAX _DIRENT_NAME + 15 +#define VPP_FULL_PATH "/usr/bin/vpp" + sc_plugin_main_t *sc_get_plugin_main() { return &sc_plugin_main; } +/** + * @brief get one pid of any running vpp process. + * @return Return vpp pid or -ESRH value if process was not found + */ +int get_vpp_pid() +{ + DIR *dir = NULL; + struct dirent *ptr = NULL; + FILE *fp = NULL; + char filepath[CMDLINE_MAX]; + char filetext[sizeof(VPP_FULL_PATH)+1]; + char *first = NULL; + size_t cnt; + + dir = opendir("/proc"); + if (dir == NULL) + return -errno; + + /* read vpp pid file in proc, return pid of vpp */ + while (NULL != (ptr = readdir(dir))) + { + if ((0 == strcmp(ptr->d_name, ".")) || (0 == strcmp(ptr->d_name, ".."))) + continue; + + if (DT_DIR != ptr->d_type) + continue; + + /* Open cmdline of PID */ + snprintf(filepath, CMDLINE_MAX, "/proc/%s/cmdline", ptr->d_name); + fp = fopen(filepath, "r"); + if (fp == NULL) + continue; + + /* Write '/0' char in filetext array to prevent stack reading */ + bzero(filetext, sizeof(VPP_FULL_PATH)); + + /* Read the string written in cmdline file */ + cnt = fread(filetext, sizeof(char), sizeof(VPP_FULL_PATH), fp); + if (cnt == 0) { + fclose(fp); + continue; + } + filetext[cnt] = '\0'; + + /* retrieve string before first space */ + first = strtok(filetext, " "); + if (first == NULL) { //unmet space delimiter + fclose(fp); + continue; + } + + /* One VPP process has been found */ + if (!strcmp(first, "vpp") || !strcmp(first, VPP_FULL_PATH)) { + fclose(fp); + closedir(dir); + return atoi(ptr->d_name); + } + + fclose(fp); // we assume fclose don't fail + + errno = 0; //to distinguish readdir() error from end of dir + } + + if (errno != 0) { //this means an error has occured in readir + SRP_LOG_ERR("readir errno %d", errno); + return -errno; + } + + closedir(dir); + + return -ESRCH; +} + + int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx) { int rc = SR_ERR_OK;; sc_plugin_main.session = session; - /* Connect to VAPI */ - if (!(sc_plugin_main.vpp_main = sc_connect_vpp())) { - SRP_LOG_ERR("VPP connect error: %d", rc); - return SR_ERR_INTERNAL; - } - - /* Connect to STAT API */ - rc = stat_segment_connect(STAT_SEGMENT_SOCKET_FILE); - if (rc != 0) { - SRP_LOG_ERR("vpp stat connect error , with return %d.", rc); - return SR_ERR_INTERNAL; + /* Connection to VAPI via VOM and VOM database */ + HW::init(); + OM::init(); + while (HW::connect() != true); + SRP_LOG_INF_MSG("Connection to VPP established"); + + try { + OM::populate("boot"); + } catch (...) { + SRP_LOG_ERR_MSG("fail populating VOM database"); + exit(1); } rc = sc_call_all_init_function(&sc_plugin_main); @@ -54,7 +141,12 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx) /* set subscription as our private context */ *private_ctx = sc_plugin_main.subscription; - return rc; + /* Get initial PID of VPP process */ + vpp_pid_start = get_vpp_pid(); + if (vpp_pid_start < 0) + return SR_ERR_DISCONNECT; + + return SR_ERR_OK; } void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx) @@ -63,22 +155,37 @@ void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx) /* subscription was set as our private context */ if (private_ctx != NULL) - sr_unsubscribe(session, private_ctx); + sr_unsubscribe(session, (sr_subscription_ctx_t*) private_ctx); SRP_LOG_DBG_MSG("unload plugin ok."); - /* Disconnect from STAT API */ - stat_segment_disconnect(); - - /* Disconnect from VAPI */ - sc_disconnect_vpp(); + HW::disconnect(); SRP_LOG_DBG_MSG("plugin disconnect vpp ok."); } -int sr_plugin_health_check_cb( __attribute__ ((unused)) sr_session_ctx_t *session, - __attribute__ ((unused)) void *private_ctx) +int sr_plugin_health_check_cb(sr_session_ctx_t *session, void *private_ctx) { - /* health check, will use shell to detect vpp when plugin is loaded */ - /* health_check will run every 10 seconds in loop*/ - pid_t pid = sc_get_vpp_pid(); - return sc_plugin_main.vpp_main->pid == pid && pid != 0 ? SR_ERR_OK : SR_ERR_INTERNAL; + UNUSED(session); UNUSED(private_ctx); + int vpp_pid_now = get_vpp_pid(); + + if (vpp_pid_now == vpp_pid_start) + return SR_ERR_OK; //VPP has not crashed + + SRP_LOG_WRN("VPP has crashed, new pid %d", vpp_pid_now); + + /* Wait until we succeed connecting to VPP */ + HW::disconnect(); + while (HW::connect() != true) { + SRP_LOG_DBG_MSG("Try connecting to VPP again"); + }; + + SRP_LOG_DBG_MSG("Connection to VPP established again"); + + /* Though VPP has crashed, VOM database has kept the configuration. + * This function replays the previous configuration to reconfigure VPP + * so that VPP state matches sysrepo RUNNING DS and VOM database. */ + OM::replay(); + + vpp_pid_start = vpp_pid_now; + + return SR_ERR_OK; } diff --git a/src/plugins/sc_plugins.h b/src/plugins/sc_plugins.h index 1ac3f44..ae401d5 100644 --- a/src/plugins/sc_plugins.h +++ b/src/plugins/sc_plugins.h @@ -16,9 +16,11 @@ #ifndef __SC_PLUGINS_H__ #define __SC_PLUGINS_H__ -#include -#include -#include +extern "C" { + #include + #include + #include +} #include "sc_init.h" #include "sys_util.h" @@ -34,15 +36,15 @@ typedef struct sc_plugin_main_t { _sc_init_function_list_elt_t *init_function_registrations; _sc_exit_function_list_elt_t *exit_function_registrations; - /* VPP main structure */ - sc_vpp_main_t *vpp_main; } sc_plugin_main_t; sc_plugin_main_t *sc_get_plugin_main(); //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); -int sr_plugin_health_check_cb(sr_session_ctx_t *session, void *private_ctx); +extern "C" int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx); +extern "C" void sr_plugin_cleanup_cb(sr_session_ctx_t *session, + void *private_ctx); +extern "C" int sr_plugin_health_check_cb(sr_session_ctx_t *session, + void *private_ctx); #endif //__SC_PLUGINS_H__ diff --git a/src/plugins/sys_util.cpp b/src/plugins/sys_util.cpp new file mode 100644 index 0000000..f011825 --- /dev/null +++ b/src/plugins/sys_util.cpp @@ -0,0 +1,61 @@ +#include "sys_util.h" + +namespace utils { + +prefix::prefix() +{ +} + +prefix::prefix(const prefix &p) +{ + m_address = p.address(); + m_prefix_len = p.prefix_length(); +} + +prefix::prefix(std::string p) +{ + size_t found = p.find_last_of('/'); + + if (found == std::string::npos) //not found + throw std::runtime_error("missing '/' in " + p); + + m_address = boost::asio::ip::address::from_string(p.substr(0, found)); + m_prefix_len = std::stoi(p.substr(found+1, p.length())); +} + +prefix prefix::make_prefix(std::string str) +{ + prefix tmp(str); + return prefix(tmp); +} + +unsigned short prefix::prefix_length() const +{ + return m_prefix_len; +} + +boost::asio::ip::address prefix::address() const +{ + return m_address; +} + +std::string prefix::to_string() const +{ + ostringstream os; + os << m_address << "/" << m_prefix_len; + return os.str(); +} + +std::ostream& operator<<(std::ostream& os, const prefix& p) +{ + os << p.to_string(); + + return os; +} + +bool prefix::empty() const +{ + return to_string().empty(); +} + +} diff --git a/src/plugins/sys_util.h b/src/plugins/sys_util.h index 3f85537..cda24a0 100644 --- a/src/plugins/sys_util.h +++ b/src/plugins/sys_util.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 PANTHEON.tech. + * 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. @@ -17,146 +18,83 @@ #ifndef __SYS_UTIL_H__ #define __SYS_UTIL_H__ -#include -#include -#include - -#include -#include +//TODO: Add to only one header file +extern "C" { + #include + #include + #include +} -#include +#include +#include +#include +#include -#include +using namespace std; /* BEGIN sysrepo utils */ -#define foreach_change(ds, it, oper, old, new) \ +#define foreach_change(ds, it, oper, old, newch) \ while( (event != SR_EV_ABORT) && \ - sr_get_change_next(ds, it, &oper, &old, &new) == SR_ERR_OK) + sr_get_change_next(ds, it, &oper, &old, &newch) == SR_ERR_OK) #define XPATH_SIZE 2000 -#define NOT_AVAL "NOT AVAILABLE" -static inline int -get_xpath_key(char *dst, char *xpath, char *node, char *key, int length, - sr_xpath_ctx_t *state) { - char *tmp; - - tmp = sr_xpath_key_value(xpath, node, key, state); - if (!tmp) { - SRP_LOG_ERR("%s %s not found.", node, key); - return SR_ERR_INVAL_ARG; - } - strncpy(dst, tmp, length); - sr_xpath_recover(state); - - return 0; -} +#define ARG_CHECK(retval, arg) \ + do \ + { \ + if (NULL == (arg)) \ + { \ + return (retval); \ + } \ + } \ + while (0) + +#define ARG_CHECK2(retval, arg1, arg2) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2) + +#define ARG_CHECK3(retval, arg1, arg2, arg3) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2); \ + ARG_CHECK(retval, arg3) + +#define ARG_CHECK4(retval, arg1, arg2, arg3, arg4) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2); \ + ARG_CHECK(retval, arg3); \ + ARG_CHECK(retval, arg4) + +/* Suppress compiler warning about unused variable. + * This must be used only for callback function else suppress your unused + * parameter in function prototype. */ +#define UNUSED(x) (void)x /* END of sysrepo utils */ -typedef struct -{ - uint8_t address[4]; -} sc_ipv4_addr; - -/** - * @brief Extract IP "AAA.BBB.CCC.DDD" from an IP prefix: "AAA.BBB.CCC.DDD/XX" - * @param prefix - IPv4 or IPv6 prefix: - * @return prefix length - */ -static inline int ip_prefix_split(const char* ip_prefix) -{ - //find the slash - char* slash = strchr(ip_prefix, '/'); - if (NULL == slash) - return -1; - - //extract subnet mask length - char * eptr = NULL; - uint8_t plen = strtoul(slash + 1, &eptr, 10); - if (*eptr || plen <= 0) - return -1; - - //keep just the address part - *slash = '\0'; //replace '/' with 0 - - //return prefix length - return plen; -} - -/** - * @brief Get IPv4 host address from IPv4 prefix. - * - * @param[out] dst Host IPv4 address. - * @param[in] src IPv4 prefix. - * @param[out] prefix Get Prefix length, optional value. Can be NULL. - * @return -1 when failure, 0 on success. - */ -static inline int -prefix2ip4(char *dst, const char *src, uint8_t *prefix_length) -{ - if (!src || !dst) - return -1; - - char *p = strchr(src, '/'); - if (!p) - return -1; // '/' not found - - size_t size = p - src; - if ((size + 1) > VPP_IP4_ADDRESS_STRING_LEN) //+ 1 needed for \0 - return -1; - - strncpy(dst, src, size); - - if (!prefix_length) - *prefix_length = atoi(++p); - - return 0; -} - -/** - * @brief Get IPv6 host address from IPv6 prefix. - * - * @param[out] dst Host IPv6 address. - * @param[in] src IPv6 prefix. - * @param[out] prefix Get Prefix length, optional value. Can be NULL. - * @return -1 when failure, 0 on success. - */ -static inline int -prefix2ip6(char *dst, const char *src, uint8_t *prefix_length) -{ - if (!src || !dst) - return -1; - - char *p = strchr(src, '/'); - if (!p) - return -1; // '/' not found - - size_t size = p - src; - if ((size + 1) > VPP_IP6_ADDRESS_STRING_LEN) //+ 1 needed for \0 - return -1; - - strncpy(dst, src, size); - - if (!prefix_length) - *prefix_length = atoi(++p); +namespace utils { - return 0; -} - -/** - * @brief Helper function for converting netmask (ex: 255.255.255.0) - * to prefix length (ex: 24). - * @param netmask - string of netmask "AAA.BBB.CCC.DDD" - * @return prefix length +/* Convert netmask to prefix length. + * 255.255.255.0->24 */ -static inline uint8_t netmask_to_prefix(const char *netmask) +inline uint8_t netmask_to_plen(boost::asio::ip::address netmask) { in_addr_t n = 0; uint8_t i = 0; + int af; + int rc; + + if (netmask.is_v4()) + af = AF_INET; + else if (netmask.is_v6()) + af = AF_INET6; + else + throw std::runtime_error("Invalid address family"); - inet_pton(AF_INET, netmask, &n); + /* Convert address to binary form */ + rc = inet_pton(af, netmask.to_string().c_str(), &n); + if (rc <= 0) + throw std::runtime_error("Fail converting netmask to prefix length"); while (n > 0) { n = n >> 1; @@ -166,69 +104,42 @@ static inline uint8_t netmask_to_prefix(const char *netmask) return i; } -/** - * @brief Convert prefix length to netmask - * @param prefix - prefix length (ex: 24) - * @return netmask - integer (ex: 111111111111111111111111100000000b ) - */ -static inline uint32_t prefix2mask(int prefix) -{ - if (prefix) { - return htonl(~((1 << (32 - prefix)) - 1)); - } else { - return htonl(0); - } -} +class prefix { +public: + /* Default Constructor */ + prefix(); -/** - * @brief Get IPv4 broadcast IP address form IPv4 network address. - * - * @param[out] broadcat Broadcast Ipv4 address. - * @param[in] network Network IPv4 address. - * @param[in] prefix Prefix number. - * @return -1 when failure, 0 on success. - */ -static inline int get_network_broadcast(sc_ipv4_addr *broadcast, const sc_ipv4_addr *network, - uint8_t prefix_length) -{ - uint8_t mask = ~0; - uint8_t tmp_p = prefix_length; - int i; + /* Copy constructor */ + prefix(const prefix &p); - ARG_CHECK2(-1, network, broadcast); + /* Constuctor from string prefix */ + prefix(std::string p); - if (32 < prefix_length) { - SRP_LOG_ERR_MSG("Prefix length to big."); - return -1; - } + /* Create a prefix from a string */ + static prefix make_prefix(std::string p); - for (i = 0; i < 4 ; i++) { - broadcast->address[i] = network->address[i] | - (mask >> (tmp_p > 8 ? 8 : tmp_p)); - if (tmp_p >= 8) { - tmp_p -= 8; - } else { - tmp_p = 0; - } - } + /* Return prefix "AAA.BBB.CCC.DDD/ZZ" + * "YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/ZZZ */ + std::string to_string() const; - return 0; -} + /* Extract prefix length "ZZ"/"ZZZ" an IP prefix: "AAA.BBB.CCC.DDD/ZZ" + * "YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/ZZZ */ + unsigned short prefix_length() const; -/** - * @brief Get last IPv4 address from the IP range. - * - * @param[out] last_ip_address Last Ipv4 address. - * @param[in] first_ip_address First IPv4 address. - * @param[in] prefix Prefix number. - * @return -1 when failure, 0 on success. - */ -static inline int get_last_ip_address(sc_ipv4_addr* last_ip_address, - const sc_ipv4_addr* first_ip_address, - uint8_t prefix_length) -{ - return get_network_broadcast(last_ip_address, first_ip_address, - prefix_length); -} + /* Extract IP "AAA.BBB.CCC.DDD" from an IP prefix: "AAA.BBB.CCC.DDD/ZZ" + * "YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY:YYYY/ZZZ */ + boost::asio::ip::address address() const; + + /* Return true if prefix is empty */ + bool empty() const; + + friend ostream& operator<<(ostream& os, const prefix& p); + +private: + boost::asio::ip::address m_address; + unsigned short m_prefix_len; +}; + +} //end of utils namespace #endif /* __SYS_UTIL_H__ */ diff --git a/src/plugins/vpp-oper/interface.cpp b/src/plugins/vpp-oper/interface.cpp new file mode 100644 index 0000000..054ec6c --- /dev/null +++ b/src/plugins/vpp-oper/interface.cpp @@ -0,0 +1,39 @@ +#include "interface.hpp" + +using namespace VOM; + +interface_dump::interface_dump() +{ +} + +interface_dump::interface_dump(std::string interface_name) + : m_name(interface_name) +{ +} + +rc_t +interface_dump::issue(connection& con) +{ + m_dump.reset(new msg_t(con.ctx(), std::ref(*this))); + + auto& payload = m_dump->get_request().get_payload(); + + if (m_name.empty()) { + payload.name_filter_valid = 0; + } else { + payload.name_filter_valid = 1; + strcpy((char*)payload.name_filter, m_name.c_str()); + } + + VAPI_CALL(m_dump->execute()); + + wait(); + + return rc_t::OK; +} + +std::string +interface_dump::to_string() const +{ + return ("itf-dump"); +} diff --git a/src/plugins/vpp-oper/interface.hpp b/src/plugins/vpp-oper/interface.hpp new file mode 100644 index 0000000..6bcbbf6 --- /dev/null +++ b/src/plugins/vpp-oper/interface.hpp @@ -0,0 +1,33 @@ +#ifndef __OPER_INTERFACE_H_ +#define __OPER_INTERFACE_H_ + +#include +#include + +class interface_dump : public VOM::dump_cmd +{ +public: + /** + * Default Constructor - dump everything + */ + interface_dump(); + + /* + * Constructor to dump one interface only + */ + interface_dump(std::string interface_name); + + /** + * Issue the command to VPP/HW + */ + VOM::rc_t issue(VOM::connection& con); + /** + * convert to string format for debug purposes + */ + std::string to_string() const; + +private: + std::string m_name; //interface name +}; + +#endif //__OPER_INTERFACE_H_ diff --git a/src/plugins/yang/ietf/ietf-ip@2018-02-22.yang b/src/plugins/yang/ietf/ietf-ip@2018-02-22.yang deleted file mode 100644 index a270f67..0000000 --- a/src/plugins/yang/ietf/ietf-ip@2018-02-22.yang +++ /dev/null @@ -1,876 +0,0 @@ -module ietf-ip { - yang-version 1.1; - namespace "urn:ietf:params:xml:ns:yang:ietf-ip"; - prefix ip; - - import ietf-interfaces { - prefix if; - } - import ietf-inet-types { - prefix inet; - } - import ietf-yang-types { - prefix yang; - } - - organization - "IETF NETMOD (Network Modeling) Working Group"; - - contact - "WG Web: - WG List: - - Editor: Martin Bjorklund - "; - description - "This module contains a collection of YANG definitions for - managing IP implementations. - - Copyright (c) 2018 IETF Trust and the persons identified as - authors of the code. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, is permitted pursuant to, and subject - to the license terms contained in, the Simplified BSD License - set forth in Section 4.c of the IETF Trust's Legal Provisions - Relating to IETF Documents - (https://trustee.ietf.org/license-info). - - This version of this YANG module is part of RFC 8344; see - the RFC itself for full legal notices."; - - revision 2018-02-22 { - description - "Updated to support NMDA."; - reference - "RFC 8344: A YANG Data Model for IP Management"; - } - - revision 2014-06-16 { - description - "Initial revision."; - reference - "RFC 7277: A YANG Data Model for IP Management"; - } - - /* - * Features - */ - - feature ipv4-non-contiguous-netmasks { - description - "Indicates support for configuring non-contiguous - subnet masks."; - } - - feature ipv6-privacy-autoconf { - description - "Indicates support for privacy extensions for stateless address - autoconfiguration in IPv6."; - reference - "RFC 4941: Privacy Extensions for Stateless Address - Autoconfiguration in IPv6"; - } - - /* - * Typedefs - */ - - typedef ip-address-origin { - type enumeration { - enum other { - description - "None of the following."; - } - - enum static { - description - "Indicates that the address has been statically - configured -- for example, using the Network Configuration - Protocol (NETCONF) or a command line interface."; - } - enum dhcp { - description - "Indicates an address that has been assigned to this - system by a DHCP server."; - } - enum link-layer { - description - "Indicates an address created by IPv6 stateless - autoconfiguration that embeds a link-layer address in its - interface identifier."; - } - enum random { - description - "Indicates an address chosen by the system at - random, e.g., an IPv4 address within 169.254/16, a - temporary address as described in RFC 4941, or a - semantically opaque address as described in RFC 7217."; - reference - "RFC 4941: Privacy Extensions for Stateless Address - Autoconfiguration in IPv6 - RFC 7217: A Method for Generating Semantically Opaque - Interface Identifiers with IPv6 Stateless - Address Autoconfiguration (SLAAC)"; - } - } - description - "The origin of an address."; - } - - typedef neighbor-origin { - type enumeration { - enum other { - description - "None of the following."; - } - enum static { - description - "Indicates that the mapping has been statically - configured -- for example, using NETCONF or a command line - interface."; - } - - enum dynamic { - description - "Indicates that the mapping has been dynamically resolved - using, for example, IPv4 ARP or the IPv6 Neighbor - Discovery protocol."; - } - } - description - "The origin of a neighbor entry."; - } - - /* - * Data nodes - */ - - augment "/if:interfaces/if:interface" { - description - "IP parameters on interfaces. - - If an interface is not capable of running IP, the server - must not allow the client to configure these parameters."; - - container ipv4 { - presence - "Enables IPv4 unless the 'enabled' leaf - (which defaults to 'true') is set to 'false'"; - description - "Parameters for the IPv4 address family."; - - leaf enabled { - type boolean; - default true; - description - "Controls whether IPv4 is enabled or disabled on this - interface. When IPv4 is enabled, this interface is - connected to an IPv4 stack, and the interface can send - and receive IPv4 packets."; - } - leaf forwarding { - type boolean; - default false; - description - "Controls IPv4 packet forwarding of datagrams received by, - but not addressed to, this interface. IPv4 routers - forward datagrams. IPv4 hosts do not (except those - source-routed via the host)."; - } - - leaf mtu { - type uint16 { - range "68..max"; - } - units "octets"; - description - "The size, in octets, of the largest IPv4 packet that the - interface will send and receive. - - The server may restrict the allowed values for this leaf, - depending on the interface's type. - - If this leaf is not configured, the operationally used MTU - depends on the interface's type."; - reference - "RFC 791: Internet Protocol"; - } - list address { - key "ip"; - description - "The list of IPv4 addresses on the interface."; - - leaf ip { - type inet:ipv4-address-no-zone; - description - "The IPv4 address on the interface."; - } - choice subnet { - mandatory true; - description - "The subnet can be specified as a prefix length or, - if the server supports non-contiguous netmasks, as - a netmask."; - leaf prefix-length { - type uint8 { - range "0..32"; - } - description - "The length of the subnet prefix."; - } - leaf netmask { - if-feature ipv4-non-contiguous-netmasks; - type yang:dotted-quad; - description - "The subnet specified as a netmask."; - } - } - - leaf origin { - type ip-address-origin; - config false; - description - "The origin of this address."; - } - } - list neighbor { - key "ip"; - description - "A list of mappings from IPv4 addresses to - link-layer addresses. - - Entries in this list in the intended configuration are - used as static entries in the ARP Cache. - - In the operational state, this list represents the ARP - Cache."; - reference - "RFC 826: An Ethernet Address Resolution Protocol"; - - leaf ip { - type inet:ipv4-address-no-zone; - description - "The IPv4 address of the neighbor node."; - } - leaf link-layer-address { - type yang:phys-address; - mandatory true; - description - "The link-layer address of the neighbor node."; - } - leaf origin { - type neighbor-origin; - config false; - description - "The origin of this neighbor entry."; - } - } - } - - container ipv6 { - presence - "Enables IPv6 unless the 'enabled' leaf - (which defaults to 'true') is set to 'false'"; - description - "Parameters for the IPv6 address family."; - - leaf enabled { - type boolean; - default true; - description - "Controls whether IPv6 is enabled or disabled on this - interface. When IPv6 is enabled, this interface is - connected to an IPv6 stack, and the interface can send - and receive IPv6 packets."; - } - leaf forwarding { - type boolean; - default false; - description - "Controls IPv6 packet forwarding of datagrams received by, - but not addressed to, this interface. IPv6 routers - forward datagrams. IPv6 hosts do not (except those - source-routed via the host)."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) - Section 6.2.1, IsRouter"; - } - leaf mtu { - type uint32 { - range "1280..max"; - } - units "octets"; - description - "The size, in octets, of the largest IPv6 packet that the - interface will send and receive. - - The server may restrict the allowed values for this leaf, - depending on the interface's type. - - If this leaf is not configured, the operationally used MTU - depends on the interface's type."; - reference - "RFC 8200: Internet Protocol, Version 6 (IPv6) - Specification - Section 5"; - } - - list address { - key "ip"; - description - "The list of IPv6 addresses on the interface."; - - leaf ip { - type inet:ipv6-address-no-zone; - description - "The IPv6 address on the interface."; - } - leaf prefix-length { - type uint8 { - range "0..128"; - } - mandatory true; - description - "The length of the subnet prefix."; - } - leaf origin { - type ip-address-origin; - config false; - description - "The origin of this address."; - } - leaf status { - type enumeration { - enum preferred { - description - "This is a valid address that can appear as the - destination or source address of a packet."; - } - enum deprecated { - description - "This is a valid but deprecated address that should - no longer be used as a source address in new - communications, but packets addressed to such an - address are processed as expected."; - } - enum invalid { - description - "This isn't a valid address, and it shouldn't appear - as the destination or source address of a packet."; - } - - enum inaccessible { - description - "The address is not accessible because the interface - to which this address is assigned is not - operational."; - } - enum unknown { - description - "The status cannot be determined for some reason."; - } - enum tentative { - description - "The uniqueness of the address on the link is being - verified. Addresses in this state should not be - used for general communication and should only be - used to determine the uniqueness of the address."; - } - enum duplicate { - description - "The address has been determined to be non-unique on - the link and so must not be used."; - } - enum optimistic { - description - "The address is available for use, subject to - restrictions, while its uniqueness on a link is - being verified."; - } - } - config false; - description - "The status of an address. Most of the states correspond - to states from the IPv6 Stateless Address - Autoconfiguration protocol."; - reference - "RFC 4293: Management Information Base for the - Internet Protocol (IP) - - IpAddressStatusTC - RFC 4862: IPv6 Stateless Address Autoconfiguration"; - } - } - - list neighbor { - key "ip"; - description - "A list of mappings from IPv6 addresses to - link-layer addresses. - - Entries in this list in the intended configuration are - used as static entries in the Neighbor Cache. - - In the operational state, this list represents the - Neighbor Cache."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)"; - - leaf ip { - type inet:ipv6-address-no-zone; - description - "The IPv6 address of the neighbor node."; - } - leaf link-layer-address { - type yang:phys-address; - mandatory true; - description - "The link-layer address of the neighbor node. - - In the operational state, if the neighbor's 'state' leaf - is 'incomplete', this leaf is not instantiated."; - } - leaf origin { - type neighbor-origin; - config false; - description - "The origin of this neighbor entry."; - } - leaf is-router { - type empty; - config false; - description - "Indicates that the neighbor node acts as a router."; - } - - leaf state { - type enumeration { - enum incomplete { - description - "Address resolution is in progress, and the - link-layer address of the neighbor has not yet been - determined."; - } - enum reachable { - description - "Roughly speaking, the neighbor is known to have been - reachable recently (within tens of seconds ago)."; - } - enum stale { - description - "The neighbor is no longer known to be reachable, but - until traffic is sent to the neighbor no attempt - should be made to verify its reachability."; - } - enum delay { - description - "The neighbor is no longer known to be reachable, and - traffic has recently been sent to the neighbor. - Rather than probe the neighbor immediately, however, - delay sending probes for a short while in order to - give upper-layer protocols a chance to provide - reachability confirmation."; - } - enum probe { - description - "The neighbor is no longer known to be reachable, and - unicast Neighbor Solicitation probes are being sent - to verify reachability."; - } - } - config false; - description - "The Neighbor Unreachability Detection state of this - entry."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) - Section 7.3.2"; - } - } - - leaf dup-addr-detect-transmits { - type uint32; - default 1; - description - "The number of consecutive Neighbor Solicitation messages - sent while performing Duplicate Address Detection on a - tentative address. A value of zero indicates that - Duplicate Address Detection is not performed on - tentative addresses. A value of one indicates a single - transmission with no follow-up retransmissions."; - reference - "RFC 4862: IPv6 Stateless Address Autoconfiguration"; - } - container autoconf { - description - "Parameters to control the autoconfiguration of IPv6 - addresses, as described in RFC 4862."; - reference - "RFC 4862: IPv6 Stateless Address Autoconfiguration"; - - leaf create-global-addresses { - type boolean; - default true; - description - "If enabled, the host creates global addresses as - described in RFC 4862."; - reference - "RFC 4862: IPv6 Stateless Address Autoconfiguration - Section 5.5"; - } - leaf create-temporary-addresses { - if-feature ipv6-privacy-autoconf; - type boolean; - default false; - description - "If enabled, the host creates temporary addresses as - described in RFC 4941."; - reference - "RFC 4941: Privacy Extensions for Stateless Address - Autoconfiguration in IPv6"; - } - - leaf temporary-valid-lifetime { - if-feature ipv6-privacy-autoconf; - type uint32; - units "seconds"; - default 604800; - description - "The time period during which the temporary address - is valid."; - reference - "RFC 4941: Privacy Extensions for Stateless Address - Autoconfiguration in IPv6 - - TEMP_VALID_LIFETIME"; - } - leaf temporary-preferred-lifetime { - if-feature ipv6-privacy-autoconf; - type uint32; - units "seconds"; - default 86400; - description - "The time period during which the temporary address is - preferred."; - reference - "RFC 4941: Privacy Extensions for Stateless Address - Autoconfiguration in IPv6 - - TEMP_PREFERRED_LIFETIME"; - } - } - } - } - - /* - * Legacy operational state data nodes - */ - - augment "/if:interfaces-state/if:interface" { - status deprecated; - description - "Data nodes for the operational state of IP on interfaces."; - - container ipv4 { - presence - "Present if IPv4 is enabled on this interface"; - config false; - status deprecated; - description - "Interface-specific parameters for the IPv4 address family."; - - leaf forwarding { - type boolean; - status deprecated; - description - "Indicates whether IPv4 packet forwarding is enabled or - disabled on this interface."; - } - leaf mtu { - type uint16 { - range "68..max"; - } - units "octets"; - status deprecated; - description - "The size, in octets, of the largest IPv4 packet that the - interface will send and receive."; - reference - "RFC 791: Internet Protocol"; - } - list address { - key "ip"; - status deprecated; - description - "The list of IPv4 addresses on the interface."; - - leaf ip { - type inet:ipv4-address-no-zone; - status deprecated; - description - "The IPv4 address on the interface."; - } - choice subnet { - status deprecated; - description - "The subnet can be specified as a prefix length or, - if the server supports non-contiguous netmasks, as - a netmask."; - leaf prefix-length { - type uint8 { - range "0..32"; - } - status deprecated; - description - "The length of the subnet prefix."; - } - leaf netmask { - if-feature ipv4-non-contiguous-netmasks; - type yang:dotted-quad; - status deprecated; - description - "The subnet specified as a netmask."; - } - } - leaf origin { - type ip-address-origin; - status deprecated; - description - "The origin of this address."; - } - } - list neighbor { - key "ip"; - status deprecated; - description - "A list of mappings from IPv4 addresses to - link-layer addresses. - - This list represents the ARP Cache."; - reference - "RFC 826: An Ethernet Address Resolution Protocol"; - - leaf ip { - type inet:ipv4-address-no-zone; - status deprecated; - description - "The IPv4 address of the neighbor node."; - } - - leaf link-layer-address { - type yang:phys-address; - status deprecated; - description - "The link-layer address of the neighbor node."; - } - leaf origin { - type neighbor-origin; - status deprecated; - description - "The origin of this neighbor entry."; - } - } - } - - container ipv6 { - presence - "Present if IPv6 is enabled on this interface"; - config false; - status deprecated; - description - "Parameters for the IPv6 address family."; - - leaf forwarding { - type boolean; - default false; - status deprecated; - description - "Indicates whether IPv6 packet forwarding is enabled or - disabled on this interface."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) - Section 6.2.1, IsRouter"; - } - leaf mtu { - type uint32 { - range "1280..max"; - } - units "octets"; - status deprecated; - description - "The size, in octets, of the largest IPv6 packet that the - interface will send and receive."; - reference - "RFC 8200: Internet Protocol, Version 6 (IPv6) - Specification - Section 5"; - } - list address { - key "ip"; - status deprecated; - description - "The list of IPv6 addresses on the interface."; - - leaf ip { - type inet:ipv6-address-no-zone; - status deprecated; - description - "The IPv6 address on the interface."; - } - leaf prefix-length { - type uint8 { - range "0..128"; - } - mandatory true; - status deprecated; - description - "The length of the subnet prefix."; - } - leaf origin { - type ip-address-origin; - status deprecated; - description - "The origin of this address."; - } - leaf status { - type enumeration { - enum preferred { - description - "This is a valid address that can appear as the - destination or source address of a packet."; - } - enum deprecated { - description - "This is a valid but deprecated address that should - no longer be used as a source address in new - communications, but packets addressed to such an - address are processed as expected."; - } - enum invalid { - description - "This isn't a valid address, and it shouldn't appear - as the destination or source address of a packet."; - } - - enum inaccessible { - description - "The address is not accessible because the interface - to which this address is assigned is not - operational."; - } - enum unknown { - description - "The status cannot be determined for some reason."; - } - enum tentative { - description - "The uniqueness of the address on the link is being - verified. Addresses in this state should not be - used for general communication and should only be - used to determine the uniqueness of the address."; - } - enum duplicate { - description - "The address has been determined to be non-unique on - the link and so must not be used."; - } - enum optimistic { - description - "The address is available for use, subject to - restrictions, while its uniqueness on a link is - being verified."; - } - } - status deprecated; - description - "The status of an address. Most of the states correspond - to states from the IPv6 Stateless Address - Autoconfiguration protocol."; - reference - "RFC 4293: Management Information Base for the - Internet Protocol (IP) - - IpAddressStatusTC - RFC 4862: IPv6 Stateless Address Autoconfiguration"; - } - } - - list neighbor { - key "ip"; - status deprecated; - description - "A list of mappings from IPv6 addresses to - link-layer addresses. - - This list represents the Neighbor Cache."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)"; - - leaf ip { - type inet:ipv6-address-no-zone; - status deprecated; - description - "The IPv6 address of the neighbor node."; - } - leaf link-layer-address { - type yang:phys-address; - status deprecated; - description - "The link-layer address of the neighbor node."; - } - leaf origin { - type neighbor-origin; - status deprecated; - description - "The origin of this neighbor entry."; - } - leaf is-router { - type empty; - status deprecated; - description - "Indicates that the neighbor node acts as a router."; - } - leaf state { - type enumeration { - enum incomplete { - description - "Address resolution is in progress, and the - link-layer address of the neighbor has not yet been - determined."; - } - enum reachable { - description - "Roughly speaking, the neighbor is known to have been - reachable recently (within tens of seconds ago)."; - } - enum stale { - description - "The neighbor is no longer known to be reachable, but - until traffic is sent to the neighbor no attempt - should be made to verify its reachability."; - } - enum delay { - description - "The neighbor is no longer known to be reachable, and - traffic has recently been sent to the neighbor. - Rather than probe the neighbor immediately, however, - delay sending probes for a short while in order to - give upper-layer protocols a chance to provide - reachability confirmation."; - } - enum probe { - description - "The neighbor is no longer known to be reachable, and - unicast Neighbor Solicitation probes are being sent - to verify reachability."; - } - } - status deprecated; - description - "The Neighbor Unreachability Detection state of this - entry."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) - Section 7.3.2"; - } - } - } - } -} diff --git a/src/plugins/yang/openconfig/openconfig-acl@2018-11-21.yang b/src/plugins/yang/openconfig/openconfig-acl@2018-11-21.yang deleted file mode 100644 index fe80988..0000000 --- a/src/plugins/yang/openconfig/openconfig-acl@2018-11-21.yang +++ /dev/null @@ -1,847 +0,0 @@ -module openconfig-acl { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/acl"; - - prefix "oc-acl"; - - import openconfig-packet-match { prefix oc-match; } - import openconfig-interfaces { prefix oc-if; } - import openconfig-yang-types { prefix oc-yang; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - www.openconfig.net"; - - description - "This module defines configuration and operational state - data for network access control lists (i.e., filters, rules, - etc.). ACLs are organized into ACL sets, with each set - containing one or more ACL entries. ACL sets are identified - by a unique name, while each entry within a set is assigned - a sequence-id that determines the order in which the ACL - rules are applied to a packet. Note that ACLs are evaluated - in ascending order based on the sequence-id (low to high). - - Individual ACL rules specify match criteria based on fields in - the packet, along with an action that defines how matching - packets should be handled. Entries have a type that indicates - the type of match criteria, e.g., MAC layer, IPv4, IPv6, etc."; - - oc-ext:openconfig-version "1.0.2"; - - revision "2018-11-21" { - description - "Add OpenConfig module metadata extensions."; - reference "1.0.2"; - } - - revision "2018-04-24" { - description - "Clarified order of ACL evaluation"; - reference "1.0.1"; - } - - revision "2017-05-26" { - description - "Separated ACL entries by type"; - reference "1.0.0"; - } - - revision "2016-08-08" { - description - "OpenConfig public release"; - reference "0.2.0"; - } - - revision "2016-01-22" { - description - "Initial revision"; - reference "TBD"; - } - - // OpenConfig specific extensions for module metadata. - oc-ext:regexp-posix; - oc-ext:catalog-organization "openconfig"; - oc-ext:origin "openconfig"; - - identity ACL_TYPE { - description - "Base identity for types of ACL sets"; - } - - identity ACL_IPV4 { - base ACL_TYPE; - description - "IP-layer ACLs with IPv4 addresses"; - } - - identity ACL_IPV6 { - base ACL_TYPE; - description - "IP-layer ACLs with IPv6 addresses"; - } - - identity ACL_L2 { - base ACL_TYPE; - description - "MAC-layer ACLs"; - } - - identity ACL_MIXED { - base ACL_TYPE; - description - "Mixed-mode ACL that specifies L2 and L3 protocol - fields. This ACL type is not implemented by many - routing/switching devices."; - } - - // ACL action type - - identity FORWARDING_ACTION { - description - "Base identity for actions in the forwarding category"; - } - - identity ACCEPT { - base FORWARDING_ACTION; - description - "Accept the packet"; - } - - identity DROP { - base FORWARDING_ACTION; - description - "Drop packet without sending any ICMP error message"; - } - - identity REJECT { - base FORWARDING_ACTION; - description - "Drop the packet and send an ICMP error message to the source"; - } - - identity LOG_ACTION { - description - "Base identity for defining the destination for logging - actions"; - } - - identity LOG_SYSLOG { - base LOG_ACTION; - description - "Log the packet in Syslog"; - } - - identity LOG_NONE { - base LOG_ACTION; - description - "No logging"; - } - - identity ACL_COUNTER_CAPABILITY { - description - "Base identity for system to indicate how it is able to report - counters"; - } - - identity INTERFACE_ONLY { - base ACL_COUNTER_CAPABILITY; - description - "ACL counters are available and reported only per interface"; - } - - identity AGGREGATE_ONLY { - base ACL_COUNTER_CAPABILITY; - description - "ACL counters are aggregated over all interfaces, and reported - only per ACL entry"; - } - - identity INTERFACE_AGGREGATE { - base ACL_COUNTER_CAPABILITY; - description - "ACL counters are reported per interface, and also aggregated - and reported per ACL entry."; - } - - // grouping statements - - // input interface - grouping input-interface-config { - description - "Config of interface"; - - } - - grouping input-interface-state { - description - "State information of interface"; - } - - grouping input-interface-top { - description - "Input interface top level container"; - - container input-interface { - description - "Input interface container"; - - container config { - description - "Config data"; - uses input-interface-config; - } - - container state { - config false; - description - "State information"; - uses input-interface-config; - uses input-interface-state; - } - - uses oc-if:interface-ref; - - } - } - - // Action Type - grouping action-config { - description - "Config of action type"; - - - leaf forwarding-action { - type identityref { - base FORWARDING_ACTION; - } - mandatory true; - description - "Specifies the forwarding action. One forwarding action - must be specified for each ACL entry"; - } - - leaf log-action { - type identityref { - base LOG_ACTION; - } - default LOG_NONE; - description - "Specifies the log action and destination for - matched packets. The default is not to log the - packet."; - } - - - } - - grouping action-state { - description - "State information of action type"; - - } - - grouping action-top { - description - "ACL action type top level container"; - - container actions { - description - "Enclosing container for list of ACL actions associated - with an entry"; - - container config { - description - "Config data for ACL actions"; - uses action-config; - } - - container state { - config false; - description - "State information for ACL actions"; - uses action-config; - uses action-state; - } - } - } - - grouping acl-counters-state { - description - "Common grouping for ACL counters"; - - leaf matched-packets { - type oc-yang:counter64; - description - "Count of the number of packets matching the current ACL - entry. - - An implementation should provide this counter on a - per-interface per-ACL-entry if possible. - - If an implementation only supports ACL counters per entry - (i.e., not broken out per interface), then the value - should be equal to the aggregate count across all interfaces. - - An implementation that provides counters per entry per - interface is not required to also provide an aggregate count, - e.g., per entry -- the user is expected to be able implement - the required aggregation if such a count is needed."; - } - - leaf matched-octets { - type oc-yang:counter64; - description - "Count of the number of octets (bytes) matching the current - ACL entry. - - An implementation should provide this counter on a - per-interface per-ACL-entry if possible. - - If an implementation only supports ACL counters per entry - (i.e., not broken out per interface), then the value - should be equal to the aggregate count across all interfaces. - - An implementation that provides counters per entry per - interface is not required to also provide an aggregate count, - e.g., per entry -- the user is expected to be able implement - the required aggregation if such a count is needed."; - } - - } - - // Access List Entries - grouping access-list-entries-config { - description - "Access List Entries (ACE) config."; - - leaf sequence-id { - type uint32; - description - "The sequence id determines the order in which ACL entries - are applied. The sequence id must be unique for each entry - in an ACL set. Target devices should apply the ACL entry - rules in ascending order determined by sequence id (low to - high), rather than the relying only on order in the list."; - } - - leaf description { - type string; - description - "A user-defined description, or comment, for this Access List - Entry."; - } - - } - - grouping access-list-entries-state { - description - "Access List Entries state."; - - uses acl-counters-state; - - } - - grouping access-list-entries-top { - description - "Access list entries to level container"; - - container acl-entries { - description - "Access list entries container"; - - list acl-entry { - key "sequence-id"; - description - "List of ACL entries comprising an ACL set"; - - leaf sequence-id { - type leafref { - path "../config/sequence-id"; - } - description - "references the list key"; - } - - container config { - description - "Access list entries config"; - uses access-list-entries-config; - } - - container state { - config false; - description - "State information for ACL entries"; - uses access-list-entries-config; - uses access-list-entries-state; - } - - uses oc-match:ethernet-header-top { - when "../../config/type='ACL_L2'" { - description - "MAC-layer fields are valid when the ACL type is L2"; - } - } - uses oc-match:ipv4-protocol-fields-top { - when "../../config/type='ACL_IPV4'" { - description - "IPv4-layer fields are valid when the ACL type is - IPv4"; - } - } - uses oc-match:ipv6-protocol-fields-top { - when "../../config/type='ACL_IPV6'" { - description - "IPv6-layer fields are valid when the ACL type is - IPv6"; - } - } - uses oc-match:transport-fields-top { - when "../../config/type='ACL_IPV6' or " + - "../../config/type='ACL_IPV4'" { - description - "Transport-layer fields are valid when specifying - L3 ACL types"; - } - } - uses input-interface-top; - - uses action-top; - } - } - } - - grouping acl-set-config { - description - "Access Control List config"; - - leaf name { - type string; - description - "The name of the access-list set"; - } - - leaf type { - type identityref { - base ACL_TYPE; - } - description - "The type determines the fields allowed in the ACL entries - belonging to the ACL set (e.g., IPv4, IPv6, etc.)"; - } - - leaf description { - type string; - description - "Description, or comment, for the ACL set"; - } - - } - - grouping acl-set-state { - description - "Access Control List state"; - } - - grouping acl-set-top { - description - "Access list entries variables top level container"; - - container acl-sets { - description - "Access list entries variables enclosing container"; - - list acl-set { - key "name type"; - description - "List of ACL sets, each comprising of a list of ACL - entries"; - - leaf name { - type leafref { - path "../config/name"; - } - description - "Reference to the name list key"; - } - - leaf type { - type leafref { - path "../config/type"; - } - description - "Reference to the type list key"; - } - - container config { - description - "Access list config"; - uses acl-set-config; - } - - container state { - config false; - description - "Access list state information"; - uses acl-set-config; - uses acl-set-state; - } - uses access-list-entries-top; - } - } - } - - grouping interface-acl-entries-config { - description - "Configuration data for per-interface ACLs"; - - } - - grouping interface-acl-entries-state { - description - "Operational state data for per-interface ACL entries"; - - leaf sequence-id { - type leafref { - path "/acl/acl-sets/" + - "acl-set[name=current()/../../../../set-name]" + - "[type=current()/../../../../type]/" + - "acl-entries/acl-entry/sequence-id"; - } - description - "Reference to an entry in the ACL set applied to an - interface"; - } - - uses acl-counters-state; - - } - - grouping interface-acl-entries-top { - description - "Top-level grouping for per-interface ACL entries"; - - container acl-entries { - config false; - description - "Enclosing container for list of references to ACLs"; - - list acl-entry { - key "sequence-id"; - description - "List of ACL entries assigned to an interface"; - - leaf sequence-id { - type leafref { - path "../state/sequence-id"; - } - description - "Reference to per-interface acl entry key"; - } - - // no config container since the enclosing container is - // read-only - - container state { - - config false; - - description - "Operational state data for per-interface ACL entries"; - - uses interface-acl-entries-config; - uses interface-acl-entries-state; - } - } - } - } - - grouping interface-ingress-acl-config { - description - "Configuration data for per-interface ingress ACLs"; - - leaf set-name { - type leafref { - path "../../../../../../acl-sets/acl-set/config/name"; - } - description - "Reference to the ACL set name applied on ingress"; - } - - leaf type { - type leafref { - path "../../../../../../acl-sets/acl-set[name=current()/../set-name]" + - "/config/type"; - } - description - "Reference to the ACL set type applied on ingress"; - } - } - - grouping interface-ingress-acl-state { - description - "Operational state data for the per-interface ingress ACL"; - } - - grouping interface-ingress-acl-top { - description - "Top-level grouping for per-interface ingress ACL data"; - - container ingress-acl-sets { - description - "Enclosing container the list of ingress ACLs on the - interface"; - - list ingress-acl-set { - key "set-name type"; - description - "List of ingress ACLs on the interface"; - - leaf set-name { - type leafref { - path "../config/set-name"; - } - description - "Reference to set name list key"; - } - - leaf type { - type leafref { - path "../config/type"; - } - description - "Reference to type list key"; - } - - container config { - description - "Configuration data "; - - uses interface-ingress-acl-config; - } - - container state { - - config false; - - description - "Operational state data for interface ingress ACLs"; - - uses interface-ingress-acl-config; - uses interface-ingress-acl-state; - } - - uses interface-acl-entries-top; - } - } - } - - grouping interface-egress-acl-config { - description - "Configuration data for per-interface egress ACLs"; - - leaf set-name { - type leafref { - path "../../../../../../acl-sets/acl-set/config/name"; - } - description - "Reference to the ACL set name applied on egress"; - } - - leaf type { - type leafref { - path "../../../../../../acl-sets/acl-set[name=current()/../set-name]" + - "/config/type"; - } - description - "Reference to the ACL set type applied on egress."; - } - } - - grouping interface-egress-acl-state { - description - "Operational state data for the per-interface egress ACL"; - } - - grouping interface-egress-acl-top { - description - "Top-level grouping for per-interface egress ACL data"; - - container egress-acl-sets { - description - "Enclosing container the list of egress ACLs on the - interface"; - - list egress-acl-set { - key "set-name type"; - description - "List of egress ACLs on the interface"; - - leaf set-name { - type leafref { - path "../config/set-name"; - } - description - "Reference to set name list key"; - } - - leaf type { - type leafref { - path "../config/type"; - } - description - "Reference to type list key"; - } - - container config { - description - "Configuration data "; - - uses interface-egress-acl-config; - } - - container state { - - config false; - - description - "Operational state data for interface egress ACLs"; - - uses interface-egress-acl-config; - uses interface-egress-acl-state; - } - - uses interface-acl-entries-top; - } - } - } - - grouping acl-interfaces-config { - description - "Configuration data for interface references"; - - leaf id { - type oc-if:interface-id; - description - "User-defined identifier for the interface -- a common - convention could be '.'"; - } - } - - grouping acl-interfaces-state { - description - "Operational state data for interface references"; - } - - grouping acl-interfaces-top { - description - "Top-level grouping for interface-specific ACL data"; - - container interfaces { - description - "Enclosing container for the list of interfaces on which - ACLs are set"; - - list interface { - key "id"; - description - "List of interfaces on which ACLs are set"; - - leaf id { - type leafref { - path "../config/id"; - } - description - "Reference to the interface id list key"; - } - - container config { - description - "Configuration for ACL per-interface data"; - - uses acl-interfaces-config; - } - - container state { - - config false; - - description - "Operational state for ACL per-interface data"; - - uses acl-interfaces-config; - uses acl-interfaces-state; - } - - uses oc-if:interface-ref; - uses interface-ingress-acl-top; - uses interface-egress-acl-top; - } - } - } - - grouping acl-config { - description - "Global configuration data for ACLs"; - } - - grouping acl-state { - description - "Global operational state data for ACLs"; - - leaf counter-capability { - type identityref { - base ACL_COUNTER_CAPABILITY; - } - description - "System reported indication of how ACL counters are reported - by the target"; - } - } - grouping acl-top { - description - "Top level grouping for ACL data and structure"; - - container acl { - description - "Top level enclosing container for ACL model config - and operational state data"; - - container config { - description - "Global config data for ACLs"; - - uses acl-config; - } - - container state { - - config false; - - description - "Global operational state data for ACLs"; - - uses acl-config; - uses acl-state; - } - - uses acl-set-top; - uses acl-interfaces-top; - } - } - - // data definition statements - uses acl-top; - - // augment statements - - -} diff --git a/src/plugins/yang/openconfig/openconfig-extensions@2017-04-11.yang b/src/plugins/yang/openconfig/openconfig-extensions@2017-04-11.yang deleted file mode 100644 index f39ecf6..0000000 --- a/src/plugins/yang/openconfig/openconfig-extensions@2017-04-11.yang +++ /dev/null @@ -1,91 +0,0 @@ -module openconfig-extensions { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/openconfig-ext"; - - prefix "oc-ext"; - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - www.openconfig.net"; - - description - "This module provides extensions to the YANG language to allow - OpenConfig specific functionality and meta-data to be defined."; - - revision "2017-04-11" { - description - "rename password type to 'hashed' and clarify description"; - reference "0.3.0"; - } - - revision "2017-01-29" { - description - "Added extension for annotating encrypted values."; - reference "0.2.0"; - } - - revision "2015-10-09" { - description - "Initial OpenConfig public release"; - reference "0.1.0"; - } - - - // extension statements - extension openconfig-version { - argument "semver" { - yin-element false; - } - description - "The OpenConfig version number for the module. This is - expressed as a semantic version number of the form: - x.y.z - where: - * x corresponds to the major version, - * y corresponds to a minor version, - * z corresponds to a patch version. - This version corresponds to the model file within which it is - defined, and does not cover the whole set of OpenConfig models. - Where several modules are used to build up a single block of - functionality, the same module version is specified across each - file that makes up the module. - - A major version number of 0 indicates that this model is still - in development (whether within OpenConfig or with industry - partners), and is potentially subject to change. - - Following a release of major version 1, all modules will - increment major revision number where backwards incompatible - changes to the model are made. - - The minor version is changed when features are added to the - model that do not impact current clients use of the model. - - The patch-level version is incremented when non-feature changes - (such as bugfixes or clarifications to human-readable - descriptions that do not impact model functionality) are made - that maintain backwards compatibility. - - The version number is stored in the module meta-data."; - } - - extension openconfig-hashed-value { - description - "This extension provides an annotation on schema nodes to - indicate that the corresponding value should be stored and - reported in hashed form. - - Hash algorithms are by definition not reversible. Clients - reading the configuration or applied configuration for the node - should expect to receive only the hashed value. Values written - in cleartext will be hashed. This annotation may be used on - nodes such as secure passwords in which the device never reports - a cleartext value, even if the input is provided as cleartext."; - } -} diff --git a/src/plugins/yang/openconfig/openconfig-if-aggregate@2018-03-23.yang b/src/plugins/yang/openconfig/openconfig-if-aggregate@2018-03-23.yang deleted file mode 100644 index 5aa80bb..0000000 --- a/src/plugins/yang/openconfig/openconfig-if-aggregate@2018-03-23.yang +++ /dev/null @@ -1,223 +0,0 @@ -module openconfig-if-aggregate { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/interfaces/aggregate"; - - prefix "oc-lag"; - - // import some basic types - import openconfig-interfaces { prefix oc-if; } - import openconfig-if-ethernet { prefix oc-eth; } - import iana-if-type { prefix ift; } - import openconfig-if-types { prefix oc-ift; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "Model for managing aggregated (aka bundle, LAG) interfaces."; - - oc-ext:openconfig-version "2.3.1"; - - revision "2018-03-23" { - description - "Fix/cleanup when statements in aggregates model."; - reference "2.3.1"; - } - - revision "2018-01-05" { - description - "Add logical loopback to interface."; - reference "2.3.0"; - } - - revision "2017-12-22" { - description - "Add IPv4 proxy ARP configuration."; - reference "2.2.0"; - } - - revision "2017-12-21" { - description - "Added IPv6 router advertisement configuration."; - reference "2.1.0"; - } - - revision "2017-07-14" { - description - "Added Ethernet/IP state data; Add dhcp-client; - migrate to OpenConfig types modules; Removed or - renamed opstate values"; - reference "2.0.0"; - } - - revision "2016-12-22" { - description - "Fixes to Ethernet interfaces model"; - reference "1.1.0"; - } - - // extension statements - - // feature statements - - // identity statements - - // typedef statements - - - - typedef aggregation-type { - type enumeration { - enum LACP { - description "LAG managed by LACP"; - } - enum STATIC { - description "Statically configured bundle / LAG"; - } - } - description - "Type to define the lag-type, i.e., how the LAG is - defined and managed"; - } - - // grouping statements - - - grouping aggregation-logical-config { - description - "Configuration data for aggregate interfaces"; - - - leaf lag-type { - type aggregation-type; - description - "Sets the type of LAG, i.e., how it is - configured / maintained"; - } - - leaf min-links { - type uint16; - description - "Specifies the mininum number of member - interfaces that must be active for the aggregate interface - to be available"; - } - } - - grouping aggregation-logical-state { - description - "Operational state data for aggregate interfaces"; - - leaf lag-speed { - type uint32; - units Mbps; - description - "Reports effective speed of the aggregate interface, - based on speed of active member interfaces"; - } - - leaf-list member { - when "../../config/lag-type = 'STATIC'" { - description - "The simple list of member interfaces is active - when the aggregate is statically configured"; - } - type oc-if:base-interface-ref; - description - "List of current member interfaces for the aggregate, - expressed as references to existing interfaces"; - } - } - - grouping aggregation-logical-top { - description "Top-level data definitions for LAGs"; - - container aggregation { - - description - "Options for logical interfaces representing - aggregates"; - - container config { - description - "Configuration variables for logical aggregate / - LAG interfaces"; - - uses aggregation-logical-config; - } - - container state { - - config false; - description - "Operational state variables for logical - aggregate / LAG interfaces"; - - uses aggregation-logical-config; - uses aggregation-logical-state; - - } - } - } - - grouping ethernet-if-aggregation-config { - description - "Adds configuration items for Ethernet interfaces - belonging to a logical aggregate / LAG"; - - leaf aggregate-id { - type leafref { - path "/oc-if:interfaces/oc-if:interface/oc-if:name"; - } - description - "Specify the logical aggregate interface to which - this interface belongs"; - } - } - - // data definition statements - - // augment statements - - augment "/oc-if:interfaces/oc-if:interface" { - - description "Adds LAG configuration to the interface module"; - - uses aggregation-logical-top { - when "oc-if:state/oc-if:type = 'ift:ieee8023adLag' or " + - "oc-if:state/oc-if:type = 'oc-ift:IF_AGGREGATE'" { - description - "active when the interface is set to type LAG"; - } - } - } - - augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" + - "oc-eth:config" { - description - "Adds LAG settings to individual Ethernet interfaces"; - - uses ethernet-if-aggregation-config; - } - - augment "/oc-if:interfaces/oc-if:interface/oc-eth:ethernet/" + - "oc-eth:state" { - description - "Adds LAG settings to individual Ethernet interfaces"; - - uses ethernet-if-aggregation-config; - } - - // rpc statements - - // notification statements - -} diff --git a/src/plugins/yang/openconfig/openconfig-if-ethernet@2018-09-04.yang b/src/plugins/yang/openconfig/openconfig-if-ethernet@2018-09-04.yang deleted file mode 100644 index cd6b526..0000000 --- a/src/plugins/yang/openconfig/openconfig-if-ethernet@2018-09-04.yang +++ /dev/null @@ -1,428 +0,0 @@ -module openconfig-if-ethernet { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/interfaces/ethernet"; - - prefix "oc-eth"; - - // import some basic types - import openconfig-interfaces { prefix oc-if; } - import iana-if-type { prefix ift; } - import openconfig-yang-types { prefix oc-yang; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "Model for managing Ethernet interfaces -- augments the OpenConfig - model for interface configuration and state."; - - oc-ext:openconfig-version "2.6.1"; - - revision "2018-09-04" { - description - "Remove in-crc-align-errors as it is a duplicate of - in-crc-errors"; - reference "2.6.1"; - } - - revision "2018-08-28" { - description - "Add Ethernet counter in-block-errors"; - reference "2.6.0"; - } - - revision "2018-07-02" { - description - "Add new ethernet counters of in-undersize-frames, - in-crc-align-errors and the distribution container"; - reference "2.5.0"; - } - - revision "2018-04-10" { - description - "Add identities for 2.5 and 5 Gbps."; - reference "2.4.0"; - } - - revision "2018-01-05" { - description - "Add logical loopback to interface."; - reference "2.3.0"; - } - - revision "2017-12-21" { - description - "Added IPv6 router advertisement configuration."; - reference "2.1.0"; - } - - revision "2017-07-14" { - description - "Added Ethernet/IP state data; Add dhcp-client; - migrate to OpenConfig types modules; Removed or - renamed opstate values"; - reference "2.0.0"; - } - - revision "2016-12-22" { - description - "Fixes to Ethernet interfaces model"; - reference "1.1.0"; - } - - - // identity statements - - identity ETHERNET_SPEED { - description "base type to specify available Ethernet link - speeds"; - } - - identity SPEED_10MB { - base ETHERNET_SPEED; - description "10 Mbps Ethernet"; - } - - identity SPEED_100MB { - base ETHERNET_SPEED; - description "100 Mbps Ethernet"; - } - - identity SPEED_1GB { - base ETHERNET_SPEED; - description "1 Gbps Ethernet"; - } - - identity SPEED_2500MB { - base ETHERNET_SPEED; - description "2.5 Gbps Ethernet"; - } - - identity SPEED_5GB { - base ETHERNET_SPEED; - description "5 Gbps Ethernet"; - } - - identity SPEED_10GB { - base ETHERNET_SPEED; - description "10 Gbps Ethernet"; - } - - identity SPEED_25GB { - base ETHERNET_SPEED; - description "25 Gbps Ethernet"; - } - - identity SPEED_40GB { - base ETHERNET_SPEED; - description "40 Gbps Ethernet"; - } - - identity SPEED_50GB { - base ETHERNET_SPEED; - description "50 Gbps Ethernet"; - } - - identity SPEED_100GB { - base ETHERNET_SPEED; - description "100 Gbps Ethernet"; - } - - identity SPEED_UNKNOWN { - base ETHERNET_SPEED; - description - "Interface speed is unknown. Systems may report - speed UNKNOWN when an interface is down or unpopuplated (e.g., - pluggable not present)."; - } - - // typedef statements - - - // grouping statements - - grouping ethernet-interface-config { - description "Configuration items for Ethernet interfaces"; - - leaf mac-address { - type oc-yang:mac-address; - description - "Assigns a MAC address to the Ethernet interface. If not - specified, the corresponding operational state leaf is - expected to show the system-assigned MAC address."; - } - - leaf auto-negotiate { - type boolean; - default true; - description - "Set to TRUE to request the interface to auto-negotiate - transmission parameters with its peer interface. When - set to FALSE, the transmission parameters are specified - manually."; - reference - "IEEE 802.3-2012 auto-negotiation transmission parameters"; - } - - leaf duplex-mode { - type enumeration { - enum FULL { - description "Full duplex mode"; - } - enum HALF { - description "Half duplex mode"; - } - } - description - "When auto-negotiate is TRUE, this optionally sets the - duplex mode that will be advertised to the peer. If - unspecified, the interface should negotiate the duplex mode - directly (typically full-duplex). When auto-negotiate is - FALSE, this sets the duplex mode on the interface directly."; - } - - leaf port-speed { - type identityref { - base ETHERNET_SPEED; - } - description - "When auto-negotiate is TRUE, this optionally sets the - port-speed mode that will be advertised to the peer for - negotiation. If unspecified, it is expected that the - interface will select the highest speed available based on - negotiation. When auto-negotiate is set to FALSE, sets the - link speed to a fixed value -- supported values are defined - by ETHERNET_SPEED identities"; - } - - leaf enable-flow-control { - type boolean; - default false; - description - "Enable or disable flow control for this interface. - Ethernet flow control is a mechanism by which a receiver - may send PAUSE frames to a sender to stop transmission for - a specified time. - - This setting should override auto-negotiated flow control - settings. If left unspecified, and auto-negotiate is TRUE, - flow control mode is negotiated with the peer interface."; - reference - "IEEE 802.3x"; - } - } - - grouping ethernet-interface-state-counters { - description - "Ethernet-specific counters and statistics"; - - // ingress counters - - leaf in-mac-control-frames { - type oc-yang:counter64; - description - "MAC layer control frames received on the interface"; - } - - leaf in-mac-pause-frames { - type oc-yang:counter64; - description - "MAC layer PAUSE frames received on the interface"; - } - - leaf in-oversize-frames { - type oc-yang:counter64; - description - "The total number of frames received that were - longer than 1518 octets (excluding framing bits, - but including FCS octets) and were otherwise - well formed."; - } - - leaf in-undersize-frames { - type oc-yang:counter64; - description - "The total number of frames received that were - less than 64 octets long (excluding framing bits, - but including FCS octets) and were otherwise well - formed."; - reference - "RFC 2819: Remote Network Monitoring MIB - - etherStatsUndersizePkts"; - } - - leaf in-jabber-frames { - type oc-yang:counter64; - description - "Number of jabber frames received on the - interface. Jabber frames are typically defined as oversize - frames which also have a bad CRC. Implementations may use - slightly different definitions of what constitutes a jabber - frame. Often indicative of a NIC hardware problem."; - } - - leaf in-fragment-frames { - type oc-yang:counter64; - description - "The total number of frames received that were less than - 64 octets in length (excluding framing bits but including - FCS octets) and had either a bad Frame Check Sequence - (FCS) with an integral number of octets (FCS Error) or a - bad FCS with a non-integral number of octets (Alignment - Error)."; - } - - leaf in-8021q-frames { - type oc-yang:counter64; - description - "Number of 802.1q tagged frames received on the interface"; - } - - leaf in-crc-errors { - type oc-yang:counter64; - description - "The total number of frames received that - had a length (excluding framing bits, but - including FCS octets) of between 64 and 1518 - octets, inclusive, but had either a bad - Frame Check Sequence (FCS) with an integral - number of octets (FCS Error) or a bad FCS with - a non-integral number of octets (Alignment Error)"; - reference - "RFC 2819: Remote Network Monitoring MIB - - etherStatsCRCAlignErrors"; - } - - leaf in-block-errors { - type oc-yang:counter64; - description - "The number of received errored blocks. Error detection codes - are capable of detecting whether one or more errors have - occurred in a given sequence of bits - the block. It is - normally not possible to determine the exact number of errored - bits within the block"; - } - - // egress counters - - leaf out-mac-control-frames { - type oc-yang:counter64; - description - "MAC layer control frames sent on the interface"; - } - - leaf out-mac-pause-frames { - type oc-yang:counter64; - description - "MAC layer PAUSE frames sent on the interface"; - } - - leaf out-8021q-frames { - type oc-yang:counter64; - description - "Number of 802.1q tagged frames sent on the interface"; - } - } - - grouping ethernet-interface-state { - description - "Grouping for defining Ethernet-specific operational state"; - - leaf hw-mac-address { - type oc-yang:mac-address; - description - "Represenets the 'burned-in', or system-assigned, MAC - address for the Ethernet interface."; - } - - leaf negotiated-duplex-mode { - type enumeration { - enum FULL { - description "Full duplex mode"; - } - enum HALF { - description "Half duplex mode"; - } - } - description - "When auto-negotiate is set to TRUE, and the interface has - completed auto-negotiation with the remote peer, this value - shows the duplex mode that has been negotiated."; - } - - leaf negotiated-port-speed { - type identityref { - base ETHERNET_SPEED; - } - description - "When auto-negotiate is set to TRUE, and the interface has - completed auto-negotiation with the remote peer, this value - shows the interface speed that has been negotiated."; - } - - container counters { - description "Ethernet interface counters"; - - uses ethernet-interface-state-counters; - - } - - } - - // data definition statements - - grouping ethernet-top { - description "top-level Ethernet config and state containers"; - - container ethernet { - description - "Top-level container for ethernet configuration - and state"; - - container config { - description "Configuration data for ethernet interfaces"; - - uses ethernet-interface-config; - - } - - container state { - - config false; - description "State variables for Ethernet interfaces"; - - uses ethernet-interface-config; - uses ethernet-interface-state; - - } - - } - } - - // augment statements - - augment "/oc-if:interfaces/oc-if:interface" { - description "Adds addtional Ethernet-specific configuration to - interfaces model"; - - uses ethernet-top { - when "oc-if:state/oc-if:type = 'ift:ethernetCsmacd'" { - description "Additional interface configuration parameters when - the interface type is Ethernet"; - } - } - } - - // rpc statements - - // notification statements - -} diff --git a/src/plugins/yang/openconfig/openconfig-if-ip@2018-01-05.yang b/src/plugins/yang/openconfig/openconfig-if-ip@2018-01-05.yang deleted file mode 100644 index a20e21c..0000000 --- a/src/plugins/yang/openconfig/openconfig-if-ip@2018-01-05.yang +++ /dev/null @@ -1,1312 +0,0 @@ -module openconfig-if-ip { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/interfaces/ip"; - - prefix "oc-ip"; - - // import some basic types - import openconfig-inet-types { prefix oc-inet; } - import openconfig-interfaces { prefix oc-if; } - import openconfig-vlan { prefix oc-vlan; } - import openconfig-yang-types { prefix oc-yang; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "This model defines data for managing configuration and - operational state on IP (IPv4 and IPv6) interfaces. - - This model reuses data items defined in the IETF YANG model for - interfaces described by RFC 7277 with an alternate structure - (particularly for operational state data) and with - additional configuration items. - - Portions of this code were derived from IETF RFC 7277. - Please reproduce this note if possible. - - IETF code is subject to the following copyright and license: - Copyright (c) IETF Trust and the persons identified as authors of - the code. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, is permitted pursuant to, and subject to the license - terms contained in, the Simplified BSD License set forth in - Section 4.c of the IETF Trust's Legal Provisions Relating - to IETF Documents (http://trustee.ietf.org/license-info)."; - - oc-ext:openconfig-version "2.3.0"; - - revision "2018-01-05" { - description - "Add logical loopback to interface."; - reference "2.3.0"; - } - - revision "2017-12-21" { - description - "Added IPv6 router advertisement configuration."; - reference "2.1.0"; - } - - revision "2017-07-14" { - description - "Added Ethernet/IP state data; Add dhcp-client; - migrate to OpenConfig types modules; Removed or - renamed opstate values"; - reference "2.0.0"; - } - - revision "2017-04-03"{ - description - "Update copyright notice."; - reference "1.1.1"; - } - - revision "2016-12-22" { - description - "Fixes to Ethernet interfaces model"; - reference "1.1.0"; - } - - - // typedef statements - - typedef ip-address-origin { - type enumeration { - enum OTHER { - description - "None of the following."; - } - enum STATIC { - description - "Indicates that the address has been statically - configured - for example, using NETCONF or a Command Line - Interface."; - } - enum DHCP { - description - "Indicates an address that has been assigned to this - system by a DHCP server."; - } - enum LINK_LAYER { - description - "Indicates an address created by IPv6 stateless - autoconfiguration that embeds a link-layer address in its - interface identifier."; - } - enum RANDOM { - description - "Indicates an address chosen by the system at - random, e.g., an IPv4 address within 169.254/16, an - RFC 4941 temporary address, or an RFC 7217 semantically - opaque address."; - reference - "RFC 4941: Privacy Extensions for Stateless Address - Autoconfiguration in IPv6 - RFC 7217: A Method for Generating Semantically Opaque - Interface Identifiers with IPv6 Stateless - Address Autoconfiguration (SLAAC)"; - } - } - description - "The origin of an address."; - } - - typedef neighbor-origin { - type enumeration { - enum OTHER { - description - "None of the following."; - } - enum STATIC { - description - "Indicates that the mapping has been statically - configured - for example, using NETCONF or a Command Line - Interface."; - } - enum DYNAMIC { - description - "Indicates that the mapping has been dynamically resolved - using, e.g., IPv4 ARP or the IPv6 Neighbor Discovery - protocol."; - } - } - description - "The origin of a neighbor entry."; - } - - // grouping statements - - grouping ip-common-global-config { - description - "Shared configuration data for IPv4 or IPv6 assigned - globally on an interface."; - - leaf dhcp-client { - type boolean; - default false; - description - "Enables a DHCP client on the interface in order to request - an address"; - } - } - - grouping ip-common-counters-state { - description - "Operational state for IP traffic statistics for IPv4 and - IPv6"; - - container counters { - description - "Packet and byte counters for IP transmission and - reception for the address family."; - - - leaf in-pkts { - type oc-yang:counter64; - description - "The total number of IP packets received for the specified - address family, including those received in error"; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf in-octets { - type oc-yang:counter64; - description - "The total number of octets received in input IP packets - for the specified address family, including those received - in error."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf in-error-pkts { - // TODO: this counter combines several error conditions -- - // could consider breaking them out to separate leaf nodes - type oc-yang:counter64; - description - "Number of IP packets discarded due to errors for the - specified address family, including errors in the IP - header, no route found to the IP destination, invalid - address, unknown protocol, etc."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf in-forwarded-pkts { - type oc-yang:counter64; - description - "The number of input packets for which the device was not - their final IP destination and for which the device - attempted to find a route to forward them to that final - destination."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf in-forwarded-octets { - type oc-yang:counter64; - description - "The number of octets received in input IP packets - for the specified address family for which the device was - not their final IP destination and for which the - device attempted to find a route to forward them to that - final destination."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf in-discarded-pkts { - type oc-yang:counter64; - description - "The number of input IP packets for the - specified address family, for which no problems were - encountered to prevent their continued processing, but - were discarded (e.g., for lack of buffer space)."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf out-pkts { - type oc-yang:counter64; - description - "The total number of IP packets for the - specified address family that the device supplied - to the lower layers for transmission. This includes - packets generated locally and those forwarded by the - device."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf out-octets { - type oc-yang:counter64; - description - "The total number of octets in IP packets for the - specified address family that the device - supplied to the lower layers for transmission. This - includes packets generated locally and those forwarded by - the device."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf out-error-pkts { - // TODO: this counter combines several error conditions -- - // could consider breaking them out to separate leaf nodes - type oc-yang:counter64; - description - "Number of IP packets for the specified address family - locally generated and discarded due to errors, including - no route found to the IP destination."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf out-forwarded-pkts { - type oc-yang:counter64; - description - "The number of packets for which this entity was not their - final IP destination and for which it was successful in - finding a path to their final destination."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf out-forwarded-octets { - type oc-yang:counter64; - description - "The number of octets in packets for which this entity was - not their final IP destination and for which it was - successful in finding a path to their final destination."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - - leaf out-discarded-pkts { - type oc-yang:counter64; - description - "The number of output IP packets for the - specified address family for which no problem was - encountered to prevent their transmission to their - destination, but were discarded (e.g., for lack of - buffer space)."; - reference - "RFC 4293 - Management Information Base for the - Internet Protocol (IP)"; - } - } - - } - - - - grouping ipv4-global-config { - description - "Configuration data for IPv4 interfaces across - all addresses assigned to the interface"; - - leaf enabled { - type boolean; - default true; - description - "Controls whether IPv4 is enabled or disabled on this - interface. When IPv4 is enabled, this interface is - connected to an IPv4 stack, and the interface can send - and receive IPv4 packets."; - } - - leaf mtu { - type uint16 { - range "68..max"; - } - units octets; - description - "The size, in octets, of the largest IPv4 packet that the - interface will send and receive. - - The server may restrict the allowed values for this leaf, - depending on the interface's type. - - If this leaf is not configured, the operationally used MTU - depends on the interface's type."; - reference - "RFC 791: Internet Protocol"; - } - - uses ip-common-global-config; - - - } - - grouping ipv4-address-config { - - description - "Per IPv4 adresss configuration data for the - interface."; - - leaf ip { - type oc-inet:ipv4-address; - description - "The IPv4 address on the interface."; - } - - leaf prefix-length { - type uint8 { - range "0..32"; - } - description - "The length of the subnet prefix."; - } - } - - grouping ipv4-neighbor-config { - description - "Per IPv4 neighbor configuration data. Neighbor - entries are analagous to static ARP entries, i.e., they - create a correspondence between IP and link-layer addresses"; - - leaf ip { - type oc-inet:ipv4-address; - description - "The IPv4 address of the neighbor node."; - } - leaf link-layer-address { - type oc-yang:phys-address; - mandatory true; - description - "The link-layer address of the neighbor node."; - } - } - - grouping ipv4-address-state { - description - "State variables for IPv4 addresses on the interface"; - - leaf origin { - type ip-address-origin; - description - "The origin of this address, e.g., statically configured, - assigned by DHCP, etc.."; - } - } - - grouping ipv4-neighbor-state { - description - "State variables for IPv4 neighbor entries on the interface."; - - leaf origin { - type neighbor-origin; - description - "The origin of this neighbor entry, static or dynamic."; - } - } - - grouping ipv6-global-config { - description - "Configuration data at the global level for each - IPv6 interface"; - - leaf enabled { - type boolean; - default true; - description - "Controls whether IPv6 is enabled or disabled on this - interface. When IPv6 is enabled, this interface is - connected to an IPv6 stack, and the interface can send - and receive IPv6 packets."; - } - - leaf mtu { - type uint32 { - range "1280..max"; - } - units octets; - description - "The size, in octets, of the largest IPv6 packet that the - interface will send and receive. - - The server may restrict the allowed values for this leaf, - depending on the interface's type. - - If this leaf is not configured, the operationally used MTU - depends on the interface's type."; - reference - "RFC 2460: Internet Protocol, Version 6 (IPv6) Specification - Section 5"; - } - - leaf dup-addr-detect-transmits { - type uint32; - default 1; - description - "The number of consecutive Neighbor Solicitation messages - sent while performing Duplicate Address Detection on a - tentative address. A value of zero indicates that - Duplicate Address Detection is not performed on - tentative addresses. A value of one indicates a single - transmission with no follow-up retransmissions."; - reference - "RFC 4862: IPv6 Stateless Address Autoconfiguration"; - } - - uses ip-common-global-config; - } - - grouping ipv6-address-config { - description "Per-address configuration data for IPv6 interfaces"; - - leaf ip { - type oc-inet:ipv6-address; - description - "The IPv6 address on the interface."; - } - - leaf prefix-length { - type uint8 { - range "0..128"; - } - mandatory true; - description - "The length of the subnet prefix."; - } - } - - grouping ipv6-address-state { - description - "Per-address operational state data for IPv6 interfaces"; - - leaf origin { - type ip-address-origin; - description - "The origin of this address, e.g., static, dhcp, etc."; - } - - leaf status { - type enumeration { - enum PREFERRED { - description - "This is a valid address that can appear as the - destination or source address of a packet."; - } - enum DEPRECATED { - description - "This is a valid but deprecated address that should - no longer be used as a source address in new - communications, but packets addressed to such an - address are processed as expected."; - } - enum INVALID { - description - "This isn't a valid address, and it shouldn't appear - as the destination or source address of a packet."; - } - enum INACCESSIBLE { - description - "The address is not accessible because the interface - to which this address is assigned is not - operational."; - } - enum UNKNOWN { - description - "The status cannot be determined for some reason."; - } - enum TENTATIVE { - description - "The uniqueness of the address on the link is being - verified. Addresses in this state should not be - used for general communication and should only be - used to determine the uniqueness of the address."; - } - enum DUPLICATE { - description - "The address has been determined to be non-unique on - the link and so must not be used."; - } - enum OPTIMISTIC { - description - "The address is available for use, subject to - restrictions, while its uniqueness on a link is - being verified."; - } - } - description - "The status of an address. Most of the states correspond - to states from the IPv6 Stateless Address - Autoconfiguration protocol."; - reference - "RFC 4293: Management Information Base for the - Internet Protocol (IP) - - IpAddressStatusTC - RFC 4862: IPv6 Stateless Address Autoconfiguration"; - } - } - - grouping ipv6-neighbor-config { - description - "Per-neighbor configuration data for IPv6 interfaces"; - - leaf ip { - type oc-inet:ipv6-address; - description - "The IPv6 address of the neighbor node."; - } - - leaf link-layer-address { - type oc-yang:phys-address; - mandatory true; - description - "The link-layer address of the neighbor node."; - } - } - - grouping ipv6-neighbor-state { - description "Per-neighbor state variables for IPv6 interfaces"; - - leaf origin { - type neighbor-origin; - description - "The origin of this neighbor entry."; - } - leaf is-router { - type empty; - description - "Indicates that the neighbor node acts as a router."; - } - leaf neighbor-state { - type enumeration { - enum INCOMPLETE { - description - "Address resolution is in progress, and the link-layer - address of the neighbor has not yet been - determined."; - } - enum REACHABLE { - description - "Roughly speaking, the neighbor is known to have been - reachable recently (within tens of seconds ago)."; - } - enum STALE { - description - "The neighbor is no longer known to be reachable, but - until traffic is sent to the neighbor no attempt - should be made to verify its reachability."; - } - enum DELAY { - description - "The neighbor is no longer known to be reachable, and - traffic has recently been sent to the neighbor. - Rather than probe the neighbor immediately, however, - delay sending probes for a short while in order to - give upper-layer protocols a chance to provide - reachability confirmation."; - } - enum PROBE { - description - "The neighbor is no longer known to be reachable, and - unicast Neighbor Solicitation probes are being sent - to verify reachability."; - } - } - description - "The Neighbor Unreachability Detection state of this - entry."; - reference - "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) - Section 7.3.2"; - } - } - - grouping ip-vrrp-ipv6-config { - description - "IPv6-specific configuration data for VRRP on IPv6 - interfaces"; - - leaf virtual-link-local { - type oc-inet:ip-address; - description - "For VRRP on IPv6 interfaces, sets the virtual link local - address"; - } - } - - grouping ip-vrrp-ipv6-state { - description - "IPv6-specific operational state for VRRP on IPv6 interfaces"; - - uses ip-vrrp-ipv6-config; - } - - grouping ip-vrrp-tracking-config { - description - "Configuration data for tracking interfaces - in a VRRP group"; - - leaf-list track-interface { - type leafref { - path "/oc-if:interfaces/oc-if:interface/oc-if:name"; - } - // TODO: we may need to add some restriction to ethernet - // or IP interfaces. - description - "Sets a list of one or more interfaces that should - be tracked for up/down events to dynamically change the - priority state of the VRRP group, and potentially - change the mastership if the tracked interface going - down lowers the priority sufficiently. Any of the tracked - interfaces going down will cause the priority to be lowered. - Some implementations may only support a single - tracked interface."; - } - - leaf priority-decrement { - type uint8 { - range 0..254; - } - default 0; - description "Set the value to subtract from priority when - the tracked interface goes down"; - } - } - - grouping ip-vrrp-tracking-state { - description - "Operational state data for tracking interfaces in a VRRP - group"; - } - - grouping ip-vrrp-tracking-top { - description - "Top-level grouping for VRRP interface tracking"; - - container interface-tracking { - description - "Top-level container for VRRP interface tracking"; - - container config { - description - "Configuration data for VRRP interface tracking"; - - uses ip-vrrp-tracking-config; - } - - container state { - - config false; - - description - "Operational state data for VRRP interface tracking"; - - uses ip-vrrp-tracking-config; - uses ip-vrrp-tracking-state; - } - } - } - - grouping ip-vrrp-config { - description - "Configuration data for VRRP on IP interfaces"; - - leaf virtual-router-id { - type uint8 { - range 1..255; - } - description - "Set the virtual router id for use by the VRRP group. This - usually also determines the virtual MAC address that is - generated for the VRRP group"; - } - - leaf-list virtual-address { - type oc-inet:ip-address; - description - "Configure one or more virtual addresses for the - VRRP group"; - } - - leaf priority { - type uint8 { - range 1..254; - } - default 100; - description - "Specifies the sending VRRP interface's priority - for the virtual router. Higher values equal higher - priority"; - } - - leaf preempt { - type boolean; - default true; - description - "When set to true, enables preemption by a higher - priority backup router of a lower priority master router"; - } - - leaf preempt-delay { - type uint16 { - range 0..3600; - } - default 0; - description - "Set the delay the higher priority router waits - before preempting"; - } - - leaf accept-mode { - type boolean; - // TODO: should we adopt the RFC default given the common - // operational practice of setting to true? - default false; - description - "Configure whether packets destined for - virtual addresses are accepted even when the virtual - address is not owned by the router interface"; - } - - leaf advertisement-interval { - type uint16 { - range 1..4095; - } - // TODO this range is theoretical -- needs to be validated - // against major implementations. - units "centiseconds"; - default 100; - description - "Sets the interval between successive VRRP - advertisements -- RFC 5798 defines this as a 12-bit - value expressed as 0.1 seconds, with default 100, i.e., - 1 second. Several implementation express this in units of - seconds"; - } - } - - grouping ip-vrrp-state { - description - "Operational state data for VRRP on IP interfaces"; - - leaf current-priority { - type uint8; - description "Operational value of the priority for the - interface in the VRRP group"; - } - } - - grouping ip-vrrp-top { - description - "Top-level grouping for Virtual Router Redundancy Protocol"; - - container vrrp { - description - "Enclosing container for VRRP groups handled by this - IP interface"; - - reference "RFC 5798 - Virtual Router Redundancy Protocol - (VRRP) Version 3 for IPv4 and IPv6"; - - list vrrp-group { - key "virtual-router-id"; - description - "List of VRRP groups, keyed by virtual router id"; - - leaf virtual-router-id { - type leafref { - path "../config/virtual-router-id"; - } - description - "References the configured virtual router id for this - VRRP group"; - } - - container config { - description - "Configuration data for the VRRP group"; - - uses ip-vrrp-config; - } - - container state { - - config false; - - description - "Operational state data for the VRRP group"; - - uses ip-vrrp-config; - uses ip-vrrp-state; - } - - uses ip-vrrp-tracking-top; - } - } - } - - grouping ipv6-ra-config { - description - "Configuration parameters for IPv6 router advertisements."; - - leaf interval { - type uint32; - units seconds; - description - "The interval between periodic router advertisement neighbor - discovery messages sent on this interface expressed in - seconds."; - } - - leaf lifetime { - type uint32; - units seconds; - description - "The lifetime advertised in the router advertisement neighbor - discovery message on this interface."; - } - - leaf suppress { - type boolean; - default false; - description - "When set to true, router advertisement neighbor discovery - messages are not transmitted on this interface."; - } - } - - grouping ipv4-proxy-arp-config { - description - "Configuration parameters for IPv4 proxy ARP"; - - leaf mode { - type enumeration { - enum DISABLE { - description - "The system should not respond to ARP requests that - do not specify an IP address configured on the local - subinterface as the target address."; - } - enum REMOTE_ONLY { - description - "The system responds to ARP requests only when the - sender and target IP addresses are in different - subnets."; - } - enum ALL { - description - "The system responds to ARP requests where the sender - and target IP addresses are in different subnets, as well - as those where they are in the same subnet."; - } - } - default "DISABLE"; - description - "When set to a value other than DISABLE, the local system should - respond to ARP requests that are for target addresses other than - those that are configured on the local subinterface using its own - MAC address as the target hardware address. If the REMOTE_ONLY - value is specified, replies are only sent when the target address - falls outside the locally configured subnets on the interface, - whereas with the ALL value, all requests, regardless of their - target address are replied to."; - reference "RFC1027: Using ARP to Implement Transparent Subnet Gateways"; - } - } - - grouping ipv4-top { - description "Top-level configuration and state for IPv4 - interfaces"; - - container ipv4 { - description - "Parameters for the IPv4 address family."; - - container addresses { - description - "Enclosing container for address list"; - - list address { - key "ip"; - description - "The list of configured IPv4 addresses on the interface."; - - leaf ip { - type leafref { - path "../config/ip"; - } - description "References the configured IP address"; - } - - container config { - description "Configuration data for each configured IPv4 - address on the interface"; - - uses ipv4-address-config; - - } - - container state { - - config false; - description "Operational state data for each IPv4 address - configured on the interface"; - - uses ipv4-address-config; - uses ipv4-address-state; - } - - } - } - - container proxy-arp { - description - "Configuration and operational state parameters - relating to proxy ARP. This functionality allows a - system to respond to ARP requests that are not - explicitly destined to the local system."; - - container config { - description - "Configuration parameters for proxy ARP"; - uses ipv4-proxy-arp-config; - } - - container state { - config false; - description - "Operational state parameters for proxy ARP"; - uses ipv4-proxy-arp-config; - } - } - - container neighbors { - description - "Enclosing container for neighbor list"; - - list neighbor { - key "ip"; - description - "A list of mappings from IPv4 addresses to - link-layer addresses. - - Entries in this list are used as static entries in the - ARP Cache."; - reference - "RFC 826: An Ethernet Address Resolution Protocol"; - - leaf ip { - type leafref { - path "../config/ip"; - } - description "References the configured IP address"; - } - - container config { - description "Configuration data for each configured IPv4 - address on the interface"; - - uses ipv4-neighbor-config; - - } - - container state { - - config false; - description "Operational state data for each IPv4 address - configured on the interface"; - - uses ipv4-neighbor-config; - uses ipv4-neighbor-state; - } - } - } - - uses oc-if:sub-unnumbered-top; - - container config { - description - "Top-level IPv4 configuration data for the interface"; - - uses ipv4-global-config; - } - - container state { - - config false; - description - "Top level IPv4 operational state data"; - - uses ipv4-global-config; - uses ip-common-counters-state; - } - } - } - - grouping ipv6-top { - description - "Top-level configuration and state for IPv6 interfaces"; - - container ipv6 { - description - "Parameters for the IPv6 address family."; - - container addresses { - description - "Enclosing container for address list"; - - list address { - key "ip"; - description - "The list of configured IPv6 addresses on the interface."; - - leaf ip { - type leafref { - path "../config/ip"; - } - description "References the configured IP address"; - } - - container config { - description - "Configuration data for each IPv6 address on - the interface"; - - uses ipv6-address-config; - - } - - container state { - - config false; - description - "State data for each IPv6 address on the - interface"; - - uses ipv6-address-config; - uses ipv6-address-state; - } - } - } - - container router-advertisement { - description - "Configuration and operational state parameters relating to - router advertisements."; - - container config { - description - "Configuration parameters relating to router advertisements - for IPv6."; - uses ipv6-ra-config; - } - - container state { - config false; - description - "Operational state parameters relating to router - advertisements for IPv6."; - uses ipv6-ra-config; - } - } - - container neighbors { - description - "Enclosing container for list of IPv6 neighbors"; - - list neighbor { - key "ip"; - description - "List of IPv6 neighbors"; - - leaf ip { - type leafref { - path "../config/ip"; - } - description - "References the configured IP neighbor address"; - } - - container config { - description "Configuration data for each IPv6 address on - the interface"; - - uses ipv6-neighbor-config; - - } - - container state { - - config false; - description "State data for each IPv6 address on the - interface"; - - uses ipv6-neighbor-config; - uses ipv6-neighbor-state; - } - } - } - uses oc-if:sub-unnumbered-top; - - container config { - description "Top-level config data for the IPv6 interface"; - - uses ipv6-global-config; - } - - container state { - config false; - description - "Top-level operational state data for the IPv6 interface"; - - uses ipv6-global-config; - uses ip-common-counters-state; - - } - } - } - - // augment statements - - augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" + - "oc-if:subinterface" { - description - "IPv4 address family configuration for - interfaces"; - - uses ipv4-top; - - } - - augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" + - "oc-if:subinterface" { - description - "IPv6 address family configuration for - interfaces"; - - uses ipv6-top; - - } - - // VRRP for IPv4 interfaces - - augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" + - "oc-if:subinterface/oc-ip:ipv4/oc-ip:addresses/oc-ip:address" { - - description - "Additional IP addr family configuration for - interfaces"; - - uses ip-vrrp-top; - - } - - // VRRP for IPv6 interfaces - - augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" + - "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address" { - description - "Additional IP addr family configuration for - interfaces"; - - uses ip-vrrp-top; - - } - - augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" + - "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/" + - "vrrp/vrrp-group/config" { - description - "Additional VRRP data for IPv6 interfaces"; - - uses ip-vrrp-ipv6-config; - } - - augment "/oc-if:interfaces/oc-if:interface/oc-if:subinterfaces/" + - "oc-if:subinterface/oc-ip:ipv6/oc-ip:addresses/oc-ip:address/vrrp/" + - "vrrp-group/state" { - description - "Additional VRRP data for IPv6 interfaces"; - - uses ip-vrrp-ipv6-state; - } - - // Augments for for routed VLANs - - augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan" { - description - "IPv4 address family configuration for - interfaces"; - - uses ipv4-top; - } - - augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan" { - description - "IPv6 address family configuration for - interfaces"; - - uses ipv6-top; - } - - // VRRP for routed VLAN interfaces - - augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" + - "oc-ip:ipv4/oc-ip:addresses/oc-ip:address" { - description - "Additional IP addr family configuration for - interfaces"; - - uses ip-vrrp-top; - - } - - augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" + - "oc-ip:ipv6/oc-ip:addresses/oc-ip:address" { - description - "Additional IP addr family configuration for - interfaces"; - - uses ip-vrrp-top; - - } - - augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" + - "oc-ip:ipv6/oc-ip:addresses/oc-ip:address/vrrp/vrrp-group/config" { - description - "Additional VRRP data for IPv6 interfaces"; - - uses ip-vrrp-ipv6-config; - } - - - augment "/oc-if:interfaces/oc-if:interface/oc-vlan:routed-vlan/" + - "oc-ip:ipv6/oc-ip:addresses/oc-ip:address/vrrp/vrrp-group/state" { - description - "Additional VRRP data for IPv6 interfaces"; - - uses ip-vrrp-ipv6-state; - } - - // rpc statements - - // notification statements -} diff --git a/src/plugins/yang/openconfig/openconfig-if-types@2018-01-05.yang b/src/plugins/yang/openconfig/openconfig-if-types@2018-01-05.yang deleted file mode 100644 index 3743878..0000000 --- a/src/plugins/yang/openconfig/openconfig-if-types@2018-01-05.yang +++ /dev/null @@ -1,98 +0,0 @@ -module openconfig-if-types { - yang-version "1"; - - namespace "http://openconfig.net/yang/openconfig-if-types"; - - prefix "oc-ift"; - - // import statements - import openconfig-extensions { prefix oc-ext; } - - // meta - organization - "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "This module contains a set of interface type definitions that - are used across OpenConfig models. These are generally physical - or logical interfaces, distinct from hardware ports (which are - described by the OpenConfig platform model)."; - - oc-ext:openconfig-version "0.2.0"; - - revision "2018-01-05" { - description - "Add tunnel types into the INTERFACE_TYPE identity."; - reference "0.2.0"; - } - - revision "2016-11-14" { - description - "Initial version"; - reference "0.1.0"; - } - - - identity INTERFACE_TYPE { - description - "Base identity from which interface types are derived."; - } - - identity IF_ETHERNET { - base INTERFACE_TYPE; - description - "Ethernet interfaces based on IEEE 802.3 standards, as well - as FlexEthernet"; - reference - "IEEE 802.3-2015 - IEEE Standard for Ethernet - OIF Flex Ethernet Implementation Agreement 1.0"; - } - - identity IF_AGGREGATE { - base INTERFACE_TYPE; - description - "An aggregated, or bonded, interface forming a - Link Aggregation Group (LAG), or bundle, most often based on - the IEEE 802.1AX (or 802.3ad) standard."; - reference - "IEEE 802.1AX-2008"; - } - - identity IF_LOOPBACK { - base INTERFACE_TYPE; - description - "A virtual interface designated as a loopback used for - various management and operations tasks."; - } - - identity IF_ROUTED_VLAN { - base INTERFACE_TYPE; - description - "A logical interface used for routing services on a VLAN. - Such interfaces are also known as switch virtual interfaces - (SVI) or integrated routing and bridging interfaces (IRBs)."; - } - - identity IF_SONET { - base INTERFACE_TYPE; - description - "SONET/SDH interface"; - } - - identity IF_TUNNEL_GRE4 { - base INTERFACE_TYPE; - description - "A GRE tunnel over IPv4 transport."; - } - - identity IF_TUNNEL_GRE6 { - base INTERFACE_TYPE; - description - "A GRE tunnel over IPv6 transport."; - } - -} diff --git a/src/plugins/yang/openconfig/openconfig-inet-types@2018-11-21.yang b/src/plugins/yang/openconfig/openconfig-inet-types@2018-11-21.yang deleted file mode 100644 index 7c23d2b..0000000 --- a/src/plugins/yang/openconfig/openconfig-inet-types@2018-11-21.yang +++ /dev/null @@ -1,343 +0,0 @@ -module openconfig-inet-types { - - yang-version "1"; - namespace "http://openconfig.net/yang/types/inet"; - prefix "oc-inet"; - - import openconfig-extensions { prefix "oc-ext"; } - - organization - "OpenConfig working group"; - - contact - "OpenConfig working group - www.openconfig.net"; - - description - "This module contains a set of Internet address related - types for use in OpenConfig modules. - - Portions of this code were derived from IETF RFC 6021. - Please reproduce this note if possible. - - IETF code is subject to the following copyright and license: - Copyright (c) IETF Trust and the persons identified as authors of - the code. - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, is permitted pursuant to, and subject to the license - terms contained in, the Simplified BSD License set forth in - Section 4.c of the IETF Trust's Legal Provisions Relating - to IETF Documents (http://trustee.ietf.org/license-info)."; - - oc-ext:openconfig-version "0.3.2"; - - revision "2018-11-21" { - description - "Add OpenConfig module metadata extensions."; - reference "0.3.2"; - } - - revision 2017-08-24 { - description - "Minor formatting fixes."; - reference "0.3.1"; - } - - revision 2017-07-06 { - description - "Add domain-name and host typedefs"; - reference "0.3.0"; - } - - revision 2017-04-03 { - description - "Add ip-version typedef."; - reference "0.2.0"; - } - - revision 2017-04-03 { - description - "Update copyright notice."; - reference "0.1.1"; - } - - revision 2017-01-26 { - description - "Initial module for inet types"; - reference "0.1.0"; - } - - // OpenConfig specific extensions for module metadata. - oc-ext:regexp-posix; - oc-ext:catalog-organization "openconfig"; - oc-ext:origin "openconfig"; - - // IPv4 and IPv6 types. - - typedef ipv4-address { - type string { - pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + - '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' + - '[0-9]|25[0-5])$'; - } - description - "An IPv4 address in dotted quad notation using the default - zone."; - } - - typedef ipv4-address-zoned { - type string { - pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + - '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' + - '[0-9]|25[0-5])(%[a-zA-Z0-9_]+)$'; - } - description - "An IPv4 address in dotted quad notation. This type allows - specification of a zone index to disambiguate identical - address values. For link-local addresses, the index is - typically the interface index or interface name."; - } - - typedef ipv6-address { - type string { - pattern - // Must support compression through different lengths - // therefore this regexp is complex. - '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + - '([0-9a-fA-F]{1,4}:){1,7}:|' + - '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + - '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + - '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + - '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + - '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + - '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + - ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + - ')$'; - } - description - "An IPv6 address represented as either a full address; shortened - or mixed-shortened formats, using the default zone."; - } - - typedef ipv6-address-zoned { - type string { - pattern - // Must support compression through different lengths - // therefore this regexp is complex. - '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + - '([0-9a-fA-F]{1,4}:){1,7}:|' + - '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + - '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + - '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + - '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + - '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + - '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + - ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + - ')(%[a-zA-Z0-9_]+)$'; - } - description - "An IPv6 address represented as either a full address; shortened - or mixed-shortened formats. This type allows specification of - a zone index to disambiguate identical address values. For - link-local addresses, the index is typically the interface - index or interface name."; - } - - typedef ipv4-prefix { - type string { - pattern '^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|' + - '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4]' + - '[0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))$'; - } - description - "An IPv4 prefix represented in dotted quad notation followed by - a slash and a CIDR mask (0 <= mask <= 32)."; - } - - typedef ipv6-prefix { - type string { - pattern - '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + - '([0-9a-fA-F]{1,4}:){1,7}:|' + - '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}' + - '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + - '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + - '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + - '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + - '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + - ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + - ')/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])$'; - } - description - "An IPv6 prefix represented in full, shortened, or mixed - shortened format followed by a slash and CIDR mask - (0 <= mask <= 128)."; - } - - typedef ip-address { - type union { - type ipv4-address; - type ipv6-address; - } - description - "An IPv4 or IPv6 address with no prefix specified."; - } - - typedef ip-prefix { - type union { - type ipv4-prefix; - type ipv6-prefix; - } - description - "An IPv4 or IPv6 prefix."; - } - - typedef ip-version { - type enumeration { - enum UNKNOWN { - value 0; - description - "An unknown or unspecified version of the Internet - protocol."; - } - enum IPV4 { - value 4; - description - "The IPv4 protocol as defined in RFC 791."; - } - enum IPV6 { - value 6; - description - "The IPv6 protocol as defined in RFC 2460."; - } - } - description - "This value represents the version of the IP protocol. - Note that integer representation of the enumerated values - are not specified, and are not required to follow the - InetVersion textual convention in SMIv2."; - reference - "RFC 791: Internet Protocol - RFC 2460: Internet Protocol, Version 6 (IPv6) Specification - RFC 4001: Textual Conventions for Internet Network Addresses"; - } - - typedef domain-name { - type string { - length "1..253"; - pattern - '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + - '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + - '|\.'; - } - description - "The domain-name type represents a DNS domain name. - Fully quallified left to the models which utilize this type. - - Internet domain names are only loosely specified. Section - 3.5 of RFC 1034 recommends a syntax (modified in Section - 2.1 of RFC 1123). The pattern above is intended to allow - for current practice in domain name use, and some possible - future expansion. It is designed to hold various types of - domain names, including names used for A or AAAA records - (host names) and other records, such as SRV records. Note - that Internet host names have a stricter syntax (described - in RFC 952) than the DNS recommendations in RFCs 1034 and - 1123, and that systems that want to store host names in - schema nodes using the domain-name type are recommended to - adhere to this stricter standard to ensure interoperability. - - The encoding of DNS names in the DNS protocol is limited - to 255 characters. Since the encoding consists of labels - prefixed by a length bytes and there is a trailing NULL - byte, only 253 characters can appear in the textual dotted - notation. - - Domain-name values use the US-ASCII encoding. Their canonical - format uses lowercase US-ASCII characters. Internationalized - domain names MUST be encoded in punycode as described in RFC - 3492"; - } - - typedef host { - type union { - type ip-address; - type domain-name; - } - description - "The host type represents either an unzoned IP address or a DNS - domain name."; - } - - typedef as-number { - type uint32; - description - "A numeric identifier for an autonomous system (AS). An AS is a - single domain, under common administrative control, which forms - a unit of routing policy. Autonomous systems can be assigned a - 2-byte identifier, or a 4-byte identifier which may have public - or private scope. Private ASNs are assigned from dedicated - ranges. Public ASNs are assigned from ranges allocated by IANA - to the regional internet registries (RIRs)."; - reference - "RFC 1930 Guidelines for creation, selection, and registration - of an Autonomous System (AS) - RFC 4271 A Border Gateway Protocol 4 (BGP-4)"; - } - - typedef dscp { - type uint8 { - range "0..63"; - } - description - "A differentiated services code point (DSCP) marking within the - IP header."; - reference - "RFC 2474 Definition of the Differentiated Services Field - (DS Field) in the IPv4 and IPv6 Headers"; - } - - typedef ipv6-flow-label { - type uint32 { - range "0..1048575"; - } - description - "The IPv6 flow-label is a 20-bit value within the IPv6 header - which is optionally used by the source of the IPv6 packet to - label sets of packets for which special handling may be - required."; - reference - "RFC 2460 Internet Protocol, Version 6 (IPv6) Specification"; - } - - typedef port-number { - type uint16; - description - "A 16-bit port number used by a transport protocol such as TCP - or UDP."; - reference - "RFC 768 User Datagram Protocol - RFC 793 Transmission Control Protocol"; - } - - typedef uri { - type string; - description - "An ASCII-encoded Uniform Resource Identifier (URI) as defined - in RFC 3986."; - reference - "RFC 3986 Uniform Resource Identifier (URI): Generic Syntax"; - } - - typedef url { - type string; - description - "An ASCII-encoded Uniform Resource Locator (URL) as defined - in RFC 3986, section 1.1.3"; - reference - "RFC 3986, paragraph 1.1.3"; - } - -} diff --git a/src/plugins/yang/openconfig/openconfig-local-routing@2017-05-15.yang b/src/plugins/yang/openconfig/openconfig-local-routing@2017-05-15.yang deleted file mode 100644 index 5184fe7..0000000 --- a/src/plugins/yang/openconfig/openconfig-local-routing@2017-05-15.yang +++ /dev/null @@ -1,408 +0,0 @@ -module openconfig-local-routing { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/local-routing"; - - prefix "oc-loc-rt"; - - // import some basic types - import openconfig-inet-types { prefix inet; } - import openconfig-policy-types { prefix oc-pt; } - import openconfig-extensions { prefix oc-ext; } - import openconfig-interfaces { prefix oc-if; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - www.openconfig.net"; - - description - "This module describes configuration and operational state data - for routes that are locally generated, i.e., not created by - dynamic routing protocols. These include static routes, locally - created aggregate routes for reducing the number of constituent - routes that must be advertised, summary routes for IGPs, etc. - - This model expresses locally generated routes as generically as - possible, avoiding configuration of protocol-specific attributes - at the time of route creation. This is primarily to avoid - assumptions about how underlying router implementations handle - route attributes in various routing table data structures they - maintain. Hence, the definition of locally generated routes - essentially creates 'bare' routes that do not have any protocol- - specific attributes. - - When protocol-specific attributes must be attached to a route - (e.g., communities on a locally defined route meant to be - advertised via BGP), the attributes should be attached via a - protocol-specific policy after importing the route into the - protocol for distribution (again via routing policy)."; - - oc-ext:openconfig-version "1.0.1"; - - revision "2017-05-15" { - description - "Update to resolve style guide non-compliance."; - reference "1.0.1"; - } - - revision "2016-05-11" { - description - "OpenConfig public release"; - reference "1.0.0"; - } - - - // identity statements - - identity LOCAL_DEFINED_NEXT_HOP { - description - "A base identity type of local defined next-hops"; - } - - identity DROP { - base LOCAL_DEFINED_NEXT_HOP; - description - "Discard traffic for the corresponding destination"; - } - - identity LOCAL_LINK { - base LOCAL_DEFINED_NEXT_HOP; - description - "Treat traffic towards addresses within the specified - next-hop prefix as though they are connected to a local - link. When the LOCAL_LINK next-hop type is specified, - an interface must also be specified such that - the local system can determine which link to trigger - link-layer address discovery against"; - } - - // typedef statements - - typedef local-defined-next-hop { - type identityref { - base LOCAL_DEFINED_NEXT_HOP; - } - description - "Pre-defined next-hop designation for locally generated - routes"; - } - - // grouping statements - - grouping local-generic-settings { - description - "Generic options that can be set on local routes When - they are defined"; - - leaf set-tag { - type oc-pt:tag-type; - description - "Set a generic tag value on the route. This tag can be - used for filtering routes that are distributed to other - routing protocols."; - } - } - - grouping local-static-config { - description - "Configuration data for static routes."; - - leaf prefix { - type inet:ip-prefix; - description - "Destination prefix for the static route, either IPv4 or - IPv6."; - } - - uses local-generic-settings; - } - - grouping local-static-state { - description - "Operational state data for static routes"; - } - - - grouping local-static-nexthop-config { - description - "Configuration parameters related to each next-hop entry - specified for a static route"; - - leaf index { - type string; - description - "An user-specified identifier utilised to uniquely reference - the next-hop entry in the next-hop list. The value of this - index has no semantic meaning other than for referencing - the entry."; - } - - leaf next-hop { - type union { - type inet:ip-address; - type local-defined-next-hop; - } - description - "The next-hop that is to be used for the static route - - this may be specified as an IP address, an interface - or a pre-defined next-hop type - for instance, DROP or - LOCAL_LINK. When this leaf is not set, and the interface-ref - value is specified for the next-hop, then the system should - treat the prefix as though it is directly connected to the - interface."; - } - - leaf metric { - type uint32; - description - "A metric which is utilised to specify the preference of - the next-hop entry when it is injected into the RIB. The - lower the metric, the more preferable the prefix is. When - this value is not specified the metric is inherited from - the default metric utilised for static routes within the - network instance that the static routes are being - instantiated. When multiple next-hops are specified for a - static route, the metric is utilised to determine which of - the next-hops is to be installed in the RIB. When multiple - next-hops have the same metric (be it specified, or simply - the default) then these next-hops should all be installed - in the RIB"; - } - - leaf recurse { - type boolean; - default false; - description - "Determines whether the next-hop should be allowed to - be looked up recursively - i.e., via a RIB entry which has - been installed by a routing protocol, or another static route - - rather than needing to be connected directly to an - interface of the local system within the current network - instance. When the interface reference specified within the - next-hop entry is set (i.e., is not null) then forwarding is - restricted to being via the interface specified - and - recursion is hence disabled."; - } - } - - grouping local-static-nexthop-state { - description - "Operational state parameters relating to a next-hop entry - for a static route"; - } - - - grouping local-static-top { - description - "Top-level grouping for the list of static route definitions"; - - container static-routes { - description - "Enclosing container for the list of static routes"; - - list static { - key "prefix"; - description - "List of locally configured static routes"; - - leaf prefix { - type leafref { - path "../config/prefix"; - } - description - "Reference to the destination prefix list key."; - } - - container config { - description - "Configuration data for static routes"; - - uses local-static-config; - } - - container state { - - config false; - - description - "Operational state data for static routes"; - - uses local-static-config; - uses local-static-state; - } - - container next-hops { - description - "Configuration and state parameters relating to the - next-hops that are to be utilised for the static - route being specified"; - - list next-hop { - key "index"; - - description - "A list of next-hops to be utilised for the static - route being specified."; - - leaf index { - type leafref { - path "../config/index"; - } - description - "A reference to the index of the current next-hop. - The index is intended to be a user-specified value - which can be used to reference the next-hop in - question, without any other semantics being - assigned to it."; - } - - container config { - description - "Configuration parameters relating to the next-hop - entry"; - - uses local-static-nexthop-config; - } - - container state { - config false; - description - "Operational state parameters relating to the - next-hop entry"; - - uses local-static-nexthop-config; - uses local-static-nexthop-state; - } - - uses oc-if:interface-ref; - } - } - } - } - } - - grouping local-aggregate-config { - description - "Configuration data for aggregate routes"; - - leaf prefix { - type inet:ip-prefix; - description - "Aggregate prefix to be advertised"; - } - - leaf discard { - type boolean; - default false; - description - "When true, install the aggregate route with a discard - next-hop -- traffic destined to the aggregate will be - discarded with no ICMP message generated. When false, - traffic destined to an aggregate address when no - constituent routes are present will generate an ICMP - unreachable message."; - } - - uses local-generic-settings; - - } - - grouping local-aggregate-state { - description - "Operational state data for local aggregate advertisement - definitions"; - } - - grouping local-aggregate-top { - description - "Top-level grouping for local aggregates"; - - container local-aggregates { - description - "Enclosing container for locally-defined aggregate - routes"; - - list aggregate { - key "prefix"; - description - "List of aggregates"; - - leaf prefix { - type leafref { - path "../config/prefix"; - } - description - "Reference to the configured prefix for this aggregate"; - } - - container config { - description - "Configuration data for aggregate advertisements"; - - uses local-aggregate-config; - } - - container state { - - config false; - - description - "Operational state data for aggregate - advertisements"; - - uses local-aggregate-config; - uses local-aggregate-state; - } - } - } - } - - grouping local-routes-config { - description - "Configuration data for locally defined routes"; - } - - grouping local-routes-state { - description - "Operational state data for locally defined routes"; - } - - grouping local-routes-top { - description - "Top-level grouping for local routes"; - - container local-routes { - description - "Top-level container for local routes"; - - container config { - description - "Configuration data for locally defined routes"; - - uses local-routes-config; - } - - container state { - - config false; - - description - "Operational state data for locally defined routes"; - - uses local-routes-config; - uses local-routes-state; - } - - uses local-static-top; - uses local-aggregate-top; - } - } - - uses local-routes-top; - -} diff --git a/src/plugins/yang/openconfig/openconfig-packet-match-types@2018-11-21.yang b/src/plugins/yang/openconfig/openconfig-packet-match-types@2018-11-21.yang deleted file mode 100644 index 1b93d52..0000000 --- a/src/plugins/yang/openconfig/openconfig-packet-match-types@2018-11-21.yang +++ /dev/null @@ -1,309 +0,0 @@ -module openconfig-packet-match-types { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/packet-match-types"; - - prefix "oc-pkt-match-types"; - - // import some basic types - import openconfig-inet-types { prefix oc-inet; } - import openconfig-extensions { prefix oc-ext; } - - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - www.openconfig.net"; - - description - "This module defines common types for use in models requiring - data definitions related to packet matches."; - - oc-ext:openconfig-version "1.0.2"; - - revision "2018-11-21" { - description - "Add OpenConfig module metadata extensions."; - reference "1.0.2"; - } - - revision "2018-04-15" { - description - "Corrected description and range for ethertype typedef"; - reference "1.0.1"; - } - - revision "2017-05-26" { - description - "Separated IP matches into AFs"; - reference "1.0.0"; - } - - revision "2016-08-08" { - description - "OpenConfig public release"; - reference "0.2.0"; - } - - revision "2016-04-27" { - description - "Initial revision"; - reference "TBD"; - } - - // OpenConfig specific extensions for module metadata. - oc-ext:regexp-posix; - oc-ext:catalog-organization "openconfig"; - oc-ext:origin "openconfig"; - - - // extension statements - - // feature statements - - // identity statements - - - //TODO: should replace this with an official IEEE module - // when available. Only a select number of types are - // defined in this identity. - identity ETHERTYPE { - description - "Base identity for commonly used Ethertype values used - in packet header matches on Ethernet frames. The Ethertype - indicates which protocol is encapsulated in the Ethernet - payload."; - reference - "IEEE 802.3"; - } - - identity ETHERTYPE_IPV4 { - base ETHERTYPE; - description - "IPv4 protocol (0x0800)"; - } - - identity ETHERTYPE_ARP { - base ETHERTYPE; - description - "Address resolution protocol (0x0806)"; - } - - identity ETHERTYPE_VLAN { - base ETHERTYPE; - description - "VLAN-tagged frame (as defined by IEEE 802.1q) (0x8100). Note - that this value is also used to represent Shortest Path - Bridging (IEEE 801.1aq) frames."; - } - - identity ETHERTYPE_IPV6 { - base ETHERTYPE; - description - "IPv6 protocol (0x86DD)"; - } - - identity ETHERTYPE_MPLS { - base ETHERTYPE; - description - "MPLS unicast (0x8847)"; - } - - identity ETHERTYPE_LLDP { - base ETHERTYPE; - description - "Link Layer Discovery Protocol (0x88CC)"; - } - - identity ETHERTYPE_ROCE { - base ETHERTYPE; - description - "RDMA over Converged Ethernet (0x8915)"; - } - - - //TODO: should replace this with an official IANA module when - //available. Only a select set of protocols are defined with - //this identity. - identity IP_PROTOCOL { - description - "Base identity for commonly used IP protocols used in - packet header matches"; - reference - "IANA Assigned Internet Protocol Numbers"; - } - - identity IP_TCP { - base IP_PROTOCOL; - description - "Transmission Control Protocol (6)"; - } - - identity IP_UDP { - base IP_PROTOCOL; - description - "User Datagram Protocol (17)"; - } - - identity IP_ICMP { - base IP_PROTOCOL; - description - "Internet Control Message Protocol (1)"; - } - - identity IP_IGMP { - base IP_PROTOCOL; - description - "Internet Group Membership Protocol (2)"; - } - - identity IP_PIM { - base IP_PROTOCOL; - description - "Protocol Independent Multicast (103)"; - } - - identity IP_RSVP { - base IP_PROTOCOL; - description - "Resource Reservation Protocol (46)"; - } - - identity IP_GRE { - base IP_PROTOCOL; - description - "Generic Routing Encapsulation (47)"; - } - - identity IP_AUTH { - base IP_PROTOCOL; - description - "Authentication header, e.g., for IPSEC (51)"; - } - - identity IP_L2TP { - base IP_PROTOCOL; - description - "Layer Two Tunneling Protocol v.3 (115)"; - } - - - - identity TCP_FLAGS { - description - "Common TCP flags used in packet header matches"; - reference - "IETF RFC 793 - Transmission Control Protocol - IETF RFC 3168 - The Addition of Explicit Congestion - Notification (ECN) to IP"; - } - - identity TCP_SYN { - base TCP_FLAGS; - description - "TCP SYN flag"; - } - - identity TCP_FIN { - base TCP_FLAGS; - description - "TCP FIN flag"; - } - - identity TCP_RST { - base TCP_FLAGS; - description - "TCP RST flag"; - } - - identity TCP_PSH { - base TCP_FLAGS; - description - "TCP push flag"; - } - - identity TCP_ACK { - base TCP_FLAGS; - description - "TCP ACK flag"; - } - - identity TCP_URG { - base TCP_FLAGS; - description - "TCP urgent flag"; - } - - identity TCP_ECE { - base TCP_FLAGS; - description - "TCP ECN-Echo flag. If the SYN flag is set, indicates that - the TCP peer is ECN-capable, otherwise indicates that a - packet with Congestion Experienced flag in the IP header - is set"; - } - - identity TCP_CWR { - base TCP_FLAGS; - description - "TCP Congestion Window Reduced flag"; - } - - // typedef statements - - typedef port-num-range { - type union { - type string { - pattern '^(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?[0-9]?' + - '[0-9]?)\.\.(6[0-5][0-5][0-3][0-5]|[0-5]?[0-9]?[0-9]?' + - '[0-9]?[0-9]?)$'; - } - type oc-inet:port-number; - type enumeration { - enum ANY { - description - "Indicates any valid port number (e.g., wildcard)"; - } - } - } - description - "Port numbers may be represented as a single value, - an inclusive range as .., or as ANY to - indicate a wildcard."; - } - - typedef ip-protocol-type { - type union { - type uint8 { - range 0..254; - } - type identityref { - base IP_PROTOCOL; - } - } - description - "The IP protocol number may be expressed as a valid protocol - number (integer) or using a protocol type defined by the - IP_PROTOCOL identity"; - } - - typedef ethertype-type { - type union { - type uint16 { - range 1536..65535; - } - type identityref { - base ETHERTYPE; - } - } - description - "The Ethertype value may be expressed as a 16-bit number in - decimal notation, or using a type defined by the - ETHERTYPE identity"; - } - -} diff --git a/src/plugins/yang/openconfig/openconfig-packet-match@2018-11-21.yang b/src/plugins/yang/openconfig/openconfig-packet-match@2018-11-21.yang deleted file mode 100644 index 510bc57..0000000 --- a/src/plugins/yang/openconfig/openconfig-packet-match@2018-11-21.yang +++ /dev/null @@ -1,371 +0,0 @@ -module openconfig-packet-match { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/header-fields"; - - prefix "oc-pkt-match"; - - // import some basic types - import openconfig-inet-types { prefix oc-inet; } - import openconfig-yang-types { prefix oc-yang; } - import openconfig-packet-match-types { prefix oc-pkt-match-types; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - www.openconfig.net"; - - description - "This module defines data related to packet header fields - used in matching operations, for example in ACLs. When a - field is omitted from a match expression, the effect is a - wildcard ('any') for that field."; - - oc-ext:openconfig-version "1.1.1"; - - revision "2018-11-21" { - description - "Add OpenConfig module metadata extensions."; - reference "1.1.1"; - } - - revision "2017-12-15" { - description - "Add MPLS packet field matches"; - reference "1.1.0"; - } - - revision "2017-05-26" { - description - "Separated IP matches into AFs"; - reference "1.0.0"; - } - - revision "2016-08-08" { - description - "OpenConfig public release"; - reference "0.2.0"; - } - - revision "2016-04-27" { - description - "Initial revision"; - reference "TBD"; - } - - // OpenConfig specific extensions for module metadata. - oc-ext:regexp-posix; - oc-ext:catalog-organization "openconfig"; - oc-ext:origin "openconfig"; - - - // Physical Layer fields - // ethernet-header - grouping ethernet-header-config { - description - "Configuration data of fields in Ethernet header."; - - leaf source-mac { - type oc-yang:mac-address; - description - "Source IEEE 802 MAC address."; - } - - leaf source-mac-mask { - type oc-yang:mac-address; - description - "Source IEEE 802 MAC address mask."; - } - - leaf destination-mac { - type oc-yang:mac-address; - description - "Destination IEEE 802 MAC address."; - } - - leaf destination-mac-mask { - type oc-yang:mac-address; - description - "Destination IEEE 802 MAC address mask."; - } - - leaf ethertype { - type oc-pkt-match-types:ethertype-type; - description - "Ethertype field to match in Ethernet packets"; - } - } - - grouping ethernet-header-state { - description - "State information of fields in Ethernet header."; - } - - grouping ethernet-header-top { - description - "Top level container for fields in Ethernet header."; - - container l2 { - description - "Ethernet header fields"; - - container config { - description - "Configuration data"; - uses ethernet-header-config; - } - - container state { - config false; - description - "State Information."; - uses ethernet-header-config; - uses ethernet-header-state; - } - } - } - - grouping mpls-header-top { - description - "Top-level container for fields in an MPLS header."; - - container mpls { - description - "MPLS header fields"; - - container config { - description - "Configuration parameters relating to fields within - the MPLS header."; - uses mpls-header-config; - } - - container state { - config false; - description - "Operational state parameters relating to fields - within the MPLS header"; - uses mpls-header-config; - } - } - } - - grouping mpls-header-config { - description - "Configuration parameters relating to matches within - MPLS header fields."; - - leaf traffic-class { - type uint8 { - range "0..7"; - } - description - "The value of the MPLS traffic class (TC) bits, - formerly known as the EXP bits."; - } - } - - grouping ip-protocol-fields-common-config { - description - "IP protocol fields common to IPv4 and IPv6"; - - leaf dscp { - type oc-inet:dscp; - description - "Value of diffserv codepoint."; - } - - leaf protocol { - type oc-pkt-match-types:ip-protocol-type; - description - "The protocol carried in the IP packet, expressed either - as its IP protocol number, or by a defined identity."; - } - - leaf hop-limit { - type uint8 { - range 0..255; - } - description - "The IP packet's hop limit -- known as TTL (in hops) in - IPv4 packets, and hop limit in IPv6"; - } - } - - // IP Layer - // ip-protocol-fields - grouping ipv4-protocol-fields-config { - description - "Configuration data of IP protocol fields - for IPv4"; - - leaf source-address { - type oc-inet:ipv4-prefix; - description - "Source IPv4 address prefix."; - } - - leaf destination-address { - type oc-inet:ipv4-prefix; - description - "Destination IPv4 address prefix."; - } - - uses ip-protocol-fields-common-config; - - } - - grouping ipv4-protocol-fields-state { - description - "State information of IP header fields for IPv4"; - } - - grouping ipv4-protocol-fields-top { - description - "IP header fields for IPv4"; - - container ipv4 { - description - "Top level container for IPv4 match field data"; - - container config { - description - "Configuration data for IPv4 match fields"; - uses ipv4-protocol-fields-config; - } - - container state { - config false; - description - "State information for IPv4 match fields"; - uses ipv4-protocol-fields-config; - uses ipv4-protocol-fields-state; - } - } - } - - grouping ipv6-protocol-fields-config { - description - "Configuration data for IPv6 match fields"; - - leaf source-address { - type oc-inet:ipv6-prefix; - description - "Source IPv6 address prefix."; - } - - leaf source-flow-label { - type oc-inet:ipv6-flow-label; - description - "Source IPv6 Flow label."; - } - - leaf destination-address { - type oc-inet:ipv6-prefix; - description - "Destination IPv6 address prefix."; - } - - leaf destination-flow-label { - type oc-inet:ipv6-flow-label; - description - "Destination IPv6 Flow label."; - } - - uses ip-protocol-fields-common-config; - } - - grouping ipv6-protocol-fields-state { - description - "Operational state data for IPv6 match fields"; - } - - grouping ipv6-protocol-fields-top { - description - "Top-level grouping for IPv6 match fields"; - - container ipv6 { - description - "Top-level container for IPv6 match field data"; - - container config { - description - "Configuration data for IPv6 match fields"; - - uses ipv6-protocol-fields-config; - } - - container state { - - config false; - - description - "Operational state data for IPv6 match fields"; - - uses ipv6-protocol-fields-config; - uses ipv6-protocol-fields-state; - } - } - } - - // Transport fields - grouping transport-fields-config { - description - "Configuration data of transport-layer packet fields"; - - leaf source-port { - type oc-pkt-match-types:port-num-range; - description - "Source port or range"; - } - - leaf destination-port { - type oc-pkt-match-types:port-num-range; - description - "Destination port or range"; - } - - leaf-list tcp-flags { - type identityref { - base oc-pkt-match-types:TCP_FLAGS; - } - description - "List of TCP flags to match"; - } - } - - grouping transport-fields-state { - description - "State data of transport-fields"; - } - - grouping transport-fields-top { - description - "Destination transport-fields top level grouping"; - - container transport { - description - "Transport fields container"; - - container config { - description - "Configuration data"; - uses transport-fields-config; - } - - container state { - config false; - description - "State data"; - uses transport-fields-config; - uses transport-fields-state; - } - } - } - -} diff --git a/src/plugins/yang/openconfig/openconfig-policy-types@2018-06-05.yang b/src/plugins/yang/openconfig/openconfig-policy-types@2018-06-05.yang deleted file mode 100644 index ef47f33..0000000 --- a/src/plugins/yang/openconfig/openconfig-policy-types@2018-06-05.yang +++ /dev/null @@ -1,220 +0,0 @@ -module openconfig-policy-types { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/policy-types"; - - prefix "oc-pol-types"; - - // import some basic types - import ietf-yang-types { prefix yang; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization - "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "This module contains general data definitions for use in routing - policy. It can be imported by modules that contain protocol- - specific policy conditions and actions."; - - oc-ext:openconfig-version "3.1.0"; - - revision "2018-06-05" { - description - "Add PIM, IGMP to INSTALL_PROTOCOL_TYPES identity"; - reference "3.1.0"; - } - - revision "2017-07-14" { - description - "Replace policy choice node/type with policy-result - enumeration;simplified defined set naming;removed generic - IGP actions; migrate to OpenConfig types; added mode for - prefix sets"; - reference "3.0.0"; - } - - revision "2016-05-12" { - description - "OpenConfig public release"; - reference "2.0.1"; - } - - // identity statements - - identity ATTRIBUTE_COMPARISON { - description - "base type for supported comparison operators on route - attributes"; - } - - identity ATTRIBUTE_EQ { - base ATTRIBUTE_COMPARISON; - description "== comparison"; - } - - identity ATTRIBUTE_GE { - base ATTRIBUTE_COMPARISON; - description ">= comparison"; - } - - identity ATTRIBUTE_LE { - base ATTRIBUTE_COMPARISON; - description "<= comparison"; - } - - typedef match-set-options-type { - type enumeration { - enum ANY { - description "match is true if given value matches any member - of the defined set"; - } - enum ALL { - description "match is true if given value matches all - members of the defined set"; - } - enum INVERT { - description "match is true if given value does not match any - member of the defined set"; - } - } - default ANY; - description - "Options that govern the behavior of a match statement. The - default behavior is ANY, i.e., the given value matches any - of the members of the defined set"; - } - - typedef match-set-options-restricted-type { - type enumeration { - enum ANY { - description "match is true if given value matches any member - of the defined set"; - } - enum INVERT { - description "match is true if given value does not match any - member of the defined set"; - } - } - default ANY; - description - "Options that govern the behavior of a match statement. The - default behavior is ANY, i.e., the given value matches any - of the members of the defined set. Note this type is a - restricted version of the match-set-options-type."; - //TODO: restriction on enumerated types is only allowed in - //YANG 1.1. Until then, we will require this additional type - } - - grouping attribute-compare-operators { - description "common definitions for comparison operations in - condition statements"; - - leaf operator { - type identityref { - base ATTRIBUTE_COMPARISON; - } - description - "type of comparison to be performed"; - } - - leaf value { - type uint32; - description - "value to compare with the community count"; - } - } - - typedef tag-type { - type union { - type uint32; - type yang:hex-string; - } - description "type for expressing route tags on a local system, - including IS-IS and OSPF; may be expressed as either decimal or - hexidecimal integer"; - reference - "RFC 2178 OSPF Version 2 - RFC 5130 A Policy Control Mechanism in IS-IS Using - Administrative Tags"; - } - - identity INSTALL_PROTOCOL_TYPE { - description - "Base type for routing protocols, including those which may - install prefixes into the RIB"; - } - - identity BGP { - base INSTALL_PROTOCOL_TYPE; - description - "BGP"; - reference - "RFC 4271"; - } - - identity ISIS { - base INSTALL_PROTOCOL_TYPE; - description - "IS-IS"; - reference - "ISO/IEC 10589"; - } - - identity OSPF { - base INSTALL_PROTOCOL_TYPE; - description - "OSPFv2"; - reference - "RFC 2328"; - } - - identity OSPF3 { - base INSTALL_PROTOCOL_TYPE; - description - "OSPFv3"; - reference - "RFC 5340"; - } - - identity STATIC { - base INSTALL_PROTOCOL_TYPE; - description - "Locally-installed static route"; - } - - identity DIRECTLY_CONNECTED { - base INSTALL_PROTOCOL_TYPE; - description - "A directly connected route"; - } - - identity LOCAL_AGGREGATE { - base INSTALL_PROTOCOL_TYPE; - description - "Locally defined aggregate route"; - } - - identity PIM { - base INSTALL_PROTOCOL_TYPE; - description - "Protocol Independent Multicast"; - reference - "RFC 7761"; - } - - identity IGMP { - base INSTALL_PROTOCOL_TYPE; - description - "Internet Group Management Protocol"; - reference - "RFC 3376"; - } -} diff --git a/src/plugins/yang/openconfig/openconfig-vlan-types@2018-02-14.yang b/src/plugins/yang/openconfig/openconfig-vlan-types@2018-02-14.yang deleted file mode 100644 index 6d9ab55..0000000 --- a/src/plugins/yang/openconfig/openconfig-vlan-types@2018-02-14.yang +++ /dev/null @@ -1,195 +0,0 @@ -module openconfig-vlan-types { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/vlan-types"; - - prefix "oc-vlan-types"; - - // import some basic types - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "This module defines configuration and state variables for VLANs, - in addition to VLAN parameters associated with interfaces"; - - oc-ext:openconfig-version "3.0.0"; - - revision "2018-02-14" { - description - "Fix bug with name of 802.1ad identity."; - reference "3.0.0"; - } - - revision "2017-07-14" { - description - "Move top-level vlan data to network-instance; Update - identities to comply to style guide; fixed pattern - quoting; corrected trunk vlan types; added TPID config to - base interface."; - reference "2.0.0"; - } - - revision "2016-05-26" { - description - "OpenConfig public release"; - reference "1.0.2"; - } - - // extension statements - - // feature statements - - // identity statements - - identity TPID_TYPES { - description - "Base identity for TPID values that can override the VLAN - ethertype value"; - } - - identity TPID_0X8100 { - base TPID_TYPES; - description - "Default TPID value for 802.1q single-tagged VLANs."; - } - - identity TPID_0X88A8 { - base TPID_TYPES; - description - "TPID value for 802.1ad provider bridging, QinQ or - stacked VLANs."; - } - - identity TPID_0X9100 { - base TPID_TYPES; - description - "Alternate TPID value"; - } - - identity TPID_0X9200 { - base TPID_TYPES; - description - "Alternate TPID value"; - } - - // typedef statements - - // TODO: typedefs should be defined in a vlan-types.yang file. - typedef vlan-id { - type uint16 { - range 1..4094; - } - description - "Type definition representing a single-tagged VLAN"; - } - - typedef vlan-range { - type string { - // range specified as [lower]..[upper] - pattern '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])\.\.(409[0-4]|' + - '40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{1,2}|' + - '[1-9])$'; - } - description - "Type definition representing a range of single-tagged - VLANs. A range is specified as x..y where x and y are - valid VLAN IDs (1 <= vlan-id <= 4094). The range is - assumed to be inclusive, such that any VLAN-ID matching - x <= VLAN-ID <= y falls within the range."; - } - - typedef qinq-id { - type string { - pattern - '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])\.' + - '((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])|\*)$'; - } - description - "Type definition representing a single double-tagged/QinQ VLAN - identifier. The format of a QinQ VLAN-ID is x.y where X is the - 'outer' VLAN identifier, and y is the 'inner' VLAN identifier. - Both x and y must be valid VLAN IDs (1 <= vlan-id <= 4094) - with the exception that y may be equal to a wildcard (*). In - cases where y is set to the wildcard, this represents all inner - VLAN identifiers where the outer VLAN identifier is equal to - x"; - } - - typedef qinq-id-range { - type union { - type string { - // match cases where the range is specified as x..y.z - pattern - '^(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])\.\.' + - '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])\.' + - '((409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])|\*)$'; - } - type string { - // match cases where the range is specified as x.y..z - pattern - '^(\*|(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9]))\.' + - '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])\.\.' + - '(409[0-4]|40[0-8][0-9]|[1-3][0-9]{3}|' + - '[1-9][0-9]{1,2}|[1-9])$'; - } - } - description - "A type definition representing a range of double-tagged/QinQ - VLAN identifiers. The format of a QinQ VLAN-ID range can be - specified in three formats. Where the range is outer VLAN IDs - the range is specified as x..y.z. In this case outer VLAN - identifiers meeting the criteria x <= outer-vlan-id <= y are - accepted iff the inner VLAN-ID is equal to y - or any inner-tag - if the wildcard is specified. Alternatively the range can be - specified as x.y..z. In this case only VLANs with an - outer-vlan-id qual to x are accepted (x may again be the - wildcard). Inner VLANs are accepted if they meet the inequality - y <= inner-vlan-id <= z."; - } - - typedef vlan-mode-type { - type enumeration { - enum ACCESS { - description "Access mode VLAN interface (No 802.1q header)"; - } - enum TRUNK { - description "Trunk mode VLAN interface"; - } - } - description - "VLAN interface mode (trunk or access)"; - } - - typedef vlan-ref { - type union { - type vlan-id; - type string; - // TODO: string should be changed to leafref to reference - // an existing VLAN. this is not allowed in YANG 1.0 but - // is expected to be in YANG 1.1. - // type leafref { - // path "vlan:vlans/vlan:vlan/vlan:config/vlan:name"; - // } - } - description - "Reference to a VLAN by name or id"; - } - -} diff --git a/src/plugins/yang/openconfig/openconfig-vlan@2018-06-05.yang b/src/plugins/yang/openconfig/openconfig-vlan@2018-06-05.yang deleted file mode 100644 index 97348c0..0000000 --- a/src/plugins/yang/openconfig/openconfig-vlan@2018-06-05.yang +++ /dev/null @@ -1,438 +0,0 @@ -module openconfig-vlan { - - yang-version "1"; - - // namespace - namespace "http://openconfig.net/yang/vlan"; - - prefix "oc-vlan"; - - // import some basic types - import openconfig-vlan-types { prefix oc-vlan-types; } - import openconfig-interfaces { prefix oc-if; } - import openconfig-if-ethernet { prefix oc-eth; } - import openconfig-if-aggregate { prefix oc-lag; } - import iana-if-type { prefix ift; } - import openconfig-extensions { prefix oc-ext; } - - // meta - organization "OpenConfig working group"; - - contact - "OpenConfig working group - netopenconfig@googlegroups.com"; - - description - "This module defines configuration and state variables for VLANs, - in addition to VLAN parameters associated with interfaces"; - - oc-ext:openconfig-version "3.0.1"; - - revision "2018-06-05" { - description - "Fix bugs in when statements."; - reference "3.0.1"; - } - - revision "2018-02-14" { - description - "Fix bug with name of 802.1ad identity."; - reference "3.0.0"; - } - - revision "2017-07-14" { - description - "Move top-level vlan data to network-instance; Update - identities to comply to style guide; fixed pattern - quoting; corrected trunk vlan types; added TPID config to - base interface."; - reference "2.0.0"; - } - - revision "2016-05-26" { - description - "OpenConfig public release"; - reference "1.0.2"; - } - - // grouping statements - - grouping vlan-config { - description "VLAN configuration container."; - - leaf vlan-id { - type oc-vlan-types:vlan-id; - description "Interface VLAN id."; - } - - leaf name { - type string; - description "Interface VLAN name."; - } - - leaf status { - type enumeration { - enum ACTIVE { - description "VLAN is active"; - } - enum SUSPENDED { - description "VLAN is inactive / suspended"; - } - } - default ACTIVE; - description "Admin state of the VLAN"; - } - - } - - grouping vlan-state { - description "State variables for VLANs"; - - // placeholder - - } - - grouping vlan-tpid-config { - description - "TPID configuration for dot1q-enabled interfaces"; - - leaf tpid { - type identityref { - base oc-vlan-types:TPID_TYPES; - } - default oc-vlan-types:TPID_0X8100; - description - "Optionally set the tag protocol identifier field (TPID) that - is accepted on the VLAN"; - } - } - - grouping vlan-tpid-state { - description - "TPID opstate for dot1q-enabled interfaces"; - - // placeholder - - } - - grouping vlan-members-state { - description - "List of interfaces / subinterfaces belonging to the VLAN."; - - container members { - description - "Enclosing container for list of member interfaces"; - - list member { - config false; - description - "List of references to interfaces / subinterfaces - associated with the VLAN."; - - uses oc-if:base-interface-ref-state; - } - } - } - - grouping vlan-switched-config { - description - "VLAN related configuration that is part of the physical - Ethernet interface."; - - leaf interface-mode { - type oc-vlan-types:vlan-mode-type; - description - "Set the interface to access or trunk mode for - VLANs"; - } - - leaf native-vlan { - when "../interface-mode = 'TRUNK'" { - description - "Native VLAN is valid for trunk mode interfaces"; - } - type oc-vlan-types:vlan-id; - description - "Set the native VLAN id for untagged frames arriving on - a trunk interface. Tagged frames sent on an interface - configured with a native VLAN should have their tags - stripped prior to transmission. This configuration is only - valid on a trunk interface."; - } - - leaf access-vlan { - when "../interface-mode = 'ACCESS'" { - description - "Access VLAN assigned to the interfaces"; - } - type oc-vlan-types:vlan-id; - description - "Assign the access vlan to the access port."; - } - - leaf-list trunk-vlans { - when "../interface-mode = 'TRUNK'" { - description - "Allowed VLANs may be specified for trunk mode - interfaces."; - } - type union { - type oc-vlan-types:vlan-id; - type oc-vlan-types:vlan-range; - } - description - "Specify VLANs, or ranges thereof, that the interface may - carry when in trunk mode. If not specified, all VLANs are - allowed on the interface. Ranges are specified in the form - x..y, where x - -#include -#include -#include - -typedef enum { - SCVPP_OK = 0, /* Success */ - SCVPP_EINVAL, /* Invalid value encountered */ - SCVPP_EAGAIN, /* Operation would block */ - SCVPP_ENOTSUP, /* Operation not supported */ - SCVPP_ENOMEM, /* Out of memory */ - SCVPP_NOT_FOUND, /* Required element can not be found */ -} scvpp_error_e; - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_VPE_API_JSON; - -#define VPP_IP4_HOST_PREFIX_LEN 32 -#define VPP_INTFC_NAME_LEN 64 /* Interface name max length */ -#define VPP_IP4_ADDRESS_LEN 4 /* IPv4 length in VPP format */ -#define VPP_IP6_ADDRESS_LEN 16 /* IPv6 length in VPP format */ -#define VPP_MAC_ADDRESS_LEN 8 /* MAC length in VPP format */ -/* IPv4 and IPv6 length in string format */ -#define VPP_IP4_ADDRESS_STRING_LEN INET_ADDRSTRLEN //16, include '\0' -#define VPP_IP6_ADDRESS_STRING_LEN INET6_ADDRSTRLEN //46, include '\0' -#define VPP_IP4_PREFIX_STRING_LEN \ - INET_ADDRSTRLEN + sizeof('/') + 2 // include '\0' -#define VPP_IP6_PREFIX_STRING_LEN \ - INET6_ADDRSTRLEN + sizeof('/') + 3 // include '\0' - -/**********************************MACROS**********************************/ -#define ARG_CHECK(retval, arg) \ - do \ - { \ - if (NULL == (arg)) \ - { \ - return (retval); \ - } \ - } \ - while (0) - -#define ARG_CHECK2(retval, arg1, arg2) \ - ARG_CHECK(retval, arg1); \ - ARG_CHECK(retval, arg2) - -#define ARG_CHECK3(retval, arg1, arg2, arg3) \ - ARG_CHECK(retval, arg1); \ - ARG_CHECK(retval, arg2); \ - ARG_CHECK(retval, arg3) - -#define ARG_CHECK4(retval, arg1, arg2, arg3, arg4) \ - ARG_CHECK(retval, arg1); \ - ARG_CHECK(retval, arg2); \ - ARG_CHECK(retval, arg3); \ - ARG_CHECK(retval, arg4) - -/* Suppress compiler warning about unused variable. - * This must be used only for callback function else suppress your unused - * parameter in function prototype. */ -#define UNUSED(x) (void)x - -#define VAPI_REQUEST_CB(api_name) \ -static vapi_error_e \ -api_name##_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, \ - bool is_last, vapi_payload_##api_name##_reply * reply) \ -{ \ - UNUSED(ctx); UNUSED(rv); UNUSED(is_last); \ - if (callback_ctx) { \ - memcpy(callback_ctx, reply, sizeof(vapi_payload_##api_name##_reply)); \ - } \ - return reply->retval; \ -} - -#define VAPI_REQUEST_CB_EXTRA(api_name, member) \ -static vapi_error_e \ -api_name##_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, \ - bool is_last, vapi_payload_##api_name##_reply * reply) \ -{ \ - UNUSED(ctx); UNUSED(rv); UNUSED(is_last); \ - vapi_payload_##api_name##_reply **p = callback_ctx; \ - int size = sizeof(vapi_payload_##api_name##_reply) + reply->member; \ - if (p) { \ - *p = malloc(size); \ - if (!*p) { \ - return VAPI_ENOMEM; \ - } \ - memcpy(*p, reply, size); \ - } \ - return reply->retval; \ -} - -#define VAPI_CALL_MODE(call_code, vapi_mode) \ - do \ - { \ - pthread_mutex_lock (&sc_vpp_main.vapi_lock); \ - if (VAPI_MODE_BLOCKING == (vapi_mode)) \ - { \ - rv = call_code; \ - } \ - else \ - { \ - while (VAPI_EAGAIN == (rv = call_code)); \ - if (rv != VAPI_OK) { /* try once more to get reply */ \ - rv = vapi_dispatch (sc_vpp_main.vapi_ctx); \ - } \ - } \ - pthread_mutex_unlock (&sc_vpp_main.vapi_lock); \ - } \ - while (0) - -#define VAPI_CALL(call_code) VAPI_CALL_MODE(call_code, sc_vpp_main.vapi_mode) - -struct elt { - void *data; //vapi_payload structure - struct elt *next; - int id; //id of the stack element to count total nb of elements -}; - -static inline int push(struct elt **stack, void *data, int length) -{ - struct elt *el; - - //new stack node - el = malloc(sizeof(struct elt)); - if (!el) - return -ENOMEM; - el->data = malloc(length); - if (!el->data) { - free(el); - return -ENOMEM; - } - - - memcpy(el->data, data, length); - if (*stack) - el->id = (*stack)->id + 1; - else - el->id = 0; - el->next = *stack; //point to old value of stack - *stack = el; //el is new stack head - - return 0; -} - -static inline void * pop(struct elt **stack) -{ - struct elt *prev; - void *data; - - if (!(*stack)) - return NULL; - - data = (*stack)->data; //get data at stack head - prev = *stack; //save stack to free memory later - *stack = (*stack)->next; //new stack - - free(prev); - prev = NULL; - - return data; -} - -#define VAPI_DUMP_LIST_CB(api_name) \ -static vapi_error_e \ -api_name##_all_cb(vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, \ - vapi_payload_##api_name##_details *reply) \ -{ \ - UNUSED(ctx); UNUSED(rv); \ - struct elt **stackp; \ - \ - if (is_last) { \ - return VAPI_OK; \ - } \ - \ - ARG_CHECK2(VAPI_EINVAL, caller_ctx, reply); \ - \ - stackp = (struct elt**) caller_ctx; \ - push(stackp, reply, sizeof(*reply)); \ - \ - return VAPI_OK; \ -} - -#define foreach_stack_elt(stack) \ - for(void *data = pop(&stack); data != NULL ; data = pop(&stack)) - - -int sc_aton(const char *cp, u8 * buf, size_t length); -char * sc_ntoa(const u8 * buf); -int sc_pton(int af, const char *cp, u8 * buf); -const char * sc_ntop(int af, const u8 * buf, char *addr); - -/** - * @brief Function converts the u8 array from network byte order to host byte order. - * - * @param[in] host IPv4 address. - * @return host byte order value. - */ -uint32_t hardntohlu32(uint8_t host[4]); - -/* - * VPP - */ - -typedef struct sc_vpp_main_t { - /* VAPI context */ - vapi_ctx_t vapi_ctx; - - /* VAPI calling mode: VAPI_MODE_BLOCKING, VAPI_MODE_NONBLOCKING */ - vapi_mode_e vapi_mode; - - /* Mutex for keeping atomicity when calling VAPI */ - pthread_mutex_t vapi_lock; - - /* pid of VPP */ - pid_t pid; -} sc_vpp_main_t; - -extern sc_vpp_main_t sc_vpp_main; - -sc_vpp_main_t *sc_connect_vpp(); -void sc_disconnect_vpp(); -pid_t sc_get_vpp_pid(); -int sc_end_with(const char* str, const char* end); - -#endif //__SC_VPP_COMMM_H__ diff --git a/src/scvpp/inc/scvpp/interface.h b/src/scvpp/inc/scvpp/interface.h deleted file mode 100644 index 86cd185..0000000 --- a/src/scvpp/inc/scvpp/interface.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 __BAPI_INTERFACE_H__ -#define __BAPI_INTERFACE_H__ - -#include -#include - -typedef vapi_payload_sw_interface_details sw_interface_dump_t; - -/** - * @brief Change an interface state - * @param interface_name - name of target interface - * @param enable - true=state up, false=state down - * @return 0 for success, else negative SCVPP error code - */ -int interface_enable(const char *interface_name, const bool enable); - -/** - * @brief Dump details about all existing interfaces - * @return stack structure containing all interfaces or NULL if empty - */ -extern struct elt * interface_dump_all(); - - -/** - * @brief Dump details about a specific interface - * @param details - where answer will be written - * @param interface_name - name of the interface to dump - * @return 0 for success or negative SCVPP error code - */ -extern int interface_dump_iface(sw_interface_dump_t *details, - const char *interface_name); - -/* - * Library internal helper functions. Symbols should not be exported eventually - */ - -/* - * @brief Get VPP internal index for an interface - * @param interface_name - name of the interface to get id from - * @param sw_if_index - pointer to interface index to be returned - * @return 0 upon success or negative SCVPP error code - */ -extern int get_interface_id(const char *interface_name, uint32_t *sw_if_index); - -/* @brief Get interface name from an interface ID. This is a super expensive - * operation !!! Avoid using it. - * @param interface_name - pointer to string holding returned interface name - * @param sw_if_index - interface index provided - * @return 0 upon success or negative SCVPP error code - */ -extern int get_interface_name(char *interface_name, uint32_t sw_if_index); - -#endif /* __BAPI_INTERFACE_H__ */ diff --git a/src/scvpp/inc/scvpp/ip.h b/src/scvpp/inc/scvpp/ip.h deleted file mode 100644 index f8805b3..0000000 --- a/src/scvpp/inc/scvpp/ip.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 __BAPI_IP_H__ -#define __BAPI_IP_H__ - -#include -#include - -typedef vapi_payload_ip_fib_details fib_dump_t; - -/* - * @brief Dump IPv4/IPv6 address from an interface. - * @param interface_name - name of the interface to get ip from. - * @param ip_addr - where dump will store IP. If IP not found, returns 0.0.0.0 - * @param prefix_len - pointer where dump will store prefix - * @param is_ipv6 - true = IPv6, false = IPv4 - * @return 0 on success, or nergative SCVPP error code - */ -extern int ipv46_address_dump(const char *interface_name, char *ip_addr, - u8 *prefix_len, bool is_ipv6); - -/** - * @brief Add or remove IPv4/IPv6 address to/from an interface. - * @param interface_name - name of interface to configure - * @param addr - address to add - * @param prefix_len - prefix length of interface - * @param is_ipv6 - true if ipv6, false otherwise - * @param add - true to add, false to remove - */ -extern int ipv46_config_add_remove(const char *interface_name, const char *addr, - uint8_t prefix_len, bool is_ipv6, bool add); - -/* - * TODO should add a field is_ipv6 because it only do ipv4 now - * @brief Add or remove an IP route - * @param dst_address - subnet IP you wish to route - * @param dst_address_length - prefix length for subnet you wish to route - * @param next_address - Next hop IP (can use next_hop_interface instead) - * @param is_add - true to add, false to remove - * @param table_id - id of the tab in FIB - * @param next_hop_interface - Next hop interface (can use next_address instead) - */ -extern int -ipv46_config_add_del_route(const char* dst_address, u8 dst_address_length, - const char* next_address, u8 is_add, u32 table_id, - const char *next_hop_interface); - -/** - * @brief Dump all FIB tables entries - * @return stacked answers on success, or NULL on failure - */ -extern struct elt* ipv4_fib_dump_all(); - -/* - * @brief Dump information about a prefix, based on fib_dump_all - * @param prefix_xpath - prefix to look for in FIB - * @param reply - FIB entry dump replied - * @return SCVPP_OK if prefix found or SCVPP_NOT_FOUND - */ -extern int ipv4_fib_dump_prefix(const char *prefix_xpath, fib_dump_t **reply); - -#endif /* __BAPI_IP_H__ */ diff --git a/src/scvpp/inc/scvpp/nat.h b/src/scvpp/inc/scvpp/nat.h deleted file mode 100644 index 40e727e..0000000 --- a/src/scvpp/inc/scvpp/nat.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 __BAPI_NAT_H__ -#define __BAPI_NAT_H__ - -#include - -typedef vapi_payload_nat44_interface_details nat44_interface_details_t; -typedef vapi_payload_nat44_add_del_interface_addr nat44_add_del_interface_addr_t; -typedef vapi_payload_nat44_add_del_address_range nat44_add_del_address_range_t; -typedef vapi_payload_nat44_add_del_static_mapping nat44_add_del_static_mapping_t; -typedef vapi_payload_nat44_static_mapping_details nat44_static_mapping_details_t; -typedef vapi_payload_nat44_forwarding_enable_disable nat44_forwarding_enable_disable_t; -typedef vapi_payload_nat_set_workers nat_set_workers_t; - - -//Wrapper function, if we want hide the VAPI return value -extern int nat44_interface_dump(nat44_interface_details_t *reply); -extern int nat44_add_del_interface_addr( - const nat44_add_del_interface_addr_t *msg); -extern int nat44_add_del_addr_range(const nat44_add_del_address_range_t *range); -extern int nat44_add_del_static_mapping( - const nat44_add_del_static_mapping_t *msg); -extern int nat44_static_mapping_dump(nat44_static_mapping_details_t *reply); -extern int nat44_forwarding_enable_disable( - const nat44_forwarding_enable_disable_t *msg); -extern int nat_set_workers(const nat_set_workers_t *msg); - - -// Alternative, if we don't want hide VAPI return value - -// extern vapi_error_e bin_api_nat44_interface_dump(nat44_interface_details_t *reply); -// extern vapi_error_e bin_api_nat44_add_del_interface_addr( -// const nat44_add_del_interface_addr_t *msg); -// extern vapi_error_e bin_api_nat44_add_del_addr_range( -// const nat44_add_del_address_range_t *range); -// extern vapi_error_e bin_api_nat44_add_del_static_mapping( -// const nat44_add_del_static_mapping_t *msg); -// extern vapi_error_e bin_api_nat44_static_mapping_dump( -// nat44_static_mapping_details_t *reply); -// extern vapi_error_e bin_api_nat44_forwarding_enable_disable( -// const nat44_forwarding_enable_disable_t *msg); -// extern vapi_error_e bin_api_nat_set_workers(const nat_set_workers_t *msg); - - -#endif /* __BAPI_NAT_H__ */ - diff --git a/src/scvpp/inc/scvpp/v3po.h b/src/scvpp/inc/scvpp/v3po.h deleted file mode 100644 index f876ab4..0000000 --- a/src/scvpp/inc/scvpp/v3po.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -#ifndef _V3PO__INTERFACE_H__ -#define _V3PO__INTERFACE_H__ - -#include -#include - -/** - * V3PO defines operations for specific interfaces used by VPP like: - * - tapv2 - */ - -/* tapv2 */ - -typedef vapi_payload_tap_create_v2 tapv2_create_t; -typedef vapi_payload_sw_interface_tap_v2_details tapv2_dump_t; - -/** - * TODO problem: vapi_payload_sw_interface_tap_v2_details reply is NULL - * @brief Dump information about a tap interface - * @param dump - where dump information will be stored - * @return 0 on success, or negative SCVPP error code - */ -extern int dump_tapv2(tapv2_dump_t *dump); - -/** - * @brief Create a tapv2 interface - * @param query - required structure for the creation of a VPP tapv2 interface - * @return 0 on success, or negative SCVPP error code - */ -extern int create_tapv2(tapv2_create_t *query); - -/** - * @brief Delete a tapv2 interface - * @param interface_name - name of the interface to delete - * @return 0 on success, or negative SCVPP error code - */ -extern int delete_tapv2(char *interface_name); - -#endif /* __V3PO_INTERFACE_H__ */ diff --git a/src/scvpp/libscvpp.pc.in b/src/scvpp/libscvpp.pc.in deleted file mode 100644 index f11ed75..0000000 --- a/src/scvpp/libscvpp.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ -libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ - -Name: scvpp -Description: VPP-Sweetcomb-Sysrepo integration library -Version: @PROJECT_VERSION@ -Libs: -L${libdir} -lscvpp -Cflags: -I${includedir} - diff --git a/src/scvpp/src/comm.c b/src/scvpp/src/comm.c deleted file mode 100644 index 11ed8a9..0000000 --- a/src/scvpp/src/comm.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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. - */ -#include - -#include -#include - -#define APP_NAME "sweetcomb_vpp" -#define MAX_OUTSTANDING_REQUESTS 4 -#define RESPONSE_QUEUE_SIZE 2 - -sc_vpp_main_t sc_vpp_main = { - .vapi_ctx = NULL, - .vapi_mode = VAPI_MODE_BLOCKING, - .pid = 0 -}; - -sc_vpp_main_t *sc_connect_vpp() -{ - vapi_error_e rv; - - if (sc_vpp_main.vapi_ctx == NULL) { - if ((rv = vapi_ctx_alloc(&sc_vpp_main.vapi_ctx)) != VAPI_OK) { - return NULL; - } - - if ((rv = - vapi_connect(sc_vpp_main.vapi_ctx, APP_NAME, NULL, - MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, - sc_vpp_main.vapi_mode, true)) != VAPI_OK) { - vapi_ctx_free(sc_vpp_main.vapi_ctx); - sc_vpp_main.vapi_ctx = NULL; - return NULL; - } - } - - sc_vpp_main.pid = sc_get_vpp_pid(); - pthread_mutex_init(&sc_vpp_main.vapi_lock, NULL); - return &sc_vpp_main; -} - -void sc_disconnect_vpp() -{ - if (NULL != sc_vpp_main.vapi_ctx) { - pthread_mutex_destroy(&sc_vpp_main.vapi_lock); - sc_vpp_main.pid = 0; - vapi_disconnect(sc_vpp_main.vapi_ctx); - vapi_ctx_free(sc_vpp_main.vapi_ctx); - sc_vpp_main.vapi_ctx = NULL; - } -} - -/* get vpp pid in system */ -pid_t sc_get_vpp_pid() -{ - DIR *dir; - struct dirent *ptr; - FILE *fp; - char cmdline_path[PATH_MAX]; - char cmdline_data[PATH_MAX]; - const char vpp_path[] = "/usr/bin/vpp"; - - dir = opendir("/proc"); - pid_t pid = 0; - /* read vpp pid file in proc, return pid of vpp */ - if (NULL != dir) { - while (NULL != (ptr = readdir(dir))) { - if ((0 == strcmp(ptr->d_name, ".")) - || (0 == strcmp(ptr->d_name, ".."))) { - continue; - } - - if (DT_DIR != ptr->d_type) { - continue; - } - - sprintf(cmdline_path, "/proc/%s/cmdline", ptr->d_name); - fp = fopen(cmdline_path, "r"); - - if (NULL != fp) { - fread(cmdline_data, 1, sizeof(vpp_path), fp); - cmdline_data[sizeof(vpp_path) - 1] = '\0'; - - if (cmdline_data == - strstr(cmdline_data, "/usr/bin/vpp")) { - pid = atoi(ptr->d_name); - } - - fclose(fp); - } - } - closedir(dir); - } - - return pid; -} - -int sc_end_with(const char* str, const char* end) -{ - if (str != NULL && end != NULL) - { - int l1 = strlen(str); - int l2 = strlen(end); - if (l1 >= l2) - { - if (strcmp(str + l1 - l2, end) == 0) - return 1; - } - } - return 0; -} - -int sc_aton(const char *cp, u8 * buf, size_t length) -{ - ARG_CHECK2(false, cp, buf); - - struct in_addr addr; - int ret = inet_aton(cp, &addr); - - if (0 == ret) - return -EINVAL; - - if (sizeof(addr) > length) - return -EINVAL; - - memcpy(buf, &addr, sizeof (addr)); - - return 0; -} - -char* sc_ntoa(const u8 * buf) -{ - ARG_CHECK(NULL, buf); - - struct in_addr addr; - memcpy(&addr, buf, sizeof(addr)); - return inet_ntoa(addr); -} - -int sc_pton(int af, const char *cp, u8 * buf) -{ - ARG_CHECK2(false, cp, buf); - - int ret = inet_pton(af, cp, buf); - - if (0 == ret) - return -EINVAL; - - return 0; -} - -const char* sc_ntop(int af, const u8 * buf, char *addr) -{ - ARG_CHECK(NULL, buf); - ARG_CHECK(NULL, addr); - - socklen_t size = 0; - if (af == AF_INET) - size = INET_ADDRSTRLEN; - else if (af == AF_INET6) - size = INET6_ADDRSTRLEN; - else - return NULL; - - return inet_ntop(af, (void*)buf, addr, size); -} - -/** - * @brief Function converts the u8 array from network byte order to host byte order. - * - * @param[in] host IPv4 address. - * @return host byte order value. - */ -uint32_t hardntohlu32(uint8_t host[4]) -{ - uint32_t tmp = host[3] | host[2] | host[1] | host[0]; - - return ntohl(tmp); -} diff --git a/src/scvpp/src/interface.c b/src/scvpp/src/interface.c deleted file mode 100644 index b6b1216..0000000 --- a/src/scvpp/src/interface.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include - -#define IFACE_SUBSTR 49 - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON - -static vapi_error_e -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) -{ - UNUSED(rv); UNUSED(ctx); UNUSED(is_last); - - vapi_payload_sw_interface_details *passed; - - if (is_last) { - return VAPI_OK; - } - - ARG_CHECK2(VAPI_EINVAL, callback_ctx, reply); - - //copy - passed = (vapi_payload_sw_interface_details *) callback_ctx; - *passed = *reply; - - return VAPI_OK; -} - -static vapi_error_e -bin_api_sw_interface_dump(vapi_payload_sw_interface_details *details, - const char *iface_name) -{ - vapi_msg_sw_interface_dump *mp; - vapi_error_e rv; - - mp = vapi_alloc_sw_interface_dump(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - /* Dump a specific interfaces */ - mp->payload.name_filter_valid = true; - strncpy((char *)mp->payload.name_filter, iface_name, IFACE_SUBSTR); - - VAPI_CALL(vapi_sw_interface_dump(sc_vpp_main.vapi_ctx, mp, - sw_interface_dump_cb, details)); - if (rv != VAPI_OK) - return -SCVPP_EINVAL; - - return rv; -} - -int get_interface_id(const char *if_name, uint32_t *sw_if_index) -{ - vapi_payload_sw_interface_details details = {0}; - vapi_error_e rv; - - ARG_CHECK2(-SCVPP_EINVAL, if_name, sw_if_index); - - rv = bin_api_sw_interface_dump(&details, if_name); - if (rv != VAPI_OK) - return -SCVPP_EINVAL; - - if (strncmp(if_name, (char*) details.interface_name, VPP_INTFC_NAME_LEN) - != 0) - return -SCVPP_NOT_FOUND; - - *sw_if_index = details.sw_if_index; - - return 0; -} - -/* - * dump only a specific interface - */ -int interface_dump_iface(sw_interface_dump_t *details, const char *iface_name) -{ - vapi_error_e rv; - - rv = bin_api_sw_interface_dump(details, iface_name); - if (rv != VAPI_OK) - return -SCVPP_EINVAL; - - if (strncmp(iface_name, (char*) details->interface_name, VPP_INTFC_NAME_LEN) - != 0) - return -SCVPP_NOT_FOUND; - - return SCVPP_OK; -} - -VAPI_DUMP_LIST_CB(sw_interface) - -struct elt* interface_dump_all() -{ - struct elt* stack = NULL; - vapi_msg_sw_interface_dump *mp; - vapi_error_e rv; - - mp = vapi_alloc_sw_interface_dump(sc_vpp_main.vapi_ctx); - - /* Dump all */ - mp->payload.name_filter_valid = false; - memset(mp->payload.name_filter, 0, sizeof(mp->payload.name_filter)); - - VAPI_CALL(vapi_sw_interface_dump(sc_vpp_main.vapi_ctx, mp, sw_interface_all_cb, - &stack)); - if (VAPI_OK != rv) - return NULL; - - return stack; -} - -VAPI_REQUEST_CB(sw_interface_set_flags); - -int interface_enable(const char *interface_name, const bool enable) -{ - vapi_msg_sw_interface_set_flags *mp; - uint32_t sw_if_index; - vapi_error_e rv; - int rc; - - ARG_CHECK(-SCVPP_EINVAL, interface_name); - - rc = get_interface_id(interface_name, &sw_if_index); - if (rc != 0) - return -SCVPP_NOT_FOUND; - - mp = vapi_alloc_sw_interface_set_flags(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - mp->payload.sw_if_index = sw_if_index; - mp->payload.admin_up_down = enable; - - VAPI_CALL(vapi_sw_interface_set_flags(sc_vpp_main.vapi_ctx, mp, - sw_interface_set_flags_cb, NULL)); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return 0; -} - -int get_interface_name(char *interface_name, uint32_t sw_if_index) -{ - struct elt *stack= NULL; - sw_interface_dump_t *dump; - int rc = -SCVPP_NOT_FOUND; - - stack = interface_dump_all(); - if (!stack) - return -SCVPP_NOT_FOUND; - - foreach_stack_elt(stack) { - dump = (sw_interface_dump_t *) data; - - if (dump->sw_if_index == sw_if_index) { - strncpy(interface_name, (char *)dump->interface_name, VPP_INTFC_NAME_LEN); - rc = SCVPP_OK; - } - - free(dump); - } - - return rc; -} diff --git a/src/scvpp/src/ip.c b/src/scvpp/src/ip.c deleted file mode 100644 index ec44f64..0000000 --- a/src/scvpp/src/ip.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_IP_API_JSON - -VAPI_REQUEST_CB(sw_interface_add_del_address); - -static vapi_error_e -bin_api_sw_interface_add_del_address(u32 sw_if_index, bool is_add, bool is_ipv6, - bool del_all, u8 address_length, - const char *ip_address) -{ - vapi_msg_sw_interface_add_del_address *mp; - vapi_error_e rv; - - ARG_CHECK(VAPI_EINVAL, ip_address); - - mp = vapi_alloc_sw_interface_add_del_address(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - mp->payload.sw_if_index = sw_if_index; - mp->payload.is_add = is_add; - mp->payload.is_ipv6 = is_ipv6; - mp->payload.del_all = del_all; - mp->payload.address_length = address_length; - if (sc_aton(ip_address, mp->payload.address, VPP_IP4_ADDRESS_LEN)) - return VAPI_EINVAL; - - VAPI_CALL(vapi_sw_interface_add_del_address(sc_vpp_main.vapi_ctx, mp, - sw_interface_add_del_address_cb, NULL)); - - return rv; -} - -VAPI_REQUEST_CB(ip_add_del_route) - -static vapi_error_e -bin_api_ip_add_del_route(vapi_payload_ip_add_del_route_reply * reply, - const char* dst_address, uint8_t dst_address_length, - const char* next_hop, uint8_t is_add, - uint32_t table_id, const char *next_interface) -{ - vapi_msg_ip_add_del_route *mp; - uint32_t sw_if_index; - vapi_error_e rv ; - int rc; - - ARG_CHECK2(VAPI_EINVAL, reply, dst_address); - - //Require interface or next hop IP or both - if (!next_interface && !next_hop) - return VAPI_EINVAL; - - mp = vapi_alloc_ip_add_del_route(sc_vpp_main.vapi_ctx, 1); - assert(NULL != mp); - - if (next_interface) { - rc = get_interface_id(next_interface, &sw_if_index); - if (rc < 0) - return VAPI_EINVAL; - } - - mp->payload.is_add = is_add; - mp->payload.table_id = table_id; - mp->payload.is_ipv6 = false; - mp->payload.is_local = false; - sc_aton(dst_address, mp->payload.dst_address, VPP_IP4_ADDRESS_LEN); - mp->payload.dst_address_length = dst_address_length; - if (next_interface) //interface is not mandatory - mp->payload.next_hop_sw_if_index = sw_if_index; - if (next_hop) //next hop ip is not mandatory - sc_aton(next_hop, mp->payload.next_hop_address, VPP_IP4_ADDRESS_LEN); - - VAPI_CALL(vapi_ip_add_del_route(sc_vpp_main.vapi_ctx, mp, - ip_add_del_route_cb, reply)); - - return rv; -} - -static vapi_error_e -ip_address_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, - bool is_last, vapi_payload_ip_address_details *reply) -{ - UNUSED(rv); - vapi_payload_ip_address_details *passed; - - ARG_CHECK3(VAPI_EINVAL, ctx, callback_ctx, reply); - - //copy dump reply in callback context - if (!is_last) { - passed = (vapi_payload_ip_address_details *) callback_ctx; - *passed = *reply; - } - - return VAPI_OK; -} - -static vapi_error_e -bin_api_ip_address_dump(u32 sw_if_index, bool is_ipv6, - vapi_payload_ip_address_details *dctx) -{ - vapi_msg_ip_address_dump *mp; - vapi_error_e rv; - - mp = vapi_alloc_ip_address_dump(sc_vpp_main.vapi_ctx); - assert(mp != NULL); - - mp->payload.sw_if_index = sw_if_index; - mp->payload.is_ipv6 = is_ipv6; - - VAPI_CALL(vapi_ip_address_dump(sc_vpp_main.vapi_ctx, mp, ip_address_dump_cb, - dctx)); - if (rv != VAPI_OK) - return rv; - - return VAPI_OK; -} - -///VAPI_DUMP_LIST_CB(ip_fib); can not be used because of path flexible array - -static vapi_error_e -ip_fib_all_cb(vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, - vapi_payload_ip_fib_details *reply) -{ - UNUSED(ctx); UNUSED(rv); UNUSED(is_last); - struct elt **stackp; - ARG_CHECK2(VAPI_EINVAL, caller_ctx, reply); - - stackp = (struct elt**) caller_ctx; - push(stackp, reply, sizeof(*reply)+reply->count*sizeof(vapi_type_fib_path)); - - return VAPI_OK; -} - -struct elt* ipv4_fib_dump_all() -{ - struct elt *stack = NULL; - vapi_msg_ip_fib_dump *mp; - vapi_error_e rv; - - mp = vapi_alloc_ip_fib_dump(sc_vpp_main.vapi_ctx); - assert(mp != NULL); - - VAPI_CALL(vapi_ip_fib_dump(sc_vpp_main.vapi_ctx, mp, ip_fib_all_cb, &stack)); - if(VAPI_OK != rv) - return NULL; - - return stack; -} - -int ipv4_fib_dump_prefix(const char *prefix_xpath, fib_dump_t **reply) -{ - struct elt *stack = NULL; - char prefix[VPP_IP4_PREFIX_STRING_LEN]; - fib_dump_t *dump; - int rc = -SCVPP_NOT_FOUND; - - stack = ipv4_fib_dump_all(); - if (!stack) - return rc; - - foreach_stack_elt(stack) { - dump = (fib_dump_t *) data; - - if (rc == -SCVPP_NOT_FOUND) { - snprintf(prefix, VPP_IP4_PREFIX_STRING_LEN, "%s/%u", - sc_ntoa(dump->address), dump->address_length); - if (!strncmp(prefix_xpath, prefix, VPP_IP4_PREFIX_STRING_LEN)) { - *reply = dump; - rc = SCVPP_OK; - continue; - } - } - - free(dump); - } - - return rc; -} - -int ipv46_address_dump(const char *interface_name, char *ip_addr, - u8 *prefix_len, bool is_ipv6) -{ - vapi_payload_ip_address_details dctx = {0}; - uint32_t sw_if_index; - vapi_error_e rv; - int rc; - - rc = get_interface_id(interface_name, &sw_if_index); - if (rc < 0) - return rc; - - rv = bin_api_ip_address_dump(sw_if_index, is_ipv6, &dctx); - if (rv != VAPI_OK) - return -SCVPP_EINVAL; - - strcpy(ip_addr, sc_ntoa(dctx.ip)); //IP string - *prefix_len = dctx.prefix_length; //prefix length - - return SCVPP_OK; -} - -int ipv46_config_add_remove(const char *if_name, const char *addr, - uint8_t prefix, bool is_ipv6, bool add) -{ - vapi_error_e rv; - uint32_t sw_if_index; - int rc; - - ARG_CHECK2(-1, if_name, addr); - - rc = get_interface_id(if_name, &sw_if_index); - if (rc < 0) - return rc; - - /* add del addr */ - rv = bin_api_sw_interface_add_del_address(sw_if_index, add, is_ipv6, 0, - prefix, addr); - if (rv != VAPI_OK) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -int ipv46_config_add_del_route(const char* dst_address, u8 dst_address_length, - const char* next_address, u8 is_add, - u32 table_id, const char *interface) -{ - vapi_payload_ip_add_del_route_reply reply = {0}; - vapi_error_e rv; - - rv = bin_api_ip_add_del_route(&reply, dst_address, dst_address_length, - next_address, is_add, table_id, interface); - if (VAPI_OK != rv || reply.retval > 0) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} diff --git a/src/scvpp/src/nat.c b/src/scvpp/src/nat.c deleted file mode 100644 index 4519c3e..0000000 --- a/src/scvpp/src/nat.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include - - -DEFINE_VAPI_MSG_IDS_NAT_API_JSON - -static vapi_error_e -nat44_interface_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_nat44_interface_details *reply) -{ - UNUSED(ctx); UNUSED(rv); - vapi_payload_nat44_interface_details *dctx = callback_ctx; - assert(dctx); - - if (is_last) - { - assert(NULL == reply); - } - else - { - //TODO: Use LOG message for scvpp -// SC_LOG_DBG("NAT Interface dump entry: [%u]: %u\n", reply->sw_if_index, -// reply->is_inside); - *dctx = *reply; - } - - return VAPI_OK; -} - -static vapi_error_e -bin_api_nat44_interface_dump(vapi_payload_nat44_interface_details *reply) -{ - vapi_error_e rv; - vapi_msg_nat44_interface_dump *mp; - - ARG_CHECK(VAPI_EINVAL, reply); - - mp = vapi_alloc_nat44_interface_dump(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - VAPI_CALL(vapi_nat44_interface_dump(sc_vpp_main.vapi_ctx, mp, - nat44_interface_dump_cb, reply)); - - return rv; -} - -VAPI_REQUEST_CB(nat44_add_del_interface_addr); - -static vapi_error_e -bin_api_nat44_add_del_interface_addr( - const vapi_payload_nat44_add_del_interface_addr *msg) -{ - vapi_error_e rv; - vapi_msg_nat44_add_del_interface_addr *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat44_add_del_interface_addr(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat44_add_del_interface_addr(sc_vpp_main.vapi_ctx, mp, - nat44_add_del_interface_addr_cb, - NULL)); - - return rv; -} - -VAPI_REQUEST_CB(nat44_add_del_address_range); - -static vapi_error_e -bin_api_nat44_add_del_addr_range( - const vapi_payload_nat44_add_del_address_range *range) -{ - vapi_error_e rv; - vapi_msg_nat44_add_del_address_range *mp; - - ARG_CHECK(VAPI_EINVAL, range); - - mp = vapi_alloc_nat44_add_del_address_range(sc_vpp_main.vapi_ctx); - - assert(NULL != mp); - - mp->payload = *range; - - VAPI_CALL(vapi_nat44_add_del_address_range(sc_vpp_main.vapi_ctx, mp, - nat44_add_del_address_range_cb, - NULL)); - - return rv; -} - -VAPI_REQUEST_CB(nat44_add_del_static_mapping); - -static vapi_error_e -bin_api_nat44_add_del_static_mapping( - const vapi_payload_nat44_add_del_static_mapping *msg) -{ - vapi_error_e rv; - vapi_msg_nat44_add_del_static_mapping *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat44_add_del_static_mapping(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat44_add_del_static_mapping(sc_vpp_main.vapi_ctx, mp, - nat44_add_del_static_mapping_cb, - NULL)); - - return rv; -} - -static vapi_error_e nat44_static_mapping_dump_cb( - struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, - bool is_last,vapi_payload_nat44_static_mapping_details *reply) -{ - UNUSED(rv); UNUSED(ctx); - vapi_payload_nat44_static_mapping_details *dctx = callback_ctx; - assert(dctx); - - if (is_last) - { - assert(NULL == reply); - } - else - { - *dctx = *reply; - } - - return VAPI_OK; -} - -static vapi_error_e -bin_api_nat44_static_mapping_dump( - vapi_payload_nat44_static_mapping_details *reply) -{ - vapi_error_e rv; - vapi_msg_nat44_static_mapping_dump *msg; - - ARG_CHECK(VAPI_EINVAL, reply); - - msg = vapi_alloc_nat44_static_mapping_dump(sc_vpp_main.vapi_ctx); - assert(NULL != msg); - - VAPI_CALL(vapi_nat44_static_mapping_dump(sc_vpp_main.vapi_ctx, msg, - nat44_static_mapping_dump_cb, - reply)); - - return rv; -} - -VAPI_REQUEST_CB(nat44_forwarding_enable_disable); - -static vapi_error_e bin_api_nat44_forwarding_enable_disable( - const vapi_payload_nat44_forwarding_enable_disable *msg) -{ - vapi_error_e rv; - vapi_msg_nat44_forwarding_enable_disable *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat44_forwarding_enable_disable(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat44_forwarding_enable_disable( - sc_vpp_main.vapi_ctx, mp, nat44_forwarding_enable_disable_cb, NULL)); - - return rv; -} - -VAPI_REQUEST_CB(nat_set_workers); - -static vapi_error_e -bin_api_nat_set_workers(const vapi_payload_nat_set_workers *msg) -{ - vapi_error_e rv; - vapi_msg_nat_set_workers *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat_set_workers(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat_set_workers(sc_vpp_main.vapi_ctx, mp, nat_set_workers_cb, NULL)); - - return rv; -} - -int nat44_interface_dump(nat44_interface_details_t *reply) -{ - vapi_error_e rv; - - rv = bin_api_nat44_interface_dump(reply); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -int nat44_add_del_interface_addr(const nat44_add_del_interface_addr_t *msg) -{ - vapi_error_e rv; - - rv = bin_api_nat44_add_del_interface_addr(msg); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -int nat44_add_del_addr_range(const nat44_add_del_address_range_t *range) -{ - vapi_error_e rv; - - rv = bin_api_nat44_add_del_addr_range(range); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -int nat44_add_del_static_mapping(const nat44_add_del_static_mapping_t *msg) -{ - vapi_error_e rv; - - rv = bin_api_nat44_add_del_static_mapping(msg); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -int nat44_static_mapping_dump(nat44_static_mapping_details_t *reply) -{ - vapi_error_e rv; - - rv = bin_api_nat44_static_mapping_dump(reply); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -int -nat44_forwarding_enable_disable(const nat44_forwarding_enable_disable_t *msg) -{ - vapi_error_e rv; - - rv = bin_api_nat44_forwarding_enable_disable(msg); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return 0; -} - -int nat_set_workers(const nat_set_workers_t *msg) -{ - vapi_error_e rv; - - rv = bin_api_nat_set_workers(msg); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - diff --git a/src/scvpp/src/v3po.c b/src/scvpp/src/v3po.c deleted file mode 100644 index 8fd83ba..0000000 --- a/src/scvpp/src/v3po.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * Copyright (c) 2018 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include -#include -#include - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_L2_API_JSON; -DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON - -/* - * tap-v2 interfaces - */ - -// Delete tapv2 - -VAPI_REQUEST_CB(tap_delete_v2); - -static vapi_error_e bin_api_delete_tapv2(u32 sw_if_index) -{ - vapi_msg_tap_delete_v2 *mp; - vapi_error_e rv; - - mp = vapi_alloc_tap_delete_v2(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - mp->payload.sw_if_index = sw_if_index; - - VAPI_CALL(vapi_tap_delete_v2(sc_vpp_main.vapi_ctx, mp, tap_delete_v2_cb, NULL)); - if (rv != VAPI_OK) - return -rv; - - return VAPI_OK; -} - -int delete_tapv2(char *iface_name) -{ - uint32_t sw_if_index; - vapi_error_e rv; - int rc; - - rc = get_interface_id(iface_name, &sw_if_index); - if (rc < 0) - return rc; - - rv = bin_api_delete_tapv2(sw_if_index); - if (VAPI_OK != rv) - return -SCVPP_EINVAL; - - return SCVPP_OK; -} - -// Create tapv2 - -VAPI_REQUEST_CB(tap_create_v2); - -int create_tapv2(tapv2_create_t *query) -{ - vapi_msg_tap_create_v2 *mp; - vapi_error_e rv; - - mp = vapi_alloc_tap_create_v2(sc_vpp_main.vapi_ctx); - assert(NULL != mp); - - memcpy(&mp->payload, query, sizeof(tapv2_create_t)); - - VAPI_CALL(vapi_tap_create_v2(sc_vpp_main.vapi_ctx, mp, tap_create_v2_cb, NULL)); - if (rv != VAPI_OK) - return -EAGAIN; - - return 0; -} diff --git a/src/scvpp/tests/CMakeLists.txt b/src/scvpp/tests/CMakeLists.txt deleted file mode 100644 index 78e1861..0000000 --- a/src/scvpp/tests/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# -# Copyright (c) 2018 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_directories ("${PROJECT_SOURCE_DIR}/src") - -# check whether valgrind is installed -find_program(valgrind_FOUND valgrind) - -set(TEST_SRC - scvpp_test.h - scvpp_test.c - scvpp_iface_test.c - scvpp_ip_test.c - scvpp_nat_test.c -) - -add_executable(scvpp_test ${TEST_SRC}) -target_link_libraries(scvpp_test ${CMOCKA_LIBRARIES} scvpp_a) -target_include_directories(scvpp_test PRIVATE ../inc) -add_test(scvpp_test ./scvpp_test) -set_tests_properties(scvpp_test PROPERTIES TIMEOUT 60) - -if(valgrind_FOUND) - add_test(scvpp_valgrind valgrind - --error-exitcode=1 --read-var-info=yes - --leak-check=full --show-leak-kinds=all - ./scvpp_test - ) - set_tests_properties(scvpp_valgrind PROPERTIES TIMEOUT 60) -endif(valgrind_FOUND) diff --git a/src/scvpp/tests/scvpp_iface_test.c b/src/scvpp/tests/scvpp_iface_test.c deleted file mode 100644 index 6a96694..0000000 --- a/src/scvpp/tests/scvpp_iface_test.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include "scvpp_test.h" - -#include -#include - -static void test_enable_disable(void **state) -{ - UNUSED(state); - sw_interface_dump_t dump = {0}; - int rc; - - rc = interface_enable("tap0", 1); - assert_int_equal(rc, SCVPP_OK); - - rc = interface_dump_iface(&dump, "tap0"); - assert_int_equal(rc, SCVPP_OK); - - assert_int_equal(dump.admin_up_down, true); - - rc = interface_enable("tap0", 0); - assert_int_equal(rc, SCVPP_OK); -} - -static void test_create_tapv2(void **state) -{ - UNUSED(state); - tapv2_create_t query = {0}; - sw_interface_dump_t dump = {0}; - int rc; - - query.id = 1; - query.use_random_mac = 1; - - rc = create_tapv2(&query); - assert_int_equal(rc, SCVPP_OK); - - rc = interface_dump_iface(&dump, "tap1"); - assert_int_equal(rc, SCVPP_OK); -} - -static int teardown_tapv2(void **state) -{ - UNUSED(state); - return delete_tapv2("tap1"); -} - -static void test_dump_iface_all(void **state) -{ - UNUSED(state); - struct elt *stack = NULL; - sw_interface_dump_t *dump; - bool exist = false; - - stack = interface_dump_all(); - assert_non_null(stack); - foreach_stack_elt(stack) { - dump = (sw_interface_dump_t *) data; - if (!strncmp((char*) dump->interface_name, "tap0", VPP_INTFC_NAME_LEN)) - exist = true; - free(dump); - } - assert_true(exist); -} - -static void test_dump_iface_exist(void **state) -{ - UNUSED(state); - vapi_payload_sw_interface_details details = {0}; - int rc; - - rc = interface_dump_iface(&details, "local0"); - assert_int_equal(rc, SCVPP_OK); - - assert_string_equal(details.interface_name, "local0"); -} - -static void test_dump_iface_unexist(void **state) -{ - UNUSED(state); - vapi_payload_sw_interface_details details = {0}; - int rc; - - rc = interface_dump_iface(&details, "unexisting"); - assert_int_equal(rc, -SCVPP_NOT_FOUND); -} - -static void test_get_interface_name(void **state) -{ - UNUSED(state); - char interface_name[VPP_INTFC_NAME_LEN]; - uint32_t tap0_if_index; - int rc; - - rc = get_interface_id("tap0", &tap0_if_index); - assert_int_equal(rc, SCVPP_OK); - - rc = get_interface_name(interface_name, tap0_if_index); - assert_int_equal(rc, SCVPP_OK); - - assert_string_equal(interface_name, "tap0"); -} - -const struct CMUnitTest iface_tests[IFACE_TEST_SIZE] = { - cmocka_unit_test_teardown(test_create_tapv2, teardown_tapv2), - cmocka_unit_test(test_enable_disable), - cmocka_unit_test(test_dump_iface_all), - cmocka_unit_test(test_dump_iface_exist), - cmocka_unit_test(test_dump_iface_unexist), - cmocka_unit_test(test_get_interface_name), -}; diff --git a/src/scvpp/tests/scvpp_ip_test.c b/src/scvpp/tests/scvpp_ip_test.c deleted file mode 100644 index 5e28123..0000000 --- a/src/scvpp/tests/scvpp_ip_test.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2019 Cisco - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include - -#include "scvpp_test.h" - -#include -#include -#include - -static void test_add_remove_ipv4(void **state) -{ - UNUSED(state); - const char ip_q[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.144"; - char ip_r[VPP_IP4_ADDRESS_STRING_LEN]; - u8 prefix_q = 24; - u8 prefix_r; - int rc; - - //add ipv4 on tap0 - rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, true); - assert_int_equal(rc, SCVPP_OK); - - //dump ipv4 on tap0 and check if it mach - rc = ipv46_address_dump("tap0", ip_r, &prefix_r, false); - assert_int_equal(rc, SCVPP_OK); - assert_string_equal(ip_q, ip_r); - assert_int_equal(prefix_q, prefix_r); - - //remove ipv4 on tap0 - rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, false); - assert_int_equal(rc, SCVPP_OK); - - //dump ipv4 after removal and check if equals 0.0.0.0 - rc = ipv46_address_dump("tap0", ip_r, &prefix_r, false); - assert_int_equal(rc, SCVPP_OK); - assert_string_equal(ip_r, "0.0.0.0"); -} - -static void test_ipv4_add_del_route_no_iface(void **state) -{ - UNUSED(state); - int rc; - char dst_address[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.0"; - uint8_t prefix_len = 24; - char next_hop[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.100"; - uint32_t table_id = 0; - fib_dump_t *dump; - struct elt *stack; - bool route_found = false; - - /* Must fail, can not have both interface and next hop IP null */ - rc = ipv46_config_add_del_route(dst_address, prefix_len, NULL, true, - table_id, NULL); - assert_int_equal(rc, -SCVPP_EINVAL); - - rc = ipv46_config_add_del_route(dst_address, prefix_len, next_hop, true, - table_id, NULL); - assert_int_equal(rc, SCVPP_OK); - - /* Dump all FIB routes and check if we find ours */ - stack = ipv4_fib_dump_all(); - assert_non_null(stack); - foreach_stack_elt(stack) { - dump = (fib_dump_t *) data; - - if (strncmp(sc_ntoa(dump->address), dst_address, - VPP_IP4_ADDRESS_STRING_LEN) == 0 && - dump->address_length == prefix_len) { - route_found = true; - assert_int_equal(dump->table_id, table_id); - assert_int_equal(dump->count, 1); - assert_string_equal(sc_ntoa(dump->path[0].next_hop), next_hop); - } - free(dump); - } - assert_true(route_found); - - /* Delete previously set route */ - rc = ipv46_config_add_del_route(dst_address, prefix_len, next_hop, false, - table_id, NULL); - assert_int_equal(rc, SCVPP_OK); - - /* Check our route has been deleted */ - route_found = false; - stack = ipv4_fib_dump_all(); - assert_non_null(stack); - foreach_stack_elt(stack) { - dump = (fib_dump_t *) data; - if (strncmp(sc_ntoa(dump->address), dst_address, - VPP_IP4_ADDRESS_STRING_LEN) == 0 && - dump->address_length == prefix_len) { - route_found = true; - } - free(dump); - } - assert_false(route_found); -} - -static void test_ipv4_add_del_route_no_next_hop_ip(void **state) -{ - UNUSED(state); - int rc; - char dst_address[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.0"; - uint8_t prefix_len = 24; - char interface[VPP_IP4_ADDRESS_STRING_LEN] = "tap0"; - uint32_t table_id = 0; - uint32_t sw_if_index; - fib_dump_t *dump; - struct elt *stack; - bool route_found = false; - - //Add a new route - rc = ipv46_config_add_del_route(dst_address, prefix_len, NULL, true, - table_id, interface); - assert_int_equal(rc, SCVPP_OK); - - //Dump all FIB routes and check we find ours - stack = ipv4_fib_dump_all(); - assert_non_null(stack); - - rc = get_interface_id(interface, &sw_if_index); - assert_int_equal(rc, SCVPP_OK); - - foreach_stack_elt(stack) { - dump = (fib_dump_t *) data; - - if (strncmp(sc_ntoa(dump->address), dst_address, - VPP_IP4_ADDRESS_STRING_LEN) == 0 && - dump->address_length == prefix_len) { - route_found = true; - assert_int_equal(dump->table_id, table_id); - assert_int_equal(dump->count, 1); - assert_int_equal(dump->path[0].sw_if_index, sw_if_index); - } - free(dump); - } - assert_true(route_found); - - //Delete route - rc = ipv46_config_add_del_route(dst_address, prefix_len, NULL, false, - table_id, interface); - assert_int_equal(rc, SCVPP_OK); - - //Check our route has been deleted - route_found = false; - stack = ipv4_fib_dump_all(); - assert_non_null(stack); - - foreach_stack_elt(stack) { - dump = (fib_dump_t *) data; - if (strncmp(sc_ntoa(dump->address), dst_address, - VPP_IP4_ADDRESS_STRING_LEN) == 0 && - dump->address_length == prefix_len) { - route_found = true; - } - free(dump); - } - assert_false(route_found); -} - - -const struct CMUnitTest ip_tests[IP_TEST_SIZE] = { - cmocka_unit_test(test_add_remove_ipv4), - cmocka_unit_test(test_ipv4_add_del_route_no_next_hop_ip), - cmocka_unit_test(test_ipv4_add_del_route_no_iface), -}; diff --git a/src/scvpp/tests/scvpp_nat_test.c b/src/scvpp/tests/scvpp_nat_test.c deleted file mode 100644 index 93541e9..0000000 --- a/src/scvpp/tests/scvpp_nat_test.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2019 PANTHEON.tech. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include - -#include "scvpp_test.h" - -#include -#include - - -void test_nat44_static_mapping(void **state) -{ - UNUSED(state); - nat44_add_del_static_mapping_t map = {0}; - nat44_static_mapping_details_t dump = {0}; - u8 empty_ip[4] = {0}; - int rc; - - /*Configure the static mapping - Alternative to this CLI command: - nat44 add static mapping local 172.168.0.1 external 172.168.8.5 - */ - sc_aton("172.168.0.1", map.local_ip_address, - sizeof(map.local_ip_address)); - sc_aton("172.168.8.5", map.external_ip_address, - sizeof(map.external_ip_address)); - map.external_sw_if_index = ~0; - map.is_add = 1; - - rc = nat44_add_del_static_mapping(&map); - assert_int_equal(rc, SCVPP_OK); - - rc = nat44_static_mapping_dump(&dump); - assert_int_equal(rc, SCVPP_OK); - - assert_memory_equal(dump.local_ip_address, map.local_ip_address, - sizeof(dump.local_ip_address)); - - assert_memory_equal(dump.external_ip_address, map.external_ip_address, - sizeof(dump.external_ip_address)); - - /* Remove previous config*/ - map.is_add = 0; - - rc = nat44_add_del_static_mapping(&map); - assert_int_equal(rc, SCVPP_OK); - - memset(&dump, 0, sizeof(dump)); - - rc = nat44_static_mapping_dump(&dump); - assert_int_equal(rc, SCVPP_OK); - - assert_memory_equal(dump.local_ip_address, empty_ip, - sizeof(dump.local_ip_address)); - - assert_memory_equal(dump.external_ip_address, empty_ip, - sizeof(dump.external_ip_address)); -} - -void test_nat44_static_mapping_with_ports(void **state) -{ - UNUSED(state); - nat44_add_del_static_mapping_t map = {0}; - nat44_static_mapping_details_t dump = {0}; - nat44_add_del_address_range_t range = {0}; - u8 empty_ip[4] = {0}; - const u16 lport = 77; - const u16 eport = 88; - int rc; - - /*Configure address pool - Alternative to this CLI: - nat44 add address 5.4.4.4 - */ - sc_aton("5.4.4.4", range.first_ip_address, - sizeof(range.first_ip_address)); - - sc_aton("5.4.4.4", range.last_ip_address, - sizeof(range.last_ip_address)); - - range.is_add = 1; - - rc = nat44_add_del_addr_range(&range); - assert_int_equal(rc, SCVPP_OK); - - /*Configure NAT with ports - Alternative to this CLI: - nat44 add static mapping tcp local 172.168.0.1 77 external 5.4.4.4 88 - */ - - sc_aton("172.168.0.1", map.local_ip_address, - sizeof(map.local_ip_address)); - - sc_aton("5.4.4.4", map.external_ip_address, - sizeof(map.external_ip_address)); - - map.protocol = 6; - - map.external_sw_if_index = ~0; - - map.external_port = eport; - map.local_port = lport; - - map.is_add = 1; - - rc = nat44_add_del_static_mapping(&map); - assert_int_equal(rc, SCVPP_OK); - - rc = nat44_static_mapping_dump(&dump); - assert_int_equal(rc, SCVPP_OK); - - assert_memory_equal(dump.local_ip_address, map.local_ip_address, - sizeof(dump.local_ip_address)); - - assert_memory_equal(dump.external_ip_address, map.external_ip_address, - sizeof(dump.external_ip_address)); - - assert_int_equal(dump.local_port, lport); - - assert_int_equal(dump.external_port, eport); - - /* Remove all previous config*/ - - map.is_add = 0; - - rc = nat44_add_del_static_mapping(&map); - assert_int_equal(rc, SCVPP_OK); - - memset(&dump, 0, sizeof(dump)); - - rc = nat44_static_mapping_dump(&dump); - assert_int_equal(rc, SCVPP_OK); - - assert_memory_equal(dump.local_ip_address, empty_ip, - sizeof(dump.local_ip_address)); - - assert_memory_equal(dump.external_ip_address, empty_ip, - sizeof(dump.external_ip_address)); - - assert_int_equal(dump.local_port, 0); - - assert_int_equal(dump.external_port, 0); - - range.is_add = 0; - - rc = nat44_add_del_addr_range(&range); - assert_int_equal(rc, SCVPP_OK); -} - -const struct CMUnitTest nat_tests[] = { - cmocka_unit_test_setup_teardown(test_nat44_static_mapping, NULL, - NULL), - cmocka_unit_test_setup_teardown(test_nat44_static_mapping_with_ports, - NULL, NULL), - }; diff --git a/src/scvpp/tests/scvpp_test.c b/src/scvpp/tests/scvpp_test.c deleted file mode 100644 index f6e99a0..0000000 --- a/src/scvpp/tests/scvpp_test.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 -#include -#include -#include - -#include -#include - -#include "scvpp_test.h" - -/* test "AAA.BBB.CCC.DDD" -> {A, B, C, D} */ -static void test_sc_ntoa(void **state) -{ - UNUSED(state); - u8 buf[4] = {192, 168, 100, 44}; - char *res; - - res = sc_ntoa(buf); - assert_string_equal(res, "192.168.100.44"); -} - -/* test {A, B, C, D} -> "AAA.BBB.CCC.DDD" */ -static void test_sc_aton(void **state) -{ - UNUSED(state); - char ip[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.44"; - uint8_t buf[4]; - int rc; - - rc = sc_aton(ip, buf, VPP_IP4_ADDRESS_LEN); - assert_int_equal(rc, 0); - - assert_int_equal(buf[0], 192); - assert_int_equal(buf[1], 168); - assert_int_equal(buf[2], 100); - assert_int_equal(buf[3], 44); -} - -static int setup(void **state) -{ - UNUSED(state); - tapv2_create_t query = {0}; - - if (sc_connect_vpp() != 0) { - fprintf(stderr, "Error connecting to VPP\n"); - return -1; - } - - /* Create interface tap0 to test several functions */ - query.id = 0; - query.use_random_mac = 1; - if (create_tapv2(&query) != 0) { - fprintf(stderr, "Error creating tap0\n"); - return -1; - } - - return 0; -} - -static int teardown(void **state) -{ - UNUSED(state); - /* Delete tap0 */ - if (delete_tapv2("tap0") != 0) { - fprintf(stderr, "Failed deleting tap0\n"); - return -1; - } - - sc_disconnect_vpp(); - - return 0; -} - -/* return code for scvpp-test binary is the number of failed test */ -int main() -{ - int rc = 0; - - const struct CMUnitTest common_tests[] = { - cmocka_unit_test(test_sc_ntoa), - cmocka_unit_test(test_sc_aton), - }; - - print_message("Common tests\n"); - rc |= cmocka_run_group_tests(common_tests, NULL, NULL); - print_message("Interface tests\n"); - rc |= cmocka_run_group_tests(iface_tests, setup, teardown); - print_message("IP tests\n"); - rc |= cmocka_run_group_tests(ip_tests, setup, teardown); - print_message("NAT tests\n"); - rc |= cmocka_run_group_tests(nat_tests, setup, teardown); - - return rc; -} diff --git a/src/scvpp/tests/scvpp_test.h b/src/scvpp/tests/scvpp_test.h deleted file mode 100644 index 28bd514..0000000 --- a/src/scvpp/tests/scvpp_test.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2019 Cisco - * - * 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 __SCVPP_TEST_H -#define __SCVPP_TEST_H__ - -#include - -#define IFACE_TEST_SIZE 6 -extern const struct CMUnitTest iface_tests[IFACE_TEST_SIZE]; - -#define IP_TEST_SIZE 3 -extern const struct CMUnitTest ip_tests[IP_TEST_SIZE]; - -#define NAT_TEST_SIZE 2 -extern const struct CMUnitTest nat_tests[NAT_TEST_SIZE]; - -#endif /* __SCVPP_TEST_H__ */ -- cgit 1.2.3-korg