Merge pull request #14943 from aTanW/master
authorRosen Penev <rosenp@gmail.com>
Wed, 3 Mar 2021 04:12:50 +0000 (20:12 -0800)
committerGitHub <noreply@github.com>
Wed, 3 Mar 2021 04:12:50 +0000 (20:12 -0800)
joe: new package joe-extras

60 files changed:
.github/workflows/multi-arch-test-build.yml
lang/php7-pecl-imagick/Makefile
lang/python/python-aiohttp/Makefile
lang/python/python-typing-extensions/Makefile [new file with mode: 0644]
libs/libdrm/Config.in
libs/libdrm/Makefile
libs/libuhttpd/Makefile
libs/redis/Makefile
libs/redis/patches/020-fix-atomicvar.patch
libs/redis/patches/030-fix-size_t-zmalloc.patch [new file with mode: 0644]
libs/xmlrpc-c/Makefile
mail/pigeonhole/Makefile
multimedia/ffmpeg/Makefile
multimedia/imagemagick/Makefile
net/family-dns/Makefile
net/frr/Makefile
net/frr/patches/046-nhrpd_cache_config_fixes.patch [new file with mode: 0644]
net/frr/patches/047-nhrpd_fix_SA_warning.patch [new file with mode: 0644]
net/frr/patches/048-nhrpd_cleanup_resources.patch [new file with mode: 0644]
net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch [new file with mode: 0644]
net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch [new file with mode: 0644]
net/frr/patches/051-ospfd_instance_fixes.patch [new file with mode: 0644]
net/frr/patches/052-nhrpd_support_for_multicast.patch [new file with mode: 0644]
net/frr/patches/053-more_SA_fixes.patch [new file with mode: 0644]
net/frr/patches/098-fix_mips_libyang.patch
net/hs20/Makefile
net/knot-resolver/Makefile
net/knot-resolver/patches/030-fix-policy-hack.patch
net/libreswan/Makefile
net/mwan3/Makefile
net/mwan3/files/usr/sbin/mwan3track
net/openvpn/Makefile
net/static-neighbor-reports/Makefile
net/uacme/Makefile
net/vpn-policy-routing/Makefile
net/vpn-policy-routing/files/vpn-policy-routing.init
net/wavemon/Makefile
net/xray-core/Makefile
sound/pulseaudio/Makefile
sound/pulseaudio/patches/010-iconv.patch
utils/docker/Makefile
utils/dockerd/Makefile
utils/dockerd/files/dockerd.init
utils/dockerd/files/etc/config/dockerd
utils/mc/Makefile
utils/runc/Makefile
utils/spi-tools/Makefile
utils/syncthing/Makefile
utils/sysstat/Makefile
utils/sysstat/patches/010-ldflags.patch
utils/tar/Makefile
utils/taskwarrior/Makefile
utils/watchcat/Makefile
utils/watchcat/files/initd_watchcat [deleted file]
utils/watchcat/files/migrate-watchcat [new file with mode: 0644]
utils/watchcat/files/uci_defaults_watchcat [deleted file]
utils/watchcat/files/watchcat.config [new file with mode: 0644]
utils/watchcat/files/watchcat.init [new file with mode: 0644]
utils/yara/Makefile
utils/yq/Makefile

index 249efff33bdbdb5192e6a3a227599fe236e1d50a..cbd9663f8b8fe389acd23e3968fdfb8044514a39 100644 (file)
@@ -32,11 +32,17 @@ jobs:
         with:
           fetch-depth: 0
 
+      - name: Determine branch name
+        run: |
+          BRANCH="${GITHUB_BASE_REF#refs/heads/}"
+          echo "Building for $BRANCH"
+          echo "BRANCH=$BRANCH" >> $GITHUB_ENV
+
       - name: Determine changed packages
         run: |
           # only detect packages with changes
           PKG_ROOTS=$(find . -name Makefile | grep -v ".*/src/Makefile" | sed -e 's@./\(.*\)/Makefile@\1/@')
-          CHANGES=$(git diff --diff-filter=d --name-only origin/master)
+          CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH)
 
           for ROOT in $PKG_ROOTS; do
             for CHANGE in $CHANGES; do
@@ -54,12 +60,6 @@ jobs:
           echo "Building $PACKAGES"
           echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV
 
-      - name: Determine branch name
-        run: |
-          BRANCH="${GITHUB_BASE_REF#refs/heads/}"
-          echo "Building for $BRANCH"
-          echo "BRANCH=$BRANCH" >> $GITHUB_ENV
-
       - name: Build
         uses: openwrt/gh-action-sdk@v1
         env:
index 4582e9373514a9befac6f8462a5b54140497a402..3036db997df127476bd57f3c264397b23c6fa986 100644 (file)
@@ -9,7 +9,7 @@ PECL_NAME:=imagick
 PECL_LONGNAME:=Image Processing (ImageMagick binding)
 
 PKG_VERSION:=3.4.4
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_HASH:=8dd5aa16465c218651fc8993e1faecd982e6a597870fd4b937e9ece02d567077
 
 PKG_NAME:=php7-pecl-imagick
@@ -29,5 +29,7 @@ include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/nls.mk
 include ../php7/pecl.mk
 
+CONFIGURE_ARGS+= --with-imagick="$(STAGING_DIR)/usr"
+
 $(eval $(call PHP7PECLPackage,imagick,$(PECL_LONGNAME),+imagemagick,30))
 $(eval $(call BuildPackage,$(PKG_NAME)))
