blob: aab8d1a3dcede78466332046489a1fc33908ca70 [file] [log] [blame]
jardineb5d44e2003-12-23 08:09:43 +00001/*
2 * IS-IS Rout(e)ing protocol - isis_adjacency.c
3 * handling of IS-IS adjacencies
4 *
5 * Copyright (C) 2001,2002 Sampo Saaristo
6 * Tampere University of Technology
7 * Institute of Communications Engineering
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public Licenseas published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
jardineb5d44e2003-12-23 08:09:43 +000024#include <zebra.h>
jardineb5d44e2003-12-23 08:09:43 +000025
26#include "log.h"
27#include "memory.h"
28#include "hash.h"
29#include "vty.h"
30#include "linklist.h"
31#include "thread.h"
32#include "if.h"
33#include "stream.h"
34
35#include "isisd/dict.h"
36#include "isisd/include-netbsd/iso.h"
37#include "isisd/isis_constants.h"
38#include "isisd/isis_common.h"
39#include "isisd/isisd.h"
40#include "isisd/isis_circuit.h"
41#include "isisd/isis_adjacency.h"
42#include "isisd/isis_misc.h"
43#include "isisd/isis_dr.h"
44#include "isisd/isis_dynhn.h"
45#include "isisd/isis_pdu.h"
46
jardineb5d44e2003-12-23 08:09:43 +000047extern struct isis *isis;
48
hasso92365882005-01-18 13:53:33 +000049static struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +000050adj_alloc (u_char * id)
jardineb5d44e2003-12-23 08:09:43 +000051{
hassof390d2c2004-09-10 20:48:21 +000052 struct isis_adjacency *adj;
jardineb5d44e2003-12-23 08:09:43 +000053
hassoaac372f2005-09-01 17:52:33 +000054 adj = XCALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency));
hassof390d2c2004-09-10 20:48:21 +000055 memcpy (adj->sysid, id, ISIS_SYS_ID_LEN);
56
57 return adj;
jardineb5d44e2003-12-23 08:09:43 +000058}
59
60struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +000061isis_new_adj (u_char * id, u_char * snpa, int level,
jardineb5d44e2003-12-23 08:09:43 +000062 struct isis_circuit *circuit)
63{
jardineb5d44e2003-12-23 08:09:43 +000064 struct isis_adjacency *adj;
hassof390d2c2004-09-10 20:48:21 +000065 int i;
jardineb5d44e2003-12-23 08:09:43 +000066
hassof390d2c2004-09-10 20:48:21 +000067 adj = adj_alloc (id); /* P2P kludge */
68
69 if (adj == NULL)
70 {
71 zlog_err ("Out of memory!");
72 return NULL;
73 }
jardineb5d44e2003-12-23 08:09:43 +000074
Paul Jakma41b36e92006-12-08 01:09:50 +000075 if (snpa) {
jardineb5d44e2003-12-23 08:09:43 +000076 memcpy (adj->snpa, snpa, 6);
Paul Jakma41b36e92006-12-08 01:09:50 +000077 } else {
78 memset (adj->snpa, ' ', 6);
79 }
80
jardineb5d44e2003-12-23 08:09:43 +000081 adj->circuit = circuit;
82 adj->level = level;
83 adj->flaps = 0;
84 adj->last_flap = time (NULL);
hassof390d2c2004-09-10 20:48:21 +000085 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
86 {
87 listnode_add (circuit->u.bc.adjdb[level - 1], adj);
88 adj->dischanges[level - 1] = 0;
89 for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
jardineb5d44e2003-12-23 08:09:43 +000090 {
hassof390d2c2004-09-10 20:48:21 +000091 adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
jardineb5d44e2003-12-23 08:09:43 +000092 = ISIS_UNKNOWN_DIS;
hassof390d2c2004-09-10 20:48:21 +000093 adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
94 = time (NULL);
jardineb5d44e2003-12-23 08:09:43 +000095 }
hassof390d2c2004-09-10 20:48:21 +000096 }
jardineb5d44e2003-12-23 08:09:43 +000097
98 return adj;
99}
100
101struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000102isis_adj_lookup (u_char * sysid, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000103{
104 struct isis_adjacency *adj;
105 struct listnode *node;
106
paul1eb8ef22005-04-07 07:30:20 +0000107 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
108 if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
109 return adj;
hassof390d2c2004-09-10 20:48:21 +0000110
jardineb5d44e2003-12-23 08:09:43 +0000111 return NULL;
112}
113
jardineb5d44e2003-12-23 08:09:43 +0000114struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000115isis_adj_lookup_snpa (u_char * ssnpa, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000116{
117 struct listnode *node;
118 struct isis_adjacency *adj;
119
paul1eb8ef22005-04-07 07:30:20 +0000120 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
121 if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
122 return adj;
hassof390d2c2004-09-10 20:48:21 +0000123
jardineb5d44e2003-12-23 08:09:43 +0000124 return NULL;
125}
126
hassof390d2c2004-09-10 20:48:21 +0000127void
jardineb5d44e2003-12-23 08:09:43 +0000128isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
129{
hasso3fdb2dd2005-09-28 18:45:54 +0000130 if (!adj)
131 return;
132 /* When we recieve a NULL list, we will know its p2p. */
hassof390d2c2004-09-10 20:48:21 +0000133 if (adjdb)
hasso3fdb2dd2005-09-28 18:45:54 +0000134 listnode_delete (adjdb, adj);
hassof390d2c2004-09-10 20:48:21 +0000135
hasso13fb40a2005-10-01 06:03:04 +0000136 THREAD_OFF (adj->t_expire);
137
jardineb5d44e2003-12-23 08:09:43 +0000138 if (adj->ipv4_addrs)
139 list_delete (adj->ipv4_addrs);
140#ifdef HAVE_IPV6
141 if (adj->ipv6_addrs)
142 list_delete (adj->ipv6_addrs);
143#endif
hasso3fdb2dd2005-09-28 18:45:54 +0000144
145 XFREE (MTYPE_ISIS_ADJACENCY, adj);
jardineb5d44e2003-12-23 08:09:43 +0000146 return;
147}
148
hassof390d2c2004-09-10 20:48:21 +0000149void
150isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
hasso1cd80842004-10-07 20:07:40 +0000151 const char *reason)
jardineb5d44e2003-12-23 08:09:43 +0000152{
153 int old_state;
154 int level = adj->level;
155 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000156
jardineb5d44e2003-12-23 08:09:43 +0000157 old_state = adj->adj_state;
158 adj->adj_state = state;
159
160 circuit = adj->circuit;
jardineb5d44e2003-12-23 08:09:43 +0000161
hassof390d2c2004-09-10 20:48:21 +0000162 if (isis->debugs & DEBUG_ADJ_PACKETS)
163 {
hasso529d65b2004-12-24 00:14:50 +0000164 zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
hassof390d2c2004-09-10 20:48:21 +0000165 circuit->area->area_tag,
166 old_state, state, reason ? reason : "unspecified");
jardineb5d44e2003-12-23 08:09:43 +0000167 }
168
hassof390d2c2004-09-10 20:48:21 +0000169 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
170 {
171 if (state == ISIS_ADJ_UP)
172 circuit->upadjcount[level - 1]++;
173 if (state == ISIS_ADJ_DOWN)
174 {
175 isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
176 circuit->upadjcount[level - 1]--;
177 }
jardineb5d44e2003-12-23 08:09:43 +0000178
hassof390d2c2004-09-10 20:48:21 +0000179 list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
180 isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
181 circuit->u.bc.lan_neighs[level - 1]);
182 }
183 else if (state == ISIS_ADJ_UP)
184 { /* p2p interface */
185 if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
186 send_hello (circuit, 1);
187
188 /* update counter & timers for debugging purposes */
189 adj->last_flap = time (NULL);
190 adj->flaps++;
191
192 /* 7.3.17 - going up on P2P -> send CSNP */
193 /* FIXME: yup, I know its wrong... but i will do it! (for now) */
194 send_csnp (circuit, 1);
195 send_csnp (circuit, 2);
196 }
197 else if (state == ISIS_ADJ_DOWN)
198 { /* p2p interface */
199 adj->circuit->u.p2p.neighbor = NULL;
200 isis_delete_adj (adj, NULL);
201 }
jardineb5d44e2003-12-23 08:09:43 +0000202 return;
203}
204
205
206void
207isis_adj_print (struct isis_adjacency *adj)
208{
209 struct isis_dynhn *dyn;
210 struct listnode *node;
211 struct in_addr *ipv4_addr;
hassof390d2c2004-09-10 20:48:21 +0000212#ifdef HAVE_IPV6
jardineb5d44e2003-12-23 08:09:43 +0000213 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000214 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000215#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000216
217 if (!adj)
jardineb5d44e2003-12-23 08:09:43 +0000218 return;
219 dyn = dynhn_find_by_id (adj->sysid);
220 if (dyn)
hasso529d65b2004-12-24 00:14:50 +0000221 zlog_debug ("%s", dyn->name.name);
jardineb5d44e2003-12-23 08:09:43 +0000222
hasso529d65b2004-12-24 00:14:50 +0000223 zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
224 adj->sysid ? sysid_print (adj->sysid) : "unknown",
225 snpa_print (adj->snpa), adj->level, adj->hold_time);
hassof390d2c2004-09-10 20:48:21 +0000226 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
227 {
hasso529d65b2004-12-24 00:14:50 +0000228 zlog_debug ("IPv4 Addresses:");
hassof390d2c2004-09-10 20:48:21 +0000229
paul1eb8ef22005-04-07 07:30:20 +0000230 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
231 zlog_debug ("%s", inet_ntoa (*ipv4_addr));
jardineb5d44e2003-12-23 08:09:43 +0000232 }
hassof390d2c2004-09-10 20:48:21 +0000233
234#ifdef HAVE_IPV6
235 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
236 {
hasso529d65b2004-12-24 00:14:50 +0000237 zlog_debug ("IPv6 Addresses:");
paul1eb8ef22005-04-07 07:30:20 +0000238 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000239 {
hassof7c43dc2004-09-26 16:24:14 +0000240 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hasso529d65b2004-12-24 00:14:50 +0000241 zlog_debug ("%s", ip6);
hassof390d2c2004-09-10 20:48:21 +0000242 }
243 }
jardineb5d44e2003-12-23 08:09:43 +0000244#endif /* HAVE_IPV6 */
hasso529d65b2004-12-24 00:14:50 +0000245 zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
jardineb5d44e2003-12-23 08:09:43 +0000246
247 return;
248}
249
hassof390d2c2004-09-10 20:48:21 +0000250int
jardineb5d44e2003-12-23 08:09:43 +0000251isis_adj_expire (struct thread *thread)
252{
253 struct isis_adjacency *adj;
254 int level;
255
256 /*
257 * Get the adjacency
258 */
259 adj = THREAD_ARG (thread);
260 assert (adj);
261 level = adj->level;
hasso83fe45e2004-02-09 11:09:39 +0000262 adj->t_expire = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000263
264 /* trigger the adj expire event */
265 isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
266
267 return 0;
268}
269
hasso92365882005-01-18 13:53:33 +0000270static const char *
jardineb5d44e2003-12-23 08:09:43 +0000271adj_state2string (int state)
272{
hassof390d2c2004-09-10 20:48:21 +0000273
274 switch (state)
275 {
276 case ISIS_ADJ_INITIALIZING:
277 return "Initializing";
278 case ISIS_ADJ_UP:
279 return "Up";
280 case ISIS_ADJ_DOWN:
281 return "Down";
282 default:
283 return "Unknown";
284 }
285
286 return NULL; /* not reached */
jardineb5d44e2003-12-23 08:09:43 +0000287}
288
289/*
290 * show clns/isis neighbor (detail)
291 */
hasso92365882005-01-18 13:53:33 +0000292static void
jardineb5d44e2003-12-23 08:09:43 +0000293isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
294{
295
296#ifdef HAVE_IPV6
297 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000298 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000299#endif /* HAVE_IPV6 */
300 struct in_addr *ip_addr;
301 time_t now;
302 struct isis_dynhn *dyn;
303 int level;
304 struct listnode *node;
305
306 dyn = dynhn_find_by_id (adj->sysid);
307 if (dyn)
308 vty_out (vty, " %-20s", dyn->name.name);
hassof390d2c2004-09-10 20:48:21 +0000309 else if (adj->sysid)
310 {
311 vty_out (vty, " %-20s", sysid_print (adj->sysid));
jardineb5d44e2003-12-23 08:09:43 +0000312 }
hassof390d2c2004-09-10 20:48:21 +0000313 else
314 {
315 vty_out (vty, " unknown ");
jardineb5d44e2003-12-23 08:09:43 +0000316 }
hassof390d2c2004-09-10 20:48:21 +0000317
318 if (detail == ISIS_UI_LEVEL_BRIEF)
319 {
320 if (adj->circuit)
321 vty_out (vty, "%-12s", adj->circuit->interface->name);
322 else
323 vty_out (vty, "NULL circuit!");
324 vty_out (vty, "%-3u", adj->level); /* level */
325 vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
326 now = time (NULL);
327 if (adj->last_upd)
328 vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
329 else
330 vty_out (vty, "- ");
331 vty_out (vty, "%-10s", snpa_print (adj->snpa));
332 vty_out (vty, "%s", VTY_NEWLINE);
333 }
334
335 if (detail == ISIS_UI_LEVEL_DETAIL)
336 {
337 level = adj->level;
338 if (adj->circuit)
339 vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
340 else
341 vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
342 vty_out (vty, ", Level: %u", adj->level); /* level */
343 vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
344 now = time (NULL);
345 if (adj->last_upd)
346 vty_out (vty, ", Expires in %s",
347 time2string (adj->last_upd + adj->hold_time - now));
348 else
349 vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
350 vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
351 vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
352 vty_out (vty, "%s Circuit type: %s",
353 VTY_NEWLINE, circuit_t2string (adj->circuit_t));
354 vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
355 vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
356 dyn = dynhn_find_by_id (adj->lanid);
357 if (dyn)
358 vty_out (vty, ", LAN id: %s.%02x",
359 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
360 else
361 vty_out (vty, ", LAN id: %s.%02x",
362 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
363
364 vty_out (vty, "%s Priority: %u",
365 VTY_NEWLINE, adj->prio[adj->level - 1]);
366
367 vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
368 isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
369 dis), adj->dischanges[level - 1],
370 time2string (now -
371 (adj->dis_record[ISIS_LEVELS + level - 1].
372 last_dis_change)), VTY_NEWLINE);
373
374 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
375 {
376 vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000377 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
378 vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
hassof390d2c2004-09-10 20:48:21 +0000379 }
380#ifdef HAVE_IPV6
381 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
382 {
383 vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
hasso5d6e2692005-04-12 14:48:19 +0000384 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000385 {
hassof7c43dc2004-09-26 16:24:14 +0000386 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hassof390d2c2004-09-10 20:48:21 +0000387 vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
388 }
389 }
jardineb5d44e2003-12-23 08:09:43 +0000390#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000391 vty_out (vty, "%s", VTY_NEWLINE);
392 }
jardineb5d44e2003-12-23 08:09:43 +0000393 return;
394}
395
396void
hassof390d2c2004-09-10 20:48:21 +0000397isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
398{
jardineb5d44e2003-12-23 08:09:43 +0000399 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
400}
401
402void
hassof390d2c2004-09-10 20:48:21 +0000403isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
404{
jardineb5d44e2003-12-23 08:09:43 +0000405 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
406}
407
408void
hassof390d2c2004-09-10 20:48:21 +0000409isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
410{
jardineb5d44e2003-12-23 08:09:43 +0000411 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
412}
413
414void
415isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
416{
417 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
418}
419
hassof390d2c2004-09-10 20:48:21 +0000420void
421isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000422{
423 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
424}
425
hassof390d2c2004-09-10 20:48:21 +0000426void
jardineb5d44e2003-12-23 08:09:43 +0000427isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
428{
429 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
430}
431
432void
hassof390d2c2004-09-10 20:48:21 +0000433isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
434 void *), void *arg)
jardineb5d44e2003-12-23 08:09:43 +0000435{
paul1eb8ef22005-04-07 07:30:20 +0000436 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000437 struct isis_adjacency *adj;
paul1eb8ef22005-04-07 07:30:20 +0000438
439 for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
440 (*func) (adj, arg);
jardineb5d44e2003-12-23 08:09:43 +0000441}
442
443void
444isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
jardineb5d44e2003-12-23 08:09:43 +0000445{
446 struct isis_adjacency *adj;
447 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000448
449 if (!list)
450 {
451 zlog_warn ("isis_adj_build_neigh_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000452 return;
453 }
hassof390d2c2004-09-10 20:48:21 +0000454
paul1eb8ef22005-04-07 07:30:20 +0000455 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000456 {
hassof390d2c2004-09-10 20:48:21 +0000457 if (!adj)
458 {
459 zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
460 return;
461 }
462
463 if ((adj->adj_state == ISIS_ADJ_UP ||
464 adj->adj_state == ISIS_ADJ_INITIALIZING))
465 listnode_add (list, adj->snpa);
466 }
jardineb5d44e2003-12-23 08:09:43 +0000467 return;
468}
469
470void
471isis_adj_build_up_list (struct list *adjdb, struct list *list)
472{
473 struct isis_adjacency *adj;
474 struct listnode *node;
475
hassof390d2c2004-09-10 20:48:21 +0000476 if (!list)
477 {
478 zlog_warn ("isis_adj_build_up_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000479 return;
480 }
481
paul1eb8ef22005-04-07 07:30:20 +0000482 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000483 {
hassof390d2c2004-09-10 20:48:21 +0000484 if (!adj)
485 {
486 zlog_warn ("isis_adj_build_up_list(): NULL adj");
487 return;
488 }
489
490 if (adj->adj_state == ISIS_ADJ_UP)
491 listnode_add (list, adj);
492 }
493
jardineb5d44e2003-12-23 08:09:43 +0000494 return;
495}