2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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.
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"
37 #include "ospf6_top.h"
38 #include "ospf6_area.h"
39 #include "ospf6_neighbor.h"
40 #include "ospf6_interface.h"
42 /* for structures and macros ospf6_lsa_examin() needs */
43 #include "ospf6_abr.h"
44 #include "ospf6_asbr.h"
45 #include "ospf6_intra.h"
47 #include "ospf6_flood.h"
50 #include <netinet/ip6.h>
52 unsigned char conf_debug_ospf6_message[6] = {0x03, 0, 0, 0, 0, 0};
53 static const struct message ospf6_message_type_str [] =
55 { OSPF6_MESSAGE_TYPE_HELLO, "Hello" },
56 { OSPF6_MESSAGE_TYPE_DBDESC, "DbDesc" },
57 { OSPF6_MESSAGE_TYPE_LSREQ, "LSReq" },
58 { OSPF6_MESSAGE_TYPE_LSUPDATE, "LSUpdate" },
59 { OSPF6_MESSAGE_TYPE_LSACK, "LSAck" },
61 static const size_t ospf6_message_type_str_max = array_size(ospf6_message_type_str);
63 /* Minimum (besides the standard OSPF packet header) lengths for OSPF
64 packets of particular types, offset is the "type" field. */
65 const u_int16_t ospf6_packet_minlen[OSPF6_MESSAGE_TYPE_ALL] =
69 OSPF6_DB_DESC_MIN_SIZE,
70 OSPF6_LS_REQ_MIN_SIZE,
71 OSPF6_LS_UPD_MIN_SIZE,
75 /* Minimum (besides the standard LSA header) lengths for LSAs of particular
76 types, offset is the "LSA function code" portion of "LSA type" field. */
77 const u_int16_t ospf6_lsa_minlen[OSPF6_LSTYPE_SIZE] =
80 /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE,
81 /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE,
82 /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
83 /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE,
84 /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
86 /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE,
87 /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE,
88 /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
94 ospf6_header_print (struct ospf6_header *oh)
96 char router_id[16], area_id[16];
97 inet_ntop (AF_INET, &oh->router_id, router_id, sizeof (router_id));
98 inet_ntop (AF_INET, &oh->area_id, area_id, sizeof (area_id));
100 zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s",
101 oh->version, oh->type, ntohs (oh->length), router_id);
102 zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d",
103 area_id, ntohs (oh->checksum), oh->instance_id);
107 ospf6_hello_print (struct ospf6_header *oh)
109 struct ospf6_hello *hello;
111 char drouter[16], bdrouter[16], neighbor[16];
114 ospf6_header_print (oh);
115 assert (oh->type == OSPF6_MESSAGE_TYPE_HELLO);
117 hello = (struct ospf6_hello *)
118 ((caddr_t) oh + sizeof (struct ospf6_header));
120 inet_ntop (AF_INET, &hello->drouter, drouter, sizeof (drouter));
121 inet_ntop (AF_INET, &hello->bdrouter, bdrouter, sizeof (bdrouter));
122 ospf6_options_printbuf (hello->options, options, sizeof (options));
124 zlog_debug (" I/F-Id:%ld Priority:%d Option:%s",
125 (u_long) ntohl (hello->interface_id), hello->priority, options);
126 zlog_debug (" HelloInterval:%hu DeadInterval:%hu",
127 ntohs (hello->hello_interval), ntohs (hello->dead_interval));
128 zlog_debug (" DR:%s BDR:%s", drouter, bdrouter);
130 for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
131 p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
132 p += sizeof (u_int32_t))
134 inet_ntop (AF_INET, (void *) p, neighbor, sizeof (neighbor));
135 zlog_debug (" Neighbor: %s", neighbor);
138 assert (p == OSPF6_MESSAGE_END (oh));
142 ospf6_dbdesc_print (struct ospf6_header *oh)
144 struct ospf6_dbdesc *dbdesc;
148 ospf6_header_print (oh);
149 assert (oh->type == OSPF6_MESSAGE_TYPE_DBDESC);
151 dbdesc = (struct ospf6_dbdesc *)
152 ((caddr_t) oh + sizeof (struct ospf6_header));
154 ospf6_options_printbuf (dbdesc->options, options, sizeof (options));
156 zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu",
157 dbdesc->reserved1, options, ntohs (dbdesc->ifmtu));
158 zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
160 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) ? "I" : "-"),
161 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) ? "M" : "-"),
162 (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) ? "m" : "s"),
163 (u_long) ntohl (dbdesc->seqnum));
165 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
166 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
167 p += sizeof (struct ospf6_lsa_header))
168 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
170 assert (p == OSPF6_MESSAGE_END (oh));
174 ospf6_lsreq_print (struct ospf6_header *oh)
176 char id[16], adv_router[16];
179 ospf6_header_print (oh);
180 assert (oh->type == OSPF6_MESSAGE_TYPE_LSREQ);
182 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
183 p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
184 p += sizeof (struct ospf6_lsreq_entry))
186 struct ospf6_lsreq_entry *e = (struct ospf6_lsreq_entry *) p;
187 inet_ntop (AF_INET, &e->adv_router, adv_router, sizeof (adv_router));
188 inet_ntop (AF_INET, &e->id, id, sizeof (id));
189 zlog_debug (" [%s Id:%s Adv:%s]",
190 ospf6_lstype_name (e->type), id, adv_router);
193 assert (p == OSPF6_MESSAGE_END (oh));
197 ospf6_lsupdate_print (struct ospf6_header *oh)
199 struct ospf6_lsupdate *lsupdate;
203 ospf6_header_print (oh);
204 assert (oh->type == OSPF6_MESSAGE_TYPE_LSUPDATE);
206 lsupdate = (struct ospf6_lsupdate *)
207 ((caddr_t) oh + sizeof (struct ospf6_header));
209 num = ntohl (lsupdate->lsa_number);
210 zlog_debug (" Number of LSA: %ld", num);
212 for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
213 p < OSPF6_MESSAGE_END (oh) &&
214 p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
215 p += OSPF6_LSA_SIZE (p))
217 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
220 assert (p == OSPF6_MESSAGE_END (oh));
224 ospf6_lsack_print (struct ospf6_header *oh)
228 ospf6_header_print (oh);
229 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
231 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
232 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
233 p += sizeof (struct ospf6_lsa_header))
234 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header *) p);
236 assert (p == OSPF6_MESSAGE_END (oh));
240 ospf6_hello_recv (struct in6_addr *src, struct in6_addr *dst,
241 struct ospf6_interface *oi, struct ospf6_header *oh)
243 struct ospf6_hello *hello;
244 struct ospf6_neighbor *on;
247 int neighborchange = 0;
250 hello = (struct ospf6_hello *)
251 ((caddr_t) oh + sizeof (struct ospf6_header));
253 /* HelloInterval check */
254 if (ntohs (hello->hello_interval) != oi->hello_interval)
256 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
257 zlog_debug ("HelloInterval mismatch");
261 /* RouterDeadInterval check */
262 if (ntohs (hello->dead_interval) != oi->dead_interval)
264 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
265 zlog_debug ("RouterDeadInterval mismatch");
270 if (OSPF6_OPT_ISSET (hello->options, OSPF6_OPT_E) !=
271 OSPF6_OPT_ISSET (oi->area->options, OSPF6_OPT_E))
273 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
274 zlog_debug ("E-bit mismatch");
278 /* Find neighbor, create if not exist */
279 on = ospf6_neighbor_lookup (oh->router_id, oi);
282 on = ospf6_neighbor_create (oh->router_id, oi);
283 on->prev_drouter = on->drouter = hello->drouter;
284 on->prev_bdrouter = on->bdrouter = hello->bdrouter;
285 on->priority = hello->priority;
288 /* always override neighbor's source address and ifindex */
289 on->ifindex = ntohl (hello->interface_id);
290 memcpy (&on->linklocal_addr, src, sizeof (struct in6_addr));
293 for (p = (char *) ((caddr_t) hello + sizeof (struct ospf6_hello));
294 p + sizeof (u_int32_t) <= OSPF6_MESSAGE_END (oh);
295 p += sizeof (u_int32_t))
297 u_int32_t *router_id = (u_int32_t *) p;
299 if (*router_id == oi->area->ospf6->router_id)
303 assert (p == OSPF6_MESSAGE_END (oh));
305 /* RouterPriority check */
306 if (on->priority != hello->priority)
308 on->priority = hello->priority;
313 if (on->drouter != hello->drouter)
315 on->prev_drouter = on->drouter;
316 on->drouter = hello->drouter;
317 if (on->prev_drouter == on->router_id || on->drouter == on->router_id)
322 if (on->bdrouter != hello->bdrouter)
324 on->prev_bdrouter = on->bdrouter;
325 on->bdrouter = hello->bdrouter;
326 if (on->prev_bdrouter == on->router_id || on->bdrouter == on->router_id)
330 /* BackupSeen check */
331 if (oi->state == OSPF6_INTERFACE_WAITING)
333 if (hello->bdrouter == on->router_id)
335 else if (hello->drouter == on->router_id && hello->bdrouter == htonl (0))
339 /* Execute neighbor events */
340 thread_execute (master, hello_received, on, 0);
342 thread_execute (master, twoway_received, on, 0);
344 thread_execute (master, oneway_received, on, 0);
346 /* Schedule interface events */
348 thread_add_event (master, backup_seen, oi, 0);
350 thread_add_event (master, neighbor_change, oi, 0);
354 ospf6_dbdesc_recv_master (struct ospf6_header *oh,
355 struct ospf6_neighbor *on)
357 struct ospf6_dbdesc *dbdesc;
360 dbdesc = (struct ospf6_dbdesc *)
361 ((caddr_t) oh + sizeof (struct ospf6_header));
363 if (on->state < OSPF6_NEIGHBOR_INIT)
365 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
366 zlog_debug ("Neighbor state less than Init, ignore");
372 case OSPF6_NEIGHBOR_TWOWAY:
373 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
374 zlog_debug ("Neighbor state is 2-Way, ignore");
377 case OSPF6_NEIGHBOR_INIT:
378 thread_execute (master, twoway_received, on, 0);
379 if (on->state != OSPF6_NEIGHBOR_EXSTART)
381 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
382 zlog_debug ("Neighbor state is not ExStart, ignore");
385 /* else fall through to ExStart */
387 case OSPF6_NEIGHBOR_EXSTART:
388 /* if neighbor obeys us as our slave, schedule negotiation_done
389 and process LSA Headers. Otherwise, ignore this message */
390 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
391 ! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
392 ntohl (dbdesc->seqnum) == on->dbdesc_seqnum)
394 /* execute NegotiationDone */
395 thread_execute (master, negotiation_done, on, 0);
397 /* Record neighbor options */
398 memcpy (on->options, dbdesc->options, sizeof (on->options));
402 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
403 zlog_debug ("Negotiation failed");
406 /* fall through to exchange */
408 case OSPF6_NEIGHBOR_EXCHANGE:
409 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
411 /* Duplicated DatabaseDescription is dropped by master */
412 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
413 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
417 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
419 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
420 zlog_debug ("Master/Slave bit mismatch");
421 thread_add_event (master, seqnumber_mismatch, on, 0);
425 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
427 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
428 zlog_debug ("Initialize bit mismatch");
429 thread_add_event (master, seqnumber_mismatch, on, 0);
433 if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
435 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
436 zlog_debug ("Option field mismatch");
437 thread_add_event (master, seqnumber_mismatch, on, 0);
441 if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum)
443 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
444 zlog_debug ("Sequence number mismatch (%#lx expected)",
445 (u_long) on->dbdesc_seqnum);
446 thread_add_event (master, seqnumber_mismatch, on, 0);
451 case OSPF6_NEIGHBOR_LOADING:
452 case OSPF6_NEIGHBOR_FULL:
453 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
455 /* Duplicated DatabaseDescription is dropped by master */
456 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
457 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
461 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
462 zlog_debug ("Not duplicate dbdesc in state %s",
463 ospf6_neighbor_state_str[on->state]);
464 thread_add_event (master, seqnumber_mismatch, on, 0);
472 /* Process LSA headers */
473 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
474 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
475 p += sizeof (struct ospf6_lsa_header))
477 struct ospf6_lsa *his, *mine;
478 struct ospf6_lsdb *lsdb = NULL;
480 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
482 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
483 zlog_debug ("%s", his->name);
485 switch (OSPF6_LSA_SCOPE (his->header->type))
487 case OSPF6_SCOPE_LINKLOCAL:
488 lsdb = on->ospf6_if->lsdb;
490 case OSPF6_SCOPE_AREA:
491 lsdb = on->ospf6_if->area->lsdb;
494 lsdb = on->ospf6_if->area->ospf6->lsdb;
496 case OSPF6_SCOPE_RESERVED:
497 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
498 zlog_debug ("Ignoring LSA of reserved scope");
499 ospf6_lsa_delete (his);
504 if (ntohs (his->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
505 IS_AREA_STUB (on->ospf6_if->area))
507 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
508 zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
509 ospf6_lsa_delete (his);
510 thread_add_event (master, seqnumber_mismatch, on, 0);
514 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
515 his->header->adv_router, lsdb);
518 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
519 zlog_debug ("Add request (No database copy)");
520 ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
522 else if (ospf6_lsa_compare (his, mine) < 0)
524 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
525 zlog_debug ("Add request (Received MoreRecent)");
526 ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
530 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
531 zlog_debug ("Discard (Existing MoreRecent)");
533 ospf6_lsa_delete (his);
536 assert (p == OSPF6_MESSAGE_END (oh));
538 /* Increment sequence number */
539 on->dbdesc_seqnum ++;
541 /* schedule send lsreq */
542 if (on->request_list->count && (on->thread_send_lsreq == NULL))
543 on->thread_send_lsreq =
544 thread_add_event (master, ospf6_lsreq_send, on, 0);
546 THREAD_OFF (on->thread_send_dbdesc);
549 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
550 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
551 thread_add_event (master, exchange_done, on, 0);
553 on->thread_send_dbdesc =
554 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
556 /* save last received dbdesc */
557 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
561 ospf6_dbdesc_recv_slave (struct ospf6_header *oh,
562 struct ospf6_neighbor *on)
564 struct ospf6_dbdesc *dbdesc;
567 dbdesc = (struct ospf6_dbdesc *)
568 ((caddr_t) oh + sizeof (struct ospf6_header));
570 if (on->state < OSPF6_NEIGHBOR_INIT)
572 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
573 zlog_debug ("Neighbor state less than Init, ignore");
579 case OSPF6_NEIGHBOR_TWOWAY:
580 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
581 zlog_debug ("Neighbor state is 2-Way, ignore");
584 case OSPF6_NEIGHBOR_INIT:
585 thread_execute (master, twoway_received, on, 0);
586 if (on->state != OSPF6_NEIGHBOR_EXSTART)
588 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
589 zlog_debug ("Neighbor state is not ExStart, ignore");
592 /* else fall through to ExStart */
594 case OSPF6_NEIGHBOR_EXSTART:
595 /* If the neighbor is Master, act as Slave. Schedule negotiation_done
596 and process LSA Headers. Otherwise, ignore this message */
597 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT) &&
598 CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MBIT) &&
599 CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT) &&
600 ntohs (oh->length) == sizeof (struct ospf6_header) +
601 sizeof (struct ospf6_dbdesc))
603 /* set the master/slave bit to slave */
604 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
606 /* set the DD sequence number to one specified by master */
607 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
609 /* schedule NegotiationDone */
610 thread_execute (master, negotiation_done, on, 0);
612 /* Record neighbor options */
613 memcpy (on->options, dbdesc->options, sizeof (on->options));
617 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
618 zlog_debug ("Negotiation failed");
623 case OSPF6_NEIGHBOR_EXCHANGE:
624 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
626 /* Duplicated DatabaseDescription causes slave to retransmit */
627 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
628 zlog_debug ("Duplicated dbdesc causes retransmit");
629 THREAD_OFF (on->thread_send_dbdesc);
630 on->thread_send_dbdesc =
631 thread_add_event (master, ospf6_dbdesc_send, on, 0);
635 if (! CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_MSBIT))
637 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
638 zlog_debug ("Master/Slave bit mismatch");
639 thread_add_event (master, seqnumber_mismatch, on, 0);
643 if (CHECK_FLAG (dbdesc->bits, OSPF6_DBDESC_IBIT))
645 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
646 zlog_debug ("Initialize bit mismatch");
647 thread_add_event (master, seqnumber_mismatch, on, 0);
651 if (memcmp (on->options, dbdesc->options, sizeof (on->options)))
653 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
654 zlog_debug ("Option field mismatch");
655 thread_add_event (master, seqnumber_mismatch, on, 0);
659 if (ntohl (dbdesc->seqnum) != on->dbdesc_seqnum + 1)
661 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
662 zlog_debug ("Sequence number mismatch (%#lx expected)",
663 (u_long) on->dbdesc_seqnum + 1);
664 thread_add_event (master, seqnumber_mismatch, on, 0);
669 case OSPF6_NEIGHBOR_LOADING:
670 case OSPF6_NEIGHBOR_FULL:
671 if (! memcmp (dbdesc, &on->dbdesc_last, sizeof (struct ospf6_dbdesc)))
673 /* Duplicated DatabaseDescription causes slave to retransmit */
674 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
675 zlog_debug ("Duplicated dbdesc causes retransmit");
676 THREAD_OFF (on->thread_send_dbdesc);
677 on->thread_send_dbdesc =
678 thread_add_event (master, ospf6_dbdesc_send, on, 0);
682 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
683 zlog_debug ("Not duplicate dbdesc in state %s",
684 ospf6_neighbor_state_str[on->state]);
685 thread_add_event (master, seqnumber_mismatch, on, 0);
693 /* Process LSA headers */
694 for (p = (char *) ((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
695 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
696 p += sizeof (struct ospf6_lsa_header))
698 struct ospf6_lsa *his, *mine;
699 struct ospf6_lsdb *lsdb = NULL;
701 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
703 switch (OSPF6_LSA_SCOPE (his->header->type))
705 case OSPF6_SCOPE_LINKLOCAL:
706 lsdb = on->ospf6_if->lsdb;
708 case OSPF6_SCOPE_AREA:
709 lsdb = on->ospf6_if->area->lsdb;
712 lsdb = on->ospf6_if->area->ospf6->lsdb;
714 case OSPF6_SCOPE_RESERVED:
715 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
716 zlog_debug ("Ignoring LSA of reserved scope");
717 ospf6_lsa_delete (his);
722 if (OSPF6_LSA_SCOPE (his->header->type) == OSPF6_SCOPE_AS &&
723 IS_AREA_STUB (on->ospf6_if->area))
725 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
726 zlog_debug ("E-bit mismatch with LSA Headers");
727 ospf6_lsa_delete (his);
728 thread_add_event (master, seqnumber_mismatch, on, 0);
732 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
733 his->header->adv_router, lsdb);
734 if (mine == NULL || ospf6_lsa_compare (his, mine) < 0)
736 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
737 zlog_debug ("Add request-list: %s", his->name);
738 ospf6_lsdb_add (ospf6_lsa_copy(his), on->request_list);
740 ospf6_lsa_delete (his);
743 assert (p == OSPF6_MESSAGE_END (oh));
745 /* Set sequence number to Master's */
746 on->dbdesc_seqnum = ntohl (dbdesc->seqnum);
748 /* schedule send lsreq */
749 if ((on->thread_send_lsreq == NULL) &&
750 (on->request_list->count))
751 on->thread_send_lsreq =
752 thread_add_event (master, ospf6_lsreq_send, on, 0);
754 THREAD_OFF (on->thread_send_dbdesc);
755 on->thread_send_dbdesc =
756 thread_add_event (master, ospf6_dbdesc_send_newone, on, 0);
758 /* save last received dbdesc */
759 memcpy (&on->dbdesc_last, dbdesc, sizeof (struct ospf6_dbdesc));
763 ospf6_dbdesc_recv (struct in6_addr *src, struct in6_addr *dst,
764 struct ospf6_interface *oi, struct ospf6_header *oh)
766 struct ospf6_neighbor *on;
767 struct ospf6_dbdesc *dbdesc;
769 on = ospf6_neighbor_lookup (oh->router_id, oi);
772 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
773 zlog_debug ("Neighbor not found, ignore");
777 dbdesc = (struct ospf6_dbdesc *)
778 ((caddr_t) oh + sizeof (struct ospf6_header));
780 /* Interface MTU check */
781 if (!oi->mtu_ignore && ntohs (dbdesc->ifmtu) != oi->ifmtu)
783 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
784 zlog_debug ("I/F MTU mismatch");
788 if (dbdesc->reserved1 || dbdesc->reserved2)
790 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
791 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
793 dbdesc->reserved1 = 0;
794 dbdesc->reserved2 = 0;
797 if (ntohl (oh->router_id) < ntohl (ospf6->router_id))
798 ospf6_dbdesc_recv_master (oh, on);
799 else if (ntohl (ospf6->router_id) < ntohl (oh->router_id))
800 ospf6_dbdesc_recv_slave (oh, on);
803 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
804 zlog_debug ("Can't decide which is master, ignore");
809 ospf6_lsreq_recv (struct in6_addr *src, struct in6_addr *dst,
810 struct ospf6_interface *oi, struct ospf6_header *oh)
812 struct ospf6_neighbor *on;
814 struct ospf6_lsreq_entry *e;
815 struct ospf6_lsdb *lsdb = NULL;
816 struct ospf6_lsa *lsa;
818 on = ospf6_neighbor_lookup (oh->router_id, oi);
821 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
822 zlog_debug ("Neighbor not found, ignore");
826 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
827 on->state != OSPF6_NEIGHBOR_LOADING &&
828 on->state != OSPF6_NEIGHBOR_FULL)
830 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
831 zlog_debug ("Neighbor state less than Exchange, ignore");
835 /* Process each request */
836 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
837 p + sizeof (struct ospf6_lsreq_entry) <= OSPF6_MESSAGE_END (oh);
838 p += sizeof (struct ospf6_lsreq_entry))
840 e = (struct ospf6_lsreq_entry *) p;
842 switch (OSPF6_LSA_SCOPE (e->type))
844 case OSPF6_SCOPE_LINKLOCAL:
845 lsdb = on->ospf6_if->lsdb;
847 case OSPF6_SCOPE_AREA:
848 lsdb = on->ospf6_if->area->lsdb;
851 lsdb = on->ospf6_if->area->ospf6->lsdb;
854 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
855 zlog_debug ("Ignoring LSA of reserved scope");
860 /* Find database copy */
861 lsa = ospf6_lsdb_lookup (e->type, e->id, e->adv_router, lsdb);
864 char id[16], adv_router[16];
865 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
867 inet_ntop (AF_INET, &e->id, id, sizeof (id));
868 inet_ntop (AF_INET, &e->adv_router, adv_router,
869 sizeof (adv_router));
870 zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
871 ospf6_lstype_name (e->type), id, adv_router);
873 thread_add_event (master, bad_lsreq, on, 0);
877 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->lsupdate_list);
880 assert (p == OSPF6_MESSAGE_END (oh));
882 /* schedule send lsupdate */
883 THREAD_OFF (on->thread_send_lsupdate);
884 on->thread_send_lsupdate =
885 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
888 /* Verify, that the specified memory area contains exactly N valid IPv6
889 prefixes as specified by RFC5340, A.4.1. */
891 ospf6_prefixes_examin
893 struct ospf6_prefix *current, /* start of buffer */
895 const u_int32_t req_num_pfxs /* always compared with the actual number of prefixes */
898 u_char requested_pfx_bytes;
899 u_int32_t real_num_pfxs = 0;
903 if (length < OSPF6_PREFIX_MIN_SIZE)
905 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
906 zlog_debug ("%s: undersized IPv6 prefix header", __func__);
909 /* safe to look deeper */
910 if (current->prefix_length > IPV6_MAX_BITLEN)
912 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
913 zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__, current->prefix_length);
916 /* covers both fixed- and variable-sized fields */
917 requested_pfx_bytes = OSPF6_PREFIX_MIN_SIZE + OSPF6_PREFIX_SPACE (current->prefix_length);
918 if (requested_pfx_bytes > length)
920 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
921 zlog_debug ("%s: undersized IPv6 prefix", __func__);
925 length -= requested_pfx_bytes;
926 current = (struct ospf6_prefix *) ((caddr_t) current + requested_pfx_bytes);
929 if (real_num_pfxs != req_num_pfxs)
931 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
932 zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)",
933 __func__, req_num_pfxs, real_num_pfxs);
939 /* Verify an LSA to have a valid length and dispatch further (where
940 appropriate) to check if the contents, including nested IPv6 prefixes,
941 is properly sized/aligned within the LSA. Note that this function gets
942 LSA type in network byte order, uses in host byte order and passes to
943 ospf6_lstype_name() in network byte order again. */
945 ospf6_lsa_examin (struct ospf6_lsa_header *lsah, const u_int16_t lsalen, const u_char headeronly)
947 struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
948 struct ospf6_as_external_lsa *as_external_lsa;
949 struct ospf6_link_lsa *link_lsa;
954 /* In case an additional minimum length constraint is defined for current
955 LSA type, make sure that this constraint is met. */
956 lsatype = ntohs (lsah->type);
957 ltindex = lsatype & OSPF6_LSTYPE_FCODE_MASK;
960 ltindex < OSPF6_LSTYPE_SIZE &&
961 ospf6_lsa_minlen[ltindex] &&
962 lsalen < ospf6_lsa_minlen[ltindex] + OSPF6_LSA_HEADER_SIZE
965 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
966 zlog_debug ("%s: undersized (%u B) LSA", __func__, lsalen);
971 case OSPF6_LSTYPE_ROUTER:
972 /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed
973 by N>=0 interface descriptions. */
974 if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_ROUTER_LSA_MIN_SIZE) % OSPF6_ROUTER_LSDESC_FIX_SIZE)
976 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
977 zlog_debug ("%s: interface description alignment error", __func__);
981 case OSPF6_LSTYPE_NETWORK:
982 /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
983 followed by N>=0 attached router descriptions. */
984 if ((lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_NETWORK_LSA_MIN_SIZE) % OSPF6_NETWORK_LSDESC_FIX_SIZE)
986 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
987 zlog_debug ("%s: router description alignment error", __func__);
991 case OSPF6_LSTYPE_INTER_PREFIX:
992 /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes
993 followed by 3-4 fields of a single IPv6 prefix. */
996 return ospf6_prefixes_examin
998 (struct ospf6_prefix *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_PREFIX_LSA_MIN_SIZE),
999 lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTER_PREFIX_LSA_MIN_SIZE,
1002 case OSPF6_LSTYPE_INTER_ROUTER:
1003 /* RFC5340 A.4.6, fixed-size LSA. */
1004 if (lsalen > OSPF6_LSA_HEADER_SIZE + OSPF6_INTER_ROUTER_LSA_FIX_SIZE)
1006 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1007 zlog_debug ("%s: oversized (%u B) LSA", __func__, lsalen);
1011 case OSPF6_LSTYPE_AS_EXTERNAL: /* RFC5340 A.4.7, same as A.4.8. */
1012 case OSPF6_LSTYPE_TYPE_7:
1013 /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes
1014 followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields:
1015 16 bytes of forwarding address, 4 bytes of external route tag,
1016 4 bytes of referenced link state ID. */
1019 as_external_lsa = (struct ospf6_as_external_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1020 exp_length = OSPF6_LSA_HEADER_SIZE + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE;
1021 /* To find out if the last optional field (Referenced Link State ID) is
1022 assumed in this LSA, we need to access fixed fields of the IPv6
1023 prefix before ospf6_prefix_examin() confirms its sizing. */
1024 if (exp_length + OSPF6_PREFIX_MIN_SIZE > lsalen)
1026 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1027 zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
1030 /* forwarding address */
1031 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
1033 /* external route tag */
1034 if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
1036 /* referenced link state ID */
1037 if (as_external_lsa->prefix.u._prefix_referenced_lstype)
1039 /* All the fixed-size fields (mandatory and optional) must fit. I.e.,
1040 this check does not include any IPv6 prefix fields. */
1041 if (exp_length > lsalen)
1043 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1044 zlog_debug ("%s: undersized (%u B) LSA header", __func__, lsalen);
1047 /* The last call completely covers the remainder (IPv6 prefix). */
1048 return ospf6_prefixes_examin
1050 (struct ospf6_prefix *) ((caddr_t) as_external_lsa + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE),
1051 lsalen - exp_length,
1054 case OSPF6_LSTYPE_LINK:
1055 /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed
1056 by N>=0 IPv6 prefix blocks (with N declared beforehand). */
1059 link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1060 return ospf6_prefixes_examin
1062 (struct ospf6_prefix *) ((caddr_t) link_lsa + OSPF6_LINK_LSA_MIN_SIZE),
1063 lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_LINK_LSA_MIN_SIZE,
1064 ntohl (link_lsa->prefix_num) /* 32 bits */
1066 case OSPF6_LSTYPE_INTRA_PREFIX:
1067 /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes
1068 followed by N>=0 IPv6 prefixes (with N declared beforehand). */
1071 intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1072 return ospf6_prefixes_examin
1074 (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE),
1075 lsalen - OSPF6_LSA_HEADER_SIZE - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE,
1076 ntohs (intra_prefix_lsa->prefix_num) /* 16 bits */
1079 /* No additional validation is possible for unknown LSA types, which are
1080 themselves valid in OPSFv3, hence the default decision is to accept. */
1084 /* Verify if the provided input buffer is a valid sequence of LSAs. This
1085 includes verification of LSA blocks length/alignment and dispatching
1086 of deeper-level checks. */
1090 struct ospf6_lsa_header *lsah, /* start of buffered data */
1092 const u_char headeronly,
1093 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
1094 and treat the difference as an error. */
1095 const u_int32_t declared_num_lsas
1098 u_int32_t counted_lsas = 0;
1103 if (length < OSPF6_LSA_HEADER_SIZE)
1105 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1106 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
1107 __func__, length, counted_lsas);
1110 /* save on ntohs() calls here and in the LSA validator */
1111 lsalen = OSPF6_LSA_SIZE (lsah);
1112 if (lsalen < OSPF6_LSA_HEADER_SIZE)
1114 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1115 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
1116 __func__, counted_lsas, lsalen);
1121 /* less checks here and in ospf6_lsa_examin() */
1122 if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 1))
1124 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1125 zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__,
1126 ospf6_lstype_name (lsah->type), counted_lsas);
1129 lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + OSPF6_LSA_HEADER_SIZE);
1130 length -= OSPF6_LSA_HEADER_SIZE;
1134 /* make sure the input buffer is deep enough before further checks */
1135 if (lsalen > length)
1137 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1138 zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
1139 __func__, ospf6_lstype_name (lsah->type), counted_lsas, lsalen, length);
1142 if (MSG_OK != ospf6_lsa_examin (lsah, lsalen, 0))
1144 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1145 zlog_debug ("%s: anomaly in %s LSA #%u", __func__,
1146 ospf6_lstype_name (lsah->type), counted_lsas);
1149 lsah = (struct ospf6_lsa_header *) ((caddr_t) lsah + lsalen);
1155 if (declared_num_lsas && counted_lsas != declared_num_lsas)
1157 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1158 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
1159 __func__, declared_num_lsas, counted_lsas);
1165 /* Verify a complete OSPF packet for proper sizing/alignment. */
1167 ospf6_packet_examin (struct ospf6_header *oh, const unsigned bytesonwire)
1169 struct ospf6_lsupdate *lsupd;
1172 /* length, 1st approximation */
1173 if (bytesonwire < OSPF6_HEADER_SIZE)
1175 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1176 zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire);
1179 /* Now it is safe to access header fields. */
1180 if (bytesonwire != ntohs (oh->length))
1182 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1183 zlog_debug ("%s: packet length error (%u real, %u declared)",
1184 __func__, bytesonwire, ntohs (oh->length));
1188 if (oh->version != OSPFV3_VERSION)
1190 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1191 zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version);
1194 /* length, 2nd approximation */
1197 oh->type < OSPF6_MESSAGE_TYPE_ALL &&
1198 ospf6_packet_minlen[oh->type] &&
1199 bytesonwire < OSPF6_HEADER_SIZE + ospf6_packet_minlen[oh->type]
1202 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1203 zlog_debug ("%s: undersized (%u B) %s packet", __func__,
1204 bytesonwire, LOOKUP (ospf6_message_type_str, oh->type));
1207 /* type-specific deeper validation */
1210 case OSPF6_MESSAGE_TYPE_HELLO:
1211 /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed
1212 by N>=0 router-IDs. */
1213 if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_HELLO_MIN_SIZE) % 4)
1215 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1216 zlog_debug ("%s: alignment error in %s packet",
1217 __func__, LOOKUP (ospf6_message_type_str, oh->type));
1219 case OSPF6_MESSAGE_TYPE_DBDESC:
1220 /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed
1221 by N>=0 header-only LSAs. */
1222 test = ospf6_lsaseq_examin
1224 (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_DB_DESC_MIN_SIZE),
1225 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_DB_DESC_MIN_SIZE,
1230 case OSPF6_MESSAGE_TYPE_LSREQ:
1231 /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
1232 if (0 == (bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_REQ_MIN_SIZE) % OSPF6_LSREQ_LSDESC_FIX_SIZE)
1234 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1235 zlog_debug ("%s: alignment error in %s packet",
1236 __func__, LOOKUP (ospf6_message_type_str, oh->type));
1238 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1239 /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed
1240 by N>=0 full LSAs (with N declared beforehand). */
1241 lsupd = (struct ospf6_lsupdate *) ((caddr_t) oh + OSPF6_HEADER_SIZE);
1242 test = ospf6_lsaseq_examin
1244 (struct ospf6_lsa_header *) ((caddr_t) lsupd + OSPF6_LS_UPD_MIN_SIZE),
1245 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_UPD_MIN_SIZE,
1247 ntohl (lsupd->lsa_number) /* 32 bits */
1250 case OSPF6_MESSAGE_TYPE_LSACK:
1251 /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1252 test = ospf6_lsaseq_examin
1254 (struct ospf6_lsa_header *) ((caddr_t) oh + OSPF6_HEADER_SIZE + OSPF6_LS_ACK_MIN_SIZE),
1255 bytesonwire - OSPF6_HEADER_SIZE - OSPF6_LS_ACK_MIN_SIZE,
1261 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1262 zlog_debug ("%s: invalid (%u) message type", __func__, oh->type);
1265 if (test != MSG_OK && IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1266 zlog_debug ("%s: anomaly in %s packet", __func__, LOOKUP (ospf6_message_type_str, oh->type));
1270 /* Verify particular fields of otherwise correct received OSPF packet to
1271 meet the requirements of RFC. */
1273 ospf6_rxpacket_examin (struct ospf6_interface *oi, struct ospf6_header *oh, const unsigned bytesonwire)
1275 char buf[2][INET_ADDRSTRLEN];
1277 if (MSG_OK != ospf6_packet_examin (oh, bytesonwire))
1281 if (oh->area_id != oi->area->area_id)
1283 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1285 if (oh->area_id == OSPF_AREA_BACKBONE)
1286 zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__);
1290 "%s: Area-ID mismatch (my %s, rcvd %s)", __func__,
1291 inet_ntop (AF_INET, &oi->area->area_id, buf[0], INET_ADDRSTRLEN),
1292 inet_ntop (AF_INET, &oh->area_id, buf[1], INET_ADDRSTRLEN)
1298 /* Instance-ID check */
1299 if (oh->instance_id != oi->instance_id)
1301 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1302 zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__, oi->instance_id, oh->instance_id);
1306 /* Router-ID check */
1307 if (oh->router_id == oi->area->ospf6->router_id)
1309 zlog_warn ("%s: Duplicate Router-ID (%s)", __func__, inet_ntop (AF_INET, &oh->router_id, buf[0], INET_ADDRSTRLEN));
1316 ospf6_lsupdate_recv (struct in6_addr *src, struct in6_addr *dst,
1317 struct ospf6_interface *oi, struct ospf6_header *oh)
1319 struct ospf6_neighbor *on;
1320 struct ospf6_lsupdate *lsupdate;
1323 on = ospf6_neighbor_lookup (oh->router_id, oi);
1326 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1327 zlog_debug ("Neighbor not found, ignore");
1331 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1332 on->state != OSPF6_NEIGHBOR_LOADING &&
1333 on->state != OSPF6_NEIGHBOR_FULL)
1335 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1336 zlog_debug ("Neighbor state less than Exchange, ignore");
1340 lsupdate = (struct ospf6_lsupdate *)
1341 ((caddr_t) oh + sizeof (struct ospf6_header));
1344 for (p = (char *) ((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
1345 p < OSPF6_MESSAGE_END (oh) &&
1346 p + OSPF6_LSA_SIZE (p) <= OSPF6_MESSAGE_END (oh);
1347 p += OSPF6_LSA_SIZE (p))
1349 ospf6_receive_lsa (on, (struct ospf6_lsa_header *) p);
1352 assert (p == OSPF6_MESSAGE_END (oh));
1357 ospf6_lsack_recv (struct in6_addr *src, struct in6_addr *dst,
1358 struct ospf6_interface *oi, struct ospf6_header *oh)
1360 struct ospf6_neighbor *on;
1362 struct ospf6_lsa *his, *mine;
1363 struct ospf6_lsdb *lsdb = NULL;
1365 assert (oh->type == OSPF6_MESSAGE_TYPE_LSACK);
1367 on = ospf6_neighbor_lookup (oh->router_id, oi);
1370 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1371 zlog_debug ("Neighbor not found, ignore");
1375 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1376 on->state != OSPF6_NEIGHBOR_LOADING &&
1377 on->state != OSPF6_NEIGHBOR_FULL)
1379 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1380 zlog_debug ("Neighbor state less than Exchange, ignore");
1384 for (p = (char *) ((caddr_t) oh + sizeof (struct ospf6_header));
1385 p + sizeof (struct ospf6_lsa_header) <= OSPF6_MESSAGE_END (oh);
1386 p += sizeof (struct ospf6_lsa_header))
1388 his = ospf6_lsa_create_headeronly ((struct ospf6_lsa_header *) p);
1390 switch (OSPF6_LSA_SCOPE (his->header->type))
1392 case OSPF6_SCOPE_LINKLOCAL:
1393 lsdb = on->ospf6_if->lsdb;
1395 case OSPF6_SCOPE_AREA:
1396 lsdb = on->ospf6_if->area->lsdb;
1398 case OSPF6_SCOPE_AS:
1399 lsdb = on->ospf6_if->area->ospf6->lsdb;
1401 case OSPF6_SCOPE_RESERVED:
1402 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1403 zlog_debug ("Ignoring LSA of reserved scope");
1404 ospf6_lsa_delete (his);
1409 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1410 zlog_debug ("%s acknowledged by %s", his->name, on->name);
1412 /* Find database copy */
1413 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1414 his->header->adv_router, lsdb);
1417 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1418 zlog_debug ("No database copy");
1419 ospf6_lsa_delete (his);
1423 /* Check if the LSA is on his retrans-list */
1424 mine = ospf6_lsdb_lookup (his->header->type, his->header->id,
1425 his->header->adv_router, on->retrans_list);
1428 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1429 zlog_debug ("Not on %s's retrans-list", on->name);
1430 ospf6_lsa_delete (his);
1434 if (ospf6_lsa_compare (his, mine) != 0)
1436 /* Log this questionable acknowledgement,
1437 and examine the next one. */
1438 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1439 zlog_debug ("Questionable acknowledgement");
1440 ospf6_lsa_delete (his);
1444 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1445 zlog_debug ("Acknowledged, remove from %s's retrans-list",
1448 ospf6_decrement_retrans_count (mine);
1449 if (OSPF6_LSA_IS_MAXAGE (mine))
1450 ospf6_maxage_remove (on->ospf6_if->area->ospf6);
1451 ospf6_lsdb_remove (mine, on->retrans_list);
1452 ospf6_lsa_delete (his);
1455 assert (p == OSPF6_MESSAGE_END (oh));
1458 static u_char *recvbuf = NULL;
1459 static u_char *sendbuf = NULL;
1460 static unsigned int iobuflen = 0;
1463 ospf6_iobuf_size (unsigned int size)
1465 u_char *recvnew, *sendnew;
1467 if (size <= iobuflen)
1470 recvnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1471 sendnew = XMALLOC (MTYPE_OSPF6_MESSAGE, size);
1472 if (recvnew == NULL || sendnew == NULL)
1475 XFREE (MTYPE_OSPF6_MESSAGE, recvnew);
1477 XFREE (MTYPE_OSPF6_MESSAGE, sendnew);
1478 zlog_debug ("Could not allocate I/O buffer of size %d.", size);
1483 XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1485 XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1494 ospf6_message_terminate (void)
1498 XFREE (MTYPE_OSPF6_MESSAGE, recvbuf);
1504 XFREE (MTYPE_OSPF6_MESSAGE, sendbuf);
1512 ospf6_receive (struct thread *thread)
1516 char srcname[64], dstname[64];
1517 struct in6_addr src, dst;
1519 struct iovec iovector[2];
1520 struct ospf6_interface *oi;
1521 struct ospf6_header *oh;
1523 /* add next read thread */
1524 sockfd = THREAD_FD (thread);
1525 thread_add_read (master, ospf6_receive, NULL, sockfd);
1528 memset (&src, 0, sizeof (src));
1529 memset (&dst, 0, sizeof (dst));
1531 memset (recvbuf, 0, iobuflen);
1532 iovector[0].iov_base = recvbuf;
1533 iovector[0].iov_len = iobuflen;
1534 iovector[1].iov_base = NULL;
1535 iovector[1].iov_len = 0;
1537 /* receive message */
1538 len = ospf6_recvmsg (&src, &dst, &ifindex, iovector);
1541 zlog_err ("Excess message read");
1545 oi = ospf6_interface_lookup_by_ifindex (ifindex);
1546 if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
1548 zlog_debug ("Message received on disabled interface");
1551 if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
1553 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
1554 zlog_debug ("%s: Ignore message on passive interface %s",
1555 __func__, oi->interface->name);
1559 oh = (struct ospf6_header *) recvbuf;
1560 if (ospf6_rxpacket_examin (oi, oh, len) != MSG_OK)
1563 /* Being here means, that no sizing/alignment issues were detected in
1564 the input packet. This renders the additional checks performed below
1565 and also in the type-specific dispatching functions a dead code,
1566 which can be dismissed in a cleanup-focused review round later. */
1569 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, RECV))
1571 inet_ntop (AF_INET6, &src, srcname, sizeof (srcname));
1572 inet_ntop (AF_INET6, &dst, dstname, sizeof (dstname));
1573 zlog_debug ("%s received on %s",
1574 LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name);
1575 zlog_debug (" src: %s", srcname);
1576 zlog_debug (" dst: %s", dstname);
1580 case OSPF6_MESSAGE_TYPE_HELLO:
1581 ospf6_hello_print (oh);
1583 case OSPF6_MESSAGE_TYPE_DBDESC:
1584 ospf6_dbdesc_print (oh);
1586 case OSPF6_MESSAGE_TYPE_LSREQ:
1587 ospf6_lsreq_print (oh);
1589 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1590 ospf6_lsupdate_print (oh);
1592 case OSPF6_MESSAGE_TYPE_LSACK:
1593 ospf6_lsack_print (oh);
1602 case OSPF6_MESSAGE_TYPE_HELLO:
1603 ospf6_hello_recv (&src, &dst, oi, oh);
1606 case OSPF6_MESSAGE_TYPE_DBDESC:
1607 ospf6_dbdesc_recv (&src, &dst, oi, oh);
1610 case OSPF6_MESSAGE_TYPE_LSREQ:
1611 ospf6_lsreq_recv (&src, &dst, oi, oh);
1614 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1615 ospf6_lsupdate_recv (&src, &dst, oi, oh);
1618 case OSPF6_MESSAGE_TYPE_LSACK:
1619 ospf6_lsack_recv (&src, &dst, oi, oh);
1630 ospf6_send (struct in6_addr *src, struct in6_addr *dst,
1631 struct ospf6_interface *oi, struct ospf6_header *oh)
1634 char srcname[64], dstname[64];
1635 struct iovec iovector[2];
1638 iovector[0].iov_base = (caddr_t) oh;
1639 iovector[0].iov_len = ntohs (oh->length);
1640 iovector[1].iov_base = NULL;
1641 iovector[1].iov_len = 0;
1643 /* fill OSPF header */
1644 oh->version = OSPFV3_VERSION;
1645 /* message type must be set before */
1646 /* message length must be set before */
1647 oh->router_id = oi->area->ospf6->router_id;
1648 oh->area_id = oi->area->area_id;
1649 /* checksum is calculated by kernel */
1650 oh->instance_id = oi->instance_id;
1654 if (IS_OSPF6_DEBUG_MESSAGE (oh->type, SEND))
1656 inet_ntop (AF_INET6, dst, dstname, sizeof (dstname));
1658 inet_ntop (AF_INET6, src, srcname, sizeof (srcname));
1660 memset (srcname, 0, sizeof (srcname));
1661 zlog_debug ("%s send on %s",
1662 LOOKUP (ospf6_message_type_str, oh->type), oi->interface->name);
1663 zlog_debug (" src: %s", srcname);
1664 zlog_debug (" dst: %s", dstname);
1668 case OSPF6_MESSAGE_TYPE_HELLO:
1669 ospf6_hello_print (oh);
1671 case OSPF6_MESSAGE_TYPE_DBDESC:
1672 ospf6_dbdesc_print (oh);
1674 case OSPF6_MESSAGE_TYPE_LSREQ:
1675 ospf6_lsreq_print (oh);
1677 case OSPF6_MESSAGE_TYPE_LSUPDATE:
1678 ospf6_lsupdate_print (oh);
1680 case OSPF6_MESSAGE_TYPE_LSACK:
1681 ospf6_lsack_print (oh);
1684 zlog_debug ("Unknown message");
1691 len = ospf6_sendmsg (src, dst, &oi->interface->ifindex, iovector);
1692 if (len != ntohs (oh->length))
1693 zlog_err ("Could not send entire message");
1697 ospf6_packet_max(struct ospf6_interface *oi)
1699 assert (oi->ifmtu > sizeof (struct ip6_hdr));
1700 return oi->ifmtu - (sizeof (struct ip6_hdr));
1704 ospf6_hello_send (struct thread *thread)
1706 struct ospf6_interface *oi;
1707 struct ospf6_header *oh;
1708 struct ospf6_hello *hello;
1710 struct listnode *node, *nnode;
1711 struct ospf6_neighbor *on;
1713 oi = (struct ospf6_interface *) THREAD_ARG (thread);
1714 oi->thread_send_hello = (struct thread *) NULL;
1716 if (oi->state <= OSPF6_INTERFACE_DOWN)
1718 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
1719 zlog_debug ("Unable to send Hello on down interface %s",
1720 oi->interface->name);
1726 zlog_debug ("Unable to send Hello on interface %s iobuflen is 0",
1727 oi->interface->name);
1731 /* set next thread */
1732 oi->thread_send_hello = thread_add_timer (master, ospf6_hello_send,
1733 oi, oi->hello_interval);
1735 memset (sendbuf, 0, iobuflen);
1736 oh = (struct ospf6_header *) sendbuf;
1737 hello = (struct ospf6_hello *)((caddr_t) oh + sizeof (struct ospf6_header));
1739 hello->interface_id = htonl (oi->interface->ifindex);
1740 hello->priority = oi->priority;
1741 hello->options[0] = oi->area->options[0];
1742 hello->options[1] = oi->area->options[1];
1743 hello->options[2] = oi->area->options[2];
1744 hello->hello_interval = htons (oi->hello_interval);
1745 hello->dead_interval = htons (oi->dead_interval);
1746 hello->drouter = oi->drouter;
1747 hello->bdrouter = oi->bdrouter;
1749 p = (u_char *)((caddr_t) hello + sizeof (struct ospf6_hello));
1751 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
1753 if (on->state < OSPF6_NEIGHBOR_INIT)
1756 if (p - sendbuf + sizeof (u_int32_t) > ospf6_packet_max(oi))
1758 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO, SEND))
1759 zlog_debug ("sending Hello message: exceeds I/F MTU");
1763 memcpy (p, &on->router_id, sizeof (u_int32_t));
1764 p += sizeof (u_int32_t);
1767 oh->type = OSPF6_MESSAGE_TYPE_HELLO;
1768 oh->length = htons (p - sendbuf);
1770 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
1775 ospf6_dbdesc_send (struct thread *thread)
1777 struct ospf6_neighbor *on;
1778 struct ospf6_header *oh;
1779 struct ospf6_dbdesc *dbdesc;
1781 struct ospf6_lsa *lsa;
1782 struct in6_addr *dst;
1784 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1785 on->thread_send_dbdesc = (struct thread *) NULL;
1787 if (on->state < OSPF6_NEIGHBOR_EXSTART)
1789 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC, SEND))
1790 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1791 on->name, ospf6_neighbor_state_str[on->state]);
1795 /* set next thread if master */
1796 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT))
1797 on->thread_send_dbdesc =
1798 thread_add_timer (master, ospf6_dbdesc_send, on,
1799 on->ospf6_if->rxmt_interval);
1801 memset (sendbuf, 0, iobuflen);
1802 oh = (struct ospf6_header *) sendbuf;
1803 dbdesc = (struct ospf6_dbdesc *)((caddr_t) oh +
1804 sizeof (struct ospf6_header));
1806 /* if this is initial one, initialize sequence number for DbDesc */
1807 if (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) &&
1808 (on->dbdesc_seqnum == 0))
1811 if (quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv) < 0)
1813 on->dbdesc_seqnum = tv.tv_sec;
1816 dbdesc->options[0] = on->ospf6_if->area->options[0];
1817 dbdesc->options[1] = on->ospf6_if->area->options[1];
1818 dbdesc->options[2] = on->ospf6_if->area->options[2];
1819 dbdesc->ifmtu = htons (on->ospf6_if->ifmtu);
1820 dbdesc->bits = on->dbdesc_bits;
1821 dbdesc->seqnum = htonl (on->dbdesc_seqnum);
1823 /* if this is not initial one, set LSA headers in dbdesc */
1824 p = (u_char *)((caddr_t) dbdesc + sizeof (struct ospf6_dbdesc));
1825 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT))
1827 for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
1828 lsa = ospf6_lsdb_next (lsa))
1830 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
1833 if (p - sendbuf + sizeof (struct ospf6_lsa_header) >
1834 ospf6_packet_max(on->ospf6_if))
1836 ospf6_lsdb_lsa_unlock (lsa);
1839 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
1840 p += sizeof (struct ospf6_lsa_header);
1844 oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
1845 oh->length = htons (p - sendbuf);
1848 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
1849 dst = &allspfrouters6;
1851 dst = &on->linklocal_addr;
1853 ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh);
1859 ospf6_dbdesc_send_newone (struct thread *thread)
1861 struct ospf6_neighbor *on;
1862 struct ospf6_lsa *lsa;
1863 unsigned int size = 0;
1865 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1866 ospf6_lsdb_remove_all (on->dbdesc_list);
1868 /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1869 so that ospf6_send_dbdesc () can send those LSAs */
1870 size = sizeof (struct ospf6_lsa_header) + sizeof (struct ospf6_dbdesc);
1871 for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
1872 lsa = ospf6_lsdb_next (lsa))
1874 if (size + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
1876 ospf6_lsdb_lsa_unlock (lsa);
1880 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->dbdesc_list);
1881 ospf6_lsdb_remove (lsa, on->summary_list);
1882 size += sizeof (struct ospf6_lsa_header);
1885 if (on->summary_list->count == 0)
1886 UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
1888 /* If slave, More bit check must be done here */
1889 if (! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) && /* Slave */
1890 ! CHECK_FLAG (on->dbdesc_last.bits, OSPF6_DBDESC_MBIT) &&
1891 ! CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT))
1892 thread_add_event (master, exchange_done, on, 0);
1894 thread_execute (master, ospf6_dbdesc_send, on, 0);
1899 ospf6_lsreq_send (struct thread *thread)
1901 struct ospf6_neighbor *on;
1902 struct ospf6_header *oh;
1903 struct ospf6_lsreq_entry *e;
1905 struct ospf6_lsa *lsa, *last_req;
1907 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1908 on->thread_send_lsreq = (struct thread *) NULL;
1910 /* LSReq will be sent only in ExStart or Loading */
1911 if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
1912 on->state != OSPF6_NEIGHBOR_LOADING)
1914 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ, SEND))
1915 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1916 on->name, ospf6_neighbor_state_str[on->state]);
1920 /* schedule loading_done if request list is empty */
1921 if (on->request_list->count == 0)
1923 thread_add_event (master, loading_done, on, 0);
1927 memset (sendbuf, 0, iobuflen);
1928 oh = (struct ospf6_header *) sendbuf;
1931 /* set Request entries in lsreq */
1932 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
1933 for (lsa = ospf6_lsdb_head (on->request_list); lsa;
1934 lsa = ospf6_lsdb_next (lsa))
1937 if (p - sendbuf + sizeof (struct ospf6_lsreq_entry) > ospf6_packet_max(on->ospf6_if))
1939 ospf6_lsdb_lsa_unlock (lsa);
1943 e = (struct ospf6_lsreq_entry *) p;
1944 e->type = lsa->header->type;
1945 e->id = lsa->header->id;
1946 e->adv_router = lsa->header->adv_router;
1947 p += sizeof (struct ospf6_lsreq_entry);
1951 if (last_req != NULL)
1953 if (on->last_ls_req != NULL)
1955 ospf6_lsa_unlock (on->last_ls_req);
1957 ospf6_lsa_lock (last_req);
1958 on->last_ls_req = last_req;
1961 oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
1962 oh->length = htons (p - sendbuf);
1964 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
1965 ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
1968 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
1971 /* set next thread */
1972 if (on->request_list->count != 0)
1974 on->thread_send_lsreq =
1975 thread_add_timer (master, ospf6_lsreq_send, on,
1976 on->ospf6_if->rxmt_interval);
1983 ospf6_lsupdate_send_neighbor (struct thread *thread)
1985 struct ospf6_neighbor *on;
1986 struct ospf6_header *oh;
1987 struct ospf6_lsupdate *lsupdate;
1990 struct ospf6_lsa *lsa;
1992 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
1993 on->thread_send_lsupdate = (struct thread *) NULL;
1995 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
1996 zlog_debug ("LSUpdate to neighbor %s", on->name);
1998 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
2000 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2001 zlog_debug ("Quit to send (neighbor state %s)",
2002 ospf6_neighbor_state_str[on->state]);
2006 memset (sendbuf, 0, iobuflen);
2007 oh = (struct ospf6_header *) sendbuf;
2008 lsupdate = (struct ospf6_lsupdate *)
2009 ((caddr_t) oh + sizeof (struct ospf6_header));
2011 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2014 /* lsupdate_list lists those LSA which doesn't need to be
2015 retransmitted. remove those from the list */
2016 for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
2017 lsa = ospf6_lsdb_next (lsa))
2020 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
2021 > ospf6_packet_max(on->ospf6_if))
2023 ospf6_lsdb_lsa_unlock (lsa);
2027 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2028 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2029 p += OSPF6_LSA_SIZE (lsa->header);
2032 assert (lsa->lock == 2);
2033 ospf6_lsdb_remove (lsa, on->lsupdate_list);
2038 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2039 oh->length = htons (p - sendbuf);
2040 lsupdate->lsa_number = htonl (lsa_cnt);
2042 if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2043 (on->ospf6_if->state == OSPF6_INTERFACE_DR) ||
2044 (on->ospf6_if->state == OSPF6_INTERFACE_BDR))
2045 ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
2048 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2052 /* The addresses used for retransmissions are different from those sent the
2053 first time and so we need to separate them here.
2055 memset (sendbuf, 0, iobuflen);
2056 oh = (struct ospf6_header *) sendbuf;
2057 lsupdate = (struct ospf6_lsupdate *)
2058 ((caddr_t) oh + sizeof (struct ospf6_header));
2059 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2062 for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
2063 lsa = ospf6_lsdb_next (lsa))
2066 if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
2067 > ospf6_packet_max(on->ospf6_if))
2069 ospf6_lsdb_lsa_unlock (lsa);
2073 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2074 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2075 p += OSPF6_LSA_SIZE (lsa->header);
2081 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2082 oh->length = htons (p - sendbuf);
2083 lsupdate->lsa_number = htonl (lsa_cnt);
2085 if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
2086 ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
2089 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2093 if (on->lsupdate_list->count != 0)
2094 on->thread_send_lsupdate =
2095 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
2096 else if (on->retrans_list->count != 0)
2097 on->thread_send_lsupdate =
2098 thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
2099 on->ospf6_if->rxmt_interval);
2104 ospf6_lsupdate_send_interface (struct thread *thread)
2106 struct ospf6_interface *oi;
2107 struct ospf6_header *oh;
2108 struct ospf6_lsupdate *lsupdate;
2111 struct ospf6_lsa *lsa;
2113 oi = (struct ospf6_interface *) THREAD_ARG (thread);
2114 oi->thread_send_lsupdate = (struct thread *) NULL;
2116 if (oi->state <= OSPF6_INTERFACE_WAITING)
2118 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
2119 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
2120 oi->interface->name, ospf6_interface_state_str[oi->state]);
2124 /* if we have nothing to send, return */
2125 if (oi->lsupdate_list->count == 0)
2128 memset (sendbuf, 0, iobuflen);
2129 oh = (struct ospf6_header *) sendbuf;
2130 lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
2131 sizeof (struct ospf6_header));
2133 p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
2136 for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
2137 lsa = ospf6_lsdb_next (lsa))
2140 if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
2141 > ospf6_packet_max(oi))
2143 ospf6_lsdb_lsa_unlock (lsa);
2147 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
2148 memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
2149 p += OSPF6_LSA_SIZE (lsa->header);
2152 assert (lsa->lock == 2);
2153 ospf6_lsdb_remove (lsa, oi->lsupdate_list);
2158 lsupdate->lsa_number = htonl (lsa_cnt);
2160 oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2161 oh->length = htons (p - sendbuf);
2163 if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2164 (oi->state == OSPF6_INTERFACE_DR) ||
2165 (oi->state == OSPF6_INTERFACE_BDR))
2166 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
2168 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
2172 if (oi->lsupdate_list->count > 0)
2174 oi->thread_send_lsupdate =
2175 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
2182 ospf6_lsack_send_neighbor (struct thread *thread)
2184 struct ospf6_neighbor *on;
2185 struct ospf6_header *oh;
2187 struct ospf6_lsa *lsa;
2190 on = (struct ospf6_neighbor *) THREAD_ARG (thread);
2191 on->thread_send_lsack = (struct thread *) NULL;
2193 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
2195 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
2196 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
2197 on->name, ospf6_neighbor_state_str[on->state]);
2201 /* if we have nothing to send, return */
2202 if (on->lsack_list->count == 0)
2205 memset (sendbuf, 0, iobuflen);
2206 oh = (struct ospf6_header *) sendbuf;
2208 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
2210 for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
2211 lsa = ospf6_lsdb_next (lsa))
2214 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
2216 /* if we run out of packet size/space here,
2217 better to try again soon. */
2218 THREAD_OFF (on->thread_send_lsack);
2219 on->thread_send_lsack =
2220 thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
2222 ospf6_lsdb_lsa_unlock (lsa);
2226 ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
2227 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
2228 p += sizeof (struct ospf6_lsa_header);
2230 assert (lsa->lock == 2);
2231 ospf6_lsdb_remove (lsa, on->lsack_list);
2237 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2238 oh->length = htons (p - sendbuf);
2240 ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
2244 if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
2246 on->thread_send_lsack =
2247 thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
2254 ospf6_lsack_send_interface (struct thread *thread)
2256 struct ospf6_interface *oi;
2257 struct ospf6_header *oh;
2259 struct ospf6_lsa *lsa;
2262 oi = (struct ospf6_interface *) THREAD_ARG (thread);
2263 oi->thread_send_lsack = (struct thread *) NULL;
2265 if (oi->state <= OSPF6_INTERFACE_WAITING)
2267 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK, SEND))
2268 zlog_debug ("Quit to send LSAck to interface %s state %s",
2269 oi->interface->name, ospf6_interface_state_str[oi->state]);
2273 /* if we have nothing to send, return */
2274 if (oi->lsack_list->count == 0)
2277 memset (sendbuf, 0, iobuflen);
2278 oh = (struct ospf6_header *) sendbuf;
2280 p = (u_char *)((caddr_t) oh + sizeof (struct ospf6_header));
2282 for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
2283 lsa = ospf6_lsdb_next (lsa))
2286 if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
2288 /* if we run out of packet size/space here,
2289 better to try again soon. */
2290 THREAD_OFF (oi->thread_send_lsack);
2291 oi->thread_send_lsack =
2292 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
2294 ospf6_lsdb_lsa_unlock (lsa);
2298 ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
2299 memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
2300 p += sizeof (struct ospf6_lsa_header);
2302 assert (lsa->lock == 2);
2303 ospf6_lsdb_remove (lsa, oi->lsack_list);
2309 oh->type = OSPF6_MESSAGE_TYPE_LSACK;
2310 oh->length = htons (p - sendbuf);
2312 if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
2313 (oi->state == OSPF6_INTERFACE_DR) ||
2314 (oi->state == OSPF6_INTERFACE_BDR))
2315 ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
2317 ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
2320 if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
2322 oi->thread_send_lsack =
2323 thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
2331 DEFUN (debug_ospf6_message,
2332 debug_ospf6_message_cmd,
2333 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
2336 "Debug OSPFv3 message\n"
2337 "Debug Unknown message\n"
2338 "Debug Hello message\n"
2339 "Debug Database Description message\n"
2340 "Debug Link State Request message\n"
2341 "Debug Link State Update message\n"
2342 "Debug Link State Acknowledgement message\n"
2343 "Debug All message\n"
2346 unsigned char level = 0;
2353 if (! strncmp (argv[0], "u", 1))
2354 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
2355 else if (! strncmp (argv[0], "h", 1))
2356 type = OSPF6_MESSAGE_TYPE_HELLO;
2357 else if (! strncmp (argv[0], "d", 1))
2358 type = OSPF6_MESSAGE_TYPE_DBDESC;
2359 else if (! strncmp (argv[0], "lsr", 3))
2360 type = OSPF6_MESSAGE_TYPE_LSREQ;
2361 else if (! strncmp (argv[0], "lsu", 3))
2362 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2363 else if (! strncmp (argv[0], "lsa", 3))
2364 type = OSPF6_MESSAGE_TYPE_LSACK;
2365 else if (! strncmp (argv[0], "a", 1))
2366 type = OSPF6_MESSAGE_TYPE_ALL;
2369 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
2370 else if (! strncmp (argv[1], "s", 1))
2371 level = OSPF6_DEBUG_MESSAGE_SEND;
2372 else if (! strncmp (argv[1], "r", 1))
2373 level = OSPF6_DEBUG_MESSAGE_RECV;
2375 if (type == OSPF6_MESSAGE_TYPE_ALL)
2377 for (i = 0; i < 6; i++)
2378 OSPF6_DEBUG_MESSAGE_ON (i, level);
2381 OSPF6_DEBUG_MESSAGE_ON (type, level);
2386 ALIAS (debug_ospf6_message,
2387 debug_ospf6_message_sendrecv_cmd,
2388 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2391 "Debug OSPFv3 message\n"
2392 "Debug Unknown message\n"
2393 "Debug Hello message\n"
2394 "Debug Database Description message\n"
2395 "Debug Link State Request message\n"
2396 "Debug Link State Update message\n"
2397 "Debug Link State Acknowledgement message\n"
2398 "Debug All message\n"
2399 "Debug only sending message\n"
2400 "Debug only receiving message\n"
2404 DEFUN (no_debug_ospf6_message,
2405 no_debug_ospf6_message_cmd,
2406 "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
2410 "Debug OSPFv3 message\n"
2411 "Debug Unknown message\n"
2412 "Debug Hello message\n"
2413 "Debug Database Description message\n"
2414 "Debug Link State Request message\n"
2415 "Debug Link State Update message\n"
2416 "Debug Link State Acknowledgement message\n"
2417 "Debug All message\n"
2420 unsigned char level = 0;
2427 if (! strncmp (argv[0], "u", 1))
2428 type = OSPF6_MESSAGE_TYPE_UNKNOWN;
2429 else if (! strncmp (argv[0], "h", 1))
2430 type = OSPF6_MESSAGE_TYPE_HELLO;
2431 else if (! strncmp (argv[0], "d", 1))
2432 type = OSPF6_MESSAGE_TYPE_DBDESC;
2433 else if (! strncmp (argv[0], "lsr", 3))
2434 type = OSPF6_MESSAGE_TYPE_LSREQ;
2435 else if (! strncmp (argv[0], "lsu", 3))
2436 type = OSPF6_MESSAGE_TYPE_LSUPDATE;
2437 else if (! strncmp (argv[0], "lsa", 3))
2438 type = OSPF6_MESSAGE_TYPE_LSACK;
2439 else if (! strncmp (argv[0], "a", 1))
2440 type = OSPF6_MESSAGE_TYPE_ALL;
2443 level = OSPF6_DEBUG_MESSAGE_SEND | OSPF6_DEBUG_MESSAGE_RECV;
2444 else if (! strncmp (argv[1], "s", 1))
2445 level = OSPF6_DEBUG_MESSAGE_SEND;
2446 else if (! strncmp (argv[1], "r", 1))
2447 level = OSPF6_DEBUG_MESSAGE_RECV;
2449 if (type == OSPF6_MESSAGE_TYPE_ALL)
2451 for (i = 0; i < 6; i++)
2452 OSPF6_DEBUG_MESSAGE_OFF (i, level);
2455 OSPF6_DEBUG_MESSAGE_OFF (type, level);
2460 ALIAS (no_debug_ospf6_message,
2461 no_debug_ospf6_message_sendrecv_cmd,
2462 "no debug ospf6 message "
2463 "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2467 "Debug OSPFv3 message\n"
2468 "Debug Unknown message\n"
2469 "Debug Hello message\n"
2470 "Debug Database Description message\n"
2471 "Debug Link State Request message\n"
2472 "Debug Link State Update message\n"
2473 "Debug Link State Acknowledgement message\n"
2474 "Debug All message\n"
2475 "Debug only sending message\n"
2476 "Debug only receiving message\n"
2480 config_write_ospf6_debug_message (struct vty *vty)
2482 const char *type_str[] = {"unknown", "hello", "dbdesc",
2483 "lsreq", "lsupdate", "lsack"};
2484 unsigned char s = 0, r = 0;
2487 for (i = 0; i < 6; i++)
2489 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2491 if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2495 if (s == 0x3f && r == 0x3f)
2497 vty_out (vty, "debug ospf6 message all%s", VNL);
2501 if (s == 0x3f && r == 0)
2503 vty_out (vty, "debug ospf6 message all send%s", VNL);
2506 else if (s == 0 && r == 0x3f)
2508 vty_out (vty, "debug ospf6 message all recv%s", VNL);
2512 /* Unknown message is logged by default */
2513 if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND) &&
2514 ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
2515 vty_out (vty, "no debug ospf6 message unknown%s", VNL);
2516 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, SEND))
2517 vty_out (vty, "no debug ospf6 message unknown send%s", VNL);
2518 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN, RECV))
2519 vty_out (vty, "no debug ospf6 message unknown recv%s", VNL);
2521 for (i = 1; i < 6; i++)
2523 if (IS_OSPF6_DEBUG_MESSAGE (i, SEND) &&
2524 IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2525 vty_out (vty, "debug ospf6 message %s%s", type_str[i], VNL);
2526 else if (IS_OSPF6_DEBUG_MESSAGE (i, SEND))
2527 vty_out (vty, "debug ospf6 message %s send%s", type_str[i],
2529 else if (IS_OSPF6_DEBUG_MESSAGE (i, RECV))
2530 vty_out (vty, "debug ospf6 message %s recv%s", type_str[i],
2538 install_element_ospf6_debug_message (void)
2540 install_element (ENABLE_NODE, &debug_ospf6_message_cmd);
2541 install_element (ENABLE_NODE, &no_debug_ospf6_message_cmd);
2542 install_element (ENABLE_NODE, &debug_ospf6_message_sendrecv_cmd);
2543 install_element (ENABLE_NODE, &no_debug_ospf6_message_sendrecv_cmd);
2544 install_element (CONFIG_NODE, &debug_ospf6_message_cmd);
2545 install_element (CONFIG_NODE, &no_debug_ospf6_message_cmd);
2546 install_element (CONFIG_NODE, &debug_ospf6_message_sendrecv_cmd);
2547 install_element (CONFIG_NODE, &no_debug_ospf6_message_sendrecv_cmd);