]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_lsa.c
SVN revision 907 from Zebra cvs repository.
[mirror_frr.git] / ospf6d / ospf6_lsa.c
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 other stuffs */
25 #include "log.h"
26 #include "linklist.h"
27 #include "command.h"
28 #include "memory.h"
29 #include "thread.h"
30
31 #include "ospf6_proto.h"
32 #include "ospf6_lsa.h"
33 #include "ospf6_lsdb.h"
34 #include "ospf6_message.h"
35
36 #include "ospf6_top.h"
37 #include "ospf6_area.h"
38 #include "ospf6_interface.h"
39 #include "ospf6_neighbor.h"
40
41 #include "ospf6_flood.h"
42 #include "ospf6d.h"
43
44 unsigned char conf_debug_ospf6_lsa = 0;
45
46 struct ospf6_lstype ospf6_lstype[OSPF6_LSTYPE_SIZE];
47
48 char *ospf6_lstype_str[OSPF6_LSTYPE_SIZE] =
49 {"Unknown", "Router", "Network", "Inter-Prefix", "Inter-Router",
50 "AS-External", "Group-Membership", "Type-7", "Link", "Intra-Prefix"};
51
52 char *
53 ospf6_lstype_name (u_int16_t type)
54 {
55 static char buf[8];
56 int index = ntohs (type) & OSPF6_LSTYPE_FCODE_MASK;
57
58 if (index < OSPF6_LSTYPE_SIZE && ospf6_lstype_str[index])
59 return ospf6_lstype_str[index];
60
61 snprintf (buf, sizeof (buf), "0x%04hx", ntohs (type));
62 return buf;
63 }
64
65 /* RFC2328: Section 13.2 */
66 int
67 ospf6_lsa_is_differ (struct ospf6_lsa *lsa1,
68 struct ospf6_lsa *lsa2)
69 {
70 int len;
71
72 assert (OSPF6_LSA_IS_SAME (lsa1, lsa2));
73
74 /* XXX, Options ??? */
75
76 ospf6_lsa_age_current (lsa1);
77 ospf6_lsa_age_current (lsa2);
78 if (ntohs (lsa1->header->age) == MAXAGE &&
79 ntohs (lsa2->header->age) != MAXAGE)
80 return 1;
81 if (ntohs (lsa1->header->age) != MAXAGE &&
82 ntohs (lsa2->header->age) == MAXAGE)
83 return 1;
84
85 /* compare body */
86 if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
87 return 1;
88
89 len = ntohs (lsa1->header->length) - sizeof (struct ospf6_lsa_header);
90 return memcmp (lsa1->header + 1, lsa2->header + 1, len);
91 }
92
93 int
94 ospf6_lsa_is_changed (struct ospf6_lsa *lsa1,
95 struct ospf6_lsa *lsa2)
96 {
97 int length;
98
99 if (OSPF6_LSA_IS_MAXAGE (lsa1) ^ OSPF6_LSA_IS_MAXAGE (lsa2))
100 return 1;
101 if (ntohs (lsa1->header->length) != ntohs (lsa2->header->length))
102 return 1;
103
104 length = OSPF6_LSA_SIZE (lsa1->header) - sizeof (struct ospf6_lsa_header);
105 assert (length > 0);
106
107 return memcmp (OSPF6_LSA_HEADER_END (lsa1->header),
108 OSPF6_LSA_HEADER_END (lsa2->header), length);
109 }
110
111 /* ospf6 age functions */
112 /* calculate birth and set expire timer */
113 static void
114 ospf6_lsa_age_set (struct ospf6_lsa *lsa)
115 {
116 struct timeval now;
117
118 assert (lsa && lsa->header);
119
120 if (gettimeofday (&now, (struct timezone *)NULL) < 0)
121 zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
122 strerror (errno));
123
124 lsa->birth.tv_sec = now.tv_sec - ntohs (lsa->header->age);
125 lsa->birth.tv_usec = now.tv_usec;
126 if (ntohs (lsa->header->age) != MAXAGE)
127 lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
128 MAXAGE + lsa->birth.tv_sec
129 - now.tv_sec);
130 else
131 lsa->expire = NULL;
132 return;
133 }
134
135 /* this function calculates current age from its birth,
136 then update age field of LSA header. return value is current age */
137 u_int16_t
138 ospf6_lsa_age_current (struct ospf6_lsa *lsa)
139 {
140 struct timeval now;
141 u_int32_t ulage;
142 u_int16_t age;
143
144 assert (lsa);
145 assert (lsa->header);
146
147 /* current time */
148 if (gettimeofday (&now, (struct timezone *)NULL) < 0)
149 zlog_warn ("LSA: gettimeofday failed, may fail LSA AGEs: %s",
150 strerror (errno));
151
152 /* calculate age */
153 ulage = now.tv_sec - lsa->birth.tv_sec;
154
155 /* if over MAXAGE, set to it */
156 age = (ulage > MAXAGE ? MAXAGE : ulage);
157
158 lsa->header->age = htons (age);
159 return age;
160 }
161
162 /* update age field of LSA header with adding InfTransDelay */
163 void
164 ospf6_lsa_age_update_to_send (struct ospf6_lsa *lsa, u_int32_t transdelay)
165 {
166 unsigned short age;
167
168 age = ospf6_lsa_age_current (lsa) + transdelay;
169 if (age > MAXAGE)
170 age = MAXAGE;
171 lsa->header->age = htons (age);
172 }
173
174 void
175 ospf6_lsa_premature_aging (struct ospf6_lsa *lsa)
176 {
177 /* log */
178 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
179 zlog_info ("LSA: Premature aging: %s", lsa->name);
180
181 THREAD_OFF (lsa->expire);
182 THREAD_OFF (lsa->refresh);
183
184 memset (&lsa->birth, 0, sizeof (struct timeval));
185 thread_execute (master, ospf6_lsa_expire, lsa, 0);
186 }
187
188 /* check which is more recent. if a is more recent, return -1;
189 if the same, return 0; otherwise(b is more recent), return 1 */
190 int
191 ospf6_lsa_compare (struct ospf6_lsa *a, struct ospf6_lsa *b)
192 {
193 signed long seqnuma, seqnumb;
194 u_int16_t cksuma, cksumb;
195 u_int16_t agea, ageb;
196
197 assert (a && a->header);
198 assert (b && b->header);
199 assert (OSPF6_LSA_IS_SAME (a, b));
200
201 seqnuma = ((signed long) ntohl (a->header->seqnum))
202 - (signed long) INITIAL_SEQUENCE_NUMBER;
203 seqnumb = ((signed long) ntohl (b->header->seqnum))
204 - (signed long) INITIAL_SEQUENCE_NUMBER;
205
206 /* compare by sequence number */
207 /* XXX, LS sequence number wrapping */
208 if (seqnuma > seqnumb)
209 return -1;
210 else if (seqnuma < seqnumb)
211 return 1;
212
213 /* Checksum */
214 cksuma = ntohs (a->header->checksum);
215 cksumb = ntohs (b->header->checksum);
216 if (cksuma > cksumb)
217 return -1;
218 if (cksuma < cksumb)
219 return 0;
220
221 /* Update Age */
222 agea = ospf6_lsa_age_current (a);
223 ageb = ospf6_lsa_age_current (b);
224
225 /* MaxAge check */
226 if (agea == MAXAGE && ageb != MAXAGE)
227 return -1;
228 else if (agea != MAXAGE && ageb == MAXAGE)
229 return 1;
230
231 /* Age check */
232 if (agea > ageb && agea - ageb >= MAX_AGE_DIFF)
233 return 1;
234 else if (agea < ageb && ageb - agea >= MAX_AGE_DIFF)
235 return -1;
236
237 /* neither recent */
238 return 0;
239 }
240
241 char *
242 ospf6_lsa_printbuf (struct ospf6_lsa *lsa, char *buf, int size)
243 {
244 char id[16], adv_router[16];
245 inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
246 inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
247 sizeof (adv_router));
248 snprintf (buf, size, "[%s Id:%s Adv:%s]",
249 OSPF6_LSTYPE_NAME (lsa->header->type), id, adv_router);
250 return buf;
251 }
252
253 void
254 ospf6_lsa_header_print_raw (struct ospf6_lsa_header *header)
255 {
256 char id[16], adv_router[16];
257 inet_ntop (AF_INET, &header->id, id, sizeof (id));
258 inet_ntop (AF_INET, &header->adv_router, adv_router,
259 sizeof (adv_router));
260 zlog_info (" [%s Id:%s Adv:%s]",
261 OSPF6_LSTYPE_NAME (header->type), id, adv_router);
262 zlog_info (" Age: %4hu SeqNum: %#08lx Cksum: %04hx Len: %d",
263 ntohs (header->age), (u_long) ntohl (header->seqnum),
264 ntohs (header->checksum), ntohs (header->length));
265 }
266
267 void
268 ospf6_lsa_header_print (struct ospf6_lsa *lsa)
269 {
270 ospf6_lsa_age_current (lsa);
271 ospf6_lsa_header_print_raw (lsa->header);
272 }
273
274 void
275 ospf6_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
276 {
277 char adv_router[64], id[64];
278 int index;
279
280 assert (lsa && lsa->header);
281
282 inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
283 inet_ntop (AF_INET, &lsa->header->adv_router,
284 adv_router, sizeof (adv_router));
285
286 vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
287 OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
288 vty_out (vty, "Link State ID: %s%s", id, VNL);
289 vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
290 vty_out (vty, "LS Sequence Number: %#010lx%s",
291 (u_long) ntohl (lsa->header->seqnum), VNL);
292 vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
293 ntohs (lsa->header->checksum),
294 ntohs (lsa->header->length), VNL);
295
296 index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
297 if (ospf6_lstype[index].show)
298 (*ospf6_lstype[index].show) (vty, lsa);
299 else
300 vty_out (vty, "%sUnknown LSA type ...%s", VNL, VNL);
301
302 vty_out (vty, "%s", VNL);
303 }
304
305 void
306 ospf6_lsa_show_summary_header (struct vty *vty)
307 {
308 vty_out (vty, "%-12s %-15s %-15s %4s %8s %4s %4s %-8s%s",
309 "Type", "LSId", "AdvRouter", "Age", "SeqNum",
310 "Cksm", "Len", "Duration", VNL);
311 }
312
313 void
314 ospf6_lsa_show_summary (struct vty *vty, struct ospf6_lsa *lsa)
315 {
316 char adv_router[16], id[16];
317 struct timeval now, res;
318 char duration[16];
319
320 assert (lsa);
321 assert (lsa->header);
322
323 inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
324 inet_ntop (AF_INET, &lsa->header->adv_router, adv_router,
325 sizeof (adv_router));
326
327 gettimeofday (&now, NULL);
328 timersub (&now, &lsa->installed, &res);
329 timerstring (&res, duration, sizeof (duration));
330
331 vty_out (vty, "%-12s %-15s %-15s %4hu %8lx %04hx %4hu %8s%s",
332 OSPF6_LSTYPE_NAME (lsa->header->type),
333 id, adv_router, ospf6_lsa_age_current (lsa),
334 (u_long) ntohl (lsa->header->seqnum),
335 ntohs (lsa->header->checksum), ntohs (lsa->header->length),
336 duration, VNL);
337 }
338
339 void
340 ospf6_lsa_show_dump (struct vty *vty, struct ospf6_lsa *lsa)
341 {
342 u_char *start, *end, *current;
343 char byte[4];
344
345 start = (char *) lsa->header;
346 end = (char *) lsa->header + ntohs (lsa->header->length);
347
348 vty_out (vty, "%s", VNL);
349 vty_out (vty, "%s:%s", lsa->name, VNL);
350
351 for (current = start; current < end; current ++)
352 {
353 if ((current - start) % 16 == 0)
354 vty_out (vty, "%s ", VNL);
355 else if ((current - start) % 4 == 0)
356 vty_out (vty, " ");
357
358 snprintf (byte, sizeof (byte), "%02x", *current);
359 vty_out (vty, "%s", byte);
360 }
361
362 vty_out (vty, "%s%s", VNL, VNL);
363 }
364
365 void
366 ospf6_lsa_show_internal (struct vty *vty, struct ospf6_lsa *lsa)
367 {
368 char adv_router[64], id[64];
369
370 assert (lsa && lsa->header);
371
372 inet_ntop (AF_INET, &lsa->header->id, id, sizeof (id));
373 inet_ntop (AF_INET, &lsa->header->adv_router,
374 adv_router, sizeof (adv_router));
375
376 vty_out (vty, "%s", VNL);
377 vty_out (vty, "Age: %4hu Type: %s%s", ospf6_lsa_age_current (lsa),
378 OSPF6_LSTYPE_NAME (lsa->header->type), VNL);
379 vty_out (vty, "Link State ID: %s%s", id, VNL);
380 vty_out (vty, "Advertising Router: %s%s", adv_router, VNL);
381 vty_out (vty, "LS Sequence Number: %#010lx%s",
382 (u_long) ntohl (lsa->header->seqnum), VNL);
383 vty_out (vty, "CheckSum: %#06hx Length: %hu%s",
384 ntohs (lsa->header->checksum),
385 ntohs (lsa->header->length), VNL);
386 vty_out (vty, " Prev: %p This: %p Next: %p%s",
387 lsa->prev, lsa, lsa->next, VNL);
388 vty_out (vty, "%s", VNL);
389 }
390
391 /* OSPFv3 LSA creation/deletion function */
392
393 struct ospf6_lsa *
394 ospf6_lsa_create (struct ospf6_lsa_header *header)
395 {
396 struct ospf6_lsa *lsa = NULL;
397 struct ospf6_lsa_header *new_header = NULL;
398 u_int16_t lsa_size = 0;
399
400 /* size of the entire LSA */
401 lsa_size = ntohs (header->length); /* XXX vulnerable */
402
403 /* allocate memory for this LSA */
404 new_header = (struct ospf6_lsa_header *)
405 XMALLOC (MTYPE_OSPF6_LSA, lsa_size);
406
407 /* copy LSA from original header */
408 memcpy (new_header, header, lsa_size);
409
410 /* LSA information structure */
411 /* allocate memory */
412 lsa = (struct ospf6_lsa *)
413 XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
414 memset (lsa, 0, sizeof (struct ospf6_lsa));
415
416 lsa->header = (struct ospf6_lsa_header *) new_header;
417 lsa->headeronly = 0; /* this is not header only */
418
419 /* dump string */
420 ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
421
422 /* calculate birth, expire and refresh of this lsa */
423 ospf6_lsa_age_set (lsa);
424
425 if (IS_OSPF6_DEBUG_LSA (MEMORY))
426 zlog_info ("Create LSA Memory: %s (%p/%p)",
427 lsa->name, lsa, lsa->header);
428
429 return lsa;
430 }
431
432 struct ospf6_lsa *
433 ospf6_lsa_create_headeronly (struct ospf6_lsa_header *header)
434 {
435 struct ospf6_lsa *lsa = NULL;
436 struct ospf6_lsa_header *new_header = NULL;
437
438 /* allocate memory for this LSA */
439 new_header = (struct ospf6_lsa_header *)
440 XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_header));
441
442 /* copy LSA from original header */
443 memcpy (new_header, header, sizeof (struct ospf6_lsa_header));
444
445 /* LSA information structure */
446 /* allocate memory */
447 lsa = (struct ospf6_lsa *)
448 XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa));
449 memset (lsa, 0, sizeof (struct ospf6_lsa));
450
451 lsa->header = (struct ospf6_lsa_header *) new_header;
452 lsa->headeronly = 1; /* this is header only */
453
454 /* dump string */
455 ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name));
456
457 /* calculate birth, expire and refresh of this lsa */
458 ospf6_lsa_age_set (lsa);
459
460 if (IS_OSPF6_DEBUG_LSA (MEMORY))
461 zlog_info ("Create LSA (Header-only) Memory: %s (%p/%p)",
462 lsa->name, lsa, lsa->header);
463
464 return lsa;
465 }
466
467 void
468 ospf6_lsa_delete (struct ospf6_lsa *lsa)
469 {
470 assert (lsa->lock == 0);
471
472 /* cancel threads */
473 THREAD_OFF (lsa->expire);
474 THREAD_OFF (lsa->refresh);
475
476 if (IS_OSPF6_DEBUG_LSA (MEMORY))
477 zlog_info ("Delete LSA %s Memory: %s (%p/%p)",
478 (lsa->headeronly ? "(Header-only) " : ""),
479 lsa->name, lsa, lsa->header);
480
481 /* do free */
482 XFREE (MTYPE_OSPF6_LSA, lsa->header);
483 XFREE (MTYPE_OSPF6_LSA, lsa);
484 }
485
486 struct ospf6_lsa *
487 ospf6_lsa_copy (struct ospf6_lsa *lsa)
488 {
489 struct ospf6_lsa *copy = NULL;
490
491 if (IS_OSPF6_DEBUG_LSA (MEMORY))
492 zlog_info ("Create LSA Copy from %s", lsa->name);
493
494 ospf6_lsa_age_current (lsa);
495 if (lsa->headeronly)
496 copy = ospf6_lsa_create_headeronly (lsa->header);
497 else
498 copy = ospf6_lsa_create (lsa->header);
499 assert (copy->lock == 0);
500
501 copy->installed = lsa->installed;
502 copy->originated = lsa->originated;
503 copy->scope = lsa->scope;
504
505 return copy;
506 }
507
508 /* increment reference counter of struct ospf6_lsa */
509 void
510 ospf6_lsa_lock (struct ospf6_lsa *lsa)
511 {
512 lsa->lock++;
513 return;
514 }
515
516 /* decrement reference counter of struct ospf6_lsa */
517 void
518 ospf6_lsa_unlock (struct ospf6_lsa *lsa)
519 {
520 /* decrement reference counter */
521 assert (lsa->lock > 0);
522 lsa->lock--;
523
524 if (lsa->lock != 0)
525 return;
526
527 ospf6_lsa_delete (lsa);
528 }
529
530 void
531 ospf6_lsa_originate (struct ospf6_lsa *lsa)
532 {
533 struct ospf6_lsa *old;
534 struct ospf6_lsdb *lsdb = NULL;
535
536 /* find previous LSA */
537 lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
538 if (lsdb == NULL)
539 {
540 zlog_warn ("Can't decide scoped LSDB");
541 ospf6_lsa_delete (lsa);
542 return;
543 }
544
545 old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
546 lsa->header->adv_router, lsdb);
547 if (old)
548 {
549 /* If this origination is neither different instance nor refresh,
550 suppress this origination */
551 if (! CHECK_FLAG (old->flag, OSPF6_LSA_REFRESH) &&
552 ! OSPF6_LSA_IS_DIFFER (lsa, old))
553 {
554 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
555 zlog_info ("Suppress updating LSA: %s", lsa->name);
556 ospf6_lsa_delete (lsa);
557 return;
558 }
559 }
560
561 lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
562 LS_REFRESH_TIME);
563
564 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
565 {
566 zlog_info ("LSA Originate:");
567 ospf6_lsa_header_print (lsa);
568 }
569
570 if (old)
571 ospf6_flood_clear (old);
572 ospf6_flood_lsa (lsa, NULL);
573 ospf6_install_lsa (lsa, lsdb);
574 }
575
576 void
577 ospf6_lsa_re_originate (struct ospf6_lsa *lsa)
578 {
579 u_int16_t index;
580
581 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
582 {
583 zlog_info ("LSA Reoriginate:");
584 ospf6_lsa_header_print (lsa);
585 }
586
587 index = OSPF6_LSTYPE_INDEX (ntohs (lsa->header->type));
588 if (ospf6_lstype[index].reoriginate)
589 (*ospf6_lstype[index].reoriginate) (lsa);
590 else
591 ospf6_lsa_premature_aging (lsa);
592 }
593
594 \f
595 /* ospf6 lsa expiry */
596 int
597 ospf6_lsa_expire (struct thread *thread)
598 {
599 struct ospf6_lsa *lsa;
600 struct ospf6_lsdb *lsdb = NULL;
601
602 lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
603
604 assert (lsa && lsa->header);
605 assert (OSPF6_LSA_IS_MAXAGE (lsa));
606 assert (! lsa->refresh);
607
608 lsa->expire = (struct thread *) NULL;
609
610 if (IS_OSPF6_DEBUG_LSA (TIMER))
611 {
612 zlog_info ("LSA Expire:");
613 ospf6_lsa_header_print (lsa);
614 }
615
616 if (lsa->headeronly)
617 return 0; /* dbexchange will do something ... */
618
619 /* reflood lsa */
620 ospf6_flood_lsa (lsa, NULL);
621
622 /* reinstall lsa */
623 lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
624 if (lsdb == NULL)
625 {
626 zlog_warn ("Can't decide scoped LSDB: %s", lsa->name);
627 return 0;
628 }
629 if (IS_OSPF6_DEBUG_LSA (DATABASE))
630 zlog_info ("Reinstall MaxAge %s", lsa->name);
631 ospf6_lsdb_add (lsa, lsdb);
632
633 /* schedule maxage remover */
634 ospf6_maxage_remove (ospf6);
635
636 return 0;
637 }
638
639 /* Below will become dummy thread.
640 refresh function must be set individually per each LSAs */
641 int
642 ospf6_lsa_refresh (struct thread *thread)
643 {
644 struct ospf6_lsa *lsa;
645
646 assert (thread);
647 lsa = (struct ospf6_lsa *) THREAD_ARG (thread);
648 assert (lsa && lsa->header);
649
650 lsa->refresh = (struct thread *) NULL;
651
652 /* this will be used later to decide really originate or not */
653 SET_FLAG (lsa->flag, OSPF6_LSA_REFRESH);
654
655 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
656 {
657 zlog_info ("LSA Refresh:");
658 ospf6_lsa_header_print (lsa);
659 }
660
661 ospf6_lsa_re_originate (lsa);
662 return 0;
663 }
664
665 \f
666
667 /* enhanced Fletcher checksum algorithm, RFC1008 7.2 */
668 #define MODX 4102
669 #define LSA_CHECKSUM_OFFSET 15
670
671 unsigned short
672 ospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header)
673 {
674 u_char *sp, *ep, *p, *q;
675 int c0 = 0, c1 = 0;
676 int x, y;
677 u_int16_t length;
678
679 lsa_header->checksum = 0;
680 length = ntohs (lsa_header->length) - 2;
681 sp = (char *) &lsa_header->type;
682
683 for (ep = sp + length; sp < ep; sp = q)
684 {
685 q = sp + MODX;
686 if (q > ep)
687 q = ep;
688 for (p = sp; p < q; p++)
689 {
690 c0 += *p;
691 c1 += c0;
692 }
693 c0 %= 255;
694 c1 %= 255;
695 }
696
697 /* r = (c1 << 8) + c0; */
698 x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
699 if (x <= 0)
700 x += 255;
701 y = 510 - c0 - x;
702 if (y > 255)
703 y -= 255;
704
705 lsa_header->checksum = htons ((x << 8) + y);
706
707 return (lsa_header->checksum);
708 }
709
710 int
711 ospf6_unknown_reoriginate (struct ospf6_lsa *lsa)
712 {
713 ospf6_lsa_premature_aging (lsa);
714 return 0;
715 }
716
717 int
718 ospf6_unknown_show (struct vty *vty, struct ospf6_lsa *lsa)
719 {
720 u_char *start, *end, *current;
721 char byte[4];
722
723 start = (char *) lsa->header + sizeof (struct ospf6_lsa_header);
724 end = (char *) lsa->header + ntohs (lsa->header->length);
725
726 vty_out (vty, " Unknown contents:%s", VNL);
727 for (current = start; current < end; current ++)
728 {
729 if ((current - start) % 16 == 0)
730 vty_out (vty, "%s ", VNL);
731 else if ((current - start) % 4 == 0)
732 vty_out (vty, " ");
733
734 snprintf (byte, sizeof (byte), "%02x", *current);
735 vty_out (vty, "%s", byte);
736 }
737
738 vty_out (vty, "%s%s", VNL, VNL);
739 return 0;
740 }
741
742 void
743 ospf6_lsa_init ()
744 {
745 memset (ospf6_lstype, 0, sizeof (ospf6_lstype));
746
747 ospf6_lstype[0].name = "Unknown";
748 ospf6_lstype[0].reoriginate = ospf6_unknown_reoriginate;
749 ospf6_lstype[0].show = ospf6_unknown_show;
750 }
751
752 \f
753
754 DEFUN (debug_ospf6_lsa_sendrecv,
755 debug_ospf6_lsa_sendrecv_cmd,
756 "debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
757 DEBUG_STR
758 OSPF6_STR
759 "Debug Link State Advertisements (LSAs)\n"
760 "Debug Sending LSAs\n"
761 "Debug Receiving LSAs\n"
762 "Debug Originating LSAs\n"
763 "Debug Timer Event of LSAs\n"
764 "Debug LSA Database\n"
765 "Debug Memory of LSAs\n"
766 "Debug LSAs all\n"
767 )
768 {
769 unsigned char level = 0;
770
771 if (argc)
772 {
773 if (! strncmp (argv[0], "s", 1))
774 level = OSPF6_DEBUG_LSA_SEND;
775 else if (! strncmp (argv[0], "r", 1))
776 level = OSPF6_DEBUG_LSA_RECV;
777 else if (! strncmp (argv[0], "o", 1))
778 level = OSPF6_DEBUG_LSA_ORIGINATE;
779 else if (! strncmp (argv[0], "t", 1))
780 level = OSPF6_DEBUG_LSA_TIMER;
781 else if (! strncmp (argv[0], "d", 1))
782 level = OSPF6_DEBUG_LSA_DATABASE;
783 else if (! strncmp (argv[0], "m", 1))
784 level = OSPF6_DEBUG_LSA_MEMORY;
785 else if (! strncmp (argv[0], "a", 1))
786 {
787 level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
788 OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
789 OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
790 }
791 }
792 else
793 {
794 level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
795 OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
796 }
797
798 OSPF6_DEBUG_LSA_ON (level);
799 return CMD_SUCCESS;
800 }
801
802 ALIAS (debug_ospf6_lsa_sendrecv,
803 debug_ospf6_lsa_cmd,
804 "debug ospf6 lsa",
805 NO_STR
806 DEBUG_STR
807 OSPF6_STR
808 "Debug Link State Advertisements (LSAs)\n"
809 );
810
811 DEFUN (no_debug_ospf6_lsa_sendrecv,
812 no_debug_ospf6_lsa_sendrecv_cmd,
813 "no debug ospf6 lsa (send|recv|originate|timer|database|memory|all)",
814 NO_STR
815 DEBUG_STR
816 OSPF6_STR
817 "Debug Link State Advertisements (LSAs)\n"
818 "Debug Sending LSAs\n"
819 "Debug Receiving LSAs\n"
820 "Debug Originating LSAs\n"
821 "Debug Timer Event of LSAs\n"
822 "Debug LSA Database\n"
823 "Debug Memory of LSAs\n"
824 "Debug LSAs all\n"
825 )
826 {
827 unsigned char level = 0;
828
829 if (argc)
830 {
831 if (! strncmp (argv[0], "s", 1))
832 level = OSPF6_DEBUG_LSA_SEND;
833 else if (! strncmp (argv[0], "r", 1))
834 level = OSPF6_DEBUG_LSA_RECV;
835 else if (! strncmp (argv[0], "o", 1))
836 level = OSPF6_DEBUG_LSA_ORIGINATE;
837 else if (! strncmp (argv[0], "t", 1))
838 level = OSPF6_DEBUG_LSA_TIMER;
839 else if (! strncmp (argv[0], "d", 1))
840 level = OSPF6_DEBUG_LSA_DATABASE;
841 else if (! strncmp (argv[0], "m", 1))
842 level = OSPF6_DEBUG_LSA_MEMORY;
843 else if (! strncmp (argv[0], "a", 1))
844 {
845 level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
846 OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER |
847 OSPF6_DEBUG_LSA_DATABASE | OSPF6_DEBUG_LSA_MEMORY;
848 }
849 }
850 else
851 {
852 level = OSPF6_DEBUG_LSA_SEND | OSPF6_DEBUG_LSA_RECV |
853 OSPF6_DEBUG_LSA_ORIGINATE | OSPF6_DEBUG_LSA_TIMER;
854 }
855
856 OSPF6_DEBUG_LSA_OFF (level);
857 return CMD_SUCCESS;
858 }
859
860 ALIAS (no_debug_ospf6_lsa_sendrecv,
861 no_debug_ospf6_lsa_cmd,
862 "no debug ospf6 lsa",
863 NO_STR
864 DEBUG_STR
865 OSPF6_STR
866 "Debug Link State Advertisements (LSAs)\n"
867 );
868
869 int
870 config_write_ospf6_debug_lsa (struct vty *vty)
871 {
872 if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_ALL)
873 vty_out (vty, "debug ospf6 lsa all%s", VNL);
874 else
875 {
876 if (conf_debug_ospf6_lsa == OSPF6_DEBUG_LSA_DEFAULT)
877 vty_out (vty, "debug ospf6 lsa%s", VNL);
878 else
879 {
880 if (IS_OSPF6_DEBUG_LSA (SEND))
881 vty_out (vty, "debug ospf6 lsa send%s", VNL);
882 if (IS_OSPF6_DEBUG_LSA (RECV))
883 vty_out (vty, "debug ospf6 lsa recv%s", VNL);
884 if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
885 vty_out (vty, "debug ospf6 lsa originate%s", VNL);
886 if (IS_OSPF6_DEBUG_LSA (TIMER))
887 vty_out (vty, "debug ospf6 lsa timer%s", VNL);
888 }
889
890 if (IS_OSPF6_DEBUG_LSA (DATABASE))
891 vty_out (vty, "debug ospf6 lsa database%s", VNL);
892 if (IS_OSPF6_DEBUG_LSA (MEMORY))
893 vty_out (vty, "debug ospf6 lsa memory%s", VNL);
894 }
895
896 return 0;
897 }
898
899 void
900 install_element_ospf6_debug_lsa ()
901 {
902 install_element (ENABLE_NODE, &debug_ospf6_lsa_cmd);
903 install_element (ENABLE_NODE, &debug_ospf6_lsa_sendrecv_cmd);
904 install_element (ENABLE_NODE, &no_debug_ospf6_lsa_cmd);
905 install_element (ENABLE_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
906 install_element (CONFIG_NODE, &debug_ospf6_lsa_cmd);
907 install_element (CONFIG_NODE, &debug_ospf6_lsa_sendrecv_cmd);
908 install_element (CONFIG_NODE, &no_debug_ospf6_lsa_cmd);
909 install_element (CONFIG_NODE, &no_debug_ospf6_lsa_sendrecv_cmd);
910 }
911
912