diff options
59 files changed, 3254 insertions, 237 deletions
diff --git a/.github/workflows/multi-arch-test-build.yml b/.github/workflows/multi-arch-test-build.yml index 249efff33..cbd9663f8 100644 --- a/.github/workflows/multi-arch-test-build.yml +++ b/.github/workflows/multi-arch-test-build.yml @@ -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: diff --git a/lang/php7-pecl-imagick/Makefile b/lang/php7-pecl-imagick/Makefile index 4582e9373..3036db997 100644 --- a/lang/php7-pecl-imagick/Makefile +++ b/lang/php7-pecl-imagick/Makefile @@ -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))) diff --git a/lang/python/python-aiohttp/Makefile b/lang/python/python-aiohttp/Makefile index 60baf9ee3..66205349d 100644 --- a/lang/python/python-aiohttp/Makefile +++ b/lang/python/python-aiohttp/Makefile @@ -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 index 000000000..ce1cb68b0 --- /dev/null +++ b/lang/python/python-typing-extensions/Makefile @@ -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)) diff --git a/libs/libdrm/Config.in b/libs/libdrm/Config.in index 32602c736..6199b704a 100644 --- a/libs/libdrm/Config.in +++ b/libs/libdrm/Config.in @@ -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 diff --git a/libs/libdrm/Makefile b/libs/libdrm/Makefile index d05ef93cf..206748878 100644 --- a/libs/libdrm/Makefile +++ b/libs/libdrm/Makefile @@ -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 diff --git a/libs/libuhttpd/Makefile b/libs/libuhttpd/Makefile index fa0fe0de3..69c99cb5d 100644 --- a/libs/libuhttpd/Makefile +++ b/libs/libuhttpd/Makefile @@ -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 diff --git a/libs/redis/Makefile b/libs/redis/Makefile index b57849fe3..418758872 100644 --- a/libs/redis/Makefile +++ b/libs/redis/Makefile @@ -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 diff --git a/libs/redis/patches/020-fix-atomicvar.patch b/libs/redis/patches/020-fix-atomicvar.patch index 01c18eab2..bf98b0e56 100644 --- a/libs/redis/patches/020-fix-atomicvar.patch +++ b/libs/redis/patches/020-fix-atomicvar.patch @@ -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 index 000000000..a0bfacb8f --- /dev/null +++ b/libs/redis/patches/030-fix-size_t-zmalloc.patch @@ -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. */ diff --git a/libs/xmlrpc-c/Makefile b/libs/xmlrpc-c/Makefile index bb564fbea..1d573b4e4 100644 --- a/libs/xmlrpc-c/Makefile +++ b/libs/xmlrpc-c/Makefile @@ -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 diff --git a/mail/pigeonhole/Makefile b/mail/pigeonhole/Makefile index a44191315..68c05c6cd 100644 --- a/mail/pigeonhole/Makefile +++ b/mail/pigeonhole/Makefile @@ -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 diff --git a/multimedia/ffmpeg/Makefile b/multimedia/ffmpeg/Makefile index 1b4881458..04ea1f4fe 100644 --- a/multimedia/ffmpeg/Makefile +++ b/multimedia/ffmpeg/Makefile @@ -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 diff --git a/multimedia/imagemagick/Makefile b/multimedia/imagemagick/Makefile index 482425131..6397be753 100644 --- a/multimedia/imagemagick/Makefile +++ b/multimedia/imagemagick/Makefile @@ -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) diff --git a/net/family-dns/Makefile b/net/family-dns/Makefile index e7cd4d1c3..54728656e 100644 --- a/net/family-dns/Makefile +++ b/net/family-dns/Makefile @@ -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 diff --git a/net/frr/Makefile b/net/frr/Makefile index f9767365f..44ccacf3c 100644 --- a/net/frr/Makefile +++ b/net/frr/Makefile @@ -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 index 000000000..1c07ab7a1 --- /dev/null +++ b/net/frr/patches/046-nhrpd_cache_config_fixes.patch @@ -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 index 000000000..fdf78a5e6 --- /dev/null +++ b/net/frr/patches/047-nhrpd_fix_SA_warning.patch @@ -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 index 000000000..5eafe61a8 --- /dev/null +++ b/net/frr/patches/048-nhrpd_cleanup_resources.patch @@ -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 index 000000000..ba259cbea --- /dev/null +++ b/net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch @@ -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 index 000000000..c9c490617 --- /dev/null +++ b/net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch @@ -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 index 000000000..91f999ab0 --- /dev/null +++ b/net/frr/patches/051-ospfd_instance_fixes.patch @@ -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 index 000000000..6a78ad45f --- /dev/null +++ b/net/frr/patches/052-nhrpd_support_for_multicast.patch @@ -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 index 000000000..5d4aab1e0 --- /dev/null +++ b/net/frr/patches/053-more_SA_fixes.patch @@ -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 + } + } + diff --git a/net/frr/patches/098-fix_mips_libyang.patch b/net/frr/patches/098-fix_mips_libyang.patch index adf0785b5..e956581d2 100644 --- a/net/frr/patches/098-fix_mips_libyang.patch +++ b/net/frr/patches/098-fix_mips_libyang.patch @@ -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; diff --git a/net/hs20/Makefile b/net/hs20/Makefile index 1d4da7dc3..330fb335a 100644 --- a/net/hs20/Makefile +++ b/net/hs20/Makefile @@ -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 diff --git a/net/knot-resolver/Makefile b/net/knot-resolver/Makefile index 464754927..ceec3d1d0 100644 --- a/net/knot-resolver/Makefile +++ b/net/knot-resolver/Makefile @@ -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 diff --git a/net/knot-resolver/patches/030-fix-policy-hack.patch b/net/knot-resolver/patches/030-fix-policy-hack.patch index 6d013a6cc..a4eac6c8d 100644 --- a/net/knot-resolver/patches/030-fix-policy-hack.patch +++ b/net/knot-resolver/patches/030-fix-policy-hack.patch @@ -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) diff --git a/net/libreswan/Makefile b/net/libreswan/Makefile index 9066df8f5..a4811f1cc 100644 --- a/net/libreswan/Makefile +++ b/net/libreswan/Makefile @@ -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 diff --git a/net/mwan3/Makefile b/net/mwan3/Makefile index 914844674..c8f551df2 100644 --- a/net/mwan3/Makefile +++ b/net/mwan3/Makefile @@ -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> diff --git a/net/mwan3/files/usr/sbin/mwan3track b/net/mwan3/files/usr/sbin/mwan3track index c6333198e..fd81f68c3 100755 --- a/net/mwan3/files/usr/sbin/mwan3track +++ b/net/mwan3/files/usr/sbin/mwan3track @@ -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=$? diff --git a/net/openvpn/Makefile b/net/openvpn/Makefile index 907d79b61..2625c1ab1 100644 --- a/net/openvpn/Makefile +++ b/net/openvpn/Makefile @@ -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 diff --git a/net/static-neighbor-reports/Makefile b/net/static-neighbor-reports/Makefile index 293ae1812..462e9f089 100644 --- a/net/static-neighbor-reports/Makefile +++ b/net/static-neighbor-reports/Makefile @@ -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 diff --git a/net/uacme/Makefile b/net/uacme/Makefile index 55ce59f81..5f017cc75 100644 --- a/net/uacme/Makefile +++ b/net/uacme/Makefile @@ -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 diff --git a/net/vpn-policy-routing/Makefile b/net/vpn-policy-routing/Makefile index f605b15b4..609674b03 100644 --- a/net/vpn-policy-routing/Makefile +++ b/net/vpn-policy-routing/Makefile @@ -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> diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.init b/net/vpn-policy-routing/files/vpn-policy-routing.init index 0f9cb479e..7bd82e6f5 100755 --- a/net/vpn-policy-routing/files/vpn-policy-routing.init +++ b/net/vpn-policy-routing/files/vpn-policy-routing.init @@ -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}." diff --git a/net/wavemon/Makefile b/net/wavemon/Makefile index b98fea669..9f59e2d3c 100644 --- a/net/wavemon/Makefile +++ b/net/wavemon/Makefile @@ -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 diff --git a/net/xray-core/Makefile b/net/xray-core/Makefile index ad2a38e56..6b5a37584 100644 --- a/net/xray-core/Makefile +++ b/net/xray-core/Makefile @@ -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 diff --git a/sound/pulseaudio/Makefile b/sound/pulseaudio/Makefile index fd5df728b..7613193e0 100644 --- a/sound/pulseaudio/Makefile +++ b/sound/pulseaudio/Makefile @@ -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 diff --git a/sound/pulseaudio/patches/010-iconv.patch b/sound/pulseaudio/patches/010-iconv.patch index 5a6f394a7..8da46b926 100644 --- a/sound/pulseaudio/patches/010-iconv.patch +++ b/sound/pulseaudio/patches/010-iconv.patch @@ -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 diff --git a/utils/docker/Makefile b/utils/docker/Makefile index 472c5e885..acfdbaf35 100644 --- a/utils/docker/Makefile +++ b/utils/docker/Makefile @@ -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> diff --git a/utils/dockerd/Makefile b/utils/dockerd/Makefile index 1075d8e28..51b979221 100644 --- a/utils/dockerd/Makefile +++ b/utils/dockerd/Makefile @@ -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> diff --git a/utils/dockerd/files/dockerd.init b/utils/dockerd/files/dockerd.init index 2eb272a70..d3709f335 100755 --- a/utils/dockerd/files/dockerd.init +++ b/utils/dockerd/files/dockerd.init @@ -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 diff --git a/utils/dockerd/files/etc/config/dockerd b/utils/dockerd/files/etc/config/dockerd index 72dc98624..872ff131e 100644 --- a/utils/dockerd/files/etc/config/dockerd +++ b/utils/dockerd/files/etc/config/dockerd @@ -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' diff --git a/utils/mc/Makefile b/utils/mc/Makefile index ea874a0ce..c201c6fff 100644 --- a/utils/mc/Makefile +++ b/utils/mc/Makefile @@ -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 diff --git a/utils/runc/Makefile b/utils/runc/Makefile index cc4e8f887..c4de6fb4a 100644 --- a/utils/runc/Makefile +++ b/utils/runc/Makefile @@ -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> diff --git a/utils/spi-tools/Makefile b/utils/spi-tools/Makefile index 804f44cf7..1019eba6f 100644 --- a/utils/spi-tools/Makefile +++ b/utils/spi-tools/Makefile @@ -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 diff --git a/utils/syncthing/Makefile b/utils/syncthing/Makefile index 8d2c3ec70..f4e4e6a6c 100644 --- a/utils/syncthing/Makefile +++ b/utils/syncthing/Makefile @@ -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) diff --git a/utils/sysstat/Makefile b/utils/sysstat/Makefile index ca6b0c396..f64ab5218 100644 --- a/utils/sysstat/Makefile +++ b/utils/sysstat/Makefile @@ -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 diff --git a/utils/sysstat/patches/010-ldflags.patch b/utils/sysstat/patches/010-ldflags.patch index 8b024ffac..654071195 100644 --- a/utils/sysstat/patches/010-ldflags.patch +++ b/utils/sysstat/patches/010-ldflags.patch @@ -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 diff --git a/utils/tar/Makefile b/utils/tar/Makefile index f124f9819..bf59f4c1d 100644 --- a/utils/tar/Makefile +++ b/utils/tar/Makefile @@ -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 diff --git a/utils/taskwarrior/Makefile b/utils/taskwarrior/Makefile index 5ca7c7002..35197b687 100644 --- a/utils/taskwarrior/Makefile +++ b/utils/taskwarrior/Makefile @@ -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:= diff --git a/utils/watchcat/Makefile b/utils/watchcat/Makefile index 0cbf11dda..cb80a6a10 100644 --- a/utils/watchcat/Makefile +++ b/utils/watchcat/Makefile @@ -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/migrate-watchcat b/utils/watchcat/files/migrate-watchcat new file mode 100644 index 000000000..93b7ce2b3 --- /dev/null +++ b/utils/watchcat/files/migrate-watchcat @@ -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 index da4993230..000000000 --- a/utils/watchcat/files/uci_defaults_watchcat +++ /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 index 000000000..ed6544cc3 --- /dev/null +++ b/utils/watchcat/files/watchcat.config @@ -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/initd_watchcat b/utils/watchcat/files/watchcat.init index 95f59271f..a48d3fded 100644 --- a/utils/watchcat/files/initd_watchcat +++ b/utils/watchcat/files/watchcat.init @@ -1,8 +1,9 @@ #!/bin/sh /etc/rc.common -START=97 +USE_PROCD=1 -PIDFILE="/tmp/run/watchcat" +START=97 +STOP=01 append_string() { varname="$1" @@ -29,25 +30,23 @@ time_to_seconds() { unset time } -load_watchcat() { +config_watchcat() { + # Read config config_get period "$1" period "120" - config_get mode "$1" mode "restart_iface" + 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 unlockbands "$1" unlockbands "0" + 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" - - 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'" "; " @@ -55,16 +54,14 @@ load_watchcat() { period="$(time_to_seconds "$period")" [ "$period" -ge 1 ] || - append_string "error" "period has invalid format! Use time value(ex: '30'; '4m'; '6h'; '2d')" "; " + 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)" "; " @@ -90,53 +87,38 @@ load_watchcat() { 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) - /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" - ;; + 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 - - 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_service() { + config_load watchcat + config_foreach config_watchcat watchcat } -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 +service_triggers() { + procd_add_reload_trigger "watchcat" } diff --git a/utils/yara/Makefile b/utils/yara/Makefile index 272ae50e9..9eae278c8 100644 --- a/utils/yara/Makefile +++ b/utils/yara/Makefile @@ -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 diff --git a/utils/yq/Makefile b/utils/yq/Makefile index e021c9a49..35659a2cd 100644 --- a/utils/yq/Makefile +++ b/utils/yq/Makefile @@ -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 |