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