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