]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
eb5d44eb | 2 | /* |
3 | * IS-IS Rout(e)ing protocol - isis_dynhn.c | |
4 | * Dynamic hostname cache | |
5 | * Copyright (C) 2001,2002 Sampo Saaristo | |
d62a17ae | 6 | * Tampere University of Technology |
eb5d44eb | 7 | * Institute of Communications Engineering |
eb5d44eb | 8 | */ |
9 | ||
eb5d44eb | 10 | #include <zebra.h> |
eb5d44eb | 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" | |
24a58196 | 19 | #include "frrevent.h" |
eb5d44eb | 20 | |
eb5d44eb | 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 | ||
66b9a381 DL |
30 | DEFINE_MTYPE_STATIC(ISISD, ISIS_DYNHN, "ISIS dyn hostname"); |
31 | ||
e6685141 | 32 | static void dyn_cache_cleanup(struct event *); |
eb5d44eb | 33 | |
eab88f36 | 34 | void dyn_cache_init(struct isis *isis) |
eb5d44eb | 35 | { |
240f48b3 | 36 | isis->dyn_cache = list_new(); |
52a7c25e | 37 | if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) |
907a2395 DS |
38 | event_add_timer(master, dyn_cache_cleanup, isis, 120, |
39 | &isis->t_dync_clean); | |
eb5d44eb | 40 | } |
41 | ||
240f48b3 | 42 | void dyn_cache_finish(struct isis *isis) |
52a7c25e RW |
43 | { |
44 | struct listnode *node, *nnode; | |
45 | struct isis_dynhn *dyn; | |
46 | ||
e16d030c | 47 | EVENT_OFF(isis->t_dync_clean); |
240f48b3 IR |
48 | |
49 | for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) { | |
50 | list_delete_node(isis->dyn_cache, node); | |
52a7c25e RW |
51 | XFREE(MTYPE_ISIS_DYNHN, dyn); |
52 | } | |
240f48b3 IR |
53 | |
54 | list_delete(&isis->dyn_cache); | |
52a7c25e RW |
55 | } |
56 | ||
e6685141 | 57 | static void dyn_cache_cleanup(struct event *thread) |
d3d7474b | 58 | { |
d62a17ae | 59 | struct listnode *node, *nnode; |
60 | struct isis_dynhn *dyn; | |
61 | time_t now = time(NULL); | |
eab88f36 K |
62 | struct isis *isis = NULL; |
63 | ||
e16d030c | 64 | isis = EVENT_ARG(thread); |
d3d7474b | 65 | |
d62a17ae | 66 | isis->t_dync_clean = NULL; |
d3d7474b | 67 | |
240f48b3 | 68 | for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) { |
d62a17ae | 69 | if ((now - dyn->refresh) < MAX_LSP_LIFETIME) |
70 | continue; | |
240f48b3 | 71 | list_delete_node(isis->dyn_cache, node); |
d62a17ae | 72 | XFREE(MTYPE_ISIS_DYNHN, dyn); |
73 | } | |
d3d7474b | 74 | |
907a2395 | 75 | event_add_timer(master, dyn_cache_cleanup, isis, 120, |
eab88f36 | 76 | &isis->t_dync_clean); |
d3d7474b | 77 | } |
78 | ||
240f48b3 | 79 | struct isis_dynhn *dynhn_find_by_id(struct isis *isis, const uint8_t *id) |
eb5d44eb | 80 | { |
d62a17ae | 81 | struct listnode *node = NULL; |
82 | struct isis_dynhn *dyn = NULL; | |
eb5d44eb | 83 | |
240f48b3 | 84 | for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) |
d62a17ae | 85 | if (memcmp(dyn->id, id, ISIS_SYS_ID_LEN) == 0) |
86 | return dyn; | |
f390d2c7 | 87 | |
d62a17ae | 88 | return NULL; |
eb5d44eb | 89 | } |
90 | ||
240f48b3 | 91 | struct isis_dynhn *dynhn_find_by_name(struct isis *isis, const char *hostname) |
3f045a08 | 92 | { |
d62a17ae | 93 | struct listnode *node = NULL; |
94 | struct isis_dynhn *dyn = NULL; | |
3f045a08 | 95 | |
240f48b3 | 96 | for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) |
af8ac8f9 | 97 | if (strncmp(dyn->hostname, hostname, 255) == 0) |
d62a17ae | 98 | return dyn; |
3f045a08 | 99 | |
d62a17ae | 100 | return NULL; |
3f045a08 JB |
101 | } |
102 | ||
240f48b3 IR |
103 | void isis_dynhn_insert(struct isis *isis, const uint8_t *id, |
104 | const char *hostname, int level) | |
eb5d44eb | 105 | { |
d62a17ae | 106 | struct isis_dynhn *dyn; |
107 | ||
240f48b3 | 108 | dyn = dynhn_find_by_id(isis, id); |
d62a17ae | 109 | if (!dyn) { |
af8ac8f9 CF |
110 | dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn)); |
111 | memcpy(dyn->id, id, ISIS_SYS_ID_LEN); | |
112 | dyn->level = level; | |
240f48b3 | 113 | listnode_add(isis->dyn_cache, dyn); |
d62a17ae | 114 | } |
115 | ||
af8ac8f9 | 116 | snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname); |
d62a17ae | 117 | dyn->refresh = time(NULL); |
eb5d44eb | 118 | } |
119 | ||
240f48b3 | 120 | void isis_dynhn_remove(struct isis *isis, const uint8_t *id) |
3f045a08 | 121 | { |
d62a17ae | 122 | struct isis_dynhn *dyn; |
123 | ||
240f48b3 | 124 | dyn = dynhn_find_by_id(isis, id); |
d62a17ae | 125 | if (!dyn) |
126 | return; | |
240f48b3 | 127 | listnode_delete(isis->dyn_cache, dyn); |
d62a17ae | 128 | XFREE(MTYPE_ISIS_DYNHN, dyn); |
3f045a08 JB |
129 | } |
130 | ||
eb5d44eb | 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 | */ | |
eab88f36 | 137 | void dynhn_print_all(struct vty *vty, struct isis *isis) |
eb5d44eb | 138 | { |
d62a17ae | 139 | struct listnode *node; |
140 | struct isis_dynhn *dyn; | |
141 | ||
eab88f36 K |
142 | vty_out(vty, "vrf : %s\n", isis->name); |
143 | if (!isis->sysid_set) | |
144 | return; | |
d62a17ae | 145 | vty_out(vty, "Level System ID Dynamic Hostname\n"); |
240f48b3 | 146 | for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) { |
d62a17ae | 147 | vty_out(vty, "%-7d", dyn->level); |
5d39a819 | 148 | vty_out(vty, "%pSY %-15s\n", dyn->id, dyn->hostname); |
d62a17ae | 149 | } |
150 | ||
5d39a819 | 151 | vty_out(vty, " * %pSY %s\n", isis->sysid, cmd_hostname_get()); |
d62a17ae | 152 | return; |
eb5d44eb | 153 | } |
1ee746d9 | 154 | |
240f48b3 IR |
155 | struct isis_dynhn *dynhn_snmp_next(struct isis *isis, const uint8_t *id, |
156 | int level) | |
1ee746d9 | 157 | { |
158 | struct listnode *node = NULL; | |
159 | struct isis_dynhn *dyn = NULL; | |
160 | struct isis_dynhn *found_dyn = NULL; | |
161 | int res; | |
162 | ||
240f48b3 | 163 | for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) { |
1ee746d9 | 164 | res = memcmp(dyn->id, id, ISIS_SYS_ID_LEN); |
165 | ||
166 | if (res < 0) | |
167 | continue; | |
168 | ||
169 | if (res == 0 && dyn->level <= level) | |
170 | continue; | |
171 | ||
172 | if (res == 0) { | |
173 | /* | |
174 | * This is the best match, we can stop | |
175 | * searching | |
176 | */ | |
177 | ||
178 | found_dyn = dyn; | |
179 | break; | |
180 | } | |
181 | ||
182 | if (found_dyn == NULL | |
183 | || memcmp(dyn->id, found_dyn->id, ISIS_SYS_ID_LEN) < 0) { | |
184 | found_dyn = dyn; | |
185 | } | |
186 | } | |
187 | ||
188 | return found_dyn; | |
189 | } |