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