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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "ospf6_proto.h"
31 #include "ospf6_lsa.h"
32 #include "ospf6_lsdb.h"
33 #include "ospf6_route.h"
37 struct ospf6_lsdb
*ospf6_lsdb_create(void *data
)
39 struct ospf6_lsdb
*lsdb
;
41 lsdb
= XCALLOC(MTYPE_OSPF6_LSDB
, sizeof(struct ospf6_lsdb
));
43 zlog_warn("Can't malloc lsdb");
46 memset(lsdb
, 0, sizeof(struct ospf6_lsdb
));
49 lsdb
->table
= route_table_init();
53 void ospf6_lsdb_delete(struct ospf6_lsdb
*lsdb
)
56 ospf6_lsdb_remove_all(lsdb
);
57 route_table_finish(lsdb
->table
);
58 XFREE(MTYPE_OSPF6_LSDB
, lsdb
);
62 static void ospf6_lsdb_set_key(struct prefix_ipv6
*key
, const void *value
,
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 (ALL_LSDB(lsdb
, debug
))
80 if (num
== lsdb
->count
)
83 zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb
,
85 for (ALL_LSDB(lsdb
, debug
))
86 zlog_debug("%p %p %s lsdb[%p]", debug
->prev
, debug
->next
,
87 debug
->name
, debug
->lsdb
);
88 zlog_debug("DUMP END");
90 assert(num
== lsdb
->count
);
92 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
94 #define ospf6_lsdb_count_assert(t) ((void) 0)
97 void ospf6_lsdb_add(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
99 struct prefix_ipv6 key
;
100 struct route_node
*current
;
101 struct ospf6_lsa
*old
= NULL
;
103 memset(&key
, 0, sizeof(key
));
104 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
105 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
106 sizeof(lsa
->header
->adv_router
));
107 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
109 current
= route_node_get(lsdb
->table
, (struct prefix
*)&key
);
118 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
119 if (lsdb
->hook_remove
)
120 (*lsdb
->hook_remove
)(lsa
);
123 (*lsdb
->hook_add
)(lsa
);
126 if (OSPF6_LSA_IS_CHANGED(old
, lsa
)) {
127 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
128 if (lsdb
->hook_remove
) {
129 (*lsdb
->hook_remove
)(old
);
130 (*lsdb
->hook_remove
)(lsa
);
132 } else if (OSPF6_LSA_IS_MAXAGE(old
)) {
134 (*lsdb
->hook_add
)(lsa
);
136 if (lsdb
->hook_remove
)
137 (*lsdb
->hook_remove
)(old
);
139 (*lsdb
->hook_add
)(lsa
);
142 /* to free the lookup lock in node get*/
143 route_unlock_node(current
);
144 ospf6_lsa_unlock(old
);
147 ospf6_lsdb_count_assert(lsdb
);
150 void ospf6_lsdb_remove(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
152 struct route_node
*node
;
153 struct prefix_ipv6 key
;
155 memset(&key
, 0, sizeof(key
));
156 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
157 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
158 sizeof(lsa
->header
->adv_router
));
159 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
161 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
162 assert(node
&& node
->info
== lsa
);
167 if (lsdb
->hook_remove
)
168 (*lsdb
->hook_remove
)(lsa
);
170 route_unlock_node(node
); /* to free the lookup lock */
171 route_unlock_node(node
); /* to free the original lock */
172 ospf6_lsa_unlock(lsa
);
174 ospf6_lsdb_count_assert(lsdb
);
177 struct ospf6_lsa
*ospf6_lsdb_lookup(u_int16_t type
, u_int32_t id
,
178 u_int32_t adv_router
,
179 struct ospf6_lsdb
*lsdb
)
181 struct route_node
*node
;
182 struct prefix_ipv6 key
;
187 memset(&key
, 0, sizeof(key
));
188 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
189 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
190 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
192 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
193 if (node
== NULL
|| node
->info
== NULL
)
196 route_unlock_node(node
);
197 return (struct ospf6_lsa
*)node
->info
;
200 struct ospf6_lsa
*ospf6_lsdb_lookup_next(u_int16_t type
, u_int32_t id
,
201 u_int32_t adv_router
,
202 struct ospf6_lsdb
*lsdb
)
204 struct route_node
*node
;
205 struct prefix_ipv6 key
;
210 memset(&key
, 0, sizeof(key
));
211 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
212 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
213 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
216 char buf
[PREFIX2STR_BUFFER
];
217 prefix2str(&key
, buf
, sizeof(buf
));
218 zlog_debug("lsdb_lookup_next: key: %s", buf
);
221 node
= route_table_get_next(lsdb
->table
, &key
);
223 /* skip to real existing entry */
224 while (node
&& node
->info
== NULL
)
225 node
= route_next(node
);
230 route_unlock_node(node
);
234 return (struct ospf6_lsa
*)node
->info
;
237 const struct route_node
*ospf6_lsdb_head(struct ospf6_lsdb
*lsdb
, int argmode
,
238 uint16_t type
, uint32_t adv_router
,
239 struct ospf6_lsa
**lsa
)
241 struct route_node
*node
, *end
;
246 struct prefix_ipv6 key
= {.family
= AF_INET6
, .prefixlen
= 0};
248 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
250 ospf6_lsdb_set_key(&key
, &adv_router
,
253 node
= route_table_get_next(lsdb
->table
, &key
);
254 if (!node
|| !prefix_match((struct prefix
*)&key
, &node
->p
))
257 for (end
= node
; end
&& end
->parent
258 && end
->parent
->p
.prefixlen
>= key
.prefixlen
;
262 node
= route_top(lsdb
->table
);
266 while (node
&& !node
->info
)
267 node
= route_next_until(node
, end
);
272 route_unlock_node(node
);
277 ospf6_lsa_lock(*lsa
);
282 struct ospf6_lsa
*ospf6_lsdb_next(const struct route_node
*iterend
,
283 struct ospf6_lsa
*lsa
)
285 struct route_node
*node
= lsa
->rn
;
287 ospf6_lsa_unlock(lsa
);
290 node
= route_next_until(node
, iterend
);
291 while (node
&& !node
->info
);
293 if (node
&& node
->info
) {
294 struct ospf6_lsa
*next
= node
->info
;
295 ospf6_lsa_lock(next
);
300 route_unlock_node(node
);
304 void ospf6_lsdb_remove_all(struct ospf6_lsdb
*lsdb
)
306 struct ospf6_lsa
*lsa
;
311 for (ALL_LSDB(lsdb
, lsa
))
312 ospf6_lsdb_remove(lsa
, lsdb
);
315 void ospf6_lsdb_lsa_unlock(struct ospf6_lsa
*lsa
)
319 route_unlock_node(lsa
->rn
);
320 ospf6_lsa_unlock(lsa
);
324 int ospf6_lsdb_maxage_remover(struct ospf6_lsdb
*lsdb
)
327 struct ospf6_lsa
*lsa
;
329 for (ALL_LSDB(lsdb
, lsa
)) {
330 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
332 if (lsa
->retrans_count
!= 0) {
336 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
337 zlog_debug("Remove MaxAge %s", lsa
->name
);
338 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)) {
339 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
341 * lsa->header->age = 0;
343 lsa
->header
->seqnum
=
344 htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
345 ospf6_lsa_checksum(lsa
->header
);
347 THREAD_OFF(lsa
->refresh
);
348 thread_execute(master
, ospf6_lsa_refresh
, lsa
, 0);
350 ospf6_lsdb_remove(lsa
, lsdb
);
357 void ospf6_lsdb_show(struct vty
*vty
, enum ospf_lsdb_show_level level
,
358 u_int16_t
*type
, u_int32_t
*id
, u_int32_t
*adv_router
,
359 struct ospf6_lsdb
*lsdb
)
361 struct ospf6_lsa
*lsa
;
362 const struct route_node
*end
= NULL
;
363 void (*showfunc
)(struct vty
*, struct ospf6_lsa
*) = NULL
;
366 case OSPF6_LSDB_SHOW_LEVEL_DETAIL
:
367 showfunc
= ospf6_lsa_show
;
369 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL
:
370 showfunc
= ospf6_lsa_show_internal
;
372 case OSPF6_LSDB_SHOW_LEVEL_DUMP
:
373 showfunc
= ospf6_lsa_show_dump
;
375 case OSPF6_LSDB_SHOW_LEVEL_NORMAL
:
377 showfunc
= ospf6_lsa_show_summary
;
380 if (type
&& id
&& adv_router
) {
381 lsa
= ospf6_lsdb_lookup(*type
, *id
, *adv_router
, lsdb
);
383 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
384 ospf6_lsa_show(vty
, lsa
);
386 (*showfunc
)(vty
, lsa
);
391 if (level
== OSPF6_LSDB_SHOW_LEVEL_NORMAL
)
392 ospf6_lsa_show_summary_header(vty
);
394 end
= ospf6_lsdb_head(lsdb
, !!type
+ !!(type
&& adv_router
),
396 adv_router
? *adv_router
: 0,
399 if ((!adv_router
|| lsa
->header
->adv_router
== *adv_router
)
400 && (!id
|| lsa
->header
->id
== *id
))
401 (*showfunc
)(vty
, lsa
);
403 lsa
= ospf6_lsdb_next(end
, lsa
);
407 u_int32_t
ospf6_new_ls_id(u_int16_t type
, u_int32_t adv_router
,
408 struct ospf6_lsdb
*lsdb
)
410 struct ospf6_lsa
*lsa
;
411 u_int32_t id
= 1, tmp_id
;
413 /* This routine is curently invoked only for Inter-Prefix LSAs for
414 * non-summarized routes (no area/range).
416 for (ALL_LSDB_TYPED_ADVRTR(lsdb
, type
, adv_router
, lsa
)) {
417 tmp_id
= ntohl(lsa
->header
->id
);
422 ospf6_lsdb_lsa_unlock(lsa
);
428 return ((u_int32_t
)htonl(id
));
431 /* Decide new LS sequence number to originate.
432 note return value is network byte order */
433 u_int32_t
ospf6_new_ls_seqnum(u_int16_t type
, u_int32_t id
,
434 u_int32_t adv_router
, struct ospf6_lsdb
*lsdb
)
436 struct ospf6_lsa
*lsa
;
437 signed long seqnum
= 0;
439 /* if current database copy not found, return InitialSequenceNumber */
440 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, lsdb
);
442 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
444 seqnum
= (signed long)ntohl(lsa
->header
->seqnum
) + 1;
446 return ((u_int32_t
)htonl(seqnum
));