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"
38 struct ospf6_lsdb
*ospf6_lsdb_create(void *data
)
40 struct ospf6_lsdb
*lsdb
;
42 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();
54 void 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 static void 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, (caddr_t
)value
, len
);
68 key
->family
= AF_INET6
;
69 key
->prefixlen
+= len
* 8;
73 static void _lsdb_count_assert(struct ospf6_lsdb
*lsdb
)
75 struct ospf6_lsa
*debug
;
77 for (debug
= ospf6_lsdb_head(lsdb
); debug
;
78 debug
= ospf6_lsdb_next(debug
))
81 if (num
== lsdb
->count
)
84 zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb
,
86 for (debug
= ospf6_lsdb_head(lsdb
); debug
;
87 debug
= ospf6_lsdb_next(debug
))
88 zlog_debug("%s lsdb[%p]", debug
->name
, debug
->lsdb
);
89 zlog_debug("DUMP END");
91 assert(num
== lsdb
->count
);
93 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
95 #define ospf6_lsdb_count_assert(t) ((void) 0)
98 void ospf6_lsdb_add(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
100 struct prefix_ipv6 key
;
101 struct route_node
*current
;
102 struct ospf6_lsa
*old
= NULL
;
104 memset(&key
, 0, sizeof(key
));
105 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
106 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
107 sizeof(lsa
->header
->adv_router
));
108 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
110 current
= route_node_get(lsdb
->table
, (struct prefix
*)&key
);
119 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
120 if (lsdb
->hook_remove
)
121 (*lsdb
->hook_remove
)(lsa
);
124 (*lsdb
->hook_add
)(lsa
);
127 if (OSPF6_LSA_IS_CHANGED(old
, lsa
)) {
128 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
129 if (lsdb
->hook_remove
) {
130 (*lsdb
->hook_remove
)(old
);
131 (*lsdb
->hook_remove
)(lsa
);
133 } else if (OSPF6_LSA_IS_MAXAGE(old
)) {
135 (*lsdb
->hook_add
)(lsa
);
137 if (lsdb
->hook_remove
)
138 (*lsdb
->hook_remove
)(old
);
140 (*lsdb
->hook_add
)(lsa
);
143 ospf6_lsa_unlock(old
);
146 ospf6_lsdb_count_assert(lsdb
);
149 void ospf6_lsdb_remove(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
151 struct route_node
*node
;
152 struct prefix_ipv6 key
;
154 memset(&key
, 0, sizeof(key
));
155 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
156 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
157 sizeof(lsa
->header
->adv_router
));
158 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
160 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
161 assert(node
&& node
->info
== lsa
);
166 if (lsdb
->hook_remove
)
167 (*lsdb
->hook_remove
)(lsa
);
169 route_unlock_node(node
); /* to free the lookup lock */
170 route_unlock_node(node
); /* to free the original lock */
171 ospf6_lsa_unlock(lsa
);
173 ospf6_lsdb_count_assert(lsdb
);
176 struct ospf6_lsa
*ospf6_lsdb_lookup(u_int16_t type
, u_int32_t id
,
177 u_int32_t adv_router
,
178 struct ospf6_lsdb
*lsdb
)
180 struct route_node
*node
;
181 struct prefix_ipv6 key
;
186 memset(&key
, 0, sizeof(key
));
187 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
188 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
189 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
191 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
192 if (node
== NULL
|| node
->info
== NULL
)
195 route_unlock_node(node
);
196 return (struct ospf6_lsa
*)node
->info
;
199 struct ospf6_lsa
*ospf6_lsdb_lookup_next(u_int16_t type
, u_int32_t id
,
200 u_int32_t adv_router
,
201 struct ospf6_lsdb
*lsdb
)
203 struct route_node
*node
;
204 struct route_node
*matched
= NULL
;
205 struct prefix_ipv6 key
;
211 memset(&key
, 0, sizeof(key
));
212 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
213 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
214 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
215 p
= (struct prefix
*)&key
;
218 char buf
[PREFIX2STR_BUFFER
];
219 prefix2str(p
, buf
, sizeof(buf
));
220 zlog_debug("lsdb_lookup_next: key: %s", buf
);
223 node
= lsdb
->table
->top
;
224 /* walk down tree. */
225 while (node
&& node
->p
.prefixlen
<= p
->prefixlen
226 && prefix_match(&node
->p
, p
)) {
228 node
= node
->link
[prefix_bit(&p
->u
.prefix
, node
->p
.prefixlen
)];
234 node
= lsdb
->table
->top
;
235 route_lock_node(node
);
237 /* skip to real existing entry */
238 while (node
&& node
->info
== NULL
)
239 node
= route_next(node
);
244 if (prefix_same(&node
->p
, p
)) {
245 node
= route_next(node
);
246 while (node
&& node
->info
== NULL
)
247 node
= route_next(node
);
253 route_unlock_node(node
);
254 return (struct ospf6_lsa
*)node
->info
;
257 /* Iteration function */
258 struct ospf6_lsa
*ospf6_lsdb_head(struct ospf6_lsdb
*lsdb
)
260 struct route_node
*node
;
262 node
= route_top(lsdb
->table
);
266 /* skip to the existing lsdb entry */
267 while (node
&& node
->info
== NULL
)
268 node
= route_next(node
);
273 ospf6_lsa_lock((struct ospf6_lsa
*)node
->info
);
274 return (struct ospf6_lsa
*)node
->info
;
277 struct ospf6_lsa
*ospf6_lsdb_next(struct ospf6_lsa
*lsa
)
279 struct route_node
*node
= lsa
->rn
;
280 struct ospf6_lsa
*next
= NULL
;
283 node
= route_next(node
);
284 } while (node
&& node
->info
== NULL
);
286 if ((node
!= NULL
) && (node
->info
!= NULL
)) {
288 ospf6_lsa_lock(next
);
291 ospf6_lsa_unlock(lsa
);
295 struct ospf6_lsa
*ospf6_lsdb_type_router_head(u_int16_t type
,
296 u_int32_t adv_router
,
297 struct ospf6_lsdb
*lsdb
)
299 struct route_node
*node
;
300 struct prefix_ipv6 key
;
301 struct ospf6_lsa
*lsa
;
303 memset(&key
, 0, sizeof(key
));
304 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
305 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
307 node
= lsdb
->table
->top
;
309 /* Walk down tree. */
310 while (node
&& node
->p
.prefixlen
<= key
.prefixlen
311 && prefix_match(&node
->p
, (struct prefix
*)&key
))
312 node
= node
->link
[prefix6_bit(&key
.prefix
, node
->p
.prefixlen
)];
315 route_lock_node(node
);
316 while (node
&& node
->info
== NULL
)
317 node
= route_next(node
);
322 if (!prefix_match((struct prefix
*)&key
, &node
->p
))
331 struct ospf6_lsa
*ospf6_lsdb_type_router_next(u_int16_t type
,
332 u_int32_t adv_router
,
333 struct ospf6_lsa
*lsa
)
335 struct ospf6_lsa
*next
= ospf6_lsdb_next(lsa
);
338 if (next
->header
->type
!= type
339 || next
->header
->adv_router
!= adv_router
) {
340 route_unlock_node(next
->rn
);
341 ospf6_lsa_unlock(next
);
349 struct ospf6_lsa
*ospf6_lsdb_type_head(u_int16_t type
, struct ospf6_lsdb
*lsdb
)
351 struct route_node
*node
;
352 struct prefix_ipv6 key
;
353 struct ospf6_lsa
*lsa
;
355 memset(&key
, 0, sizeof(key
));
356 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
358 /* Walk down tree. */
359 node
= lsdb
->table
->top
;
360 while (node
&& node
->p
.prefixlen
<= key
.prefixlen
361 && prefix_match(&node
->p
, (struct prefix
*)&key
))
362 node
= node
->link
[prefix6_bit(&key
.prefix
, node
->p
.prefixlen
)];
365 route_lock_node(node
);
366 while (node
&& node
->info
== NULL
)
367 node
= route_next(node
);
372 if (!prefix_match((struct prefix
*)&key
, &node
->p
))
381 struct ospf6_lsa
*ospf6_lsdb_type_next(u_int16_t type
, struct ospf6_lsa
*lsa
)
383 struct ospf6_lsa
*next
= ospf6_lsdb_next(lsa
);
386 if (next
->header
->type
!= type
) {
387 route_unlock_node(next
->rn
);
388 ospf6_lsa_unlock(next
);
396 void ospf6_lsdb_remove_all(struct ospf6_lsdb
*lsdb
)
398 struct ospf6_lsa
*lsa
;
403 for (lsa
= ospf6_lsdb_head(lsdb
); lsa
; lsa
= ospf6_lsdb_next(lsa
))
404 ospf6_lsdb_remove(lsa
, lsdb
);
407 void ospf6_lsdb_lsa_unlock(struct ospf6_lsa
*lsa
)
411 route_unlock_node(lsa
->rn
);
412 ospf6_lsa_unlock(lsa
);
416 int ospf6_lsdb_maxage_remover(struct ospf6_lsdb
*lsdb
)
419 struct ospf6_lsa
*lsa
;
421 for (lsa
= ospf6_lsdb_head(lsdb
); lsa
; lsa
= ospf6_lsdb_next(lsa
)) {
422 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
424 if (lsa
->retrans_count
!= 0) {
428 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
429 zlog_debug("Remove MaxAge %s", lsa
->name
);
430 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)) {
431 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
433 * lsa->header->age = 0;
435 lsa
->header
->seqnum
=
436 htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
437 ospf6_lsa_checksum(lsa
->header
);
439 THREAD_OFF(lsa
->refresh
);
440 thread_execute(master
, ospf6_lsa_refresh
, lsa
, 0);
442 ospf6_lsdb_remove(lsa
, lsdb
);
449 void ospf6_lsdb_show(struct vty
*vty
, enum ospf_lsdb_show_level level
,
450 u_int16_t
*type
, u_int32_t
*id
, u_int32_t
*adv_router
,
451 struct ospf6_lsdb
*lsdb
)
453 struct ospf6_lsa
*lsa
;
454 void (*showfunc
)(struct vty
*, struct ospf6_lsa
*) = NULL
;
457 case OSPF6_LSDB_SHOW_LEVEL_DETAIL
:
458 showfunc
= ospf6_lsa_show
;
460 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL
:
461 showfunc
= ospf6_lsa_show_internal
;
463 case OSPF6_LSDB_SHOW_LEVEL_DUMP
:
464 showfunc
= ospf6_lsa_show_dump
;
466 case OSPF6_LSDB_SHOW_LEVEL_NORMAL
:
468 showfunc
= ospf6_lsa_show_summary
;
471 if (type
&& id
&& adv_router
) {
472 lsa
= ospf6_lsdb_lookup(*type
, *id
, *adv_router
, lsdb
);
474 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
475 ospf6_lsa_show(vty
, lsa
);
477 (*showfunc
)(vty
, lsa
);
482 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
483 ospf6_lsa_show_summary_header(vty
);
485 if (type
&& adv_router
)
486 lsa
= ospf6_lsdb_type_router_head(*type
, *adv_router
, lsdb
);
488 lsa
= ospf6_lsdb_type_head(*type
, lsdb
);
490 lsa
= ospf6_lsdb_head(lsdb
);
492 if ((!adv_router
|| lsa
->header
->adv_router
== *adv_router
)
493 && (!id
|| lsa
->header
->id
== *id
))
494 (*showfunc
)(vty
, lsa
);
496 if (type
&& adv_router
)
497 lsa
= ospf6_lsdb_type_router_next(*type
, *adv_router
,
500 lsa
= ospf6_lsdb_type_next(*type
, lsa
);
502 lsa
= ospf6_lsdb_next(lsa
);
506 u_int32_t
ospf6_new_ls_id(u_int16_t type
, u_int32_t adv_router
,
507 struct ospf6_lsdb
*lsdb
)
509 struct ospf6_lsa
*lsa
;
510 u_int32_t id
= 1, tmp_id
;
512 /* This routine is curently invoked only for Inter-Prefix LSAs for
513 * non-summarized routes (no area/range).
515 for (lsa
= ospf6_lsdb_type_router_head(type
, adv_router
, lsdb
); lsa
;
516 lsa
= ospf6_lsdb_type_router_next(type
, adv_router
, lsa
)) {
517 tmp_id
= ntohl(lsa
->header
->id
);
522 ospf6_lsdb_lsa_unlock(lsa
);
528 return ((u_int32_t
)htonl(id
));
531 /* Decide new LS sequence number to originate.
532 note return value is network byte order */
533 u_int32_t
ospf6_new_ls_seqnum(u_int16_t type
, u_int32_t id
,
534 u_int32_t adv_router
, struct ospf6_lsdb
*lsdb
)
536 struct ospf6_lsa
*lsa
;
537 signed long seqnum
= 0;
539 /* if current database copy not found, return InitialSequenceNumber */
540 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, lsdb
);
542 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
544 seqnum
= (signed long)ntohl(lsa
->header
->seqnum
) + 1;
546 return ((u_int32_t
)htonl(seqnum
));