blob: af4e963b2e414daa00ca950d99beb0bcf00f2434 [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
hassof390d2c2004-09-10 20:48:21 +000057 adj = XMALLOC (MTYPE_ISIS_ADJACENCY, sizeof (struct isis_adjacency));
58 memset (adj, 0, sizeof (struct isis_adjacency));
59 memcpy (adj->sysid, id, ISIS_SYS_ID_LEN);
60
61 return adj;
jardineb5d44e2003-12-23 08:09:43 +000062}
63
64struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +000065isis_new_adj (u_char * id, u_char * snpa, int level,
jardineb5d44e2003-12-23 08:09:43 +000066 struct isis_circuit *circuit)
67{
jardineb5d44e2003-12-23 08:09:43 +000068 struct isis_adjacency *adj;
hassof390d2c2004-09-10 20:48:21 +000069 int i;
jardineb5d44e2003-12-23 08:09:43 +000070
hassof390d2c2004-09-10 20:48:21 +000071 adj = adj_alloc (id); /* P2P kludge */
72
73 if (adj == NULL)
74 {
75 zlog_err ("Out of memory!");
76 return NULL;
77 }
jardineb5d44e2003-12-23 08:09:43 +000078
79 memcpy (adj->snpa, snpa, 6);
80 adj->circuit = circuit;
81 adj->level = level;
82 adj->flaps = 0;
83 adj->last_flap = time (NULL);
hassof390d2c2004-09-10 20:48:21 +000084 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
85 {
86 listnode_add (circuit->u.bc.adjdb[level - 1], adj);
87 adj->dischanges[level - 1] = 0;
88 for (i = 0; i < DIS_RECORDS; i++) /* clear N DIS state change records */
jardineb5d44e2003-12-23 08:09:43 +000089 {
hassof390d2c2004-09-10 20:48:21 +000090 adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
jardineb5d44e2003-12-23 08:09:43 +000091 = ISIS_UNKNOWN_DIS;
hassof390d2c2004-09-10 20:48:21 +000092 adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
93 = time (NULL);
jardineb5d44e2003-12-23 08:09:43 +000094 }
hassof390d2c2004-09-10 20:48:21 +000095 }
jardineb5d44e2003-12-23 08:09:43 +000096
97 return adj;
98}
99
100struct isis_adjacency *
hassof390d2c2004-09-10 20:48:21 +0000101isis_adj_lookup (u_char * sysid, struct list *adjdb)
jardineb5d44e2003-12-23 08:09:43 +0000102{
103 struct isis_adjacency *adj;
104 struct listnode *node;
105
paul1eb8ef22005-04-07 07:30:20 +0000106 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
107 if (memcmp (adj->sysid, sysid, ISIS_SYS_ID_LEN) == 0)
108 return adj;
hassof390d2c2004-09-10 20:48:21 +0000109
jardineb5d44e2003-12-23 08:09:43 +0000110 return NULL;
111}
112
113
114struct 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
127/*
128 * When we recieve a NULL list, we will know its p2p
129 */
hassof390d2c2004-09-10 20:48:21 +0000130void
jardineb5d44e2003-12-23 08:09:43 +0000131isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)
132{
paul1eb8ef22005-04-07 07:30:20 +0000133 struct isis_adjacency *adj2 = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000134 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000135
136 if (adjdb)
137 {
paul1eb8ef22005-04-07 07:30:20 +0000138 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj2))
139 if (adj2 == adj)
140 break;
141
hassof390d2c2004-09-10 20:48:21 +0000142 listnode_delete (adjdb, adj);
jardineb5d44e2003-12-23 08:09:43 +0000143 }
hassof390d2c2004-09-10 20:48:21 +0000144
jardineb5d44e2003-12-23 08:09:43 +0000145 if (adj->ipv4_addrs)
146 list_delete (adj->ipv4_addrs);
147#ifdef HAVE_IPV6
148 if (adj->ipv6_addrs)
149 list_delete (adj->ipv6_addrs);
150#endif
hassof390d2c2004-09-10 20:48:21 +0000151 if (adj)
152 {
153 XFREE (MTYPE_ISIS_ADJACENCY, adj);
154 }
155 else
156 {
hasso529d65b2004-12-24 00:14:50 +0000157 zlog_warn ("tried to delete a non-existent adjacency");
hassof390d2c2004-09-10 20:48:21 +0000158 }
jardineb5d44e2003-12-23 08:09:43 +0000159
160 return;
161}
162
hassof390d2c2004-09-10 20:48:21 +0000163void
164isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,
hasso1cd80842004-10-07 20:07:40 +0000165 const char *reason)
jardineb5d44e2003-12-23 08:09:43 +0000166{
167 int old_state;
168 int level = adj->level;
169 struct isis_circuit *circuit;
hassof390d2c2004-09-10 20:48:21 +0000170
jardineb5d44e2003-12-23 08:09:43 +0000171 old_state = adj->adj_state;
172 adj->adj_state = state;
173
174 circuit = adj->circuit;
jardineb5d44e2003-12-23 08:09:43 +0000175
hassof390d2c2004-09-10 20:48:21 +0000176 if (isis->debugs & DEBUG_ADJ_PACKETS)
177 {
hasso529d65b2004-12-24 00:14:50 +0000178 zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
hassof390d2c2004-09-10 20:48:21 +0000179 circuit->area->area_tag,
180 old_state, state, reason ? reason : "unspecified");
jardineb5d44e2003-12-23 08:09:43 +0000181 }
182
hassof390d2c2004-09-10 20:48:21 +0000183 if (circuit->circ_type == CIRCUIT_T_BROADCAST)
184 {
185 if (state == ISIS_ADJ_UP)
186 circuit->upadjcount[level - 1]++;
187 if (state == ISIS_ADJ_DOWN)
188 {
189 isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);
190 circuit->upadjcount[level - 1]--;
191 }
jardineb5d44e2003-12-23 08:09:43 +0000192
hassof390d2c2004-09-10 20:48:21 +0000193 list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
194 isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
195 circuit->u.bc.lan_neighs[level - 1]);
196 }
197 else if (state == ISIS_ADJ_UP)
198 { /* p2p interface */
199 if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
200 send_hello (circuit, 1);
201
202 /* update counter & timers for debugging purposes */
203 adj->last_flap = time (NULL);
204 adj->flaps++;
205
206 /* 7.3.17 - going up on P2P -> send CSNP */
207 /* FIXME: yup, I know its wrong... but i will do it! (for now) */
208 send_csnp (circuit, 1);
209 send_csnp (circuit, 2);
210 }
211 else if (state == ISIS_ADJ_DOWN)
212 { /* p2p interface */
213 adj->circuit->u.p2p.neighbor = NULL;
214 isis_delete_adj (adj, NULL);
215 }
jardineb5d44e2003-12-23 08:09:43 +0000216 return;
217}
218
219
220void
221isis_adj_print (struct isis_adjacency *adj)
222{
223 struct isis_dynhn *dyn;
224 struct listnode *node;
225 struct in_addr *ipv4_addr;
hassof390d2c2004-09-10 20:48:21 +0000226#ifdef HAVE_IPV6
jardineb5d44e2003-12-23 08:09:43 +0000227 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000228 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000229#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000230
231 if (!adj)
jardineb5d44e2003-12-23 08:09:43 +0000232 return;
233 dyn = dynhn_find_by_id (adj->sysid);
234 if (dyn)
hasso529d65b2004-12-24 00:14:50 +0000235 zlog_debug ("%s", dyn->name.name);
jardineb5d44e2003-12-23 08:09:43 +0000236
hasso529d65b2004-12-24 00:14:50 +0000237 zlog_debug ("SystemId %20s SNPA %s, level %d\nHolding Time %d",
238 adj->sysid ? sysid_print (adj->sysid) : "unknown",
239 snpa_print (adj->snpa), adj->level, adj->hold_time);
hassof390d2c2004-09-10 20:48:21 +0000240 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
241 {
hasso529d65b2004-12-24 00:14:50 +0000242 zlog_debug ("IPv4 Addresses:");
hassof390d2c2004-09-10 20:48:21 +0000243
paul1eb8ef22005-04-07 07:30:20 +0000244 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
245 zlog_debug ("%s", inet_ntoa (*ipv4_addr));
jardineb5d44e2003-12-23 08:09:43 +0000246 }
hassof390d2c2004-09-10 20:48:21 +0000247
248#ifdef HAVE_IPV6
249 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
250 {
hasso529d65b2004-12-24 00:14:50 +0000251 zlog_debug ("IPv6 Addresses:");
paul1eb8ef22005-04-07 07:30:20 +0000252 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000253 {
hassof7c43dc2004-09-26 16:24:14 +0000254 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hasso529d65b2004-12-24 00:14:50 +0000255 zlog_debug ("%s", ip6);
hassof390d2c2004-09-10 20:48:21 +0000256 }
257 }
jardineb5d44e2003-12-23 08:09:43 +0000258#endif /* HAVE_IPV6 */
hasso529d65b2004-12-24 00:14:50 +0000259 zlog_debug ("Speaks: %s", nlpid2string (&adj->nlpids));
jardineb5d44e2003-12-23 08:09:43 +0000260
261 return;
262}
263
hassof390d2c2004-09-10 20:48:21 +0000264int
jardineb5d44e2003-12-23 08:09:43 +0000265isis_adj_expire (struct thread *thread)
266{
267 struct isis_adjacency *adj;
268 int level;
269
270 /*
271 * Get the adjacency
272 */
273 adj = THREAD_ARG (thread);
274 assert (adj);
275 level = adj->level;
hasso83fe45e2004-02-09 11:09:39 +0000276 adj->t_expire = NULL;
jardineb5d44e2003-12-23 08:09:43 +0000277
278 /* trigger the adj expire event */
279 isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired");
280
281 return 0;
282}
283
hasso92365882005-01-18 13:53:33 +0000284static const char *
jardineb5d44e2003-12-23 08:09:43 +0000285adj_state2string (int state)
286{
hassof390d2c2004-09-10 20:48:21 +0000287
288 switch (state)
289 {
290 case ISIS_ADJ_INITIALIZING:
291 return "Initializing";
292 case ISIS_ADJ_UP:
293 return "Up";
294 case ISIS_ADJ_DOWN:
295 return "Down";
296 default:
297 return "Unknown";
298 }
299
300 return NULL; /* not reached */
jardineb5d44e2003-12-23 08:09:43 +0000301}
302
303/*
304 * show clns/isis neighbor (detail)
305 */
hasso92365882005-01-18 13:53:33 +0000306static void
jardineb5d44e2003-12-23 08:09:43 +0000307isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)
308{
309
310#ifdef HAVE_IPV6
311 struct in6_addr *ipv6_addr;
hassof390d2c2004-09-10 20:48:21 +0000312 u_char ip6[INET6_ADDRSTRLEN];
jardineb5d44e2003-12-23 08:09:43 +0000313#endif /* HAVE_IPV6 */
314 struct in_addr *ip_addr;
315 time_t now;
316 struct isis_dynhn *dyn;
317 int level;
318 struct listnode *node;
319
320 dyn = dynhn_find_by_id (adj->sysid);
321 if (dyn)
322 vty_out (vty, " %-20s", dyn->name.name);
hassof390d2c2004-09-10 20:48:21 +0000323 else if (adj->sysid)
324 {
325 vty_out (vty, " %-20s", sysid_print (adj->sysid));
jardineb5d44e2003-12-23 08:09:43 +0000326 }
hassof390d2c2004-09-10 20:48:21 +0000327 else
328 {
329 vty_out (vty, " unknown ");
jardineb5d44e2003-12-23 08:09:43 +0000330 }
hassof390d2c2004-09-10 20:48:21 +0000331
332 if (detail == ISIS_UI_LEVEL_BRIEF)
333 {
334 if (adj->circuit)
335 vty_out (vty, "%-12s", adj->circuit->interface->name);
336 else
337 vty_out (vty, "NULL circuit!");
338 vty_out (vty, "%-3u", adj->level); /* level */
339 vty_out (vty, "%-13s", adj_state2string (adj->adj_state));
340 now = time (NULL);
341 if (adj->last_upd)
342 vty_out (vty, "%-9lu", adj->last_upd + adj->hold_time - now);
343 else
344 vty_out (vty, "- ");
345 vty_out (vty, "%-10s", snpa_print (adj->snpa));
346 vty_out (vty, "%s", VTY_NEWLINE);
347 }
348
349 if (detail == ISIS_UI_LEVEL_DETAIL)
350 {
351 level = adj->level;
352 if (adj->circuit)
353 vty_out (vty, "%s Interface: %s", VTY_NEWLINE, adj->circuit->interface->name); /* interface name */
354 else
355 vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);
356 vty_out (vty, ", Level: %u", adj->level); /* level */
357 vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
358 now = time (NULL);
359 if (adj->last_upd)
360 vty_out (vty, ", Expires in %s",
361 time2string (adj->last_upd + adj->hold_time - now));
362 else
363 vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
364 vty_out (vty, "%s Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);
365 vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
366 vty_out (vty, "%s Circuit type: %s",
367 VTY_NEWLINE, circuit_t2string (adj->circuit_t));
368 vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
369 vty_out (vty, "%s SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));
370 dyn = dynhn_find_by_id (adj->lanid);
371 if (dyn)
372 vty_out (vty, ", LAN id: %s.%02x",
373 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
374 else
375 vty_out (vty, ", LAN id: %s.%02x",
376 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
377
378 vty_out (vty, "%s Priority: %u",
379 VTY_NEWLINE, adj->prio[adj->level - 1]);
380
381 vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",
382 isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
383 dis), adj->dischanges[level - 1],
384 time2string (now -
385 (adj->dis_record[ISIS_LEVELS + level - 1].
386 last_dis_change)), VTY_NEWLINE);
387
388 if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
389 {
390 vty_out (vty, " IPv4 Addresses:%s", VTY_NEWLINE);
paul1eb8ef22005-04-07 07:30:20 +0000391 for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
392 vty_out (vty, " %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
hassof390d2c2004-09-10 20:48:21 +0000393 }
394#ifdef HAVE_IPV6
395 if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
396 {
397 vty_out (vty, " IPv6 Addresses:%s", VTY_NEWLINE);
hasso5d6e2692005-04-12 14:48:19 +0000398 for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
hassof390d2c2004-09-10 20:48:21 +0000399 {
hassof7c43dc2004-09-26 16:24:14 +0000400 inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
hassof390d2c2004-09-10 20:48:21 +0000401 vty_out (vty, " %s%s", ip6, VTY_NEWLINE);
402 }
403 }
jardineb5d44e2003-12-23 08:09:43 +0000404#endif /* HAVE_IPV6 */
hassof390d2c2004-09-10 20:48:21 +0000405 vty_out (vty, "%s", VTY_NEWLINE);
406 }
jardineb5d44e2003-12-23 08:09:43 +0000407 return;
408}
409
410void
hassof390d2c2004-09-10 20:48:21 +0000411isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)
412{
jardineb5d44e2003-12-23 08:09:43 +0000413 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
414}
415
416void
hassof390d2c2004-09-10 20:48:21 +0000417isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
418{
jardineb5d44e2003-12-23 08:09:43 +0000419 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
420}
421
422void
hassof390d2c2004-09-10 20:48:21 +0000423isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
424{
jardineb5d44e2003-12-23 08:09:43 +0000425 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
426}
427
428void
429isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)
430{
431 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);
432}
433
hassof390d2c2004-09-10 20:48:21 +0000434void
435isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)
jardineb5d44e2003-12-23 08:09:43 +0000436{
437 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);
438}
439
hassof390d2c2004-09-10 20:48:21 +0000440void
jardineb5d44e2003-12-23 08:09:43 +0000441isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)
442{
443 isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);
444}
445
446void
hassof390d2c2004-09-10 20:48:21 +0000447isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,
448 void *), void *arg)
jardineb5d44e2003-12-23 08:09:43 +0000449{
paul1eb8ef22005-04-07 07:30:20 +0000450 struct listnode *node, *nnode;
jardineb5d44e2003-12-23 08:09:43 +0000451 struct isis_adjacency *adj;
paul1eb8ef22005-04-07 07:30:20 +0000452
453 for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))
454 (*func) (adj, arg);
jardineb5d44e2003-12-23 08:09:43 +0000455}
456
457void
458isis_adj_build_neigh_list (struct list *adjdb, struct list *list)
jardineb5d44e2003-12-23 08:09:43 +0000459{
460 struct isis_adjacency *adj;
461 struct listnode *node;
hassof390d2c2004-09-10 20:48:21 +0000462
463 if (!list)
464 {
465 zlog_warn ("isis_adj_build_neigh_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000466 return;
467 }
hassof390d2c2004-09-10 20:48:21 +0000468
paul1eb8ef22005-04-07 07:30:20 +0000469 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000470 {
hassof390d2c2004-09-10 20:48:21 +0000471 if (!adj)
472 {
473 zlog_warn ("isis_adj_build_neigh_list(): NULL adj");
474 return;
475 }
476
477 if ((adj->adj_state == ISIS_ADJ_UP ||
478 adj->adj_state == ISIS_ADJ_INITIALIZING))
479 listnode_add (list, adj->snpa);
480 }
jardineb5d44e2003-12-23 08:09:43 +0000481 return;
482}
483
484void
485isis_adj_build_up_list (struct list *adjdb, struct list *list)
486{
487 struct isis_adjacency *adj;
488 struct listnode *node;
489
hassof390d2c2004-09-10 20:48:21 +0000490 if (!list)
491 {
492 zlog_warn ("isis_adj_build_up_list(): NULL list");
jardineb5d44e2003-12-23 08:09:43 +0000493 return;
494 }
495
paul1eb8ef22005-04-07 07:30:20 +0000496 for (ALL_LIST_ELEMENTS_RO (adjdb, node, adj))
hassof390d2c2004-09-10 20:48:21 +0000497 {
hassof390d2c2004-09-10 20:48:21 +0000498 if (!adj)
499 {
500 zlog_warn ("isis_adj_build_up_list(): NULL adj");
501 return;
502 }
503
504 if (adj->adj_state == ISIS_ADJ_UP)
505 listnode_add (list, adj);
506 }
507
jardineb5d44e2003-12-23 08:09:43 +0000508 return;
509}