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 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_LSDB
, "OSPF6 LSA database");
39 struct ospf6_lsdb
*ospf6_lsdb_create(void *data
)
41 struct ospf6_lsdb
*lsdb
;
43 lsdb
= XCALLOC(MTYPE_OSPF6_LSDB
, sizeof(struct ospf6_lsdb
));
44 memset(lsdb
, 0, sizeof(struct ospf6_lsdb
));
47 lsdb
->table
= route_table_init();
51 void ospf6_lsdb_delete(struct ospf6_lsdb
*lsdb
)
54 ospf6_lsdb_remove_all(lsdb
);
55 route_table_finish(lsdb
->table
);
56 XFREE(MTYPE_OSPF6_LSDB
, lsdb
);
60 static void ospf6_lsdb_set_key(struct prefix_ipv6
*key
, const void *value
,
63 assert(key
->prefixlen
% 8 == 0);
65 memcpy((caddr_t
)&key
->prefix
+ key
->prefixlen
/ 8, (caddr_t
)value
, len
);
66 key
->family
= AF_INET6
;
67 key
->prefixlen
+= len
* 8;
71 static void _lsdb_count_assert(struct ospf6_lsdb
*lsdb
)
73 struct ospf6_lsa
*debug
, *debugnext
;
75 for (ALL_LSDB(lsdb
, debug
, debugnext
))
78 if (num
== lsdb
->count
)
81 zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb
,
83 for (ALL_LSDB(lsdb
, debug
, debugnext
))
84 zlog_debug("%s lsdb[%p]", debug
->name
, debug
->lsdb
);
85 zlog_debug("DUMP END");
87 assert(num
== lsdb
->count
);
89 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
91 #define ospf6_lsdb_count_assert(t) ((void) 0)
94 void ospf6_lsdb_add(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
96 struct prefix_ipv6 key
;
97 struct route_node
*current
;
98 struct ospf6_lsa
*old
= NULL
;
100 memset(&key
, 0, sizeof(key
));
101 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
102 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
103 sizeof(lsa
->header
->adv_router
));
104 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
106 current
= route_node_get(lsdb
->table
, (struct prefix
*)&key
);
115 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
116 if (lsdb
->hook_remove
)
117 (*lsdb
->hook_remove
)(lsa
);
120 (*lsdb
->hook_add
)(lsa
);
123 if (OSPF6_LSA_IS_CHANGED(old
, lsa
)) {
124 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
125 if (lsdb
->hook_remove
) {
126 (*lsdb
->hook_remove
)(old
);
127 (*lsdb
->hook_remove
)(lsa
);
129 } else if (OSPF6_LSA_IS_MAXAGE(old
)) {
131 (*lsdb
->hook_add
)(lsa
);
133 if (lsdb
->hook_remove
)
134 (*lsdb
->hook_remove
)(old
);
136 (*lsdb
->hook_add
)(lsa
);
139 /* to free the lookup lock in node get*/
140 route_unlock_node(current
);
141 ospf6_lsa_unlock(old
);
144 ospf6_lsdb_count_assert(lsdb
);
147 void ospf6_lsdb_remove(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
149 struct route_node
*node
;
150 struct prefix_ipv6 key
;
152 memset(&key
, 0, sizeof(key
));
153 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
154 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
155 sizeof(lsa
->header
->adv_router
));
156 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
158 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
159 assert(node
&& node
->info
== lsa
);
164 if (lsdb
->hook_remove
)
165 (*lsdb
->hook_remove
)(lsa
);
167 route_unlock_node(node
); /* to free the lookup lock */
168 route_unlock_node(node
); /* to free the original lock */
169 ospf6_lsa_unlock(lsa
);
171 ospf6_lsdb_count_assert(lsdb
);
174 struct ospf6_lsa
*ospf6_lsdb_lookup(uint16_t type
, uint32_t id
,
176 struct ospf6_lsdb
*lsdb
)
178 struct route_node
*node
;
179 struct prefix_ipv6 key
;
184 memset(&key
, 0, sizeof(key
));
185 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
186 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
187 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
189 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
190 if (node
== NULL
|| node
->info
== NULL
)
193 route_unlock_node(node
);
194 return (struct ospf6_lsa
*)node
->info
;
197 struct ospf6_lsa
*ospf6_lsdb_lookup_next(uint16_t type
, uint32_t id
,
199 struct ospf6_lsdb
*lsdb
)
201 struct route_node
*node
;
202 struct prefix_ipv6 key
;
207 memset(&key
, 0, sizeof(key
));
208 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
209 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
210 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
212 zlog_debug("lsdb_lookup_next: key: %pFX", &key
);
214 node
= route_table_get_next(lsdb
->table
, &key
);
216 /* skip to real existing entry */
217 while (node
&& node
->info
== NULL
)
218 node
= route_next(node
);
223 route_unlock_node(node
);
227 return (struct ospf6_lsa
*)node
->info
;
230 const struct route_node
*ospf6_lsdb_head(struct ospf6_lsdb
*lsdb
, int argmode
,
231 uint16_t type
, uint32_t adv_router
,
232 struct ospf6_lsa
**lsa
)
234 struct route_node
*node
, *end
;
239 struct prefix_ipv6 key
= {.family
= AF_INET6
, .prefixlen
= 0};
241 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
243 ospf6_lsdb_set_key(&key
, &adv_router
,
246 node
= route_table_get_next(lsdb
->table
, &key
);
247 if (!node
|| !prefix_match((struct prefix
*)&key
, &node
->p
))
250 for (end
= node
; end
&& end
->parent
251 && end
->parent
->p
.prefixlen
>= key
.prefixlen
;
255 node
= route_top(lsdb
->table
);
259 while (node
&& !node
->info
)
260 node
= route_next_until(node
, end
);
265 route_unlock_node(node
);
270 ospf6_lsa_lock(*lsa
);
275 struct ospf6_lsa
*ospf6_lsdb_next(const struct route_node
*iterend
,
276 struct ospf6_lsa
*lsa
)
278 struct route_node
*node
= lsa
->rn
;
280 ospf6_lsa_unlock(lsa
);
283 node
= route_next_until(node
, iterend
);
284 while (node
&& !node
->info
);
286 if (node
&& node
->info
) {
287 struct ospf6_lsa
*next
= node
->info
;
288 ospf6_lsa_lock(next
);
293 route_unlock_node(node
);
297 void ospf6_lsdb_remove_all(struct ospf6_lsdb
*lsdb
)
299 struct ospf6_lsa
*lsa
, *lsanext
;
304 for (ALL_LSDB(lsdb
, lsa
, lsanext
))
305 ospf6_lsdb_remove(lsa
, lsdb
);
308 void ospf6_lsdb_lsa_unlock(struct ospf6_lsa
*lsa
)
312 route_unlock_node(lsa
->rn
);
313 ospf6_lsa_unlock(lsa
);
317 int ospf6_lsdb_maxage_remover(struct ospf6_lsdb
*lsdb
)
320 struct ospf6_lsa
*lsa
, *lsanext
;
322 for (ALL_LSDB(lsdb
, lsa
, lsanext
)) {
323 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
324 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
325 zlog_debug("Not MaxAge %s", lsa
->name
);
329 if (lsa
->retrans_count
!= 0) {
330 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
331 zlog_debug("Remove MaxAge %s retrans_count %d",
332 lsa
->name
, lsa
->retrans_count
);
337 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
338 zlog_debug("Remove MaxAge %s", lsa
->name
);
340 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)) {
341 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
343 * lsa->header->age = 0;
345 lsa
->header
->seqnum
=
346 htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
347 ospf6_lsa_checksum(lsa
->header
);
349 THREAD_OFF(lsa
->refresh
);
350 thread_execute(master
, ospf6_lsa_refresh
, lsa
, 0);
352 zlog_debug("calling ospf6_lsdb_remove %s", lsa
->name
);
353 ospf6_lsdb_remove(lsa
, lsdb
);
360 uint32_t ospf6_new_ls_id(uint16_t type
, uint32_t adv_router
,
361 struct ospf6_lsdb
*lsdb
)
363 struct ospf6_lsa
*lsa
;
364 uint32_t id
= 1, tmp_id
;
366 /* This routine is curently invoked only for Inter-Prefix LSAs for
367 * non-summarized routes (no area/range).
369 for (ALL_LSDB_TYPED_ADVRTR(lsdb
, type
, adv_router
, lsa
)) {
370 tmp_id
= ntohl(lsa
->header
->id
);
375 ospf6_lsdb_lsa_unlock(lsa
);
381 return ((uint32_t)htonl(id
));
384 /* Decide new LS sequence number to originate.
385 note return value is network byte order */
386 uint32_t ospf6_new_ls_seqnum(uint16_t type
, uint32_t id
, uint32_t adv_router
,
387 struct ospf6_lsdb
*lsdb
)
389 struct ospf6_lsa
*lsa
;
390 signed long seqnum
= 0;
392 /* if current database copy not found, return InitialSequenceNumber */
393 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, lsdb
);
395 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
397 seqnum
= (signed long)ntohl(lsa
->header
->seqnum
) + 1;
399 return ((uint32_t)htonl(seqnum
));