index 60baf9ee344d9ad00fe0740829106239eee2e1e8..66205349dd6e459fd1f56ff4818dfd1d8fc6fb57 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2019-2020 CZ.NIC, z. s. p. o. (https://www.nic.cz/)
+# Copyright (C) 2019-2021 CZ.NIC, z. s. p. o. (https://www.nic.cz/)
 #
 # This is free software, licensed under the GNU General Public License v2.
 # See /LICENSE for more information.
@@ -8,11 +8,11 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=aiohttp
-PKG_VERSION:=3.7.1
+PKG_VERSION:=3.7.4
 PKG_RELEASE:=1
 
 PYPI_NAME:=$(PKG_NAME)
-PKG_HASH:=04f9d70f6c4d089be5068d7df6281e638f6820d4f1b1ec3dc012b0b43fa997d2
+PKG_HASH:=5d84ecc73141d0a0d61ece0742bb7ff5751b0657dab8405f899d3ceb104cc7de
 
 PKG_MAINTAINER:=Josef Schlehofer <pepe.schlehofer@gmail.com>
 PKG_LICENSE:=Apache-2.0
@@ -39,7 +39,8 @@ define Package/python3-aiohttp
        +python3-logging \
        +python3-codecs \
        +python3-cgi \
-       +python3-openssl
+       +python3-openssl \
+       +python3-typing-extensions
 endef
 
 define Package/python3-aiohttp/description
diff --git a/lang/python/python-typing-extensions/Makefile b/lang/python/python-typing-extensions/Makefile
new file mode 100644 (file)
index 0000000..ce1cb68
--- /dev/null
@@ -0,0 +1,42 @@
+#
+# Copyright (C) 2021 CZ.NIC, z. s. p. o. (https://www.nic.cz/)
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=python-typing-extensions
+PKG_VERSION:=3.7.4.3
+PKG_RELEASE:=1
+
+PYPI_NAME:=typing-extensions
+PYPI_SOURCE_NAME:=typing_extensions
+PKG_HASH:=99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c
+
+PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz>
+PKG_LICENSE:=PSF-2.0
+PKG_LICENSE_FILES:=LICENSE
+
+include ../pypi.mk
+include $(INCLUDE_DIR)/package.mk
+include ../python3-package.mk
+
+define Package/python3-typing-extensions
+  SUBMENU:=Python
+  SECTION:=lang
+  CATEGORY:=Languages
+  TITLE:=Module with type hints for Python
+  URL:=https://github.com/python/typing
+  DEPENDS:= \
+       +python3-light
+endef
+
+define Package/python3-typing-extensions/description
+  Backported and Experimental Type Hints for Python.
+endef
+
+$(eval $(call Py3Package,python3-typing-extensions))
+$(eval $(call BuildPackage,python3-typing-extensions))
+$(eval $(call BuildPackage,python3-typing-extensions-src))
index 32602c736ff63c03cfb00bdc5b1c487386ae455c..6199b704a86f4c22f75d6d92b4a81358e9a9e764 100644 (file)
@@ -8,4 +8,16 @@ config LIBDRM_INTEL
        help
                Installs the Intel driver.
 
+config LIBDRM_NOUVEAU
+       bool "Nouveau support"
+       default n
+       help
+               Installs the Nouveau driver.
+
+config LIBDRM_RADEON
+       bool "Radeon support"
+       default n
+       help
+               Installs the Radeon driver.
+
 endmenu
index d05ef93cf735da915be03340380f313d3e470a31..206748878305c8cd99e2a4e29e18853095a5e533 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libdrm
 PKG_VERSION:=2.4.104
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=https://dri.freedesktop.org/libdrm
@@ -17,7 +17,9 @@ PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
 PKG_LICENSE:=BSD-3-Clause
 
 PKG_CONFIG_DEPENDS:= \
-       CONFIG_LIBDRM_INTEL
+       CONFIG_LIBDRM_INTEL \
+       CONFIG_LIBDRM_NOUVEAU \
+       CONFIG_LIBDRM_RADEON
 
 PKG_INSTALL:=1
 PKG_BUILD_DEPENDS:=meson/host
@@ -45,9 +47,9 @@ endef
 
 MESON_ARGS += \
        $(if $(CONFIG_LIBDRM_INTEL),-Dintel=true -Dlibkms=true,-Dintel=false -Dlibkms=false) \
-       -Dradeon=false \
+       -Dradeon=$(if $(CONFIG_LIBDRM_RADEON),true,false) \
        -Damdgpu=false \
-       -Dnouveau=false \
+       -Dnouveau=$(if $(CONFIG_LIBDRM_NOUVEAU),true,false) \
        -Dvmwgfx=false \
        -Domap=false \
        -Dexynos=false \
@@ -64,7 +66,7 @@ MESON_ARGS += \
 
 define Build/InstallDev
        $(INSTALL_DIR) $(1)/usr/include
-       $(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
+       $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
        $(INSTALL_DIR) $(1)/usr/lib
        $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib*.so* $(1)/usr/lib/
        $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
index fa0fe0de3fcd2add398e7565a8eab751d74e320b..69c99cb5dd3ddcabac288e21d4b17c5873f607e5 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libuhttpd
-PKG_VERSION:=3.10.0
+PKG_VERSION:=3.10.1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL=https://github.com/zhaojh329/libuhttpd/releases/download/v$(PKG_VERSION)
-PKG_HASH:=78b1c670e4f259346a1e49e57d158c619eace23f0b72821b0ff2ba991f7dcc51
+PKG_HASH:=6e7a9ad61e3d0ab5bd4d20b274b850542dff8057a8fcf6c36ce59eb34818f61f
 
 PKG_MAINTAINER:=Jianhui Zhao <zhaojh329@gmail.com>
 PKG_LICENSE:=MIT
index b57849fe3263c32f7d671f680290b7d046906d12..41875887234eded35cf42827ced18e8702da2721 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=redis
-PKG_VERSION:=6.0.10
+PKG_VERSION:=6.2.0
 PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=http://download.redis.io/releases/
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=79bbb894f9dceb33ca699ee3ca4a4e1228be7fb5547aeb2f99d921e86c1285bd
+PKG_HASH:=67d624c25d962bd68aff8812a135df85bad07556b8825f3bcd5b522a9932dbca
 
 PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz>
 PKG_LICENSE:=BSD-3-Clause
index 01c18eab23a53183e7cf59988624f92b0b3ce605..bf98b0e56eb3a61a392ac7980c2255d7a4fa435e 100644 (file)
@@ -1,16 +1,16 @@
 --- a/src/atomicvar.h
 +++ b/src/atomicvar.h
-@@ -68,7 +68,7 @@
-  * is reported. */
- // #define __ATOMIC_VAR_FORCE_SYNC_MACROS
+@@ -81,7 +81,7 @@
+ #define ANNOTATE_HAPPENS_AFTER(v)  ((void) v)
+ #endif
  
--#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__ATOMIC_RELAXED) && !defined(__sun) && (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057)
-+#if defined(CONFIG_EDAC_ATOMIC_SCRUB) &&  !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__ATOMIC_RELAXED) && !defined(__sun) && (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057)
- /* Implementation using __atomic macros. */
- #define atomicIncr(var,count) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED)
-@@ -82,7 +82,7 @@
#define atomicSet(var,value) __atomic_store_n(&var,value,__ATOMIC_RELAXED)
+-#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__STDC_VERSION__) && \
++#if defined(CONFIG_EDAC_ATOMIC_SCRUB) && !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__STDC_VERSION__) && \
+     (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)
+ /* Use '_Atomic' keyword if the compiler supports. */
+ #undef  redisAtomic
+@@ -126,7 +126,7 @@
    __atomic_store_n(&var,value,__ATOMIC_SEQ_CST)
  #define REDIS_ATOMIC_API "atomic-builtin"
  
 -#elif defined(HAVE_ATOMIC)
diff --git a/libs/redis/patches/030-fix-size_t-zmalloc.patch b/libs/redis/patches/030-fix-size_t-zmalloc.patch
new file mode 100644 (file)
index 0000000..a0bfacb
--- /dev/null
@@ -0,0 +1,43 @@
+From dd885780d67f18f356a5652ab6d4f947ee035305 Mon Sep 17 00:00:00 2001
+From: Yossi Gottlieb <yossigo@gmail.com>
+Date: Tue, 23 Feb 2021 17:08:49 +0200
+Subject: [PATCH] Fix compile errors with no HAVE_MALLOC_SIZE. (#8533)
+
+Also adds a new daily CI test, relying on the fact that we don't use malloc_size() on alpine libmusl.
+
+Fixes #8531
+---
+ .github/workflows/daily.yml | 22 +++++++++++++++++++++-
+ src/zmalloc.c               |  7 ++-----
+ 2 files changed, 23 insertions(+), 6 deletions(-)
+
+--- a/src/zmalloc.c
++++ b/src/zmalloc.c
+@@ -32,6 +32,7 @@
+ #include <stdlib.h>
+ #include <stdint.h>
+ #include <unistd.h>
++#include <assert.h>
+ /* This function provide us access to the original libc free(). This is useful
+  * for instance to free results obtained by backtrace_symbols(). We need
+@@ -49,18 +50,14 @@ void zlibc_free(void *ptr) {
+ #ifdef HAVE_MALLOC_SIZE
+ #define PREFIX_SIZE (0)
++#define ASSERT_NO_SIZE_OVERFLOW(sz)
+ #else
+ #if defined(__sun) || defined(__sparc) || defined(__sparc__)
+ #define PREFIX_SIZE (sizeof(long long))
+ #else
+ #define PREFIX_SIZE (sizeof(size_t))
+ #endif
+-#endif
+-
+-#if PREFIX_SIZE > 0
+ #define ASSERT_NO_SIZE_OVERFLOW(sz) assert((sz) + PREFIX_SIZE > (sz))
+-#else
+-#define ASSERT_NO_SIZE_OVERFLOW(sz)
+ #endif
+ /* Explicitly override malloc/free etc when using tcmalloc. */
index bb564fbea4cda88ef8033024627f31d78c6cf615..1d573b4e4dbd1060e9776d9526b8810cddbbde68 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=xmlrpc-c
-PKG_VERSION:=1.51.06
-PKG_RELEASE:=2
+PKG_VERSION:=1.51.07
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tgz
 PKG_SOURCE_URL:=@SF/xmlrpc-c/Xmlrpc-c%20Super%20Stable/$(PKG_VERSION)
-PKG_HASH:=06dcd87d9c88374559369ffbe83b3139cf41418c1a2d03f20e08808085f89fd0
+PKG_HASH:=84d20ae33f927582f821d61c0b9194aefbf1d7924590a13fa9da5ae1698aded9
 
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>
 PKG_LICENSE:=VARIOUS
index a44191315681da03900e006f8179158ddc674019..68c05c6cd5cc3ce9a699724c25829fd1b8693de2 100644 (file)
@@ -8,16 +8,16 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=dovecot-pigeonhole
-PKG_VERSION_PLUGIN:=0.5.11
+PKG_VERSION_PLUGIN:=0.5.13
 PKG_VERSION_DOVECOT:=$(shell make --no-print-directory -C ../dovecot/ val.PKG_VERSION V=s)
 PKG_VERSION:=$(PKG_VERSION_DOVECOT)-$(PKG_VERSION_PLUGIN)
-PKG_RELEASE:=1
+PKG_RELEASE:=$(AUTORELEASE)
 
 DOVECOT_VERSION:=2.3
 
 PKG_SOURCE:=dovecot-$(DOVECOT_VERSION)-pigeonhole-$(PKG_VERSION_PLUGIN).tar.gz
 PKG_SOURCE_URL:=https://pigeonhole.dovecot.org/releases/$(DOVECOT_VERSION)
-PKG_HASH:=0b972a441f680545ddfacd2f41fb2a705fb03249d46ed5ce7e01fe68b6cfb5f0
+PKG_HASH:=911fe566da5b638eab1b11105314300bc9049cc3832d4bd2aed44c265013bf17
 
 PKG_MAINTAINER:=W. Michael Petullo <mike@flyn.org>
 PKG_LICENSE:=LGPL-2.1-or-later
index 1b488145840653930734cf92a8b321131293e2a4..04ea1f4fed4614aae926aa8d927f0d613ec05de1 100644 (file)
@@ -9,12 +9,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ffmpeg
-PKG_VERSION:=4.3.1
+PKG_VERSION:=4.3.2
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=https://ffmpeg.org/releases/
-PKG_HASH:=ad009240d46e307b4e03a213a0f49c11b650e445b1f8be0dda2a9212b34d2ffb
+PKG_HASH:=46e4e64f1dd0233cbc0934b9f1c0da676008cad34725113fb7f802cfa84ccddb
 PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>, \
                Ian Leonard <antonlacon@gmail.com>
 
@@ -630,7 +630,7 @@ define Build/Configure
 endef
 
 define Build/Compile
-       $(MAKE) -C $(PKG_BUILD_DIR) \
+       $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
                DESTDIR="$(PKG_INSTALL_DIR)" \
                all install
 endef
index 48242513182d354e65f59f1c8aedb41448a7e3d1..6397be753764be30a62596e3d6803c2f968bf174 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=imagemagick
 PKG_VERSION:=7.0.9
 PKG_REVISION:=5
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 PKG_MAINTAINER:=Val Kulkov <val.kulkov@gmail.com>
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_REVISION).tar.gz
@@ -126,6 +126,13 @@ define Build/InstallDev
        $(INSTALL_DATA) \
                $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* \
                $(1)/usr/lib/pkgconfig/
+
+       $(INSTALL_DIR) $(1)/usr/bin
+       $(INSTALL_BIN) \
+               $(PKG_INSTALL_DIR)/usr/bin/*-config \
+               $(1)/usr/bin/
+       $(SED) 's|prefix=/usr|prefix=$(STAGING_DIR)/usr|' \
+               $(1)/usr/bin/*-config
 endef
 
 IMlibdir:=usr/lib/ImageMagick-$(PKG_VERSION)
index e7cd4d1c33b599d421956364215adbec1fc60a6c..54728656e0e644381831b34cf927bedcc47c7e1e 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=family-dns
 PKG_VERSION:=1.0.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 PKG_LICENSE:=MIT
 PKG_MAINTAINER:=Gregory L. Dietsche <Gregory.Dietsche@cuw.edu>
 
@@ -47,7 +47,7 @@ endef
 
 define Package/family-dns/prerm
 #!/bin/sh
-if [ -z "$${IPGK_INSTROOT}" ]; then
+if [ -z "$${IPKG_INSTROOT}" ]; then
   /usr/sbin/family-dns-update uninstall
 fi
 exit 0
index f9767365fb55688e126d7019c0299dccc47f3973..44ccacf3c66af934c6a206ad2109fc05ba0747d2 100644 (file)
@@ -8,15 +8,15 @@
 include $(TOPDIR)/rules.mk
 PKG_NAME:=frr
 PKG_VERSION:=7.5
-PKG_RELEASE:=4
-PKG_SOURCE_DATE:=2021-02-05
+PKG_RELEASE:=5
+PKG_SOURCE_DATE:=2021-02-26
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
-PKG_SOURCE_VERSION:=20b35e4c3386de798f3b0cb9f2a7e6b04d995485
+PKG_SOURCE_VERSION:=13a8efb4b6e3c92e8b9361c9cb1e78a86b0194cf
 PKG_SOURCE_URL:=https://codeload.github.com/FRRouting/frr/tar.gz/$(PKG_SOURCE_VERSION)?
 
 
-PKG_HASH:=f3b4a4ce43ad60fcf4b908dc4467cbc9dae277b5829489b3d221913e043dd250
+PKG_HASH:=6e313edff69cd12444b53dbc5593892b280280b7735e620c00189a669f80bdcc
 PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
 
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
diff --git a/net/frr/patches/046-nhrpd_cache_config_fixes.patch b/net/frr/patches/046-nhrpd_cache_config_fixes.patch
new file mode 100644 (file)
index 0000000..1c07ab7
--- /dev/null
@@ -0,0 +1,385 @@
+From fef2ed139d140f551cdfcbb21c5a023dea2e02cb Mon Sep 17 00:00:00 2001
+From: Philippe Guibert <philippe.guibert@6wind.com>
+Date: Thu, 26 Mar 2020 17:33:53 +0100
+Subject: [PATCH] nhrpd: cache config may disappear if iface not present at
+ startup
+
+When interface not present at config time, store separately the list of
+config parameters. Then, when interface is ready and an address has been configured, the nbma setting is done. Reversely, when interface disappears,
+there is no need to keep the maps present, then keep only the configuration.
+
+Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
+---
+ nhrpd/nhrp_cache.c     | 86 ++++++++++++++++++++++++++++++++++++++++++
+ nhrpd/nhrp_interface.c | 63 ++++++++++++++++++++++++++++++-
+ nhrpd/nhrp_vty.c       | 49 ++++++++++++++++--------
+ nhrpd/nhrpd.h          | 14 +++++++
+ 4 files changed, 195 insertions(+), 17 deletions(-)
+
+--- a/nhrpd/nhrp_cache.c
++++ b/nhrpd/nhrp_cache.c
+@@ -16,6 +16,7 @@
+ #include "netlink.h"
+ DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE, "NHRP cache entry")
++DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE_CONFIG, "NHRP cache config entry")
+ unsigned long nhrp_cache_counts[NHRP_CACHE_NUM_TYPES];
+@@ -77,6 +78,68 @@ static void nhrp_cache_free(struct nhrp_
+       XFREE(MTYPE_NHRP_CACHE, c);
+ }
++static unsigned int nhrp_cache_config_protocol_key(const void *peer_data)
++{
++      const struct nhrp_cache_config *p = peer_data;
++      return sockunion_hash(&p->remote_addr);
++}
++
++static bool nhrp_cache_config_protocol_cmp(const void *cache_data,
++                                         const void *key_data)
++{
++      const struct nhrp_cache_config *a = cache_data;
++      const struct nhrp_cache_config *b = key_data;
++
++      if (!sockunion_same(&a->remote_addr, &b->remote_addr))
++              return false;
++      if (a->ifp != b->ifp)
++              return false;
++      return true;
++}
++
++static void *nhrp_cache_config_alloc(void *data)
++{
++      struct nhrp_cache_config *p, *key = data;
++
++      p = XCALLOC(MTYPE_NHRP_CACHE_CONFIG, sizeof(struct nhrp_cache_config));
++
++      *p = (struct nhrp_cache_config){
++              .remote_addr = key->remote_addr,
++              .ifp = key->ifp,
++      };
++      return p;
++}
++
++void nhrp_cache_config_free(struct nhrp_cache_config *c)
++{
++      struct nhrp_interface *nifp = c->ifp->info;
++
++      hash_release(nifp->cache_config_hash, c);
++      XFREE(MTYPE_NHRP_CACHE_CONFIG, c);
++}
++
++struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
++                                              union sockunion *remote_addr,
++                                              int create)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_cache_config key;
++
++      if (!nifp->cache_config_hash) {
++              nifp->cache_config_hash =
++                      hash_create(nhrp_cache_config_protocol_key,
++                                  nhrp_cache_config_protocol_cmp,
++                                  "NHRP Config Cache");
++              if (!nifp->cache_config_hash)
++                      return NULL;
++      }
++      key.remote_addr = *remote_addr;
++      key.ifp = ifp;
++
++      return hash_get(nifp->cache_config_hash, &key,
++                      create ? nhrp_cache_config_alloc : NULL);
++}
++
+ struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
+                                 union sockunion *remote_addr, int create)
+ {
+@@ -423,12 +486,23 @@ struct nhrp_cache_iterator_ctx {
+       void *ctx;
+ };
++struct nhrp_cache_config_iterator_ctx {
++      void (*cb)(struct nhrp_cache_config *, void *);
++      void *ctx;
++};
++
+ static void nhrp_cache_iterator(struct hash_bucket *b, void *ctx)
+ {
+       struct nhrp_cache_iterator_ctx *ic = ctx;
+       ic->cb(b->data, ic->ctx);
+ }
++static void nhrp_cache_config_iterator(struct hash_bucket *b, void *ctx)
++{
++      struct nhrp_cache_config_iterator_ctx *ic = ctx;
++      ic->cb(b->data, ic->ctx);
++}
++
+ void nhrp_cache_foreach(struct interface *ifp,
+                       void (*cb)(struct nhrp_cache *, void *), void *ctx)
+ {
+@@ -441,6 +515,18 @@ void nhrp_cache_foreach(struct interface
+               hash_iterate(nifp->cache_hash, nhrp_cache_iterator, &ic);
+ }
++void nhrp_cache_config_foreach(struct interface *ifp,
++                             void (*cb)(struct nhrp_cache_config *, void *), void *ctx)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_cache_config_iterator_ctx ic = {
++              .cb = cb, .ctx = ctx,
++      };
++
++      if (nifp->cache_config_hash)
++              hash_iterate(nifp->cache_config_hash, nhrp_cache_config_iterator, &ic);
++}
++
+ void nhrp_cache_notify_add(struct nhrp_cache *c, struct notifier_block *n,
+                          notifier_fn_t fn)
+ {
+--- a/nhrpd/nhrp_interface.c
++++ b/nhrpd/nhrp_interface.c
+@@ -23,6 +23,10 @@
+ DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF, "NHRP interface")
++static void nhrp_interface_update_cache_config(struct interface *ifp,
++                                             bool available,
++                                             uint8_t family);
++
+ static int nhrp_if_new_hook(struct interface *ifp)
+ {
+       struct nhrp_interface *nifp;
+@@ -311,11 +315,68 @@ int nhrp_ifp_destroy(struct interface *i
+ {
+       debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name);
++      nhrp_interface_update_cache_config(ifp, false, AF_INET);
++      nhrp_interface_update_cache_config(ifp, false, AF_INET6);
+       nhrp_interface_update(ifp);
+       return 0;
+ }
++struct map_ctx {
++      int family;
++      bool enabled;
++};
++
++static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, void *data)
++{
++      struct map_ctx *ctx = data;
++      struct interface *ifp = cc->ifp;
++      struct nhrp_cache *c;
++      union sockunion nbma_addr;
++
++      if (sockunion_family(&cc->remote_addr) != ctx->family)
++              return;
++
++      /* gre layer not ready */
++      if (ifp->vrf_id == VRF_UNKNOWN)
++              return;
++
++      c = nhrp_cache_get(ifp, &cc->remote_addr, ctx->enabled ? 1 : 0);
++      if (!c && !ctx->enabled)
++              return;
++      /* suppress */
++      if (!ctx->enabled) {
++              if (c && c->map) {
++                      nhrp_cache_update_binding(c, c->cur.type, -1,
++                                                nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
++              }
++              return;
++      }
++      /* create */
++      c->map = 1;
++      if (cc->type == NHRP_CACHE_LOCAL)
++              nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
++                                        NULL);
++      else {
++              nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
++                                        nhrp_peer_get(ifp, &cc->nbma), 0,
++                                        NULL);
++      }
++}
++
++static void nhrp_interface_update_cache_config(struct interface *ifp, bool available, uint8_t family)
++{
++      struct map_ctx mapctx;
++
++      mapctx = (struct map_ctx){
++              .family = family,
++              .enabled = available
++      };
++      nhrp_cache_config_foreach(ifp, interface_config_update_nhrp_map,
++                                &mapctx);
++
++}
++
+ int nhrp_ifp_up(struct interface *ifp)
+ {
+       debugf(NHRP_DEBUG_IF, "if-up: %s", ifp->name);
+@@ -346,7 +407,7 @@ int nhrp_interface_address_add(ZAPI_CALL
+       nhrp_interface_update_address(
+               ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
+-
++      nhrp_interface_update_cache_config(ifc->ifp, true, PREFIX_FAMILY(ifc->address));
+       return 0;
+ }
+--- a/nhrpd/nhrp_vty.c
++++ b/nhrpd/nhrp_vty.c
+@@ -494,28 +494,42 @@ DEFUN(if_nhrp_map, if_nhrp_map_cmd,
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       afi_t afi = cmd_to_afi(argv[0]);
+       union sockunion proto_addr, nbma_addr;
++      struct nhrp_cache_config *cc;
+       struct nhrp_cache *c;
++      enum nhrp_cache_type type;
+       if (str2sockunion(argv[3]->arg, &proto_addr) < 0
+           || afi2family(afi) != sockunion_family(&proto_addr))
+               return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
++      if (strmatch(argv[4]->text, "local"))
++              type = NHRP_CACHE_LOCAL;
++      else {
++              if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
++                      return nhrp_vty_return(vty, NHRP_ERR_FAIL);
++              type = NHRP_CACHE_STATIC;
++      }
++      cc = nhrp_cache_config_get(ifp, &proto_addr, 1);
++      if (!cc)
++              return nhrp_vty_return(vty, NHRP_ERR_FAIL);
++      cc->nbma = nbma_addr;
++      cc->type = type;
++      /* gre layer not ready */
++      if (ifp->ifindex == IFINDEX_INTERNAL)
++              return CMD_SUCCESS;
++
+       c = nhrp_cache_get(ifp, &proto_addr, 1);
+       if (!c)
+               return nhrp_vty_return(vty, NHRP_ERR_FAIL);
+       c->map = 1;
+-      if (strmatch(argv[4]->text, "local")) {
++      if (type == NHRP_CACHE_LOCAL)
+               nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
+                                         NULL);
+-      } else {
+-              if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
+-                      return nhrp_vty_return(vty, NHRP_ERR_FAIL);
++      else
+               nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
+                                         nhrp_peer_get(ifp, &nbma_addr), 0,
+                                         NULL);
+-      }
+-
+       return CMD_SUCCESS;
+ }
+@@ -533,15 +547,22 @@ DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       afi_t afi = cmd_to_afi(argv[1]);
+       union sockunion proto_addr, nbma_addr;
++      struct nhrp_cache_config *cc;
+       struct nhrp_cache *c;
+       if (str2sockunion(argv[4]->arg, &proto_addr) < 0
+           || afi2family(afi) != sockunion_family(&proto_addr))
+               return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
++      cc = nhrp_cache_config_get(ifp, &proto_addr, 0);
++      if (!cc)
++              return nhrp_vty_return(vty, NHRP_ERR_FAIL);
++      nhrp_cache_config_free(cc);
++
+       c = nhrp_cache_get(ifp, &proto_addr, 0);
++      /* silently return */
+       if (!c || !c->map)
+-              return nhrp_vty_return(vty, NHRP_ERR_ENTRY_NOT_FOUND);
++              return CMD_SUCCESS;
+       nhrp_cache_update_binding(c, c->cur.type, -1,
+                                 nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
+@@ -997,23 +1018,19 @@ struct write_map_ctx {
+       const char *aficmd;
+ };
+-static void interface_config_write_nhrp_map(struct nhrp_cache *c, void *data)
++static void interface_config_write_nhrp_map(struct nhrp_cache_config *c, void *data)
+ {
+       struct write_map_ctx *ctx = data;
+       struct vty *vty = ctx->vty;
+       char buf[2][SU_ADDRSTRLEN];
+-      if (!c->map)
+-              return;
+       if (sockunion_family(&c->remote_addr) != ctx->family)
+               return;
+       vty_out(vty, " %s nhrp map %s %s\n", ctx->aficmd,
+               sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])),
+-              c->cur.type == NHRP_CACHE_LOCAL
+-                      ? "local"
+-                      : sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1],
+-                                      sizeof(buf[1])));
++              c->type == NHRP_CACHE_LOCAL
++              ? "local" : sockunion2str(&c->nbma, buf[1], sizeof(buf[1])));
+ }
+ static int interface_config_write(struct vty *vty)
+@@ -1076,8 +1093,8 @@ static int interface_config_write(struct
+                               .family = afi2family(afi),
+                               .aficmd = aficmd,
+                       };
+-                      nhrp_cache_foreach(ifp, interface_config_write_nhrp_map,
+-                                         &mapctx);
++                      nhrp_cache_config_foreach(ifp, interface_config_write_nhrp_map,
++                                                &mapctx);
+                       list_for_each_entry(nhs, &ad->nhslist_head,
+                                           nhslist_entry)
+--- a/nhrpd/nhrpd.h
++++ b/nhrpd/nhrpd.h
+@@ -197,6 +197,13 @@ enum nhrp_cache_type {
+ extern const char *const nhrp_cache_type_str[];
+ extern unsigned long nhrp_cache_counts[NHRP_CACHE_NUM_TYPES];
++struct nhrp_cache_config {
++      struct interface *ifp;
++      union sockunion remote_addr;
++      enum nhrp_cache_type type;
++      union sockunion nbma;
++};
++
+ struct nhrp_cache {
+       struct interface *ifp;
+       union sockunion remote_addr;
+@@ -280,6 +287,7 @@ struct nhrp_interface {
+       uint32_t grekey;
+       struct hash *peer_hash;
++      struct hash *cache_config_hash;
+       struct hash *cache_hash;
+       struct notifier_list notifier_list;
+@@ -358,10 +366,16 @@ void nhrp_shortcut_foreach(afi_t afi,
+ void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force);
+ void nhrp_shortcut_prefix_change(const struct prefix *p, int deleted);
++void nhrp_cache_config_free(struct nhrp_cache_config *c);
++struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
++                                              union sockunion *remote_addr,
++                                              int create);
+ struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
+                                 union sockunion *remote_addr, int create);
+ void nhrp_cache_foreach(struct interface *ifp,
+                       void (*cb)(struct nhrp_cache *, void *), void *ctx);
++void nhrp_cache_config_foreach(struct interface *ifp,
++                             void (*cb)(struct nhrp_cache_config *, void *), void *ctx);
+ void nhrp_cache_set_used(struct nhrp_cache *, int);
+ int nhrp_cache_update_binding(struct nhrp_cache *, enum nhrp_cache_type type,
+                             int holding_time, struct nhrp_peer *p,
diff --git a/net/frr/patches/047-nhrpd_fix_SA_warning.patch b/net/frr/patches/047-nhrpd_fix_SA_warning.patch
new file mode 100644 (file)
index 0000000..fdf78a5
--- /dev/null
@@ -0,0 +1,48 @@
+From e5773617afba7408c76ec2683814ce076c72c79d Mon Sep 17 00:00:00 2001
+From: Mark Stapp <mjs@voltanet.io>
+Date: Tue, 8 Dec 2020 09:10:10 -0500
+Subject: [PATCH] nhrpd: fix SA warning in nhrp_interface
+
+Clear SA warning from recent nhrp cache code changes.
+
+Signed-off-by: Mark Stapp <mjs@voltanet.io>
+---
+ nhrpd/nhrp_interface.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+--- a/nhrpd/nhrp_interface.c
++++ b/nhrpd/nhrp_interface.c
+@@ -327,7 +327,8 @@ struct map_ctx {
+       bool enabled;
+ };
+-static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, void *data)
++static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc,
++                                           void *data)
+ {
+       struct map_ctx *ctx = data;
+       struct interface *ifp = cc->ifp;
+@@ -344,15 +345,20 @@ static void interface_config_update_nhrp
+       c = nhrp_cache_get(ifp, &cc->remote_addr, ctx->enabled ? 1 : 0);
+       if (!c && !ctx->enabled)
+               return;
++
+       /* suppress */
+       if (!ctx->enabled) {
+               if (c && c->map) {
+-                      nhrp_cache_update_binding(c, c->cur.type, -1,
+-                                                nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
++                      nhrp_cache_update_binding(
++                              c, c->cur.type, -1,
++                              nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
+               }
+               return;
+       }
+-      /* create */
++
++      /* Newly created */
++      assert(c != NULL);
++
+       c->map = 1;
+       if (cc->type == NHRP_CACHE_LOCAL)
+               nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
diff --git a/net/frr/patches/048-nhrpd_cleanup_resources.patch b/net/frr/patches/048-nhrpd_cleanup_resources.patch
new file mode 100644 (file)
index 0000000..5eafe61
--- /dev/null
@@ -0,0 +1,226 @@
+From ee72f0a0eb93038ef6dfd01fed9f32e24c5de2a1 Mon Sep 17 00:00:00 2001
+From: Reuben Dowle <reuben.dowle@4rf.com>
+Date: Mon, 7 Dec 2020 16:35:13 +1300
+Subject: [PATCH] nhrpd: Cleanup resources when interface is deleted
+
+Currently when an interface is deleted from configuration, associated
+resources are not freed. This causes memory leaks and crashes.
+
+To reproduce this issue:
+* Connect to a DMVPN hub
+* Outside of frr, delete the underlying GRE interface
+* Use 'no interface xxx' to delete the interface containing nhrp configurations
+
+Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
+---
+ nhrpd/nhrp_cache.c     | 42 ++++++++++++++++++++++++++++++++++++++++--
+ nhrpd/nhrp_interface.c | 15 +++++++++++++++
+ nhrpd/nhrp_nhs.c       | 18 ++++++++++++++++++
+ nhrpd/nhrp_peer.c      | 27 +++++++++++++++++++++++++++
+ nhrpd/nhrpd.h          |  3 +++
+ 5 files changed, 103 insertions(+), 2 deletions(-)
+ mode change 100644 => 100755 nhrpd/nhrp_cache.c
+ mode change 100644 => 100755 nhrpd/nhrp_interface.c
+ mode change 100644 => 100755 nhrpd/nhrpd.h
+
+--- a/nhrpd/nhrp_cache.c
++++ b/nhrpd/nhrp_cache.c
+@@ -69,12 +69,13 @@ static void nhrp_cache_free(struct nhrp_
+ {
+       struct nhrp_interface *nifp = c->ifp->info;
+-      zassert(c->cur.type == NHRP_CACHE_INVALID && c->cur.peer == NULL);
+-      zassert(c->new.type == NHRP_CACHE_INVALID && c->new.peer == NULL);
++      debugf(NHRP_DEBUG_COMMON, "Deleting cache entry");
+       nhrp_cache_counts[c->cur.type]--;
+       notifier_call(&c->notifier_list, NOTIFY_CACHE_DELETE);
+       zassert(!notifier_active(&c->notifier_list));
+       hash_release(nifp->cache_hash, c);
++      THREAD_OFF(c->t_timeout);
++      THREAD_OFF(c->t_auth);
+       XFREE(MTYPE_NHRP_CACHE, c);
+ }
+@@ -140,6 +141,41 @@ struct nhrp_cache_config *nhrp_cache_con
+                       create ? nhrp_cache_config_alloc : NULL);
+ }
++static void do_nhrp_cache_free(struct hash_bucket *hb,
++                             void *arg __attribute__((__unused__)))
++{
++      struct nhrp_cache *c = hb->data;
++
++      nhrp_cache_free(c);
++}
++
++static void do_nhrp_cache_config_free(struct hash_bucket *hb,
++                                    void *arg __attribute__((__unused__)))
++{
++      struct nhrp_cache_config *cc = hb->data;
++
++      nhrp_cache_config_free(cc);
++}
++
++void nhrp_cache_interface_del(struct interface *ifp)
++{
++      struct nhrp_interface *nifp = ifp->info;
++
++      debugf(NHRP_DEBUG_COMMON, "Cleaning up undeleted cache entries (%lu)",
++             nifp->cache_hash ? nifp->cache_hash->count : 0);
++
++      if (nifp->cache_hash) {
++              hash_iterate(nifp->cache_hash, do_nhrp_cache_free, NULL);
++              hash_free(nifp->cache_hash);
++      }
++
++      if (nifp->cache_config_hash) {
++              hash_iterate(nifp->cache_config_hash, do_nhrp_cache_config_free,
++                           NULL);
++              hash_free(nifp->cache_config_hash);
++      }
++}
++
+ struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
+                                 union sockunion *remote_addr, int create)
+ {
+@@ -164,6 +200,7 @@ struct nhrp_cache *nhrp_cache_get(struct
+ static int nhrp_cache_do_free(struct thread *t)
+ {
+       struct nhrp_cache *c = THREAD_ARG(t);
++
+       c->t_timeout = NULL;
+       nhrp_cache_free(c);
+       return 0;
+@@ -172,6 +209,7 @@ static int nhrp_cache_do_free(struct thr
+ static int nhrp_cache_do_timeout(struct thread *t)
+ {
+       struct nhrp_cache *c = THREAD_ARG(t);
++
+       c->t_timeout = NULL;
+       if (c->cur.type != NHRP_CACHE_INVALID)
+               nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
+--- a/nhrpd/nhrp_interface.c
++++ b/nhrpd/nhrp_interface.c
+@@ -49,6 +49,21 @@ static int nhrp_if_new_hook(struct inter
+ static int nhrp_if_delete_hook(struct interface *ifp)
+ {
++      struct nhrp_interface *nifp = ifp->info;
++
++      debugf(NHRP_DEBUG_IF, "Deleted interface (%s)", ifp->name);
++
++      nhrp_cache_interface_del(ifp);
++      nhrp_nhs_interface_del(ifp);
++      nhrp_peer_interface_del(ifp);
++
++      if (nifp->ipsec_profile)
++              free(nifp->ipsec_profile);
++      if (nifp->ipsec_fallback_profile)
++              free(nifp->ipsec_fallback_profile);
++      if (nifp->source)
++              free(nifp->source);
++
+       XFREE(MTYPE_NHRP_IF, ifp->info);
+       return 0;
+ }
+--- a/nhrpd/nhrp_nhs.c
++++ b/nhrpd/nhrp_nhs.c
+@@ -378,6 +378,24 @@ int nhrp_nhs_free(struct nhrp_nhs *nhs)
+       return 0;
+ }
++void nhrp_nhs_interface_del(struct interface *ifp)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_nhs *nhs, *tmp;
++      afi_t afi;
++
++      for (afi = 0; afi < AFI_MAX; afi++) {
++              debugf(NHRP_DEBUG_COMMON, "Cleaning up nhs entries (%d)",
++                     !list_empty(&nifp->afi[afi].nhslist_head));
++
++              list_for_each_entry_safe(nhs, tmp, &nifp->afi[afi].nhslist_head,
++                                       nhslist_entry)
++              {
++                      nhrp_nhs_free(nhs);
++              }
++      }
++}
++
+ void nhrp_nhs_terminate(void)
+ {
+       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+--- a/nhrpd/nhrp_peer.c
++++ b/nhrpd/nhrp_peer.c
+@@ -38,11 +38,17 @@ static void nhrp_packet_debug(struct zbu
+ static void nhrp_peer_check_delete(struct nhrp_peer *p)
+ {
++      char buf[2][256];
+       struct nhrp_interface *nifp = p->ifp->info;
+       if (p->ref || notifier_active(&p->notifier_list))
+               return;
++      debugf(NHRP_DEBUG_COMMON, "Deleting peer ref:%d remote:%s local:%s",
++             p->ref,
++             sockunion2str(&p->vc->remote.nbma, buf[0], sizeof(buf[0])),
++             sockunion2str(&p->vc->local.nbma, buf[1], sizeof(buf[1])));
++
+       THREAD_OFF(p->t_fallback);
+       hash_release(nifp->peer_hash, p);
+       nhrp_interface_notify_del(p->ifp, &p->ifp_notifier);
+@@ -185,6 +191,27 @@ static void *nhrp_peer_create(void *data
+       return p;
+ }
++static void do_peer_hash_free(struct hash_bucket *hb,
++                            void *arg __attribute__((__unused__)))
++{
++      struct nhrp_peer *p = hb->data;
++      nhrp_peer_check_delete(p);
++}
++
++void nhrp_peer_interface_del(struct interface *ifp)
++{
++      struct nhrp_interface *nifp = ifp->info;
++
++      debugf(NHRP_DEBUG_COMMON, "Cleaning up undeleted peer entries (%lu)",
++             nifp->peer_hash ? nifp->peer_hash->count : 0);
++
++      if (nifp->peer_hash) {
++              hash_iterate(nifp->peer_hash, do_peer_hash_free, NULL);
++              assert(nifp->peer_hash->count == 0);
++              hash_free(nifp->peer_hash);
++      }
++}
++
+ struct nhrp_peer *nhrp_peer_get(struct interface *ifp,
+                               const union sockunion *remote_nbma)
+ {
+--- a/nhrpd/nhrpd.h
++++ b/nhrpd/nhrpd.h
+@@ -343,6 +343,7 @@ void nhrp_nhs_foreach(struct interface *
+                     void (*cb)(struct nhrp_nhs *, struct nhrp_registration *,
+                                void *),
+                     void *ctx);
++void nhrp_nhs_interface_del(struct interface *ifp);
+ void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp);
+ void nhrp_route_announce(int add, enum nhrp_cache_type type,
+@@ -366,6 +367,7 @@ void nhrp_shortcut_foreach(afi_t afi,
+ void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force);
+ void nhrp_shortcut_prefix_change(const struct prefix *p, int deleted);
++void nhrp_cache_interface_del(struct interface *ifp);
+ void nhrp_cache_config_free(struct nhrp_cache_config *c);
+ struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
+                                               union sockunion *remote_addr,
+@@ -446,6 +448,7 @@ struct nhrp_reqid *nhrp_reqid_lookup(str
+ int nhrp_packet_init(void);
++void nhrp_peer_interface_del(struct interface *ifp);
+ struct nhrp_peer *nhrp_peer_get(struct interface *ifp,
+                               const union sockunion *remote_nbma);
+ struct nhrp_peer *nhrp_peer_ref(struct nhrp_peer *p);
diff --git a/net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch b/net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch
new file mode 100644 (file)
index 0000000..ba259cb
--- /dev/null
@@ -0,0 +1,383 @@
+From f91ce319d3cdb465df54ff4e091dbd4aed85b24c Mon Sep 17 00:00:00 2001
+From: Mobashshera Rasool <mrasool@vmware.com>
+Date: Wed, 23 Dec 2020 13:20:22 +0000
+Subject: [PATCH] ospfd: Clear ip ospf process and clear ip ospf neighbor
+
+Implement the below 2 CLIs to clear the current data in the process
+and neighbor data structure.
+1. clear ip ospf process
+2. clear ip ospf neighbor
+
+Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
+---
+ doc/user/ospfd.rst | 17 ++++++++
+ ospfd/ospf_ase.c   |  1 +
+ ospfd/ospf_lsa.c   | 13 +++++-
+ ospfd/ospf_vty.c   | 72 +++++++++++++++++++++++++++++++--
+ ospfd/ospfd.c      | 99 ++++++++++++++++++++++++++++++++++++----------
+ ospfd/ospfd.h      |  5 +++
+ 6 files changed, 182 insertions(+), 25 deletions(-)
+
+--- a/doc/user/ospfd.rst
++++ b/doc/user/ospfd.rst
+@@ -322,6 +322,23 @@ To start OSPF process you have to specif
+    This feature is enabled by default.
++.. index:: clear ip ospf [(1-65535)] process
++.. clicmd:: clear ip ospf [(1-65535)] process
++
++   This command can be used to clear the ospf process data structures. This
++   will clear the ospf neighborship as well and it will get re-established.
++   This will clear the LSDB too. This will be helpful when there is a change
++   in router-id and if user wants the router-id change to take effect, user can
++   use this cli instead of restarting the ospfd daemon.
++
++.. index:: clear ip ospf [(1-65535)] neighbor
++.. clicmd:: clear ip ospf [(1-65535)] neighbor
++
++   This command can be used to clear the ospf neighbor data structures. This
++   will clear the ospf neighborship and it will get re-established. This
++   command can be used when the neighbor state get stuck at some state and
++   this can be used to recover it from that state.
++
+ .. _ospf-area:
+ Areas
+--- a/ospfd/ospf_ase.c
++++ b/ospfd/ospf_ase.c
+@@ -753,6 +753,7 @@ void ospf_ase_unregister_external_lsa(st
+               lst = rn->info;
+               listnode_delete(lst, lsa);
+               ospf_lsa_unlock(&lsa); /* external_lsas list */
++
+               route_unlock_node(rn);
+       }
+ }
+--- a/ospfd/ospf_lsa.c
++++ b/ospfd/ospf_lsa.c
+@@ -2735,7 +2735,7 @@ int ospf_check_nbr_status(struct ospf *o
+ static int ospf_maxage_lsa_remover(struct thread *thread)
+ {
+       struct ospf *ospf = THREAD_ARG(thread);
+-      struct ospf_lsa *lsa;
++      struct ospf_lsa *lsa, *old;
+       struct route_node *rn;
+       int reschedule = 0;
+@@ -2797,6 +2797,17 @@ static int ospf_maxage_lsa_remover(struc
+                       /* Remove from lsdb. */
+                       if (lsa->lsdb) {
++                              old = ospf_lsdb_lookup(lsa->lsdb, lsa);
++                              /* The max age LSA here must be the same
++                               * as the LSA in LSDB
++                               */
++                              if (old != lsa) {
++                                      flog_err(EC_OSPF_LSA_MISSING,
++                                      "%s: LSA[Type%d:%s]: LSA not in LSDB",
++                                      __func__, lsa->data->type,
++                                      inet_ntoa(lsa->data->id));
++                                      continue;
++                              }
+                               ospf_discard_from_db(ospf, lsa->lsdb, lsa);
+                               ospf_lsdb_delete(lsa->lsdb, lsa);
+                       } else {
+--- a/ospfd/ospf_vty.c
++++ b/ospfd/ospf_vty.c
+@@ -276,7 +276,7 @@ DEFPY (ospf_router_id,
+       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
+               if (area->full_nbrs) {
+                       vty_out(vty,
+-                              "For this router-id change to take effect, save config and restart ospfd\n");
++                              "For this router-id change to take effect, use “clear ip ospf process” command\n");
+                       return CMD_SUCCESS;
+               }
+@@ -309,7 +309,7 @@ DEFUN_HIDDEN (ospf_router_id_old,
+       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
+               if (area->full_nbrs) {
+                       vty_out(vty,
+-                              "For this router-id change to take effect, save config and restart ospfd\n");
++                              "For this router-id change to take effect, use “clear ip ospf process” command\n");
+                       return CMD_SUCCESS;
+               }
+@@ -342,7 +342,7 @@ DEFPY (no_ospf_router_id,
+       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
+               if (area->full_nbrs) {
+                       vty_out(vty,
+-                              "For this router-id change to take effect, save config and restart ospfd\n");
++                              "For this router-id change to take effect, use “clear ip ospf process” command\n");
+                       return CMD_SUCCESS;
+               }
+@@ -9769,6 +9769,70 @@ DEFUN (show_ip_ospf_vrfs,
+       return CMD_SUCCESS;
+ }
++DEFPY (clear_ip_ospf_neighbor,
++       clear_ip_ospf_neighbor_cmd,
++       "clear ip ospf [(1-65535)]$instance neighbor [A.B.C.D$nbr_id]",
++       CLEAR_STR
++       IP_STR
++       "OSPF information\n"
++       "Instance ID\n"
++       "Reset OSPF Neighbor\n"
++       "Neighbor ID\n")
++{
++      struct listnode *node;
++      struct ospf *ospf = NULL;
++
++      /* If user does not specify the arguments,
++       * instance = 0 and nbr_id = 0.0.0.0
++       */
++      if (instance != 0) {
++              /* This means clear only the particular ospf process */
++              ospf = ospf_lookup_instance(instance);
++              if (ospf == NULL)
++                      return CMD_NOT_MY_INSTANCE;
++      }
++
++      /* Clear all the ospf processes */
++      for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
++              if (!ospf->oi_running)
++                      continue;
++
++              ospf_neighbor_reset(ospf, nbr_id, nbr_id_str);
++      }
++
++      return CMD_SUCCESS;
++}
++
++DEFPY (clear_ip_ospf_process,
++       clear_ip_ospf_process_cmd,
++       "clear ip ospf [(1-65535)]$instance process",
++       CLEAR_STR
++       IP_STR
++       "OSPF information\n"
++       "Instance ID\n"
++       "Reset OSPF Process\n")
++{
++      struct listnode *node;
++      struct ospf *ospf = NULL;
++
++      /* Check if instance is not passed as an argument */
++      if (instance != 0) {
++              /* This means clear only the particular ospf process */
++              ospf = ospf_lookup_instance(instance);
++              if (ospf == NULL)
++                      return CMD_NOT_MY_INSTANCE;
++      }
++
++      /* Clear all the ospf processes */
++      for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
++              if (!ospf->oi_running)
++                      continue;
++
++              ospf_process_reset(ospf);
++      }
++
++      return CMD_SUCCESS;
++}
+ static const char *const ospf_abr_type_str[] = {
+       "unknown", "standard", "ibm", "cisco", "shortcut"
+@@ -10806,6 +10870,8 @@ DEFUN (clear_ip_ospf_interface,
+ void ospf_vty_clear_init(void)
+ {
+       install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
++      install_element(ENABLE_NODE, &clear_ip_ospf_process_cmd);
++      install_element(ENABLE_NODE, &clear_ip_ospf_neighbor_cmd);
+ }
+--- a/ospfd/ospfd.c
++++ b/ospfd/ospfd.c
+@@ -84,13 +84,15 @@ static void ospf_finish_final(struct osp
+ #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
+-void ospf_router_id_update(struct ospf *ospf)
++void ospf_process_refresh_data(struct ospf *ospf, bool reset)
+ {
+       struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
+       struct in_addr router_id, router_id_old;
+       struct ospf_interface *oi;
+       struct interface *ifp;
+-      struct listnode *node;
++      struct listnode *node, *nnode;
++      struct ospf_area *area;
++      bool rid_change = false;
+       if (!ospf->oi_running) {
+               if (IS_DEBUG_OSPF_EVENT)
+@@ -123,8 +125,8 @@ void ospf_router_id_update(struct ospf *
+               zlog_debug("Router-ID[OLD:%s]: Update to %s",
+                          inet_ntoa(ospf->router_id), inet_ntoa(router_id));
+-      if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
+-
++      rid_change = !(IPV4_ADDR_SAME(&router_id_old, &router_id));
++      if (rid_change || (reset)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+                       /* Some nbrs are identified by router_id, these needs
+                        * to be rebuilt. Possible optimization would be to do
+@@ -146,16 +148,8 @@ void ospf_router_id_update(struct ospf *
+                               ospf_if_up(oi);
+               }
+-              /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF
+-               * flag */
+-              if (ospf->lsdb) {
+-                      struct route_node *rn;
+-                      struct ospf_lsa *lsa;
+-
+-                      LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
+-                              if (IS_LSA_SELF(lsa))
+-                                      ospf_lsa_flush_schedule(ospf, lsa);
+-              }
++              /* Flush (inline) all the self originated LSAs */
++              ospf_flush_self_originated_lsas_now(ospf);
+               ospf->router_id = router_id;
+               if (IS_DEBUG_OSPF_EVENT)
+@@ -180,24 +174,81 @@ void ospf_router_id_update(struct ospf *
+                       LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
+                               /* AdvRouter and Router ID is the same. */
+                               if (IPV4_ADDR_SAME(&lsa->data->adv_router,
+-                                                 &ospf->router_id)) {
++                                      &ospf->router_id) && rid_change) {
+                                       SET_FLAG(lsa->flags,
+                                                OSPF_LSA_SELF_CHECKED);
+                                       SET_FLAG(lsa->flags, OSPF_LSA_SELF);
+                                       ospf_lsa_flush_schedule(ospf, lsa);
+                               }
++                              /* The above flush will send immediately
++                               * So discard the LSA to originate new
++                               */
++                              ospf_discard_from_db(ospf, ospf->lsdb, lsa);
+                       }
++
++                      LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
++                              ospf_discard_from_db(ospf, ospf->lsdb, lsa);
++
++                      ospf_lsdb_delete_all(ospf->lsdb);
+               }
++              /* Delete the LSDB */
++              for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
++                      ospf_area_lsdb_discard_delete(area);
++
+               /* update router-lsa's for each area */
+               ospf_router_lsa_update(ospf);
+               /* update ospf_interface's */
+-              FOR_ALL_INTERFACES (vrf, ifp)
+-                      ospf_if_update(ospf, ifp);
++              FOR_ALL_INTERFACES (vrf, ifp) {
++                      if (reset)
++                              ospf_if_reset(ifp);
++                      else
++                              ospf_if_update(ospf, ifp);
++              }
+               ospf_external_lsa_rid_change(ospf);
+       }
++
++      ospf->inst_shutdown = 0;
++}
++
++void ospf_router_id_update(struct ospf *ospf)
++{
++      ospf_process_refresh_data(ospf, false);
++}
++
++void ospf_process_reset(struct ospf *ospf)
++{
++      ospf_process_refresh_data(ospf, true);
++}
++
++void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
++                      const char *nbr_str)
++{
++      struct route_node *rn;
++      struct ospf_neighbor *nbr;
++      struct ospf_interface *oi;
++      struct listnode *node;
++
++      /* Clear only a particular nbr with nbr router id as nbr_id */
++      if (nbr_str != NULL) {
++              for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
++                      nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &nbr_id);
++                      if (nbr)
++                              OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
++              }
++              return;
++      }
++
++      /* send Neighbor event KillNbr to all associated neighbors. */
++      for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
++              for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
++                      nbr = rn->info;
++                      if (nbr && (nbr != oi->nbr_self))
++                              OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
++              }
++      }
+ }
+ /* For OSPF area sort by area id. */
+@@ -839,14 +890,11 @@ static struct ospf_area *ospf_area_new(s
+       return new;
+ }
+-static void ospf_area_free(struct ospf_area *area)
++void ospf_area_lsdb_discard_delete(struct ospf_area *area)
+ {
+       struct route_node *rn;
+       struct ospf_lsa *lsa;
+-      ospf_opaque_type10_lsa_term(area);
+-
+-      /* Free LSDBs. */
+       LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
+               ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+       LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
+@@ -864,6 +912,15 @@ static void ospf_area_free(struct ospf_a
+               ospf_discard_from_db(area->ospf, area->lsdb, lsa);
+       ospf_lsdb_delete_all(area->lsdb);
++}
++
++static void ospf_area_free(struct ospf_area *area)
++{
++      ospf_opaque_type10_lsa_term(area);
++
++      /* Free LSDBs. */
++      ospf_area_lsdb_discard_delete(area);
++
+       ospf_lsdb_free(area->lsdb);
+       ospf_lsa_unlock(&area->router_lsa_self);
+--- a/ospfd/ospfd.h
++++ b/ospfd/ospfd.h
+@@ -523,7 +523,11 @@ extern struct ospf *ospf_lookup_by_inst_
+                                            const char *name);
+ extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
+ extern void ospf_finish(struct ospf *);
++extern void ospf_process_refresh_data(struct ospf *ospf, bool reset);
+ extern void ospf_router_id_update(struct ospf *ospf);
++extern void ospf_process_reset(struct ospf *ospf);
++extern void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
++                              const char *nbr_str);
+ extern int ospf_network_set(struct ospf *, struct prefix_ipv4 *, struct in_addr,
+                           int);
+ extern int ospf_network_unset(struct ospf *, struct prefix_ipv4 *,
+@@ -548,6 +552,7 @@ extern int ospf_area_shortcut_set(struct
+ extern int ospf_area_shortcut_unset(struct ospf *, struct ospf_area *);
+ extern int ospf_timers_refresh_set(struct ospf *, int);
+ extern int ospf_timers_refresh_unset(struct ospf *);
++void ospf_area_lsdb_discard_delete(struct ospf_area *area);
+ extern int ospf_nbr_nbma_set(struct ospf *, struct in_addr);
+ extern int ospf_nbr_nbma_unset(struct ospf *, struct in_addr);
+ extern int ospf_nbr_nbma_priority_set(struct ospf *, struct in_addr, uint8_t);
diff --git a/net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch b/net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch
new file mode 100644 (file)
index 0000000..c9c4906
--- /dev/null
@@ -0,0 +1,105 @@
+From 153bdb3d03542530ed1deccbefc716cb4b699a67 Mon Sep 17 00:00:00 2001
+From: Donald Sharp <sharpd@nvidia.com>
+Date: Thu, 28 Jan 2021 14:56:11 -0500
+Subject: [PATCH] ospfd: ospf_nbr_nbma_lookup_next always returns NULL
+
+The calling function of ospf_nbr_nbma_lookup_next calls
+this function and then immediately returns when it
+gets the NULL.  Just cleanup a bit more code.
+
+Signed-off-by: Donald Sharp <sharpd@nvidia.com>
+---
+ ospfd/ospf_snmp.c | 23 +----------------------
+ ospfd/ospfd.c     |  9 ---------
+ ospfd/ospfd.h     |  2 --
+ 3 files changed, 1 insertion(+), 33 deletions(-)
+
+--- a/ospfd/ospf_snmp.c
++++ b/ospfd/ospf_snmp.c
+@@ -1236,7 +1236,6 @@ static struct ospf_nbr_nbma *ospfHostLoo
+                                           size_t *length,
+                                           struct in_addr *addr, int exact)
+ {
+-      int len;
+       struct ospf_nbr_nbma *nbr_nbma;
+       struct ospf *ospf;
+@@ -1258,28 +1257,8 @@ static struct ospf_nbr_nbma *ospfHostLoo
+               nbr_nbma = ospf_nbr_nbma_lookup(ospf, *addr);
+               return nbr_nbma;
+-      } else {
+-              len = *length - v->namelen;
+-              if (len > 4)
+-                      len = 4;
+-
+-              oid2in_addr(name + v->namelen, len, addr);
+-
+-              nbr_nbma =
+-                      ospf_nbr_nbma_lookup_next(ospf, addr, len == 0 ? 1 : 0);
+-
+-              if (nbr_nbma == NULL)
+-                      return NULL;
+-
+-              oid_copy_addr(name + v->namelen, addr, IN_ADDR_SIZE);
+-
+-              /* Set TOS 0. */
+-              name[v->namelen + IN_ADDR_SIZE] = 0;
+-
+-              *length = v->namelen + IN_ADDR_SIZE + 1;
+-
+-              return nbr_nbma;
+       }
++
+       return NULL;
+ }
+--- a/ospfd/ospfd.c
++++ b/ospfd/ospfd.c
+@@ -1932,35 +1932,6 @@ struct ospf_nbr_nbma *ospf_nbr_nbma_look
+       return NULL;
+ }
+-struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next(struct ospf *ospf,
+-                                              struct in_addr *addr, int first)
+-{
+-#if 0
+-  struct ospf_nbr_nbma *nbr_nbma;
+-  struct listnode *node;
+-#endif
+-
+-      if (ospf == NULL)
+-              return NULL;
+-
+-#if 0
+-  for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
+-    {
+-      if (first)
+-      {
+-        *addr = nbr_nbma->addr;
+-        return nbr_nbma;
+-      }
+-      else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
+-      {
+-        *addr = nbr_nbma->addr;
+-        return nbr_nbma;
+-      }
+-    }
+-#endif
+-      return NULL;
+-}
+-
+ int ospf_nbr_nbma_set(struct ospf *ospf, struct in_addr nbr_addr)
+ {
+       struct ospf_nbr_nbma *nbr_nbma;
+--- a/ospfd/ospfd.h
++++ b/ospfd/ospfd.h
+@@ -567,8 +567,6 @@ extern void ospf_terminate(void);
+ extern void ospf_nbr_nbma_if_update(struct ospf *, struct ospf_interface *);
+ extern struct ospf_nbr_nbma *ospf_nbr_nbma_lookup(struct ospf *,
+                                                 struct in_addr);
+-extern struct ospf_nbr_nbma *ospf_nbr_nbma_lookup_next(struct ospf *,
+-                                                     struct in_addr *, int);
+ extern int ospf_oi_count(struct interface *);
+ extern struct ospf_area *ospf_area_get(struct ospf *, struct in_addr);
diff --git a/net/frr/patches/051-ospfd_instance_fixes.patch b/net/frr/patches/051-ospfd_instance_fixes.patch
new file mode 100644 (file)
index 0000000..91f999a
--- /dev/null
@@ -0,0 +1,797 @@
+From 409f98ab443682ec360e3e76954f1c8985b3371d Mon Sep 17 00:00:00 2001
+From: Igor Ryzhov <iryzhov@nfware.com>
+Date: Thu, 28 Jan 2021 02:41:07 +0300
+Subject: [PATCH 1/2] ospfd: don't rely on instance existence in vty
+
+Store instance index at startup and use it when processing vty commands.
+The instance itself may be created and deleted by the user in runtime
+using `[no] router ospf X` command.
+
+Fixes #7908
+
+Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
+---
+ ospfd/ospf_dump.c |  70 ++++++---------
+ ospfd/ospf_main.c |  20 +----
+ ospfd/ospf_vty.c  | 220 +++++++++++++++++++++++-----------------------
+ ospfd/ospfd.c     |  26 +++---
+ ospfd/ospfd.h     |   3 +-
+ 5 files changed, 154 insertions(+), 185 deletions(-)
+
+--- a/ospfd/ospf_dump.c
++++ b/ospfd/ospf_dump.c
+@@ -607,7 +607,7 @@ DEFUN (debug_ospf_packet,
+       if (inst) // user passed instance ID
+       {
+-              if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10)))
++              if (inst != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+       }
+@@ -683,7 +683,7 @@ DEFUN (no_debug_ospf_packet,
+       if (inst) // user passed instance ID
+       {
+-              if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10)))
++              if (inst != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+       }
+@@ -754,7 +754,7 @@ DEFUN (debug_ospf_ism,
+       if (inst) // user passed instance ID
+       {
+-              if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10)))
++              if (inst != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+       }
+@@ -805,7 +805,7 @@ DEFUN (no_debug_ospf_ism,
+       if (inst) // user passed instance ID
+       {
+-              if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10)))
++              if (inst != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+       }
+@@ -900,8 +900,8 @@ DEFUN (debug_ospf_instance_nsm,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+       return debug_ospf_nsm_common(vty, 4, argc, argv);
+ }
+@@ -972,7 +972,7 @@ DEFUN (no_debug_ospf_instance_nsm,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+       return no_debug_ospf_nsm_common(vty, 5, argc, argv);
+@@ -1046,7 +1046,7 @@ DEFUN (debug_ospf_instance_lsa,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+       return debug_ospf_lsa_common(vty, 4, argc, argv);
+@@ -1122,7 +1122,7 @@ DEFUN (no_debug_ospf_instance_lsa,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+       return no_debug_ospf_lsa_common(vty, 5, argc, argv);
+@@ -1184,7 +1184,7 @@ DEFUN (debug_ospf_instance_zebra,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+       return debug_ospf_zebra_common(vty, 4, argc, argv);
+@@ -1248,8 +1248,8 @@ DEFUN (no_debug_ospf_instance_zebra,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+       return no_debug_ospf_zebra_common(vty, 5, argc, argv);
+ }
+@@ -1294,8 +1294,8 @@ DEFUN (debug_ospf_instance_event,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+       if (vty->node == CONFIG_NODE)
+               CONF_DEBUG_ON(event, EVENT);
+@@ -1316,8 +1316,8 @@ DEFUN (no_debug_ospf_instance_event,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+       if (vty->node == CONFIG_NODE)
+               CONF_DEBUG_OFF(event, EVENT);
+@@ -1364,8 +1364,8 @@ DEFUN (debug_ospf_instance_nssa,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+       if (vty->node == CONFIG_NODE)
+               CONF_DEBUG_ON(nssa, NSSA);
+@@ -1386,8 +1386,8 @@ DEFUN (no_debug_ospf_instance_nssa,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if (!ospf_lookup_instance(instance))
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+       if (vty->node == CONFIG_NODE)
+               CONF_DEBUG_OFF(nssa, NSSA);
+@@ -1536,12 +1536,12 @@ DEFUN (no_debug_ospf,
+       return CMD_SUCCESS;
+ }
+-static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf)
++static int show_debugging_ospf_common(struct vty *vty)
+ {
+       int i;
+-      if (ospf->instance)
+-              vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
++      if (ospf_instance)
++              vty_out(vty, "\nOSPF Instance: %d\n\n", ospf_instance);
+       vty_out(vty, "OSPF debugging status:\n");
+@@ -1645,13 +1645,7 @@ DEFUN_NOSH (show_debugging_ospf,
+           DEBUG_STR
+           OSPF_STR)
+ {
+-      struct ospf *ospf = NULL;
+-
+-      ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+-      if (ospf == NULL)
+-              return CMD_SUCCESS;
+-
+-      return show_debugging_ospf_common(vty, ospf);
++      return show_debugging_ospf_common(vty);
+ }
+ DEFUN_NOSH (show_debugging_ospf_instance,
+@@ -1663,14 +1657,13 @@ DEFUN_NOSH (show_debugging_ospf_instance
+           "Instance ID\n")
+ {
+       int idx_number = 3;
+-      struct ospf *ospf;
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      if ((ospf = ospf_lookup_instance(instance)) == NULL)
+-              return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
+-      return show_debugging_ospf_common(vty, ospf);
++      return show_debugging_ospf_common(vty);
+ }
+ static int config_write_debug(struct vty *vty);
+@@ -1693,16 +1686,11 @@ static int config_write_debug(struct vty
+               "",     " send",        " recv",        "",
+               " detail", " send detail", " recv detail", " detail"};
+-      struct ospf *ospf;
+       char str[16];
+       memset(str, 0, 16);
+-      ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+-      if (ospf == NULL)
+-              return CMD_SUCCESS;
+-
+-      if (ospf->instance)
+-              snprintf(str, sizeof(str), " %u", ospf->instance);
++      if (ospf_instance)
++              snprintf(str, sizeof(str), " %u", ospf_instance);
+       /* debug ospf ism (status|events|timers). */
+       if (IS_CONF_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM)
+--- a/ospfd/ospf_main.c
++++ b/ospfd/ospf_main.c
+@@ -145,9 +145,6 @@ FRR_DAEMON_INFO(ospfd, OSPF, .vty_port =
+ /* OSPFd main routine. */
+ int main(int argc, char **argv)
+ {
+-      unsigned short instance = 0;
+-      bool created = false;
+-
+ #ifdef SUPPORT_OSPF_API
+       /* OSPF apiserver is disabled by default. */
+       ospf_apiserver_enable = 0;
+@@ -168,8 +165,8 @@ int main(int argc, char **argv)
+               switch (opt) {
+               case 'n':
+-                      ospfd_di.instance = instance = atoi(optarg);
+-                      if (instance < 1)
++                      ospfd_di.instance = ospf_instance = atoi(optarg);
++                      if (ospf_instance < 1)
+                               exit(0);
+                       break;
+               case 0:
+@@ -207,7 +204,7 @@ int main(int argc, char **argv)
+       /* OSPFd inits. */
+       ospf_if_init();
+-      ospf_zebra_init(master, instance);
++      ospf_zebra_init(master, ospf_instance);
+       /* OSPF vty inits. */
+       ospf_vty_init();
+@@ -223,17 +220,6 @@ int main(int argc, char **argv)
+       /* OSPF errors init */
+       ospf_error_init();
+-      /*
+-       * Need to initialize the default ospf structure, so the interface mode
+-       * commands can be duly processed if they are received before 'router
+-       * ospf',  when ospfd is restarted
+-       */
+-      if (instance && !ospf_get_instance(instance, &created)) {
+-              flog_err(EC_OSPF_INIT_FAIL, "OSPF instance init failed: %s",
+-                       strerror(errno));
+-              exit(1);
+-      }
+-
+       frr_config_fork();
+       frr_run(master);
+--- a/ospfd/ospf_vty.c
++++ b/ospfd/ospf_vty.c
+@@ -136,44 +136,37 @@ int ospf_oi_count(struct interface *ifp)
+               all_vrf = strmatch(vrf_name, "all");                           \
+       }
+-static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
+-                                       struct cmd_token *argv[],
+-                                       const int argc, uint32_t enable,
+-                                       unsigned short *instance)
++static int ospf_router_cmd_parse(struct vty *vty, struct cmd_token *argv[],
++                               const int argc, unsigned short *instance,
++                               const char **vrf_name)
+ {
+-      struct ospf *ospf = NULL;
+       int idx_vrf = 0, idx_inst = 0;
+-      const char *vrf_name = NULL;
+-      bool created = false;
+       *instance = 0;
+-      if (argv_find(argv, argc, "(1-65535)", &idx_inst))
++      if (argv_find(argv, argc, "(1-65535)", &idx_inst)) {
++              if (ospf_instance == 0) {
++                      vty_out(vty,
++                              "%% OSPF is not running in instance mode\n");
++                      return CMD_WARNING_CONFIG_FAILED;
++              }
++
+               *instance = strtoul(argv[idx_inst]->arg, NULL, 10);
++      }
++      *vrf_name = NULL;
+       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
+-              vrf_name = argv[idx_vrf + 1]->arg;
+-              if (vrf_name == NULL || strmatch(vrf_name, VRF_DEFAULT_NAME))
+-                      vrf_name = NULL;
+-              if (enable) {
+-                      /* Allocate VRF aware instance */
+-                      ospf = ospf_get(*instance, vrf_name, &created);
+-              } else {
+-                      ospf = ospf_lookup_by_inst_name(*instance, vrf_name);
+-              }
+-      } else {
+-              if (enable) {
+-                      ospf = ospf_get(*instance, NULL, &created);
+-              } else {
+-                      ospf = ospf_lookup_instance(*instance);
++              if (ospf_instance != 0) {
++                      vty_out(vty,
++                              "%% VRF is not supported in instance mode\n");
++                      return CMD_WARNING_CONFIG_FAILED;
+               }
+-      }
+-      if (created) {
+-              if (DFLT_OSPF_LOG_ADJACENCY_CHANGES)
+-                      SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
++              *vrf_name = argv[idx_vrf + 1]->arg;
++              if (*vrf_name && strmatch(*vrf_name, VRF_DEFAULT_NAME))
++                      *vrf_name = NULL;
+       }
+-      return ospf;
++      return CMD_SUCCESS;
+ }
+ static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty,
+@@ -209,28 +202,35 @@ DEFUN_NOSH (router_ospf,
+        "Instance ID\n"
+        VRF_CMD_HELP_STR)
+ {
+-      struct ospf *ospf = NULL;
+-      int ret = CMD_SUCCESS;
+-      unsigned short instance = 0;
++      unsigned short instance;
++      const char *vrf_name;
++      bool created = false;
++      struct ospf *ospf;
++      int ret;
+-      ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
+-      if (!ospf)
+-              return CMD_WARNING_CONFIG_FAILED;
++      ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name);
++      if (ret != CMD_SUCCESS)
++              return ret;
+-      /* The following logic to set the vty qobj index is in place to be able
+-         to ignore the commands which dont belong to this instance. */
+-      if (ospf->instance != instance) {
++      if (instance != ospf_instance) {
+               VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
+-              ret = CMD_NOT_MY_INSTANCE;
+-      } else {
+-              if (IS_DEBUG_OSPF_EVENT)
+-                      zlog_debug(
+-                              "Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
+-                              instance, ospf->name ? ospf->name : "NIL",
+-                              ospf->vrf_id, ospf->oi_running);
+-              VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
++              return CMD_NOT_MY_INSTANCE;
+       }
++      ospf = ospf_get(instance, vrf_name, &created);
++
++      if (created)
++              if (DFLT_OSPF_LOG_ADJACENCY_CHANGES)
++                      SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
++
++      if (IS_DEBUG_OSPF_EVENT)
++              zlog_debug(
++                      "Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
++                      ospf->instance, ospf->name ? ospf->name : "NIL",
++                      ospf->vrf_id, ospf->oi_running);
++
++      VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
++
+       return ret;
+ }
+@@ -243,19 +243,25 @@ DEFUN (no_router_ospf,
+        "Instance ID\n"
+        VRF_CMD_HELP_STR)
+ {
++      unsigned short instance;
++      const char *vrf_name;
+       struct ospf *ospf;
+-      unsigned short instance = 0;
++      int ret;
+-      ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance);
+-      if (ospf == NULL) {
+-              if (instance)
+-                      return CMD_NOT_MY_INSTANCE;
+-              else
+-                      return CMD_WARNING;
+-      }
+-      ospf_finish(ospf);
++      ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name);
++      if (ret != CMD_SUCCESS)
++              return ret;
+-      return CMD_SUCCESS;
++      if (instance != ospf_instance)
++              return CMD_NOT_MY_INSTANCE;
++
++      ospf = ospf_lookup(instance, vrf_name);
++      if (ospf)
++              ospf_finish(ospf);
++      else
++              ret = CMD_WARNING_CONFIG_FAILED;
++
++      return ret;
+ }
+@@ -3324,11 +3330,11 @@ DEFUN (show_ip_ospf_instance,
+       json_object *json = NULL;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (uj)
+@@ -4014,11 +4020,11 @@ DEFUN (show_ip_ospf_instance_interface,
+       json_object *json = NULL;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (uj)
+@@ -4407,11 +4413,11 @@ DEFUN (show_ip_ospf_instance_neighbor,
+       int ret = CMD_SUCCESS;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (uj)
+@@ -4619,11 +4625,11 @@ DEFUN (show_ip_ospf_instance_neighbor_al
+       int ret = CMD_SUCCESS;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (uj)
+               json = json_object_new_object();
+@@ -4759,11 +4765,11 @@ DEFUN (show_ip_ospf_instance_neighbor_in
+               show_ip_ospf_neighbour_header(vty);
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (!uj)
+@@ -5168,11 +5174,11 @@ DEFPY (show_ip_ospf_instance_neighbor_id
+ {
+       struct ospf *ospf;
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json,
+@@ -5341,11 +5347,11 @@ DEFUN (show_ip_ospf_instance_neighbor_de
+       int ret = CMD_SUCCESS;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (uj)
+@@ -5536,11 +5542,11 @@ DEFUN (show_ip_ospf_instance_neighbor_de
+       int ret = CMD_SUCCESS;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       if (uj)
+@@ -5668,11 +5674,11 @@ DEFUN (show_ip_ospf_instance_neighbor_in
+       bool uj = use_json(argc, argv);
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname,
+@@ -6418,10 +6424,11 @@ DEFUN (show_ip_ospf_instance_database,
+       if (argv_find(argv, argc, "(1-65535)", &idx)) {
+               instance = strtoul(argv[idx]->arg, NULL, 10);
+-              ospf = ospf_lookup_instance(instance);
+-              if (ospf == NULL)
++              if (instance != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+-              if (!ospf->oi_running)
++
++              ospf = ospf_lookup_instance(instance);
++              if (!ospf || !ospf->oi_running)
+                       return CMD_SUCCESS;
+               return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0,
+@@ -6482,15 +6489,12 @@ DEFUN (show_ip_ospf_instance_database_ma
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running) {
+-              vty_out(vty, "%% OSPF instance not found\n");
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+-      }
+       return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0);
+ }
+@@ -6576,13 +6580,12 @@ DEFUN (show_ip_ospf_instance_database_ty
+       if (argv_find(argv, argc, "(1-65535)", &idx)) {
+               instance = strtoul(argv[idx]->arg, NULL, 10);
+-              ospf = ospf_lookup_instance(instance);
+-              if (ospf == NULL)
++              if (instance != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+-              if (!ospf->oi_running) {
+-                      vty_out(vty, "%% OSPF instance not found\n");
++
++              ospf = ospf_lookup_instance(instance);
++              if (!ospf || !ospf->oi_running)
+                       return CMD_SUCCESS;
+-              }
+               return (show_ip_ospf_database_type_adv_router_common(
+                       vty, ospf, idx ? 1 : 0, argc, argv, use_vrf));
+@@ -8033,7 +8036,7 @@ DEFUN (ip_ospf_area,
+       else
+               ospf = ospf_lookup_instance(instance);
+-      if (instance && ospf == NULL) {
++      if (instance && instance != ospf_instance) {
+               /*
+                * At this point we know we have received
+                * an instance and there is no ospf instance
+@@ -8158,7 +8161,7 @@ DEFUN (no_ip_ospf_area,
+       else
+               ospf = ospf_lookup_instance(instance);
+-      if (instance && ospf == NULL)
++      if (instance && instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+       argv_find(argv, argc, "area", &idx);
+@@ -9519,11 +9522,11 @@ DEFUN (show_ip_ospf_instance_border_rout
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       return show_ip_ospf_border_routers_common(vty, ospf, 0);
+@@ -9687,11 +9690,11 @@ DEFUN (show_ip_ospf_instance_route,
+       unsigned short instance = 0;
+       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+-      ospf = ospf_lookup_instance(instance);
+-      if (ospf == NULL)
++      if (instance != ospf_instance)
+               return CMD_NOT_MY_INSTANCE;
+-      if (!ospf->oi_running)
++      ospf = ospf_lookup_instance(instance);
++      if (!ospf || !ospf->oi_running)
+               return CMD_SUCCESS;
+       return show_ip_ospf_route_common(vty, ospf, NULL, 0);
+@@ -9787,8 +9790,7 @@ DEFPY (clear_ip_ospf_neighbor,
+        */
+       if (instance != 0) {
+               /* This means clear only the particular ospf process */
+-              ospf = ospf_lookup_instance(instance);
+-              if (ospf == NULL)
++              if (instance != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+       }
+@@ -9818,8 +9820,7 @@ DEFPY (clear_ip_ospf_process,
+       /* Check if instance is not passed as an argument */
+       if (instance != 0) {
+               /* This means clear only the particular ospf process */
+-              ospf = ospf_lookup_instance(instance);
+-              if (ospf == NULL)
++              if (instance != ospf_instance)
+                       return CMD_NOT_MY_INSTANCE;
+       }
+@@ -9860,7 +9861,6 @@ static int config_write_interface_one(st
+       struct route_node *rn = NULL;
+       struct ospf_if_params *params;
+       int write = 0;
+-      struct ospf *ospf = vrf->info;
+       FOR_ALL_INTERFACES (vrf, ifp) {
+@@ -10039,9 +10039,9 @@ static int config_write_interface_one(st
+                       /* Area  print. */
+                       if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
+-                              if (ospf && ospf->instance)
++                              if (ospf_instance)
+                                       vty_out(vty, " ip ospf %d",
+-                                              ospf->instance);
++                                              ospf_instance);
+                               else
+                                       vty_out(vty, " ip ospf");
+--- a/ospfd/ospfd.c
++++ b/ospfd/ospfd.c
+@@ -67,6 +67,8 @@ static struct ospf_master ospf_master;
+ /* OSPF process wide configuration pointer to export. */
+ struct ospf_master *om;
++unsigned short ospf_instance;
++
+ extern struct zclient *zclient;
+@@ -468,36 +470,28 @@ static void ospf_init(struct ospf *ospf)
+       ospf_router_id_update(ospf);
+ }
+-struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
++struct ospf *ospf_lookup(unsigned short instance, const char *name)
+ {
+       struct ospf *ospf;
+-      /* vrf name provided call inst and name based api
+-       * in case of no name pass default ospf instance */
+-      if (name)
++      if (ospf_instance) {
++              ospf = ospf_lookup_instance(instance);
++      } else {
+               ospf = ospf_lookup_by_inst_name(instance, name);
+-      else
+-              ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+-
+-      *created = (ospf == NULL);
+-      if (ospf == NULL) {
+-              ospf = ospf_new(instance, name);
+-              ospf_add(ospf);
+-
+-              ospf_init(ospf);
+       }
+       return ospf;
+ }
+-struct ospf *ospf_get_instance(unsigned short instance, bool *created)
++struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
+ {
+       struct ospf *ospf;
+-      ospf = ospf_lookup_instance(instance);
++      ospf = ospf_lookup(instance, name);
++
+       *created = (ospf == NULL);
+       if (ospf == NULL) {
+-              ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
++              ospf = ospf_new(instance, name);
+               ospf_add(ospf);
+               ospf_init(ospf);
+--- a/ospfd/ospfd.h
++++ b/ospfd/ospfd.h
+@@ -507,6 +507,7 @@ struct ospf_nbr_nbma {
+ /* Extern variables. */
+ extern struct ospf_master *om;
++extern unsigned short ospf_instance;
+ extern const int ospf_redistributed_proto_max;
+ extern struct zclient *zclient;
+ extern struct thread_master *master;
+@@ -516,9 +517,9 @@ extern struct zebra_privs_t ospfd_privs;
+ /* Prototypes. */
+ extern const char *ospf_redist_string(unsigned int route_type);
+ extern struct ospf *ospf_lookup_instance(unsigned short);
++extern struct ospf *ospf_lookup(unsigned short instance, const char *name);
+ extern struct ospf *ospf_get(unsigned short instance, const char *name,
+                            bool *created);
+-extern struct ospf *ospf_get_instance(unsigned short, bool *created);
+ extern struct ospf *ospf_lookup_by_inst_name(unsigned short instance,
+                                            const char *name);
+ extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id);
+--- a/vtysh/vtysh.c
++++ b/vtysh/vtysh.c
+@@ -2487,7 +2487,7 @@ static int show_per_daemon(const char *l
+       int ret = CMD_SUCCESS;
+       for (i = 0; i < array_size(vtysh_client); i++)
+-              if (vtysh_client[i].fd >= 0) {
++              if (vtysh_client[i].fd >= 0 || vtysh_client[i].next) {
+                       vty_out(vty, headline, vtysh_client[i].name);
+                       ret = vtysh_client_execute(&vtysh_client[i], line);
+                       vty_out(vty, "\n");
diff --git a/net/frr/patches/052-nhrpd_support_for_multicast.patch b/net/frr/patches/052-nhrpd_support_for_multicast.patch
new file mode 100644 (file)
index 0000000..6a78ad4
--- /dev/null
@@ -0,0 +1,793 @@
+From f9ff7bf497894b74fd02d54dc0f0a39981f7cc06 Mon Sep 17 00:00:00 2001
+From: Amol Lad <amol.lad@4rf.com>
+Date: Wed, 17 Feb 2021 13:47:32 +1300
+Subject: [PATCH 1/6] nhrpd: Add support for forwarding multicast packets
+
+Forwarding multicast is a pre-requisite for allowing multicast based routing
+protocols such as OSPF to work with DMVPN
+
+This code relies on externally adding iptables rule. For example:
+iptables -A OUTPUT -d 224.0.0.0/24 -o gre1 -j NFLOG --nflog-group 224
+
+Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
+---
+ nhrpd/linux.c          |  11 +-
+ nhrpd/nhrp_interface.c |   2 +
+ nhrpd/nhrp_multicast.c | 312 +++++++++++++++++++++++++++++++++++++++++
+ nhrpd/nhrp_peer.c      |   3 +-
+ nhrpd/nhrp_vty.c       |  63 +++++++++
+ nhrpd/nhrpd.h          |  16 +++
+ nhrpd/os.h             |   2 +-
+ nhrpd/subdir.am        |   1 +
+ 8 files changed, 403 insertions(+), 7 deletions(-)
+ create mode 100644 nhrpd/nhrp_multicast.c
+
+--- a/nhrpd/linux.c
++++ b/nhrpd/linux.c
+@@ -15,6 +15,7 @@
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <string.h>
++#include <errno.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ #include <sys/types.h>
+@@ -42,7 +43,7 @@ int os_socket(void)
+ }
+ int os_sendmsg(const uint8_t *buf, size_t len, int ifindex, const uint8_t *addr,
+-             size_t addrlen)
++             size_t addrlen, uint16_t protocol)
+ {
+       struct sockaddr_ll lladdr;
+       struct iovec iov = {
+@@ -61,16 +62,16 @@ int os_sendmsg(const uint8_t *buf, size_
+       memset(&lladdr, 0, sizeof(lladdr));
+       lladdr.sll_family = AF_PACKET;
+-      lladdr.sll_protocol = htons(ETH_P_NHRP);
++      lladdr.sll_protocol = htons(protocol);
+       lladdr.sll_ifindex = ifindex;
+       lladdr.sll_halen = addrlen;
+       memcpy(lladdr.sll_addr, addr, addrlen);
+-      status = sendmsg(nhrp_socket_fd, &msg, 0);
++      status = sendmsg(os_socket(), &msg, 0);
+       if (status < 0)
+-              return -1;
++              return -errno;
+-      return 0;
++      return status;
+ }
+ int os_recvmsg(uint8_t *buf, size_t *len, int *ifindex, uint8_t *addr,
+--- a/nhrpd/nhrp_interface.c
++++ b/nhrpd/nhrp_interface.c
+@@ -42,6 +42,7 @@ static int nhrp_if_new_hook(struct inter
+               struct nhrp_afi_data *ad = &nifp->afi[afi];
+               ad->holdtime = NHRPD_DEFAULT_HOLDTIME;
+               list_init(&ad->nhslist_head);
++              list_init(&ad->mcastlist_head);
+       }
+       return 0;
+@@ -55,6 +56,7 @@ static int nhrp_if_delete_hook(struct in
+       nhrp_cache_interface_del(ifp);
+       nhrp_nhs_interface_del(ifp);
++      nhrp_multicast_interface_del(ifp);
+       nhrp_peer_interface_del(ifp);
+       if (nifp->ipsec_profile)
+--- /dev/null
++++ b/nhrpd/nhrp_multicast.c
+@@ -0,0 +1,312 @@
++/* NHRP Multicast Support
++ * Copyright (c) 2020-2021 4RF Limited
++ *
++ * This file is free software: you may copy, redistribute 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.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <fcntl.h>
++#include <net/if.h>
++#include <net/ethernet.h>
++#include <netinet/if_ether.h>
++#include <linux/netlink.h>
++#include <linux/neighbour.h>
++#include <linux/netfilter/nfnetlink_log.h>
++#include <linux/if_packet.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++
++#include "thread.h"
++#include "nhrpd.h"
++#include "netlink.h"
++#include "znl.h"
++#include "os.h"
++
++DEFINE_MTYPE_STATIC(NHRPD, NHRP_MULTICAST, "NHRP Multicast")
++
++static int netlink_mcast_nflog_group;
++static int netlink_mcast_log_fd = -1;
++static struct thread *netlink_mcast_log_thread;
++static int nhrp_multicast_ip_count;
++
++struct mcast_ctx {
++      struct interface *ifp;
++      struct zbuf *pkt;
++};
++
++static void nhrp_multicast_send(struct nhrp_peer *p, struct zbuf *zb)
++{
++      char buf[2][256];
++      size_t addrlen;
++      int ret;
++
++      addrlen = sockunion_get_addrlen(&p->vc->remote.nbma);
++      ret = os_sendmsg(zb->head, zbuf_used(zb), p->ifp->ifindex,
++                 sockunion_get_addr(&p->vc->remote.nbma),
++                 addrlen, addrlen == 4 ? 0x0800 : 0x86DD);
++
++      debugf(NHRP_DEBUG_COMMON, "Multicast Packet: %s -> %s, ret = %d, size = %zu, addrlen = %zu",
++                 sockunion2str(&p->vc->local.nbma, buf[0], sizeof(buf[0])),
++                 sockunion2str(&p->vc->remote.nbma, buf[1], sizeof(buf[1])),
++                 ret, zbuf_used(zb), addrlen);
++}
++
++static void nhrp_multicast_forward_nbma(union sockunion *nbma_addr, struct interface *ifp, struct zbuf *pkt)
++{
++      struct nhrp_peer *p = nhrp_peer_get(ifp, nbma_addr);
++      if(p && p->online) {
++              /* Send packet */
++              nhrp_multicast_send(p, pkt);
++      }
++      nhrp_peer_unref(p);
++}
++
++static void nhrp_multicast_forward_cache(struct nhrp_cache *c, void *pctx)
++{
++      struct mcast_ctx *ctx = (struct mcast_ctx *)pctx;
++
++      if (c->cur.type == NHRP_CACHE_DYNAMIC && c->cur.peer)
++              nhrp_multicast_forward_nbma(&c->cur.peer->vc->remote.nbma, ctx->ifp, ctx->pkt);
++}
++
++static void nhrp_multicast_forward(struct nhrp_multicast *mcast, void *pctx)
++{
++      struct mcast_ctx *ctx = (struct mcast_ctx *)pctx;
++      struct nhrp_interface *nifp = ctx->ifp->info;
++
++      if (!nifp->enabled)
++              return;
++
++      /* dynamic */
++      if (sockunion_family(&mcast->nbma_addr) == AF_UNSPEC) {
++              nhrp_cache_foreach(ctx->ifp, nhrp_multicast_forward_cache, pctx);
++              return;
++      }
++
++      /* Fixed IP Address */
++      nhrp_multicast_forward_nbma(&mcast->nbma_addr, ctx->ifp, ctx->pkt);
++}
++
++static void netlink_mcast_log_handler(struct nlmsghdr *msg, struct zbuf *zb)
++{
++      struct nfgenmsg *nf;
++      struct rtattr *rta;
++      struct zbuf rtapl, pktpl;
++      struct interface *ifp;
++      uint32_t *out_ndx = NULL;
++      afi_t afi;
++      struct mcast_ctx ctx;
++
++      debugf(NHRP_DEBUG_COMMON,"Inside %s\n", __func__);
++
++      nf = znl_pull(zb, sizeof(*nf));
++      if (!nf)
++              return;
++
++      memset(&pktpl, 0, sizeof(pktpl));
++      while ((rta = znl_rta_pull(zb, &rtapl)) != NULL) {
++              switch (rta->rta_type) {
++              case NFULA_IFINDEX_OUTDEV:
++                      out_ndx = znl_pull(&rtapl, sizeof(*out_ndx));
++                      break;
++              case NFULA_PAYLOAD:
++                      pktpl = rtapl;
++                      break;
++                      /* NFULA_HWHDR exists and is supposed to contain source
++                       * hardware address. However, for ip_gre it seems to be
++                       * the nexthop destination address if the packet matches
++                       * route. */
++              }
++      }
++
++      if (!out_ndx || !zbuf_used(&pktpl))
++              return;
++
++      ifp = if_lookup_by_index(htonl(*out_ndx), VRF_DEFAULT);
++      if (!ifp)
++              return;
++
++      debugf(NHRP_DEBUG_COMMON,"Outgoing interface = %s\n", ifp->name);
++
++      ctx = (struct mcast_ctx) {
++              .ifp = ifp,
++              .pkt = &pktpl,
++      };
++
++      for (afi = 0; afi < AFI_MAX; afi++) {
++              nhrp_multicast_foreach(ifp, afi, nhrp_multicast_forward, (void *)&ctx);
++      }
++}
++
++static int netlink_mcast_log_recv(struct thread *t)
++{
++      uint8_t buf[65535]; /* Max OSPF Packet size */
++      int fd = THREAD_FD(t);
++      struct zbuf payload, zb;
++      struct nlmsghdr *n;
++
++      netlink_mcast_log_thread = NULL;
++
++      zbuf_init(&zb, buf, sizeof(buf), 0);
++      while (zbuf_recv(&zb, fd) > 0) {
++              while ((n = znl_nlmsg_pull(&zb, &payload)) != NULL) {
++                      debugf(NHRP_DEBUG_COMMON,
++                             "Netlink-mcast-log: Received msg_type %u, msg_flags %u",
++                             n->nlmsg_type, n->nlmsg_flags);
++                      switch (n->nlmsg_type) {
++                      case (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_PACKET:
++                              netlink_mcast_log_handler(n, &payload);
++                              break;
++                      }
++              }
++      }
++
++      thread_add_read(master, netlink_mcast_log_recv, 0, netlink_mcast_log_fd,
++                      &netlink_mcast_log_thread);
++
++      return 0;
++}
++
++static void netlink_mcast_log_register(int fd, int group)
++{
++      struct nlmsghdr *n;
++      struct nfgenmsg *nf;
++      struct nfulnl_msg_config_cmd cmd;
++      struct zbuf *zb = zbuf_alloc(512);
++
++      n = znl_nlmsg_push(zb, (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG,
++                         NLM_F_REQUEST | NLM_F_ACK);
++      nf = znl_push(zb, sizeof(*nf));
++      *nf = (struct nfgenmsg){
++              .nfgen_family = AF_UNSPEC,
++              .version = NFNETLINK_V0,
++              .res_id = htons(group),
++      };
++      cmd.command = NFULNL_CFG_CMD_BIND;
++      znl_rta_push(zb, NFULA_CFG_CMD, &cmd, sizeof(cmd));
++      znl_nlmsg_complete(zb, n);
++
++      zbuf_send(zb, fd);
++      zbuf_free(zb);
++}
++
++static void netlink_mcast_set_nflog_group(struct interface *ifp, int nlgroup)
++{
++      if (netlink_mcast_log_fd >= 0) {
++              THREAD_OFF(netlink_mcast_log_thread);
++              close(netlink_mcast_log_fd);
++              netlink_mcast_log_fd = -1;
++              debugf(NHRP_DEBUG_COMMON, "De-register nflog group");
++      }
++      netlink_mcast_nflog_group = nlgroup;
++      if (nlgroup) {
++              netlink_mcast_log_fd = znl_open(NETLINK_NETFILTER, 0);
++              if (netlink_mcast_log_fd < 0)
++                      return;
++
++              netlink_mcast_log_register(netlink_mcast_log_fd, nlgroup);
++              thread_add_read(master, netlink_mcast_log_recv, 0, netlink_mcast_log_fd,
++                              &netlink_mcast_log_thread);
++              debugf(NHRP_DEBUG_COMMON, "Register nflog group: %d", netlink_mcast_nflog_group);
++      }
++}
++
++static int nhrp_multicast_free(struct interface *ifp, struct nhrp_multicast *mcast)
++{
++      list_del(&mcast->list_entry);
++      XFREE(MTYPE_NHRP_MULTICAST, mcast);
++      if (--nhrp_multicast_ip_count == 0)
++              netlink_mcast_set_nflog_group(ifp, 0);
++      return 0;
++}
++
++int nhrp_multicast_add(struct interface *ifp, afi_t afi, union sockunion *nbma_addr)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_multicast *mcast;
++      char buf[SU_ADDRSTRLEN];
++
++      list_for_each_entry(mcast, &nifp->afi[afi].mcastlist_head, list_entry)
++      {
++              if (sockunion_same(&mcast->nbma_addr, nbma_addr))
++                      return NHRP_ERR_ENTRY_EXISTS;
++      }
++
++      mcast = XMALLOC(MTYPE_NHRP_MULTICAST, sizeof(struct nhrp_multicast));
++
++      *mcast = (struct nhrp_multicast){
++              .afi = afi,
++              .ifp = ifp,
++              .nbma_addr = *nbma_addr,
++      };
++      list_add_tail(&mcast->list_entry, &nifp->afi[afi].mcastlist_head);
++
++      if (netlink_mcast_log_fd == -1)
++              netlink_mcast_set_nflog_group(ifp, MCAST_NFLOG_GROUP);
++
++      nhrp_multicast_ip_count++;
++
++      sockunion2str(nbma_addr, buf, sizeof(buf));
++      debugf(NHRP_DEBUG_COMMON, "Adding multicast entry (%s) [%d]", buf, nhrp_multicast_ip_count);
++
++      return NHRP_OK;
++}
++
++int nhrp_multicast_del(struct interface *ifp, afi_t afi, union sockunion *nbma_addr)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_multicast *mcast, *tmp;
++      char buf[SU_ADDRSTRLEN];
++
++      list_for_each_entry_safe(mcast, tmp, &nifp->afi[afi].mcastlist_head,
++                               list_entry)
++      {
++              if (!sockunion_same(&mcast->nbma_addr, nbma_addr))
++                      continue;
++
++              sockunion2str(nbma_addr, buf, sizeof(buf));
++              debugf(NHRP_DEBUG_COMMON, "Deleting multicast entry (%s) [%d]", buf, nhrp_multicast_ip_count);
++
++              nhrp_multicast_free(ifp, mcast);
++
++              return NHRP_OK;
++      }
++
++      return NHRP_ERR_ENTRY_NOT_FOUND;
++}
++
++void nhrp_multicast_interface_del(struct interface *ifp)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_multicast *mcast, *tmp;
++      afi_t afi;
++
++      for (afi = 0; afi < AFI_MAX; afi++) {
++              debugf(NHRP_DEBUG_COMMON, "Cleaning up multicast entries (%d, %d)", !list_empty(&nifp->afi[afi].mcastlist_head), nhrp_multicast_ip_count);
++
++              list_for_each_entry_safe(
++                              mcast, tmp, &nifp->afi[afi].mcastlist_head,
++                              list_entry) {
++                      nhrp_multicast_free(ifp, mcast);
++              }
++      }
++}
++
++void nhrp_multicast_foreach(struct interface *ifp, afi_t afi,
++                    void (*cb)(struct nhrp_multicast *, void *),
++                    void *ctx)
++{
++      struct nhrp_interface *nifp = ifp->info;
++      struct nhrp_multicast *mcast;
++
++      list_for_each_entry(mcast, &nifp->afi[afi].mcastlist_head, list_entry)
++      {
++              cb (mcast, ctx);
++      }
++}
+--- a/nhrpd/nhrp_peer.c
++++ b/nhrpd/nhrp_peer.c
+@@ -337,7 +337,8 @@ void nhrp_peer_send(struct nhrp_peer *p,
+       os_sendmsg(zb->head, zbuf_used(zb), p->ifp->ifindex,
+                  sockunion_get_addr(&p->vc->remote.nbma),
+-                 sockunion_get_addrlen(&p->vc->remote.nbma));
++                 sockunion_get_addrlen(&p->vc->remote.nbma),
++                 ETH_P_NHRP);
+       zbuf_reset(zb);
+ }
+--- a/nhrpd/nhrp_vty.c
++++ b/nhrpd/nhrp_vty.c
+@@ -569,6 +569,53 @@ DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd
+       return CMD_SUCCESS;
+ }
++DEFUN(if_nhrp_map_multicast, if_nhrp_map_multicast_cmd,
++      AFI_CMD " nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
++      AFI_STR
++      NHRP_STR
++      "Multicast NBMA Configuration\n"
++      "Use this NBMA mapping for multicasts\n"
++      "IPv4 NBMA address\n"
++      "IPv6 NBMA address\n"
++      "Dynamically learn destinations from client registrations on hub\n")
++{
++      VTY_DECLVAR_CONTEXT(interface, ifp);
++      afi_t afi = cmd_to_afi(argv[0]);
++      union sockunion nbma_addr;
++      int ret;
++
++      if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
++              sockunion_family(&nbma_addr) = AF_UNSPEC;
++
++      ret = nhrp_multicast_add(ifp, afi, &nbma_addr);
++
++      return nhrp_vty_return(vty, ret);
++}
++
++DEFUN(if_no_nhrp_map_multicast, if_no_nhrp_map_multicast_cmd,
++      "no " AFI_CMD " nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
++      NO_STR
++      AFI_STR
++      NHRP_STR
++      "Multicast NBMA Configuration\n"
++      "Use this NBMA mapping for multicasts\n"
++      "IPv4 NBMA address\n"
++      "IPv6 NBMA address\n"
++      "Dynamically learn destinations from client registrations on hub\n")
++{
++      VTY_DECLVAR_CONTEXT(interface, ifp);
++      afi_t afi = cmd_to_afi(argv[1]);
++      union sockunion nbma_addr;
++      int ret;
++
++      if (str2sockunion(argv[5]->arg, &nbma_addr) < 0)
++              sockunion_family(&nbma_addr) = AF_UNSPEC;
++
++      ret = nhrp_multicast_del(ifp, afi, &nbma_addr);
++
++      return nhrp_vty_return(vty, ret);
++}
++
+ DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd,
+       AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
+       AFI_STR
+@@ -1040,6 +1087,7 @@ static int interface_config_write(struct
+       struct interface *ifp;
+       struct nhrp_interface *nifp;
+       struct nhrp_nhs *nhs;
++      struct nhrp_multicast *mcast;
+       const char *aficmd;
+       afi_t afi;
+       char buf[SU_ADDRSTRLEN];
+@@ -1109,6 +1157,19 @@ static int interface_config_write(struct
+                                                         sizeof(buf)),
+                                       nhs->nbma_fqdn);
+                       }
++
++                      list_for_each_entry(mcast, &ad->mcastlist_head,
++                                          list_entry)
++                      {
++                              vty_out(vty, " %s nhrp map multicast %s\n",
++                                      aficmd,
++                                      sockunion_family(&mcast->nbma_addr)
++                                                      == AF_UNSPEC
++                                              ? "dynamic"
++                                              : sockunion2str(
++                                                        &mcast->nbma_addr, buf,
++                                                        sizeof(buf)));
++                      }
+               }
+               vty_endframe(vty, "!\n");
+@@ -1163,6 +1224,8 @@ void nhrp_config_init(void)
+       install_element(INTERFACE_NODE, &if_no_nhrp_reg_flags_cmd);
+       install_element(INTERFACE_NODE, &if_nhrp_map_cmd);
+       install_element(INTERFACE_NODE, &if_no_nhrp_map_cmd);
++      install_element(INTERFACE_NODE, &if_nhrp_map_multicast_cmd);
++      install_element(INTERFACE_NODE, &if_no_nhrp_map_multicast_cmd);
+       install_element(INTERFACE_NODE, &if_nhrp_nhs_cmd);
+       install_element(INTERFACE_NODE, &if_no_nhrp_nhs_cmd);
+ }
+--- a/nhrpd/nhrpd.h
++++ b/nhrpd/nhrpd.h
+@@ -24,6 +24,7 @@ DECLARE_MGROUP(NHRPD)
+ #define NHRP_VTY_PORT         2610
+ #define NHRP_DEFAULT_CONFIG   "nhrpd.conf"
++#define MCAST_NFLOG_GROUP 224
+ extern struct thread_master *master;
+@@ -259,6 +260,13 @@ struct nhrp_nhs {
+       struct list_head reglist_head;
+ };
++struct nhrp_multicast {
++      struct interface *ifp;
++      struct list_head list_entry;
++      afi_t afi;
++      union sockunion nbma_addr; /* IP-address */
++};
++
+ struct nhrp_registration {
+       struct list_head reglist_entry;
+       struct thread *t_register;
+@@ -304,6 +312,7 @@ struct nhrp_interface {
+               unsigned short mtu;
+               unsigned int holdtime;
+               struct list_head nhslist_head;
++              struct list_head mcastlist_head;
+       } afi[AFI_MAX];
+ };
+@@ -345,6 +354,13 @@ void nhrp_nhs_foreach(struct interface *
+                     void *ctx);
+ void nhrp_nhs_interface_del(struct interface *ifp);
++int nhrp_multicast_add(struct interface *ifp, afi_t afi, union sockunion *nbma_addr);
++int nhrp_multicast_del(struct interface *ifp, afi_t afi, union sockunion *nbma_addr);
++void nhrp_multicast_interface_del(struct interface *ifp);
++void nhrp_multicast_foreach(struct interface *ifp, afi_t afi,
++                    void (*cb)(struct nhrp_multicast *, void *),
++                    void *ctx);
++
+ void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp);
+ void nhrp_route_announce(int add, enum nhrp_cache_type type,
+                        const struct prefix *p, struct interface *ifp,
+--- a/nhrpd/os.h
++++ b/nhrpd/os.h
+@@ -1,7 +1,7 @@
+ int os_socket(void);
+ int os_sendmsg(const uint8_t *buf, size_t len, int ifindex, const uint8_t *addr,
+-             size_t addrlen);
++             size_t addrlen, uint16_t protocol);
+ int os_recvmsg(uint8_t *buf, size_t *len, int *ifindex, uint8_t *addr,
+              size_t *addrlen);
+ int os_configure_dmvpn(unsigned int ifindex, const char *ifname, int af);
+--- a/nhrpd/subdir.am
++++ b/nhrpd/subdir.am
+@@ -21,6 +21,7 @@ nhrpd_nhrpd_SOURCES = \
+       nhrpd/nhrp_nhs.c \
+       nhrpd/nhrp_packet.c \
+       nhrpd/nhrp_peer.c \
++      nhrpd/nhrp_multicast.c \
+       nhrpd/nhrp_route.c \
+       nhrpd/nhrp_shortcut.c \
+       nhrpd/nhrp_vc.c \
+--- a/ospfd/ospf_interface.c
++++ b/ospfd/ospf_interface.c
+@@ -534,6 +534,8 @@ static struct ospf_if_params *ospf_new_i
+       oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
+       oip->is_v_wait_set = false;
++      oip->ptp_dmvpn = 0;
++
+       return oip;
+ }
+--- a/ospfd/ospf_interface.h
++++ b/ospfd/ospf_interface.h
+@@ -105,6 +105,9 @@ struct ospf_if_params {
+       /* BFD configuration */
+       struct bfd_info *bfd_info;
++
++      /* point-to-point DMVPN configuration */
++      uint8_t ptp_dmvpn;
+ };
+ enum { MEMBER_ALLROUTERS = 0,
+@@ -167,6 +170,9 @@ struct ospf_interface {
+       /* OSPF Network Type. */
+       uint8_t type;
++      /* point-to-point DMVPN configuration */
++      uint8_t ptp_dmvpn;
++
+       /* State of Interface State Machine. */
+       uint8_t state;
+--- a/ospfd/ospf_lsa.c
++++ b/ospfd/ospf_lsa.c
+@@ -469,6 +469,12 @@ static char link_info_set(struct stream
+ }
+ /* Describe Point-to-Point link (Section 12.4.1.1). */
++
++/* Note: If the interface is configured as point-to-point dmvpn then the other
++ * end of link is dmvpn hub with point-to-multipoint ospf network type. The
++ * hub then expects this router to populate the stub network and also Link Data
++ * Field set to IP Address and not MIB-II ifIndex
++ */
+ static int lsa_link_ptop_set(struct stream **s, struct ospf_interface *oi)
+ {
+       int links = 0;
+@@ -482,7 +488,8 @@ static int lsa_link_ptop_set(struct stre
+       if ((nbr = ospf_nbr_lookup_ptop(oi)))
+               if (nbr->state == NSM_Full) {
+                       if (CHECK_FLAG(oi->connected->flags,
+-                                     ZEBRA_IFA_UNNUMBERED)) {
++                                     ZEBRA_IFA_UNNUMBERED)
++                          && !oi->ptp_dmvpn) {
+                               /* For unnumbered point-to-point networks, the
+                                  Link Data field
+                                  should specify the interface's MIB-II ifIndex
+@@ -500,7 +507,8 @@ static int lsa_link_ptop_set(struct stre
+               }
+       /* no need for a stub link for unnumbered interfaces */
+-      if (!CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) {
++      if (oi->ptp_dmvpn
++          || !CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) {
+               /* Regardless of the state of the neighboring router, we must
+                  add a Type 3 link (stub network).
+                  N.B. Options 1 & 2 share basically the same logic. */
+--- a/ospfd/ospf_vty.c
++++ b/ospfd/ospf_vty.c
+@@ -7560,20 +7560,21 @@ DEFUN_HIDDEN (no_ospf_hello_interval,
+       return no_ip_ospf_hello_interval(self, vty, argc, argv);
+ }
+-DEFUN (ip_ospf_network,
+-       ip_ospf_network_cmd,
+-       "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
+-       "IP Information\n"
+-       "OSPF interface commands\n"
+-       "Network type\n"
+-       "Specify OSPF broadcast multi-access network\n"
+-       "Specify OSPF NBMA network\n"
+-       "Specify OSPF point-to-multipoint network\n"
+-       "Specify OSPF point-to-point network\n")
++DEFUN(ip_ospf_network, ip_ospf_network_cmd,
++      "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point [dmvpn]>",
++      "IP Information\n"
++      "OSPF interface commands\n"
++      "Network type\n"
++      "Specify OSPF broadcast multi-access network\n"
++      "Specify OSPF NBMA network\n"
++      "Specify OSPF point-to-multipoint network\n"
++      "Specify OSPF point-to-point network\n"
++      "Specify OSPF point-to-point DMVPN network\n")
+ {
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       int idx = 0;
+       int old_type = IF_DEF_PARAMS(ifp)->type;
++      uint8_t old_ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+       struct route_node *rn;
+       if (old_type == OSPF_IFTYPE_LOOPBACK) {
+@@ -7582,16 +7583,22 @@ DEFUN (ip_ospf_network,
+               return CMD_WARNING_CONFIG_FAILED;
+       }
++      IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
++
+       if (argv_find(argv, argc, "broadcast", &idx))
+               IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST;
+       else if (argv_find(argv, argc, "non-broadcast", &idx))
+               IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA;
+       else if (argv_find(argv, argc, "point-to-multipoint", &idx))
+               IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT;
+-      else if (argv_find(argv, argc, "point-to-point", &idx))
++      else if (argv_find(argv, argc, "point-to-point", &idx)) {
+               IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT;
++              if (argv_find(argv, argc, "dmvpn", &idx))
++                      IF_DEF_PARAMS(ifp)->ptp_dmvpn = 1;
++      }
+-      if (IF_DEF_PARAMS(ifp)->type == old_type)
++      if (IF_DEF_PARAMS(ifp)->type == old_type
++          && IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn)
+               return CMD_SUCCESS;
+       SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
+@@ -7603,6 +7610,7 @@ DEFUN (ip_ospf_network,
+                       continue;
+               oi->type = IF_DEF_PARAMS(ifp)->type;
++              oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+               if (oi->state > ISM_Down) {
+                       OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
+@@ -7643,6 +7651,7 @@ DEFUN (no_ip_ospf_network,
+       struct route_node *rn;
+       IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
++      IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
+       if (IF_DEF_PARAMS(ifp)->type == old_type)
+               return CMD_SUCCESS;
+@@ -9888,6 +9897,10 @@ static int config_write_interface_one(st
+                                       vty_out(vty, " ip ospf network %s",
+                                               ospf_int_type_str
+                                                       [params->type]);
++                                      if (params->type
++                                                  == OSPF_IFTYPE_POINTOPOINT
++                                          && params->ptp_dmvpn)
++                                              vty_out(vty, " dmvpn");
+                                       if (params != IF_DEF_PARAMS(ifp) && rn)
+                                               vty_out(vty, " %s",
+                                                       inet_ntoa(
+--- a/ospfd/ospfd.c
++++ b/ospfd/ospfd.c
+@@ -1017,6 +1017,7 @@ static void add_ospf_interface(struct co
+       /* If network type is specified previously,
+          skip network type setting. */
+       oi->type = IF_DEF_PARAMS(co->ifp)->type;
++      oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn;
+       /* Add pseudo neighbor. */
+       ospf_nbr_self_reset(oi, oi->ospf->router_id);
+--- a/doc/user/nhrpd.rst
++++ b/doc/user/nhrpd.rst
+@@ -189,6 +189,34 @@ and
+ https://git.alpinelinux.org/user/tteras/strongswan/log/?h=tteras
+ git repositories for the patches.
++.. _multicast-functionality:
++
++Multicast Functionality
++=======================
++
++nhrpd can be configured to forward multicast packets, allowing routing
++protocols that use multicast (such as OSPF) to be supported in the DMVPN
++network.
++
++This support requires an NFLOG redirection rule to work:
++
++ .. code-block:: shell
++
++   iptables -I OUTPUT -d 224.0.0.0/24 -o gre1 -j NFLOG --nflog-group 2
++
++.. index::  nhrp multicast-nflog-group (1-65535)
++.. clicmd:: nhrp multicast-nflog-group (1-65535)
++
++   Sets the nflog group that nhrpd will listen on for multicast packets. This
++   value must match the nflog-group value set in the iptables rule.
++
++.. index::  ip nhrp map multicast A.B.C.D|X:X::X:X A.B.C.D|dynamic
++.. clicmd:: ip nhrp map multicast A.B.C.D|X:X::X:X A.B.C.D|dynamic
++
++   Sends multicast packets to the specified NBMA address. If dynamic is
++   specified then destination NBMA address (or addresses) are learnt
++   dynamically.
++
+ .. _nhrp-events:
+ NHRP Events
+--- a/doc/user/ospfd.rst
++++ b/doc/user/ospfd.rst
+@@ -687,8 +687,8 @@ Interfaces
+    :clicmd:`ip ospf dead-interval minimal hello-multiplier (2-20)` is also
+    specified for the interface.
+-.. index:: ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)
+-.. clicmd:: ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point)
++.. index:: ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point [dmvpn])
++.. clicmd:: ip ospf network (broadcast|non-broadcast|point-to-multipoint|point-to-point [dmvpn])
+    When configuring a point-to-point network on an interface and the interface
+    has a /32 address associated with then OSPF will treat the interface
+@@ -870,6 +870,9 @@ Redistribution
+ .. index:: no router zebra
+ .. clicmd:: no router zebra
++   When used in a DMVPN network at a spoke, this OSPF will be configured in
++   point-to-point, but the HUB will be a point-to-multipoint. To make this
++   topology work, specify the optional 'dmvpn' parameter at the spoke.
+ .. _showing-ospf-information:
diff --git a/net/frr/patches/053-more_SA_fixes.patch b/net/frr/patches/053-more_SA_fixes.patch
new file mode 100644 (file)
index 0000000..5d4aab1
--- /dev/null
@@ -0,0 +1,96 @@
+From bd9caa8f11d931db21f628ad61be042147861ad4 Mon Sep 17 00:00:00 2001
+From: Mark Stapp <mjs@voltanet.io>
+Date: Fri, 26 Feb 2021 11:16:09 -0500
+Subject: [PATCH 1/3] lib: fix some misc SA warnings
+
+- clippy.c: fix valid memleak
+- defun_lex.l: suppress warnings in generated code
+- northbound_cli.c: suppress warning in eldritch libyang macro
+
+Signed-off-by: Quentin Young <qlyoung@nvidia.com>
+---
+ lib/clippy.c         |  4 +++-
+ lib/defun_lex.l      |  4 ++++
+ lib/northbound_cli.c | 12 ++++++++++++
+ 3 files changed, 19 insertions(+), 1 deletion(-)
+
+--- a/lib/clippy.c
++++ b/lib/clippy.c
+@@ -51,7 +51,8 @@ int main(int argc, char **argv)
+ #if PY_VERSION_HEX >= 0x03040000 /* 3.4 */
+       Py_SetStandardStreamEncoding("UTF-8", NULL);
+ #endif
+-      Py_SetProgramName(wconv(argv[0]));
++      wchar_t *name = wconv(argv[0]);
++      Py_SetProgramName(name);
+       PyImport_AppendInittab("_clippy", command_py_init);
+       Py_Initialize();
+@@ -67,6 +68,8 @@ int main(int argc, char **argv)
+               fp = fopen(pyfile, "r");
+               if (!fp) {
+                       fprintf(stderr, "%s: %s\n", pyfile, strerror(errno));
++
++                      free(name);
+                       return 1;
+               }
+       } else {
+@@ -85,6 +88,8 @@ int main(int argc, char **argv)
+       if (PyRun_AnyFile(fp, pyfile)) {
+               if (PyErr_Occurred())
+                       PyErr_Print();
++
++              free(name);
+               return 1;
+       }
+       Py_Finalize();
+@@ -93,6 +98,7 @@ int main(int argc, char **argv)
+       for (int i = 1; i < argc; i++)
+               free(wargv[i - 1]);
+ #endif
++      free(name);
+       free(wargv);
+       return 0;
+ }
+--- a/lib/defun_lex.l
++++ b/lib/defun_lex.l
+@@ -80,6 +80,8 @@ static void extendbuf(char **what, const
+ }
+ #define extend(x) extendbuf(&value, x)
++#ifndef __clang_analyzer__
++
+ %}
+ ID            [A-Za-z0-9_]+
+@@ -157,6 +159,8 @@ SPECIAL            [(),]
+ %%
++#endif /* __clang_analyzer__ */
++
+ static int yylex_clr(char **retbuf)
+ {
+       int rv = def_yylex();
+--- a/lib/northbound_cli.c
++++ b/lib/northbound_cli.c
+@@ -595,7 +595,19 @@ void nb_cli_show_dnode_cmds(struct vty *
+                               (*nb_node->cbs.cli_show_end)(vty, parent);
+               }
++              /*
++               * There is a possible path in this macro that ends up
++               * dereferencing child->parent->parent. We just null checked
++               * child->parent by checking (ly_iter_next_up(child) != NULL)
++               * above.
++               *
++               * I am not sure whether it is possible for the other
++               * conditions within this macro guarding the problem
++               * dereference to be satisfied when child->parent == NULL.
++               */
++#ifndef __clang_analyzer__
+               LY_TREE_DFS_END(root, next, child);
++#endif
+       }
+ }
index adf0785b5e7aaab911e30a8ef50562a43d4d096f..e956581d2c7d705c8ffa72edc31fea5993aba999 100644 (file)
@@ -1,6 +1,6 @@
 --- a/lib/northbound.h
 +++ b/lib/northbound.h
-@@ -562,11 +562,7 @@ struct frr_yang_module_info {
+@@ -569,11 +569,7 @@ struct frr_yang_module_info {
  
                /* Priority - lower priorities are processed first. */
                uint32_t priority;
index 1d4da7dc3a33091d5e22cced9b42d1d5c26c195a..330fb335ac8dddcbd0a92bc71dfdaf97e4a6d7dd 100644 (file)
@@ -40,6 +40,7 @@ ifdef CONFIG_USE_GLIBC
 endif
 
 include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
 
 define Package/hs20-common
   SECTION:=net
index 464754927744d3851e12170103e26c0cc5e853e0..ceec3d1d06c5bbfccb79ec5a86374f09b75fb42a 100644 (file)
@@ -10,12 +10,12 @@ PKG_RELRO_FULL:=0
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=knot-resolver
-PKG_VERSION:=5.2.1
+PKG_VERSION:=5.3.0
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=https://secure.nic.cz/files/knot-resolver
-PKG_HASH:=aa37b744c400f437acba7a54aebcbdbe722ece743d342cbc39f2dd8087f05826
+PKG_HASH:=fb6cb2c03f4fffbdd8a0098127383d03b14cf7d6abf3a0cd229fb13ff68ee33e
 
 PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz>
 PKG_LICENSE:=GPL-3.0-later
@@ -41,10 +41,10 @@ define Package/knot-resolver
     +luasec \
     +luasocket \
     +libstdcpp \
+    +libnghttp2 \
     +lmdb \
     PACKAGE_knot-resolver_dnstap:libfstrm \
-    PACKAGE_knot-resolver_dnstap:libprotobuf-c \
-    @(aarch64||mips64||mips64el||powerpc64||x86_64)
+    PACKAGE_knot-resolver_dnstap:libprotobuf-c
   USERID:=kresd=3536:kresd=3536
 endef
 
index 6d013a6ccd901052c22d8911c3a0f01b02cc140f..a4eac6c8dc0690ee540da98a858c4f28f2617a2b 100644 (file)
@@ -2,7 +2,7 @@ This patch fixes the problem with forwarding in knot-resolver v4.3.0.
 It reintroduces a fix which enables  policy related hack (knot/knot-resolver#205 (comment 94566) )
 --- a/modules/policy/policy.lua
 +++ b/modules/policy/policy.lua
-@@ -985,7 +985,7 @@ policy.layer = {
+@@ -982,7 +982,7 @@ policy.layer = {
                if bit.band(state, bit.bor(kres.FAIL, kres.DONE)) ~= 0 then return state end
                local qry = req:initial() -- same as :current() but more descriptive
                return policy.evaluate(policy.rules, req, qry, state)
index 9066df8f504d52dcb167f6d53d736907a98c259b..a4811f1cccc52b51ea759594d3c3870e7ea4e0b3 100644 (file)
@@ -7,12 +7,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=libreswan
-PKG_VERSION:=4.2
+PKG_VERSION:=4.3
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://download.libreswan.org/
-PKG_HASH:=bbf1babda23bdb269f6ac75d8e1a24cdc6da5d15191b15ad7b10096319105cd7
+PKG_HASH:=7ec4c06290b9643a7422b1f2f77c366b79f039117168d6b80cde0b11d76b8970
 
 PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
 PKG_LICENSE:=GPL-2.0-or-later
index 914844674fe932ae5f96f887676e3c2280ac3587..c8f551df2fba84f60968b9d6da920a81eb76147e 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mwan3
-PKG_VERSION:=2.10.6
+PKG_VERSION:=2.10.7
 PKG_RELEASE:=1
 PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>, \
                Aaron Goodman <aaronjg@alumni.stanford.edu>
index c6333198e9e1df4cb18f3bcf6daa89f5c87399da..fd81f68c3b68ff2253ce29bb163bd2dc8dfb15ce 100755 (executable)
@@ -242,12 +242,12 @@ main() {
                                case "$track_method" in
                                        ping)
                                                if [ $check_quality -eq 0 ]; then
-                                                       WRAP $PING -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null &
+                                                       WRAP $PING -n -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null &
                                                        TRACK_PID=$!
                                                        wait $TRACK_PID
                                                        result=$?
                                                else
-                                                       WRAP $PING -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null > $TRACK_OUTPUT &
+                                                       WRAP $PING -n -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null > $TRACK_OUTPUT &
                                                        TRACK_PID=$!
                                                        wait $TRACK_PID
                                                        ping_status=$?
index 907d79b61c5d17aa2e89985d616563d7011594cc..2625c1ab16a9e3420d822fdd7b3d1aafcadbd310 100644 (file)
@@ -9,16 +9,16 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=openvpn
 
-PKG_VERSION:=2.5.0
-PKG_RELEASE:=2
+PKG_VERSION:=2.5.1
+PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=\
        https://build.openvpn.net/downloads/releases/ \
        https://swupdate.openvpn.net/community/releases/
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
-PKG_HASH:=029a426e44d656cb4e1189319c95fe6fc9864247724f5599d99df9c4c3478fbd
+PKG_HASH:=40930489c837c05f6153f38e1ebaec244431ef1a034e4846ff732d71d59ff194
 
-PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
+PKG_MAINTAINER:=Magnus Kroken <mkroken@gmail.com>
 
 PKG_INSTALL:=1
 PKG_FIXUP:=autoreconf
index 293ae181219b73b94e797527436f8b2ebbe0fb73..462e9f0897b0e85e83548e079fe914dec9ddb8c7 100644 (file)
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=static-neighbor-reports
 PKG_VERSION:=1
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_MAINTAINER:=David Bauer <mail@david-bauer.net>
 PKG_LICENSE:=GPL-2.0-only
@@ -19,7 +19,7 @@ define Package/static-neighbor-reports
   CATEGORY:=Network
   TITLE:=Configure static 802.11k neighbor reports
   PKGARCH:=all
-  DEPENDS:=+libuci-lua +libubus-lua
+  DEPENDS:=+libuci-lua +libubus-lua +lua
 endef
 
 define Package/static-neighbor-reports/install
index 55ce59f81144f54617ceb0bf0aeeb468b1e5e48c..5f017cc75ca59c246f1fbfa77c64c782472f8fa1 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uacme
-PKG_VERSION:=1.6
-PKG_RELEASE:=1
+PKG_VERSION:=1.7
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/ndilieto/uacme/tar.gz/upstream/$(PKG_VERSION)?
-PKG_HASH:=baeb1621e4b5d3cbf339531aa8c0df29ccffbb9c996379265349976d2c09c259
+PKG_HASH:=32ca99851194cadb16c05f3c5d32892b0b93fc247321de2b560fa0f667e6cf04
 
 PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
 PKG_LICENSE:=GPL-3.0-or-later
index f605b15b41842ea8e7d1622591d2aae1ae41ffff..609674b0321aabb8969affa66a1f58ecee72c6c4 100644 (file)
@@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=vpn-policy-routing
 PKG_VERSION:=0.3.2
-PKG_RELEASE:=16
+PKG_RELEASE:=18
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net>
 
index 0f9cb479ea7f700ab6433f8372485208ed510175..7bd82e6f589a29123c01d7008505222538478087 100755 (executable)
@@ -31,7 +31,8 @@ fi
 
 readonly packageName='vpn-policy-routing'
 readonly serviceName="$packageName $PKG_VERSION"
-readonly PID="/var/run/${packageName}.pid"
+readonly PIDFile="/var/run/${packageName}.pid"
+readonly jsonFile="/var/run/${packageName}.json"
 readonly dnsmasqFile="/var/dnsmasq.d/${packageName}"
 readonly sharedMemoryOutput="/dev/shm/$packageName-output"
 readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
@@ -55,8 +56,8 @@ ipsetSupported='true'
 configLoaded='false'
 
 version() { echo "$PKG_VERSION"; }
-create_lock() { [ -e "$PID" ] && return 1; touch "$PID"; }
-remove_lock() { [ -e "$PID" ] && rm -f "$PID"; }
+create_lock() { [ -e "$PIDFile" ] && return 1; touch "$PIDFile"; }
+remove_lock() { [ -e "$PIDFile" ] && rm -f "$PIDFile"; }
 trap remove_lock EXIT
 output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
 output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
@@ -91,21 +92,19 @@ output() {
 is_installed() { [ -s "/usr/lib/opkg/info/${1}.control" ]; }
 is_variant_installed() { [ "$(echo /usr/lib/opkg/info/"${1}"*.control)" != "/usr/lib/opkg/info/${1}*.control" ]; }
 
-list_iface() { ifAll="${ifAll}${1} "; }
-list_supported_iface() { is_supported_interface "$1" && ifSupported="${ifSupported}${1} "; }
-vpr_find_true() {
+build_ifAll() { ifAll="${ifAll}${1} "; }
+build_ifSupported() { is_supported_interface "$1" && ifSupported="${ifSupported}${1} "; }
+vpr_find_iface() {
        local iface i param="$2"
        [ "$param" = 'wan6' ] || param='wan'
        "network_find_${param}" iface
        is_tunnel "$iface" && unset iface
        if [ -z "$iface" ]; then
-               unset ifAll; config_load 'network';
-               config_foreach list_iface 'interface'
                for i in $ifAll; do
                        if "is_${param}" "$i"; then break; else unset i; fi
                done
        fi
-       export "$1=${iface:-$i}"
+       eval "$1"='${iface:-$i}'
 }
 vpr_get_gateway() {
        local iface="$2" dev="$3" gw
@@ -113,7 +112,7 @@ vpr_get_gateway() {
        if [ -z "$gw" ] || [ "$gw" = '0.0.0.0' ]; then
                gw="$(ip -4 a list dev "$dev" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')"
        fi
-       export "$1=$gw"
+       eval "$1"='$gw'
 }
 vpr_get_gateway6() {
        local iface="$2" dev="$3" gw
@@ -121,7 +120,7 @@ vpr_get_gateway6() {
        if [ -z "$gw" ] || [ "$gw" = '::/0' ] || [ "$gw" = '::0/0' ] || [ "$gw" = '::' ]; then
                gw="$(ip -6 a list dev "$dev" 2>/dev/null | grep inet6 | awk '{print $2}')"
        fi
-       export "$1=$gw"
+       eval "$1"='$gw'
 }
 is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; }
 is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; }
@@ -161,7 +160,8 @@ dnsmasq_restart() { output 3 'Restarting DNSMASQ '; if /etc/init.d/dnsmasq resta
 is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; }
 is_supported_iface_dev() {
        for n in $ifSupported; do 
-               if [ "$1" = "$(uci -q get "network.${n}.ifname" || echo "$n")" ] || [ "$1" = "$(uci -q get "network.${n}.proto")-${n}" ] ; then return 0; fi
+               if [ "$1" = "$(uci -q get "network.${n}.ifname" || echo "$n")" ] || \
+                       [ "$1" = "$(uci -q get "network.${n}.proto")-${n}" ] ; then return 0; fi
        done
        return 1
 }
@@ -215,11 +215,13 @@ load_package_config() {
 
        . /lib/functions/network.sh
        . /usr/share/libubox/jshn.sh
-       vpr_find_true wanIface4 'wan'
-       [ "$ipv6Enabled" -ne 0 ] && vpr_find_true wanIface6 'wan6'
-       [ -n "$wanIface4" ] && network_get_gateway wanGW4 "$wanIface4"
-       [ -n "$wanIface6" ] && network_get_gateway6 wanGW6 "$wanIface6"
-       wanGW="${wanGW4:-$wanGW6}"
+       mkdir -p "${PIDFile%/*}"
+       mkdir -p "${jsonFile%/*}"
+       mkdir -p "${dnsmasqFile%/*}"
+
+       if [ -n "$icmpIface" ] && ! str_contains_word "$usedChainsList" 'OUTPUT'; then
+               usedChainsList="$usedChainsList OUTPUT"
+       fi
 
        case $insertOption in
                insert|-i|-I) insertOption='-I';;
@@ -230,27 +232,27 @@ load_package_config() {
        if dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'; then
                unset dnsmasqIpsetSupported
                if [ -n "$dnsmasqIpsetSupported" ]; then
-                       errorSummary="${errorSummary}$_ERROR_: Resolver ipset support (dnsmasq.ipset) is enabled in $packageName, but DNSMASQ ipsets are not supported on this system!\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: Resolver ipset support (dnsmasq.ipset) is enabled in $packageName, but DNSMASQ ipsets are not supported on this system!\\n"
                fi
        fi
        if ! ipset help hash:net >/dev/null 2>&1; then
                unset ipsetSupported
                if [ -n "$dnsmasqIpsetSupported" ]; then
-                       errorSummary="${errorSummary}$_ERROR_: DNSMASQ ipsets are supported, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: DNSMASQ ipsets are supported, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
                        unset dnsmasqIpsetSupported
                fi
                if [ "$destIpset" -ne 0 ]; then
-                       errorSummary="${errorSummary}$_ERROR_: Destination ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: Destination ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
                        destIpset=0
                fi
                if [ "$srcIpset" -ne 0 ]; then
-                       errorSummary="${errorSummary}$_ERROR_: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n"
                        srcIpset=0
                fi
        fi
        if ! ipset help hash:mac >/dev/null 2>&1; then
                if [ "$srcIpset" -ne 0 ]; then
-                       errorSummary="${errorSummary}$_ERROR_: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:mac' type!\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:mac' type!\\n"
                        srcIpset=0
                fi
        fi
@@ -262,34 +264,44 @@ is_enabled() {
        load_package_config
        if [ "$serviceEnabled" -eq 0 ]; then
                if [ "$1" = 'on_start' ]; then
-                       output "$packageName is currently disabled.\\n"
-                       output "Run the following commands before starting service again:\\n"
-                       output "uci set $packageName.config.enabled='1'; uci commit;\\n"
+                       errorSummary="${errorSummary}${_ERROR_}: ${packageName} is currently disabled.\\n"
+                       errorSummary="${errorSummary}Enable ${packageName} from WebUI or run the following commands:\\n"
+                       errorSummary="${errorSummary}uci set $packageName.config.enabled='1'; uci commit $packageName;\\n"
                fi
                return 1
        fi
+}
 
+load_network() {
+       if [ -z "$ifAll" ]; then
+               config_load 'network'
+               config_foreach build_ifAll 'interface'
+       fi
+       vpr_find_iface wanIface4 'wan'
+       [ "$ipv6Enabled" -ne 0 ] && vpr_find_iface wanIface6 'wan6'
+       [ -n "$wanIface4" ] && network_get_gateway wanGW4 "$wanIface4"
+       [ -n "$wanIface6" ] && network_get_gateway6 wanGW6 "$wanIface6"
+       wanGW="${wanGW4:-$wanGW6}"
+       unset ifSupported
+       config_load 'network'
+       config_foreach build_ifSupported 'interface'
 }
 
 is_wan_up() {
        local sleepCount=1
+       load_network
        while [ -z "$wanGW" ] ; do
-               vpr_find_true wanIface4 'wan'
-               [ "$ipv6Enabled" -ne 0 ] && vpr_find_true wanIface6 'wan6'
-               [ -n "$wanIface4" ] && network_get_gateway wanGW4 "$wanIface4"
-               [ -n "$wanIface6" ] && network_get_gateway6 wanGW6 "$wanIface6"
-               wanGW="${wanGW4:-$wanGW6}"
+               load_network
                if [ $((sleepCount)) -gt $((bootTimeout)) ] || [ -n "$wanGW" ]; then break; fi
-               output "$serviceName waiting for wan gateway...\\n"; sleep 1; network_flush_cache; sleepCount=$((sleepCount+1));
+               output "$serviceName waiting for wan gateway...\\n"
+               sleep 1
+               network_flush_cache
+               sleepCount=$((sleepCount+1))
        done
-       mkdir -p "${PID%/*}"; mkdir -p "${dnsmasqFile%/*}";
-       unset ifSupported
-       config_load 'network'
-       config_foreach list_supported_iface 'interface'
        if [ -n "$wanGW" ]; then
-               return 0        
-       else    
-               output "$_ERROR_: $serviceName failed to discover WAN gateway!\\n"
+               return 0
+       else
+               errorSummary="${errorSummary}${_ERROR_}: ${serviceName} failed to discover WAN gateway!\\n"
                return 1
        fi
 }
@@ -714,7 +726,8 @@ process_interface(){
                        ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))";
                        ;;
                create)
-                       export "mark_${iface//-/_}=$ifaceMark"; export "tid_${iface//-/_}=$ifaceTableID";
+                       eval "mark_${iface//-/_}"='$ifaceMark'
+                       eval "tid_${iface//-/_}"='$ifaceTableID'
                        table_destroy "${ifaceTableID}" "${iface}"
                        vpr_get_gateway gw4 "$iface" "$dev"
                        vpr_get_gateway6 gw6 "$iface" "$dev6"
@@ -802,7 +815,6 @@ convert_config(){
        grep -q "remote_port" "/etc/config/${packageName}" && sed -i 's/remote_port/dest_port/g' "/etc/config/${packageName}"
        grep -q "local_ipset" "/etc/config/${packageName}" && sed -i 's/local_ipset/src_ipset/g' "/etc/config/${packageName}"
        grep -q "remote_ipset" "/etc/config/${packageName}" && sed -i 's/remote_ipset/dest_ipset/g' "/etc/config/${packageName}"
-#      sync
        dest_ipset="$(uci -q get $packageName.config.dest_ipset)"
        src_ipset="$(uci -q get $packageName.config.src_ipset)"
        resolver_ipset="$(uci -q get $packageName.config.resolver_ipset)"
@@ -880,7 +892,7 @@ start_service() {
        local dnsmasqStoredHash dnsmasqNewHash i modprobeStatus=0
        convert_config
        is_enabled 'on_start' || return 1
-       is_wan_up || return 0
+       is_wan_up || return 1
        if create_lock; then
                if [ -s "$dnsmasqFile" ]; then
                        dnsmasqStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')"
@@ -921,11 +933,7 @@ start_service() {
                [ "$dnsmasqNewHash" != "$dnsmasqStoredHash" ] && dnsmasq_restart
 
                if [ -z "$gatewaySummary" ]; then
-                       errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway\\n"
-               else
-                       output "$serviceName started with gateways:\\n${gatewaySummary}"
-                       [ -n "$errorSummary" ] && output "${errorSummary}"
-                       [ -n "$warningSummary" ] && output "${warningSummary}"
+                       errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway!\\n"
                fi
                procd_open_instance "main"
                procd_set_param command /bin/true
@@ -952,7 +960,54 @@ start_service() {
        fi
 }
 
+tmpfs() {
+       local action="$1" param="$2" value="$3"
+# shellcheck disable=SC2034
+       local gateway error warning mode i
+       if [ -s "$jsonFile" ]; then
+               json_load_file "$jsonFile" 2>/dev/null
+               json_select 'status' 2>/dev/null
+               for i in gateway error warning mode; do
+                       json_get_var $i "$i" 2>/dev/null
+               done
+       fi
+       case "$action" in
+               get)
+                       printf "%b" "$(eval echo "\$$param")"; return;;
+               add)
+                       eval "$param"='$(eval echo "\$$param")${value}';;
+               del)
+                       case "$param" in
+                               all)
+                                       unset gateway error warning mode;;
+                               *)
+                                       unset "$param";;
+                       esac
+                       ;;
+               set)
+                       eval "$param"='$value';;
+       esac
+       json_init
+       json_add_object 'status'
+       json_add_string version "$PKG_VERSION"
+       for i in gateway error warning mode; do
+               json_add_string "$i" "$(eval echo "\$$i")"
+       done 
+       json_close_object
+       json_dump > "$jsonFile"
+       sync
+}
+
 service_started() {
+       tmpfs set 'gateway' "$gatewaySummary"
+       tmpfs set 'error' "$errorSummary"
+       tmpfs set 'warning' "$warningSummary"
+       if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then
+               tmpfs set 'mode' 'strict'
+       fi
+       [ -n "$gatewaySummary" ] && output "$serviceName started with gateways:\\n${gatewaySummary}"
+       [ -n "$errorSummary" ] && output "${errorSummary}"
+       [ -n "$warningSummary" ] && output "${warningSummary}"
        if [ -n "$errorSummary" ]; then
                return 2
        elif [ -n "$warningSummary" ]; then
@@ -1032,7 +1087,7 @@ support() {
                wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}')
                [ "$wanGW6" = "default" ] && wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}')
        fi
-       while [ "${1:0:1}" = "-" ]; do param="${1//-/}"; export "set_$param=1"; shift; done
+       while [ "${1:0:1}" = "-" ]; do param="${1//-/}"; eval "set_$param=1"; shift; done
        [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support"
        status="$serviceName running on $dist $vers."
        [ -n "$wanIface4" ] && status="$status WAN (IPv4): ${wanIface4}/${dev}/${wanGW4:-0.0.0.0}."
index b98fea669e8f1a25a92177d82a007568074c07a4..9f59e2d3cef729d7e4c556b025820c7924162bed 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=wavemon
-PKG_VERSION:=0.9.2
-PKG_RELEASE:=1
+PKG_VERSION:=0.9.3
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/uoaerg/wavemon/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=13334ff17720ba4d17f4658dd2b93a50a6b5bc0583dedd72b88fd0cb90db686a
+PKG_HASH:=ddbeb6ec8ed7d94fa895e5d57ecfe338495df3991f6facc7cf40aa121bf7ff60
 
 PKG_MAINTAINER:=Jonathan McCrohan <jmccrohan@gmail.com>
 PKG_LICENSE:=GPL-2.0-or-later
index ad2a38e563a0d0d805846214cf32296878f4da21..6b5a375846cc9e8270e42d571e87d612e6e03232 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=xray-core
-PKG_VERSION:=1.3.0
+PKG_VERSION:=1.3.1
 PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=1125af4411655abf47913af14a22fd7e2b13371e3566cc03676207519b0fe407
+PKG_HASH:=5b860144c470c3f7c6b71ffdf0c3830980f1f6ce431fbe6bf10249c1f0e991a7
 
 PKG_MAINTAINER:=
 PKG_LICENSE:=MPL-2.0
@@ -31,7 +31,7 @@ define Package/xray/template
   TITLE:=A platform for building proxies to bypass network restrictions
   SECTION:=net
   CATEGORY:=Network
-  URL:=https://xray.sh
+  URL:=https://xtls.github.io
 endef
 
 define Package/xray-core
@@ -80,24 +80,24 @@ define Package/xray-core/conffiles
 /etc/config/xray
 endef
 
-GEOIP_VER:=202102110014
+GEOIP_VER:=202102250625
 GEOIP_FILE:=geoip.dat.$(GEOIP_VER)
 
 define Download/geoip
   URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/
   URL_FILE:=geoip.dat
   FILE:=$(GEOIP_FILE)
-  HASH:=c80e61b251fd76b09df5624b12cc84d7e1d9a0492b9acb43e21f0a244b1f9fc3
+  HASH:=ee41b3c624e27a47b611d7cbee9da605fb9cda7c23bec1326969eb137ca6ebe7
 endef
 
-GEOSITE_VER:=20210211141342
+GEOSITE_VER:=20210226210728
 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
 
 define Download/geosite
   URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
   URL_FILE:=dlc.dat
   FILE:=$(GEOSITE_FILE)
-  HASH:=e71b4acf2918851dd56e7cda714abb4758deb57b91d716911f33c453b909e796
+  HASH:=ef9c30bacc6989a0b9fae6043dcef1ec15af96c01eddfa1f1d1ad93d14864f81
 endef
 
 define Build/Prepare
index fd5df728b3478a40ddc5dd2c20da5f2d6d925f1b..7613193e0be5c3e30421c64ac35a58c3c0298965 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pulseaudio
-PKG_VERSION:=14.0
+PKG_VERSION:=14.2
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=https://freedesktop.org/software/pulseaudio/releases
-PKG_HASH:=a834775d9382b055504e5ee7625dc50768daac29329531deb6597bf05e06c261
+PKG_HASH:=75d3f7742c1ae449049a4c88900e454b8b350ecaa8c544f3488a2562a9ff66f1
 
 PKG_MAINTAINER:=Peter Wagner <tripolar@gmx.at>
 PKG_LICENSE:=LGPL-2.1-or-later
@@ -111,7 +111,6 @@ MESON_ARGS += \
        -Datomic-arm-memory-barrier=false \
        -Dalsa=enabled \
        -Dasyncns=disabled \
-       -Dbluez5=false \
        -Dbluez5-native-headset=false \
        -Dbluez5-ofono-headset=false \
        -Dfftw=disabled \
@@ -137,12 +136,14 @@ MESON_ARGS += \
 ifeq ($(BUILD_VARIANT),avahi)
 MESON_ARGS += \
        -Davahi=enabled \
+       -Dbluez5=true \
        -Ddbus=enabled
 endif
 
 ifeq ($(BUILD_VARIANT),noavahi)
 MESON_ARGS += \
        -Davahi=disabled \
+       -Dbluez5=false \
        -Ddbus=disabled
 endif
 
index 5a6f394a7e49b34b109990b4140b39f48786645b..8da46b9263aad8efa8d420ad60b6a74a8ec8499f 100644 (file)
@@ -1,6 +1,6 @@
 --- a/meson.build
 +++ b/meson.build
-@@ -391,12 +391,11 @@ if dl_dep.found()
+@@ -390,12 +390,11 @@ if dl_dep.found()
  endif
  
  have_iconv = false
index 472c5e885cf2af3731466e5b1e16cb8db0f93f0c..acfdbaf354f39a12d47dd2648bf974dee83f39ed 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=docker
-PKG_VERSION:=20.10.3
+PKG_VERSION:=20.10.4
 PKG_RELEASE:=1
 PKG_LICENSE:=Apache-2.0
 PKG_LICENSE_FILES:=LICENSE
@@ -10,8 +10,8 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_GIT_URL:=github.com/docker/cli
 PKG_GIT_REF:=v$(PKG_VERSION)
 PKG_SOURCE_URL:=https://codeload.$(PKG_GIT_URL)/tar.gz/$(PKG_GIT_REF)?
-PKG_HASH:=aafba3765d9013cb75810b4f4334525f0e74e82ef073b4df9e8b524f3794e60a
-PKG_GIT_SHORT_COMMIT:=48d30b5 # SHA1 used within the docker executables
+PKG_HASH:=2757ce724b80289d834618f338faa49c512240f3006d18119677f63ec12f0631
+PKG_GIT_SHORT_COMMIT:=d3cb89e # SHA1 used within the docker executables
 
 PKG_MAINTAINER:=Gerard Ryan <G.M0N3Y.2503@gmail.com>
 
index 1075d8e2837d1c69fde494cab6f4fdecc3bf2ca2..51b97922184e1c472b55831fb65c4af9bdef29ae 100644 (file)
@@ -1,7 +1,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=dockerd
-PKG_VERSION:=20.10.3
+PKG_VERSION:=20.10.4
 PKG_RELEASE:=1
 PKG_LICENSE:=Apache-2.0
 PKG_LICENSE_FILES:=LICENSE
@@ -10,8 +10,8 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_GIT_URL:=github.com/moby/moby
 PKG_GIT_REF:=v$(PKG_VERSION)
 PKG_SOURCE_URL:=https://codeload.$(PKG_GIT_URL)/tar.gz/$(PKG_GIT_REF)?
-PKG_HASH:=62bb03f197b8a064da568e62639f6834f91c8cfc9273126a978847becc214c31
-PKG_GIT_SHORT_COMMIT:=46229ca # SHA1 used within the docker executables
+PKG_HASH:=97e8861fe68427bf695846d9cca7ff15101f4f393547660fac2fee2e99eba07d
+PKG_GIT_SHORT_COMMIT:=363e9a8 # SHA1 used within the docker executables
 
 PKG_MAINTAINER:=Gerard Ryan <G.M0N3Y.2503@gmail.com>
 
index 2eb272a70c5e563ef44bdc62976d819f3e0304ac..d3709f33569eaf3f55e5f81ec61c8fb65ea0197c 100755 (executable)
@@ -143,6 +143,10 @@ process_config() {
        config_get registry_mirrors globals registry_mirrors ""
        config_get hosts globals hosts ""
        config_get dns globals dns ""
+       config_get_bool ipv6 globals ipv6 ""
+       config_get ip globals ip ""
+       config_get fixed_cidr globals fixed_cidr ""
+       config_get fixed_cidr_v6 globals fixed_cidr_v6 ""
 
        . /usr/share/libubox/jshn.sh
        json_init
@@ -159,6 +163,10 @@ process_config() {
        [ -z "${dns}" ] || json_add_array "dns"
        [ -z "${dns}" ] || config_list_foreach globals dns json_add_array_string
        [ -z "${dns}" ] || json_close_array
+       [ -z "${ipv6}" ] || json_add_boolean "ipv6" "${ipv6}"
+       [ -z "${ip}" ] || json_add_string "ip" "${ip}"
+       [ -z "${fixed_cidr}" ] || json_add_string "fixed-cidr" "${fixed_cidr}"
+       [ -z "${fixed_cidr_v6}" ] || json_add_string "fixed-cidr-v6" "${fixed_cidr_v6}"
        json_dump > "${DOCKERD_CONF}"
 
        [ "${iptables}" -eq "1" ] && config_foreach iptables_add_blocking_rule firewall
index 72dc98624a69c7559879ea3ac28c7c86b6388c1c..872ff131e4ce041034e3e3b317fdea5da48edd7b 100644 (file)
@@ -11,6 +11,10 @@ config globals 'globals'
        option iptables '1'
 #      list hosts 'unix:///var/run/docker.sock'
 #      option bip '172.18.0.1/24'
+#      option fixed_cidr '172.17.0.0/16'
+#      option fixed_cidr_v6 'fc00:1::/80'
+#      option ipv6 '1'
+#      option ip '::ffff:0.0.0.0'
 #      list dns '172.17.0.1'
 #      list registry_mirrors 'https://<my-docker-mirror-host>'
 #      list registry_mirrors 'https://hub.docker.com'
index ea874a0ce3051dd0669b9349795bba7d750ddf2c..c201c6fffd06d8124d9a5f739a4e007173aa791a 100644 (file)
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=mc
 PKG_VERSION:=4.8.26
 PKG_RELEASE:=1
-PKG_MAINTAINER:=Dirk Brenken <dev@brenken.org>
+PKG_MAINTAINER:=
 PKG_LICENSE:=GPL-3.0-or-later
 PKG_CPE_ID:=cpe:/a:midnight_commander:midnight_commander
 
index cc4e8f8879a1e07490588575570364cb0983cc74..c4de6fb4a603ab06dc72cfdbce7338a792149031 100644 (file)
@@ -1,15 +1,15 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=runc
-PKG_VERSION:=1.0.0-rc92
-PKG_RELEASE:=2
+PKG_VERSION:=1.0.0-rc93
+PKG_RELEASE:=1
 PKG_LICENSE:=Apache-2.0
 PKG_LICENSE_FILES:=LICENSE
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/opencontainers/runc/tar.gz/v${PKG_VERSION}?
-PKG_HASH:=28378df983a3c586ed3ec8c76a774a9b10f36a0c323590a284b801cce95cc61f
-PKG_SOURCE_VERSION:=ff819c7e9184c13b7c2607fe6c30ae19403a7aff
+PKG_HASH:=e42456078d2f76c925cdd656e4f423b918525d8188521de05e893b6bb473a6f8
+PKG_SOURCE_VERSION:=12644e614e25b05da6fd08a38ffa0cfe1903fdec
 
 PKG_MAINTAINER:=Gerard Ryan <G.M0N3Y.2503@gmail.com>
 
index 804f44cf7f7f5a59a1f55fee20dbb659f01f0222..1019eba6f019555f2ef9e2f7524c71db9598a739 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=spi-tools
-PKG_VERSION:=0.8.6
-PKG_RELEASE:=1
+PKG_VERSION:=0.8.7
+PKG_RELEASE:=$(AUTORELEASE)
 
-PKG_SOURCE_URL:=https://codeload.github.com/cpb-/spi-tools/tar.gz/$(PKG_VERSION)?
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_HASH:=319ad6ab296111109ea4a820e216cef392429295de7e10e76f7146677337cf09
+PKG_SOURCE_URL:=https://codeload.github.com/cpb-/spi-tools/tar.gz/$(PKG_VERSION)?
+PKG_HASH:=550f505cc5c34a50d5cd36c49c69b2709fca3f0be4f0777e3f96a45c1ffdbd79
 
 PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
 PKG_LICENSE:=GPL-2.0-only
index 8d2c3ec706ae19b4fb0d7c95647c3dc62de049de..f4e4e6a6c17e179e0b81f3061de037cfe648926c 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=syncthing
-PKG_VERSION:=1.12.1
-PKG_RELEASE:=0
+PKG_VERSION:=1.13.1
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=syncthing-source-v$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://github.com/syncthing/syncthing/releases/download/v$(PKG_VERSION)
-PKG_HASH:=f636441137650316b83809c177efb4df73be024547e056ea03dcf0ed627d81c7
+PKG_HASH:=bc5c431f28fb5bd219dcbeb68534e0da2b118a5ea6ed27edd17317aa84e08e5d
 
 PKG_BUILD_DIR=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/$(PKG_NAME)
 
index ca6b0c396b7ecf7fe1e86af2b147d36a218ac3c8..f64ab52189a107a79740b9ebc14ec65007bf5018 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=sysstat
-PKG_VERSION:=12.4.2
-PKG_RELEASE:=1
+PKG_VERSION:=12.4.3
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=http://pagesperso-orange.fr/sebastien.godard/
-PKG_HASH:=3701b2c1883d50eb384d7b95ce5b6df0a71fdcb3c23f96cb58098d1bcffa018f
+PKG_HASH:=ae432431f45aacbcabacfbbe129e2505e215cafa9ce996d7550c6091a46f0bfd
 
 PKG_MAINTAINER:=Marko Ratkaj <marko.ratkaj@sartura.hr>
 PKG_LICENSE:=GPL-2.0-or-later
index 8b024ffacdd2cc83c0530dbd5cc934a57e20ac50..6540711950f463c5ad1cc927727b00bc039007aa 100644 (file)
@@ -9,7 +9,7 @@
  DFLAGS += -DSA_DIR=\"$(SA_DIR)\" -DSADC_PATH=\"$(SADC_PATH)\"
  DFLAGS += $(DFSENSORS)
  DFLAGS += $(DFPCP)
-@@ -117,7 +117,7 @@ ifeq ($(SYSPARAM),y)
+@@ -120,7 +120,7 @@ ifeq ($(SYSPARAM),y)
        DFLAGS += -DHAVE_SYS_PARAM_H
  endif
  NLS = @NLS@
@@ -18,7 +18,7 @@
  ifeq ($(NLS),y)
  REQUIRE_NLS = -DUSE_NLS -DPACKAGE=\"$(PACKAGE)\" -DLOCALEDIR=\"$(NLS_DIR)\"
  endif
-@@ -195,7 +195,7 @@ NLSPOT= $(NLSPO:.po=.pot)
+@@ -198,7 +198,7 @@ NLSPOT= $(NLSPO:.po=.pot)
        $(CC) -o $@ -c $(CFLAGS) $(DFLAGS) $<
  
  % : %.o
@@ -27,7 +27,7 @@
  
  all: sadc sar sadf iostat tapestat mpstat pidstat cifsiostat locales
  
-@@ -283,7 +283,7 @@ librdsensors.a: rd_sensors.o
+@@ -286,7 +286,7 @@ librdsensors.a: rd_sensors.o
  
  sadc.o: sadc.c sa.h version.h common.h rd_stats.h rd_sensors.h
  
@@ -36,7 +36,7 @@
  
  sadc: sadc.o act_sadc.o sa_wrap.o sa_common_sadc.o common_sadc.o systest.o librdstats.a librdsensors.a
  
-@@ -293,7 +293,7 @@ sar: sar.o act_sar.o format_sar.o sa_com
+@@ -296,7 +296,7 @@ sar: sar.o act_sar.o format_sar.o sa_com
  
  sadf.o: sadf.c sadf.h version.h sa.h common.h rd_stats.h rd_sensors.h
  
index f124f98196a297e7f5486e7bccc79f7852375e13..bf59f4c1d5509ff1a0bf960d09435479ac0551ba 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=tar
-PKG_VERSION:=1.32
-PKG_RELEASE:=3
+PKG_VERSION:=1.34
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
 PKG_SOURCE_URL:=@GNU/tar
-PKG_HASH:=d0d3ae07f103323be809bc3eac0dcc386d52c5262499fe05511ac4788af1fdd8
+PKG_HASH:=63bebd26879c5e1eea4352f0d03c991f966aeb3ddeb3c7445c902568d5411d28
 
 PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
 PKG_LICENSE:=GPL-3.0-or-later
index 5ca7c70024615656137a732a2d1017eafab65179..35197b687c6ac5f8c73c5ac58fcb0a5335c7f6ac 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=taskwarrior
-PKG_VERSION:=2.5.1
-PKG_RELEASE:=1
+PKG_VERSION:=2.5.3
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=task-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.taskwarrior.org/download
-PKG_HASH:=d87bcee58106eb8a79b850e9abc153d98b79e00d50eade0d63917154984f2a15
+PKG_HASH:=7243d75e0911d9e2c9119ad94a61a87f041e4053e197f7280c42410aa1ee963b
 PKG_BUILD_DIR:=$(BUILD_DIR)/task-$(PKG_VERSION)
 
 PKG_MAINTAINER:=
index 0cbf11ddab01022a4bd675179d489c04c76ab249..cb80a6a10ee9c38dae9431e1709ba6b187f1e96d 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=watchcat
 PKG_VERSION:=1
-PKG_RELEASE:=11
+PKG_RELEASE:=12
 
 PKG_MAINTAINER:=Roger D <rogerdammit@gmail.com>
 PKG_LICENSE:=GPL-2.0
@@ -19,16 +19,16 @@ include $(INCLUDE_DIR)/package.mk
 define Package/watchcat
   SECTION:=utils
   CATEGORY:=Utilities
-  TITLE:=Enable the configuration of programed reboots
+  TITLE:=Enable the configuration of programmed reboots or network interface restarts
   PKGARCH:=all
 endef
 
 define Package/watchcat/description
-Allows to configure a periodically reboot, or after losing internet connectivity. Configured trough UCI /etc/config/system.
+Restart network interfaces or reboot if pings to hosts fail, or set up periodic reboots. Configured via UCI /etc/config/watchcat
 endef
 
 define Package/watchcat/conffiles
-/etc/config/system
+/etc/config/watchcat
 endef
 
 define Build/Compile
@@ -36,11 +36,13 @@ endef
 
 define Package/watchcat/install
        $(INSTALL_DIR) $(1)/etc/init.d
-       $(INSTALL_BIN) ./files/initd_watchcat $(1)/etc/init.d/watchcat
+       $(INSTALL_BIN) ./files/watchcat.init $(1)/etc/init.d/watchcat
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) ./files/watchcat.sh $(1)/usr/bin/watchcat.sh
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DATA) ./files/watchcat.config $(1)/etc/config/watchcat
        $(INSTALL_DIR) $(1)/etc/uci-defaults
-       $(INSTALL_BIN) ./files/uci_defaults_watchcat $(1)/etc/uci-defaults/50-watchcat
+       $(INSTALL_BIN) ./files/migrate-watchcat $(1)/etc/uci-defaults/migrate-watchcat
 endef
 
 $(eval $(call BuildPackage,watchcat))
diff --git a/utils/watchcat/files/initd_watchcat b/utils/watchcat/files/initd_watchcat
deleted file mode 100644 (file)
index 95f5927..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh /etc/rc.common
-
-START=97
-
-PIDFILE="/tmp/run/watchcat"
-
-append_string() {
-       varname="$1"
-       add="$2"
-       separator="${3:- }"
-       actual
-       eval "actual=\$$varname"
-
-       new="${actual:+$actual$separator}$add"
-       eval "$varname=\$new"
-}
-
-time_to_seconds() {
-       time=$1
-
-       { [ "$time" -ge 1 ] 2>/dev/null && seconds="$time"; } ||
-               { [ "${time%s}" -ge 1 ] 2>/dev/null && seconds="${time%s}"; } ||
-               { [ "${time%m}" -ge 1 ] 2>/dev/null && seconds=$((${time%m} * 60)); } ||
-               { [ "${time%h}" -ge 1 ] 2>/dev/null && seconds=$((${time%h} * 3600)); } ||
-               { [ "${time%d}" -ge 1 ] 2>/dev/null && seconds=$((${time%d} * 86400)); }
-
-       echo $seconds
-       unset seconds
-       unset time
-}
-
-load_watchcat() {
-       config_get period "$1" period "120"
-       config_get mode "$1" mode "restart_iface"
-       config_get pinghosts "$1" pinghosts "8.8.8.8"
-       config_get pingperiod "$1" pingperiod "60"
-       config_get forcedelay "$1" forcedelay "60"
-       config_get pingsize "$1" pingsize "standard"
-       config_get interface "$1" interface
-       config_get mmifacename "$1" mmifacename
-       config_get unlockbands "$1" unlockbands "0"
-
-       # Fix potential typo in mode and provide backward compatibility.
-       [ "$mode" = "allways" ] && mode="periodic_reboot"
-       [ "$mode" = "always" ] && mode="periodic_reboot"
-       [ "$mode" = "ping" ] && mode="ping_reboot"
-       
-       error=""
-       warn=""
-
-       # Checks for settings common to all operation modes
-       if [ "$mode" != "periodic_reboot" ] && [ "$mode" != "ping_reboot" ] && [ "$mode" != "restart_iface" ]; then
-               append_string "error" "mode must be 'periodic_reboot' or 'ping_reboot' or 'restart_iface'" "; "
-       fi
-
-       period="$(time_to_seconds "$period")"
-       [ "$period" -ge 1 ] ||
-               append_string "error" "period has invalid format! Use time value(ex: '30'; '4m'; '6h'; '2d')" "; "
-
-       # ping_reboot mode and restart_iface mode specific checks
-       if [ "$mode" = "ping_reboot" ] || [ "$mode" = "restart_iface" ]; then
-
-               if [ -z "$error" ]; then
-
-                       pingperiod_default="$((period / 5))"
-
-                       pingperiod="$(time_to_seconds "$pingperiod")"
-                       if [ "$pingperiod" -ge 0 ] && [ "$pingperiod" -ge "$period" ]; then
-                               pingperiod="$(time_to_seconds "$pingperiod_default")"
-                               append_string "warn" "pingperiod cannot be greater than $period. Defaulted to $pingperiod_default seconds (1/5 of period)" "; "
-                       fi
-
-                       if [ "$pingperiod" -lt 0 ]; then
-                               append_string "warn" "pingperiod cannot be a negative value." "; "
-                       fi
-
-                       if [ "$mmifacename" != "" ] && [ "$period" -lt 30 ]; then
-                               append_string "error" "Check interval is less than 30s. For robust operation with ModemManager modem interfaces it is recommended to set the period to at least 30s."
-                       fi
-               fi
-       fi
-
-       # ping_reboot mode and periodic_reboot mode specific checks
-       if [ "$mode" = "ping_reboot" ] || [ "$mode" = "periodic_reboot" ]; then
-               forcedelay="$(time_to_seconds "$forcedelay")"
-       fi
-
-       [ -n "$warn" ] && logger -p user.warn -t "watchcat" "$1: $warn"
-       [ -n "$error" ] && {
-               logger -p user.err -t "watchcat" "reboot program $1 not started - $error"
-               return
-       }
-
-       case "$mode" in
-       periodic_reboot)
-               /usr/bin/watchcat.sh "periodic_reboot" "$period" "$forcedelay" &
-               logger -p user.info -t "watchcat" "started task (mode=$mode;period=$period;forcedelay=$forcedelay)"
-               ;;
-       ping_reboot)
-               /usr/bin/watchcat.sh "ping_reboot" "$period" "$forcedelay" "$pinghosts" "$pingperiod" "$pingsize" &
-               logger -p user.info -t "watchcat" "started task (mode=$mode;period=$period;pinghosts=$pinghosts;pingperiod=$pingperiod;forcedelay=$forcedelay;pingsize=$pingsize)"
-               ;;
-       restart_iface)
-               /usr/bin/watchcat.sh "restart_iface" "$period" "$pinghosts" "$pingperiod" "$pingsize" "$interface" "$mmifacename" &
-               logger -p user.info -t "watchcat" "started task (mode=$mode;period=$period;pinghosts=$pinghosts;pingperiod=$pingperiod;pingsize=$pingsize;interface=$interface;mmifacename=$mmifacename;unlockbands=$unlockbands)"
-               ;;
-       *)
-               echo "Error starting Watchcat service. Invalid mode selection: $mode"
-               ;;
-       esac
-
-       echo $! >>"${PIDFILE}.pids"
-}
-
-stop() {
-       if [ -f "${PIDFILE}.pids" ]; then
-               logger -p user.info -t "watchcat" "stopping all tasks"
-
-               while read pid; do
-                       kill -KILL "$pid"
-               done <"${PIDFILE}.pids"
-
-               rm "${PIDFILE}.pids"
-
-               logger -p user.info -t "watchcat" "all tasks stopped"
-       else
-               logger -p user.info -t "watchcat" "no tasks running"
-       fi
-}
-
-start() {
-       [ -f "${PIDFILE}.pids" ] && stop
-
-       config_load system
-       if [ -n "$(uci show system.@watchcat[0])" ]; then # at least one watchcat section exists
-               logger -p user.info -t "watchcat" "starting all tasks"
-               config_foreach load_watchcat watchcat
-               logger -p user.info -t "watchcat" "all tasks started"
-       else
-               logger -p user.info -t "watchcat" "no tasks defined"
-       fi
-}
diff --git a/utils/watchcat/files/migrate-watchcat b/utils/watchcat/files/migrate-watchcat
new file mode 100644 (file)
index 0000000..93b7ce2
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+. /lib/functions.sh
+
+upgrade_watchcat() {
+        local cfg="$1"
+
+        config_get period "$cfg" period
+        config_get mode "$cfg" mode
+        config_get pinghosts "$cfg" pinghosts
+        config_get forcedelay "$cfg" forcedelay
+
+        [ -f "/etc/config/watchcat" ] || touch /etc/config/watchcat
+        uci_add watchcat watchcat
+        uci_set watchcat @watchcat[-1] period "$period"
+        uci_set watchcat @watchcat[-1] mode "$mode"
+        uci_set watchcat @watchcat[-1] pinghosts "$pinghosts"
+        uci_set watchcat @watchcat[-1] forcedelay "$forcedelay"
+
+        uci_remove system "$cfg"
+}
+
+config_load system
+config_foreach upgrade_watchcat watchcat
+
+uci_commit watchcat
+uci commit system
diff --git a/utils/watchcat/files/uci_defaults_watchcat b/utils/watchcat/files/uci_defaults_watchcat
deleted file mode 100644 (file)
index da49932..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-uci -q show system.@watchcat[0] || {
-       uci add system watchcat
-       uci set system.@watchcat[0].period=6h
-       uci set system.@watchcat[0].mode=ping_reboot
-       uci set system.@watchcat[0].pinghosts=8.8.8.8
-       uci set system.@watchcat[0].forcedelay=30
-       uci commit
-}
diff --git a/utils/watchcat/files/watchcat.config b/utils/watchcat/files/watchcat.config
new file mode 100644 (file)
index 0000000..ed6544c
--- /dev/null
@@ -0,0 +1,5 @@
+config watchcat
+       option period '6h'
+       option mode 'ping_reboot'
+       option pinghosts '8.8.8.8'
+       option forcedelay '30'
diff --git a/utils/watchcat/files/watchcat.init b/utils/watchcat/files/watchcat.init
new file mode 100644 (file)
index 0000000..a48d3fd
--- /dev/null
@@ -0,0 +1,124 @@
+#!/bin/sh /etc/rc.common
+
+USE_PROCD=1
+
+START=97
+STOP=01
+
+append_string() {
+       varname="$1"
+       add="$2"
+       separator="${3:- }"
+       actual
+       eval "actual=\$$varname"
+
+       new="${actual:+$actual$separator}$add"
+       eval "$varname=\$new"
+}
+
+time_to_seconds() {
+       time=$1
+
+       { [ "$time" -ge 1 ] 2>/dev/null && seconds="$time"; } ||
+               { [ "${time%s}" -ge 1 ] 2>/dev/null && seconds="${time%s}"; } ||
+               { [ "${time%m}" -ge 1 ] 2>/dev/null && seconds=$((${time%m} * 60)); } ||
+               { [ "${time%h}" -ge 1 ] 2>/dev/null && seconds=$((${time%h} * 3600)); } ||
+               { [ "${time%d}" -ge 1 ] 2>/dev/null && seconds=$((${time%d} * 86400)); }
+
+       echo $seconds
+       unset seconds
+       unset time
+}
+
+config_watchcat() {
+       # Read config
+       config_get period "$1" period "120"
+       config_get mode "$1" mode "ping_reboot"
+       config_get pinghosts "$1" pinghosts "8.8.8.8"
+       config_get pingperiod "$1" pingperiod "60"
+       config_get forcedelay "$1" forcedelay "60"
+       config_get pingsize "$1" pingsize "standard"
+       config_get interface "$1" interface
+       config_get mmifacename "$1" mmifacename
+       config_get_bool unlockbands "$1" unlockbands "0"
+
+       # Fix potential typo in mode and provide backward compatibility.
+       [ "$mode" = "allways" ] && mode="periodic_reboot"
+       [ "$mode" = "always" ] && mode="periodic_reboot"
+       [ "$mode" = "ping" ] && mode="ping_reboot"
+  
+       # Checks for settings common to all operation modes
+       if [ "$mode" != "periodic_reboot" ] && [ "$mode" != "ping_reboot" ] && [ "$mode" != "restart_iface" ]; then
+               append_string "error" "mode must be 'periodic_reboot' or 'ping_reboot' or 'restart_iface'" "; "
+       fi
+
+       period="$(time_to_seconds "$period")"
+       [ "$period" -ge 1 ] ||
+               append_string "error" "period has invalid format. Use time value(ex: '30'; '4m'; '6h'; '2d')" "; "
+
+       # ping_reboot mode and restart_iface mode specific checks
+       if [ "$mode" = "ping_reboot" ] || [ "$mode" = "restart_iface" ]; then
+               if [ -z "$error" ]; then
+                       pingperiod_default="$((period / 5))"
+                       pingperiod="$(time_to_seconds "$pingperiod")"
+
+                       if [ "$pingperiod" -ge 0 ] && [ "$pingperiod" -ge "$period" ]; then
+                               pingperiod="$(time_to_seconds "$pingperiod_default")"
+                               append_string "warn" "pingperiod cannot be greater than $period. Defaulted to $pingperiod_default seconds (1/5 of period)" "; "
+                       fi
+
+                       if [ "$pingperiod" -lt 0 ]; then
+                               append_string "warn" "pingperiod cannot be a negative value." "; "
+                       fi
+
+                       if [ "$mmifacename" != "" ] && [ "$period" -lt 30 ]; then
+                               append_string "error" "Check interval is less than 30s. For robust operation with ModemManager modem interfaces it is recommended to set the period to at least 30s."
+                       fi
+               fi
+       fi
+
+       # ping_reboot mode and periodic_reboot mode specific checks
+       if [ "$mode" = "ping_reboot" ] || [ "$mode" = "periodic_reboot" ]; then
+               forcedelay="$(time_to_seconds "$forcedelay")"
+       fi
+
+       [ -n "$warn" ] && logger -p user.warn -t "watchcat" "$1: $warn"
+       [ -n "$error" ] && {
+               logger -p user.err -t "watchcat" "reboot program $1 not started - $error"
+               return
+       }
+       
+       # Need to conditionally run mode functions because they have different signatures
+       case "$mode" in
+               periodic_reboot)
+                       procd_open_instance "watchcat_${1}"
+                       procd_set_param command /usr/bin/watchcat.sh "periodic_reboot" "$period" "$forcedelay"
+                       procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+                       procd_close_instance
+                       ;;
+               ping_reboot)
+                       procd_open_instance "watchcat_${1}"
+                       procd_set_param command /usr/bin/watchcat.sh "ping_reboot" "$period" "$forcedelay" "$pinghosts" "$pingperiod" "$pingsize"
+                       procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+                       procd_close_instance
+                       ;;
+               restart_iface)
+                       procd_open_instance "watchcat_${1}"
+                       procd_set_param command /usr/bin/watchcat.sh "restart_iface" "$period" "$pinghosts" "$pingperiod" "$pingsize" "$interface" "$mmifacename"
+                       procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+                       procd_close_instance
+                       ;;
+               *)
+                       echo "Error starting Watchcat service. Invalid mode selection: $mode"
+                       ;;
+       esac
+}
+
+start_service() {
+       config_load watchcat
+       config_foreach config_watchcat watchcat
+}
+
+service_triggers() {
+       procd_add_reload_trigger "watchcat"
+}
index 272ae50e9ec3467a9e03d651e0e0bfe525575b76..9eae278c8d0ad2a7f62fc700b22187215c9e3a67 100644 (file)
@@ -8,12 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=yara
-PKG_VERSION:=4.0.2
-PKG_RELEASE:=2
+PKG_VERSION:=4.0.5
+PKG_RELEASE:=$(AUTORELEASE)
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/VirusTotal/yara/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=05ad88eac9a9f0232432fd14516bdaeda14349d6cf0cac802d76e369abcee001
+PKG_HASH:=ea7ebefad05831faf6f780cab721611b0135803f03a84c27eeba7bfe0afc3aae
 
 PKG_MAINTAINER:=Marko Ratkaj <marko.ratkaj@sartura.hr>
 PKG_LICENSE:=BSD-3-Clause
index e021c9a498c5e0f98a04a0d303f0946904f7f8c0..35659a2cd6179738c8d226fdffa3018ad08de15a 100644 (file)
@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=yq
-PKG_VERSION:=4.6.0
+PKG_VERSION:=4.6.1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/mikefarah/yq/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=67c2c4d832da46e3f2d2f364f8b85af5468c9dc1800d5cf066bd25ff5beb9a66
+PKG_HASH:=a843b90e4e86efa310284823ab6f1249e4ae3c6aa5df4d61c10b0fdc543b267d
 
 PKG_MAINTAINER:=
 PKG_LICENSE:=MIT