frr: update to 8.1.0
authorLucian Cristian <lucian.cristian@gmail.com>
Fri, 12 Nov 2021 19:15:54 +0000 (21:15 +0200)
committerRosen Penev <rosenp@gmail.com>
Sat, 13 Nov 2021 01:20:37 +0000 (17:20 -0800)
Signed-off-by: Lucian Cristian <lucian.cristian@gmail.com>
13 files changed:
net/frr/Makefile
net/frr/files/daemons
net/frr/files/frrcommon.sh
net/frr/patches/046-nhrpd_cache_config_fixes.patch [deleted file]
net/frr/patches/047-nhrpd_fix_SA_warning.patch [deleted file]
net/frr/patches/048-nhrpd_cleanup_resources.patch [deleted file]
net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch [deleted file]
net/frr/patches/050-ospf_nbr_nbma_lookup_next.patch [deleted file]
net/frr/patches/051-ospfd_instance_fixes.patch [deleted file]
net/frr/patches/052-nhrpd_support_for_multicast.patch [deleted file]
net/frr/patches/053-nhrpd_replace_socket.patch [deleted file]
net/frr/patches/098-fix_mips_libyang.patch
net/frr/patches/999-thread_reverse.patch

index 4fd4163cc2fb13481dbc3cbe899b77c22c12bc68..ea1b76f3b9669a7ffd482925e7673c04bdbf12ae 100644 (file)
@@ -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 <lucian.cristian@gmail.com>
 
 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,))
index ac39e25b5a62ea3c08c79f10d46abf28da2731ac..0005da4e3d6f59c791ce306f32c77c56e72cebb3 100644 (file)
@@ -13,6 +13,7 @@ nhrpd=no
 eigrpd=no
 babeld=no
 sharpd=no
+pathd=no
 pbrd=no
 bfdd=no
 fabricd=no
