summaryrefslogtreecommitdiffstats
path: root/isisd/isis_dynhn.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:53:30 +0000
commit2c7cac91ed6e7db0f6937923d2b57f97dbdbc337 (patch)
treec05dc0f8e6aa3accc84e3e5cffc933ed94941383 /isisd/isis_dynhn.c
parentInitial commit. (diff)
downloadfrr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.tar.xz
frr-2c7cac91ed6e7db0f6937923d2b57f97dbdbc337.zip
Adding upstream version 8.4.4.upstream/8.4.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--isisd/isis_dynhn.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c
new file mode 100644
index 0000000..5d6b7bc
--- /dev/null
+++ b/isisd/isis_dynhn.c
@@ -0,0 +1,204 @@
+/*
+ * IS-IS Rout(e)ing protocol - isis_dynhn.c
+ * Dynamic hostname cache
+ * Copyright (C) 2001,2002 Sampo Saaristo
+ * Tampere University of Technology
+ * Institute of Communications Engineering
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public Licenseas published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "vty.h"
+#include "linklist.h"
+#include "memory.h"
+#include "log.h"
+#include "stream.h"
+#include "command.h"
+#include "if.h"
+#include "thread.h"
+
+#include "isisd/isis_constants.h"
+#include "isisd/isis_common.h"
+#include "isisd/isis_flags.h"
+#include "isisd/isis_circuit.h"
+#include "isisd/isisd.h"
+#include "isisd/isis_dynhn.h"
+#include "isisd/isis_misc.h"
+#include "isisd/isis_constants.h"
+
+DEFINE_MTYPE_STATIC(ISISD, ISIS_DYNHN, "ISIS dyn hostname");
+
+static void dyn_cache_cleanup(struct thread *);
+
+void dyn_cache_init(struct isis *isis)
+{
+ isis->dyn_cache = list_new();
+ if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
+ thread_add_timer(master, dyn_cache_cleanup, isis, 120,
+ &isis->t_dync_clean);
+}
+
+void dyn_cache_finish(struct isis *isis)
+{
+ struct listnode *node, *nnode;
+ struct isis_dynhn *dyn;
+
+ THREAD_OFF(isis->t_dync_clean);
+
+ for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
+ list_delete_node(isis->dyn_cache, node);
+ XFREE(MTYPE_ISIS_DYNHN, dyn);
+ }
+
+ list_delete(&isis->dyn_cache);
+}
+
+static void dyn_cache_cleanup(struct thread *thread)
+{
+ struct listnode *node, *nnode;
+ struct isis_dynhn *dyn;
+ time_t now = time(NULL);
+ struct isis *isis = NULL;
+
+ isis = THREAD_ARG(thread);
+
+ isis->t_dync_clean = NULL;
+
+ for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
+ if ((now - dyn->refresh) < MAX_LSP_LIFETIME)
+ continue;
+ list_delete_node(isis->dyn_cache, node);
+ XFREE(MTYPE_ISIS_DYNHN, dyn);
+ }
+
+ thread_add_timer(master, dyn_cache_cleanup, isis, 120,
+ &isis->t_dync_clean);
+}
+
+struct isis_dynhn *dynhn_find_by_id(struct isis *isis, const uint8_t *id)
+{
+ struct listnode *node = NULL;
+ struct isis_dynhn *dyn = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn))
+ if (memcmp(dyn->id, id, ISIS_SYS_ID_LEN) == 0)
+ return dyn;
+
+ return NULL;
+}
+
+struct isis_dynhn *dynhn_find_by_name(struct isis *isis, const char *hostname)
+{
+ struct listnode *node = NULL;
+ struct isis_dynhn *dyn = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn))
+ if (strncmp(dyn->hostname, hostname, 255) == 0)
+ return dyn;
+
+ return NULL;
+}
+
+void isis_dynhn_insert(struct isis *isis, const uint8_t *id,
+ const char *hostname, int level)
+{
+ struct isis_dynhn *dyn;
+
+ dyn = dynhn_find_by_id(isis, id);
+ if (!dyn) {
+ dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
+ memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
+ dyn->level = level;
+ listnode_add(isis->dyn_cache, dyn);
+ }
+
+ snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname);
+ dyn->refresh = time(NULL);
+}
+
+void isis_dynhn_remove(struct isis *isis, const uint8_t *id)
+{
+ struct isis_dynhn *dyn;
+
+ dyn = dynhn_find_by_id(isis, id);
+ if (!dyn)
+ return;
+ listnode_delete(isis->dyn_cache, dyn);
+ XFREE(MTYPE_ISIS_DYNHN, dyn);
+}
+
+/*
+ * Level System ID Dynamic Hostname (notag)
+ * 2 0000.0000.0001 foo-gw
+ * 2 0000.0000.0002 bar-gw
+ * * 0000.0000.0004 this-gw
+ */
+void dynhn_print_all(struct vty *vty, struct isis *isis)
+{
+ struct listnode *node;
+ struct isis_dynhn *dyn;
+
+ vty_out(vty, "vrf : %s\n", isis->name);
+ if (!isis->sysid_set)
+ return;
+ vty_out(vty, "Level System ID Dynamic Hostname\n");
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
+ vty_out(vty, "%-7d", dyn->level);
+ vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id),
+ dyn->hostname);
+ }
+
+ vty_out(vty, " * %s %s\n", sysid_print(isis->sysid),
+ cmd_hostname_get());
+ return;
+}
+
+struct isis_dynhn *dynhn_snmp_next(struct isis *isis, const uint8_t *id,
+ int level)
+{
+ struct listnode *node = NULL;
+ struct isis_dynhn *dyn = NULL;
+ struct isis_dynhn *found_dyn = NULL;
+ int res;
+
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
+ res = memcmp(dyn->id, id, ISIS_SYS_ID_LEN);
+
+ if (res < 0)
+ continue;
+
+ if (res == 0 && dyn->level <= level)
+ continue;
+
+ if (res == 0) {
+ /*
+ * This is the best match, we can stop
+ * searching
+ */
+
+ found_dyn = dyn;
+ break;
+ }
+
+ if (found_dyn == NULL
+ || memcmp(dyn->id, found_dyn->id, ISIS_SYS_ID_LEN) < 0) {
+ found_dyn = dyn;
+ }
+ }
+
+ return found_dyn;
+}