From e965229a7d4d96d9a268488c861b66535fba28b5 Mon Sep 17 00:00:00 2001 From: Lucian Cristian Date: Fri, 12 Nov 2021 21:15:54 +0200 Subject: [PATCH] frr: update to 8.1.0 Signed-off-by: Lucian Cristian --- net/frr/Makefile | 20 +- net/frr/files/daemons | 1 + net/frr/files/frrcommon.sh | 2 +- .../046-nhrpd_cache_config_fixes.patch | 385 ------- .../patches/047-nhrpd_fix_SA_warning.patch | 48 - .../patches/048-nhrpd_cleanup_resources.patch | 226 ---- ...9-clear_ip_ospf_process_and_neighbor.patch | 383 ------- .../050-ospf_nbr_nbma_lookup_next.patch | 105 -- .../patches/051-ospfd_instance_fixes.patch | 797 --------------- .../052-nhrpd_support_for_multicast.patch | 964 ------------------ .../patches/053-nhrpd_replace_socket.patch | 82 -- net/frr/patches/098-fix_mips_libyang.patch | 2 +- net/frr/patches/999-thread_reverse.patch | 26 +- 13 files changed, 28 insertions(+), 3013 deletions(-) delete mode 100644 net/frr/patches/046-nhrpd_cache_config_fixes.patch delete mode 100644 net/frr/patches/047-nhrpd_fix_SA_warning.patch delete mode 100644 net/frr/patches/048-nhrpd_cleanup_resources.patch delete mode 100644 net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch delete mode 100644 net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch delete mode 100644 net/frr/patches/051-ospfd_instance_fixes.patch delete mode 100644 net/frr/patches/052-nhrpd_support_for_multicast.patch delete mode 100644 net/frr/patches/053-nhrpd_replace_socket.patch diff --git a/net/frr/Makefile b/net/frr/Makefile index 4fd4163cc..ea1b76f3b 100644 --- a/net/frr/Makefile +++ b/net/frr/Makefile @@ -7,16 +7,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=frr -PKG_VERSION:=7.5.1 -PKG_RELEASE:=2 -PKG_SOURCE_DATE:=2021-08-26 +PKG_VERSION:=8.1.0 +PKG_RELEASE:=1 +PKG_SOURCE_DATE:=2021-11-12 PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz -PKG_SOURCE_VERSION:=4cc14d346bdedc81a52b2981f9f568176513dc3e +PKG_SOURCE_VERSION:=c18235d5b1e33fad9d3181aa29fefa48b8c6ff3f PKG_SOURCE_URL:=https://codeload.github.com/FRRouting/frr/tar.gz/$(PKG_SOURCE_VERSION)? -PKG_HASH:=dd0ec4616b85f5142c9e4ecc4a17b944000a3219bedf9d091484503e8c91e0e7 +PKG_HASH:=95922586d6c39565b3eec362563e031fd4cb2b6d6c0012256e345b364de1ae82 PKG_MAINTAINER:=Lucian Cristian PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION) @@ -35,6 +35,7 @@ PKG_DAEMON_AVAILABLE:= \ nhrpd \ ospfd \ ospf6d \ + pathd \ pbrd \ pimd \ ripd \ @@ -59,7 +60,7 @@ PKG_BUILD_PARALLEL:=1 PKG_INSTALL:=1 PKG_BUILD_DEPENDS:=frr/host -HOST_BUILD_DEPENDS:=python3/host +HOST_BUILD_DEPENDS:=python3/host elfutils/host include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/host-build.mk @@ -144,6 +145,8 @@ define BuildDaemon TITLE:= $(1) routing engine DEPENDS+=frr-libfrr $(2) endef +# if [ "$(1)" == "bfdd" ]; then \ +# export HAVE_BFDD == 1 ; fi define Package/frr-$(1)/install $(INSTALL_DIR) $$(1)/usr/sbin @@ -170,7 +173,7 @@ define Host/Configure $(SED) 's/$$$$(MAKE) $$$$(AM_MAKEFLAGS) install-am/# $$$$(MAKE) $$$$(AM_MAKEFLAGS) install-am/' $(HOST_BUILD_DIR)/Makefile.in endef -#HOST_CPPFLAGS += -I$(STAGING_DIR_HOST)/include/libelf +HOST_CPPFLAGS += -I$(STAGING_DIR_HOST)/include/libelf HOST_CONFIGURE_ARGS+= \ --enable-clippy-only @@ -184,7 +187,6 @@ CONFIGURE_ARGS+= \ --prefix=/usr \ --enable-shared \ --disable-static \ - --disable-pathd \ --enable-user=network \ --enable-group=network \ --disable-ospfclient \ @@ -224,6 +226,7 @@ define Package/frr-libfrr/install $(INSTALL_CONF) ./files/{frr.conf,daemons} $(1)/etc/frr/ endef + define Package/frr-pythontools/install $(INSTALL_DIR) $(1)/usr/lib/frr $(1)/usr/sbin $(1)/etc/frr $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/*.py $(1)/usr/lib/frr/ @@ -254,6 +257,7 @@ $(eval $(call BuildDaemon,ldpd,)) $(eval $(call BuildDaemon,nhrpd,+libcares)) $(eval $(call BuildDaemon,ospfd,)) $(eval $(call BuildDaemon,ospf6d,@IPV6)) +$(eval $(call BuildDaemon,pathd,)) $(eval $(call BuildDaemon,pbrd,)) $(eval $(call BuildDaemon,pimd,)) $(eval $(call BuildDaemon,ripd,)) diff --git a/net/frr/files/daemons b/net/frr/files/daemons index ac39e25b5..0005da4e3 100644 --- a/net/frr/files/daemons +++ b/net/frr/files/daemons @@ -13,6 +13,7 @@ nhrpd=no eigrpd=no babeld=no sharpd=no +pathd=no pbrd=no bfdd=no fabricd=no diff --git a/net/frr/files/frrcommon.sh b/net/frr/files/frrcommon.sh index 80822ceb8..f59fce873 100644 --- a/net/frr/files/frrcommon.sh +++ b/net/frr/files/frrcommon.sh @@ -35,7 +35,7 @@ FRR_DEFAULT_PROFILE="traditional" # traditional / datacenter # - keep zebra first # - watchfrr does NOT belong in this list -DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd" +DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pathd pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd vrrpd" RELOAD_SCRIPT="$D_PATH/frr-reload.py" # diff --git a/net/frr/patches/046-nhrpd_cache_config_fixes.patch b/net/frr/patches/046-nhrpd_cache_config_fixes.patch deleted file mode 100644 index 1c07ab7a1..000000000 --- a/net/frr/patches/046-nhrpd_cache_config_fixes.patch +++ /dev/null @@ -1,385 +0,0 @@ -From fef2ed139d140f551cdfcbb21c5a023dea2e02cb Mon Sep 17 00:00:00 2001 -From: Philippe Guibert -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 ---- - 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 deleted file mode 100644 index fdf78a5e6..000000000 --- a/net/frr/patches/047-nhrpd_fix_SA_warning.patch +++ /dev/null @@ -1,48 +0,0 @@ -From e5773617afba7408c76ec2683814ce076c72c79d Mon Sep 17 00:00:00 2001 -From: Mark Stapp -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 ---- - 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 deleted file mode 100644 index 5eafe61a8..000000000 --- a/net/frr/patches/048-nhrpd_cleanup_resources.patch +++ /dev/null @@ -1,226 +0,0 @@ -From ee72f0a0eb93038ef6dfd01fed9f32e24c5de2a1 Mon Sep 17 00:00:00 2001 -From: Reuben Dowle -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 ---- - 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 deleted file mode 100644 index 8e02baaca..000000000 --- a/net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch +++ /dev/null @@ -1,383 +0,0 @@ -From f91ce319d3cdb465df54ff4e091dbd4aed85b24c Mon Sep 17 00:00:00 2001 -From: Mobashshera Rasool -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 ---- - 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. */ -@@ -826,14 +877,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) -@@ -851,6 +899,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 -@@ -519,7 +519,11 @@ extern struct ospf *ospf_lookup_by_inst_ - extern struct ospf *ospf_lookup_by_vrf_id(vrf_id_t vrf_id); - extern uint32_t ospf_count_area_params(struct ospf *ospf); - 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 *, -@@ -544,6 +548,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 deleted file mode 100644 index 96e7ab71d..000000000 --- a/net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 153bdb3d03542530ed1deccbefc716cb4b699a67 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -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 ---- - 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 -@@ -1919,35 +1919,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 -@@ -563,8 +563,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 deleted file mode 100644 index eb3b17cb3..000000000 --- a/net/frr/patches/051-ospfd_instance_fixes.patch +++ /dev/null @@ -1,797 +0,0 @@ -From 409f98ab443682ec360e3e76954f1c8985b3371d Mon Sep 17 00:00:00 2001 -From: Igor Ryzhov -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 ---- - 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; - } - - -@@ -3326,11 +3332,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) -@@ -4016,11 +4022,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) -@@ -4409,11 +4415,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) -@@ -4621,11 +4627,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(); -@@ -4761,11 +4767,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) -@@ -5170,11 +5176,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, -@@ -5343,11 +5349,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) -@@ -5538,11 +5544,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) -@@ -5670,11 +5676,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, -@@ -6420,10 +6426,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, -@@ -6484,15 +6491,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); - } -@@ -6578,13 +6582,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)); -@@ -8035,7 +8038,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 -@@ -8159,7 +8162,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; - - -@@ -438,36 +440,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 -@@ -502,6 +502,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; -@@ -511,9 +512,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 deleted file mode 100644 index ad7be89af..000000000 --- a/net/frr/patches/052-nhrpd_support_for_multicast.patch +++ /dev/null @@ -1,964 +0,0 @@ -From 6ea5d99456b14db5e82abc2461228bb37aa7556d Mon Sep 17 00:00:00 2001 -From: Amol Lad -Date: Wed, 17 Feb 2021 13:47:32 +1300 -Subject: [PATCH 01/14] 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 ---- - nhrpd/linux.c | 11 +- - nhrpd/nhrp_interface.c | 2 + - nhrpd/nhrp_multicast.c | 307 +++++++++++++++++++++++++++++++++++++++++ - 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, 398 insertions(+), 7 deletions(-) - create mode 100755 nhrpd/nhrp_multicast.c - ---- a/nhrpd/linux.c -+++ b/nhrpd/linux.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -31,6 +32,11 @@ - #include "os.h" - #include "netlink.h" - -+#ifndef HAVE_STRLCPY -+size_t strlcpy(char *__restrict dest, -+ const char *__restrict src, size_t destsize); -+#endif -+ - static int nhrp_socket_fd = -1; - - int os_socket(void) -@@ -42,7 +48,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 +67,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, -@@ -111,7 +117,7 @@ static int linux_configure_arp(const cha - { - struct ifreq ifr; - -- strncpy(ifr.ifr_name, iface, IFNAMSIZ - 1); -+ strlcpy(ifr.ifr_name, iface, IFNAMSIZ); - if (ioctl(nhrp_socket_fd, SIOCGIFFLAGS, &ifr)) - return -1; - ---- 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,309 @@ -+/* 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "thread.h" -+#include "nhrpd.h" -+#include "netlink.h" -+#include "znl.h" -+#include "os.h" -+ -+DEFINE_MTYPE_STATIC(NHRPD, NHRP_MULTICAST, "NHRP Multicast") -+ -+int netlink_mcast_nflog_group; -+static int netlink_mcast_log_fd = -1; -+static struct thread *netlink_mcast_log_thread; -+ -+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 ? ETH_P_IP : ETH_P_IPV6); -+ -+ 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; -+ uint32_t *out_ndx = NULL; -+ afi_t afi; -+ struct mcast_ctx ctx; -+ -+ nf = znl_pull(zb, sizeof(*nf)); -+ if (!nf) -+ return; -+ -+ ctx.pkt = NULL; -+ 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: -+ ctx.pkt = &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 || !ctx.pkt) -+ return; -+ -+ ctx.ifp = if_lookup_by_index(htonl(*out_ndx), VRF_DEFAULT); -+ if (!ctx.ifp) -+ return; -+ -+ debugf(NHRP_DEBUG_COMMON, "Received multicast packet on %s len %zu\n", -+ ctx.ifp->name, zbuf_used(ctx.pkt)); -+ -+ for (afi = 0; afi < AFI_MAX; afi++) { -+ nhrp_multicast_foreach(ctx.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); -+} -+ -+void netlink_mcast_set_nflog_group(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); -+ 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); -+ -+ sockunion2str(nbma_addr, buf, sizeof(buf)); -+ debugf(NHRP_DEBUG_COMMON, "Adding multicast entry (%s)", buf); -+ -+ 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)", buf); -+ -+ 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)", -+ !list_empty(&nifp->afi[afi].mcastlist_head)); -+ -+ 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,7 @@ 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 -@@ -187,6 +187,9 @@ static int nhrp_config_write(struct vty - if (netlink_nflog_group) { - vty_out(vty, "nhrp nflog-group %d\n", netlink_nflog_group); - } -+ if (netlink_mcast_nflog_group) -+ vty_out(vty, "nhrp multicast-nflog-group %d\n", -+ netlink_mcast_nflog_group); - - return 0; - } -@@ -257,6 +260,31 @@ DEFUN(no_nhrp_nflog_group, no_nhrp_nflog - return CMD_SUCCESS; - } - -+DEFUN(nhrp_multicast_nflog_group, nhrp_multicast_nflog_group_cmd, -+ "nhrp multicast-nflog-group (1-65535)", -+ NHRP_STR -+ "Specify NFLOG group number for Multicast Packets\n" -+ "NFLOG group number\n") -+{ -+ uint32_t nfgroup; -+ -+ nfgroup = strtoul(argv[2]->arg, NULL, 10); -+ netlink_mcast_set_nflog_group(nfgroup); -+ -+ return CMD_SUCCESS; -+} -+ -+DEFUN(no_nhrp_multicast_nflog_group, no_nhrp_multicast_nflog_group_cmd, -+ "no nhrp multicast-nflog-group [(1-65535)]", -+ NO_STR -+ NHRP_STR -+ "Specify NFLOG group number\n" -+ "NFLOG group number\n") -+{ -+ netlink_mcast_set_nflog_group(0); -+ return CMD_SUCCESS; -+} -+ - DEFUN(tunnel_protection, tunnel_protection_cmd, - "tunnel protection vici profile PROFILE [fallback-profile FALLBACK]", - "NHRP/GRE integration\n" -@@ -569,6 +597,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 ", -+ 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 ", -+ 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 nbma ", - AFI_STR -@@ -644,8 +719,8 @@ static void show_ip_nhrp_cache(struct nh - - sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])); - if (c->cur.peer) -- sockunion2str(&c->cur.peer->vc->remote.nbma, -- buf[1], sizeof(buf[1])); -+ sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1], -+ sizeof(buf[1])); - else - snprintf(buf[1], sizeof(buf[1]), "-"); - -@@ -704,8 +779,8 @@ static void show_ip_nhrp_nhs(struct nhrp - ctx->count++; - - if (reg && reg->peer) -- sockunion2str(®->peer->vc->remote.nbma, -- buf[0], sizeof(buf[0])); -+ sockunion2str(®->peer->vc->remote.nbma, buf[0], -+ sizeof(buf[0])); - else - snprintf(buf[0], sizeof(buf[0]), "-"); - sockunion2str(reg ? ®->proto_addr : &n->proto_addr, buf[1], -@@ -1018,7 +1093,8 @@ struct write_map_ctx { - const char *aficmd; - }; - --static void interface_config_write_nhrp_map(struct nhrp_cache_config *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; -@@ -1030,7 +1106,8 @@ static void interface_config_write_nhrp_ - vty_out(vty, " %s nhrp map %s %s\n", ctx->aficmd, - sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])), - c->type == NHRP_CACHE_LOCAL -- ? "local" : sockunion2str(&c->nbma, buf[1], sizeof(buf[1]))); -+ ? "local" -+ : sockunion2str(&c->nbma, buf[1], sizeof(buf[1]))); - } - - static int interface_config_write(struct vty *vty) -@@ -1040,6 +1117,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]; -@@ -1093,8 +1171,8 @@ static int interface_config_write(struct - .family = afi2family(afi), - .aficmd = aficmd, - }; -- nhrp_cache_config_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) -@@ -1109,6 +1187,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"); -@@ -1142,6 +1233,8 @@ void nhrp_config_init(void) - install_element(CONFIG_NODE, &no_nhrp_event_socket_cmd); - install_element(CONFIG_NODE, &nhrp_nflog_group_cmd); - install_element(CONFIG_NODE, &no_nhrp_nflog_group_cmd); -+ install_element(CONFIG_NODE, &nhrp_multicast_nflog_group_cmd); -+ install_element(CONFIG_NODE, &no_nhrp_multicast_nflog_group_cmd); - - /* interface specific commands */ - install_node(&nhrp_interface_node); -@@ -1163,6 +1256,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 -@@ -259,6 +259,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 +311,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 +353,16 @@ 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 netlink_mcast_set_nflog_group(int nlgroup); -+ - 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 -@@ -7562,20 +7562,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 ", -- "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 ", -+ "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) { -@@ -7584,16 +7585,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); -@@ -7605,6 +7612,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); -@@ -7645,6 +7653,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 -@@ -1004,6 +1004,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,37 @@ 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 iptables NFLOG rule to allow nhrpd to intercept -+multicast packets. A second iptables rule is also usually used to drop the -+original multicast packet. -+ -+ .. code-block:: shell -+ -+ iptables -A OUTPUT -d 224.0.0.0/24 -o gre1 -j NFLOG --nflog-group 2 -+ iptables -A OUTPUT -d 224.0.0.0/24 -o gre1 -j DROP -+ -+.. 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: - ---- a/nhrpd/netlink.h -+++ b/nhrpd/netlink.h -@@ -13,6 +13,7 @@ union sockunion; - struct interface; - - extern int netlink_nflog_group; -+extern int netlink_mcast_nflog_group; - extern int netlink_req_fd; - - void netlink_init(void); ---- a/ospfd/ospf_packet.c -+++ b/ospfd/ospf_packet.c -@@ -802,7 +802,13 @@ static int ospf_write(struct thread *thr - inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off, - iph.ip_len, oi->ifp->name, oi->ifp->mtu); - -- if (ret < 0) -+ /* sendmsg will return EPERM if firewall is blocking sending. -+ * This is a normal situation when 'ip nhrp map multicast xxx' -+ * is being used to send multicast packets to DMVPN peers. In -+ * that case the original message is blocked with iptables rule -+ * causing the EPERM result -+ */ -+ if (ret < 0 && errno != EPERM) - flog_err( - EC_LIB_SOCKET, - "*** sendmsg in ospf_write failed to %s, id %d, off %d, len %d, interface %s, mtu %u: %s", -@@ -910,8 +916,11 @@ static void ospf_hello(struct ip *iph, s - - /* Compare network mask. */ - /* Checking is ignored for Point-to-Point and Virtual link. */ -+ /* Checking is also ignored for Point-to-Multipoint with /32 prefix */ - if (oi->type != OSPF_IFTYPE_POINTOPOINT -- && oi->type != OSPF_IFTYPE_VIRTUALLINK) -+ && oi->type != OSPF_IFTYPE_VIRTUALLINK -+ && !(oi->type == OSPF_IFTYPE_POINTOMULTIPOINT -+ && oi->address->prefixlen == IPV4_MAX_BITLEN)) - if (oi->address->prefixlen != p.prefixlen) { - flog_warn( - EC_OSPF_PACKET, -@@ -2439,6 +2448,11 @@ static int ospf_check_network_mask(struc - || oi->type == OSPF_IFTYPE_VIRTUALLINK) - return 1; - -+ /* Ignore mask check for max prefix length (32) */ -+ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT -+ && oi->address->prefixlen == IPV4_MAX_BITLEN) -+ return 1; -+ - masklen2ip(oi->address->prefixlen, &mask); - - me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr; diff --git a/net/frr/patches/053-nhrpd_replace_socket.patch b/net/frr/patches/053-nhrpd_replace_socket.patch deleted file mode 100644 index 9ee3db1a6..000000000 --- a/net/frr/patches/053-nhrpd_replace_socket.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 354196c027e81affb05163a6c3676eef1ba06dd9 Mon Sep 17 00:00:00 2001 -From: Zoran Pericic -Date: Sat, 25 Jan 2020 19:38:39 +0100 -Subject: [PATCH] nhrp: Make vici socket path configurable -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -nhrp: Configure vici socket path using - -configure --with-vici-socket=/var/run/charon.vici - -If not specified default to /var/run/charon.vici - -Signed-off-by: Zoran Peričić ---- - configure.ac | 8 ++++++++ - doc/user/installation.rst | 4 ++++ - nhrpd/README.nhrpd | 3 ++- - nhrpd/vici.c | 2 +- - 4 files changed, 15 insertions(+), 2 deletions(-) - ---- a/configure.ac -+++ b/configure.ac -@@ -139,6 +139,13 @@ AC_ARG_WITH([yangmodelsdir], [AS_HELP_ST - ]) - AC_SUBST([yangmodelsdir]) - -+AC_ARG_WITH([vici-socket], [AS_HELP_STRING([--with-vici-socket=PATH], [vici-socket (/var/run/charon.vici)])], [ -+ vici_socket="$withval" -+], [ -+ vici_socket="/var/run/charon.vici" -+]) -+AC_DEFINE_UNQUOTED([VICI_SOCKET], ["$vici_socket"], [StrongSWAN vici socket path]) -+ - AC_ARG_ENABLE(tcmalloc, - AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]), - [case "${enableval}" in -@@ -2480,6 +2487,7 @@ group for vty sockets : ${enable_vty_g - config file mask : ${enable_configfile_mask} - log file mask : ${enable_logfile_mask} - zebra protobuf enabled : ${enable_protobuf:-no} -+vici socket path : ${vici_socket} - - The above user and group must have read/write access to the state file - directory and to the config files in the config file directory." ---- a/doc/user/installation.rst -+++ b/doc/user/installation.rst -@@ -383,6 +383,10 @@ options to the configuration script. - Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR - YANG modules will be installed here. - -+.. option:: --with-vici-socket -+ -+ Set StrongSWAN vici interface socket path [/var/run/charon.vici]. -+ - Python dependency, documentation and tests - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ---- a/nhrpd/README.nhrpd -+++ b/nhrpd/README.nhrpd -@@ -126,7 +126,8 @@ Integration with strongSwan - - Contrary to opennhrp, Quagga/NHRP has tight integration with IKE daemon. - Currently strongSwan is supported using the VICI protocol. strongSwan --is connected using UNIX socket (hardcoded now as /var/run/charon.vici). -+is connected using UNIX socket (default /var/run/charon.vici use configure -+argument --with-vici-socket= to change). - Thus nhrpd needs to be run as user that can open that file. - - Currently, you will need patched strongSwan. The working tree is at: ---- a/nhrpd/vici.c -+++ b/nhrpd/vici.c -@@ -478,7 +478,7 @@ static int vici_reconnect(struct thread - if (vici->fd >= 0) - return 0; - -- fd = sock_open_unix("/var/run/charon.vici"); -+ fd = sock_open_unix(VICI_SOCKET); - if (fd < 0) { - debugf(NHRP_DEBUG_VICI, - "%s: failure connecting VICI socket: %s", __func__, diff --git a/net/frr/patches/098-fix_mips_libyang.patch b/net/frr/patches/098-fix_mips_libyang.patch index e956581d2..76bc87401 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 -@@ -569,11 +569,7 @@ struct frr_yang_module_info { +@@ -592,11 +592,7 @@ struct frr_yang_module_info { /* Priority - lower priorities are processed first. */ uint32_t priority; diff --git a/net/frr/patches/999-thread_reverse.patch b/net/frr/patches/999-thread_reverse.patch index 65a950c2f..cd7c3a7be 100644 --- a/net/frr/patches/999-thread_reverse.patch +++ b/net/frr/patches/999-thread_reverse.patch @@ -1,6 +1,6 @@ --- a/lib/thread.c +++ b/lib/thread.c -@@ -723,13 +723,9 @@ static void thread_free(struct thread_ma +@@ -824,13 +824,9 @@ static void thread_free(struct thread_ma XFREE(MTYPE_THREAD, thread); } @@ -16,7 +16,7 @@ /* * If timer_wait is null here, that means poll() should block * indefinitely, unless the thread_master has overridden it by setting -@@ -760,58 +756,15 @@ static int fd_poll(struct thread_master +@@ -861,58 +857,15 @@ static int fd_poll(struct thread_master rcu_assert_read_unlocked(); /* add poll pipe poker */ @@ -47,10 +47,15 @@ - /* Don't make any changes for the non-main pthreads */ - pthread_sigmask(SIG_SETMASK, NULL, &origsigs); - } -- ++ assert(count + 1 < pfdsize); ++ pfds[count].fd = m->io_pipe[0]; ++ pfds[count].events = POLLIN; ++ pfds[count].revents = 0x00; + -#if defined(HAVE_PPOLL) - struct timespec ts, *tsp; -- ++ num = poll(pfds, count + 1, timeout); + - if (timeout >= 0) { - ts.tv_sec = timeout / 1000; - ts.tv_nsec = (timeout % 1000) * 1000000; @@ -67,22 +72,17 @@ -#endif - -done: -+ assert(count + 1 < pfdsize); -+ pfds[count].fd = m->io_pipe[0]; -+ pfds[count].events = POLLIN; -+ pfds[count].revents = 0x00; - +- - if (num < 0 && errno == EINTR) - *eintr_p = true; -+ num = poll(pfds, count + 1, timeout); - +- - if (num > 0 && m->handler.copy[count].revents != 0 && num--) + unsigned char trash[64]; + if (num > 0 && pfds[count].revents != 0 && num--) while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0) ; -@@ -1438,7 +1391,7 @@ struct thread *thread_fetch(struct threa +@@ -1700,7 +1653,7 @@ struct thread *thread_fetch(struct threa struct timeval zerotime = {0, 0}; struct timeval tv; struct timeval *tw = NULL; @@ -91,7 +91,7 @@ int num = 0; do { -@@ -1510,14 +1463,14 @@ struct thread *thread_fetch(struct threa +@@ -1776,14 +1729,14 @@ struct thread *thread_fetch(struct threa pthread_mutex_unlock(&m->mtx); {