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