]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_lsdb.c
Merge pull request #885 from bingen/fix_debug_directive
[mirror_frr.git] / ospf6d / ospf6_lsdb.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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.
20 */
21
22#include <zebra.h>
23
24#include "memory.h"
25#include "log.h"
26#include "command.h"
508e53e2 27#include "prefix.h"
28#include "table.h"
049207c3 29#include "vty.h"
718e3744 30
508e53e2 31#include "ospf6_proto.h"
32#include "ospf6_lsa.h"
718e3744 33#include "ospf6_lsdb.h"
c3c0ac83 34#include "ospf6_route.h"
049207c3 35#include "ospf6d.h"
c3c0ac83 36#include "bitfield.h"
718e3744 37
718e3744 38struct ospf6_lsdb *
6452df09 39ospf6_lsdb_create (void *data)
718e3744 40{
41 struct ospf6_lsdb *lsdb;
42
43 lsdb = XCALLOC (MTYPE_OSPF6_LSDB, sizeof (struct ospf6_lsdb));
44 if (lsdb == NULL)
45 {
46 zlog_warn ("Can't malloc lsdb");
47 return NULL;
48 }
49 memset (lsdb, 0, sizeof (struct ospf6_lsdb));
50
6452df09 51 lsdb->data = data;
718e3744 52 lsdb->table = route_table_init ();
53 return lsdb;
54}
55
56void
57ospf6_lsdb_delete (struct ospf6_lsdb *lsdb)
58{
a765eb93
DD
59 if (lsdb != NULL)
60 {
61 ospf6_lsdb_remove_all (lsdb);
62 route_table_finish (lsdb->table);
63 XFREE (MTYPE_OSPF6_LSDB, lsdb);
64 }
718e3744 65}
66
67static void
508e53e2 68ospf6_lsdb_set_key (struct prefix_ipv6 *key, void *value, int len)
718e3744 69{
508e53e2 70 assert (key->prefixlen % 8 == 0);
718e3744 71
508e53e2 72 memcpy ((caddr_t) &key->prefix + key->prefixlen / 8,
73 (caddr_t) value, len);
74 key->family = AF_INET6;
75 key->prefixlen += len * 8;
76}
718e3744 77
e39d0538 78#ifdef DEBUG
508e53e2 79static void
80_lsdb_count_assert (struct ospf6_lsdb *lsdb)
81{
82 struct ospf6_lsa *debug;
0c083ee9 83 unsigned int num = 0;
508e53e2 84 for (debug = ospf6_lsdb_head (lsdb); debug;
85 debug = ospf6_lsdb_next (debug))
86 num++;
718e3744 87
508e53e2 88 if (num == lsdb->count)
89 return;
90
c6487d61 91 zlog_debug ("PANIC !! lsdb[%p]->count = %d, real = %d",
3b68735f 92 lsdb, lsdb->count, num);
93 for (debug = ospf6_lsdb_head (lsdb); debug;
94 debug = ospf6_lsdb_next (debug))
59f851e9 95 zlog_debug ("%s lsdb[%p]", debug->name, debug->lsdb);
c6487d61 96 zlog_debug ("DUMP END");
3b68735f 97
508e53e2 98 assert (num == lsdb->count);
718e3744 99}
508e53e2 100#define ospf6_lsdb_count_assert(t) (_lsdb_count_assert (t))
e39d0538 101#else /*DEBUG*/
508e53e2 102#define ospf6_lsdb_count_assert(t) ((void) 0)
e39d0538 103#endif /*DEBUG*/
718e3744 104
105void
106ospf6_lsdb_add (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
107{
718e3744 108 struct prefix_ipv6 key;
a765eb93
DD
109 struct route_node *current;
110 struct ospf6_lsa *old = NULL;
508e53e2 111
112 memset (&key, 0, sizeof (key));
113 ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
114 ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
115 sizeof (lsa->header->adv_router));
116 ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
117
118 current = route_node_get (lsdb->table, (struct prefix *) &key);
119 old = current->info;
120 current->info = lsa;
a765eb93 121 lsa->rn = current;
718e3744 122 ospf6_lsa_lock (lsa);
123
a765eb93 124 if (!old)
508e53e2 125 {
a765eb93 126 lsdb->count++;
718e3744 127
a765eb93
DD
128 if (OSPF6_LSA_IS_MAXAGE (lsa))
129 {
130 if (lsdb->hook_remove)
131 (*lsdb->hook_remove) (lsa);
132 }
508e53e2 133 else
a765eb93
DD
134 {
135 if (lsdb->hook_add)
136 (*lsdb->hook_add) (lsa);
137 }
508e53e2 138 }
a765eb93 139 else
718e3744 140 {
508e53e2 141 if (OSPF6_LSA_IS_CHANGED (old, lsa))
142 {
143 if (OSPF6_LSA_IS_MAXAGE (lsa))
144 {
145 if (lsdb->hook_remove)
146 {
147 (*lsdb->hook_remove) (old);
148 (*lsdb->hook_remove) (lsa);
149 }
150 }
ccb59b11 151 else if (OSPF6_LSA_IS_MAXAGE (old))
152 {
153 if (lsdb->hook_add)
154 (*lsdb->hook_add) (lsa);
155 }
508e53e2 156 else
157 {
158 if (lsdb->hook_remove)
159 (*lsdb->hook_remove) (old);
160 if (lsdb->hook_add)
161 (*lsdb->hook_add) (lsa);
162 }
163 }
a765eb93 164 ospf6_lsa_unlock (old);
718e3744 165 }
718e3744 166
508e53e2 167 ospf6_lsdb_count_assert (lsdb);
718e3744 168}
169
718e3744 170void
508e53e2 171ospf6_lsdb_remove (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
718e3744 172{
508e53e2 173 struct route_node *node;
174 struct prefix_ipv6 key;
718e3744 175
508e53e2 176 memset (&key, 0, sizeof (key));
177 ospf6_lsdb_set_key (&key, &lsa->header->type, sizeof (lsa->header->type));
178 ospf6_lsdb_set_key (&key, &lsa->header->adv_router,
179 sizeof (lsa->header->adv_router));
180 ospf6_lsdb_set_key (&key, &lsa->header->id, sizeof (lsa->header->id));
718e3744 181
508e53e2 182 node = route_node_lookup (lsdb->table, (struct prefix *) &key);
183 assert (node && node->info == lsa);
718e3744 184
508e53e2 185 node->info = NULL;
186 lsdb->count--;
718e3744 187
508e53e2 188 if (lsdb->hook_remove)
189 (*lsdb->hook_remove) (lsa);
718e3744 190
a765eb93
DD
191 route_unlock_node (node); /* to free the lookup lock */
192 route_unlock_node (node); /* to free the original lock */
508e53e2 193 ospf6_lsa_unlock (lsa);
6452df09 194
508e53e2 195 ospf6_lsdb_count_assert (lsdb);
718e3744 196}
197
508e53e2 198struct ospf6_lsa *
199ospf6_lsdb_lookup (u_int16_t type, u_int32_t id, u_int32_t adv_router,
200 struct ospf6_lsdb *lsdb)
718e3744 201{
508e53e2 202 struct route_node *node;
203 struct prefix_ipv6 key;
718e3744 204
508e53e2 205 if (lsdb == NULL)
206 return NULL;
718e3744 207
508e53e2 208 memset (&key, 0, sizeof (key));
209 ospf6_lsdb_set_key (&key, &type, sizeof (type));
210 ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
211 ospf6_lsdb_set_key (&key, &id, sizeof (id));
718e3744 212
508e53e2 213 node = route_node_lookup (lsdb->table, (struct prefix *) &key);
214 if (node == NULL || node->info == NULL)
215 return NULL;
a765eb93
DD
216
217 route_unlock_node (node);
508e53e2 218 return (struct ospf6_lsa *) node->info;
718e3744 219}
220
2680aa2b 221struct ospf6_lsa *
222ospf6_lsdb_lookup_next (u_int16_t type, u_int32_t id, u_int32_t adv_router,
223 struct ospf6_lsdb *lsdb)
224{
225 struct route_node *node;
226 struct route_node *matched = NULL;
227 struct prefix_ipv6 key;
228 struct prefix *p;
229
230 if (lsdb == NULL)
231 return NULL;
232
233 memset (&key, 0, sizeof (key));
234 ospf6_lsdb_set_key (&key, &type, sizeof (type));
235 ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
236 ospf6_lsdb_set_key (&key, &id, sizeof (id));
237 p = (struct prefix *) &key;
238
239 {
4690c7d7 240 char buf[PREFIX2STR_BUFFER];
2680aa2b 241 prefix2str (p, buf, sizeof (buf));
c6487d61 242 zlog_debug ("lsdb_lookup_next: key: %s", buf);
2680aa2b 243 }
244
245 node = lsdb->table->top;
246 /* walk down tree. */
247 while (node && node->p.prefixlen <= p->prefixlen &&
248 prefix_match (&node->p, p))
249 {
250 matched = node;
1352ef32 251 node = node->link[prefix_bit(&p->u.prefix, node->p.prefixlen)];
2680aa2b 252 }
253
254 if (matched)
255 node = matched;
256 else
257 node = lsdb->table->top;
258 route_lock_node (node);
259
260 /* skip to real existing entry */
261 while (node && node->info == NULL)
262 node = route_next (node);
263
264 if (! node)
265 return NULL;
266
267 if (prefix_same (&node->p, p))
268 {
2680aa2b 269 node = route_next (node);
270 while (node && node->info == NULL)
271 node = route_next (node);
2680aa2b 272 }
273
274 if (! node)
275 return NULL;
276
277 route_unlock_node (node);
278 return (struct ospf6_lsa *) node->info;
279}
280
508e53e2 281/* Iteration function */
282struct ospf6_lsa *
283ospf6_lsdb_head (struct ospf6_lsdb *lsdb)
718e3744 284{
508e53e2 285 struct route_node *node;
286
287 node = route_top (lsdb->table);
288 if (node == NULL)
289 return NULL;
290
291 /* skip to the existing lsdb entry */
292 while (node && node->info == NULL)
293 node = route_next (node);
294 if (node == NULL)
295 return NULL;
296
508e53e2 297 if (node->info)
298 ospf6_lsa_lock ((struct ospf6_lsa *) node->info);
299 return (struct ospf6_lsa *) node->info;
718e3744 300}
301
302struct ospf6_lsa *
508e53e2 303ospf6_lsdb_next (struct ospf6_lsa *lsa)
718e3744 304{
a765eb93
DD
305 struct route_node *node = lsa->rn;
306 struct ospf6_lsa *next = NULL;
718e3744 307
a765eb93
DD
308 do {
309 node = route_next (node);
310 } while (node && node->info == NULL);
311
312 if ((node != NULL) && (node->info != NULL))
313 {
314 next = node->info;
315 ospf6_lsa_lock (next);
316 }
718e3744 317
a765eb93 318 ospf6_lsa_unlock (lsa);
508e53e2 319 return next;
718e3744 320}
321
508e53e2 322struct ospf6_lsa *
323ospf6_lsdb_type_router_head (u_int16_t type, u_int32_t adv_router,
324 struct ospf6_lsdb *lsdb)
325{
326 struct route_node *node;
327 struct prefix_ipv6 key;
328 struct ospf6_lsa *lsa;
718e3744 329
508e53e2 330 memset (&key, 0, sizeof (key));
331 ospf6_lsdb_set_key (&key, &type, sizeof (type));
332 ospf6_lsdb_set_key (&key, &adv_router, sizeof (adv_router));
718e3744 333
508e53e2 334 node = lsdb->table->top;
718e3744 335
508e53e2 336 /* Walk down tree. */
337 while (node && node->p.prefixlen <= key.prefixlen &&
338 prefix_match (&node->p, (struct prefix *) &key))
813f6a00 339 node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)];
718e3744 340
508e53e2 341 if (node)
342 route_lock_node (node);
343 while (node && node->info == NULL)
344 node = route_next (node);
718e3744 345
508e53e2 346 if (node == NULL)
347 return NULL;
718e3744 348
508e53e2 349 if (! prefix_match ((struct prefix *) &key, &node->p))
350 return NULL;
718e3744 351
508e53e2 352 lsa = node->info;
353 ospf6_lsa_lock (lsa);
718e3744 354
508e53e2 355 return lsa;
718e3744 356}
357
508e53e2 358struct ospf6_lsa *
359ospf6_lsdb_type_router_next (u_int16_t type, u_int32_t adv_router,
360 struct ospf6_lsa *lsa)
718e3744 361{
a765eb93 362 struct ospf6_lsa *next = ospf6_lsdb_next(lsa);
718e3744 363
508e53e2 364 if (next)
718e3744 365 {
508e53e2 366 if (next->header->type != type ||
367 next->header->adv_router != adv_router)
a765eb93
DD
368 {
369 route_unlock_node (next->rn);
370 ospf6_lsa_unlock (next);
371 next = NULL;
372 }
718e3744 373 }
718e3744 374
508e53e2 375 return next;
718e3744 376}
377
508e53e2 378struct ospf6_lsa *
379ospf6_lsdb_type_head (u_int16_t type, struct ospf6_lsdb *lsdb)
718e3744 380{
508e53e2 381 struct route_node *node;
382 struct prefix_ipv6 key;
383 struct ospf6_lsa *lsa;
718e3744 384
508e53e2 385 memset (&key, 0, sizeof (key));
386 ospf6_lsdb_set_key (&key, &type, sizeof (type));
718e3744 387
508e53e2 388 /* Walk down tree. */
389 node = lsdb->table->top;
390 while (node && node->p.prefixlen <= key.prefixlen &&
391 prefix_match (&node->p, (struct prefix *) &key))
813f6a00 392 node = node->link[prefix6_bit(&key.prefix, node->p.prefixlen)];
718e3744 393
508e53e2 394 if (node)
395 route_lock_node (node);
396 while (node && node->info == NULL)
397 node = route_next (node);
718e3744 398
508e53e2 399 if (node == NULL)
400 return NULL;
718e3744 401
508e53e2 402 if (! prefix_match ((struct prefix *) &key, &node->p))
403 return NULL;
718e3744 404
508e53e2 405 lsa = node->info;
406 ospf6_lsa_lock (lsa);
718e3744 407
508e53e2 408 return lsa;
718e3744 409}
410
508e53e2 411struct ospf6_lsa *
412ospf6_lsdb_type_next (u_int16_t type, struct ospf6_lsa *lsa)
718e3744 413{
a765eb93 414 struct ospf6_lsa *next = ospf6_lsdb_next (lsa);
718e3744 415
508e53e2 416 if (next)
718e3744 417 {
508e53e2 418 if (next->header->type != type)
a765eb93
DD
419 {
420 route_unlock_node (next->rn);
421 ospf6_lsa_unlock (next);
422 next = NULL;
423 }
718e3744 424 }
425
508e53e2 426 return next;
718e3744 427}
428
718e3744 429void
508e53e2 430ospf6_lsdb_remove_all (struct ospf6_lsdb *lsdb)
718e3744 431{
508e53e2 432 struct ospf6_lsa *lsa;
a765eb93
DD
433
434 if (lsdb == NULL)
435 return;
436
508e53e2 437 for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
438 ospf6_lsdb_remove (lsa, lsdb);
718e3744 439}
440
a765eb93
DD
441void
442ospf6_lsdb_lsa_unlock (struct ospf6_lsa *lsa)
443{
444 if (lsa != NULL)
445 {
446 if (lsa->rn != NULL)
447 route_unlock_node (lsa->rn);
448 ospf6_lsa_unlock (lsa);
449 }
450}
451
2449fcd6
DD
452int
453ospf6_lsdb_maxage_remover (struct ospf6_lsdb *lsdb)
454{
455 int reschedule = 0;
456 struct ospf6_lsa *lsa;
457
458 for (lsa = ospf6_lsdb_head (lsdb); lsa; lsa = ospf6_lsdb_next (lsa))
459 {
460 if (! OSPF6_LSA_IS_MAXAGE (lsa))
461 continue;
462 if (lsa->retrans_count != 0)
463 {
464 reschedule = 1;
465 continue;
466 }
467 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type))
468 zlog_debug ("Remove MaxAge %s", lsa->name);
3b220289
DD
469 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED))
470 {
471 UNSET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
472 /*
473 * lsa->header->age = 0;
474 */
475 lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER + 1);
476 ospf6_lsa_checksum (lsa->header);
11b4f013
DL
477
478 THREAD_OFF(lsa->refresh);
3b220289
DD
479 thread_execute (master, ospf6_lsa_refresh, lsa, 0);
480 } else {
481 ospf6_lsdb_remove (lsa, lsdb);
482 }
2449fcd6
DD
483 }
484
485 return (reschedule);
486}
487
049207c3 488void
f58c5fbd 489ospf6_lsdb_show (struct vty *vty, enum ospf_lsdb_show_level level,
049207c3 490 u_int16_t *type, u_int32_t *id, u_int32_t *adv_router,
491 struct ospf6_lsdb *lsdb)
492{
493 struct ospf6_lsa *lsa;
494 void (*showfunc) (struct vty *, struct ospf6_lsa *) = NULL;
495
f58c5fbd
PJ
496 switch (level)
497 {
498 case OSPF6_LSDB_SHOW_LEVEL_DETAIL:
499 showfunc = ospf6_lsa_show;
500 break;
501 case OSPF6_LSDB_SHOW_LEVEL_INTERNAL:
502 showfunc = ospf6_lsa_show_internal;
503 break;
504 case OSPF6_LSDB_SHOW_LEVEL_DUMP:
505 showfunc = ospf6_lsa_show_dump;
506 break;
507 case OSPF6_LSDB_SHOW_LEVEL_NORMAL:
508 default:
509 showfunc = ospf6_lsa_show_summary;
510 }
511
049207c3 512 if (type && id && adv_router)
513 {
514 lsa = ospf6_lsdb_lookup (*type, *id, *adv_router, lsdb);
515 if (lsa)
516 {
517 if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
518 ospf6_lsa_show (vty, lsa);
519 else
520 (*showfunc) (vty, lsa);
521 }
522 return;
523 }
524
525 if (level == OSPF6_LSDB_SHOW_LEVEL_NORMAL)
526 ospf6_lsa_show_summary_header (vty);
527
528 if (type && adv_router)
529 lsa = ospf6_lsdb_type_router_head (*type, *adv_router, lsdb);
530 else if (type)
531 lsa = ospf6_lsdb_type_head (*type, lsdb);
532 else
533 lsa = ospf6_lsdb_head (lsdb);
534 while (lsa)
535 {
536 if ((! adv_router || lsa->header->adv_router == *adv_router) &&
537 (! id || lsa->header->id == *id))
538 (*showfunc) (vty, lsa);
539
540 if (type && adv_router)
541 lsa = ospf6_lsdb_type_router_next (*type, *adv_router, lsa);
542 else if (type)
543 lsa = ospf6_lsdb_type_next (*type, lsa);
544 else
545 lsa = ospf6_lsdb_next (lsa);
546 }
547}
548
049207c3 549u_int32_t
550ospf6_new_ls_id (u_int16_t type, u_int32_t adv_router,
551 struct ospf6_lsdb *lsdb)
552{
553 struct ospf6_lsa *lsa;
c3c0ac83 554 u_int32_t id = 1, tmp_id;
049207c3 555
c3c0ac83
DS
556 /* This routine is curently invoked only for Inter-Prefix LSAs for
557 * non-summarized routes (no area/range).
558 */
049207c3 559 for (lsa = ospf6_lsdb_type_router_head (type, adv_router, lsdb); lsa;
560 lsa = ospf6_lsdb_type_router_next (type, adv_router, lsa))
561 {
c3c0ac83
DS
562 tmp_id = ntohl (lsa->header->id);
563 if (tmp_id < id)
564 continue;
565
566 if (tmp_id > id)
16c1c487 567 {
a765eb93 568 ospf6_lsdb_lsa_unlock (lsa);
6452df09 569 break;
16c1c487 570 }
049207c3 571 id++;
572 }
573
574 return ((u_int32_t) htonl (id));
575}
576
577/* Decide new LS sequence number to originate.
578 note return value is network byte order */
579u_int32_t
580ospf6_new_ls_seqnum (u_int16_t type, u_int32_t id, u_int32_t adv_router,
581 struct ospf6_lsdb *lsdb)
582{
583 struct ospf6_lsa *lsa;
584 signed long seqnum = 0;
585
586 /* if current database copy not found, return InitialSequenceNumber */
587 lsa = ospf6_lsdb_lookup (type, id, adv_router, lsdb);
588 if (lsa == NULL)
8551e6da 589 seqnum = OSPF_INITIAL_SEQUENCE_NUMBER;
049207c3 590 else
591 seqnum = (signed long) ntohl (lsa->header->seqnum) + 1;
592
593 return ((u_int32_t) htonl (seqnum));
594}
595
718e3744 596