include $(TOPDIR)/rules.mk
PKG_NAME:=netdata
-PKG_VERSION:=1.22.1
+PKG_VERSION:=1.23.2
PKG_RELEASE:=1
PKG_MAINTAINER:=Josef Schlehofer <pepe.schlehofer@gmail.com>, Daniel Engberg <daniel.engberg.lists@pyret.net>
PKG_SOURCE:=$(PKG_NAME)-v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/netdata/netdata/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=6efd785eab82f98892b4b4017cadfa4ce1688985915499bc75f2f888765a3446
+PKG_HASH:=b6dd13292e0b1fb4137b1f7c0dc3d7c5e8a1bf408b82c2b8394f3751800e0eb5
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
include $(TOPDIR)/rules.mk
PKG_NAME:=meson
-PKG_VERSION:=0.54.3
-PKG_RELEASE:=2
+PKG_VERSION:=0.55.0
+PKG_RELEASE:=3
PYPI_NAME:=meson
-PKG_HASH:=f2bdf4cf0694e696b48261cdd14380fb1d0fe33d24744d8b2df0c12f33ebb662
+PKG_HASH:=0a1ae2bfe2ae14ac47593537f93290fb79e9b775c55b4c53c282bc3ca3745b35
PKG_MAINTAINER:=Andre Heider <a.heider@gmail.com>
PKG_LICENSE:=Apache-2.0
+++ /dev/null
-From 4db4fd79d9bb2b98cea1117f22b6c97942ab2ecd Mon Sep 17 00:00:00 2001
-From: Eric Le Bihan <eric.le.bihan.dev@free.fr>
-Date: Sat, 14 Jul 2018 11:18:45 +0200
-Subject: [PATCH] Only fix RPATH if install_rpath is not empty
-
-Signed-off-by: Eric Le Bihan <eric.le.bihan.dev@free.fr>
-[Fix: remove leftover from original/unconditional code]
-Signed-off-by: Peter Seiderer <ps.report@gmx.net>
----
- mesonbuild/minstall.py | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py
-index 8ac6aab1..7ef04116 100644
---- a/mesonbuild/minstall.py
-+++ b/mesonbuild/minstall.py
-@@ -508,8 +508,14 @@ class Installer:
- if file_copied:
- self.did_install_something = True
- try:
-- depfixer.fix_rpath(outname, install_rpath, final_path,
-- install_name_mappings, verbose=False)
-+ # Buildroot check-host-rpath script expects RPATH
-+ # But if install_rpath is empty, it will stripped.
-+ # So, preserve it in this case
-+ if install_rpath:
-+ depfixer.fix_rpath(outname, install_rpath, final_path,
-+ install_name_mappings, verbose=False)
-+ else:
-+ print("Skipping RPATH fixing")
- except SystemExit as e:
- if isinstance(e.code, int) and e.code == 0:
- pass
-
--- /dev/null
+From 019ed04331695bb6f5c5fff70dfced34c4ba9012 Mon Sep 17 00:00:00 2001
+From: Daniel Mensinger <daniel@mensinger-ka.de>
+Date: Thu, 16 Jul 2020 20:29:34 +0200
+Subject: [PATCH 1/3] mdata: Generate mesondata.py from */data folders
+
+---
+ mesonbuild/mesondata.py | 374 ++++++++++++++++++++++++++++++++++++++++
+ tools/gen_data.py | 139 +++++++++++++++
+ 2 files changed, 513 insertions(+)
+ create mode 100644 mesonbuild/mesondata.py
+ create mode 100755 tools/gen_data.py
+
+diff --git a/mesonbuild/mesondata.py b/mesonbuild/mesondata.py
+new file mode 100644
+index 0000000000..1f223c251b
+--- /dev/null
++++ b/mesonbuild/mesondata.py
+@@ -0,0 +1,374 @@
++# Copyright 2020 The Meson development team
++
++# 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.
++
++
++####
++#### WARNING: This is an automatically generated file! Do not edit!
++#### Generated by tools/gen_data.py
++####
++
++
++from pathlib import Path
++import typing as T
++
++if T.TYPE_CHECKING:
++ from .environment import Environment
++
++######################
++# BEGIN Data section #
++######################
++
++file_0_data_CMakeListsLLVM_txt = '''\
++cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )
++
++set(PACKAGE_FOUND FALSE)
++
++while(TRUE)
++ find_package(LLVM REQUIRED CONFIG QUIET)
++
++ # ARCHS has to be set via the CMD interface
++ if(LLVM_FOUND OR "${ARCHS}" STREQUAL "")
++ break()
++ endif()
++
++ list(GET ARCHS 0 CMAKE_LIBRARY_ARCHITECTURE)
++ list(REMOVE_AT ARCHS 0)
++endwhile()
++
++if(LLVM_FOUND)
++ set(PACKAGE_FOUND TRUE)
++
++ foreach(mod IN LISTS LLVM_MESON_MODULES)
++ # Reset variables
++ set(out_mods)
++ set(real_mods)
++
++ # Generate a lower and upper case version
++ string(TOLOWER "${mod}" mod_L)
++ string(TOUPPER "${mod}" mod_U)
++
++ # Get the mapped components
++ llvm_map_components_to_libnames(out_mods ${mod} ${mod_L} ${mod_U})
++ list(SORT out_mods)
++ list(REMOVE_DUPLICATES out_mods)
++
++ # Make sure that the modules exist
++ foreach(i IN LISTS out_mods)
++ if(TARGET ${i})
++ list(APPEND real_mods ${i})
++ endif()
++ endforeach()
++
++ # Set the output variables
++ set(MESON_LLVM_TARGETS_${mod} ${real_mods})
++ foreach(i IN LISTS real_mods)
++ set(MESON_TARGET_TO_LLVM_${i} ${mod})
++ endforeach()
++ endforeach()
++
++ # Check the following variables:
++ # LLVM_PACKAGE_VERSION
++ # LLVM_VERSION
++ # LLVM_VERSION_STRING
++ if(NOT DEFINED PACKAGE_VERSION)
++ if(DEFINED LLVM_PACKAGE_VERSION)
++ set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
++ elseif(DEFINED LLVM_VERSION)
++ set(PACKAGE_VERSION "${LLVM_VERSION}")
++ elseif(DEFINED LLVM_VERSION_STRING)
++ set(PACKAGE_VERSION "${LLVM_VERSION_STRING}")
++ endif()
++ endif()
++
++ # Check the following variables:
++ # LLVM_LIBRARIES
++ # LLVM_LIBS
++ set(libs)
++ if(DEFINED LLVM_LIBRARIES)
++ set(libs LLVM_LIBRARIES)
++ elseif(DEFINED LLVM_LIBS)
++ set(libs LLVM_LIBS)
++ endif()
++
++ # Check the following variables:
++ # LLVM_INCLUDE_DIRS
++ # LLVM_INCLUDES
++ # LLVM_INCLUDE_DIR
++ set(includes)
++ if(DEFINED LLVM_INCLUDE_DIRS)
++ set(includes LLVM_INCLUDE_DIRS)
++ elseif(DEFINED LLVM_INCLUDES)
++ set(includes LLVM_INCLUDES)
++ elseif(DEFINED LLVM_INCLUDE_DIR)
++ set(includes LLVM_INCLUDE_DIR)
++ endif()
++
++ # Check the following variables:
++ # LLVM_DEFINITIONS
++ set(definitions)
++ if(DEFINED LLVM_DEFINITIONS)
++ set(definitions LLVM_DEFINITIONS)
++ endif()
++
++ set(PACKAGE_INCLUDE_DIRS "${${includes}}")
++ set(PACKAGE_DEFINITIONS "${${definitions}}")
++ set(PACKAGE_LIBRARIES "${${libs}}")
++endif()
++'''
++
++file_1_data_CMakePathInfo_txt = '''\
++cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION})
++
++set(TMP_PATHS_LIST)
++list(APPEND TMP_PATHS_LIST ${CMAKE_PREFIX_PATH})
++list(APPEND TMP_PATHS_LIST ${CMAKE_FRAMEWORK_PATH})
++list(APPEND TMP_PATHS_LIST ${CMAKE_APPBUNDLE_PATH})
++list(APPEND TMP_PATHS_LIST $ENV{CMAKE_PREFIX_PATH})
++list(APPEND TMP_PATHS_LIST $ENV{CMAKE_FRAMEWORK_PATH})
++list(APPEND TMP_PATHS_LIST $ENV{CMAKE_APPBUNDLE_PATH})
++list(APPEND TMP_PATHS_LIST ${CMAKE_SYSTEM_PREFIX_PATH})
++list(APPEND TMP_PATHS_LIST ${CMAKE_SYSTEM_FRAMEWORK_PATH})
++list(APPEND TMP_PATHS_LIST ${CMAKE_SYSTEM_APPBUNDLE_PATH})
++
++set(LIB_ARCH_LIST)
++if(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
++ file(GLOB implicit_dirs RELATIVE /lib /lib/*-linux-gnu* )
++ foreach(dir ${implicit_dirs})
++ if("${dir}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
++ list(APPEND LIB_ARCH_LIST "${dir}")
++ endif()
++ endforeach()
++endif()
++
++# "Export" these variables:
++set(MESON_ARCH_LIST ${LIB_ARCH_LIST})
++set(MESON_PATHS_LIST ${TMP_PATHS_LIST})
++set(MESON_CMAKE_ROOT ${CMAKE_ROOT})
++set(MESON_CMAKE_SYSROOT ${CMAKE_SYSROOT})
++set(MESON_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH})
++
++message(STATUS ${TMP_PATHS_LIST})
++'''
++
++file_2_data_CMakeLists_txt = '''\
++# fail noisily if attempt to use this file without setting:
++# cmake_minimum_required(VERSION ${CMAKE_VERSION})
++# project(... LANGUAGES ...)
++
++cmake_policy(SET CMP0000 NEW)
++
++set(PACKAGE_FOUND FALSE)
++set(_packageName "${NAME}")
++string(TOUPPER "${_packageName}" PACKAGE_NAME)
++
++while(TRUE)
++ find_package("${NAME}" QUIET COMPONENTS ${COMPS})
++
++ # ARCHS has to be set via the CMD interface
++ if(${_packageName}_FOUND OR ${PACKAGE_NAME}_FOUND OR "${ARCHS}" STREQUAL "")
++ break()
++ endif()
++
++ list(GET ARCHS 0 CMAKE_LIBRARY_ARCHITECTURE)
++ list(REMOVE_AT ARCHS 0)
++endwhile()
++
++if(${_packageName}_FOUND OR ${PACKAGE_NAME}_FOUND)
++ set(PACKAGE_FOUND TRUE)
++
++ # Check the following variables:
++ # FOO_VERSION
++ # Foo_VERSION
++ # FOO_VERSION_STRING
++ # Foo_VERSION_STRING
++ if(NOT DEFINED PACKAGE_VERSION)
++ if(DEFINED ${_packageName}_VERSION)
++ set(PACKAGE_VERSION "${${_packageName}_VERSION}")
++ elseif(DEFINED ${PACKAGE_NAME}_VERSION)
++ set(PACKAGE_VERSION "${${PACKAGE_NAME}_VERSION}")
++ elseif(DEFINED ${_packageName}_VERSION_STRING)
++ set(PACKAGE_VERSION "${${_packageName}_VERSION_STRING}")
++ elseif(DEFINED ${PACKAGE_NAME}_VERSION_STRING)
++ set(PACKAGE_VERSION "${${PACKAGE_NAME}_VERSION_STRING}")
++ endif()
++ endif()
++
++ # Check the following variables:
++ # FOO_LIBRARIES
++ # Foo_LIBRARIES
++ # FOO_LIBS
++ # Foo_LIBS
++ set(libs)
++ if(DEFINED ${_packageName}_LIBRARIES)
++ set(libs ${_packageName}_LIBRARIES)
++ elseif(DEFINED ${PACKAGE_NAME}_LIBRARIES)
++ set(libs ${PACKAGE_NAME}_LIBRARIES)
++ elseif(DEFINED ${_packageName}_LIBS)
++ set(libs ${_packageName}_LIBS)
++ elseif(DEFINED ${PACKAGE_NAME}_LIBS)
++ set(libs ${PACKAGE_NAME}_LIBS)
++ endif()
++
++ # Check the following variables:
++ # FOO_INCLUDE_DIRS
++ # Foo_INCLUDE_DIRS
++ # FOO_INCLUDES
++ # Foo_INCLUDES
++ # FOO_INCLUDE_DIR
++ # Foo_INCLUDE_DIR
++ set(includes)
++ if(DEFINED ${_packageName}_INCLUDE_DIRS)
++ set(includes ${_packageName}_INCLUDE_DIRS)
++ elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIRS)
++ set(includes ${PACKAGE_NAME}_INCLUDE_DIRS)
++ elseif(DEFINED ${_packageName}_INCLUDES)
++ set(includes ${_packageName}_INCLUDES)
++ elseif(DEFINED ${PACKAGE_NAME}_INCLUDES)
++ set(includes ${PACKAGE_NAME}_INCLUDES)
++ elseif(DEFINED ${_packageName}_INCLUDE_DIR)
++ set(includes ${_packageName}_INCLUDE_DIR)
++ elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIR)
++ set(includes ${PACKAGE_NAME}_INCLUDE_DIR)
++ endif()
++
++ # Check the following variables:
++ # FOO_DEFINITIONS
++ # Foo_DEFINITIONS
++ set(definitions)
++ if(DEFINED ${_packageName}_DEFINITIONS)
++ set(definitions ${_packageName}_DEFINITIONS)
++ elseif(DEFINED ${PACKAGE_NAME}_DEFINITIONS)
++ set(definitions ${PACKAGE_NAME}_DEFINITIONS)
++ endif()
++
++ set(PACKAGE_INCLUDE_DIRS "${${includes}}")
++ set(PACKAGE_DEFINITIONS "${${definitions}}")
++ set(PACKAGE_LIBRARIES "${${libs}}")
++endif()
++'''
++
++file_3_data_preload_cmake = '''\
++if(MESON_PS_LOADED)
++ return()
++endif()
++
++set(MESON_PS_LOADED ON)
++
++# Dummy macros that have a special meaning in the meson code
++macro(meson_ps_execute_delayed_calls)
++endmacro()
++
++macro(meson_ps_reload_vars)
++endmacro()
++
++# Helper macro to inspect the current CMake state
++macro(meson_ps_inspect_vars)
++ set(MESON_PS_CMAKE_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
++ set(MESON_PS_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
++ meson_ps_execute_delayed_calls()
++endmacro()
++
++
++# Override some system functions with custom code and forward the args
++# to the original function
++macro(add_custom_command)
++ meson_ps_inspect_vars()
++ _add_custom_command(${ARGV})
++endmacro()
++
++macro(add_custom_target)
++ meson_ps_inspect_vars()
++ _add_custom_target(${ARGV})
++endmacro()
++
++macro(set_property)
++ meson_ps_inspect_vars()
++ _set_property(${ARGV})
++endmacro()
++
++function(set_source_files_properties)
++ set(FILES)
++ set(I 0)
++ set(PROPERTIES OFF)
++
++ while(I LESS ARGC)
++ if(NOT PROPERTIES)
++ if("${ARGV${I}}" STREQUAL "PROPERTIES")
++ set(PROPERTIES ON)
++ else()
++ list(APPEND FILES "${ARGV${I}}")
++ endif()
++
++ math(EXPR I "${I} + 1")
++ else()
++ set(ID_IDX ${I})
++ math(EXPR PROP_IDX "${ID_IDX} + 1")
++
++ set(ID "${ARGV${ID_IDX}}")
++ set(PROP "${ARGV${PROP_IDX}}")
++
++ set_property(SOURCE ${FILES} PROPERTY "${ID}" "${PROP}")
++ math(EXPR I "${I} + 2")
++ endif()
++ endwhile()
++endfunction()
++
++set(MESON_PS_DELAYED_CALLS add_custom_command;add_custom_target;set_property)
++meson_ps_reload_vars()
++'''
++
++
++####################
++# END Data section #
++####################
++
++class DataFile:
++ def __init__(self, path: Path, sha256sum: str, data: str) -> None:
++ self.path = path
++ self.sha256sum = sha256sum
++ self.data = data
++
++ def write_once(self, path: Path) -> None:
++ if not path.exists():
++ path.write_text(self.data)
++
++ def write_to_private(self, env: 'Environment') -> Path:
++ out_file = Path(env.scratch_dir) / 'data' / self.path.name
++ out_file.parent.mkdir(exist_ok=True)
++ self.write_once(out_file)
++ return out_file
++
++
++mesondata = {
++ 'dependencies/data/CMakeListsLLVM.txt': DataFile(
++ Path('dependencies/data/CMakeListsLLVM.txt'),
++ '412cec3315597041a978d018cdaca282dcd47693793540da88ae2f80d0cbd7cd',
++ file_0_data_CMakeListsLLVM_txt,
++ ),
++ 'dependencies/data/CMakePathInfo.txt': DataFile(
++ Path('dependencies/data/CMakePathInfo.txt'),
++ '90da8b443982d9c87139b7dc84228eb58cab4315764949637208f25e2bda7db2',
++ file_1_data_CMakePathInfo_txt,
++ ),
++ 'dependencies/data/CMakeLists.txt': DataFile(
++ Path('dependencies/data/CMakeLists.txt'),
++ '71a2d58381f912bbfb1c8709884d34d721f682edf2fca001e1f582f0bffd0da7',
++ file_2_data_CMakeLists_txt,
++ ),
++ 'cmake/data/preload.cmake': DataFile(
++ Path('cmake/data/preload.cmake'),
++ '064d047b18a5c919ad016b838bed50c5d40aebe9e53da0e70eff9d52a2c1ca1f',
++ file_3_data_preload_cmake,
++ ),
++}
+diff --git a/tools/gen_data.py b/tools/gen_data.py
+new file mode 100755
+index 0000000000..2cc05a44e7
+--- /dev/null
++++ b/tools/gen_data.py
+@@ -0,0 +1,139 @@
++#!/usr/bin/env python3
++
++# Copyright 2020 Daniel Mensinger
++
++# 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.
++
++import sys
++import hashlib
++import textwrap
++import re
++from pathlib import Path
++from datetime import datetime
++import typing as T
++
++class DataFile:
++ file_counter = 0
++
++ def __init__(self, path: Path, root: Path):
++ self.path = path
++ self.id = self.path.relative_to(root)
++ self.data_str = f'file_{DataFile.file_counter}_data_' + re.sub('[^a-zA-Z0-9]', '_', self.path.name)
++ DataFile.file_counter += 1
++
++ b = self.path.read_bytes()
++ self.data = b.decode()
++ self.sha256sum = hashlib.sha256(b).hexdigest()
++
++ def __repr__(self) -> str:
++ return f'<{type(self).__name__}: [{self.sha256sum}] {self.id}>'
++
++def main() -> int:
++ root_dir = Path(__file__).resolve().parents[1]
++ mesonbuild_dir = root_dir / 'mesonbuild'
++ out_file = mesonbuild_dir / 'mesondata.py'
++
++ data_dirs = mesonbuild_dir.glob('**/data')
++
++ data_files: T.List[DataFile] = []
++
++ for d in data_dirs:
++ for p in d.iterdir():
++ data_files += [DataFile(p, mesonbuild_dir)]
++
++ print(f'Found {len(data_files)} data files')
++
++ # Generate the data script
++ data = ''
++
++ data += textwrap.dedent(f'''\
++ # Copyright {datetime.today().year} The Meson development team
++
++ # 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.
++
++
++ ####
++ #### WARNING: This is an automatically generated file! Do not edit!
++ #### Generated by {Path(__file__).resolve().relative_to(root_dir)}
++ ####
++
++
++ from pathlib import Path
++ import typing as T
++
++ if T.TYPE_CHECKING:
++ from .environment import Environment
++
++ ######################
++ # BEGIN Data section #
++ ######################
++
++ ''')
++
++ for i in data_files:
++ data += f"{i.data_str} = '''\\\n{i.data}'''\n\n"
++
++ data += textwrap.dedent(f'''
++ ####################
++ # END Data section #
++ ####################
++
++ class DataFile:
++ def __init__(self, path: Path, sha256sum: str, data: str) -> None:
++ self.path = path
++ self.sha256sum = sha256sum
++ self.data = data
++
++ def write_once(self, path: Path) -> None:
++ if not path.exists():
++ path.write_text(self.data)
++
++ def write_to_private(self, env: 'Environment') -> Path:
++ out_file = Path(env.scratch_dir) / 'data' / self.path.name
++ out_file.parent.mkdir(exist_ok=True)
++ self.write_once(out_file)
++ return out_file
++
++
++ mesondata = {{
++ ''')
++
++ for i in data_files:
++ data += textwrap.indent(textwrap.dedent(f"""\
++ '{i.id}': DataFile(
++ Path('{i.id}'),
++ '{i.sha256sum}',
++ {i.data_str},
++ ),
++ """), ' ')
++
++ data += textwrap.dedent('''\
++ }
++ ''')
++
++ print(f'Updating {out_file}')
++ out_file.write_text(data)
++ return 0
++
++if __name__ == '__main__':
++ sys.exit(main())
+
+From 05ddd6543d4c4fc33b4c64f26291e73f49733f71 Mon Sep 17 00:00:00 2001
+From: Daniel Mensinger <daniel@mensinger-ka.de>
+Date: Thu, 16 Jul 2020 20:33:57 +0200
+Subject: [PATCH 2/3] mdata: remove setuptools and use mesondata instead
+
+---
+ mesonbuild/cmake/interpreter.py | 5 ++---
+ mesonbuild/dependencies/base.py | 6 ++----
+ setup.py | 5 -----
+ 4 files changed, 4 insertions(+), 16 deletions(-)
+
+diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
+index 05169478e8..f404109cf6 100644
+--- a/mesonbuild/cmake/interpreter.py
++++ b/mesonbuild/cmake/interpreter.py
+@@ -15,8 +15,6 @@
+ # This class contains the basic functionality needed to run any interpreter
+ # or an interpreter-based tool.
+
+-import pkg_resources
+-
+ from .common import CMakeException, CMakeTarget, TargetOptions
+ from .client import CMakeClient, RequestCMakeInputs, RequestConfigure, RequestCompute, RequestCodeModel
+ from .fileapi import CMakeFileAPI
+@@ -25,6 +23,7 @@
+ from .. import mlog, mesonlib
+ from ..environment import Environment
+ from ..mesonlib import MachineChoice, OrderedSet, version_compare
++from ..mesondata import mesondata
+ from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
+ from enum import Enum
+ from functools import lru_cache
+@@ -814,7 +813,7 @@ def configure(self, extra_cmake_options: T.List[str]) -> None:
+ raise CMakeException('Unable to find CMake')
+ self.trace = CMakeTraceParser(cmake_exe.version(), self.build_dir, permissive=True)
+
+- preload_file = pkg_resources.resource_filename('mesonbuild', 'cmake/data/preload.cmake')
++ preload_file = mesondata['cmake/data/preload.cmake'].write_to_private(self.env)
+
+ # Prefere CMAKE_PROJECT_INCLUDE over CMAKE_TOOLCHAIN_FILE if possible,
+ # since CMAKE_PROJECT_INCLUDE was actually designed for code injection.
+diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
+index 23701da957..4c9c9fe18a 100644
+--- a/mesonbuild/dependencies/base.py
++++ b/mesonbuild/dependencies/base.py
+@@ -29,8 +29,6 @@
+ from enum import Enum
+ from pathlib import Path, PurePath
+
+-import pkg_resources
+-
+ from .. import mlog
+ from .. import mesonlib
+ from ..compilers import clib_langs
+@@ -40,6 +38,7 @@
+ from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
+ from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify, stringlistify, extract_as_list, split_args
+ from ..mesonlib import Version, LibType
++from ..mesondata import mesondata
+
+ if T.TYPE_CHECKING:
+ from ..compilers.compilers import CompilerType # noqa: F401
+@@ -1512,8 +1511,7 @@ def _setup_cmake_dir(self, cmake_file: str) -> str:
+ build_dir = self._get_build_dir()
+
+ # Insert language parameters into the CMakeLists.txt and write new CMakeLists.txt
+- # Per the warning in pkg_resources, this is *not* a path and os.path and Pathlib are *not* safe to use here.
+- cmake_txt = pkg_resources.resource_string('mesonbuild', 'dependencies/data/' + cmake_file).decode()
++ cmake_txt = mesondata['dependencies/data/' + cmake_file].data
+
+ # In general, some Fortran CMake find_package() also require C language enabled,
+ # even if nothing from C is directly used. An easy Fortran example that fails
+diff --git a/setup.py b/setup.py
+index 1f95be70c8..145f19c522 100644
+--- a/setup.py
++++ b/setup.py
+@@ -37,10 +37,6 @@
+ 'mesonbuild.scripts',
+ 'mesonbuild.templates',
+ 'mesonbuild.wrap']
+-package_data = {
+- 'mesonbuild.dependencies': ['data/CMakeLists.txt', 'data/CMakeListsLLVM.txt', 'data/CMakePathInfo.txt'],
+- 'mesonbuild.cmake': ['data/run_ctgt.py', 'data/preload.cmake'],
+-}
+ data_files = []
+ if sys.platform != 'win32':
+ # Only useful on UNIX-like systems
+@@ -51,6 +47,5 @@
+ setup(name='meson',
+ version=version,
+ packages=packages,
+- package_data=package_data,
+ entry_points=entries,
+ data_files=data_files,)
+
+From 393d6e133d9abd584a2fc414971628e84ea48b7c Mon Sep 17 00:00:00 2001
+From: Daniel Mensinger <daniel@mensinger-ka.de>
+Date: Thu, 16 Jul 2020 20:34:15 +0200
+Subject: [PATCH 3/3] mdata: Add test to ensure mesondata.py is up-to-date
+
+---
+ run_unittests.py | 32 ++++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/run_unittests.py b/run_unittests.py
+index 820b705b54..2c03a3e75c 100755
+--- a/run_unittests.py
++++ b/run_unittests.py
+@@ -1485,6 +1485,38 @@ def test_all_functions_defined_in_ast_interpreter(self):
+ astint = AstInterpreter('.', '', '')
+ self.assertEqual(set(interp.funcs.keys()), set(astint.funcs.keys()))
+
++ def test_mesondata_is_up_to_date(self):
++ from mesonbuild.mesondata import mesondata
++ err_msg = textwrap.dedent('''
++
++ ###########################################################
++ ### mesonbuild.mesondata is not up-to-date ###
++ ### Please regenerate it by running tools/gen_data.py ###
++ ###########################################################
++
++ ''')
++
++ root_dir = Path(__file__).resolve().parent
++ mesonbuild_dir = root_dir / 'mesonbuild'
++
++ data_dirs = mesonbuild_dir.glob('**/data')
++ data_files = [] # type: T.List[T.Tuple(str, str)]
++
++ for i in data_dirs:
++ for p in i.iterdir():
++ data_files += [(p.relative_to(mesonbuild_dir).as_posix(), hashlib.sha256(p.read_bytes()).hexdigest())]
++
++ from pprint import pprint
++ current_files = set(mesondata.keys())
++ scanned_files = set([x[0] for x in data_files])
++
++ self.assertSetEqual(current_files, scanned_files, err_msg + 'Data files were added or removed\n')
++ errors = []
++ for i in data_files:
++ if mesondata[i[0]].sha256sum != i[1]:
++ errors += [i[0]]
++
++ self.assertListEqual(errors, [], err_msg + 'Files were changed')
+
+ class BasePlatformTests(unittest.TestCase):
+ prefix = '/usr'
--- /dev/null
+From 1ce4258c219fe08b6d6eaa6aa944f27d91d054cb Mon Sep 17 00:00:00 2001
+From: James Hilliard <james.hilliard1@gmail.com>
+Date: Sat, 18 Jul 2020 17:01:33 -0600
+Subject: [PATCH] backends: fix rpath match pattern
+
+Since -Wl,-rpath= is not the only valid rpath ldflags syntax we
+need to try and match all valid rpath ldflags.
+
+In addition we should prevent -Wl,--just-symbols from being used to
+set rpath due to inconsistent compiler support.
+
+Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
+---
+ mesonbuild/backend/backends.py | 30 ++++++++++++++++++++++++--
+ run_unittests.py | 39 +++++++++++++++++++++++-----------
+ 2 files changed, 55 insertions(+), 14 deletions(-)
+
+diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
+index cfd3a397fd..e053f67e6b 100644
+--- a/mesonbuild/backend/backends.py
++++ b/mesonbuild/backend/backends.py
+@@ -14,6 +14,7 @@
+
+ from collections import OrderedDict
+ from functools import lru_cache
++from pathlib import Path
+ import enum
+ import json
+ import os
+@@ -455,10 +456,35 @@ def get_external_rpath_dirs(self, target):
+ args.extend(self.environment.coredata.get_external_link_args(target.for_machine, lang))
+ except Exception:
+ pass
++ # Match rpath formats:
++ # -Wl,-rpath=
++ # -Wl,-rpath,
++ rpath_regex = re.compile(r'-Wl,-rpath[=,]([^,]+)')
++ # Match solaris style compat runpath formats:
++ # -Wl,-R
++ # -Wl,-R,
++ runpath_regex = re.compile(r'-Wl,-R[,]?([^,]+)')
++ # Match symbols formats:
++ # -Wl,--just-symbols=
++ # -Wl,--just-symbols,
++ symbols_regex = re.compile(r'-Wl,--just-symbols[=,]([^,]+)')
+ for arg in args:
+- if arg.startswith('-Wl,-rpath='):
+- for dir in arg.replace('-Wl,-rpath=','').split(':'):
++ rpath_match = rpath_regex.match(arg)
++ if rpath_match:
++ for dir in rpath_match.group(1).split(':'):
+ dirs.add(dir)
++ runpath_match = runpath_regex.match(arg)
++ if runpath_match:
++ for dir in runpath_match.group(1).split(':'):
++ # The symbols arg is an rpath if the path is a directory
++ if Path(dir).is_dir():
++ dirs.add(dir)
++ symbols_match = symbols_regex.match(arg)
++ if symbols_match:
++ for dir in symbols_match.group(1).split(':'):
++ # Prevent usage of --just-symbols to specify rpath
++ if Path(dir).is_dir():
++ raise MesonException('Invalid arg for --just-symbols, {} is a directory.'.format(dir))
+ return dirs
+
+ def rpaths_for_bundled_shared_libraries(self, target, exclude_system=True):
+diff --git a/run_unittests.py b/run_unittests.py
+index b5294b9f82..73131c75b7 100755
+--- a/run_unittests.py
++++ b/run_unittests.py
+@@ -6451,19 +6451,34 @@ def test_global_rpath(self):
+ self.init(yonder_dir)
+ self.build()
+ self.install(use_destdir=False)
+- self.new_builddir()
+
+- # Build an app that uses that installed library.
+- # Supply the rpath to the installed library via LDFLAGS
+- # (as systems like buildroot and guix are wont to do)
+- # and verify install preserves that rpath.
+- env = {'LDFLAGS': '-Wl,-rpath=' + yonder_libdir,
+- 'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
+- self.init(testdir, override_envvars=env)
+- self.build()
+- self.install(use_destdir=False)
+- got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
+- self.assertEqual(got_rpath, yonder_libdir)
++ # Since rpath has multiple valid formats we need to
++ # test that they are all properly used.
++ rpath_formats = [
++ ('-Wl,-rpath=', False),
++ ('-Wl,-rpath,', False),
++ ('-Wl,--just-symbols=', True),
++ ('-Wl,--just-symbols,', True),
++ ('-Wl,-R', False),
++ ('-Wl,-R,', False)
++ ]
++ for rpath_format, exception in rpath_formats:
++ # Build an app that uses that installed library.
++ # Supply the rpath to the installed library via LDFLAGS
++ # (as systems like buildroot and guix are wont to do)
++ # and verify install preserves that rpath.
++ self.new_builddir()
++ env = {'LDFLAGS': rpath_format + yonder_libdir,
++ 'PKG_CONFIG_PATH': os.path.join(yonder_libdir, 'pkgconfig')}
++ if exception:
++ with self.assertRaises(subprocess.CalledProcessError):
++ self.init(testdir, override_envvars=env)
++ break
++ self.init(testdir, override_envvars=env)
++ self.build()
++ self.install(use_destdir=False)
++ got_rpath = get_rpath(os.path.join(yonder_prefix, 'bin/rpathified'))
++ self.assertEqual(got_rpath, yonder_libdir, rpath_format)
+
+ @skip_if_not_base_option('b_sanitize')
+ def test_pch_with_address_sanitizer(self):
include $(TOPDIR)/rules.mk
PKG_NAME:=ksmbd
-PKG_VERSION:=3.2.2
+PKG_VERSION:=3.2.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/cifsd-team/cifsd/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=16ad304c09d5f04ddbe99d21ca9df8a9a6d8e35b21ff0e205f212f8c545b979b
+PKG_HASH:=a7beeb0e804b361adf2b79dcd98ccf4b92b2c1fa8a65a39dd4fbb63479cdf7cd
PKG_MAINTAINER:=Andy Walsh <andy.walsh44+github@gmail.com>
PKG_LICENSE:=GPL-2.0-or-later
include $(TOPDIR)/rules.mk
PKG_NAME:=luaposix
-PKG_VERSION:=34.1.1
+PKG_VERSION:=35.0
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://codeload.github.com/$(PKG_NAME)/$(PKG_NAME)/tar.gz/v$(PKG_VERSION)?
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=7948f4ac8b953172e928753632e37ad97cc3014df74b524fe7839f71216a7e90
+PKG_HASH:=a4edf2f715feff65acb009e8d1689e57ec665eb79bc36a6649fae55eafd56809
PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=COPYING
+++ /dev/null
-diff --git i/lib/posix/init.lua w/lib/posix/init.lua
-index c17693a..d4db923 100644
---- i/lib/posix/init.lua
-+++ w/lib/posix/init.lua
-@@ -325,14 +325,6 @@ do
- end
- end
- end
--
-- -- Inject deprecated APIs (overwriting submodules) for backwards compatibility.
-- for k, v in next, require 'posix.deprecated' do
-- M[k] = v
-- end
-- for k, v in next, require 'posix.compat' do
-- M[k] = v
-- end
- end
-
-
--- /dev/null
+diff --git a/lib/posix/init.lua b/lib/posix/init.lua
+index cf51bf3..e66af04 100644
+--- a/lib/posix/init.lua
++++ b/lib/posix/init.lua
+@@ -325,14 +325,6 @@ do
+ end
+ end
+ end
+-
+- -- Inject deprecated APIs (overwriting submodules) for backwards compatibility.
+- for k, v in next, (require 'posix.deprecated') do
+- M[k] = v
+- end
+- for k, v in next, (require 'posix.compat') do
+- M[k] = v
+- end
+ end
+
+
include $(TOPDIR)/rules.mk
PKG_NAME:=pymysql
-PKG_VERSION:=0.9.3
-PKG_RELEASE:=3
+PKG_VERSION:=0.10.0
+PKG_RELEASE:=1
PYPI_NAME:=PyMySQL
-PKG_HASH:=d8c059dcd81dedb85a9f034d5e22dcb4442c0b201908bede99e306d65ea7c8e7
+PKG_HASH:=e14070bc84e050e0f80bf6063e31d276f03a0bb4d46b9eca2854566c4ae19837
PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
PKG_LICENSE:=MIT
include $(TOPDIR)/rules.mk
PKG_NAME:=python-cryptography
-PKG_VERSION:=2.9.2
-PKG_RELEASE:=2
+PKG_VERSION:=3.0
+PKG_RELEASE:=1
PYPI_NAME:=cryptography
-PKG_HASH:=a0c30272fb4ddda5f5ffc1089d7405b7a71b0b0f51993cb4e5dbb4590b2fc229
+PKG_HASH:=8e924dbc025206e97756e8903039662aa58aa9ba357d8e1d8fc29e3092322053
PKG_LICENSE:=Apache-2.0 BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE.APACHE LICENSE.BSD
URL:=https://github.com/pyca/cryptography
DEPENDS:= \
+libopenssl \
- +python3 \
+ +python3-light \
+ +python3-email \
+ +python3-openssl \
+ +python3-urllib \
+python3-cffi \
+python3-six
endef
+++ /dev/null
-From eec1f066476eccf7135af0a4cfef9e1c883795b3 Mon Sep 17 00:00:00 2001
-From: Paul Kehrer <paul.l.kehrer@gmail.com>
-Date: Mon, 25 Feb 2019 10:55:16 +0800
-Subject: [PATCH] remove NPN bindings -- you should be using ALPN!
-
-pyOpenSSL consumed these, but we've marked it as deprecated and it
-already handles the case where the bindings are not available.
----
- src/_cffi_src/openssl/ssl.py | 16 ----------------
- 1 file changed, 16 deletions(-)
-
-diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
-index da21f3ce90..0e8610f988 100644
---- a/src/_cffi_src/openssl/ssl.py
-+++ b/src/_cffi_src/openssl/ssl.py
-@@ -431,25 +431,9 @@
-
- long SSL_session_reused(SSL *);
-
--void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *,
-- int (*)(SSL *,
-- const unsigned char **,
-- unsigned int *,
-- void *),
-- void *);
--void SSL_CTX_set_next_proto_select_cb(SSL_CTX *,
-- int (*)(SSL *,
-- unsigned char **,
-- unsigned char *,
-- const unsigned char *,
-- unsigned int,
-- void *),
-- void *);
- int SSL_select_next_proto(unsigned char **, unsigned char *,
- const unsigned char *, unsigned int,
- const unsigned char *, unsigned int);
--void SSL_get0_next_proto_negotiated(const SSL *,
-- const unsigned char **, unsigned *);
-
- int sk_SSL_CIPHER_num(Cryptography_STACK_OF_SSL_CIPHER *);
- const SSL_CIPHER *sk_SSL_CIPHER_value(Cryptography_STACK_OF_SSL_CIPHER *, int);
+++ /dev/null
-From d7293d64d503fcbde442d69a3e11c55bf6f1374a Mon Sep 17 00:00:00 2001
-From: Paul Kehrer <paul.l.kehrer@gmail.com>
-Date: Mon, 25 Feb 2019 11:05:46 +0800
-Subject: [PATCH] set Cryptography_HAS_NEXTPROTONEG to 0 for pyOpenSSL
-
-we can remove this symbol in like...5 years.
----
- src/_cffi_src/openssl/ssl.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
-index 0e8610f988..e3a7790ee1 100644
---- a/src/_cffi_src/openssl/ssl.py
-+++ b/src/_cffi_src/openssl/ssl.py
-@@ -623,7 +623,7 @@
- static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING = 1;
- static const long Cryptography_HAS_SSL_OP_NO_TICKET = 1;
- static const long Cryptography_HAS_SSL_SET_SSL_CTX = 1;
--static const long Cryptography_HAS_NEXTPROTONEG = 1;
-+static const long Cryptography_HAS_NEXTPROTONEG = 0;
-
- /* SSL_get0_param was added in OpenSSL 1.0.2. */
- #if CRYPTOGRAPHY_OPENSSL_LESS_THAN_102 && !CRYPTOGRAPHY_LIBRESSL_27_OR_GREATER
+++ /dev/null
-From b0b50b6bbbdf3abadc70b64c56e25b872721a7f3 Mon Sep 17 00:00:00 2001
-From: Paul Kehrer <paul.l.kehrer@gmail.com>
-Date: Mon, 25 Feb 2019 11:12:10 +0800
-Subject: [PATCH] remove another NPN related definition
-
----
- src/_cffi_src/openssl/ssl.py | 2 --
- 1 file changed, 2 deletions(-)
-
-diff --git a/src/_cffi_src/openssl/ssl.py b/src/_cffi_src/openssl/ssl.py
-index e3a7790ee1..f98f576838 100644
---- a/src/_cffi_src/openssl/ssl.py
-+++ b/src/_cffi_src/openssl/ssl.py
-@@ -139,8 +139,6 @@
- static const long TLS_ST_BEFORE;
- static const long TLS_ST_OK;
-
--static const long OPENSSL_NPN_NEGOTIATED;
--
- typedef ... SSL_METHOD;
- typedef ... SSL_CTX;
-
include $(TOPDIR)/rules.mk
PKG_NAME:=python-lxml
-PKG_VERSION:=4.5.1
+PKG_VERSION:=4.5.2
PKG_RELEASE:=1
PYPI_NAME:=lxml
-PKG_HASH:=27ee0faf8077c7c1a589573b1450743011117f1aa1a91d5ae776bbc5ca6070f2
+PKG_HASH:=cdc13a1682b2a6241080745b1953719e7fe0850b40a5c71ca574f090a1391df6
PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSES.txt
include $(TOPDIR)/rules.mk
PKG_NAME:=python-simplejson
-PKG_VERSION:=3.17.0
-PKG_RELEASE:=2
+PKG_VERSION:=3.17.2
+PKG_RELEASE:=1
PKG_LICENSE:=MIT
PKG_CPE_ID:=cpe:/a:simplejson_project:simplejson
PYPI_NAME:=simplejson
-PKG_HASH:=2b4b2b738b3b99819a17feaf118265d0753d5536049ea570b3c43b51c4701e81
+PKG_HASH:=75ecc79f26d99222a084fbdd1ce5aad3ac3a8bd535cd9059528452da38b68841
include ../pypi.mk
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/rules.mk
PKG_NAME:=python-urllib3
-PKG_VERSION:=1.25.9
+PKG_VERSION:=1.25.10
PKG_RELEASE:=1
PKG_MAINTAINER:=Josef Schlehofer <pepe.schlehofer@gmail.com>
PKG_CPE_ID:=cpe:/a:urllib3_project:urllib3
PYPI_NAME:=urllib3
-PKG_HASH:=3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527
+PKG_HASH:=91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a
include ../pypi.mk
include $(INCLUDE_DIR)/package.mk
LDSHARED="$(HOSTCC) -shared" \
CFLAGS="$(HOST_CFLAGS)" \
CPPFLAGS="$(HOST_CPPFLAGS) -I$(HOST_PYTHON3_INC_DIR)" \
- LDFLAGS="$(HOST_LDFLAGS) -lpython$(PYTHON3_VERSION) -Wl$(comma)-rpath=$(STAGING_DIR_HOSTPKG)/lib" \
+ LDFLAGS="$(HOST_LDFLAGS) -lpython$(PYTHON3_VERSION) -Wl$(comma)-rpath$(comma)$(STAGING_DIR_HOSTPKG)/lib" \
PYTHONPATH="$(HOST_PYTHON3PATH)" \
PYTHONDONTWRITEBYTECODE=0 \
PYTHONOPTIMIZE=""
include $(TOPDIR)/rules.mk
PKG_NAME:=maxminddb
-PKG_VERSION:=1.5.4
+PKG_VERSION:=2.0.1
PKG_RELEASE:=1
PYPI_NAME:=$(PKG_NAME)
-PKG_HASH:=f4d28823d9ca23323d113dc7af8db2087aa4f657fafc64ff8f7a8afda871425b
+PKG_HASH:=ed42434c3b88229a6a3c0e9e58c5a0f4fc17dcdde42dedcbcf225db8f04e8848
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz>
PKG_LICENSE:=Apache-2.0
# Note: keep in sync with setuptools & pip
PYTHON3_VERSION_MAJOR:=3
PYTHON3_VERSION_MINOR:=8
-PYTHON3_VERSION_MICRO:=4
+PYTHON3_VERSION_MICRO:=5
PYTHON3_VERSION:=$(PYTHON3_VERSION_MAJOR).$(PYTHON3_VERSION_MINOR)
include ../python3-version.mk
PKG_NAME:=python3
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_VERSION:=$(PYTHON3_VERSION).$(PYTHON3_VERSION_MICRO)
PKG_SOURCE:=Python-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.python.org/ftp/python/$(PKG_VERSION)
-PKG_HASH:=5f41968a95afe9bc12192d7e6861aab31e80a46c46fa59d3d837def6a4cd4d37
+PKG_HASH:=e3003ed57db17e617acb382b0cade29a248c6026b1bd8aad1f976e9af66a83b0
PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>, Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=Python/2.0
define Package/python3-distutils
$(call Package/python3/Default)
TITLE:=Python $(PYTHON3_VERSION) distutils module
- DEPENDS:=+python3-light
+ DEPENDS:=+python3-light +python3-email
endef
$(eval $(call Py3BasePackage,python3-distutils, \
+++ /dev/null
-From f56c75ed53dcad4d59dff4377ae463d6b96acd3e Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Mon, 13 Jul 2020 06:05:44 -0700
-Subject: [PATCH] bpo-41288: Fix a crash in unpickling invalid NEWOBJ_EX.
- (GH-21458)
-
-Automerge-Triggered-By: @tiran
-(cherry picked from commit 4f309abf55f0e6f8950ac13d6ec83c22b8d47bf8)
-
-Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
----
- Lib/test/pickletester.py | 18 ++++++++++++
- .../2020-07-13-15-06-35.bpo-41288.8mn5P-.rst | 2 ++
- Modules/_pickle.c | 29 ++++++++++++++-----
- 3 files changed, 41 insertions(+), 8 deletions(-)
- create mode 100644 Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst
-
-diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py
-index 9401043d78d18..ff7bbb0c8a9bf 100644
---- a/Lib/test/pickletester.py
-+++ b/Lib/test/pickletester.py
-@@ -1170,6 +1170,24 @@ def test_compat_unpickle(self):
- self.assertIs(type(unpickled), collections.UserDict)
- self.assertEqual(unpickled, collections.UserDict({1: 2}))
-
-+ def test_bad_reduce(self):
-+ self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0)
-+ self.check_unpickling_error(TypeError, b'N)R.')
-+ self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.')
-+
-+ def test_bad_newobj(self):
-+ error = (pickle.UnpicklingError, TypeError)
-+ self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0)
-+ self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.')
-+ self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.')
-+
-+ def test_bad_newobj_ex(self):
-+ error = (pickle.UnpicklingError, TypeError)
-+ self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0)
-+ self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.')
-+ self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.')
-+ self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.')
-+
- def test_bad_stack(self):
- badpickles = [
- b'.', # STOP
-diff --git a/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst
-new file mode 100644
-index 0000000000000..3c3adbabf16ff
---- /dev/null
-+++ b/Misc/NEWS.d/next/Library/2020-07-13-15-06-35.bpo-41288.8mn5P-.rst
-@@ -0,0 +1,2 @@
-+Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now
-+UnpicklingError instead of crashing.
-diff --git a/Modules/_pickle.c b/Modules/_pickle.c
-index 55affb2c7c479..42ce62fc7cdf4 100644
---- a/Modules/_pickle.c
-+++ b/Modules/_pickle.c
-@@ -5988,23 +5988,30 @@ load_newobj_ex(UnpicklerObject *self)
- }
-
- if (!PyType_Check(cls)) {
-- Py_DECREF(kwargs);
-- Py_DECREF(args);
- PyErr_Format(st->UnpicklingError,
- "NEWOBJ_EX class argument must be a type, not %.200s",
- Py_TYPE(cls)->tp_name);
-- Py_DECREF(cls);
-- return -1;
-+ goto error;
- }
-
- if (((PyTypeObject *)cls)->tp_new == NULL) {
-- Py_DECREF(kwargs);
-- Py_DECREF(args);
-- Py_DECREF(cls);
- PyErr_SetString(st->UnpicklingError,
- "NEWOBJ_EX class argument doesn't have __new__");
-- return -1;
-+ goto error;
-+ }
-+ if (!PyTuple_Check(args)) {
-+ PyErr_Format(st->UnpicklingError,
-+ "NEWOBJ_EX args argument must be a tuple, not %.200s",
-+ Py_TYPE(args)->tp_name);
-+ goto error;
-+ }
-+ if (!PyDict_Check(kwargs)) {
-+ PyErr_Format(st->UnpicklingError,
-+ "NEWOBJ_EX kwargs argument must be a dict, not %.200s",
-+ Py_TYPE(kwargs)->tp_name);
-+ goto error;
- }
-+
- obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs);
- Py_DECREF(kwargs);
- Py_DECREF(args);
-@@ -6014,6 +6021,12 @@ load_newobj_ex(UnpicklerObject *self)
- }
- PDATA_PUSH(self->stack, obj, -1);
- return 0;
-+
-+error:
-+ Py_DECREF(kwargs);
-+ Py_DECREF(args);
-+ Py_DECREF(cls);
-+ return -1;
- }
-
- static int
+++ /dev/null
-From c55479556db015f48fc8bbca17f64d3e65598559 Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Wed, 15 Jul 2020 05:30:53 -0700
-Subject: [PATCH] [3.8] bpo-39017: Avoid infinite loop in the tarfile module
- (GH-21454) (GH-21483)
-
-Avoid infinite loop when reading specially crafted TAR files using the tarfile module
-(CVE-2019-20907).
-(cherry picked from commit 5a8d121a1f3ef5ad7c105ee378cc79a3eac0c7d4)
-
-
-Co-authored-by: Rishi <rishi_devan@mail.com>
-
-Automerge-Triggered-By: @encukou
----
- Lib/tarfile.py | 2 ++
- Lib/test/recursion.tar | Bin 0 -> 516 bytes
- Lib/test/test_tarfile.py | 7 +++++++
- .../2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst | 1 +
- 4 files changed, 10 insertions(+)
- create mode 100644 Lib/test/recursion.tar
- create mode 100644 Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst
-
-diff --git a/Lib/tarfile.py b/Lib/tarfile.py
-index d31b9cbb51d65..7a69e1b1aa544 100755
---- a/Lib/tarfile.py
-+++ b/Lib/tarfile.py
-@@ -1241,6 +1241,8 @@ def _proc_pax(self, tarfile):
-
- length, keyword = match.groups()
- length = int(length)
-+ if length == 0:
-+ raise InvalidHeaderError("invalid header")
- value = buf[match.end(2) + 1:match.start(1) + length - 1]
-
- # Normally, we could just use "utf-8" as the encoding and "strict"
-diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
-index 15324a4e48819..b512168d6ea87 100644
---- a/Lib/test/test_tarfile.py
-+++ b/Lib/test/test_tarfile.py
-@@ -397,6 +397,13 @@ def test_premature_end_of_archive(self):
- with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"):
- tar.extractfile(t).read()
-
-+ def test_length_zero_header(self):
-+ # bpo-39017 (CVE-2019-20907): reading a zero-length header should fail
-+ # with an exception
-+ with self.assertRaisesRegex(tarfile.ReadError, "file could not be opened successfully"):
-+ with tarfile.open(support.findfile('recursion.tar')) as tar:
-+ pass
-+
- class MiscReadTestBase(CommonReadTest):
- def requires_name_attribute(self):
- pass
-diff --git a/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst
-new file mode 100644
-index 0000000000000..ad26676f8b856
---- /dev/null
-+++ b/Misc/NEWS.d/next/Library/2020-07-12-22-16-58.bpo-39017.x3Cg-9.rst
-@@ -0,0 +1 @@
-+Avoid infinite loop when reading specially crafted TAR files using the tarfile module (CVE-2019-20907).
+++ /dev/null
-From 668d321476d974c4f51476b33aaca870272523bf Mon Sep 17 00:00:00 2001
-From: "Miss Islington (bot)"
- <31488909+miss-islington@users.noreply.github.com>
-Date: Sat, 18 Jul 2020 13:39:12 -0700
-Subject: [PATCH] bpo-39603: Prevent header injection in http methods
- (GH-18485)
-
-reject control chars in http method in http.client.putrequest to prevent http header injection
-(cherry picked from commit 8ca8a2e8fb068863c1138f07e3098478ef8be12e)
-
-Co-authored-by: AMIR <31338382+amiremohamadi@users.noreply.github.com>
----
- Lib/http/client.py | 15 +++++++++++++
- Lib/test/test_httplib.py | 22 +++++++++++++++++++
- .../2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst | 2 ++
- 3 files changed, 39 insertions(+)
- create mode 100644 Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst
-
-diff --git a/Lib/http/client.py b/Lib/http/client.py
-index 019380a720318..c2ad0471bfee5 100644
---- a/Lib/http/client.py
-+++ b/Lib/http/client.py
-@@ -147,6 +147,10 @@
- # _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$")
- # We are more lenient for assumed real world compatibility purposes.
-
-+# These characters are not allowed within HTTP method names
-+# to prevent http header injection.
-+_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]')
-+
- # We always set the Content-Length header for these methods because some
- # servers will otherwise respond with a 411
- _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
-@@ -1087,6 +1091,8 @@ def putrequest(self, method, url, skip_host=False,
- else:
- raise CannotSendRequest(self.__state)
-
-+ self._validate_method(method)
-+
- # Save the method for use later in the response phase
- self._method = method
-
-@@ -1177,6 +1183,15 @@ def _encode_request(self, request):
- # ASCII also helps prevent CVE-2019-9740.
- return request.encode('ascii')
-
-+ def _validate_method(self, method):
-+ """Validate a method name for putrequest."""
-+ # prevent http header injection
-+ match = _contains_disallowed_method_pchar_re.search(method)
-+ if match:
-+ raise ValueError(
-+ f"method can't contain control characters. {method!r} "
-+ f"(found at least {match.group()!r})")
-+
- def _validate_path(self, url):
- """Validate a url for putrequest."""
- # Prevent CVE-2019-9740.
-diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
-index 8f0e27a1fb836..5a5fcecbc9c15 100644
---- a/Lib/test/test_httplib.py
-+++ b/Lib/test/test_httplib.py
-@@ -364,6 +364,28 @@ def test_headers_debuglevel(self):
- self.assertEqual(lines[3], "header: Second: val2")
-
-
-+class HttpMethodTests(TestCase):
-+ def test_invalid_method_names(self):
-+ methods = (
-+ 'GET\r',
-+ 'POST\n',
-+ 'PUT\n\r',
-+ 'POST\nValue',
-+ 'POST\nHOST:abc',
-+ 'GET\nrHost:abc\n',
-+ 'POST\rRemainder:\r',
-+ 'GET\rHOST:\n',
-+ '\nPUT'
-+ )
-+
-+ for method in methods:
-+ with self.assertRaisesRegex(
-+ ValueError, "method can't contain control characters"):
-+ conn = client.HTTPConnection('example.com')
-+ conn.sock = FakeSocket(None)
-+ conn.request(method=method, url="/")
-+
-+
- class TransferEncodingTest(TestCase):
- expected_body = b"It's just a flesh wound"
-
-diff --git a/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst
-new file mode 100644
-index 0000000000000..990affc3edd9d
---- /dev/null
-+++ b/Misc/NEWS.d/next/Security/2020-02-12-14-17-39.bpo-39603.Gt3RSg.rst
-@@ -0,0 +1,2 @@
-+Prevent http header injection by rejecting control characters in
-+http.client.putrequest(...).
include $(TOPDIR)/rules.mk
PKG_NAME:=vala
-PKG_VERSION:=0.48.6
-PKG_RELEASE:=1
+PKG_VERSION:=0.48.7
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNOME/vala/0.48
-PKG_HASH:=d18d08ed030ce0e0f044f4c15c9df3c25b15beaf8700e45e43b736a6debf9707
+PKG_HASH:=28de33e28da24500cc1675c3a6ced1301c9a6a5e6dd06193569001f9ce9a5c53
PKG_MAINTAINER:=
PKG_LICENSE:=LGPL-2.1-or-later
--without-cgraph
HOST_LDFLAGS += \
- -Wl,--rpath-link=$(STAGING_DIR_HOSTPKG)/lib
+ -Wl,--rpath,$(STAGING_DIR_HOSTPKG)/lib
$(eval $(call HostBuild))
$(eval $(call BuildPackage,vala))
include $(TOPDIR)/rules.mk
PKG_NAME:=glib2
-PKG_VERSION:=2.58.3
-PKG_RELEASE:=5
+PKG_VERSION:=2.65.0
+PKG_RELEASE:=4
PKG_SOURCE:=glib-$(PKG_VERSION).tar.xz
-PKG_BUILD_DIR:=$(BUILD_DIR)/glib-$(PKG_VERSION)
-PKG_SOURCE_URL:=@GNOME/glib/2.58
-PKG_HASH:=8f43c31767e88a25da72b52a40f3301fefc49a665b56dc10ee7cc9565cbe7481
-
-PKG_BUILD_PARALLEL:=1
-HOST_BUILD_PARALLEL:=1
-PKG_BUILD_DEPENDS:=gettext
-HOST_BUILD_DEPENDS:=gettext-full/host libiconv/host libffi/host
-PKG_INSTALL:=1
+PKG_SOURCE_URL:=@GNOME/glib/2.65
+PKG_HASH:=b041e63cd0ac1fccb486374022ade040d907aad29b278e27d9e43e9294a6e7a3
+PKG_MAINTAINER:=Peter Wagner <tripolar@gmx.at>
+PKG_LICENSE:=LGPL-2.1-or-later
+PKG_LICENSE_FILES:=COPYING
PKG_CPE_ID:=cpe:/a:gnome:glib
-PKG_FIXUP:=autoreconf
-
+PKG_BUILD_DIR:=$(BUILD_DIR)/glib-$(PKG_VERSION)
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/glib-$(PKG_VERSION)
+PKG_BUILD_DEPENDS:=meson/host gettext-full libiconv/host
+HOST_BUILD_DEPENDS:=meson/host gettext-full/host libiconv/host libffi/host
+PKG_INSTALL:=1
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
+include ../../devel/meson/meson.mk
define Package/glib2
SECTION:=libs
CATEGORY:=Libraries
DEPENDS:=$(ICONV_DEPENDS) $(INTL_DEPENDS) +zlib +libpthread +libffi +libattr
TITLE:=glib 2.0
- MAINTAINER:=Peter Wagner <tripolar@gmx.at>
URL:=http://www.gtk.org/
endef
The GLib library of C routines
endef
-TARGET_CFLAGS += $(FPIC) -ffunction-sections -fdata-sections -flto
-
-HOST_CONFIGURE_ARGS += \
- --disable-libelf \
- --disable-selinux \
- --with-libiconv=gnu \
- --with-pcre=internal \
- --disable-libmount
-
-CONFIGURE_ARGS += \
- --enable-shared \
- --enable-static \
- --disable-debug \
- --disable-selinux \
- --disable-libmount \
- --disable-fam \
- --disable-gtk-doc-html \
- --disable-man \
- --disable-compile-warnings \
- --with-libiconv=gnu \
- --with-pcre=internal
-
-CONFIGURE_VARS += \
- glib_cv_stack_grows=no \
- glib_cv_uscore=no \
- ac_cv_path_GLIB_GENMARSHAL=$(STAGING_DIR_HOSTPKG)/bin/glib-genmarshal \
- ac_cv_func_mmap_fixed_mapped=yes \
- ac_cv_func_posix_getpwuid_r=yes \
- ac_cv_func_posix_getgrgid_r=yes
+HOST_LDFLAGS += -liconv -Wl,-rpath,$(STAGING_DIR_HOSTPKG)/lib
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections -liconv $(if $(INTL_FULL),-lintl)
+
+COMP_ARGS= \
+ -Diconv=external \
+ -Dselinux=disabled \
+ -Dlibmount=disabled \
+ -Dinternal_pcre=true \
+ -Dman=false \
+ -Ddtrace=false \
+ -Dsystemtap=false \
+ -Dgtk_doc=false \
+ -Dbsymbolic_functions=true \
+ -Dforce_posix_threads=true \
+ -Dfam=false \
+ -Dinstalled_tests=false \
+ -Dnls=$(if $(CONFIG_BUILD_NLS),en,dis)abled \
+ -Doss_fuzz=disabled \
+ -Dglib_assert=false \
+ -Dglib_checks=false
+
+MESON_HOST_ARGS += $(COMP_ARGS) -Dxattr=false
+MESON_ARGS += $(COMP_ARGS) -Dxattr=true -Db_lto=true
+
+# hack to compile static libraries
+define Build/Compile
+ $(call Build/Compile/Meson)
+ $(call Ninja,-C $(MESON_BUILD_DIR) install,DESTDIR="$(PKG_INSTALL_DIR)")
+ $(call Meson, \
+ --reconfigure \
+ --buildtype plain \
+ --native-file $(PKG_BUILD_DIR)/openwrt-native.txt \
+ --cross-file $(PKG_BUILD_DIR)/openwrt-cross.txt \
+ -Ddefault_library=static \
+ $(MESON_ARGS) \
+ $(MESON_BUILD_DIR) \
+ $(PKG_BUILD_DIR), \
+ $(MESON_VARS))
+endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/bin
$(1)/usr/lib/
$(CP) \
- $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a,la} \
+ $(PKG_INSTALL_DIR)/usr/lib/*.{so*,a} \
$(1)/usr/lib/
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
$(INSTALL_DATA) \
$(PKG_INSTALL_DIR)/usr/share/aclocal/*.m4 \
$(2)/share/aclocal/
+
+ $(INSTALL_DIR) $(1)/usr/share/glib-2.0
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/share/glib-2.0/codegen \
+ $(1)/usr/share/glib-2.0/
endef
define Package/glib2/install
+++ /dev/null
-From d8f8f4d637ce43f8699ba94c9b7648beda0ca174 Mon Sep 17 00:00:00 2001
-From: Ondrej Holy <oholy@redhat.com>
-Date: Thu, 23 May 2019 10:41:53 +0200
-Subject: [PATCH] gfile: Limit access to files when copying
-
-file_copy_fallback creates new files with default permissions and
-set the correct permissions after the operation is finished. This
-might cause that the files can be accessible by more users during
-the operation than expected. Use G_FILE_CREATE_PRIVATE for the new
-files to limit access to those files.
----
- gio/gfile.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/gio/gfile.c b/gio/gfile.c
-index 24b136d80..74b58047c 100644
---- a/gio/gfile.c
-+++ b/gio/gfile.c
-@@ -3284,12 +3284,12 @@ file_copy_fallback (GFile *source,
- out = (GOutputStream*)_g_local_file_output_stream_replace (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
- FALSE, NULL,
- flags & G_FILE_COPY_BACKUP,
-- G_FILE_CREATE_REPLACE_DESTINATION,
-- info,
-+ G_FILE_CREATE_REPLACE_DESTINATION |
-+ G_FILE_CREATE_PRIVATE, info,
- cancellable, error);
- else
- out = (GOutputStream*)_g_local_file_output_stream_create (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
-- FALSE, 0, info,
-+ FALSE, G_FILE_CREATE_PRIVATE, info,
- cancellable, error);
- }
- else if (flags & G_FILE_COPY_OVERWRITE)
-@@ -3297,12 +3297,13 @@ file_copy_fallback (GFile *source,
- out = (GOutputStream *)g_file_replace (destination,
- NULL,
- flags & G_FILE_COPY_BACKUP,
-- G_FILE_CREATE_REPLACE_DESTINATION,
-+ G_FILE_CREATE_REPLACE_DESTINATION |
-+ G_FILE_CREATE_PRIVATE,
- cancellable, error);
- }
- else
- {
-- out = (GOutputStream *)g_file_create (destination, 0, cancellable, error);
-+ out = (GOutputStream *)g_file_create (destination, G_FILE_CREATE_PRIVATE, cancellable, error);
- }
-
- if (!out)
---
-2.21.0
-
+++ /dev/null
---- /dev/null
-+++ b/gtk-doc.make
-@@ -0,0 +1,2 @@
-+EXTRA_DIST =
-+CLEANFILES =
--- /dev/null
+--- a/gio/meson.build
++++ b/gio/meson.build
+@@ -881,20 +881,6 @@ endif
+
+ # Dependencies used by executables below
+ have_libelf = false
+-libelf = dependency('libelf', version : '>= 0.8.12', required : false)
+-if libelf.found()
+- have_libelf = true
+-else
+- # This fallback is necessary on *BSD. elfutils isn't the only libelf
+- # implementation, and *BSD usually includes their own libelf as a system
+- # library which doesn't have a corresponding .pc file.
+- libelf = cc.find_library('elf', required : false)
+- have_libelf = libelf.found()
+- have_libelf = have_libelf and cc.has_function('elf_begin', dependencies : libelf)
+- have_libelf = have_libelf and cc.has_function('elf_getshdrstrndx', dependencies : libelf)
+- have_libelf = have_libelf and cc.has_function('elf_getshdrnum', dependencies : libelf)
+- have_libelf = have_libelf and cc.has_header('libelf.h')
+-endif
+
+ if have_libelf
+ glib_conf.set('HAVE_LIBELF', 1)
+++ /dev/null
---- a/gio/gthreadedresolver.c
-+++ b/gio/gthreadedresolver.c
-@@ -873,6 +873,8 @@ do_lookup_records (GTask *task,
-
- #ifdef HAVE_RES_NQUERY
-
-+#ifdef HAVE_RES_NQUERY
-+
- #if defined(HAVE_RES_NDESTROY)
- res_ndestroy (&res);
- #elif defined(HAVE_RES_NCLOSE)
-@@ -883,6 +885,8 @@ do_lookup_records (GTask *task,
-
- #endif /* HAVE_RES_NQUERY */
-
-+#endif
-+
- #else
-
- DNS_STATUS status;
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -94,7 +94,7 @@ installed_tests_template = files('template.test.in')
+ installed_tests_template_tap = files('template-tap.test.in')
+
+ # Don’t build the tests unless we can run them (either natively, in an exe wrapper, or by installing them for later use)
+-build_tests = not meson.is_cross_build() or (meson.is_cross_build() and meson.has_exe_wrapper()) or installed_tests_enabled
++build_tests = false
+
+ add_project_arguments('-D_GNU_SOURCE', language: 'c')
+
--- a/glib/valgrind.h 2019-12-12 14:53:26.000200499 +0100
+++ b/glib/valgrind.h 2019-12-12 14:49:45.056163300 +0100
-@@ -157,7 +157,7 @@
+@@ -158,7 +158,7 @@
# define PLAT_s390x_linux 1
#elif defined(__linux__) && defined(__mips__) && (__mips==64)
# define PLAT_mips64_linux 1
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -2137,16 +2137,10 @@ endif
+
+ glib_conf.set('HAVE_PROC_SELF_CMDLINE', have_proc_self_cmdline)
+
+-python = import('python').find_installation('python3')
++python = 'python3'
+ # used for '#!/usr/bin/env <name>'
+ python_name = 'python3'
+
+-python_version = python.language_version()
+-python_version_req = '>=3.5'
+-if not python_version.version_compare(python_version_req)
+- error('Requires Python @0@, @1@ found.'.format(python_version_req, python_version))
+-endif
+-
+ # Determine which user environment-dependent files that we want to install
+ have_bash = find_program('bash', required : false).found() # For completion scripts
+ have_sh = find_program('sh', required : false).found() # For glib-gettextize
include $(TOPDIR)/rules.mk
PKG_NAME:=jsoncpp
-PKG_VERSION:=1.9.2
-PKG_RELEASE:=2
+PKG_VERSION:=1.9.3
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/open-source-parsers/jsoncpp/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=77a402fb577b2e0e5d0bdc1cf9c65278915cdb25171e3452c68b6da8a561f8f0
+PKG_HASH:=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz>
PKG_LICENSE:=MIT
endef
MESON_ARGS += \
- -Db_lto=true
+ -Db_lto=true \
+ -Dtests=false
TARGET_LDFLAGS += -Wl,--gc-sections
include $(TOPDIR)/rules.mk
PKG_NAME:=libextractor
-PKG_VERSION:=1.9
-PKG_RELEASE:=2
+PKG_VERSION:=1.10
+PKG_RELEASE:=1
# ToDo:
# - package missing optional dependencies: libexiv2, gsf, librpm, smf, tidy
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
-PKG_HASH:=f08f257d26c5e9b503f068d6753c8e55cb76f47f73a81da6ed2bba3de3fee2ff
+PKG_HASH:=9eed11b5ddc7c929ba112c50de8cfaa379f1d99a0c8e064101775837cf432357
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=COPYING
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
PKG_INSTALL:=1
-PKG_FIXUP:=autoreconf
+PKG_BUILD_PARALLEL:=1
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_PACKAGE_libextractor-plugin-thumbnailffmpeg \
+ CONFIG_PACKAGE_libextractor-plugin-gstreamer
PLUGINS:= \
archive:+libarchive-noopenssl \
include $(INCLUDE_DIR)/nls.mk
CONFIGURE_ARGS += \
- --enable-ffmpeg \
- --with-gstreamer \
+ --$(if $(CONFIG_PACKAGE_libextractor-plugin-thumbnailffmpeg),en,dis)able-ffmpeg \
+ --disable-glibtest \
--disable-gsf \
- --disable-rpath
+ --disable-rpath \
+ --with$(if $(CONFIG_PACKAGE_libextractor-plugin-gstreamer),,out)-gstreamer
+
+CONFIGURE_VARS += \
+ ac_cv_lib_jpeg_jpeg_mem_src=yes
+
+TARGET_LDFLAGS += \
+ -liconv
define Package/libextractor
SECTION:=libs
-diff --git a/src/common/le_architecture.h b/src/common/le_architecture.h
-index b863ddb..713acdd 100644
--- a/src/common/le_architecture.h
+++ b/src/common/le_architecture.h
@@ -26,6 +26,8 @@
--- /dev/null
+--- a/src/plugins/jpeg_extractor.c
++++ b/src/plugins/jpeg_extractor.c
+@@ -31,8 +31,97 @@ typedef int boolean;
+ #define HAVE_BOOLEAN
+ #endif
+ #include <jpeglib.h>
++#include <jerror.h>
+ #include <setjmp.h>
+
++#if JPEG_LIB_VERSION < 80 && !defined(MEM_SRCDST_SUPPORTED)
++typedef struct {
++ struct jpeg_source_mgr pub; /* public fields */
++
++ JOCTET eoi_buffer[2]; /* a place to put a dummy EOI */
++} my_source_mgr;
++
++typedef my_source_mgr * my_src_ptr;
++
++static void
++init_source (j_decompress_ptr cinfo)
++{
++ /* No work, since jpeg_mem_src set up the buffer pointer and count.
++ * Indeed, if we want to read multiple JPEG images from one buffer,
++ * this *must* not do anything to the pointer.
++ */
++}
++
++static boolean
++fill_input_buffer (j_decompress_ptr cinfo)
++{
++ my_src_ptr src = (my_src_ptr) cinfo->src;
++
++ WARNMS(cinfo, JWRN_JPEG_EOF);
++
++ /* Create a fake EOI marker */
++ src->eoi_buffer[0] = (JOCTET) 0xFF;
++ src->eoi_buffer[1] = (JOCTET) JPEG_EOI;
++ src->pub.next_input_byte = src->eoi_buffer;
++ src->pub.bytes_in_buffer = 2;
++
++ return TRUE;
++}
++
++static void
++skip_input_data (j_decompress_ptr cinfo, long num_bytes)
++{
++ my_src_ptr src = (my_src_ptr) cinfo->src;
++
++ if (num_bytes > 0) {
++ while (num_bytes > (long) src->pub.bytes_in_buffer) {
++ num_bytes -= (long) src->pub.bytes_in_buffer;
++ (void) fill_input_buffer(cinfo);
++ /* note we assume that fill_input_buffer will never
++ * return FALSE, so suspension need not be handled.
++ */
++ }
++ src->pub.next_input_byte += (size_t) num_bytes;
++ src->pub.bytes_in_buffer -= (size_t) num_bytes;
++ }
++}
++
++static void
++term_source (j_decompress_ptr cinfo)
++{
++ /* no work necessary here */
++}
++
++static void
++jpeg_mem_src (j_decompress_ptr cinfo, unsigned char * buffer,
++ unsigned long bufsize)
++{
++ my_src_ptr src;
++
++ /* The source object is made permanent so that a series of JPEG images
++ * can be read from a single buffer by calling jpeg_mem_src
++ * only before the first one.
++ * This makes it unsafe to use this manager and a different source
++ * manager serially with the same JPEG object. Caveat programmer.
++ */
++ if (cinfo->src == NULL) { /* first time for this JPEG object? */
++ cinfo->src = (struct jpeg_source_mgr *)
++ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
++ JPOOL_PERMANENT,
++ sizeof(my_source_mgr));
++ }
++
++ src = (my_src_ptr) cinfo->src;
++ src->pub.init_source = init_source;
++ src->pub.fill_input_buffer = fill_input_buffer;
++ src->pub.skip_input_data = skip_input_data;
++ src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
++ src->pub.term_source = term_source;
++
++ src->pub.next_input_byte = buffer;
++ src->pub.bytes_in_buffer = bufsize;
++}
++#endif
+
+ /**
+ * Context for custom functions.
+++ /dev/null
-#
-# Copyright (C) 2006-2015 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=libfuse3
-PKG_VERSION:=3.9.1
-PKG_RELEASE:=1
-
-PKG_SOURCE:=fuse-$(PKG_VERSION).tar.xz
-PKG_SOURCE_URL:=https://github.com/libfuse/libfuse/releases/download/fuse-$(PKG_VERSION)
-PKG_HASH:=1bafcfd6c66ba35b7b0beb822532a9106eb8409ad6cde988888fde85f89be645
-PKG_BUILD_DIR:=$(BUILD_DIR)/fuse-$(PKG_VERSION)
-
-PKG_MAINTAINER:=
-PKG_CPE_ID:=cpe:/a:fuse_project:fuse
-
-PKG_INSTALL:=1
-PKG_BUILD_PARALLEL:=1
-PKG_BUILD_DEPENDS:=meson/host
-
-include $(INCLUDE_DIR)/package.mk
-include ../../devel/meson/meson.mk
-
-define Package/libfuse3
- TITLE:=FUSE3 library
- URL:=https://github.com/libfuse/libfuse
- SECTION:=libs
- CATEGORY:=Libraries
- DEPENDS:=+kmod-fuse +libpthread
- SUBMENU:=Filesystem
- ABI_VERSION:=1
- LICENSE:=LGPL-2.1-only
- LICENSE_FILES:=LGPL2.txt
-endef
-
-define Package/libfuse3/description
- fuse3 (Filesystem in UserSpacE)
- This package contains the fuse3 shared libraries, needed by other programs.
- - libfuse3
-endef
-
-MESON_ARGS += \
- -Ddisable-mtab=true \
- -Dutils=false \
- -Dexamples=false \
- -Duseroot=false
-
-define Build/InstallDev
- $(INSTALL_DIR) $(1)/usr/include/fuse3
- $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/fuse3/*.h $(1)/usr/include/fuse3
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libfuse3.so* $(1)/usr/lib/
- $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
- $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/fuse3.pc $(1)/usr/lib/pkgconfig/
-endef
-
-define Package/libfuse3/install
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libfuse3.so.* $(1)/usr/lib/
-endef
-
-$(eval $(call BuildPackage,libfuse3))
--- /dev/null
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=libjpeg-turbo
+PKG_VERSION:=2.0.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_HASH:=16f8f6f2715b3a38ab562a84357c793dd56ae9899ce130563c72cd93d8357b5d
+
+PKG_MAINTAINER:=Rosen Penev <rosenp@gmail.com>
+PKG_LICENSE:=BSD-3-Clause IJG zlib
+PKG_LICENSE_FILES:=LICENSE.md
+
+PKG_USE_MIPS16:=0 #Allows ASM compilation for speed.
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/libjpeg-turbo/Default
+ TITLE:=libjpeg-turbo
+ URL:=https://www.libjpeg-turbo.org/
+endef
+
+define Package/libjpeg-turbo
+ $(call Package/libjpeg-turbo/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE+= runtime library
+ PROVIDES:=libjpeg
+endef
+
+define Package/libjpeg-turbo-utils
+ $(call Package/libjpeg-turbo/Default)
+ SECTION:=utils
+ CATEGORY:=Utilities
+ SUBMENU:=Image Manipulation
+ DEPENDS:=+libjpeg-turbo
+ TITLE+= manipulation tools
+ PROVIDES:=jpeg-tools
+endef
+
+define Package/libjpeg-turbo/description
+ libjpeg-turbo is a speed focused fork of libjpeg.
+endef
+
+define Package/libjpeg-turbo-utils/description
+ These are the JPEG utilities that come with libjpeg-turbo.
+endef
+
+CMAKE_OPTIONS += \
+ -DENABLE_SHARED=ON \
+ -DENABLE_STATIC=OFF \
+ -DREQUIRE_SIMD=OFF \
+ -DWITH_12BIT=OFF \
+ -DWITH_ARITH_DEC=OFF \
+ -DWITH_ARITH_ENC=OFF \
+ -DWITH_JAVA=OFF \
+ -DWITH_JPEG7=OFF \
+ -DWITH_JPEG8=OFF \
+ -DWITH_MEM_SRCDST=OFF \
+ -DWITH_SIMD=O$(if $(findstring mips,$(CONFIG_ARCH)),FF,N) \
+ -DWITH_TURBOJPEG=OFF
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.so* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/*.pc $(1)/usr/lib/pkgconfig/
+ $(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libjpeg.pc
+ $(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libjpeg.pc
+ $(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libturbojpeg.pc
+ $(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libturbojpeg.pc
+endef
+
+define Package/libjpeg-turbo/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.so* $(1)/usr/lib
+endef
+
+define Package/libjpeg-turbo-utils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/rdjpgcom $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wrjpgcom $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/cjpeg $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/djpeg $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/jpegtran $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,libjpeg-turbo))
+$(eval $(call BuildPackage,libjpeg-turbo-utils))
+++ /dev/null
-#
-# Copyright (C) 2006-2014 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=jpeg
-PKG_VERSION:=9c
-PKG_RELEASE:=2
-
-PKG_SOURCE:=$(PKG_NAME)src.v$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://www.ijg.org/files
-PKG_HASH:=650250979303a649e21f87b5ccd02672af1ea6954b911342ea491f351ceb7122
-
-PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
-PKG_LICENSE:=IJG
-PKG_LICENSE_FILES:=README
-
-PKG_BUILD_PARALLEL:=1
-PKG_BUILD_DEPENDS:=libtool
-
-include $(INCLUDE_DIR)/host-build.mk
-include $(INCLUDE_DIR)/package.mk
-
-define Package/jpeg/Default
- TITLE:=The Independent JPEG Group's JPEG
- URL:=http://www.ijg.org/
-endef
-
-define Package/libjpeg
- $(call Package/jpeg/Default)
- SECTION:=libs
- CATEGORY:=Libraries
- TITLE+= runtime library
-endef
-
-define Package/jpeg-tools
- $(call Package/jpeg/Default)
- SECTION:=utils
- CATEGORY:=Utilities
- SUBMENU:=Image Manipulation
- DEPENDS:=+libjpeg
- TITLE+= manipulation tools
-endef
-
-TARGET_CFLAGS += $(FPIC)
-
-CONFIGURE_ARGS += \
- --enable-shared \
- --enable-static \
-
-HOST_CONFIGURE_ARGS += \
- --enable-shared \
- --enable-static \
-
-define Build/Compile
- +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
- LIBTOOL="./libtool --tag=CC" \
- prefix="$(PKG_INSTALL_DIR)/usr" \
- exec_prefix="$(PKG_INSTALL_DIR)/usr" \
- all
- $(MAKE) -C $(PKG_BUILD_DIR) \
- DESTDIR="$(PKG_INSTALL_DIR)" \
- install
-endef
-
-define Build/InstallDev
- $(INSTALL_DIR) $(1)/usr/include
- $(CP) $(PKG_INSTALL_DIR)/usr/include/jpeglib.h $(1)/usr/include/
- $(CP) $(PKG_BUILD_DIR)/jpegint.h $(1)/usr/include/
- $(CP) $(PKG_INSTALL_DIR)/usr/include/j{config,error,morecfg}.h $(1)/usr/include/
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.{a,so*} $(1)/usr/lib/
- $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libjpeg.pc $(1)/usr/lib/pkgconfig/
-endef
-
-define Package/libjpeg/install
- $(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libjpeg.so.* $(1)/usr/lib/
-endef
-
-define Package/jpeg-tools/install
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/*jpeg* $(1)/usr/bin/
-endef
-
-$(eval $(call HostBuild))
-$(eval $(call BuildPackage,libjpeg))
-$(eval $(call BuildPackage,jpeg-tools))
include $(TOPDIR)/rules.mk
PKG_NAME:=libmicrohttpd
-PKG_VERSION:=0.9.70
-PKG_RELEASE:=2
+PKG_VERSION:=0.9.71
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/libmicrohttpd
-PKG_HASH:=90d0a3d396f96f9bc41eb0f7e8187796049285fabef82604acd4879590977307
+PKG_HASH:=e8f445e85faf727b89e9f9590daea4473ae00ead38b237cf1eda55172b89b182
PKG_MAINTAINER:=Alexander Couzens <lynxis@fe80.eu>
PKG_LICENSE:=LGPL-2.1-or-later
include $(TOPDIR)/rules.mk
PKG_NAME:=libpsl
-PKG_VERSION:=0.21.0
+PKG_VERSION:=0.21.1
PKG_RELEASE:=1
-PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://github.com/rockdaboot/libpsl/releases/download/$(PKG_VERSION)
+PKG_HASH:=ac6ce1e1fbd4d0254c4ddb9d37f1fa99dec83619c1253328155206b896210d4c
+PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://github.com/rockdaboot/libpsl/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
-PKG_HASH:=41bd1c75a375b85c337b59783f5deb93dbb443fb0a52d257f403df7bd653ee12
-
-PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1
+PKG_BUILD_DEPENDS:=meson/host
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
+include ../../devel/meson/meson.mk
define Package/libpsl
SECTION:=libs
TITLE:=C library to handle the Public Suffix List
URL:=https://github.com/rockdaboot/libpsl
DEPENDS:=+libidn2 +libunistring $(INTL_DEPENDS)
+ ABI_VERSION:=5
endef
define Package/libpsl/description
C library to handle the Public Suffix List
endef
-CONFIGURE_ARGS += \
- --disable-gtk-doc-html \
- --disable-man \
- --disable-rpath
-
-define Build/InstallDev
- $(INSTALL_DIR) \
- $(1)/usr/lib \
- $(1)/usr/include
+MESON_ARGS += \
+ -Druntime=libidn2 \
+ -Dbuiltin=libidn2
- $(CP) \
- $(PKG_INSTALL_DIR)/usr/include/* \
- $(1)/usr/include/
+TARGET_LDFLAGS += -liconv
- $(CP) \
- $(PKG_INSTALL_DIR)/usr/lib/* \
- $(1)/usr/lib/
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include $(1)/usr/lib $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/libpsl.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpsl.so* $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpsl.pc $(1)/usr/lib/pkgconfig/
endef
define Package/libpsl/install
$(INSTALL_DIR) $(1)/usr/lib
- $(CP) \
- $(PKG_INSTALL_DIR)/usr/lib/*.so* \
- $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpsl.so.* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,libpsl))
include $(TOPDIR)/rules.mk
PKG_NAME:=libqmi
-PKG_VERSION:=1.26.0
+PKG_VERSION:=1.26.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.freedesktop.org/software/libqmi
-PKG_HASH:=7f0429e0ae58792e21512d09ca2412537840ea42696762795af1284a65fd6e40
+PKG_HASH:=133467b2fe0706850eb587c0103ae6e61b97ce6e2c440d66358f2b72b0db7b03
PKG_MAINTAINER:=Nicholas Smith <nicholas.smith@telcoantennas.com.au>
PKG_NAME:=libsodium
PKG_VERSION:=1.0.18
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://download.libsodium.org/libsodium/releases \
--- /dev/null
+--- a/src/libsodium/Makefile.am
++++ b/src/libsodium/Makefile.am
+@@ -59,6 +59,7 @@ libsodium_la_SOURCES = \
+ crypto_scalarmult/curve25519/ref10/x25519_ref10.h \
+ crypto_scalarmult/curve25519/scalarmult_curve25519.c \
+ crypto_scalarmult/curve25519/scalarmult_curve25519.h \
++ crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c \
+ crypto_secretbox/crypto_secretbox.c \
+ crypto_secretbox/crypto_secretbox_easy.c \
+ crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c \
+@@ -160,7 +161,6 @@ libsodium_la_SOURCES += \
+ crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h \
+ crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c \
+ crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c \
+- crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c \
+ crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c \
+ crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c \
+ crypto_shorthash/siphash24/shorthash_siphashx24.c \
+--- a/src/libsodium/include/sodium.h
++++ b/src/libsodium/include/sodium.h
+@@ -33,6 +33,7 @@
+ #include "sodium/crypto_pwhash_argon2i.h"
+ #include "sodium/crypto_scalarmult.h"
+ #include "sodium/crypto_scalarmult_curve25519.h"
++#include "sodium/crypto_scalarmult_ed25519.h"
+ #include "sodium/crypto_secretbox.h"
+ #include "sodium/crypto_secretbox_xsalsa20poly1305.h"
+ #include "sodium/crypto_secretstream_xchacha20poly1305.h"
+@@ -57,7 +58,6 @@
+ # include "sodium/crypto_box_curve25519xchacha20poly1305.h"
+ # include "sodium/crypto_core_ed25519.h"
+ # include "sodium/crypto_core_ristretto255.h"
+-# include "sodium/crypto_scalarmult_ed25519.h"
+ # include "sodium/crypto_scalarmult_ristretto255.h"
+ # include "sodium/crypto_secretbox_xchacha20poly1305.h"
+ # include "sodium/crypto_pwhash_scryptsalsa208sha256.h"
PKG_NAME:=libulfius
PKG_VERSION:=2.6.7
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/babelouest/ulfius/tar.gz/v$(PKG_VERSION)?
--- /dev/null
+--- a/src/ulfius.c
++++ b/src/ulfius.c
+@@ -61,7 +61,7 @@ int y_close_logs() {
+ /**
+ * Fill a map with the key/values specified
+ */
+-static int ulfius_fill_map_check_utf8(void * cls, enum MHD_ValueKind kind, const char * key, const char * value) {
++static enum MHD_Result ulfius_fill_map_check_utf8(void * cls, enum MHD_ValueKind kind, const char * key, const char * value) {
+ char * tmp;
+ int res;
+ UNUSED(kind);
+@@ -94,7 +94,7 @@ static int ulfius_fill_map_check_utf8(void * cls, enum MHD_ValueKind kind, const
+ /**
+ * Fill a map with the key/values specified
+ */
+-static int ulfius_fill_map(void * cls, enum MHD_ValueKind kind, const char * key, const char * value) {
++static enum MHD_Result ulfius_fill_map(void * cls, enum MHD_ValueKind kind, const char * key, const char * value) {
+ char * tmp;
+ int res;
+ UNUSED(kind);
+@@ -290,7 +290,7 @@ void mhd_request_completed (void *cls, struct MHD_Connection *connection,
+ * if a parameter is larger than max_post_param_size, truncate it
+ * return MHD_NO on error
+ */
+-static int mhd_iterate_post_data (void * coninfo_cls, enum MHD_ValueKind kind, const char * key,
++static enum MHD_Result mhd_iterate_post_data (void * coninfo_cls, enum MHD_ValueKind kind, const char * key,
+ const char * filename, const char * content_type,
+ const char * transfer_encoding, const char * data, uint64_t off, size_t size) {
+
+@@ -352,7 +352,7 @@ static int mhd_iterate_post_data (void * coninfo_cls, enum MHD_ValueKind kind, c
+ * function executed by libmicrohttpd every time an HTTP call is made
+ * return MHD_NO on error
+ */
+-static int ulfius_webservice_dispatcher (void * cls,
++static enum MHD_Result ulfius_webservice_dispatcher (void * cls,
+ struct MHD_Connection * connection,
+ const char * url,
+ const char * method,
+@@ -363,7 +363,8 @@ static int ulfius_webservice_dispatcher (void * cls,
+
+ struct _u_endpoint * endpoint_list = ((struct _u_instance *)cls)->endpoint_list, ** current_endpoint_list = NULL, * current_endpoint = NULL;
+ struct connection_info_struct * con_info = * con_cls;
+- int mhd_ret = MHD_NO, callback_ret = U_OK, i, close_loop = 0, inner_error = U_OK, mhd_response_flag;
++ enum MHD_Result mhd_ret = MHD_NO;
++ int callback_ret = U_OK, i, close_loop = 0, inner_error = U_OK, mhd_response_flag;
+ #ifndef U_DISABLE_WEBSOCKET
+ // Websocket variables
+ int upgrade_protocol = 0;
include $(TOPDIR)/rules.mk
PKG_NAME:=libupnp
-PKG_VERSION:=1.12.1
+PKG_VERSION:=1.14.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=@SF/pupnp
-PKG_HASH:=fc36642b1848fe5a81296d496291d350ecfc12b85fd0b268478ab230976d4009
+PKG_HASH:=ecb23d4291968c8a7bdd4eb16fc2250dbacc16b354345a13342d67f571d35ceb
PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
PKG_LICENSE:=BSD-3-Clause
--disable-scriptsupport \
--disable-postwrite
-TARGET_CFLAGS += -flto
-TARGET_LDFLAGS += -flto
-
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(CP) $(PKG_INSTALL_DIR)/usr/include/upnp $(1)/usr/include/
PKG_NAME:=v4l-utils
PKG_VERSION:=1.20.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://www.linuxtv.org/downloads/v4l-utils
--- /dev/null
+--- a/utils/v4l2-ctl/v4l2-ctl-common.cpp
++++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
+@@ -785,15 +785,17 @@ static bool parse_subset(char *optarg)
+
+ static bool parse_next_subopt(char **subs, char **value)
+ {
+- static char *const subopts[] = {
+- NULL
+- };
+- int opt = getsubopt(subs, subopts, value);
++ char *p = *subs;
++ *value = *subs;
+
+- if (opt < 0 || *value)
+- return false;
+- fprintf(stderr, "Missing suboption value\n");
+- return true;
++ while (*p && *p != ',')
++ p++;
++
++ if (*p)
++ *p++ = '\0';
++
++ *subs = p;
++ return false;
+ }
+
+ void common_cmd(const std::string &media_bus_info, int ch, char *optarg)
PKG_NAME:=log4cplus
PKG_VERSION:=2.0.5
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@SF/$(PKG_NAME)
configuration. It is modeled after the Java log4j API.
endef
-CMAKE_OPTIONS += \
+OPTIONS:= \
-DLOG4CPLUS_BUILD_LOGGINGSERVER:BOOL=OFF \
-DLOG4CPLUS_BUILD_TESTING:BOOL=OFF \
-DUNICODE:BOOL=OFF \
-DWITH_ICONV:BOOL=OFF
+CMAKE_HOST_OPTIONS += $(OPTIONS)
+CMAKE_OPTIONS += $(OPTIONS)
+
TARGET_CFLAGS += -flto
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
include $(TOPDIR)/rules.mk
PKG_NAME:=measurement-kit
-PKG_VERSION:=0.10.11
-PKG_RELEASE:=2
+PKG_VERSION:=0.10.12
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/measurement-kit/measurement-kit/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=f9dbf5f721516fd709c13ac5011737b3622076299e3c899a1f70861901ec1b40
+PKG_HASH:=508d9db72579efbe4747dd791771f47299bc5867c72d67a86e371d66d20fd19e
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz>
PKG_LICENSE:=BSD-2-Clause
PKG_NAME:=spice
PKG_VERSION:=0.14.3
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=https://www.spice-space.org/download/releases/spice-server
PKG_HASH:=551d4be4a07667cf0543f3c895beb6da8a93ef5a9829f2ae47817be5e616a114
PKG_BUILD_DEPENDS+=spice-protocol
include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
define Package/libspice-server
SECTION:=libs
include $(TOPDIR)/rules.mk
PKG_NAME:=zeromq
-PKG_VERSION:=4.1.7
-PKG_RELEASE:=2
+PKG_VERSION:=4.3.2
+PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://github.com/zeromq/zeromq4-1/releases/download/v$(PKG_VERSION)
-PKG_HASH:=31c383cfcd3be1dc8a66e448c403029e793687e70473b89c4cc0bd626e7da299
+PKG_SOURCE_URL:=https://github.com/zeromq/libzmq/releases/download/v$(PKG_VERSION)
+PKG_HASH:=ebd7b5c830d6428956b67a0454a7f8cbed1de74b3b01e5c33c5378e22740f763
PKG_MAINTAINER:=Dirk Chang <dirk@kooiot.com>
PKG_LICENSE:=GPL-3.0-or-later
CMAKE_OPTIONS += \
-DA2X_EXECUTABLE=OFF \
-DASCIIDOC_EXECUTABLE=OFF \
+ -DBUILD_STATIC=OFF \
-DCMAKE_SKIP_INSTALL_RPATH=ON \
-DZMQ_HAVE_SOCK_CLOEXEC=ON \
-DZMQ_HAVE_SO_KEEPALIVE=ON \
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libzmq.so* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libzmq.pc $(1)/usr/lib/pkgconfig/
+ $(SED) 's,/usr/include,$$$${prefix}/include,g' $(1)/usr/lib/pkgconfig/libzmq.pc
+ $(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' $(1)/usr/lib/pkgconfig/libzmq.pc
endef
define Package/libzmq-nc/install
$(INSTALL_DIR) $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libzmq.so $(1)/usr/lib/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libzmq.so.* $(1)/usr/lib/
endef
Package/libzmq-curve/install=$(Package/libzmq-nc/install)
+++ /dev/null
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -3,6 +3,8 @@
- cmake_minimum_required(VERSION 2.8.11)
- project(ZeroMQ)
-
-+include(FindPkgConfig)
-+
- option(WITH_OPENPGM "Build with support for OpenPGM" OFF)
-
- if(APPLE)
-@@ -21,7 +23,7 @@ if (NOT ENABLE_CURVE)
- message (STATUS "CURVE security is disabled")
-
- elseif (WITH_LIBSODIUM)
-- find_package (Sodium)
-+ pkg_search_module (SODIUM REQUIRED libsodium)
- if (SODIUM_FOUND)
- message (STATUS "Using libsodium for CURVE security")
- include_directories (${SODIUM_INCLUDE_DIRS})
--- /dev/null
+--- a/perf/benchmark_radix_tree.cpp
++++ b/perf/benchmark_radix_tree.cpp
+@@ -26,8 +26,8 @@
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+-
+-#if __cplusplus >= 201103L
++#include <ios>
++#if __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__)
+
+ #include "radix_tree.hpp"
+ #include "trie.hpp"
+--- a/src/atomic_counter.hpp
++++ b/src/atomic_counter.hpp
+@@ -35,7 +35,7 @@
+
+ #if defined ZMQ_FORCE_MUTEXES
+ #define ZMQ_ATOMIC_COUNTER_MUTEX
+-#elif (defined __cplusplus && __cplusplus >= 201103L) \
++#elif (defined __cplusplus && __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__)) \
+ || (defined _MSC_VER && _MSC_VER >= 1900)
+ #define ZMQ_ATOMIC_COUNTER_CXX11
+ #elif defined ZMQ_HAVE_ATOMIC_INTRINSICS
+--- a/src/atomic_ptr.hpp
++++ b/src/atomic_ptr.hpp
+@@ -34,7 +34,7 @@
+
+ #if defined ZMQ_FORCE_MUTEXES
+ #define ZMQ_ATOMIC_PTR_MUTEX
+-#elif (defined __cplusplus && __cplusplus >= 201103L) \
++#elif (defined __cplusplus && __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__)) \
+ || (defined _MSC_VER && _MSC_VER >= 1900)
+ #define ZMQ_ATOMIC_PTR_CXX11
+ #elif defined ZMQ_HAVE_ATOMIC_INTRINSICS
+--- a/src/blob.hpp
++++ b/src/blob.hpp
+@@ -38,7 +38,7 @@
+ #include <algorithm>
+ #include <ios>
+
+-#if __cplusplus >= 201103L || defined(_MSC_VER) && _MSC_VER > 1700
++#if __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__) || defined(_MSC_VER) && _MSC_VER > 1700
+ #define ZMQ_HAS_MOVE_SEMANTICS
+ #define ZMQ_MAP_INSERT_OR_EMPLACE(k, v) emplace (k, v)
+ #define ZMQ_PUSH_OR_EMPLACE_BACK emplace_back
+--- a/src/ctx.cpp
++++ b/src/ctx.cpp
+@@ -544,7 +544,7 @@ void zmq::ctx_t::unregister_endpoints (socket_base_t *socket_)
+ end = _endpoints.end ();
+ it != end;) {
+ if (it->second.socket == socket_)
+-#if __cplusplus >= 201103L
++#if __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__)
+ it = _endpoints.erase (it);
+ #else
+ _endpoints.erase (it++);
+--- a/src/msg.hpp
++++ b/src/msg.hpp
+@@ -30,8 +30,8 @@
+ #ifndef __ZMQ_MSG_HPP_INCLUDE__
+ #define __ZMQ_MSG_HPP_INCLUDE__
+
+-#include <stddef.h>
+-#include <stdio.h>
++#include <cstddef>
++#include <cstdio>
+
+ #include "config.hpp"
+ #include "err.hpp"
+--- a/src/options.hpp
++++ b/src/options.hpp
+@@ -305,7 +305,7 @@ int do_getsockopt (void *const optval_,
+ template <typename T>
+ int do_getsockopt (void *const optval_, size_t *const optvallen_, T value_)
+ {
+-#if __cplusplus >= 201103L && (!defined(__GNUC__) || __GNUC__ > 5)
++#if __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__) && (!defined(__GNUC__) || __GNUC__ > 5)
+ static_assert (std::is_trivially_copyable<T>::value,
+ "invalid use of do_getsockopt");
+ #endif
+--- a/src/radio.cpp
++++ b/src/radio.cpp
+@@ -126,7 +126,7 @@ void zmq::radio_t::xpipe_terminated (pipe_t *pipe_)
+ end = _subscriptions.end ();
+ it != end;) {
+ if (it->second == pipe_) {
+-#if __cplusplus >= 201103L
++#if __cplusplus >= 201103L && !defined(__UCLIBCXX_MAJOR__)
+ it = _subscriptions.erase (it);
+ #else
+ _subscriptions.erase (it++);
+++ /dev/null
---- a/src/metadata.hpp
-+++ b/src/metadata.hpp
-@@ -41,7 +41,11 @@ namespace zmq
- {
- public:
-
-+#ifdef __UCLIBCXX_MAJOR__
-+ typedef std::map <std::string, std::string> dict_t;
-+#else
- typedef std::map <std::string, const std::string> dict_t;
-+#endif
-
- metadata_t (const dict_t &dict);
- virtual ~metadata_t ();
---- a/src/stream_engine.cpp
-+++ b/src/stream_engine.cpp
-@@ -208,7 +208,11 @@ void zmq::stream_engine_t::plug (io_thread_t *io_thread_,
- // Compile metadata.
- typedef metadata_t::dict_t properties_t;
- properties_t properties;
-+#ifdef __UCLIBCXX_MAJOR__
-+ properties.insert(std::make_pair<std::string, std::string>("Peer-Address", peer_address));
-+#else
- properties.insert(std::make_pair("Peer-Address", peer_address));
-+#endif
- zmq_assert (metadata == NULL);
- metadata = new (std::nothrow) metadata_t (properties);
- }
-@@ -824,7 +828,11 @@ void zmq::stream_engine_t::mechanism_ready ()
-
- // If we have a peer_address, add it to metadata
- if (!peer_address.empty()) {
-+#ifdef __UCLIBCXX_MAJOR__
-+ properties.insert(std::make_pair<std::string, std::string>("Peer-Address", peer_address));
-+#else
- properties.insert(std::make_pair("Peer-Address", peer_address));
-+#endif
- }
-
- // Add ZAP properties.
+++ /dev/null
---- a/src/blob.hpp
-+++ b/src/blob.hpp
-@@ -31,6 +31,7 @@
- #define __ZMQ_BLOB_HPP_INCLUDED__
-
- #include <string>
-+#include <ios>
- #include <string.h>
-
- // Borrowed from id3lib_strings.h:
+++ /dev/null
---- a/src/blob.hpp
-+++ b/src/blob.hpp
-@@ -38,7 +38,7 @@
- // They seem to be doing something for MSC, but since I only have gcc, I'll just do that
- // Assuming this is uneccessary on GCC 4
- // #if (defined(__GNUC__) && (__GNUC__ >= 3) || (defined(_MSC_VER) && _MSC_VER > 1000))
--#if (defined(__GNUC__) && (__GNUC__ >= 3) && (__GNUC__ <= 4))
-+#if (defined(__GNUC__) && (__GNUC__ >= 3))
- namespace std
- {
- template<>
+++ /dev/null
---- a/src/signaler.cpp
-+++ b/src/signaler.cpp
-@@ -86,7 +86,8 @@ static int sleep_ms (unsigned int ms_)
- usleep (ms_ * 1000);
- return 0;
- #else
-- return usleep (ms_ * 1000);
-+ const struct timespec req = {0, (long int)ms_ * 1000 * 1000};
-+ return nanosleep (&req, NULL);
- #endif
- }
-
---- a/src/tcp_address.cpp
-+++ b/src/tcp_address.cpp
-@@ -29,6 +29,7 @@
-
- #include <string>
- #include <sstream>
-+#include <ctime>
-
- #include "tcp_address.hpp"
- #include "platform.hpp"
-@@ -194,7 +195,8 @@ int zmq::tcp_address_t::resolve_nic_name (const char *nic_, bool ipv6_, bool is_
- rc = getifaddrs (&ifa);
- if (rc == 0 || (rc < 0 && errno != ECONNREFUSED))
- break;
-- usleep ((backoff_msec << i) * 1000);
-+ const struct timespec req = {0, (backoff_msec << i) * 1000 * 1000};
-+ nanosleep (&req, NULL);
- }
- errno_assert (rc == 0);
- zmq_assert (ifa != NULL);
---- a/src/zmq.cpp
-+++ b/src/zmq.cpp
-@@ -692,7 +692,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
- usleep (timeout_ * 1000);
- return 0;
- #else
-- return usleep (timeout_ * 1000);
-+ const struct timespec req = {0, timeout_ * 1000 * 1000};
-+ return nanosleep (&req, NULL);
- #endif
- }
-
-@@ -852,7 +853,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)
- Sleep (timeout_ > 0 ? timeout_ : INFINITE);
- return 0;
- #else
-- return usleep (timeout_ * 1000);
-+ const struct timespec req = {0, timeout_ * 1000 * 1000};
-+ return nanosleep (&req, NULL);
- #endif
- }
- zmq::clock_t clock;
include $(TOPDIR)/rules.mk
PKG_NAME:=mutt
-PKG_VERSION:=1.12.2
+PKG_VERSION:=1.14.6
PKG_RELEASE:=1
PKG_SOURCE_URL:=https://bitbucket.org/mutt/mutt/downloads/ \
http://ftp.mutt.org/pub/mutt/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=bc42750ce8237742b9382f2148fc547a8d8601aa4a7cd28c55fe7ca045196882
+PKG_HASH:=47972a0152b81b9f67ff322a0a6682b914c15545bfdeac6bcc2f2c0bf9361844
PKG_MAINTAINER:=Phil Eichinger <phil@zankapfel.net>
PKG_LICENSE:=GPL-2.0-or-later
+++ /dev/null
-From 6dbfafd4b8bfc9f5e53db90c5279784c506a3253 Mon Sep 17 00:00:00 2001
-From: Phil Eichinger <phil@zankapfel.net>
-Date: Tue, 17 Oct 2017 06:44:04 +0200
-Subject: [PATCH] no po
-
-docs are disabled via ./configure --disable-doc now
----
- Makefile.am | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile.am b/Makefile.am
-index 4bc2db4..bb00927 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -14,7 +14,7 @@ IMAP_SUBDIR = imap
- IMAP_INCLUDES = -I$(top_srcdir)/imap
- endif
-
--SUBDIRS = m4 po intl $(DOC_SUBDIR) contrib $(IMAP_SUBDIR)
-+SUBDIRS = m4 intl $(DOC_SUBDIR) contrib $(IMAP_SUBDIR)
-
- bin_SCRIPTS = muttbug flea $(SMIMEAUX_TARGET)
-
---
-2.11.0
-
include $(TOPDIR)/rules.mk
PKG_NAME:=gerbera
-PKG_VERSION:=1.5.0
-PKG_RELEASE:=9
+PKG_VERSION:=1.6.0
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/gerbera/gerbera/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=693a99b295bc79d842f036a6d04996d4676ac0791d65f3a1f7aab4badf9fb5ef
+PKG_HASH:=3a4956ec5fea1101e8daa32d9cfb985db908a49e2ac6137a1b2bf509e2684a6c
PKG_MAINTAINER:=
PKG_LICENSE:=GPL-2.0-or-later
PKG_BUILD_DEPENDS:=libmatroska pugixml spdlog taglib
PKG_BUILD_PARALLEL:=1
+PKG_CONFIG_DEPENDS:=CONFIG_BUILD_PATENTED
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/gerbera
SECTION:=multimedia
CATEGORY:=Multimedia
- DEPENDS:=+file +libnpupnp +libsqlite3 +libexif +libuuid +libfmt $(ICONV_DEPENDS)
+ DEPENDS:=+file +libnpupnp +libsqlite3 +libexif +libuuid +libfmt +BUILD_PATENTED:libffmpeg $(ICONV_DEPENDS)
TITLE:=A free media server
URL:=https://gerbera.io
USERID:=gerbera:gerbera
CMAKE_OPTIONS += \
-DCXX_FILESYSTEM_NO_LINK_NEEDED=$(if $(CONFIG_GCC_USE_VERSION_9),ON,OFF) \
-DCXX_FILESYSTEM_STDCPPFS_NEEDED=$(if $(CONFIG_GCC_USE_VERSION_8),OFF,ON) \
- -DICONV_INCLUDE_DIR=$(ICONV_PREFIX)/include \
- -DICONV_LIBRARIES=$(ICONV_PREFIX)/lib/libiconv.a \
+ -DIconv_INCLUDE_DIR=$(ICONV_PREFIX)/include \
+ -DIconv_LIBRARY=$(ICONV_PREFIX)/lib/libiconv.a \
-DWITH_MAGIC=ON \
-DWITH_MYSQL=OFF \
-DWITH_CURL=OFF \
-DWITH_INOTIFY=ON \
-DWITH_JS=OFF \
-DWITH_TAGLIB=ON \
- -DWITH_AVCODEC=OFF \
+ -DWITH_AVCODEC=$(if $(CONFIG_BUILD_PATENTED),ON,OFF) \
-DWITH_FFMPEGTHUMBNAILER=OFF \
-DWITH_EXIF=ON \
-DWITH_EXIV2=OFF \
-DWITH_SYSTEMD=OFF \
-DWITH_LASTFM=OFF \
-DWITH_DEBUG=OFF \
- -DWITH_TESTS=OFF
+ -DWITH_TESTS=OFF \
+ -DWITH_NPUPNP=ON
TARGET_CFLAGS += \
-ffunction-sections \
-fdata-sections \
-flto \
-I$(STAGING_DIR)/usr/include/npupnp/upnp
+
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
define Package/gerbera/install
--- /dev/null
+From 72f9db7bd75f03e9e7afeaaa0aa0ab7af9fe81a5 Mon Sep 17 00:00:00 2001
+From: Yuri Timenkov <yuri@timenkov.ru>
+Date: Sun, 26 Jul 2020 12:17:15 +0000
+Subject: [PATCH] Fixed build with ffmnpeg but without thumbnailer
+
+Fixes: #953
+---
+ src/metadata/ffmpeg_handler.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/metadata/ffmpeg_handler.cc b/src/metadata/ffmpeg_handler.cc
+index 4bba5655..e0ff84bb 100644
+--- a/src/metadata/ffmpeg_handler.cc
++++ b/src/metadata/ffmpeg_handler.cc
+@@ -265,6 +265,8 @@ void FfmpegHandler::fillMetadata(std::shared_ptr<CdsItem> item)
+ avformat_close_input(&pFormatCtx);
+ }
+
++#ifdef HAVE_FFMPEGTHUMBNAILER
++
+ fs::path getThumbnailCacheBasePath(Config& config)
+ {
+ if (auto configuredDir = config.getOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR);
+@@ -284,7 +286,6 @@ fs::path getThumbnailCachePath(const fs::path& base, const fs::path& movie)
+ return path;
+ }
+
+-#ifdef HAVE_FFMPEGTHUMBNAILER
+ std::optional<std::vector<std::byte>> FfmpegHandler::readThumbnailCacheFile(const fs::path& movie_filename) const
+ {
+ auto path = getThumbnailCachePath(getThumbnailCacheBasePath(*config), movie_filename);
+++ /dev/null
-From 77cae5ff9b8dff22bfebac905f1579562609dd35 Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Mon, 4 May 2020 12:44:34 -0700
-Subject: [PATCH] remove iconv casting
-
-iconv_t is sometimes a pointer and other times an int. Remove casting
-to make it work with the latter.
-
-Signed-off-by: Rosen Penev <rosenp@gmail.com>
----
- src/util/string_converter.cc | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/util/string_converter.cc b/src/util/string_converter.cc
-index 272787ad..e1724b39 100644
---- a/src/util/string_converter.cc
-+++ b/src/util/string_converter.cc
-@@ -41,15 +41,15 @@ StringConverter::StringConverter(const std::string& from, const std::string& to)
- dirty = false;
-
- cd = iconv_open(to.c_str(), from.c_str());
-- if (cd == reinterpret_cast<iconv_t>(-1)) {
-- cd = static_cast<iconv_t>(nullptr);
-+ if (!cd) {
-+ cd = {};
- throw_std_runtime_error(std::string("iconv: ") + strerror(errno));
- }
- }
-
- StringConverter::~StringConverter()
- {
-- if (cd != static_cast<iconv_t>(nullptr))
-+ if (cd)
- iconv_close(cd);
- }
-
--- /dev/null
+From 993e4e157e4a8c4898b45982045cf63e3b57a6a1 Mon Sep 17 00:00:00 2001
+From: Jean-Francois Dockes <jf@dockes.org>
+Date: Fri, 13 Mar 2020 09:19:04 +0100
+Subject: [PATCH] Quick changes for working with NPUPNP
+
+(Rebased and made default)
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ CMakeLists.txt | 35 +++++++++++++++---------
+ src/action_request.cc | 11 +++++++-
+ src/device_description_handler.cc | 4 +++
+ src/file_request_handler.cc | 4 +++
+ src/iohandler/file_io_handler.cc | 1 -
+ src/iohandler/io_handler.cc | 1 -
+ src/iohandler/mem_io_handler.cc | 1 -
+ src/serve_request_handler.cc | 8 ++++++
+ src/server.cc | 8 ++++++
+ src/transcoding/transcode_ext_handler.cc | 1 -
+ src/upnp_cds.cc | 11 ++++++++
+ src/upnp_cm.cc | 11 ++++++++
+ src/upnp_mrreg.cc | 7 ++++-
+ src/url_request_handler.cc | 5 +++-
+ src/util/upnp_clients.cc | 12 ++++++++
+ src/util/upnp_headers.cc | 14 ++++++++++
+ src/web/web_request_handler.cc | 4 +++
+ 17 files changed, 118 insertions(+), 20 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 81f7818e..56472b97 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -35,6 +35,7 @@ if (CONAN_EXPORTED)
+ endif()
+
+ set(CMAKE_VERBOSE_MAKEFILE off CACHE BOOL "Show verbose build commands")
++set(WITH_NPUPNP 0 CACHE BOOL "Use npupnp instead of pupnp")
+ set(WITH_MAGIC 1 CACHE BOOL "Use libmagic to identify file mime types")
+ set(WITH_MYSQL 0 CACHE BOOL "Store media information in MySQL DB")
+ set(WITH_CURL 1 CACHE BOOL "CURL required for online services")
+@@ -303,23 +304,31 @@ add_definitions(${LFS_DEFINITIONS})
+ add_compile_options(${LFS_COMPILE_OPTIONS})
+ target_link_libraries(libgerbera ${LFS_LIBRARIES})
+
+-find_package (pupnp "1.12.1" REQUIRED)
++if (WITH_NPUPNP)
++ pkg_check_modules (NPUPNP REQUIRED libnpupnp)
++ include_directories (${NPUPNP_INCLUDE_DIRS})
++ set(CMAKE_REQUIRED_LIBRARIES npupnp)
++ add_definitions(-DUSING_NPUPNP)
++ target_link_libraries (libgerbera ${NPUPNP_LIBRARIES})
++else()
++ find_package (pupnp "1.12.1" REQUIRED)
+
+-set(CMAKE_REQUIRED_LIBRARIES pupnp::pupnp)
++ set(CMAKE_REQUIRED_LIBRARIES pupnp::pupnp)
+
+-check_cxx_symbol_exists(UPNP_ENABLE_IPV6 "upnpconfig.h" UPNP_HAS_IPV6)
+-if (NOT UPNP_HAS_IPV6)
+- message(FATAL_ERROR "Gerbera requires libupnp with IPv6 support.")
+-endif()
++ check_cxx_symbol_exists(UPNP_ENABLE_IPV6 "upnpconfig.h" UPNP_HAS_IPV6)
++ if (NOT UPNP_HAS_IPV6)
++ message(FATAL_ERROR "Gerbera requires libupnp with IPv6 support.")
++ endif()
+
+-check_cxx_symbol_exists(UPNP_MINISERVER_REUSEADDR "upnpconfig.h" UPNP_HAS_REUSEADDR)
+-if (NOT UPNP_HAS_REUSEADDR)
+- message(WARNING [=[
+-!! It is strongly recommended to build libupnp with --enable-reuseaddr !!
+-Without this option Gerbera will be unable to restart with the same port number.]=])
+-endif()
++ check_cxx_symbol_exists(UPNP_MINISERVER_REUSEADDR "upnpconfig.h" UPNP_HAS_REUSEADDR)
++ if (NOT UPNP_HAS_REUSEADDR)
++ message(WARNING [=[
++ !! It is strongly recommended to build libupnp with --enable-reuseaddr !!
++ Without this option Gerbera will be unable to restart with the same port number.]=])
++ endif()
+
+-target_link_libraries (libgerbera pupnp::pupnp)
++ target_link_libraries (libgerbera pupnp::pupnp)
++endif()
+
+ find_package(fmt REQUIRED)
+ target_link_libraries(libgerbera fmt::fmt)
+diff --git a/src/action_request.cc b/src/action_request.cc
+index fab0e910..5677e61e 100644
+--- a/src/action_request.cc
++++ b/src/action_request.cc
+@@ -65,10 +65,14 @@ std::string ActionRequest::getServiceID() const
+
+ std::unique_ptr<pugi::xml_document> ActionRequest::getRequest() const
+ {
+- DOMString cxml = ixmlPrintDocument(UpnpActionRequest_get_ActionRequest(upnp_request));
+ auto request = std::make_unique<pugi::xml_document>();
++#if defined(USING_NPUPNP)
++ auto ret = request->load_string(upnp_request->xmlAction.c_str());
++#else
++ DOMString cxml = ixmlPrintDocument(UpnpActionRequest_get_ActionRequest(upnp_request));
+ auto ret = request->load_string(cxml);
+ ixmlFreeDOMString(cxml);
++#endif
+
+ if (ret.status != pugi::xml_parse_status::status_ok)
+ throw_std_runtime_error("Unable to parse ixml");
+@@ -94,6 +98,10 @@ void ActionRequest::update()
+ std::string xml = buf.str();
+ log_debug("ActionRequest::update(): {}", xml.c_str());
+
++#if defined(USING_NPUPNP)
++ UpnpActionRequest_set_xmlResponse(upnp_request, xml);
++ UpnpActionRequest_set_ErrCode(upnp_request, errCode);
++#else
+ IXML_Document* result = nullptr;
+ int err = ixmlParseBufferEx(xml.c_str(), &result);
+
+@@ -105,6 +113,7 @@ void ActionRequest::update()
+ UpnpActionRequest_set_ActionResult(upnp_request, result);
+ UpnpActionRequest_set_ErrCode(upnp_request, errCode);
+ }
++#endif
+ } else {
+ // ok, here there can be two cases
+ // either the function below already did set an error code,
+diff --git a/src/device_description_handler.cc b/src/device_description_handler.cc
+index 6aca745e..cf2e8015 100644
+--- a/src/device_description_handler.cc
++++ b/src/device_description_handler.cc
+@@ -45,7 +45,11 @@ void DeviceDescriptionHandler::getInfo(const char* filename, UpnpFileInfo* info)
+ {
+ // We should be able to do the generation here, but libupnp doesnt support the request cookies yet
+ UpnpFileInfo_set_FileLength(info, -1);
++#if defined(USING_NPUPNP)
+ UpnpFileInfo_set_ContentType(info, "application/xml");
++#else
++ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString("application/xml"));
++#endif
+ UpnpFileInfo_set_IsReadable(info, 1);
+ UpnpFileInfo_set_IsDirectory(info, 0);
+ }
+diff --git a/src/file_request_handler.cc b/src/file_request_handler.cc
+index cfa3eaed..915e411b 100644
+--- a/src/file_request_handler.cc
++++ b/src/file_request_handler.cc
+@@ -238,7 +238,11 @@ void FileRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
+
+ UpnpFileInfo_set_LastModified(info, statbuf.st_mtime);
+ UpnpFileInfo_set_IsDirectory(info, S_ISDIR(statbuf.st_mode));
++#if defined(USING_NPUPNP)
++ UpnpFileInfo_set_ContentType(info, mimeType);
++#else
+ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimeType.c_str()));
++#endif
+
+ headers->writeHeaders(info);
+
+diff --git a/src/iohandler/file_io_handler.cc b/src/iohandler/file_io_handler.cc
+index 7e239250..b023e85b 100644
+--- a/src/iohandler/file_io_handler.cc
++++ b/src/iohandler/file_io_handler.cc
+@@ -32,7 +32,6 @@
+ #include "file_io_handler.h" // API
+
+ #include <cstdio>
+-#include <ixml.h>
+ #include <utility>
+
+ #include "cds_objects.h"
+diff --git a/src/iohandler/io_handler.cc b/src/iohandler/io_handler.cc
+index f9789425..1153ce6b 100644
+--- a/src/iohandler/io_handler.cc
++++ b/src/iohandler/io_handler.cc
+@@ -31,7 +31,6 @@
+
+ #include "io_handler.h" // API
+
+-#include <ixml.h>
+ #include <unistd.h>
+
+ #include "server.h"
+diff --git a/src/iohandler/mem_io_handler.cc b/src/iohandler/mem_io_handler.cc
+index 5574a16d..223746ef 100644
+--- a/src/iohandler/mem_io_handler.cc
++++ b/src/iohandler/mem_io_handler.cc
+@@ -35,7 +35,6 @@
+ #include <cstdlib>
+ #include <cstring>
+ #include <ctime>
+-#include <ixml.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+diff --git a/src/serve_request_handler.cc b/src/serve_request_handler.cc
+index 210140a3..01dde69b 100644
+--- a/src/serve_request_handler.cc
++++ b/src/serve_request_handler.cc
+@@ -94,7 +94,11 @@ void ServeRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
+ UpnpFileInfo_set_IsReadable(info, 0);
+ }
+
++#if defined(USING_NPUPNP)
++ UpnpFileInfo_set_ContentType(info, mimetype);
++#else
+ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimetype.c_str()));
++#endif
+ } else {
+ throw_std_runtime_error("Not a regular file: " + path);
+ }
+@@ -158,7 +162,11 @@ std::unique_ptr<IOHandler> ServeRequestHandler::open(const char* filename,
+ }
+
+
++#if defined(USING_NPUPNP)
++ info->content_type = mimetype;
++#else
+ info->content_type = ixmlCloneDOMString(mimetype.c_str());
++#endif
+ */
+ } else {
+ throw_std_runtime_error("Not a regular file: " + path);
+diff --git a/src/server.cc b/src/server.cc
+index a83c28cd..d4ce3e51 100644
+--- a/src/server.cc
++++ b/src/server.cc
+@@ -393,9 +393,17 @@ int Server::handleUpnpClientEvent(Upnp_EventType eventType, const void* event)
+ case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
+ case UPNP_DISCOVERY_SEARCH_RESULT: {
+ auto d_event = reinterpret_cast<const UpnpDiscovery*>(event);
++#if defined(USING_NPUPNP)
++ const char* userAgent = UpnpDiscovery_get_Os_cstr(d_event);
++#else
+ const char* userAgent = UpnpString_get_String(UpnpDiscovery_get_Os(d_event));
++#endif
+ const struct sockaddr_storage* destAddr = UpnpDiscovery_get_DestAddr(d_event);
++#if defined(USING_NPUPNP)
++ const char* location = UpnpDiscovery_get_Location_cstr(d_event);
++#else
+ const char* location = UpnpString_get_String(UpnpDiscovery_get_Location(d_event));
++#endif
+
+ Clients::addClientByDiscovery(destAddr, userAgent, location);
+ break;
+diff --git a/src/transcoding/transcode_ext_handler.cc b/src/transcoding/transcode_ext_handler.cc
+index 67ee79d9..1da59ea2 100644
+--- a/src/transcoding/transcode_ext_handler.cc
++++ b/src/transcoding/transcode_ext_handler.cc
+@@ -37,7 +37,6 @@
+ #include <cstring>
+ #include <fcntl.h>
+ #include <filesystem>
+-#include <ixml.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <unistd.h>
+diff --git a/src/upnp_cds.cc b/src/upnp_cds.cc
+index 12ffeea2..5c2e1043 100644
+--- a/src/upnp_cds.cc
++++ b/src/upnp_cds.cc
+@@ -284,6 +284,11 @@ void ContentDirectoryService::processSubscriptionRequest(const std::unique_ptr<S
+ propset->print(buf, "", 0);
+ std::string xml = buf.str();
+
++#if defined(USING_NPUPNP)
++ UpnpAcceptSubscriptionXML(
++ deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
++ DESC_CDS_SERVICE_ID, xml, request->getSubscriptionID().c_str());
++#else
+ IXML_Document* event = nullptr;
+ int err = ixmlParseBufferEx(xml.c_str(), &event);
+ if (err != IXML_SUCCESS) {
+@@ -295,6 +300,7 @@ void ContentDirectoryService::processSubscriptionRequest(const std::unique_ptr<S
+ DESC_CDS_SERVICE_ID, event, request->getSubscriptionID().c_str());
+
+ ixmlDocument_free(event);
++#endif
+ log_debug("end");
+ }
+
+@@ -313,6 +319,10 @@ void ContentDirectoryService::sendSubscriptionUpdate(const std::string& containe
+ propset->print(buf, "", 0);
+ std::string xml = buf.str();
+
++#if defined(USING_NPUPNP)
++ UpnpNotifyXML(deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
++ DESC_CDS_SERVICE_ID, xml);
++#else
+ IXML_Document* event = nullptr;
+ int err = ixmlParseBufferEx(xml.c_str(), &event);
+ if (err != IXML_SUCCESS) {
+@@ -325,6 +335,7 @@ void ContentDirectoryService::sendSubscriptionUpdate(const std::string& containe
+ DESC_CDS_SERVICE_ID, event);
+
+ ixmlDocument_free(event);
++#endif
+
+ log_debug("end");
+ }
+diff --git a/src/upnp_cm.cc b/src/upnp_cm.cc
+index aa608480..d7ab40cf 100644
+--- a/src/upnp_cm.cc
++++ b/src/upnp_cm.cc
+@@ -127,6 +127,11 @@ void ConnectionManagerService::processSubscriptionRequest(const std::unique_ptr<
+ propset->print(buf, "", 0);
+ std::string xml = buf.str();
+
++#if defined(USING_NPUPNP)
++ UpnpAcceptSubscriptionXML(
++ deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
++ DESC_CM_SERVICE_ID, xml, request->getSubscriptionID().c_str());
++#else
+ IXML_Document* event = nullptr;
+ int err = ixmlParseBufferEx(xml.c_str(), &event);
+ if (err != IXML_SUCCESS) {
+@@ -138,6 +143,7 @@ void ConnectionManagerService::processSubscriptionRequest(const std::unique_ptr<
+ DESC_CM_SERVICE_ID, event, request->getSubscriptionID().c_str());
+
+ ixmlDocument_free(event);
++#endif
+ }
+
+ void ConnectionManagerService::sendSubscriptionUpdate(const std::string& sourceProtocol_CSV)
+@@ -150,6 +156,10 @@ void ConnectionManagerService::sendSubscriptionUpdate(const std::string& sourceP
+ propset->print(buf, "", 0);
+ std::string xml = buf.str();
+
++#if defined(USING_NPUPNP)
++ UpnpNotifyXML(deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
++ DESC_CM_SERVICE_ID, xml);
++#else
+ IXML_Document* event = nullptr;
+ int err = ixmlParseBufferEx(xml.c_str(), &event);
+ if (err != IXML_SUCCESS) {
+@@ -162,4 +172,5 @@ void ConnectionManagerService::sendSubscriptionUpdate(const std::string& sourceP
+ DESC_CM_SERVICE_ID, event);
+
+ ixmlDocument_free(event);
++#endif
+ }
+diff --git a/src/upnp_mrreg.cc b/src/upnp_mrreg.cc
+index 16eefaed..ecb49025 100644
+--- a/src/upnp_mrreg.cc
++++ b/src/upnp_mrreg.cc
+@@ -34,7 +34,6 @@
+ #include <utility>
+
+ #include "config/config_manager.h"
+-#include "ixml.h"
+ #include "server.h"
+ #include "storage/storage.h"
+ #include "upnp_xml.h"
+@@ -120,6 +119,11 @@ void MRRegistrarService::processSubscriptionRequest(const std::unique_ptr<Subscr
+ propset->print(buf, "", 0);
+ std::string xml = buf.str();
+
++#if defined(USING_NPUPNP)
++ UpnpAcceptSubscriptionXML(
++ deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
++ DESC_MRREG_SERVICE_ID, xml, request->getSubscriptionID().c_str());
++#else
+ IXML_Document* event = nullptr;
+ int err = ixmlParseBufferEx(xml.c_str(), &event);
+ if (err != IXML_SUCCESS) {
+@@ -131,6 +135,7 @@ void MRRegistrarService::processSubscriptionRequest(const std::unique_ptr<Subscr
+ DESC_MRREG_SERVICE_ID, event, request->getSubscriptionID().c_str());
+
+ ixmlDocument_free(event);
++#endif
+ }
+
+ // TODO: FIXME
+diff --git a/src/url_request_handler.cc b/src/url_request_handler.cc
+index f2a99c94..7de2227d 100644
+--- a/src/url_request_handler.cc
++++ b/src/url_request_handler.cc
+@@ -32,7 +32,6 @@
+ #ifdef HAVE_CURL
+ #include "url_request_handler.h" // API
+
+-#include <ixml.h>
+ #include <utility>
+
+ #include "config/config_manager.h"
+@@ -138,7 +137,11 @@ void URLRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
+ // ixmlCloneDOMString(header.c_str()));
+ // }
+
++#if defined(USING_NPUPNP)
++ UpnpFileInfo_set_ContentType(info, mimeType);
++#else
+ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimeType.c_str()));
++#endif
+ log_debug("web_get_info(): end");
+
+ /// \todo transcoding for get_info
+diff --git a/src/util/upnp_clients.cc b/src/util/upnp_clients.cc
+index 2033cf31..1dd7964d 100644
+--- a/src/util/upnp_clients.cc
++++ b/src/util/upnp_clients.cc
+@@ -268,6 +268,17 @@ bool Clients::getInfoByType(const std::string& match, ClientMatchType type, cons
+
+ bool Clients::downloadDescription(const std::string& location, std::unique_ptr<pugi::xml_document>& xml)
+ {
++#if defined(USING_NPUPNP)
++ std::string description, ct;
++ int errCode = UpnpDownloadUrlItem(location, description, ct);
++ if (errCode != UPNP_E_SUCCESS) {
++ log_debug("Error obtaining client description from {} -- error = {}", location, errCode);
++ return false;
++ }
++ const char* cxml = description.c_str();
++ xml = std::make_unique<pugi::xml_document>();
++ auto ret = xml->load_string(cxml);
++#else
+ IXML_Document* descDoc = nullptr;
+ int errCode = UpnpDownloadXmlDoc(location.c_str(), &descDoc);
+ if (errCode != UPNP_E_SUCCESS) {
+@@ -281,6 +292,7 @@ bool Clients::downloadDescription(const std::string& location, std::unique_ptr<p
+
+ ixmlFreeDOMString(cxml);
+ ixmlDocument_free(descDoc);
++#endif
+
+ if (ret.status != pugi::xml_parse_status::status_ok) {
+ log_debug("Unable to parse xml client description from {}", location);
+diff --git a/src/util/upnp_headers.cc b/src/util/upnp_headers.cc
+index ef85106b..aec13850 100644
+--- a/src/util/upnp_headers.cc
++++ b/src/util/upnp_headers.cc
+@@ -25,11 +25,13 @@
+
+ #include "upnp_headers.h" // API
+
++#if !defined(USING_NPUPNP)
+ #if (UPNP_VERSION > 11201)
+ #include <UpnpExtraHeaders.h>
+ #else
+ #include <ExtraHeaders.h>
+ #endif
++#endif
+ #include <string>
+
+ #include "common.h"
+@@ -101,18 +103,29 @@ void Headers::writeHeaders(UpnpFileInfo* fileInfo) const
+ if (headers == nullptr)
+ return;
+
++#if defined(USING_NPUPNP)
++ for (const auto& iter : *headers) {
++ fileInfo->response_headers.push_back(iter);
++ }
++#else
+ auto head = const_cast<UpnpListHead*>(UpnpFileInfo_get_ExtraHeadersList(fileInfo));
+ for (const auto& iter : *headers) {
+ UpnpExtraHeaders* h = UpnpExtraHeaders_new();
+ UpnpExtraHeaders_set_resp(h, formatHeader(iter, false).c_str());
+ UpnpListInsert(head, UpnpListEnd(head), const_cast<UpnpListHead*>(UpnpExtraHeaders_get_node(h)));
+ }
++#endif
+ }
+
+ std::unique_ptr<std::map<std::string, std::string>> Headers::readHeaders(UpnpFileInfo* fileInfo)
+ {
+ auto ret = std::make_unique<std::map<std::string, std::string>>();
+
++#if defined(USING_NPUPNP)
++ for (const auto& entry : fileInfo->request_headers) {
++ ret->insert(entry);
++ }
++#else
+ auto head = const_cast<UpnpListHead*>(UpnpFileInfo_get_ExtraHeadersList(fileInfo));
+ UpnpListIter pos;
+ for (pos = UpnpListBegin(head); pos != UpnpListEnd(head); pos = UpnpListNext(head, pos)) {
+@@ -121,6 +134,7 @@ std::unique_ptr<std::map<std::string, std::string>> Headers::readHeaders(UpnpFil
+ auto add = parseHeader(header);
+ ret->insert(add);
+ }
++#endif
+
+ return ret;
+ }
+diff --git a/src/web/web_request_handler.cc b/src/web/web_request_handler.cc
+index 60e2d028..117dcbfa 100644
+--- a/src/web/web_request_handler.cc
++++ b/src/web/web_request_handler.cc
+@@ -112,7 +112,11 @@ void WebRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
+ std::string mimetype = (returnType == "xml") ? MIMETYPE_XML : MIMETYPE_JSON;
+ std::string contentType = mimetype + "; charset=" + DEFAULT_INTERNAL_CHARSET;
+
++#if defined(USING_NPUPNP)
++ UpnpFileInfo_set_ContentType(info, contentType);
++#else
+ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(contentType.c_str()));
++#endif
+ Headers headers;
+ headers.addHeader(std::string { "Cache-Control" }, std::string { "no-cache, must-revalidate" });
+ headers.writeHeaders(info);
+++ /dev/null
-From 59d37af2d6afd3d0ab6e8c5f3ea099435150c349 Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Tue, 2 Jun 2020 15:55:25 -0700
-Subject: [PATCH] add missing unistd header
-
-Error with pid_t.
-
-Found with musl + libcxx.
-
-Signed-off-by: Rosen Penev <rosenp@gmail.com>
----
- src/util/process.h | 2 ++
- src/util/process_executor.h | 2 ++
- 2 files changed, 4 insertions(+)
-
-diff --git a/src/util/process.h b/src/util/process.h
-index e79e016c..8778aa34 100644
---- a/src/util/process.h
-+++ b/src/util/process.h
-@@ -35,6 +35,8 @@
- #include <memory>
- #include <string>
-
-+#include <unistd.h>
-+
- // forward declaration
- class Config;
-
-diff --git a/src/util/process_executor.h b/src/util/process_executor.h
-index eaccf451..2a724087 100644
---- a/src/util/process_executor.h
-+++ b/src/util/process_executor.h
-@@ -35,6 +35,8 @@
- #include <string>
- #include <vector>
-
-+#include <unistd.h>
-+
- #include "executor.h"
-
- class ProcessExecutor : public Executor {
+++ /dev/null
-From 89b289cde29c731f995642a341dc5fd3b47ec7a0 Mon Sep 17 00:00:00 2001
-From: Jean-Francois Dockes <jf@dockes.org>
-Date: Mon, 4 May 2020 16:32:23 +0200
-Subject: [PATCH] The access() system call needs unistd.h, at least on Focal
-
----
- src/file_request_handler.cc | 2 +-
- src/iohandler/io_handler_chainer.cc | 2 +-
- src/serve_request_handler.cc | 2 +-
- src/util/upnp_quirks.cc | 2 +-
- 4 files changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/src/file_request_handler.cc b/src/file_request_handler.cc
-index e8579b06..cfa3eaed 100644
---- a/src/file_request_handler.cc
-+++ b/src/file_request_handler.cc
-@@ -30,9 +30,9 @@
- /// \file file_request_handler.cc
-
- #include "file_request_handler.h" // API
--
- #include <filesystem>
- #include <sys/stat.h>
-+#include <unistd.h>
- #include <utility>
-
- #include "config/config_manager.h"
-diff --git a/src/iohandler/io_handler_chainer.cc b/src/iohandler/io_handler_chainer.cc
-index e8701cd7..beaa9d03 100644
---- a/src/iohandler/io_handler_chainer.cc
-+++ b/src/iohandler/io_handler_chainer.cc
-@@ -30,8 +30,8 @@
- /// \file io_handler_chainer.cc
-
- #include "io_handler_chainer.h" // API
--
- #include <cstdlib>
-+#include <unistd.h>
-
- #include "exceptions.h"
-
-diff --git a/src/serve_request_handler.cc b/src/serve_request_handler.cc
-index 8eaf46af..210140a3 100644
---- a/src/serve_request_handler.cc
-+++ b/src/serve_request_handler.cc
-@@ -30,8 +30,8 @@
- /// \file serve_request_handler.cc
-
- #include "serve_request_handler.h"
--
- #include <sys/stat.h>
-+#include <unistd.h>
- #include <utility>
-
- #include "config/config_manager.h"
-diff --git a/src/util/upnp_quirks.cc b/src/util/upnp_quirks.cc
-index df137370..e6f510b4 100644
---- a/src/util/upnp_quirks.cc
-+++ b/src/util/upnp_quirks.cc
-@@ -24,13 +24,13 @@
- /// \file upnp_quirks.cc
-
- #include "upnp_quirks.h" // API
--
- #include "cds_objects.h"
- #include "config/config_manager.h"
- #include "server.h"
- #include "util/tools.h"
- #include "util/upnp_clients.h"
- #include "util/upnp_headers.h"
-+#include <unistd.h>
-
- Quirks::Quirks(std::shared_ptr<Config> config, const struct sockaddr_storage* addr, const std::string& userAgent)
- : config(std::move(config))
+++ /dev/null
-From 2ebccbb993dca41674de295f2d513abd568f971a Mon Sep 17 00:00:00 2001
-From: Jean-Francois Dockes <jf@dockes.org>
-Date: Fri, 13 Mar 2020 09:19:04 +0100
-Subject: [PATCH] Quick changes for working with NPUPNP
-
----
- CMakeLists.txt | 12 +++++-------
- src/action_request.cc | 11 +++++++++++
- src/device_description_handler.cc | 4 ++++
- src/file_request_handler.cc | 4 ++++
- src/iohandler/file_io_handler.cc | 2 ++
- src/iohandler/io_handler.cc | 2 ++
- src/iohandler/mem_io_handler.cc | 2 ++
- src/serve_request_handler.cc | 9 ++++++++-
- src/server.cc | 8 ++++++++
- src/transcoding/transcode_ext_handler.cc | 2 ++
- src/upnp_cds.cc | 12 +++++++++++-
- src/upnp_cm.cc | 11 +++++++++++
- src/upnp_mrreg.cc | 10 +++++++++-
- src/url_request_handler.cc | 6 ++++++
- src/util/upnp_clients.cc | 12 ++++++++++++
- src/util/upnp_headers.cc | 14 +++++++++++++-
- src/util/upnp_headers.h | 2 ++
- src/web/web_request_handler.cc | 4 ++++
- 18 files changed, 116 insertions(+), 11 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 46f2ca5c..b51300d9 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -293,13 +293,11 @@ if (LFS_FOUND)
- target_link_libraries(gerbera ${LFS_LIBRARIES})
- endif()
-
--find_package (LibUpnp REQUIRED)
--include_directories(${UPNP_INCLUDE_DIRS})
--target_link_libraries (gerbera ${UPNP_LIBRARIES})
--
--if (UPNP_VERSION_STRING VERSION_LESS "1.12.1")
-- message(FATAL_ERROR "gerbera requires libupnp 1.12.1 or above.")
--endif()
-+#### Hard-coded NPUPNP defs for now, just for testing
-+add_definitions(-DUSING_NPUPNP)
-+include_directories(/usr/include/npupnp/upnp)
-+target_link_libraries (gerbera -lnpupnp)
-+set (UPNP_HAS_IPV6 1)
-
- if (NOT UPNP_HAS_IPV6)
- message(FATAL_ERROR "Gerbera requires libupnp with IPv6 support.")
-diff --git a/src/action_request.cc b/src/action_request.cc
-index 3aa4a991..29be6aaf 100644
---- a/src/action_request.cc
-+++ b/src/action_request.cc
-@@ -65,11 +65,17 @@ std::string ActionRequest::getServiceID() const
-
- std::unique_ptr<pugi::xml_document> ActionRequest::getRequest() const
- {
-+#if !defined(USING_NPUPNP)
- DOMString cxml = ixmlPrintDocument(UpnpActionRequest_get_ActionRequest(upnp_request));
-+#endif
- auto request = std::make_unique<pugi::xml_document>();
-+#if defined(USING_NPUPNP)
-+ auto ret = request->load_string(upnp_request->xmlAction.c_str());
-+#else
- auto ret = request->load_string(cxml);
- ixmlFreeDOMString(cxml);
-
-+#endif
- if (ret.status != pugi::xml_parse_status::status_ok)
- throw_std_runtime_error("Unable to parse ixml");
-
-@@ -94,6 +100,7 @@ void ActionRequest::update()
- std::string xml = buf.str();
- log_debug("ActionRequest::update(): {}", xml.c_str());
-
-+#if !defined(USING_NPUPNP)
- IXML_Document* result = nullptr;
- int err = ixmlParseBufferEx(xml.c_str(), &result);
-
-@@ -105,6 +112,10 @@ void ActionRequest::update()
- UpnpActionRequest_set_ActionResult(upnp_request, result);
- UpnpActionRequest_set_ErrCode(upnp_request, errCode);
- }
-+#else
-+ UpnpActionRequest_set_xmlResponse(upnp_request, xml);
-+ UpnpActionRequest_set_ErrCode(upnp_request, errCode);
-+#endif
- } else {
- // ok, here there can be two cases
- // either the function below already did set an error code,
-diff --git a/src/device_description_handler.cc b/src/device_description_handler.cc
-index 6aca745e..cf2e8015 100644
---- a/src/device_description_handler.cc
-+++ b/src/device_description_handler.cc
-@@ -45,7 +45,11 @@ void DeviceDescriptionHandler::getInfo(const char* filename, UpnpFileInfo* info)
- {
- // We should be able to do the generation here, but libupnp doesnt support the request cookies yet
- UpnpFileInfo_set_FileLength(info, -1);
-+#if defined(USING_NPUPNP)
- UpnpFileInfo_set_ContentType(info, "application/xml");
-+#else
-+ UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString("application/xml"));
-+#endif
- UpnpFileInfo_set_IsReadable(info, 1);
- UpnpFileInfo_set_IsDirectory(info, 0);
- }
-diff --git a/src/file_request_handler.cc b/src/file_request_handler.cc
-index e8579b06..615f7e85 100644
---- a/src/file_request_handler.cc
-+++ b/src/file_request_handler.cc
-@@ -238,7 +238,11 @@ void FileRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
-
- UpnpFileInfo_set_LastModified(info, statbuf.st_mtime);
- UpnpFileInfo_set_IsDirectory(info, S_ISDIR(statbuf.st_mode));
-+#if defined(USING_NPUPNP)
-+ UpnpFileInfo_set_ContentType(info, mimeType);
-+#else
- UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimeType.c_str()));
-+#endif
-
- headers->writeHeaders(info);
-
-diff --git a/src/iohandler/file_io_handler.cc b/src/iohandler/file_io_handler.cc
-index 7e239250..ab5155ec 100644
---- a/src/iohandler/file_io_handler.cc
-+++ b/src/iohandler/file_io_handler.cc
-@@ -32,7 +32,9 @@
- #include "file_io_handler.h" // API
-
- #include <cstdio>
-+#ifndef USING_NPUPNP
- #include <ixml.h>
-+#endif
- #include <utility>
-
- #include "cds_objects.h"
-diff --git a/src/iohandler/io_handler.cc b/src/iohandler/io_handler.cc
-index f9789425..75a36130 100644
---- a/src/iohandler/io_handler.cc
-+++ b/src/iohandler/io_handler.cc
-@@ -31,7 +31,9 @@
-
- #include "io_handler.h" // API
-
-+#ifndef USING_NPUPNP
- #include <ixml.h>
-+#endif
- #include <unistd.h>
-
- #include "server.h"
-diff --git a/src/iohandler/mem_io_handler.cc b/src/iohandler/mem_io_handler.cc
-index 5574a16d..2916fd12 100644
---- a/src/iohandler/mem_io_handler.cc
-+++ b/src/iohandler/mem_io_handler.cc
-@@ -35,7 +35,9 @@
- #include <cstdlib>
- #include <cstring>
- #include <ctime>
-+#ifndef USING_NPUPNP
- #include <ixml.h>
-+#endif
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <unistd.h>
-diff --git a/src/serve_request_handler.cc b/src/serve_request_handler.cc
-index 8eaf46af..b9bd7b25 100644
---- a/src/serve_request_handler.cc
-+++ b/src/serve_request_handler.cc
-@@ -94,7 +94,11 @@ void ServeRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
- UpnpFileInfo_set_IsReadable(info, 0);
- }
-
-+#if defined(USING_NPUPNP)
-+ UpnpFileInfo_set_ContentType(info, mimetype);
-+#else
- UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimetype.c_str()));
-+#endif
- } else {
- throw_std_runtime_error("Not a regular file: " + path);
- }
-@@ -157,8 +161,11 @@ std::unique_ptr<IOHandler> ServeRequestHandler::open(const char* filename,
- info->is_readable = 0;
- }
-
--
-+#if defined(USING_NPUPNP)
-+ info->content_type = mimetype;
-+#else
- info->content_type = ixmlCloneDOMString(mimetype.c_str());
-+#endif
- */
- } else {
- throw_std_runtime_error("Not a regular file: " + path);
-diff --git a/src/server.cc b/src/server.cc
-index 913a4913..7cbabc71 100644
---- a/src/server.cc
-+++ b/src/server.cc
-@@ -398,9 +398,17 @@ int Server::handleUpnpClientEvent(Upnp_EventType eventType, const void* event)
- case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
- case UPNP_DISCOVERY_SEARCH_RESULT: {
- auto d_event = reinterpret_cast<const UpnpDiscovery*>(event);
-+#if defined(USING_NPUPNP)
-+ const char* userAgent = UpnpDiscovery_get_Os_cstr(d_event);
-+#else
- const char* userAgent = UpnpString_get_String(UpnpDiscovery_get_Os(d_event));
-+#endif
- const struct sockaddr_storage* destAddr = UpnpDiscovery_get_DestAddr(d_event);
-+#if defined(USING_NPUPNP)
-+ const char* location = UpnpDiscovery_get_Location_cstr(d_event);
-+#else
- const char* location = UpnpString_get_String(UpnpDiscovery_get_Location(d_event));
-+#endif
-
- Clients::addClientByDiscovery(destAddr, userAgent, location);
- break;
-diff --git a/src/transcoding/transcode_ext_handler.cc b/src/transcoding/transcode_ext_handler.cc
-index 4dad0e3f..412c1370 100644
---- a/src/transcoding/transcode_ext_handler.cc
-+++ b/src/transcoding/transcode_ext_handler.cc
-@@ -37,7 +37,9 @@
- #include <cstring>
- #include <fcntl.h>
- #include <filesystem>
-+#ifndef USING_NPUPNP
- #include <ixml.h>
-+#endif
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <unistd.h>
-diff --git a/src/upnp_cds.cc b/src/upnp_cds.cc
-index 6491fa78..a758655c 100644
---- a/src/upnp_cds.cc
-+++ b/src/upnp_cds.cc
-@@ -284,6 +284,7 @@ void ContentDirectoryService::processSubscriptionRequest(const std::unique_ptr<S
- propset->print(buf, "", 0);
- std::string xml = buf.str();
-
-+#if !defined(USING_NPUPNP)
- IXML_Document* event = nullptr;
- int err = ixmlParseBufferEx(xml.c_str(), &event);
- if (err != IXML_SUCCESS) {
-@@ -295,6 +296,11 @@ void ContentDirectoryService::processSubscriptionRequest(const std::unique_ptr<S
- DESC_CDS_SERVICE_ID, event, request->getSubscriptionID().c_str());
-
- ixmlDocument_free(event);
-+#else
-+ UpnpAcceptSubscriptionXML(
-+ deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
-+ DESC_CDS_SERVICE_ID, xml, request->getSubscriptionID().c_str());
-+#endif
- log_debug("end");
- }
-
-@@ -313,6 +319,7 @@ void ContentDirectoryService::sendSubscriptionUpdate(const std::string& containe
- propset->print(buf, "", 0);
- std::string xml = buf.str();
-
-+#if !defined(USING_NPUPNP)
- IXML_Document* event = nullptr;
- int err = ixmlParseBufferEx(xml.c_str(), &event);
- if (err != IXML_SUCCESS) {
-@@ -323,8 +330,11 @@ void ContentDirectoryService::sendSubscriptionUpdate(const std::string& containe
- UpnpNotifyExt(deviceHandle,
- config->getOption(CFG_SERVER_UDN).c_str(),
- DESC_CDS_SERVICE_ID, event);
--
- ixmlDocument_free(event);
-+#else
-+ UpnpNotifyXML(deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
-+ DESC_CDS_SERVICE_ID, xml);
-+#endif
-
- log_debug("end");
- }
-diff --git a/src/upnp_cm.cc b/src/upnp_cm.cc
-index aa608480..33f86bd2 100644
---- a/src/upnp_cm.cc
-+++ b/src/upnp_cm.cc
-@@ -127,6 +127,7 @@ void ConnectionManagerService::processSubscriptionRequest(const std::unique_ptr<
- propset->print(buf, "", 0);
- std::string xml = buf.str();
-
-+#if !defined(USING_NPUPNP)
- IXML_Document* event = nullptr;
- int err = ixmlParseBufferEx(xml.c_str(), &event);
- if (err != IXML_SUCCESS) {
-@@ -138,6 +139,11 @@ void ConnectionManagerService::processSubscriptionRequest(const std::unique_ptr<
- DESC_CM_SERVICE_ID, event, request->getSubscriptionID().c_str());
-
- ixmlDocument_free(event);
-+#else
-+ UpnpAcceptSubscriptionXML(
-+ deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
-+ DESC_CM_SERVICE_ID, xml, request->getSubscriptionID().c_str());
-+#endif
- }
-
- void ConnectionManagerService::sendSubscriptionUpdate(const std::string& sourceProtocol_CSV)
-@@ -150,6 +156,7 @@ void ConnectionManagerService::sendSubscriptionUpdate(const std::string& sourceP
- propset->print(buf, "", 0);
- std::string xml = buf.str();
-
-+#if !defined(USING_NPUPNP)
- IXML_Document* event = nullptr;
- int err = ixmlParseBufferEx(xml.c_str(), &event);
- if (err != IXML_SUCCESS) {
-@@ -162,4 +169,8 @@ void ConnectionManagerService::sendSubscriptionUpdate(const std::string& sourceP
- DESC_CM_SERVICE_ID, event);
-
- ixmlDocument_free(event);
-+#else
-+ UpnpNotifyXML(deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
-+ DESC_CM_SERVICE_ID, xml);
-+#endif
- }
-diff --git a/src/upnp_mrreg.cc b/src/upnp_mrreg.cc
-index 16eefaed..f993f452 100644
---- a/src/upnp_mrreg.cc
-+++ b/src/upnp_mrreg.cc
-@@ -34,7 +34,9 @@
- #include <utility>
-
- #include "config/config_manager.h"
--#include "ixml.h"
-+#ifndef USING_NPUPNP
-+#include <ixml.h>
-+#endif
- #include "server.h"
- #include "storage/storage.h"
- #include "upnp_xml.h"
-@@ -120,6 +122,7 @@ void MRRegistrarService::processSubscriptionRequest(const std::unique_ptr<Subscr
- propset->print(buf, "", 0);
- std::string xml = buf.str();
-
-+#if !defined(USING_NPUPNP)
- IXML_Document* event = nullptr;
- int err = ixmlParseBufferEx(xml.c_str(), &event);
- if (err != IXML_SUCCESS) {
-@@ -131,6 +134,11 @@ void MRRegistrarService::processSubscriptionRequest(const std::unique_ptr<Subscr
- DESC_MRREG_SERVICE_ID, event, request->getSubscriptionID().c_str());
-
- ixmlDocument_free(event);
-+#else
-+ UpnpAcceptSubscriptionXML(
-+ deviceHandle, config->getOption(CFG_SERVER_UDN).c_str(),
-+ DESC_MRREG_SERVICE_ID, xml, request->getSubscriptionID().c_str());
-+#endif
- }
-
- // TODO: FIXME
-diff --git a/src/url_request_handler.cc b/src/url_request_handler.cc
-index f2a99c94..66af027b 100644
---- a/src/url_request_handler.cc
-+++ b/src/url_request_handler.cc
-@@ -32,7 +32,9 @@
- #ifdef HAVE_CURL
- #include "url_request_handler.h" // API
-
-+#ifndef USING_NPUPNP
- #include <ixml.h>
-+#endif
- #include <utility>
-
- #include "config/config_manager.h"
-@@ -138,7 +140,11 @@ void URLRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
- // ixmlCloneDOMString(header.c_str()));
- // }
-
-+#if defined(USING_NPUPNP)
-+ UpnpFileInfo_set_ContentType(info, mimeType);
-+#else
- UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(mimeType.c_str()));
-+#endif
- log_debug("web_get_info(): end");
-
- /// \todo transcoding for get_info
-diff --git a/src/util/upnp_clients.cc b/src/util/upnp_clients.cc
-index ab02b58d..7bc85d77 100644
---- a/src/util/upnp_clients.cc
-+++ b/src/util/upnp_clients.cc
-@@ -203,6 +203,15 @@ bool Clients::getInfoByType(const std::string& match, ClientMatchType type, cons
-
- bool Clients::downloadDescription(const std::string& location, std::unique_ptr<pugi::xml_document>& xml)
- {
-+#if defined(USING_NPUPNP)
-+ std::string description, ct;
-+ int errCode = UpnpDownloadUrlItem(location, description, ct);
-+ if (errCode != UPNP_E_SUCCESS) {
-+ log_debug("Error obtaining client description from {} -- error = {}", location, errCode);
-+ return false;
-+ }
-+ const char *cxml = description.c_str();
-+#else
- IXML_Document* descDoc = nullptr;
- int errCode = UpnpDownloadXmlDoc(location.c_str(), &descDoc);
- if (errCode != UPNP_E_SUCCESS) {
-@@ -211,12 +220,15 @@ bool Clients::downloadDescription(const std::string& location, std::unique_ptr<p
- }
-
- DOMString cxml = ixmlPrintDocument(descDoc);
-+#endif
- xml = std::make_unique<pugi::xml_document>();
- auto ret = xml->load_string(cxml);
-
-+#if !defined(USING_NPUPNP)
- ixmlFreeDOMString(cxml);
- ixmlDocument_free(descDoc);
-
-+#endif
- if (ret.status != pugi::xml_parse_status::status_ok) {
- log_debug("Unable to parse xml client description from {}", location);
- return false;
-diff --git a/src/util/upnp_headers.cc b/src/util/upnp_headers.cc
-index c05cffe6..19ba88ca 100644
---- a/src/util/upnp_headers.cc
-+++ b/src/util/upnp_headers.cc
-@@ -96,18 +96,29 @@ void Headers::writeHeaders(UpnpFileInfo* fileInfo) const
- if (headers == nullptr)
- return;
-
-+#if defined(USING_NPUPNP)
-+ for (auto iter : *headers) {
-+ fileInfo->response_headers.push_back(iter);
-+ }
-+#else
- auto head = const_cast<UpnpListHead*>(UpnpFileInfo_get_ExtraHeadersList(fileInfo));
- for (auto iter : *headers) {
- UpnpExtraHeaders* h = UpnpExtraHeaders_new();
- UpnpExtraHeaders_set_resp(h, formatHeader(iter, false).c_str());
- UpnpListInsert(head, UpnpListEnd(head), const_cast<UpnpListHead*>(UpnpExtraHeaders_get_node(h)));
- }
-+#endif
- }
-
- std::unique_ptr<std::map<std::string, std::string>> Headers::readHeaders(UpnpFileInfo* fileInfo)
- {
- auto ret = std::make_unique<std::map<std::string, std::string>>();
-
-+#if defined(USING_NPUPNP)
-+ for (const auto& entry : fileInfo->request_headers) {
-+ ret->insert(entry);
-+ }
-+#else
- auto head = const_cast<UpnpListHead*>(UpnpFileInfo_get_ExtraHeadersList(fileInfo));
- UpnpListIter pos;
- for (pos = UpnpListBegin(head); pos != UpnpListEnd(head); pos = UpnpListNext(head, pos)) {
-@@ -116,6 +127,7 @@ std::unique_ptr<std::map<std::string, std::string>> Headers::readHeaders(UpnpFil
- auto add = parseHeader(header);
- ret->insert(add);
- }
--
-+#endif
-+
- return ret;
- }
-diff --git a/src/util/upnp_headers.h b/src/util/upnp_headers.h
-index 9677d6e4..dd839236 100644
---- a/src/util/upnp_headers.h
-+++ b/src/util/upnp_headers.h
-@@ -26,7 +26,9 @@
- #ifndef GERBERA_HEADERS_H
- #define GERBERA_HEADERS_H
-
-+#if !defined(USING_NPUPNP)
- #include <ExtraHeaders.h>
-+#endif
- #include <map>
- #include <memory>
- #include <upnp.h>
-diff --git a/src/web/web_request_handler.cc b/src/web/web_request_handler.cc
-index 71fc9fd5..2ca6601b 100644
---- a/src/web/web_request_handler.cc
-+++ b/src/web/web_request_handler.cc
-@@ -120,7 +120,11 @@ void WebRequestHandler::getInfo(const char* filename, UpnpFileInfo* info)
-
- contentType = mimetype + "; charset=" + DEFAULT_INTERNAL_CHARSET;
-
-+#if defined(USING_NPUPNP)
-+ UpnpFileInfo_set_ContentType(info, contentType);
-+#else
- UpnpFileInfo_set_ContentType(info, ixmlCloneDOMString(contentType.c_str()));
-+#endif
- Headers headers;
- headers.addHeader(std::string { "Cache-Control" }, std::string { "no-cache, must-revalidate" });
- headers.writeHeaders(info);
+++ /dev/null
---- a/src/upnp_cds.cc
-+++ b/src/upnp_cds.cc
-@@ -83,7 +83,7 @@ void ContentDirectoryService::doBrowse(const std::unique_ptr<ActionRequest>& req
- if (BrowseFlag == "BrowseDirectChildren")
- flag |= BROWSE_DIRECT_CHILDREN;
- else if (BrowseFlag != "BrowseMetadata")
-- throw UpnpException(UPNP_SOAP_E_INVALID_ARGS,
-+ throw UpnpException(UPNP_E_INVALID_ARGUMENT,
- "invalid browse flag: " + BrowseFlag);
-
- auto parent = storage->loadObject(objectID);
PKG_BUILD_PARALLEL:=1
DISABLE_NLS:=
-PKG_BUILD_DEPENDS:=zlib freetype libpng libjpeg tiff
+PKG_BUILD_DEPENDS:=zlib freetype libpng libjpeg-turbo tiff
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-libav
-PKG_VERSION:=1.17.1
+PKG_VERSION:=1.17.2
PKG_RELEASE:=1
PKG_SOURCE:=gst-libav-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-libav
-PKG_HASH:=9d8d73a7944f776199c7648b3b7330f940b10dc4e08a6509185ae43cb456cb1f
+PKG_HASH:=5c8768e308b547b237700d4003c3a5622eb361914d69ec43b480f1c23ea31752
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-libav-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -188,5 +188,5 @@ plugins = []
+ subdir('ext/libav')
+ subdir('docs')
+
+-python3 = import('python').find_installation()
++python3 = 'python3'
+ run_command(python3, '-c', 'import shutil; shutil.copy("hooks/pre-commit.hook", ".git/hooks/pre-commit")')
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-bad
-PKG_VERSION:=1.17.1
+PKG_VERSION:=1.17.2
PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-bad-$(PKG_VERSION)
PKG_SOURCE:=gst-plugins-bad-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://gstreamer.freedesktop.org/src/gst-plugins-bad/
-PKG_HASH:=598937c818d0955543318203faa28d826eb68d487934be4737e999ad272210d0
+PKG_HASH:=fadbf229dbb29cae15ecb1858382aee60f2fa82067673598791c5fdfc52ad2cc
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
Ted Hess <thess@kitschensync.net>
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -417,7 +417,7 @@ gst_plugins_bad_args = ['-DHAVE_CONFIG_H']
+ configinc = include_directories('.')
+ libsinc = include_directories('gst-libs')
+
+-python3 = import('python').find_installation()
++python3 = 'python3'
+
+ gir = find_program('g-ir-scanner', required : get_option('introspection'))
+ gnome = import('gnome')
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-base
-PKG_VERSION:=1.17.1
+PKG_VERSION:=1.17.2
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-base-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-plugins-base
-PKG_HASH:=c0d8a84e3262e706ebc88831ca7349e5ae221274ef362599734573b3d3c028f3
+PKG_HASH:=30bfdaad8faa380fd74c3e74261748e218649786939ad10edfe067a39d4c4996
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-base-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
$(eval $(call GstBuildPlugin,alsa,ALSA audio source/sink,audio tag,,+alsa-lib))
$(eval $(call GstBuildPlugin,ivorbisdec,Integer Vorbis decoder plugin for devices without floating point,audio tag,,+libvorbisidec))
#$(eval $(call GstBuildPlugin,cdparanoia,cdparanoia,,+libcdparanoia))
-#$(eval $(call GstBuildPlugin,libvisual,libvisual audio visualization,,+alsa-lib))
+#$(eval $(call GstBuildPlugin,libvisual,libvisual audio visualization,,+libvisual))
$(eval $(call GstBuildPlugin,ogg,ogg parser muxer demuxer,riff tag pbutils video,,+libogg))
$(eval $(call GstBuildPlugin,opus,OPUS audio codec,pbutils video,,+libopus))
-#$(eval $(call GstBuildPlugin,pango,Pango text rendering and overlay plugin,,+libopus))
+#$(eval $(call GstBuildPlugin,pango,Pango text rendering and overlay plugin,,+pango))
$(eval $(call GstBuildPlugin,theora,Theora,tag video,,+libogg +libtheora))
$(eval $(call GstBuildPlugin,vorbis,Vorbis,audio tag,ogg,+libvorbis))
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -400,7 +400,7 @@ if get_option('default_library') == 'shared'
+ plugins_pkgconfig_install_dir = disabler()
+ endif
+
+-python3 = import('python').find_installation()
++python3 = 'python3'
+ subdir('gst-libs')
+ subdir('gst')
+ subdir('ext')
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-good
-PKG_VERSION:=1.17.1
+PKG_VERSION:=1.17.2
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-good-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-plugins-good/
-PKG_HASH:=ea8957460ed38261e5c4bf6a8bf98d946298b756a695b27c9b1209aa7b76b0d7
+PKG_HASH:=4278ebd32383d1e26219e6bb9ae492fe5dc7d3246ba8570a192e9dc98e2a436a
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-good-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -400,7 +400,7 @@ endif
+
+ presetdir = join_paths(get_option('datadir'), 'gstreamer-' + api_version, 'presets')
+
+-python3 = import('python').find_installation()
++python3 = 'python3'
+ pkgconfig = import('pkgconfig')
+ plugins_pkgconfig_install_dir = join_paths(plugins_install_dir, 'pkgconfig')
+ if get_option('default_library') == 'shared'
include $(TOPDIR)/rules.mk
PKG_NAME:=gst1-plugins-ugly
-PKG_VERSION:=1.17.1
+PKG_VERSION:=1.17.2
PKG_RELEASE:=1
PKG_SOURCE:=gst-plugins-ugly-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gst-plugins-ugly
-PKG_HASH:=a5e564107120b5b27c48709c5dfdb266737def5b3eb7aaabaddd304d425d8f21
+PKG_HASH:=af32ea2ca43e6e3199c0b3f71942838bbf5e08c15f69f26db5d81a8ea85a88ad
PKG_BUILD_DIR:=$(BUILD_DIR)/gst-plugins-ugly-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -257,7 +257,7 @@ if get_option('default_library') == 'shared'
+ plugins_pkgconfig_install_dir = disabler()
+ endif
+
+-python3 = import('python').find_installation()
++python3 = 'python3'
+ subdir('gst')
+ subdir('ext')
+ subdir('tests')
include $(TOPDIR)/rules.mk
PKG_NAME:=gstreamer1
-PKG_VERSION:=1.17.1
+PKG_VERSION:=1.17.2
PKG_RELEASE:=1
PKG_SOURCE:=gstreamer-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://gstreamer.freedesktop.org/src/gstreamer
-PKG_HASH:=f63566152755aab98414feb859ea8b00d3b07cad2486f304a8feec1265e5aa0e
+PKG_HASH:=0163bb2c086759411b686526e7d8f4b22efc4ac02ddf3941f66b14949f106eef
PKG_BUILD_DIR:=$(BUILD_DIR)/gstreamer-$(PKG_VERSION)
PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org> \
PKG_CPE_ID:=cpe:/a:gstreamer_project:gstreamer
PKG_INSTALL:=1
-PKG_BUILD_DEPENDS:=meson/host glib2/host
+PKG_BUILD_DEPENDS:=meson/host glib2/host gettext-full/host
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
--- a/gst/gstplugin.c
+++ b/gst/gstplugin.c
-@@ -777,15 +777,8 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename,
- goto return_error;
+@@ -790,15 +790,8 @@ _priv_gst_plugin_load_file_for_registry (const gchar * filename,
}
+ #endif
- flags = G_MODULE_BIND_LOCAL;
- /* libgstpython.so is the gst-python plugin loader. It needs to be loaded with
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -505,7 +505,7 @@ if get_option('default_library') == 'static'
+ endif
+
+ # Used in gst/parse/meson.build and below
+-python3 = import('python').find_installation()
++python3 = 'python3'
+
+ bashcomp_option = get_option('bash-completion')
+ bashcomp_dep = dependency('bash-completion', version : '>= 2.0', required : bashcomp_option)
include $(TOPDIR)/rules.mk
PKG_NAME:=youtube-dl
-PKG_VERSION:=2020.6.16.1
+PKG_VERSION:=2020.7.28
PKG_RELEASE:=1
PYPI_NAME:=youtube_dl
-PKG_HASH:=9fc0389a1bbbeb609a5bb4ad5630dea107a9d1a24c73721c611a78c234309a75
+PKG_HASH:=4af90dac41dba8b2c8bdce3903177c4ecbc27d75e03a3f08070f9d9decbae829
-PKG_MAINTAINER:=Adrian Panella <ianchi74@outlook.com>, Josef Schlehofer <pepe.schlehofer@gmail.com>
+PKG_MAINTAINER:=Josef Schlehofer <pepe.schlehofer@gmail.com>
PKG_LICENSE:=Unlicense
PKG_LICENSE_FILES:=LICENSE
prepare_wifidog_conf() {
local cfg=$1
- local enable
+ local disabled
local gateway_id
local gateway_interface
local auth_server_hostname
[ -f ${CONFIGFILE} ] && rm -f ${CONFIGFILE}
- config_get enable "${cfg}" "disabled" 0
- if [ "${enable}" = "0" ]; then
+ config_get disabled "${cfg}" "disabled" 1
+ if [ "${disabled}" = "1" ]; then
echo "wifidogx disabled in /etc/config/wifidogx file, please set disabled to 0 to enable it" >&2
return
fi
exit
fi
- if [ -s "${APFREE_CERT}" ] && [ -s "${APFREE_KEY}" ]; then
+ if [ ! -s "${APFREE_CERT}" ] || [ ! -s "${APFREE_KEY}" ]; then
generate_keys
fi
- if [ -s ${APFREE_KEY} ] && [ -s ${APFREE_CERT} ]; then
+ if [ ! -s ${APFREE_KEY} ] || [ ! -s ${APFREE_CERT} ]; then
echo "no cert or key, exit..." >&2
exit
fi
include $(TOPDIR)/rules.mk
PKG_NAME:=clamav
-PKG_VERSION:=0.102.3
+PKG_VERSION:=0.102.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.clamav.net/downloads/production/
-PKG_HASH:=ed3050c4569989ee7ab54c7b87246b41ed808259632849be0706467442dc0693
+PKG_HASH:=eebd426a68020ecad0d2084b8c763e6898ccfd5febcae833d719640bb3ff391b
PKG_MAINTAINER:=Marko Ratkaj <marko.ratkaj@sartura.hr> \
Lucian Cristian <lucian.cristian@gmail.com>
include $(TOPDIR)/rules.mk
PKG_NAME:=fping
-PKG_VERSION:=4.3
+PKG_VERSION:=4.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://fping.org/dist/
-PKG_HASH:=92040ae842f7b8942d5cf26d8f58702a8d84c40a1fd492b415bd01b622bf372d
+PKG_HASH:=9f854b65a52dc7b1749d6743e35d0a6268179d1a724267339fc9a066b2b72d11
PKG_MAINTAINER:=Nikil Mehta <nikil.mehta@gmail.com>
PKG_LICENSE:=BSD-4-Clause
URL:=https://fping.org/
endef
-
define Package/fping/description
- fping is a ping like program which uses the Internet Control Message Protocol
- (ICMP) echo request to determine if a target host is responding. fping
- differs from ping in that you can specify any number of targets on the command
- line, or specify a file containing the lists of targets to ping. Instead of
- sending to one target until it times out or replies, fping will send out a
- ping packet and move on to the next target in a round-robin fashion.
+ fping is a ping like program which uses the Internet Control Message Protocol
+ (ICMP) echo request to determine if a target host is responding. fping
+ differs from ping in that you can specify any number of targets on the command
+ line, or specify a file containing the lists of targets to ping. Instead of
+ sending to one target until it times out or replies, fping will send out a
+ ping packet and move on to the next target in a round-robin fashion.
endef
-CONFIGURE_ARGS+= \
+CONFIGURE_ARGS += \
--enable-ipv4 \
$(if $(CONFIG_IPV6),en,dis)able-ipv6
+++ /dev/null
-From 54e97d9e393e375820e9c6ca0a56c7a4092ea5de Mon Sep 17 00:00:00 2001
-From: Lars Wendler <polynomial-c@gentoo.org>
-Date: Sun, 12 Jul 2020 13:55:44 +0200
-Subject: [PATCH] Fix build with --disable-ipv6
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Otherwise build breaks with:
-
-fping.c:399:14: error: ‘ident6’ undeclared (first use in this function); did you mean ‘ident4’?
- 399 | ident4 = ident6 = getpid() & 0xFFFF;
- | ^~~~~~
- | ident4
-
-Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
----
- src/fping.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/fping.c b/src/fping.c
-index 3522123..4304531 100644
---- a/src/fping.c
-+++ b/src/fping.c
-@@ -258,12 +258,12 @@ HOST_ENTRY* ev_last;
-
- char* prog;
- int ident4 = 0; /* our icmp identity field */
-+int ident6 = 0;
- int socket4 = -1;
- int using_sock_dgram4 = 0;
- #ifndef IPV6
- int hints_ai_family = AF_INET;
- #else
--int ident6 = 0;
- int socket6 = -1;
- int hints_ai_family = AF_UNSPEC;
- #endif
PKG_NAME:=freeradius3
PKG_VERSION:=release_3_0_21
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/FreeRADIUS/freeradius-server/archive
define Package/freeradius3/conffiles
/etc/freeradius3/clients.conf
+/etc/freeradius3/policy.d/accounting
+/etc/freeradius3/policy.d/filter
+/etc/freeradius3/proxy.conf
/etc/freeradius3/radiusd.conf
-/etc/freeradius3/sites/default
+/etc/freeradius3/sites-available/default
+/etc/freeradius3/sites-enabled/default
endef
define Package/freeradius3-common
include $(TOPDIR)/rules.mk
PKG_NAME:=frr
-PKG_VERSION:=7.3.1
+PKG_VERSION:=7.4
PKG_RELEASE:=1
-PKG_SOURCE_URL:=https://github.com/FRRouting/frr/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_HASH:=85571b63d2774329b7e97871e4761f852066a17e99a8daae9972c6bd7a533e05
+PKG_SOURCE_URL:=https://github.com/FRRouting/frr/archive/
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_HASH:=3c8204fda1c9b178d8446562579bbbc49d134b98f3ad02aa56f68724a2f9e40a
PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
+HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
+PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_NAME)-$(PKG_VERSION)
+
PKG_LICENSE:=GPL-2.0-only LGPL-2.1-only
PKG_DAEMON_AVAILABLE:= \
--- /dev/null
+From 34f6d0c67a48e2117c061f6ccdcf1f512982fe8f Mon Sep 17 00:00:00 2001
+From: Donald Sharp <sharpd@cumulusnetworks.com>
+Date: Tue, 2 Jun 2020 16:10:48 -0400
+Subject: [PATCH] bgpd: Actually find the sequence number for `bgp
+ extcommunity-list...`
+
+The code in the bgp extcommunity-list function was using
+argv_find to get the correct idx. The problem was that
+we had already done argv_finds before and idx was non-zero
+thus having us always set the seq pointer to what was last
+looked up. This causes us to pass in a value to the
+underlying function and it would just wisely ignore it
+causing a seq number of 0.
+
+We would then write this seq number of 0 and then immediately
+reject it on read in again. BOO!
+
+Actually handle argv_find the way it was meant to be.
+
+Ticket:CM-29926
+Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
+---
+ bgpd/bgp_vty.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
+index 3669205ee3..9c8f1e1def 100644
+--- a/bgpd/bgp_vty.c
++++ b/bgpd/bgp_vty.c
+@@ -17617,8 +17617,7 @@ DEFUN (extcommunity_list_standard,
+ argv_find(argv, argc, "WORD", &idx);
+ cl_number_or_name = argv[idx]->arg;
+
+- argv_find(argv, argc, "(1-4294967295)", &idx);
+- if (idx)
++ if (argv_find(argv, argc, "(1-4294967295)", &idx))
+ seq = argv[idx]->arg;
+
+ direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
+@@ -17663,8 +17662,7 @@ DEFUN (extcommunity_list_name_expanded,
+ argv_find(argv, argc, "WORD", &idx);
+ cl_number_or_name = argv[idx]->arg;
+
+- argv_find(argv, argc, "(1-4294967295)", &idx);
+- if (idx)
++ if (argv_find(argv, argc, "(1-4294967295)", &idx))
+ seq = argv[idx]->arg;
+
+ direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
+@@ -17707,8 +17705,7 @@ DEFUN (no_extcommunity_list_standard_all,
+ char *seq = NULL;
+ int idx = 0;
+
+- argv_find(argv, argc, "(1-4294967295)", &idx);
+- if (idx)
++ if (argv_find(argv, argc, "(1-4294967295)", &idx))
+ seq = argv[idx]->arg;
+
+ idx = 0;
+@@ -17772,8 +17769,7 @@ DEFUN (no_extcommunity_list_expanded_all,
+ char *seq = NULL;
+ int idx = 0;
+
+- argv_find(argv, argc, "(1-4294967295)", &idx);
+- if (idx)
++ if (argv_find(argv, argc, "(1-4294967295)", &idx))
+ seq = argv[idx]->arg;
+
+ idx = 0;
--- /dev/null
+From acf6f22d150b0050afbdaf5887b8e25d1614db4c Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Thu, 2 Jul 2020 11:08:29 +0300
+Subject: [PATCH 1/2] bgpd: Return bool type for ecommunity_add_val and
+ subgroup_announce_check
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ bgpd/bgp_ecommunity.c | 6 +++---
+ bgpd/bgp_route.c | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
+index d13da74b04..7d5cac4d62 100644
+--- a/bgpd/bgp_ecommunity.c
++++ b/bgpd/bgp_ecommunity.c
+@@ -107,14 +107,14 @@ bool ecommunity_add_val(struct ecommunity *ecom, struct ecommunity_val *eval,
+ p[1] == eval->val[1]) {
+ if (overwrite) {
+ memcpy(p, eval->val, ECOMMUNITY_SIZE);
+- return 1;
++ return true;
+ }
+- return 0;
++ return false;
+ }
+ }
+ int ret = memcmp(p, eval->val, ECOMMUNITY_SIZE);
+ if (ret == 0)
+- return 0;
++ return false;
+ if (ret > 0) {
+ if (!unique)
+ break;
+diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
+index 6ae7a59a14..7bfefde482 100644
+--- a/bgpd/bgp_route.c
++++ b/bgpd/bgp_route.c
+@@ -1941,7 +1941,7 @@ bool subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
+
+ /* Codification of AS 0 Processing */
+ if (aspath_check_as_zero(attr->aspath))
+- return 0;
++ return false;
+
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+ if (peer->sort == BGP_PEER_IBGP
+
+From d5a157b7c377081d23b136b5ba4849abdcbecd97 Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Thu, 2 Jul 2020 11:39:40 +0300
+Subject: [PATCH 2/2] bgpd: Actually find the sequence number for
+ large-community-list
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ bgpd/bgp_vty.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
+index 9c8f1e1def..67ff31df8f 100644
+--- a/bgpd/bgp_vty.c
++++ b/bgpd/bgp_vty.c
+@@ -17235,8 +17235,7 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc,
+ char *cl_name;
+ char *seq = NULL;
+
+- argv_find(argv, argc, "(1-4294967295)", &idx);
+- if (idx)
++ if (argv_find(argv, argc, "(1-4294967295)", &idx))
+ seq = argv[idx]->arg;
+
+ idx = 0;
+@@ -17285,8 +17284,7 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
+ int idx = 0;
+ char *seq = NULL;
+
+- argv_find(argv, argc, "(1-4294967295)", &idx);
+- if (idx)
++ if (argv_find(argv, argc, "(1-4294967295)", &idx))
+ seq = argv[idx]->arg;
+
+ idx = 0;
+++ /dev/null
---- a/zebra/zebra_nhg.c 2019-10-18 01:59:17.582282539 +0300
-+++ b/zebra/zebra_nhg.c 2019-10-18 02:00:17.501997253 +0300
-@@ -1456,20 +1456,9 @@
- while (rn) {
- route_unlock_node(rn);
-
-- /* Lookup should halt if we've matched against ourselves ('top',
-- * if specified) - i.e., we cannot have a nexthop NH1 is
-- * resolved by a route NH1. The exception is if the route is a
-- * host route.
-- */
-- if (top && rn == top)
-- if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
-- || ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
-- if (IS_ZEBRA_DEBUG_RIB_DETAILED)
-- zlog_debug(
-- "\t%s: Matched against ourself and prefix length is not max bit length",
-- __PRETTY_FUNCTION__);
-- return 0;
-- }
-+ /* If lookup self prefix return immediately. */
-+ if (rn == top)
-+ return 0;
-
- /* Pick up selected route. */
- /* However, do not resolve over default route unless explicitly
--- /dev/null
+From cc45875e0d2af0b53100ec78364dc51b39a12ac9 Mon Sep 17 00:00:00 2001
+From: Rafael Zalamena <rzalamena@opensourcerouting.org>
+Date: Mon, 6 Jul 2020 11:39:27 -0300
+Subject: [PATCH] lib: fix route map description memory leak
+
+Route map entries are not getting a chance to call `description` string
+deallocation on shutdown or when the parent entry is destroyed, so lets
+add a code to handle this in the `route_map_index_delete` function.
+
+Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
+(cherry picked from commit f0951335830203426074ddca4317f84b477e4afb)
+---
+ lib/routemap.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/lib/routemap.c b/lib/routemap.c
+index 3d69a3495a..3b45133450 100644
+--- a/lib/routemap.c
++++ b/lib/routemap.c
+@@ -971,6 +971,9 @@ void route_map_index_delete(struct route_map_index *index, int notify)
+ zlog_debug("Deleting route-map %s sequence %d",
+ index->map->name, index->pref);
+
++ /* Free route map entry description. */
++ XFREE(MTYPE_TMP, index->description);
++
+ /* Free route map northbound hook contexts. */
+ while ((rhc = TAILQ_FIRST(&index->rhclist)) != NULL)
+ routemap_hook_context_free(rhc);
--- /dev/null
+From 2939f712d152f7e3ae438cc0f1d96dd9485e7487 Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Thu, 9 Jul 2020 16:00:27 +0300
+Subject: [PATCH 1/2] bgpd: Add command to show only established sessions
+
+```
+exit1-debian-9# show bgp summary
+
+IPv4 Unicast Summary:
+BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
+BGP table version 8
+RIB entries 15, using 2880 bytes of memory
+Peers 2, using 43 KiB of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+192.168.0.2 4 200 10 6 0 0 0 00:00:35 8 8
+2a02:4780::2 4 0 0 1 0 0 0 never Active 0
+
+Total number of neighbors 2
+exit1-debian-9# show bgp summary established
+
+IPv4 Unicast Summary:
+BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
+BGP table version 8
+RIB entries 15, using 2880 bytes of memory
+Peers 2, using 43 KiB of memory
+
+Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt
+192.168.0.2 4 200 10 6 0 0 0 00:00:39 8 8
+
+Total number of neighbors 2
+exit1-debian-9# show bgp summary failed
+
+IPv4 Unicast Summary:
+BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
+BGP table version 8
+RIB entries 15, using 2880 bytes of memory
+Peers 2, using 43 KiB of memory
+
+Neighbor EstdCnt DropCnt ResetTime Reason
+2a02:4780::2 0 0 never Waiting for peer OPEN
+
+Total number of neighbors 2
+exit1-debian-9#
+```
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ bgpd/bgp_evpn_vty.c | 11 ++++++++---
+ bgpd/bgp_vty.c | 43 +++++++++++++++++++++++++++++++------------
+ bgpd/bgp_vty.h | 3 ++-
+ 3 files changed, 41 insertions(+), 16 deletions(-)
+
+diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
+index 85604d856d..42987117d4 100644
+--- a/bgpd/bgp_evpn_vty.c
++++ b/bgpd/bgp_evpn_vty.c
+@@ -4077,7 +4077,7 @@ DEFUN(show_bgp_l2vpn_evpn_es,
+ */
+ DEFUN(show_bgp_l2vpn_evpn_summary,
+ show_bgp_l2vpn_evpn_summary_cmd,
+- "show bgp [vrf VRFNAME] l2vpn evpn summary [failed] [json]",
++ "show bgp [vrf VRFNAME] l2vpn evpn summary [established|failed] [json]",
+ SHOW_STR
+ BGP_STR
+ "bgp vrf\n"
+@@ -4085,6 +4085,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
+ L2VPN_HELP_STR
+ EVPN_HELP_STR
+ "Summary of BGP neighbor status\n"
++ "Show only sessions in Established state\n"
+ "Show only sessions not in Established state\n"
+ JSON_STR)
+ {
+@@ -4092,13 +4093,17 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
+ bool uj = use_json(argc, argv);
+ char *vrf = NULL;
+ bool show_failed = false;
++ bool show_established = false;
+
+ if (argv_find(argv, argc, "vrf", &idx_vrf))
+ vrf = argv[++idx_vrf]->arg;
+ if (argv_find(argv, argc, "failed", &idx_vrf))
+ show_failed = true;
+- return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN,
+- show_failed, uj);
++ if (argv_find(argv, argc, "established", &idx_vrf))
++ show_established = true;
++
++ return bgp_show_summary_vty(vty, vrf, AFI_L2VPN, SAFI_EVPN, show_failed,
++ show_established, uj);
+ }
+
+ /*
+diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
+index 67ff31df8f..78521457fd 100644
+--- a/bgpd/bgp_vty.c
++++ b/bgpd/bgp_vty.c
+@@ -8772,7 +8772,8 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp,
+
+ /* Show BGP peer's summary information. */
+ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
+- bool show_failed, bool use_json)
++ bool show_failed, bool show_established,
++ bool use_json)
+ {
+ struct peer *peer;
+ struct listnode *node, *nnode;
+@@ -9104,6 +9105,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
+ bgp_show_failed_summary(vty, bgp, peer,
+ json_peer, 0, use_json);
+ } else if (!show_failed) {
++ if (show_established
++ && bgp_has_peer_failed(peer, afi, safi))
++ continue;
++
+ json_peer = json_object_new_object();
+ if (peer_dynamic_neighbor(peer)) {
+ json_object_boolean_true_add(json_peer,
+@@ -9193,6 +9198,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
+ max_neighbor_width,
+ use_json);
+ } else if (!show_failed) {
++ if (show_established
++ && bgp_has_peer_failed(peer, afi, safi))
++ continue;
++
+ memset(dn_flag, '\0', sizeof(dn_flag));
+ if (peer_dynamic_neighbor(peer)) {
+ dn_flag[0] = '*';
+@@ -9315,7 +9324,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
+ }
+
+ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
+- int safi, bool show_failed, bool use_json)
++ int safi, bool show_failed,
++ bool show_established, bool use_json)
+ {
+ int is_first = 1;
+ int afi_wildcard = (afi == AFI_MAX);
+@@ -9358,7 +9368,8 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
+ false));
+ }
+ }
+- bgp_show_summary(vty, bgp, afi, safi, show_failed,
++ bgp_show_summary(vty, bgp, afi, safi,
++ show_failed, show_established,
+ use_json);
+ }
+ safi++;
+@@ -9382,6 +9393,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
+
+ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
+ safi_t safi, bool show_failed,
++ bool show_established,
+ bool use_json)
+ {
+ struct listnode *node, *nnode;
+@@ -9411,7 +9423,7 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
+ : bgp->name);
+ }
+ bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
+- use_json);
++ show_established, use_json);
+ }
+
+ if (use_json)
+@@ -9421,15 +9433,16 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
+ }
+
+ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
+- safi_t safi, bool show_failed, bool use_json)
++ safi_t safi, bool show_failed, bool show_established,
++ bool use_json)
+ {
+ struct bgp *bgp;
+
+ if (name) {
+ if (strmatch(name, "all")) {
+- bgp_show_all_instances_summary_vty(vty, afi, safi,
+- show_failed,
+- use_json);
++ bgp_show_all_instances_summary_vty(
++ vty, afi, safi, show_failed, show_established,
++ use_json);
+ return CMD_SUCCESS;
+ } else {
+ bgp = bgp_lookup_by_name(name);
+@@ -9444,7 +9457,8 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
+ }
+
+ bgp_show_summary_afi_safi(vty, bgp, afi, safi,
+- show_failed, use_json);
++ show_failed, show_established,
++ use_json);
+ return CMD_SUCCESS;
+ }
+ }
+@@ -9453,7 +9467,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
+
+ if (bgp)
+ bgp_show_summary_afi_safi(vty, bgp, afi, safi, show_failed,
+- use_json);
++ show_established, use_json);
+ else {
+ if (use_json)
+ vty_out(vty, "{}\n");
+@@ -9468,7 +9482,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
+ /* `show [ip] bgp summary' commands. */
+ DEFUN (show_ip_bgp_summary,
+ show_ip_bgp_summary_cmd,
+- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [failed] [json]",
++ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] summary [established|failed] [json]",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+@@ -9476,6 +9490,7 @@ DEFUN (show_ip_bgp_summary,
+ BGP_AFI_HELP_STR
+ BGP_SAFI_WITH_LABEL_HELP_STR
+ "Summary of BGP neighbor status\n"
++ "Show only sessions in Established state\n"
+ "Show only sessions not in Established state\n"
+ JSON_STR)
+ {
+@@ -9483,6 +9498,7 @@ DEFUN (show_ip_bgp_summary,
+ afi_t afi = AFI_MAX;
+ safi_t safi = SAFI_MAX;
+ bool show_failed = false;
++ bool show_established = false;
+
+ int idx = 0;
+
+@@ -9504,10 +9520,13 @@ DEFUN (show_ip_bgp_summary,
+
+ if (argv_find(argv, argc, "failed", &idx))
+ show_failed = true;
++ if (argv_find(argv, argc, "established", &idx))
++ show_established = true;
+
+ bool uj = use_json(argc, argv);
+
+- return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed, uj);
++ return bgp_show_summary_vty(vty, vrf, afi, safi, show_failed,
++ show_established, uj);
+ }
+
+ const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json)
+diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
+index d6ca198d09..95eefbc36f 100644
+--- a/bgpd/bgp_vty.h
++++ b/bgpd/bgp_vty.h
+@@ -178,6 +178,7 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
+ int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv,
+ int argc, struct bgp **bgp, bool use_json);
+ extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
+- safi_t safi, bool show_failed, bool use_json);
++ safi_t safi, bool show_failed,
++ bool show_established, bool use_json);
+
+ #endif /* _QUAGGA_BGP_VTY_H */
+
+From 2600443342d8e21d30df2b6ca095a5f2d0d4de2d Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Thu, 9 Jul 2020 16:05:08 +0300
+Subject: [PATCH 2/2] doc: Add 'show bgp summary established' command
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ doc/user/bgp.rst | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
+index cb343e8dad..36227db604 100644
+--- a/doc/user/bgp.rst
++++ b/doc/user/bgp.rst
+@@ -2710,6 +2710,12 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
+ Show a bgp peer summary for peers that are not succesfully exchanging routes
+ for the specified address family, and subsequent address-family.
+
++.. index:: show bgp [afi] [safi] summary established [json]
++.. clicmd:: show bgp [afi] [safi] summary established [json]
++
++ Show a bgp peer summary for peers that are succesfully exchanging routes
++ for the specified address family, and subsequent address-family.
++
+ .. index:: show bgp [afi] [safi] neighbor [PEER]
+ .. clicmd:: show bgp [afi] [safi] neighbor [PEER]
+
--- /dev/null
+From 692ce87393de9497a7821e9e0856ff70a7973ff6 Mon Sep 17 00:00:00 2001
+From: Paul Manley <paul.manley@wholefoods.com>
+Date: Thu, 9 Jul 2020 11:21:16 -0500
+Subject: [PATCH 1/2] tools: create sub-context for bfd peers
+
+add lines starting with 'peer' to the list of sub-contexts that are handled by frr-reload.py.
+
+https://github.com/FRRouting/frr/issues/6511#issuecomment-655163833
+
+Signed-off-by: Paul Manley <paul.manley@wholefoods.com>
+(cherry picked from commit 1c23a0aaa1c5d20af50af75b070e93e1eff21222)
+---
+ tools/frr-reload.py | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/frr-reload.py b/tools/frr-reload.py
+index d4020cdfc9..e9641b2b13 100755
+--- a/tools/frr-reload.py
++++ b/tools/frr-reload.py
+@@ -496,6 +496,7 @@ def load_contexts(self):
+ line.startswith("vnc defaults") or
+ line.startswith("vnc l2-group") or
+ line.startswith("vnc nve-group") or
++ line.startswith("peer") or
+ line.startswith("member pseudowire")):
+ main_ctx_key = []
+
+
+From 2604086c3d9face0aca2497a982782c865bb2b59 Mon Sep 17 00:00:00 2001
+From: Paul Manley <paul.manley@wholefoods.com>
+Date: Thu, 9 Jul 2020 11:25:34 -0500
+Subject: [PATCH 2/2] vtysh: properly exit BFD_PEER_NODE when marking file
+
+vtysh needs to be aware of how to properly exit a bfd peer when subsequent commands only succeed in a higher context.
+
+https://github.com/FRRouting/frr/issues/6511#issuecomment-656166206
+
+Signed-off-by: Paul Manley <paul.manley@wholefoods.com>
+(cherry picked from commit b727c12aabf1afc2b6e33f8590c9786e349e4fcb)
+---
+ vtysh/vtysh.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
+index 15ec866fc9..4fdf68c0e6 100644
+--- a/vtysh/vtysh.c
++++ b/vtysh/vtysh.c
+@@ -809,6 +809,9 @@ int vtysh_mark_file(const char *filename)
+ } else if ((prev_node == KEYCHAIN_KEY_NODE)
+ && (tried == 1)) {
+ vty_out(vty, "exit\n");
++ } else if ((prev_node == BFD_PEER_NODE)
++ && (tried == 1)) {
++ vty_out(vty, "exit\n");
+ } else if (tried) {
+ vty_out(vty, "end\n");
+ }
--- /dev/null
+From cc5934ed5939315ba5d95bfaf052625762107205 Mon Sep 17 00:00:00 2001
+From: Donald Sharp <sharpd@cumulusnetworks.com>
+Date: Tue, 30 Jun 2020 08:59:46 -0400
+Subject: [PATCH 1/2] vtysh: master is a non-sorted list
+
+The commit:
+a798241265a5808083a06b14ce1637d1ddf6a45a
+
+attempted to use sorted master lists to do faster lookups
+by using a RB Tree. Unfortunately the original code
+was creating a list->cmp function *but* never using it.
+If you look at the commit, it clearly shows that the
+function listnode_add is used to insert but when you
+look at that function it is a tail push.
+
+Fixes: #6573
+
+Namely now this ordering is preserved:
+bgp as-path access-list originate-only permit ^$
+bgp as-path access-list originate-only deny .*
+
+Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
+---
+ vtysh/vtysh_config.c | 21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
+index abbb111f9d..2ab9dd5a9a 100644
+--- a/vtysh/vtysh_config.c
++++ b/vtysh/vtysh_config.c
+@@ -34,7 +34,7 @@ DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CONFIG_LINE, "Vtysh configuration line")
+
+ vector configvec;
+
+-PREDECL_RBTREE_UNIQ(config_master);
++PREDECL_LIST(config_master);
+
+ struct config {
+ /* Configuration node name. */
+@@ -72,11 +72,6 @@ static struct config *config_new(void)
+ return config;
+ }
+
+-static int config_cmp(const struct config *c1, const struct config *c2)
+-{
+- return strcmp(c1->name, c2->name);
+-}
+-
+ static void config_del(struct config *config)
+ {
+ list_delete(&config->line);
+@@ -84,13 +79,15 @@ static void config_del(struct config *config)
+ XFREE(MTYPE_VTYSH_CONFIG, config);
+ }
+
+-DECLARE_RBTREE_UNIQ(config_master, struct config, rbt_item, config_cmp)
++DECLARE_LIST(config_master, struct config, rbt_item)
+
+ static struct config *config_get(int index, const char *line)
+ {
+- struct config *config;
++ struct config *config, *config_loop;
+ struct config_master_head *master;
+
++ config = config_loop = NULL;
++
+ master = vector_lookup_ensure(configvec, index);
+
+ if (!master) {
+@@ -99,8 +96,10 @@ static struct config *config_get(int index, const char *line)
+ vector_set_index(configvec, index, master);
+ }
+
+- const struct config config_ref = { .name = (char *)line };
+- config = config_master_find(master, &config_ref);
++ frr_each (config_master, master, config_loop) {
++ if (strcmp(config_loop->name, line) == 0)
++ config = config_loop;
++ }
+
+ if (!config) {
+ config = config_new();
+@@ -109,7 +108,7 @@ static struct config *config_get(int index, const char *line)
+ config->line->cmp = (int (*)(void *, void *))line_cmp;
+ config->name = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line);
+ config->index = index;
+- config_master_add(master, config);
++ config_master_add_tail(master, config);
+ }
+ return config;
+ }
+
+From 3e4d90ec556649e11954f2f56b5282f95e7e013b Mon Sep 17 00:00:00 2001
+From: Donald Sharp <sharpd@cumulusnetworks.com>
+Date: Tue, 30 Jun 2020 09:03:55 -0400
+Subject: [PATCH 2/2] vtysh: Improve lookup performance
+
+When we find the line we are interested in, stop looking.
+
+Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
+---
+ vtysh/vtysh_config.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
+index 2ab9dd5a9a..61bcf3b658 100644
+--- a/vtysh/vtysh_config.c
++++ b/vtysh/vtysh_config.c
+@@ -97,8 +97,10 @@ static struct config *config_get(int index, const char *line)
+ }
+
+ frr_each (config_master, master, config_loop) {
+- if (strcmp(config_loop->name, line) == 0)
++ if (strcmp(config_loop->name, line) == 0) {
+ config = config_loop;
++ break;
++ }
+ }
+
+ if (!config) {
--- /dev/null
+From c6a5994609deec62c8aefa1fa15c517e32575ca3 Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Wed, 6 May 2020 17:45:31 +0300
+Subject: [PATCH 1/4] tests: Remove bgp_show_ip_bgp_fqdn test
+
+Not really relevant for now.
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ .../bgp_show_ip_bgp_fqdn/__init__.py | 0
+ .../bgp_show_ip_bgp_fqdn/r1/bgpd.conf | 5 -
+ .../bgp_show_ip_bgp_fqdn/r1/zebra.conf | 9 --
+ .../bgp_show_ip_bgp_fqdn/r2/bgpd.conf | 5 -
+ .../bgp_show_ip_bgp_fqdn/r2/zebra.conf | 12 --
+ .../bgp_show_ip_bgp_fqdn/r3/bgpd.conf | 3 -
+ .../bgp_show_ip_bgp_fqdn/r3/zebra.conf | 6 -
+ .../test_bgp_show_ip_bgp_fqdn.py | 133 ------------------
+ 8 files changed, 173 deletions(-)
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf
+ delete mode 100644 tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
+
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py b/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py
+deleted file mode 100644
+index e69de29bb2..0000000000
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
+deleted file mode 100644
+index f0df56e947..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
++++ /dev/null
+@@ -1,5 +0,0 @@
+-router bgp 65000
+- no bgp ebgp-requires-policy
+- neighbor 192.168.255.2 remote-as 65001
+- address-family ipv4 unicast
+- redistribute connected
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
+deleted file mode 100644
+index 0a283c06d5..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
++++ /dev/null
+@@ -1,9 +0,0 @@
+-!
+-interface lo
+- ip address 172.16.255.254/32
+-!
+-interface r1-eth0
+- ip address 192.168.255.1/24
+-!
+-ip forwarding
+-!
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
+deleted file mode 100644
+index 422a7345f9..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
++++ /dev/null
+@@ -1,5 +0,0 @@
+-router bgp 65001
+- no bgp ebgp-requires-policy
+- bgp default show-hostname
+- neighbor 192.168.255.1 remote-as 65000
+- neighbor 192.168.254.1 remote-as 65001
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
+deleted file mode 100644
+index e9e2e4391f..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
++++ /dev/null
+@@ -1,12 +0,0 @@
+-!
+-interface lo
+- ip address 172.16.255.253/32
+-!
+-interface r2-eth0
+- ip address 192.168.255.2/24
+-!
+-interface r2-eth1
+- ip address 192.168.254.2/24
+-!
+-ip forwarding
+-!
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf
+deleted file mode 100644
+index 8fcf6a736d..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf
++++ /dev/null
+@@ -1,3 +0,0 @@
+-router bgp 65001
+- bgp default show-hostname
+- neighbor 192.168.254.2 remote-as 65001
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf
+deleted file mode 100644
+index a8b8bc38c5..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf
++++ /dev/null
+@@ -1,6 +0,0 @@
+-!
+-interface r3-eth0
+- ip address 192.168.254.1/24
+-!
+-ip forwarding
+-!
+diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py b/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
+deleted file mode 100644
+index e8ad180935..0000000000
+--- a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
++++ /dev/null
+@@ -1,133 +0,0 @@
+-#!/usr/bin/env python
+-
+-#
+-# test_bgp_show_ip_bgp_fqdn.py
+-# Part of NetDEF Topology Tests
+-#
+-# Copyright (c) 2019 by
+-# Donatas Abraitis <donatas.abraitis@gmail.com>
+-#
+-# Permission to use, copy, modify, and/or distribute this software
+-# for any purpose with or without fee is hereby granted, provided
+-# that the above copyright notice and this permission notice appear
+-# in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+-# OF THIS SOFTWARE.
+-#
+-
+-"""
+-test_bgp_show_ip_bgp_fqdn.py:
+-Test if FQND is visible in `show [ip] bgp` output if
+-`bgp default show-hostname` is toggled.
+-
+-Topology:
+-r1 <-- eBGP --> r2 <-- iBGP --> r3
+-
+-1. Check if both hostname and ip are added to JSON output
+-for 172.16.255.254/32 on r2.
+-2. Check if only ip is added to JSON output for 172.16.255.254/32 on r3.
+-"""
+-
+-import os
+-import sys
+-import json
+-import time
+-import pytest
+-import functools
+-
+-CWD = os.path.dirname(os.path.realpath(__file__))
+-sys.path.append(os.path.join(CWD, "../"))
+-
+-# pylint: disable=C0413
+-from lib import topotest
+-from lib.topogen import Topogen, TopoRouter, get_topogen
+-from lib.topolog import logger
+-from mininet.topo import Topo
+-
+-
+-class TemplateTopo(Topo):
+- def build(self, *_args, **_opts):
+- tgen = get_topogen(self)
+-
+- for routern in range(1, 4):
+- tgen.add_router("r{}".format(routern))
+-
+- switch = tgen.add_switch("s1")
+- switch.add_link(tgen.gears["r1"])
+- switch.add_link(tgen.gears["r2"])
+-
+- switch = tgen.add_switch("s2")
+- switch.add_link(tgen.gears["r2"])
+- switch.add_link(tgen.gears["r3"])
+-
+-
+-def setup_module(mod):
+- tgen = Topogen(TemplateTopo, mod.__name__)
+- tgen.start_topology()
+-
+- router_list = tgen.routers()
+-
+- for i, (rname, router) in enumerate(router_list.iteritems(), 1):
+- router.load_config(
+- TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+- )
+- router.load_config(
+- TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+- )
+-
+- tgen.start_router()
+-
+-
+-def teardown_module(mod):
+- tgen = get_topogen()
+- tgen.stop_topology()
+-
+-
+-def test_bgp_show_ip_bgp_hostname():
+- tgen = get_topogen()
+-
+- if tgen.routers_have_failure():
+- pytest.skip(tgen.errors)
+-
+- def _bgp_converge(router):
+- output = json.loads(router.vtysh_cmd("show ip bgp 172.16.255.254/32 json"))
+- expected = {"prefix": "172.16.255.254/32"}
+- return topotest.json_cmp(output, expected)
+-
+- def _bgp_show_nexthop_hostname_and_ip(router):
+- output = json.loads(router.vtysh_cmd("show ip bgp json"))
+- for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]:
+- if "hostname" in nh and "ip" in nh:
+- return True
+- return False
+-
+- def _bgp_show_nexthop_ip_only(router):
+- output = json.loads(router.vtysh_cmd("show ip bgp json"))
+- for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]:
+- if "ip" in nh and not "hostname" in nh:
+- return True
+- return False
+-
+- test_func = functools.partial(_bgp_converge, tgen.gears["r2"])
+- success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+-
+- test_func = functools.partial(_bgp_converge, tgen.gears["r3"])
+- success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
+-
+- assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r2"])
+- assert _bgp_show_nexthop_hostname_and_ip(tgen.gears["r2"]) == True
+-
+- assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r3"])
+- assert _bgp_show_nexthop_ip_only(tgen.gears["r3"]) == True
+-
+-
+-if __name__ == "__main__":
+- args = ["-s"] + sys.argv[1:]
+- sys.exit(pytest.main(args))
+
+From e7cc3d21452bd771a97bc46ab5a1e4853c46f944 Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Wed, 6 May 2020 17:46:10 +0300
+Subject: [PATCH 2/4] bgpd: Show the real next-hop address in addition to
+ hostname in `show bgp`
+
+It's hard to cope with cases when next-hop is changed/unchanged or
+peers are non-direct.
+
+It would be better to show the hostname and nexthop IP address (both)
+under `show bgp` to quickly identify the source and the real next-hop
+of the route.
+
+If `bgp default show-nexthop-hostname` is toggled the output looks like:
+```
+spine1-debian-9# show bgp
+BGP table version is 1, local router ID is 2.2.2.2, vrf id 0
+Default local pref 100, local AS 65002
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+* 2a02:4780::/64 fe80::a00:27ff:fe09:f8a3(exit1-debian-9)
+ 0 0 65001 ?
+
+spine1-debian-9# show ip bgp
+BGP table version is 5, local router ID is 2.2.2.2, vrf id 0
+Default local pref 100, local AS 65002
+Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
+ i internal, r RIB-failure, S Stale, R Removed
+Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+Origin codes: i - IGP, e - EGP, ? - incomplete
+
+ Network Next Hop Metric LocPrf Weight Path
+*> 10.255.255.0/24 192.168.0.1(exit1-debian-9)
+ 0 0 65001 ?
+```
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ bgpd/bgp_route.c | 161 ++++++++++++++++++++++++++++++-----------------
+ bgpd/bgp_vty.c | 45 +++++++++++++
+ bgpd/bgpd.h | 1 +
+ 3 files changed, 149 insertions(+), 58 deletions(-)
+
+diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
+index 7bfefde482..f033f525e5 100644
+--- a/bgpd/bgp_route.c
++++ b/bgpd/bgp_route.c
+@@ -7559,8 +7559,7 @@ static char *bgp_nexthop_hostname(struct peer *peer,
+ struct bgp_nexthop_cache *bnc)
+ {
+ if (peer->hostname
+- && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME) && bnc
+- && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
++ && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
+ return peer->hostname;
+ return NULL;
+ }
+@@ -7570,6 +7569,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ struct bgp_path_info *path, int display, safi_t safi,
+ json_object *json_paths)
+ {
++ int len;
+ struct attr *attr = path->attr;
+ json_object *json_path = NULL;
+ json_object *json_nexthops = NULL;
+@@ -7681,10 +7681,19 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ : "ipv6");
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+- } else
+- vty_out(vty, "%s%s",
+- nexthop_hostname ? nexthop_hostname : nexthop,
+- vrf_id_str);
++ } else {
++ if (nexthop_hostname)
++ len = vty_out(vty, "%s(%s)%s", nexthop,
++ nexthop_hostname, vrf_id_str);
++ else
++ len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
++
++ len = 16 - len;
++ if (len < 1)
++ vty_out(vty, "\n%*s", 36, " ");
++ else
++ vty_out(vty, "%*s", len, " ");
++ }
+ } else if (safi == SAFI_EVPN) {
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+@@ -7701,11 +7710,20 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ "ipv4");
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+- } else
+- vty_out(vty, "%-16s%s",
+- nexthop_hostname ? nexthop_hostname
+- : inet_ntoa(attr->nexthop),
+- vrf_id_str);
++ } else {
++ if (nexthop_hostname)
++ len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
++ nexthop_hostname, vrf_id_str);
++ else
++ len = vty_out(vty, "%pI4%s", &attr->nexthop,
++ vrf_id_str);
++
++ len = 16 - len;
++ if (len < 1)
++ vty_out(vty, "\n%*s", 36, " ");
++ else
++ vty_out(vty, "%*s", len, " ");
++ }
+ } else if (safi == SAFI_FLOWSPEC) {
+ if (attr->nexthop.s_addr != INADDR_ANY) {
+ if (json_paths) {
+@@ -7726,10 +7744,21 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ json_nexthop_global,
+ "used");
+ } else {
+- vty_out(vty, "%-16s",
+- nexthop_hostname
+- ? nexthop_hostname
+- : inet_ntoa(attr->nexthop));
++ if (nexthop_hostname)
++ len = vty_out(vty, "%pI4(%s)%s",
++ &attr->nexthop,
++ nexthop_hostname,
++ vrf_id_str);
++ else
++ len = vty_out(vty, "%pI4%s",
++ &attr->nexthop,
++ vrf_id_str);
++
++ len = 16 - len;
++ if (len < 1)
++ vty_out(vty, "\n%*s", 36, " ");
++ else
++ vty_out(vty, "%*s", len, " ");
+ }
+ }
+ } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+@@ -7749,19 +7778,23 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ json_object_boolean_true_add(json_nexthop_global,
+ "used");
+ } else {
+- char buf[BUFSIZ];
++ if (nexthop_hostname)
++ len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
++ nexthop_hostname, vrf_id_str);
++ else
++ len = vty_out(vty, "%pI4%s", &attr->nexthop,
++ vrf_id_str);
+
+- snprintf(buf, sizeof(buf), "%s%s",
+- nexthop_hostname ? nexthop_hostname
+- : inet_ntoa(attr->nexthop),
+- vrf_id_str);
+- vty_out(vty, "%-16s", buf);
++ len = 16 - len;
++ if (len < 1)
++ vty_out(vty, "\n%*s", 36, " ");
++ else
++ vty_out(vty, "%*s", len, " ");
+ }
+ }
+
+ /* IPv6 Next Hop */
+ else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+- int len;
+ char buf[BUFSIZ];
+
+ if (json_paths) {
+@@ -7835,15 +7868,18 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ else
+ vty_out(vty, "%*s", len, " ");
+ } else {
+- len = vty_out(
+- vty, "%s%s",
+- nexthop_hostname
+- ? nexthop_hostname
+- : inet_ntop(
+- AF_INET6,
+- &attr->mp_nexthop_local,
+- buf, BUFSIZ),
+- vrf_id_str);
++ if (nexthop_hostname)
++ len = vty_out(
++ vty, "%pI6(%s)%s",
++ &attr->mp_nexthop_local,
++ nexthop_hostname,
++ vrf_id_str);
++ else
++ len = vty_out(
++ vty, "%pI6%s",
++ &attr->mp_nexthop_local,
++ vrf_id_str);
++
+ len = 16 - len;
+
+ if (len < 1)
+@@ -7852,15 +7888,16 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ vty_out(vty, "%*s", len, " ");
+ }
+ } else {
+- len = vty_out(
+- vty, "%s%s",
+- nexthop_hostname
+- ? nexthop_hostname
+- : inet_ntop(
+- AF_INET6,
+- &attr->mp_nexthop_global,
+- buf, BUFSIZ),
+- vrf_id_str);
++ if (nexthop_hostname)
++ len = vty_out(vty, "%pI6(%s)%s",
++ &attr->mp_nexthop_global,
++ nexthop_hostname,
++ vrf_id_str);
++ else
++ len = vty_out(vty, "%pI6%s",
++ &attr->mp_nexthop_global,
++ vrf_id_str);
++
+ len = 16 - len;
+
+ if (len < 1)
+@@ -7986,6 +8023,7 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
+ {
+ json_object *json_status = NULL;
+ json_object *json_net = NULL;
++ int len;
+ char buff[BUFSIZ];
+
+ /* Route status display. */
+@@ -8079,7 +8117,6 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
+ inet_ntoa(attr->nexthop));
+ } else if (p->family == AF_INET6
+ || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+- int len;
+ char buf[BUFSIZ];
+
+ len = vty_out(
+@@ -8823,12 +8860,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ json_object_string_add(
+ json_nexthop_global, "hostname",
+ nexthop_hostname);
+- } else
+- vty_out(vty, " %s",
+- nexthop_hostname
+- ? nexthop_hostname
+- : inet_ntoa(
+- attr->mp_nexthop_global_in));
++ } else {
++ if (nexthop_hostname)
++ vty_out(vty, " %pI4(%s)",
++ &attr->mp_nexthop_global_in,
++ nexthop_hostname);
++ else
++ vty_out(vty, " %pI4",
++ &attr->mp_nexthop_global_in);
++ }
+ } else {
+ if (json_paths) {
+ json_object_string_add(
+@@ -8839,11 +8879,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ json_object_string_add(
+ json_nexthop_global, "hostname",
+ nexthop_hostname);
+- } else
+- vty_out(vty, " %s",
+- nexthop_hostname
+- ? nexthop_hostname
+- : inet_ntoa(attr->nexthop));
++ } else {
++ if (nexthop_hostname)
++ vty_out(vty, " %pI4(%s)",
++ &attr->nexthop,
++ nexthop_hostname);
++ else
++ vty_out(vty, " %pI4",
++ &attr->nexthop);
++ }
+ }
+
+ if (json_paths)
+@@ -8866,12 +8910,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ json_object_string_add(json_nexthop_global, "scope",
+ "global");
+ } else {
+- vty_out(vty, " %s",
+- nexthop_hostname
+- ? nexthop_hostname
+- : inet_ntop(AF_INET6,
+- &attr->mp_nexthop_global,
+- buf, INET6_ADDRSTRLEN));
++ if (nexthop_hostname)
++ vty_out(vty, " %pI6(%s)",
++ &attr->mp_nexthop_global,
++ nexthop_hostname);
++ else
++ vty_out(vty, " %pI6",
++ &attr->mp_nexthop_global);
+ }
+ }
+
+diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
+index 78521457fd..7f00ff3fbe 100644
+--- a/bgpd/bgp_vty.c
++++ b/bgpd/bgp_vty.c
+@@ -84,6 +84,10 @@ FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME,
+ { .val_bool = true, .match_profile = "datacenter", },
+ { .val_bool = false },
+ )
++FRR_CFG_DEFAULT_BOOL(BGP_SHOW_NEXTHOP_HOSTNAME,
++ { .val_bool = true, .match_profile = "datacenter", },
++ { .val_bool = false },
++)
+ FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES,
+ { .val_bool = true, .match_profile = "datacenter", },
+ { .val_bool = false },
+@@ -422,6 +426,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
+ SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK);
+ if (DFLT_BGP_SHOW_HOSTNAME)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_HOSTNAME);
++ if (DFLT_BGP_SHOW_NEXTHOP_HOSTNAME)
++ SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
+ if (DFLT_BGP_LOG_NEIGHBOR_CHANGES)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+ if (DFLT_BGP_DETERMINISTIC_MED)
+@@ -3100,6 +3106,32 @@ DEFUN (no_bgp_default_show_hostname,
+ return CMD_SUCCESS;
+ }
+
++/* Display hostname in certain command outputs */
++DEFUN (bgp_default_show_nexthop_hostname,
++ bgp_default_show_nexthop_hostname_cmd,
++ "bgp default show-nexthop-hostname",
++ "BGP specific commands\n"
++ "Configure BGP defaults\n"
++ "Show hostname for nexthop in certain command outputs\n")
++{
++ VTY_DECLVAR_CONTEXT(bgp, bgp);
++ SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
++ return CMD_SUCCESS;
++}
++
++DEFUN (no_bgp_default_show_nexthop_hostname,
++ no_bgp_default_show_nexthop_hostname_cmd,
++ "no bgp default show-nexthop-hostname",
++ NO_STR
++ "BGP specific commands\n"
++ "Configure BGP defaults\n"
++ "Show hostname for nexthop in certain command outputs\n")
++{
++ VTY_DECLVAR_CONTEXT(bgp, bgp);
++ UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
++ return CMD_SUCCESS;
++}
++
+ /* "bgp network import-check" configuration. */
+ DEFUN (bgp_network_import_check,
+ bgp_network_import_check_cmd,
+@@ -15190,6 +15222,15 @@ int bgp_config_write(struct vty *vty)
+ ? ""
+ : "no ");
+
++ /* BGP default show-nexthop-hostname */
++ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME)
++ != SAVE_BGP_SHOW_HOSTNAME)
++ vty_out(vty, " %sbgp default show-nexthop-hostname\n",
++ CHECK_FLAG(bgp->flags,
++ BGP_FLAG_SHOW_NEXTHOP_HOSTNAME)
++ ? ""
++ : "no ");
++
+ /* BGP default subgroup-pkt-queue-max. */
+ if (bgp->default_subgroup_pkt_queue_max
+ != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
+@@ -15815,6 +15856,10 @@ void bgp_vty_init(void)
+ install_element(BGP_NODE, &bgp_default_show_hostname_cmd);
+ install_element(BGP_NODE, &no_bgp_default_show_hostname_cmd);
+
++ /* bgp default show-nexthop-hostname */
++ install_element(BGP_NODE, &bgp_default_show_nexthop_hostname_cmd);
++ install_element(BGP_NODE, &no_bgp_default_show_nexthop_hostname_cmd);
++
+ /* "bgp default subgroup-pkt-queue-max" commands. */
+ install_element(BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd);
+ install_element(BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd);
+diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
+index 4a5772a53b..4efc068dea 100644
+--- a/bgpd/bgpd.h
++++ b/bgpd/bgpd.h
+@@ -447,6 +447,7 @@ struct bgp {
+ #define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23)
+ #define BGP_FLAG_GR_DISABLE_EOR (1 << 24)
+ #define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 25)
++#define BGP_FLAG_SHOW_NEXTHOP_HOSTNAME (1 << 26)
+
+ enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE]
+ [BGP_GLOBAL_GR_EVENT_CMD];
+
+From 104dfe5258cbeb0443fa4d6577794a1e5a5dafd3 Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Wed, 6 May 2020 17:50:04 +0300
+Subject: [PATCH 3/4] bgpd: Add "hostname" in JSON output for `show bgp` family
+ outputs
+
+This adds hostname regardless if `bgp default show-hostname` enabled or not.
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ bgpd/bgp_route.c | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
+index f033f525e5..5f645fa871 100644
+--- a/bgpd/bgp_route.c
++++ b/bgpd/bgp_route.c
+@@ -7671,10 +7671,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ json_object_string_add(json_nexthop_global, "ip",
+ nexthop);
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(json_nexthop_global,
+ "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_global, "afi",
+ (af == AF_INET) ? "ipv4"
+@@ -7701,10 +7701,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ json_object_string_add(json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(json_nexthop_global,
+ "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_global, "afi",
+ "ipv4");
+@@ -7735,10 +7735,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(
+ json_nexthop_global, "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_boolean_true_add(
+ json_nexthop_global,
+@@ -7768,10 +7768,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ json_object_string_add(json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(json_nexthop_global,
+ "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_global, "afi",
+ "ipv4");
+@@ -7804,10 +7804,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ inet_ntop(AF_INET6, &attr->mp_nexthop_global,
+ buf, BUFSIZ));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(json_nexthop_global,
+ "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_global, "afi",
+ "ipv6");
+@@ -7826,10 +7826,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
+ &attr->mp_nexthop_local, buf,
+ BUFSIZ));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(
+ json_nexthop_ll, "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_ll, "afi",
+ "ipv6");
+@@ -8856,10 +8856,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ json_nexthop_global, "ip",
+ inet_ntoa(attr->mp_nexthop_global_in));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(
+ json_nexthop_global, "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+ } else {
+ if (nexthop_hostname)
+ vty_out(vty, " %pI4(%s)",
+@@ -8875,10 +8875,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(
+ json_nexthop_global, "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+ } else {
+ if (nexthop_hostname)
+ vty_out(vty, " %pI4(%s)",
+@@ -8900,10 +8900,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ inet_ntop(AF_INET6, &attr->mp_nexthop_global,
+ buf, INET6_ADDRSTRLEN));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(json_nexthop_global,
+ "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_global, "afi",
+ "ipv6");
+@@ -9094,10 +9094,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ inet_ntop(AF_INET6, &attr->mp_nexthop_local,
+ buf, INET6_ADDRSTRLEN));
+
+- if (nexthop_hostname)
++ if (path->peer->hostname)
+ json_object_string_add(json_nexthop_ll,
+ "hostname",
+- nexthop_hostname);
++ path->peer->hostname);
+
+ json_object_string_add(json_nexthop_ll, "afi", "ipv6");
+ json_object_string_add(json_nexthop_ll, "scope",
+
+From 8df39282ea64e2a65a7910012627f78d080833b1 Mon Sep 17 00:00:00 2001
+From: Donatas Abraitis <donatas.abraitis@gmail.com>
+Date: Wed, 24 Jun 2020 17:26:27 +0300
+Subject: [PATCH 4/4] doc: Add some words about `bgp default
+ show-[nexthop]-hostname`
+
+Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
+---
+ doc/user/bgp.rst | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
+index 36227db604..a6c29724b0 100644
+--- a/doc/user/bgp.rst
++++ b/doc/user/bgp.rst
+@@ -1366,6 +1366,19 @@ Configuring Peers
+ on by default or not. This command defaults to on and is not displayed.
+ The `no bgp default ipv4-unicast` form of the command is displayed.
+
++.. index:: [no] bgp default show-hostname
++.. clicmd:: [no] bgp default show-hostname
++
++ This command shows the hostname of the peer in certain BGP commands
++ outputs. It's easier to troubleshoot if you have a number of BGP peers.
++
++.. index:: [no] bgp default show-nexthop-hostname
++.. clicmd:: [no] bgp default show-nexthop-hostname
++
++ This command shows the hostname of the next-hop in certain BGP commands
++ outputs. It's easier to troubleshoot if you have a number of BGP peers
++ and a number of routes to check.
++
+ .. index:: [no] neighbor PEER advertisement-interval (0-600)
+ .. clicmd:: [no] neighbor PEER advertisement-interval (0-600)
+
--- /dev/null
+From 2bbe7133eb5cb97ba4b745cd251a8615cd2bd008 Mon Sep 17 00:00:00 2001
+From: Richard Wu <wutong23@baidu.com>
+Date: Fri, 5 Jun 2020 17:54:57 +0800
+Subject: [PATCH] bgpd: Fix the bug that BGP MRAI does not work.
+
+Issue: bgp_process_writes will be called when the fd is writable.
+ And it will bgp_generate_updgrp_packets to generate the
+ update packets no matter MRAI is set or not.
+Fix: bgp_generate_updgrp_packets thread will return without sending
+ any update when MRAI timer is still running.
+
+Signed-off-by: Richard Wu <wutong23@baidu.com>
+---
+ bgpd/bgp_packet.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
+index 29c03f4014..6f1c033f2a 100644
+--- a/bgpd/bgp_packet.c
++++ b/bgpd/bgp_packet.c
+@@ -408,6 +408,9 @@ int bgp_generate_updgrp_packets(struct thread *thread)
+ if (peer->bgp->main_peers_update_hold)
+ return 0;
+
++ if (peer->t_routeadv)
++ return 0;
++
+ do {
+ s = NULL;
+ FOREACH_AFI_SAFI (afi, safi) {
+++ /dev/null
-From 2332428d3c80ac3d3b4e1c0bdba830b098ef440f Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Fri, 5 Jul 2019 11:07:30 -0300
-Subject: [PATCH] yang: initial filter YANG model import
-
-This model contains the description of access-list, prefix-list and
-other lists used by route map and other filtering interfaces.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- yang/frr-filter.yang | 365 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 365 insertions(+)
- create mode 100644 yang/frr-filter.yang
-
-diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang
-new file mode 100644
-index 0000000000..92af6aebfd
---- /dev/null
-+++ b/yang/frr-filter.yang
-@@ -0,0 +1,365 @@
-+module frr-filter {
-+ yang-version 1.1;
-+ namespace "http://frrouting.org/yang/filter";
-+ prefix frr-filter;
-+
-+ import ietf-inet-types {
-+ prefix inet;
-+ }
-+ import ietf-yang-types {
-+ prefix yang;
-+ }
-+
-+ organization "Free Range Routing";
-+ contact
-+ "FRR Users List: <mailto:frog@lists.frrouting.org>
-+ FRR Development List: <mailto:dev@lists.frrouting.org>";
-+ description "This module defines filter settings";
-+
-+ revision 2019-07-04 {
-+ description "Initial revision";
-+ }
-+
-+ /*
-+ * Types.
-+ */
-+ typedef access-list-standard {
-+ description "Standard IPv4 access list (any, host or a prefix)";
-+ type uint16 {
-+ range "1..99 | 1300..1999";
-+ }
-+ }
-+
-+ typedef access-list-extended {
-+ description
-+ "Extended IPv4 access list (source / destination any, hosts or prefixes)";
-+ type uint16 {
-+ range "100..199 | 2000..2699";
-+ }
-+ }
-+
-+ typedef access-list-legacy {
-+ description "Standard/Extended IPv4 access list";
-+ type uint16 {
-+ range "1..199 | 1300..2699";
-+ }
-+ }
-+
-+ typedef access-list-name {
-+ description "Access list name formatting";
-+ type string;
-+ }
-+
-+ typedef access-list-sequence {
-+ description "Access list sequence number";
-+ type uint32 {
-+ range "1..4294967295";
-+ }
-+ }
-+
-+ typedef access-list-action {
-+ description "Access list return action on match";
-+ type enumeration {
-+ enum deny {
-+ description "Deny an entry";
-+ value 0;
-+ }
-+ enum permit {
-+ description "Accept an entry";
-+ value 1;
-+ }
-+ }
-+ }
-+
-+ /*
-+ * Configuration data.
-+ */
-+ container filter-list {
-+ list access-list-legacy {
-+ description "Access list legacy instance";
-+
-+ key "number sequence";
-+
-+ leaf number {
-+ description "Access list sequence value";
-+ type access-list-legacy;
-+ }
-+
-+ leaf sequence {
-+ description "Access list sequence value";
-+ type access-list-sequence;
-+ }
-+
-+ leaf action {
-+ description "Access list action on match";
-+ type access-list-action;
-+ mandatory true;
-+ }
-+
-+ leaf remark {
-+ description "Access list remark";
-+ type string;
-+ }
-+
-+ choice value {
-+ description
-+ "Standard access list: value to match.
-+ Extended access list: source value to match.";
-+ mandatory true;
-+
-+ case host {
-+ leaf host {
-+ description "Host to match";
-+ type inet:ipv4-address;
-+ }
-+ }
-+ case network {
-+ leaf network {
-+ description "Network to match";
-+ type inet:ipv4-prefix;
-+ }
-+ }
-+ case any {
-+ leaf any {
-+ description "Match any";
-+ type empty;
-+ }
-+ }
-+ }
-+
-+ choice extended-value {
-+ when "./sequence >= 100 and ./sequence <= 199 or
-+ ./sequence >= 2000 and ./sequence <= 2699";
-+ description "Destination value to match";
-+
-+ case destination-host {
-+ leaf destination-host {
-+ description "Host to match";
-+ type inet:ipv4-address;
-+ }
-+ }
-+ case destination-network {
-+ leaf destination-network {
-+ description "Network to match";
-+ type inet:ipv4-prefix;
-+ }
-+ }
-+ case destination-any {
-+ leaf destination-any {
-+ description "Match any";
-+ type empty;
-+ }
-+ }
-+ }
-+ }
-+
-+ list access-list {
-+ description "Access list instance";
-+
-+ key "type identifier sequence";
-+
-+ leaf type {
-+ description "Access list content type";
-+ type enumeration {
-+ enum ipv4 {
-+ description "Internet Protocol address version 4";
-+ value 0;
-+ }
-+ enum ipv6 {
-+ description "Internet Protocol address version 6";
-+ value 1;
-+ }
-+ enum mac {
-+ description "Media Access Control address";
-+ value 2;
-+ }
-+
-+ /*
-+ * Protocol YANG models should augment the parent node to
-+ * contain the routing protocol specific value. The protocol
-+ * must also augment `value` leaf to include its specific
-+ * values or expand the `when` statement on the existing cases.
-+ */
-+ enum custom {
-+ description "Custom data type";
-+ value 100;
-+ }
-+ }
-+ }
-+
-+ leaf identifier {
-+ description "Access list identifier";
-+ type access-list-name;
-+ }
-+
-+ leaf sequence {
-+ description "Access list sequence value";
-+ type access-list-sequence;
-+ }
-+
-+ leaf action {
-+ description "Access list action on match";
-+ type access-list-action;
-+ mandatory true;
-+ }
-+
-+ leaf remark {
-+ description "Access list remark";
-+ type string;
-+ }
-+
-+ choice value {
-+ description "Access list value to match";
-+ mandatory true;
-+
-+ case ipv4-prefix {
-+ when "./type = 'ipv4'";
-+
-+ leaf ipv4-prefix {
-+ description "Configure IPv4 prefix to match";
-+ type inet:ipv4-prefix;
-+ }
-+
-+ leaf ipv4-exact-match {
-+ description "Exact match of prefix";
-+ type boolean;
-+ default false;
-+ }
-+ }
-+ case ipv6-prefix {
-+ when "./type = 'ipv6'";
-+
-+ leaf ipv6-prefix {
-+ description "Configure IPv6 prefix to match";
-+ type inet:ipv6-prefix;
-+ }
-+
-+ leaf ipv6-exact-match {
-+ description "Exact match of prefix";
-+ type boolean;
-+ default false;
-+ }
-+ }
-+ case mac {
-+ when "./type = 'mac'";
-+
-+ leaf mac {
-+ description "Configure MAC address to match";
-+ type yang:mac-address;
-+ }
-+ }
-+ case any {
-+ leaf any {
-+ description "Match anything";
-+ type empty;
-+ }
-+ }
-+ }
-+ }
-+
-+ list prefix-list {
-+ description "Prefix list instance";
-+
-+ key "type name sequence";
-+
-+ leaf type {
-+ description "Prefix list type";
-+ type enumeration {
-+ enum ipv4 {
-+ description "Internet Protocol address version 4";
-+ value 0;
-+ }
-+ enum ipv6 {
-+ description "Internet Protocol address version 6";
-+ value 1;
-+ }
-+ }
-+ }
-+
-+ leaf name {
-+ description "Prefix list name";
-+ type access-list-name;
-+ }
-+
-+ leaf sequence {
-+ description "Access list sequence value";
-+ type access-list-sequence;
-+ }
-+
-+ leaf action {
-+ description "Prefix list action on match";
-+ type access-list-action;
-+ mandatory true;
-+ }
-+
-+ leaf description {
-+ description "Prefix list user description";
-+ type string;
-+ }
-+
-+ choice value {
-+ description "Prefix list value to match";
-+ mandatory true;
-+
-+ case ipv4-prefix {
-+ when "./type = 'ipv4'";
-+
-+ leaf ipv4-prefix {
-+ description "Configure IPv4 prefix to match";
-+ type inet:ipv4-prefix;
-+ }
-+
-+ leaf ipv4-prefix-length-greater-or-equal {
-+ description
-+ "Specifies if matching prefixes with length greater than
-+ or equal to value";
-+ type uint8 {
-+ range "0..32";
-+ }
-+ }
-+
-+ leaf ipv4-prefix-length-lesser-or-equal {
-+ description
-+ "Specifies if matching prefixes with length lesser than
-+ or equal to value";
-+ type uint8 {
-+ range "0..32";
-+ }
-+ }
-+ }
-+ case ipv6-prefix {
-+ when "./type = 'ipv6'";
-+
-+ leaf ipv6-prefix {
-+ description "Configure IPv6 prefix to match";
-+ type inet:ipv6-prefix;
-+ }
-+
-+ leaf ipv6-prefix-length-greater-or-equal {
-+ description
-+ "Specifies if matching prefixes with length greater than
-+ or equal to value";
-+ type uint8 {
-+ range "0..128";
-+ }
-+ }
-+
-+ leaf ipv6-prefix-length-lesser-or-equal {
-+ description
-+ "Specifies if matching prefixes with length lesser than
-+ or equal to value";
-+ type uint8 {
-+ range "0..128";
-+ }
-+ }
-+ }
-+ case any {
-+ leaf any {
-+ description "Match anything";
-+ type empty;
-+ }
-+ }
-+ }
-+ }
-+ }
-+}
+++ /dev/null
---- a/dev/null 2020-04-10 18:48:03.582667900 +0300
-+++ b/yang/frr-route-map.yang 2020-05-02 11:43:04.182956847 +0300
-@@ -0,0 +1,387 @@
-+module frr-route-map {
-+ yang-version 1.1;
-+ namespace "http://frrouting.org/yang/route-map";
-+ prefix frr-route-map;
-+
-+ import ietf-inet-types {
-+ prefix inet;
-+ }
-+ import frr-filter {
-+ prefix filter;
-+ }
-+ import frr-interface {
-+ prefix frr-interface;
-+ }
-+
-+ organization "FRRouting";
-+ contact
-+ "FRR Users List: <mailto:frog@lists.frrouting.org>
-+ FRR Development List: <mailto:dev@lists.frrouting.org>";
-+ description "This module defines route map settings";
-+
-+ revision 2019-07-01 {
-+ description "Initial revision";
-+ }
-+
-+ /*
-+ * Types.
-+ */
-+ typedef route-map-sequence {
-+ description "Route map valid sequence numbers";
-+ type uint16 {
-+ range "1..65535";
-+ }
-+ }
-+
-+ typedef route-map-name {
-+ description "Route map name format";
-+ type string;
-+ }
-+
-+ /*
-+ * Operational data.
-+ */
-+ container lib {
-+ list route-map {
-+ description "Route map instance";
-+
-+ key "name";
-+
-+ leaf name {
-+ description "Route map instance name";
-+ type route-map-name;
-+ }
-+
-+ list entry {
-+ description "Route map entry";
-+
-+ key "sequence";
-+
-+ leaf sequence {
-+ description
-+ "Route map instance priority (low number means higher priority)";
-+ type route-map-sequence;
-+ }
-+
-+ leaf description {
-+ description "Route map description";
-+ type string;
-+ }
-+
-+ leaf action {
-+ description
-+ "Route map actions: permit (executes action), deny (quits evaluation)";
-+ mandatory true;
-+ type enumeration {
-+ enum permit {
-+ description
-+ "Executes configured action and permits the prefix/route
-+ if the conditions matched. An alternative exit action can
-+ be configured to continue processing the route map list
-+ or jump to process another route map.";
-+ value 0;
-+ }
-+ enum deny {
-+ description
-+ "If all conditions are met the prefix/route is denied and
-+ route map processing stops.";
-+ value 1;
-+ }
-+ }
-+ }
-+
-+ leaf call {
-+ description
-+ "Call another route map before calling `exit-policy`. If the
-+ called route map returns deny then this route map will also
-+ return deny";
-+ type route-map-name;
-+ }
-+
-+ leaf exit-policy {
-+ description "What do to after route map successful match, set and call";
-+ type enumeration {
-+ enum permit-or-deny {
-+ description "End route map evaluation and return";
-+ value 0;
-+ }
-+ enum next {
-+ description
-+ "Proceed evaluating next route map entry per sequence";
-+ value 1;
-+ }
-+ enum goto {
-+ description
-+ "Go to route map entry with the provided sequence number";
-+ value 2;
-+ }
-+ }
-+ default "permit-or-deny";
-+ }
-+
-+ leaf goto-value {
-+ when "../exit-policy = 'goto'";
-+ description
-+ "Sequence number to jump (when using `goto` exit policy)";
-+ mandatory true;
-+ type route-map-sequence;
-+ }
-+
-+ list match-condition {
-+ description "Route map match conditions";
-+
-+ key "condition";
-+
-+ leaf condition {
-+ description "Match condition";
-+ type enumeration {
-+ enum interface {
-+ description "Match interface";
-+ value 0;
-+ }
-+ enum ipv4-address-list {
-+ description "Match an IPv4 access-list";
-+ value 1;
-+ }
-+ enum ipv4-prefix-list {
-+ description "Match an IPv4 prefix-list";
-+ value 2;
-+ }
-+ enum ipv4-next-hop-list {
-+ description "Match an IPv4 next-hop";
-+ value 3;
-+ }
-+ enum ipv4-next-hop-prefix-list {
-+ description "Match an IPv4 next-hop prefix list";
-+ value 4;
-+ }
-+ enum ipv4-next-hop-type {
-+ description "Match an IPv4 next-hop type";
-+ value 5;
-+ }
-+ enum ipv6-address-list {
-+ description "Match an IPv6 access-list";
-+ value 6;
-+ }
-+ enum ipv6-prefix-list {
-+ description "Match an IPv6 prefix-list";
-+ value 7;
-+ }
-+ enum ipv6-next-hop-type {
-+ description "Match an IPv6 next-hop type";
-+ value 8;
-+ }
-+ enum metric {
-+ description "Match a route metric";
-+ value 9;
-+ }
-+ enum tag {
-+ description "Match a route tag";
-+ value 10;
-+ }
-+ /* zebra specific conditions. */
-+ enum ipv4-prefix-length {
-+ description "Match IPv4 prefix length";
-+ value 100;
-+ }
-+ enum ipv6-prefix-length {
-+ description "Match IPv6 prefix length";
-+ value 101;
-+ }
-+ enum ipv4-next-hop-prefix-length {
-+ description "Match next-hop prefix length";
-+ value 102;
-+ }
-+ enum source-protocol {
-+ description "Match source protocol";
-+ value 103;
-+ }
-+ enum source-instance {
-+ description "Match source protocol instance";
-+ value 104;
-+ }
-+ }
-+ }
-+
-+ choice condition-value {
-+ description
-+ "Value to match (interpretation depends on condition type)";
-+ mandatory true;
-+ case interface {
-+ when "./condition = 'interface'";
-+ leaf interface {
-+ type string;
-+ }
-+ }
-+ case access-list-num {
-+ when "./condition = 'ipv4-address-list' or
-+ ./condition = 'ipv4-next-hop-list'";
-+ leaf access-list-num {
-+ type filter:access-list-standard;
-+ }
-+ }
-+ case access-list-num-extended {
-+ when "./condition = 'ipv4-address-list' or
-+ ./condition = 'ipv4-next-hop-list'";
-+ leaf access-list-num-extended {
-+ type filter:access-list-extended;
-+ }
-+ }
-+ case list-name {
-+ when "./condition = 'ipv4-address-list' or
-+ ./condition = 'ipv4-prefix-list' or
-+ ./condition = 'ipv4-next-hop-list' or
-+ ./condition = 'ipv4-next-hop-prefix-list' or
-+ ./condition = 'ipv6-address-list' or
-+ ./condition = 'ipv6-prefix-list'";
-+ leaf list-name {
-+ type filter:access-list-name;
-+ }
-+ }
-+ case ipv4-next-hop-type {
-+ when "./condition = 'ipv4-next-hop-type'";
-+ leaf ipv4-next-hop-type {
-+ type enumeration {
-+ enum blackhole {
-+ value 0;
-+ }
-+ }
-+ }
-+ }
-+ case ipv6-next-hop-type {
-+ when "./condition = 'ipv6-next-hop-type'";
-+ leaf ipv6-next-hop-type {
-+ type enumeration {
-+ enum blackhole {
-+ value 0;
-+ }
-+ }
-+ }
-+ }
-+ case metric {
-+ when "./condition = 'metric'";
-+ leaf metric {
-+ type uint32 {
-+ range "1..4294967295";
-+ }
-+ }
-+ }
-+ case tag {
-+ when "./condition = 'tag'";
-+ leaf tag {
-+ type uint32 {
-+ range "1..4294967295";
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ list set-action {
-+ description "Route map set actions";
-+
-+ key "action";
-+
-+ leaf action {
-+ description "Action to do when the route map matches";
-+ type enumeration {
-+ enum ipv4-next-hop {
-+ description "Set IPv4 address of the next hop";
-+ value 0;
-+ }
-+ enum ipv6-next-hop {
-+ description "Set IPv6 address of the next hop";
-+ value 1;
-+ }
-+ enum metric {
-+ description "Set prefix/route metric";
-+ value 2;
-+ }
-+ enum tag {
-+ description "Set tag";
-+ value 3;
-+ }
-+ /* zebra specific conditions. */
-+ enum source {
-+ description "Set source address for route";
-+ value 100;
-+ }
-+ }
-+ }
-+
-+ choice action-value {
-+ description
-+ "Value to set (interpretation depends on action-type)";
-+ case ipv4-address {
-+ when "./action = 'ipv4-next-hop'";
-+ leaf ipv4-address {
-+ description "IPv4 address";
-+ type inet:ipv4-address;
-+ }
-+ }
-+ case ipv6-address {
-+ when "./action = 'ipv6-next-hop'";
-+ leaf ipv6-address {
-+ description "IPv6 address";
-+ type inet:ipv6-address;
-+ }
-+ }
-+ case metric {
-+ when "./action = 'metric'";
-+ choice metric-value {
-+ description "Metric to set or use";
-+ case value {
-+ leaf value {
-+ description "Use the following metric value";
-+ type uint32 {
-+ range "0..4294967295";
-+ }
-+ }
-+ }
-+ case add-metric {
-+ leaf add-metric {
-+ description "Add unit to metric";
-+ type boolean;
-+ }
-+ }
-+ case subtract-metric {
-+ leaf subtract-metric {
-+ description "Subtract unit from metric";
-+ type boolean;
-+ }
-+ }
-+ case use-round-trip-time {
-+ leaf use-round-trip-time {
-+ description "Use the round trip time as metric";
-+ type boolean;
-+ }
-+ }
-+ case add-round-trip-time {
-+ leaf add-round-trip-time {
-+ description "Add round trip time to metric";
-+ type boolean;
-+ }
-+ }
-+ case subtract-round-trip-time {
-+ leaf subtract-round-trip-time {
-+ description "Subtract round trip time to metric";
-+ type boolean;
-+ }
-+ }
-+ }
-+ }
-+ case tag {
-+ when "./action = 'tag'";
-+ leaf tag {
-+ description "Tag value";
-+ type uint32 {
-+ range "0..4294967295";
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+}
+++ /dev/null
-From 0c0e73045b1898610eef9309b9f5927254356710 Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Fri, 27 Sep 2019 19:32:10 -0300
-Subject: [PATCH 01/10] yang: update route map model
-
-Important changes:
-
- * Rename top container `route-map` to `lib`;
- * Rename list `instance` to `route-map`;
- * Move route map repeated data to list `entry`;
- * Use interface reference instead of typedef'ed string;
- * Remove some zebra specific route map conditions;
- * Protect `tag` set value with `when "./action = 'tag'"`;
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
-From a7282663eff6f036a427165b7fa73c75dccd47ff Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Mon, 30 Sep 2019 10:17:33 -0300
-Subject: [PATCH 02/10] lib: export route map structures and functions
-
-These exported items are going to be used by the new northbound CLI.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap.c | 213 ++-----------------------------------------------
- lib/routemap.h | 209 ++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 216 insertions(+), 206 deletions(-)
-
-diff --git a/lib/routemap.c b/lib/routemap.c
-index 14fec0283c..a8feebd313 100644
---- a/lib/routemap.c
-+++ b/lib/routemap.c
-@@ -50,178 +50,7 @@ static vector route_match_vec;
- /* Vector for route set rules. */
- static vector route_set_vec;
-
--struct route_map_match_set_hooks {
-- /* match interface */
-- int (*match_interface)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* no match interface */
-- int (*no_match_interface)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* match ip address */
-- int (*match_ip_address)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* no match ip address */
-- int (*no_match_ip_address)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* match ip address prefix list */
-- int (*match_ip_address_prefix_list)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* no match ip address prefix list */
-- int (*no_match_ip_address_prefix_list)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* match ip next hop */
-- int (*match_ip_next_hop)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* no match ip next hop */
-- int (*no_match_ip_next_hop)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* match ip next hop prefix list */
-- int (*match_ip_next_hop_prefix_list)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* no match ip next hop prefix list */
-- int (*no_match_ip_next_hop_prefix_list)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* match ip next-hop type */
-- int (*match_ip_next_hop_type)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* no match ip next-hop type */
-- int (*no_match_ip_next_hop_type)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* match ipv6 address */
-- int (*match_ipv6_address)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* no match ipv6 address */
-- int (*no_match_ipv6_address)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
--
-- /* match ipv6 address prefix list */
-- int (*match_ipv6_address_prefix_list)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* no match ipv6 address prefix list */
-- int (*no_match_ipv6_address_prefix_list)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* match ipv6 next-hop type */
-- int (*match_ipv6_next_hop_type)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command,
-- const char *arg,
-- route_map_event_t type);
--
-- /* no match ipv6 next-hop type */
-- int (*no_match_ipv6_next_hop_type)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* match metric */
-- int (*match_metric)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* no match metric */
-- int (*no_match_metric)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* match tag */
-- int (*match_tag)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* no match tag */
-- int (*no_match_tag)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg,
-- route_map_event_t type);
--
-- /* set ip nexthop */
-- int (*set_ip_nexthop)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* no set ip nexthop */
-- int (*no_set_ip_nexthop)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* set ipv6 nexthop local */
-- int (*set_ipv6_nexthop_local)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* no set ipv6 nexthop local */
-- int (*no_set_ipv6_nexthop_local)(struct vty *vty,
-- struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* set metric */
-- int (*set_metric)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* no set metric */
-- int (*no_set_metric)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* set tag */
-- int (*set_tag)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg);
--
-- /* no set tag */
-- int (*no_set_tag)(struct vty *vty, struct route_map_index *index,
-- const char *command, const char *arg);
--};
--
--static struct route_map_match_set_hooks rmap_match_set_hook;
-+struct route_map_match_set_hooks rmap_match_set_hook;
-
- /* match interface */
- void route_map_match_interface_hook(int (*func)(
-@@ -595,35 +424,9 @@ int generic_set_delete(struct vty *vty, struct route_map_index *index,
- }
-
-
--/* Route map rule. This rule has both `match' rule and `set' rule. */
--struct route_map_rule {
-- /* Rule type. */
-- const struct route_map_rule_cmd *cmd;
--
-- /* For pretty printing. */
-- char *rule_str;
--
-- /* Pre-compiled match rule. */
-- void *value;
--
-- /* Linked list. */
-- struct route_map_rule *next;
-- struct route_map_rule *prev;
--};
--
--/* Making route map list. */
--struct route_map_list {
-- struct route_map *head;
-- struct route_map *tail;
--
-- void (*add_hook)(const char *);
-- void (*delete_hook)(const char *);
-- void (*event_hook)(const char *);
--};
--
- /* Master list of route map. */
--static struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
--static struct hash *route_map_master_hash = NULL;
-+struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL};
-+struct hash *route_map_master_hash = NULL;
-
- static unsigned int route_map_hash_key_make(const void *p)
- {
-@@ -691,8 +494,6 @@ static void route_map_rule_delete(struct route_map_rule_list *,
- struct route_map_rule *);
- static bool rmap_debug;
-
--static void route_map_index_delete(struct route_map_index *, int);
--
- /* New route map allocation. Please note route map's name must be
- specified. */
- static struct route_map *route_map_new(const char *name)
-@@ -784,7 +585,7 @@ static void route_map_free_map(struct route_map *map)
- }
-
- /* Route map delete from list. */
--static void route_map_delete(struct route_map *map)
-+void route_map_delete(struct route_map *map)
- {
- struct route_map_index *index;
- char *name;
-@@ -883,7 +684,7 @@ static int route_map_clear_updated(struct route_map *map)
-
- /* Lookup route map. If there isn't route map create one and return
- it. */
--static struct route_map *route_map_get(const char *name)
-+struct route_map *route_map_get(const char *name)
- {
- struct route_map *map;
-
-@@ -1097,7 +898,7 @@ static struct route_map_index *route_map_index_new(void)
- }
-
- /* Free route map index. */
--static void route_map_index_delete(struct route_map_index *index, int notify)
-+void route_map_index_delete(struct route_map_index *index, int notify)
- {
- struct route_map_rule *rule;
-
-@@ -1202,7 +1003,7 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref)
- }
-
- /* Get route map index. */
--static struct route_map_index *
-+struct route_map_index *
- route_map_index_get(struct route_map *map, enum route_map_type type, int pref)
- {
- struct route_map_index *index;
-diff --git a/lib/routemap.h b/lib/routemap.h
-index 1ffd0525ae..41959c24e5 100644
---- a/lib/routemap.h
-+++ b/lib/routemap.h
-@@ -140,6 +140,22 @@ enum rmap_compile_rets {
-
- };
-
-+/* Route map rule. This rule has both `match' rule and `set' rule. */
-+struct route_map_rule {
-+ /* Rule type. */
-+ const struct route_map_rule_cmd *cmd;
-+
-+ /* For pretty printing. */
-+ char *rule_str;
-+
-+ /* Pre-compiled match rule. */
-+ void *value;
-+
-+ /* Linked list. */
-+ struct route_map_rule *next;
-+ struct route_map_rule *prev;
-+};
-+
- /* Route map rule list. */
- struct route_map_rule_list {
- struct route_map_rule *head;
-@@ -435,6 +451,199 @@ extern void route_map_counter_increment(struct route_map *map);
- /* Decrement the route-map used counter */
- extern void route_map_counter_decrement(struct route_map *map);
-
-+/* Route map hooks data structure. */
-+struct route_map_match_set_hooks {
-+ /* match interface */
-+ int (*match_interface)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match interface */
-+ int (*no_match_interface)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ip address */
-+ int (*match_ip_address)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ip address */
-+ int (*no_match_ip_address)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ip address prefix list */
-+ int (*match_ip_address_prefix_list)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ip address prefix list */
-+ int (*no_match_ip_address_prefix_list)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ip next hop */
-+ int (*match_ip_next_hop)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ip next hop */
-+ int (*no_match_ip_next_hop)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ip next hop prefix list */
-+ int (*match_ip_next_hop_prefix_list)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ip next hop prefix list */
-+ int (*no_match_ip_next_hop_prefix_list)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ip next-hop type */
-+ int (*match_ip_next_hop_type)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ip next-hop type */
-+ int (*no_match_ip_next_hop_type)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ipv6 address */
-+ int (*match_ipv6_address)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ipv6 address */
-+ int (*no_match_ipv6_address)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+
-+ /* match ipv6 address prefix list */
-+ int (*match_ipv6_address_prefix_list)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ipv6 address prefix list */
-+ int (*no_match_ipv6_address_prefix_list)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* match ipv6 next-hop type */
-+ int (*match_ipv6_next_hop_type)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command,
-+ const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match ipv6 next-hop type */
-+ int (*no_match_ipv6_next_hop_type)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* match metric */
-+ int (*match_metric)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match metric */
-+ int (*no_match_metric)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* match tag */
-+ int (*match_tag)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* no match tag */
-+ int (*no_match_tag)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg,
-+ route_map_event_t type);
-+
-+ /* set ip nexthop */
-+ int (*set_ip_nexthop)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* no set ip nexthop */
-+ int (*no_set_ip_nexthop)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* set ipv6 nexthop local */
-+ int (*set_ipv6_nexthop_local)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* no set ipv6 nexthop local */
-+ int (*no_set_ipv6_nexthop_local)(struct vty *vty,
-+ struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* set metric */
-+ int (*set_metric)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* no set metric */
-+ int (*no_set_metric)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* set tag */
-+ int (*set_tag)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg);
-+
-+ /* no set tag */
-+ int (*no_set_tag)(struct vty *vty, struct route_map_index *index,
-+ const char *command, const char *arg);
-+};
-+
-+extern struct route_map_match_set_hooks rmap_match_set_hook;
-+
-+/* Making route map list. */
-+struct route_map_list {
-+ struct route_map *head;
-+ struct route_map *tail;
-+
-+ void (*add_hook)(const char *);
-+ void (*delete_hook)(const char *);
-+ void (*event_hook)(const char *);
-+};
-+
-+extern struct route_map_list route_map_master;
-+
-+extern struct route_map *route_map_get(const char *name);
-+extern void route_map_delete(struct route_map *map);
-+extern struct route_map_index *route_map_index_get(struct route_map *map,
-+ enum route_map_type type,
-+ int pref);
-+extern void route_map_index_delete(struct route_map_index *index, int notify);
-+
- #ifdef __cplusplus
- }
- #endif
-
-From 686d244f00d87fa0b76c8e4644550d413fc3400b Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Mon, 30 Sep 2019 10:34:49 -0300
-Subject: [PATCH 03/10] lib: implement route map northbound
-
-Based on the route map old CLI, implement the route map handling using
-the exported functions.
-
-Use a curry-like programming pattern avoid code repetition when
-destroying match/set entries. This is needed by other daemons that
-implement custom route map functions and need to pass to lib their
-specific destroy functions.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap.h | 24 +
- lib/routemap_northbound.c | 1393 +++++++++++++++++++++++++++++++++++++
- lib/subdir.am | 2 +
- yang/subdir.am | 1 +
- 4 files changed, 1420 insertions(+)
- create mode 100644 lib/routemap_northbound.c
-
-diff --git a/lib/routemap.h b/lib/routemap.h
-index 41959c24e5..d9e7f73f81 100644
---- a/lib/routemap.h
-+++ b/lib/routemap.h
-@@ -644,6 +644,30 @@ extern struct route_map_index *route_map_index_get(struct route_map *map,
- int pref);
- extern void route_map_index_delete(struct route_map_index *index, int notify);
-
-+/* routemap_northbound.c */
-+typedef int (*routemap_match_hook_fun)(struct vty *vty,
-+ struct route_map_index *rmi,
-+ const char *command, const char *arg,
-+ route_map_event_t event);
-+
-+typedef int (*routemap_set_hook_fun)(struct vty *vty,
-+ struct route_map_index *rmi,
-+ const char *command, const char *arg);
-+
-+struct routemap_hook_context {
-+ struct route_map_index *rhc_rmi;
-+ const char *rhc_rule;
-+ route_map_event_t rhc_event;
-+ routemap_set_hook_fun rhc_shook;
-+ routemap_match_hook_fun rhc_mhook;
-+};
-+
-+int lib_route_map_entry_match_destroy(enum nb_event event,
-+ const struct lyd_node *dnode);
-+int lib_route_map_entry_set_destroy(enum nb_event event,
-+ const struct lyd_node *dnode);
-+extern const struct frr_yang_module_info frr_route_map_info;
-+
- #ifdef __cplusplus
- }
- #endif
-diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
-new file mode 100644
-index 0000000000..02eb756334
---- /dev/null
-+++ b/lib/routemap_northbound.c
-@@ -0,0 +1,1393 @@
-+/*
-+ * Route map northbound implementation.
-+ *
-+ * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
-+ * Rafael Zalamena
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301 USA.
-+ */
-+
-+#include <zebra.h>
-+
-+#include "lib/command.h"
-+#include "lib/log.h"
-+#include "lib/northbound.h"
-+#include "lib/routemap.h"
-+
-+/*
-+ * Auxiliary functions to avoid code duplication:
-+ *
-+ * lib_route_map_entry_set_destroy: unset `set` commands.
-+ * lib_route_map_entry_match_destroy: unset `match` commands.
-+ */
-+int lib_route_map_entry_match_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct routemap_hook_context *rhc;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ if (rhc->rhc_mhook == NULL)
-+ return NB_OK;
-+
-+ rv = rhc->rhc_mhook(NULL, rhc->rhc_rmi, rhc->rhc_rule, NULL,
-+ rhc->rhc_event);
-+ if (rv != CMD_SUCCESS)
-+ return NB_ERR_INCONSISTENCY;
-+
-+ return NB_OK;
-+}
-+
-+int lib_route_map_entry_set_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct routemap_hook_context *rhc;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ if (rhc->rhc_shook == NULL)
-+ return NB_OK;
-+
-+ rv = rhc->rhc_shook(NULL, rhc->rhc_rmi, rhc->rhc_rule, NULL);
-+ if (rv != CMD_SUCCESS)
-+ return NB_ERR_INCONSISTENCY;
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map
-+ */
-+static int lib_route_map_create(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map *rm;
-+ const char *rm_name;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rm_name = yang_dnode_get_string(dnode, "./name");
-+ rm = route_map_get(rm_name);
-+ nb_running_set_entry(dnode, rm);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct route_map *rm;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rm = nb_running_unset_entry(dnode);
-+ route_map_delete(rm);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry
-+ */
-+static int lib_route_map_entry_create(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map_index *rmi;
-+ struct route_map *rm;
-+ uint16_t sequence;
-+ int action;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ sequence = yang_dnode_get_uint16(dnode, "./sequence");
-+ action = yang_dnode_get_enum(dnode, "./action") == 0
-+ ? RMAP_PERMIT
-+ : RMAP_DENY;
-+ rm = nb_running_get_entry(dnode, NULL, true);
-+ rmi = route_map_index_get(rm, action, sequence);
-+ nb_running_set_entry(dnode, rmi);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct route_map_index *rmi;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_unset_entry(dnode);
-+ route_map_index_delete(rmi, 1);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/description
-+ */
-+static int lib_route_map_entry_description_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map_index *rmi;
-+ const char *description;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_PREPARE:
-+ description = yang_dnode_get_string(dnode, NULL);
-+ resource->ptr = XSTRDUP(MTYPE_TMP, description);
-+ if (resource->ptr == NULL)
-+ return NB_ERR_RESOURCE;
-+ break;
-+ case NB_EV_ABORT:
-+ XFREE(MTYPE_TMP, resource->ptr);
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ if (rmi->description != NULL)
-+ XFREE(MTYPE_TMP, rmi->description);
-+ rmi->description = resource->ptr;
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_description_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct route_map_index *rmi;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ if (rmi->description != NULL)
-+ XFREE(MTYPE_TMP, rmi->description);
-+ rmi->description = NULL;
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/action
-+ */
-+static int lib_route_map_entry_action_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map_index *rmi;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ rmi->type = yang_dnode_get_enum(dnode, NULL);
-+ /* TODO: notify? */
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/call
-+ */
-+static int lib_route_map_entry_call_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map_index *rmi;
-+ const char *rm_name, *rmn_name;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ rm_name = yang_dnode_get_string(dnode, "../../name");
-+ rmn_name = yang_dnode_get_string(dnode, NULL);
-+ /* Don't allow to jump to the same route map instance. */
-+ if (strcmp(rm_name, rmn_name) == 0)
-+ return NB_ERR_VALIDATION;
-+
-+ /* TODO: detect circular route map sequences. */
-+ break;
-+ case NB_EV_PREPARE:
-+ rmn_name = yang_dnode_get_string(dnode, NULL);
-+ resource->ptr = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmn_name);
-+ break;
-+ case NB_EV_ABORT:
-+ XFREE(MTYPE_ROUTE_MAP_NAME, resource->ptr);
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ if (rmi->nextrm) {
-+ route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
-+ rmi->nextrm, rmi->map->name);
-+ XFREE(MTYPE_ROUTE_MAP_NAME, rmi->nextrm);
-+ }
-+ rmi->nextrm = resource->ptr;
-+ route_map_upd8_dependency(RMAP_EVENT_CALL_ADDED, rmi->nextrm,
-+ rmi->map->name);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_call_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct route_map_index *rmi;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED, rmi->nextrm,
-+ rmi->map->name);
-+ XFREE(MTYPE_ROUTE_MAP_NAME, rmi->nextrm);
-+ rmi->nextrm = NULL;
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/exit-policy
-+ */
-+static int lib_route_map_entry_exit_policy_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map_index *rmi;
-+ int rm_action;
-+ int policy;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ policy = yang_dnode_get_enum(dnode, NULL);
-+ switch (policy) {
-+ case 0: /* permit-or-deny */
-+ break;
-+ case 1: /* next */
-+ /* FALLTHROUGH */
-+ case 2: /* goto */
-+ rm_action = yang_dnode_get_enum(dnode, "../action");
-+ if (rm_action == 1 /* deny */) {
-+ /*
-+ * On deny it is not possible to 'goto'
-+ * anywhere.
-+ */
-+ return NB_ERR_VALIDATION;
-+ }
-+ break;
-+ }
-+ break;
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ policy = yang_dnode_get_enum(dnode, NULL);
-+
-+ switch (policy) {
-+ case 0: /* permit-or-deny */
-+ rmi->exitpolicy = RMAP_EXIT;
-+ break;
-+ case 1: /* next */
-+ rmi->exitpolicy = RMAP_NEXT;
-+ break;
-+ case 2: /* goto */
-+ rmi->exitpolicy = RMAP_GOTO;
-+ break;
-+ }
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/goto-value
-+ */
-+static int lib_route_map_entry_goto_value_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct route_map_index *rmi;
-+ uint16_t rmi_index;
-+ uint16_t rmi_next;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ rmi_index = yang_dnode_get_uint16(dnode, "../sequence");
-+ rmi_next = yang_dnode_get_uint16(dnode, NULL);
-+ if (rmi_next <= rmi_index) {
-+ /* Can't jump backwards on a route map. */
-+ return NB_ERR_VALIDATION;
-+ }
-+ break;
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ rmi->nextpref = yang_dnode_get_uint16(dnode, NULL);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_goto_value_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct route_map_index *rmi;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_APPLY:
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ rmi->nextpref = 0;
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition
-+ */
-+static int
-+lib_route_map_entry_match_condition_create(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ /* NOTHING */
-+ break;
-+ case NB_EV_PREPARE:
-+ resource->ptr = XCALLOC(MTYPE_TMP, sizeof(*rhc));
-+ break;
-+ case NB_EV_ABORT:
-+ XFREE(MTYPE_TMP, resource->ptr);
-+ break;
-+ case NB_EV_APPLY:
-+ rhc = resource->ptr;
-+ rhc->rhc_rmi = nb_running_get_entry(dnode, NULL, true);
-+ nb_running_set_entry(dnode, rhc);
-+ break;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int
-+lib_route_map_entry_match_condition_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct routemap_hook_context *rhc;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ rv = lib_route_map_entry_match_destroy(event, dnode);
-+ rhc = nb_running_unset_entry(dnode);
-+ XFREE(MTYPE_TMP, rhc);
-+
-+ return rv;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/interface
-+ */
-+static int lib_route_map_entry_match_condition_interface_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *ifname;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.match_interface == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ ifname = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_interface;
-+ rhc->rhc_rule = "interface";
-+ rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
-+
-+ rv = rmap_match_set_hook.match_interface(NULL, rhc->rhc_rmi,
-+ "interface", ifname,
-+ RMAP_EVENT_MATCH_ADDED);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_match_condition_interface_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/access-list-num
-+ */
-+static int lib_route_map_entry_match_condition_access_list_num_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *acl;
-+ int condition, rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ rv = CMD_SUCCESS;
-+ acl = yang_dnode_get_string(dnode, NULL);
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ condition = yang_dnode_get_enum(dnode, "../condition");
-+ switch (condition) {
-+ case 1: /* ipv4-address-list */
-+ if (rmap_match_set_hook.match_ip_address == NULL)
-+ break;
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_address;
-+ rhc->rhc_rule = "ip address";
-+ rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
-+ rv = rmap_match_set_hook.match_ip_address(
-+ NULL, rhc->rhc_rmi, "ip address", acl,
-+ RMAP_EVENT_FILTER_ADDED);
-+ break;
-+ case 3: /* ipv4-next-hop-list */
-+ if (rmap_match_set_hook.match_ip_next_hop == NULL)
-+ break;
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop;
-+ rhc->rhc_rule = "ip next-hop";
-+ rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
-+ rv = rmap_match_set_hook.match_ip_next_hop(
-+ NULL, rhc->rhc_rmi, "ip next-hop", acl,
-+ RMAP_EVENT_FILTER_ADDED);
-+ break;
-+ }
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_match_condition_access_list_num_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath:
-+ * /frr-route-map:lib/route-map/entry/match-condition/access-list-num-extended
-+ */
-+static int lib_route_map_entry_match_condition_access_list_num_extended_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return lib_route_map_entry_match_condition_access_list_num_modify(
-+ event, dnode, resource);
-+}
-+
-+static int lib_route_map_entry_match_condition_access_list_num_extended_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_condition_access_list_num_destroy(
-+ event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/list-name
-+ */
-+static int lib_route_map_entry_match_condition_list_name_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *acl;
-+ int condition;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook installation, otherwise we can just stop. */
-+ acl = yang_dnode_get_string(dnode, NULL);
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ condition = yang_dnode_get_enum(dnode, "../condition");
-+ switch (condition) {
-+ case 1: /* ipv4-address-list */
-+ if (rmap_match_set_hook.match_ip_address == NULL)
-+ return NB_OK;
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_address;
-+ rhc->rhc_rule = "ip address";
-+ rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
-+ rv = rmap_match_set_hook.match_ip_address(
-+ NULL, rhc->rhc_rmi, "ip address", acl,
-+ RMAP_EVENT_FILTER_ADDED);
-+ break;
-+ case 2: /* ipv4-prefix-list */
-+ if (rmap_match_set_hook.match_ip_address_prefix_list == NULL)
-+ return NB_OK;
-+ rhc->rhc_mhook =
-+ rmap_match_set_hook.no_match_ip_address_prefix_list;
-+ rhc->rhc_rule = "ip address prefix-list";
-+ rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
-+ rv = rmap_match_set_hook.match_ip_address_prefix_list(
-+ NULL, rhc->rhc_rmi, "ip address prefix-list", acl,
-+ RMAP_EVENT_PLIST_ADDED);
-+ break;
-+ case 3: /* ipv4-next-hop-list */
-+ if (rmap_match_set_hook.match_ip_next_hop == NULL)
-+ return NB_OK;
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop;
-+ rhc->rhc_rule = "ip next-hop";
-+ rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
-+ rv = rmap_match_set_hook.match_ip_next_hop(
-+ NULL, rhc->rhc_rmi, "ip next-hop", acl,
-+ RMAP_EVENT_FILTER_ADDED);
-+ break;
-+ case 4: /* ipv4-next-hop-prefix-list */
-+ if (rmap_match_set_hook.match_ip_next_hop_prefix_list == NULL)
-+ return NB_OK;
-+ rhc->rhc_mhook =
-+ rmap_match_set_hook.no_match_ip_next_hop_prefix_list;
-+ rhc->rhc_rule = "ip next-hop prefix-list";
-+ rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
-+ rv = rmap_match_set_hook.match_ip_next_hop_prefix_list(
-+ NULL, rhc->rhc_rmi, "ip next-hop prefix-list", acl,
-+ RMAP_EVENT_PLIST_ADDED);
-+ break;
-+ case 6: /* ipv6-address-list */
-+ if (rmap_match_set_hook.match_ipv6_address == NULL)
-+ return NB_OK;
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_address;
-+ rhc->rhc_rule = "ipv6 address";
-+ rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
-+ rv = rmap_match_set_hook.match_ipv6_address(
-+ NULL, rhc->rhc_rmi, "ipv6 address", acl,
-+ RMAP_EVENT_FILTER_ADDED);
-+ break;
-+ case 7: /* ipv6-prefix-list */
-+ if (rmap_match_set_hook.match_ipv6_address_prefix_list == NULL)
-+ return NB_OK;
-+ rhc->rhc_mhook =
-+ rmap_match_set_hook.no_match_ipv6_address_prefix_list;
-+ rhc->rhc_rule = "ipv6 address prefix-list";
-+ rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
-+ rv = rmap_match_set_hook.match_ipv6_address_prefix_list(
-+ NULL, rhc->rhc_rmi, "ipv6 address prefix-list", acl,
-+ RMAP_EVENT_PLIST_ADDED);
-+ break;
-+ default:
-+ rv = CMD_ERR_NO_MATCH;
-+ break;
-+ }
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_match_condition_list_name_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/ipv4-next-hop-type
-+ */
-+static int lib_route_map_entry_match_condition_ipv4_next_hop_type_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *type;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.match_ip_next_hop_type == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ type = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop_type;
-+ rhc->rhc_rule = "ip next-hop type";
-+ rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
-+
-+ rv = rmap_match_set_hook.match_ip_next_hop_type(
-+ NULL, rhc->rhc_rmi, "ip next-hop type", type,
-+ RMAP_EVENT_MATCH_ADDED);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_match_condition_ipv4_next_hop_type_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/ipv6-next-hop-type
-+ */
-+static int lib_route_map_entry_match_condition_ipv6_next_hop_type_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *type;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.match_ipv6_next_hop_type == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ type = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_next_hop_type;
-+ rhc->rhc_rule = "ipv6 next-hop type";
-+ rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
-+
-+ rv = rmap_match_set_hook.match_ipv6_next_hop_type(
-+ NULL, rhc->rhc_rmi, "ipv6 next-hop type", type,
-+ RMAP_EVENT_MATCH_ADDED);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_match_condition_ipv6_next_hop_type_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/metric
-+ */
-+static int
-+lib_route_map_entry_match_condition_metric_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *type;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.match_metric == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ type = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_metric;
-+ rhc->rhc_rule = "metric";
-+ rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
-+
-+ rv = rmap_match_set_hook.match_metric(NULL, rhc->rhc_rmi, "metric",
-+ type, RMAP_EVENT_MATCH_ADDED);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int
-+lib_route_map_entry_match_condition_metric_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/tag
-+ */
-+static int
-+lib_route_map_entry_match_condition_tag_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *tag;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.match_tag == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ tag = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_mhook = rmap_match_set_hook.no_match_tag;
-+ rhc->rhc_rule = "tag";
-+ rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
-+
-+ rv = rmap_match_set_hook.match_tag(NULL, rhc->rhc_rmi, "tag", tag,
-+ RMAP_EVENT_MATCH_ADDED);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_mhook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int
-+lib_route_map_entry_match_condition_tag_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_match_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action
-+ */
-+static int lib_route_map_entry_set_action_create(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return lib_route_map_entry_match_condition_create(event, dnode,
-+ resource);
-+}
-+
-+static int lib_route_map_entry_set_action_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ struct routemap_hook_context *rhc;
-+ int rv;
-+
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ rv = lib_route_map_entry_set_destroy(event, dnode);
-+ rhc = nb_running_unset_entry(dnode);
-+ XFREE(MTYPE_TMP, rhc);
-+
-+ return rv;
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/ipv4-address
-+ */
-+static int
-+lib_route_map_entry_set_action_ipv4_address_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *address;
-+ struct in_addr ia;
-+ int rv;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ /*
-+ * NOTE: validate if 'action' is 'ipv4-next-hop',
-+ * currently it is not necessary because this is the
-+ * only implemented action.
-+ */
-+ yang_dnode_get_ipv4(&ia, dnode, NULL);
-+ if (ia.s_addr == 0 || IPV4_CLASS_DE(ntohl(ia.s_addr)))
-+ return NB_ERR_VALIDATION;
-+ /* FALLTHROUGH */
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ return NB_OK;
-+ case NB_EV_APPLY:
-+ break;
-+ }
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.set_ip_nexthop == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ address = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_shook = rmap_match_set_hook.no_set_ip_nexthop;
-+ rhc->rhc_rule = "ip next-hop";
-+
-+ rv = rmap_match_set_hook.set_ip_nexthop(NULL, rhc->rhc_rmi,
-+ "ip next-hop", address);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_shook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_set_action_ipv4_address_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/ipv6-address
-+ */
-+static int
-+lib_route_map_entry_set_action_ipv6_address_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *address;
-+ struct in6_addr i6a;
-+ int rv;
-+
-+ switch (event) {
-+ case NB_EV_VALIDATE:
-+ /*
-+ * NOTE: validate if 'action' is 'ipv6-next-hop',
-+ * currently it is not necessary because this is the
-+ * only implemented action. Other actions might have
-+ * different validations.
-+ */
-+ yang_dnode_get_ipv6(&i6a, dnode, NULL);
-+ if (!IN6_IS_ADDR_LINKLOCAL(&i6a))
-+ return NB_ERR_VALIDATION;
-+ /* FALLTHROUGH */
-+ case NB_EV_PREPARE:
-+ case NB_EV_ABORT:
-+ return NB_OK;
-+ case NB_EV_APPLY:
-+ break;
-+ }
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.set_ipv6_nexthop_local == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ address = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_shook = rmap_match_set_hook.no_set_ipv6_nexthop_local;
-+ rhc->rhc_rule = "ipv6 next-hop local";
-+
-+ rv = rmap_match_set_hook.set_ipv6_nexthop_local(
-+ NULL, rhc->rhc_rmi, "ipv6 next-hop local", address);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_shook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int lib_route_map_entry_set_action_ipv6_address_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/value
-+ */
-+static int set_action_modify(enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource, const char *value)
-+{
-+ struct routemap_hook_context *rhc;
-+ int rv;
-+
-+ /*
-+ * NOTE: validate if 'action' is 'metric', currently it is not
-+ * necessary because this is the only implemented action. Other
-+ * actions might have different validations.
-+ */
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.set_metric == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_shook = rmap_match_set_hook.no_set_metric;
-+ rhc->rhc_rule = "metric";
-+
-+ rv = rmap_match_set_hook.set_metric(NULL, rhc->rhc_rmi, "metric",
-+ value);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_shook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int
-+lib_route_map_entry_set_action_value_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ const char *metric = yang_dnode_get_string(dnode, NULL);
-+
-+ return set_action_modify(event, dnode, resource, metric);
-+}
-+
-+static int
-+lib_route_map_entry_set_action_value_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/add-metric
-+ */
-+static int
-+lib_route_map_entry_set_action_add_metric_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return set_action_modify(event, dnode, resource, "+metric");
-+}
-+
-+static int
-+lib_route_map_entry_set_action_add_metric_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_action_value_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/subtract-metric
-+ */
-+static int lib_route_map_entry_set_action_subtract_metric_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return set_action_modify(event, dnode, resource, "-metric");
-+}
-+
-+static int lib_route_map_entry_set_action_subtract_metric_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_action_value_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/use-round-trip-time
-+ */
-+static int lib_route_map_entry_set_action_use_round_trip_time_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return set_action_modify(event, dnode, resource, "rtt");
-+}
-+
-+static int lib_route_map_entry_set_action_use_round_trip_time_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_action_value_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/add-round-trip-time
-+ */
-+static int lib_route_map_entry_set_action_add_round_trip_time_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return set_action_modify(event, dnode, resource, "+rtt");
-+}
-+
-+static int lib_route_map_entry_set_action_add_round_trip_time_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_action_value_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/subtract-round-trip-time
-+ */
-+static int lib_route_map_entry_set_action_subtract_round_trip_time_modify(
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ return set_action_modify(event, dnode, resource, "-rtt");
-+}
-+
-+static int lib_route_map_entry_set_action_subtract_round_trip_time_destroy(
-+ enum nb_event event, const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_action_value_destroy(event, dnode);
-+}
-+
-+/*
-+ * XPath: /frr-route-map:lib/route-map/entry/set-action/tag
-+ */
-+static int
-+lib_route_map_entry_set_action_tag_modify(enum nb_event event,
-+ const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ struct routemap_hook_context *rhc;
-+ const char *tag;
-+ int rv;
-+
-+ /*
-+ * NOTE: validate if 'action' is 'tag', currently it is not
-+ * necessary because this is the only implemented action. Other
-+ * actions might have different validations.
-+ */
-+ if (event != NB_EV_APPLY)
-+ return NB_OK;
-+
-+ /* Check for hook function. */
-+ if (rmap_match_set_hook.set_tag == NULL)
-+ return NB_OK;
-+
-+ /* Add configuration. */
-+ rhc = nb_running_get_entry(dnode, NULL, true);
-+ tag = yang_dnode_get_string(dnode, NULL);
-+
-+ /* Set destroy information. */
-+ rhc->rhc_shook = rmap_match_set_hook.no_set_tag;
-+ rhc->rhc_rule = "tag";
-+
-+ rv = rmap_match_set_hook.set_tag(NULL, rhc->rhc_rmi, "tag", tag);
-+ if (rv != CMD_SUCCESS) {
-+ rhc->rhc_shook = NULL;
-+ return NB_ERR_INCONSISTENCY;
-+ }
-+
-+ return NB_OK;
-+}
-+
-+static int
-+lib_route_map_entry_set_action_tag_destroy(enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ return lib_route_map_entry_set_destroy(event, dnode);
-+}
-+
-+/* clang-format off */
-+const struct frr_yang_module_info frr_route_map_info = {
-+ .name = "frr-route-map",
-+ .nodes = {
-+ {
-+ .xpath = "/frr-route-map:lib/route-map",
-+ .cbs = {
-+ .create = lib_route_map_create,
-+ .destroy = lib_route_map_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry",
-+ .cbs = {
-+ .create = lib_route_map_entry_create,
-+ .destroy = lib_route_map_entry_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/description",
-+ .cbs = {
-+ .modify = lib_route_map_entry_description_modify,
-+ .destroy = lib_route_map_entry_description_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/action",
-+ .cbs = {
-+ .modify = lib_route_map_entry_action_modify,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/call",
-+ .cbs = {
-+ .modify = lib_route_map_entry_call_modify,
-+ .destroy = lib_route_map_entry_call_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/exit-policy",
-+ .cbs = {
-+ .modify = lib_route_map_entry_exit_policy_modify,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/goto-value",
-+ .cbs = {
-+ .modify = lib_route_map_entry_goto_value_modify,
-+ .destroy = lib_route_map_entry_goto_value_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition",
-+ .cbs = {
-+ .create = lib_route_map_entry_match_condition_create,
-+ .destroy = lib_route_map_entry_match_condition_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/interface",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_interface_modify,
-+ .destroy = lib_route_map_entry_match_condition_interface_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/access-list-num",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_access_list_num_modify,
-+ .destroy = lib_route_map_entry_match_condition_access_list_num_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/access-list-num-extended",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_access_list_num_extended_modify,
-+ .destroy = lib_route_map_entry_match_condition_access_list_num_extended_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/list-name",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_list_name_modify,
-+ .destroy = lib_route_map_entry_match_condition_list_name_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/ipv4-next-hop-type",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_ipv4_next_hop_type_modify,
-+ .destroy = lib_route_map_entry_match_condition_ipv4_next_hop_type_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/ipv6-next-hop-type",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_ipv6_next_hop_type_modify,
-+ .destroy = lib_route_map_entry_match_condition_ipv6_next_hop_type_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/metric",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_metric_modify,
-+ .destroy = lib_route_map_entry_match_condition_metric_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/match-condition/tag",
-+ .cbs = {
-+ .modify = lib_route_map_entry_match_condition_tag_modify,
-+ .destroy = lib_route_map_entry_match_condition_tag_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action",
-+ .cbs = {
-+ .create = lib_route_map_entry_set_action_create,
-+ .destroy = lib_route_map_entry_set_action_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/ipv4-address",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_ipv4_address_modify,
-+ .destroy = lib_route_map_entry_set_action_ipv4_address_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/ipv6-address",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_ipv6_address_modify,
-+ .destroy = lib_route_map_entry_set_action_ipv6_address_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/value",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_value_modify,
-+ .destroy = lib_route_map_entry_set_action_value_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/add-metric",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_add_metric_modify,
-+ .destroy = lib_route_map_entry_set_action_add_metric_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/subtract-metric",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_subtract_metric_modify,
-+ .destroy = lib_route_map_entry_set_action_subtract_metric_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/use-round-trip-time",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_use_round_trip_time_modify,
-+ .destroy = lib_route_map_entry_set_action_use_round_trip_time_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/add-round-trip-time",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_add_round_trip_time_modify,
-+ .destroy = lib_route_map_entry_set_action_add_round_trip_time_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/subtract-round-trip-time",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_subtract_round_trip_time_modify,
-+ .destroy = lib_route_map_entry_set_action_subtract_round_trip_time_destroy,
-+ }
-+ },
-+ {
-+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/tag",
-+ .cbs = {
-+ .modify = lib_route_map_entry_set_action_tag_modify,
-+ .destroy = lib_route_map_entry_set_action_tag_destroy,
-+ }
-+ },
-+ {
-+ .xpath = NULL,
-+ },
-+ }
-+};
-diff --git a/lib/subdir.am b/lib/subdir.am
-index d804d839db..94b3d933ac 100644
---- a/lib/subdir.am
-+++ b/lib/subdir.am
-@@ -71,6 +71,7 @@ lib_libfrr_la_SOURCES = \
- lib/qobj.c \
- lib/ringbuf.c \
- lib/routemap.c \
-+ lib/routemap_northbound.c \
- lib/sbuf.c \
- lib/seqlock.c \
- lib/sha256.c \
-@@ -105,6 +106,7 @@ lib_libfrr_la_SOURCES = \
-
- nodist_lib_libfrr_la_SOURCES = \
- yang/frr-interface.yang.c \
-+ yang/frr-route-map.yang.c \
- yang/frr-route-types.yang.c \
- yang/ietf/ietf-routing-types.yang.c \
- yang/frr-module-translator.yang.c \
-diff --git a/yang/subdir.am b/yang/subdir.am
-index cfaf1a6401..7a15a6a309 100644
---- a/yang/subdir.am
-+++ b/yang/subdir.am
-@@ -22,6 +22,7 @@ EXTRA_DIST += yang/embedmodel.py
- dist_yangmodels_DATA += yang/frr-module-translator.yang
- dist_yangmodels_DATA += yang/frr-test-module.yang
- dist_yangmodels_DATA += yang/frr-interface.yang
-+dist_yangmodels_DATA += yang/frr-route-map.yang
- dist_yangmodels_DATA += yang/frr-route-types.yang
- dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang
-
-
-From 2b3e4807ecf4d2586fe4d651b904967ea8d759c0 Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Mon, 30 Sep 2019 15:01:46 -0300
-Subject: [PATCH 04/10] lib: implement new route map CLI
-
-Use the northbound back-end instead of the old route map CLI.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap.c | 1103 +------------------------------------
- lib/routemap.h | 19 +
- lib/routemap_cli.c | 1075 ++++++++++++++++++++++++++++++++++++
- lib/routemap_northbound.c | 7 +
- lib/subdir.am | 4 +
- vtysh/extract.pl.in | 2 +-
- 6 files changed, 1108 insertions(+), 1102 deletions(-)
- create mode 100644 lib/routemap_cli.c
-
-diff --git a/lib/routemap.c b/lib/routemap.c
-index a8feebd313..e07ad08123 100644
---- a/lib/routemap.c
-+++ b/lib/routemap.c
-@@ -759,14 +759,6 @@ static const char *route_map_result_str(route_map_result_t res)
- return "invalid";
- }
-
--static int route_map_empty(struct route_map *map)
--{
-- if (map->head == NULL && map->tail == NULL)
-- return 1;
-- else
-- return 0;
--}
--
- /* show route-map */
- static void vty_show_route_map_entry(struct vty *vty, struct route_map *map)
- {
-@@ -2010,871 +2002,6 @@ void route_map_notify_dependencies(const char *affected_name,
-
-
- /* VTY related functions. */
--DEFUN (match_interface,
-- match_interface_cmd,
-- "match interface WORD",
-- MATCH_STR
-- "match first hop interface of route\n"
-- "Interface name\n")
--{
-- int idx_word = 2;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_interface)
-- return rmap_match_set_hook.match_interface(
-- vty, index, "interface", argv[idx_word]->arg,
-- RMAP_EVENT_MATCH_ADDED);
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_match_interface,
-- no_match_interface_cmd,
-- "no match interface [WORD]",
-- NO_STR
-- MATCH_STR
-- "Match first hop interface of route\n"
-- "Interface name\n")
--{
-- char *iface = (argc == 4) ? argv[3]->arg : NULL;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_interface)
-- return rmap_match_set_hook.no_match_interface(
-- vty, index, "interface", iface,
-- RMAP_EVENT_MATCH_DELETED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_ip_address,
-- match_ip_address_cmd,
-- "match ip address <(1-199)|(1300-2699)|WORD>",
-- MATCH_STR
-- IP_STR
-- "Match address of route\n"
-- "IP access-list number\n"
-- "IP access-list number (expanded range)\n"
-- "IP Access-list name\n")
--{
-- int idx_acl = 3;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ip_address)
-- return rmap_match_set_hook.match_ip_address(
-- vty, index, "ip address", argv[idx_acl]->arg,
-- RMAP_EVENT_FILTER_ADDED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_match_ip_address,
-- no_match_ip_address_cmd,
-- "no match ip address [<(1-199)|(1300-2699)|WORD>]",
-- NO_STR
-- MATCH_STR
-- IP_STR
-- "Match address of route\n"
-- "IP access-list number\n"
-- "IP access-list number (expanded range)\n"
-- "IP Access-list name\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ip_address) {
-- if (argc <= idx_word)
-- return rmap_match_set_hook.no_match_ip_address(
-- vty, index, "ip address", NULL,
-- RMAP_EVENT_FILTER_DELETED);
-- return rmap_match_set_hook.no_match_ip_address(
-- vty, index, "ip address", argv[idx_word]->arg,
-- RMAP_EVENT_FILTER_DELETED);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_ip_address_prefix_list,
-- match_ip_address_prefix_list_cmd,
-- "match ip address prefix-list WORD",
-- MATCH_STR
-- IP_STR
-- "Match address of route\n"
-- "Match entries of prefix-lists\n"
-- "IP prefix-list name\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ip_address_prefix_list)
-- return rmap_match_set_hook.match_ip_address_prefix_list(
-- vty, index, "ip address prefix-list",
-- argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_match_ip_address_prefix_list,
-- no_match_ip_address_prefix_list_cmd,
-- "no match ip address prefix-list [WORD]",
-- NO_STR
-- MATCH_STR
-- IP_STR
-- "Match address of route\n"
-- "Match entries of prefix-lists\n"
-- "IP prefix-list name\n")
--{
-- int idx_word = 5;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ip_address_prefix_list) {
-- if (argc <= idx_word)
-- return rmap_match_set_hook
-- .no_match_ip_address_prefix_list(
-- vty, index, "ip address prefix-list",
-- NULL, RMAP_EVENT_PLIST_DELETED);
-- return rmap_match_set_hook.no_match_ip_address_prefix_list(
-- vty, index, "ip address prefix-list",
-- argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_ip_next_hop,
-- match_ip_next_hop_cmd,
-- "match ip next-hop <(1-199)|(1300-2699)|WORD>",
-- MATCH_STR
-- IP_STR
-- "Match next-hop address of route\n"
-- "IP access-list number\n"
-- "IP access-list number (expanded range)\n"
-- "IP Access-list name\n")
--{
-- int idx_acl = 3;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ip_next_hop)
-- return rmap_match_set_hook.match_ip_next_hop(
-- vty, index, "ip next-hop", argv[idx_acl]->arg,
-- RMAP_EVENT_FILTER_ADDED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_match_ip_next_hop,
-- no_match_ip_next_hop_cmd,
-- "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]",
-- NO_STR
-- MATCH_STR
-- IP_STR
-- "Match next-hop address of route\n"
-- "IP access-list number\n"
-- "IP access-list number (expanded range)\n"
-- "IP Access-list name\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ip_next_hop) {
-- if (argc <= idx_word)
-- return rmap_match_set_hook.no_match_ip_next_hop(
-- vty, index, "ip next-hop", NULL,
-- RMAP_EVENT_FILTER_DELETED);
-- return rmap_match_set_hook.no_match_ip_next_hop(
-- vty, index, "ip next-hop", argv[idx_word]->arg,
-- RMAP_EVENT_FILTER_DELETED);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_ip_next_hop_prefix_list,
-- match_ip_next_hop_prefix_list_cmd,
-- "match ip next-hop prefix-list WORD",
-- MATCH_STR
-- IP_STR
-- "Match next-hop address of route\n"
-- "Match entries of prefix-lists\n"
-- "IP prefix-list name\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ip_next_hop_prefix_list)
-- return rmap_match_set_hook.match_ip_next_hop_prefix_list(
-- vty, index, "ip next-hop prefix-list",
-- argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_match_ip_next_hop_prefix_list,
-- no_match_ip_next_hop_prefix_list_cmd,
-- "no match ip next-hop prefix-list [WORD]",
-- NO_STR
-- MATCH_STR
-- IP_STR
-- "Match next-hop address of route\n"
-- "Match entries of prefix-lists\n"
-- "IP prefix-list name\n")
--{
-- int idx_word = 5;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ip_next_hop) {
-- if (argc <= idx_word)
-- return rmap_match_set_hook.no_match_ip_next_hop(
-- vty, index, "ip next-hop prefix-list", NULL,
-- RMAP_EVENT_PLIST_DELETED);
-- return rmap_match_set_hook.no_match_ip_next_hop(
-- vty, index, "ip next-hop prefix-list",
-- argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
-- }
-- return CMD_SUCCESS;
--}
--
--DEFUN(match_ip_next_hop_type, match_ip_next_hop_type_cmd,
-- "match ip next-hop type <blackhole>",
-- MATCH_STR IP_STR
-- "Match next-hop address of route\n"
-- "Match entries by type\n"
-- "Blackhole\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ip_next_hop_type)
-- return rmap_match_set_hook.match_ip_next_hop_type(
-- vty, index, "ip next-hop type", argv[idx_word]->arg,
-- RMAP_EVENT_MATCH_ADDED);
-- return CMD_SUCCESS;
--}
--
--DEFUN(no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
-- "no match ip next-hop type [<blackhole>]",
-- NO_STR MATCH_STR IP_STR
-- "Match next-hop address of route\n"
-- "Match entries by type\n"
-- "Blackhole\n")
--{
-- int idx_word = 5;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ip_next_hop) {
-- if (argc <= idx_word)
-- return rmap_match_set_hook.no_match_ip_next_hop(
-- vty, index, "ip next-hop type", NULL,
-- RMAP_EVENT_MATCH_DELETED);
-- return rmap_match_set_hook.no_match_ip_next_hop(
-- vty, index, "ip next-hop type", argv[idx_word]->arg,
-- RMAP_EVENT_MATCH_DELETED);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_ipv6_address,
-- match_ipv6_address_cmd,
-- "match ipv6 address WORD",
-- MATCH_STR
-- IPV6_STR
-- "Match IPv6 address of route\n"
-- "IPv6 access-list name\n")
--{
-- int idx_word = 3;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ipv6_address)
-- return rmap_match_set_hook.match_ipv6_address(
-- vty, index, "ipv6 address", argv[idx_word]->arg,
-- RMAP_EVENT_FILTER_ADDED);
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_match_ipv6_address,
-- no_match_ipv6_address_cmd,
-- "no match ipv6 address WORD",
-- NO_STR
-- MATCH_STR
-- IPV6_STR
-- "Match IPv6 address of route\n"
-- "IPv6 access-list name\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ipv6_address)
-- return rmap_match_set_hook.no_match_ipv6_address(
-- vty, index, "ipv6 address", argv[idx_word]->arg,
-- RMAP_EVENT_FILTER_DELETED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_ipv6_address_prefix_list,
-- match_ipv6_address_prefix_list_cmd,
-- "match ipv6 address prefix-list WORD",
-- MATCH_STR
-- IPV6_STR
-- "Match address of route\n"
-- "Match entries of prefix-lists\n"
-- "IP prefix-list name\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ipv6_address_prefix_list)
-- return rmap_match_set_hook.match_ipv6_address_prefix_list(
-- vty, index, "ipv6 address prefix-list",
-- argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_match_ipv6_address_prefix_list,
-- no_match_ipv6_address_prefix_list_cmd,
-- "no match ipv6 address prefix-list WORD",
-- NO_STR
-- MATCH_STR
-- IPV6_STR
-- "Match address of route\n"
-- "Match entries of prefix-lists\n"
-- "IP prefix-list name\n")
--{
-- int idx_word = 5;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ipv6_address_prefix_list)
-- return rmap_match_set_hook.no_match_ipv6_address_prefix_list(
-- vty, index, "ipv6 address prefix-list",
-- argv[idx_word]->arg, RMAP_EVENT_PLIST_DELETED);
-- return CMD_SUCCESS;
--}
--
--DEFUN(match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
-- "match ipv6 next-hop type <blackhole>",
-- MATCH_STR IPV6_STR
-- "Match next-hop address of route\n"
-- "Match entries by type\n"
-- "Blackhole\n")
--{
-- int idx_word = 4;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_ipv6_next_hop_type)
-- return rmap_match_set_hook.match_ipv6_next_hop_type(
-- vty, index, "ipv6 next-hop type", argv[idx_word]->arg,
-- RMAP_EVENT_MATCH_ADDED);
-- return CMD_SUCCESS;
--}
--
--DEFUN(no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
-- "no match ipv6 next-hop type [<blackhole>]",
-- NO_STR MATCH_STR IPV6_STR
-- "Match address of route\n"
-- "Match entries by type\n"
-- "Blackhole\n")
--{
-- int idx_word = 5;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_ipv6_next_hop_type)
-- return rmap_match_set_hook.no_match_ipv6_next_hop_type(
-- vty, index, "ipv6 next-hop type",
-- (argc <= idx_word) ? NULL : argv[idx_word]->arg,
-- RMAP_EVENT_MATCH_DELETED);
-- return CMD_SUCCESS;
--}
--
--DEFUN (match_metric,
-- match_metric_cmd,
-- "match metric (0-4294967295)",
-- MATCH_STR
-- "Match metric of route\n"
-- "Metric value\n")
--{
-- int idx_number = 2;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_metric)
-- return rmap_match_set_hook.match_metric(vty, index, "metric",
-- argv[idx_number]->arg,
-- RMAP_EVENT_MATCH_ADDED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_match_metric,
-- no_match_metric_cmd,
-- "no match metric [(0-4294967295)]",
-- NO_STR
-- MATCH_STR
-- "Match metric of route\n"
-- "Metric value\n")
--{
-- int idx_number = 3;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_match_metric) {
-- if (argc <= idx_number)
-- return rmap_match_set_hook.no_match_metric(
-- vty, index, "metric", NULL,
-- RMAP_EVENT_MATCH_DELETED);
-- return rmap_match_set_hook.no_match_metric(
-- vty, index, "metric", argv[idx_number]->arg,
-- RMAP_EVENT_MATCH_DELETED);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (match_tag,
-- match_tag_cmd,
-- "match tag (1-4294967295)",
-- MATCH_STR
-- "Match tag of route\n"
-- "Tag value\n")
--{
-- int idx_number = 2;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.match_tag)
-- return rmap_match_set_hook.match_tag(vty, index, "tag",
-- argv[idx_number]->arg,
-- RMAP_EVENT_MATCH_ADDED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_match_tag,
-- no_match_tag_cmd,
-- "no match tag [(1-4294967295)]",
-- NO_STR
-- MATCH_STR
-- "Match tag of route\n"
-- "Tag value\n")
--{
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- int idx = 0;
-- char *arg = argv_find(argv, argc, "(1-4294967295)", &idx)
-- ? argv[idx]->arg
-- : NULL;
--
-- if (rmap_match_set_hook.no_match_tag)
-- return rmap_match_set_hook.no_match_tag(
-- vty, index, "tag", arg, RMAP_EVENT_MATCH_DELETED);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (set_ip_nexthop,
-- set_ip_nexthop_cmd,
-- "set ip next-hop A.B.C.D",
-- SET_STR
-- IP_STR
-- "Next hop address\n"
-- "IP address of next hop\n")
--{
-- int idx_ipv4 = 3;
-- union sockunion su;
-- int ret;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- ret = str2sockunion(argv[idx_ipv4]->arg, &su);
-- if (ret < 0) {
-- vty_out(vty, "%% Malformed nexthop address\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- }
-- if (su.sin.sin_addr.s_addr == 0
-- || IPV4_CLASS_DE(ntohl(su.sin.sin_addr.s_addr))) {
-- vty_out(vty,
-- "%% nexthop address cannot be 0.0.0.0, multicast or reserved\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- }
--
-- if (rmap_match_set_hook.set_ip_nexthop)
-- return rmap_match_set_hook.set_ip_nexthop(
-- vty, index, "ip next-hop", argv[idx_ipv4]->arg);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_set_ip_nexthop,
-- no_set_ip_nexthop_cmd,
-- "no set ip next-hop [A.B.C.D]",
-- NO_STR
-- SET_STR
-- IP_STR
-- "Next hop address\n"
-- "IP address of next hop\n")
--{
-- int idx = 0;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
-- const char *arg = NULL;
--
-- if (argv_find(argv, argc, "A.B.C.D", &idx))
-- arg = argv[idx]->arg;
--
-- if (rmap_match_set_hook.no_set_ip_nexthop)
-- return rmap_match_set_hook.no_set_ip_nexthop(
-- vty, index, "ip next-hop", arg);
--
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (set_ipv6_nexthop_local,
-- set_ipv6_nexthop_local_cmd,
-- "set ipv6 next-hop local X:X::X:X",
-- SET_STR
-- IPV6_STR
-- "IPv6 next-hop address\n"
-- "IPv6 local address\n"
-- "IPv6 address of next hop\n")
--{
-- int idx_ipv6 = 4;
-- struct in6_addr addr;
-- int ret;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- ret = inet_pton(AF_INET6, argv[idx_ipv6]->arg, &addr);
-- if (!ret) {
-- vty_out(vty, "%% Malformed nexthop address\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- }
-- if (!IN6_IS_ADDR_LINKLOCAL(&addr)) {
-- vty_out(vty, "%% Invalid link-local nexthop address\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- }
--
-- if (rmap_match_set_hook.set_ipv6_nexthop_local)
-- return rmap_match_set_hook.set_ipv6_nexthop_local(
-- vty, index, "ipv6 next-hop local", argv[idx_ipv6]->arg);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_set_ipv6_nexthop_local,
-- no_set_ipv6_nexthop_local_cmd,
-- "no set ipv6 next-hop local [X:X::X:X]",
-- NO_STR
-- SET_STR
-- IPV6_STR
-- "IPv6 next-hop address\n"
-- "IPv6 local address\n"
-- "IPv6 address of next hop\n")
--{
-- int idx_ipv6 = 5;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_set_ipv6_nexthop_local) {
-- if (argc <= idx_ipv6)
-- return rmap_match_set_hook.no_set_ipv6_nexthop_local(
-- vty, index, "ipv6 next-hop local", NULL);
-- return rmap_match_set_hook.no_set_ipv6_nexthop_local(
-- vty, index, "ipv6 next-hop local", argv[5]->arg);
-- }
-- return CMD_SUCCESS;
--}
--
--DEFUN (set_metric,
-- set_metric_cmd,
-- "set metric <(0-4294967295)|rtt|+rtt|-rtt|+metric|-metric>",
-- SET_STR
-- "Metric value for destination routing protocol\n"
-- "Metric value\n"
-- "Assign round trip time\n"
-- "Add round trip time\n"
-- "Subtract round trip time\n"
-- "Add metric\n"
-- "Subtract metric\n")
--{
-- int idx_number = 2;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- const char *pass = (argv[idx_number]->type == RANGE_TKN)
-- ? argv[idx_number]->arg
-- : argv[idx_number]->text;
--
-- if (rmap_match_set_hook.set_metric)
-- return rmap_match_set_hook.set_metric(vty, index, "metric",
-- pass);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_set_metric,
-- no_set_metric_cmd,
-- "no set metric [(0-4294967295)]",
-- NO_STR
-- SET_STR
-- "Metric value for destination routing protocol\n"
-- "Metric value\n")
--{
-- int idx_number = 3;
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- if (rmap_match_set_hook.no_set_metric) {
-- if (argc <= idx_number)
-- return rmap_match_set_hook.no_set_metric(
-- vty, index, "metric", NULL);
-- return rmap_match_set_hook.no_set_metric(vty, index, "metric",
-- argv[idx_number]->arg);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (set_tag,
-- set_tag_cmd,
-- "set tag (1-4294967295)",
-- SET_STR
-- "Tag value for routing protocol\n"
-- "Tag value\n")
--{
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- int idx_number = 2;
-- if (rmap_match_set_hook.set_tag)
-- return rmap_match_set_hook.set_tag(vty, index, "tag",
-- argv[idx_number]->arg);
-- return CMD_SUCCESS;
--}
--
--
--DEFUN (no_set_tag,
-- no_set_tag_cmd,
-- "no set tag [(1-4294967295)]",
-- NO_STR
-- SET_STR
-- "Tag value for routing protocol\n"
-- "Tag value\n")
--{
-- VTY_DECLVAR_CONTEXT(route_map_index, index);
--
-- int idx_number = 3;
-- if (rmap_match_set_hook.no_set_tag) {
-- if (argc <= idx_number)
-- return rmap_match_set_hook.no_set_tag(vty, index, "tag",
-- NULL);
-- return rmap_match_set_hook.no_set_tag(vty, index, "tag",
-- argv[idx_number]->arg);
-- }
-- return CMD_SUCCESS;
--}
--
--
--DEFUN_NOSH (route_map,
-- route_map_cmd,
-- "route-map WORD <deny|permit> (1-65535)",
-- "Create route-map or enter route-map command mode\n"
-- "Route map tag\n"
-- "Route map denies set operations\n"
-- "Route map permits set operations\n"
-- "Sequence to insert to/delete from existing route-map entry\n")
--{
-- int idx_word = 1;
-- int idx_permit_deny = 2;
-- int idx_number = 3;
-- struct route_map *map;
-- struct route_map_index *index;
-- char *endptr = NULL;
-- int permit =
-- argv[idx_permit_deny]->arg[0] == 'p' ? RMAP_PERMIT : RMAP_DENY;
-- unsigned long pref = strtoul(argv[idx_number]->arg, &endptr, 10);
-- const char *mapname = argv[idx_word]->arg;
--
-- /* Get route map. */
-- map = route_map_get(mapname);
-- index = route_map_index_get(map, permit, pref);
--
-- VTY_PUSH_CONTEXT(RMAP_NODE, index);
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_route_map_all,
-- no_route_map_all_cmd,
-- "no route-map WORD",
-- NO_STR
-- "Create route-map or enter route-map command mode\n"
-- "Route map tag\n")
--{
-- int idx_word = 2;
-- const char *mapname = argv[idx_word]->arg;
-- struct route_map *map;
--
-- map = route_map_lookup_by_name(mapname);
-- if (map == NULL) {
-- vty_out(vty, "%% Could not find route-map %s\n", mapname);
-- return CMD_WARNING_CONFIG_FAILED;
-- }
--
-- route_map_delete(map);
--
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_route_map,
-- no_route_map_cmd,
-- "no route-map WORD <deny|permit> (1-65535)",
-- NO_STR
-- "Create route-map or enter route-map command mode\n"
-- "Route map tag\n"
-- "Route map denies set operations\n"
-- "Route map permits set operations\n"
-- "Sequence to insert to/delete from existing route-map entry\n")
--{
-- int idx_word = 2;
-- int idx_permit_deny = 3;
-- int idx_number = 4;
-- struct route_map *map;
-- struct route_map_index *index;
-- char *endptr = NULL;
-- int permit = strmatch(argv[idx_permit_deny]->text, "permit")
-- ? RMAP_PERMIT
-- : RMAP_DENY;
-- const char *prefstr = argv[idx_number]->arg;
-- const char *mapname = argv[idx_word]->arg;
-- unsigned long pref = strtoul(prefstr, &endptr, 10);
--
-- /* Existence check. */
-- map = route_map_lookup_by_name(mapname);
-- if (map == NULL) {
-- vty_out(vty, "%% Could not find route-map %s\n", mapname);
-- return CMD_WARNING_CONFIG_FAILED;
-- }
--
-- /* Lookup route map index. */
-- index = route_map_index_lookup(map, permit, pref);
-- if (index == NULL) {
-- vty_out(vty, "%% Could not find route-map entry %s %s\n",
-- mapname, prefstr);
-- return CMD_WARNING_CONFIG_FAILED;
-- }
--
-- /* Delete index from route map. */
-- route_map_index_delete(index, 1);
--
-- /* If this route rule is the last one, delete route map itself. */
-- if (route_map_empty(map))
-- route_map_delete(map);
--
-- return CMD_SUCCESS;
--}
--
--DEFUN (rmap_onmatch_next,
-- rmap_onmatch_next_cmd,
-- "on-match next",
-- "Exit policy on matches\n"
-- "Next clause\n")
--{
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
--
-- if (index) {
-- if (index->type == RMAP_DENY) {
-- /* Under a deny clause, match means it's finished. No
-- * need to set next */
-- vty_out(vty,
-- "on-match next not supported under route-map deny\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- }
-- index->exitpolicy = RMAP_NEXT;
-- }
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_rmap_onmatch_next,
-- no_rmap_onmatch_next_cmd,
-- "no on-match next",
-- NO_STR
-- "Exit policy on matches\n"
-- "Next clause\n")
--{
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
--
-- if (index)
-- index->exitpolicy = RMAP_EXIT;
--
-- return CMD_SUCCESS;
--}
--
--DEFUN (rmap_onmatch_goto,
-- rmap_onmatch_goto_cmd,
-- "on-match goto (1-65535)",
-- "Exit policy on matches\n"
-- "Goto Clause number\n"
-- "Number\n")
--{
-- int idx = 0;
-- char *num = argv_find(argv, argc, "(1-65535)", &idx) ? argv[idx]->arg
-- : NULL;
--
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-- int d = 0;
--
-- if (index) {
-- if (index->type == RMAP_DENY) {
-- /* Under a deny clause, match means it's finished. No
-- * need to go anywhere */
-- vty_out(vty,
-- "on-match goto not supported under route-map deny\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- }
--
-- if (num)
-- d = strtoul(num, NULL, 10);
-- else
-- d = index->pref + 1;
--
-- if (d <= index->pref) {
-- /* Can't allow you to do that, Dave */
-- vty_out(vty, "can't jump backwards in route-maps\n");
-- return CMD_WARNING_CONFIG_FAILED;
-- } else {
-- index->exitpolicy = RMAP_GOTO;
-- index->nextpref = d;
-- }
-- }
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_rmap_onmatch_goto,
-- no_rmap_onmatch_goto_cmd,
-- "no on-match goto",
-- NO_STR
-- "Exit policy on matches\n"
-- "Goto Clause number\n")
--{
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
--
-- if (index)
-- index->exitpolicy = RMAP_EXIT;
--
-- return CMD_SUCCESS;
--}
--
--/* Cisco/GNU Zebra compatibility aliases */
--/* ALIAS_FIXME */
--DEFUN (rmap_continue,
-- rmap_continue_cmd,
-- "continue (1-65535)",
-- "Continue on a different entry within the route-map\n"
-- "Route-map entry sequence number\n")
--{
-- return rmap_onmatch_goto(self, vty, argc, argv);
--}
--
--/* ALIAS_FIXME */
--DEFUN (no_rmap_continue,
-- no_rmap_continue_cmd,
-- "no continue [(1-65535)]",
-- NO_STR
-- "Continue on a different entry within the route-map\n"
-- "Route-map entry sequence number\n")
--{
-- return no_rmap_onmatch_goto(self, vty, argc, argv);
--}
--
- static void clear_route_map_helper(struct route_map *map)
- {
- struct route_map_index *index;
-@@ -2937,89 +2064,6 @@ DEFUN (rmap_show_unused,
- return vty_show_unused_route_map(vty);
- }
-
--DEFUN (rmap_call,
-- rmap_call_cmd,
-- "call WORD",
-- "Jump to another Route-Map after match+set\n"
-- "Target route-map name\n")
--{
-- int idx_word = 1;
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
-- const char *rmap = argv[idx_word]->arg;
--
-- assert(index);
--
-- /* If "call" is invoked with the same route-map name as
-- * the one previously configured then, ignore the duplicate
-- * configuration.
-- */
-- if (index->nextrm && (strcmp(index->nextrm, rmap) == 0))
-- return CMD_SUCCESS;
--
-- if (index->nextrm) {
-- route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
-- index->nextrm, index->map->name);
-- XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
-- }
-- index->nextrm = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
--
-- /* Execute event hook. */
-- route_map_upd8_dependency(RMAP_EVENT_CALL_ADDED, index->nextrm,
-- index->map->name);
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_rmap_call,
-- no_rmap_call_cmd,
-- "no call",
-- NO_STR
-- "Jump to another Route-Map after match+set\n")
--{
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
--
-- if (index->nextrm) {
-- route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED,
-- index->nextrm, index->map->name);
-- XFREE(MTYPE_ROUTE_MAP_NAME, index->nextrm);
-- index->nextrm = NULL;
-- }
--
-- return CMD_SUCCESS;
--}
--
--DEFUN (rmap_description,
-- rmap_description_cmd,
-- "description LINE...",
-- "Route-map comment\n"
-- "Comment describing this route-map rule\n")
--{
-- int idx_line = 1;
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
--
-- if (index) {
-- if (index->description)
-- XFREE(MTYPE_TMP, index->description);
-- index->description = argv_concat(argv, argc, idx_line);
-- }
-- return CMD_SUCCESS;
--}
--
--DEFUN (no_rmap_description,
-- no_rmap_description_cmd,
-- "no description",
-- NO_STR
-- "Route-map comment\n")
--{
-- struct route_map_index *index = VTY_GET_CONTEXT(route_map_index);
--
-- if (index) {
-- if (index->description)
-- XFREE(MTYPE_TMP, index->description);
-- index->description = NULL;
-- }
-- return CMD_SUCCESS;
--}
--
- DEFUN (debug_rmap,
- debug_rmap_cmd,
- "debug route-map",
-@@ -3045,59 +2089,6 @@ DEFUN (no_debug_rmap,
- static struct cmd_node rmap_debug_node = {RMAP_DEBUG_NODE, "", 1};
-
- /* Configuration write function. */
--static int route_map_config_write(struct vty *vty)
--{
-- struct route_map *map;
-- struct route_map_index *index;
-- struct route_map_rule *rule;
-- int first = 1;
-- int write = 0;
-- struct listnode *ln;
-- struct list *maplist = list_new();
--
-- for (map = route_map_master.head; map; map = map->next)
-- listnode_add(maplist, map);
--
-- list_sort(maplist, sort_route_map);
--
-- for (ALL_LIST_ELEMENTS_RO(maplist, ln, map))
-- for (index = map->head; index; index = index->next) {
-- if (!first)
-- vty_out(vty, "!\n");
-- else
-- first = 0;
--
-- vty_out(vty, "route-map %s %s %d\n", map->name,
-- route_map_type_str(index->type), index->pref);
--
-- if (index->description)
-- vty_out(vty, " description %s\n",
-- index->description);
--
-- for (rule = index->match_list.head; rule;
-- rule = rule->next)
-- vty_out(vty, " match %s %s\n", rule->cmd->str,
-- rule->rule_str ? rule->rule_str : "");
--
-- for (rule = index->set_list.head; rule;
-- rule = rule->next)
-- vty_out(vty, " set %s %s\n", rule->cmd->str,
-- rule->rule_str ? rule->rule_str : "");
-- if (index->nextrm)
-- vty_out(vty, " call %s\n", index->nextrm);
-- if (index->exitpolicy == RMAP_GOTO)
-- vty_out(vty, " on-match goto %d\n",
-- index->nextpref);
-- if (index->exitpolicy == RMAP_NEXT)
-- vty_out(vty, " on-match next\n");
--
-- write++;
-- }
--
-- list_delete(&maplist);
-- return write;
--}
--
- static int rmap_config_write_debug(struct vty *vty)
- {
- int write = 0;
-@@ -3110,9 +2101,6 @@ static int rmap_config_write_debug(struct vty *vty)
- return write;
- }
-
--/* Route map node structure. */
--static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# ", 1};
--
- /* Common route map rules */
-
- void *route_map_rule_tag_compile(const char *arg)
-@@ -3171,14 +2159,6 @@ void route_map_finish(void)
- route_map_master_hash = NULL;
- }
-
--static void rmap_autocomplete(vector comps, struct cmd_token *token)
--{
-- struct route_map *map;
--
-- for (map = route_map_master.head; map; map = map->next)
-- vector_set(comps, XSTRDUP(MTYPE_COMPLETION, map->name));
--}
--
- /* Increment the use_count counter while attaching the route map */
- void route_map_counter_increment(struct route_map *map)
- {
-@@ -3196,14 +2176,6 @@ void route_map_counter_decrement(struct route_map *map)
- }
- }
-
--static const struct cmd_variable_handler rmap_var_handlers[] = {
-- {/* "route-map WORD" */
-- .varname = "route_map",
-- .completions = rmap_autocomplete},
-- {.tokenname = "ROUTEMAP_NAME", .completions = rmap_autocomplete},
-- {.tokenname = "RMAP_NAME", .completions = rmap_autocomplete},
-- {.completions = NULL}};
--
- /* Initialization of route map vector. */
- void route_map_init(void)
- {
-@@ -3221,43 +2193,17 @@ void route_map_init(void)
- 8, route_map_dep_hash_make_key, route_map_dep_hash_cmp,
- "Route Map Dep Hash");
-
-- cmd_variable_handler_register(rmap_var_handlers);
--
- rmap_debug = false;
-
-- /* Install route map top node. */
-- install_node(&rmap_node, route_map_config_write);
-+ route_map_cli_init();
-
-+ /* Install route map top node. */
- install_node(&rmap_debug_node, rmap_config_write_debug);
-
- /* Install route map commands. */
-- install_default(RMAP_NODE);
-- install_element(CONFIG_NODE, &route_map_cmd);
-- install_element(CONFIG_NODE, &no_route_map_cmd);
-- install_element(CONFIG_NODE, &no_route_map_all_cmd);
--
- install_element(CONFIG_NODE, &debug_rmap_cmd);
- install_element(CONFIG_NODE, &no_debug_rmap_cmd);
-
-- /* Install the on-match stuff */
-- install_element(RMAP_NODE, &route_map_cmd);
-- install_element(RMAP_NODE, &rmap_onmatch_next_cmd);
-- install_element(RMAP_NODE, &no_rmap_onmatch_next_cmd);
-- install_element(RMAP_NODE, &rmap_onmatch_goto_cmd);
-- install_element(RMAP_NODE, &no_rmap_onmatch_goto_cmd);
-- install_element(RMAP_NODE, &rmap_continue_cmd);
-- install_element(RMAP_NODE, &no_rmap_continue_cmd);
--
-- /* Install the continue stuff (ALIAS of on-match). */
--
-- /* Install the call stuff. */
-- install_element(RMAP_NODE, &rmap_call_cmd);
-- install_element(RMAP_NODE, &no_rmap_call_cmd);
--
-- /* Install description commands. */
-- install_element(RMAP_NODE, &rmap_description_cmd);
-- install_element(RMAP_NODE, &no_rmap_description_cmd);
--
- /* Install show command */
- install_element(ENABLE_NODE, &rmap_clear_counters_cmd);
-
-@@ -3266,49 +2212,4 @@ void route_map_init(void)
-
- install_element(ENABLE_NODE, &debug_rmap_cmd);
- install_element(ENABLE_NODE, &no_debug_rmap_cmd);
--
-- install_element(RMAP_NODE, &match_interface_cmd);
-- install_element(RMAP_NODE, &no_match_interface_cmd);
--
-- install_element(RMAP_NODE, &match_ip_address_cmd);
-- install_element(RMAP_NODE, &no_match_ip_address_cmd);
--
-- install_element(RMAP_NODE, &match_ip_address_prefix_list_cmd);
-- install_element(RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
--
-- install_element(RMAP_NODE, &match_ip_next_hop_cmd);
-- install_element(RMAP_NODE, &no_match_ip_next_hop_cmd);
--
-- install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
-- install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
--
-- install_element(RMAP_NODE, &match_ip_next_hop_type_cmd);
-- install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd);
--
-- install_element(RMAP_NODE, &match_ipv6_address_cmd);
-- install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
--
-- install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
-- install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
--
-- install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd);
-- install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd);
--
-- install_element(RMAP_NODE, &match_metric_cmd);
-- install_element(RMAP_NODE, &no_match_metric_cmd);
--
-- install_element(RMAP_NODE, &match_tag_cmd);
-- install_element(RMAP_NODE, &no_match_tag_cmd);
--
-- install_element(RMAP_NODE, &set_ip_nexthop_cmd);
-- install_element(RMAP_NODE, &no_set_ip_nexthop_cmd);
--
-- install_element(RMAP_NODE, &set_ipv6_nexthop_local_cmd);
-- install_element(RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
--
-- install_element(RMAP_NODE, &set_metric_cmd);
-- install_element(RMAP_NODE, &no_set_metric_cmd);
--
-- install_element(RMAP_NODE, &set_tag_cmd);
-- install_element(RMAP_NODE, &no_set_tag_cmd);
- }
-diff --git a/lib/routemap.h b/lib/routemap.h
-index d9e7f73f81..70e150c981 100644
---- a/lib/routemap.h
-+++ b/lib/routemap.h
-@@ -666,8 +666,27 @@ int lib_route_map_entry_match_destroy(enum nb_event event,
- const struct lyd_node *dnode);
- int lib_route_map_entry_set_destroy(enum nb_event event,
- const struct lyd_node *dnode);
-+
- extern const struct frr_yang_module_info frr_route_map_info;
-
-+/* routemap_cli.c */
-+extern void route_map_instance_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults);
-+extern void route_map_instance_show_end(struct vty *vty,
-+ struct lyd_node *dnode);
-+extern void route_map_condition_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults);
-+extern void route_map_action_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults);
-+extern void route_map_exit_policy_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults);
-+extern void route_map_call_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults);
-+extern void route_map_description_show(struct vty *vty,
-+ struct lyd_node *dnode,
-+ bool show_defaults);
-+extern void route_map_cli_init(void);
-+
- #ifdef __cplusplus
- }
- #endif
-diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c
-new file mode 100644
-index 0000000000..987693c961
---- /dev/null
-+++ b/lib/routemap_cli.c
-@@ -0,0 +1,1075 @@
-+/*
-+ * Route map northbound CLI implementation.
-+ *
-+ * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
-+ * Rafael Zalamena
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-+ * 02110-1301 USA.
-+ */
-+
-+#include <zebra.h>
-+
-+#include "lib/command.h"
-+#include "lib/northbound_cli.h"
-+#include "lib/routemap.h"
-+
-+#ifndef VTYSH_EXTRACT_PL
-+#include "lib/routemap_cli_clippy.c"
-+#endif /* VTYSH_EXTRACT_PL */
-+
-+#define ROUTE_MAP_CMD_STR \
-+ "Create route-map or enter route-map command mode\n" \
-+ "Route map tag\n"
-+#define ROUTE_MAP_OP_CMD_STR \
-+ "Route map denies set operations\n" \
-+ "Route map permits set operations\n"
-+#define ROUTE_MAP_SEQUENCE_CMD_STR \
-+ "Sequence to insert to/delete from existing route-map entry\n"
-+
-+DEFPY_NOSH(
-+ route_map, route_map_cmd,
-+ "route-map WORD$name <deny|permit>$action (1-65535)$sequence",
-+ ROUTE_MAP_CMD_STR
-+ ROUTE_MAP_OP_CMD_STR
-+ ROUTE_MAP_SEQUENCE_CMD_STR)
-+{
-+ char xpath_action[XPATH_MAXLEN + 64];
-+ char xpath_index[XPATH_MAXLEN + 32];
-+ char xpath[XPATH_MAXLEN];
-+ int rv;
-+
-+ snprintf(xpath, sizeof(xpath),
-+ "/frr-route-map:lib/route-map[name='%s']", name);
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+
-+ snprintf(xpath_index, sizeof(xpath_index), "%s/entry[sequence='%lu']",
-+ xpath, sequence);
-+ nb_cli_enqueue_change(vty, xpath_index, NB_OP_CREATE, NULL);
-+
-+ snprintf(xpath_action, sizeof(xpath_action), "%s/action", xpath_index);
-+ nb_cli_enqueue_change(vty, xpath_action, NB_OP_MODIFY, action);
-+
-+ rv = nb_cli_apply_changes(vty, NULL);
-+ if (rv == CMD_SUCCESS)
-+ VTY_PUSH_XPATH(RMAP_NODE, xpath_index);
-+
-+ return rv;
-+}
-+
-+DEFPY(
-+ no_route_map_all, no_route_map_all_cmd,
-+ "no route-map WORD$name",
-+ NO_STR
-+ ROUTE_MAP_CMD_STR)
-+{
-+ char xpath[XPATH_MAXLEN];
-+
-+ snprintf(xpath, sizeof(xpath),
-+ "/frr-route-map:lib/route-map[name='%s']", name);
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_route_map, no_route_map_cmd,
-+ "no route-map WORD$name <deny|permit>$action (1-65535)$sequence",
-+ NO_STR
-+ ROUTE_MAP_CMD_STR
-+ ROUTE_MAP_OP_CMD_STR
-+ ROUTE_MAP_SEQUENCE_CMD_STR)
-+{
-+ char xpath[XPATH_MAXLEN];
-+
-+ snprintf(xpath, sizeof(xpath),
-+ "/frr-route-map:lib/route-map[name='%s']/entry[sequence='%lu']",
-+ name, sequence);
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+void route_map_instance_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults)
-+{
-+ const char *name = yang_dnode_get_string(dnode, "../name");
-+ const char *action = yang_dnode_get_string(dnode, "./action");
-+ const char *sequence = yang_dnode_get_string(dnode, "./sequence");
-+
-+ vty_out(vty, "route-map %s %s %s\n", name, action, sequence);
-+}
-+
-+void route_map_instance_show_end(struct vty *vty, struct lyd_node *dnode)
-+{
-+ vty_out(vty, "!\n");
-+}
-+
-+DEFPY(
-+ match_interface, match_interface_cmd,
-+ "match interface IFNAME",
-+ MATCH_STR
-+ "Match first hop interface of route\n"
-+ INTERFACE_STR)
-+{
-+ const char *xpath = "./match-condition[condition='interface']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/interface", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, ifname);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_interface, no_match_interface_cmd,
-+ "no match interface [IFNAME]",
-+ NO_STR
-+ MATCH_STR
-+ "Match first hop interface of route\n"
-+ INTERFACE_STR)
-+{
-+ const char *xpath = "./match-condition[condition='interface']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ip_address, match_ip_address_cmd,
-+ "match ip address <(1-199)$acll|(1300-2699)$aclh|WORD$name>",
-+ MATCH_STR
-+ IP_STR
-+ "Match address of route\n"
-+ "IP access-list number\n"
-+ "IP access-list number (expanded range)\n"
-+ "IP Access-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-address-list']";
-+ char xpath_value[XPATH_MAXLEN + 32];
-+ int acln = acll ? acll : aclh;
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ if (name) {
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/list-name",
-+ xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
-+ } else /* if (acll || aclh) */ {
-+ if ((acln >= 1 && acln <= 99)
-+ || (acln >= 1300 && acln <= 1999)) {
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/access-list-num", xpath);
-+ } else {
-+ /*
-+ * if ((acln >= 100 && acln <= 199)
-+ * || (acln >= 2000 && acln <= 2699))
-+ */
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/access-list-num-extended", xpath);
-+ }
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
-+ acll_str ? acll_str : aclh_str);
-+ }
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ip_address, no_match_ip_address_cmd,
-+ "no match ip address [<(1-199)|(1300-2699)|WORD>]",
-+ NO_STR
-+ MATCH_STR
-+ IP_STR
-+ "Match address of route\n"
-+ "IP access-list number\n"
-+ "IP access-list number (expanded range)\n"
-+ "IP Access-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-address-list']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ip_address_prefix_list,
-+ match_ip_address_prefix_list_cmd,
-+ "match ip address prefix-list WORD$name",
-+ MATCH_STR
-+ IP_STR
-+ "Match address of route\n"
-+ "Match entries of prefix-lists\n"
-+ "IP prefix-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-prefix-list']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ip_address_prefix_list, no_match_ip_address_prefix_list_cmd,
-+ "no match ip address prefix-list [WORD]",
-+ NO_STR
-+ MATCH_STR
-+ IP_STR
-+ "Match address of route\n"
-+ "Match entries of prefix-lists\n"
-+ "IP prefix-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-prefix-list']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ip_next_hop, match_ip_next_hop_cmd,
-+ "match ip next-hop <(1-199)$acll|(1300-2699)$aclh|WORD$name>",
-+ MATCH_STR
-+ IP_STR
-+ "Match next-hop address of route\n"
-+ "IP access-list number\n"
-+ "IP access-list number (expanded range)\n"
-+ "IP Access-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-next-hop-list']";
-+ char xpath_value[XPATH_MAXLEN + 32];
-+ int acln = acll ? acll : aclh;
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ if (name) {
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/list-name",
-+ xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
-+ } else /* if (acll || aclh) */ {
-+ if ((acln >= 1 && acln <= 99)
-+ || (acln >= 1300 && acln <= 1999)) {
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/access-list-num", xpath);
-+ } else {
-+ /*
-+ * if ((acln >= 100 && acln <= 199)
-+ * || (acln >= 2000 && acln <= 2699))
-+ */
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/access-list-num-extended", xpath);
-+ }
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
-+ acll_str ? acll_str : aclh_str);
-+ }
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ip_next_hop, no_match_ip_next_hop_cmd,
-+ "no match ip next-hop [<(1-199)|(1300-2699)|WORD>]",
-+ NO_STR
-+ MATCH_STR
-+ IP_STR
-+ "Match address of route\n"
-+ "IP access-list number\n"
-+ "IP access-list number (expanded range)\n"
-+ "IP Access-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-next-hop-list']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ip_next_hop_prefix_list,
-+ match_ip_next_hop_prefix_list_cmd,
-+ "match ip next-hop prefix-list WORD$name",
-+ MATCH_STR
-+ IP_STR
-+ "Match next-hop address of route\n"
-+ "Match entries of prefix-lists\n"
-+ "IP prefix-list name\n")
-+{
-+ const char *xpath =
-+ "./match-condition[condition='ipv4-next-hop-prefix-list']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ip_next_hop_prefix_list,
-+ no_match_ip_next_hop_prefix_list_cmd,
-+ "no match ip next-hop prefix-list [WORD]",
-+ NO_STR
-+ MATCH_STR
-+ IP_STR
-+ "Match next-hop address of route\n"
-+ "Match entries of prefix-lists\n"
-+ "IP prefix-list name\n")
-+{
-+ const char *xpath =
-+ "./match-condition[condition='ipv4-next-hop-prefix-list']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ip_next_hop_type, match_ip_next_hop_type_cmd,
-+ "match ip next-hop type <blackhole>$type",
-+ MATCH_STR
-+ IP_STR
-+ "Match next-hop address of route\n"
-+ "Match entries by type\n"
-+ "Blackhole\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-next-hop-type']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/ipv4-next-hop-type",
-+ xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, type);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ip_next_hop_type, no_match_ip_next_hop_type_cmd,
-+ "no match ip next-hop type [<blackhole>]",
-+ NO_STR MATCH_STR IP_STR
-+ "Match next-hop address of route\n"
-+ "Match entries by type\n"
-+ "Blackhole\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv4-next-hop-type']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ipv6_address, match_ipv6_address_cmd,
-+ "match ipv6 address WORD$name",
-+ MATCH_STR
-+ IPV6_STR
-+ "Match IPv6 address of route\n"
-+ "IPv6 access-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv6-address-list']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ipv6_address, no_match_ipv6_address_cmd,
-+ "no match ipv6 address [WORD]",
-+ NO_STR
-+ MATCH_STR
-+ IPV6_STR
-+ "Match IPv6 address of route\n"
-+ "IPv6 access-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv6-address-list']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ipv6_address_prefix_list, match_ipv6_address_prefix_list_cmd,
-+ "match ipv6 address prefix-list WORD$name",
-+ MATCH_STR
-+ IPV6_STR
-+ "Match address of route\n"
-+ "Match entries of prefix-lists\n"
-+ "IP prefix-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv6-prefix-list']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ipv6_address_prefix_list,
-+ no_match_ipv6_address_prefix_list_cmd,
-+ "no match ipv6 address prefix-list [WORD]",
-+ NO_STR
-+ MATCH_STR
-+ IPV6_STR
-+ "Match address of route\n"
-+ "Match entries of prefix-lists\n"
-+ "IP prefix-list name\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv6-prefix-list']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_ipv6_next_hop_type, match_ipv6_next_hop_type_cmd,
-+ "match ipv6 next-hop type <blackhole>$type",
-+ MATCH_STR IPV6_STR
-+ "Match next-hop address of route\n"
-+ "Match entries by type\n"
-+ "Blackhole\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv6-next-hop-type']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/ipv6-next-hop-type",
-+ xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, type);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_ipv6_next_hop_type, no_match_ipv6_next_hop_type_cmd,
-+ "no match ipv6 next-hop type [<blackhole>]",
-+ NO_STR MATCH_STR IPV6_STR
-+ "Match address of route\n"
-+ "Match entries by type\n"
-+ "Blackhole\n")
-+{
-+ const char *xpath = "./match-condition[condition='ipv6-next-hop-type']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_metric, match_metric_cmd,
-+ "match metric (0-4294967295)$metric",
-+ MATCH_STR
-+ "Match metric of route\n"
-+ "Metric value\n")
-+{
-+ const char *xpath = "./match-condition[condition='metric']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/metric", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, metric_str);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_metric, no_match_metric_cmd,
-+ "no match metric [(0-4294967295)]",
-+ NO_STR
-+ MATCH_STR
-+ "Match metric of route\n"
-+ "Metric value\n")
-+{
-+ const char *xpath = "./match-condition[condition='metric']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ match_tag, match_tag_cmd,
-+ "match tag (1-4294967295)$tag",
-+ MATCH_STR
-+ "Match tag of route\n"
-+ "Tag value\n")
-+{
-+ const char *xpath = "./match-condition[condition='tag']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/tag", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_match_tag, no_match_tag_cmd,
-+ "no match tag [(1-4294967295)]",
-+ NO_STR
-+ MATCH_STR
-+ "Match tag of route\n"
-+ "Tag value\n")
-+{
-+ const char *xpath = "./match-condition[condition='tag']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+void route_map_condition_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults)
-+{
-+ int condition = yang_dnode_get_enum(dnode, "./condition");
-+ struct lyd_node *ln;
-+ const char *acl;
-+
-+ switch (condition) {
-+ case 0: /* interface */
-+ vty_out(vty, " match interface %s\n",
-+ yang_dnode_get_string(dnode, "./interface"));
-+ break;
-+ case 1: /* ipv4-address-list */
-+ case 3: /* ipv4-next-hop-list */
-+ acl = NULL;
-+ if ((ln = yang_dnode_get(dnode, "./list-name")) != NULL)
-+ acl = yang_dnode_get_string(ln, NULL);
-+ else if ((ln = yang_dnode_get(dnode, "./access-list-num"))
-+ != NULL)
-+ acl = yang_dnode_get_string(ln, NULL);
-+ else if ((ln = yang_dnode_get(dnode,
-+ "./access-list-num-extended"))
-+ != NULL)
-+ acl = yang_dnode_get_string(ln, NULL);
-+
-+ assert(acl);
-+
-+ switch (condition) {
-+ case 1:
-+ vty_out(vty, " match ip address %s\n", acl);
-+ break;
-+ case 3:
-+ vty_out(vty, " match ip next-hop %s\n", acl);
-+ break;
-+ }
-+ break;
-+ case 2: /* ipv4-prefix-list */
-+ vty_out(vty, " match ip address prefix-list %s\n",
-+ yang_dnode_get_string(dnode, "./list-name"));
-+ break;
-+ case 4: /* ipv4-next-hop-prefix-list */
-+ vty_out(vty, " match ip next-hop prefix-list %s\n",
-+ yang_dnode_get_string(dnode, "./list-name"));
-+ break;
-+ case 5: /* ipv4-next-hop-type */
-+ vty_out(vty, " match ip next-hop type %s\n",
-+ yang_dnode_get_string(dnode, "./ipv4-next-hop-type"));
-+ break;
-+ case 6: /* ipv6-address-list */
-+ vty_out(vty, " match ipv6 address %s\n",
-+ yang_dnode_get_string(dnode, "./list-name"));
-+ break;
-+ case 7: /* ipv6-prefix-list */
-+ vty_out(vty, " match ipv6 address prefix-list %s\n",
-+ yang_dnode_get_string(dnode, "./list-name"));
-+ break;
-+ case 8: /* ipv6-next-hop-type */
-+ vty_out(vty, " match ipv6 next-hop type %s\n",
-+ yang_dnode_get_string(dnode, "./ipv6-next-hop-type"));
-+ break;
-+ case 9: /* metric */
-+ vty_out(vty, " match metric %s\n",
-+ yang_dnode_get_string(dnode, "./metric"));
-+ break;
-+ case 10: /* tag */
-+ vty_out(vty, " match tag %s\n",
-+ yang_dnode_get_string(dnode, "./tag"));
-+ break;
-+ case 100:
-+ /* NOTHING: custom field, should be handled by daemon. */
-+ break;
-+ }
-+}
-+
-+DEFPY(
-+ set_ip_nexthop, set_ip_nexthop_cmd,
-+ "set ip next-hop A.B.C.D$addr",
-+ SET_STR
-+ IP_STR
-+ "Next hop address\n"
-+ "IP address of next hop\n")
-+{
-+ const char *xpath = "./set-action[action='ipv4-next-hop']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/ipv4-address", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, addr_str);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_set_ip_nexthop, no_set_ip_nexthop_cmd,
-+ "no set ip next-hop [A.B.C.D]",
-+ NO_STR
-+ SET_STR
-+ IP_STR
-+ "Next hop address\n"
-+ "IP address of next hop\n")
-+{
-+ const char *xpath = "./set-action[action='ipv4-next-hop']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ set_ipv6_nexthop_local, set_ipv6_nexthop_local_cmd,
-+ "set ipv6 next-hop local X:X::X:X$addr",
-+ SET_STR
-+ IPV6_STR
-+ "IPv6 next-hop address\n"
-+ "IPv6 local address\n"
-+ "IPv6 address of next hop\n")
-+{
-+ const char *xpath = "./set-action[action='ipv6-next-hop']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/ipv6-address", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, addr_str);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_set_ipv6_nexthop_local, no_set_ipv6_nexthop_local_cmd,
-+ "no set ipv6 next-hop local [X:X::X:X]",
-+ NO_STR
-+ SET_STR
-+ IPV6_STR
-+ "IPv6 next-hop address\n"
-+ "IPv6 local address\n"
-+ "IPv6 address of next hop\n")
-+{
-+ const char *xpath = "./set-action[action='ipv6-next-hop']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ set_metric, set_metric_cmd,
-+ "set metric <(0-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt|+metric$ametric|-metric$smetric>",
-+ SET_STR
-+ "Metric value for destination routing protocol\n"
-+ "Metric value\n"
-+ "Assign round trip time\n"
-+ "Add round trip time\n"
-+ "Subtract round trip time\n"
-+ "Add metric\n"
-+ "Subtract metric\n")
-+{
-+ const char *xpath = "./set-action[action='metric']";
-+ char xpath_value[XPATH_MAXLEN];
-+ char value[64];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ if (rtt) {
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/use-round-trip-time", xpath);
-+ snprintf(value, sizeof(value), "true");
-+ } else if (artt) {
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/add-round-trip-time", xpath);
-+ snprintf(value, sizeof(value), "true");
-+ } else if (srtt) {
-+ snprintf(xpath_value, sizeof(xpath_value),
-+ "%s/subtract-round-trip-time", xpath);
-+ snprintf(value, sizeof(value), "true");
-+ } else if (ametric) {
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/add-metric",
-+ xpath);
-+ snprintf(value, sizeof(value), "true");
-+ } else if (smetric) {
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/subtract-metric",
-+ xpath);
-+ snprintf(value, sizeof(value), "true");
-+ } else {
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/value", xpath);
-+ snprintf(value, sizeof(value), "%lu", metric);
-+ }
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_set_metric, no_set_metric_cmd,
-+ "no set metric [(0-4294967295)]",
-+ NO_STR
-+ SET_STR
-+ "Metric value for destination routing protocol\n"
-+ "Metric value\n")
-+{
-+ const char *xpath = "./set-action[action='metric']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ set_tag, set_tag_cmd,
-+ "set tag (1-4294967295)$tag",
-+ SET_STR
-+ "Tag value for routing protocol\n"
-+ "Tag value\n")
-+{
-+ const char *xpath = "./set-action[action='tag']";
-+ char xpath_value[XPATH_MAXLEN];
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
-+ snprintf(xpath_value, sizeof(xpath_value), "%s/tag", xpath);
-+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_set_tag, no_set_tag_cmd,
-+ "no set tag [(1-4294967295)]",
-+ NO_STR
-+ SET_STR
-+ "Tag value for routing protocol\n"
-+ "Tag value\n")
-+{
-+ const char *xpath = "./set-action[action='tag']";
-+
-+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+void route_map_action_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults)
-+{
-+ int action = yang_dnode_get_enum(dnode, "./action");
-+
-+ switch (action) {
-+ case 0: /* ipv4-next-hop */
-+ vty_out(vty, " set ip next-hop %s\n",
-+ yang_dnode_get_string(dnode, "./ipv4-address"));
-+ break;
-+ case 1: /* ipv6-next-hop */
-+ vty_out(vty, " set ipv6 next-hop local %s\n",
-+ yang_dnode_get_string(dnode, "./ipv6-address"));
-+ break;
-+ case 2: /* metric */
-+ if (yang_dnode_get(dnode, "./use-round-trip-time")) {
-+ vty_out(vty, " set metric rtt\n");
-+ } else if (yang_dnode_get(dnode, "./add-round-trip-time")) {
-+ vty_out(vty, " set metric +rtt\n");
-+ } else if (yang_dnode_get(dnode, "./subtract-round-trip-time")) {
-+ vty_out(vty, " set metric -rtt\n");
-+ } else if (yang_dnode_get(dnode, "./add-metric")) {
-+ vty_out(vty, " set metric +metric\n");
-+ } else if (yang_dnode_get(dnode, "./subtract-metric")) {
-+ vty_out(vty, " set metric -metric\n");
-+ } else {
-+ vty_out(vty, " set metric %s\n",
-+ yang_dnode_get_string(dnode, "./value"));
-+ }
-+ break;
-+ case 3: /* tag */
-+ vty_out(vty, " set tag %s\n",
-+ yang_dnode_get_string(dnode, "./tag"));
-+ break;
-+ case 100:
-+ /* NOTHING: custom field, should be handled by daemon. */
-+ break;
-+ }
-+}
-+
-+DEFPY(
-+ rmap_onmatch_next, rmap_onmatch_next_cmd,
-+ "on-match next",
-+ "Exit policy on matches\n"
-+ "Next clause\n")
-+{
-+ nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_MODIFY, "next");
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_rmap_onmatch_next,
-+ no_rmap_onmatch_next_cmd,
-+ "no on-match next",
-+ NO_STR
-+ "Exit policy on matches\n"
-+ "Next clause\n")
-+{
-+ nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ rmap_onmatch_goto, rmap_onmatch_goto_cmd,
-+ "on-match goto (1-65535)$rm_num",
-+ "Exit policy on matches\n"
-+ "Goto Clause number\n"
-+ "Number\n")
-+{
-+ nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_MODIFY, "goto");
-+ nb_cli_enqueue_change(vty, "./goto-value", NB_OP_MODIFY, rm_num_str);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_rmap_onmatch_goto, no_rmap_onmatch_goto_cmd,
-+ "no on-match goto",
-+ NO_STR
-+ "Exit policy on matches\n"
-+ "Goto Clause number\n")
-+{
-+ nb_cli_enqueue_change(vty, "./exit-policy", NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+/* Cisco/GNU Zebra compatibility aliases */
-+ALIAS(
-+ rmap_onmatch_goto, rmap_continue_cmd,
-+ "continue (1-65535)$rm_num",
-+ "Continue on a different entry within the route-map\n"
-+ "Route-map entry sequence number\n")
-+
-+ALIAS(
-+ no_rmap_onmatch_goto, no_rmap_continue_cmd,
-+ "no continue [(1-65535)]",
-+ NO_STR
-+ "Continue on a different entry within the route-map\n"
-+ "Route-map entry sequence number\n")
-+
-+void route_map_exit_policy_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults)
-+{
-+ int exit_policy = yang_dnode_get_enum(dnode, NULL);
-+
-+ switch (exit_policy) {
-+ case 0: /* permit-or-deny */
-+ /* NOTHING: default option. */
-+ break;
-+ case 1: /* next */
-+ vty_out(vty, " on-match next\n");
-+ break;
-+ case 2: /* goto */
-+ vty_out(vty, " on-match goto %s\n",
-+ yang_dnode_get_string(dnode, "../goto-value"));
-+ break;
-+ }
-+}
-+
-+DEFPY(
-+ rmap_call, rmap_call_cmd,
-+ "call WORD$name",
-+ "Jump to another Route-Map after match+set\n"
-+ "Target route-map name\n")
-+{
-+ nb_cli_enqueue_change(vty, "./call", NB_OP_MODIFY, name);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+DEFPY(
-+ no_rmap_call, no_rmap_call_cmd,
-+ "no call",
-+ NO_STR
-+ "Jump to another Route-Map after match+set\n")
-+{
-+ nb_cli_enqueue_change(vty, "./call", NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+void route_map_call_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults)
-+{
-+ vty_out(vty, " call %s\n", yang_dnode_get_string(dnode, NULL));
-+}
-+
-+DEFPY(
-+ rmap_description, rmap_description_cmd,
-+ "description LINE...",
-+ "Route-map comment\n"
-+ "Comment describing this route-map rule\n")
-+{
-+ char *desc;
-+ int rv;
-+
-+ desc = argv_concat(argv, argc, 1);
-+ nb_cli_enqueue_change(vty, "./description", NB_OP_MODIFY, desc);
-+ rv = nb_cli_apply_changes(vty, NULL);
-+ XFREE(MTYPE_TMP, desc);
-+
-+ return rv;
-+}
-+
-+DEFUN (no_rmap_description,
-+ no_rmap_description_cmd,
-+ "no description",
-+ NO_STR
-+ "Route-map comment\n")
-+{
-+ nb_cli_enqueue_change(vty, "./description", NB_OP_DESTROY, NULL);
-+
-+ return nb_cli_apply_changes(vty, NULL);
-+}
-+
-+void route_map_description_show(struct vty *vty, struct lyd_node *dnode,
-+ bool show_defaults)
-+{
-+ vty_out(vty, " description %s\n", yang_dnode_get_string(dnode, NULL));
-+}
-+
-+static int route_map_config_write(struct vty *vty)
-+{
-+ struct lyd_node *dnode;
-+ int written = 0;
-+
-+ dnode = yang_dnode_get(running_config->dnode,
-+ "/frr-route-map:lib");
-+ if (dnode) {
-+ nb_cli_show_dnode_cmds(vty, dnode, false);
-+ written = 1;
-+ }
-+
-+ return written;
-+}
-+
-+/* Route map node structure. */
-+static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# ", 1};
-+
-+static void rmap_autocomplete(vector comps, struct cmd_token *token)
-+{
-+ struct route_map *map;
-+
-+ for (map = route_map_master.head; map; map = map->next)
-+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION, map->name));
-+}
-+
-+static const struct cmd_variable_handler rmap_var_handlers[] = {
-+ {.varname = "route_map", .completions = rmap_autocomplete},
-+ {.tokenname = "ROUTEMAP_NAME", .completions = rmap_autocomplete},
-+ {.tokenname = "RMAP_NAME", .completions = rmap_autocomplete},
-+ {.completions = NULL}
-+};
-+
-+void route_map_cli_init(void)
-+{
-+ /* Auto complete handler. */
-+ cmd_variable_handler_register(rmap_var_handlers);
-+
-+ /* CLI commands. */
-+ install_node(&rmap_node, route_map_config_write);
-+ install_default(RMAP_NODE);
-+ install_element(CONFIG_NODE, &route_map_cmd);
-+ install_element(CONFIG_NODE, &no_route_map_cmd);
-+ install_element(CONFIG_NODE, &no_route_map_all_cmd);
-+
-+ /* Install the on-match stuff */
-+ install_element(RMAP_NODE, &route_map_cmd);
-+ install_element(RMAP_NODE, &rmap_onmatch_next_cmd);
-+ install_element(RMAP_NODE, &no_rmap_onmatch_next_cmd);
-+ install_element(RMAP_NODE, &rmap_onmatch_goto_cmd);
-+ install_element(RMAP_NODE, &no_rmap_onmatch_goto_cmd);
-+ install_element(RMAP_NODE, &rmap_continue_cmd);
-+ install_element(RMAP_NODE, &no_rmap_continue_cmd);
-+
-+ /* Install the call stuff. */
-+ install_element(RMAP_NODE, &rmap_call_cmd);
-+ install_element(RMAP_NODE, &no_rmap_call_cmd);
-+
-+ /* Install description commands. */
-+ install_element(RMAP_NODE, &rmap_description_cmd);
-+ install_element(RMAP_NODE, &no_rmap_description_cmd);
-+
-+ /* Install 'match' commands. */
-+ install_element(RMAP_NODE, &match_interface_cmd);
-+ install_element(RMAP_NODE, &no_match_interface_cmd);
-+
-+ install_element(RMAP_NODE, &match_ip_address_cmd);
-+ install_element(RMAP_NODE, &no_match_ip_address_cmd);
-+
-+ install_element(RMAP_NODE, &match_ip_address_prefix_list_cmd);
-+ install_element(RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
-+
-+ install_element(RMAP_NODE, &match_ip_next_hop_cmd);
-+ install_element(RMAP_NODE, &no_match_ip_next_hop_cmd);
-+
-+ install_element(RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
-+ install_element(RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
-+
-+ install_element(RMAP_NODE, &match_ip_next_hop_type_cmd);
-+ install_element(RMAP_NODE, &no_match_ip_next_hop_type_cmd);
-+
-+ install_element(RMAP_NODE, &match_ipv6_address_cmd);
-+ install_element(RMAP_NODE, &no_match_ipv6_address_cmd);
-+
-+ install_element(RMAP_NODE, &match_ipv6_address_prefix_list_cmd);
-+ install_element(RMAP_NODE, &no_match_ipv6_address_prefix_list_cmd);
-+
-+ install_element(RMAP_NODE, &match_ipv6_next_hop_type_cmd);
-+ install_element(RMAP_NODE, &no_match_ipv6_next_hop_type_cmd);
-+
-+ install_element(RMAP_NODE, &match_metric_cmd);
-+ install_element(RMAP_NODE, &no_match_metric_cmd);
-+
-+ install_element(RMAP_NODE, &match_tag_cmd);
-+ install_element(RMAP_NODE, &no_match_tag_cmd);
-+
-+ /* Install 'set' commands. */
-+ install_element(RMAP_NODE, &set_ip_nexthop_cmd);
-+ install_element(RMAP_NODE, &no_set_ip_nexthop_cmd);
-+
-+ install_element(RMAP_NODE, &set_ipv6_nexthop_local_cmd);
-+ install_element(RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
-+
-+ install_element(RMAP_NODE, &set_metric_cmd);
-+ install_element(RMAP_NODE, &no_set_metric_cmd);
-+
-+ install_element(RMAP_NODE, &set_tag_cmd);
-+ install_element(RMAP_NODE, &no_set_tag_cmd);
-+}
-diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
-index 02eb756334..b9ac01e865 100644
---- a/lib/routemap_northbound.c
-+++ b/lib/routemap_northbound.c
-@@ -1218,6 +1218,8 @@ const struct frr_yang_module_info frr_route_map_info = {
- .cbs = {
- .create = lib_route_map_entry_create,
- .destroy = lib_route_map_entry_destroy,
-+ .cli_show = route_map_instance_show,
-+ .cli_show_end = route_map_instance_show_end,
- }
- },
- {
-@@ -1225,6 +1227,7 @@ const struct frr_yang_module_info frr_route_map_info = {
- .cbs = {
- .modify = lib_route_map_entry_description_modify,
- .destroy = lib_route_map_entry_description_destroy,
-+ .cli_show = route_map_description_show,
- }
- },
- {
-@@ -1238,12 +1241,14 @@ const struct frr_yang_module_info frr_route_map_info = {
- .cbs = {
- .modify = lib_route_map_entry_call_modify,
- .destroy = lib_route_map_entry_call_destroy,
-+ .cli_show = route_map_call_show,
- }
- },
- {
- .xpath = "/frr-route-map:lib/route-map/entry/exit-policy",
- .cbs = {
- .modify = lib_route_map_entry_exit_policy_modify,
-+ .cli_show = route_map_exit_policy_show,
- }
- },
- {
-@@ -1258,6 +1263,7 @@ const struct frr_yang_module_info frr_route_map_info = {
- .cbs = {
- .create = lib_route_map_entry_match_condition_create,
- .destroy = lib_route_map_entry_match_condition_destroy,
-+ .cli_show = route_map_condition_show,
- }
- },
- {
-@@ -1321,6 +1327,7 @@ const struct frr_yang_module_info frr_route_map_info = {
- .cbs = {
- .create = lib_route_map_entry_set_action_create,
- .destroy = lib_route_map_entry_set_action_destroy,
-+ .cli_show = route_map_action_show,
- }
- },
- {
-diff --git a/lib/subdir.am b/lib/subdir.am
-index 94b3d933ac..ffac721256 100644
---- a/lib/subdir.am
-+++ b/lib/subdir.am
-@@ -71,6 +71,7 @@ lib_libfrr_la_SOURCES = \
- lib/qobj.c \
- lib/ringbuf.c \
- lib/routemap.c \
-+ lib/routemap_cli.c \
- lib/routemap_northbound.c \
- lib/sbuf.c \
- lib/seqlock.c \
-@@ -122,6 +123,7 @@ vtysh_scan += \
- $(top_srcdir)/lib/nexthop_group.c \
- $(top_srcdir)/lib/plist.c \
- $(top_srcdir)/lib/routemap.c \
-+ $(top_srcdir)/lib/routemap_cli.c \
- $(top_srcdir)/lib/vrf.c \
- $(top_srcdir)/lib/vty.c \
- # end
-@@ -141,6 +143,8 @@ lib/nexthop_group_clippy.c: $(CLIPPY_DEPS)
- lib/nexthop_group.lo: lib/nexthop_group_clippy.c
- lib/northbound_cli_clippy.c: $(CLIPPY_DEPS)
- lib/northbound_cli.lo: lib/northbound_cli_clippy.c
-+lib/routemap_cli_clippy.c: $(CLIPPY_DEPS)
-+lib/routemap_cli.lo: lib/routemap_cli_clippy.c
- lib/vty_clippy.c: $(CLIPPY_DEPS)
- lib/vty.lo: lib/vty_clippy.c
- lib/log_vty_clippy.c: $(CLIPPY_DEPS)
-diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in
-index 13413888bf..b7ac0abe02 100755
---- a/vtysh/extract.pl.in
-+++ b/vtysh/extract.pl.in
-@@ -87,7 +87,7 @@ sub scan_file {
- if ($file =~ /lib\/keychain\.c$/) {
- $protocol = "VTYSH_RIPD|VTYSH_EIGRPD";
- }
-- elsif ($file =~ /lib\/routemap\.c$/) {
-+ elsif ($file =~ /lib\/routemap\.c$/ || $file =~ /lib\/routemap_cli\.c$/) {
- $protocol = "VTYSH_RMAP";
- }
- elsif ($file =~ /lib\/vrf\.c$/) {
-
-From a513824c343971e51603471948c958430b602371 Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Tue, 1 Oct 2019 17:56:16 -0300
-Subject: [PATCH 05/10] yang/lib: add filter model to code
-
-This fixes a warning on daemons that use route map about filter yang
-model not being included in the binary.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/subdir.am | 1 +
- yang/subdir.am | 1 +
- 2 files changed, 2 insertions(+)
-
-diff --git a/lib/subdir.am b/lib/subdir.am
-index ffac721256..4f62eb2264 100644
---- a/lib/subdir.am
-+++ b/lib/subdir.am
-@@ -106,6 +106,7 @@ lib_libfrr_la_SOURCES = \
- # end
-
- nodist_lib_libfrr_la_SOURCES = \
-+ yang/frr-filter.yang.c \
- yang/frr-interface.yang.c \
- yang/frr-route-map.yang.c \
- yang/frr-route-types.yang.c \
-diff --git a/yang/subdir.am b/yang/subdir.am
-index 7a15a6a309..c1297dafd5 100644
---- a/yang/subdir.am
-+++ b/yang/subdir.am
-@@ -19,6 +19,7 @@ EXTRA_DIST += yang/embedmodel.py
- # global symbols :(. Just put it in the daemon. Dynamic libraries.so work
- # without problems, as seen in libfrr.
-
-+dist_yangmodels_DATA += yang/frr-filter.yang
- dist_yangmodels_DATA += yang/frr-module-translator.yang
- dist_yangmodels_DATA += yang/frr-test-module.yang
- dist_yangmodels_DATA += yang/frr-interface.yang
-
-From a162869ef0798ef98d756238c6b89108a69f5a5d Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Mon, 30 Sep 2019 15:02:15 -0300
-Subject: [PATCH 06/10] lib: fix route map generic error output
-
-Two fixes here:
-
-* Don't attempt to use `vty` pointer in vty;
-* When `vty` is unavailable output to log;
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap.c | 68 ++++++++++++++++++++++++++++++++++----------------
- 1 file changed, 46 insertions(+), 22 deletions(-)
-
-diff --git a/lib/routemap.c b/lib/routemap.c
-index e07ad08123..5369fa771f 100644
---- a/lib/routemap.c
-+++ b/lib/routemap.c
-@@ -308,15 +308,21 @@ int generic_match_add(struct vty *vty, struct route_map_index *index,
- ret = route_map_add_match(index, command, arg, type);
- switch (ret) {
- case RMAP_RULE_MISSING:
-- vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
-+ if (vty)
-+ vty_out(vty, "%% [%s] Can't find rule.\n",
-+ frr_protonameinst);
-+ else
-+ zlog_warn("Can't find rule: %s", command);
- return CMD_WARNING_CONFIG_FAILED;
-- break;
- case RMAP_COMPILE_ERROR:
-- vty_out(vty,
-- "%% [%s] Argument form is unsupported or malformed.\n",
-- frr_protonameinst);
-+ if (vty)
-+ vty_out(vty,
-+ "%% [%s] Argument form is unsupported or malformed.\n",
-+ frr_protonameinst);
-+ else
-+ zlog_warn("Argument form is unsupported or malformed: "
-+ "%s %s", command, arg);
- return CMD_WARNING_CONFIG_FAILED;
-- break;
- case RMAP_COMPILE_SUCCESS:
- /*
- * Nothing to do here move along
-@@ -353,13 +359,21 @@ int generic_match_delete(struct vty *vty, struct route_map_index *index,
- ret = route_map_delete_match(index, command, dep_name, type);
- switch (ret) {
- case RMAP_RULE_MISSING:
-- vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
-+ if (vty)
-+ vty_out(vty, "%% [%s] Can't find rule.\n",
-+ frr_protonameinst);
-+ else
-+ zlog_warn("Can't find rule: %s", command);
- retval = CMD_WARNING_CONFIG_FAILED;
- break;
- case RMAP_COMPILE_ERROR:
-- vty_out(vty,
-- "%% [%s] Argument form is unsupported or malformed.\n",
-- frr_protonameinst);
-+ if (vty)
-+ vty_out(vty,
-+ "%% [%s] Argument form is unsupported or malformed.\n",
-+ frr_protonameinst);
-+ else
-+ zlog_warn("Argument form is unsupported or malformed: "
-+ "%s %s", command, arg);
- retval = CMD_WARNING_CONFIG_FAILED;
- break;
- case RMAP_COMPILE_SUCCESS:
-@@ -383,15 +397,20 @@ int generic_set_add(struct vty *vty, struct route_map_index *index,
- ret = route_map_add_set(index, command, arg);
- switch (ret) {
- case RMAP_RULE_MISSING:
-- vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
-+ if (vty)
-+ vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
-+ else
-+ zlog_warn("Can't find rule: %s", command);
- return CMD_WARNING_CONFIG_FAILED;
-- break;
- case RMAP_COMPILE_ERROR:
-- vty_out(vty,
-- "%% [%s] Argument form is unsupported or malformed.\n",
-- frr_protonameinst);
-+ if (vty)
-+ vty_out(vty,
-+ "%% [%s] Argument form is unsupported or malformed.\n",
-+ frr_protonameinst);
-+ else
-+ zlog_warn("Argument form is unsupported or malformed: "
-+ "%s %s", command, arg);
- return CMD_WARNING_CONFIG_FAILED;
-- break;
- case RMAP_COMPILE_SUCCESS:
- break;
- }
-@@ -407,15 +426,20 @@ int generic_set_delete(struct vty *vty, struct route_map_index *index,
- ret = route_map_delete_set(index, command, arg);
- switch (ret) {
- case RMAP_RULE_MISSING:
-- vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
-+ if (vty)
-+ vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst);
-+ else
-+ zlog_warn("Can't find rule: %s", command);
- return CMD_WARNING_CONFIG_FAILED;
-- break;
- case RMAP_COMPILE_ERROR:
-- vty_out(vty,
-- "%% [%s] Argument form is unsupported or malformed.\n",
-- frr_protonameinst);
-+ if (vty)
-+ vty_out(vty,
-+ "%% [%s] Argument form is unsupported or malformed.\n",
-+ frr_protonameinst);
-+ else
-+ zlog_warn("Argument form is unsupported or malformed: "
-+ "%s %s", command, arg);
- return CMD_WARNING_CONFIG_FAILED;
-- break;
- case RMAP_COMPILE_SUCCESS:
- break;
- }
-
-From e324ef433ca611ddf8274015c0b36c8de1fb3075 Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Tue, 1 Oct 2019 15:52:51 -0300
-Subject: [PATCH 07/10] lib: add backward compatibility for route map
-
-Allow old CLI users to still print their configuration without migrating
-to northbound.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap_cli.c | 56 +++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 55 insertions(+), 1 deletion(-)
-
-diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c
-index 987693c961..7023710564 100644
---- a/lib/routemap_cli.c
-+++ b/lib/routemap_cli.c
-@@ -46,6 +46,9 @@ DEFPY_NOSH(
- ROUTE_MAP_OP_CMD_STR
- ROUTE_MAP_SEQUENCE_CMD_STR)
- {
-+ struct route_map_index *rmi;
-+ struct route_map *rm;
-+ int action_type;
- char xpath_action[XPATH_MAXLEN + 64];
- char xpath_index[XPATH_MAXLEN + 32];
- char xpath[XPATH_MAXLEN];
-@@ -63,9 +66,16 @@ DEFPY_NOSH(
- nb_cli_enqueue_change(vty, xpath_action, NB_OP_MODIFY, action);
-
- rv = nb_cli_apply_changes(vty, NULL);
-- if (rv == CMD_SUCCESS)
-+ if (rv == CMD_SUCCESS) {
- VTY_PUSH_XPATH(RMAP_NODE, xpath_index);
-
-+ /* Add support for non-migrated route map users. */
-+ rm = route_map_get(name);
-+ action_type = (action[0] == 'p') ? RMAP_PERMIT : RMAP_DENY;
-+ rmi = route_map_index_get(rm, action_type, sequence);
-+ VTY_PUSH_CONTEXT(RMAP_NODE, rmi);
-+ }
-+
- return rv;
- }
-
-@@ -105,11 +115,55 @@ DEFPY(
- void route_map_instance_show(struct vty *vty, struct lyd_node *dnode,
- bool show_defaults)
- {
-+ const struct route_map_rule *rmr;
-+ const struct route_map_index *rmi;
- const char *name = yang_dnode_get_string(dnode, "../name");
- const char *action = yang_dnode_get_string(dnode, "./action");
- const char *sequence = yang_dnode_get_string(dnode, "./sequence");
-
- vty_out(vty, "route-map %s %s %s\n", name, action, sequence);
-+
-+ rmi = nb_running_get_entry(dnode, NULL, false);
-+ if (rmi == NULL) {
-+ /*
-+ * We can't have outdated rules if route map hasn't
-+ * been created yet.
-+ */
-+ return;
-+ }
-+
-+#define SKIP_RULE(name) if (strcmp((name), rmr->cmd->str) == 0) continue
-+
-+ /* Print route map `match` for old CLI users. */
-+ for (rmr = rmi->match_list.head; rmr; rmr = rmr->next) {
-+ /* Skip all matches implemented by northbound. */
-+ SKIP_RULE("interface");
-+ SKIP_RULE("ip address");
-+ SKIP_RULE("ip address prefix-list");
-+ SKIP_RULE("ip next-hop");
-+ SKIP_RULE("ip next-hop prefix-list");
-+ SKIP_RULE("ip next-hop type");
-+ SKIP_RULE("ipv6 address");
-+ SKIP_RULE("ipv6 address prefix-list");
-+ SKIP_RULE("ipv6 next-hop type");
-+ SKIP_RULE("metric");
-+ SKIP_RULE("tag");
-+
-+ vty_out(vty, " match %s %s\n", rmr->cmd->str,
-+ rmr->rule_str ? rmr->rule_str : "");
-+ }
-+
-+ /* Print route map `set` for old CLI users. */
-+ for (rmr = rmi->set_list.head; rmr; rmr = rmr->next) {
-+ /* Skip all sets implemented by northbound. */
-+ SKIP_RULE("metric");
-+ SKIP_RULE("tag");
-+
-+ vty_out(vty, " set %s %s\n", rmr->cmd->str,
-+ rmr->rule_str ? rmr->rule_str : "");
-+ }
-+
-+#undef SKIP_RULE
- }
-
- void route_map_instance_show_end(struct vty *vty, struct lyd_node *dnode)
-
-From 91835f1fd2a8dd05a5ba03c8961b699aaabed7e7 Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Tue, 1 Oct 2019 17:56:41 -0300
-Subject: [PATCH 08/10] *: fix route map integration
-
-Add the appropriated code to bootstrap route map northbound for all
-daemons.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- bgpd/bgp_main.c | 2 ++
- eigrpd/eigrp_main.c | 1 +
- isisd/isis_main.c | 2 ++
- ospf6d/ospf6_main.c | 1 +
- ospfd/ospf_main.c | 2 ++
- ripd/rip_main.c | 2 ++
- ripngd/ripng_main.c | 2 ++
- zebra/main.c | 1 +
- 8 files changed, 13 insertions(+)
-
-diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
-index fab2a584c0..0b33f7e9d9 100644
---- a/bgpd/bgp_main.c
-+++ b/bgpd/bgp_main.c
-@@ -360,6 +360,8 @@ static void bgp_vrf_terminate(void)
- }
-
- static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
-+ &frr_interface_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
-diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
-index 0746b04edb..922c0fe3e7 100644
---- a/eigrpd/eigrp_main.c
-+++ b/eigrpd/eigrp_main.c
-@@ -140,6 +140,7 @@ struct quagga_signal_t eigrp_signals[] = {
- static const struct frr_yang_module_info *const eigrpd_yang_modules[] = {
- &frr_eigrpd_info,
- &frr_interface_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(eigrpd, EIGRP, .vty_port = EIGRP_VTY_PORT,
-diff --git a/isisd/isis_main.c b/isisd/isis_main.c
-index 364441f79d..f7fe089b99 100644
---- a/isisd/isis_main.c
-+++ b/isisd/isis_main.c
-@@ -39,6 +39,7 @@
- #include "vrf.h"
- #include "qobj.h"
- #include "libfrr.h"
-+#include "routemap.h"
-
- #include "isisd/isis_constants.h"
- #include "isisd/isis_common.h"
-@@ -166,6 +167,7 @@ static const struct frr_yang_module_info *const isisd_yang_modules[] = {
- #ifndef FABRICD
- &frr_isisd_info,
- #endif /* ifndef FABRICD */
-+ &frr_route_map_info,
- };
-
- #ifdef FABRICD
-diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
-index 0aaefeb3c2..e4bed7a79d 100644
---- a/ospf6d/ospf6_main.c
-+++ b/ospf6d/ospf6_main.c
-@@ -167,6 +167,7 @@ struct quagga_signal_t ospf6_signals[] = {
-
- static const struct frr_yang_module_info *const ospf6d_yang_modules[] = {
- &frr_interface_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(ospf6d, OSPF6, .vty_port = OSPF6_VTY_PORT,
-diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c
-index d02ffe0448..7caa79d207 100644
---- a/ospfd/ospf_main.c
-+++ b/ospfd/ospf_main.c
-@@ -40,6 +40,7 @@
- #include "zclient.h"
- #include "vrf.h"
- #include "libfrr.h"
-+#include "routemap.h"
-
- #include "ospfd/ospfd.h"
- #include "ospfd/ospf_interface.h"
-@@ -126,6 +127,7 @@ struct quagga_signal_t ospf_signals[] = {
-
- static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
- &frr_interface_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT,
-diff --git a/ripd/rip_main.c b/ripd/rip_main.c
-index 060bb76585..ca41afaea6 100644
---- a/ripd/rip_main.c
-+++ b/ripd/rip_main.c
-@@ -35,6 +35,7 @@
- #include "vrf.h"
- #include "if_rmap.h"
- #include "libfrr.h"
-+#include "routemap.h"
-
- #include "ripd/ripd.h"
- #include "ripd/rip_nb.h"
-@@ -115,6 +116,7 @@ static struct quagga_signal_t ripd_signals[] = {
- static const struct frr_yang_module_info *const ripd_yang_modules[] = {
- &frr_interface_info,
- &frr_ripd_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(ripd, RIP, .vty_port = RIP_VTY_PORT,
-diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c
-index 9daeeb9580..99adb2cba7 100644
---- a/ripngd/ripng_main.c
-+++ b/ripngd/ripng_main.c
-@@ -36,6 +36,7 @@
- #include "vrf.h"
- #include "if_rmap.h"
- #include "libfrr.h"
-+#include "routemap.h"
-
- #include "ripngd/ripngd.h"
- #include "ripngd/ripng_nb.h"
-@@ -115,6 +116,7 @@ struct quagga_signal_t ripng_signals[] = {
- static const struct frr_yang_module_info *const ripngd_yang_modules[] = {
- &frr_interface_info,
- &frr_ripngd_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT,
-diff --git a/zebra/main.c b/zebra/main.c
-index f23702d878..5951c7e280 100644
---- a/zebra/main.c
-+++ b/zebra/main.c
-@@ -237,6 +237,7 @@ struct quagga_signal_t zebra_signals[] = {
-
- static const struct frr_yang_module_info *const zebra_yang_modules[] = {
- &frr_interface_info,
-+ &frr_route_map_info,
- };
-
- FRR_DAEMON_INFO(
-
-From 54a35ff48b600cd59b715b6e5aea4e69de1b995f Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Mon, 14 Oct 2019 23:29:19 -0300
-Subject: [PATCH 09/10] lib: fix route map northbound memory leak
-
-Keep a list of hook contexts used by northbound so we don't lose the
-pointer when free()ing the route map index entry data.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap.c | 5 +++++
- lib/routemap.h | 11 +++++++++++
- lib/routemap_northbound.c | 39 ++++++++++++++++++++++++++++++---------
- 3 files changed, 46 insertions(+), 9 deletions(-)
-
-diff --git a/lib/routemap.c b/lib/routemap.c
-index 5369fa771f..912cf28202 100644
---- a/lib/routemap.c
-+++ b/lib/routemap.c
-@@ -909,6 +909,7 @@ static struct route_map_index *route_map_index_new(void)
-
- new = XCALLOC(MTYPE_ROUTE_MAP_INDEX, sizeof(struct route_map_index));
- new->exitpolicy = RMAP_EXIT; /* Default to Cisco-style */
-+ TAILQ_INIT(&new->rhclist);
- QOBJ_REG(new, route_map_index);
- return new;
- }
-@@ -924,6 +925,10 @@ void route_map_index_delete(struct route_map_index *index, int notify)
- zlog_debug("Deleting route-map %s sequence %d",
- index->map->name, index->pref);
-
-+ /* Free route map northbound hook contexts. */
-+ while (!TAILQ_EMPTY(&index->rhclist))
-+ routemap_hook_context_free(TAILQ_FIRST(&index->rhclist));
-+
- /* Free route match. */
- while ((rule = index->match_list.head) != NULL)
- route_map_rule_delete(&index->match_list, rule);
-diff --git a/lib/routemap.h b/lib/routemap.h
-index 70e150c981..05c958967c 100644
---- a/lib/routemap.h
-+++ b/lib/routemap.h
-@@ -162,6 +162,9 @@ struct route_map_rule_list {
- struct route_map_rule *tail;
- };
-
-+/* Forward struct declaration: the complete can be found later this file. */
-+struct routemap_hook_context;
-+
- /* Route map index structure. */
- struct route_map_index {
- struct route_map *map;
-@@ -194,6 +197,9 @@ struct route_map_index {
- uint64_t applied;
- uint64_t applied_clear;
-
-+ /* List of match/sets contexts. */
-+ TAILQ_HEAD(, routemap_hook_context) rhclist;
-+
- QOBJ_FIELDS
- };
- DECLARE_QOBJ_TYPE(route_map_index)
-@@ -660,6 +666,7 @@ struct routemap_hook_context {
- route_map_event_t rhc_event;
- routemap_set_hook_fun rhc_shook;
- routemap_match_hook_fun rhc_mhook;
-+ TAILQ_ENTRY(routemap_hook_context) rhc_entry;
- };
-
- int lib_route_map_entry_match_destroy(enum nb_event event,
-@@ -667,6 +674,10 @@ int lib_route_map_entry_match_destroy(enum nb_event event,
- int lib_route_map_entry_set_destroy(enum nb_event event,
- const struct lyd_node *dnode);
-
-+struct routemap_hook_context *
-+routemap_hook_context_insert(struct route_map_index *rmi);
-+void routemap_hook_context_free(struct routemap_hook_context *rhc);
-+
- extern const struct frr_yang_module_info frr_route_map_info;
-
- /* routemap_cli.c */
-diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
-index b9ac01e865..3173a708e4 100644
---- a/lib/routemap_northbound.c
-+++ b/lib/routemap_northbound.c
-@@ -74,6 +74,30 @@ int lib_route_map_entry_set_destroy(enum nb_event event,
- return NB_OK;
- }
-
-+/*
-+ * Auxiliary hook context list manipulation functions.
-+ */
-+struct routemap_hook_context *
-+routemap_hook_context_insert(struct route_map_index *rmi)
-+{
-+ struct routemap_hook_context *rhc;
-+
-+ rhc = XCALLOC(MTYPE_TMP, sizeof(*rhc));
-+ rhc->rhc_rmi = rmi;
-+ TAILQ_INSERT_TAIL(&rmi->rhclist, rhc, rhc_entry);
-+
-+ return rhc;
-+}
-+
-+void
-+routemap_hook_context_free(struct routemap_hook_context *rhc)
-+{
-+ struct route_map_index *rmi = rhc->rhc_rmi;
-+
-+ TAILQ_REMOVE(&rmi->rhclist, rhc, rhc_entry);
-+ XFREE(MTYPE_TMP, rhc);
-+}
-+
- /*
- * XPath: /frr-route-map:lib/route-map
- */
-@@ -436,20 +460,17 @@ lib_route_map_entry_match_condition_create(enum nb_event event,
- union nb_resource *resource)
- {
- struct routemap_hook_context *rhc;
-+ struct route_map_index *rmi;
-
- switch (event) {
- case NB_EV_VALIDATE:
-- /* NOTHING */
-- break;
- case NB_EV_PREPARE:
-- resource->ptr = XCALLOC(MTYPE_TMP, sizeof(*rhc));
-- break;
- case NB_EV_ABORT:
-- XFREE(MTYPE_TMP, resource->ptr);
-+ /* NOTHING */
- break;
- case NB_EV_APPLY:
-- rhc = resource->ptr;
-- rhc->rhc_rmi = nb_running_get_entry(dnode, NULL, true);
-+ rmi = nb_running_get_entry(dnode, NULL, true);
-+ rhc = routemap_hook_context_insert(rmi);
- nb_running_set_entry(dnode, rhc);
- break;
- }
-@@ -469,7 +490,7 @@ lib_route_map_entry_match_condition_destroy(enum nb_event event,
-
- rv = lib_route_map_entry_match_destroy(event, dnode);
- rhc = nb_running_unset_entry(dnode);
-- XFREE(MTYPE_TMP, rhc);
-+ routemap_hook_context_free(rhc);
-
- return rv;
- }
-@@ -893,7 +914,7 @@ static int lib_route_map_entry_set_action_destroy(enum nb_event event,
-
- rv = lib_route_map_entry_set_destroy(event, dnode);
- rhc = nb_running_unset_entry(dnode);
-- XFREE(MTYPE_TMP, rhc);
-+ routemap_hook_context_free(rhc);
-
- return rv;
- }
-
-From 79661106763d4f6d9c200a4f4d25439f1cfecf3a Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Wed, 5 Feb 2020 11:09:31 -0300
-Subject: [PATCH 10/10] lib: fix route-map YANG module on old gcc versions
-
-Copy the fix made in 'lib/if.c' to 'lib/routemap_northbound.c' so we can
-have a working YANG model when compiled with GCC version less than 5.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- lib/routemap_northbound.c | 25 +++++++++++++++++++++++++
- 1 file changed, 25 insertions(+)
-
-diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
-index 3173a708e4..78f2a5a018 100644
---- a/lib/routemap_northbound.c
-+++ b/lib/routemap_northbound.c
-@@ -1224,7 +1224,32 @@ lib_route_map_entry_set_action_tag_destroy(enum nb_event event,
- }
-
- /* clang-format off */
-+#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
-+/*
-+ * gcc versions before 5.x miscalculate the size for structs with variable
-+ * length arrays (they just count it as size 0)
-+ */
-+struct frr_yang_module_info_sizen {
-+ /* YANG module name. */
-+ const char *name;
-+
-+ /* Northbound callbacks. */
-+ const struct {
-+ /* Data path of this YANG node. */
-+ const char *xpath;
-+
-+ /* Callbacks implemented for this node. */
-+ struct nb_callbacks cbs;
-+
-+ /* Priority - lower priorities are processed first. */
-+ uint32_t priority;
-+ } nodes[28];
-+};
-+
-+const struct frr_yang_module_info_sizen frr_route_map_info_sizen asm("frr_route_map_info") = {
-+#else
- const struct frr_yang_module_info frr_route_map_info = {
-+#endif
- .name = "frr-route-map",
- .nodes = {
- {
+++ /dev/null
-From bec0aa85b1f404ac9800c7524070fcf8582e82bc Mon Sep 17 00:00:00 2001
-From: Rafael Zalamena <rzalamena@opensourcerouting.org>
-Date: Thu, 1 Aug 2019 19:56:46 -0300
-Subject: [PATCH] yang: simplify filter choice by removing cases
-
-Based on @rwestphal feedback, lets remove `case`s where we don't expect
-to add more items or items with more than one `leaf`.
-
-Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
----
- yang/frr-filter.yang | 48 +++++++++++++++++---------------------------
- 1 file changed, 18 insertions(+), 30 deletions(-)
-
-diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang
-index 92af6aebfd..e79ede87b7 100644
---- a/yang/frr-filter.yang
-+++ b/yang/frr-filter.yang
-@@ -107,23 +107,17 @@ module frr-filter {
- Extended access list: source value to match.";
- mandatory true;
-
-- case host {
-- leaf host {
-- description "Host to match";
-- type inet:ipv4-address;
-- }
-+ leaf host {
-+ description "Host to match";
-+ type inet:ipv4-address;
- }
-- case network {
-- leaf network {
-- description "Network to match";
-- type inet:ipv4-prefix;
-- }
-+ leaf network {
-+ description "Network to match";
-+ type inet:ipv4-prefix;
- }
-- case any {
-- leaf any {
-- description "Match any";
-- type empty;
-- }
-+ leaf any {
-+ description "Match any";
-+ type empty;
- }
- }
-
-@@ -132,23 +126,17 @@ module frr-filter {
- ./sequence >= 2000 and ./sequence <= 2699";
- description "Destination value to match";
-
-- case destination-host {
-- leaf destination-host {
-- description "Host to match";
-- type inet:ipv4-address;
-- }
-+ leaf destination-host {
-+ description "Host to match";
-+ type inet:ipv4-address;
- }
-- case destination-network {
-- leaf destination-network {
-- description "Network to match";
-- type inet:ipv4-prefix;
-- }
-+ leaf destination-network {
-+ description "Network to match";
-+ type inet:ipv4-prefix;
- }
-- case destination-any {
-- leaf destination-any {
-- description "Match any";
-- type empty;
-- }
-+ leaf destination-any {
-+ description "Match any";
-+ type empty;
- }
- }
- }
+++ /dev/null
-From dc397e4c0adc13982fc5d83a1afc42178708f4a5 Mon Sep 17 00:00:00 2001
-From: Renato Westphal <renato@opensourcerouting.org>
-Date: Fri, 3 Apr 2020 20:10:04 -0300
-Subject: [PATCH] lib: consolidate flexible array hack in a single place
-
-Old gcc versions (< 5.x) have a bug that prevents C99 flexible
-arrays from working properly on shared libraries.
-
-We already have a hack in place to work around this problem, but it
-needs to be replicated in every declaration of a frr_yang_module_info
-variable within libfrr. This clearly isn't a good solution if we
-consider that many more libfrr YANG modules are about to come in
-the future.
-
-This commit introduces a different workaround that operates within
-the northbound layer itself, such that implementers of libfrr YANG
-modules won't need to worry about this problem anymore.
-
-Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
----
- lib/if.c | 24 ------------------------
- lib/northbound.c | 7 +++++++
- lib/northbound.h | 11 +++++++++++
- lib/routemap_northbound.c | 25 -------------------------
- 4 files changed, 18 insertions(+), 49 deletions(-)
-
-diff --git a/lib/if.c b/lib/if.c
-index dabf66799d..24b103b3ff 100644
---- a/lib/if.c
-+++ b/lib/if.c
-@@ -1657,31 +1657,7 @@ static int lib_interface_description_destroy(enum nb_event event,
-
- /* clang-format off */
-
--#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
--/* gcc versions before 5.x miscalculate the size for structs with variable
-- * length arrays (they just count it as size 0)
-- */
--struct frr_yang_module_info_size3 {
-- /* YANG module name. */
-- const char *name;
--
-- /* Northbound callbacks. */
-- const struct {
-- /* Data path of this YANG node. */
-- const char *xpath;
--
-- /* Callbacks implemented for this node. */
-- struct nb_callbacks cbs;
--
-- /* Priority - lower priorities are processed first. */
-- uint32_t priority;
-- } nodes[3];
--};
--
--const struct frr_yang_module_info_size3 frr_interface_info_size3 asm("frr_interface_info") = {
--#else
- const struct frr_yang_module_info frr_interface_info = {
--#endif
- .name = "frr-interface",
- .nodes = {
- {
-diff --git a/lib/northbound.c b/lib/northbound.c
-index cebedcff09..85e723d7cf 100644
---- a/lib/northbound.c
-+++ b/lib/northbound.c
-@@ -1866,6 +1866,13 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module)
- struct nb_node *nb_node;
- uint32_t priority;
-
-+ if (i > YANG_MODULE_MAX_NODES) {
-+ zlog_err(
-+ "%s: %s.yang has more than %u nodes. Please increase YANG_MODULE_MAX_NODES to fix this problem.",
-+ __func__, module->name, YANG_MODULE_MAX_NODES);
-+ exit(1);
-+ }
-+
- nb_node = nb_node_find(module->nodes[i].xpath);
- if (!nb_node) {
- flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH,
-diff --git a/lib/northbound.h b/lib/northbound.h
-index 76a11e518c..19a2ba0865 100644
---- a/lib/northbound.h
-+++ b/lib/northbound.h
-@@ -403,6 +403,13 @@ struct nb_node {
- /* The YANG list doesn't contain key leafs. */
- #define F_NB_NODE_KEYLESS_LIST 0x02
-
-+/*
-+ * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays
-+ * from working properly on shared libraries. For those compilers, use a fixed
-+ * size array to work around the problem.
-+ */
-+#define YANG_MODULE_MAX_NODES 1024
-+
- struct frr_yang_module_info {
- /* YANG module name. */
- const char *name;
-@@ -417,7 +424,11 @@ struct frr_yang_module_info {
-
- /* Priority - lower priorities are processed first. */
- uint32_t priority;
-+#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
-+ } nodes[YANG_MODULE_MAX_NODES + 1];
-+#else
- } nodes[];
-+#endif
- };
-
- /* Northbound error codes. */
-diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
-index 69cebbd2a1..dd4cbd7d99 100644
---- a/lib/routemap_northbound.c
-+++ b/lib/routemap_northbound.c
-@@ -1221,32 +1221,7 @@ lib_route_map_entry_set_action_tag_destroy(enum nb_event event,
- }
-
- /* clang-format off */
--#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
--/*
-- * gcc versions before 5.x miscalculate the size for structs with variable
-- * length arrays (they just count it as size 0)
-- */
--struct frr_yang_module_info_sizen {
-- /* YANG module name. */
-- const char *name;
--
-- /* Northbound callbacks. */
-- const struct {
-- /* Data path of this YANG node. */
-- const char *xpath;
--
-- /* Callbacks implemented for this node. */
-- struct nb_callbacks cbs;
--
-- /* Priority - lower priorities are processed first. */
-- uint32_t priority;
-- } nodes[28];
--};
--
--const struct frr_yang_module_info_sizen frr_route_map_info_sizen asm("frr_route_map_info") = {
--#else
- const struct frr_yang_module_info frr_route_map_info = {
--#endif
- .name = "frr-route-map",
- .nodes = {
- {
+++ /dev/null
-From 97cd849362b45ecbcb20194b5771c5ce777de6bc Mon Sep 17 00:00:00 2001
-From: Renato Westphal <renato@opensourcerouting.org>
-Date: Tue, 21 Apr 2020 21:27:47 -0300
-Subject: [PATCH] lib: create a wrapper function for all northbound callbacks
-
-The intention here is to keep the code more organized. These wrappers
-should be used by the northbound clients only, and never directly
-by any YANG backend code.
-
-Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
----
- lib/northbound.c | 222 +++++++++++++++++++++++-----------------
- lib/northbound_grpc.cpp | 3 +-
- 2 files changed, 131 insertions(+), 94 deletions(-)
-
-diff --git a/lib/northbound.c b/lib/northbound.c
-index 85e723d7cf..d10e4713f5 100644
---- a/lib/northbound.c
-+++ b/lib/northbound.c
-@@ -62,11 +62,10 @@ static struct {
- */
- static bool transaction_in_progress;
-
-+static int nb_callback_pre_validate(const struct nb_node *nb_node,
-+ const struct lyd_node *dnode);
- static int nb_callback_configuration(const enum nb_event event,
- struct nb_config_change *change);
--static void nb_log_callback(const enum nb_event event,
-- enum nb_operation operation, const char *xpath,
-- const char *value);
- static struct nb_transaction *nb_transaction_new(struct nb_config *config,
- struct nb_config_cbs *changes,
- enum nb_client client,
-@@ -609,18 +608,7 @@ static int nb_candidate_validate_code(struct nb_config *candidate,
- if (!nb_node->cbs.pre_validate)
- goto next;
-
-- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config,
-- DEBUG_MODE_ALL)) {
-- char xpath[XPATH_MAXLEN];
--
-- yang_dnode_get_path(child, xpath,
-- sizeof(xpath));
-- nb_log_callback(NB_EV_VALIDATE,
-- NB_OP_PRE_VALIDATE, xpath,
-- NULL);
-- }
--
-- ret = (*nb_node->cbs.pre_validate)(child);
-+ ret = nb_callback_pre_validate(nb_node, child);
- if (ret != NB_OK)
- return NB_ERR_VALIDATION;
-
-@@ -791,14 +779,128 @@ int nb_running_lock_check(enum nb_client client, const void *user)
- return ret;
- }
-
--static void nb_log_callback(const enum nb_event event,
-- enum nb_operation operation, const char *xpath,
-- const char *value)
-+static void nb_log_config_callback(const enum nb_event event,
-+ enum nb_operation operation,
-+ const struct lyd_node *dnode)
- {
-+ const char *value;
-+ char xpath[XPATH_MAXLEN];
-+
-+ if (!DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL))
-+ return;
-+
-+ yang_dnode_get_path(dnode, xpath, sizeof(xpath));
-+ if (yang_snode_is_typeless_data(dnode->schema))
-+ value = "(none)";
-+ else
-+ value = yang_dnode_get_string(dnode, NULL);
-+
- zlog_debug(
- "northbound callback: event [%s] op [%s] xpath [%s] value [%s]",
- nb_event_name(event), nb_operation_name(operation), xpath,
-- value ? value : "(NULL)");
-+ value);
-+}
-+
-+static int nb_callback_create(const struct nb_node *nb_node,
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ nb_log_config_callback(event, NB_OP_CREATE, dnode);
-+
-+ return nb_node->cbs.create(event, dnode, resource);
-+}
-+
-+static int nb_callback_modify(const struct nb_node *nb_node,
-+ enum nb_event event, const struct lyd_node *dnode,
-+ union nb_resource *resource)
-+{
-+ nb_log_config_callback(event, NB_OP_MODIFY, dnode);
-+
-+ return nb_node->cbs.modify(event, dnode, resource);
-+}
-+
-+static int nb_callback_destroy(const struct nb_node *nb_node,
-+ enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ nb_log_config_callback(event, NB_OP_DESTROY, dnode);
-+
-+ return nb_node->cbs.destroy(event, dnode);
-+}
-+
-+static int nb_callback_move(const struct nb_node *nb_node, enum nb_event event,
-+ const struct lyd_node *dnode)
-+{
-+ nb_log_config_callback(event, NB_OP_MOVE, dnode);
-+
-+ return nb_node->cbs.move(event, dnode);
-+}
-+
-+static int nb_callback_pre_validate(const struct nb_node *nb_node,
-+ const struct lyd_node *dnode)
-+{
-+ nb_log_config_callback(NB_EV_VALIDATE, NB_OP_PRE_VALIDATE, dnode);
-+
-+ return nb_node->cbs.pre_validate(dnode);
-+}
-+
-+static void nb_callback_apply_finish(const struct nb_node *nb_node,
-+ const struct lyd_node *dnode)
-+{
-+ nb_log_config_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, dnode);
-+
-+ nb_node->cbs.apply_finish(dnode);
-+}
-+
-+struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
-+ const char *xpath,
-+ const void *list_entry)
-+{
-+ DEBUGD(&nb_dbg_cbs_state,
-+ "northbound callback (get_elem): xpath [%s] list_entry [%p]",
-+ xpath, list_entry);
-+
-+ return nb_node->cbs.get_elem(xpath, list_entry);
-+}
-+
-+const void *nb_callback_get_next(const struct nb_node *nb_node,
-+ const void *parent_list_entry,
-+ const void *list_entry)
-+{
-+ DEBUGD(&nb_dbg_cbs_state,
-+ "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]",
-+ nb_node->xpath, parent_list_entry, list_entry);
-+
-+ return nb_node->cbs.get_next(parent_list_entry, list_entry);
-+}
-+
-+int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry,
-+ struct yang_list_keys *keys)
-+{
-+ DEBUGD(&nb_dbg_cbs_state,
-+ "northbound callback (get_keys): node [%s] list_entry [%p]",
-+ nb_node->xpath, list_entry);
-+
-+ return nb_node->cbs.get_keys(list_entry, keys);
-+}
-+
-+const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
-+ const void *parent_list_entry,
-+ const struct yang_list_keys *keys)
-+{
-+ DEBUGD(&nb_dbg_cbs_state,
-+ "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]",
-+ nb_node->xpath, parent_list_entry);
-+
-+ return nb_node->cbs.lookup_entry(parent_list_entry, keys);
-+}
-+
-+int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
-+ const struct list *input, struct list *output)
-+{
-+ DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath);
-+
-+ return nb_node->cbs.rpc(xpath, input, output);
- }
-
- /*
-@@ -815,15 +917,6 @@ static int nb_callback_configuration(const enum nb_event event,
- union nb_resource *resource;
- int ret = NB_ERR;
-
-- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
-- const char *value = "(none)";
--
-- if (dnode && !yang_snode_is_typeless_data(dnode->schema))
-- value = yang_dnode_get_string(dnode, NULL);
--
-- yang_dnode_get_path(dnode, xpath, sizeof(xpath));
-- nb_log_callback(event, operation, xpath, value);
-- }
-
- if (event == NB_EV_VALIDATE)
- resource = NULL;
-@@ -832,16 +925,16 @@ static int nb_callback_configuration(const enum nb_event event,
-
- switch (operation) {
- case NB_OP_CREATE:
-- ret = (*nb_node->cbs.create)(event, dnode, resource);
-+ ret = nb_callback_create(nb_node, event, dnode, resource);
- break;
- case NB_OP_MODIFY:
-- ret = (*nb_node->cbs.modify)(event, dnode, resource);
-+ ret = nb_callback_modify(nb_node, event, dnode, resource);
- break;
- case NB_OP_DESTROY:
-- ret = (*nb_node->cbs.destroy)(event, dnode);
-+ ret = nb_callback_destroy(nb_node, event, dnode);
- break;
- case NB_OP_MOVE:
-- ret = (*nb_node->cbs.move)(event, dnode);
-+ ret = nb_callback_move(nb_node, event, dnode);
- break;
- default:
- yang_dnode_get_path(dnode, xpath, sizeof(xpath));
-@@ -890,57 +983,6 @@ static int nb_callback_configuration(const enum nb_event event,
- return ret;
- }
-
--struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node,
-- const char *xpath,
-- const void *list_entry)
--{
-- DEBUGD(&nb_dbg_cbs_state,
-- "northbound callback (get_elem): xpath [%s] list_entry [%p]",
-- xpath, list_entry);
--
-- return nb_node->cbs.get_elem(xpath, list_entry);
--}
--
--const void *nb_callback_get_next(const struct nb_node *nb_node,
-- const void *parent_list_entry,
-- const void *list_entry)
--{
-- DEBUGD(&nb_dbg_cbs_state,
-- "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]",
-- nb_node->xpath, parent_list_entry, list_entry);
--
-- return nb_node->cbs.get_next(parent_list_entry, list_entry);
--}
--
--int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry,
-- struct yang_list_keys *keys)
--{
-- DEBUGD(&nb_dbg_cbs_state,
-- "northbound callback (get_keys): node [%s] list_entry [%p]",
-- nb_node->xpath, list_entry);
--
-- return nb_node->cbs.get_keys(list_entry, keys);
--}
--
--const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
-- const void *parent_list_entry,
-- const struct yang_list_keys *keys)
--{
-- DEBUGD(&nb_dbg_cbs_state,
-- "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]",
-- nb_node->xpath, parent_list_entry);
--
-- return nb_node->cbs.lookup_entry(parent_list_entry, keys);
--}
--
--int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
-- const struct list *input, struct list *output)
--{
-- DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath);
--
-- return nb_node->cbs.rpc(xpath, input, output);
--}
--
- static struct nb_transaction *
- nb_transaction_new(struct nb_config *config, struct nb_config_cbs *changes,
- enum nb_client client, const void *user, const char *comment)
-@@ -1058,7 +1100,6 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
- {
- struct nb_config_cbs cbs;
- struct nb_config_cb *cb;
-- char xpath[XPATH_MAXLEN];
-
- /* Initialize tree of 'apply_finish' callbacks. */
- RB_INIT(nb_config_cbs, &cbs);
-@@ -1075,6 +1116,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
- * be called though).
- */
- if (change->cb.operation == NB_OP_DESTROY) {
-+ char xpath[XPATH_MAXLEN];
-+
- dnode = dnode->parent;
- if (!dnode)
- break;
-@@ -1111,15 +1154,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction)
- }
-
- /* Call the 'apply_finish' callbacks, sorted by their priorities. */
-- RB_FOREACH (cb, nb_config_cbs, &cbs) {
-- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) {
-- yang_dnode_get_path(cb->dnode, xpath, sizeof(xpath));
-- nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, xpath,
-- NULL);
-- }
--
-- (*cb->nb_node->cbs.apply_finish)(cb->dnode);
-- }
-+ RB_FOREACH (cb, nb_config_cbs, &cbs)
-+ nb_callback_apply_finish(cb->nb_node, cb->dnode);
-
- /* Release memory. */
- while (!RB_EMPTY(nb_config_cbs, &cbs)) {
-diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp
-index b195f1aeca..66bf05c1ab 100644
---- a/lib/northbound_grpc.cpp
-+++ b/lib/northbound_grpc.cpp
-@@ -545,7 +545,8 @@ class NorthboundImpl final : public frr::Northbound::Service
- }
-
- // Execute callback registered for this XPath.
-- if (nb_node->cbs.rpc(xpath, input_list, output_list) != NB_OK) {
-+ if (nb_callback_rpc(nb_node, xpath, input_list, output_list)
-+ != NB_OK) {
- flog_warn(EC_LIB_NB_CB_RPC,
- "%s: rpc callback failed: %s", __func__,
- xpath);
+++ /dev/null
---- a/lib/northbound.h
-+++ b/lib/northbound.h
-@@ -504,11 +504,7 @@ struct frr_yang_module_info {
-
- /* Priority - lower priorities are processed first. */
- uint32_t priority;
--#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__)
- } nodes[YANG_MODULE_MAX_NODES + 1];
--#else
-- } nodes[];
--#endif
- };
-
- /* Northbound error codes. */
include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
-PKG_VERSION:=2.1.7
+PKG_VERSION:=2.2.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://www.haproxy.org/download/2.1/src
-PKG_HASH:=392e6cf18e75fe7e166102e8c4512942890a0b5ae738f6064faab4687f60a339
+PKG_SOURCE_URL:=https://www.haproxy.org/download/2.2/src
+PKG_HASH:=391c705a46c6208a63a67ea842c6600146ca24618531570c89c7915b0c6a54d6
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
Christian Lachner <gladiac@gmail.com>
endef
ENABLE_LUA:=y
-ENABLE_REGPARM:=n
-
-ifeq ($(CONFIG_TARGET_x86),y)
- ENABLE_REGPARM:=y
-endif
ifeq ($(CONFIG_USE_UCLIBC),y)
ADDON+=USE_LIBCRYPT=
ADDON+=ADDLIB="-lcrypto -lm"
endif
-ifeq ($(ENABLE_REGPARM),y)
- ADDON+=USE_REGPARM=1
-endif
-
define Build/Compile
$(MAKE) TARGET=linux-glibc -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" \
#!/bin/sh
-CLONEURL=https://git.haproxy.org/git/haproxy-2.1.git
-BASE_TAG=v2.1.7
+CLONEURL=https://git.haproxy.org/git/haproxy-2.2.git
+BASE_TAG=v2.2.2
TMP_REPODIR=tmprepo
PATCHESDIR=patches
+++ /dev/null
-commit 62af9c83f9ed2b25e0061798e29e3cccfce5fbdc
-Author: Willy Tarreau <w@1wt.eu>
-Date: Tue Mar 10 07:51:48 2020 +0100
-
- BUILD: make dladdr1 depend on glibc version and not __USE_GNU
-
- Technically speaking the call was implemented in glibc 2.3 so we must
- rely on this and not on __USE_GNU which is an internal define of glibc
- to track use of GNU_SOURCE.
-
-diff --git a/src/standard.c b/src/standard.c
-index e0ea8328e..d16eebfea 100644
---- a/src/standard.c
-+++ b/src/standard.c
-@@ -4350,7 +4350,7 @@ void debug_hexdump(FILE *out, const char *pfx, const char *buf,
- static int dladdr_and_size(const void *addr, Dl_info *dli, size_t *size)
- {
- int ret;
--#ifdef __USE_GNU // most detailed one
-+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) // most detailed one
- const ElfW(Sym) *sym;
-
- ret = dladdr1(addr, dli, (void **)&sym, RTLD_DL_SYMENT);
PKG_NAME:=modemmanager
PKG_VERSION:=1.14.0
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE:=ModemManager-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.freedesktop.org/software/ModemManager
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=COPYING
-PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
-PKG_BUILD_DEPENDS:=glib2/host libxslt/host
+PKG_BUILD_DEPENDS:=libxslt/host
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
( cd "$(PKG_BUILD_DIR)"; \
printf "all:\ninstall:\n" >po/Makefile.in.in; \
)
- $(SED) 's|^\(GLIB_MKENUMS\)=.*|\1=$(STAGING_DIR_HOSTPKG)/bin/glib-mkenums|' \
- $(PKG_BUILD_DIR)/configure.ac
- $(SED) 's|^\(GDBUS_CODEGEN\)=.*|\1=$(STAGING_DIR_HOSTPKG)/bin/gdbus-codegen|' \
- $(PKG_BUILD_DIR)/configure.ac
endef
define Build/InstallDev
include $(TOPDIR)/rules.mk
PKG_NAME:=mwan3
-PKG_VERSION:=2.8.11
+PKG_VERSION:=2.8.12
PKG_RELEASE:=1
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
PKG_LICENSE:=GPL-2.0
[ -n "$INTERFACE" ] || exit 2
if [ "$ACTION" == "ifup" ]; then
- [ -n "$DEVICE" ] || exit 3
+ [ -n "$DEVICE" ] || exit 3
fi
+mwan3_lock "$ACTION" "$INTERFACE"
config_load mwan3
config_get_bool enabled globals 'enabled' '0'
-[ ${enabled} -gt 0 ] || exit 0
+[ "${enabled}" -gt 0 ] || {
+ mwan3_unlock "$ACTION" "$INTERFACE"
+ exit 0
+}
-mwan3_lock "$ACTION" "$INTERFACE"
mwan3_init
mwan3_set_connected_iptables
mwan3_set_custom_ipset
-mwan3_unlock "$ACTION" "$INTERFACE"
-config_get enabled $INTERFACE enabled 0
config_get initial_state $INTERFACE initial_state "online"
-[ "$enabled" == "1" ] || exit 0
+config_get_bool enabled $INTERFACE 'enabled' '0'
+[ "${enabled}" -eq 1 ] || {
+ mwan3_unlock "$ACTION" "$INTERFACE"
+ exit 0
+}
-if [ "$ACTION" == "ifup" ]; then
+if [ "$ACTION" = "ifup" ]; then
config_get family $INTERFACE family ipv4
if [ "$family" = "ipv4" ]; then
ubus call network.interface.${INTERFACE}_4 status &>/dev/null
running=1
fi
-mwan3_lock "$ACTION" "$INTERFACE"
$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})"
case "$ACTION" in
mwan3_create_iface_iptables $INTERFACE $DEVICE
mwan3_create_iface_rules $INTERFACE $DEVICE
mwan3_create_iface_route $INTERFACE $DEVICE
- if [ ${running} -eq 1 -a "${status}" = "online" ]; then
+ if [ "${running}" -eq 1 ] && [ "${status}" = "online" ]; then
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
mwan3_set_iface_hotplug_state $INTERFACE "online"
mwan3_track $INTERFACE $DEVICE "online" "$src_ip"
. /lib/functions/network.sh
. /lib/mwan3/mwan3.sh
+mwan3_lock "$ACTION" "mwan3rtmon"
+
config_load mwan3
config_get_bool enabled globals 'enabled' '0'
-[ ${enabled} -gt 0 ] || exit 0
+[ "${enabled}" -gt 0 ] || {
+ mwan3_unlock "$ACTION" "mwan3rtmon"
+ exit 0
+}
-if [ "$ACTION" == "ifup" ]; then
- mwan3_lock "$ACTION" "mwan3rtmon"
+if [ "$ACTION" = "ifup" ]; then
mwan3_rtmon
- mwan3_unlock "$ACTION" "mwan3rtmon"
fi
-config_get enabled $INTERFACE enabled 0
-[ "${enabled}" = "0" ] || {
+config_get_bool enabled "$INTERFACE" 'enabled' '0'
+[ "${enabled}" -eq 0 ] || {
mwan3_flush_conntrack "$INTERFACE" "$ACTION"
}
+mwan3_unlock "$ACTION" "mwan3rtmon"
+
exit 0
[ -f "/etc/mwan3.user" ] && {
. /lib/functions.sh
+ . /lib/mwan3/mwan3.sh
+
+ mwan3_lock "$ACTION" "user"
config_load mwan3
config_get_bool enabled globals 'enabled' '0'
- [ ${enabled} -gt 0 ] || exit 0
+ [ "${enabled}" -gt 0 ] || {
+ mwan3_unlock "$ACTION" "user"
+ exit 0
+ }
+
+ config_get_bool enabled "$INTERFACE" enabled 0
+ [ "${enabled}" -eq 1 ] || {
+ mwan3_unlock "$ACTION" "user"
+ exit 0
+ }
+
+ mwan3_unlock "$ACTION" "user"
- config_get enabled "$INTERFACE" enabled 0
- [ "${enabled}" = "1" ] || exit 0
env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \
/bin/sh /etc/mwan3.user
}
lock -u /var/run/mwan3.lock
}
-mwan3_lock_clean() {
- for pid in $(pgrep -f "lock /var/run/mwan3.lock"); do
- kill -TERM "$pid" > /dev/null 2>&1
- done
- sleep 1
- for pid in $(pgrep -f "lock /var/run/mwan3.lock"); do
- kill -KILL "$pid" > /dev/null 2>&1
- done
- rm -rf /var/run/mwan3.lock
-}
-
mwan3_get_iface_id()
{
local _tmp _iface _iface_count
{
local device enabled up l3_device status
+ mwan3_lock "command" "mwan3"
+
config_load mwan3
config_get_bool enabled globals 'enabled' 0
+
[ ${enabled} -gt 0 ] || {
echo "The service mwan3 is global disabled."
echo "Please execute \"/etc/init.d/mwan3 start\" first."
+ mwan3_unlock "command" "mwan3"
exit 1
}
if [ -z "$1" ]; then
- echo "Expecting interface. Usage: mwan3 ifup <interface>" && exit 0
+ echo "Expecting interface. Usage: mwan3 ifup <interface>"
+ mwan3_unlock "command" "mwan3"
+ exit 0
fi
if [ -n "$2" ]; then
- echo "Too many arguments. Usage: mwan3 ifup <interface>" && exit 0
+ echo "Too many arguments. Usage: mwan3 ifup <interface>"
+ mwan3_unlock "command" "mwan3"
+ exit 0
fi
+ config_get enabled "$1" enabled 0
+ mwan3_unlock "command" "mwan3"
+
status=$(ubus -S call network.interface.$1 status)
[ -n "$status" ] && {
json_load "$status"
json_get_vars up l3_device
}
- config_get enabled "$1" enabled 0
-
if [ "$up" = "1" ] \
&& [ -n "$l3_device" ] \
&& [ "$enabled" = "1" ]; then
{
local enabled
+ mwan3_lock "command" "mwan3"
uci_toggle_state mwan3 globals enabled "1"
+ mwan3_unlock "command" "mwan3"
config_load mwan3
config_foreach ifup interface
local ipset route rule table IP IPT pid
mwan3_lock "command" "mwan3"
+ uci_toggle_state mwan3 globals enabled "0"
for pid in $(pgrep -f "mwan3rtmon"); do
kill -TERM "$pid" > /dev/null 2>&1
mwan3_unlock "command" "mwan3"
- mwan3_lock_clean
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
-
- uci_toggle_state mwan3 globals enabled "0"
}
restart() {
include $(TOPDIR)/rules.mk
PKG_NAME:=nextdns
-PKG_VERSION:=1.7.0
+PKG_VERSION:=1.7.1
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
PKG_SOURCE_URL:=https://github.com/nextdns/nextdns.git
-PKG_MIRROR_HASH:=91d812b406abee2a0e733b7cbc06d0d2f04a60bb3694477ac2d2a68fd8b8be5d
+PKG_MIRROR_HASH:=79ae12b494e1c9c7e309a8763975f2457771f26221113ed51dc0884299ae25b4
PKG_MAINTAINER:=Olivier Poitrey <rs@nextdns.io>
PKG_LICENSE:=MIT
PKG_NAME:=nginx-util
PKG_VERSION:=1.4
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_MAINTAINER:=Peter Stadler <peter.stadler@student.uibk.ac.at>
include $(INCLUDE_DIR)/package.mk
CMAKE_OPTIONS+= -DVERSION=$(PKG_VERSION)
-define Package/nginx-util/default
+define Package/nginx-ssl-util/default
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
- TITLE:=Nginx configurator
- DEPENDS:=+libstdcpp +libubus +libubox +libpthread
-endef
-
-
-define Package/nginx-util
- $(Package/nginx-util/default)
- CONFLICTS:=nginx-ssl-util-nopcre nginx-ssl-util
-endef
-
-
-define Package/nginx-ssl-util/default
- $(Package/nginx-util/default)
- TITLE+= including SSL
- DEPENDS+= +libopenssl
- CONFLICTS:=nginx-util,
+ TITLE:=Nginx configurator including SSL
+ DEPENDS:=+libstdcpp +libubus +libubox +libpthread +libopenssl
+ # TODO: remove after a transition period (together with below and pkg nginx):
+ # It actually removes nginx-util (replacing it by a dummy pkg) to avoid
+ # conflicts with nginx-ssl-util*
+ EXTRA_DEPENDS:=nginx-util (>=1.4-2)
endef
$(Package/nginx-ssl-util/default)
TITLE+= (using PCRE)
DEPENDS+= +libpcre
- CONFLICTS+= nginx-ssl-util-nopcre,
+ CONFLICTS:=nginx-ssl-util-nopcre,
endef
define Package/nginx-ssl-util-nopcre
$(Package/nginx-ssl-util/default)
TITLE+= (using <regex>)
- CONFLICTS+= nginx-ssl-util
+ CONFLICTS:=nginx-ssl-util
endef
-define Package/nginx-util/description
+define Package/nginx-ssl-util/default/description
Utility that builds dynamically LAN listen directives for Nginx.
-endef
-
-
-Package/nginx-ssl-util/default/description = $(Package/nginx-util/description)\
- Furthermore, it manages SSL directives for its server parts and can create \
+ Furthermore, it manages SSL directives for its server parts and can create
corresponding (self-signed) certificates.
+endef
Package/nginx-ssl-util/description = \
It uses the standard regex library of C++.
-define Package/nginx-util/install
- $(INSTALL_DIR) $(1)/usr/bin
- $(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-util $(1)/usr/bin/nginx-util
-endef
-
-
define Package/nginx-ssl-util/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-ssl-util $(1)/usr/bin/nginx-util
endef
-$(eval $(call BuildPackage,nginx-util))
$(eval $(call BuildPackage,nginx-ssl-util))
$(eval $(call BuildPackage,nginx-ssl-util-nopcre))
+
+
+# TODO: remove after a transition period (together with above and pkg nginx):
+# It replaces nginx-util by a dummy pkg for a smooth upgrade of nginx*
+
+define Package/nginx-util
+ TITLE:=Dummy package for removing nginx-util when upgrading.
+ DEPENDS:=+libstdcpp +libubus +libubox +libpthread
+ PKGARCH:=all
+endef
+
+define Package/nginx-util/install
+ $(INSTALL_DIR) $(1)/usr/bin
+endef
+
+$(eval $(call BuildPackage,nginx-util))
FIND_LIBRARY(ubox NAMES ubox)
INCLUDE_DIRECTORIES(${ubox_include_dir})
-ADD_EXECUTABLE(nginx-util nginx-util.cpp)
-TARGET_COMPILE_DEFINITIONS(nginx-util PUBLIC -DNO_SSL)
-TARGET_LINK_LIBRARIES(nginx-util ${ubox} ${ubus} pthread)
-INSTALL(TARGETS nginx-util RUNTIME DESTINATION bin)
-
ADD_EXECUTABLE(nginx-ssl-util nginx-util.cpp)
TARGET_LINK_LIBRARIES(nginx-ssl-util ${ubox} ${ubus} pthread ssl crypto pcre)
INSTALL(TARGETS nginx-ssl-util RUNTIME DESTINATION bin)
+++ /dev/null
-#
-# Copyright (C) 2010-2016 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-
-menu "Configuration"
- depends on PACKAGE_nginx
-
-config NGINX_SSL
- bool
- prompt "Enable SSL module"
- help
- Enable HTTPS/SSL support.
- default n
-
-config NGINX_DAV
- bool
- prompt "Enable WebDAV module"
- help
- Enable the HTTP and WebDAV methods PUT, DELETE, MKCOL, COPY and MOVE.
- default n
-
-config NGINX_UBUS
- bool
- prompt "Enable UBUS module"
- help
- Enable UBUS api support directly from the server.
- default y
-
-config NGINX_FLV
- bool
- prompt "Enable FLV module"
- help
- Provides the ability to seek within FLV (Flash) files using time-based offsets.
- default n
-
-config NGINX_STUB_STATUS
- bool
- prompt "Enable stub status module"
- help
- Enable the stub status module which gives some status from the server.
- default n
-
-config NGINX_HTTP_CHARSET
- bool
- prompt "Enable HTTP charset module"
- default y
-
-config NGINX_HTTP_GZIP
- bool
- prompt "Enable HTTP gzip module"
- default y
-
-config NGINX_HTTP_SSI
- bool
- prompt "Enable HTTP ssi module"
- default y
-
-config NGINX_HTTP_USERID
- bool
- prompt "Enable HTTP userid module"
- default y
-
-config NGINX_HTTP_ACCESS
- bool
- prompt "Enable HTTP access module"
- default y
-
-config NGINX_HTTP_AUTH_BASIC
- bool
- prompt "Enable HTTP auth basic"
- default y
-
-config NGINX_HTTP_AUTH_REQUEST
- bool
- prompt "Enable HTTP auth request module"
- default n
-
-config NGINX_HTTP_AUTOINDEX
- bool
- prompt "Enable HTTP autoindex module"
- default y
-
-config NGINX_HTTP_GEO
- bool
- prompt "Enable HTTP geo module"
- default y
-
-config NGINX_HTTP_MAP
- bool
- prompt "Enable HTTP map module"
- default y
-
-config NGINX_HTTP_SPLIT_CLIENTS
- bool
- prompt "Enable HTTP split clients"
- default y
-
-config NGINX_HTTP_REFERER
- bool
- prompt "Enable HTTP referer module"
- default y
-
-config NGINX_HTTP_REWRITE
- bool
- prompt "Enable HTTP rewrite module"
- select NGINX_PCRE
- default y
-
-config NGINX_HTTP_PROXY
- bool
- prompt "Enable HTTP proxy module"
- default y
-
-config NGINX_HTTP_FASTCGI
- bool
- prompt "Enable HTTP fastcgi module"
- default y
-
-config NGINX_HTTP_UWSGI
- bool
- prompt "Enable HTTP uwsgi module"
- default y
-
-config NGINX_HTTP_SCGI
- bool
- prompt "Enable HTTP scgi module"
- default y
-
-config NGINX_HTTP_MEMCACHED
- bool
- prompt "Enable HTTP memcached module"
- default y
-
-config NGINX_HTTP_LIMIT_CONN
- bool
- prompt "Enable HTTP limit conn"
- default y
-
-config NGINX_HTTP_LIMIT_REQ
- bool
- prompt "Enable HTTP limit req"
- default y
-
-config NGINX_HTTP_EMPTY_GIF
- bool
- prompt "Enable HTTP empty gif"
- default y
-
-config NGINX_HTTP_BROWSER
- bool
- prompt "Enable HTTP browser module"
- default y
-
-config NGINX_HTTP_UPSTREAM_HASH
- bool
- prompt "Enable HTTP hash module"
- default y
-
-config NGINX_HTTP_UPSTREAM_IP_HASH
- bool
- prompt "Enable HTTP IP hash module"
- default y
-
-config NGINX_HTTP_UPSTREAM_LEAST_CONN
- bool
- prompt "Enable HTTP least conn module"
- default y
-
-config NGINX_HTTP_UPSTREAM_KEEPALIVE
- bool
- prompt "Enable HTTP keepalive module"
- default y
-
-config NGINX_HTTP_CACHE
- bool
- prompt "Enable HTTP cache"
- default y
-
-config NGINX_HTTP_V2
- bool
- prompt "Enable HTTP_V2 module"
- default n
-
-config NGINX_PCRE
- bool
- prompt "Enable PCRE library usage"
- default y
-
-config NGINX_NAXSI
- bool
- prompt "Enable NAXSI module"
- default y
-
-config NGINX_LUA
- bool
- prompt "Enable Lua module"
- default n
-
-config NGINX_HTTP_REAL_IP
- bool
- prompt "Enable HTTP real ip module"
- default n
-
-config NGINX_HTTP_SECURE_LINK
- bool
- prompt "Enable HTTP secure link module"
- default n
-
-config NGINX_HTTP_SUB
- bool
- prompt "Enable HTTP sub module"
- default n
-
-config NGINX_HEADERS_MORE
- bool
- prompt "Enable Headers_more module"
- help
- Set and clear input and output headers...more than "add"!
- default y
-
-config NGINX_HTTP_BROTLI
- bool
- prompt "Enable Brotli compression module"
- help
- Add support for brotli compression module.
- default n
-
-config NGINX_STREAM_CORE_MODULE
- bool
- prompt "Enable stream support"
- help
- Add support for NGINX request streaming.
- default n
-
-config NGINX_STREAM_SSL_MODULE
- bool
- prompt "Enable stream support with SSL/TLS termination"
- depends on NGINX_STREAM_CORE_MODULE
- help
- Add support for NGINX request streaming with SSL/TLS termination.
- default n
-
-config NGINX_STREAM_SSL_PREREAD_MODULE
- bool
- prompt "Enable stream support with SSL/TLS pre-read"
- depends on NGINX_STREAM_CORE_MODULE
- help
- Add support for NGINX request streaming using information from the ClientHello message without terminating SSL/TLS.
- default n
-
-config NGINX_RTMP_MODULE
- bool
- prompt "Enable RTMP module"
- depends on NGINX_SSL
- help
- Add support for NGINX-based Media Streaming Server module.
- DASH enhanced - https://github.com/ut0mt8/nginx-rtmp-module
- default n
-
-config NGINX_TS_MODULE
- bool
- prompt "Enable TS module"
- help
- Add support for MPEG-TS Live Module module.
- default n
-
-endmenu
config NGINX_HTTP_V2
bool
prompt "Enable HTTP_V2 module"
- default n
+ default y
config NGINX_PCRE
bool
PKG_NAME:=nginx
PKG_VERSION:=1.19.1
-PKG_RELEASE:=1
+PKG_RELEASE:=3
PKG_SOURCE:=nginx-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://nginx.org/download/
PKG_INSTALL:=1
PKG_CONFIG_DEPENDS := \
- CONFIG_NGINX_SSL \
CONFIG_NGINX_DAV \
CONFIG_NGINX_FLV \
CONFIG_NGINX_UBUS \
CONFIG_NGINX_RTMP_MODULE \
CONFIG_NGINX_TS_MODULE \
CONFIG_OPENSSL_ENGINE \
- CONFIG_OPENSSL_WITH_NPN \
- CONFIG_NGINX_NOPCRE
+ CONFIG_OPENSSL_WITH_NPN
include $(INCLUDE_DIR)/package.mk
SUBMENU:=Web Servers/Proxies
TITLE:=Nginx web server
URL:=http://nginx.org/
- DEPENDS:=+NGINX_PCRE:libpcre +NGINX_SSL:libopenssl \
+ DEPENDS:=+NGINX_PCRE:libpcre +libopenssl \
+ +NGINX_PCRE:nginx-ssl-util +!NGINX_PCRE:nginx-ssl-util-nopcre \
+NGINX_HTTP_GZIP:zlib +NGINX_LUA:liblua +libpthread +NGINX_DAV:libxml2 \
+NGINX_UBUS:libubus +NGINX_UBUS:libblobmsg-json +NGINX_UBUS:libjson-c
+ PROVIDES:=nginx
endef
define Package/nginx/description
nginx is an HTTP and reverse proxy server, as well as a mail proxy server, \
- written by Igor Sysoev. (Some module require SSL module enable to show up in \
- config menu)
-endef
-
-define Package/nginx
- $(Package/nginx/default)
- DEPENDS += +!NGINX_SSL:nginx-util +NGINX_SSL&&NGINX_PCRE:nginx-ssl-util \
- +NGINX_SSL&&NGINX_NOPCRE:nginx-ssl-util-nopcre
- VARIANT:=no-ssl
+ written by Igor Sysoev.
endef
define Package/nginx-ssl
$(Package/nginx/default)
TITLE += with SSL support
- DEPENDS += +libopenssl +NGINX_PCRE:nginx-ssl-util \
- +!NGINX_PCRE:nginx-ssl-util-nopcre
VARIANT:=ssl
- PROVIDES:=nginx
+ CONFLICTS:=nginx-all-module
endef
Package/nginx-ssl/description = $(Package/nginx/description) \
$(Package/nginx/default)
TITLE += with ALL module selected
DEPENDS:=+libpcre +libopenssl +zlib +liblua +libpthread +libxml2 \
- +libubus +libblobmsg-json +libjson-c +nginx-ssl-util
+ +libubus +libblobmsg-json +libjson-c +nginx-ssl-util
VARIANT:=all-module
- PROVIDES:=nginx nginx-ssl
+ PROVIDES += nginx-ssl
endef
Package/nginx-all-module/description = $(Package/nginx/description) \
This variant is compiled with ALL module selected.
-define Package/nginx/config
- source "$(SOURCE)/Config.in"
-config NGINX_NOPCRE
- bool
- default y if !NGINX_PCRE
- default n if NGINX_PCRE
-endef
-
define Package/nginx-ssl/config
source "$(SOURCE)/Config_ssl.in"
endef
Package/nginx-all-module/conffiles = $(Package/nginx/conffiles)
-ADDITIONAL_MODULES:=
+ADDITIONAL_MODULES:= --with-http_ssl_module
ifneq ($(BUILD_VARIANT),all-module)
ifneq ($(CONFIG_NGINX_HTTP_CACHE),y)
ifneq ($(CONFIG_NGINX_HTTP_UPSTREAM_KEEPALIVE),y)
ADDITIONAL_MODULES += --without-http_upstream_keepalive_module
endif
-
- ifeq ($(BUILD_VARIANT),ssl)
- ifneq ($(CONFIG_NGINX_SSL),y)
- ADDITIONAL_MODULES += --with-http_ssl_module
- endif
- endif
-
- ifeq ($(CONFIG_NGINX_SSL),y)
- ADDITIONAL_MODULES += --with-http_ssl_module
- endif
ifeq ($(CONFIG_NGINX_NAXSI),y)
ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src
endif
CONFIG_NGINX_LUA:=y
CONFIG_NGINX_DAV:=y
CONFIG_NGINX_UBUS:=y
- ADDITIONAL_MODULES += --with-http_ssl_module --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src \
+ ADDITIONAL_MODULES += --add-module=$(PKG_BUILD_DIR)/nginx-naxsi/naxsi_src \
--add-module=$(PKG_BUILD_DIR)/lua-nginx --with-ipv6 --with-http_stub_status_module --with-http_flv_module \
--with-http_dav_module --add-module=$(PKG_BUILD_DIR)/nginx-dav-ext-module \
--with-http_auth_request_module --with-http_v2_module --with-http_realip_module \
config_files += koi-utf koi-win win-utf fastcgi_params uwsgi_params
endif
-define Package/nginx-mod-luci/default
+define Package/nginx-mod-luci
TITLE:=Nginx on LuCI
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=Support file for Nginx
URL:=http://nginx.org/
- DEPENDS:=+uwsgi +uwsgi-luci-support
-endef
-
-define Package/nginx-mod-luci
- $(Package/nginx-mod-luci/default)
- DEPENDS += +nginx
+ DEPENDS:=+uwsgi +uwsgi-luci-support +nginx
+ # TODO: add PROVIDES when removing nginx-mod-luci-ssl
+ # PROVIDES:=nginx-mod-luci-ssl
endef
define Package/nginx-mod-luci/description
Support file for LuCI in nginx. Include custom nginx configuration, autostart script for uwsgi.
endef
-define Package/nginx-mod-luci-ssl
- $(Package/nginx-mod-luci/default)
- TITLE += with HTTPS support
- DEPENDS += +nginx-ssl
-endef
-
-Package/nginx-mod-luci-ssl/description = $(define Package/nginx-mod-luci/description) \
- This also include redirect from http to https and cert autogeneration.
TARGET_CFLAGS += -fvisibility=hidden -ffunction-sections -fdata-sections -DNGX_LUA_NO_BY_LUA_BLOCK
TARGET_LDFLAGS += -Wl,--gc-sections
$(INSTALL_BIN) ./files-luci-support/60_nginx-luci-support $(1)/etc/uci-defaults/60_nginx-luci-support
endef
-Package/nginx-mod-luci-ssl/install = $(Package/nginx-mod-luci/install)
-
-define Package/nginx/install
+define Package/nginx-ssl/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/nginx $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc/nginx/conf.d
endif
$(if $(CONFIG_NGINX_NAXSI),$($(INSTALL_BIN) $(PKG_BUILD_DIR)/nginx-naxsi/naxsi_config/naxsi_core.rules $(1)/etc/nginx))
$(if $(CONFIG_NGINX_NAXSI),$(chmod 0640 $(1)/etc/nginx/naxsi_core.rules))
-ifeq ($(CONFIG_NGINX_SSL),y)
- $(INSTALL_CONF) ./files/_redirect2ssl.conf $(1)/etc/nginx/conf.d/
-endif
-ifneq ($(CONFIG_IPV6),y)
- $(SED) '/listen\s*\[/d' $(1)/etc/nginx/conf.d/*.conf # without IPv6 [::]
-endif
-endef
-
-define Package/nginx-ssl/install
- $(call Package/nginx/install, $(1))
$(INSTALL_CONF) ./files/_redirect2ssl.conf $(1)/etc/nginx/conf.d/
ifneq ($(CONFIG_IPV6),y)
$(SED) '/listen\s*\[/d' $(1)/etc/nginx/conf.d/*.conf # without IPv6 [::]
define Package/nginx-ssl/prerm
#!/bin/sh
[ -z "$${IPKG_INSTROOT}" ] || exit 0
-if [ "$${PKG_UPGRADE}" = "1" ]; then
- eval $$(/usr/bin/nginx-util get_env)
- TMP_CRT=$$(mktemp -p "$${CONF_DIR}" "$${LAN_NAME}.crt.tmp-XXXXXX")
- ln -f "$${CONF_DIR}$${LAN_NAME}.crt" "$${TMP_CRT}"
- TMP_KEY=$$(mktemp -p "$${CONF_DIR}" "$${LAN_NAME}.key.tmp-XXXXXX")
- ln -f "$${CONF_DIR}$${LAN_NAME}.key" "$${TMP_KEY}"
-fi
-/usr/bin/nginx-util del_ssl
-[ -f "$${TMP_CRT}" ] &&
-rm -f "$${CONF_DIR}$${LAN_NAME}.crt" &&
-mv -f "$${TMP_CRT}" "$${CONF_DIR}$${LAN_NAME}.crt"
-[ -f "$${TMP_KEY}" ] &&
-rm -f "$${CONF_DIR}$${LAN_NAME}.key" &&
-mv -f "$${TMP_KEY}" "$${CONF_DIR}$${LAN_NAME}.key"
+[ "$${PKG_UPGRADE}" = "1" ] && exit 0
+eval $$(/usr/bin/nginx-util get_env)
+rm -f "$${CONF_DIR}$${LAN_NAME}.crt"
+rm -f "$${CONF_DIR}$${LAN_NAME}.key"
exit 0
endef
-ifeq ($(CONFIG_NGINX_SSL),y)
-Package/nginx/prerm = $(Package/nginx-ssl/prerm)
-endif
-
Package/nginx-all-module/prerm = $(Package/nginx-ssl/prerm)
define Build/Prepare
endef
endif
-$(eval $(call BuildPackage,nginx))
$(eval $(call BuildPackage,nginx-ssl))
$(eval $(call BuildPackage,nginx-all-module))
$(eval $(call BuildPackage,nginx-mod-luci))
+
+
+# TODO: remove after a transition period (together with pkg nginx-util):
+# It is for smoothly substituting nginx and nginx-mod-luci-ssl (by nginx-ssl
+# respectively nginx-mod-luci). Add above commented PROVIDES when removing.
+
+Package/nginx = $(Package/nginx-ssl)
+
+Package/nginx/install = $(Package/nginx-ssl/install)
+
+Package/nginx/prerm = $(Package/nginx-ssl/prerm)
+
+$(eval $(call BuildPackage,nginx))
+
+
+define Package/nginx-mod-luci-ssl
+ TITLE:=Dummy package for transition when upgrading.
+ DEPENDS:=+nginx-mod-luci
+ PKGARCH:=all
+endef
+
+define Package/nginx-mod-luci-ssl/install
+ $(INSTALL_DIR) $(1)/usr/bin
+endef
+
$(eval $(call BuildPackage,nginx-mod-luci-ssl))
* There is a ''${LAN_NAME}.conf'' containing a default server for the LAN, \
which includes all ''*.locations''.
* We can disable parts of the configuration by renaming them.
- * If we want to install other servers that are also reachable from the LAN, \
- we can include the ''${LAN_LISTEN}'' file (or ''${LAN_SSL_LISTEN}'' for \
- HTTPS servers).
- * If Nginx is installed with SSL support, we have a server \
-in ''_redirect2ssl.conf'' that redirects inexistent URLs to HTTPS, too.
+ * If we want to install other HTTPS servers that are also reachable locally, \
+ we can include the ''${LAN_SSL_LISTEN}'' file.
+ * We have a server in ''_redirect2ssl.conf'' that redirects inexistent URLs \
+ to HTTPS, too.
* We can create a self-signed certificate and add corresponding directives \
to e.g. ''${EXAMPLE_COM}.conf'' by invoking \
<code>$(basename ${NGINX_UTIL}) ${ADD_SSL_FCT} ${EXAMPLE_COM}</code>
We modify the configuration by creating different configuration files in the
''${CONF_DIR}'' directory.
The configuration files use the file extensions ''.locations'' and
-''.conf'' (plus ''.crt'' and ''.key'' for Nginx with SSL).
+''.conf'' plus ''.crt'' and ''.key'' for SSL certificates and keys.
We can disable single configuration parts by giving them another extension,
e.g., by adding ''.disabled''.
For the new configuration to take effect, we must reload it by:
since they are all included in the ''${LAN_NAME}.conf'' that is part of the
[[#openwrt_s_defaults|OpenWrt’s Defaults]].
We reserve the ''location /'' for making LuCI available under the root URL,
-e.g. [[http://192.168.1.1/|192.168.1.1/]].
+e.g. [[https://192.168.1.1/|192.168.1.1/]].
All other sites shouldn’t use the root ''location /'' without suffix.
We can make other sites available on the root URL of other domain names, e.g.
on www.example.com/.
In order to do that, we create a ''.conf'' file for every domain name:
see the next section [[#new_server_parts|New Server Parts]].
-For Nginx with SSL we can also activate SSL there, as described below in the
-section [[#ssl_server_parts|SSL Server Parts]].
+We can also activate SSL there, as described below in the section
+[[#ssl_server_parts|SSL Server Parts]].
We use such server parts also for publishing sites to the internet (WAN)
instead of making them available just in the LAN.
Then the site is reachable under the same path at both domains, e.g., by
http://192.168.1.1/ex/am/ple as well as by http://example.com/ex/am/ple.
-The [[#openwrt_s_defaults|OpenWrt’s Defaults]] include a ''${LAN_NAME}.conf''
-file containing a server part that listens on the LAN address(es) and acts as
-//default_server//.
-For making the domain name accessible in the LAN, too, the corresponding
-server part must listen **explicitly** on the local IP address(es), cf. the
-official documentation on
-[[https://nginx.org/en/docs/http/request_processing.html|request_processing]].
-We can include the file ''${LAN_LISTEN}'' that contains the listen
-directives for all LAN addresses on the HTTP port 80 and is automatically
-updated.
-
-The following example is a simple template, see
-[[https://github.com/search?q=repo%3Aopenwrt%2Fpackages
-+include+${LAN_LISTEN}+extension%3Aconf&type=Code|
-such server parts of other packages]], too:
+The following example is a simple template:
<code nginx ${CONF_DIR}${EXAMPLE_COM}.conf>
server {
listen 80;
listen [::]:80;
- include '${LAN_LISTEN}';
server_name ${EXAMPLE_COM};
# location / { … } # root location for this server.
include '${CONF_DIR}${EXAMPLE_COM}.locations';
see the official documentation for
[[https://nginx.org/en/docs/http/configuring_https_servers.html|
configuring HTTPS servers]], too.
-For making the domain available also in the LAN, we can include the file
-''${LAN_SSL_LISTEN}'' that contains the listen directives with ssl
-parameter for all LAN addresses on the HTTPS port 443 and is automatically
-updated.
+
+The [[#openwrt_s_defaults|OpenWrt’s Defaults]] include a ''${LAN_NAME}.conf''
+file containing a server part that listens on the LAN address(es) and acts as
+//default_server// with ssl on port 443.
+For making the domain name accessible in the LAN, too, the corresponding
+server part must listen **explicitly** on the local IP address(es), cf. the
+official documentation on
+[[https://nginx.org/en/docs/http/request_processing.html|request_processing]].
+We can include the file ''${LAN_SSL_LISTEN}'' that contains the listen
+directives with ssl parameter for all LAN addresses on the HTTP port 443 and is
+updated automatically.
The official documentation of the SSL module contains an
[[https://nginx.org/en/docs/http/ngx_http_ssl_module.html#example|
example]],
which includes some optimizations.
-The following template is extended similarly, see also
-[[https://github.com/search?q=repo%3Aopenwrt%2Fpackages
-+include+${LAN_SSL_LISTEN}+extension%3Aconf&type=Code|
-other packages providing SSL server parts]]:
+The following template is extended similarly:
<code nginx ${CONF_DIR}${EXAMPLE_COM}>
server {
listen 443 ssl;
This is needed especially for making them available to the WAN as described
above in the section [[#new_server_parts|New Server Parts]].
All ''.locations'' become available on the LAN through the file
-''$(basename ${LAN_LISTEN}).default'', which contains one of the following
+''$(basename ${LAN_SSL_LISTEN}).default'', which contains one of the following
directives for every local IP address:
<code nginx>
- listen IPv4:80 default_server;
- listen [IPv6]:80 default_server;
+ listen IPv4:443 ssl default_server;
+ listen [IPv6]:443 ssl default_server;
</code>
-The ''${LAN_LISTEN}'' file contains the same directives without the
+The ''${LAN_SSL_LISTEN}'' file contains the same directives without the
parameter ''default_server''.
We can include this file in other server parts that should be reachable in the
LAN through their //server_name//.
-Both files ''${LAN_LISTEN}{,.default}'' are (re-)created if Nginx starts
+Both files ''${LAN_SSL_LISTEN}{,.default}'' are (re-)created if Nginx starts
through its init for OpenWrt or the LAN interface changes.
-=== Additional Defaults for OpenWrt if Nginx is installed with SSL support ===
-
-When Nginx is installed with SSL support, there will be automatically managed
-files ''$(basename ${LAN_SSL_LISTEN}).default'' and
-''$(basename ${LAN_SSL_LISTEN})'' in the directory
-''$(dirname ${LAN_SSL_LISTEN})/'' containing the following directives for all
-IPv4 and IPv6 addresses of the LAN:
-<code nginx>
- listen IP:443 ssl; # with respectively without: default_server
-</code>
-Both files as well as the ''${LAN_LISTEN}{,.default}'' files are (re-)created
-if Nginx starts through its init for OpenWrt or the LAN interface changes.
-
-For Nginx with SSL there is also the following server part that redirects
-requests for an inexistent ''server_name'' from HTTP to HTTPS (using an invalid
-name, more in the official documentation on
+There is also the following server part that redirects requests for an
+inexistent ''server_name'' from HTTP to HTTPS (using an invalid name, more in
+the official documentation on
[[https://nginx.org/en/docs/http/request_processing.html|request_processing]]):
$(code ${CONF_DIR}_redirect2ssl.conf)
# default_server for the LAN addresses getting the IPs by:
# ifstatus lan | jsonfilter -e '@["ipv4-address","ipv6-address"].*.address'
server {
- include '/var/lib/nginx/lan.listen.default';
- server_name _lan;
- # access_log /proc/self/fd/1 openwrt; # use logd (init forwards stdout).
- include conf.d/*.locations;
+ server_name _lan;
+ include '/var/lib/nginx/lan_ssl.listen.default';
+ ssl_certificate '/etc/nginx/conf.d/_lan.crt';
+ ssl_certificate_key '/etc/nginx/conf.d/_lan.key';
+ ssl_session_cache 'shared:SSL:32k';
+ ssl_session_timeout '64m';
+ # access_log /proc/self/fd/1 openwrt; # use logd (init forwards stdout).
+ include conf.d/*.locations;
}
server {
listen 80;
listen [::]:80;
- include '/var/lib/nginx/lan.listen';
server_name _redirect2ssl;
return 302 https://$host$request_uri;
}
USE_PROCD=1
+G_OPTS="daemon off;"
+
NGINX_UTIL="/usr/bin/nginx-util"
eval $("${NGINX_UTIL}" get_env)
-start_service() {
+CONF=""
+
+
+nginx_init() {
+ [ -z "${CONF}" ] || return # already called.
+
[ -d /var/log/nginx ] || mkdir -p /var/log/nginx
[ -d /var/lib/nginx ] || mkdir -p /var/lib/nginx
${NGINX_UTIL} init_lan
+ CONF="${NGINX_CONF}"
+
+ local message
+ message="$(/usr/sbin/nginx -t -c "${CONF}" -g "${G_OPTS}" 2>&1)" ||
+ {
+ echo -e "${message}" | logger -t "nginx_init" -p "daemon.err"
+ logger -s -t "nginx_init" -p "daemon.err" "NOT using conf file!"
+ echo "show config to be used by: nginx -T -c '${CONF}'" >&2
+ exit 1
+ }
+
+ logger -t "nginx_init" -p "daemon.info" "using ${CONF} (the test is ok)"
+}
+
+
+start_service() {
+ nginx_init
+
procd_open_instance
- procd_set_param command /usr/sbin/nginx -c "${NGINX_CONF}" \
- -g "daemon off;"
+ procd_set_param command /usr/sbin/nginx -c "${CONF}" -g "${G_OPTS}"
procd_set_param stdout 1
procd_set_param stderr 1
- procd_set_param file "${LAN_LISTEN}" "${LAN_LISTEN}.default" \
- "${NGINX_CONF}" "${CONF_DIR}*.conf" "${CONF_DIR}*.locations"
- [ "${LAN_SSL_LISTEN}" == "" ] \
- || procd_append_param file "${CONF_DIR}*.crt" "${CONF_DIR}*.key" \
- "${LAN_SSL_LISTEN}" "${LAN_SSL_LISTEN}.default"
+ procd_set_param file "${CONF}" "${CONF_DIR}*.crt" "${CONF_DIR}*.key" \
+ "${CONF_DIR}*.conf" "${CONF_DIR}*.locations"
procd_set_param respawn
procd_close_instance
}
-stop_service() {
- rm -f "${LAN_LISTEN}" "${LAN_LISTEN}.default"
- [ "${LAN_SSL_LISTEN}" == "" ] \
- || rm -f "${LAN_SSL_LISTEN}" "${LAN_SSL_LISTEN}.default"
-}
service_triggers() {
procd_add_reload_interface_trigger loopback
procd_add_reload_interface_trigger lan
}
-reload_service() {
- [ -d /var/log/nginx ] || mkdir -p /var/log/nginx
- [ -d /var/lib/nginx ] || mkdir -p /var/lib/nginx
- ${NGINX_UTIL} init_lan
+reload_service() {
+ nginx_init
procd_send_signal nginx
}
+
relog() {
[ -d /var/log/nginx ] || mkdir -p /var/log/nginx
procd_send_signal nginx '*' USR1
}
+
EXTRA_COMMANDS="relog"
EXTRA_HELP=" relog Reopen log files (without reloading)"
include $(TOPDIR)/rules.mk
PKG_NAME:=nlbwmon
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/jow-/nlbwmon.git
SECTION:=net
CATEGORY:=Network
DEPENDS:=+libubox +libnl-tiny +zlib +kmod-nf-conntrack-netlink
- TITLE:=LEDE Traffic Usage Monitor
+ TITLE:=OpenWrt Traffic Usage Monitor
endef
define Package/nlbwmon/install
$(INSTALL_BIN) ./files/nlbwmon.init $(1)/etc/init.d/nlbwmon
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_CONF) ./files/nlbwmon.config $(1)/etc/config/nlbwmon
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface
+ $(INSTALL_BIN) ./files/nlbwmon.hotplug $(1)/etc/hotplug.d/iface/30-nlbwmon
endef
define Package/nlbwmon/conffiles
--- /dev/null
+#!/bin/sh
+
+[ -n "$DEVICE" ] || exit 0
+
+[ "$ACTION" = ifup ] && /etc/init.d/nlbwmon enabled && {
+ /etc/init.d/nlbwmon reload
+ logger -t nlbwmon "Reloading nlbwmon due to $ACTION of $INTERFACE ($DEVICE)"
+}
+
PKG_NAME:=ola
PKG_VERSION:=0.10.7
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/OpenLightingProject/ola/tar.gz/$(PKG_VERSION)?
CONFIGURE_VARS += \
require_gnu_plus_plus_11=yes
-HOST_LDFLAGS += -Wl,-rpath="$(STAGING_DIR_HOSTPKG)/lib"
+HOST_LDFLAGS += -Wl,-rpath$(comma)$(STAGING_DIR_HOSTPKG)/lib
TARGET_LDFLAGS += $(if $(CONFIG_USE_GLIBC),-lm)
# only build the ola_protoc thingy
PKG_NAME:=openfortivpn
PKG_VERSION:=1.14.1
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/adrienverge/openfortivpn/tar.gz/v$(PKG_VERSION)?
#!/bin/sh
+. /lib/functions.sh
. /usr/share/libubox/jshn.sh
[ "$ACTION" != ifup ] && exit
-networks=$(uci show network | sed "s/network.\([^.]*\).proto='openfortivpn'/\1/;t;d")
-for i in $networks; do
- iface=$(uci get "network.${i}.iface_name")
- iface_success=$?
- [ $? -eq 0 ] && [ $INTERFACE == "$iface" ] && {
- logger -t "openfortivpnhotplug" "$ACTION on $INTERFACE to bring up $i"
- json_load "$(ifstatus $i)"
+handle_network()
+{
+ config_get iface $1 iface_name
+ [ $INTERFACE != "$iface" ] && return
+ [ $(config_get $1 proto) != "openfortivpn" ] && return
+
+ config_get_bool load_on_boot $1 auto
+ [ -n "$load_on_boot" ] && [ "$load_on_boot" -eq 0 ] && return
+ status="$(ifstatus $1)" || continue
+ json_load "$status"
json_get_var autostart autostart
+ logger -t "openfortivpnhotplug" "$ACTION on $INTERFACE to bring up $1. Autostart is $autostart"
[ "$autostart" -eq 0 ] && {
- logger -t "openfortivpnhotplug" "auto-start was false. bringing $i up"
- ubus call network.interface up "{ \"interface\" : \"$i\" }"
+ logger -t "openfortivpnhotplug" "auto-start was false. bringing $1 up"
+ ubus call network.interface up "{ \"interface\" : \"$1\" }"
}
- }
-done
+}
+
+
+config_load network
+config_foreach handle_network interface
+exit 0
# file from cmd and to daemonize
# $1 password file
-# $2... are passed to openconnect
+# $2 is the config name
+# $3... are passed to openconnect
test -z "$1" && exit 1
-pwfile=$1
-shift
-exec /usr/sbin/openfortivpn "$@" < $pwfile
\ No newline at end of file
+pwfile=$1; shift
+config=$1; shift
+killed=0
+
+trap_with_arg() {
+ func="$1" ; shift
+ for sig ; do
+ trap "$func $sig" "$sig"
+ done
+}
+
+func_trap() {
+ logger "openfortivpn-wrapper[$$]" "$config: sending signal ${1}"
+ killed=1
+ kill -${1} $child 2>/dev/null
+}
+
+trap_with_arg func_trap INT TERM KILL
+
+
+start_time=$(date '+%s')
+/usr/sbin/openfortivpn "$@" < $pwfile 2>/dev/null &
+child=$!
+wait $child || {
+ [ "$killed" = 1 ] && exit 0
+ current_time=$(date '+%s')
+ elapsed=$(($current_time-$start_time))
+ . /lib/netifd/netifd-proto.sh
+ proto_notify_error "$config" "Failed to connect after $elapsed seconds."
+ proto_block_restart "$config"
+ exit 1
+}
#!/bin/sh
. /lib/functions.sh
+. /lib/functions/network.sh
. ../netifd-proto.sh
init_proto "$@"
proto_config_add_string "username"
proto_config_add_string "password"
proto_config_add_string "trusted_cert"
- proto_config_add_string "remote_status_check"
- proto_config_add_int "peerdns"
- proto_config_add_int "metric"
+ proto_config_add_string "remote_status_check"
no_device=1
available=1
}
proto_openfortivpn_setup() {
- local config="$1"
- local msg
+ local config="$1"
+
+ local msg ifname ip server_ip pwfile callfile
+ local host server port iface_name local_ip username password trusted_cert \
+ remote_status_check
json_get_vars host server port iface_name local_ip username password trusted_cert \
- remote_status_check peerdns metric
+ remote_status_check
ifname="vpn-$config"
[ -n "$iface_name" ] && {
- json_load "$(ifstatus $iface_name)"
- json_get_var iface_device_name l3_device
- json_get_var iface_device_up up
- }
-
- [ "$iface_device_up" -eq 1 ] || {
- msg="$iface_name is not up $iface_device_up"
- logger -t "openfortivpn" "$config: $msg"
- proto_notify_error "$config" "$msg"
- proto_block_restart "$config"
- exit 1
- }
+ network_get_device iface_device_name "$iface_name"
+ network_is_up "$iface_name" || {
+ msg="$iface_name is not up $iface_device_up"
+ logger -t "openfortivpn" "$config: $msg"
+ proto_notify_error "$config" "$msg"
+ proto_block_restart "$config"
+ exit 1
+ }
+ }
- server_ip=$(resolveip -t 10 "$server")
+ server_ip=$(resolveip -4 -t 10 "$server")
[ $? -eq 0 ] || {
msg="$config: failed to resolve server ip for $server"
}
}
- for ip in $(resolveip -t 10 "$server"); do
+ for ip in $(resolveip -4 -t 10 "$server"); do
logger -p 6 -t "openfortivpn" "$config: adding host dependency for $ip on $iface_name at $config"
proto_add_host_dependency "$config" "$ip" "$iface_name"
done
[ -n "$port" ] && port=":$port"
- [ -z "$peerdns" ] && peerdns=1
-
append_args "$server$port" --pppd-ifname="$ifname" --use-syslog -c /dev/null
append_args "--set-dns=0"
append_args "--no-routes"
- append_args "--pppd-use-peerdns=$peerdns"
+ append_args "--pppd-use-peerdns=1"
[ -n "$iface_name" ] && {
append_args "--ifname=$iface_device_name"
[ -n "$username" ] && append_args -u "$username"
[ -n "$password" ] && {
umask 077
- mkdir -p /var/etc
+ mkdir -p '/var/etc/openfortivpn'
pwfile="/var/etc/openfortivpn/$config.passwd"
echo "$password" > "$pwfile"
}
- [ -n "$local_ip" ] || local_ip=192.0.2.1
+ [ -n "$local_ip" ] || local_ip=$server_ip
[ -e '/etc/ppp/peers' ] || mkdir -p '/etc/ppp/peers'
[ -e '/etc/ppp/peers/openfortivpn' ] || {
- ln -s -T '/var/etc/openfortivpn/peers' '/etc/ppp/peers/openfortivpn'
+ ln -s -T '/var/etc/openfortivpn/peers' '/etc/ppp/peers/openfortivpn' 2> /dev/null
mkdir -p '/var/etc/openfortivpn/peers'
}
default-asyncmap
nopcomp
receive-all
-defaultroute
nodetach
ipparam $config
lcp-max-configure 40
mru 1354" > $callfile
append_args "--pppd-call=openfortivpn/$config"
- proto_export INTERFACE="$ifname"
logger -p 6 -t openfortivpn "$config: executing 'openfortivpn $cmdline'"
-
- eval "proto_run_command '$config' /usr/sbin/openfortivpn-wrapper '$pwfile' $cmdline"
+ eval "proto_run_command '$config' /usr/sbin/openfortivpn-wrapper '$pwfile' '$config' $cmdline"
}
#
PKG_NAME:=openvswitch
PKG_VERSION:=$(ovs_version)
-PKG_RELEASE:=5
+PKG_RELEASE:=9
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.openvswitch.org/releases/
PKG_HASH:=dd5f727427e36cab22bdeae61529d8c8fccacc53d968cfa7658f7f935ddda531
ovs_kmod_openvswitch-lisp-intree_files:= $(ovs_kmod_intree_dir)/vport-lisp.ko
$(eval $(call OvsKmodPackageTemplate,openvswitch-lisp-intree))
-ovs_common_depends:= +libatomic +libunbound +libunwind
-
# Dependency review
#
# for f in sbin/*; do echo $f; readelf -d $f | grep -i shared; done
#
ovs_libopenvswitch_title:=Open vSwitch (libopenvswitch.so)
ovs_libopenvswitch_hidden:=1
-ovs_libopenvswitch_depends:=+libopenssl +librt
+ovs_libopenvswitch_depends:=+libopenssl +libunbound +!(arc||arceb):libunwind
+ovs_libopenvswitch_depends+=+libatomic
ovs_libopenvswitch_files:=usr/lib/libopenvswitch*.so*
$(eval $(call OvsPackageTemplate,libopenvswitch))
ovs_libofproto_title:=Open vSwitch (libofproto.so libsflow.so)
ovs_libofproto_hidden:=1
-ovs_libofproto_depends:=+librt
+ovs_libofproto_depends+=+libatomic
ovs_libofproto_files:=usr/lib/libofproto*.so* usr/lib/libsflow*.so*
$(eval $(call OvsPackageTemplate,libofproto))
ovs_libovsdb_title:=Open vSwitch (libovsdb.so)
ovs_libovsdb_hidden:=1
-ovs_libovsdb_depends:=+librt
+ovs_libovsdb_depends+=+libatomic
ovs_libovsdb_files:=usr/lib/libovsdb*.so*
$(eval $(call OvsPackageTemplate,libovsdb))
ovs_vswitchd_title:=Open vSwitch (ovs-vswitchd)
ovs_vswitchd_hidden:=1
-ovs_vswitchd_depends:=+librt +openvswitch-libopenvswitch +openvswitch-libofproto
+ovs_vswitchd_depends:=+openvswitch-libopenvswitch +openvswitch-libofproto
+ovs_vswitchd_depends+=+libatomic
ovs_vswitchd_files:=usr/sbin/ovs-vswitchd
$(eval $(call OvsPackageTemplate,vswitchd))
ovs_ovsdb_title:=Open vSwitch (ovsdb-server)
ovs_ovsdb_hidden:=1
-ovs_ovsdb_depends:=+librt +openvswitch-libopenvswitch +openvswitch-libovsdb
+ovs_ovsdb_depends:=+openvswitch-libopenvswitch +openvswitch-libovsdb
+ovs_ovsdb_depends+=+libatomic
ovs_ovsdb_files:=usr/sbin/ovsdb-server
$(eval $(call OvsPackageTemplate,ovsdb))
ovs_common_title:=Open vSwitch (common files)
ovs_common_hidden:=1
-ovs_common_depends:=+librt +openvswitch-libopenvswitch +openvswitch-libofproto +openvswitch-libovsdb
+ovs_common_depends:=+openvswitch-libopenvswitch +openvswitch-libofproto +openvswitch-libovsdb
+ovs_common_depends+=+libatomic
ovs_common_files:= \
usr/share/openvswitch/scripts/ovs-lib \
usr/share/openvswitch/scripts/ovs-ctl \
# uuidgen is required for generating system-id
ovs_openvswitch_title:=Open vSwitch
ovs_openvswitch_hidden:=
-ovs_openvswitch_depends:=+librt +coreutils +coreutils-sleep +uuidgen \
+ovs_openvswitch_depends:=+coreutils +coreutils-sleep +uuidgen \
+openvswitch-common +openvswitch-vswitchd +openvswitch-ovsdb +kmod-openvswitch
+ovs_openvswitch_depends+=+libatomic
ovs_openvswitch_files:= usr/share/openvswitch/vswitch.ovsschema
$(eval $(call OvsPackageTemplate,openvswitch))
opkg remove --force-depends kmod-openvswitch-intree
opkg install kmod-openvswitch
ovs-ctl force-reload-kmod
+
+# UCI configuration options
+
+There are 4 config section types in package openvswitch:
+ovs ovn_northd, ovn_controller & ovs_bridge.
+
+Each of these supports a disabled option, which should be
+set to 0 to launch the respective daemons.
+
+The ovs_bridge section also supports the options below,
+for initialising a virtual bridge with an OpenFlow controller.
+
+| Name | Type | Required | Default | Description |
+|------------|---------|----------|--------------------------------|------------------------------------------------------------|
+| disabled | boolean | no | 0 | If set to true, disable initialisation of the named bridge |
+| name | string | no | Inherits UCI config block name | The name of the switch in the OVS daemon |
+| controller | string | no | (none) | The endpoint of an OpenFlow controller for this bridge |
config ovn_controller controller
option disabled 1
+
+config ovs_bridge
+ option disabled 1
+ option name 'my-bridge'
+ option controller 'tcp:192.168.0.1'
\ No newline at end of file
for cfgtype in ovs ovn_northd ovn_controller; do
config_foreach "ovs_xx" "$cfgtype" "$action" "$cfgtype"
done
+
+ config_foreach ovs_bridge_init "ovs_bridge"
}
ovs_xx() {
status|stop) ;;
*)
config_get_bool disabled "$cfg" disabled 0
- [ "$disabled" -le 0 ] || return
+ [ "$disabled" == "0" ] || return
;;
esac
;;
esac
}
+
+ovs_bridge_init() {
+ local cfg="$1"
+
+ local disabled
+ local name
+ local controller
+
+ config_get_bool disabled "$cfg" disabled 0
+ [ "$disabled" == "0" ] || return
+
+ config_get name "$cfg" name $cfg
+ ovs-vsctl --may-exist add-br "$name"
+
+ config_get controller "$cfg" controller
+ [ -n "$controller" ] && \
+ ovs-vsctl set-controller "$name" "$controller"
+}
# Shared vars, macros
-ovs_common_depends:=
ovs_packages:=
ovs_package_name=$(if $(filter openvswitch,$(1)),openvswitch,openvswitch-$(1))
URL:=https://www.openvswitch.org
TITLE:=$(ovs_$(1)_title)
HIDDEN:=$(ovs_$(1)_hidden)
- DEPENDS:=$(ovs_$(1)_depends) $(ovs_common_depends)
+ DEPENDS:=$(ovs_$(1)_depends)
endef
define Package/$(call ovs_package_name,$(1))/install
--- /dev/null
+From ab78cc673ebf8e13558fdde459d74538e8cf0760 Mon Sep 17 00:00:00 2001
+From: Yi-Hung Wei <yihung.wei@gmail.com>
+Date: Wed, 29 Apr 2020 14:25:50 -0700
+Subject: [PATCH] compat: Fix ipv6_dst_lookup build error
+
+The geneve/vxlan compat code base invokes ipv6_dst_lookup() which is
+recently replaced by ipv6_dst_lookup_flow() in the stable kernel tree.
+
+This causes travis build failure:
+ * https://travis-ci.org/github/openvswitch/ovs/builds/681084038
+
+This patch updates the backport logic to invoke the right function.
+
+Related patch in
+ git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
+
+b9f3e457098e ("net: ipv6_stub: use ip6_dst_lookup_flow instead of
+ ip6_dst_lookup")
+
+Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
+Signed-off-by: William Tu <u9012063@gmail.com>
+---
+ acinclude.m4 | 3 +++
+ datapath/linux/compat/geneve.c | 11 +++++++----
+ datapath/linux/compat/vxlan.c | 14 ++++++++------
+ 3 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/acinclude.m4 b/acinclude.m4
+index c1470ccc6..ebe8b43b5 100644
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -569,7 +569,10 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
+
+ OVS_GREP_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_dst_lookup.*net],
+ [OVS_DEFINE([HAVE_IPV6_DST_LOOKUP_NET])])
++ OVS_GREP_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_dst_lookup_flow.*net],
++ [OVS_DEFINE([HAVE_IPV6_DST_LOOKUP_FLOW_NET])])
+ OVS_GREP_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_stub])
++ OVS_GREP_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_dst_lookup_flow])
+
+ OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [ERR_CAST])
+ OVS_GREP_IFELSE([$KSRC/include/linux/err.h], [IS_ERR_OR_NULL])
+diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
+index c044b1489..4bdab6836 100644
+--- a/datapath/linux/compat/geneve.c
++++ b/datapath/linux/compat/geneve.c
+@@ -962,14 +962,17 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
+ return dst;
+ }
+
+-#ifdef HAVE_IPV6_DST_LOOKUP_NET
++#if defined(HAVE_IPV6_DST_LOOKUP_FLOW_NET)
++ if (ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, &dst,
++ fl6)) {
++#elif defined(HAVE_IPV6_DST_LOOKUP_FLOW)
++ if (ipv6_stub->ipv6_dst_lookup_flow(gs6->sock->sk, &dst, fl6)) {
++#elif defined(HAVE_IPV6_DST_LOOKUP_NET)
+ if (ipv6_stub->ipv6_dst_lookup(geneve->net, gs6->sock->sk, &dst, fl6)) {
+-#else
+-#ifdef HAVE_IPV6_STUB
++#elif defined(HAVE_IPV6_STUB)
+ if (ipv6_stub->ipv6_dst_lookup(gs6->sock->sk, &dst, fl6)) {
+ #else
+ if (ip6_dst_lookup(gs6->sock->sk, &dst, fl6)) {
+-#endif
+ #endif
+ netdev_dbg(dev, "no route to %pI6\n", &fl6->daddr);
+ return ERR_PTR(-ENETUNREACH);
+diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
+index 23118e8b6..ff10ae6f4 100644
+--- a/datapath/linux/compat/vxlan.c
++++ b/datapath/linux/compat/vxlan.c
+@@ -990,17 +990,19 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
+ fl6.fl6_dport = dport;
+ fl6.fl6_sport = sport;
+
+-#ifdef HAVE_IPV6_DST_LOOKUP_NET
+- err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
+- sock6->sock->sk,
++#if defined(HAVE_IPV6_DST_LOOKUP_FLOW_NET)
++ err = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk,
++ &ndst, &fl6);
++#elif defined(HAVE_IPV6_DST_LOOKUP_FLOW)
++ err = ipv6_stub->ipv6_dst_lookup_flow(sock6->sock->sk, &ndst, &fl6);
++#elif defined(HAVE_IPV6_DST_LOOKUP_NET)
++ err = ipv6_stub->ipv6_dst_lookup(vxlan->net, sock6->sock->sk,
+ &ndst, &fl6);
+-#else
+-#ifdef HAVE_IPV6_STUB
++#elif defined(HAVE_IPV6_STUB)
+ err = ipv6_stub->ipv6_dst_lookup(vxlan->vn6_sock->sock->sk,
+ &ndst, &fl6);
+ #else
+ err = ip6_dst_lookup(vxlan->vn6_sock->sock->sk, &ndst, &fl6);
+-#endif
+ #endif
+ if (err < 0)
+ return ERR_PTR(err);
--- /dev/null
+From 28f52edd7f6978fcd97442312122543bae32597d Mon Sep 17 00:00:00 2001
+From: Greg Rose <gvrose8192@gmail.com>
+Date: Thu, 21 May 2020 14:54:03 -0700
+Subject: [PATCH] compat: Backport ipv6_stub change
+
+A patch backported to the Linux stable 4.14 tree and present in the
+latest stable 4.14.181 kernel breaks ipv6_stub usage.
+
+The commit is
+8ab8786f78c3 ("net ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup").
+
+Create the compat layer define to check for it and fixup usage in vxlan
+and geneve modules.
+
+Passes Travis here:
+https://travis-ci.org/github/gvrose8192/ovs-experimental/builds/689798733
+
+Signed-off-by: Greg Rose <gvrose8192@gmail.com>
+Signed-off-by: William Tu <u9012063@gmail.com>
+---
+ acinclude.m4 | 2 ++
+ datapath/linux/compat/geneve.c | 11 ++++++++++-
+ datapath/linux/compat/vxlan.c | 18 +++++++++++++++++-
+ 3 files changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/acinclude.m4 b/acinclude.m4
+index ebe8b43b5..c47a77ed6 100644
+--- a/acinclude.m4
++++ b/acinclude.m4
+@@ -567,6 +567,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
+ OVS_GREP_IFELSE([$KSRC/include/net/ip6_fib.h], [rt6_get_cookie],
+ [OVS_DEFINE([HAVE_RT6_GET_COOKIE])])
+
++ OVS_FIND_FIELD_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_stub],
++ [dst_entry])
+ OVS_GREP_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_dst_lookup.*net],
+ [OVS_DEFINE([HAVE_IPV6_DST_LOOKUP_NET])])
+ OVS_GREP_IFELSE([$KSRC/include/net/addrconf.h], [ipv6_dst_lookup_flow.*net],
+diff --git a/datapath/linux/compat/geneve.c b/datapath/linux/compat/geneve.c
+index 4bdab6836..bf995aa83 100644
+--- a/datapath/linux/compat/geneve.c
++++ b/datapath/linux/compat/geneve.c
+@@ -962,7 +962,16 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
+ return dst;
+ }
+
+-#if defined(HAVE_IPV6_DST_LOOKUP_FLOW_NET)
++#if defined(HAVE_IPV6_STUB_WITH_DST_ENTRY) && defined(HAVE_IPV6_DST_LOOKUP_FLOW)
++#ifdef HAVE_IPV6_DST_LOOKUP_FLOW_NET
++ dst = ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, fl6,
++ NULL);
++#else
++ dst = ipv6_stub->ipv6_dst_lookup_flow(gs6->sock->sk, fl6,
++ NULL);
++#endif
++ if (IS_ERR(dst)) {
++#elif defined(HAVE_IPV6_DST_LOOKUP_FLOW_NET)
+ if (ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, &dst,
+ fl6)) {
+ #elif defined(HAVE_IPV6_DST_LOOKUP_FLOW)
+diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c
+index ff10ae6f4..05ccfb928 100644
+--- a/datapath/linux/compat/vxlan.c
++++ b/datapath/linux/compat/vxlan.c
+@@ -967,7 +967,10 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
+ bool use_cache = (dst_cache && ip_tunnel_dst_cache_usable(skb, info));
+ struct dst_entry *ndst;
+ struct flowi6 fl6;
++#if !defined(HAVE_IPV6_STUB_WITH_DST_ENTRY) || \
++ !defined(HAVE_IPV6_DST_LOOKUP_FLOW)
+ int err;
++#endif
+
+ if (!sock6)
+ return ERR_PTR(-EIO);
+@@ -990,7 +993,15 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
+ fl6.fl6_dport = dport;
+ fl6.fl6_sport = sport;
+
+-#if defined(HAVE_IPV6_DST_LOOKUP_FLOW_NET)
++#if defined(HAVE_IPV6_STUB_WITH_DST_ENTRY) && defined(HAVE_IPV6_DST_LOOKUP_FLOW)
++#ifdef HAVE_IPV6_DST_LOOKUP_FLOW_NET
++ ndst = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk,
++ &fl6, NULL);
++#else
++ ndst = ipv6_stub->ipv6_dst_lookup_flow(sock6->sock->sk, &fl6, NULL);
++#endif
++ if (unlikely(IS_ERR(ndst))) {
++#elif defined(HAVE_IPV6_DST_LOOKUP_FLOW_NET)
+ err = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk,
+ &ndst, &fl6);
+ #elif defined(HAVE_IPV6_DST_LOOKUP_FLOW)
+@@ -1004,8 +1015,13 @@ static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
+ #else
+ err = ip6_dst_lookup(vxlan->vn6_sock->sock->sk, &ndst, &fl6);
+ #endif
++#if defined(HAVE_IPV6_STUB_WITH_DST_ENTRY) && defined(HAVE_IPV6_DST_LOOKUP_FLOW)
++ return ERR_PTR(-ENETUNREACH);
++ }
++#else
+ if (err < 0)
+ return ERR_PTR(err);
++#endif
+
+ *saddr = fl6.saddr;
+ if (use_cache)
--- /dev/null
+From 6324f0c594e3773c754861e630fff694d1bec15a Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech@gmail.com>
+Date: Wed, 29 Jul 2020 17:29:14 +0800
+Subject: [PATCH] build: only link libopenvswitch with libunwind, libunbound
+
+Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
+---
+ lib/automake.mk | 2 ++
+ lib/libopenvswitch.pc.in | 2 +-
+ m4/openvswitch.m4 | 6 ++++--
+ 3 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/lib/automake.mk b/lib/automake.mk
+index 95925b57c..df95bea10 100644
+--- a/lib/automake.mk
++++ b/lib/automake.mk
+@@ -10,6 +10,8 @@ lib_LTLIBRARIES += lib/libopenvswitch.la
+ lib_libopenvswitch_la_LIBADD = $(SSL_LIBS)
+ lib_libopenvswitch_la_LIBADD += $(CAPNG_LDADD)
+ lib_libopenvswitch_la_LIBADD += $(LIBBPF_LDADD)
++lib_libopenvswitch_la_LIBADD += $(LIBUNBOUND_LDADD)
++lib_libopenvswitch_la_LIBADD += $(LIBUNWIND_LDADD)
+
+ if WIN32
+ lib_libopenvswitch_la_LIBADD += ${PTHREAD_LIBS}
+diff --git a/lib/libopenvswitch.pc.in b/lib/libopenvswitch.pc.in
+index 2a3f2ca7b..c8d02eb5a 100644
+--- a/lib/libopenvswitch.pc.in
++++ b/lib/libopenvswitch.pc.in
+@@ -7,5 +7,5 @@ Name: libopenvswitch
+ Description: Open vSwitch library
+ Version: @VERSION@
+ Libs: -L${libdir} -lopenvswitch
+-Libs.private: @LIBS@
++Libs.private: @LIBS@ @SSL_LIBS@ @CAPNG_LDADD@ @LIBBPF_LDADD@ @LIBUNBOUND_LDADD@ @LIBUNWIND_LDADD@
+ Cflags: -I${includedir}/openvswitch
+diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4
+index ada31c491..6165cc7b1 100644
+--- a/m4/openvswitch.m4
++++ b/m4/openvswitch.m4
+@@ -623,7 +623,8 @@ AC_DEFUN([OVS_CHECK_UNBOUND],
+ [AC_CHECK_LIB(unbound, ub_ctx_create, [HAVE_UNBOUND=yes], [HAVE_UNBOUND=no])
+ if test "$HAVE_UNBOUND" = yes; then
+ AC_DEFINE([HAVE_UNBOUND], [1], [Define to 1 if unbound is detected.])
+- LIBS="$LIBS -lunbound"
++ LIBUNBOUND_LDADD="-lunbound"
++ AC_SUBST(LIBUNBOUND_LDADD)
+ fi
+ AM_CONDITIONAL([HAVE_UNBOUND], [test "$HAVE_UNBOUND" = yes])
+ AC_SUBST([HAVE_UNBOUND])])
+@@ -635,7 +636,8 @@ AC_DEFUN([OVS_CHECK_UNWIND],
+ [HAVE_UNWIND=no])
+ if test "$HAVE_UNWIND" = yes; then
+ AC_DEFINE([HAVE_UNWIND], [1], [Define to 1 if unwind is detected.])
+- LIBS="$LIBS -lunwind"
++ LIBUNWIND_LDADD="-lunwind"
++ AC_SUBST(LIBUNWIND_LDADD)
+ fi
+ AM_CONDITIONAL([HAVE_UNWIND], [test "$HAVE_UNWIND" = yes])
+ AC_SUBST([HAVE_UNWIND])])
PKG_NAME:=ovn
PKG_VERSION:=20.06.1
-PKG_RELEASE:=1
+PKG_RELEASE:=3
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/ovn-org/ovn.git
include $(INCLUDE_DIR)/package.mk
include ../../lang/python/python3-host.mk
-ovs_common_depends:= +libatomic +libunbound
-
ovs_libovn_title:=Open vSwitch (libovn.so)
ovs_libovn_hidden:=1
-ovs_libovn_depends:=+librt
+ovs_libovn_depends+=+libatomic
ovs_libovn_files:=usr/lib/libovn*.so*
$(eval $(call OvsPackageTemplate,libovn))
ovs_ovn-common_title:=Open Virtual Network (common files)
ovs_ovn-common_hidden:=1
-ovs_ovn-common_depends:=+librt +openvswitch-common +openvswitch-libopenvswitch +openvswitch-libovn +openvswitch-libovsdb
+ovs_ovn-common_depends:=+openvswitch-common +openvswitch-libopenvswitch +openvswitch-libovn +openvswitch-libovsdb
+ovs_ovn-common_depends+=+libatomic
ovs_ovn-common_files:= \
usr/share/ovn/scripts/ovn-ctl \
usr/share/ovn/scripts/ovn-lib \
ovs_ovn-north_title:=Open Virtual Network (north package)
ovs_ovn-north_hidden:=
ovs_ovn-north_depends:=+openvswitch-ovsdb +openvswitch-ovn-common
+ovs_ovn-north_depends+=+libatomic
ovs_ovn-north_files:=\
usr/share/ovn/ovn-nb.ovsschema \
usr/share/ovn/ovn-sb.ovsschema \
ovs_ovn-host_title:=Open Virtual Network (chassis package)
ovs_ovn-host_hidden:=
ovs_ovn-host_depends:=+openvswitch +openvswitch-ovn-common
+ovs_ovn-host_depends+=+libatomic
ovs_ovn-host_files:=usr/bin/ovn-controller
$(eval $(call OvsPackageTemplate,ovn-host))
+++ /dev/null
-From d048a1e98363197c0d2609f6adb6919bde473df4 Mon Sep 17 00:00:00 2001
-From: Yousong Zhou <yszhou4tech@gmail.com>
-Date: Mon, 23 Mar 2020 14:18:30 +0800
-Subject: [PATCH] build: skip building tests
-
-Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
----
- Makefile.am | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/Makefile.am b/Makefile.am
-index 04400e184..b2c42d84c 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -492,7 +492,6 @@ include Documentation/automake.mk
- include m4/automake.mk
- include lib/automake.mk
- include utilities/automake.mk
--include tests/automake.mk
- include include/automake.mk
- include third-party/automake.mk
- include debian/automake.mk
--- /dev/null
+From f3cc8c83993486b9d35557f2bd85038d5bb96bc5 Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech@gmail.com>
+Date: Wed, 29 Jul 2020 20:09:56 +0800
+Subject: [PATCH] build: skip check and use of libunbound
+
+Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
+---
+ configure.ac | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 2bcd1945b..ad550fff8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -130,7 +130,6 @@ OVS_CHECK_LINUX_HOST
+ OVS_LIBTOOL_VERSIONS
+ OVS_CHECK_CXX
+ AX_FUNC_POSIX_MEMALIGN
+-OVN_CHECK_UNBOUND
+
+ OVS_CHECK_INCLUDE_NEXT([stdio.h string.h])
+ AC_CONFIG_FILES([lib/libovn.sym])
--- /dev/null
+From cea7c74ecc4a0843f29ce1882d7876fff199a721 Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech@gmail.com>
+Date: Mon, 23 Mar 2020 14:18:30 +0800
+Subject: [PATCH] build: skip tests and docs
+
+Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
+---
+ Makefile.am | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 04400e184..c12cfcd11 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -488,11 +488,9 @@ dist-docs:
+
+
+ include automake.mk
+-include Documentation/automake.mk
+ include m4/automake.mk
+ include lib/automake.mk
+ include utilities/automake.mk
+-include tests/automake.mk
+ include include/automake.mk
+ include third-party/automake.mk
+ include debian/automake.mk
+++ /dev/null
-From ecf232bf32dd433642bb9da2ac0c2de483b8736a Mon Sep 17 00:00:00 2001
-From: Yousong Zhou <yszhou4tech@gmail.com>
-Date: Mon, 23 Mar 2020 15:54:26 +0800
-Subject: [PATCH] ovn-lib: fix install_dir()
-
-The command "install" is not available in OpenWrt by default
-
-Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
----
- utilities/ovn-lib.in | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/utilities/ovn-lib.in b/utilities/ovn-lib.in
-index af1b72edb..f6ab5581c 100644
---- a/utilities/ovn-lib.in
-+++ b/utilities/ovn-lib.in
-@@ -54,7 +54,10 @@ ovn_install_dir () {
- [ "${OVN_USER##*:}" != "" ] && INSTALL_GROUP="${OVN_USER##*:}"
-
- if test ! -d "$DIR"; then
-- install -d -m "$INSTALL_MODE" -o "$INSTALL_USER" -g "$INSTALL_GROUP" "$DIR"
-+ mkdir -p "$DIR"
-+ chmod "$INSTALL_MODE" "$DIR"
-+ chown "$INSTALL_USER" "$DIR"
-+ chgrp "$INSTALL_GROUP" "$DIR"
- restorecon "$DIR" >/dev/null 2>&1
- fi
- }
--- /dev/null
+From 7385d1e67dda100853cf748034220cdbed6b3d7c Mon Sep 17 00:00:00 2001
+From: Yousong Zhou <yszhou4tech@gmail.com>
+Date: Mon, 23 Mar 2020 15:54:26 +0800
+Subject: [PATCH] ovn-lib: fix install_dir()
+
+The command "install" is not available in OpenWrt by default
+
+Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
+---
+ utilities/ovn-lib.in | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/utilities/ovn-lib.in b/utilities/ovn-lib.in
+index af1b72edb..f6ab5581c 100644
+--- a/utilities/ovn-lib.in
++++ b/utilities/ovn-lib.in
+@@ -54,7 +54,10 @@ ovn_install_dir () {
+ [ "${OVN_USER##*:}" != "" ] && INSTALL_GROUP="${OVN_USER##*:}"
+
+ if test ! -d "$DIR"; then
+- install -d -m "$INSTALL_MODE" -o "$INSTALL_USER" -g "$INSTALL_GROUP" "$DIR"
++ mkdir -p "$DIR"
++ chmod "$INSTALL_MODE" "$DIR"
++ chown "$INSTALL_USER" "$DIR"
++ chgrp "$INSTALL_GROUP" "$DIR"
+ restorecon "$DIR" >/dev/null 2>&1
+ fi
+ }
#
PKG_NAME:=shadowsocks-libev
PKG_VERSION:=3.3.4
-PKG_RELEASE:=4
+PKG_RELEASE:=5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-libev/releases/download/v$(PKG_VERSION)
option server_port '9001'
option password '********'
option method 'aes-256-cfb'
- option bind_address '192.168.7.72'
json_add_boolean no_delay "$no_delay"
[ -z "$local_address" ] || json_add_string local_address "$local_address"
[ -z "$local_port" ] || json_add_int local_port "$local_port"
+ [ -z "$local_ipv4_address" ] || json_add_string local_ipv4_address "$local_ipv4_address"
+ [ -z "$local_ipv6_address" ] || json_add_string local_ipv6_address "$local_ipv6_address"
[ -z "$mode" ] || json_add_string mode "$mode"
[ -z "$mtu" ] || json_add_int mtu "$mtu"
[ -z "$timeout" ] || json_add_int timeout "$timeout"
procd_open_instance "$cfgtype.$cfg"
procd_set_param command "$bin" -c "$confjson"
[ "$verbose" = 0 ] || procd_append_param command -v
- [ -z "$bind_address" ] || procd_append_param command -b "$bind_address"
+ if [ -n "$bind_address" ]; then
+ echo "$cfgtype $cfg: uci option bind_address deprecated, please switch to local_address" >&2
+ procd_append_param command -b "$bind_address"
+ fi
procd_set_param file "$confjson"
procd_set_param respawn
procd_close_instance
validate_common_client_options_() {
validate_common_options_ "$@" \
'server:uci("shadowsocks-libev", "@server")' \
- 'local_address:host:0.0.0.0' \
+ 'local_address:ipaddr:0.0.0.0' \
'local_port:port'
}
validate_common_server_options_ ss_server "$1" \
validate_common_options_ \
"$2" \
+ 'local_address:ipaddr' \
+ 'local_ipv4_address:ip4addr' \
+ 'local_ipv6_address:ip6addr' \
'bind_address:ipaddr'
}
PKG_VERSION:=4.29-9680
PKG_VERREL:=rtm
PKG_VERDATE:=2019.02.28
-PKG_RELEASE:=4
+PKG_RELEASE:=5
PKG_SOURCE:=softether-src-v$(PKG_VERSION)-$(PKG_VERREL).tar.gz
PKG_SOURCE_URL:=http://www.softether-download.com/files/softether/v$(PKG_VERSION)-$(PKG_VERREL)-$(PKG_VERDATE)-tree/Source_Code/
# Select 32 or 64 bit Makefile for host build depending on host architecture
HOST_MAKE_FLAGS += -f src/makefiles/linux_$(if $(shell uname -m | grep 64),64,32)bit.mak
-HOST_LDFLAGS += -Wl,-rpath="$(STAGING_DIR_HOSTPKG)/lib"
+HOST_LDFLAGS += -Wl,-rpath$(comma)$(STAGING_DIR_HOSTPKG)/lib
# Prevent calling upstream configure
define Host/Configure
endef
#
-# Copyright (C) 2019 The Regents of the University of California
+# Copyright (C) 2018-2020 The Regents of the University of California
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
PKG_NAME:=spoofer
-PKG_VERSION:=1.4.5
+PKG_VERSION:=1.4.6
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.caida.org/projects/spoofer/downloads
-PKG_HASH:=5f045be7269d93efb1ee7918e923e7695c9a36d192c3ada932bb6ae7fba8d15e
+PKG_HASH:=fb814d0beaccc48a155e55bb1e7057520d0fe0584dbcc4c0a89f5cee55d0eaf1
PKG_MAINTAINER:=Ken Keys <spoofer-info@caida.org>
PKG_LICENSE:=GPL-3.0-or-later
The spoofer client is part of a system to measure the Internet's
resistance to packets with a spoofed (forged) source IP address.
-This package comes bundled with a small certificate file that allows
+This package comes bundled with small certificate files that allow
secure communication with the spoofer server without depending on
the large ca-certificates package. But if the server's private
certificate ever changes, it will be necessary to either install the
$(INSTALL_BIN) $(PKG_BUILD_DIR)/openwrt-files/initscript $(1)/etc/init.d/spoofer
$(INSTALL_DIR) $(1)/usr/share/spoofer
$(INSTALL_DATA) $(PKG_BUILD_DIR)/gd_bundle.crt $(1)/usr/share/spoofer
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/letsencrypt_bundle.pem.txt $(1)/usr/share/spoofer
$(INSTALL_DATA) $(PKG_BUILD_DIR)/openwrt-files/spoofer-lib.sh $(1)/usr/share/spoofer
endef
include $(TOPDIR)/rules.mk
PKG_NAME:=sshfs
-PKG_VERSION:=2.10
+PKG_VERSION:=3.7.0
PKG_RELEASE:=1
-PKG_LICENSE:=GPL-2.0
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/libfuse/sshfs/releases/download/$(PKG_NAME)-$(PKG_VERSION)
+PKG_HASH:=6e7e86831f3066b356e7f16e22f1b8a8f177fda05146f6a5eb821c2fd0541c34
+
PKG_MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
+PKG_LICENSE:=GPL-2.0-only
+PKG_LICENSE_FILES:=COPYING
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=https://github.com/libfuse/sshfs/releases/download/$(PKG_NAME)-$(PKG_VERSION)
-PKG_HASH:=70845dde2d70606aa207db5edfe878e266f9c193f1956dd10ba1b7e9a3c8d101
+PKG_INSTALL:=1
-include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/nls.mk
+include $(INCLUDE_DIR)/package.mk
+include ../../devel/meson/meson.mk
define Package/sshfs
TITLE:=SSHFS
- DEPENDS:=+libfuse +fuse-utils +glib2 +libpthread
+ DEPENDS:=+fuse3-utils +glib2 +libpthread
SECTION:=net
CATEGORY:=Network
SUBMENU:=Filesystem
- URL:=http://fuse.sourceforge.net/
+ URL:=https://github.com/libfuse/sshfs
endef
define Package/sshfs/description
Mount remote system over sftp.
endef
-CONFIGURE_VARS += \
- SSHFS_CFLAGS=" \
- -D_FILE_OFFSET_BITS=64 \
- -I$(STAGING_DIR)/usr/include/glib-2.0 \
- -I$(STAGING_DIR)/usr/lib/glib-2.0/include \
- -I$(STAGING_DIR)/usr/include/fuse" \
- SSHFS_LIBS=" \
- -lglib-2.0 -liconv $(if $(INTL_FULL),-lintl) -lfuse -pthread -lgthread-2.0 \
- -L$(STAGING_DIR)/usr/lib"
-
-define Build/Compile
- $(MAKE) -C $(PKG_BUILD_DIR) \
- ARCH="$(LINUX_KARCH)" \
- CROSS_COMPILE="$(TARGET_CROSS)" \
- DESTDIR="$(PKG_INSTALL_DIR)" \
- all install
-endef
-
define Package/sshfs/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/sshfs $(1)/usr/bin/
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -51,7 +51,7 @@ sshfs_deps = [ dependency('fuse3', version: '>= 3.1.0'),
+ executable('sshfs', sshfs_sources,
+ include_directories: include_dirs,
+ dependencies: sshfs_deps,
+- c_args: ['-DFUSE_USE_VERSION=31'],
++ c_args: ['-DFUSE_USE_VERSION=30'],
+ install: true,
+ install_dir: get_option('bindir'))
+
include $(TOPDIR)/rules.mk
PKG_NAME:=tor
-PKG_VERSION:=0.4.3.5
-PKG_RELEASE:=2
+PKG_VERSION:=0.4.3.6
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://dist.torproject.org/ \
https://archive.torproject.org/tor-package-archive
-PKG_HASH:=616a0e4ae688d0e151d46e3e4258565da4d443d1ddbd316db0b90910e2d5d868
+PKG_HASH:=6a2d0637d4e514be2ec574723a05065245cce51da78a21cec1dc831be5ccac62
PKG_MAINTAINER:=Hauke Mehrtens <hauke@hauke-m.de> \
Peter Wagner <tripolar@gmx.at>
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/rules.mk
PKG_NAME:=unbound
-PKG_VERSION:=1.10.1
-PKG_RELEASE:=5
+PKG_VERSION:=1.11.0
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://nlnetlabs.nl/downloads/unbound
-PKG_HASH:=b73677c21a71cf92f15cc8cfe76a3d875e40f65b6150081c39620b286582d536
+PKG_HASH:=9f2f0798f76eb8f30feaeda7e442ceed479bc54db0e3ac19c052d68685e51ef7
PKG_MAINTAINER:=Eric Luehrsen <ericluehrsen@gmail.com>
PKG_LICENSE:=BSD-3-Clause
PKG_NAME:=yggdrasil
PKG_VERSION:=0.3.14
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/yggdrasil-network/yggdrasil-go/tar.gz/v$(PKG_VERSION)?
--- /dev/null
+diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go
+index 9cca419..45f93a5 100644
+--- a/src/yggdrasil/tcp.go
++++ b/src/yggdrasil/tcp.go
+@@ -25,6 +25,7 @@ import (
+
+ "golang.org/x/net/proxy"
+
++ "github.com/yggdrasil-network/yggdrasil-go/src/address"
+ "github.com/yggdrasil-network/yggdrasil-go/src/util"
+ )
+
+@@ -386,6 +387,19 @@ func (t *tcp) handler(sock net.Conn, incoming bool, options interface{}, upgrade
+ local, _, _ = net.SplitHostPort(sock.LocalAddr().String())
+ remote, _, _ = net.SplitHostPort(sock.RemoteAddr().String())
+ }
++ localIP := net.ParseIP(local)
++ if localIP = localIP.To16(); localIP != nil {
++ var laddr address.Address
++ var lsubnet address.Subnet
++ copy(laddr[:], localIP)
++ copy(lsubnet[:], localIP)
++ if laddr.IsValid() || lsubnet.IsValid() {
++ // The local address is with the network address/prefix range
++ // This would route ygg over ygg, which we don't want
++ t.link.core.log.Debugln("Dropping ygg-tunneled connection", local, remote)
++ return
++ }
++ }
+ force := net.ParseIP(strings.Split(remote, "%")[0]).IsLinkLocalUnicast()
+ link, err := t.link.core.link.create(&stream, name, proto, local, remote, incoming, force)
+ if err != nil {
+
PKG_NAME:=zerotier
PKG_VERSION:=1.4.6
-PKG_RELEASE:=4
+PKG_RELEASE:=5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/zerotier/ZeroTierOne/tar.gz/$(PKG_VERSION)?
PKG_LICENSE:=BSL 1.1
PKG_LICENSE_FILES:=LICENSE.txt
+PKG_ASLR_PIE:=0
PKG_BUILD_PARALLEL:=1
+
include $(INCLUDE_DIR)/package.mk
define Package/zerotier
PKG_NAME:=mpd
PKG_VERSION:=0.21.25
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.musicpd.org/download/mpd/0.21/
/etc/avahi/services/mpd.service
endef
-TARGET_LDFLAGS += \
- -liconv \
- $(if $(CONFIG_USE_GLIBC),-lpthread)
-
ifeq ($(CONFIG_AUDIO_SUPPORT),y)
TARGET_LDFLAGS += -Wl,-rpath-link=$(STAGING_DIR)/usr/lib/pulseaudio
endif
+From 90fcdb5b02e08b3faf2e321b081798cc18d35b15 Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Thu, 30 Jul 2020 14:34:07 -0700
+Subject: [PATCH] icu/meson: link against iconv when used externally
+
+This basically adds -liconv to LDFLAGS, fixing a linking issue when
+iconv is missing in the libc.
+
+The previous commit fixed finding iconv but did not fix linking.
+
+Switched to using c_compiler for iconv. It seems compiler does not work
+properly.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ src/lib/icu/meson.build | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/src/lib/icu/meson.build b/src/lib/icu/meson.build
+index bd6e30944..132e15b89 100644
--- a/src/lib/icu/meson.build
+++ b/src/lib/icu/meson.build
-@@ -18,7 +18,7 @@ if icu_dep.found()
+@@ -18,8 +18,18 @@ if icu_dep.found()
'Init.cxx',
]
elif not get_option('iconv').disabled()
- have_iconv = compiler.has_function('iconv')
-+ have_iconv = compiler.has_function('iconv', prefix : '#include <iconv.h>')
- conf.set('HAVE_ICONV', have_iconv)
+- conf.set('HAVE_ICONV', have_iconv)
++ have_iconv = c_compiler.has_header_symbol('iconv.h', 'iconv')
++ if have_iconv
++ libiconv = c_compiler.find_library('iconv')
++ conf.set('HAVE_ICONV', have_iconv)
++ libiconv_dep = static_library('iconv', icu_sources, include_directories: inc, dependencies: libiconv)
++ icu_dep = declare_dependency(link_with: libiconv_dep, dependencies: util_dep)
++ endif
++ if not have_iconv and c_compiler.has_function('iconv')
++ libiconv = []
++ have_iconv = true
++ conf.set('HAVE_ICONV', have_iconv)
++ endif
if not have_iconv and get_option('iconv').enabled()
error('iconv() not available')
+ endif
+--
+2.17.1
+
--- /dev/null
+From c2da1d47eeaf83d3683555b965a16654561f14b3 Mon Sep 17 00:00:00 2001
+From: Rosen Penev <rosenp@gmail.com>
+Date: Thu, 30 Jul 2020 16:27:02 -0700
+Subject: [PATCH] icu: fix compilation with const char iconv
+
+libiconv uses const char. Test for it and use it properly to fix
+compilation.
+
+Signed-off-by: Rosen Penev <rosenp@gmail.com>
+---
+ src/lib/icu/Converter.cxx | 2 +-
+ src/lib/icu/meson.build | 10 ++++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/src/lib/icu/Converter.cxx b/src/lib/icu/Converter.cxx
+index b03543a82..4c459e57e 100644
+--- a/src/lib/icu/Converter.cxx
++++ b/src/lib/icu/Converter.cxx
+@@ -83,7 +83,7 @@ DoConvert(iconv_t conv, const char *src)
+ {
+ // TODO: dynamic buffer?
+ char buffer[4096];
+- char *in = const_cast<char *>(src);
++ ICONV_CONST char *in = (ICONV_CONST char *)(src);
+ char *out = buffer;
+ size_t in_left = strlen(src);
+ size_t out_left = sizeof(buffer);
+diff --git a/src/lib/icu/meson.build b/src/lib/icu/meson.build
+index 132e15b89..ac7d1b72a 100644
+--- a/src/lib/icu/meson.build
++++ b/src/lib/icu/meson.build
+@@ -30,6 +30,16 @@ elif not get_option('iconv').disabled()
+ have_iconv = true
+ conf.set('HAVE_ICONV', have_iconv)
+ endif
++ if have_iconv
++ iconvconsttest = '''#include <iconv.h>
++size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
++'''
++ if c_compiler.compiles(iconvconsttest, dependencies : libiconv)
++ conf.set('ICONV_CONST', '')
++ else
++ conf.set('ICONV_CONST', 'const')
++ endif
++ endif
+ if not have_iconv and get_option('iconv').enabled()
+ error('iconv() not available')
+ endif
+--
+2.17.1
+
PKG_NAME:=pulseaudio
PKG_VERSION:=13.0
-PKG_RELEASE:=4
+PKG_RELEASE:=5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://freedesktop.org/software/pulseaudio/releases
-Ddbus=disabled
endif
-TARGET_LDFLAGS += -Wl,--gc-sections -liconv
+TARGET_LDFLAGS += -Wl,--gc-sections $(if $(INTL_FULL),-lintl)
define Build/Prepare
$(call Build/Prepare/Default)
--- /dev/null
+--- a/meson.build
++++ b/meson.build
+@@ -380,12 +380,11 @@ if dl_dep.found()
+ endif
+
+ have_iconv = false
+-if cc.has_function('iconv_open')
++iconv_dep = cc.find_library('iconv', required : false)
++have_iconv = iconv_dep.found()
++if not have_iconv and cc.has_function('iconv_open')
+ iconv_dep = dependency('', required : false)
+ have_iconv = true
+-else
+- iconv_dep = cc.find_library('iconv', required : false)
+- have_iconv = iconv_dep.found()
+ endif
+ if have_iconv
+ cdata.set('HAVE_ICONV', 1)
PKG_NAME:=squeezelite
PKG_VERSION:=1.9.6-1210
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/ralph-irving/squeezelite
config SQUEEZELITE_WMA
bool "WMA/ALAC decode support"
+ depends on BUILD_PATENTED
help
Include WMA and ALAC decoding using ffmpeg
default n
+
#
# Copyright (C) 2016 OpenWrt.org
#
PKG_NAME:=upmpdcli
PKG_VERSION:=1.4.12
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.lesbonscomptes.com/upmpdcli/downloads
--- /dev/null
+--- a/src/mediaserver/cdplugins/streamproxy.cpp
++++ b/src/mediaserver/cdplugins/streamproxy.cpp
+@@ -155,7 +155,7 @@ public:
+ ~Internal();
+ bool startMHD();
+
+- int answerConn(
++ enum MHD_Result answerConn(
+ struct MHD_Connection *connection, const char *url,
+ const char *method, const char *version,
+ const char *upload_data, size_t *upload_data_size,
+@@ -202,7 +202,7 @@ StreamProxy::Internal::Internal(int _listenport, UrlTransFunc _urltrans)
+ }
+
+
+-static int answer_to_connection(
++static enum MHD_Result answer_to_connection(
+ void *cls, struct MHD_Connection *conn,
+ const char *url, const char *method, const char *version,
+ const char *upload_data, size_t *upload_data_size,
+@@ -214,7 +214,7 @@ static int answer_to_connection(
+ return internal->answerConn(
+ conn, url, method, version, upload_data, upload_data_size, con_cls);
+ } else {
+- return -1;
++ return MHD_NO;
+ }
+ }
+
+@@ -238,7 +238,7 @@ static int print_out_key (void *cls, enum MHD_ValueKind kind,
+ }
+ #endif /* PRINT_KEYS */
+
+-static int mapvalues_cb(void *cls, enum MHD_ValueKind kind,
++static enum MHD_Result mapvalues_cb(void *cls, enum MHD_ValueKind kind,
+ const char *key, const char *value)
+ {
+ unordered_map<string,string> *mp = (unordered_map<string,string> *)cls;
+@@ -307,7 +307,7 @@ static bool processRange(struct MHD_Connection *mhdconn, uint64_t& offset)
+ return true;
+ }
+
+-int StreamProxy::Internal::answerConn(
++enum MHD_Result StreamProxy::Internal::answerConn(
+ struct MHD_Connection *mhdconn, const char *_url,
+ const char *method, const char *version,
+ const char *upload_data, size_t *upload_data_size,
+@@ -352,7 +352,7 @@ int StreamProxy::Internal::answerConn(
+ return MHD_NO;
+ }
+ MHD_add_response_header (response, "Location", url.c_str());
+- int ret = MHD_queue_response(mhdconn, 302, response);
++ enum MHD_Result ret = MHD_queue_response(mhdconn, 302, response);
+ MHD_destroy_response(response);
+ return ret;
+ }
+@@ -393,7 +393,7 @@ int StreamProxy::Internal::answerConn(
+ int code = httpcode ? httpcode : MHD_HTTP_INTERNAL_SERVER_ERROR;
+ struct MHD_Response *response =
+ MHD_create_response_from_buffer(0, 0, MHD_RESPMEM_PERSISTENT);
+- int ret = MHD_queue_response(mhdconn, code, response);
++ enum MHD_Result ret = MHD_queue_response(mhdconn, code, response);
+ MHD_destroy_response(response);
+ LOGINF("StreamProxy::answerConn (1): return with http code: " <<
+ code << endl);
+@@ -434,7 +434,7 @@ int StreamProxy::Internal::answerConn(
+ if (reader->fetcher->fetchDone(&fetchcode, &httpcode)) {
+ code = httpcode ? httpcode : MHD_HTTP_INTERNAL_SERVER_ERROR;
+ }
+- int ret = MHD_queue_response(mhdconn, code, response);
++ enum MHD_Result ret = MHD_queue_response(mhdconn, code, response);
+ MHD_destroy_response(response);
+ return ret;
+ }
PKG_NAME:=device-observatory
PKG_VERSION:=1.2.0
-PKG_RELEASE:=6
+PKG_RELEASE:=7
PKG_SOURCE_URL:=https://codeload.github.com/mwarning/device-observatory/tar.gz/v$(PKG_VERSION)?
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
--- /dev/null
+--- a/src/webserver.c
++++ b/src/webserver.c
+@@ -129,7 +129,7 @@ const char *get_mimetype(const char str[])
+ return "application/octet-stream";
+ }
+
+-static int send_response(void *cls, struct MHD_Connection *connection,
++static enum MHD_Result send_response(void *cls, struct MHD_Connection *connection,
+ const char *url, const char *method, const char *version,
+ const char *upload_data, size_t *upload_data_size, void **con_cls)
+ {
+@@ -142,7 +142,7 @@ static int send_response(void *cls, struct MHD_Connection *connection,
+ struct device *device;
+ int is_localhost;
+ FILE *fp;
+- int ret;
++ enum MHD_Result ret;
+
+ connection_info = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS);
+ if (!connection_info) {
PKG_NAME:=docker-ce
PKG_VERSION:=19.03.12
-PKG_RELEASE:=3
+PKG_RELEASE:=5
PKG_LICENSE:=Apache-2.0
PKG_LICENSE_FILES:=components/cli/LICENSE components/engine/LICENSE
USE_PROCD=1
START=25
+EXTRA_COMMANDS="uciadd ucidel"
+EXTRA_HELP="\
+ uciadd Add default bridge configuration to network and firewall uci config
+ ucidel Delete default bridge configuration from network and firewall uci config"
+
DOCKERD_CONF="/tmp/dockerd/daemon.json"
+uci_quiet() {
+ uci -q ${@} >/dev/null
+}
+
json_add_array_string() {
json_add_string "" "$1"
}
+boot() {
+ uciadd
+ rc_procd start_service
+}
+
+uciupdate() {
+ local net="$1"
+
+ uci -q get network.docker >/dev/null || {
+ logger -t "dockerd-init" -p warn "No network uci config section for docker default bridge (docker0) found"
+ return
+ }
+
+ [ -z "$net" ] && {
+ logger -t "dockerd-init" -p notice "Removing network uci config options for docker default bridge (docker0)"
+ uci_quiet delete network.docker.netmask
+ uci_quiet delete network.docker.ipaddr
+ uci_quiet commit network
+ return
+ }
+
+ eval "$(ipcalc.sh "$net")"
+ logger -t "dockerd-init" -p notice "Updating network uci config option \"$net\" for docker default bridge (docker0)"
+ uci_quiet set network.docker.netmask="$NETMASK"
+ uci_quiet set network.docker.ipaddr="$IP"
+ uci_quiet commit network
+}
+
+uciadd() {
+ /etc/init.d/dockerd running && {
+ echo "Please stop dockerd service first"
+ exit 0
+ }
+
+ # Add network interface
+ if ! uci -q get network.docker >/dev/null; then
+ logger -t "dockerd-init" -p notice "Adding docker default bridge to network uci config (docker0)"
+ uci_quiet add network interface
+ uci_quiet rename network.@interface[-1]="docker"
+ uci_quiet set network.docker.ifname="docker0"
+ uci_quiet set network.docker.proto="static"
+ uci_quiet set network.docker.auto="0"
+ uci_quiet commit network
+ fi
+
+ # Add firewall zone
+ if ! uci -q get firewall.docker >/dev/null; then
+ logger -t "dockerd-init" -p notice "Adding docker default bridge firewall zone (docker0)"
+ uci_quiet add firewall zone
+ uci_quiet rename firewall.@zone[-1]="docker"
+ uci_quiet set firewall.docker.network="docker"
+ uci_quiet set firewall.docker.input="REJECT"
+ uci_quiet set firewall.docker.output="ACCEPT"
+ uci_quiet set firewall.docker.forward="REJECT"
+ uci_quiet set firewall.docker.name="docker"
+ uci_quiet commit firewall
+ fi
+
+ reload_config
+}
+
+ucidel() {
+ /etc/init.d/dockerd running && {
+ echo "Please stop dockerd service first"
+ exit 0
+ }
+
+ logger -t "dockerd-init" -p notice "Deleting docker default bridge network from network uci config (docker0)"
+ uci_quiet delete network.docker
+ uci_quiet commit network
+
+ logger -t "dockerd-init" -p notice "Deleting docker default bridge firewall zone from firewall uci config (docker0)"
+ uci_quiet delete firewall.docker
+ uci_quiet commit firewall
+
+ reload_config
+}
+
process_config() {
- local alt_config_file data_root log_level
+ local alt_config_file data_root log_level bip
rm -f "$DOCKERD_CONF"
config_get data_root globals data_root "/opt/docker/"
config_get log_level globals log_level "warn"
+ config_get bip globals bip ""
. /usr/share/libubox/jshn.sh
json_init
json_add_string "data-root" "$data_root"
json_add_string "log-level" "$log_level"
+ [ -z "$bip" ] || json_add_string "bip" "$bip"
json_add_array "registry-mirrors"
- config_list_foreach globals registry_mirror json_add_array_string
+ config_list_foreach globals registry_mirrors json_add_array_string
+ json_close_array
+ json_add_array "hosts"
+ config_list_foreach globals hosts json_add_array_string
json_close_array
mkdir -p /tmp/dockerd
json_dump > "$DOCKERD_CONF"
+
+ uciupdate "$bip"
}
start_service() {
}
ip4tables_remove_filter() {
- iptables -t filter -D FORWARD -j DOCKER-USER
+ # Chain DOCKER-USER is only present,
+ # if bip option is NOT set, so >/dev/null 2>&1
+ iptables -t filter -D FORWARD -j DOCKER-USER >/dev/null 2>&1
iptables -t filter -D FORWARD -j DOCKER-ISOLATION-STAGE-1
iptables -t filter -D FORWARD -o docker0 -j DOCKER
iptables -t filter -F DOCKER
iptables -t filter -F DOCKER-ISOLATION-STAGE-1
iptables -t filter -F DOCKER-ISOLATION-STAGE-2
- iptables -t filter -F DOCKER-USER
+ # Chain DOCKER-USER is only present,
+ # if bip option is NOT set, so >/dev/null 2>&1
+ iptables -t filter -F DOCKER-USER >/dev/null 2>&1
iptables -t filter -X DOCKER
iptables -t filter -X DOCKER-ISOLATION-STAGE-1
iptables -t filter -X DOCKER-ISOLATION-STAGE-2
- iptables -t filter -X DOCKER-USER
+ # Chain DOCKER-USER is only present,
+ # if bip option is NOT set, so >/dev/null 2>&1
+ iptables -t filter -X DOCKER-USER >/dev/null 2>&1
}
ip4tables_remove() {
}
stop_service() {
- ip4tables_remove
+ if /etc/init.d/dockerd running; then
+ service_stop "/usr/bin/dockerd"
+ ip4tables_remove
+ fi
}
# option alt_config_file "/etc/docker/daemon.json"
option data_root "/opt/docker/"
option log_level "warn"
-# list registry_mirror "https://<my-docker-mirror-host>"
-# list registry_mirror "https://hub.docker.com"
+ option hosts "unix://var/run/docker.sock"
+ # If the bip option is changed, dockerd must be restarted.
+ # A service reload is not enough.
+ option bip "172.18.0.1/24"
+# list registry_mirrors "https://<my-docker-mirror-host>"
+# list registry_mirrors "https://hub.docker.com"
--- /dev/null
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=fuse3
+PKG_VERSION:=3.9.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=fuse-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=https://github.com/libfuse/libfuse/releases/download/fuse-$(PKG_VERSION)
+PKG_HASH:=6999b6d48e7c0a79628fa901f6e66def3513cab4ffdd8097821e7dc3cdeae08a
+PKG_BUILD_DIR:=$(BUILD_DIR)/fuse-$(PKG_VERSION)
+
+PKG_MAINTAINER:=
+PKG_CPE_ID:=cpe:/a:fuse_project:fuse
+
+PKG_INSTALL:=1
+PKG_BUILD_DEPENDS:=meson/host
+
+include $(INCLUDE_DIR)/package.mk
+include ../../devel/meson/meson.mk
+
+define Package/fuse3/Default
+ TITLE:=FUSE
+ URL:=https://github.com/libfuse/libfuse
+ SUBMENU:=Filesystem
+endef
+
+define Package/fuse3/Default/description
+ fuse3 (Filesystem in UserSpacE)
+endef
+
+define Package/libfuse3
+$(call Package/fuse3/Default)
+ TITLE+= library
+ URL:=https://github.com/libfuse/libfuse
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+kmod-fuse +libpthread
+ ABI_VERSION:=3
+ LICENSE:=LGPL-2.1-only
+ LICENSE_FILES:=LGPL2.txt
+endef
+
+define Package/libfuse3/description
+$(call Package/fuse3/Default/description)
+ This package contains the fuse3 shared libraries, needed by other programs.
+ - libfuse3
+endef
+
+define Package/fuse3-utils
+$(call Package/fuse3/Default)
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libfuse3
+ TITLE+= (utilities)
+ SUBMENU:=Filesystem
+ LICENSE:=GPL-2.0-only
+ LICENSE_FILES:=COPYING
+endef
+
+define Package/fuse3-utils/description
+$(call Package/fuse3/Default/description)
+ This package contains the FUSE utilities.
+ - fusermount3
+ - mount.fuse3
+endef
+
+MESON_ARGS += \
+ -Ddisable-mtab=true \
+ -Dudevrulesdir=/dev/null \
+ -Dutils=$(if $(CONFIG_PACKAGE_fuse3-utils),true,false) \
+ -Dexamples=false \
+ -Duseroot=false
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include/fuse3
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/include/fuse3/*.h $(1)/usr/include/fuse3
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libfuse3.so* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/fuse3.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/libfuse3/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libfuse3.so.* $(1)/usr/lib/
+endef
+
+define Package/fuse3-utils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(CP) $(PKG_INSTALL_DIR)/usr/bin/fusermount3 $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/mount.fuse3 $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,libfuse3))
+$(eval $(call BuildPackage,fuse3-utils))
--- /dev/null
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=gl-mifi-mcu
+PKG_VERSION:=1
+PKG_RELEASE:=1
+
+PKG_MAINTAINER:=Nuno Goncalves <nunojpg@gmail.com>
+PKG_LICENSE:=GPL-3.0-or-later
+
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/gl-mifi-mcu
+ SUBMENU:=Hardware Monitoring Support
+ TITLE:=GL.iNet GL-MiFI Power monitoring support
+ AUTOLOAD:=$(call AutoLoad,60,gl-mifi-mcu)
+ FILES:=$(PKG_BUILD_DIR)/gl-mifi-mcu.ko
+endef
+
+define KernelPackage/gl-mifi-mcu/description
+ Interfaces with GL-MiFI Power monitoring MCU with a soft UART
+ and provides Battery SOC, Temperature and charging data at
+ /proc/gl_mifi_mcu.
+ This feature is supported from GL-MiFi PCB revision v2.6.2.
+ The content of /proc/gl_mifi_mcu is JSON as received from the
+ UART and will frequenty contain corrupted data due to soft UART
+ unreliability. User application must validate the data.
+endef
+
+define Build/Compile
+ $(KERNEL_MAKE) \
+ M="$(PKG_BUILD_DIR)" \
+ modules
+endef
+
+$(eval $(call KernelPackage,gl-mifi-mcu))
--- /dev/null
+obj-m += gl-mifi-mcu.o
+
+gl-mifi-mcu-objs := module.o
+
--- /dev/null
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/hrtimer.h>
+#include <linux/interrupt.h>
+#include <linux/ktime.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Nuno Goncalves");
+MODULE_DESCRIPTION("GL-MiFi power monitoring MCU interface");
+MODULE_VERSION("0.1");
+
+static int gpio_tx = 19;
+static int gpio_rx = 8;
+static int baudrate = 1200;
+static int query_interval_sec = 4;
+
+static struct hrtimer timer_tx;
+static struct hrtimer timer_rx;
+static ktime_t period;
+static int rx_bit_index = -1;
+
+static unsigned read_buf_ready = 0;
+static unsigned read_buf_size = 0;
+static char read_buf[2][64] = {{0},{0}};
+
+static int proc_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "%s\n", read_buf[read_buf_ready]);
+ return 0;
+}
+
+static int proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_show, NULL);
+}
+
+static const struct file_operations hello_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static irq_handler_t handle_rx_start(unsigned int irq, void* device, struct pt_regs* registers)
+{
+ if (rx_bit_index == -1)
+ {
+ hrtimer_start(&timer_rx, ktime_set(0, period / 2), HRTIMER_MODE_REL);
+ }
+ return (irq_handler_t) IRQ_HANDLED;
+}
+
+static enum hrtimer_restart handle_tx(struct hrtimer* timer)
+{
+ ktime_t current_time = ktime_get();
+ const unsigned char character = 'g';
+ static int bit_index = -1;
+
+ // Start bit.
+ if (bit_index == -1)
+ {
+ gpio_set_value(gpio_tx, 0);
+ bit_index++;
+ }
+
+ // Data bits.
+ else if (0 <= bit_index && bit_index < 8)
+ {
+ gpio_set_value(gpio_tx, 1 & (character >> bit_index));
+ bit_index++;
+ }
+
+ // Stop bit.
+ else if (bit_index == 8)
+ {
+ gpio_set_value(gpio_tx, 1);
+ bit_index = -1;
+ }
+
+ hrtimer_forward(&timer_tx, current_time, bit_index == 8
+ ? ktime_set(query_interval_sec, 0) //wait for next query cycle
+ : period); //wait for next bit period
+
+ return HRTIMER_RESTART;
+}
+
+void receive_character(unsigned char character)
+{
+ if(character == '{')
+ read_buf_size = 0;
+
+ if(read_buf_size < (sizeof(read_buf[0])-1) || character == '}')
+ {
+ read_buf[!read_buf_ready][read_buf_size++] = character;
+ if(character == '}')
+ {
+ read_buf[!read_buf_ready][read_buf_size] = '\0';
+ read_buf_ready = !read_buf_ready;
+ read_buf_size = 0;
+ }
+ }
+}
+
+static enum hrtimer_restart handle_rx(struct hrtimer* timer)
+{
+ ktime_t current_time = ktime_get();
+ static unsigned int character = 0;
+ int bit_value = gpio_get_value(gpio_rx);
+ enum hrtimer_restart result = HRTIMER_NORESTART;
+ bool must_restart_timer = false;
+
+ // Start bit.
+ if (rx_bit_index == -1)
+ {
+ rx_bit_index++;
+ character = 0;
+ must_restart_timer = true;
+ }
+
+ // Data bits.
+ else if (0 <= rx_bit_index && rx_bit_index < 8)
+ {
+ if (bit_value == 0)
+ {
+ character &= 0xfeff;
+ }
+ else
+ {
+ character |= 0x0100;
+ }
+
+ rx_bit_index++;
+ character >>= 1;
+ must_restart_timer = true;
+ }
+
+ // Stop bit.
+ else if (rx_bit_index == 8)
+ {
+ receive_character(character);
+ rx_bit_index = -1;
+ }
+
+ // Restarts the RX timer.
+ if (must_restart_timer)
+ {
+ hrtimer_forward(&timer_rx, current_time, period);
+ result = HRTIMER_RESTART;
+ }
+
+ return result;
+}
+
+static int __init init(void)
+{
+ bool success = true;
+
+ proc_create("gl_mifi_mcu", 0, NULL, &hello_proc_fops);
+
+ success &= gpio_request(gpio_tx, "soft_uart_tx") == 0;
+ success &= gpio_direction_output(gpio_tx, 1) == 0;
+ success &= gpio_request(gpio_rx, "soft_uart_rx") == 0;
+ success &= gpio_direction_input(gpio_rx) == 0;
+ success &= gpio_set_debounce(gpio_rx, 1000/baudrate/2);
+
+ success &= request_irq(
+ gpio_to_irq(gpio_rx),
+ (irq_handler_t) handle_rx_start,
+ IRQF_TRIGGER_FALLING,
+ "gl_mifi_mcu_irq_handler",
+ NULL) == 0;
+
+ hrtimer_init(&timer_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ timer_tx.function = &handle_tx;
+ hrtimer_init(&timer_rx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ timer_rx.function = &handle_rx;
+ period = ktime_set(0, 1000000000/baudrate);
+ hrtimer_start(&timer_tx, period, HRTIMER_MODE_REL);
+
+ return success;
+}
+
+static void __exit exit(void)
+{
+ disable_irq(gpio_to_irq(gpio_rx));
+ hrtimer_cancel(&timer_tx);
+ hrtimer_cancel(&timer_rx);
+ free_irq(gpio_to_irq(gpio_rx), NULL);
+ gpio_set_value(gpio_tx, 0);
+ gpio_free(gpio_tx);
+ gpio_free(gpio_rx);
+ remove_proc_entry("gl_mifi_mcu", NULL);
+}
+
+module_init(init);
+module_exit(exit);
+
include $(TOPDIR)/rules.mk
PKG_NAME:=gnuplot
-PKG_VERSION:=5.2.8
-PKG_RELEASE:=1
+PKG_VERSION:=5.4.0
+PKG_RELEASE:=2
PKG_MAINTAINER:=Matteo Cicuttin <datafl4sh@toxicnet.eu>
PKG_BUILD_DIR:=$(BUILD_DIR)/gnuplot-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/gnuplot
-PKG_HASH:=60a6764ccf404a1668c140f11cc1f699290ab70daa1151bb58fed6139a28ac37
+PKG_HASH:=eb4082f03a399fd1e9e2b380cf7a4f785e77023d8dcc7e17570c1b5570a49c47
PKG_CAT:=zcat
PKG_FIXUP:=autoreconf
-Index: gnuplot-5.2.8/Makefile.am
+Index: gnuplot-5.4.0/Makefile.am
===================================================================
---- gnuplot-5.2.8.orig/Makefile.am
-+++ gnuplot-5.2.8/Makefile.am
+--- gnuplot-5.4.0.orig/Makefile.am
++++ gnuplot-5.4.0/Makefile.am
@@ -1,7 +1,7 @@
## Process this file with automake to produce Makefile.in -*-Makefile-*-
AUTOMAKE_OPTIONS = foreign
--SUBDIRS = config m4 term src docs man demo tutorial share
-+SUBDIRS = config m4 term src man tutorial share
+-SUBDIRS = config m4 term src docs man demo share
++SUBDIRS = config m4 term src man share
- EXTRA_DIST = BUGS Copyright FAQ.pdf GNUmakefile INSTALL INSTALL.gnu \
- Makefile.maint PATCHLEVEL PGPKEYS README RELEASE_NOTES \
+ EXTRA_DIST = BUGS Copyright FAQ.pdf INSTALL INSTALL.gnu \
+ PATCHLEVEL PGPKEYS README RELEASE_NOTES \
include $(TOPDIR)/rules.mk
PKG_NAME:=mc
-PKG_VERSION:=4.8.24
-PKG_RELEASE:=2
+PKG_VERSION:=4.8.25
+PKG_RELEASE:=1
PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
PKG_LICENSE:=GPL-3.0-or-later
PKG_CPE_ID:=cpe:/a:midnight_commander:midnight_commander
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=http://ftp.midnight-commander.org/
-PKG_HASH:=859f1cc070450bf6eb4d319ffcb6a5ac29deb0ac0d81559fb2e71242b1176d46
+PKG_HASH:=ffc19617f20ebb23330acd3998b7fd559a042d172fa55746d53d246697b2548a
PKG_BUILD_PARALLEL:=1
PKG_FIXUP:=autoreconf gettext-version
PKG_BUILD_DEPENDS:=MC_VFS:libtirpc
---- a/src/subshell/common.c
+-- a/src/subshell/common.c
+++ b/src/subshell/common.c
-@@ -877,7 +877,7 @@ init_subshell_precmd (char *precmd, size
+@@ -836,7 +836,7 @@ init_subshell_precmd (char *precmd, size
"else "
"[ \"${PWD##$HOME/}\" = \"$PWD\" ] && MC_PWD=\"$PWD\" || MC_PWD=\"~/${PWD##$HOME/}\"; "
"fi; "
-From b92c7f86b4be3b200e0f2de713a4c40b28599e61 Mon Sep 17 00:00:00 2001
-From: Egmont Koblinger <egmont@gmail.com>
-Date: Fri, 14 Feb 2020 22:14:19 +0100
-Subject: [PATCH] Ticket #3954: fix mouse handling with newer terminfo entries.
-
-Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
----
- lib/tty/key.c | 11 +++++++++--
- lib/tty/mouse.c | 6 ++++--
- lib/tty/tty.c | 9 ++++++++-
- 3 files changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/lib/tty/key.c b/lib/tty/key.c
-index 1aa5110af0..4abfc71d73 100644
---- a/lib/tty/key.c
-+++ b/lib/tty/key.c
-@@ -2120,8 +2120,15 @@ tty_get_event (struct Gpm_Event *event, gboolean redo_event, gboolean block)
- #endif /* KEY_MOUSE */
- || c == MCKEY_EXTENDED_MOUSE))
- {
-- /* Mouse event */
-- xmouse_get_event (event, c == MCKEY_EXTENDED_MOUSE);
-+ /* Mouse event. See tickets 2956 and 3954 for extended mode detection. */
-+ gboolean extended = c == MCKEY_EXTENDED_MOUSE;
-+
-+#ifdef KEY_MOUSE
-+ extended = extended || (c == KEY_MOUSE && xmouse_seq == NULL
-+ && xmouse_extended_seq != NULL);
-+#endif /* KEY_MOUSE */
-+
-+ xmouse_get_event (event, extended);
- c = (event->type != 0) ? EV_MOUSE : EV_NONE;
- }
- else if (c == MCKEY_BRACKETED_PASTING_START)
-diff --git a/lib/tty/mouse.c b/lib/tty/mouse.c
-index 0f830ce08a..1bba0cc587 100644
---- a/lib/tty/mouse.c
-+++ b/lib/tty/mouse.c
-@@ -90,8 +90,10 @@ init_mouse (void)
-
- case MOUSE_XTERM_NORMAL_TRACKING:
- case MOUSE_XTERM_BUTTON_EVENT_TRACKING:
-- define_sequence (MCKEY_MOUSE, xmouse_seq, MCKEY_NOACTION);
-- define_sequence (MCKEY_EXTENDED_MOUSE, xmouse_extended_seq, MCKEY_NOACTION);
-+ if (xmouse_seq != NULL)
-+ define_sequence (MCKEY_MOUSE, xmouse_seq, MCKEY_NOACTION);
-+ if (xmouse_extended_seq != NULL)
-+ define_sequence (MCKEY_EXTENDED_MOUSE, xmouse_extended_seq, MCKEY_NOACTION);
- break;
-
- default:
-diff --git a/lib/tty/tty.c b/lib/tty/tty.c
-index 1bca37c476..a232cd96e8 100644
--- a/lib/tty/tty.c
+++ b/lib/tty/tty.c
-@@ -361,9 +361,16 @@ tty_init_xterm_support (gboolean is_xterm)
- }
- }
-
-- /* No termcap for SGR extended mouse (yet), hardcode it for now */
-+ /* There's only one termcap entry "kmous", typically containing "\E[M" or "\E[<".
-+ * We need the former in xmouse_seq, the latter in xmouse_extended_seq.
-+ * See tickets 2956 and 3954 for details. */
+@@ -370,7 +370,7 @@ tty_init_xterm_support (gboolean is_xter
if (xmouse_seq != NULL)
-+ {
-+ if (strcmp (xmouse_seq, ESC_STR "[<") == 0)
+ {
+ if (strcmp (xmouse_seq, ESC_STR "[<") == 0)
+- xmouse_seq = ESC_STR "[M";
+ xmouse_seq = NULL;
-+
- xmouse_extended_seq = ESC_STR "[<";
-+ }
- }
- /* --------------------------------------------------------------------------------------------- */
+ xmouse_extended_seq = ESC_STR "[<";
+ }
include $(TOPDIR)/rules.mk
PKG_NAME:=nano
-PKG_VERSION:=4.9.3
+PKG_VERSION:=5.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@GNU/nano
-PKG_HASH:=6e3438f033a0ed07d3d74c30d0803cbda3d2366ba1601b7bbf9b16ac371f51b4
+PKG_HASH:=7c0d94be69cd066f20df2868a2da02f7b1d416ce8d47c0850a8bd270897caa36
PKG_LICENSE:=GPL-3.0-or-later
PKG_LICENSE_FILES:=COPYING
PKG_NAME:=netwhere
PKG_VERSION:=0.9
-PKG_RELEASE:=1
-PKG_LICENSE:=MIT
+PKG_RELEASE:=2
PKG_SOURCE:=netwhere-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/benhsmith/netwhere/archive/$(PKG_VERSION)/
PKG_HASH:=94a672bdcd9d4455b85429dddd81ffc778e0b26fe87af19ad75c27858ec9dbe2
-PKG_BUILD_DEPENDS:=boost
-
PKG_MAINTAINER:=Ben Smith <le.ben.smith@gmail.com>
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=LICENSE
-CMAKE_INSTALL:=1
+PKG_BUILD_DEPENDS:=boost
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Netwhere
- MAINTAINER:=Ben Smith
+ URL:=https://github.com/benhsmith/netwhere
DEPENDS:=+libtins +libmicrohttpd
endef
--- /dev/null
+--- a/webservice.hpp
++++ b/webservice.hpp
+@@ -38,13 +38,13 @@ class WebService {
+ MHD_Daemon* daemon;
+ Functor functor;
+
+- static int on_request(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version,
++ static enum MHD_Result on_request(void * cls, struct MHD_Connection * connection, const char * url, const char * method, const char * version,
+ const char * upload_data, size_t * upload_data_size,
+ void ** ptr);
+ };
+
+ template <typename Functor>
+-int WebService<Functor>::on_request(void * cls,
++enum MHD_Result WebService<Functor>::on_request(void * cls,
+ struct MHD_Connection * connection,
+ const char * url,
+ const char * method,
+@@ -53,7 +53,7 @@ int WebService<Functor>::on_request(void * cls,
+ size_t * upload_data_size,
+ void ** ptr) {
+ static int dummy;
+- int ret;
++ enum MHD_Result ret;
+
+ if (std::string("GET") != method)
+ return MHD_NO; /* unexpected method */
include $(TOPDIR)/rules.mk
PKG_NAME:=ttyd
-PKG_VERSION:=1.6.0
-PKG_RELEASE:=2
+PKG_VERSION:=1.6.1
+PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/tsl0922/ttyd/tar.gz/$(PKG_VERSION)?
-PKG_HASH:=d14740bc82be0d0760dd0a3c97acbcbde490412a4edc61edabe46d311b068f83
+PKG_HASH:=d72dcca3dec00cda87b80a0a25ae4fee2f8b9098c1cdb558508dcb14fbb6fafc
PKG_MAINTAINER:=Shuanglei Tao <tsl0922@gmail.com>
PKG_LICENSE:=MIT
--- a/src/server.c
+++ b/src/server.c
-@@ -6,6 +6,7 @@
- #include <getopt.h>
- #include <signal.h>
+@@ -10,6 +10,7 @@
+ #include <stdlib.h>
+ #include <string.h>
#include <sys/stat.h>
+#include <syslog.h>
- #include <libwebsockets.h>
- #include <json.h>
-@@ -418,7 +419,8 @@ main(int argc, char **argv) {
- return -1;
- }
+ #include "utils.h"
-- lws_set_log_level(debug_level, NULL);
-+ openlog("ttyd", LOG_NDELAY | LOG_PID, LOG_DAEMON);
-+ lws_set_log_level(debug_level, lwsl_emit_syslog);
+@@ -441,7 +442,8 @@ int main(int argc, char **argv) {
+ return -1;
+ }
+
+- lws_set_log_level(debug_level, NULL);
++ openlog("ttyd", LOG_NDELAY | LOG_PID, LOG_DAEMON);
++ lws_set_log_level(debug_level, lwsl_emit_syslog);
#if LWS_LIBRARY_VERSION_MAJOR >= 2
- char server_hdr[128] = "";
+ char server_hdr[128] = "";
include $(TOPDIR)/rules.mk
PKG_NAME:=unrar
-PKG_VERSION:=5.9.3
+PKG_VERSION:=5.9.4
PKG_RELEASE:=1
PKG_SOURCE:=unrarsrc-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.rarlab.com/rar
-PKG_HASH:=28c176c29da86d7efe3cb9a227255d8340f761ba95969195982ec87c8eb2dd69
+PKG_HASH:=3d010d14223e0c7a385ed740e8f046edcbe885e5c22c5ad5733d009596865300
PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>, \
Ted Hess <thess@kitschensync.net>
include $(TOPDIR)/rules.mk
PKG_NAME:=vim
-PKG_VERSION:=8.1
-PKG_RELEASE:=6
-VIMVER:=81
+PKG_VERSION:=8.2
+PKG_RELEASE:=1
+VIMVER:=82
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_SOURCE_URL:=http://ftp.vim.org/pub/vim/unix
-PKG_HASH:=8b69fbd01c877dd8ecbbeca1dc66e5e927228d631ac4c2174b9307eb5c827c86
+PKG_HASH:=f087f821831b4fece16a0461d574ccd55a8279f64d635510a1e10225966ced3b
PKG_MAINTAINER:=Marko Ratkaj <marko.ratkaj@sartura.hr>
PKG_CPE_ID:=cpe:/a:vim:vim
define Build/Compile/vim
$(call Build/Configure/Default, \
--with-features=tiny \
- --disable-multibyte \
)
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" all
define Build/Compile/vim-full
$(call Build/Configure/Default, \
--with-features=normal \
- --enable-multibyte \
)
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" all
define Build/Compile/vim-fuller
$(call Build/Configure/Default, \
--with-features=big \
- --enable-multibyte \
)
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" all
set showcmd " show (partial) command in status line
set showmatch " show matching brackets
set incsearch " incremental search
-set autowrite " automatically save before commands like :next and :make
+"set autowrite " automatically save before commands like :next and :make
set nocompatible " use vim defaults instead of 100% vi compatibility
set backspace=indent,eol,start " more powerful backspacing
set autoindent " always set autoindenting on
set showcmd " show (partial) command in status line
set showmatch " show matching brackets
set incsearch " incremental search
-set autowrite " automatically save before commands like :next and :make
+"set autowrite " automatically save before commands like :next and :make
set nocompatible " use Vim defaults instead of 100% vi compatibility
set backspace=indent,eol,start " more powerful backspacing
set autoindent " always set autoindenting on
---
src/config.h.in | 3 +++
src/configure.ac | 10 ++++++++++
- src/version.c | 6 ++++++
- 3 files changed, 19 insertions(+)
+ src/version.c | 8 ++++++++
+ 3 files changed, 21 insertions(+)
diff --git a/src/config.h.in b/src/config.h.in
-index e692d40..d3aa1a2 100644
+index 5c8c7e5..436a0b7 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -30,6 +30,9 @@
#undef HAVE_ATTRIBUTE_UNUSED
diff --git a/src/configure.ac b/src/configure.ac
-index e287124..5a16797 100644
+index 8751b2e..cd43387 100644
--- a/src/configure.ac
+++ b/src/configure.ac
-@@ -29,6 +29,16 @@ dnl in autoconf needs it, where it uses STDC_HEADERS.
- AC_HEADER_STDC
- AC_HEADER_SYS_WAIT
+@@ -62,6 +62,16 @@ if test x"$ac_cv_prog_cc_c99" != xno; then
+ fi
+ fi
+dnl If $SOURCE_DATE_EPOCH is present in the environment, use that as the
+dnl "compiled" timestamp in :version's output. Attempt to get the formatted
+ AC_DEFINE_UNQUOTED(BUILD_DATE, ["$BUILD_DATE"])
+fi
+
- dnl Check that the C99 features that Vim uses are supported:
- if test x"$ac_cv_prog_cc_c99" != xno; then
- dnl If the compiler doesn't explicitly support C99, then check
+ dnl Check for the flag that fails if stuff are missing.
+
+ AC_MSG_CHECKING(--enable-fail-if-missing argument)
diff --git a/src/version.c b/src/version.c
-index 65f5a4b..9422657 100644
+index c8361eb..e51c738 100644
--- a/src/version.c
+++ b/src/version.c
-@@ -44,11 +44,17 @@ make_version(void)
- * VAX C can't catenate strings in the preprocessor.
+@@ -44,9 +44,13 @@ init_longVersion(void)
+ * VAX C can't concatenate strings in the preprocessor.
*/
strcpy(longVersion, VIM_VERSION_LONG_DATE);
+#ifdef BUILD_DATE
+#endif
strcat(longVersion, ")");
}
-+# elif defined(BUILD_DATE)
-+char *longVersion = VIM_VERSION_LONG_DATE BUILD_DATE ")";
- # else
- char *longVersion = VIM_VERSION_LONG_DATE __DATE__ " " __TIME__ ")";
- # endif
+
+@@ -54,7 +58,11 @@ init_longVersion(void)
+ void
+ init_longVersion(void)
+ {
++#ifdef BUILD_DATE
++ char *date_time = BUILD_DATE;
++#else
+ char *date_time = __DATE__ " " __TIME__;
++#endif
+ char *msg = _("%s (%s, compiled %s)");
+ size_t len = strlen(msg)
+ + strlen(VIM_VERSION_LONG_ONLY)
--- a/runtime/doc/Makefile
+++ b/runtime/doc/Makefile
-@@ -317,7 +317,6 @@ all: tags vim.man evim.man vimdiff.man v
+@@ -323,10 +323,6 @@ all: tags vim.man evim.man vimdiff.man vimtutor.man xxd.man $(CONVERTED)
# Use Vim to generate the tags file. Can only be used when Vim has been
# compiled and installed. Supports multiple languages.
vimtags: $(DOCS)
-- $(VIMEXE) -u NONE -esX -c "helptags ++t ." -c quit
+- @if command -v $(VIMEXE); then \
+- $(VIMEXE) --clean -eX -u doctags.vim >/dev/null && \
+- echo "help tags updated"; \
+- else echo "vim executable $(VIMEXE) not found; help tags not updated"; fi
# Use "doctags" to generate the tags file. Only works for English!
tags: doctags $(DOCS)
+++ /dev/null
---- a/src/getchar.c
-+++ b/src/getchar.c
-@@ -1407,6 +1407,12 @@ openscript(
- emsg(_(e_nesting));
- return;
- }
-+
-+ // Disallow sourcing a file in the sandbox, the commands would be executed
-+ // later, possibly outside of the sandbox.
-+ if (check_secure())
-+ return;
-+
- #ifdef FEAT_EVAL
- if (ignore_script)
- /* Not reading from script, also don't open one. Warning message? */
include $(TOPDIR)/rules.mk
PKG_NAME:=yara
-PKG_VERSION:=4.0.1
+PKG_VERSION:=4.0.2
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/VirusTotal/yara/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=c63e2c4d73fc37e860db5d7e13d945684a0a6d1d17be7161fe1dd8f99268b03c
+PKG_HASH:=05ad88eac9a9f0232432fd14516bdaeda14349d6cf0cac802d76e369abcee001
PKG_MAINTAINER:=Marko Ratkaj <marko.ratkaj@sartura.hr>
PKG_LICENSE:=BSD-3-Clause