index 80822ceb8d1d5f5f7b387426c5cf2e42928f2a4e..f59fce8730f51c861d22c55dab6eb2c0858bf6d3 100644 (file)
@@ -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 (file)
index 1c07ab7..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-From fef2ed139d140f551cdfcbb21c5a023dea2e02cb Mon Sep 17 00:00:00 2001
-From: Philippe Guibert <philippe.guibert@6wind.com>
-Date: Thu, 26 Mar 2020 17:33:53 +0100
-Subject: [PATCH] nhrpd: cache config may disappear if iface not present at
- startup
-
-When interface not present at config time, store separately the list of
-config parameters. Then, when interface is ready and an address has been configured, the nbma setting is done. Reversely, when interface disappears,
-there is no need to keep the maps present, then keep only the configuration.
-
-Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
----
- nhrpd/nhrp_cache.c     | 86 ++++++++++++++++++++++++++++++++++++++++++
- nhrpd/nhrp_interface.c | 63 ++++++++++++++++++++++++++++++-
- nhrpd/nhrp_vty.c       | 49 ++++++++++++++++--------
- nhrpd/nhrpd.h          | 14 +++++++
- 4 files changed, 195 insertions(+), 17 deletions(-)
-
---- a/nhrpd/nhrp_cache.c
-+++ b/nhrpd/nhrp_cache.c
-@@ -16,6 +16,7 @@
- #include "netlink.h"
- DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE, "NHRP cache entry")
-+DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE_CONFIG, "NHRP cache config entry")
- unsigned long nhrp_cache_counts[NHRP_CACHE_NUM_TYPES];
-@@ -77,6 +78,68 @@ static void nhrp_cache_free(struct nhrp_
-       XFREE(MTYPE_NHRP_CACHE, c);
- }
-+static unsigned int nhrp_cache_config_protocol_key(const void *peer_data)
-+{
-+      const struct nhrp_cache_config *p = peer_data;
-+      return sockunion_hash(&p->remote_addr);
-+}
-+
-+static bool nhrp_cache_config_protocol_cmp(const void *cache_data,
-+                                         const void *key_data)
-+{
-+      const struct nhrp_cache_config *a = cache_data;
-+      const struct nhrp_cache_config *b = key_data;
-+
-+      if (!sockunion_same(&a->remote_addr, &b->remote_addr))
-+              return false;
-+      if (a->ifp != b->ifp)
-+              return false;
-+      return true;
-+}
-+
-+static void *nhrp_cache_config_alloc(void *data)
-+{
-+      struct nhrp_cache_config *p, *key = data;
-+
-+      p = XCALLOC(MTYPE_NHRP_CACHE_CONFIG, sizeof(struct nhrp_cache_config));
-+
-+      *p = (struct nhrp_cache_config){
-+              .remote_addr = key->remote_addr,
-+              .ifp = key->ifp,
-+      };
-+      return p;
-+}
-+
-+void nhrp_cache_config_free(struct nhrp_cache_config *c)
-+{
-+      struct nhrp_interface *nifp = c->ifp->info;
-+
-+      hash_release(nifp->cache_config_hash, c);
-+      XFREE(MTYPE_NHRP_CACHE_CONFIG, c);
-+}
-+
-+struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
-+                                              union sockunion *remote_addr,
-+                                              int create)
-+{
-+      struct nhrp_interface *nifp = ifp->info;
-+      struct nhrp_cache_config key;
-+
-+      if (!nifp->cache_config_hash) {
-+              nifp->cache_config_hash =
-+                      hash_create(nhrp_cache_config_protocol_key,
-+                                  nhrp_cache_config_protocol_cmp,
-+                                  "NHRP Config Cache");
-+              if (!nifp->cache_config_hash)
-+                      return NULL;
-+      }
-+      key.remote_addr = *remote_addr;
-+      key.ifp = ifp;
-+
-+      return hash_get(nifp->cache_config_hash, &key,
-+                      create ? nhrp_cache_config_alloc : NULL);
-+}
-+
- struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
-                                 union sockunion *remote_addr, int create)
- {
-@@ -423,12 +486,23 @@ struct nhrp_cache_iterator_ctx {
-       void *ctx;
- };
-+struct nhrp_cache_config_iterator_ctx {
-+      void (*cb)(struct nhrp_cache_config *, void *);
-+      void *ctx;
-+};
-+
- static void nhrp_cache_iterator(struct hash_bucket *b, void *ctx)
- {
-       struct nhrp_cache_iterator_ctx *ic = ctx;
-       ic->cb(b->data, ic->ctx);
- }
-+static void nhrp_cache_config_iterator(struct hash_bucket *b, void *ctx)
-+{
-+      struct nhrp_cache_config_iterator_ctx *ic = ctx;
-+      ic->cb(b->data, ic->ctx);
-+}
-+
- void nhrp_cache_foreach(struct interface *ifp,
-                       void (*cb)(struct nhrp_cache *, void *), void *ctx)
- {
-@@ -441,6 +515,18 @@ void nhrp_cache_foreach(struct interface
-               hash_iterate(nifp->cache_hash, nhrp_cache_iterator, &ic);
- }
-+void nhrp_cache_config_foreach(struct interface *ifp,
-+                             void (*cb)(struct nhrp_cache_config *, void *), void *ctx)
-+{
-+      struct nhrp_interface *nifp = ifp->info;
-+      struct nhrp_cache_config_iterator_ctx ic = {
-+              .cb = cb, .ctx = ctx,
-+      };
-+
-+      if (nifp->cache_config_hash)
-+              hash_iterate(nifp->cache_config_hash, nhrp_cache_config_iterator, &ic);
-+}
-+
- void nhrp_cache_notify_add(struct nhrp_cache *c, struct notifier_block *n,
-                          notifier_fn_t fn)
- {
---- a/nhrpd/nhrp_interface.c
-+++ b/nhrpd/nhrp_interface.c
-@@ -23,6 +23,10 @@
- DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF, "NHRP interface")
-+static void nhrp_interface_update_cache_config(struct interface *ifp,
-+                                             bool available,
-+                                             uint8_t family);
-+
- static int nhrp_if_new_hook(struct interface *ifp)
- {
-       struct nhrp_interface *nifp;
-@@ -311,11 +315,68 @@ int nhrp_ifp_destroy(struct interface *i
- {
-       debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name);
-+      nhrp_interface_update_cache_config(ifp, false, AF_INET);
-+      nhrp_interface_update_cache_config(ifp, false, AF_INET6);
-       nhrp_interface_update(ifp);
-       return 0;
- }
-+struct map_ctx {
-+      int family;
-+      bool enabled;
-+};
-+
-+static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, void *data)
-+{
-+      struct map_ctx *ctx = data;
-+      struct interface *ifp = cc->ifp;
-+      struct nhrp_cache *c;
-+      union sockunion nbma_addr;
-+
-+      if (sockunion_family(&cc->remote_addr) != ctx->family)
-+              return;
-+
-+      /* gre layer not ready */
-+      if (ifp->vrf_id == VRF_UNKNOWN)
-+              return;
-+
-+      c = nhrp_cache_get(ifp, &cc->remote_addr, ctx->enabled ? 1 : 0);
-+      if (!c && !ctx->enabled)
-+              return;
-+      /* suppress */
-+      if (!ctx->enabled) {
-+              if (c && c->map) {
-+                      nhrp_cache_update_binding(c, c->cur.type, -1,
-+                                                nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
-+              }
-+              return;
-+      }
-+      /* create */
-+      c->map = 1;
-+      if (cc->type == NHRP_CACHE_LOCAL)
-+              nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
-+                                        NULL);
-+      else {
-+              nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
-+                                        nhrp_peer_get(ifp, &cc->nbma), 0,
-+                                        NULL);
-+      }
-+}
-+
-+static void nhrp_interface_update_cache_config(struct interface *ifp, bool available, uint8_t family)
-+{
-+      struct map_ctx mapctx;
-+
-+      mapctx = (struct map_ctx){
-+              .family = family,
-+              .enabled = available
-+      };
-+      nhrp_cache_config_foreach(ifp, interface_config_update_nhrp_map,
-+                                &mapctx);
-+
-+}
-+
- int nhrp_ifp_up(struct interface *ifp)
- {
-       debugf(NHRP_DEBUG_IF, "if-up: %s", ifp->name);
-@@ -346,7 +407,7 @@ int nhrp_interface_address_add(ZAPI_CALL
-       nhrp_interface_update_address(
-               ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
--
-+      nhrp_interface_update_cache_config(ifc->ifp, true, PREFIX_FAMILY(ifc->address));
-       return 0;
- }
---- a/nhrpd/nhrp_vty.c
-+++ b/nhrpd/nhrp_vty.c
-@@ -494,28 +494,42 @@ DEFUN(if_nhrp_map, if_nhrp_map_cmd,
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       afi_t afi = cmd_to_afi(argv[0]);
-       union sockunion proto_addr, nbma_addr;
-+      struct nhrp_cache_config *cc;
-       struct nhrp_cache *c;
-+      enum nhrp_cache_type type;
-       if (str2sockunion(argv[3]->arg, &proto_addr) < 0
-           || afi2family(afi) != sockunion_family(&proto_addr))
-               return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
-+      if (strmatch(argv[4]->text, "local"))
-+              type = NHRP_CACHE_LOCAL;
-+      else {
-+              if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
-+                      return nhrp_vty_return(vty, NHRP_ERR_FAIL);
-+              type = NHRP_CACHE_STATIC;
-+      }
-+      cc = nhrp_cache_config_get(ifp, &proto_addr, 1);
-+      if (!cc)
-+              return nhrp_vty_return(vty, NHRP_ERR_FAIL);
-+      cc->nbma = nbma_addr;
-+      cc->type = type;
-+      /* gre layer not ready */
-+      if (ifp->ifindex == IFINDEX_INTERNAL)
-+              return CMD_SUCCESS;
-+
-       c = nhrp_cache_get(ifp, &proto_addr, 1);
-       if (!c)
-               return nhrp_vty_return(vty, NHRP_ERR_FAIL);
-       c->map = 1;
--      if (strmatch(argv[4]->text, "local")) {
-+      if (type == NHRP_CACHE_LOCAL)
-               nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
-                                         NULL);
--      } else {
--              if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
--                      return nhrp_vty_return(vty, NHRP_ERR_FAIL);
-+      else
-               nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
-                                         nhrp_peer_get(ifp, &nbma_addr), 0,
-                                         NULL);
--      }
--
-       return CMD_SUCCESS;
- }
-@@ -533,15 +547,22 @@ DEFUN(if_no_nhrp_map, if_no_nhrp_map_cmd
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       afi_t afi = cmd_to_afi(argv[1]);
-       union sockunion proto_addr, nbma_addr;
-+      struct nhrp_cache_config *cc;
-       struct nhrp_cache *c;
-       if (str2sockunion(argv[4]->arg, &proto_addr) < 0
-           || afi2family(afi) != sockunion_family(&proto_addr))
-               return nhrp_vty_return(vty, NHRP_ERR_PROTOCOL_ADDRESS_MISMATCH);
-+      cc = nhrp_cache_config_get(ifp, &proto_addr, 0);
-+      if (!cc)
-+              return nhrp_vty_return(vty, NHRP_ERR_FAIL);
-+      nhrp_cache_config_free(cc);
-+
-       c = nhrp_cache_get(ifp, &proto_addr, 0);
-+      /* silently return */
-       if (!c || !c->map)
--              return nhrp_vty_return(vty, NHRP_ERR_ENTRY_NOT_FOUND);
-+              return CMD_SUCCESS;
-       nhrp_cache_update_binding(c, c->cur.type, -1,
-                                 nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
-@@ -997,23 +1018,19 @@ struct write_map_ctx {
-       const char *aficmd;
- };
--static void interface_config_write_nhrp_map(struct nhrp_cache *c, void *data)
-+static void interface_config_write_nhrp_map(struct nhrp_cache_config *c, void *data)
- {
-       struct write_map_ctx *ctx = data;
-       struct vty *vty = ctx->vty;
-       char buf[2][SU_ADDRSTRLEN];
--      if (!c->map)
--              return;
-       if (sockunion_family(&c->remote_addr) != ctx->family)
-               return;
-       vty_out(vty, " %s nhrp map %s %s\n", ctx->aficmd,
-               sockunion2str(&c->remote_addr, buf[0], sizeof(buf[0])),
--              c->cur.type == NHRP_CACHE_LOCAL
--                      ? "local"
--                      : sockunion2str(&c->cur.peer->vc->remote.nbma, buf[1],
--                                      sizeof(buf[1])));
-+              c->type == NHRP_CACHE_LOCAL
-+              ? "local" : sockunion2str(&c->nbma, buf[1], sizeof(buf[1])));
- }
- static int interface_config_write(struct vty *vty)
-@@ -1076,8 +1093,8 @@ static int interface_config_write(struct
-                               .family = afi2family(afi),
-                               .aficmd = aficmd,
-                       };
--                      nhrp_cache_foreach(ifp, interface_config_write_nhrp_map,
--                                         &mapctx);
-+                      nhrp_cache_config_foreach(ifp, interface_config_write_nhrp_map,
-+                                                &mapctx);
-                       list_for_each_entry(nhs, &ad->nhslist_head,
-                                           nhslist_entry)
---- a/nhrpd/nhrpd.h
-+++ b/nhrpd/nhrpd.h
-@@ -197,6 +197,13 @@ enum nhrp_cache_type {
- extern const char *const nhrp_cache_type_str[];
- extern unsigned long nhrp_cache_counts[NHRP_CACHE_NUM_TYPES];
-+struct nhrp_cache_config {
-+      struct interface *ifp;
-+      union sockunion remote_addr;
-+      enum nhrp_cache_type type;
-+      union sockunion nbma;
-+};
-+
- struct nhrp_cache {
-       struct interface *ifp;
-       union sockunion remote_addr;
-@@ -280,6 +287,7 @@ struct nhrp_interface {
-       uint32_t grekey;
-       struct hash *peer_hash;
-+      struct hash *cache_config_hash;
-       struct hash *cache_hash;
-       struct notifier_list notifier_list;
-@@ -358,10 +366,16 @@ void nhrp_shortcut_foreach(afi_t afi,
- void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force);
- void nhrp_shortcut_prefix_change(const struct prefix *p, int deleted);
-+void nhrp_cache_config_free(struct nhrp_cache_config *c);
-+struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
-+                                              union sockunion *remote_addr,
-+                                              int create);
- struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
-                                 union sockunion *remote_addr, int create);
- void nhrp_cache_foreach(struct interface *ifp,
-                       void (*cb)(struct nhrp_cache *, void *), void *ctx);
-+void nhrp_cache_config_foreach(struct interface *ifp,
-+                             void (*cb)(struct nhrp_cache_config *, void *), void *ctx);
- void nhrp_cache_set_used(struct nhrp_cache *, int);
- int nhrp_cache_update_binding(struct nhrp_cache *, enum nhrp_cache_type type,
-                             int holding_time, struct nhrp_peer *p,
diff --git a/net/frr/patches/047-nhrpd_fix_SA_warning.patch b/net/frr/patches/047-nhrpd_fix_SA_warning.patch
deleted file mode 100644 (file)
index fdf78a5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From e5773617afba7408c76ec2683814ce076c72c79d Mon Sep 17 00:00:00 2001
-From: Mark Stapp <mjs@voltanet.io>
-Date: Tue, 8 Dec 2020 09:10:10 -0500
-Subject: [PATCH] nhrpd: fix SA warning in nhrp_interface
-
-Clear SA warning from recent nhrp cache code changes.
-
-Signed-off-by: Mark Stapp <mjs@voltanet.io>
----
- nhrpd/nhrp_interface.c | 14 ++++++++++----
- 1 file changed, 10 insertions(+), 4 deletions(-)
-
---- a/nhrpd/nhrp_interface.c
-+++ b/nhrpd/nhrp_interface.c
-@@ -327,7 +327,8 @@ struct map_ctx {
-       bool enabled;
- };
--static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, void *data)
-+static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc,
-+                                           void *data)
- {
-       struct map_ctx *ctx = data;
-       struct interface *ifp = cc->ifp;
-@@ -344,15 +345,20 @@ static void interface_config_update_nhrp
-       c = nhrp_cache_get(ifp, &cc->remote_addr, ctx->enabled ? 1 : 0);
-       if (!c && !ctx->enabled)
-               return;
-+
-       /* suppress */
-       if (!ctx->enabled) {
-               if (c && c->map) {
--                      nhrp_cache_update_binding(c, c->cur.type, -1,
--                                                nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
-+                      nhrp_cache_update_binding(
-+                              c, c->cur.type, -1,
-+                              nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
-               }
-               return;
-       }
--      /* create */
-+
-+      /* Newly created */
-+      assert(c != NULL);
-+
-       c->map = 1;
-       if (cc->type == NHRP_CACHE_LOCAL)
-               nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
diff --git a/net/frr/patches/048-nhrpd_cleanup_resources.patch b/net/frr/patches/048-nhrpd_cleanup_resources.patch
deleted file mode 100644 (file)
index 5eafe61..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-From ee72f0a0eb93038ef6dfd01fed9f32e24c5de2a1 Mon Sep 17 00:00:00 2001
-From: Reuben Dowle <reuben.dowle@4rf.com>
-Date: Mon, 7 Dec 2020 16:35:13 +1300
-Subject: [PATCH] nhrpd: Cleanup resources when interface is deleted
-
-Currently when an interface is deleted from configuration, associated
-resources are not freed. This causes memory leaks and crashes.
-
-To reproduce this issue:
-* Connect to a DMVPN hub
-* Outside of frr, delete the underlying GRE interface
-* Use 'no interface xxx' to delete the interface containing nhrp configurations
-
-Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
----
- nhrpd/nhrp_cache.c     | 42 ++++++++++++++++++++++++++++++++++++++++--
- nhrpd/nhrp_interface.c | 15 +++++++++++++++
- nhrpd/nhrp_nhs.c       | 18 ++++++++++++++++++
- nhrpd/nhrp_peer.c      | 27 +++++++++++++++++++++++++++
- nhrpd/nhrpd.h          |  3 +++
- 5 files changed, 103 insertions(+), 2 deletions(-)
- mode change 100644 => 100755 nhrpd/nhrp_cache.c
- mode change 100644 => 100755 nhrpd/nhrp_interface.c
- mode change 100644 => 100755 nhrpd/nhrpd.h
-
---- a/nhrpd/nhrp_cache.c
-+++ b/nhrpd/nhrp_cache.c
-@@ -69,12 +69,13 @@ static void nhrp_cache_free(struct nhrp_
- {
-       struct nhrp_interface *nifp = c->ifp->info;
--      zassert(c->cur.type == NHRP_CACHE_INVALID && c->cur.peer == NULL);
--      zassert(c->new.type == NHRP_CACHE_INVALID && c->new.peer == NULL);
-+      debugf(NHRP_DEBUG_COMMON, "Deleting cache entry");
-       nhrp_cache_counts[c->cur.type]--;
-       notifier_call(&c->notifier_list, NOTIFY_CACHE_DELETE);
-       zassert(!notifier_active(&c->notifier_list));
-       hash_release(nifp->cache_hash, c);
-+      THREAD_OFF(c->t_timeout);
-+      THREAD_OFF(c->t_auth);
-       XFREE(MTYPE_NHRP_CACHE, c);
- }
-@@ -140,6 +141,41 @@ struct nhrp_cache_config *nhrp_cache_con
-                       create ? nhrp_cache_config_alloc : NULL);
- }
-+static void do_nhrp_cache_free(struct hash_bucket *hb,
-+                             void *arg __attribute__((__unused__)))
-+{
-+      struct nhrp_cache *c = hb->data;
-+
-+      nhrp_cache_free(c);
-+}
-+
-+static void do_nhrp_cache_config_free(struct hash_bucket *hb,
-+                                    void *arg __attribute__((__unused__)))
-+{
-+      struct nhrp_cache_config *cc = hb->data;
-+
-+      nhrp_cache_config_free(cc);
-+}
-+
-+void nhrp_cache_interface_del(struct interface *ifp)
-+{
-+      struct nhrp_interface *nifp = ifp->info;
-+
-+      debugf(NHRP_DEBUG_COMMON, "Cleaning up undeleted cache entries (%lu)",
-+             nifp->cache_hash ? nifp->cache_hash->count : 0);
-+
-+      if (nifp->cache_hash) {
-+              hash_iterate(nifp->cache_hash, do_nhrp_cache_free, NULL);
-+              hash_free(nifp->cache_hash);
-+      }
-+
-+      if (nifp->cache_config_hash) {
-+              hash_iterate(nifp->cache_config_hash, do_nhrp_cache_config_free,
-+                           NULL);
-+              hash_free(nifp->cache_config_hash);
-+      }
-+}
-+
- struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
-                                 union sockunion *remote_addr, int create)
- {
-@@ -164,6 +200,7 @@ struct nhrp_cache *nhrp_cache_get(struct
- static int nhrp_cache_do_free(struct thread *t)
- {
-       struct nhrp_cache *c = THREAD_ARG(t);
-+
-       c->t_timeout = NULL;
-       nhrp_cache_free(c);
-       return 0;
-@@ -172,6 +209,7 @@ static int nhrp_cache_do_free(struct thr
- static int nhrp_cache_do_timeout(struct thread *t)
- {
-       struct nhrp_cache *c = THREAD_ARG(t);
-+
-       c->t_timeout = NULL;
-       if (c->cur.type != NHRP_CACHE_INVALID)
-               nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL);
---- a/nhrpd/nhrp_interface.c
-+++ b/nhrpd/nhrp_interface.c
-@@ -49,6 +49,21 @@ static int nhrp_if_new_hook(struct inter
- static int nhrp_if_delete_hook(struct interface *ifp)
- {
-+      struct nhrp_interface *nifp = ifp->info;
-+
-+      debugf(NHRP_DEBUG_IF, "Deleted interface (%s)", ifp->name);
-+
-+      nhrp_cache_interface_del(ifp);
-+      nhrp_nhs_interface_del(ifp);
-+      nhrp_peer_interface_del(ifp);
-+
-+      if (nifp->ipsec_profile)
-+              free(nifp->ipsec_profile);
-+      if (nifp->ipsec_fallback_profile)
-+              free(nifp->ipsec_fallback_profile);
-+      if (nifp->source)
-+              free(nifp->source);
-+
-       XFREE(MTYPE_NHRP_IF, ifp->info);
-       return 0;
- }
---- a/nhrpd/nhrp_nhs.c
-+++ b/nhrpd/nhrp_nhs.c
-@@ -378,6 +378,24 @@ int nhrp_nhs_free(struct nhrp_nhs *nhs)
-       return 0;
- }
-+void nhrp_nhs_interface_del(struct interface *ifp)
-+{
-+      struct nhrp_interface *nifp = ifp->info;
-+      struct nhrp_nhs *nhs, *tmp;
-+      afi_t afi;
-+
-+      for (afi = 0; afi < AFI_MAX; afi++) {
-+              debugf(NHRP_DEBUG_COMMON, "Cleaning up nhs entries (%d)",
-+                     !list_empty(&nifp->afi[afi].nhslist_head));
-+
-+              list_for_each_entry_safe(nhs, tmp, &nifp->afi[afi].nhslist_head,
-+                                       nhslist_entry)
-+              {
-+                      nhrp_nhs_free(nhs);
-+              }
-+      }
-+}
-+
- void nhrp_nhs_terminate(void)
- {
-       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
---- a/nhrpd/nhrp_peer.c
-+++ b/nhrpd/nhrp_peer.c
-@@ -38,11 +38,17 @@ static void nhrp_packet_debug(struct zbu
- static void nhrp_peer_check_delete(struct nhrp_peer *p)
- {
-+      char buf[2][256];
-       struct nhrp_interface *nifp = p->ifp->info;
-       if (p->ref || notifier_active(&p->notifier_list))
-               return;
-+      debugf(NHRP_DEBUG_COMMON, "Deleting peer ref:%d remote:%s local:%s",
-+             p->ref,
-+             sockunion2str(&p->vc->remote.nbma, buf[0], sizeof(buf[0])),
-+             sockunion2str(&p->vc->local.nbma, buf[1], sizeof(buf[1])));
-+
-       THREAD_OFF(p->t_fallback);
-       hash_release(nifp->peer_hash, p);
-       nhrp_interface_notify_del(p->ifp, &p->ifp_notifier);
-@@ -185,6 +191,27 @@ static void *nhrp_peer_create(void *data
-       return p;
- }
-+static void do_peer_hash_free(struct hash_bucket *hb,
-+                            void *arg __attribute__((__unused__)))
-+{
-+      struct nhrp_peer *p = hb->data;
-+      nhrp_peer_check_delete(p);
-+}
-+
-+void nhrp_peer_interface_del(struct interface *ifp)
-+{
-+      struct nhrp_interface *nifp = ifp->info;
-+
-+      debugf(NHRP_DEBUG_COMMON, "Cleaning up undeleted peer entries (%lu)",
-+             nifp->peer_hash ? nifp->peer_hash->count : 0);
-+
-+      if (nifp->peer_hash) {
-+              hash_iterate(nifp->peer_hash, do_peer_hash_free, NULL);
-+              assert(nifp->peer_hash->count == 0);
-+              hash_free(nifp->peer_hash);
-+      }
-+}
-+
- struct nhrp_peer *nhrp_peer_get(struct interface *ifp,
-                               const union sockunion *remote_nbma)
- {
---- a/nhrpd/nhrpd.h
-+++ b/nhrpd/nhrpd.h
-@@ -343,6 +343,7 @@ void nhrp_nhs_foreach(struct interface *
-                     void (*cb)(struct nhrp_nhs *, struct nhrp_registration *,
-                                void *),
-                     void *ctx);
-+void nhrp_nhs_interface_del(struct interface *ifp);
- void nhrp_route_update_nhrp(const struct prefix *p, struct interface *ifp);
- void nhrp_route_announce(int add, enum nhrp_cache_type type,
-@@ -366,6 +367,7 @@ void nhrp_shortcut_foreach(afi_t afi,
- void nhrp_shortcut_purge(struct nhrp_shortcut *s, int force);
- void nhrp_shortcut_prefix_change(const struct prefix *p, int deleted);
-+void nhrp_cache_interface_del(struct interface *ifp);
- void nhrp_cache_config_free(struct nhrp_cache_config *c);
- struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
-                                               union sockunion *remote_addr,
-@@ -446,6 +448,7 @@ struct nhrp_reqid *nhrp_reqid_lookup(str
- int nhrp_packet_init(void);
-+void nhrp_peer_interface_del(struct interface *ifp);
- struct nhrp_peer *nhrp_peer_get(struct interface *ifp,
-                               const union sockunion *remote_nbma);
- struct nhrp_peer *nhrp_peer_ref(struct nhrp_peer *p);
diff --git a/net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch b/net/frr/patches/049-clear_ip_ospf_process_and_neighbor.patch
deleted file mode 100644 (file)
index 8e02baa..0000000
+++ /dev/null
@@ -1,383 +0,0 @@
-From f91ce319d3cdb465df54ff4e091dbd4aed85b24c Mon Sep 17 00:00:00 2001
-From: Mobashshera Rasool <mrasool@vmware.com>
-Date: Wed, 23 Dec 2020 13:20:22 +0000
-Subject: [PATCH] ospfd: Clear ip ospf process and clear ip ospf neighbor
-
-Implement the below 2 CLIs to clear the current data in the process
-and neighbor data structure.
-1. clear ip ospf process
-2. clear ip ospf neighbor
-
-Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
----
- doc/user/ospfd.rst | 17 ++++++++
- ospfd/ospf_ase.c   |  1 +
- ospfd/ospf_lsa.c   | 13 +++++-
- ospfd/ospf_vty.c   | 72 +++++++++++++++++++++++++++++++--
- ospfd/ospfd.c      | 99 ++++++++++++++++++++++++++++++++++++----------
- ospfd/ospfd.h      |  5 +++
- 6 files changed, 182 insertions(+), 25 deletions(-)
-
---- a/doc/user/ospfd.rst
-+++ b/doc/user/ospfd.rst
-@@ -322,6 +322,23 @@ To start OSPF process you have to specif
-    This feature is enabled by default.
-+.. index:: clear ip ospf [(1-65535)] process
-+.. clicmd:: clear ip ospf [(1-65535)] process
-+
-+   This command can be used to clear the ospf process data structures. This
-+   will clear the ospf neighborship as well and it will get re-established.
-+   This will clear the LSDB too. This will be helpful when there is a change
-+   in router-id and if user wants the router-id change to take effect, user can
-+   use this cli instead of restarting the ospfd daemon.
-+
-+.. index:: clear ip ospf [(1-65535)] neighbor
-+.. clicmd:: clear ip ospf [(1-65535)] neighbor
-+
-+   This command can be used to clear the ospf neighbor data structures. This
-+   will clear the ospf neighborship and it will get re-established. This
-+   command can be used when the neighbor state get stuck at some state and
-+   this can be used to recover it from that state.
-+
- .. _ospf-area:
- Areas
---- a/ospfd/ospf_ase.c
-+++ b/ospfd/ospf_ase.c
-@@ -753,6 +753,7 @@ void ospf_ase_unregister_external_lsa(st
-               lst = rn->info;
-               listnode_delete(lst, lsa);
-               ospf_lsa_unlock(&lsa); /* external_lsas list */
-+
-               route_unlock_node(rn);
-       }
- }
---- a/ospfd/ospf_lsa.c
-+++ b/ospfd/ospf_lsa.c
-@@ -2735,7 +2735,7 @@ int ospf_check_nbr_status(struct ospf *o
- static int ospf_maxage_lsa_remover(struct thread *thread)
- {
-       struct ospf *ospf = THREAD_ARG(thread);
--      struct ospf_lsa *lsa;
-+      struct ospf_lsa *lsa, *old;
-       struct route_node *rn;
-       int reschedule = 0;
-@@ -2797,6 +2797,17 @@ static int ospf_maxage_lsa_remover(struc
-                       /* Remove from lsdb. */
-                       if (lsa->lsdb) {
-+                              old = ospf_lsdb_lookup(lsa->lsdb, lsa);
-+                              /* The max age LSA here must be the same
-+                               * as the LSA in LSDB
-+                               */
-+                              if (old != lsa) {
-+                                      flog_err(EC_OSPF_LSA_MISSING,
-+                                      "%s: LSA[Type%d:%s]: LSA not in LSDB",
-+                                      __func__, lsa->data->type,
-+                                      inet_ntoa(lsa->data->id));
-+                                      continue;
-+                              }
-                               ospf_discard_from_db(ospf, lsa->lsdb, lsa);
-                               ospf_lsdb_delete(lsa->lsdb, lsa);
-                       } else {
---- a/ospfd/ospf_vty.c
-+++ b/ospfd/ospf_vty.c
-@@ -276,7 +276,7 @@ DEFPY (ospf_router_id,
-       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
-               if (area->full_nbrs) {
-                       vty_out(vty,
--                              "For this router-id change to take effect, save config and restart ospfd\n");
-+                              "For this router-id change to take effect, use “clear ip ospf process” command\n");
-                       return CMD_SUCCESS;
-               }
-@@ -309,7 +309,7 @@ DEFUN_HIDDEN (ospf_router_id_old,
-       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
-               if (area->full_nbrs) {
-                       vty_out(vty,
--                              "For this router-id change to take effect, save config and restart ospfd\n");
-+                              "For this router-id change to take effect, use “clear ip ospf process” command\n");
-                       return CMD_SUCCESS;
-               }
-@@ -342,7 +342,7 @@ DEFPY (no_ospf_router_id,
-       for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
-               if (area->full_nbrs) {
-                       vty_out(vty,
--                              "For this router-id change to take effect, save config and restart ospfd\n");
-+                              "For this router-id change to take effect, use “clear ip ospf process” command\n");
-                       return CMD_SUCCESS;
-               }
-@@ -9769,6 +9769,70 @@ DEFUN (show_ip_ospf_vrfs,
-       return CMD_SUCCESS;
- }
-+DEFPY (clear_ip_ospf_neighbor,
-+       clear_ip_ospf_neighbor_cmd,
-+       "clear ip ospf [(1-65535)]$instance neighbor [A.B.C.D$nbr_id]",
-+       CLEAR_STR
-+       IP_STR
-+       "OSPF information\n"
-+       "Instance ID\n"
-+       "Reset OSPF Neighbor\n"
-+       "Neighbor ID\n")
-+{
-+      struct listnode *node;
-+      struct ospf *ospf = NULL;
-+
-+      /* If user does not specify the arguments,
-+       * instance = 0 and nbr_id = 0.0.0.0
-+       */
-+      if (instance != 0) {
-+              /* This means clear only the particular ospf process */
-+              ospf = ospf_lookup_instance(instance);
-+              if (ospf == NULL)
-+                      return CMD_NOT_MY_INSTANCE;
-+      }
-+
-+      /* Clear all the ospf processes */
-+      for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-+              if (!ospf->oi_running)
-+                      continue;
-+
-+              ospf_neighbor_reset(ospf, nbr_id, nbr_id_str);
-+      }
-+
-+      return CMD_SUCCESS;
-+}
-+
-+DEFPY (clear_ip_ospf_process,
-+       clear_ip_ospf_process_cmd,
-+       "clear ip ospf [(1-65535)]$instance process",
-+       CLEAR_STR
-+       IP_STR
-+       "OSPF information\n"
-+       "Instance ID\n"
-+       "Reset OSPF Process\n")
-+{
-+      struct listnode *node;
-+      struct ospf *ospf = NULL;
-+
-+      /* Check if instance is not passed as an argument */
-+      if (instance != 0) {
-+              /* This means clear only the particular ospf process */
-+              ospf = ospf_lookup_instance(instance);
-+              if (ospf == NULL)
-+                      return CMD_NOT_MY_INSTANCE;
-+      }
-+
-+      /* Clear all the ospf processes */
-+      for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
-+              if (!ospf->oi_running)
-+                      continue;
-+
-+              ospf_process_reset(ospf);
-+      }
-+
-+      return CMD_SUCCESS;
-+}
- static const char *const ospf_abr_type_str[] = {
-       "unknown", "standard", "ibm", "cisco", "shortcut"
-@@ -10806,6 +10870,8 @@ DEFUN (clear_ip_ospf_interface,
- void ospf_vty_clear_init(void)
- {
-       install_element(ENABLE_NODE, &clear_ip_ospf_interface_cmd);
-+      install_element(ENABLE_NODE, &clear_ip_ospf_process_cmd);
-+      install_element(ENABLE_NODE, &clear_ip_ospf_neighbor_cmd);
- }
---- a/ospfd/ospfd.c
-+++ b/ospfd/ospfd.c
-@@ -84,13 +84,15 @@ static void ospf_finish_final(struct osp
- #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
--void ospf_router_id_update(struct ospf *ospf)
-+void ospf_process_refresh_data(struct ospf *ospf, bool reset)
- {
-       struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
-       struct in_addr router_id, router_id_old;
-       struct ospf_interface *oi;
-       struct interface *ifp;
--      struct listnode *node;
-+      struct listnode *node, *nnode;
-+      struct ospf_area *area;
-+      bool rid_change = false;
-       if (!ospf->oi_running) {
-               if (IS_DEBUG_OSPF_EVENT)
-@@ -123,8 +125,8 @@ void ospf_router_id_update(struct ospf *
-               zlog_debug("Router-ID[OLD:%s]: Update to %s",
-                          inet_ntoa(ospf->router_id), inet_ntoa(router_id));
--      if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
--
-+      rid_change = !(IPV4_ADDR_SAME(&router_id_old, &router_id));
-+      if (rid_change || (reset)) {
-               for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
-                       /* Some nbrs are identified by router_id, these needs
-                        * to be rebuilt. Possible optimization would be to do
-@@ -146,16 +148,8 @@ void ospf_router_id_update(struct ospf *
-                               ospf_if_up(oi);
-               }
--              /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF
--               * flag */
--              if (ospf->lsdb) {
--                      struct route_node *rn;
--                      struct ospf_lsa *lsa;
--
--                      LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
--                              if (IS_LSA_SELF(lsa))
--                                      ospf_lsa_flush_schedule(ospf, lsa);
--              }
-+              /* Flush (inline) all the self originated LSAs */
-+              ospf_flush_self_originated_lsas_now(ospf);
-               ospf->router_id = router_id;
-               if (IS_DEBUG_OSPF_EVENT)
-@@ -180,24 +174,81 @@ void ospf_router_id_update(struct ospf *
-                       LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa) {
-                               /* AdvRouter and Router ID is the same. */
-                               if (IPV4_ADDR_SAME(&lsa->data->adv_router,
--                                                 &ospf->router_id)) {
-+                                      &ospf->router_id) && rid_change) {
-                                       SET_FLAG(lsa->flags,
-                                                OSPF_LSA_SELF_CHECKED);
-                                       SET_FLAG(lsa->flags, OSPF_LSA_SELF);
-                                       ospf_lsa_flush_schedule(ospf, lsa);
-                               }
-+                              /* The above flush will send immediately
-+                               * So discard the LSA to originate new
-+                               */
-+                              ospf_discard_from_db(ospf, ospf->lsdb, lsa);
-                       }
-+
-+                      LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
-+                              ospf_discard_from_db(ospf, ospf->lsdb, lsa);
-+
-+                      ospf_lsdb_delete_all(ospf->lsdb);
-               }
-+              /* Delete the LSDB */
-+              for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area))
-+                      ospf_area_lsdb_discard_delete(area);
-+
-               /* update router-lsa's for each area */
-               ospf_router_lsa_update(ospf);
-               /* update ospf_interface's */
--              FOR_ALL_INTERFACES (vrf, ifp)
--                      ospf_if_update(ospf, ifp);
-+              FOR_ALL_INTERFACES (vrf, ifp) {
-+                      if (reset)
-+                              ospf_if_reset(ifp);
-+                      else
-+                              ospf_if_update(ospf, ifp);
-+              }
-               ospf_external_lsa_rid_change(ospf);
-       }
-+
-+      ospf->inst_shutdown = 0;
-+}
-+
-+void ospf_router_id_update(struct ospf *ospf)
-+{
-+      ospf_process_refresh_data(ospf, false);
-+}
-+
-+void ospf_process_reset(struct ospf *ospf)
-+{
-+      ospf_process_refresh_data(ospf, true);
-+}
-+
-+void ospf_neighbor_reset(struct ospf *ospf, struct in_addr nbr_id,
-+                      const char *nbr_str)
-+{
-+      struct route_node *rn;
-+      struct ospf_neighbor *nbr;
-+      struct ospf_interface *oi;
-+      struct listnode *node;
-+
-+      /* Clear only a particular nbr with nbr router id as nbr_id */
-+      if (nbr_str != NULL) {
-+              for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
-+                      nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, &nbr_id);
-+                      if (nbr)
-+                              OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
-+              }
-+              return;
-+      }
-+
-+      /* send Neighbor event KillNbr to all associated neighbors. */
-+      for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
-+              for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
-+                      nbr = rn->info;
-+                      if (nbr && (nbr != oi->nbr_self))
-+                              OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
-+              }
-+      }
- }
- /* For OSPF area sort by area id. */
-@@ -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 (file)
index 96e7ab7..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-From 153bdb3d03542530ed1deccbefc716cb4b699a67 Mon Sep 17 00:00:00 2001
-From: Donald Sharp <sharpd@nvidia.com>
-Date: Thu, 28 Jan 2021 14:56:11 -0500
-Subject: [PATCH] ospfd: ospf_nbr_nbma_lookup_next always returns NULL
-
-The calling function of ospf_nbr_nbma_lookup_next calls
-this function and then immediately returns when it
-gets the NULL.  Just cleanup a bit more code.
-
-Signed-off-by: Donald Sharp <sharpd@nvidia.com>
----
- ospfd/ospf_snmp.c | 23 +----------------------
- ospfd/ospfd.c     |  9 ---------
- ospfd/ospfd.h     |  2 --
- 3 files changed, 1 insertion(+), 33 deletions(-)
-
---- a/ospfd/ospf_snmp.c
-+++ b/ospfd/ospf_snmp.c
-@@ -1236,7 +1236,6 @@ static struct ospf_nbr_nbma *ospfHostLoo
-                                           size_t *length,
-                                           struct in_addr *addr, int exact)
- {
--      int len;
-       struct ospf_nbr_nbma *nbr_nbma;
-       struct ospf *ospf;
-@@ -1258,28 +1257,8 @@ static struct ospf_nbr_nbma *ospfHostLoo
-               nbr_nbma = ospf_nbr_nbma_lookup(ospf, *addr);
-               return nbr_nbma;
--      } else {
--              len = *length - v->namelen;
--              if (len > 4)
--                      len = 4;
--
--              oid2in_addr(name + v->namelen, len, addr);
--
--              nbr_nbma =
--                      ospf_nbr_nbma_lookup_next(ospf, addr, len == 0 ? 1 : 0);
--
--              if (nbr_nbma == NULL)
--                      return NULL;
--
--              oid_copy_addr(name + v->namelen, addr, IN_ADDR_SIZE);
--
--              /* Set TOS 0. */
--              name[v->namelen + IN_ADDR_SIZE] = 0;
--
--              *length = v->namelen + IN_ADDR_SIZE + 1;
--
--              return nbr_nbma;
-       }
-+
-       return NULL;
- }
---- a/ospfd/ospfd.c
-+++ b/ospfd/ospfd.c
-@@ -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 (file)
index eb3b17c..0000000
+++ /dev/null
@@ -1,797 +0,0 @@
-From 409f98ab443682ec360e3e76954f1c8985b3371d Mon Sep 17 00:00:00 2001
-From: Igor Ryzhov <iryzhov@nfware.com>
-Date: Thu, 28 Jan 2021 02:41:07 +0300
-Subject: [PATCH 1/2] ospfd: don't rely on instance existence in vty
-
-Store instance index at startup and use it when processing vty commands.
-The instance itself may be created and deleted by the user in runtime
-using `[no] router ospf X` command.
-
-Fixes #7908
-
-Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
----
- ospfd/ospf_dump.c |  70 ++++++---------
- ospfd/ospf_main.c |  20 +----
- ospfd/ospf_vty.c  | 220 +++++++++++++++++++++++-----------------------
- ospfd/ospfd.c     |  26 +++---
- ospfd/ospfd.h     |   3 +-
- 5 files changed, 154 insertions(+), 185 deletions(-)
-
---- a/ospfd/ospf_dump.c
-+++ b/ospfd/ospf_dump.c
-@@ -607,7 +607,7 @@ DEFUN (debug_ospf_packet,
-       if (inst) // user passed instance ID
-       {
--              if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10)))
-+              if (inst != ospf_instance)
-                       return CMD_NOT_MY_INSTANCE;
-       }
-@@ -683,7 +683,7 @@ DEFUN (no_debug_ospf_packet,
-       if (inst) // user passed instance ID
-       {
--              if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10)))
-+              if (inst != ospf_instance)
-                       return CMD_NOT_MY_INSTANCE;
-       }
-@@ -754,7 +754,7 @@ DEFUN (debug_ospf_ism,
-       if (inst) // user passed instance ID
-       {
--              if (!ospf_lookup_instance(strtoul(argv[2]->arg, NULL, 10)))
-+              if (inst != ospf_instance)
-                       return CMD_NOT_MY_INSTANCE;
-       }
-@@ -805,7 +805,7 @@ DEFUN (no_debug_ospf_ism,
-       if (inst) // user passed instance ID
-       {
--              if (!ospf_lookup_instance(strtoul(argv[3]->arg, NULL, 10)))
-+              if (inst != ospf_instance)
-                       return CMD_NOT_MY_INSTANCE;
-       }
-@@ -900,8 +900,8 @@ DEFUN (debug_ospf_instance_nsm,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-       return debug_ospf_nsm_common(vty, 4, argc, argv);
- }
-@@ -972,7 +972,7 @@ DEFUN (no_debug_ospf_instance_nsm,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
-+      if (instance != ospf_instance)
-               return CMD_NOT_MY_INSTANCE;
-       return no_debug_ospf_nsm_common(vty, 5, argc, argv);
-@@ -1046,7 +1046,7 @@ DEFUN (debug_ospf_instance_lsa,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
-+      if (instance != ospf_instance)
-               return CMD_NOT_MY_INSTANCE;
-       return debug_ospf_lsa_common(vty, 4, argc, argv);
-@@ -1122,7 +1122,7 @@ DEFUN (no_debug_ospf_instance_lsa,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
-+      if (instance != ospf_instance)
-               return CMD_NOT_MY_INSTANCE;
-       return no_debug_ospf_lsa_common(vty, 5, argc, argv);
-@@ -1184,7 +1184,7 @@ DEFUN (debug_ospf_instance_zebra,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
-+      if (instance != ospf_instance)
-               return CMD_NOT_MY_INSTANCE;
-       return debug_ospf_zebra_common(vty, 4, argc, argv);
-@@ -1248,8 +1248,8 @@ DEFUN (no_debug_ospf_instance_zebra,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-       return no_debug_ospf_zebra_common(vty, 5, argc, argv);
- }
-@@ -1294,8 +1294,8 @@ DEFUN (debug_ospf_instance_event,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(event, EVENT);
-@@ -1316,8 +1316,8 @@ DEFUN (no_debug_ospf_instance_event,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(event, EVENT);
-@@ -1364,8 +1364,8 @@ DEFUN (debug_ospf_instance_nssa,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_ON(nssa, NSSA);
-@@ -1386,8 +1386,8 @@ DEFUN (no_debug_ospf_instance_nssa,
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if (!ospf_lookup_instance(instance))
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-       if (vty->node == CONFIG_NODE)
-               CONF_DEBUG_OFF(nssa, NSSA);
-@@ -1536,12 +1536,12 @@ DEFUN (no_debug_ospf,
-       return CMD_SUCCESS;
- }
--static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf)
-+static int show_debugging_ospf_common(struct vty *vty)
- {
-       int i;
--      if (ospf->instance)
--              vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
-+      if (ospf_instance)
-+              vty_out(vty, "\nOSPF Instance: %d\n\n", ospf_instance);
-       vty_out(vty, "OSPF debugging status:\n");
-@@ -1645,13 +1645,7 @@ DEFUN_NOSH (show_debugging_ospf,
-           DEBUG_STR
-           OSPF_STR)
- {
--      struct ospf *ospf = NULL;
--
--      ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
--      if (ospf == NULL)
--              return CMD_SUCCESS;
--
--      return show_debugging_ospf_common(vty, ospf);
-+      return show_debugging_ospf_common(vty);
- }
- DEFUN_NOSH (show_debugging_ospf_instance,
-@@ -1663,14 +1657,13 @@ DEFUN_NOSH (show_debugging_ospf_instance
-           "Instance ID\n")
- {
-       int idx_number = 3;
--      struct ospf *ospf;
-       unsigned short instance = 0;
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
--      if ((ospf = ospf_lookup_instance(instance)) == NULL)
--              return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
--      return show_debugging_ospf_common(vty, ospf);
-+      return show_debugging_ospf_common(vty);
- }
- static int config_write_debug(struct vty *vty);
-@@ -1693,16 +1686,11 @@ static int config_write_debug(struct vty
-               "",     " send",        " recv",        "",
-               " detail", " send detail", " recv detail", " detail"};
--      struct ospf *ospf;
-       char str[16];
-       memset(str, 0, 16);
--      ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
--      if (ospf == NULL)
--              return CMD_SUCCESS;
--
--      if (ospf->instance)
--              snprintf(str, sizeof(str), " %u", ospf->instance);
-+      if (ospf_instance)
-+              snprintf(str, sizeof(str), " %u", ospf_instance);
-       /* debug ospf ism (status|events|timers). */
-       if (IS_CONF_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM)
---- a/ospfd/ospf_main.c
-+++ b/ospfd/ospf_main.c
-@@ -145,9 +145,6 @@ FRR_DAEMON_INFO(ospfd, OSPF, .vty_port =
- /* OSPFd main routine. */
- int main(int argc, char **argv)
- {
--      unsigned short instance = 0;
--      bool created = false;
--
- #ifdef SUPPORT_OSPF_API
-       /* OSPF apiserver is disabled by default. */
-       ospf_apiserver_enable = 0;
-@@ -168,8 +165,8 @@ int main(int argc, char **argv)
-               switch (opt) {
-               case 'n':
--                      ospfd_di.instance = instance = atoi(optarg);
--                      if (instance < 1)
-+                      ospfd_di.instance = ospf_instance = atoi(optarg);
-+                      if (ospf_instance < 1)
-                               exit(0);
-                       break;
-               case 0:
-@@ -207,7 +204,7 @@ int main(int argc, char **argv)
-       /* OSPFd inits. */
-       ospf_if_init();
--      ospf_zebra_init(master, instance);
-+      ospf_zebra_init(master, ospf_instance);
-       /* OSPF vty inits. */
-       ospf_vty_init();
-@@ -223,17 +220,6 @@ int main(int argc, char **argv)
-       /* OSPF errors init */
-       ospf_error_init();
--      /*
--       * Need to initialize the default ospf structure, so the interface mode
--       * commands can be duly processed if they are received before 'router
--       * ospf',  when ospfd is restarted
--       */
--      if (instance && !ospf_get_instance(instance, &created)) {
--              flog_err(EC_OSPF_INIT_FAIL, "OSPF instance init failed: %s",
--                       strerror(errno));
--              exit(1);
--      }
--
-       frr_config_fork();
-       frr_run(master);
---- a/ospfd/ospf_vty.c
-+++ b/ospfd/ospf_vty.c
-@@ -136,44 +136,37 @@ int ospf_oi_count(struct interface *ifp)
-               all_vrf = strmatch(vrf_name, "all");                           \
-       }
--static struct ospf *ospf_cmd_lookup_ospf(struct vty *vty,
--                                       struct cmd_token *argv[],
--                                       const int argc, uint32_t enable,
--                                       unsigned short *instance)
-+static int ospf_router_cmd_parse(struct vty *vty, struct cmd_token *argv[],
-+                               const int argc, unsigned short *instance,
-+                               const char **vrf_name)
- {
--      struct ospf *ospf = NULL;
-       int idx_vrf = 0, idx_inst = 0;
--      const char *vrf_name = NULL;
--      bool created = false;
-       *instance = 0;
--      if (argv_find(argv, argc, "(1-65535)", &idx_inst))
-+      if (argv_find(argv, argc, "(1-65535)", &idx_inst)) {
-+              if (ospf_instance == 0) {
-+                      vty_out(vty,
-+                              "%% OSPF is not running in instance mode\n");
-+                      return CMD_WARNING_CONFIG_FAILED;
-+              }
-+
-               *instance = strtoul(argv[idx_inst]->arg, NULL, 10);
-+      }
-+      *vrf_name = NULL;
-       if (argv_find(argv, argc, "vrf", &idx_vrf)) {
--              vrf_name = argv[idx_vrf + 1]->arg;
--              if (vrf_name == NULL || strmatch(vrf_name, VRF_DEFAULT_NAME))
--                      vrf_name = NULL;
--              if (enable) {
--                      /* Allocate VRF aware instance */
--                      ospf = ospf_get(*instance, vrf_name, &created);
--              } else {
--                      ospf = ospf_lookup_by_inst_name(*instance, vrf_name);
--              }
--      } else {
--              if (enable) {
--                      ospf = ospf_get(*instance, NULL, &created);
--              } else {
--                      ospf = ospf_lookup_instance(*instance);
-+              if (ospf_instance != 0) {
-+                      vty_out(vty,
-+                              "%% VRF is not supported in instance mode\n");
-+                      return CMD_WARNING_CONFIG_FAILED;
-               }
--      }
--      if (created) {
--              if (DFLT_OSPF_LOG_ADJACENCY_CHANGES)
--                      SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
-+              *vrf_name = argv[idx_vrf + 1]->arg;
-+              if (*vrf_name && strmatch(*vrf_name, VRF_DEFAULT_NAME))
-+                      *vrf_name = NULL;
-       }
--      return ospf;
-+      return CMD_SUCCESS;
- }
- static void ospf_show_vrf_name(struct ospf *ospf, struct vty *vty,
-@@ -209,28 +202,35 @@ DEFUN_NOSH (router_ospf,
-        "Instance ID\n"
-        VRF_CMD_HELP_STR)
- {
--      struct ospf *ospf = NULL;
--      int ret = CMD_SUCCESS;
--      unsigned short instance = 0;
-+      unsigned short instance;
-+      const char *vrf_name;
-+      bool created = false;
-+      struct ospf *ospf;
-+      int ret;
--      ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
--      if (!ospf)
--              return CMD_WARNING_CONFIG_FAILED;
-+      ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name);
-+      if (ret != CMD_SUCCESS)
-+              return ret;
--      /* The following logic to set the vty qobj index is in place to be able
--         to ignore the commands which dont belong to this instance. */
--      if (ospf->instance != instance) {
-+      if (instance != ospf_instance) {
-               VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
--              ret = CMD_NOT_MY_INSTANCE;
--      } else {
--              if (IS_DEBUG_OSPF_EVENT)
--                      zlog_debug(
--                              "Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
--                              instance, ospf->name ? ospf->name : "NIL",
--                              ospf->vrf_id, ospf->oi_running);
--              VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
-+              return CMD_NOT_MY_INSTANCE;
-       }
-+      ospf = ospf_get(instance, vrf_name, &created);
-+
-+      if (created)
-+              if (DFLT_OSPF_LOG_ADJACENCY_CHANGES)
-+                      SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES);
-+
-+      if (IS_DEBUG_OSPF_EVENT)
-+              zlog_debug(
-+                      "Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
-+                      ospf->instance, ospf->name ? ospf->name : "NIL",
-+                      ospf->vrf_id, ospf->oi_running);
-+
-+      VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
-+
-       return ret;
- }
-@@ -243,19 +243,25 @@ DEFUN (no_router_ospf,
-        "Instance ID\n"
-        VRF_CMD_HELP_STR)
- {
-+      unsigned short instance;
-+      const char *vrf_name;
-       struct ospf *ospf;
--      unsigned short instance = 0;
-+      int ret;
--      ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 0, &instance);
--      if (ospf == NULL) {
--              if (instance)
--                      return CMD_NOT_MY_INSTANCE;
--              else
--                      return CMD_WARNING;
--      }
--      ospf_finish(ospf);
-+      ret = ospf_router_cmd_parse(vty, argv, argc, &instance, &vrf_name);
-+      if (ret != CMD_SUCCESS)
-+              return ret;
--      return CMD_SUCCESS;
-+      if (instance != ospf_instance)
-+              return CMD_NOT_MY_INSTANCE;
-+
-+      ospf = ospf_lookup(instance, vrf_name);
-+      if (ospf)
-+              ospf_finish(ospf);
-+      else
-+              ret = CMD_WARNING_CONFIG_FAILED;
-+
-+      return ret;
- }
-@@ -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 (file)
index ad7be89..0000000
+++ /dev/null
@@ -1,964 +0,0 @@
-From 6ea5d99456b14db5e82abc2461228bb37aa7556d Mon Sep 17 00:00:00 2001
-From: Amol Lad <amol.lad@4rf.com>
-Date: Wed, 17 Feb 2021 13:47:32 +1300
-Subject: [PATCH 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 <reuben.dowle@4rf.com>
----
- 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 <stdio.h>
- #include <unistd.h>
- #include <string.h>
-+#include <errno.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/types.h>
-@@ -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 <fcntl.h>
-+#include <net/if.h>
-+#include <net/ethernet.h>
-+#include <netinet/if_ether.h>
-+#include <linux/netlink.h>
-+#include <linux/neighbour.h>
-+#include <linux/netfilter/nfnetlink_log.h>
-+#include <linux/if_packet.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+
-+#include "thread.h"
-+#include "nhrpd.h"
-+#include "netlink.h"
-+#include "znl.h"
-+#include "os.h"
-+
-+DEFINE_MTYPE_STATIC(NHRPD, NHRP_MULTICAST, "NHRP Multicast")
-+
-+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 <A.B.C.D|X:X::X:X|dynamic>",
-+      AFI_STR
-+      NHRP_STR
-+      "Multicast NBMA Configuration\n"
-+      "Use this NBMA mapping for multicasts\n"
-+      "IPv4 NBMA address\n"
-+      "IPv6 NBMA address\n"
-+      "Dynamically learn destinations from client registrations on hub\n")
-+{
-+      VTY_DECLVAR_CONTEXT(interface, ifp);
-+      afi_t afi = cmd_to_afi(argv[0]);
-+      union sockunion nbma_addr;
-+      int ret;
-+
-+      if (str2sockunion(argv[4]->arg, &nbma_addr) < 0)
-+              sockunion_family(&nbma_addr) = AF_UNSPEC;
-+
-+      ret = nhrp_multicast_add(ifp, afi, &nbma_addr);
-+
-+      return nhrp_vty_return(vty, ret);
-+}
-+
-+DEFUN(if_no_nhrp_map_multicast, if_no_nhrp_map_multicast_cmd,
-+      "no " AFI_CMD " nhrp map multicast <A.B.C.D|X:X::X:X|dynamic>",
-+      NO_STR
-+      AFI_STR
-+      NHRP_STR
-+      "Multicast NBMA Configuration\n"
-+      "Use this NBMA mapping for multicasts\n"
-+      "IPv4 NBMA address\n"
-+      "IPv6 NBMA address\n"
-+      "Dynamically learn destinations from client registrations on hub\n")
-+{
-+      VTY_DECLVAR_CONTEXT(interface, ifp);
-+      afi_t afi = cmd_to_afi(argv[1]);
-+      union sockunion nbma_addr;
-+      int ret;
-+
-+      if (str2sockunion(argv[5]->arg, &nbma_addr) < 0)
-+              sockunion_family(&nbma_addr) = AF_UNSPEC;
-+
-+      ret = nhrp_multicast_del(ifp, afi, &nbma_addr);
-+
-+      return nhrp_vty_return(vty, ret);
-+}
-+
- DEFUN(if_nhrp_nhs, if_nhrp_nhs_cmd,
-       AFI_CMD " nhrp nhs <A.B.C.D|X:X::X:X|dynamic> nbma <A.B.C.D|FQDN>",
-       AFI_STR
-@@ -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(&reg->peer->vc->remote.nbma,
--                            buf[0], sizeof(buf[0]));
-+              sockunion2str(&reg->peer->vc->remote.nbma, buf[0],
-+                            sizeof(buf[0]));
-       else
-               snprintf(buf[0], sizeof(buf[0]), "-");
-       sockunion2str(reg ? &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 <broadcast|non-broadcast|point-to-multipoint|point-to-point>",
--       "IP Information\n"
--       "OSPF interface commands\n"
--       "Network type\n"
--       "Specify OSPF broadcast multi-access network\n"
--       "Specify OSPF NBMA network\n"
--       "Specify OSPF point-to-multipoint network\n"
--       "Specify OSPF point-to-point network\n")
-+DEFUN(ip_ospf_network, ip_ospf_network_cmd,
-+      "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point [dmvpn]>",
-+      "IP Information\n"
-+      "OSPF interface commands\n"
-+      "Network type\n"
-+      "Specify OSPF broadcast multi-access network\n"
-+      "Specify OSPF NBMA network\n"
-+      "Specify OSPF point-to-multipoint network\n"
-+      "Specify OSPF point-to-point network\n"
-+      "Specify OSPF point-to-point DMVPN network\n")
- {
-       VTY_DECLVAR_CONTEXT(interface, ifp);
-       int idx = 0;
-       int old_type = IF_DEF_PARAMS(ifp)->type;
-+      uint8_t old_ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
-       struct route_node *rn;
-       if (old_type == OSPF_IFTYPE_LOOPBACK) {
-@@ -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 (file)
index 9ee3db1..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-From 354196c027e81affb05163a6c3676eef1ba06dd9 Mon Sep 17 00:00:00 2001
-From: Zoran Pericic <zpericic@netst.org>
-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ć <zpericic@netst.org>
----
- 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 <path>
-+
-+   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__,
index e956581d2c7d705c8ffa72edc31fea5993aba999..76bc87401f7add3a4cb2f8bfc755be65af330cce 100644 (file)
@@ -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;
index 65a950c2f2ee2d91eb63b2eace0cfb2e6d000fda..cd7c3a7be950787983475cb2a989b71d6a73e8e8 100644 (file)
@@ -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 */
 -              /* 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;
 -#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);
                {