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