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