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"
34 #include "ospf6_route.h"
39 ospf6_lsdb_create (void *data
)
41 struct ospf6_lsdb
*lsdb
;
43 lsdb
= XCALLOC (MTYPE_OSPF6_LSDB
, sizeof (struct ospf6_lsdb
));
46 zlog_warn ("Can't malloc lsdb");
49 memset (lsdb
, 0, sizeof (struct ospf6_lsdb
));
52 lsdb
->table
= route_table_init ();
57 ospf6_lsdb_delete (struct ospf6_lsdb
*lsdb
)
61 ospf6_lsdb_remove_all (lsdb
);
62 route_table_finish (lsdb
->table
);
63 XFREE (MTYPE_OSPF6_LSDB
, lsdb
);
68 ospf6_lsdb_set_key (struct prefix_ipv6
*key
, void *value
, int len
)
70 assert (key
->prefixlen
% 8 == 0);
72 memcpy ((caddr_t
) &key
->prefix
+ key
->prefixlen
/ 8,
73 (caddr_t
) value
, len
);
74 key
->family
= AF_INET6
;
75 key
->prefixlen
+= len
* 8;
80 _lsdb_count_assert (struct ospf6_lsdb
*lsdb
)
82 struct ospf6_lsa
*debug
;
84 for (debug
= ospf6_lsdb_head (lsdb
); debug
;
85 debug
= ospf6_lsdb_next (debug
))
88 if (num
== lsdb
->count
)
91 zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d",
92 lsdb
, lsdb
->count
, num
);
93 for (debug
= ospf6_lsdb_head (lsdb
); debug
;
94 debug
= ospf6_lsdb_next (debug
))
95 zlog_debug ("%p %p %s lsdb[%p]", debug
->prev
, debug
->next
, debug
->name
,
97 zlog_debug ("DUMP END");
99 assert (num
== lsdb
->count
);
101 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
103 #define ospf6_lsdb_count_assert(t) ((void) 0)
107 ospf6_lsdb_add (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
109 struct prefix_ipv6 key
;
110 struct route_node
*current
;
111 struct ospf6_lsa
*old
= NULL
;
113 memset (&key
, 0, sizeof (key
));
114 ospf6_lsdb_set_key (&key
, &lsa
->header
->type
, sizeof (lsa
->header
->type
));
115 ospf6_lsdb_set_key (&key
, &lsa
->header
->adv_router
,
116 sizeof (lsa
->header
->adv_router
));
117 ospf6_lsdb_set_key (&key
, &lsa
->header
->id
, sizeof (lsa
->header
->id
));
119 current
= route_node_get (lsdb
->table
, (struct prefix
*) &key
);
123 ospf6_lsa_lock (lsa
);
129 if (OSPF6_LSA_IS_MAXAGE (lsa
))
131 if (lsdb
->hook_remove
)
132 (*lsdb
->hook_remove
) (lsa
);
137 (*lsdb
->hook_add
) (lsa
);
142 if (OSPF6_LSA_IS_CHANGED (old
, lsa
))
144 if (OSPF6_LSA_IS_MAXAGE (lsa
))
146 if (lsdb
->hook_remove
)
148 (*lsdb
->hook_remove
) (old
);
149 (*lsdb
->hook_remove
) (lsa
);
152 else if (OSPF6_LSA_IS_MAXAGE (old
))
155 (*lsdb
->hook_add
) (lsa
);
159 if (lsdb
->hook_remove
)
160 (*lsdb
->hook_remove
) (old
);
162 (*lsdb
->hook_add
) (lsa
);
165 ospf6_lsa_unlock (old
);
168 ospf6_lsdb_count_assert (lsdb
);
172 ospf6_lsdb_remove (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
174 struct route_node
*node
;
175 struct prefix_ipv6 key
;
177 memset (&key
, 0, sizeof (key
));
178 ospf6_lsdb_set_key (&key
, &lsa
->header
->type
, sizeof (lsa
->header
->type
));
179 ospf6_lsdb_set_key (&key
, &lsa
->header
->adv_router
,
180 sizeof (lsa
->header
->adv_router
));
181 ospf6_lsdb_set_key (&key
, &lsa
->header
->id
, sizeof (lsa
->header
->id
));
183 node
= route_node_lookup (lsdb
->table
, (struct prefix
*) &key
);
184 assert (node
&& node
->info
== lsa
);
189 if (lsdb
->hook_remove
)
190 (*lsdb
->hook_remove
) (lsa
);
192 route_unlock_node (node
); /* to free the lookup lock */
193 route_unlock_node (node
); /* to free the original lock */
194 ospf6_lsa_unlock (lsa
);
196 ospf6_lsdb_count_assert (lsdb
);
200 ospf6_lsdb_lookup (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
201 struct ospf6_lsdb
*lsdb
)
203 struct route_node
*node
;
204 struct prefix_ipv6 key
;
209 memset (&key
, 0, sizeof (key
));
210 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
211 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
212 ospf6_lsdb_set_key (&key
, &id
, sizeof (id
));
214 node
= route_node_lookup (lsdb
->table
, (struct prefix
*) &key
);
215 if (node
== NULL
|| node
->info
== NULL
)
218 route_unlock_node (node
);
219 return (struct ospf6_lsa
*) node
->info
;
223 ospf6_lsdb_lookup_next (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
224 struct ospf6_lsdb
*lsdb
)
226 struct route_node
*node
;
227 struct route_node
*matched
= NULL
;
228 struct prefix_ipv6 key
;
234 memset (&key
, 0, sizeof (key
));
235 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
236 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
237 ospf6_lsdb_set_key (&key
, &id
, sizeof (id
));
238 p
= (struct prefix
*) &key
;
241 char buf
[PREFIX2STR_BUFFER
];
242 prefix2str (p
, buf
, sizeof (buf
));
243 zlog_debug ("lsdb_lookup_next: key: %s", buf
);
246 node
= lsdb
->table
->top
;
247 /* walk down tree. */
248 while (node
&& node
->p
.prefixlen
<= p
->prefixlen
&&
249 prefix_match (&node
->p
, p
))
252 node
= node
->link
[prefix_bit(&p
->u
.prefix
, node
->p
.prefixlen
)];
258 node
= lsdb
->table
->top
;
259 route_lock_node (node
);
261 /* skip to real existing entry */
262 while (node
&& node
->info
== NULL
)
263 node
= route_next (node
);
268 if (prefix_same (&node
->p
, p
))
270 node
= route_next (node
);
271 while (node
&& node
->info
== NULL
)
272 node
= route_next (node
);
278 route_unlock_node (node
);
279 return (struct ospf6_lsa
*) node
->info
;
282 /* Iteration function */
284 ospf6_lsdb_head (struct ospf6_lsdb
*lsdb
)
286 struct route_node
*node
;
288 node
= route_top (lsdb
->table
);
292 /* skip to the existing lsdb entry */
293 while (node
&& node
->info
== NULL
)
294 node
= route_next (node
);
299 ospf6_lsa_lock ((struct ospf6_lsa
*) node
->info
);
300 return (struct ospf6_lsa
*) node
->info
;
304 ospf6_lsdb_next (struct ospf6_lsa
*lsa
)
306 struct route_node
*node
= lsa
->rn
;
307 struct ospf6_lsa
*next
= NULL
;
310 node
= route_next (node
);
311 } while (node
&& node
->info
== NULL
);
313 if ((node
!= NULL
) && (node
->info
!= NULL
))
316 ospf6_lsa_lock (next
);
319 ospf6_lsa_unlock (lsa
);
324 ospf6_lsdb_type_router_head (u_int16_t type
, u_int32_t adv_router
,
325 struct ospf6_lsdb
*lsdb
)
327 struct route_node
*node
;
328 struct prefix_ipv6 key
;
329 struct ospf6_lsa
*lsa
;
331 memset (&key
, 0, sizeof (key
));
332 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
333 ospf6_lsdb_set_key (&key
, &adv_router
, sizeof (adv_router
));
335 node
= lsdb
->table
->top
;
337 /* Walk down tree. */
338 while (node
&& node
->p
.prefixlen
<= key
.prefixlen
&&
339 prefix_match (&node
->p
, (struct prefix
*) &key
))
340 node
= node
->link
[prefix6_bit(&key
.prefix
, node
->p
.prefixlen
)];
343 route_lock_node (node
);
344 while (node
&& node
->info
== NULL
)
345 node
= route_next (node
);
350 if (! prefix_match ((struct prefix
*) &key
, &node
->p
))
354 ospf6_lsa_lock (lsa
);
360 ospf6_lsdb_type_router_next (u_int16_t type
, u_int32_t adv_router
,
361 struct ospf6_lsa
*lsa
)
363 struct ospf6_lsa
*next
= ospf6_lsdb_next(lsa
);
367 if (next
->header
->type
!= type
||
368 next
->header
->adv_router
!= adv_router
)
370 route_unlock_node (next
->rn
);
371 ospf6_lsa_unlock (next
);
380 ospf6_lsdb_type_head (u_int16_t type
, struct ospf6_lsdb
*lsdb
)
382 struct route_node
*node
;
383 struct prefix_ipv6 key
;
384 struct ospf6_lsa
*lsa
;
386 memset (&key
, 0, sizeof (key
));
387 ospf6_lsdb_set_key (&key
, &type
, sizeof (type
));
389 /* Walk down tree. */
390 node
= lsdb
->table
->top
;
391 while (node
&& node
->p
.prefixlen
<= key
.prefixlen
&&
392 prefix_match (&node
->p
, (struct prefix
*) &key
))
393 node
= node
->link
[prefix6_bit(&key
.prefix
, node
->p
.prefixlen
)];
396 route_lock_node (node
);
397 while (node
&& node
->info
== NULL
)
398 node
= route_next (node
);
403 if (! prefix_match ((struct prefix
*) &key
, &node
->p
))
407 ospf6_lsa_lock (lsa
);
413 ospf6_lsdb_type_next (u_int16_t type
, struct ospf6_lsa
*lsa
)
415 struct ospf6_lsa
*next
= ospf6_lsdb_next (lsa
);
419 if (next
->header
->type
!= type
)
421 route_unlock_node (next
->rn
);
422 ospf6_lsa_unlock (next
);
431 ospf6_lsdb_remove_all (struct ospf6_lsdb
*lsdb
)
433 struct ospf6_lsa
*lsa
;
438 for (lsa
= ospf6_lsdb_head (lsdb
); lsa
; lsa
= ospf6_lsdb_next (lsa
))
439 ospf6_lsdb_remove (lsa
, lsdb
);
443 ospf6_lsdb_lsa_unlock (struct ospf6_lsa
*lsa
)
448 route_unlock_node (lsa
->rn
);
449 ospf6_lsa_unlock (lsa
);
454 ospf6_lsdb_maxage_remover (struct ospf6_lsdb
*lsdb
)
457 struct ospf6_lsa
*lsa
;
459 for (lsa
= ospf6_lsdb_head (lsdb
); lsa
; lsa
= ospf6_lsdb_next (lsa
))
461 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
463 if (lsa
->retrans_count
!= 0)
468 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa
->header
->type
))
469 zlog_debug ("Remove MaxAge %s", lsa
->name
);
470 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
))
472 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
474 * lsa->header->age = 0;
476 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
477 ospf6_lsa_checksum (lsa
->header
);
479 THREAD_OFF(lsa
->refresh
);
480 thread_execute (master
, ospf6_lsa_refresh
, lsa
, 0);
482 ospf6_lsdb_remove (lsa
, lsdb
);
490 ospf6_lsdb_show (struct vty
*vty
, enum ospf_lsdb_show_level level
,
491 u_int16_t
*type
, u_int32_t
*id
, u_int32_t
*adv_router
,
492 struct ospf6_lsdb
*lsdb
)
494 struct ospf6_lsa
*lsa
;
495 void (*showfunc
) (struct vty
*, struct ospf6_lsa
*) = NULL
;
499 case OSPF6_LSDB_SHOW_LEVEL_DETAIL
:
500 showfunc
= ospf6_lsa_show
;
502 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL
:
503 showfunc
= ospf6_lsa_show_internal
;
505 case OSPF6_LSDB_SHOW_LEVEL_DUMP
:
506 showfunc
= ospf6_lsa_show_dump
;
508 case OSPF6_LSDB_SHOW_LEVEL_NORMAL
:
510 showfunc
= ospf6_lsa_show_summary
;
513 if (type
&& id
&& adv_router
)
515 lsa
= ospf6_lsdb_lookup (*type
, *id
, *adv_router
, lsdb
);
518 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
519 ospf6_lsa_show (vty
, lsa
);
521 (*showfunc
) (vty
, lsa
);
526 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
527 ospf6_lsa_show_summary_header (vty
);
529 if (type
&& adv_router
)
530 lsa
= ospf6_lsdb_type_router_head (*type
, *adv_router
, lsdb
);
532 lsa
= ospf6_lsdb_type_head (*type
, lsdb
);
534 lsa
= ospf6_lsdb_head (lsdb
);
537 if ((! adv_router
|| lsa
->header
->adv_router
== *adv_router
) &&
538 (! id
|| lsa
->header
->id
== *id
))
539 (*showfunc
) (vty
, lsa
);
541 if (type
&& adv_router
)
542 lsa
= ospf6_lsdb_type_router_next (*type
, *adv_router
, lsa
);
544 lsa
= ospf6_lsdb_type_next (*type
, lsa
);
546 lsa
= ospf6_lsdb_next (lsa
);
551 ospf6_new_ls_id (u_int16_t type
, u_int32_t adv_router
,
552 struct ospf6_lsdb
*lsdb
)
554 struct ospf6_lsa
*lsa
;
555 u_int32_t id
= 1, tmp_id
;
557 /* This routine is curently invoked only for Inter-Prefix LSAs for
558 * non-summarized routes (no area/range).
560 for (lsa
= ospf6_lsdb_type_router_head (type
, adv_router
, lsdb
); lsa
;
561 lsa
= ospf6_lsdb_type_router_next (type
, adv_router
, lsa
))
563 tmp_id
= ntohl (lsa
->header
->id
);
569 ospf6_lsdb_lsa_unlock (lsa
);
575 return ((u_int32_t
) htonl (id
));
578 /* Decide new LS sequence number to originate.
579 note return value is network byte order */
581 ospf6_new_ls_seqnum (u_int16_t type
, u_int32_t id
, u_int32_t adv_router
,
582 struct ospf6_lsdb
*lsdb
)
584 struct ospf6_lsa
*lsa
;
585 signed long seqnum
= 0;
587 /* if current database copy not found, return InitialSequenceNumber */
588 lsa
= ospf6_lsdb_lookup (type
, id
, adv_router
, lsdb
);
590 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
592 seqnum
= (signed long) ntohl (lsa
->header
->seqnum
) + 1;
594 return ((u_int32_t
) htonl (seqnum
));