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_asbr.h"
34 #include "ospf6_route.h"
38 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_LSDB
, "OSPF6 LSA database");
40 struct ospf6_lsdb
*ospf6_lsdb_create(void *data
)
42 struct ospf6_lsdb
*lsdb
;
44 lsdb
= XCALLOC(MTYPE_OSPF6_LSDB
, sizeof(struct ospf6_lsdb
));
45 memset(lsdb
, 0, sizeof(struct ospf6_lsdb
));
48 lsdb
->table
= route_table_init();
52 void ospf6_lsdb_delete(struct ospf6_lsdb
*lsdb
)
55 ospf6_lsdb_remove_all(lsdb
);
56 route_table_finish(lsdb
->table
);
57 XFREE(MTYPE_OSPF6_LSDB
, lsdb
);
61 static void ospf6_lsdb_set_key(struct prefix_ipv6
*key
, const void *value
,
64 assert(key
->prefixlen
% 8 == 0);
66 memcpy((caddr_t
)&key
->prefix
+ key
->prefixlen
/ 8, (caddr_t
)value
, len
);
67 key
->family
= AF_INET6
;
68 key
->prefixlen
+= len
* 8;
72 static void _lsdb_count_assert(struct ospf6_lsdb
*lsdb
)
74 struct ospf6_lsa
*debug
, *debugnext
;
76 for (ALL_LSDB(lsdb
, debug
, debugnext
))
79 if (num
== lsdb
->count
)
82 zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb
,
84 for (ALL_LSDB(lsdb
, debug
, debugnext
))
85 zlog_debug("%s lsdb[%p]", debug
->name
, debug
->lsdb
);
86 zlog_debug("DUMP END");
88 assert(num
== lsdb
->count
);
90 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
92 #define ospf6_lsdb_count_assert(t) ((void) 0)
95 void ospf6_lsdb_add(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
97 struct prefix_ipv6 key
;
98 struct route_node
*current
;
99 struct ospf6_lsa
*old
= NULL
;
101 memset(&key
, 0, sizeof(key
));
102 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
103 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
104 sizeof(lsa
->header
->adv_router
));
105 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
107 current
= route_node_get(lsdb
->table
, (struct prefix
*)&key
);
116 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
117 if (lsdb
->hook_remove
)
118 (*lsdb
->hook_remove
)(lsa
);
121 (*lsdb
->hook_add
)(lsa
);
124 if (OSPF6_LSA_IS_CHANGED(old
, lsa
)) {
125 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
126 if (lsdb
->hook_remove
) {
127 (*lsdb
->hook_remove
)(old
);
128 (*lsdb
->hook_remove
)(lsa
);
130 } else if (OSPF6_LSA_IS_MAXAGE(old
)) {
132 (*lsdb
->hook_add
)(lsa
);
134 if (lsdb
->hook_remove
)
135 (*lsdb
->hook_remove
)(old
);
137 (*lsdb
->hook_add
)(lsa
);
140 /* to free the lookup lock in node get*/
141 route_unlock_node(current
);
142 ospf6_lsa_unlock(old
);
145 ospf6_lsdb_count_assert(lsdb
);
148 void ospf6_lsdb_remove(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
150 struct route_node
*node
;
151 struct prefix_ipv6 key
;
153 memset(&key
, 0, sizeof(key
));
154 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
155 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
156 sizeof(lsa
->header
->adv_router
));
157 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
159 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
160 assert(node
&& node
->info
== lsa
);
165 if (lsdb
->hook_remove
)
166 (*lsdb
->hook_remove
)(lsa
);
168 route_unlock_node(node
); /* to free the lookup lock */
169 route_unlock_node(node
); /* to free the original lock */
170 ospf6_lsa_unlock(lsa
);
172 ospf6_lsdb_count_assert(lsdb
);
175 struct ospf6_lsa
*ospf6_lsdb_lookup(uint16_t type
, uint32_t id
,
177 struct ospf6_lsdb
*lsdb
)
179 struct route_node
*node
;
180 struct prefix_ipv6 key
;
185 memset(&key
, 0, sizeof(key
));
186 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
187 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
188 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
190 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
191 if (node
== NULL
|| node
->info
== NULL
)
194 route_unlock_node(node
);
195 return (struct ospf6_lsa
*)node
->info
;
198 struct ospf6_lsa
*ospf6_find_external_lsa(struct ospf6
*ospf6
, struct prefix
*p
)
200 struct ospf6_route
*match
;
201 struct ospf6_lsa
*lsa
;
202 struct ospf6_external_info
*info
;
204 match
= ospf6_route_lookup(p
, ospf6
->external_table
);
206 if (IS_OSPF6_DEBUG_ASBR
)
207 zlog_debug("No such route %pFX to withdraw", p
);
212 info
= match
->route_option
;
215 lsa
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL
),
216 htonl(info
->id
), ospf6
->router_id
, ospf6
->lsdb
);
220 struct ospf6_lsa
*ospf6_lsdb_lookup_next(uint16_t type
, uint32_t id
,
222 struct ospf6_lsdb
*lsdb
)
224 struct route_node
*node
;
225 struct prefix_ipv6 key
;
230 memset(&key
, 0, sizeof(key
));
231 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
232 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
233 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
235 zlog_debug("lsdb_lookup_next: key: %pFX", &key
);
237 node
= route_table_get_next(lsdb
->table
, &key
);
239 /* skip to real existing entry */
240 while (node
&& node
->info
== NULL
)
241 node
= route_next(node
);
246 route_unlock_node(node
);
250 return (struct ospf6_lsa
*)node
->info
;
253 const struct route_node
*ospf6_lsdb_head(struct ospf6_lsdb
*lsdb
, int argmode
,
254 uint16_t type
, uint32_t adv_router
,
255 struct ospf6_lsa
**lsa
)
257 struct route_node
*node
, *end
;
262 struct prefix_ipv6 key
= {.family
= AF_INET6
, .prefixlen
= 0};
264 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
266 ospf6_lsdb_set_key(&key
, &adv_router
,
269 node
= route_table_get_next(lsdb
->table
, &key
);
270 if (!node
|| !prefix_match((struct prefix
*)&key
, &node
->p
))
273 for (end
= node
; end
&& end
->parent
274 && end
->parent
->p
.prefixlen
>= key
.prefixlen
;
278 node
= route_top(lsdb
->table
);
282 while (node
&& !node
->info
)
283 node
= route_next_until(node
, end
);
288 route_unlock_node(node
);
293 ospf6_lsa_lock(*lsa
);
298 struct ospf6_lsa
*ospf6_lsdb_next(const struct route_node
*iterend
,
299 struct ospf6_lsa
*lsa
)
301 struct route_node
*node
= lsa
->rn
;
303 ospf6_lsa_unlock(lsa
);
306 node
= route_next_until(node
, iterend
);
307 while (node
&& !node
->info
);
309 if (node
&& node
->info
) {
310 struct ospf6_lsa
*next
= node
->info
;
311 ospf6_lsa_lock(next
);
316 route_unlock_node(node
);
320 void ospf6_lsdb_remove_all(struct ospf6_lsdb
*lsdb
)
322 struct ospf6_lsa
*lsa
, *lsanext
;
327 for (ALL_LSDB(lsdb
, lsa
, lsanext
))
328 ospf6_lsdb_remove(lsa
, lsdb
);
331 void ospf6_lsdb_lsa_unlock(struct ospf6_lsa
*lsa
)
335 route_unlock_node(lsa
->rn
);
336 ospf6_lsa_unlock(lsa
);
340 int ospf6_lsdb_maxage_remover(struct ospf6_lsdb
*lsdb
)
343 struct ospf6_lsa
*lsa
, *lsanext
;
345 for (ALL_LSDB(lsdb
, lsa
, lsanext
)) {
346 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
347 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
348 zlog_debug("Not MaxAge %s", lsa
->name
);
352 if (lsa
->retrans_count
!= 0) {
353 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
354 zlog_debug("Remove MaxAge %s retrans_count %d",
355 lsa
->name
, lsa
->retrans_count
);
360 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
361 zlog_debug("Remove MaxAge %s", lsa
->name
);
363 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)) {
364 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
366 * lsa->header->age = 0;
368 lsa
->header
->seqnum
=
369 htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
370 ospf6_lsa_checksum(lsa
->header
);
372 THREAD_OFF(lsa
->refresh
);
373 thread_execute(master
, ospf6_lsa_refresh
, lsa
, 0);
375 zlog_debug("calling ospf6_lsdb_remove %s", lsa
->name
);
376 ospf6_lsdb_remove(lsa
, lsdb
);
383 uint32_t ospf6_new_ls_id(uint16_t type
, uint32_t adv_router
,
384 struct ospf6_lsdb
*lsdb
)
386 struct ospf6_lsa
*lsa
;
387 uint32_t id
= 1, tmp_id
;
389 /* This routine is curently invoked only for Inter-Prefix LSAs for
390 * non-summarized routes (no area/range).
392 for (ALL_LSDB_TYPED_ADVRTR(lsdb
, type
, adv_router
, lsa
)) {
393 tmp_id
= ntohl(lsa
->header
->id
);
398 ospf6_lsdb_lsa_unlock(lsa
);
404 return ((uint32_t)htonl(id
));
407 /* Decide new LS sequence number to originate.
408 note return value is network byte order */
409 uint32_t ospf6_new_ls_seqnum(uint16_t type
, uint32_t id
, uint32_t adv_router
,
410 struct ospf6_lsdb
*lsdb
)
412 struct ospf6_lsa
*lsa
;
413 signed long seqnum
= 0;
415 /* if current database copy not found, return InitialSequenceNumber */
416 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, lsdb
);
418 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
420 seqnum
= (signed long)ntohl(lsa
->header
->seqnum
) + 1;
422 return ((uint32_t)htonl(seqnum
));