blob: a898f24ba9998a3309553e86400f51a56b022565 [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
jardineb5d44e2003-12-23 08:09:43 +0000134 if (adj->ipv4_addrs)
135 list_delete (adj->ipv4_addrs);
136#ifdef HAVE_IPV6
137 if (adj->ipv6_addrs)
138 list_delete (adj->ipv6_addrs);
139#endif
hasso3fdb2dd2005-09-28 18:45:54 +0000140
141 XFREE (MTYPE_ISIS_ADJACENCY, adj);
jardineb5d44e2003-12-23 08:09:43 +0000142 return;
143}
144
hassof390d2c2004-09-10 20:48:21 +0000145void
146isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
hasso1cd80842004-10-07 20:07:40 +0000147 const char *reason)
jardineb5d44e2003-12-23 08:09:43 +0000148{
149 int old_state;
150 int level = adj->level;
151 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000152
jardineb5d44e2003-12-23 08:09:43 +0000153 old_state = adj->adj_state;
154 adj->adj_state = state;
155
156 circuit = adj->circuit;
jardineb5d44e2003-12-23 08:09:43 +0000157
hassof390d2c2004-09-10 20:48:21 +0000158 if (isis->debugs & DEBUG_ADJ_PACKETS)
159 {
hasso529d65b2004-12-24 00:14:50 +0000160 zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
hassof390d2c2004-09-10 20:48:21 +0000161 circuit->area->area_tag,
162 old_state, state, reason ? reason : "unspecified");
jardineb5d44e2003-12-23 08:09:43 +0000163 }
164
hassof390d2c2004-09-10 20:48:21 +0000165 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
166 {
167 if (state == ISIS_ADJ_UP)
168 circuit->upadjcount[level - 1]++;
169 if (state == ISIS_ADJ_DOWN)
170 {
171 isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
172 circuit->upadjcount[level - 1]--;
173 }
jardineb5d44e2003-12-23 08:09:43 +0000174
hassof390d2c2004-09-10 20:48:21 +0000175 list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
176 isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
177 circuit->u.bc.lan_neighs[level - 1]);
178 }
179 else if (state == ISIS_ADJ_UP)
180 { /* p2p interface */
181 if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
182 send_hello (circuit, 1);
183
184 /* update counter & timers for debugging purposes */
185 adj->last_flap = time (NULL);
186 adj->flaps++;
187
188 /* 7.3.17 - going up on P2P -> send CSNP */
189 /* FIXME: yup, I know its wrong... but i will do it! (for now) */
190 send_csnp (circuit, 1);
191 send_csnp (circuit, 2);
192 }
193 else if (state == ISIS_ADJ_DOWN)
194 { /* p2p interface */
195 adj->circuit->u.p2p.neighbor = NULL;
196 isis_delete_adj (adj, NULL);
197 }
jardineb5d44e2003-12-23 08:09:43 +0000198 return;
199}
200
201
202void
203isis_adj_print (struct isis_adjacency *adj)
204{
205 struct isis_dynhn *dyn;
206 struct listnode *node;
207 struct in_addr *ipv4_addr;
hassof390d2c2004-09-10 20:48:21 +0000208#ifdef HAVE_IPV6
jardineb5d44e2003-12-23 08:09:43 +0000209 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000210 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000211#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000212
213 if (!adj)
jardineb5d44e2003-12-23 08:09:43 +0000214 return;
215 dyn = dynhn_find_by_id (adj->sysid);
216 if (dyn)
hasso529d65b2004-12-24 00:14:50 +0000217 zlog_debug ("%s", dyn->name.name);
jardineb5d44e2003-12-23 08:09:43 +0000218
hasso529d65b2004-12-24 00:14:50 +0000219 zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
220 adj->sysid ? sysid_print (adj->sysid) : "unknown",
221 snpa_print (adj->snpa), adj->level, adj->hold_time);
hassof390d2c2004-09-10 20:48:21 +0000222 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
223 {
hasso529d65b2004-12-24 00:14:50 +0000224 zlog_debug ("IPv4 Addresses:");
hassof390d2c2004-09-10 20:48:21 +0000225
paul1eb8ef22005-04-07 07:30:20 +0000226 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
227 zlog_debug ("%s", inet_ntoa (*ipv4_addr));
jardineb5d44e2003-12-23 08:09:43 +0000228 }
hassof390d2c2004-09-10 20:48:21 +0000229
230#ifdef HAVE_IPV6
231 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
232 {
hasso529d65b2004-12-24 00:14:50 +0000233 zlog_debug ("IPv6 Addresses:");
paul1eb8ef22005-04-07 07:30:20 +0000234 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000235 {
hassof7c43dc2004-09-26 16:24:14 +0000236 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hasso529d65b2004-12-24 00:14:50 +0000237 zlog_debug ("%s", ip6);
hassof390d2c2004-09-10 20:48:21 +0000238 }
239 }
jardineb5d44e2003-12-23 08:09:43 +0000240#endif /* HAVE_IPV6 */
hasso529d65b2004-12-24 00:14:50 +0000241 zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
jardineb5d44e2003-12-23 08:09:43 +0000242
243 return;
244}
245
hassof390d2c2004-09-10 20:48:21 +0000246int
jardineb5d44e2003-12-23 08:09:43 +0000247isis_adj_expire (struct thread *thread)
248{
249 struct isis_adjacency *adj;
250 int level;
251
252 /*
253 * Get the adjacency
254 */
255 adj = THREAD_ARG (thread);
256 assert (adj);
257 level = adj->level;
hasso83fe45e2004-02-09 11:09:39 +0000258 adj->t_expire = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000259
260 /* trigger the adj expire event */
261 isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
262
263 return 0;
264}
265
hasso92365882005-01-18 13:53:33 +0000266static const char *
jardineb5d44e2003-12-23 08:09:43 +0000267adj_state2string (int state)
268{
hassof390d2c2004-09-10 20:48:21 +0000269
270 switch (state)
271 {
272 case ISIS_ADJ_INITIALIZING:
273 return "Initializing";
274 case ISIS_ADJ_UP:
275 return "Up";
276 case ISIS_ADJ_DOWN:
277 return "Down";
278 default:
279 return "Unknown";
280 }
281
282 return NULL; /* not reached */
jardineb5d44e2003-12-23 08:09:43 +0000283}
284
285/*
286 * show clns/isis neighbor (detail)
287 */
hasso92365882005-01-18 13:53:33 +0000288static void
jardineb5d44e2003-12-23 08:09:43 +0000289isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
290{
291
292#ifdef HAVE_IPV6
293 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000294 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000295#endif /* HAVE_IPV6 */
296 struct in_addr *ip_addr;
297 time_t now;
298 struct isis_dynhn *dyn;
299 int level;
300 struct listnode *node;
301
302 dyn = dynhn_find_by_id (adj->sysid);
303 if (dyn)
304 vty_out (vty, " %-20s", dyn->name.name);
hassof390d2c2004-09-10 20:48:21 +0000305 else if (adj->sysid)
306 {
307 vty_out (vty, " %-20s", sysid_print (adj->sysid));
jardineb5d44e2003-12-23 08:09:43 +0000308 }
hassof390d2c2004-09-10 20:48:21 +0000309 else
310 {
311 vty_out (vty, " unknown ");
jardineb5d44e2003-12-23 08:09:43 +0000312 }
hassof390d2c2004-09-10 20:48:21 +0000313
314 if (detail == ISIS_UI_LEVEL_BRIEF)
315 {
316 if (adj->circuit)
317 vty_out (vty, "%-12s", adj->circuit->interface->name);
318 else
319 vty_out (vty, "NULL circuit!");
320 vty_out (vty, "%-3u", adj->level); /* level */
321 vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
322 now = time (NULL);
323 if (adj->last_upd)
324 vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
325 else
326 vty_out (vty, "- ");
327 vty_out (vty, "%-10s", snpa_print (adj->snpa));
328 vty_out (vty, "%s", VTY_NEWLINE);
329 }
330
331 if (detail == ISIS_UI_LEVEL_DETAIL)
332 {
333 level = adj->level;
334 if (adj->circuit)
335 vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
336 else
337 vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
338 vty_out (vty, ", Level: %u", adj->level); /* level */
339 vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
340 now = time (NULL);
341 if (adj->last_upd)
342 vty_out (vty, ", Expires in %s",
343 time2string (adj->last_upd + adj->hold_time - now));
344 else
345 vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
346 vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
347 vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
348 vty_out (vty, "%s Circuit type: %s",
349 VTY_NEWLINE, circuit_t2string (adj->circuit_t));
350 vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
351 vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
352 dyn = dynhn_find_by_id (adj->lanid);
353 if (dyn)
354 vty_out (vty, ", LAN id: %s.%02x",
355 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
356 else
357 vty_out (vty, ", LAN id: %s.%02x",
358 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
359
360 vty_out (vty, "%s Priority: %u",
361 VTY_NEWLINE, adj->prio[adj->level - 1]);
362
363 vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
364 isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
365 dis), adj->dischanges[level - 1],
366 time2string (now -
367 (adj->dis_record[ISIS_LEVELS + level - 1].
368 last_dis_change)), VTY_NEWLINE);
369
370 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
371 {
372 vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000373 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
374 vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
hassof390d2c2004-09-10 20:48:21 +0000375 }
376#ifdef HAVE_IPV6
377 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
378 {
379 vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
hasso5d6e2692005-04-12 14:48:19 +0000380 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000381 {
hassof7c43dc2004-09-26 16:24:14 +0000382 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hassof390d2c2004-09-10 20:48:21 +0000383 vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
384 }
385 }
jardineb5d44e2003-12-23 08:09:43 +0000386#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000387 vty_out (vty, "%s", VTY_NEWLINE);
388 }
jardineb5d44e2003-12-23 08:09:43 +0000389 return;
390}
391
392void
hassof390d2c2004-09-10 20:48:21 +0000393isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
394{
jardineb5d44e2003-12-23 08:09:43 +0000395 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
396}
397
398void
hassof390d2c2004-09-10 20:48:21 +0000399isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
400{
jardineb5d44e2003-12-23 08:09:43 +0000401 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
402}
403
404void
hassof390d2c2004-09-10 20:48:21 +0000405isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
406{
jardineb5d44e2003-12-23 08:09:43 +0000407 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
408}
409
410void
411isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
412{
413 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
414}
415
hassof390d2c2004-09-10 20:48:21 +0000416void
417isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000418{
419 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
420}
421
hassof390d2c2004-09-10 20:48:21 +0000422void
jardineb5d44e2003-12-23 08:09:43 +0000423isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
424{
425 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
426}
427
428void
hassof390d2c2004-09-10 20:48:21 +0000429isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
430 void *), void *arg)
jardineb5d44e2003-12-23 08:09:43 +0000431{
paul1eb8ef22005-04-07 07:30:20 +0000432 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000433 struct isis_adjacency *adj;
paul1eb8ef22005-04-07 07:30:20 +0000434
435 for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
436 (*func) (adj, arg);
jardineb5d44e2003-12-23 08:09:43 +0000437}
438
439void
440isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
jardineb5d44e2003-12-23 08:09:43 +0000441{
442 struct isis_adjacency *adj;
443 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000444
445 if (!list)
446 {
447 zlog_warn ("isis_adj_build_neigh_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000448 return;
449 }
hassof390d2c2004-09-10 20:48:21 +0000450
paul1eb8ef22005-04-07 07:30:20 +0000451 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000452 {
hassof390d2c2004-09-10 20:48:21 +0000453 if (!adj)
454 {
455 zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
456 return;
457 }
458
459 if ((adj->adj_state == ISIS_ADJ_UP ||
460 adj->adj_state == ISIS_ADJ_INITIALIZING))
461 listnode_add (list, adj->snpa);
462 }
jardineb5d44e2003-12-23 08:09:43 +0000463 return;
464}
465
466void
467isis_adj_build_up_list (struct list *adjdb, struct list *list)
468{
469 struct isis_adjacency *adj;
470 struct listnode *node;
471
hassof390d2c2004-09-10 20:48:21 +0000472 if (!list)
473 {
474 zlog_warn ("isis_adj_build_up_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000475 return;
476 }
477
paul1eb8ef22005-04-07 07:30:20 +0000478 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000479 {
hassof390d2c2004-09-10 20:48:21 +0000480 if (!adj)
481 {
482 zlog_warn ("isis_adj_build_up_list(): NULL adj");
483 return;
484 }
485
486 if (adj->adj_state == ISIS_ADJ_UP)
487 listnode_add (list, adj);
488 }
489
jardineb5d44e2003-12-23 08:09:43 +0000490 return;
491}