]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_message.c
all: scrubbed some argc CHECK MEs
[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
abc7ef44
DO
42/* for structures and macros ospf6_lsa_examin() needs */
43#include "ospf6_abr.h"
44#include "ospf6_asbr.h"
45#include "ospf6_intra.h"
46
508e53e2 47#include "ospf6_flood.h"
049207c3 48#include "ospf6d.h"
718e3744 49
681b84e8
DT
50#include <netinet/ip6.h>
51
508e53e2 52unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
5031ed13
DO
53static const struct message ospf6_message_type_str [] =
54{
55 { OSPF6_MESSAGE_TYPE_HELLO, "Hello" },
56 { OSPF6_MESSAGE_TYPE_DBDESC, "DbDesc" },
57 { OSPF6_MESSAGE_TYPE_LSREQ, "LSReq" },
58 { OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate" },
59 { OSPF6_MESSAGE_TYPE_LSACK, "LSAck" },
60};
837d16cc 61static const size_t ospf6_message_type_str_max = array_size(ospf6_message_type_str);
718e3744 62
abc7ef44
DO
63/* Minimum (besides the standard OSPF packet header) lengths for OSPF
64 packets of particular types, offset is the "type" field. */
65const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] =
66{
67 0,
68 OSPF6_HELLO_MIN_SIZE,
69 OSPF6_DB_DESC_MIN_SIZE,
70 OSPF6_LS_REQ_MIN_SIZE,
71 OSPF6_LS_UPD_MIN_SIZE,
72 OSPF6_LS_ACK_MIN_SIZE
73};
74
75/* Minimum (besides the standard LSA header) lengths for LSAs of particular
76 types, offset is the "LSA function code" portion of "LSA type" field. */
77const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] =
78{
79 0,
80 /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE,
81 /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE,
82 /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
83 /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE,
84 /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
85 /* 0x2006 */ 0,
86 /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
87 /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE,
88 /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
89};
90
508e53e2 91/* print functions */
718e3744 92
93static void
508e53e2 94ospf6_header_print (struct ospf6_header *oh)
718e3744 95{
508e53e2 96 char router_id[16], area_id[16];
97 inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id));
98 inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id));
99
c6487d61 100 zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s",
508e53e2 101 oh->version, oh->type, ntohs (oh->length), router_id);
c6487d61 102 zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d",
508e53e2 103 area_id, ntohs (oh->checksum), oh->instance_id);
718e3744 104}
105
508e53e2 106void
107ospf6_hello_print (struct ospf6_header *oh)
718e3744 108{
718e3744 109 struct ospf6_hello *hello;
508e53e2 110 char options[16];
111 char drouter[16], bdrouter[16], neighbor[16];
112 char *p;
718e3744 113
508e53e2 114 ospf6_header_print (oh);
115 assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
718e3744 116
508e53e2 117 hello = (struct ospf6_hello *)
118 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 119
508e53e2 120 inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter));
121 inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter));
122 ospf6_options_printbuf (hello->options, options, sizeof (options));
718e3744 123
c6487d61 124 zlog_debug (" I/F-Id:%ld Priority:%d Option:%s",
508e53e2 125 (u_long) ntohl (hello->interface_id), hello->priority, options);
c6487d61 126 zlog_debug (" HelloInterval:%hu DeadInterval:%hu",
508e53e2 127 ntohs (hello->hello_interval), ntohs (hello->dead_interval));
c6487d61 128 zlog_debug (" DR:%s BDR:%s", drouter, bdrouter);
718e3744 129
508e53e2 130 for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
131 p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
132 p += sizeof (u_int32_t))
718e3744 133 {
508e53e2 134 inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
c6487d61 135 zlog_debug (" Neighbor: %s", neighbor);
718e3744 136 }
508e53e2 137
fa079666 138 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 139}
140
508e53e2 141void
142ospf6_dbdesc_print (struct ospf6_header *oh)
718e3744 143{
718e3744 144 struct ospf6_dbdesc *dbdesc;
508e53e2 145 char options[16];
146 char *p;
147
148 ospf6_header_print (oh);
149 assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
150
151 dbdesc = (struct ospf6_dbdesc *)
152 ((caddr_t) oh + sizeof (struct ospf6_header));
153
154 ospf6_options_printbuf (dbdesc->options, options, sizeof (options));
155
c6487d61 156 zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu",
508e53e2 157 dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
c6487d61 158 zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
508e53e2 159 dbdesc->reserved2,
160 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
161 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
162 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
163 (u_long) ntohl (dbdesc->seqnum));
164
165 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
166 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
167 p += sizeof (struct ospf6_lsa_header))
168 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
169
fa079666 170 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 171}
172
508e53e2 173void
174ospf6_lsreq_print (struct ospf6_header *oh)
718e3744 175{
508e53e2 176 char id[16], adv_router[16];
177 char *p;
718e3744 178
508e53e2 179 ospf6_header_print (oh);
180 assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
718e3744 181
508e53e2 182 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
183 p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
184 p += sizeof (struct ospf6_lsreq_entry))
718e3744 185 {
508e53e2 186 struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p;
187 inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router));
188 inet_ntop (AF_INET, &e->id, id, sizeof (id));
c6487d61 189 zlog_debug (" [%s Id:%s Adv:%s]",
1e05838a 190 ospf6_lstype_name (e->type), id, adv_router);
718e3744 191 }
508e53e2 192
fa079666 193 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 194}
195
508e53e2 196void
197ospf6_lsupdate_print (struct ospf6_header *oh)
718e3744 198{
718e3744 199 struct ospf6_lsupdate *lsupdate;
508e53e2 200 u_long num;
201 char *p;
718e3744 202
508e53e2 203 ospf6_header_print (oh);
204 assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
718e3744 205
508e53e2 206 lsupdate = (struct ospf6_lsupdate *)
207 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 208
508e53e2 209 num = ntohl (lsupdate->lsa_number);
c6487d61 210 zlog_debug (" Number of LSA: %ld", num);
718e3744 211
508e53e2 212 for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
213 p < OSPF6_MESSAGE_END (oh) &&
214 p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
215 p += OSPF6_LSA_SIZE (p))
216 {
217 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
508e53e2 218 }
718e3744 219
fa079666 220 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 221}
222
508e53e2 223void
224ospf6_lsack_print (struct ospf6_header *oh)
718e3744 225{
508e53e2 226 char *p;
718e3744 227
508e53e2 228 ospf6_header_print (oh);
229 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
718e3744 230
508e53e2 231 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
232 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
233 p += sizeof (struct ospf6_lsa_header))
234 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
235
fa079666 236 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 237}
238
6ac29a51 239static void
508e53e2 240ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
241 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 242{
718e3744 243 struct ospf6_hello *hello;
508e53e2 244 struct ospf6_neighbor *on;
245 char *p;
246 int twoway = 0;
247 int neighborchange = 0;
552237cf 248 int neighbor_ifindex_change = 0;
508e53e2 249 int backupseen = 0;
250
508e53e2 251 hello = (struct ospf6_hello *)
252 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 253
254 /* HelloInterval check */
508e53e2 255 if (ntohs (hello->hello_interval) != oi->hello_interval)
718e3744 256 {
508e53e2 257 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 258 zlog_debug ("HelloInterval mismatch");
718e3744 259 return;
260 }
261
262 /* RouterDeadInterval check */
508e53e2 263 if (ntohs (hello->dead_interval) != oi->dead_interval)
718e3744 264 {
508e53e2 265 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 266 zlog_debug ("RouterDeadInterval mismatch");
718e3744 267 return;
268 }
269
508e53e2 270 /* E-bit check */
271 if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
272 OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
718e3744 273 {
508e53e2 274 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 275 zlog_debug ("E-bit mismatch");
718e3744 276 return;
277 }
278
508e53e2 279 /* Find neighbor, create if not exist */
280 on = ospf6_neighbor_lookup (oh->router_id, oi);
281 if (on == NULL)
718e3744 282 {
508e53e2 283 on = ospf6_neighbor_create (oh->router_id, oi);
284 on->prev_drouter = on->drouter = hello->drouter;
285 on->prev_bdrouter = on->bdrouter = hello->bdrouter;
286 on->priority = hello->priority;
718e3744 287 }
288
552237cf 289 /* Always override neighbor's source address */
7b6ae028 290 memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr));
291
552237cf 292 /* Neighbor ifindex check */
b892f1dd 293 if (on->ifindex != (ifindex_t)ntohl (hello->interface_id))
552237cf
DS
294 {
295 on->ifindex = ntohl (hello->interface_id);
296 neighbor_ifindex_change++;
297 }
298
508e53e2 299 /* TwoWay check */
300 for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
301 p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
302 p += sizeof (u_int32_t))
718e3744 303 {
508e53e2 304 u_int32_t *router_id = (u_int32_t *) p;
305
306 if (*router_id == oi->area->ospf6->router_id)
307 twoway++;
718e3744 308 }
309
fa079666 310 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 311
508e53e2 312 /* RouterPriority check */
313 if (on->priority != hello->priority)
718e3744 314 {
508e53e2 315 on->priority = hello->priority;
316 neighborchange++;
718e3744 317 }
318
508e53e2 319 /* DR check */
320 if (on->drouter != hello->drouter)
321 {
322 on->prev_drouter = on->drouter;
323 on->drouter = hello->drouter;
324 if (on->prev_drouter == on->router_id || on->drouter == on->router_id)
325 neighborchange++;
326 }
718e3744 327
508e53e2 328 /* BDR check */
329 if (on->bdrouter != hello->bdrouter)
718e3744 330 {
508e53e2 331 on->prev_bdrouter = on->bdrouter;
332 on->bdrouter = hello->bdrouter;
333 if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id)
334 neighborchange++;
335 }
718e3744 336
508e53e2 337 /* BackupSeen check */
338 if (oi->state == OSPF6_INTERFACE_WAITING)
339 {
340 if (hello->bdrouter == on->router_id)
718e3744 341 backupseen++;
508e53e2 342 else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
718e3744 343 backupseen++;
344 }
345
508e53e2 346 /* Execute neighbor events */
347 thread_execute (master, hello_received, on, 0);
348 if (twoway)
349 thread_execute (master, twoway_received, on, 0);
350 else
351 thread_execute (master, oneway_received, on, 0);
718e3744 352
508e53e2 353 /* Schedule interface events */
718e3744 354 if (backupseen)
508e53e2 355 thread_add_event (master, backup_seen, oi, 0);
356 if (neighborchange)
357 thread_add_event (master, neighbor_change, oi, 0);
552237cf
DS
358
359 if (neighbor_ifindex_change && on->state == OSPF6_NEIGHBOR_FULL)
360 OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
718e3744 361}
362
508e53e2 363static void
364ospf6_dbdesc_recv_master (struct ospf6_header *oh,
365 struct ospf6_neighbor *on)
718e3744 366{
508e53e2 367 struct ospf6_dbdesc *dbdesc;
368 char *p;
718e3744 369
508e53e2 370 dbdesc = (struct ospf6_dbdesc *)
371 ((caddr_t) oh + sizeof (struct ospf6_header));
372
373 if (on->state < OSPF6_NEIGHBOR_INIT)
718e3744 374 {
508e53e2 375 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 376 zlog_debug ("Neighbor state less than Init, ignore");
508e53e2 377 return;
718e3744 378 }
718e3744 379
508e53e2 380 switch (on->state)
381 {
382 case OSPF6_NEIGHBOR_TWOWAY:
383 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 384 zlog_debug ("Neighbor state is 2-Way, ignore");
508e53e2 385 return;
718e3744 386
508e53e2 387 case OSPF6_NEIGHBOR_INIT:
388 thread_execute (master, twoway_received, on, 0);
389 if (on->state != OSPF6_NEIGHBOR_EXSTART)
390 {
391 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 392 zlog_debug ("Neighbor state is not ExStart, ignore");
508e53e2 393 return;
394 }
395 /* else fall through to ExStart */
396
397 case OSPF6_NEIGHBOR_EXSTART:
398 /* if neighbor obeys us as our slave, schedule negotiation_done
399 and process LSA Headers. Otherwise, ignore this message */
400 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
401 ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
402 ntohl (dbdesc->seqnum) == on->dbdesc_seqnum)
403 {
404 /* execute NegotiationDone */
405 thread_execute (master, negotiation_done, on, 0);
718e3744 406
508e53e2 407 /* Record neighbor options */
408 memcpy (on->options, dbdesc->options, sizeof (on->options));
409 }
410 else
411 {
412 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 413 zlog_debug ("Negotiation failed");
508e53e2 414 return;
415 }
416 /* fall through to exchange */
718e3744 417
508e53e2 418 case OSPF6_NEIGHBOR_EXCHANGE:
419 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
420 {
421 /* Duplicated DatabaseDescription is dropped by master */
422 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 423 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
508e53e2 424 return;
425 }
718e3744 426
508e53e2 427 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
428 {
429 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 430 zlog_debug ("Master/Slave bit mismatch");
508e53e2 431 thread_add_event (master, seqnumber_mismatch, on, 0);
432 return;
433 }
434
435 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
436 {
437 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 438 zlog_debug ("Initialize bit mismatch");
508e53e2 439 thread_add_event (master, seqnumber_mismatch, on, 0);
440 return;
441 }
442
443 if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
444 {
445 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 446 zlog_debug ("Option field mismatch");
508e53e2 447 thread_add_event (master, seqnumber_mismatch, on, 0);
448 return;
449 }
450
451 if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum)
452 {
453 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 454 zlog_debug ("Sequence number mismatch (%#lx expected)",
508e53e2 455 (u_long) on->dbdesc_seqnum);
456 thread_add_event (master, seqnumber_mismatch, on, 0);
457 return;
458 }
459 break;
460
461 case OSPF6_NEIGHBOR_LOADING:
462 case OSPF6_NEIGHBOR_FULL:
463 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
464 {
465 /* Duplicated DatabaseDescription is dropped by master */
466 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 467 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
508e53e2 468 return;
469 }
470
471 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 472 zlog_debug ("Not duplicate dbdesc in state %s",
473 ospf6_neighbor_state_str[on->state]);
508e53e2 474 thread_add_event (master, seqnumber_mismatch, on, 0);
475 return;
476
477 default:
478 assert (0);
479 break;
718e3744 480 }
481
508e53e2 482 /* Process LSA headers */
483 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
484 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
485 p += sizeof (struct ospf6_lsa_header))
718e3744 486 {
508e53e2 487 struct ospf6_lsa *his, *mine;
488 struct ospf6_lsdb *lsdb = NULL;
489
490 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
6452df09 491
492 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 493 zlog_debug ("%s", his->name);
6452df09 494
495 switch (OSPF6_LSA_SCOPE (his->header->type))
508e53e2 496 {
6452df09 497 case OSPF6_SCOPE_LINKLOCAL:
498 lsdb = on->ospf6_if->lsdb;
499 break;
500 case OSPF6_SCOPE_AREA:
501 lsdb = on->ospf6_if->area->lsdb;
502 break;
503 case OSPF6_SCOPE_AS:
504 lsdb = on->ospf6_if->area->ospf6->lsdb;
505 break;
506 case OSPF6_SCOPE_RESERVED:
507 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 508 zlog_debug ("Ignoring LSA of reserved scope");
508e53e2 509 ospf6_lsa_delete (his);
6452df09 510 continue;
511 break;
508e53e2 512 }
513
514 if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
6452df09 515 IS_AREA_STUB (on->ospf6_if->area))
718e3744 516 {
508e53e2 517 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 518 zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
508e53e2 519 ospf6_lsa_delete (his);
520 thread_add_event (master, seqnumber_mismatch, on, 0);
718e3744 521 return;
522 }
508e53e2 523
524 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
525 his->header->adv_router, lsdb);
6452df09 526 if (mine == NULL)
508e53e2 527 {
6452df09 528 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 529 zlog_debug ("Add request (No database copy)");
eb82e9ee 530 ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
6452df09 531 }
532 else if (ospf6_lsa_compare (his, mine) < 0)
533 {
534 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 535 zlog_debug ("Add request (Received MoreRecent)");
eb82e9ee 536 ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
508e53e2 537 }
538 else
6452df09 539 {
540 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 541 zlog_debug ("Discard (Existing MoreRecent)");
6452df09 542 }
eb82e9ee 543 ospf6_lsa_delete (his);
718e3744 544 }
545
fa079666 546 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 547
508e53e2 548 /* Increment sequence number */
549 on->dbdesc_seqnum ++;
718e3744 550
508e53e2 551 /* schedule send lsreq */
eb82e9ee 552 if (on->request_list->count && (on->thread_send_lsreq == NULL))
508e53e2 553 on->thread_send_lsreq =
554 thread_add_event (master, ospf6_lsreq_send, on, 0);
718e3744 555
508e53e2 556 THREAD_OFF (on->thread_send_dbdesc);
718e3744 557
508e53e2 558 /* More bit check */
559 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
560 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
561 thread_add_event (master, exchange_done, on, 0);
562 else
563 on->thread_send_dbdesc =
564 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
718e3744 565
508e53e2 566 /* save last received dbdesc */
567 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
718e3744 568}
569
508e53e2 570static void
571ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
572 struct ospf6_neighbor *on)
718e3744 573{
718e3744 574 struct ospf6_dbdesc *dbdesc;
508e53e2 575 char *p;
718e3744 576
508e53e2 577 dbdesc = (struct ospf6_dbdesc *)
578 ((caddr_t) oh + sizeof (struct ospf6_header));
579
580 if (on->state < OSPF6_NEIGHBOR_INIT)
581 {
582 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 583 zlog_debug ("Neighbor state less than Init, ignore");
508e53e2 584 return;
585 }
718e3744 586
508e53e2 587 switch (on->state)
588 {
589 case OSPF6_NEIGHBOR_TWOWAY:
590 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 591 zlog_debug ("Neighbor state is 2-Way, ignore");
508e53e2 592 return;
718e3744 593
508e53e2 594 case OSPF6_NEIGHBOR_INIT:
595 thread_execute (master, twoway_received, on, 0);
596 if (on->state != OSPF6_NEIGHBOR_EXSTART)
597 {
598 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 599 zlog_debug ("Neighbor state is not ExStart, ignore");
508e53e2 600 return;
601 }
602 /* else fall through to ExStart */
603
604 case OSPF6_NEIGHBOR_EXSTART:
605 /* If the neighbor is Master, act as Slave. Schedule negotiation_done
606 and process LSA Headers. Otherwise, ignore this message */
607 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
608 CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
609 CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
610 ntohs (oh->length) == sizeof (struct ospf6_header) +
611 sizeof (struct ospf6_dbdesc))
612 {
613 /* set the master/slave bit to slave */
614 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
615
616 /* set the DD sequence number to one specified by master */
617 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
618
619 /* schedule NegotiationDone */
620 thread_execute (master, negotiation_done, on, 0);
621
622 /* Record neighbor options */
623 memcpy (on->options, dbdesc->options, sizeof (on->options));
624 }
625 else
626 {
627 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 628 zlog_debug ("Negotiation failed");
508e53e2 629 return;
630 }
631 break;
632
633 case OSPF6_NEIGHBOR_EXCHANGE:
634 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
635 {
636 /* Duplicated DatabaseDescription causes slave to retransmit */
637 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 638 zlog_debug ("Duplicated dbdesc causes retransmit");
508e53e2 639 THREAD_OFF (on->thread_send_dbdesc);
640 on->thread_send_dbdesc =
641 thread_add_event (master, ospf6_dbdesc_send, on, 0);
642 return;
643 }
644
645 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
646 {
647 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 648 zlog_debug ("Master/Slave bit mismatch");
508e53e2 649 thread_add_event (master, seqnumber_mismatch, on, 0);
650 return;
651 }
652
653 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
654 {
655 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 656 zlog_debug ("Initialize bit mismatch");
508e53e2 657 thread_add_event (master, seqnumber_mismatch, on, 0);
658 return;
659 }
660
661 if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
662 {
663 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 664 zlog_debug ("Option field mismatch");
508e53e2 665 thread_add_event (master, seqnumber_mismatch, on, 0);
666 return;
667 }
668
669 if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1)
670 {
671 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 672 zlog_debug ("Sequence number mismatch (%#lx expected)",
673 (u_long) on->dbdesc_seqnum + 1);
508e53e2 674 thread_add_event (master, seqnumber_mismatch, on, 0);
675 return;
676 }
677 break;
678
679 case OSPF6_NEIGHBOR_LOADING:
680 case OSPF6_NEIGHBOR_FULL:
681 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
682 {
683 /* Duplicated DatabaseDescription causes slave to retransmit */
684 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 685 zlog_debug ("Duplicated dbdesc causes retransmit");
508e53e2 686 THREAD_OFF (on->thread_send_dbdesc);
687 on->thread_send_dbdesc =
688 thread_add_event (master, ospf6_dbdesc_send, on, 0);
689 return;
690 }
691
692 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 693 zlog_debug ("Not duplicate dbdesc in state %s",
694 ospf6_neighbor_state_str[on->state]);
508e53e2 695 thread_add_event (master, seqnumber_mismatch, on, 0);
696 return;
697
698 default:
699 assert (0);
700 break;
718e3744 701 }
702
508e53e2 703 /* Process LSA headers */
704 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
705 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
706 p += sizeof (struct ospf6_lsa_header))
718e3744 707 {
508e53e2 708 struct ospf6_lsa *his, *mine;
709 struct ospf6_lsdb *lsdb = NULL;
710
711 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
6452df09 712
713 switch (OSPF6_LSA_SCOPE (his->header->type))
508e53e2 714 {
6452df09 715 case OSPF6_SCOPE_LINKLOCAL:
716 lsdb = on->ospf6_if->lsdb;
717 break;
718 case OSPF6_SCOPE_AREA:
719 lsdb = on->ospf6_if->area->lsdb;
720 break;
721 case OSPF6_SCOPE_AS:
722 lsdb = on->ospf6_if->area->ospf6->lsdb;
723 break;
724 case OSPF6_SCOPE_RESERVED:
725 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 726 zlog_debug ("Ignoring LSA of reserved scope");
508e53e2 727 ospf6_lsa_delete (his);
6452df09 728 continue;
729 break;
508e53e2 730 }
731
6452df09 732 if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
733 IS_AREA_STUB (on->ospf6_if->area))
718e3744 734 {
508e53e2 735 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 736 zlog_debug ("E-bit mismatch with LSA Headers");
508e53e2 737 ospf6_lsa_delete (his);
738 thread_add_event (master, seqnumber_mismatch, on, 0);
718e3744 739 return;
740 }
508e53e2 741
742 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
743 his->header->adv_router, lsdb);
744 if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
745 {
6452df09 746 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 747 zlog_debug ("Add request-list: %s", his->name);
eb82e9ee 748 ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
508e53e2 749 }
eb82e9ee 750 ospf6_lsa_delete (his);
718e3744 751 }
752
fa079666 753 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 754
508e53e2 755 /* Set sequence number to Master's */
756 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
718e3744 757
508e53e2 758 /* schedule send lsreq */
eb82e9ee
DD
759 if ((on->thread_send_lsreq == NULL) &&
760 (on->request_list->count))
508e53e2 761 on->thread_send_lsreq =
762 thread_add_event (master, ospf6_lsreq_send, on, 0);
718e3744 763
508e53e2 764 THREAD_OFF (on->thread_send_dbdesc);
765 on->thread_send_dbdesc =
766 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
718e3744 767
508e53e2 768 /* save last received dbdesc */
769 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
718e3744 770}
771
6ac29a51 772static void
508e53e2 773ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
774 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 775{
508e53e2 776 struct ospf6_neighbor *on;
718e3744 777 struct ospf6_dbdesc *dbdesc;
718e3744 778
508e53e2 779 on = ospf6_neighbor_lookup (oh->router_id, oi);
780 if (on == NULL)
718e3744 781 {
508e53e2 782 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 783 zlog_debug ("Neighbor not found, ignore");
718e3744 784 return;
785 }
786
508e53e2 787 dbdesc = (struct ospf6_dbdesc *)
788 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 789
508e53e2 790 /* Interface MTU check */
d42306d9 791 if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
718e3744 792 {
508e53e2 793 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 794 zlog_debug ("I/F MTU mismatch");
508e53e2 795 return;
718e3744 796 }
797
508e53e2 798 if (dbdesc->reserved1 || dbdesc->reserved2)
799 {
800 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 801 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
802 on->name);
508e53e2 803 dbdesc->reserved1 = 0;
804 dbdesc->reserved2 = 0;
805 }
718e3744 806
508e53e2 807 if (ntohl (oh->router_id) < ntohl (ospf6->router_id))
808 ospf6_dbdesc_recv_master (oh, on);
809 else if (ntohl (ospf6->router_id) < ntohl (oh->router_id))
810 ospf6_dbdesc_recv_slave (oh, on);
811 else
812 {
813 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 814 zlog_debug ("Can't decide which is master, ignore");
508e53e2 815 }
718e3744 816}
817
6ac29a51 818static void
508e53e2 819ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
820 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 821{
508e53e2 822 struct ospf6_neighbor *on;
823 char *p;
824 struct ospf6_lsreq_entry *e;
508e53e2 825 struct ospf6_lsdb *lsdb = NULL;
718e3744 826 struct ospf6_lsa *lsa;
718e3744 827
508e53e2 828 on = ospf6_neighbor_lookup (oh->router_id, oi);
829 if (on == NULL)
718e3744 830 {
508e53e2 831 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 832 zlog_debug ("Neighbor not found, ignore");
718e3744 833 return;
834 }
835
508e53e2 836 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
837 on->state != OSPF6_NEIGHBOR_LOADING &&
838 on->state != OSPF6_NEIGHBOR_FULL)
718e3744 839 {
508e53e2 840 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 841 zlog_debug ("Neighbor state less than Exchange, ignore");
718e3744 842 return;
843 }
844
508e53e2 845 /* Process each request */
846 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
847 p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
848 p += sizeof (struct ospf6_lsreq_entry))
718e3744 849 {
508e53e2 850 e = (struct ospf6_lsreq_entry *) p;
6452df09 851
852 switch (OSPF6_LSA_SCOPE (e->type))
853 {
854 case OSPF6_SCOPE_LINKLOCAL:
855 lsdb = on->ospf6_if->lsdb;
856 break;
857 case OSPF6_SCOPE_AREA:
858 lsdb = on->ospf6_if->area->lsdb;
859 break;
860 case OSPF6_SCOPE_AS:
861 lsdb = on->ospf6_if->area->ospf6->lsdb;
862 break;
863 default:
864 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 865 zlog_debug ("Ignoring LSA of reserved scope");
6452df09 866 continue;
867 break;
868 }
718e3744 869
508e53e2 870 /* Find database copy */
871 lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
872 if (lsa == NULL)
718e3744 873 {
508e53e2 874 char id[16], adv_router[16];
875 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
876 {
877 inet_ntop (AF_INET, &e->id, id, sizeof (id));
878 inet_ntop (AF_INET, &e->adv_router, adv_router,
879 sizeof (adv_router));
c6487d61 880 zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
881 ospf6_lstype_name (e->type), id, adv_router);
508e53e2 882 }
883 thread_add_event (master, bad_lsreq, on, 0);
718e3744 884 return;
885 }
886
508e53e2 887 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
718e3744 888 }
889
fa079666 890 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 891
508e53e2 892 /* schedule send lsupdate */
893 THREAD_OFF (on->thread_send_lsupdate);
894 on->thread_send_lsupdate =
895 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
718e3744 896}
897
abc7ef44
DO
898/* Verify, that the specified memory area contains exactly N valid IPv6
899 prefixes as specified by RFC5340, A.4.1. */
900static unsigned
901ospf6_prefixes_examin
902(
903 struct ospf6_prefix *current, /* start of buffer */
904 unsigned length,
905 const u_int32_t req_num_pfxs /* always compared with the actual number of prefixes */
906)
907{
908 u_char requested_pfx_bytes;
909 u_int32_t real_num_pfxs = 0;
910
911 while (length)
912 {
913 if (length < OSPF6_PREFIX_MIN_SIZE)
914 {
915 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
916 zlog_debug ("%s: undersized IPv6 prefix header", __func__);
917 return MSG_NG;
918 }
919 /* safe to look deeper */
920 if (current->prefix_length > IPV6_MAX_BITLEN)
921 {
922 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
923 zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length);
924 return MSG_NG;
925 }
926 /* covers both fixed- and variable-sized fields */
927 requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length);
928 if (requested_pfx_bytes > length)
929 {
930 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
931 zlog_debug ("%s: undersized IPv6 prefix", __func__);
932 return MSG_NG;
933 }
934 /* next prefix */
935 length -= requested_pfx_bytes;
936 current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes);
937 real_num_pfxs++;
938 }
939 if (real_num_pfxs != req_num_pfxs)
940 {
941 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
942 zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)",
943 __func__, req_num_pfxs, real_num_pfxs);
944 return MSG_NG;
945 }
946 return MSG_OK;
947}
948
949/* Verify an LSA to have a valid length and dispatch further (where
950 appropriate) to check if the contents, including nested IPv6 prefixes,
951 is properly sized/aligned within the LSA. Note that this function gets
952 LSA type in network byte order, uses in host byte order and passes to
953 ospf6_lstype_name() in network byte order again. */
954static unsigned
955ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly)
956{
957 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
958 struct ospf6_as_external_lsa *as_external_lsa;
959 struct ospf6_link_lsa *link_lsa;
960 unsigned exp_length;
961 u_int8_t ltindex;
962 u_int16_t lsatype;
963
964 /* In case an additional minimum length constraint is defined for current
965 LSA type, make sure that this constraint is met. */
966 lsatype = ntohs (lsah->type);
967 ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK;
968 if
969 (
970 ltindex < OSPF6_LSTYPE_SIZE &&
971 ospf6_lsa_minlen[ltindex] &&
972 lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE
973 )
974 {
975 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
976 zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen);
977 return MSG_NG;
978 }
979 switch (lsatype)
980 {
981 case OSPF6_LSTYPE_ROUTER:
982 /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed
983 by N>=0 interface descriptions. */
984 if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE)
985 {
986 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
987 zlog_debug ("%s: interface description alignment error", __func__);
988 return MSG_NG;
989 }
990 break;
991 case OSPF6_LSTYPE_NETWORK:
992 /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
993 followed by N>=0 attached router descriptions. */
994 if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE)
995 {
996 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
997 zlog_debug ("%s: router description alignment error", __func__);
998 return MSG_NG;
999 }
1000 break;
1001 case OSPF6_LSTYPE_INTER_PREFIX:
1002 /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes
1003 followed by 3-4 fields of a single IPv6 prefix. */
1004 if (headeronly)
1005 break;
1006 return ospf6_prefixes_examin
1007 (
1008 (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE),
1009 lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
1010 1
1011 );
1012 case OSPF6_LSTYPE_INTER_ROUTER:
1013 /* RFC5340 A.4.6, fixed-size LSA. */
1014 if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE)
1015 {
1016 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1017 zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen);
1018 return MSG_NG;
1019 }
1020 break;
1021 case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */
1022 case OSPF6_LSTYPE_TYPE_7:
1023 /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes
1024 followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields:
1025 16 bytes of forwarding address, 4 bytes of external route tag,
1026 4 bytes of referenced link state ID. */
1027 if (headeronly)
1028 break;
1029 as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1030 exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE;
1031 /* To find out if the last optional field (Referenced Link State ID) is
1032 assumed in this LSA, we need to access fixed fields of the IPv6
1033 prefix before ospf6_prefix_examin() confirms its sizing. */
1034 if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen)
1035 {
1036 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1037 zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
1038 return MSG_NG;
1039 }
1040 /* forwarding address */
1041 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
1042 exp_length += 16;
1043 /* external route tag */
1044 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
1045 exp_length += 4;
1046 /* referenced link state ID */
1047 if (as_external_lsa->prefix.u._prefix_referenced_lstype)
1048 exp_length += 4;
1049 /* All the fixed-size fields (mandatory and optional) must fit. I.e.,
1050 this check does not include any IPv6 prefix fields. */
1051 if (exp_length > lsalen)
1052 {
1053 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1054 zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
1055 return MSG_NG;
1056 }
1057 /* The last call completely covers the remainder (IPv6 prefix). */
1058 return ospf6_prefixes_examin
1059 (
1060 (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE),
1061 lsalen - exp_length,
1062 1
1063 );
1064 case OSPF6_LSTYPE_LINK:
1065 /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed
1066 by N>=0 IPv6 prefix blocks (with N declared beforehand). */
1067 if (headeronly)
1068 break;
1069 link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1070 return ospf6_prefixes_examin
1071 (
1072 (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE),
1073 lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE,
1074 ntohl (link_lsa->prefix_num) /* 32 bits */
1075 );
1076 case OSPF6_LSTYPE_INTRA_PREFIX:
1077 /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes
1078 followed by N>=0 IPv6 prefixes (with N declared beforehand). */
1079 if (headeronly)
1080 break;
1081 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1082 return ospf6_prefixes_examin
1083 (
1084 (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE),
1085 lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE,
1086 ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */
1087 );
1088 }
1089 /* No additional validation is possible for unknown LSA types, which are
1090 themselves valid in OPSFv3, hence the default decision is to accept. */
1091 return MSG_OK;
1092}
1093
1094/* Verify if the provided input buffer is a valid sequence of LSAs. This
1095 includes verification of LSA blocks length/alignment and dispatching
1096 of deeper-level checks. */
1097static unsigned
1098ospf6_lsaseq_examin
1099(
1100 struct ospf6_lsa_header *lsah, /* start of buffered data */
1101 size_t length,
1102 const u_char headeronly,
1103 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
1104 and treat the difference as an error. */
1105 const u_int32_t declared_num_lsas
1106)
1107{
1108 u_int32_t counted_lsas = 0;
1109
1110 while (length)
1111 {
1112 u_int16_t lsalen;
1113 if (length < OSPF6_LSA_HEADER_SIZE)
1114 {
1115 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
cba1fab2 1116 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
abc7ef44
DO
1117 __func__, length, counted_lsas);
1118 return MSG_NG;
1119 }
1120 /* save on ntohs() calls here and in the LSA validator */
1121 lsalen = OSPF6_LSA_SIZE (lsah);
1122 if (lsalen < OSPF6_LSA_HEADER_SIZE)
1123 {
1124 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1125 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
1126 __func__, counted_lsas, lsalen);
1127 return MSG_NG;
1128 }
1129 if (headeronly)
1130 {
1131 /* less checks here and in ospf6_lsa_examin() */
1132 if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1))
1133 {
1134 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1135 zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__,
1136 ospf6_lstype_name (lsah->type), counted_lsas);
1137 return MSG_NG;
1138 }
1139 lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1140 length -= OSPF6_LSA_HEADER_SIZE;
1141 }
1142 else
1143 {
1144 /* make sure the input buffer is deep enough before further checks */
1145 if (lsalen > length)
1146 {
1147 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
cba1fab2 1148 zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
abc7ef44
DO
1149 __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length);
1150 return MSG_NG;
1151 }
1152 if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0))
1153 {
1154 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1155 zlog_debug ("%s: anomaly in %s LSA #%u", __func__,
1156 ospf6_lstype_name (lsah->type), counted_lsas);
1157 return MSG_NG;
1158 }
1159 lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen);
1160 length -= lsalen;
1161 }
1162 counted_lsas++;
1163 }
1164
1165 if (declared_num_lsas && counted_lsas != declared_num_lsas)
1166 {
1167 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1168 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
1169 __func__, declared_num_lsas, counted_lsas);
1170 return MSG_NG;
1171 }
1172 return MSG_OK;
1173}
1174
1175/* Verify a complete OSPF packet for proper sizing/alignment. */
1176static unsigned
1177ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire)
1178{
1179 struct ospf6_lsupdate *lsupd;
1180 unsigned test;
1181
1182 /* length, 1st approximation */
1183 if (bytesonwire < OSPF6_HEADER_SIZE)
1184 {
1185 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1186 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
1187 return MSG_NG;
1188 }
1189 /* Now it is safe to access header fields. */
1190 if (bytesonwire != ntohs (oh->length))
1191 {
1192 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1193 zlog_debug ("%s: packet length error (%u real, %u declared)",
1194 __func__, bytesonwire, ntohs (oh->length));
1195 return MSG_NG;
1196 }
1197 /* version check */
1198 if (oh->version != OSPFV3_VERSION)
1199 {
1200 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1201 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
1202 return MSG_NG;
1203 }
1204 /* length, 2nd approximation */
1205 if
1206 (
1207 oh->type < OSPF6_MESSAGE_TYPE_ALL &&
1208 ospf6_packet_minlen[oh->type] &&
1209 bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]
1210 )
1211 {
1212 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1213 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
5031ed13 1214 bytesonwire, LOOKUP (ospf6_message_type_str, oh->type));
abc7ef44
DO
1215 return MSG_NG;
1216 }
1217 /* type-specific deeper validation */
1218 switch (oh->type)
1219 {
1220 case OSPF6_MESSAGE_TYPE_HELLO:
1221 /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed
1222 by N>=0 router-IDs. */
1223 if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4)
1224 return MSG_OK;
1225 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1226 zlog_debug ("%s: alignment error in %s packet",
5031ed13 1227 __func__, LOOKUP (ospf6_message_type_str, oh->type));
abc7ef44
DO
1228 return MSG_NG;
1229 case OSPF6_MESSAGE_TYPE_DBDESC:
1230 /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed
1231 by N>=0 header-only LSAs. */
1232 test = ospf6_lsaseq_examin
1233 (
1234 (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE),
1235 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE,
1236 1,
1237 0
1238 );
1239 break;
1240 case OSPF6_MESSAGE_TYPE_LSREQ:
1241 /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
1242 if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE)
1243 return MSG_OK;
1244 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1245 zlog_debug ("%s: alignment error in %s packet",
5031ed13 1246 __func__, LOOKUP (ospf6_message_type_str, oh->type));
abc7ef44
DO
1247 return MSG_NG;
1248 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1249 /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed
1250 by N>=0 full LSAs (with N declared beforehand). */
1251 lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE);
1252 test = ospf6_lsaseq_examin
1253 (
1254 (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE),
1255 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE,
1256 0,
1257 ntohl (lsupd->lsa_number) /* 32 bits */
1258 );
1259 break;
1260 case OSPF6_MESSAGE_TYPE_LSACK:
1261 /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1262 test = ospf6_lsaseq_examin
1263 (
1264 (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE),
1265 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE,
1266 1,
1267 0
1268 );
1269 break;
1270 default:
1271 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1272 zlog_debug ("%s: invalid (%u) message type", __func__, oh->type);
1273 return MSG_NG;
1274 }
1275 if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
5031ed13 1276 zlog_debug ("%s: anomaly in %s packet", __func__, LOOKUP (ospf6_message_type_str, oh->type));
abc7ef44
DO
1277 return test;
1278}
1279
1280/* Verify particular fields of otherwise correct received OSPF packet to
1281 meet the requirements of RFC. */
1282static int
1283ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire)
1284{
1285 char buf[2][INET_ADDRSTRLEN];
1286
1287 if (MSG_OK != ospf6_packet_examin (oh, bytesonwire))
1288 return MSG_NG;
1289
1290 /* Area-ID check */
1291 if (oh->area_id != oi->area->area_id)
1292 {
1293 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1294 {
8551e6da 1295 if (oh->area_id == OSPF_AREA_BACKBONE)
abc7ef44
DO
1296 zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__);
1297 else
1298 zlog_debug
1299 (
1300 "%s: Area-ID mismatch (my %s, rcvd %s)", __func__,
1301 inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN),
1302 inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN)
1303 );
1304 }
1305 return MSG_NG;
1306 }
1307
1308 /* Instance-ID check */
1309 if (oh->instance_id != oi->instance_id)
1310 {
1311 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1312 zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id);
1313 return MSG_NG;
1314 }
1315
1316 /* Router-ID check */
1317 if (oh->router_id == oi->area->ospf6->router_id)
1318 {
1319 zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN));
1320 return MSG_NG;
1321 }
1322 return MSG_OK;
1323}
1324
6ac29a51 1325static void
508e53e2 1326ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
1327 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 1328{
508e53e2 1329 struct ospf6_neighbor *on;
718e3744 1330 struct ospf6_lsupdate *lsupdate;
508e53e2 1331 char *p;
718e3744 1332
508e53e2 1333 on = ospf6_neighbor_lookup (oh->router_id, oi);
1334 if (on == NULL)
718e3744 1335 {
508e53e2 1336 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1337 zlog_debug ("Neighbor not found, ignore");
718e3744 1338 return;
1339 }
1340
508e53e2 1341 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1342 on->state != OSPF6_NEIGHBOR_LOADING &&
1343 on->state != OSPF6_NEIGHBOR_FULL)
718e3744 1344 {
508e53e2 1345 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1346 zlog_debug ("Neighbor state less than Exchange, ignore");
718e3744 1347 return;
1348 }
1349
508e53e2 1350 lsupdate = (struct ospf6_lsupdate *)
1351 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1352
508e53e2 1353 /* Process LSAs */
1354 for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1355 p < OSPF6_MESSAGE_END (oh) &&
1356 p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
1357 p += OSPF6_LSA_SIZE (p))
1358 {
6452df09 1359 ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
508e53e2 1360 }
1361
fa079666 1362 assert (p == OSPF6_MESSAGE_END (oh));
718e3744 1363
508e53e2 1364}
1365
6ac29a51 1366static void
508e53e2 1367ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
1368 struct ospf6_interface *oi, struct ospf6_header *oh)
1369{
1370 struct ospf6_neighbor *on;
1371 char *p;
1372 struct ospf6_lsa *his, *mine;
1373 struct ospf6_lsdb *lsdb = NULL;
1374
1375 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
508e53e2 1376
1377 on = ospf6_neighbor_lookup (oh->router_id, oi);
1378 if (on == NULL)
1379 {
1380 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1381 zlog_debug ("Neighbor not found, ignore");
508e53e2 1382 return;
1383 }
1384
508e53e2 1385 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1386 on->state != OSPF6_NEIGHBOR_LOADING &&
1387 on->state != OSPF6_NEIGHBOR_FULL)
718e3744 1388 {
508e53e2 1389 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1390 zlog_debug ("Neighbor state less than Exchange, ignore");
508e53e2 1391 return;
718e3744 1392 }
1393
508e53e2 1394 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
1395 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
1396 p += sizeof (struct ospf6_lsa_header))
1397 {
1398 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
508e53e2 1399
6452df09 1400 switch (OSPF6_LSA_SCOPE (his->header->type))
1401 {
1402 case OSPF6_SCOPE_LINKLOCAL:
1403 lsdb = on->ospf6_if->lsdb;
1404 break;
1405 case OSPF6_SCOPE_AREA:
1406 lsdb = on->ospf6_if->area->lsdb;
1407 break;
1408 case OSPF6_SCOPE_AS:
1409 lsdb = on->ospf6_if->area->ospf6->lsdb;
1410 break;
1411 case OSPF6_SCOPE_RESERVED:
1412 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1413 zlog_debug ("Ignoring LSA of reserved scope");
6452df09 1414 ospf6_lsa_delete (his);
1415 continue;
1416 break;
1417 }
1418
1419 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1420 zlog_debug ("%s acknowledged by %s", his->name, on->name);
508e53e2 1421
1422 /* Find database copy */
1423 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1424 his->header->adv_router, lsdb);
1425 if (mine == NULL)
1426 {
1427 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1428 zlog_debug ("No database copy");
508e53e2 1429 ospf6_lsa_delete (his);
1430 continue;
1431 }
1432
1433 /* Check if the LSA is on his retrans-list */
1434 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1435 his->header->adv_router, on->retrans_list);
1436 if (mine == NULL)
1437 {
1438 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1439 zlog_debug ("Not on %s's retrans-list", on->name);
508e53e2 1440 ospf6_lsa_delete (his);
1441 continue;
1442 }
1443
1444 if (ospf6_lsa_compare (his, mine) != 0)
1445 {
1446 /* Log this questionable acknowledgement,
1447 and examine the next one. */
1448 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1449 zlog_debug ("Questionable acknowledgement");
508e53e2 1450 ospf6_lsa_delete (his);
1451 continue;
1452 }
1453
6452df09 1454 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
c6487d61 1455 zlog_debug ("Acknowledged, remove from %s's retrans-list",
1456 on->name);
508e53e2 1457
932bf197 1458 ospf6_decrement_retrans_count (mine);
508e53e2 1459 if (OSPF6_LSA_IS_MAXAGE (mine))
1460 ospf6_maxage_remove (on->ospf6_if->area->ospf6);
cf1ce250 1461 ospf6_lsdb_remove (mine, on->retrans_list);
508e53e2 1462 ospf6_lsa_delete (his);
1463 }
1464
fa079666 1465 assert (p == OSPF6_MESSAGE_END (oh));
508e53e2 1466}
1467
6ac29a51
PJ
1468static u_char *recvbuf = NULL;
1469static u_char *sendbuf = NULL;
1470static unsigned int iobuflen = 0;
3b4cd3a9 1471
1472int
0c083ee9 1473ospf6_iobuf_size (unsigned int size)
3b4cd3a9 1474{
6ac29a51 1475 u_char *recvnew, *sendnew;
3b4cd3a9 1476
1477 if (size <= iobuflen)
1478 return iobuflen;
1479
1480 recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1481 sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1482 if (recvnew == NULL || sendnew == NULL)
1483 {
b596c71e 1484 if (recvnew)
1485 XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
1486 if (sendnew)
1487 XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
c6487d61 1488 zlog_debug ("Could not allocate I/O buffer of size %d.", size);
3b4cd3a9 1489 return iobuflen;
1490 }
1491
1492 if (recvbuf)
1493 XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1494 if (sendbuf)
1495 XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1496 recvbuf = recvnew;
1497 sendbuf = sendnew;
1498 iobuflen = size;
1499
1500 return iobuflen;
1501}
508e53e2 1502
ae2254aa
TG
1503void
1504ospf6_message_terminate (void)
1505{
1506 if (recvbuf)
1507 {
1508 XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1509 recvbuf = NULL;
1510 }
1511
1512 if (sendbuf)
1513 {
1514 XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1515 sendbuf = NULL;
1516 }
1517
1518 iobuflen = 0;
1519}
1520
508e53e2 1521int
1522ospf6_receive (struct thread *thread)
1523{
0c083ee9 1524 int sockfd;
1525 unsigned int len;
508e53e2 1526 char srcname[64], dstname[64];
1527 struct in6_addr src, dst;
b892f1dd 1528 ifindex_t ifindex;
508e53e2 1529 struct iovec iovector[2];
1530 struct ospf6_interface *oi;
1531 struct ospf6_header *oh;
1532
1533 /* add next read thread */
1534 sockfd = THREAD_FD (thread);
1535 thread_add_read (master, ospf6_receive, NULL, sockfd);
1536
1537 /* initialize */
cf1ce250
PJ
1538 memset (&src, 0, sizeof (src));
1539 memset (&dst, 0, sizeof (dst));
1540 ifindex = 0;
3b4cd3a9 1541 memset (recvbuf, 0, iobuflen);
508e53e2 1542 iovector[0].iov_base = recvbuf;
3b4cd3a9 1543 iovector[0].iov_len = iobuflen;
508e53e2 1544 iovector[1].iov_base = NULL;
1545 iovector[1].iov_len = 0;
1546
1547 /* receive message */
1548 len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
3b4cd3a9 1549 if (len > iobuflen)
508e53e2 1550 {
1551 zlog_err ("Excess message read");
1552 return 0;
1553 }
508e53e2 1554
1555 oi = ospf6_interface_lookup_by_ifindex (ifindex);
d9628728 1556 if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
508e53e2 1557 {
c6487d61 1558 zlog_debug ("Message received on disabled interface");
508e53e2 1559 return 0;
1560 }
abc7ef44
DO
1561 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1562 {
1563 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1564 zlog_debug ("%s: Ignore message on passive interface %s",
1565 __func__, oi->interface->name);
1566 return 0;
1567 }
508e53e2 1568
1569 oh = (struct ospf6_header *) recvbuf;
abc7ef44
DO
1570 if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK)
1571 return 0;
1572
1573 /* Being here means, that no sizing/alignment issues were detected in
1574 the input packet. This renders the additional checks performed below
1575 and also in the type-specific dispatching functions a dead code,
1576 which can be dismissed in a cleanup-focused review round later. */
508e53e2 1577
1578 /* Log */
1579 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1580 {
1581 inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
1582 inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
c6487d61 1583 zlog_debug ("%s received on %s",
5031ed13 1584 LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name);
c6487d61 1585 zlog_debug (" src: %s", srcname);
1586 zlog_debug (" dst: %s", dstname);
508e53e2 1587
1588 switch (oh->type)
1589 {
1590 case OSPF6_MESSAGE_TYPE_HELLO:
1591 ospf6_hello_print (oh);
1592 break;
1593 case OSPF6_MESSAGE_TYPE_DBDESC:
1594 ospf6_dbdesc_print (oh);
1595 break;
1596 case OSPF6_MESSAGE_TYPE_LSREQ:
1597 ospf6_lsreq_print (oh);
1598 break;
1599 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1600 ospf6_lsupdate_print (oh);
1601 break;
1602 case OSPF6_MESSAGE_TYPE_LSACK:
1603 ospf6_lsack_print (oh);
1604 break;
1605 default:
fa079666 1606 assert (0);
508e53e2 1607 }
508e53e2 1608 }
1609
1610 switch (oh->type)
1611 {
1612 case OSPF6_MESSAGE_TYPE_HELLO:
1613 ospf6_hello_recv (&src, &dst, oi, oh);
1614 break;
1615
1616 case OSPF6_MESSAGE_TYPE_DBDESC:
1617 ospf6_dbdesc_recv (&src, &dst, oi, oh);
1618 break;
1619
1620 case OSPF6_MESSAGE_TYPE_LSREQ:
1621 ospf6_lsreq_recv (&src, &dst, oi, oh);
1622 break;
1623
1624 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1625 ospf6_lsupdate_recv (&src, &dst, oi, oh);
1626 break;
1627
1628 case OSPF6_MESSAGE_TYPE_LSACK:
1629 ospf6_lsack_recv (&src, &dst, oi, oh);
1630 break;
1631
1632 default:
fa079666 1633 assert (0);
508e53e2 1634 }
718e3744 1635
508e53e2 1636 return 0;
718e3744 1637}
1638
6ac29a51 1639static void
508e53e2 1640ospf6_send (struct in6_addr *src, struct in6_addr *dst,
1641 struct ospf6_interface *oi, struct ospf6_header *oh)
718e3744 1642{
b07c4cb3 1643 unsigned int len;
508e53e2 1644 char srcname[64], dstname[64];
1645 struct iovec iovector[2];
718e3744 1646
508e53e2 1647 /* initialize */
1648 iovector[0].iov_base = (caddr_t) oh;
1649 iovector[0].iov_len = ntohs (oh->length);
1650 iovector[1].iov_base = NULL;
1651 iovector[1].iov_len = 0;
1652
1653 /* fill OSPF header */
1654 oh->version = OSPFV3_VERSION;
1655 /* message type must be set before */
1656 /* message length must be set before */
1657 oh->router_id = oi->area->ospf6->router_id;
1658 oh->area_id = oi->area->area_id;
1659 /* checksum is calculated by kernel */
1660 oh->instance_id = oi->instance_id;
1661 oh->reserved = 0;
718e3744 1662
508e53e2 1663 /* Log */
1664 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
718e3744 1665 {
508e53e2 1666 inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
1667 if (src)
1668 inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
718e3744 1669 else
508e53e2 1670 memset (srcname, 0, sizeof (srcname));
c6487d61 1671 zlog_debug ("%s send on %s",
5031ed13 1672 LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name);
c6487d61 1673 zlog_debug (" src: %s", srcname);
1674 zlog_debug (" dst: %s", dstname);
508e53e2 1675
1676 switch (oh->type)
718e3744 1677 {
508e53e2 1678 case OSPF6_MESSAGE_TYPE_HELLO:
1679 ospf6_hello_print (oh);
1680 break;
1681 case OSPF6_MESSAGE_TYPE_DBDESC:
1682 ospf6_dbdesc_print (oh);
1683 break;
1684 case OSPF6_MESSAGE_TYPE_LSREQ:
1685 ospf6_lsreq_print (oh);
1686 break;
1687 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1688 ospf6_lsupdate_print (oh);
1689 break;
1690 case OSPF6_MESSAGE_TYPE_LSACK:
1691 ospf6_lsack_print (oh);
1692 break;
1693 default:
c6487d61 1694 zlog_debug ("Unknown message");
508e53e2 1695 assert (0);
1696 break;
718e3744 1697 }
718e3744 1698 }
1699
508e53e2 1700 /* send message */
1701 len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
1702 if (len != ntohs (oh->length))
1703 zlog_err ("Could not send entire message");
718e3744 1704}
1705
cba1fab2 1706static uint32_t
681b84e8
DT
1707ospf6_packet_max(struct ospf6_interface *oi)
1708{
cba1fab2
VT
1709 assert (oi->ifmtu > sizeof (struct ip6_hdr));
1710 return oi->ifmtu - (sizeof (struct ip6_hdr));
681b84e8
DT
1711}
1712
508e53e2 1713int
1714ospf6_hello_send (struct thread *thread)
718e3744 1715{
508e53e2 1716 struct ospf6_interface *oi;
1717 struct ospf6_header *oh;
1718 struct ospf6_hello *hello;
0c083ee9 1719 u_char *p;
1eb8ef25 1720 struct listnode *node, *nnode;
508e53e2 1721 struct ospf6_neighbor *on;
718e3744 1722
508e53e2 1723 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1724 oi->thread_send_hello = (struct thread *) NULL;
718e3744 1725
508e53e2 1726 if (oi->state <= OSPF6_INTERFACE_DOWN)
718e3744 1727 {
508e53e2 1728 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
c6487d61 1729 zlog_debug ("Unable to send Hello on down interface %s",
508e53e2 1730 oi->interface->name);
1731 return 0;
718e3744 1732 }
1733
1db65fad
IF
1734 if (iobuflen == 0)
1735 {
1736 zlog_debug ("Unable to send Hello on interface %s iobuflen is 0",
1737 oi->interface->name);
1738 return 0;
1739 }
1740
508e53e2 1741 /* set next thread */
1742 oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
1743 oi, oi->hello_interval);
718e3744 1744
3b4cd3a9 1745 memset (sendbuf, 0, iobuflen);
508e53e2 1746 oh = (struct ospf6_header *) sendbuf;
1747 hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 1748
508e53e2 1749 hello->interface_id = htonl (oi->interface->ifindex);
1750 hello->priority = oi->priority;
1751 hello->options[0] = oi->area->options[0];
1752 hello->options[1] = oi->area->options[1];
1753 hello->options[2] = oi->area->options[2];
1754 hello->hello_interval = htons (oi->hello_interval);
1755 hello->dead_interval = htons (oi->dead_interval);
1756 hello->drouter = oi->drouter;
1757 hello->bdrouter = oi->bdrouter;
718e3744 1758
6ac29a51 1759 p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello));
718e3744 1760
1eb8ef25 1761 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
718e3744 1762 {
508e53e2 1763 if (on->state < OSPF6_NEIGHBOR_INIT)
1764 continue;
1765
681b84e8 1766 if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi))
508e53e2 1767 {
1768 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
c6487d61 1769 zlog_debug ("sending Hello message: exceeds I/F MTU");
508e53e2 1770 break;
1771 }
718e3744 1772
508e53e2 1773 memcpy (p, &on->router_id, sizeof (u_int32_t));
1774 p += sizeof (u_int32_t);
1775 }
718e3744 1776
508e53e2 1777 oh->type = OSPF6_MESSAGE_TYPE_HELLO;
1778 oh->length = htons (p - sendbuf);
718e3744 1779
508e53e2 1780 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1781 return 0;
718e3744 1782}
1783
1784int
508e53e2 1785ospf6_dbdesc_send (struct thread *thread)
718e3744 1786{
508e53e2 1787 struct ospf6_neighbor *on;
1788 struct ospf6_header *oh;
1789 struct ospf6_dbdesc *dbdesc;
0c083ee9 1790 u_char *p;
508e53e2 1791 struct ospf6_lsa *lsa;
c5926a92 1792 struct in6_addr *dst;
718e3744 1793
508e53e2 1794 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1795 on->thread_send_dbdesc = (struct thread *) NULL;
718e3744 1796
508e53e2 1797 if (on->state < OSPF6_NEIGHBOR_EXSTART)
1798 {
1799 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
c6487d61 1800 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1801 on->name, ospf6_neighbor_state_str[on->state]);
508e53e2 1802 return 0;
1803 }
718e3744 1804
508e53e2 1805 /* set next thread if master */
1806 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
1807 on->thread_send_dbdesc =
1808 thread_add_timer (master, ospf6_dbdesc_send, on,
1809 on->ospf6_if->rxmt_interval);
718e3744 1810
3b4cd3a9 1811 memset (sendbuf, 0, iobuflen);
508e53e2 1812 oh = (struct ospf6_header *) sendbuf;
1813 dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
1814 sizeof (struct ospf6_header));
718e3744 1815
508e53e2 1816 /* if this is initial one, initialize sequence number for DbDesc */
7a10a359
DD
1817 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) &&
1818 (on->dbdesc_seqnum == 0))
508e53e2 1819 {
1820 struct timeval tv;
86f72dcb 1821 if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
508e53e2 1822 tv.tv_sec = 1;
1823 on->dbdesc_seqnum = tv.tv_sec;
1824 }
1825
1826 dbdesc->options[0] = on->ospf6_if->area->options[0];
1827 dbdesc->options[1] = on->ospf6_if->area->options[1];
1828 dbdesc->options[2] = on->ospf6_if->area->options[2];
1829 dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
1830 dbdesc->bits = on->dbdesc_bits;
1831 dbdesc->seqnum = htonl (on->dbdesc_seqnum);
718e3744 1832
508e53e2 1833 /* if this is not initial one, set LSA headers in dbdesc */
6ac29a51 1834 p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
508e53e2 1835 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
718e3744 1836 {
508e53e2 1837 for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
1838 lsa = ospf6_lsdb_next (lsa))
1839 {
1840 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1841
1842 /* MTU check */
1843 if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
681b84e8 1844 ospf6_packet_max(on->ospf6_if))
508e53e2 1845 {
a765eb93 1846 ospf6_lsdb_lsa_unlock (lsa);
508e53e2 1847 break;
1848 }
1849 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1850 p += sizeof (struct ospf6_lsa_header);
1851 }
718e3744 1852 }
1853
508e53e2 1854 oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
1855 oh->length = htons (p - sendbuf);
718e3744 1856
c5926a92
DD
1857
1858 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
1859 dst = &allspfrouters6;
1860 else
1861 dst = &on->linklocal_addr;
1862
1863 ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh);
1864
718e3744 1865 return 0;
1866}
1867
718e3744 1868int
508e53e2 1869ospf6_dbdesc_send_newone (struct thread *thread)
718e3744 1870{
508e53e2 1871 struct ospf6_neighbor *on;
1872 struct ospf6_lsa *lsa;
1873 unsigned int size = 0;
1874
1875 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
508e53e2 1876 ospf6_lsdb_remove_all (on->dbdesc_list);
1877
1878 /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1879 so that ospf6_send_dbdesc () can send those LSAs */
1880 size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
1881 for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
1882 lsa = ospf6_lsdb_next (lsa))
718e3744 1883 {
681b84e8 1884 if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
718e3744 1885 {
a765eb93 1886 ospf6_lsdb_lsa_unlock (lsa);
508e53e2 1887 break;
718e3744 1888 }
508e53e2 1889
508e53e2 1890 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
1891 ospf6_lsdb_remove (lsa, on->summary_list);
1892 size += sizeof (struct ospf6_lsa_header);
718e3744 1893 }
1894
508e53e2 1895 if (on->summary_list->count == 0)
1896 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
718e3744 1897
508e53e2 1898 /* If slave, More bit check must be done here */
1899 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
1900 ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
1901 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
1902 thread_add_event (master, exchange_done, on, 0);
718e3744 1903
508e53e2 1904 thread_execute (master, ospf6_dbdesc_send, on, 0);
1905 return 0;
1906}
718e3744 1907
508e53e2 1908int
1909ospf6_lsreq_send (struct thread *thread)
1910{
1911 struct ospf6_neighbor *on;
1912 struct ospf6_header *oh;
1913 struct ospf6_lsreq_entry *e;
0c083ee9 1914 u_char *p;
eb82e9ee 1915 struct ospf6_lsa *lsa, *last_req;
718e3744 1916
508e53e2 1917 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1918 on->thread_send_lsreq = (struct thread *) NULL;
1919
1920 /* LSReq will be sent only in ExStart or Loading */
1921 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1922 on->state != OSPF6_NEIGHBOR_LOADING)
718e3744 1923 {
508e53e2 1924 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
c6487d61 1925 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1926 on->name, ospf6_neighbor_state_str[on->state]);
508e53e2 1927 return 0;
718e3744 1928 }
1929
508e53e2 1930 /* schedule loading_done if request list is empty */
1931 if (on->request_list->count == 0)
1932 {
1933 thread_add_event (master, loading_done, on, 0);
718e3744 1934 return 0;
1935 }
1936
3b4cd3a9 1937 memset (sendbuf, 0, iobuflen);
508e53e2 1938 oh = (struct ospf6_header *) sendbuf;
eb82e9ee 1939 last_req = NULL;
718e3744 1940
508e53e2 1941 /* set Request entries in lsreq */
6ac29a51 1942 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
508e53e2 1943 for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1944 lsa = ospf6_lsdb_next (lsa))
718e3744 1945 {
508e53e2 1946 /* MTU check */
681b84e8 1947 if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if))
718e3744 1948 {
a765eb93 1949 ospf6_lsdb_lsa_unlock (lsa);
718e3744 1950 break;
1951 }
1952
508e53e2 1953 e = (struct ospf6_lsreq_entry *) p;
1954 e->type = lsa->header->type;
1955 e->id = lsa->header->id;
1956 e->adv_router = lsa->header->adv_router;
1957 p += sizeof (struct ospf6_lsreq_entry);
eb82e9ee
DD
1958 last_req = lsa;
1959 }
1960
1961 if (last_req != NULL)
1962 {
1963 if (on->last_ls_req != NULL)
1964 {
1965 ospf6_lsa_unlock (on->last_ls_req);
1966 }
1967 ospf6_lsa_lock (last_req);
1968 on->last_ls_req = last_req;
718e3744 1969 }
718e3744 1970
508e53e2 1971 oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
1972 oh->length = htons (p - sendbuf);
718e3744 1973
c5926a92
DD
1974 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
1975 ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
508e53e2 1976 on->ospf6_if, oh);
c5926a92
DD
1977 else
1978 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1979 on->ospf6_if, oh);
1980
eb82e9ee
DD
1981 /* set next thread */
1982 if (on->request_list->count != 0)
1983 {
1984 on->thread_send_lsreq =
1985 thread_add_timer (master, ospf6_lsreq_send, on,
1986 on->ospf6_if->rxmt_interval);
1987 }
1988
718e3744 1989 return 0;
1990}
1991
718e3744 1992int
508e53e2 1993ospf6_lsupdate_send_neighbor (struct thread *thread)
718e3744 1994{
508e53e2 1995 struct ospf6_neighbor *on;
1996 struct ospf6_header *oh;
1997 struct ospf6_lsupdate *lsupdate;
0c083ee9 1998 u_char *p;
c5926a92 1999 int lsa_cnt;
718e3744 2000 struct ospf6_lsa *lsa;
718e3744 2001
508e53e2 2002 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
2003 on->thread_send_lsupdate = (struct thread *) NULL;
718e3744 2004
6452df09 2005 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 2006 zlog_debug ("LSUpdate to neighbor %s", on->name);
6452df09 2007
508e53e2 2008 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
2009 {
2010 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 2011 zlog_debug ("Quit to send (neighbor state %s)",
2012 ospf6_neighbor_state_str[on->state]);
508e53e2 2013 return 0;
2014 }
718e3744 2015
3b4cd3a9 2016 memset (sendbuf, 0, iobuflen);
508e53e2 2017 oh = (struct ospf6_header *) sendbuf;
2018 lsupdate = (struct ospf6_lsupdate *)
2019 ((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 2020
6ac29a51 2021 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
c5926a92 2022 lsa_cnt = 0;
718e3744 2023
508e53e2 2024 /* lsupdate_list lists those LSA which doesn't need to be
2025 retransmitted. remove those from the list */
2026 for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
2027 lsa = ospf6_lsdb_next (lsa))
718e3744 2028 {
508e53e2 2029 /* MTU check */
0c083ee9 2030 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
c5926a92
DD
2031 > ospf6_packet_max(on->ospf6_if))
2032 {
a765eb93 2033 ospf6_lsdb_lsa_unlock (lsa);
c5926a92
DD
2034 break;
2035 }
718e3744 2036
508e53e2 2037 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2038 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2039 p += OSPF6_LSA_SIZE (lsa->header);
c5926a92 2040 lsa_cnt++;
718e3744 2041
508e53e2 2042 assert (lsa->lock == 2);
2043 ospf6_lsdb_remove (lsa, on->lsupdate_list);
2044 }
2045
c5926a92
DD
2046 if (lsa_cnt)
2047 {
2048 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2049 oh->length = htons (p - sendbuf);
2050 lsupdate->lsa_number = htonl (lsa_cnt);
2051
2052 if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2053 (on->ospf6_if->state == OSPF6_INTERFACE_DR) ||
2054 (on->ospf6_if->state == OSPF6_INTERFACE_BDR))
2055 ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
2056 on->ospf6_if, oh);
2057 else
2058 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2059 on->ospf6_if, oh);
2060 }
2061
2062 /* The addresses used for retransmissions are different from those sent the
2063 first time and so we need to separate them here.
2064 */
2065 memset (sendbuf, 0, iobuflen);
2066 oh = (struct ospf6_header *) sendbuf;
2067 lsupdate = (struct ospf6_lsupdate *)
2068 ((caddr_t) oh + sizeof (struct ospf6_header));
2069 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2070 lsa_cnt = 0;
2071
508e53e2 2072 for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
2073 lsa = ospf6_lsdb_next (lsa))
2074 {
2075 /* MTU check */
0c083ee9 2076 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
c5926a92
DD
2077 > ospf6_packet_max(on->ospf6_if))
2078 {
a765eb93 2079 ospf6_lsdb_lsa_unlock (lsa);
c5926a92
DD
2080 break;
2081 }
508e53e2 2082
508e53e2 2083 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2084 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2085 p += OSPF6_LSA_SIZE (lsa->header);
c5926a92 2086 lsa_cnt++;
718e3744 2087 }
2088
c5926a92 2089 if (lsa_cnt)
508e53e2 2090 {
c5926a92
DD
2091 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2092 oh->length = htons (p - sendbuf);
2093 lsupdate->lsa_number = htonl (lsa_cnt);
2094
2095 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2096 ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
2097 on->ospf6_if, oh);
508e53e2 2098 else
c5926a92
DD
2099 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2100 on->ospf6_if, oh);
508e53e2 2101 }
718e3744 2102
c5926a92
DD
2103 if (on->lsupdate_list->count != 0)
2104 on->thread_send_lsupdate =
2105 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
2106 else if (on->retrans_list->count != 0)
2107 on->thread_send_lsupdate =
2108 thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
2109 on->ospf6_if->rxmt_interval);
718e3744 2110 return 0;
2111}
2112
2113int
508e53e2 2114ospf6_lsupdate_send_interface (struct thread *thread)
718e3744 2115{
508e53e2 2116 struct ospf6_interface *oi;
2117 struct ospf6_header *oh;
2118 struct ospf6_lsupdate *lsupdate;
0c083ee9 2119 u_char *p;
c5926a92 2120 int lsa_cnt;
718e3744 2121 struct ospf6_lsa *lsa;
718e3744 2122
508e53e2 2123 oi = (struct ospf6_interface *) THREAD_ARG (thread);
2124 oi->thread_send_lsupdate = (struct thread *) NULL;
718e3744 2125
508e53e2 2126 if (oi->state <= OSPF6_INTERFACE_WAITING)
718e3744 2127 {
508e53e2 2128 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
c6487d61 2129 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
2130 oi->interface->name, ospf6_interface_state_str[oi->state]);
508e53e2 2131 return 0;
2132 }
718e3744 2133
508e53e2 2134 /* if we have nothing to send, return */
2135 if (oi->lsupdate_list->count == 0)
2136 return 0;
718e3744 2137
3b4cd3a9 2138 memset (sendbuf, 0, iobuflen);
508e53e2 2139 oh = (struct ospf6_header *) sendbuf;
2140 lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
c5926a92 2141 sizeof (struct ospf6_header));
718e3744 2142
6ac29a51 2143 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
c5926a92 2144 lsa_cnt = 0;
718e3744 2145
508e53e2 2146 for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
2147 lsa = ospf6_lsdb_next (lsa))
2148 {
2149 /* MTU check */
0c083ee9 2150 if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
c5926a92
DD
2151 > ospf6_packet_max(oi))
2152 {
a765eb93 2153 ospf6_lsdb_lsa_unlock (lsa);
c5926a92
DD
2154 break;
2155 }
718e3744 2156
508e53e2 2157 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
2158 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2159 p += OSPF6_LSA_SIZE (lsa->header);
c5926a92 2160 lsa_cnt++;
718e3744 2161
508e53e2 2162 assert (lsa->lock == 2);
2163 ospf6_lsdb_remove (lsa, oi->lsupdate_list);
2164 }
718e3744 2165
c5926a92
DD
2166 if (lsa_cnt)
2167 {
2168 lsupdate->lsa_number = htonl (lsa_cnt);
718e3744 2169
c5926a92
DD
2170 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2171 oh->length = htons (p - sendbuf);
718e3744 2172
c5926a92
DD
2173 if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2174 (oi->state == OSPF6_INTERFACE_DR) ||
2175 (oi->state == OSPF6_INTERFACE_BDR))
2176 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
2177 else
2178 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
2179
2180 }
718e3744 2181
508e53e2 2182 if (oi->lsupdate_list->count > 0)
2183 {
2184 oi->thread_send_lsupdate =
2185 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
2186 }
718e3744 2187
718e3744 2188 return 0;
2189}
2190
2191int
508e53e2 2192ospf6_lsack_send_neighbor (struct thread *thread)
718e3744 2193{
508e53e2 2194 struct ospf6_neighbor *on;
2195 struct ospf6_header *oh;
0c083ee9 2196 u_char *p;
718e3744 2197 struct ospf6_lsa *lsa;
c5926a92 2198 int lsa_cnt = 0;
718e3744 2199
508e53e2 2200 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
2201 on->thread_send_lsack = (struct thread *) NULL;
718e3744 2202
508e53e2 2203 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
718e3744 2204 {
508e53e2 2205 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
c6487d61 2206 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
2207 on->name, ospf6_neighbor_state_str[on->state]);
718e3744 2208 return 0;
2209 }
2210
508e53e2 2211 /* if we have nothing to send, return */
2212 if (on->lsack_list->count == 0)
2213 return 0;
718e3744 2214
3b4cd3a9 2215 memset (sendbuf, 0, iobuflen);
508e53e2 2216 oh = (struct ospf6_header *) sendbuf;
718e3744 2217
6ac29a51 2218 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 2219
508e53e2 2220 for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
2221 lsa = ospf6_lsdb_next (lsa))
2222 {
2223 /* MTU check */
681b84e8 2224 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
c5926a92
DD
2225 {
2226 /* if we run out of packet size/space here,
2227 better to try again soon. */
2228 THREAD_OFF (on->thread_send_lsack);
2229 on->thread_send_lsack =
2230 thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
718e3744 2231
a765eb93 2232 ospf6_lsdb_lsa_unlock (lsa);
c5926a92
DD
2233 break;
2234 }
718e3744 2235
508e53e2 2236 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2237 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
2238 p += sizeof (struct ospf6_lsa_header);
718e3744 2239
508e53e2 2240 assert (lsa->lock == 2);
2241 ospf6_lsdb_remove (lsa, on->lsack_list);
c5926a92 2242 lsa_cnt++;
508e53e2 2243 }
718e3744 2244
c5926a92
DD
2245 if (lsa_cnt)
2246 {
2247 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2248 oh->length = htons (p - sendbuf);
2249
2250 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2251 on->ospf6_if, oh);
2252 }
2253
2254 if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
2255 {
2256 on->thread_send_lsack =
2257 thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
2258 }
718e3744 2259
2260 return 0;
2261}
2262
718e3744 2263int
508e53e2 2264ospf6_lsack_send_interface (struct thread *thread)
718e3744 2265{
508e53e2 2266 struct ospf6_interface *oi;
2267 struct ospf6_header *oh;
0c083ee9 2268 u_char *p;
718e3744 2269 struct ospf6_lsa *lsa;
c5926a92 2270 int lsa_cnt = 0;
718e3744 2271
508e53e2 2272 oi = (struct ospf6_interface *) THREAD_ARG (thread);
2273 oi->thread_send_lsack = (struct thread *) NULL;
718e3744 2274
508e53e2 2275 if (oi->state <= OSPF6_INTERFACE_WAITING)
2276 {
2277 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
c6487d61 2278 zlog_debug ("Quit to send LSAck to interface %s state %s",
2279 oi->interface->name, ospf6_interface_state_str[oi->state]);
508e53e2 2280 return 0;
2281 }
718e3744 2282
508e53e2 2283 /* if we have nothing to send, return */
2284 if (oi->lsack_list->count == 0)
2285 return 0;
718e3744 2286
3b4cd3a9 2287 memset (sendbuf, 0, iobuflen);
508e53e2 2288 oh = (struct ospf6_header *) sendbuf;
718e3744 2289
6ac29a51 2290 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
718e3744 2291
508e53e2 2292 for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
2293 lsa = ospf6_lsdb_next (lsa))
718e3744 2294 {
508e53e2 2295 /* MTU check */
681b84e8 2296 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
c5926a92
DD
2297 {
2298 /* if we run out of packet size/space here,
2299 better to try again soon. */
2300 THREAD_OFF (oi->thread_send_lsack);
2301 oi->thread_send_lsack =
2302 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
718e3744 2303
a765eb93 2304 ospf6_lsdb_lsa_unlock (lsa);
c5926a92
DD
2305 break;
2306 }
718e3744 2307
508e53e2 2308 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
2309 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
2310 p += sizeof (struct ospf6_lsa_header);
718e3744 2311
508e53e2 2312 assert (lsa->lock == 2);
2313 ospf6_lsdb_remove (lsa, oi->lsack_list);
c5926a92 2314 lsa_cnt++;
508e53e2 2315 }
718e3744 2316
c5926a92
DD
2317 if (lsa_cnt)
2318 {
2319 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2320 oh->length = htons (p - sendbuf);
718e3744 2321
c5926a92
DD
2322 if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2323 (oi->state == OSPF6_INTERFACE_DR) ||
2324 (oi->state == OSPF6_INTERFACE_BDR))
2325 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
2326 else
2327 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
2328 }
718e3744 2329
508e53e2 2330 if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
2331 {
2332 oi->thread_send_lsack =
2333 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
2334 }
718e3744 2335
718e3744 2336 return 0;
2337}
2338
6b0655a2 2339
508e53e2 2340/* Commands */
f412b39a
DW
2341/*
2342 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
2343 * "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2344 * DEBUG_STR
2345 * OSPF6_STR
2346 * "Debug OSPFv3 message\n"
2347 * "Debug Unknown message\n"
2348 * "Debug Hello message\n"
2349 * "Debug Database Description message\n"
2350 * "Debug Link State Request message\n"
2351 * "Debug Link State Update message\n"
2352 * "Debug Link State Acknowledgement message\n"
2353 * "Debug All message\n"
2354 * "Debug only sending message\n"
2355 * "Debug only receiving message\n"
2356 *
2357 *
2358 */
508e53e2 2359DEFUN (debug_ospf6_message,
2360 debug_ospf6_message_cmd,
6147e2c6 2361 "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all>",
508e53e2 2362 DEBUG_STR
2363 OSPF6_STR
2364 "Debug OSPFv3 message\n"
2365 "Debug Unknown message\n"
2366 "Debug Hello message\n"
2367 "Debug Database Description message\n"
2368 "Debug Link State Request message\n"
2369 "Debug Link State Update message\n"
2370 "Debug Link State Acknowledgement message\n"
2371 "Debug All message\n"
2372 )
718e3744 2373{
67656e9b 2374 /* CHECK ME argc referenced below */
51c26414 2375 int idx_packet = 3;
508e53e2 2376 unsigned char level = 0;
2377 int type = 0;
2378 int i;
718e3744 2379
508e53e2 2380 assert (argc > 0);
718e3744 2381
508e53e2 2382 /* check type */
51c26414 2383 if (! strncmp (argv[idx_packet]->arg, "u", 1))
508e53e2 2384 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
51c26414 2385 else if (! strncmp (argv[idx_packet]->arg, "h", 1))
508e53e2 2386 type = OSPF6_MESSAGE_TYPE_HELLO;
51c26414 2387 else if (! strncmp (argv[idx_packet]->arg, "d", 1))
508e53e2 2388 type = OSPF6_MESSAGE_TYPE_DBDESC;
51c26414 2389 else if (! strncmp (argv[idx_packet]->arg, "lsr", 3))
508e53e2 2390 type = OSPF6_MESSAGE_TYPE_LSREQ;
51c26414 2391 else if (! strncmp (argv[idx_packet]->arg, "lsu", 3))
508e53e2 2392 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
51c26414 2393 else if (! strncmp (argv[idx_packet]->arg, "lsa", 3))
508e53e2 2394 type = OSPF6_MESSAGE_TYPE_LSACK;
51c26414 2395 else if (! strncmp (argv[idx_packet]->arg, "a", 1))
508e53e2 2396 type = OSPF6_MESSAGE_TYPE_ALL;
2397
2398 if (argc == 1)
2399 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
cc9de1ba 2400 else if (! strncmp (argv[4]->arg, "s", 1))
508e53e2 2401 level = OSPF6_DEBUG_MESSAGE_SEND;
cc9de1ba 2402 else if (! strncmp (argv[4]->arg, "r", 1))
508e53e2 2403 level = OSPF6_DEBUG_MESSAGE_RECV;
2404
2405 if (type == OSPF6_MESSAGE_TYPE_ALL)
2406 {
2407 for (i = 0; i < 6; i++)
2408 OSPF6_DEBUG_MESSAGE_ON (i, level);
2409 }
2410 else
2411 OSPF6_DEBUG_MESSAGE_ON (type, level);
718e3744 2412
508e53e2 2413 return CMD_SUCCESS;
718e3744 2414}
2415
718e3744 2416
6b0655a2 2417
f412b39a
DW
2418/*
2419 * CHECK ME - The following ALIASes need to be implemented in this DEFUN
2420 * "no debug ospf6 message "
2421 * "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2422 * NO_STR
2423 * DEBUG_STR
2424 * OSPF6_STR
2425 * "Debug OSPFv3 message\n"
2426 * "Debug Unknown message\n"
2427 * "Debug Hello message\n"
2428 * "Debug Database Description message\n"
2429 * "Debug Link State Request message\n"
2430 * "Debug Link State Update message\n"
2431 * "Debug Link State Acknowledgement message\n"
2432 * "Debug All message\n"
2433 * "Debug only sending message\n"
2434 * "Debug only receiving message\n"
2435 *
2436 *
2437 */
508e53e2 2438DEFUN (no_debug_ospf6_message,
2439 no_debug_ospf6_message_cmd,
6147e2c6 2440 "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all>",
508e53e2 2441 NO_STR
2442 DEBUG_STR
2443 OSPF6_STR
2444 "Debug OSPFv3 message\n"
2445 "Debug Unknown message\n"
2446 "Debug Hello message\n"
2447 "Debug Database Description message\n"
2448 "Debug Link State Request message\n"
2449 "Debug Link State Update message\n"
2450 "Debug Link State Acknowledgement message\n"
2451 "Debug All message\n"
2452 )
2453{
67656e9b 2454 /* CHECK ME argc referenced below */
51c26414 2455 int idx_packet = 4;
508e53e2 2456 unsigned char level = 0;
2457 int type = 0;
2458 int i;
718e3744 2459
508e53e2 2460 assert (argc > 0);
718e3744 2461
508e53e2 2462 /* check type */
51c26414 2463 if (! strncmp (argv[idx_packet]->arg, "u", 1))
508e53e2 2464 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
51c26414 2465 else if (! strncmp (argv[idx_packet]->arg, "h", 1))
508e53e2 2466 type = OSPF6_MESSAGE_TYPE_HELLO;
51c26414 2467 else if (! strncmp (argv[idx_packet]->arg, "d", 1))
508e53e2 2468 type = OSPF6_MESSAGE_TYPE_DBDESC;
51c26414 2469 else if (! strncmp (argv[idx_packet]->arg, "lsr", 3))
508e53e2 2470 type = OSPF6_MESSAGE_TYPE_LSREQ;
51c26414 2471 else if (! strncmp (argv[idx_packet]->arg, "lsu", 3))
508e53e2 2472 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
51c26414 2473 else if (! strncmp (argv[idx_packet]->arg, "lsa", 3))
508e53e2 2474 type = OSPF6_MESSAGE_TYPE_LSACK;
51c26414 2475 else if (! strncmp (argv[idx_packet]->arg, "a", 1))
508e53e2 2476 type = OSPF6_MESSAGE_TYPE_ALL;
2477
2478 if (argc == 1)
2479 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
cc9de1ba 2480 else if (! strncmp (argv[5]->arg, "s", 1))
508e53e2 2481 level = OSPF6_DEBUG_MESSAGE_SEND;
cc9de1ba 2482 else if (! strncmp (argv[5]->arg, "r", 1))
508e53e2 2483 level = OSPF6_DEBUG_MESSAGE_RECV;
2484
2485 if (type == OSPF6_MESSAGE_TYPE_ALL)
718e3744 2486 {
508e53e2 2487 for (i = 0; i < 6; i++)
2488 OSPF6_DEBUG_MESSAGE_OFF (i, level);
718e3744 2489 }
2490 else
508e53e2 2491 OSPF6_DEBUG_MESSAGE_OFF (type, level);
718e3744 2492
508e53e2 2493 return CMD_SUCCESS;
718e3744 2494}
2495
508e53e2 2496
718e3744 2497int
508e53e2 2498config_write_ospf6_debug_message (struct vty *vty)
718e3744 2499{
0c083ee9 2500 const char *type_str[] = {"unknown", "hello", "dbdesc",
508e53e2 2501 "lsreq", "lsupdate", "lsack"};
2502 unsigned char s = 0, r = 0;
2503 int i;
718e3744 2504
508e53e2 2505 for (i = 0; i < 6; i++)
2506 {
2507 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2508 s |= 1 << i;
2509 if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2510 r |= 1 << i;
2511 }
718e3744 2512
508e53e2 2513 if (s == 0x3f && r == 0x3f)
718e3744 2514 {
049207c3 2515 vty_out (vty, "debug ospf6 message all%s", VNL);
508e53e2 2516 return 0;
2517 }
718e3744 2518
508e53e2 2519 if (s == 0x3f && r == 0)
2520 {
049207c3 2521 vty_out (vty, "debug ospf6 message all send%s", VNL);
508e53e2 2522 return 0;
2523 }
2524 else if (s == 0 && r == 0x3f)
2525 {
049207c3 2526 vty_out (vty, "debug ospf6 message all recv%s", VNL);
508e53e2 2527 return 0;
718e3744 2528 }
2529
508e53e2 2530 /* Unknown message is logged by default */
2531 if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
2532 ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
049207c3 2533 vty_out (vty, "no debug ospf6 message unknown%s", VNL);
508e53e2 2534 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
049207c3 2535 vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
508e53e2 2536 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
049207c3 2537 vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
718e3744 2538
508e53e2 2539 for (i = 1; i < 6; i++)
718e3744 2540 {
508e53e2 2541 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
2542 IS_OSPF6_DEBUG_MESSAGE (i, RECV))
049207c3 2543 vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
508e53e2 2544 else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2545 vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
049207c3 2546 VNL);
508e53e2 2547 else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2548 vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
049207c3 2549 VNL);
718e3744 2550 }
2551
718e3744 2552 return 0;
2553}
2554
508e53e2 2555void
6ac29a51 2556install_element_ospf6_debug_message (void)
508e53e2 2557{
2558 install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
2559 install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
508e53e2 2560 install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
2561 install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
508e53e2 2562}
2563
2564