]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_message.c
[lib] mes_lookup string lookup table argument should be marked const
[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
932bf197 1122 ospf6_decrement_retrans_count (mine);
508e53e2 1123 if (OSPF6_LSA_IS_MAXAGE (mine))
1124 ospf6_maxage_remove (on->ospf6_if->area->ospf6);
cf1ce250 1125 ospf6_lsdb_remove (mine, on->retrans_list);
508e53e2 1126 ospf6_lsa_delete (his);
1127 }
1128
1129 if (p != OSPF6_MESSAGE_END (oh))
1130 {
1131 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1132 zlog_debug ("Trailing garbage ignored");
508e53e2 1133 }
1134}
1135
0c083ee9 1136u_char *recvbuf = NULL;
1137u_char *sendbuf = NULL;
1138unsigned int iobuflen = 0;
3b4cd3a9 1139
1140int
0c083ee9 1141ospf6_iobuf_size (unsigned int size)
3b4cd3a9 1142{
1143 char *recvnew, *sendnew;
1144
1145 if (size <= iobuflen)
1146 return iobuflen;
1147
1148 recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1149 sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1150 if (recvnew == NULL || sendnew == NULL)
1151 {
b596c71e 1152 if (recvnew)
1153 XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
1154 if (sendnew)
1155 XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
c6487d61 1156 zlog_debug ("Could not allocate I/O buffer of size %d.", size);
3b4cd3a9 1157 return iobuflen;
1158 }
1159
1160 if (recvbuf)
1161 XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1162 if (sendbuf)
1163 XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1164 recvbuf = recvnew;
1165 sendbuf = sendnew;
1166 iobuflen = size;
1167
1168 return iobuflen;
1169}
508e53e2 1170
1171int
1172ospf6_receive (struct thread *thread)
1173{
0c083ee9 1174 int sockfd;
1175 unsigned int len;
508e53e2 1176 char srcname[64], dstname[64];
1177 struct in6_addr src, dst;
1178 unsigned int ifindex;
1179 struct iovec iovector[2];
1180 struct ospf6_interface *oi;
1181 struct ospf6_header *oh;
1182
1183 /* add next read thread */
1184 sockfd = THREAD_FD (thread);
1185 thread_add_read (master, ospf6_receive, NULL, sockfd);
1186
1187 /* initialize */
cf1ce250
PJ
1188 memset (&src, 0, sizeof (src));
1189 memset (&dst, 0, sizeof (dst));
1190 ifindex = 0;
3b4cd3a9 1191 memset (recvbuf, 0, iobuflen);
508e53e2 1192 iovector[0].iov_base = recvbuf;
3b4cd3a9 1193 iovector[0].iov_len = iobuflen;
508e53e2 1194 iovector[1].iov_base = NULL;
1195 iovector[1].iov_len = 0;
1196
1197 /* receive message */
1198 len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
3b4cd3a9 1199 if (len > iobuflen)
508e53e2 1200 {
1201 zlog_err ("Excess message read");
1202 return 0;
1203 }
1204 else if (len < sizeof (struct ospf6_header))
1205 {
1206 zlog_err ("Deficient message read");
1207 return 0;
1208 }
1209
1210 oi = ospf6_interface_lookup_by_ifindex (ifindex);
1211 if (oi == NULL || oi->area == NULL)
1212 {
c6487d61 1213 zlog_debug ("Message received on disabled interface");
508e53e2 1214 return 0;
1215 }
1216
1217 oh = (struct ospf6_header *) recvbuf;
1218
1219 /* Log */
1220 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1221 {
1222 inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
1223 inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
c6487d61 1224 zlog_debug ("%s received on %s",
508e53e2 1225 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
c6487d61 1226 zlog_debug (" src: %s", srcname);
1227 zlog_debug (" dst: %s", dstname);
508e53e2 1228 if (len != ntohs (oh->length))
c6487d61 1229 zlog_debug ("Message length does not match actually received: %d", len);
508e53e2 1230
1231 switch (oh->type)
1232 {
1233 case OSPF6_MESSAGE_TYPE_HELLO:
1234 ospf6_hello_print (oh);
1235 break;
1236 case OSPF6_MESSAGE_TYPE_DBDESC:
1237 ospf6_dbdesc_print (oh);
1238 break;
1239 case OSPF6_MESSAGE_TYPE_LSREQ:
1240 ospf6_lsreq_print (oh);
1241 break;
1242 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1243 ospf6_lsupdate_print (oh);
1244 break;
1245 case OSPF6_MESSAGE_TYPE_LSACK:
1246 ospf6_lsack_print (oh);
1247 break;
1248 default:
c6487d61 1249 zlog_debug ("Unknown message");
508e53e2 1250 break;
1251 }
1252 }
1253
1254 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1255 {
1256 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1257 zlog_debug ("Ignore message on passive interface %s",
508e53e2 1258 oi->interface->name);
1259 return 0;
1260 }
1261
1262 switch (oh->type)
1263 {
1264 case OSPF6_MESSAGE_TYPE_HELLO:
1265 ospf6_hello_recv (&src, &dst, oi, oh);
1266 break;
1267
1268 case OSPF6_MESSAGE_TYPE_DBDESC:
1269 ospf6_dbdesc_recv (&src, &dst, oi, oh);
1270 break;
1271
1272 case OSPF6_MESSAGE_TYPE_LSREQ:
1273 ospf6_lsreq_recv (&src, &dst, oi, oh);
1274 break;
1275
1276 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1277 ospf6_lsupdate_recv (&src, &dst, oi, oh);
1278 break;
1279
1280 case OSPF6_MESSAGE_TYPE_LSACK:
1281 ospf6_lsack_recv (&src, &dst, oi, oh);
1282 break;
1283
1284 default:
1285 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
c6487d61 1286 zlog_debug ("Unknown message");
508e53e2 1287 break;
1288 }
718e3744 1289
508e53e2 1290 return 0;
718e3744 1291}
1292
1293void
508e53e2 1294ospf6_send (struct in6_addr *src, struct in6_addr *dst,
1295 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 1296{
508e53e2 1297 int len;
1298 char srcname[64], dstname[64];
1299 struct iovec iovector[2];
718e3744 1300
508e53e2 1301 /* initialize */
1302 iovector[0].iov_base = (caddr_t) oh;
1303 iovector[0].iov_len = ntohs (oh->length);
1304 iovector[1].iov_base = NULL;
1305 iovector[1].iov_len = 0;
1306
1307 /* fill OSPF header */
1308 oh->version = OSPFV3_VERSION;
1309 /* message type must be set before */
1310 /* message length must be set before */
1311 oh->router_id = oi->area->ospf6->router_id;
1312 oh->area_id = oi->area->area_id;
1313 /* checksum is calculated by kernel */
1314 oh->instance_id = oi->instance_id;
1315 oh->reserved = 0;
718e3744 1316
508e53e2 1317 /* Log */
1318 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
718e3744 1319 {
508e53e2 1320 inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
1321 if (src)
1322 inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
718e3744 1323 else
508e53e2 1324 memset (srcname, 0, sizeof (srcname));
c6487d61 1325 zlog_debug ("%s send on %s",
508e53e2 1326 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
c6487d61 1327 zlog_debug (" src: %s", srcname);
1328 zlog_debug (" dst: %s", dstname);
508e53e2 1329
1330 switch (oh->type)
718e3744 1331 {
508e53e2 1332 case OSPF6_MESSAGE_TYPE_HELLO:
1333 ospf6_hello_print (oh);
1334 break;
1335 case OSPF6_MESSAGE_TYPE_DBDESC:
1336 ospf6_dbdesc_print (oh);
1337 break;
1338 case OSPF6_MESSAGE_TYPE_LSREQ:
1339 ospf6_lsreq_print (oh);
1340 break;
1341 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1342 ospf6_lsupdate_print (oh);
1343 break;
1344 case OSPF6_MESSAGE_TYPE_LSACK:
1345 ospf6_lsack_print (oh);
1346 break;
1347 default:
c6487d61 1348 zlog_debug ("Unknown message");
508e53e2 1349 assert (0);
1350 break;
718e3744 1351 }
718e3744 1352 }
1353
508e53e2 1354 /* send message */
1355 len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
1356 if (len != ntohs (oh->length))
1357 zlog_err ("Could not send entire message");
718e3744 1358}
1359
508e53e2 1360int
1361ospf6_hello_send (struct thread *thread)
718e3744 1362{
508e53e2 1363 struct ospf6_interface *oi;
1364 struct ospf6_header *oh;
1365 struct ospf6_hello *hello;
0c083ee9 1366 u_char *p;
1eb8ef25 1367 struct listnode *node, *nnode;
508e53e2 1368 struct ospf6_neighbor *on;
718e3744 1369
508e53e2 1370 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1371 oi->thread_send_hello = (struct thread *) NULL;
718e3744 1372
508e53e2 1373 if (oi->state <= OSPF6_INTERFACE_DOWN)
718e3744 1374 {
508e53e2 1375 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
c6487d61 1376 zlog_debug ("Unable to send Hello on down interface %s",
508e53e2 1377 oi->interface->name);
1378 return 0;
718e3744 1379 }
1380
508e53e2 1381 /* set next thread */
1382 oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
1383 oi, oi->hello_interval);
718e3744 1384
3b4cd3a9 1385 memset (sendbuf, 0, iobuflen);
508e53e2 1386 oh = (struct ospf6_header *) sendbuf;
1387 hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1388
508e53e2 1389 hello->interface_id = htonl (oi->interface->ifindex);
1390 hello->priority = oi->priority;
1391 hello->options[0] = oi->area->options[0];
1392 hello->options[1] = oi->area->options[1];
1393 hello->options[2] = oi->area->options[2];
1394 hello->hello_interval = htons (oi->hello_interval);
1395 hello->dead_interval = htons (oi->dead_interval);
1396 hello->drouter = oi->drouter;
1397 hello->bdrouter = oi->bdrouter;
718e3744 1398
508e53e2 1399 p = (char *)((caddr_t) hello + sizeof (struct ospf6_hello));
718e3744 1400
1eb8ef25 1401 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
718e3744 1402 {
508e53e2 1403 if (on->state < OSPF6_NEIGHBOR_INIT)
1404 continue;
1405
1406 if (p - sendbuf + sizeof (u_int32_t) > oi->ifmtu)
1407 {
1408 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
c6487d61 1409 zlog_debug ("sending Hello message: exceeds I/F MTU");
508e53e2 1410 break;
1411 }
718e3744 1412
508e53e2 1413 memcpy (p, &on->router_id, sizeof (u_int32_t));
1414 p += sizeof (u_int32_t);
1415 }
718e3744 1416
508e53e2 1417 oh->type = OSPF6_MESSAGE_TYPE_HELLO;
1418 oh->length = htons (p - sendbuf);
718e3744 1419
508e53e2 1420 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1421 return 0;
718e3744 1422}
1423
1424int
508e53e2 1425ospf6_dbdesc_send (struct thread *thread)
718e3744 1426{
508e53e2 1427 struct ospf6_neighbor *on;
1428 struct ospf6_header *oh;
1429 struct ospf6_dbdesc *dbdesc;
0c083ee9 1430 u_char *p;
508e53e2 1431 struct ospf6_lsa *lsa;
718e3744 1432
508e53e2 1433 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1434 on->thread_send_dbdesc = (struct thread *) NULL;
718e3744 1435
508e53e2 1436 if (on->state < OSPF6_NEIGHBOR_EXSTART)
1437 {
1438 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
c6487d61 1439 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1440 on->name, ospf6_neighbor_state_str[on->state]);
508e53e2 1441 return 0;
1442 }
718e3744 1443
508e53e2 1444 /* set next thread if master */
1445 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
1446 on->thread_send_dbdesc =
1447 thread_add_timer (master, ospf6_dbdesc_send, on,
1448 on->ospf6_if->rxmt_interval);
718e3744 1449
3b4cd3a9 1450 memset (sendbuf, 0, iobuflen);
508e53e2 1451 oh = (struct ospf6_header *) sendbuf;
1452 dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
1453 sizeof (struct ospf6_header));
718e3744 1454
508e53e2 1455 /* if this is initial one, initialize sequence number for DbDesc */
1456 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
1457 {
1458 struct timeval tv;
1459 if (gettimeofday (&tv, (struct timezone *) NULL) < 0)
1460 tv.tv_sec = 1;
1461 on->dbdesc_seqnum = tv.tv_sec;
1462 }
1463
1464 dbdesc->options[0] = on->ospf6_if->area->options[0];
1465 dbdesc->options[1] = on->ospf6_if->area->options[1];
1466 dbdesc->options[2] = on->ospf6_if->area->options[2];
1467 dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
1468 dbdesc->bits = on->dbdesc_bits;
1469 dbdesc->seqnum = htonl (on->dbdesc_seqnum);
718e3744 1470
508e53e2 1471 /* if this is not initial one, set LSA headers in dbdesc */
1472 p = (char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
1473 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
718e3744 1474 {
508e53e2 1475 for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
1476 lsa = ospf6_lsdb_next (lsa))
1477 {
1478 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1479
1480 /* MTU check */
1481 if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
1482 on->ospf6_if->ifmtu)
1483 {
1484 ospf6_lsa_unlock (lsa);
1485 break;
1486 }
1487 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1488 p += sizeof (struct ospf6_lsa_header);
1489 }
718e3744 1490 }
1491
508e53e2 1492 oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
1493 oh->length = htons (p - sendbuf);
718e3744 1494
508e53e2 1495 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1496 on->ospf6_if, oh);
718e3744 1497 return 0;
1498}
1499
718e3744 1500int
508e53e2 1501ospf6_dbdesc_send_newone (struct thread *thread)
718e3744 1502{
508e53e2 1503 struct ospf6_neighbor *on;
1504 struct ospf6_lsa *lsa;
1505 unsigned int size = 0;
1506
1507 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
508e53e2 1508 ospf6_lsdb_remove_all (on->dbdesc_list);
1509
1510 /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1511 so that ospf6_send_dbdesc () can send those LSAs */
1512 size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
1513 for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
1514 lsa = ospf6_lsdb_next (lsa))
718e3744 1515 {
508e53e2 1516 if (size + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
718e3744 1517 {
508e53e2 1518 ospf6_lsa_unlock (lsa);
1519 break;
718e3744 1520 }
508e53e2 1521
508e53e2 1522 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
1523 ospf6_lsdb_remove (lsa, on->summary_list);
1524 size += sizeof (struct ospf6_lsa_header);
718e3744 1525 }
1526
508e53e2 1527 if (on->summary_list->count == 0)
1528 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
718e3744 1529
508e53e2 1530 /* If slave, More bit check must be done here */
1531 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
1532 ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
1533 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
1534 thread_add_event (master, exchange_done, on, 0);
718e3744 1535
508e53e2 1536 thread_execute (master, ospf6_dbdesc_send, on, 0);
1537 return 0;
1538}
718e3744 1539
508e53e2 1540int
1541ospf6_lsreq_send (struct thread *thread)
1542{
1543 struct ospf6_neighbor *on;
1544 struct ospf6_header *oh;
1545 struct ospf6_lsreq_entry *e;
0c083ee9 1546 u_char *p;
508e53e2 1547 struct ospf6_lsa *lsa;
718e3744 1548
508e53e2 1549 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1550 on->thread_send_lsreq = (struct thread *) NULL;
1551
1552 /* LSReq will be sent only in ExStart or Loading */
1553 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1554 on->state != OSPF6_NEIGHBOR_LOADING)
718e3744 1555 {
508e53e2 1556 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
c6487d61 1557 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1558 on->name, ospf6_neighbor_state_str[on->state]);
508e53e2 1559 return 0;
718e3744 1560 }
1561
508e53e2 1562 /* schedule loading_done if request list is empty */
1563 if (on->request_list->count == 0)
1564 {
1565 thread_add_event (master, loading_done, on, 0);
718e3744 1566 return 0;
1567 }
1568
508e53e2 1569 /* set next thread */
1570 on->thread_send_lsreq =
1571 thread_add_timer (master, ospf6_lsreq_send, on,
1572 on->ospf6_if->rxmt_interval);
718e3744 1573
3b4cd3a9 1574 memset (sendbuf, 0, iobuflen);
508e53e2 1575 oh = (struct ospf6_header *) sendbuf;
718e3744 1576
508e53e2 1577 /* set Request entries in lsreq */
1578 p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
1579 for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1580 lsa = ospf6_lsdb_next (lsa))
718e3744 1581 {
508e53e2 1582 /* MTU check */
1583 if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > on->ospf6_if->ifmtu)
718e3744 1584 {
508e53e2 1585 ospf6_lsa_unlock (lsa);
718e3744 1586 break;
1587 }
1588
508e53e2 1589 e = (struct ospf6_lsreq_entry *) p;
1590 e->type = lsa->header->type;
1591 e->id = lsa->header->id;
1592 e->adv_router = lsa->header->adv_router;
1593 p += sizeof (struct ospf6_lsreq_entry);
718e3744 1594 }
718e3744 1595
508e53e2 1596 oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
1597 oh->length = htons (p - sendbuf);
718e3744 1598
508e53e2 1599 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1600 on->ospf6_if, oh);
718e3744 1601 return 0;
1602}
1603
718e3744 1604int
508e53e2 1605ospf6_lsupdate_send_neighbor (struct thread *thread)
718e3744 1606{
508e53e2 1607 struct ospf6_neighbor *on;
1608 struct ospf6_header *oh;
1609 struct ospf6_lsupdate *lsupdate;
0c083ee9 1610 u_char *p;
508e53e2 1611 int num;
718e3744 1612 struct ospf6_lsa *lsa;
718e3744 1613
508e53e2 1614 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1615 on->thread_send_lsupdate = (struct thread *) NULL;
718e3744 1616
6452df09 1617 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1618 zlog_debug ("LSUpdate to neighbor %s", on->name);
6452df09 1619
508e53e2 1620 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
1621 {
1622 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1623 zlog_debug ("Quit to send (neighbor state %s)",
1624 ospf6_neighbor_state_str[on->state]);
508e53e2 1625 return 0;
1626 }
718e3744 1627
508e53e2 1628 /* if we have nothing to send, return */
1629 if (on->lsupdate_list->count == 0 &&
1630 on->retrans_list->count == 0)
6452df09 1631 {
1632 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1633 zlog_debug ("Quit to send (nothing to send)");
6452df09 1634 return 0;
1635 }
508e53e2 1636
3b4cd3a9 1637 memset (sendbuf, 0, iobuflen);
508e53e2 1638 oh = (struct ospf6_header *) sendbuf;
1639 lsupdate = (struct ospf6_lsupdate *)
1640 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1641
508e53e2 1642 p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1643 num = 0;
718e3744 1644
508e53e2 1645 /* lsupdate_list lists those LSA which doesn't need to be
1646 retransmitted. remove those from the list */
1647 for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
1648 lsa = ospf6_lsdb_next (lsa))
718e3744 1649 {
508e53e2 1650 /* MTU check */
0c083ee9 1651 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
1652 > on->ospf6_if->ifmtu)
718e3744 1653 {
508e53e2 1654 ospf6_lsa_unlock (lsa);
1655 break;
1656 }
718e3744 1657
508e53e2 1658 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1659 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
1660 p += OSPF6_LSA_SIZE (lsa->header);
1661 num++;
718e3744 1662
508e53e2 1663 assert (lsa->lock == 2);
1664 ospf6_lsdb_remove (lsa, on->lsupdate_list);
1665 }
1666
1667 for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
1668 lsa = ospf6_lsdb_next (lsa))
1669 {
1670 /* MTU check */
0c083ee9 1671 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
1672 > on->ospf6_if->ifmtu)
508e53e2 1673 {
1674 ospf6_lsa_unlock (lsa);
1675 break;
718e3744 1676 }
508e53e2 1677
508e53e2 1678 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1679 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
1680 p += OSPF6_LSA_SIZE (lsa->header);
1681 num++;
718e3744 1682 }
1683
508e53e2 1684 lsupdate->lsa_number = htonl (num);
1685
1686 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
1687 oh->length = htons (p - sendbuf);
718e3744 1688
508e53e2 1689 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1690 on->ospf6_if, oh);
718e3744 1691
508e53e2 1692 if (on->lsupdate_list->count != 0 ||
1693 on->retrans_list->count != 0)
1694 {
1695 if (on->lsupdate_list->count != 0)
1696 on->thread_send_lsupdate =
1697 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
1698 else
1699 on->thread_send_lsupdate =
1700 thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
1701 on->ospf6_if->rxmt_interval);
1702 }
718e3744 1703
1704 return 0;
1705}
1706
1707int
508e53e2 1708ospf6_lsupdate_send_interface (struct thread *thread)
718e3744 1709{
508e53e2 1710 struct ospf6_interface *oi;
1711 struct ospf6_header *oh;
1712 struct ospf6_lsupdate *lsupdate;
0c083ee9 1713 u_char *p;
508e53e2 1714 int num;
718e3744 1715 struct ospf6_lsa *lsa;
718e3744 1716
508e53e2 1717 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1718 oi->thread_send_lsupdate = (struct thread *) NULL;
718e3744 1719
508e53e2 1720 if (oi->state <= OSPF6_INTERFACE_WAITING)
718e3744 1721 {
508e53e2 1722 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 1723 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
1724 oi->interface->name, ospf6_interface_state_str[oi->state]);
508e53e2 1725 return 0;
1726 }
718e3744 1727
508e53e2 1728 /* if we have nothing to send, return */
1729 if (oi->lsupdate_list->count == 0)
1730 return 0;
718e3744 1731
3b4cd3a9 1732 memset (sendbuf, 0, iobuflen);
508e53e2 1733 oh = (struct ospf6_header *) sendbuf;
1734 lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
1735 sizeof (struct ospf6_header));
718e3744 1736
508e53e2 1737 p = (char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1738 num = 0;
718e3744 1739
508e53e2 1740 for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
1741 lsa = ospf6_lsdb_next (lsa))
1742 {
1743 /* MTU check */
0c083ee9 1744 if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
1745 > oi->ifmtu)
718e3744 1746 {
508e53e2 1747 ospf6_lsa_unlock (lsa);
1748 break;
718e3744 1749 }
718e3744 1750
508e53e2 1751 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
1752 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
1753 p += OSPF6_LSA_SIZE (lsa->header);
1754 num++;
718e3744 1755
508e53e2 1756 assert (lsa->lock == 2);
1757 ospf6_lsdb_remove (lsa, oi->lsupdate_list);
1758 }
718e3744 1759
508e53e2 1760 lsupdate->lsa_number = htonl (num);
718e3744 1761
508e53e2 1762 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
1763 oh->length = htons (p - sendbuf);
718e3744 1764
508e53e2 1765 if (oi->state == OSPF6_INTERFACE_DR ||
1766 oi->state == OSPF6_INTERFACE_BDR)
1767 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1768 else
1769 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
718e3744 1770
508e53e2 1771 if (oi->lsupdate_list->count > 0)
1772 {
1773 oi->thread_send_lsupdate =
1774 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
1775 }
718e3744 1776
718e3744 1777 return 0;
1778}
1779
1780int
508e53e2 1781ospf6_lsack_send_neighbor (struct thread *thread)
718e3744 1782{
508e53e2 1783 struct ospf6_neighbor *on;
1784 struct ospf6_header *oh;
0c083ee9 1785 u_char *p;
718e3744 1786 struct ospf6_lsa *lsa;
718e3744 1787
508e53e2 1788 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1789 on->thread_send_lsack = (struct thread *) NULL;
718e3744 1790
508e53e2 1791 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
718e3744 1792 {
508e53e2 1793 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
c6487d61 1794 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
1795 on->name, ospf6_neighbor_state_str[on->state]);
718e3744 1796 return 0;
1797 }
1798
508e53e2 1799 /* if we have nothing to send, return */
1800 if (on->lsack_list->count == 0)
1801 return 0;
718e3744 1802
3b4cd3a9 1803 memset (sendbuf, 0, iobuflen);
508e53e2 1804 oh = (struct ospf6_header *) sendbuf;
718e3744 1805
508e53e2 1806 p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1807
508e53e2 1808 for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
1809 lsa = ospf6_lsdb_next (lsa))
1810 {
1811 /* MTU check */
1812 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > on->ospf6_if->ifmtu)
1813 {
1814 /* if we run out of packet size/space here,
1815 better to try again soon. */
1816 THREAD_OFF (on->thread_send_lsack);
1817 on->thread_send_lsack =
1818 thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
718e3744 1819
508e53e2 1820 ospf6_lsa_unlock (lsa);
1821 break;
1822 }
718e3744 1823
508e53e2 1824 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1825 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1826 p += sizeof (struct ospf6_lsa_header);
718e3744 1827
508e53e2 1828 assert (lsa->lock == 2);
1829 ospf6_lsdb_remove (lsa, on->lsack_list);
1830 }
718e3744 1831
508e53e2 1832 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
1833 oh->length = htons (p - sendbuf);
718e3744 1834
508e53e2 1835 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1836 on->ospf6_if, oh);
718e3744 1837 return 0;
1838}
1839
718e3744 1840int
508e53e2 1841ospf6_lsack_send_interface (struct thread *thread)
718e3744 1842{
508e53e2 1843 struct ospf6_interface *oi;
1844 struct ospf6_header *oh;
0c083ee9 1845 u_char *p;
718e3744 1846 struct ospf6_lsa *lsa;
718e3744 1847
508e53e2 1848 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1849 oi->thread_send_lsack = (struct thread *) NULL;
718e3744 1850
508e53e2 1851 if (oi->state <= OSPF6_INTERFACE_WAITING)
1852 {
1853 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
c6487d61 1854 zlog_debug ("Quit to send LSAck to interface %s state %s",
1855 oi->interface->name, ospf6_interface_state_str[oi->state]);
508e53e2 1856 return 0;
1857 }
718e3744 1858
508e53e2 1859 /* if we have nothing to send, return */
1860 if (oi->lsack_list->count == 0)
1861 return 0;
718e3744 1862
3b4cd3a9 1863 memset (sendbuf, 0, iobuflen);
508e53e2 1864 oh = (struct ospf6_header *) sendbuf;
718e3744 1865
508e53e2 1866 p = (char *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1867
508e53e2 1868 for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
1869 lsa = ospf6_lsdb_next (lsa))
718e3744 1870 {
508e53e2 1871 /* MTU check */
1872 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > oi->ifmtu)
1873 {
1874 /* if we run out of packet size/space here,
1875 better to try again soon. */
1876 THREAD_OFF (oi->thread_send_lsack);
1877 oi->thread_send_lsack =
1878 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
718e3744 1879
508e53e2 1880 ospf6_lsa_unlock (lsa);
1881 break;
1882 }
718e3744 1883
508e53e2 1884 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
1885 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1886 p += sizeof (struct ospf6_lsa_header);
718e3744 1887
508e53e2 1888 assert (lsa->lock == 2);
1889 ospf6_lsdb_remove (lsa, oi->lsack_list);
1890 }
718e3744 1891
508e53e2 1892 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
1893 oh->length = htons (p - sendbuf);
718e3744 1894
508e53e2 1895 if (oi->state == OSPF6_INTERFACE_DR ||
1896 oi->state == OSPF6_INTERFACE_BDR)
1897 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1898 else
1899 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
718e3744 1900
508e53e2 1901 if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
1902 {
1903 oi->thread_send_lsack =
1904 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
1905 }
718e3744 1906
718e3744 1907 return 0;
1908}
1909
508e53e2 1910\f
1911/* Commands */
1912DEFUN (debug_ospf6_message,
1913 debug_ospf6_message_cmd,
1914 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
1915 DEBUG_STR
1916 OSPF6_STR
1917 "Debug OSPFv3 message\n"
1918 "Debug Unknown message\n"
1919 "Debug Hello message\n"
1920 "Debug Database Description message\n"
1921 "Debug Link State Request message\n"
1922 "Debug Link State Update message\n"
1923 "Debug Link State Acknowledgement message\n"
1924 "Debug All message\n"
1925 )
718e3744 1926{
508e53e2 1927 unsigned char level = 0;
1928 int type = 0;
1929 int i;
718e3744 1930
508e53e2 1931 assert (argc > 0);
718e3744 1932
508e53e2 1933 /* check type */
1934 if (! strncmp (argv[0], "u", 1))
1935 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
1936 else if (! strncmp (argv[0], "h", 1))
1937 type = OSPF6_MESSAGE_TYPE_HELLO;
1938 else if (! strncmp (argv[0], "d", 1))
1939 type = OSPF6_MESSAGE_TYPE_DBDESC;
1940 else if (! strncmp (argv[0], "lsr", 3))
1941 type = OSPF6_MESSAGE_TYPE_LSREQ;
1942 else if (! strncmp (argv[0], "lsu", 3))
1943 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
1944 else if (! strncmp (argv[0], "lsa", 3))
1945 type = OSPF6_MESSAGE_TYPE_LSACK;
1946 else if (! strncmp (argv[0], "a", 1))
1947 type = OSPF6_MESSAGE_TYPE_ALL;
1948
1949 if (argc == 1)
1950 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
1951 else if (! strncmp (argv[1], "s", 1))
1952 level = OSPF6_DEBUG_MESSAGE_SEND;
1953 else if (! strncmp (argv[1], "r", 1))
1954 level = OSPF6_DEBUG_MESSAGE_RECV;
1955
1956 if (type == OSPF6_MESSAGE_TYPE_ALL)
1957 {
1958 for (i = 0; i < 6; i++)
1959 OSPF6_DEBUG_MESSAGE_ON (i, level);
1960 }
1961 else
1962 OSPF6_DEBUG_MESSAGE_ON (type, level);
718e3744 1963
508e53e2 1964 return CMD_SUCCESS;
718e3744 1965}
1966
508e53e2 1967ALIAS (debug_ospf6_message,
1968 debug_ospf6_message_sendrecv_cmd,
1969 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
1970 DEBUG_STR
1971 OSPF6_STR
1972 "Debug OSPFv3 message\n"
1973 "Debug Unknown message\n"
1974 "Debug Hello message\n"
1975 "Debug Database Description message\n"
1976 "Debug Link State Request message\n"
1977 "Debug Link State Update message\n"
1978 "Debug Link State Acknowledgement message\n"
1979 "Debug All message\n"
1980 "Debug only sending message\n"
1981 "Debug only receiving message\n"
1982 );
718e3744 1983
508e53e2 1984\f
1985DEFUN (no_debug_ospf6_message,
1986 no_debug_ospf6_message_cmd,
1987 "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
1988 NO_STR
1989 DEBUG_STR
1990 OSPF6_STR
1991 "Debug OSPFv3 message\n"
1992 "Debug Unknown message\n"
1993 "Debug Hello message\n"
1994 "Debug Database Description message\n"
1995 "Debug Link State Request message\n"
1996 "Debug Link State Update message\n"
1997 "Debug Link State Acknowledgement message\n"
1998 "Debug All message\n"
1999 )
2000{
2001 unsigned char level = 0;
2002 int type = 0;
2003 int i;
718e3744 2004
508e53e2 2005 assert (argc > 0);
718e3744 2006
508e53e2 2007 /* check type */
2008 if (! strncmp (argv[0], "u", 1))
2009 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
2010 else if (! strncmp (argv[0], "h", 1))
2011 type = OSPF6_MESSAGE_TYPE_HELLO;
2012 else if (! strncmp (argv[0], "d", 1))
2013 type = OSPF6_MESSAGE_TYPE_DBDESC;
2014 else if (! strncmp (argv[0], "lsr", 3))
2015 type = OSPF6_MESSAGE_TYPE_LSREQ;
2016 else if (! strncmp (argv[0], "lsu", 3))
2017 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2018 else if (! strncmp (argv[0], "lsa", 3))
2019 type = OSPF6_MESSAGE_TYPE_LSACK;
2020 else if (! strncmp (argv[0], "a", 1))
2021 type = OSPF6_MESSAGE_TYPE_ALL;
2022
2023 if (argc == 1)
2024 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
2025 else if (! strncmp (argv[1], "s", 1))
2026 level = OSPF6_DEBUG_MESSAGE_SEND;
2027 else if (! strncmp (argv[1], "r", 1))
2028 level = OSPF6_DEBUG_MESSAGE_RECV;
2029
2030 if (type == OSPF6_MESSAGE_TYPE_ALL)
718e3744 2031 {
508e53e2 2032 for (i = 0; i < 6; i++)
2033 OSPF6_DEBUG_MESSAGE_OFF (i, level);
718e3744 2034 }
2035 else
508e53e2 2036 OSPF6_DEBUG_MESSAGE_OFF (type, level);
718e3744 2037
508e53e2 2038 return CMD_SUCCESS;
718e3744 2039}
2040
508e53e2 2041ALIAS (no_debug_ospf6_message,
2042 no_debug_ospf6_message_sendrecv_cmd,
049207c3 2043 "no debug ospf6 message "
2044 "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
508e53e2 2045 NO_STR
2046 DEBUG_STR
2047 OSPF6_STR
2048 "Debug OSPFv3 message\n"
2049 "Debug Unknown message\n"
2050 "Debug Hello message\n"
2051 "Debug Database Description message\n"
2052 "Debug Link State Request message\n"
2053 "Debug Link State Update message\n"
2054 "Debug Link State Acknowledgement message\n"
2055 "Debug All message\n"
2056 "Debug only sending message\n"
2057 "Debug only receiving message\n"
2058 );
2059
718e3744 2060int
508e53e2 2061config_write_ospf6_debug_message (struct vty *vty)
718e3744 2062{
0c083ee9 2063 const char *type_str[] = {"unknown", "hello", "dbdesc",
508e53e2 2064 "lsreq", "lsupdate", "lsack"};
2065 unsigned char s = 0, r = 0;
2066 int i;
718e3744 2067
508e53e2 2068 for (i = 0; i < 6; i++)
2069 {
2070 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2071 s |= 1 << i;
2072 if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2073 r |= 1 << i;
2074 }
718e3744 2075
508e53e2 2076 if (s == 0x3f && r == 0x3f)
718e3744 2077 {
049207c3 2078 vty_out (vty, "debug ospf6 message all%s", VNL);
508e53e2 2079 return 0;
2080 }
718e3744 2081
508e53e2 2082 if (s == 0x3f && r == 0)
2083 {
049207c3 2084 vty_out (vty, "debug ospf6 message all send%s", VNL);
508e53e2 2085 return 0;
2086 }
2087 else if (s == 0 && r == 0x3f)
2088 {
049207c3 2089 vty_out (vty, "debug ospf6 message all recv%s", VNL);
508e53e2 2090 return 0;
718e3744 2091 }
2092
508e53e2 2093 /* Unknown message is logged by default */
2094 if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
2095 ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
049207c3 2096 vty_out (vty, "no debug ospf6 message unknown%s", VNL);
508e53e2 2097 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
049207c3 2098 vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
508e53e2 2099 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
049207c3 2100 vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
718e3744 2101
508e53e2 2102 for (i = 1; i < 6; i++)
718e3744 2103 {
508e53e2 2104 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
2105 IS_OSPF6_DEBUG_MESSAGE (i, RECV))
049207c3 2106 vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
508e53e2 2107 else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2108 vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
049207c3 2109 VNL);
508e53e2 2110 else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2111 vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
049207c3 2112 VNL);
718e3744 2113 }
2114
718e3744 2115 return 0;
2116}
2117
508e53e2 2118void
2119install_element_ospf6_debug_message ()
2120{
2121 install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
2122 install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
2123 install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
2124 install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2125 install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
2126 install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
2127 install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
2128 install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2129}
2130
2131