2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
31 #include "ospf6_proto.h"
32 #include "ospf6_lsa.h"
33 #include "ospf6_lsdb.h"
37 ospf6_lsdb_create (void *data
)
39 struct ospf6_lsdb
*lsdb
;
41 lsdb
= XCALLOC (MTYPE_OSPF6_LSDB
, sizeof (struct ospf6_lsdb
));
44 zlog_warn ("Can't malloc lsdb");
47 memset (lsdb
, 0, sizeof (struct ospf6_lsdb
));
50 lsdb
->table
= route_table_init ();
55 ospf6_lsdb_delete (struct ospf6_lsdb
*lsdb
)
57 ospf6_lsdb_remove_all (lsdb
);
58 route_table_finish (lsdb
->table
);
59 XFREE (MTYPE_OSPF6_LSDB
, lsdb
);
63 ospf6_lsdb_set_key (struct prefix_ipv6
*key
, void *value
, int len
)
65 assert (key
->prefixlen
% 8 == 0);
67 memcpy ((caddr_t
) &key
->prefix
+ key
->prefixlen
/ 8,
68 (caddr_t
) value
, len
);
69 key
->family
= AF_INET6
;
70 key
->prefixlen
+= len
* 8;
75 _lsdb_count_assert (struct ospf6_lsdb
*lsdb
)
77 struct ospf6_lsa
*debug
;
79 for (debug
= ospf6_lsdb_head (lsdb
); debug
;
80 debug
= ospf6_lsdb_next (debug
))
83 if (num
== lsdb
->count
)
86 zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d",
87 lsdb
, lsdb
->count
, num
);
88 for (debug
= ospf6_lsdb_head (lsdb
); debug
;
89 debug
= ospf6_lsdb_next (debug
))
90 zlog_debug ("%p %p %s lsdb[%p]", debug
->prev
, debug
->next
, debug
->name
,
92 zlog_debug ("DUMP END");
94 assert (num
== lsdb
->count
);
96 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
98 #define ospf6_lsdb_count_assert(t) ((void) 0)
102 ospf6_lsdb_add (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
104 struct prefix_ipv6 key
;
105 struct route_node
*current
, *nextnode
, *prevnode
;
106 struct ospf6_lsa
*next
, *prev
, *old
= NULL
;
108 memset (&key
, 0, sizeof (key
));
109 ospf6_lsdb_set_key (&key
, &lsa
->header
->type
, sizeof (lsa
->header
->type
));
110 ospf6_lsdb_set_key (&key
, &lsa
->header
->adv_router
,
111 sizeof (lsa
->header
->adv_router
));
112 ospf6_lsdb_set_key (&key
, &lsa
->header
->id
, sizeof (lsa
->header
->id
));
114 current
= route_node_get (lsdb
->table
, (struct prefix
*) &key
);
117 ospf6_lsa_lock (lsa
);
122 old
->prev
->next
= lsa
;
124 old
->next
->prev
= lsa
;
125 lsa
->next
= old
->next
;
126 lsa
->prev
= old
->prev
;
132 route_lock_node (nextnode
);
134 nextnode
= route_next (nextnode
);
135 } while (nextnode
&& nextnode
->info
== NULL
);
136 if (nextnode
== NULL
)
140 next
= nextnode
->info
;
143 route_unlock_node (nextnode
);
148 route_lock_node (prevnode
);
150 prevnode
= route_prev (prevnode
);
151 } while (prevnode
&& prevnode
->info
== NULL
);
152 if (prevnode
== NULL
)
156 prev
= prevnode
->info
;
159 route_unlock_node (prevnode
);
167 if (OSPF6_LSA_IS_CHANGED (old
, lsa
))
169 if (OSPF6_LSA_IS_MAXAGE (lsa
))
171 if (lsdb
->hook_remove
)
173 (*lsdb
->hook_remove
) (old
);
174 (*lsdb
->hook_remove
) (lsa
);
177 else if (OSPF6_LSA_IS_MAXAGE (old
))
180 (*lsdb
->hook_add
) (lsa
);
184 if (lsdb
->hook_remove
)
185 (*lsdb
->hook_remove
) (old
);
187 (*lsdb
->hook_add
) (lsa
);
191 else if (OSPF6_LSA_IS_MAXAGE (lsa
))
193 if (lsdb
->hook_remove
)
194 (*lsdb
->hook_remove
) (lsa
);
199 (*lsdb
->hook_add
) (lsa
);
203 ospf6_lsa_unlock (old
);
205 ospf6_lsdb_count_assert (lsdb
);
209 ospf6_lsdb_remove (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
211 struct route_node
*node
;
212 struct prefix_ipv6 key
;
214 memset (&key
, 0, sizeof (key
));
215 ospf6_lsdb_set_key (&key
, &lsa
->header
->type
, sizeof (lsa
->header
->type
));
216 ospf6_lsdb_set_key (&key
, &lsa
->header
->adv_router
,
217 sizeof (lsa
->header
->adv_router
));
218 ospf6_lsdb_set_key (&key
, &lsa
->header
->id
, sizeof (lsa
->header
->id
));
220 node
= route_node_lookup (lsdb
->table
, (struct prefix
*) &key
);
221 assert (node
&& node
->info
== lsa
);
224 lsa
->prev
->next
= lsa
->next
;
226 lsa
->next
->prev
= lsa
->prev
;
231 if (lsdb
->hook_remove
)
232 (*lsdb
->hook_remove
) (lsa
);
234 ospf6_lsa_unlock (lsa
);
235 route_unlock_node (node
);
237 ospf6_lsdb_count_assert (lsdb
);
241 ospf6_lsdb_lookup (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
242 struct ospf6_lsdb
*lsdb
)
244 struct route_node
*node
;
245 struct prefix_ipv6 key
;
250 memset (&key
, 0, sizeof (key
));
251 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
252 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
253 ospf6_lsdb_set_key (&key
, &id
, sizeof (id
));
255 node
= route_node_lookup (lsdb
->table
, (struct prefix
*) &key
);
256 if (node
== NULL
|| node
->info
== NULL
)
258 return (struct ospf6_lsa
*) node
->info
;
261 /* Macro version of check_bit (). */
262 #define CHECK_BIT(X,P) ((((u_char *)(X))[(P) / 8]) >> (7 - ((P) % 8)) & 1)
265 ospf6_lsdb_lookup_next (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
266 struct ospf6_lsdb
*lsdb
)
268 struct route_node
*node
;
269 struct route_node
*matched
= NULL
;
270 struct prefix_ipv6 key
;
276 memset (&key
, 0, sizeof (key
));
277 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
278 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
279 ospf6_lsdb_set_key (&key
, &id
, sizeof (id
));
280 p
= (struct prefix
*) &key
;
284 prefix2str (p
, buf
, sizeof (buf
));
285 zlog_debug ("lsdb_lookup_next: key: %s", buf
);
288 node
= lsdb
->table
->top
;
289 /* walk down tree. */
290 while (node
&& node
->p
.prefixlen
<= p
->prefixlen
&&
291 prefix_match (&node
->p
, p
))
294 node
= node
->link
[CHECK_BIT(&p
->u
.prefix
, node
->p
.prefixlen
)];
300 node
= lsdb
->table
->top
;
301 route_lock_node (node
);
303 /* skip to real existing entry */
304 while (node
&& node
->info
== NULL
)
305 node
= route_next (node
);
310 if (prefix_same (&node
->p
, p
))
312 struct route_node
*prev
= node
;
313 struct ospf6_lsa
*lsa_prev
;
314 struct ospf6_lsa
*lsa_next
;
316 node
= route_next (node
);
317 while (node
&& node
->info
== NULL
)
318 node
= route_next (node
);
320 lsa_prev
= prev
->info
;
321 lsa_next
= (node
? node
->info
: NULL
);
323 assert (lsa_prev
->next
== lsa_next
);
325 assert (lsa_next
->prev
== lsa_prev
);
326 zlog_debug ("lsdb_lookup_next: assert OK with previous LSA");
332 route_unlock_node (node
);
333 return (struct ospf6_lsa
*) node
->info
;
336 /* Iteration function */
338 ospf6_lsdb_head (struct ospf6_lsdb
*lsdb
)
340 struct route_node
*node
;
342 node
= route_top (lsdb
->table
);
346 /* skip to the existing lsdb entry */
347 while (node
&& node
->info
== NULL
)
348 node
= route_next (node
);
352 route_unlock_node (node
);
354 ospf6_lsa_lock ((struct ospf6_lsa
*) node
->info
);
355 return (struct ospf6_lsa
*) node
->info
;
359 ospf6_lsdb_next (struct ospf6_lsa
*lsa
)
361 struct ospf6_lsa
*next
= lsa
->next
;
363 ospf6_lsa_unlock (lsa
);
365 ospf6_lsa_lock (next
);
371 ospf6_lsdb_type_router_head (u_int16_t type
, u_int32_t adv_router
,
372 struct ospf6_lsdb
*lsdb
)
374 struct route_node
*node
;
375 struct prefix_ipv6 key
;
376 struct ospf6_lsa
*lsa
;
378 memset (&key
, 0, sizeof (key
));
379 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
380 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
382 node
= lsdb
->table
->top
;
384 /* Walk down tree. */
385 while (node
&& node
->p
.prefixlen
<= key
.prefixlen
&&
386 prefix_match (&node
->p
, (struct prefix
*) &key
))
387 node
= node
->link
[CHECK_BIT(&key
.prefix
, node
->p
.prefixlen
)];
390 route_lock_node (node
);
391 while (node
&& node
->info
== NULL
)
392 node
= route_next (node
);
397 route_unlock_node (node
);
399 if (! prefix_match ((struct prefix
*) &key
, &node
->p
))
403 ospf6_lsa_lock (lsa
);
409 ospf6_lsdb_type_router_next (u_int16_t type
, u_int32_t adv_router
,
410 struct ospf6_lsa
*lsa
)
412 struct ospf6_lsa
*next
= lsa
->next
;
416 if (next
->header
->type
!= type
||
417 next
->header
->adv_router
!= adv_router
)
422 ospf6_lsa_lock (next
);
423 ospf6_lsa_unlock (lsa
);
428 ospf6_lsdb_type_head (u_int16_t type
, struct ospf6_lsdb
*lsdb
)
430 struct route_node
*node
;
431 struct prefix_ipv6 key
;
432 struct ospf6_lsa
*lsa
;
434 memset (&key
, 0, sizeof (key
));
435 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
437 /* Walk down tree. */
438 node
= lsdb
->table
->top
;
439 while (node
&& node
->p
.prefixlen
<= key
.prefixlen
&&
440 prefix_match (&node
->p
, (struct prefix
*) &key
))
441 node
= node
->link
[CHECK_BIT(&key
.prefix
, node
->p
.prefixlen
)];
444 route_lock_node (node
);
445 while (node
&& node
->info
== NULL
)
446 node
= route_next (node
);
451 route_unlock_node (node
);
453 if (! prefix_match ((struct prefix
*) &key
, &node
->p
))
457 ospf6_lsa_lock (lsa
);
463 ospf6_lsdb_type_next (u_int16_t type
, struct ospf6_lsa
*lsa
)
465 struct ospf6_lsa
*next
= lsa
->next
;
469 if (next
->header
->type
!= type
)
474 ospf6_lsa_lock (next
);
475 ospf6_lsa_unlock (lsa
);
480 ospf6_lsdb_remove_all (struct ospf6_lsdb
*lsdb
)
482 struct ospf6_lsa
*lsa
;
483 for (lsa
= ospf6_lsdb_head (lsdb
); lsa
; lsa
= ospf6_lsdb_next (lsa
))
484 ospf6_lsdb_remove (lsa
, lsdb
);
488 ospf6_lsdb_show (struct vty
*vty
, int level
,
489 u_int16_t
*type
, u_int32_t
*id
, u_int32_t
*adv_router
,
490 struct ospf6_lsdb
*lsdb
)
492 struct ospf6_lsa
*lsa
;
493 void (*showfunc
) (struct vty
*, struct ospf6_lsa
*) = NULL
;
495 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
496 showfunc
= ospf6_lsa_show_summary
;
497 else if (level
== OSPF6_LSDB_SHOW_LEVEL_DETAIL
)
498 showfunc
= ospf6_lsa_show
;
499 else if (level
== OSPF6_LSDB_SHOW_LEVEL_INTERNAL
)
500 showfunc
= ospf6_lsa_show_internal
;
501 else if (level
== OSPF6_LSDB_SHOW_LEVEL_DUMP
)
502 showfunc
= ospf6_lsa_show_dump
;
504 if (type
&& id
&& adv_router
)
506 lsa
= ospf6_lsdb_lookup (*type
, *id
, *adv_router
, lsdb
);
509 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
510 ospf6_lsa_show (vty
, lsa
);
512 (*showfunc
) (vty
, lsa
);
517 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
518 ospf6_lsa_show_summary_header (vty
);
520 if (type
&& adv_router
)
521 lsa
= ospf6_lsdb_type_router_head (*type
, *adv_router
, lsdb
);
523 lsa
= ospf6_lsdb_type_head (*type
, lsdb
);
525 lsa
= ospf6_lsdb_head (lsdb
);
528 if ((! adv_router
|| lsa
->header
->adv_router
== *adv_router
) &&
529 (! id
|| lsa
->header
->id
== *id
))
530 (*showfunc
) (vty
, lsa
);
532 if (type
&& adv_router
)
533 lsa
= ospf6_lsdb_type_router_next (*type
, *adv_router
, lsa
);
535 lsa
= ospf6_lsdb_type_next (*type
, lsa
);
537 lsa
= ospf6_lsdb_next (lsa
);
541 /* Decide new Link State ID to originate.
542 note return value is network byte order */
544 ospf6_new_ls_id (u_int16_t type
, u_int32_t adv_router
,
545 struct ospf6_lsdb
*lsdb
)
547 struct ospf6_lsa
*lsa
;
550 for (lsa
= ospf6_lsdb_type_router_head (type
, adv_router
, lsdb
); lsa
;
551 lsa
= ospf6_lsdb_type_router_next (type
, adv_router
, lsa
))
553 if (ntohl (lsa
->header
->id
) < id
)
555 if (ntohl (lsa
->header
->id
) > id
)
560 return ((u_int32_t
) htonl (id
));
563 /* Decide new LS sequence number to originate.
564 note return value is network byte order */
566 ospf6_new_ls_seqnum (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
567 struct ospf6_lsdb
*lsdb
)
569 struct ospf6_lsa
*lsa
;
570 signed long seqnum
= 0;
572 /* if current database copy not found, return InitialSequenceNumber */
573 lsa
= ospf6_lsdb_lookup (type
, id
, adv_router
, lsdb
);
575 seqnum
= INITIAL_SEQUENCE_NUMBER
;
577 seqnum
= (signed long) ntohl (lsa
->header
->seqnum
) + 1;
579 return ((u_int32_t
) htonl (seqnum
));