]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_dynhn.c
Merge pull request #12366 from manojvn/ospfv2-flood-reduction
[mirror_frr.git] / isisd / isis_dynhn.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * IS-IS Rout(e)ing protocol - isis_dynhn.c
4 * Dynamic hostname cache
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
8 */
9
10 #include <zebra.h>
11
12 #include "vty.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "log.h"
16 #include "stream.h"
17 #include "command.h"
18 #include "if.h"
19 #include "thread.h"
20
21 #include "isisd/isis_constants.h"
22 #include "isisd/isis_common.h"
23 #include "isisd/isis_flags.h"
24 #include "isisd/isis_circuit.h"
25 #include "isisd/isisd.h"
26 #include "isisd/isis_dynhn.h"
27 #include "isisd/isis_misc.h"
28 #include "isisd/isis_constants.h"
29
30 DEFINE_MTYPE_STATIC(ISISD, ISIS_DYNHN, "ISIS dyn hostname");
31
32 static void dyn_cache_cleanup(struct thread *);
33
34 void dyn_cache_init(struct isis *isis)
35 {
36 isis->dyn_cache = list_new();
37 if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
38 thread_add_timer(master, dyn_cache_cleanup, isis, 120,
39 &isis->t_dync_clean);
40 }
41
42 void dyn_cache_finish(struct isis *isis)
43 {
44 struct listnode *node, *nnode;
45 struct isis_dynhn *dyn;
46
47 THREAD_OFF(isis->t_dync_clean);
48
49 for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
50 list_delete_node(isis->dyn_cache, node);
51 XFREE(MTYPE_ISIS_DYNHN, dyn);
52 }
53
54 list_delete(&isis->dyn_cache);
55 }
56
57 static void dyn_cache_cleanup(struct thread *thread)
58 {
59 struct listnode *node, *nnode;
60 struct isis_dynhn *dyn;
61 time_t now = time(NULL);
62 struct isis *isis = NULL;
63
64 isis = THREAD_ARG(thread);
65
66 isis->t_dync_clean = NULL;
67
68 for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
69 if ((now - dyn->refresh) < MAX_LSP_LIFETIME)
70 continue;
71 list_delete_node(isis->dyn_cache, node);
72 XFREE(MTYPE_ISIS_DYNHN, dyn);
73 }
74
75 thread_add_timer(master, dyn_cache_cleanup, isis, 120,
76 &isis->t_dync_clean);
77 }
78
79 struct isis_dynhn *dynhn_find_by_id(struct isis *isis, const uint8_t *id)
80 {
81 struct listnode *node = NULL;
82 struct isis_dynhn *dyn = NULL;
83
84 for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn))
85 if (memcmp(dyn->id, id, ISIS_SYS_ID_LEN) == 0)
86 return dyn;
87
88 return NULL;
89 }
90
91 struct isis_dynhn *dynhn_find_by_name(struct isis *isis, const char *hostname)
92 {
93 struct listnode *node = NULL;
94 struct isis_dynhn *dyn = NULL;
95
96 for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn))
97 if (strncmp(dyn->hostname, hostname, 255) == 0)
98 return dyn;
99
100 return NULL;
101 }
102
103 void isis_dynhn_insert(struct isis *isis, const uint8_t *id,
104 const char *hostname, int level)
105 {
106 struct isis_dynhn *dyn;
107
108 dyn = dynhn_find_by_id(isis, id);
109 if (!dyn) {
110 dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
111 memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
112 dyn->level = level;
113 listnode_add(isis->dyn_cache, dyn);
114 }
115
116 snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname);
117 dyn->refresh = time(NULL);
118 }
119
120 void isis_dynhn_remove(struct isis *isis, const uint8_t *id)
121 {
122 struct isis_dynhn *dyn;
123
124 dyn = dynhn_find_by_id(isis, id);
125 if (!dyn)
126 return;
127 listnode_delete(isis->dyn_cache, dyn);
128 XFREE(MTYPE_ISIS_DYNHN, dyn);
129 }
130
131 /*
132 * Level System ID Dynamic Hostname (notag)
133 * 2 0000.0000.0001 foo-gw
134 * 2 0000.0000.0002 bar-gw
135 * * 0000.0000.0004 this-gw
136 */
137 void dynhn_print_all(struct vty *vty, struct isis *isis)
138 {
139 struct listnode *node;
140 struct isis_dynhn *dyn;
141
142 vty_out(vty, "vrf : %s\n", isis->name);
143 if (!isis->sysid_set)
144 return;
145 vty_out(vty, "Level System ID Dynamic Hostname\n");
146 for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
147 vty_out(vty, "%-7d", dyn->level);
148 vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id),
149 dyn->hostname);
150 }
151
152 vty_out(vty, " * %s %s\n", sysid_print(isis->sysid),
153 cmd_hostname_get());
154 return;
155 }
156
157 struct isis_dynhn *dynhn_snmp_next(struct isis *isis, const uint8_t *id,
158 int level)
159 {
160 struct listnode *node = NULL;
161 struct isis_dynhn *dyn = NULL;
162 struct isis_dynhn *found_dyn = NULL;
163 int res;
164
165 for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
166 res = memcmp(dyn->id, id, ISIS_SYS_ID_LEN);
167
168 if (res < 0)
169 continue;
170
171 if (res == 0 && dyn->level <= level)
172 continue;
173
174 if (res == 0) {
175 /*
176 * This is the best match, we can stop
177 * searching
178 */
179
180 found_dyn = dyn;
181 break;
182 }
183
184 if (found_dyn == NULL
185 || memcmp(dyn->id, found_dyn->id, ISIS_SYS_ID_LEN) < 0) {
186 found_dyn = dyn;
187 }
188 }
189
190 return found_dyn;
191 }