1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2003 Yasuhiro Ohara
15 #include "ospf6_proto.h"
16 #include "ospf6_lsa.h"
17 #include "ospf6_lsdb.h"
18 #include "ospf6_asbr.h"
19 #include "ospf6_route.h"
23 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_LSDB
, "OSPF6 LSA database");
25 struct ospf6_lsdb
*ospf6_lsdb_create(void *data
)
27 struct ospf6_lsdb
*lsdb
;
29 lsdb
= XCALLOC(MTYPE_OSPF6_LSDB
, sizeof(struct ospf6_lsdb
));
30 memset(lsdb
, 0, sizeof(struct ospf6_lsdb
));
33 lsdb
->table
= route_table_init();
37 void ospf6_lsdb_delete(struct ospf6_lsdb
*lsdb
)
40 ospf6_lsdb_remove_all(lsdb
);
41 route_table_finish(lsdb
->table
);
42 XFREE(MTYPE_OSPF6_LSDB
, lsdb
);
46 static void ospf6_lsdb_set_key(struct prefix_ipv6
*key
, const void *value
,
49 assert(key
->prefixlen
% 8 == 0);
51 memcpy((caddr_t
)&key
->prefix
+ key
->prefixlen
/ 8, (caddr_t
)value
, len
);
52 key
->family
= AF_INET6
;
53 key
->prefixlen
+= len
* 8;
57 static void _lsdb_count_assert(struct ospf6_lsdb
*lsdb
)
59 struct ospf6_lsa
*debug
, *debugnext
;
61 for (ALL_LSDB(lsdb
, debug
, debugnext
))
64 if (num
== lsdb
->count
)
67 zlog_debug("PANIC !! lsdb[%p]->count = %d, real = %d", lsdb
,
69 for (ALL_LSDB(lsdb
, debug
, debugnext
))
70 zlog_debug("%s lsdb[%p]", debug
->name
, debug
->lsdb
);
71 zlog_debug("DUMP END");
73 assert(num
== lsdb
->count
);
75 #define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
77 #define ospf6_lsdb_count_assert(t) ((void) 0)
80 static inline void ospf6_lsdb_stats_update(struct ospf6_lsa
*lsa
,
81 struct ospf6_lsdb
*lsdb
, int count
)
83 uint16_t stat
= ntohs(lsa
->header
->type
) & OSPF6_LSTYPE_FCODE_MASK
;
85 if (stat
>= OSPF6_LSTYPE_SIZE
)
86 stat
= OSPF6_LSTYPE_UNKNOWN
;
87 lsdb
->stats
[stat
] += count
;
90 void ospf6_lsdb_add(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
92 struct prefix_ipv6 key
;
93 struct route_node
*current
;
94 struct ospf6_lsa
*old
= NULL
;
96 memset(&key
, 0, sizeof(key
));
97 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
98 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
99 sizeof(lsa
->header
->adv_router
));
100 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
102 current
= route_node_get(lsdb
->table
, (struct prefix
*)&key
);
110 ospf6_lsdb_stats_update(lsa
, lsdb
, 1);
112 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
113 if (lsdb
->hook_remove
)
114 (*lsdb
->hook_remove
)(lsa
);
117 (*lsdb
->hook_add
)(lsa
);
120 lsa
->retrans_count
= old
->retrans_count
;
122 if (OSPF6_LSA_IS_CHANGED(old
, lsa
)) {
123 if (OSPF6_LSA_IS_MAXAGE(lsa
)) {
124 if (lsdb
->hook_remove
) {
125 (*lsdb
->hook_remove
)(old
);
126 (*lsdb
->hook_remove
)(lsa
);
128 } else if (OSPF6_LSA_IS_MAXAGE(old
)) {
130 (*lsdb
->hook_add
)(lsa
);
132 if (lsdb
->hook_remove
)
133 (*lsdb
->hook_remove
)(old
);
135 (*lsdb
->hook_add
)(lsa
);
138 /* to free the lookup lock in node get*/
139 route_unlock_node(current
);
140 ospf6_lsa_unlock(old
);
143 ospf6_lsdb_count_assert(lsdb
);
146 void ospf6_lsdb_remove(struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
148 struct route_node
*node
;
149 struct prefix_ipv6 key
;
151 memset(&key
, 0, sizeof(key
));
152 ospf6_lsdb_set_key(&key
, &lsa
->header
->type
, sizeof(lsa
->header
->type
));
153 ospf6_lsdb_set_key(&key
, &lsa
->header
->adv_router
,
154 sizeof(lsa
->header
->adv_router
));
155 ospf6_lsdb_set_key(&key
, &lsa
->header
->id
, sizeof(lsa
->header
->id
));
157 node
= route_node_lookup(lsdb
->table
, (struct prefix
*)&key
);
158 assert(node
&& node
->info
== lsa
);
162 ospf6_lsdb_stats_update(lsa
, lsdb
, -1);
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_find_external_lsa(struct ospf6
*ospf6
, struct prefix
*p
)
199 struct ospf6_route
*match
;
200 struct ospf6_lsa
*lsa
;
201 struct ospf6_external_info
*info
;
203 match
= ospf6_route_lookup(p
, ospf6
->external_table
);
205 if (IS_OSPF6_DEBUG_ASBR
)
206 zlog_debug("No such route %pFX to withdraw", p
);
211 info
= match
->route_option
;
214 lsa
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL
),
215 htonl(info
->id
), ospf6
->router_id
, ospf6
->lsdb
);
219 struct ospf6_lsa
*ospf6_lsdb_lookup_next(uint16_t type
, uint32_t id
,
221 struct ospf6_lsdb
*lsdb
)
223 struct route_node
*node
;
224 struct prefix_ipv6 key
;
229 memset(&key
, 0, sizeof(key
));
230 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
231 ospf6_lsdb_set_key(&key
, &adv_router
, sizeof(adv_router
));
232 ospf6_lsdb_set_key(&key
, &id
, sizeof(id
));
234 zlog_debug("lsdb_lookup_next: key: %pFX", &key
);
236 node
= route_table_get_next(lsdb
->table
, &key
);
238 /* skip to real existing entry */
239 while (node
&& node
->info
== NULL
)
240 node
= route_next(node
);
245 route_unlock_node(node
);
249 return (struct ospf6_lsa
*)node
->info
;
252 const struct route_node
*ospf6_lsdb_head(struct ospf6_lsdb
*lsdb
, int argmode
,
253 uint16_t type
, uint32_t adv_router
,
254 struct ospf6_lsa
**lsa
)
256 struct route_node
*node
, *end
;
261 struct prefix_ipv6 key
= {.family
= AF_INET6
, .prefixlen
= 0};
263 ospf6_lsdb_set_key(&key
, &type
, sizeof(type
));
265 ospf6_lsdb_set_key(&key
, &adv_router
,
268 node
= route_table_get_next(lsdb
->table
, &key
);
269 if (!node
|| !prefix_match((struct prefix
*)&key
, &node
->p
))
272 for (end
= node
; end
&& end
->parent
273 && end
->parent
->p
.prefixlen
>= key
.prefixlen
;
277 node
= route_top(lsdb
->table
);
281 while (node
&& !node
->info
)
282 node
= route_next_until(node
, end
);
287 route_unlock_node(node
);
292 ospf6_lsa_lock(*lsa
);
297 struct ospf6_lsa
*ospf6_lsdb_next(const struct route_node
*iterend
,
298 struct ospf6_lsa
*lsa
)
300 struct route_node
*node
= lsa
->rn
;
302 ospf6_lsa_unlock(lsa
);
305 node
= route_next_until(node
, iterend
);
306 while (node
&& !node
->info
);
308 if (node
&& node
->info
) {
309 struct ospf6_lsa
*next
= node
->info
;
310 ospf6_lsa_lock(next
);
315 route_unlock_node(node
);
319 void ospf6_lsdb_remove_all(struct ospf6_lsdb
*lsdb
)
321 struct ospf6_lsa
*lsa
, *lsanext
;
326 for (ALL_LSDB(lsdb
, lsa
, lsanext
))
327 ospf6_lsdb_remove(lsa
, lsdb
);
330 void ospf6_lsdb_lsa_unlock(struct ospf6_lsa
*lsa
)
334 route_unlock_node(lsa
->rn
);
335 ospf6_lsa_unlock(lsa
);
339 int ospf6_lsdb_maxage_remover(struct ospf6_lsdb
*lsdb
)
342 struct ospf6_lsa
*lsa
, *lsanext
;
344 for (ALL_LSDB(lsdb
, lsa
, lsanext
)) {
345 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
346 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
347 zlog_debug("Not MaxAge %s", lsa
->name
);
351 if (lsa
->retrans_count
!= 0) {
352 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
353 zlog_debug("Remove MaxAge %s retrans_count %d",
354 lsa
->name
, lsa
->retrans_count
);
359 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
))
360 zlog_debug("Remove MaxAge %s", lsa
->name
);
362 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)) {
363 UNSET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
365 * lsa->header->age = 0;
367 lsa
->header
->seqnum
=
368 htonl(OSPF_MAX_SEQUENCE_NUMBER
+ 1);
369 ospf6_lsa_checksum(lsa
->header
);
371 THREAD_OFF(lsa
->refresh
);
372 thread_execute(master
, ospf6_lsa_refresh
, lsa
, 0);
374 zlog_debug("calling ospf6_lsdb_remove %s", lsa
->name
);
375 ospf6_lsdb_remove(lsa
, lsdb
);
382 uint32_t ospf6_new_ls_id(uint16_t type
, uint32_t adv_router
,
383 struct ospf6_lsdb
*lsdb
)
385 struct ospf6_lsa
*lsa
;
386 uint32_t id
= 1, tmp_id
;
388 /* This routine is curently invoked only for Inter-Prefix LSAs for
389 * non-summarized routes (no area/range).
391 for (ALL_LSDB_TYPED_ADVRTR(lsdb
, type
, adv_router
, lsa
)) {
392 tmp_id
= ntohl(lsa
->header
->id
);
397 ospf6_lsdb_lsa_unlock(lsa
);
403 return ((uint32_t)htonl(id
));
406 /* Decide new LS sequence number to originate.
407 note return value is network byte order */
408 uint32_t ospf6_new_ls_seqnum(uint16_t type
, uint32_t id
, uint32_t adv_router
,
409 struct ospf6_lsdb
*lsdb
)
411 struct ospf6_lsa
*lsa
;
412 signed long seqnum
= 0;
414 /* if current database copy not found, return InitialSequenceNumber */
415 lsa
= ospf6_lsdb_lookup(type
, id
, adv_router
, lsdb
);
417 seqnum
= OSPF_INITIAL_SEQUENCE_NUMBER
;
419 seqnum
= (signed long)ntohl(lsa
->header
->seqnum
) + 1;
421 return ((uint32_t)htonl(seqnum
));