]> git.proxmox.com Git - mirror_frr.git/blob - ospf6d/ospf6_message.c
ospf6d: CVE-2011-3323 (fortify packet reception)
[mirror_frr.git] / ospf6d / ospf6_message.c
1 /*
2 * Copyright (C) 2003 Yasuhiro Ohara
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
22 #include <zebra.h>
23
24 #include "memory.h"
25 #include "log.h"
26 #include "vty.h"
27 #include "command.h"
28 #include "thread.h"
29 #include "linklist.h"
30
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"
36
37 #include "ospf6_top.h"
38 #include "ospf6_area.h"
39 #include "ospf6_neighbor.h"
40 #include "ospf6_interface.h"
41
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
47 #include "ospf6_flood.h"
48 #include "ospf6d.h"
49
50 #include <netinet/ip6.h>
51
52 unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
53 const char *ospf6_message_type_str[] =
54 { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };
55
56 /* Minimum (besides the standard OSPF packet header) lengths for OSPF
57 packets of particular types, offset is the "type" field. */
58 const 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. */
70 const 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
84 /* print functions */
85
86 static void
87 ospf6_header_print (struct ospf6_header *oh)
88 {
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
93 zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s",
94 oh->version, oh->type, ntohs (oh->length), router_id);
95 zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d",
96 area_id, ntohs (oh->checksum), oh->instance_id);
97 }
98
99 void
100 ospf6_hello_print (struct ospf6_header *oh)
101 {
102 struct ospf6_hello *hello;
103 char options[16];
104 char drouter[16], bdrouter[16], neighbor[16];
105 char *p;
106
107 ospf6_header_print (oh);
108 assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
109
110 hello = (struct ospf6_hello *)
111 ((caddr_t) oh + sizeof (struct ospf6_header));
112
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));
116
117 zlog_debug (" I/F-Id:%ld Priority:%d Option:%s",
118 (u_long) ntohl (hello->interface_id), hello->priority, options);
119 zlog_debug (" HelloInterval:%hu DeadInterval:%hu",
120 ntohs (hello->hello_interval), ntohs (hello->dead_interval));
121 zlog_debug (" DR:%s BDR:%s", drouter, bdrouter);
122
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))
126 {
127 inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
128 zlog_debug (" Neighbor: %s", neighbor);
129 }
130
131 if (p != OSPF6_MESSAGE_END (oh))
132 zlog_debug ("Trailing garbage exists");
133 }
134
135 void
136 ospf6_dbdesc_print (struct ospf6_header *oh)
137 {
138 struct ospf6_dbdesc *dbdesc;
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
150 zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu",
151 dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
152 zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
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))
165 zlog_debug ("Trailing garbage exists");
166 }
167
168 void
169 ospf6_lsreq_print (struct ospf6_header *oh)
170 {
171 char id[16], adv_router[16];
172 char *p;
173
174 ospf6_header_print (oh);
175 assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
176
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))
180 {
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));
184 zlog_debug (" [%s Id:%s Adv:%s]",
185 ospf6_lstype_name (e->type), id, adv_router);
186 }
187
188 if (p != OSPF6_MESSAGE_END (oh))
189 zlog_debug ("Trailing garbage exists");
190 }
191
192 void
193 ospf6_lsupdate_print (struct ospf6_header *oh)
194 {
195 struct ospf6_lsupdate *lsupdate;
196 u_long num;
197 char *p;
198
199 ospf6_header_print (oh);
200 assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
201
202 lsupdate = (struct ospf6_lsupdate *)
203 ((caddr_t) oh + sizeof (struct ospf6_header));
204
205 num = ntohl (lsupdate->lsa_number);
206 zlog_debug (" Number of LSA: %ld", num);
207
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 {
216 zlog_debug (" Malformed LSA length, quit printing");
217 break;
218 }
219 }
220
221 if (p != OSPF6_MESSAGE_END (oh))
222 {
223 char buf[32];
224
225 int num = 0;
226 memset (buf, 0, sizeof (buf));
227
228 zlog_debug (" Trailing garbage exists");
229 while (p < OSPF6_MESSAGE_END (oh))
230 {
231 snprintf (buf, sizeof (buf), "%s %2x", buf, *p++);
232 num++;
233 if (num == 8)
234 {
235 zlog_debug (" %s", buf);
236 memset (buf, 0, sizeof (buf));
237 num = 0;
238 }
239 }
240 if (num)
241 zlog_debug (" %s", buf);
242 }
243 }
244
245 void
246 ospf6_lsack_print (struct ospf6_header *oh)
247 {
248 char *p;
249
250 ospf6_header_print (oh);
251 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
252
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))
259 zlog_debug ("Trailing garbage exists");
260 }
261
262 static void
263 ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
264 struct ospf6_interface *oi, struct ospf6_header *oh)
265 {
266 struct ospf6_hello *hello;
267 struct ospf6_neighbor *on;
268 char *p;
269 int twoway = 0;
270 int neighborchange = 0;
271 int backupseen = 0;
272
273 hello = (struct ospf6_hello *)
274 ((caddr_t) oh + sizeof (struct ospf6_header));
275
276 /* HelloInterval check */
277 if (ntohs (hello->hello_interval) != oi->hello_interval)
278 {
279 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
280 zlog_debug ("HelloInterval mismatch");
281 return;
282 }
283
284 /* RouterDeadInterval check */
285 if (ntohs (hello->dead_interval) != oi->dead_interval)
286 {
287 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
288 zlog_debug ("RouterDeadInterval mismatch");
289 return;
290 }
291
292 /* E-bit check */
293 if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
294 OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
295 {
296 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
297 zlog_debug ("E-bit mismatch");
298 return;
299 }
300
301 /* Find neighbor, create if not exist */
302 on = ospf6_neighbor_lookup (oh->router_id, oi);
303 if (on == NULL)
304 {
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;
309 }
310
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
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))
319 {
320 u_int32_t *router_id = (u_int32_t *) p;
321
322 if (*router_id == oi->area->ospf6->router_id)
323 twoway++;
324 }
325
326 if (p != OSPF6_MESSAGE_END (oh))
327 {
328 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
329 zlog_debug ("Trailing garbage ignored");
330 }
331
332 /* RouterPriority check */
333 if (on->priority != hello->priority)
334 {
335 on->priority = hello->priority;
336 neighborchange++;
337 }
338
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 }
347
348 /* BDR check */
349 if (on->bdrouter != hello->bdrouter)
350 {
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 }
356
357 /* BackupSeen check */
358 if (oi->state == OSPF6_INTERFACE_WAITING)
359 {
360 if (hello->bdrouter == on->router_id)
361 backupseen++;
362 else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
363 backupseen++;
364 }
365
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);
372
373 /* Schedule interface events */
374 if (backupseen)
375 thread_add_event (master, backup_seen, oi, 0);
376 if (neighborchange)
377 thread_add_event (master, neighbor_change, oi, 0);
378 }
379
380 static void
381 ospf6_dbdesc_recv_master (struct ospf6_header *oh,
382 struct ospf6_neighbor *on)
383 {
384 struct ospf6_dbdesc *dbdesc;
385 char *p;
386
387 dbdesc = (struct ospf6_dbdesc *)
388 ((caddr_t) oh + sizeof (struct ospf6_header));
389
390 if (on->state < OSPF6_NEIGHBOR_INIT)
391 {
392 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
393 zlog_debug ("Neighbor state less than Init, ignore");
394 return;
395 }
396
397 switch (on->state)
398 {
399 case OSPF6_NEIGHBOR_TWOWAY:
400 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
401 zlog_debug ("Neighbor state is 2-Way, ignore");
402 return;
403
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))
409 zlog_debug ("Neighbor state is not ExStart, ignore");
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);
423
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))
430 zlog_debug ("Negotiation failed");
431 return;
432 }
433 /* fall through to exchange */
434
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))
440 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
441 return;
442 }
443
444 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
445 {
446 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
447 zlog_debug ("Master/Slave bit mismatch");
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))
455 zlog_debug ("Initialize bit mismatch");
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))
463 zlog_debug ("Option field mismatch");
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))
471 zlog_debug ("Sequence number mismatch (%#lx expected)",
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))
484 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
485 return;
486 }
487
488 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
489 zlog_debug ("Not duplicate dbdesc in state %s",
490 ospf6_neighbor_state_str[on->state]);
491 thread_add_event (master, seqnumber_mismatch, on, 0);
492 return;
493
494 default:
495 assert (0);
496 break;
497 }
498
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))
503 {
504 struct ospf6_lsa *his, *mine;
505 struct ospf6_lsdb *lsdb = NULL;
506
507 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
508
509 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
510 zlog_debug ("%s", his->name);
511
512 switch (OSPF6_LSA_SCOPE (his->header->type))
513 {
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))
525 zlog_debug ("Ignoring LSA of reserved scope");
526 ospf6_lsa_delete (his);
527 continue;
528 break;
529 }
530
531 if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
532 IS_AREA_STUB (on->ospf6_if->area))
533 {
534 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
535 zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
536 ospf6_lsa_delete (his);
537 thread_add_event (master, seqnumber_mismatch, on, 0);
538 return;
539 }
540
541 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
542 his->header->adv_router, lsdb);
543 if (mine == NULL)
544 {
545 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
546 zlog_debug ("Add request (No database copy)");
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))
552 zlog_debug ("Add request (Received MoreRecent)");
553 ospf6_lsdb_add (his, on->request_list);
554 }
555 else
556 {
557 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
558 zlog_debug ("Discard (Existing MoreRecent)");
559 ospf6_lsa_delete (his);
560 }
561 }
562
563 if (p != OSPF6_MESSAGE_END (oh))
564 {
565 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
566 zlog_debug ("Trailing garbage ignored");
567 }
568
569 /* Increment sequence number */
570 on->dbdesc_seqnum ++;
571
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);
576
577 THREAD_OFF (on->thread_send_dbdesc);
578
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);
586
587 /* save last received dbdesc */
588 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
589 }
590
591 static void
592 ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
593 struct ospf6_neighbor *on)
594 {
595 struct ospf6_dbdesc *dbdesc;
596 char *p;
597
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))
604 zlog_debug ("Neighbor state less than Init, ignore");
605 return;
606 }
607
608 switch (on->state)
609 {
610 case OSPF6_NEIGHBOR_TWOWAY:
611 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
612 zlog_debug ("Neighbor state is 2-Way, ignore");
613 return;
614
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))
620 zlog_debug ("Neighbor state is not ExStart, ignore");
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))
649 zlog_debug ("Negotiation failed");
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))
659 zlog_debug ("Duplicated dbdesc causes retransmit");
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))
669 zlog_debug ("Master/Slave bit mismatch");
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))
677 zlog_debug ("Initialize bit mismatch");
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))
685 zlog_debug ("Option field mismatch");
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))
693 zlog_debug ("Sequence number mismatch (%#lx expected)",
694 (u_long) on->dbdesc_seqnum + 1);
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))
706 zlog_debug ("Duplicated dbdesc causes retransmit");
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))
714 zlog_debug ("Not duplicate dbdesc in state %s",
715 ospf6_neighbor_state_str[on->state]);
716 thread_add_event (master, seqnumber_mismatch, on, 0);
717 return;
718
719 default:
720 assert (0);
721 break;
722 }
723
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))
728 {
729 struct ospf6_lsa *his, *mine;
730 struct ospf6_lsdb *lsdb = NULL;
731
732 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
733
734 switch (OSPF6_LSA_SCOPE (his->header->type))
735 {
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))
747 zlog_debug ("Ignoring LSA of reserved scope");
748 ospf6_lsa_delete (his);
749 continue;
750 break;
751 }
752
753 if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
754 IS_AREA_STUB (on->ospf6_if->area))
755 {
756 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
757 zlog_debug ("E-bit mismatch with LSA Headers");
758 ospf6_lsa_delete (his);
759 thread_add_event (master, seqnumber_mismatch, on, 0);
760 return;
761 }
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 {
767 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
768 zlog_debug ("Add request-list: %s", his->name);
769 ospf6_lsdb_add (his, on->request_list);
770 }
771 else
772 ospf6_lsa_delete (his);
773 }
774
775 if (p != OSPF6_MESSAGE_END (oh))
776 {
777 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
778 zlog_debug ("Trailing garbage ignored");
779 }
780
781 /* Set sequence number to Master's */
782 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
783
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);
788
789 THREAD_OFF (on->thread_send_dbdesc);
790 on->thread_send_dbdesc =
791 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
792
793 /* save last received dbdesc */
794 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
795 }
796
797 static void
798 ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
799 struct ospf6_interface *oi, struct ospf6_header *oh)
800 {
801 struct ospf6_neighbor *on;
802 struct ospf6_dbdesc *dbdesc;
803
804 on = ospf6_neighbor_lookup (oh->router_id, oi);
805 if (on == NULL)
806 {
807 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
808 zlog_debug ("Neighbor not found, ignore");
809 return;
810 }
811
812 dbdesc = (struct ospf6_dbdesc *)
813 ((caddr_t) oh + sizeof (struct ospf6_header));
814
815 /* Interface MTU check */
816 if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
817 {
818 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
819 zlog_debug ("I/F MTU mismatch");
820 return;
821 }
822
823 if (dbdesc->reserved1 || dbdesc->reserved2)
824 {
825 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
826 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
827 on->name);
828 dbdesc->reserved1 = 0;
829 dbdesc->reserved2 = 0;
830 }
831
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))
839 zlog_debug ("Can't decide which is master, ignore");
840 }
841 }
842
843 static void
844 ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
845 struct ospf6_interface *oi, struct ospf6_header *oh)
846 {
847 struct ospf6_neighbor *on;
848 char *p;
849 struct ospf6_lsreq_entry *e;
850 struct ospf6_lsdb *lsdb = NULL;
851 struct ospf6_lsa *lsa;
852
853 on = ospf6_neighbor_lookup (oh->router_id, oi);
854 if (on == NULL)
855 {
856 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
857 zlog_debug ("Neighbor not found, ignore");
858 return;
859 }
860
861 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
862 on->state != OSPF6_NEIGHBOR_LOADING &&
863 on->state != OSPF6_NEIGHBOR_FULL)
864 {
865 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
866 zlog_debug ("Neighbor state less than Exchange, ignore");
867 return;
868 }
869
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))
874 {
875 e = (struct ospf6_lsreq_entry *) p;
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))
890 zlog_debug ("Ignoring LSA of reserved scope");
891 continue;
892 break;
893 }
894
895 /* Find database copy */
896 lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
897 if (lsa == NULL)
898 {
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));
905 zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
906 ospf6_lstype_name (e->type), id, adv_router);
907 }
908 thread_add_event (master, bad_lsreq, on, 0);
909 return;
910 }
911
912 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
913 }
914
915 if (p != OSPF6_MESSAGE_END (oh))
916 {
917 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
918 zlog_debug ("Trailing garbage ignored");
919 }
920
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);
925 }
926
927 /* Verify, that the specified memory area contains exactly N valid IPv6
928 prefixes as specified by RFC5340, A.4.1. */
929 static unsigned
930 ospf6_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. */
983 static unsigned
984 ospf6_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. */
1126 static unsigned
1127 ospf6_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. */
1205 static unsigned
1206 ospf6_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. */
1311 static int
1312 ospf6_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
1354 static void
1355 ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
1356 struct ospf6_interface *oi, struct ospf6_header *oh)
1357 {
1358 struct ospf6_neighbor *on;
1359 struct ospf6_lsupdate *lsupdate;
1360 unsigned long num;
1361 char *p;
1362
1363 on = ospf6_neighbor_lookup (oh->router_id, oi);
1364 if (on == NULL)
1365 {
1366 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1367 zlog_debug ("Neighbor not found, ignore");
1368 return;
1369 }
1370
1371 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1372 on->state != OSPF6_NEIGHBOR_LOADING &&
1373 on->state != OSPF6_NEIGHBOR_FULL)
1374 {
1375 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1376 zlog_debug ("Neighbor state less than Exchange, ignore");
1377 return;
1378 }
1379
1380 lsupdate = (struct ospf6_lsupdate *)
1381 ((caddr_t) oh + sizeof (struct ospf6_header));
1382
1383 num = ntohl (lsupdate->lsa_number);
1384
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))
1396 zlog_debug ("Malformed LSA length, quit processing");
1397 break;
1398 }
1399
1400 ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
1401 num--;
1402 }
1403
1404 if (num != 0)
1405 {
1406 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1407 zlog_debug ("Malformed LSA number or LSA length");
1408 }
1409 if (p != OSPF6_MESSAGE_END (oh))
1410 {
1411 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1412 zlog_debug ("Trailing garbage ignored");
1413 }
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. */
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
1430 static void
1431 ospf6_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);
1440
1441 on = ospf6_neighbor_lookup (oh->router_id, oi);
1442 if (on == NULL)
1443 {
1444 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1445 zlog_debug ("Neighbor not found, ignore");
1446 return;
1447 }
1448
1449 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1450 on->state != OSPF6_NEIGHBOR_LOADING &&
1451 on->state != OSPF6_NEIGHBOR_FULL)
1452 {
1453 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1454 zlog_debug ("Neighbor state less than Exchange, ignore");
1455 return;
1456 }
1457
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);
1463
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))
1477 zlog_debug ("Ignoring LSA of reserved scope");
1478 ospf6_lsa_delete (his);
1479 continue;
1480 break;
1481 }
1482
1483 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1484 zlog_debug ("%s acknowledged by %s", his->name, on->name);
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))
1492 zlog_debug ("No database copy");
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))
1503 zlog_debug ("Not on %s's retrans-list", on->name);
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))
1513 zlog_debug ("Questionable acknowledgement");
1514 ospf6_lsa_delete (his);
1515 continue;
1516 }
1517
1518 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1519 zlog_debug ("Acknowledged, remove from %s's retrans-list",
1520 on->name);
1521
1522 ospf6_decrement_retrans_count (mine);
1523 if (OSPF6_LSA_IS_MAXAGE (mine))
1524 ospf6_maxage_remove (on->ospf6_if->area->ospf6);
1525 ospf6_lsdb_remove (mine, on->retrans_list);
1526 ospf6_lsa_delete (his);
1527 }
1528
1529 if (p != OSPF6_MESSAGE_END (oh))
1530 {
1531 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1532 zlog_debug ("Trailing garbage ignored");
1533 }
1534 }
1535
1536 static u_char *recvbuf = NULL;
1537 static u_char *sendbuf = NULL;
1538 static unsigned int iobuflen = 0;
1539
1540 int
1541 ospf6_iobuf_size (unsigned int size)
1542 {
1543 u_char *recvnew, *sendnew;
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 {
1552 if (recvnew)
1553 XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
1554 if (sendnew)
1555 XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
1556 zlog_debug ("Could not allocate I/O buffer of size %d.", size);
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 }
1570
1571 int
1572 ospf6_receive (struct thread *thread)
1573 {
1574 int sockfd;
1575 unsigned int len;
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 */
1588 memset (&src, 0, sizeof (src));
1589 memset (&dst, 0, sizeof (dst));
1590 ifindex = 0;
1591 memset (recvbuf, 0, iobuflen);
1592 iovector[0].iov_base = recvbuf;
1593 iovector[0].iov_len = iobuflen;
1594 iovector[1].iov_base = NULL;
1595 iovector[1].iov_len = 0;
1596
1597 /* receive message */
1598 len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
1599 if (len > iobuflen)
1600 {
1601 zlog_err ("Excess message read");
1602 return 0;
1603 }
1604
1605 oi = ospf6_interface_lookup_by_ifindex (ifindex);
1606 if (oi == NULL || oi->area == NULL)
1607 {
1608 zlog_debug ("Message received on disabled interface");
1609 return 0;
1610 }
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 }
1618
1619 oh = (struct ospf6_header *) recvbuf;
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. */
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));
1633 zlog_debug ("%s received on %s",
1634 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
1635 zlog_debug (" src: %s", srcname);
1636 zlog_debug (" dst: %s", dstname);
1637 if (len != ntohs (oh->length))
1638 zlog_debug ("Message length does not match actually received: %d", len);
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:
1658 zlog_debug ("Unknown message");
1659 break;
1660 }
1661 }
1662
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))
1687 zlog_debug ("Unknown message");
1688 break;
1689 }
1690
1691 return 0;
1692 }
1693
1694 static void
1695 ospf6_send (struct in6_addr *src, struct in6_addr *dst,
1696 struct ospf6_interface *oi, struct ospf6_header *oh)
1697 {
1698 int len;
1699 char srcname[64], dstname[64];
1700 struct iovec iovector[2];
1701
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;
1717
1718 /* Log */
1719 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
1720 {
1721 inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
1722 if (src)
1723 inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
1724 else
1725 memset (srcname, 0, sizeof (srcname));
1726 zlog_debug ("%s send on %s",
1727 OSPF6_MESSAGE_TYPE_NAME (oh->type), oi->interface->name);
1728 zlog_debug (" src: %s", srcname);
1729 zlog_debug (" dst: %s", dstname);
1730
1731 switch (oh->type)
1732 {
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:
1749 zlog_debug ("Unknown message");
1750 assert (0);
1751 break;
1752 }
1753 }
1754
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");
1759 }
1760
1761 static int
1762 ospf6_packet_max(struct ospf6_interface *oi)
1763 {
1764 return oi->ifmtu - sizeof(struct ip6_hdr);
1765 }
1766
1767 int
1768 ospf6_hello_send (struct thread *thread)
1769 {
1770 struct ospf6_interface *oi;
1771 struct ospf6_header *oh;
1772 struct ospf6_hello *hello;
1773 u_char *p;
1774 struct listnode *node, *nnode;
1775 struct ospf6_neighbor *on;
1776
1777 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1778 oi->thread_send_hello = (struct thread *) NULL;
1779
1780 if (oi->state <= OSPF6_INTERFACE_DOWN)
1781 {
1782 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
1783 zlog_debug ("Unable to send Hello on down interface %s",
1784 oi->interface->name);
1785 return 0;
1786 }
1787
1788 /* set next thread */
1789 oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
1790 oi, oi->hello_interval);
1791
1792 memset (sendbuf, 0, iobuflen);
1793 oh = (struct ospf6_header *) sendbuf;
1794 hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
1795
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;
1805
1806 p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello));
1807
1808 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1809 {
1810 if (on->state < OSPF6_NEIGHBOR_INIT)
1811 continue;
1812
1813 if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi))
1814 {
1815 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
1816 zlog_debug ("sending Hello message: exceeds I/F MTU");
1817 break;
1818 }
1819
1820 memcpy (p, &on->router_id, sizeof (u_int32_t));
1821 p += sizeof (u_int32_t);
1822 }
1823
1824 oh->type = OSPF6_MESSAGE_TYPE_HELLO;
1825 oh->length = htons (p - sendbuf);
1826
1827 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1828 return 0;
1829 }
1830
1831 int
1832 ospf6_dbdesc_send (struct thread *thread)
1833 {
1834 struct ospf6_neighbor *on;
1835 struct ospf6_header *oh;
1836 struct ospf6_dbdesc *dbdesc;
1837 u_char *p;
1838 struct ospf6_lsa *lsa;
1839
1840 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1841 on->thread_send_dbdesc = (struct thread *) NULL;
1842
1843 if (on->state < OSPF6_NEIGHBOR_EXSTART)
1844 {
1845 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
1846 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1847 on->name, ospf6_neighbor_state_str[on->state]);
1848 return 0;
1849 }
1850
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);
1856
1857 memset (sendbuf, 0, iobuflen);
1858 oh = (struct ospf6_header *) sendbuf;
1859 dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
1860 sizeof (struct ospf6_header));
1861
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;
1866 if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
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);
1877
1878 /* if this is not initial one, set LSA headers in dbdesc */
1879 p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
1880 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
1881 {
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) >
1889 ospf6_packet_max(on->ospf6_if))
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 }
1897 }
1898
1899 oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
1900 oh->length = htons (p - sendbuf);
1901
1902 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1903 on->ospf6_if, oh);
1904 return 0;
1905 }
1906
1907 int
1908 ospf6_dbdesc_send_newone (struct thread *thread)
1909 {
1910 struct ospf6_neighbor *on;
1911 struct ospf6_lsa *lsa;
1912 unsigned int size = 0;
1913
1914 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
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))
1922 {
1923 if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
1924 {
1925 ospf6_lsa_unlock (lsa);
1926 break;
1927 }
1928
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);
1932 }
1933
1934 if (on->summary_list->count == 0)
1935 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
1936
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);
1942
1943 thread_execute (master, ospf6_dbdesc_send, on, 0);
1944 return 0;
1945 }
1946
1947 int
1948 ospf6_lsreq_send (struct thread *thread)
1949 {
1950 struct ospf6_neighbor *on;
1951 struct ospf6_header *oh;
1952 struct ospf6_lsreq_entry *e;
1953 u_char *p;
1954 struct ospf6_lsa *lsa;
1955
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)
1962 {
1963 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
1964 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1965 on->name, ospf6_neighbor_state_str[on->state]);
1966 return 0;
1967 }
1968
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);
1973 return 0;
1974 }
1975
1976 /* set next thread */
1977 on->thread_send_lsreq =
1978 thread_add_timer (master, ospf6_lsreq_send, on,
1979 on->ospf6_if->rxmt_interval);
1980
1981 memset (sendbuf, 0, iobuflen);
1982 oh = (struct ospf6_header *) sendbuf;
1983
1984 /* set Request entries in lsreq */
1985 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
1986 for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1987 lsa = ospf6_lsdb_next (lsa))
1988 {
1989 /* MTU check */
1990 if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if))
1991 {
1992 ospf6_lsa_unlock (lsa);
1993 break;
1994 }
1995
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);
2001 }
2002
2003 oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
2004 oh->length = htons (p - sendbuf);
2005
2006 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2007 on->ospf6_if, oh);
2008 return 0;
2009 }
2010
2011 int
2012 ospf6_lsupdate_send_neighbor (struct thread *thread)
2013 {
2014 struct ospf6_neighbor *on;
2015 struct ospf6_header *oh;
2016 struct ospf6_lsupdate *lsupdate;
2017 u_char *p;
2018 int num;
2019 struct ospf6_lsa *lsa;
2020
2021 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
2022 on->thread_send_lsupdate = (struct thread *) NULL;
2023
2024 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2025 zlog_debug ("LSUpdate to neighbor %s", on->name);
2026
2027 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
2028 {
2029 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2030 zlog_debug ("Quit to send (neighbor state %s)",
2031 ospf6_neighbor_state_str[on->state]);
2032 return 0;
2033 }
2034
2035 /* if we have nothing to send, return */
2036 if (on->lsupdate_list->count == 0 &&
2037 on->retrans_list->count == 0)
2038 {
2039 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2040 zlog_debug ("Quit to send (nothing to send)");
2041 return 0;
2042 }
2043
2044 memset (sendbuf, 0, iobuflen);
2045 oh = (struct ospf6_header *) sendbuf;
2046 lsupdate = (struct ospf6_lsupdate *)
2047 ((caddr_t) oh + sizeof (struct ospf6_header));
2048
2049 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2050 num = 0;
2051
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))
2056 {
2057 /* MTU check */
2058 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
2059 > ospf6_packet_max(on->ospf6_if))
2060 {
2061 ospf6_lsa_unlock (lsa);
2062 break;
2063 }
2064
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++;
2069
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 */
2078 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
2079 > ospf6_packet_max(on->ospf6_if))
2080 {
2081 ospf6_lsa_unlock (lsa);
2082 break;
2083 }
2084
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++;
2089 }
2090
2091 lsupdate->lsa_number = htonl (num);
2092
2093 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2094 oh->length = htons (p - sendbuf);
2095
2096 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2097 on->ospf6_if, oh);
2098
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 }
2110
2111 return 0;
2112 }
2113
2114 int
2115 ospf6_lsupdate_send_interface (struct thread *thread)
2116 {
2117 struct ospf6_interface *oi;
2118 struct ospf6_header *oh;
2119 struct ospf6_lsupdate *lsupdate;
2120 u_char *p;
2121 int num;
2122 struct ospf6_lsa *lsa;
2123
2124 oi = (struct ospf6_interface *) THREAD_ARG (thread);
2125 oi->thread_send_lsupdate = (struct thread *) NULL;
2126
2127 if (oi->state <= OSPF6_INTERFACE_WAITING)
2128 {
2129 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2130 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
2131 oi->interface->name, ospf6_interface_state_str[oi->state]);
2132 return 0;
2133 }
2134
2135 /* if we have nothing to send, return */
2136 if (oi->lsupdate_list->count == 0)
2137 return 0;
2138
2139 memset (sendbuf, 0, iobuflen);
2140 oh = (struct ospf6_header *) sendbuf;
2141 lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
2142 sizeof (struct ospf6_header));
2143
2144 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2145 num = 0;
2146
2147 for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
2148 lsa = ospf6_lsdb_next (lsa))
2149 {
2150 /* MTU check */
2151 if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
2152 > ospf6_packet_max(oi))
2153 {
2154 ospf6_lsa_unlock (lsa);
2155 break;
2156 }
2157
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++;
2162
2163 assert (lsa->lock == 2);
2164 ospf6_lsdb_remove (lsa, oi->lsupdate_list);
2165 }
2166
2167 lsupdate->lsa_number = htonl (num);
2168
2169 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2170 oh->length = htons (p - sendbuf);
2171
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);
2177
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 }
2183
2184 return 0;
2185 }
2186
2187 int
2188 ospf6_lsack_send_neighbor (struct thread *thread)
2189 {
2190 struct ospf6_neighbor *on;
2191 struct ospf6_header *oh;
2192 u_char *p;
2193 struct ospf6_lsa *lsa;
2194
2195 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
2196 on->thread_send_lsack = (struct thread *) NULL;
2197
2198 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
2199 {
2200 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
2201 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
2202 on->name, ospf6_neighbor_state_str[on->state]);
2203 return 0;
2204 }
2205
2206 /* if we have nothing to send, return */
2207 if (on->lsack_list->count == 0)
2208 return 0;
2209
2210 memset (sendbuf, 0, iobuflen);
2211 oh = (struct ospf6_header *) sendbuf;
2212
2213 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
2214
2215 for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
2216 lsa = ospf6_lsdb_next (lsa))
2217 {
2218 /* MTU check */
2219 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
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);
2226
2227 ospf6_lsa_unlock (lsa);
2228 break;
2229 }
2230
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);
2234
2235 assert (lsa->lock == 2);
2236 ospf6_lsdb_remove (lsa, on->lsack_list);
2237 }
2238
2239 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2240 oh->length = htons (p - sendbuf);
2241
2242 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2243 on->ospf6_if, oh);
2244 return 0;
2245 }
2246
2247 int
2248 ospf6_lsack_send_interface (struct thread *thread)
2249 {
2250 struct ospf6_interface *oi;
2251 struct ospf6_header *oh;
2252 u_char *p;
2253 struct ospf6_lsa *lsa;
2254
2255 oi = (struct ospf6_interface *) THREAD_ARG (thread);
2256 oi->thread_send_lsack = (struct thread *) NULL;
2257
2258 if (oi->state <= OSPF6_INTERFACE_WAITING)
2259 {
2260 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
2261 zlog_debug ("Quit to send LSAck to interface %s state %s",
2262 oi->interface->name, ospf6_interface_state_str[oi->state]);
2263 return 0;
2264 }
2265
2266 /* if we have nothing to send, return */
2267 if (oi->lsack_list->count == 0)
2268 return 0;
2269
2270 memset (sendbuf, 0, iobuflen);
2271 oh = (struct ospf6_header *) sendbuf;
2272
2273 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
2274
2275 for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
2276 lsa = ospf6_lsdb_next (lsa))
2277 {
2278 /* MTU check */
2279 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
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);
2286
2287 ospf6_lsa_unlock (lsa);
2288 break;
2289 }
2290
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);
2294
2295 assert (lsa->lock == 2);
2296 ospf6_lsdb_remove (lsa, oi->lsack_list);
2297 }
2298
2299 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2300 oh->length = htons (p - sendbuf);
2301
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);
2307
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 }
2313
2314 return 0;
2315 }
2316
2317 \f
2318 /* Commands */
2319 DEFUN (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 )
2333 {
2334 unsigned char level = 0;
2335 int type = 0;
2336 int i;
2337
2338 assert (argc > 0);
2339
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);
2370
2371 return CMD_SUCCESS;
2372 }
2373
2374 ALIAS (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"
2389 )
2390
2391 \f
2392 DEFUN (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;
2411
2412 assert (argc > 0);
2413
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)
2438 {
2439 for (i = 0; i < 6; i++)
2440 OSPF6_DEBUG_MESSAGE_OFF (i, level);
2441 }
2442 else
2443 OSPF6_DEBUG_MESSAGE_OFF (type, level);
2444
2445 return CMD_SUCCESS;
2446 }
2447
2448 ALIAS (no_debug_ospf6_message,
2449 no_debug_ospf6_message_sendrecv_cmd,
2450 "no debug ospf6 message "
2451 "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
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"
2465 )
2466
2467 int
2468 config_write_ospf6_debug_message (struct vty *vty)
2469 {
2470 const char *type_str[] = {"unknown", "hello", "dbdesc",
2471 "lsreq", "lsupdate", "lsack"};
2472 unsigned char s = 0, r = 0;
2473 int i;
2474
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 }
2482
2483 if (s == 0x3f && r == 0x3f)
2484 {
2485 vty_out (vty, "debug ospf6 message all%s", VNL);
2486 return 0;
2487 }
2488
2489 if (s == 0x3f && r == 0)
2490 {
2491 vty_out (vty, "debug ospf6 message all send%s", VNL);
2492 return 0;
2493 }
2494 else if (s == 0 && r == 0x3f)
2495 {
2496 vty_out (vty, "debug ospf6 message all recv%s", VNL);
2497 return 0;
2498 }
2499
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))
2503 vty_out (vty, "no debug ospf6 message unknown%s", VNL);
2504 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
2505 vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
2506 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
2507 vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
2508
2509 for (i = 1; i < 6; i++)
2510 {
2511 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
2512 IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2513 vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
2514 else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2515 vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
2516 VNL);
2517 else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2518 vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
2519 VNL);
2520 }
2521
2522 return 0;
2523 }
2524
2525 void
2526 install_element_ospf6_debug_message (void)
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