]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_message.c
* ospf6_message.c: Changed to be insensitive to changes of neighbors'
[mirror_frr.git] / ospf6d / ospf6_message.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
508e53e2 22#include <zebra.h>
23
3b4cd3a9 24#include "memory.h"
508e53e2 25#include "log.h"
26#include "vty.h"
27#include "command.h"
28#include "thread.h"
29#include "linklist.h"
30
508e53e2 31#include "ospf6_proto.h"
32#include "ospf6_lsa.h"
33#include "ospf6_lsdb.h"
34#include "ospf6_network.h"
35#include "ospf6_message.h"
718e3744 36
508e53e2 37#include "ospf6_top.h"
38#include "ospf6_area.h"
39#include "ospf6_neighbor.h"
40#include "ospf6_interface.h"
718e3744 41
508e53e2 42#include "ospf6_flood.h"
049207c3 43#include "ospf6d.h"
718e3744 44
508e53e2 45unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
0c083ee9 46const char *ospf6_message_type_str[] =
508e53e2 47 { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };
718e3744 48
508e53e2 49/* print functions */
718e3744 50
51static void
508e53e2 52ospf6_header_print (struct ospf6_header *oh)
718e3744 53{
508e53e2 54 char router_id[16], area_id[16];
55 inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id));
56 inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id));
57
c6487d61 58 zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s",
508e53e2 59 oh->version, oh->type, ntohs (oh->length), router_id);
c6487d61 60 zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d",
508e53e2 61 area_id, ntohs (oh->checksum), oh->instance_id);
718e3744 62}
63
508e53e2 64void
65ospf6_hello_print (struct ospf6_header *oh)
718e3744 66{
718e3744 67 struct ospf6_hello *hello;
508e53e2 68 char options[16];
69 char drouter[16], bdrouter[16], neighbor[16];
70 char *p;
718e3744 71
508e53e2 72 ospf6_header_print (oh);
73 assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
718e3744 74
508e53e2 75 hello = (struct ospf6_hello *)
76 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 77
508e53e2 78 inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter));
79 inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter));
80 ospf6_options_printbuf (hello->options, options, sizeof (options));
718e3744 81
c6487d61 82 zlog_debug (" I/F-Id:%ld Priority:%d Option:%s",
508e53e2 83 (u_long) ntohl (hello->interface_id), hello->priority, options);
c6487d61 84 zlog_debug (" HelloInterval:%hu DeadInterval:%hu",
508e53e2 85 ntohs (hello->hello_interval), ntohs (hello->dead_interval));
c6487d61 86 zlog_debug (" DR:%s BDR:%s", drouter, bdrouter);
718e3744 87
508e53e2 88 for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
89 p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
90 p += sizeof (u_int32_t))
718e3744 91 {
508e53e2 92 inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
c6487d61 93 zlog_debug (" Neighbor: %s", neighbor);
718e3744 94 }
508e53e2 95
96 if (p != OSPF6_MESSAGE_END (oh))
c6487d61 97 zlog_debug ("Trailing garbage exists");
718e3744 98}
99
508e53e2 100void
101ospf6_dbdesc_print (struct ospf6_header *oh)
718e3744 102{
718e3744 103 struct ospf6_dbdesc *dbdesc;
508e53e2 104 char options[16];
105 char *p;
106
107 ospf6_header_print (oh);
108 assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
109
110 dbdesc = (struct ospf6_dbdesc *)
111 ((caddr_t) oh + sizeof (struct ospf6_header));
112
113 ospf6_options_printbuf (dbdesc->options, options, sizeof (options));
114
c6487d61 115 zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu",
508e53e2 116 dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
c6487d61 117 zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
508e53e2 118 dbdesc->reserved2,
119 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
120 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
121 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
122 (u_long) ntohl (dbdesc->seqnum));
123
124 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
125 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
126 p += sizeof (struct ospf6_lsa_header))
127 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
128
129 if (p != OSPF6_MESSAGE_END (oh))
c6487d61 130 zlog_debug ("Trailing garbage exists");
718e3744 131}
132
508e53e2 133void
134ospf6_lsreq_print (struct ospf6_header *oh)
718e3744 135{
508e53e2 136 char id[16], adv_router[16];
137 char *p;
718e3744 138
508e53e2 139 ospf6_header_print (oh);
140 assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
718e3744 141
508e53e2 142 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
143 p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
144 p += sizeof (struct ospf6_lsreq_entry))
718e3744 145 {
508e53e2 146 struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p;
147 inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router));
148 inet_ntop (AF_INET, &e->id, id, sizeof (id));
c6487d61 149 zlog_debug (" [%s Id:%s Adv:%s]",
1e05838a 150 ospf6_lstype_name (e->type), id, adv_router);
718e3744 151 }
508e53e2 152
153 if (p != OSPF6_MESSAGE_END (oh))
c6487d61 154 zlog_debug ("Trailing garbage exists");
718e3744 155}
156
508e53e2 157void
158ospf6_lsupdate_print (struct ospf6_header *oh)
718e3744 159{
718e3744 160 struct ospf6_lsupdate *lsupdate;
508e53e2 161 u_long num;
162 char *p;
718e3744 163
508e53e2 164 ospf6_header_print (oh);
165 assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
718e3744 166
508e53e2 167 lsupdate = (struct ospf6_lsupdate *)
168 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 169
508e53e2 170 num = ntohl (lsupdate->lsa_number);
c6487d61 171 zlog_debug (" Number of LSA: %ld", num);
718e3744 172
508e53e2 173 for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
174 p < OSPF6_MESSAGE_END (oh) &&
175 p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
176 p += OSPF6_LSA_SIZE (p))
177 {
178 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
179 if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header))
180 {
c6487d61 181 zlog_debug (" Malformed LSA length, quit printing");
508e53e2 182 break;
183 }
184 }
718e3744 185
508e53e2 186 if (p != OSPF6_MESSAGE_END (oh))
718e3744 187 {
508e53e2 188 char buf[32];
189
190 int num = 0;
191 memset (buf, 0, sizeof (buf));
718e3744 192
c6487d61 193 zlog_debug (" Trailing garbage exists");
508e53e2 194 while (p < OSPF6_MESSAGE_END (oh))
195 {
196 snprintf (buf, sizeof (buf), "%s %2x", buf, *p++);
197 num++;
198 if (num == 8)
199 {
c6487d61 200 zlog_debug (" %s", buf);
508e53e2 201 memset (buf, 0, sizeof (buf));
202 num = 0;
203 }
204 }
205 if (num)
c6487d61 206 zlog_debug (" %s", buf);
718e3744 207 }
208}
209
508e53e2 210void
211ospf6_lsack_print (struct ospf6_header *oh)
718e3744 212{
508e53e2 213 char *p;
718e3744 214
508e53e2 215 ospf6_header_print (oh);
216 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
718e3744 217
508e53e2 218 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
219 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
220 p += sizeof (struct ospf6_lsa_header))
221 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
222
223 if (p != OSPF6_MESSAGE_END (oh))
c6487d61 224 zlog_debug ("Trailing garbage exists");
718e3744 225}
226
508e53e2 227/* Receive function */
228#define MSG_OK 0
229#define MSG_NG 1
230static int
231ospf6_header_examin (struct in6_addr *src, struct in6_addr *dst,
232 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 233{
718e3744 234 u_char type;
508e53e2 235 type = OSPF6_MESSAGE_TYPE_CANONICAL (oh->type);
718e3744 236
508e53e2 237 /* version check */
238 if (oh->version != OSPFV3_VERSION)
239 {
240 if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
c6487d61 241 zlog_debug ("Message with unknown version");
508e53e2 242 return MSG_NG;
243 }
718e3744 244
508e53e2 245 /* Area-ID check */
246 if (oh->area_id != oi->area->area_id)
247 {
6452df09 248 if (oh->area_id == BACKBONE_AREA_ID)
508e53e2 249 {
250 if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
c6487d61 251 zlog_debug ("Message may be via Virtual Link: not supported");
508e53e2 252 return MSG_NG;
253 }
718e3744 254
508e53e2 255 if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
c6487d61 256 zlog_debug ("Area-ID mismatch");
508e53e2 257 return MSG_NG;
258 }
718e3744 259
508e53e2 260 /* Instance-ID check */
261 if (oh->instance_id != oi->instance_id)
262 {
263 if (IS_OSPF6_DEBUG_MESSAGE (type, RECV))
c6487d61 264 zlog_debug ("Instance-ID mismatch");
508e53e2 265 return MSG_NG;
266 }
718e3744 267
508e53e2 268 /* Router-ID check */
269 if (oh->router_id == oi->area->ospf6->router_id)
270 zlog_warn ("Detect duplicate Router-ID");
718e3744 271
508e53e2 272 return MSG_OK;
718e3744 273}
274
275void
508e53e2 276ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
277 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 278{
718e3744 279 struct ospf6_hello *hello;
508e53e2 280 struct ospf6_neighbor *on;
281 char *p;
282 int twoway = 0;
283 int neighborchange = 0;
284 int backupseen = 0;
285
286 if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
287 return;
288
289 hello = (struct ospf6_hello *)
290 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 291
292 /* HelloInterval check */
508e53e2 293 if (ntohs (hello->hello_interval) != oi->hello_interval)
718e3744 294 {
508e53e2 295 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 296 zlog_debug ("HelloInterval mismatch");
718e3744 297 return;
298 }
299
300 /* RouterDeadInterval check */
508e53e2 301 if (ntohs (hello->dead_interval) != oi->dead_interval)
718e3744 302 {
508e53e2 303 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 304 zlog_debug ("RouterDeadInterval mismatch");
718e3744 305 return;
306 }
307
508e53e2 308 /* E-bit check */
309 if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
310 OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
718e3744 311 {
508e53e2 312 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 313 zlog_debug ("E-bit mismatch");
718e3744 314 return;
315 }
316
508e53e2 317 /* Find neighbor, create if not exist */
318 on = ospf6_neighbor_lookup (oh->router_id, oi);
319 if (on == NULL)
718e3744 320 {
508e53e2 321 on = ospf6_neighbor_create (oh->router_id, oi);
322 on->prev_drouter = on->drouter = hello->drouter;
323 on->prev_bdrouter = on->bdrouter = hello->bdrouter;
324 on->priority = hello->priority;
718e3744 325 }
326
7b6ae028 327 /* always override neighbor's source address and ifindex */
328 on->ifindex = ntohl (hello->interface_id);
329 memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr));
330
508e53e2 331 /* TwoWay check */
332 for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
333 p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
334 p += sizeof (u_int32_t))
718e3744 335 {
508e53e2 336 u_int32_t *router_id = (u_int32_t *) p;
337
338 if (*router_id == oi->area->ospf6->router_id)
339 twoway++;
718e3744 340 }
341
508e53e2 342 if (p != OSPF6_MESSAGE_END (oh))
718e3744 343 {
508e53e2 344 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 345 zlog_debug ("Trailing garbage ignored");
718e3744 346 }
347
508e53e2 348 /* RouterPriority check */
349 if (on->priority != hello->priority)
718e3744 350 {
508e53e2 351 on->priority = hello->priority;
352 neighborchange++;
718e3744 353 }
354
508e53e2 355 /* DR check */
356 if (on->drouter != hello->drouter)
357 {
358 on->prev_drouter = on->drouter;
359 on->drouter = hello->drouter;
360 if (on->prev_drouter == on->router_id || on->drouter == on->router_id)
361 neighborchange++;
362 }
718e3744 363
508e53e2 364 /* BDR check */
365 if (on->bdrouter != hello->bdrouter)
718e3744 366 {
508e53e2 367 on->prev_bdrouter = on->bdrouter;
368 on->bdrouter = hello->bdrouter;
369 if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id)
370 neighborchange++;
371 }
718e3744 372
508e53e2 373 /* BackupSeen check */
374 if (oi->state == OSPF6_INTERFACE_WAITING)
375 {
376 if (hello->bdrouter == on->router_id)
718e3744 377 backupseen++;
508e53e2 378 else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
718e3744 379 backupseen++;
380 }
381
508e53e2 382 /* Execute neighbor events */
383 thread_execute (master, hello_received, on, 0);
384 if (twoway)
385 thread_execute (master, twoway_received, on, 0);
386 else
387 thread_execute (master, oneway_received, on, 0);
718e3744 388
508e53e2 389 /* Schedule interface events */
718e3744 390 if (backupseen)
508e53e2 391 thread_add_event (master, backup_seen, oi, 0);
392 if (neighborchange)
393 thread_add_event (master, neighbor_change, oi, 0);
718e3744 394}
395
508e53e2 396static void
397ospf6_dbdesc_recv_master (struct ospf6_header *oh,
398 struct ospf6_neighbor *on)
718e3744 399{
508e53e2 400 struct ospf6_dbdesc *dbdesc;
401 char *p;
718e3744 402
508e53e2 403 dbdesc = (struct ospf6_dbdesc *)
404 ((caddr_t) oh + sizeof (struct ospf6_header));
405
406 if (on->state < OSPF6_NEIGHBOR_INIT)
718e3744 407 {
508e53e2 408 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 409 zlog_debug ("Neighbor state less than Init, ignore");
508e53e2 410 return;
718e3744 411 }
718e3744 412
508e53e2 413 switch (on->state)
414 {
415 case OSPF6_NEIGHBOR_TWOWAY:
416 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 417 zlog_debug ("Neighbor state is 2-Way, ignore");
508e53e2 418 return;
718e3744 419
508e53e2 420 case OSPF6_NEIGHBOR_INIT:
421 thread_execute (master, twoway_received, on, 0);
422 if (on->state != OSPF6_NEIGHBOR_EXSTART)
423 {
424 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 425 zlog_debug ("Neighbor state is not ExStart, ignore");
508e53e2 426 return;
427 }
428 /* else fall through to ExStart */
429
430 case OSPF6_NEIGHBOR_EXSTART:
431 /* if neighbor obeys us as our slave, schedule negotiation_done
432 and process LSA Headers. Otherwise, ignore this message */
433 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
434 ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
435 ntohl (dbdesc->seqnum) == on->dbdesc_seqnum)
436 {
437 /* execute NegotiationDone */
438 thread_execute (master, negotiation_done, on, 0);
718e3744 439
508e53e2 440 /* Record neighbor options */
441 memcpy (on->options, dbdesc->options, sizeof (on->options));
442 }
443 else
444 {
445 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 446 zlog_debug ("Negotiation failed");
508e53e2 447 return;
448 }
449 /* fall through to exchange */
718e3744 450
508e53e2 451 case OSPF6_NEIGHBOR_EXCHANGE:
452 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
453 {
454 /* Duplicated DatabaseDescription is dropped by master */
455 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 456 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
508e53e2 457 return;
458 }
718e3744 459
508e53e2 460 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
461 {
462 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 463 zlog_debug ("Master/Slave bit mismatch");
508e53e2 464 thread_add_event (master, seqnumber_mismatch, on, 0);
465 return;
466 }
467
468 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
469 {
470 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 471 zlog_debug ("Initialize bit mismatch");
508e53e2 472 thread_add_event (master, seqnumber_mismatch, on, 0);
473 return;
474 }
475
476 if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
477 {
478 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 479 zlog_debug ("Option field mismatch");
508e53e2 480 thread_add_event (master, seqnumber_mismatch, on, 0);
481 return;
482 }
483
484 if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum)
485 {
486 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 487 zlog_debug ("Sequence number mismatch (%#lx expected)",
508e53e2 488 (u_long) on->dbdesc_seqnum);
489 thread_add_event (master, seqnumber_mismatch, on, 0);
490 return;
491 }
492 break;
493
494 case OSPF6_NEIGHBOR_LOADING:
495 case OSPF6_NEIGHBOR_FULL:
496 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
497 {
498 /* Duplicated DatabaseDescription is dropped by master */
499 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 500 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
508e53e2 501 return;
502 }
503
504 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 505 zlog_debug ("Not duplicate dbdesc in state %s",
506 ospf6_neighbor_state_str[on->state]);
508e53e2 507 thread_add_event (master, seqnumber_mismatch, on, 0);
508 return;
509
510 default:
511 assert (0);
512 break;
718e3744 513 }
514
508e53e2 515 /* Process LSA headers */
516 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
517 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
518 p += sizeof (struct ospf6_lsa_header))
718e3744 519 {
508e53e2 520 struct ospf6_lsa *his, *mine;
521 struct ospf6_lsdb *lsdb = NULL;
522
523 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
6452df09 524
525 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 526 zlog_debug ("%s", his->name);
6452df09 527
528 switch (OSPF6_LSA_SCOPE (his->header->type))
508e53e2 529 {
6452df09 530 case OSPF6_SCOPE_LINKLOCAL:
531 lsdb = on->ospf6_if->lsdb;
532 break;
533 case OSPF6_SCOPE_AREA:
534 lsdb = on->ospf6_if->area->lsdb;
535 break;
536 case OSPF6_SCOPE_AS:
537 lsdb = on->ospf6_if->area->ospf6->lsdb;
538 break;
539 case OSPF6_SCOPE_RESERVED:
540 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 541 zlog_debug ("Ignoring LSA of reserved scope");
508e53e2 542 ospf6_lsa_delete (his);
6452df09 543 continue;
544 break;
508e53e2 545 }
546
547 if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
6452df09 548 IS_AREA_STUB (on->ospf6_if->area))
718e3744 549 {
508e53e2 550 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 551 zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
508e53e2 552 ospf6_lsa_delete (his);
553 thread_add_event (master, seqnumber_mismatch, on, 0);
718e3744 554 return;
555 }
508e53e2 556
557 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
558 his->header->adv_router, lsdb);
6452df09 559 if (mine == NULL)
508e53e2 560 {
6452df09 561 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 562 zlog_debug ("Add request (No database copy)");
6452df09 563 ospf6_lsdb_add (his, on->request_list);
564 }
565 else if (ospf6_lsa_compare (his, mine) < 0)
566 {
567 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 568 zlog_debug ("Add request (Received MoreRecent)");
508e53e2 569 ospf6_lsdb_add (his, on->request_list);
570 }
571 else
6452df09 572 {
573 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 574 zlog_debug ("Discard (Existing MoreRecent)");
6452df09 575 ospf6_lsa_delete (his);
576 }
718e3744 577 }
578
508e53e2 579 if (p != OSPF6_MESSAGE_END (oh))
580 {
581 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 582 zlog_debug ("Trailing garbage ignored");
508e53e2 583 }
718e3744 584
508e53e2 585 /* Increment sequence number */
586 on->dbdesc_seqnum ++;
718e3744 587
508e53e2 588 /* schedule send lsreq */
589 if (on->thread_send_lsreq == NULL)
590 on->thread_send_lsreq =
591 thread_add_event (master, ospf6_lsreq_send, on, 0);
718e3744 592
508e53e2 593 THREAD_OFF (on->thread_send_dbdesc);
718e3744 594
508e53e2 595 /* More bit check */
596 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
597 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
598 thread_add_event (master, exchange_done, on, 0);
599 else
600 on->thread_send_dbdesc =
601 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
718e3744 602
508e53e2 603 /* save last received dbdesc */
604 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
718e3744 605}
606
508e53e2 607static void
608ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
609 struct ospf6_neighbor *on)
718e3744 610{
718e3744 611 struct ospf6_dbdesc *dbdesc;
508e53e2 612 char *p;
718e3744 613
508e53e2 614 dbdesc = (struct ospf6_dbdesc *)
615 ((caddr_t) oh + sizeof (struct ospf6_header));
616
617 if (on->state < OSPF6_NEIGHBOR_INIT)
618 {
619 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 620 zlog_debug ("Neighbor state less than Init, ignore");
508e53e2 621 return;
622 }
718e3744 623
508e53e2 624 switch (on->state)
625 {
626 case OSPF6_NEIGHBOR_TWOWAY:
627 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 628 zlog_debug ("Neighbor state is 2-Way, ignore");
508e53e2 629 return;
718e3744 630
508e53e2 631 case OSPF6_NEIGHBOR_INIT:
632 thread_execute (master, twoway_received, on, 0);
633 if (on->state != OSPF6_NEIGHBOR_EXSTART)
634 {
635 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 636 zlog_debug ("Neighbor state is not ExStart, ignore");
508e53e2 637 return;
638 }
639 /* else fall through to ExStart */
640
641 case OSPF6_NEIGHBOR_EXSTART:
642 /* If the neighbor is Master, act as Slave. Schedule negotiation_done
643 and process LSA Headers. Otherwise, ignore this message */
644 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
645 CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
646 CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
647 ntohs (oh->length) == sizeof (struct ospf6_header) +
648 sizeof (struct ospf6_dbdesc))
649 {
650 /* set the master/slave bit to slave */
651 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
652
653 /* set the DD sequence number to one specified by master */
654 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
655
656 /* schedule NegotiationDone */
657 thread_execute (master, negotiation_done, on, 0);
658
659 /* Record neighbor options */
660 memcpy (on->options, dbdesc->options, sizeof (on->options));
661 }
662 else
663 {
664 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 665 zlog_debug ("Negotiation failed");
508e53e2 666 return;
667 }
668 break;
669
670 case OSPF6_NEIGHBOR_EXCHANGE:
671 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
672 {
673 /* Duplicated DatabaseDescription causes slave to retransmit */
674 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 675 zlog_debug ("Duplicated dbdesc causes retransmit");
508e53e2 676 THREAD_OFF (on->thread_send_dbdesc);
677 on->thread_send_dbdesc =
678 thread_add_event (master, ospf6_dbdesc_send, on, 0);
679 return;
680 }
681
682 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
683 {
684 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 685 zlog_debug ("Master/Slave bit mismatch");
508e53e2 686 thread_add_event (master, seqnumber_mismatch, on, 0);
687 return;
688 }
689
690 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
691 {
692 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 693 zlog_debug ("Initialize bit mismatch");
508e53e2 694 thread_add_event (master, seqnumber_mismatch, on, 0);
695 return;
696 }
697
698 if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
699 {
700 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 701 zlog_debug ("Option field mismatch");
508e53e2 702 thread_add_event (master, seqnumber_mismatch, on, 0);
703 return;
704 }
705
706 if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1)
707 {
708 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 709 zlog_debug ("Sequence number mismatch (%#lx expected)",
710 (u_long) on->dbdesc_seqnum + 1);
508e53e2 711 thread_add_event (master, seqnumber_mismatch, on, 0);
712 return;
713 }
714 break;
715
716 case OSPF6_NEIGHBOR_LOADING:
717 case OSPF6_NEIGHBOR_FULL:
718 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
719 {
720 /* Duplicated DatabaseDescription causes slave to retransmit */
721 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 722 zlog_debug ("Duplicated dbdesc causes retransmit");
508e53e2 723 THREAD_OFF (on->thread_send_dbdesc);
724 on->thread_send_dbdesc =
725 thread_add_event (master, ospf6_dbdesc_send, on, 0);
726 return;
727 }
728
729 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 730 zlog_debug ("Not duplicate dbdesc in state %s",
731 ospf6_neighbor_state_str[on->state]);
508e53e2 732 thread_add_event (master, seqnumber_mismatch, on, 0);
733 return;
734
735 default:
736 assert (0);
737 break;
718e3744 738 }
739
508e53e2 740 /* Process LSA headers */
741 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
742 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
743 p += sizeof (struct ospf6_lsa_header))
718e3744 744 {
508e53e2 745 struct ospf6_lsa *his, *mine;
746 struct ospf6_lsdb *lsdb = NULL;
747
748 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
6452df09 749
750 switch (OSPF6_LSA_SCOPE (his->header->type))
508e53e2 751 {
6452df09 752 case OSPF6_SCOPE_LINKLOCAL:
753 lsdb = on->ospf6_if->lsdb;
754 break;
755 case OSPF6_SCOPE_AREA:
756 lsdb = on->ospf6_if->area->lsdb;
757 break;
758 case OSPF6_SCOPE_AS:
759 lsdb = on->ospf6_if->area->ospf6->lsdb;
760 break;
761 case OSPF6_SCOPE_RESERVED:
762 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 763 zlog_debug ("Ignoring LSA of reserved scope");
508e53e2 764 ospf6_lsa_delete (his);
6452df09 765 continue;
766 break;
508e53e2 767 }
768
6452df09 769 if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
770 IS_AREA_STUB (on->ospf6_if->area))
718e3744 771 {
508e53e2 772 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 773 zlog_debug ("E-bit mismatch with LSA Headers");
508e53e2 774 ospf6_lsa_delete (his);
775 thread_add_event (master, seqnumber_mismatch, on, 0);
718e3744 776 return;
777 }
508e53e2 778
779 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
780 his->header->adv_router, lsdb);
781 if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
782 {
6452df09 783 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 784 zlog_debug ("Add request-list: %s", his->name);
508e53e2 785 ospf6_lsdb_add (his, on->request_list);
786 }
787 else
788 ospf6_lsa_delete (his);
718e3744 789 }
790
508e53e2 791 if (p != OSPF6_MESSAGE_END (oh))
792 {
793 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 794 zlog_debug ("Trailing garbage ignored");
508e53e2 795 }
718e3744 796
508e53e2 797 /* Set sequence number to Master's */
798 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
718e3744 799
508e53e2 800 /* schedule send lsreq */
801 if (on->thread_send_lsreq == NULL)
802 on->thread_send_lsreq =
803 thread_add_event (master, ospf6_lsreq_send, on, 0);
718e3744 804
508e53e2 805 THREAD_OFF (on->thread_send_dbdesc);
806 on->thread_send_dbdesc =
807 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
718e3744 808
508e53e2 809 /* save last received dbdesc */
810 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
718e3744 811}
812
813void
508e53e2 814ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
815 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 816{
508e53e2 817 struct ospf6_neighbor *on;
718e3744 818 struct ospf6_dbdesc *dbdesc;
718e3744 819
508e53e2 820 if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
821 return;
718e3744 822
508e53e2 823 on = ospf6_neighbor_lookup (oh->router_id, oi);
824 if (on == NULL)
718e3744 825 {
508e53e2 826 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 827 zlog_debug ("Neighbor not found, ignore");
718e3744 828 return;
829 }
830
508e53e2 831 dbdesc = (struct ospf6_dbdesc *)
832 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 833
508e53e2 834 /* Interface MTU check */
835 if (ntohs (dbdesc->ifmtu) != oi->ifmtu)
718e3744 836 {
508e53e2 837 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 838 zlog_debug ("I/F MTU mismatch");
508e53e2 839 return;
718e3744 840 }
841
508e53e2 842 if (dbdesc->reserved1 || dbdesc->reserved2)
843 {
844 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 845 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
846 on->name);
508e53e2 847 dbdesc->reserved1 = 0;
848 dbdesc->reserved2 = 0;
849 }
718e3744 850
508e53e2 851 if (ntohl (oh->router_id) < ntohl (ospf6->router_id))
852 ospf6_dbdesc_recv_master (oh, on);
853 else if (ntohl (ospf6->router_id) < ntohl (oh->router_id))
854 ospf6_dbdesc_recv_slave (oh, on);
855 else
856 {
857 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 858 zlog_debug ("Can't decide which is master, ignore");
508e53e2 859 }
718e3744 860}
861
862void
508e53e2 863ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
864 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 865{
508e53e2 866 struct ospf6_neighbor *on;
867 char *p;
868 struct ospf6_lsreq_entry *e;
508e53e2 869 struct ospf6_lsdb *lsdb = NULL;
718e3744 870 struct ospf6_lsa *lsa;
718e3744 871
508e53e2 872 if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
873 return;
718e3744 874
508e53e2 875 on = ospf6_neighbor_lookup (oh->router_id, oi);
876 if (on == NULL)
718e3744 877 {
508e53e2 878 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 879 zlog_debug ("Neighbor not found, ignore");
718e3744 880 return;
881 }
882
508e53e2 883 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
884 on->state != OSPF6_NEIGHBOR_LOADING &&
885 on->state != OSPF6_NEIGHBOR_FULL)
718e3744 886 {
508e53e2 887 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 888 zlog_debug ("Neighbor state less than Exchange, ignore");
718e3744 889 return;
890 }
891
508e53e2 892 /* Process each request */
893 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
894 p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
895 p += sizeof (struct ospf6_lsreq_entry))
718e3744 896 {
508e53e2 897 e = (struct ospf6_lsreq_entry *) p;
6452df09 898
899 switch (OSPF6_LSA_SCOPE (e->type))
900 {
901 case OSPF6_SCOPE_LINKLOCAL:
902 lsdb = on->ospf6_if->lsdb;
903 break;
904 case OSPF6_SCOPE_AREA:
905 lsdb = on->ospf6_if->area->lsdb;
906 break;
907 case OSPF6_SCOPE_AS:
908 lsdb = on->ospf6_if->area->ospf6->lsdb;
909 break;
910 default:
911 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 912 zlog_debug ("Ignoring LSA of reserved scope");
6452df09 913 continue;
914 break;
915 }
718e3744 916
508e53e2 917 /* Find database copy */
918 lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
919 if (lsa == NULL)
718e3744 920 {
508e53e2 921 char id[16], adv_router[16];
922 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
923 {
924 inet_ntop (AF_INET, &e->id, id, sizeof (id));
925 inet_ntop (AF_INET, &e->adv_router, adv_router,
926 sizeof (adv_router));
c6487d61 927 zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
928 ospf6_lstype_name (e->type), id, adv_router);
508e53e2 929 }
930 thread_add_event (master, bad_lsreq, on, 0);
718e3744 931 return;
932 }
933
508e53e2 934 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
718e3744 935 }
936
508e53e2 937 if (p != OSPF6_MESSAGE_END (oh))
718e3744 938 {
508e53e2 939 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 940 zlog_debug ("Trailing garbage ignored");
718e3744 941 }
942
508e53e2 943 /* schedule send lsupdate */
944 THREAD_OFF (on->thread_send_lsupdate);
945 on->thread_send_lsupdate =
946 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
718e3744 947}
948
949void
508e53e2 950ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
951 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 952{
508e53e2 953 struct ospf6_neighbor *on;
718e3744 954 struct ospf6_lsupdate *lsupdate;
508e53e2 955 unsigned long num;
956 char *p;
718e3744 957
508e53e2 958 if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
959 return;
718e3744 960
508e53e2 961 on = ospf6_neighbor_lookup (oh->router_id, oi);
962 if (on == NULL)
718e3744 963 {
508e53e2 964 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 965 zlog_debug ("Neighbor not found, ignore");
718e3744 966 return;
967 }
968
508e53e2 969 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
970 on->state != OSPF6_NEIGHBOR_LOADING &&
971 on->state != OSPF6_NEIGHBOR_FULL)
718e3744 972 {
508e53e2 973 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 974 zlog_debug ("Neighbor state less than Exchange, ignore");
718e3744 975 return;
976 }
977
508e53e2 978 lsupdate = (struct ospf6_lsupdate *)
979 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 980
508e53e2 981 num = ntohl (lsupdate->lsa_number);
718e3744 982
508e53e2 983 /* Process LSAs */
984 for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
985 p < OSPF6_MESSAGE_END (oh) &&
986 p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
987 p += OSPF6_LSA_SIZE (p))
988 {
989 if (num == 0)
990 break;
991 if (OSPF6_LSA_SIZE (p) < sizeof (struct ospf6_lsa_header))
992 {
993 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 994 zlog_debug ("Malformed LSA length, quit processing");
508e53e2 995 break;
996 }
997
6452df09 998 ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
508e53e2 999 num--;
1000 }
1001
1002 if (num != 0)
1003 {
1004 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1005 zlog_debug ("Malformed LSA number or LSA length");
508e53e2 1006 }
1007 if (p != OSPF6_MESSAGE_END (oh))
1008 {
1009 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1010 zlog_debug ("Trailing garbage ignored");
508e53e2 1011 }
718e3744 1012
1013 /* RFC2328 Section 10.9: When the neighbor responds to these requests
1014 with the proper Link State Update packet(s), the Link state request
1015 list is truncated and a new Link State Request packet is sent. */
508e53e2 1016 /* send new Link State Request packet if this LS Update packet
1017 can be recognized as a response to our previous LS Request */
1018 if (! IN6_IS_ADDR_MULTICAST (dst) &&
1019 (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
1020 on->state == OSPF6_NEIGHBOR_LOADING))
1021 {
1022 THREAD_OFF (on->thread_send_lsreq);
1023 on->thread_send_lsreq =
1024 thread_add_event (master, ospf6_lsreq_send, on, 0);
1025 }
1026}
1027
1028void
1029ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
1030 struct ospf6_interface *oi, struct ospf6_header *oh)
1031{
1032 struct ospf6_neighbor *on;
1033 char *p;
1034 struct ospf6_lsa *his, *mine;
1035 struct ospf6_lsdb *lsdb = NULL;
1036
1037 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
1038 if (ospf6_header_examin (src, dst, oi, oh) != MSG_OK)
1039 return;
1040
1041 on = ospf6_neighbor_lookup (oh->router_id, oi);
1042 if (on == NULL)
1043 {
1044 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1045 zlog_debug ("Neighbor not found, ignore");
508e53e2 1046 return;
1047 }
1048
508e53e2 1049 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1050 on->state != OSPF6_NEIGHBOR_LOADING &&
1051 on->state != OSPF6_NEIGHBOR_FULL)
718e3744 1052 {
508e53e2 1053 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1054 zlog_debug ("Neighbor state less than Exchange, ignore");
508e53e2 1055 return;
718e3744 1056 }
1057
508e53e2 1058 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
1059 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
1060 p += sizeof (struct ospf6_lsa_header))
1061 {
1062 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
508e53e2 1063
6452df09 1064 switch (OSPF6_LSA_SCOPE (his->header->type))
1065 {
1066 case OSPF6_SCOPE_LINKLOCAL:
1067 lsdb = on->ospf6_if->lsdb;
1068 break;
1069 case OSPF6_SCOPE_AREA:
1070 lsdb = on->ospf6_if->area->lsdb;
1071 break;
1072 case OSPF6_SCOPE_AS:
1073 lsdb = on->ospf6_if->area->ospf6->lsdb;
1074 break;
1075 case OSPF6_SCOPE_RESERVED:
1076 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1077 zlog_debug ("Ignoring LSA of reserved scope");
6452df09 1078 ospf6_lsa_delete (his);
1079 continue;
1080 break;
1081 }
1082
1083 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1084 zlog_debug ("%s acknowledged by %s", his->name, on->name);
508e53e2 1085
1086 /* Find database copy */
1087 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1088 his->header->adv_router, lsdb);
1089 if (mine == NULL)
1090 {
1091 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1092 zlog_debug ("No database copy");
508e53e2 1093 ospf6_lsa_delete (his);
1094 continue;
1095 }
1096
1097 /* Check if the LSA is on his retrans-list */
1098 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1099 his->header->adv_router, on->retrans_list);
1100 if (mine == NULL)
1101 {
1102 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1103 zlog_debug ("Not on %s's retrans-list", on->name);
508e53e2 1104 ospf6_lsa_delete (his);
1105 continue;
1106 }
1107
1108 if (ospf6_lsa_compare (his, mine) != 0)
1109 {
1110 /* Log this questionable acknowledgement,
1111 and examine the next one. */
1112 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1113 zlog_debug ("Questionable acknowledgement");
508e53e2 1114 ospf6_lsa_delete (his);
1115 continue;
1116 }
1117
6452df09 1118 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1119 zlog_debug ("Acknowledged, remove from %s's retrans-list",
1120 on->name);
508e53e2 1121
1122 if (OSPF6_LSA_IS_MAXAGE (mine))
1123 ospf6_maxage_remove (on->ospf6_if->area->ospf6);
1124
6452df09 1125 ospf6_decrement_retrans_count (mine);
508e53e2 1126 ospf6_lsdb_remove (mine, on->retrans_list);
1127 ospf6_lsa_delete (his);
1128 }
1129
1130 if (p != OSPF6_MESSAGE_END (oh))
1131 {
1132 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1133 zlog_debug ("Trailing garbage ignored");
508e53e2 1134 }
1135}
1136
0c083ee9 1137u_char *recvbuf = NULL;
1138u_char *sendbuf = NULL;
1139unsigned int iobuflen = 0;
3b4cd3a9 1140
1141int
0c083ee9 1142ospf6_iobuf_size (unsigned int size)
3b4cd3a9 1143{
1144 char *recvnew, *sendnew;
1145
1146 if (size <= iobuflen)
1147 return iobuflen;
1148
1149 recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1150 sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1151 if (recvnew == NULL || sendnew == NULL)
1152 {
b596c71e 1153 if (recvnew)
1154 XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
1155 if (sendnew)
1156 XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
c6487d61 1157 zlog_debug ("Could not allocate I/O buffer of size %d.", size);
3b4cd3a9 1158 return iobuflen;
1159 }
1160
1161 if (recvbuf)
1162 XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1163 if (sendbuf)
1164 XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1165 recvbuf = recvnew;
1166 sendbuf = sendnew;
1167 iobuflen = size;
1168
1169 return iobuflen;
1170}
508e53e2 1171
1172int
1173ospf6_receive (struct thread *thread)
1174{
0c083ee9 1175 int sockfd;
1176 unsigned int len;
508e53e2 1177 char srcname[64], dstname[64];
1178 struct in6_addr src, dst;
1179 unsigned int ifindex;
1180 struct iovec iovector[2];
1181 struct ospf6_interface *oi;
1182 struct ospf6_header *oh;
1183
1184 /* add next read thread */
1185 sockfd = THREAD_FD (thread);
1186 thread_add_read (master, ospf6_receive, NULL, sockfd);
1187
1188 /* initialize */
3b4cd3a9 1189 memset (recvbuf, 0, iobuflen);
508e53e2 1190 iovector[0].iov_base = recvbuf;
3b4cd3a9 1191 iovector[0].iov_len = iobuflen;
508e53e2 1192 iovector[1].iov_base = NULL;
1193 iovector[1].iov_len = 0;
1194
1195 /* receive message */
1196 len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
3b4cd3a9 1197 if (len > iobuflen)
508e53e2 1198 {
1199 zlog_err ("Excess message read");
1200 return 0;
1201 }
1202 else if (len < sizeof (struct ospf6_header))
1203 {
1204 zlog_err ("Deficient message read");
1205 return 0;
1206 }
1207
1208 oi = ospf6_interface_lookup_by_ifindex (ifindex);
1209 if (oi == NULL || oi->area == NULL)
1210 {
c6487d61 1211 zlog_debug ("Message received on disabled interface");
508e53e2 1212 return 0;
1213 }
1214
1215 oh = (struct ospf6_header *) recvbuf;
1216
1217 /* Log */
1218 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1219 {
1220 inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
1221 inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
c6487d61 1222 zlog_debug ("%s received on %s",
508e53e2 1223 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
c6487d61 1224 zlog_debug (" src: %s", srcname);
1225 zlog_debug (" dst: %s", dstname);
508e53e2 1226 if (len != ntohs (oh->length))
c6487d61 1227 zlog_debug ("Message length does not match actually received: %d", len);
508e53e2 1228
1229 switch (oh->type)
1230 {
1231 case OSPF6_MESSAGE_TYPE_HELLO:
1232 ospf6_hello_print (oh);
1233 break;
1234 case OSPF6_MESSAGE_TYPE_DBDESC:
1235 ospf6_dbdesc_print (oh);
1236 break;
1237 case OSPF6_MESSAGE_TYPE_LSREQ:
1238 ospf6_lsreq_print (oh);
1239 break;
1240 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1241 ospf6_lsupdate_print (oh);
1242 break;
1243 case OSPF6_MESSAGE_TYPE_LSACK:
1244 ospf6_lsack_print (oh);
1245 break;
1246 default:
c6487d61 1247 zlog_debug ("Unknown message");
508e53e2 1248 break;
1249 }
1250 }
1251
1252 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1253 {
1254 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1255 zlog_debug ("Ignore message on passive interface %s",
508e53e2 1256 oi->interface->name);
1257 return 0;
1258 }
1259
1260 switch (oh->type)
1261 {
1262 case OSPF6_MESSAGE_TYPE_HELLO:
1263 ospf6_hello_recv (&src, &dst, oi, oh);
1264 break;
1265
1266 case OSPF6_MESSAGE_TYPE_DBDESC:
1267 ospf6_dbdesc_recv (&src, &dst, oi, oh);
1268 break;
1269
1270 case OSPF6_MESSAGE_TYPE_LSREQ:
1271 ospf6_lsreq_recv (&src, &dst, oi, oh);
1272 break;
1273
1274 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1275 ospf6_lsupdate_recv (&src, &dst, oi, oh);
1276 break;
1277
1278 case OSPF6_MESSAGE_TYPE_LSACK:
1279 ospf6_lsack_recv (&src, &dst, oi, oh);
1280 break;
1281
1282 default:
1283 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
c6487d61 1284 zlog_debug ("Unknown message");
508e53e2 1285 break;
1286 }
718e3744 1287
508e53e2 1288 return 0;
718e3744 1289}
1290
1291void
508e53e2 1292ospf6_send (struct in6_addr *src, struct in6_addr *dst,
1293 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 1294{
508e53e2 1295 int len;
1296 char srcname[64], dstname[64];
1297 struct iovec iovector[2];
718e3744 1298
508e53e2 1299 /* initialize */
1300 iovector[0].iov_base = (caddr_t) oh;
1301 iovector[0].iov_len = ntohs (oh->length);
1302 iovector[1].iov_base = NULL;
1303 iovector[1].iov_len = 0;
1304
1305 /* fill OSPF header */
1306 oh->version = OSPFV3_VERSION;
1307 /* message type must be set before */
1308 /* message length must be set before */
1309 oh->router_id = oi->area->ospf6->router_id;
1310 oh->area_id = oi->area->area_id;
1311 /* checksum is calculated by kernel */
1312 oh->instance_id = oi->instance_id;
1313 oh->reserved = 0;
718e3744 1314
508e53e2 1315 /* Log */
1316 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
718e3744 1317 {
508e53e2 1318 inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
1319 if (src)
1320 inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
718e3744 1321 else
508e53e2 1322 memset (srcname, 0, sizeof (srcname));
c6487d61 1323 zlog_debug ("%s send on %s",
508e53e2 1324 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
c6487d61 1325 zlog_debug (" src: %s", srcname);
1326 zlog_debug (" dst: %s", dstname);
508e53e2 1327
1328 switch (oh->type)
718e3744 1329 {
508e53e2 1330 case OSPF6_MESSAGE_TYPE_HELLO:
1331 ospf6_hello_print (oh);
1332 break;
1333 case OSPF6_MESSAGE_TYPE_DBDESC:
1334 ospf6_dbdesc_print (oh);
1335 break;
1336 case OSPF6_MESSAGE_TYPE_LSREQ:
1337 ospf6_lsreq_print (oh);
1338 break;
1339 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1340 ospf6_lsupdate_print (oh);
1341 break;
1342 case OSPF6_MESSAGE_TYPE_LSACK:
1343 ospf6_lsack_print (oh);
1344 break;
1345 default:
c6487d61 1346 zlog_debug ("Unknown message");
508e53e2 1347 assert (0);
1348 break;
718e3744 1349 }
718e3744 1350 }
1351
508e53e2 1352 /* send message */
1353 len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
1354 if (len != ntohs (oh->length))
1355 zlog_err ("Could not send entire message");
718e3744 1356}
1357
508e53e2 1358int
1359ospf6_hello_send (struct thread *thread)
718e3744 1360{
508e53e2 1361 struct ospf6_interface *oi;
1362 struct ospf6_header *oh;
1363 struct ospf6_hello *hello;
0c083ee9 1364 u_char *p;
1eb8ef25 1365 struct listnode *node, *nnode;
508e53e2 1366 struct ospf6_neighbor *on;
718e3744 1367
508e53e2 1368 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1369 oi->thread_send_hello = (struct thread *) NULL;
718e3744 1370
508e53e2 1371 if (oi->state <= OSPF6_INTERFACE_DOWN)
718e3744 1372 {
508e53e2 1373 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
c6487d61 1374 zlog_debug ("Unable to send Hello on down interface %s",
508e53e2 1375 oi->interface->name);
1376 return 0;
718e3744 1377 }
1378
508e53e2 1379 /* set next thread */
1380 oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
1381 oi, oi->hello_interval);
718e3744 1382
3b4cd3a9 1383 memset (sendbuf, 0, iobuflen);
508e53e2 1384 oh = (struct ospf6_header *) sendbuf;
1385 hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1386
508e53e2 1387 hello->interface_id = htonl (oi->interface->ifindex);
1388 hello->priority = oi->priority;
1389 hello->options[0] = oi->area->options[0];
1390 hello->options[1] = oi->area->options[1];
1391 hello->options[2] = oi->area->options[2];
1392 hello->hello_interval = htons (oi->hello_interval);
1393 hello->dead_interval = htons (oi->dead_interval);
1394 hello->drouter = oi->drouter;
1395 hello->bdrouter = oi->bdrouter;
718e3744 1396
508e53e2 1397 p = (char *)((caddr_t) hello + sizeof (struct ospf6_hello));
718e3744 1398
1eb8ef25 1399 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
718e3744 1400 {
508e53e2 1401 if (on->state < OSPF6_NEIGHBOR_INIT)
1402 continue;
1403
1404 if (p - sendbuf + sizeof (u_int32_t) > oi->ifmtu)
1405 {
1406 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
c6487d61 1407 zlog_debug ("sending Hello message: exceeds I/F MTU");
508e53e2 1408 break;
1409 }
718e3744 1410
508e53e2 1411 memcpy (p, &on->router_id, sizeof (u_int32_t));
1412 p += sizeof (u_int32_t);
1413 }
718e3744 1414
508e53e2 1415 oh->type = OSPF6_MESSAGE_TYPE_HELLO;
1416 oh->length = htons (p - sendbuf);
718e3744 1417
508e53e2 1418 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1419 return 0;
718e3744 1420}
1421
1422int
508e53e2 1423ospf6_dbdesc_send (struct thread *thread)
718e3744 1424{
508e53e2 1425 struct ospf6_neighbor *on;
1426 struct ospf6_header *oh;
1427 struct ospf6_dbdesc *dbdesc;
0c083ee9 1428 u_char *p;
508e53e2 1429 struct ospf6_lsa *lsa;
718e3744 1430
508e53e2 1431 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1432 on->thread_send_dbdesc = (struct thread *) NULL;
718e3744 1433
508e53e2 1434 if (on->state < OSPF6_NEIGHBOR_EXSTART)
1435 {
1436 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
c6487d61 1437 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1438 on->name, ospf6_neighbor_state_str[on->state]);
508e53e2 1439 return 0;
1440 }
718e3744 1441
508e53e2 1442 /* set next thread if master */
1443 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
1444 on->thread_send_dbdesc =
1445 thread_add_timer (master, ospf6_dbdesc_send, on,
1446 on->ospf6_if->rxmt_interval);
718e3744 1447
3b4cd3a9 1448 memset (sendbuf, 0, iobuflen);
508e53e2 1449 oh = (struct ospf6_header *) sendbuf;
1450 dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
1451 sizeof (struct ospf6_header));
718e3744 1452
508e53e2 1453 /* if this is initial one, initialize sequence number for DbDesc */
1454 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
1455 {
1456 struct timeval tv;
1457 if (gettimeofday (&tv, (struct timezone *) NULL) < 0)
1458 tv.tv_sec = 1;
1459 on->dbdesc_seqnum = tv.tv_sec;
1460 }
1461
1462 dbdesc->options[0] = on->ospf6_if->area->options[0];
1463 dbdesc->options[1] = on->ospf6_if->area->options[1];
1464 dbdesc->options[2] = on->ospf6_if->area->options[2];
1465 dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
1466 dbdesc->bits = on->dbdesc_bits;
1467 dbdesc->seqnum = htonl (on->dbdesc_seqnum);
718e3744 1468
508e53e2 1469 /* if this is not initial one, set LSA headers in dbdesc */
1470 p = (char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
1471 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
718e3744 1472 {
508e53e2 1473 for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
1474 lsa = ospf6_lsdb_next (lsa))
1475 {
1476 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1477
1478 /* MTU check */
1479 if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
1480 on->ospf6_if->ifmtu)
1481 {
1482 ospf6_lsa_unlock (lsa);
1483 break;
1484 }
1485 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1486 p += sizeof (struct ospf6_lsa_header);
1487 }
718e3744 1488 }
1489
508e53e2 1490 oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
1491 oh->length = htons (p - sendbuf);
718e3744 1492
508e53e2 1493 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1494 on->ospf6_if, oh);
718e3744 1495 return 0;
1496}
1497
718e3744 1498int
508e53e2 1499ospf6_dbdesc_send_newone (struct thread *thread)
718e3744 1500{
508e53e2 1501 struct ospf6_neighbor *on;
1502 struct ospf6_lsa *lsa;
1503 unsigned int size = 0;
1504
1505 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
508e53e2 1506 ospf6_lsdb_remove_all (on->dbdesc_list);
1507
1508 /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1509 so that ospf6_send_dbdesc () can send those LSAs */
1510 size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
1511 for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
1512 lsa = ospf6_lsdb_next (lsa))
718e3744 1513 {
508e53e2 1514 if (size + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
718e3744 1515 {
508e53e2 1516 ospf6_lsa_unlock (lsa);
1517 break;
718e3744 1518 }
508e53e2 1519
508e53e2 1520 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
1521 ospf6_lsdb_remove (lsa, on->summary_list);
1522 size += sizeof (struct ospf6_lsa_header);
718e3744 1523 }
1524
508e53e2 1525 if (on->summary_list->count == 0)
1526 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
718e3744 1527
508e53e2 1528 /* If slave, More bit check must be done here */
1529 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
1530 ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
1531 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
1532 thread_add_event (master, exchange_done, on, 0);
718e3744 1533
508e53e2 1534 thread_execute (master, ospf6_dbdesc_send, on, 0);
1535 return 0;
1536}
718e3744 1537
508e53e2 1538int
1539ospf6_lsreq_send (struct thread *thread)
1540{
1541 struct ospf6_neighbor *on;
1542 struct ospf6_header *oh;
1543 struct ospf6_lsreq_entry *e;
0c083ee9 1544 u_char *p;
508e53e2 1545 struct ospf6_lsa *lsa;
718e3744 1546
508e53e2 1547 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1548 on->thread_send_lsreq = (struct thread *) NULL;
1549
1550 /* LSReq will be sent only in ExStart or Loading */
1551 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1552 on->state != OSPF6_NEIGHBOR_LOADING)
718e3744 1553 {
508e53e2 1554 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
c6487d61 1555 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1556 on->name, ospf6_neighbor_state_str[on->state]);
508e53e2 1557 return 0;
718e3744 1558 }
1559
508e53e2 1560 /* schedule loading_done if request list is empty */
1561 if (on->request_list->count == 0)
1562 {
1563 thread_add_event (master, loading_done, on, 0);
718e3744 1564 return 0;
1565 }
1566
508e53e2 1567 /* set next thread */
1568 on->thread_send_lsreq =
1569 thread_add_timer (master, ospf6_lsreq_send, on,
1570 on->ospf6_if->rxmt_interval);
718e3744 1571
3b4cd3a9 1572 memset (sendbuf, 0, iobuflen);
508e53e2 1573 oh = (struct ospf6_header *) sendbuf;
718e3744 1574
508e53e2 1575 /* set Request entries in lsreq */
1576 p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
1577 for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1578 lsa = ospf6_lsdb_next (lsa))
718e3744 1579 {
508e53e2 1580 /* MTU check */
1581 if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > on->ospf6_if->ifmtu)
718e3744 1582 {
508e53e2 1583 ospf6_lsa_unlock (lsa);
718e3744 1584 break;
1585 }
1586
508e53e2 1587 e = (struct ospf6_lsreq_entry *) p;
1588 e->type = lsa->header->type;
1589 e->id = lsa->header->id;
1590 e->adv_router = lsa->header->adv_router;
1591 p += sizeof (struct ospf6_lsreq_entry);
718e3744 1592 }
718e3744 1593
508e53e2 1594 oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
1595 oh->length = htons (p - sendbuf);
718e3744 1596
508e53e2 1597 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1598 on->ospf6_if, oh);
718e3744 1599 return 0;
1600}
1601
718e3744 1602int
508e53e2 1603ospf6_lsupdate_send_neighbor (struct thread *thread)
718e3744 1604{
508e53e2 1605 struct ospf6_neighbor *on;
1606 struct ospf6_header *oh;
1607 struct ospf6_lsupdate *lsupdate;
0c083ee9 1608 u_char *p;
508e53e2 1609 int num;
718e3744 1610 struct ospf6_lsa *lsa;
718e3744 1611
508e53e2 1612 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1613 on->thread_send_lsupdate = (struct thread *) NULL;
718e3744 1614
6452df09 1615 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1616 zlog_debug ("LSUpdate to neighbor %s", on->name);
6452df09 1617
508e53e2 1618 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
1619 {
1620 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1621 zlog_debug ("Quit to send (neighbor state %s)",
1622 ospf6_neighbor_state_str[on->state]);
508e53e2 1623 return 0;
1624 }
718e3744 1625
508e53e2 1626 /* if we have nothing to send, return */
1627 if (on->lsupdate_list->count == 0 &&
1628 on->retrans_list->count == 0)
6452df09 1629 {
1630 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1631 zlog_debug ("Quit to send (nothing to send)");
6452df09 1632 return 0;
1633 }
508e53e2 1634
3b4cd3a9 1635 memset (sendbuf, 0, iobuflen);
508e53e2 1636 oh = (struct ospf6_header *) sendbuf;
1637 lsupdate = (struct ospf6_lsupdate *)
1638 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1639
508e53e2 1640 p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1641 num = 0;
718e3744 1642
508e53e2 1643 /* lsupdate_list lists those LSA which doesn't need to be
1644 retransmitted. remove those from the list */
1645 for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
1646 lsa = ospf6_lsdb_next (lsa))
718e3744 1647 {
508e53e2 1648 /* MTU check */
0c083ee9 1649 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
1650 > on->ospf6_if->ifmtu)
718e3744 1651 {
508e53e2 1652 ospf6_lsa_unlock (lsa);
1653 break;
1654 }
718e3744 1655
508e53e2 1656 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1657 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
1658 p += OSPF6_LSA_SIZE (lsa->header);
1659 num++;
718e3744 1660
508e53e2 1661 assert (lsa->lock == 2);
1662 ospf6_lsdb_remove (lsa, on->lsupdate_list);
1663 }
1664
1665 for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
1666 lsa = ospf6_lsdb_next (lsa))
1667 {
1668 /* MTU check */
0c083ee9 1669 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
1670 > on->ospf6_if->ifmtu)
508e53e2 1671 {
1672 ospf6_lsa_unlock (lsa);
1673 break;
718e3744 1674 }
508e53e2 1675
508e53e2 1676 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1677 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
1678 p += OSPF6_LSA_SIZE (lsa->header);
1679 num++;
718e3744 1680 }
1681
508e53e2 1682 lsupdate->lsa_number = htonl (num);
1683
1684 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
1685 oh->length = htons (p - sendbuf);
718e3744 1686
508e53e2 1687 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1688 on->ospf6_if, oh);
718e3744 1689
508e53e2 1690 if (on->lsupdate_list->count != 0 ||
1691 on->retrans_list->count != 0)
1692 {
1693 if (on->lsupdate_list->count != 0)
1694 on->thread_send_lsupdate =
1695 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
1696 else
1697 on->thread_send_lsupdate =
1698 thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
1699 on->ospf6_if->rxmt_interval);
1700 }
718e3744 1701
1702 return 0;
1703}
1704
1705int
508e53e2 1706ospf6_lsupdate_send_interface (struct thread *thread)
718e3744 1707{
508e53e2 1708 struct ospf6_interface *oi;
1709 struct ospf6_header *oh;
1710 struct ospf6_lsupdate *lsupdate;
0c083ee9 1711 u_char *p;
508e53e2 1712 int num;
718e3744 1713 struct ospf6_lsa *lsa;
718e3744 1714
508e53e2 1715 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1716 oi->thread_send_lsupdate = (struct thread *) NULL;
718e3744 1717
508e53e2 1718 if (oi->state <= OSPF6_INTERFACE_WAITING)
718e3744 1719 {
508e53e2 1720 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1721 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
1722 oi->interface->name, ospf6_interface_state_str[oi->state]);
508e53e2 1723 return 0;
1724 }
718e3744 1725
508e53e2 1726 /* if we have nothing to send, return */
1727 if (oi->lsupdate_list->count == 0)
1728 return 0;
718e3744 1729
3b4cd3a9 1730 memset (sendbuf, 0, iobuflen);
508e53e2 1731 oh = (struct ospf6_header *) sendbuf;
1732 lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
1733 sizeof (struct ospf6_header));
718e3744 1734
508e53e2 1735 p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1736 num = 0;
718e3744 1737
508e53e2 1738 for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
1739 lsa = ospf6_lsdb_next (lsa))
1740 {
1741 /* MTU check */
0c083ee9 1742 if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
1743 > oi->ifmtu)
718e3744 1744 {
508e53e2 1745 ospf6_lsa_unlock (lsa);
1746 break;
718e3744 1747 }
718e3744 1748
508e53e2 1749 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
1750 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
1751 p += OSPF6_LSA_SIZE (lsa->header);
1752 num++;
718e3744 1753
508e53e2 1754 assert (lsa->lock == 2);
1755 ospf6_lsdb_remove (lsa, oi->lsupdate_list);
1756 }
718e3744 1757
508e53e2 1758 lsupdate->lsa_number = htonl (num);
718e3744 1759
508e53e2 1760 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
1761 oh->length = htons (p - sendbuf);
718e3744 1762
508e53e2 1763 if (oi->state == OSPF6_INTERFACE_DR ||
1764 oi->state == OSPF6_INTERFACE_BDR)
1765 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1766 else
1767 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
718e3744 1768
508e53e2 1769 if (oi->lsupdate_list->count > 0)
1770 {
1771 oi->thread_send_lsupdate =
1772 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
1773 }
718e3744 1774
718e3744 1775 return 0;
1776}
1777
1778int
508e53e2 1779ospf6_lsack_send_neighbor (struct thread *thread)
718e3744 1780{
508e53e2 1781 struct ospf6_neighbor *on;
1782 struct ospf6_header *oh;
0c083ee9 1783 u_char *p;
718e3744 1784 struct ospf6_lsa *lsa;
718e3744 1785
508e53e2 1786 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1787 on->thread_send_lsack = (struct thread *) NULL;
718e3744 1788
508e53e2 1789 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
718e3744 1790 {
508e53e2 1791 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
c6487d61 1792 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
1793 on->name, ospf6_neighbor_state_str[on->state]);
718e3744 1794 return 0;
1795 }
1796
508e53e2 1797 /* if we have nothing to send, return */
1798 if (on->lsack_list->count == 0)
1799 return 0;
718e3744 1800
3b4cd3a9 1801 memset (sendbuf, 0, iobuflen);
508e53e2 1802 oh = (struct ospf6_header *) sendbuf;
718e3744 1803
508e53e2 1804 p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1805
508e53e2 1806 for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
1807 lsa = ospf6_lsdb_next (lsa))
1808 {
1809 /* MTU check */
1810 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
1811 {
1812 /* if we run out of packet size/space here,
1813 better to try again soon. */
1814 THREAD_OFF (on->thread_send_lsack);
1815 on->thread_send_lsack =
1816 thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
718e3744 1817
508e53e2 1818 ospf6_lsa_unlock (lsa);
1819 break;
1820 }
718e3744 1821
508e53e2 1822 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1823 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1824 p += sizeof (struct ospf6_lsa_header);
718e3744 1825
508e53e2 1826 assert (lsa->lock == 2);
1827 ospf6_lsdb_remove (lsa, on->lsack_list);
1828 }
718e3744 1829
508e53e2 1830 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
1831 oh->length = htons (p - sendbuf);
718e3744 1832
508e53e2 1833 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1834 on->ospf6_if, oh);
718e3744 1835 return 0;
1836}
1837
718e3744 1838int
508e53e2 1839ospf6_lsack_send_interface (struct thread *thread)
718e3744 1840{
508e53e2 1841 struct ospf6_interface *oi;
1842 struct ospf6_header *oh;
0c083ee9 1843 u_char *p;
718e3744 1844 struct ospf6_lsa *lsa;
718e3744 1845
508e53e2 1846 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1847 oi->thread_send_lsack = (struct thread *) NULL;
718e3744 1848
508e53e2 1849 if (oi->state <= OSPF6_INTERFACE_WAITING)
1850 {
1851 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
c6487d61 1852 zlog_debug ("Quit to send LSAck to interface %s state %s",
1853 oi->interface->name, ospf6_interface_state_str[oi->state]);
508e53e2 1854 return 0;
1855 }
718e3744 1856
508e53e2 1857 /* if we have nothing to send, return */
1858 if (oi->lsack_list->count == 0)
1859 return 0;
718e3744 1860
3b4cd3a9 1861 memset (sendbuf, 0, iobuflen);
508e53e2 1862 oh = (struct ospf6_header *) sendbuf;
718e3744 1863
508e53e2 1864 p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1865
508e53e2 1866 for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
1867 lsa = ospf6_lsdb_next (lsa))
718e3744 1868 {
508e53e2 1869 /* MTU check */
1870 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > oi->ifmtu)
1871 {
1872 /* if we run out of packet size/space here,
1873 better to try again soon. */
1874 THREAD_OFF (oi->thread_send_lsack);
1875 oi->thread_send_lsack =
1876 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
718e3744 1877
508e53e2 1878 ospf6_lsa_unlock (lsa);
1879 break;
1880 }
718e3744 1881
508e53e2 1882 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
1883 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1884 p += sizeof (struct ospf6_lsa_header);
718e3744 1885
508e53e2 1886 assert (lsa->lock == 2);
1887 ospf6_lsdb_remove (lsa, oi->lsack_list);
1888 }
718e3744 1889
508e53e2 1890 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
1891 oh->length = htons (p - sendbuf);
718e3744 1892
508e53e2 1893 if (oi->state == OSPF6_INTERFACE_DR ||
1894 oi->state == OSPF6_INTERFACE_BDR)
1895 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1896 else
1897 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
718e3744 1898
508e53e2 1899 if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
1900 {
1901 oi->thread_send_lsack =
1902 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
1903 }
718e3744 1904
718e3744 1905 return 0;
1906}
1907
508e53e2 1908\f
1909/* Commands */
1910DEFUN (debug_ospf6_message,
1911 debug_ospf6_message_cmd,
1912 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
1913 DEBUG_STR
1914 OSPF6_STR
1915 "Debug OSPFv3 message\n"
1916 "Debug Unknown message\n"
1917 "Debug Hello message\n"
1918 "Debug Database Description message\n"
1919 "Debug Link State Request message\n"
1920 "Debug Link State Update message\n"
1921 "Debug Link State Acknowledgement message\n"
1922 "Debug All message\n"
1923 )
718e3744 1924{
508e53e2 1925 unsigned char level = 0;
1926 int type = 0;
1927 int i;
718e3744 1928
508e53e2 1929 assert (argc > 0);
718e3744 1930
508e53e2 1931 /* check type */
1932 if (! strncmp (argv[0], "u", 1))
1933 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
1934 else if (! strncmp (argv[0], "h", 1))
1935 type = OSPF6_MESSAGE_TYPE_HELLO;
1936 else if (! strncmp (argv[0], "d", 1))
1937 type = OSPF6_MESSAGE_TYPE_DBDESC;
1938 else if (! strncmp (argv[0], "lsr", 3))
1939 type = OSPF6_MESSAGE_TYPE_LSREQ;
1940 else if (! strncmp (argv[0], "lsu", 3))
1941 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
1942 else if (! strncmp (argv[0], "lsa", 3))
1943 type = OSPF6_MESSAGE_TYPE_LSACK;
1944 else if (! strncmp (argv[0], "a", 1))
1945 type = OSPF6_MESSAGE_TYPE_ALL;
1946
1947 if (argc == 1)
1948 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
1949 else if (! strncmp (argv[1], "s", 1))
1950 level = OSPF6_DEBUG_MESSAGE_SEND;
1951 else if (! strncmp (argv[1], "r", 1))
1952 level = OSPF6_DEBUG_MESSAGE_RECV;
1953
1954 if (type == OSPF6_MESSAGE_TYPE_ALL)
1955 {
1956 for (i = 0; i < 6; i++)
1957 OSPF6_DEBUG_MESSAGE_ON (i, level);
1958 }
1959 else
1960 OSPF6_DEBUG_MESSAGE_ON (type, level);
718e3744 1961
508e53e2 1962 return CMD_SUCCESS;
718e3744 1963}
1964
508e53e2 1965ALIAS (debug_ospf6_message,
1966 debug_ospf6_message_sendrecv_cmd,
1967 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
1968 DEBUG_STR
1969 OSPF6_STR
1970 "Debug OSPFv3 message\n"
1971 "Debug Unknown message\n"
1972 "Debug Hello message\n"
1973 "Debug Database Description message\n"
1974 "Debug Link State Request message\n"
1975 "Debug Link State Update message\n"
1976 "Debug Link State Acknowledgement message\n"
1977 "Debug All message\n"
1978 "Debug only sending message\n"
1979 "Debug only receiving message\n"
1980 );
718e3744 1981
508e53e2 1982\f
1983DEFUN (no_debug_ospf6_message,
1984 no_debug_ospf6_message_cmd,
1985 "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
1986 NO_STR
1987 DEBUG_STR
1988 OSPF6_STR
1989 "Debug OSPFv3 message\n"
1990 "Debug Unknown message\n"
1991 "Debug Hello message\n"
1992 "Debug Database Description message\n"
1993 "Debug Link State Request message\n"
1994 "Debug Link State Update message\n"
1995 "Debug Link State Acknowledgement message\n"
1996 "Debug All message\n"
1997 )
1998{
1999 unsigned char level = 0;
2000 int type = 0;
2001 int i;
718e3744 2002
508e53e2 2003 assert (argc > 0);
718e3744 2004
508e53e2 2005 /* check type */
2006 if (! strncmp (argv[0], "u", 1))
2007 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
2008 else if (! strncmp (argv[0], "h", 1))
2009 type = OSPF6_MESSAGE_TYPE_HELLO;
2010 else if (! strncmp (argv[0], "d", 1))
2011 type = OSPF6_MESSAGE_TYPE_DBDESC;
2012 else if (! strncmp (argv[0], "lsr", 3))
2013 type = OSPF6_MESSAGE_TYPE_LSREQ;
2014 else if (! strncmp (argv[0], "lsu", 3))
2015 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2016 else if (! strncmp (argv[0], "lsa", 3))
2017 type = OSPF6_MESSAGE_TYPE_LSACK;
2018 else if (! strncmp (argv[0], "a", 1))
2019 type = OSPF6_MESSAGE_TYPE_ALL;
2020
2021 if (argc == 1)
2022 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
2023 else if (! strncmp (argv[1], "s", 1))
2024 level = OSPF6_DEBUG_MESSAGE_SEND;
2025 else if (! strncmp (argv[1], "r", 1))
2026 level = OSPF6_DEBUG_MESSAGE_RECV;
2027
2028 if (type == OSPF6_MESSAGE_TYPE_ALL)
718e3744 2029 {
508e53e2 2030 for (i = 0; i < 6; i++)
2031 OSPF6_DEBUG_MESSAGE_OFF (i, level);
718e3744 2032 }
2033 else
508e53e2 2034 OSPF6_DEBUG_MESSAGE_OFF (type, level);
718e3744 2035
508e53e2 2036 return CMD_SUCCESS;
718e3744 2037}
2038
508e53e2 2039ALIAS (no_debug_ospf6_message,
2040 no_debug_ospf6_message_sendrecv_cmd,
049207c3 2041 "no debug ospf6 message "
2042 "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
508e53e2 2043 NO_STR
2044 DEBUG_STR
2045 OSPF6_STR
2046 "Debug OSPFv3 message\n"
2047 "Debug Unknown message\n"
2048 "Debug Hello message\n"
2049 "Debug Database Description message\n"
2050 "Debug Link State Request message\n"
2051 "Debug Link State Update message\n"
2052 "Debug Link State Acknowledgement message\n"
2053 "Debug All message\n"
2054 "Debug only sending message\n"
2055 "Debug only receiving message\n"
2056 );
2057
718e3744 2058int
508e53e2 2059config_write_ospf6_debug_message (struct vty *vty)
718e3744 2060{
0c083ee9 2061 const char *type_str[] = {"unknown", "hello", "dbdesc",
508e53e2 2062 "lsreq", "lsupdate", "lsack"};
2063 unsigned char s = 0, r = 0;
2064 int i;
718e3744 2065
508e53e2 2066 for (i = 0; i < 6; i++)
2067 {
2068 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2069 s |= 1 << i;
2070 if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2071 r |= 1 << i;
2072 }
718e3744 2073
508e53e2 2074 if (s == 0x3f && r == 0x3f)
718e3744 2075 {
049207c3 2076 vty_out (vty, "debug ospf6 message all%s", VNL);
508e53e2 2077 return 0;
2078 }
718e3744 2079
508e53e2 2080 if (s == 0x3f && r == 0)
2081 {
049207c3 2082 vty_out (vty, "debug ospf6 message all send%s", VNL);
508e53e2 2083 return 0;
2084 }
2085 else if (s == 0 && r == 0x3f)
2086 {
049207c3 2087 vty_out (vty, "debug ospf6 message all recv%s", VNL);
508e53e2 2088 return 0;
718e3744 2089 }
2090
508e53e2 2091 /* Unknown message is logged by default */
2092 if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
2093 ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
049207c3 2094 vty_out (vty, "no debug ospf6 message unknown%s", VNL);
508e53e2 2095 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
049207c3 2096 vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
508e53e2 2097 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
049207c3 2098 vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
718e3744 2099
508e53e2 2100 for (i = 1; i < 6; i++)
718e3744 2101 {
508e53e2 2102 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
2103 IS_OSPF6_DEBUG_MESSAGE (i, RECV))
049207c3 2104 vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
508e53e2 2105 else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2106 vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
049207c3 2107 VNL);
508e53e2 2108 else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2109 vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
049207c3 2110 VNL);
718e3744 2111 }
2112
718e3744 2113 return 0;
2114}
2115
508e53e2 2116void
2117install_element_ospf6_debug_message ()
2118{
2119 install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
2120 install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
2121 install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
2122 install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2123 install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
2124 install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
2125 install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
2126 install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2127}
2128
2129