blob: 3d847732c4d958c347120a240327249220a02b1b [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
112
113struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000114isis_adj_lookup_snpa (u_char * ssnpa, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000115{
116 struct listnode *node;
117 struct isis_adjacency *adj;
118
paul1eb8ef22005-04-07 07:30:20 +0000119 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
120 if (memcmp (adj->snpa, ssnpa, ETH_ALEN) == 0)
121 return adj;
hassof390d2c2004-09-10 20:48:21 +0000122
jardineb5d44e2003-12-23 08:09:43 +0000123 return NULL;
124}
125
126/*
127 * When we recieve a NULL list, we will know its p2p
128 */
hassof390d2c2004-09-10 20:48:21 +0000129void
jardineb5d44e2003-12-23 08:09:43 +0000130isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
131{
paul1eb8ef22005-04-07 07:30:20 +0000132 struct isis_adjacency *adj2 = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000133 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000134
135 if (adjdb)
136 {
paul1eb8ef22005-04-07 07:30:20 +0000137 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj2))
138 if (adj2 == adj)
139 break;
140
hassof390d2c2004-09-10 20:48:21 +0000141 listnode_delete (adjdb, adj);
jardineb5d44e2003-12-23 08:09:43 +0000142 }
hassof390d2c2004-09-10 20:48:21 +0000143
jardineb5d44e2003-12-23 08:09:43 +0000144 if (adj->ipv4_addrs)
145 list_delete (adj->ipv4_addrs);
146#ifdef HAVE_IPV6
147 if (adj->ipv6_addrs)
148 list_delete (adj->ipv6_addrs);
149#endif
hassof390d2c2004-09-10 20:48:21 +0000150 if (adj)
151 {
152 XFREE (MTYPE_ISIS_ADJACENCY, adj);
153 }
154 else
155 {
hasso529d65b2004-12-24 00:14:50 +0000156 zlog_warn ("tried to delete a non-existent adjacency");
hassof390d2c2004-09-10 20:48:21 +0000157 }
jardineb5d44e2003-12-23 08:09:43 +0000158
159 return;
160}
161
hassof390d2c2004-09-10 20:48:21 +0000162void
163isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
hasso1cd80842004-10-07 20:07:40 +0000164 const char *reason)
jardineb5d44e2003-12-23 08:09:43 +0000165{
166 int old_state;
167 int level = adj->level;
168 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000169
jardineb5d44e2003-12-23 08:09:43 +0000170 old_state = adj->adj_state;
171 adj->adj_state = state;
172
173 circuit = adj->circuit;
jardineb5d44e2003-12-23 08:09:43 +0000174
hassof390d2c2004-09-10 20:48:21 +0000175 if (isis->debugs & DEBUG_ADJ_PACKETS)
176 {
hasso529d65b2004-12-24 00:14:50 +0000177 zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
hassof390d2c2004-09-10 20:48:21 +0000178 circuit->area->area_tag,
179 old_state, state, reason ? reason : "unspecified");
jardineb5d44e2003-12-23 08:09:43 +0000180 }
181
hassof390d2c2004-09-10 20:48:21 +0000182 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
183 {
184 if (state == ISIS_ADJ_UP)
185 circuit->upadjcount[level - 1]++;
186 if (state == ISIS_ADJ_DOWN)
187 {
188 isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
189 circuit->upadjcount[level - 1]--;
190 }
jardineb5d44e2003-12-23 08:09:43 +0000191
hassof390d2c2004-09-10 20:48:21 +0000192 list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
193 isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
194 circuit->u.bc.lan_neighs[level - 1]);
195 }
196 else if (state == ISIS_ADJ_UP)
197 { /* p2p interface */
198 if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
199 send_hello (circuit, 1);
200
201 /* update counter & timers for debugging purposes */
202 adj->last_flap = time (NULL);
203 adj->flaps++;
204
205 /* 7.3.17 - going up on P2P -> send CSNP */
206 /* FIXME: yup, I know its wrong... but i will do it! (for now) */
207 send_csnp (circuit, 1);
208 send_csnp (circuit, 2);
209 }
210 else if (state == ISIS_ADJ_DOWN)
211 { /* p2p interface */
212 adj->circuit->u.p2p.neighbor = NULL;
213 isis_delete_adj (adj, NULL);
214 }
jardineb5d44e2003-12-23 08:09:43 +0000215 return;
216}
217
218
219void
220isis_adj_print (struct isis_adjacency *adj)
221{
222 struct isis_dynhn *dyn;
223 struct listnode *node;
224 struct in_addr *ipv4_addr;
hassof390d2c2004-09-10 20:48:21 +0000225#ifdef HAVE_IPV6
jardineb5d44e2003-12-23 08:09:43 +0000226 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000227 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000228#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000229
230 if (!adj)
jardineb5d44e2003-12-23 08:09:43 +0000231 return;
232 dyn = dynhn_find_by_id (adj->sysid);
233 if (dyn)
hasso529d65b2004-12-24 00:14:50 +0000234 zlog_debug ("%s", dyn->name.name);
jardineb5d44e2003-12-23 08:09:43 +0000235
hasso529d65b2004-12-24 00:14:50 +0000236 zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
237 adj->sysid ? sysid_print (adj->sysid) : "unknown",
238 snpa_print (adj->snpa), adj->level, adj->hold_time);
hassof390d2c2004-09-10 20:48:21 +0000239 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
240 {
hasso529d65b2004-12-24 00:14:50 +0000241 zlog_debug ("IPv4 Addresses:");
hassof390d2c2004-09-10 20:48:21 +0000242
paul1eb8ef22005-04-07 07:30:20 +0000243 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
244 zlog_debug ("%s", inet_ntoa (*ipv4_addr));
jardineb5d44e2003-12-23 08:09:43 +0000245 }
hassof390d2c2004-09-10 20:48:21 +0000246
247#ifdef HAVE_IPV6
248 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
249 {
hasso529d65b2004-12-24 00:14:50 +0000250 zlog_debug ("IPv6 Addresses:");
paul1eb8ef22005-04-07 07:30:20 +0000251 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000252 {
hassof7c43dc2004-09-26 16:24:14 +0000253 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hasso529d65b2004-12-24 00:14:50 +0000254 zlog_debug ("%s", ip6);
hassof390d2c2004-09-10 20:48:21 +0000255 }
256 }
jardineb5d44e2003-12-23 08:09:43 +0000257#endif /* HAVE_IPV6 */
hasso529d65b2004-12-24 00:14:50 +0000258 zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
jardineb5d44e2003-12-23 08:09:43 +0000259
260 return;
261}
262
hassof390d2c2004-09-10 20:48:21 +0000263int
jardineb5d44e2003-12-23 08:09:43 +0000264isis_adj_expire (struct thread *thread)
265{
266 struct isis_adjacency *adj;
267 int level;
268
269 /*
270 * Get the adjacency
271 */
272 adj = THREAD_ARG (thread);
273 assert (adj);
274 level = adj->level;
hasso83fe45e2004-02-09 11:09:39 +0000275 adj->t_expire = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000276
277 /* trigger the adj expire event */
278 isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
279
280 return 0;
281}
282
hasso92365882005-01-18 13:53:33 +0000283static const char *
jardineb5d44e2003-12-23 08:09:43 +0000284adj_state2string (int state)
285{
hassof390d2c2004-09-10 20:48:21 +0000286
287 switch (state)
288 {
289 case ISIS_ADJ_INITIALIZING:
290 return "Initializing";
291 case ISIS_ADJ_UP:
292 return "Up";
293 case ISIS_ADJ_DOWN:
294 return "Down";
295 default:
296 return "Unknown";
297 }
298
299 return NULL; /* not reached */
jardineb5d44e2003-12-23 08:09:43 +0000300}
301
302/*
303 * show clns/isis neighbor (detail)
304 */
hasso92365882005-01-18 13:53:33 +0000305static void
jardineb5d44e2003-12-23 08:09:43 +0000306isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
307{
308
309#ifdef HAVE_IPV6
310 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000311 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000312#endif /* HAVE_IPV6 */
313 struct in_addr *ip_addr;
314 time_t now;
315 struct isis_dynhn *dyn;
316 int level;
317 struct listnode *node;
318
319 dyn = dynhn_find_by_id (adj->sysid);
320 if (dyn)
321 vty_out (vty, " %-20s", dyn->name.name);
hassof390d2c2004-09-10 20:48:21 +0000322 else if (adj->sysid)
323 {
324 vty_out (vty, " %-20s", sysid_print (adj->sysid));
jardineb5d44e2003-12-23 08:09:43 +0000325 }
hassof390d2c2004-09-10 20:48:21 +0000326 else
327 {
328 vty_out (vty, " unknown ");
jardineb5d44e2003-12-23 08:09:43 +0000329 }
hassof390d2c2004-09-10 20:48:21 +0000330
331 if (detail == ISIS_UI_LEVEL_BRIEF)
332 {
333 if (adj->circuit)
334 vty_out (vty, "%-12s", adj->circuit->interface->name);
335 else
336 vty_out (vty, "NULL circuit!");
337 vty_out (vty, "%-3u", adj->level); /* level */
338 vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
339 now = time (NULL);
340 if (adj->last_upd)
341 vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
342 else
343 vty_out (vty, "- ");
344 vty_out (vty, "%-10s", snpa_print (adj->snpa));
345 vty_out (vty, "%s", VTY_NEWLINE);
346 }
347
348 if (detail == ISIS_UI_LEVEL_DETAIL)
349 {
350 level = adj->level;
351 if (adj->circuit)
352 vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
353 else
354 vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
355 vty_out (vty, ", Level: %u", adj->level); /* level */
356 vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
357 now = time (NULL);
358 if (adj->last_upd)
359 vty_out (vty, ", Expires in %s",
360 time2string (adj->last_upd + adj->hold_time - now));
361 else
362 vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
363 vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
364 vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
365 vty_out (vty, "%s Circuit type: %s",
366 VTY_NEWLINE, circuit_t2string (adj->circuit_t));
367 vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
368 vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
369 dyn = dynhn_find_by_id (adj->lanid);
370 if (dyn)
371 vty_out (vty, ", LAN id: %s.%02x",
372 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
373 else
374 vty_out (vty, ", LAN id: %s.%02x",
375 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
376
377 vty_out (vty, "%s Priority: %u",
378 VTY_NEWLINE, adj->prio[adj->level - 1]);
379
380 vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
381 isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
382 dis), adj->dischanges[level - 1],
383 time2string (now -
384 (adj->dis_record[ISIS_LEVELS + level - 1].
385 last_dis_change)), VTY_NEWLINE);
386
387 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
388 {
389 vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000390 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
391 vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
hassof390d2c2004-09-10 20:48:21 +0000392 }
393#ifdef HAVE_IPV6
394 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
395 {
396 vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
hasso5d6e2692005-04-12 14:48:19 +0000397 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000398 {
hassof7c43dc2004-09-26 16:24:14 +0000399 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hassof390d2c2004-09-10 20:48:21 +0000400 vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
401 }
402 }
jardineb5d44e2003-12-23 08:09:43 +0000403#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000404 vty_out (vty, "%s", VTY_NEWLINE);
405 }
jardineb5d44e2003-12-23 08:09:43 +0000406 return;
407}
408
409void
hassof390d2c2004-09-10 20:48:21 +0000410isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
411{
jardineb5d44e2003-12-23 08:09:43 +0000412 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
413}
414
415void
hassof390d2c2004-09-10 20:48:21 +0000416isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
417{
jardineb5d44e2003-12-23 08:09:43 +0000418 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
419}
420
421void
hassof390d2c2004-09-10 20:48:21 +0000422isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
423{
jardineb5d44e2003-12-23 08:09:43 +0000424 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
425}
426
427void
428isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
429{
430 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
431}
432
hassof390d2c2004-09-10 20:48:21 +0000433void
434isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000435{
436 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
437}
438
hassof390d2c2004-09-10 20:48:21 +0000439void
jardineb5d44e2003-12-23 08:09:43 +0000440isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
441{
442 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
443}
444
445void
hassof390d2c2004-09-10 20:48:21 +0000446isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
447 void *), void *arg)
jardineb5d44e2003-12-23 08:09:43 +0000448{
paul1eb8ef22005-04-07 07:30:20 +0000449 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000450 struct isis_adjacency *adj;
paul1eb8ef22005-04-07 07:30:20 +0000451
452 for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
453 (*func) (adj, arg);
jardineb5d44e2003-12-23 08:09:43 +0000454}
455
456void
457isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
jardineb5d44e2003-12-23 08:09:43 +0000458{
459 struct isis_adjacency *adj;
460 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000461
462 if (!list)
463 {
464 zlog_warn ("isis_adj_build_neigh_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000465 return;
466 }
hassof390d2c2004-09-10 20:48:21 +0000467
paul1eb8ef22005-04-07 07:30:20 +0000468 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000469 {
hassof390d2c2004-09-10 20:48:21 +0000470 if (!adj)
471 {
472 zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
473 return;
474 }
475
476 if ((adj->adj_state == ISIS_ADJ_UP ||
477 adj->adj_state == ISIS_ADJ_INITIALIZING))
478 listnode_add (list, adj->snpa);
479 }
jardineb5d44e2003-12-23 08:09:43 +0000480 return;
481}
482
483void
484isis_adj_build_up_list (struct list *adjdb, struct list *list)
485{
486 struct isis_adjacency *adj;
487 struct listnode *node;
488
hassof390d2c2004-09-10 20:48:21 +0000489 if (!list)
490 {
491 zlog_warn ("isis_adj_build_up_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000492 return;
493 }
494
paul1eb8ef22005-04-07 07:30:20 +0000495 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000496 {
hassof390d2c2004-09-10 20:48:21 +0000497 if (!adj)
498 {
499 zlog_warn ("isis_adj_build_up_list(): NULL adj");
500 return;
501 }
502
503 if (adj->adj_state == ISIS_ADJ_UP)
504 listnode_add (list, adj);
505 }
506
jardineb5d44e2003-12-23 08:09:43 +0000507 return;
508}