blob: a4078d7211b9441f2f6aa8df34b737e3d51afb9b [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
24#include <stdio.h>
25#include <limits.h>
26#include <string.h>
27#include <zebra.h>
jardineb5d44e2003-12-23 08:09:43 +000028
29#include "log.h"
30#include "memory.h"
31#include "hash.h"
32#include "vty.h"
33#include "linklist.h"
34#include "thread.h"
35#include "if.h"
36#include "stream.h"
37
38#include "isisd/dict.h"
39#include "isisd/include-netbsd/iso.h"
40#include "isisd/isis_constants.h"
41#include "isisd/isis_common.h"
42#include "isisd/isisd.h"
43#include "isisd/isis_circuit.h"
44#include "isisd/isis_adjacency.h"
45#include "isisd/isis_misc.h"
46#include "isisd/isis_dr.h"
47#include "isisd/isis_dynhn.h"
48#include "isisd/isis_pdu.h"
49
jardineb5d44e2003-12-23 08:09:43 +000050extern struct isis *isis;
51
hasso92365882005-01-18 13:53:33 +000052static struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +000053adj_alloc (u_char * id)
jardineb5d44e2003-12-23 08:09:43 +000054{
hassof390d2c2004-09-10 20:48:21 +000055 struct isis_adjacency *adj;
jardineb5d44e2003-12-23 08:09:43 +000056
hassoaac372f2005-09-01 17:52:33 +000057 adj = XCALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency));
hassof390d2c2004-09-10 20:48:21 +000058 memcpy (adj->sysid, id, ISIS_SYS_ID_LEN);
59
60 return adj;
jardineb5d44e2003-12-23 08:09:43 +000061}
62
63struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +000064isis_new_adj (u_char * id, u_char * snpa, int level,
jardineb5d44e2003-12-23 08:09:43 +000065 struct isis_circuit *circuit)
66{
jardineb5d44e2003-12-23 08:09:43 +000067 struct isis_adjacency *adj;
hassof390d2c2004-09-10 20:48:21 +000068 int i;
jardineb5d44e2003-12-23 08:09:43 +000069
hassof390d2c2004-09-10 20:48:21 +000070 adj = adj_alloc (id); /* P2P kludge */
71
72 if (adj == NULL)
73 {
74 zlog_err ("Out of memory!");
75 return NULL;
76 }
jardineb5d44e2003-12-23 08:09:43 +000077
78 memcpy (adj->snpa, snpa, 6);
79 adj->circuit = circuit;
80 adj->level = level;
81 adj->flaps = 0;
82 adj->last_flap = time (NULL);
hassof390d2c2004-09-10 20:48:21 +000083 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
84 {
85 listnode_add (circuit->u.bc.adjdb[level - 1], adj);
86 adj->dischanges[level - 1] = 0;
87 for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
jardineb5d44e2003-12-23 08:09:43 +000088 {
hassof390d2c2004-09-10 20:48:21 +000089 adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
jardineb5d44e2003-12-23 08:09:43 +000090 = ISIS_UNKNOWN_DIS;
hassof390d2c2004-09-10 20:48:21 +000091 adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
92 = time (NULL);
jardineb5d44e2003-12-23 08:09:43 +000093 }
hassof390d2c2004-09-10 20:48:21 +000094 }
jardineb5d44e2003-12-23 08:09:43 +000095
96 return adj;
97}
98
99struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000100isis_adj_lookup (u_char * sysid, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000101{
102 struct isis_adjacency *adj;
103 struct listnode *node;
104
paul1eb8ef22005-04-07 07:30:20 +0000105 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
106 if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
107 return adj;
hassof390d2c2004-09-10 20:48:21 +0000108
jardineb5d44e2003-12-23 08:09:43 +0000109 return NULL;
110}
111
jardineb5d44e2003-12-23 08:09:43 +0000112struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000113isis_adj_lookup_snpa (u_char * ssnpa, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000114{
115 struct listnode *node;
116 struct isis_adjacency *adj;
117
paul1eb8ef22005-04-07 07:30:20 +0000118 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
119 if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
120 return adj;
hassof390d2c2004-09-10 20:48:21 +0000121
jardineb5d44e2003-12-23 08:09:43 +0000122 return NULL;
123}
124
hassof390d2c2004-09-10 20:48:21 +0000125void
jardineb5d44e2003-12-23 08:09:43 +0000126isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
127{
hasso3fdb2dd2005-09-28 18:45:54 +0000128 if (!adj)
129 return;
130 /* When we recieve a NULL list, we will know its p2p. */
hassof390d2c2004-09-10 20:48:21 +0000131 if (adjdb)
hasso3fdb2dd2005-09-28 18:45:54 +0000132 listnode_delete (adjdb, adj);
hassof390d2c2004-09-10 20:48:21 +0000133
hasso13fb40a2005-10-01 06:03:04 +0000134 THREAD_OFF (adj->t_expire);
135
jardineb5d44e2003-12-23 08:09:43 +0000136 if (adj->ipv4_addrs)
137 list_delete (adj->ipv4_addrs);
138#ifdef HAVE_IPV6
139 if (adj->ipv6_addrs)
140 list_delete (adj->ipv6_addrs);
141#endif
hasso3fdb2dd2005-09-28 18:45:54 +0000142
143 XFREE (MTYPE_ISIS_ADJACENCY, adj);
jardineb5d44e2003-12-23 08:09:43 +0000144 return;
145}
146
hassof390d2c2004-09-10 20:48:21 +0000147void
148isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
hasso1cd80842004-10-07 20:07:40 +0000149 const char *reason)
jardineb5d44e2003-12-23 08:09:43 +0000150{
151 int old_state;
152 int level = adj->level;
153 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000154
jardineb5d44e2003-12-23 08:09:43 +0000155 old_state = adj->adj_state;
156 adj->adj_state = state;
157
158 circuit = adj->circuit;
jardineb5d44e2003-12-23 08:09:43 +0000159
hassof390d2c2004-09-10 20:48:21 +0000160 if (isis->debugs & DEBUG_ADJ_PACKETS)
161 {
hasso529d65b2004-12-24 00:14:50 +0000162 zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
hassof390d2c2004-09-10 20:48:21 +0000163 circuit->area->area_tag,
164 old_state, state, reason ? reason : "unspecified");
jardineb5d44e2003-12-23 08:09:43 +0000165 }
166
hassof390d2c2004-09-10 20:48:21 +0000167 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
168 {
169 if (state == ISIS_ADJ_UP)
170 circuit->upadjcount[level - 1]++;
171 if (state == ISIS_ADJ_DOWN)
172 {
173 isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
174 circuit->upadjcount[level - 1]--;
175 }
jardineb5d44e2003-12-23 08:09:43 +0000176
hassof390d2c2004-09-10 20:48:21 +0000177 list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
178 isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
179 circuit->u.bc.lan_neighs[level - 1]);
180 }
181 else if (state == ISIS_ADJ_UP)
182 { /* p2p interface */
183 if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
184 send_hello (circuit, 1);
185
186 /* update counter & timers for debugging purposes */
187 adj->last_flap = time (NULL);
188 adj->flaps++;
189
190 /* 7.3.17 - going up on P2P -> send CSNP */
191 /* FIXME: yup, I know its wrong... but i will do it! (for now) */
192 send_csnp (circuit, 1);
193 send_csnp (circuit, 2);
194 }
195 else if (state == ISIS_ADJ_DOWN)
196 { /* p2p interface */
197 adj->circuit->u.p2p.neighbor = NULL;
198 isis_delete_adj (adj, NULL);
199 }
jardineb5d44e2003-12-23 08:09:43 +0000200 return;
201}
202
203
204void
205isis_adj_print (struct isis_adjacency *adj)
206{
207 struct isis_dynhn *dyn;
208 struct listnode *node;
209 struct in_addr *ipv4_addr;
hassof390d2c2004-09-10 20:48:21 +0000210#ifdef HAVE_IPV6
jardineb5d44e2003-12-23 08:09:43 +0000211 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000212 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000213#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000214
215 if (!adj)
jardineb5d44e2003-12-23 08:09:43 +0000216 return;
217 dyn = dynhn_find_by_id (adj->sysid);
218 if (dyn)
hasso529d65b2004-12-24 00:14:50 +0000219 zlog_debug ("%s", dyn->name.name);
jardineb5d44e2003-12-23 08:09:43 +0000220
hasso529d65b2004-12-24 00:14:50 +0000221 zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
222 adj->sysid ? sysid_print (adj->sysid) : "unknown",
223 snpa_print (adj->snpa), adj->level, adj->hold_time);
hassof390d2c2004-09-10 20:48:21 +0000224 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
225 {
hasso529d65b2004-12-24 00:14:50 +0000226 zlog_debug ("IPv4 Addresses:");
hassof390d2c2004-09-10 20:48:21 +0000227
paul1eb8ef22005-04-07 07:30:20 +0000228 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
229 zlog_debug ("%s", inet_ntoa (*ipv4_addr));
jardineb5d44e2003-12-23 08:09:43 +0000230 }
hassof390d2c2004-09-10 20:48:21 +0000231
232#ifdef HAVE_IPV6
233 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
234 {
hasso529d65b2004-12-24 00:14:50 +0000235 zlog_debug ("IPv6 Addresses:");
paul1eb8ef22005-04-07 07:30:20 +0000236 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000237 {
hassof7c43dc2004-09-26 16:24:14 +0000238 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hasso529d65b2004-12-24 00:14:50 +0000239 zlog_debug ("%s", ip6);
hassof390d2c2004-09-10 20:48:21 +0000240 }
241 }
jardineb5d44e2003-12-23 08:09:43 +0000242#endif /* HAVE_IPV6 */
hasso529d65b2004-12-24 00:14:50 +0000243 zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
jardineb5d44e2003-12-23 08:09:43 +0000244
245 return;
246}
247
hassof390d2c2004-09-10 20:48:21 +0000248int
jardineb5d44e2003-12-23 08:09:43 +0000249isis_adj_expire (struct thread *thread)
250{
251 struct isis_adjacency *adj;
252 int level;
253
254 /*
255 * Get the adjacency
256 */
257 adj = THREAD_ARG (thread);
258 assert (adj);
259 level = adj->level;
hasso83fe45e2004-02-09 11:09:39 +0000260 adj->t_expire = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000261
262 /* trigger the adj expire event */
263 isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
264
265 return 0;
266}
267
hasso92365882005-01-18 13:53:33 +0000268static const char *
jardineb5d44e2003-12-23 08:09:43 +0000269adj_state2string (int state)
270{
hassof390d2c2004-09-10 20:48:21 +0000271
272 switch (state)
273 {
274 case ISIS_ADJ_INITIALIZING:
275 return "Initializing";
276 case ISIS_ADJ_UP:
277 return "Up";
278 case ISIS_ADJ_DOWN:
279 return "Down";
280 default:
281 return "Unknown";
282 }
283
284 return NULL; /* not reached */
jardineb5d44e2003-12-23 08:09:43 +0000285}
286
287/*
288 * show clns/isis neighbor (detail)
289 */
hasso92365882005-01-18 13:53:33 +0000290static void
jardineb5d44e2003-12-23 08:09:43 +0000291isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
292{
293
294#ifdef HAVE_IPV6
295 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000296 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000297#endif /* HAVE_IPV6 */
298 struct in_addr *ip_addr;
299 time_t now;
300 struct isis_dynhn *dyn;
301 int level;
302 struct listnode *node;
303
304 dyn = dynhn_find_by_id (adj->sysid);
305 if (dyn)
306 vty_out (vty, " %-20s", dyn->name.name);
hassof390d2c2004-09-10 20:48:21 +0000307 else if (adj->sysid)
308 {
309 vty_out (vty, " %-20s", sysid_print (adj->sysid));
jardineb5d44e2003-12-23 08:09:43 +0000310 }
hassof390d2c2004-09-10 20:48:21 +0000311 else
312 {
313 vty_out (vty, " unknown ");
jardineb5d44e2003-12-23 08:09:43 +0000314 }
hassof390d2c2004-09-10 20:48:21 +0000315
316 if (detail == ISIS_UI_LEVEL_BRIEF)
317 {
318 if (adj->circuit)
319 vty_out (vty, "%-12s", adj->circuit->interface->name);
320 else
321 vty_out (vty, "NULL circuit!");
322 vty_out (vty, "%-3u", adj->level); /* level */
323 vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
324 now = time (NULL);
325 if (adj->last_upd)
326 vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
327 else
328 vty_out (vty, "- ");
329 vty_out (vty, "%-10s", snpa_print (adj->snpa));
330 vty_out (vty, "%s", VTY_NEWLINE);
331 }
332
333 if (detail == ISIS_UI_LEVEL_DETAIL)
334 {
335 level = adj->level;
336 if (adj->circuit)
337 vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
338 else
339 vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
340 vty_out (vty, ", Level: %u", adj->level); /* level */
341 vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
342 now = time (NULL);
343 if (adj->last_upd)
344 vty_out (vty, ", Expires in %s",
345 time2string (adj->last_upd + adj->hold_time - now));
346 else
347 vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
348 vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
349 vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
350 vty_out (vty, "%s Circuit type: %s",
351 VTY_NEWLINE, circuit_t2string (adj->circuit_t));
352 vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
353 vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
354 dyn = dynhn_find_by_id (adj->lanid);
355 if (dyn)
356 vty_out (vty, ", LAN id: %s.%02x",
357 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
358 else
359 vty_out (vty, ", LAN id: %s.%02x",
360 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
361
362 vty_out (vty, "%s Priority: %u",
363 VTY_NEWLINE, adj->prio[adj->level - 1]);
364
365 vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
366 isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
367 dis), adj->dischanges[level - 1],
368 time2string (now -
369 (adj->dis_record[ISIS_LEVELS + level - 1].
370 last_dis_change)), VTY_NEWLINE);
371
372 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
373 {
374 vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000375 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
376 vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
hassof390d2c2004-09-10 20:48:21 +0000377 }
378#ifdef HAVE_IPV6
379 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
380 {
381 vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
hasso5d6e2692005-04-12 14:48:19 +0000382 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000383 {
hassof7c43dc2004-09-26 16:24:14 +0000384 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hassof390d2c2004-09-10 20:48:21 +0000385 vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
386 }
387 }
jardineb5d44e2003-12-23 08:09:43 +0000388#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000389 vty_out (vty, "%s", VTY_NEWLINE);
390 }
jardineb5d44e2003-12-23 08:09:43 +0000391 return;
392}
393
394void
hassof390d2c2004-09-10 20:48:21 +0000395isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
396{
jardineb5d44e2003-12-23 08:09:43 +0000397 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
398}
399
400void
hassof390d2c2004-09-10 20:48:21 +0000401isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
402{
jardineb5d44e2003-12-23 08:09:43 +0000403 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
404}
405
406void
hassof390d2c2004-09-10 20:48:21 +0000407isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
408{
jardineb5d44e2003-12-23 08:09:43 +0000409 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
410}
411
412void
413isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
414{
415 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
416}
417
hassof390d2c2004-09-10 20:48:21 +0000418void
419isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000420{
421 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
422}
423
hassof390d2c2004-09-10 20:48:21 +0000424void
jardineb5d44e2003-12-23 08:09:43 +0000425isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
426{
427 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
428}
429
430void
hassof390d2c2004-09-10 20:48:21 +0000431isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
432 void *), void *arg)
jardineb5d44e2003-12-23 08:09:43 +0000433{
paul1eb8ef22005-04-07 07:30:20 +0000434 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000435 struct isis_adjacency *adj;
paul1eb8ef22005-04-07 07:30:20 +0000436
437 for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
438 (*func) (adj, arg);
jardineb5d44e2003-12-23 08:09:43 +0000439}
440
441void
442isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
jardineb5d44e2003-12-23 08:09:43 +0000443{
444 struct isis_adjacency *adj;
445 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000446
447 if (!list)
448 {
449 zlog_warn ("isis_adj_build_neigh_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000450 return;
451 }
hassof390d2c2004-09-10 20:48:21 +0000452
paul1eb8ef22005-04-07 07:30:20 +0000453 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000454 {
hassof390d2c2004-09-10 20:48:21 +0000455 if (!adj)
456 {
457 zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
458 return;
459 }
460
461 if ((adj->adj_state == ISIS_ADJ_UP ||
462 adj->adj_state == ISIS_ADJ_INITIALIZING))
463 listnode_add (list, adj->snpa);
464 }
jardineb5d44e2003-12-23 08:09:43 +0000465 return;
466}
467
468void
469isis_adj_build_up_list (struct list *adjdb, struct list *list)
470{
471 struct isis_adjacency *adj;
472 struct listnode *node;
473
hassof390d2c2004-09-10 20:48:21 +0000474 if (!list)
475 {
476 zlog_warn ("isis_adj_build_up_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000477 return;
478 }
479
paul1eb8ef22005-04-07 07:30:20 +0000480 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000481 {
hassof390d2c2004-09-10 20:48:21 +0000482 if (!adj)
483 {
484 zlog_warn ("isis_adj_build_up_list(): NULL adj");
485 return;
486 }
487
488 if (adj->adj_state == ISIS_ADJ_UP)
489 listnode_add (list, adj);
490 }
491
jardineb5d44e2003-12-23 08:09:43 +0000492 return;
493}