blob: d8c7448e8343074f43fb22bf75707187b4dbca03 [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
75 memcpy (adj->snpa, snpa, 6);
76 adj->circuit = circuit;
77 adj->level = level;
78 adj->flaps = 0;
79 adj->last_flap = time (NULL);
hassof390d2c2004-09-10 20:48:21 +000080 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
81 {
82 listnode_add (circuit->u.bc.adjdb[level - 1], adj);
83 adj->dischanges[level - 1] = 0;
84 for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
jardineb5d44e2003-12-23 08:09:43 +000085 {
hassof390d2c2004-09-10 20:48:21 +000086 adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
jardineb5d44e2003-12-23 08:09:43 +000087 = ISIS_UNKNOWN_DIS;
hassof390d2c2004-09-10 20:48:21 +000088 adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
89 = time (NULL);
jardineb5d44e2003-12-23 08:09:43 +000090 }
hassof390d2c2004-09-10 20:48:21 +000091 }
jardineb5d44e2003-12-23 08:09:43 +000092
93 return adj;
94}
95
96struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +000097isis_adj_lookup (u_char * sysid, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +000098{
99 struct isis_adjacency *adj;
100 struct listnode *node;
101
paul1eb8ef22005-04-07 07:30:20 +0000102 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
103 if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
104 return adj;
hassof390d2c2004-09-10 20:48:21 +0000105
jardineb5d44e2003-12-23 08:09:43 +0000106 return NULL;
107}
108
jardineb5d44e2003-12-23 08:09:43 +0000109struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000110isis_adj_lookup_snpa (u_char * ssnpa, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000111{
112 struct listnode *node;
113 struct isis_adjacency *adj;
114
paul1eb8ef22005-04-07 07:30:20 +0000115 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
116 if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
117 return adj;
hassof390d2c2004-09-10 20:48:21 +0000118
jardineb5d44e2003-12-23 08:09:43 +0000119 return NULL;
120}
121
hassof390d2c2004-09-10 20:48:21 +0000122void
jardineb5d44e2003-12-23 08:09:43 +0000123isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
124{
hasso3fdb2dd2005-09-28 18:45:54 +0000125 if (!adj)
126 return;
127 /* When we recieve a NULL list, we will know its p2p. */
hassof390d2c2004-09-10 20:48:21 +0000128 if (adjdb)
hasso3fdb2dd2005-09-28 18:45:54 +0000129 listnode_delete (adjdb, adj);
hassof390d2c2004-09-10 20:48:21 +0000130
hasso13fb40a2005-10-01 06:03:04 +0000131 THREAD_OFF (adj->t_expire);
132
jardineb5d44e2003-12-23 08:09:43 +0000133 if (adj->ipv4_addrs)
134 list_delete (adj->ipv4_addrs);
135#ifdef HAVE_IPV6
136 if (adj->ipv6_addrs)
137 list_delete (adj->ipv6_addrs);
138#endif
hasso3fdb2dd2005-09-28 18:45:54 +0000139
140 XFREE (MTYPE_ISIS_ADJACENCY, adj);
jardineb5d44e2003-12-23 08:09:43 +0000141 return;
142}
143
hassof390d2c2004-09-10 20:48:21 +0000144void
145isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
hasso1cd80842004-10-07 20:07:40 +0000146 const char *reason)
jardineb5d44e2003-12-23 08:09:43 +0000147{
148 int old_state;
149 int level = adj->level;
150 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000151
jardineb5d44e2003-12-23 08:09:43 +0000152 old_state = adj->adj_state;
153 adj->adj_state = state;
154
155 circuit = adj->circuit;
jardineb5d44e2003-12-23 08:09:43 +0000156
hassof390d2c2004-09-10 20:48:21 +0000157 if (isis->debugs & DEBUG_ADJ_PACKETS)
158 {
hasso529d65b2004-12-24 00:14:50 +0000159 zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
hassof390d2c2004-09-10 20:48:21 +0000160 circuit->area->area_tag,
161 old_state, state, reason ? reason : "unspecified");
jardineb5d44e2003-12-23 08:09:43 +0000162 }
163
hassof390d2c2004-09-10 20:48:21 +0000164 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
165 {
166 if (state == ISIS_ADJ_UP)
167 circuit->upadjcount[level - 1]++;
168 if (state == ISIS_ADJ_DOWN)
169 {
170 isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
171 circuit->upadjcount[level - 1]--;
172 }
jardineb5d44e2003-12-23 08:09:43 +0000173
hassof390d2c2004-09-10 20:48:21 +0000174 list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
175 isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
176 circuit->u.bc.lan_neighs[level - 1]);
177 }
178 else if (state == ISIS_ADJ_UP)
179 { /* p2p interface */
180 if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
181 send_hello (circuit, 1);
182
183 /* update counter & timers for debugging purposes */
184 adj->last_flap = time (NULL);
185 adj->flaps++;
186
187 /* 7.3.17 - going up on P2P -> send CSNP */
188 /* FIXME: yup, I know its wrong... but i will do it! (for now) */
189 send_csnp (circuit, 1);
190 send_csnp (circuit, 2);
191 }
192 else if (state == ISIS_ADJ_DOWN)
193 { /* p2p interface */
194 adj->circuit->u.p2p.neighbor = NULL;
195 isis_delete_adj (adj, NULL);
196 }
jardineb5d44e2003-12-23 08:09:43 +0000197 return;
198}
199
200
201void
202isis_adj_print (struct isis_adjacency *adj)
203{
204 struct isis_dynhn *dyn;
205 struct listnode *node;
206 struct in_addr *ipv4_addr;
hassof390d2c2004-09-10 20:48:21 +0000207#ifdef HAVE_IPV6
jardineb5d44e2003-12-23 08:09:43 +0000208 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000209 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000210#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000211
212 if (!adj)
jardineb5d44e2003-12-23 08:09:43 +0000213 return;
214 dyn = dynhn_find_by_id (adj->sysid);
215 if (dyn)
hasso529d65b2004-12-24 00:14:50 +0000216 zlog_debug ("%s", dyn->name.name);
jardineb5d44e2003-12-23 08:09:43 +0000217
hasso529d65b2004-12-24 00:14:50 +0000218 zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
219 adj->sysid ? sysid_print (adj->sysid) : "unknown",
220 snpa_print (adj->snpa), adj->level, adj->hold_time);
hassof390d2c2004-09-10 20:48:21 +0000221 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
222 {
hasso529d65b2004-12-24 00:14:50 +0000223 zlog_debug ("IPv4 Addresses:");
hassof390d2c2004-09-10 20:48:21 +0000224
paul1eb8ef22005-04-07 07:30:20 +0000225 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
226 zlog_debug ("%s", inet_ntoa (*ipv4_addr));
jardineb5d44e2003-12-23 08:09:43 +0000227 }
hassof390d2c2004-09-10 20:48:21 +0000228
229#ifdef HAVE_IPV6
230 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
231 {
hasso529d65b2004-12-24 00:14:50 +0000232 zlog_debug ("IPv6 Addresses:");
paul1eb8ef22005-04-07 07:30:20 +0000233 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000234 {
hassof7c43dc2004-09-26 16:24:14 +0000235 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hasso529d65b2004-12-24 00:14:50 +0000236 zlog_debug ("%s", ip6);
hassof390d2c2004-09-10 20:48:21 +0000237 }
238 }
jardineb5d44e2003-12-23 08:09:43 +0000239#endif /* HAVE_IPV6 */
hasso529d65b2004-12-24 00:14:50 +0000240 zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
jardineb5d44e2003-12-23 08:09:43 +0000241
242 return;
243}
244
hassof390d2c2004-09-10 20:48:21 +0000245int
jardineb5d44e2003-12-23 08:09:43 +0000246isis_adj_expire (struct thread *thread)
247{
248 struct isis_adjacency *adj;
249 int level;
250
251 /*
252 * Get the adjacency
253 */
254 adj = THREAD_ARG (thread);
255 assert (adj);
256 level = adj->level;
hasso83fe45e2004-02-09 11:09:39 +0000257 adj->t_expire = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000258
259 /* trigger the adj expire event */
260 isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
261
262 return 0;
263}
264
hasso92365882005-01-18 13:53:33 +0000265static const char *
jardineb5d44e2003-12-23 08:09:43 +0000266adj_state2string (int state)
267{
hassof390d2c2004-09-10 20:48:21 +0000268
269 switch (state)
270 {
271 case ISIS_ADJ_INITIALIZING:
272 return "Initializing";
273 case ISIS_ADJ_UP:
274 return "Up";
275 case ISIS_ADJ_DOWN:
276 return "Down";
277 default:
278 return "Unknown";
279 }
280
281 return NULL; /* not reached */
jardineb5d44e2003-12-23 08:09:43 +0000282}
283
284/*
285 * show clns/isis neighbor (detail)
286 */
hasso92365882005-01-18 13:53:33 +0000287static void
jardineb5d44e2003-12-23 08:09:43 +0000288isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
289{
290
291#ifdef HAVE_IPV6
292 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000293 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000294#endif /* HAVE_IPV6 */
295 struct in_addr *ip_addr;
296 time_t now;
297 struct isis_dynhn *dyn;
298 int level;
299 struct listnode *node;
300
301 dyn = dynhn_find_by_id (adj->sysid);
302 if (dyn)
303 vty_out (vty, " %-20s", dyn->name.name);
hassof390d2c2004-09-10 20:48:21 +0000304 else if (adj->sysid)
305 {
306 vty_out (vty, " %-20s", sysid_print (adj->sysid));
jardineb5d44e2003-12-23 08:09:43 +0000307 }
hassof390d2c2004-09-10 20:48:21 +0000308 else
309 {
310 vty_out (vty, " unknown ");
jardineb5d44e2003-12-23 08:09:43 +0000311 }
hassof390d2c2004-09-10 20:48:21 +0000312
313 if (detail == ISIS_UI_LEVEL_BRIEF)
314 {
315 if (adj->circuit)
316 vty_out (vty, "%-12s", adj->circuit->interface->name);
317 else
318 vty_out (vty, "NULL circuit!");
319 vty_out (vty, "%-3u", adj->level); /* level */
320 vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
321 now = time (NULL);
322 if (adj->last_upd)
323 vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
324 else
325 vty_out (vty, "- ");
326 vty_out (vty, "%-10s", snpa_print (adj->snpa));
327 vty_out (vty, "%s", VTY_NEWLINE);
328 }
329
330 if (detail == ISIS_UI_LEVEL_DETAIL)
331 {
332 level = adj->level;
333 if (adj->circuit)
334 vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
335 else
336 vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
337 vty_out (vty, ", Level: %u", adj->level); /* level */
338 vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
339 now = time (NULL);
340 if (adj->last_upd)
341 vty_out (vty, ", Expires in %s",
342 time2string (adj->last_upd + adj->hold_time - now));
343 else
344 vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
345 vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
346 vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
347 vty_out (vty, "%s Circuit type: %s",
348 VTY_NEWLINE, circuit_t2string (adj->circuit_t));
349 vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
350 vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
351 dyn = dynhn_find_by_id (adj->lanid);
352 if (dyn)
353 vty_out (vty, ", LAN id: %s.%02x",
354 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
355 else
356 vty_out (vty, ", LAN id: %s.%02x",
357 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
358
359 vty_out (vty, "%s Priority: %u",
360 VTY_NEWLINE, adj->prio[adj->level - 1]);
361
362 vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
363 isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
364 dis), adj->dischanges[level - 1],
365 time2string (now -
366 (adj->dis_record[ISIS_LEVELS + level - 1].
367 last_dis_change)), VTY_NEWLINE);
368
369 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
370 {
371 vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000372 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
373 vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
hassof390d2c2004-09-10 20:48:21 +0000374 }
375#ifdef HAVE_IPV6
376 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
377 {
378 vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
hasso5d6e2692005-04-12 14:48:19 +0000379 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000380 {
hassof7c43dc2004-09-26 16:24:14 +0000381 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hassof390d2c2004-09-10 20:48:21 +0000382 vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
383 }
384 }
jardineb5d44e2003-12-23 08:09:43 +0000385#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000386 vty_out (vty, "%s", VTY_NEWLINE);
387 }
jardineb5d44e2003-12-23 08:09:43 +0000388 return;
389}
390
391void
hassof390d2c2004-09-10 20:48:21 +0000392isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
393{
jardineb5d44e2003-12-23 08:09:43 +0000394 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
395}
396
397void
hassof390d2c2004-09-10 20:48:21 +0000398isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
399{
jardineb5d44e2003-12-23 08:09:43 +0000400 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
401}
402
403void
hassof390d2c2004-09-10 20:48:21 +0000404isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
405{
jardineb5d44e2003-12-23 08:09:43 +0000406 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
407}
408
409void
410isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
411{
412 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
413}
414
hassof390d2c2004-09-10 20:48:21 +0000415void
416isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000417{
418 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
419}
420
hassof390d2c2004-09-10 20:48:21 +0000421void
jardineb5d44e2003-12-23 08:09:43 +0000422isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
423{
424 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
425}
426
427void
hassof390d2c2004-09-10 20:48:21 +0000428isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
429 void *), void *arg)
jardineb5d44e2003-12-23 08:09:43 +0000430{
paul1eb8ef22005-04-07 07:30:20 +0000431 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000432 struct isis_adjacency *adj;
paul1eb8ef22005-04-07 07:30:20 +0000433
434 for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
435 (*func) (adj, arg);
jardineb5d44e2003-12-23 08:09:43 +0000436}
437
438void
439isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
jardineb5d44e2003-12-23 08:09:43 +0000440{
441 struct isis_adjacency *adj;
442 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000443
444 if (!list)
445 {
446 zlog_warn ("isis_adj_build_neigh_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000447 return;
448 }
hassof390d2c2004-09-10 20:48:21 +0000449
paul1eb8ef22005-04-07 07:30:20 +0000450 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000451 {
hassof390d2c2004-09-10 20:48:21 +0000452 if (!adj)
453 {
454 zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
455 return;
456 }
457
458 if ((adj->adj_state == ISIS_ADJ_UP ||
459 adj->adj_state == ISIS_ADJ_INITIALIZING))
460 listnode_add (list, adj->snpa);
461 }
jardineb5d44e2003-12-23 08:09:43 +0000462 return;
463}
464
465void
466isis_adj_build_up_list (struct list *adjdb, struct list *list)
467{
468 struct isis_adjacency *adj;
469 struct listnode *node;
470
hassof390d2c2004-09-10 20:48:21 +0000471 if (!list)
472 {
473 zlog_warn ("isis_adj_build_up_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000474 return;
475 }
476
paul1eb8ef22005-04-07 07:30:20 +0000477 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000478 {
hassof390d2c2004-09-10 20:48:21 +0000479 if (!adj)
480 {
481 zlog_warn ("isis_adj_build_up_list(): NULL adj");
482 return;
483 }
484
485 if (adj->adj_state == ISIS_ADJ_UP)
486 listnode_add (list, adj);
487 }
488
jardineb5d44e2003-12-23 08:09:43 +0000489 return;
490}