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 const char *ospf6_message_type_str
[] =
54 { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };
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
] =
62 OSPF6_DB_DESC_MIN_SIZE
,
63 OSPF6_LS_REQ_MIN_SIZE
,
64 OSPF6_LS_UPD_MIN_SIZE
,
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
] =
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
,
79 /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
,
80 /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE
,
81 /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
87 ospf6_header_print (struct ospf6_header
*oh
)
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
));
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
);
100 ospf6_hello_print (struct ospf6_header
*oh
)
102 struct ospf6_hello
*hello
;
104 char drouter
[16], bdrouter
[16], neighbor
[16];
107 ospf6_header_print (oh
);
108 assert (oh
->type
== OSPF6_MESSAGE_TYPE_HELLO
);
110 hello
= (struct ospf6_hello
*)
111 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
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
));
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
);
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
))
127 inet_ntop (AF_INET
, (void *) p
, neighbor
, sizeof (neighbor
));
128 zlog_debug (" Neighbor: %s", neighbor
);
131 if (p
!= OSPF6_MESSAGE_END (oh
))
132 zlog_debug ("Trailing garbage exists");
136 ospf6_dbdesc_print (struct ospf6_header
*oh
)
138 struct ospf6_dbdesc
*dbdesc
;
142 ospf6_header_print (oh
);
143 assert (oh
->type
== OSPF6_MESSAGE_TYPE_DBDESC
);
145 dbdesc
= (struct ospf6_dbdesc
*)
146 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
148 ospf6_options_printbuf (dbdesc
->options
, options
, sizeof (options
));
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",
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
));
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
);
164 if (p
!= OSPF6_MESSAGE_END (oh
))
165 zlog_debug ("Trailing garbage exists");
169 ospf6_lsreq_print (struct ospf6_header
*oh
)
171 char id
[16], adv_router
[16];
174 ospf6_header_print (oh
);
175 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSREQ
);
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
))
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
);
188 if (p
!= OSPF6_MESSAGE_END (oh
))
189 zlog_debug ("Trailing garbage exists");
193 ospf6_lsupdate_print (struct ospf6_header
*oh
)
195 struct ospf6_lsupdate
*lsupdate
;
199 ospf6_header_print (oh
);
200 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSUPDATE
);
202 lsupdate
= (struct ospf6_lsupdate
*)
203 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
205 num
= ntohl (lsupdate
->lsa_number
);
206 zlog_debug (" Number of LSA: %ld", num
);
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
))
213 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
214 if (OSPF6_LSA_SIZE (p
) < sizeof (struct ospf6_lsa_header
))
216 zlog_debug (" Malformed LSA length, quit printing");
221 if (p
!= OSPF6_MESSAGE_END (oh
))
226 memset (buf
, 0, sizeof (buf
));
228 zlog_debug (" Trailing garbage exists");
229 while (p
< OSPF6_MESSAGE_END (oh
))
231 snprintf (buf
, sizeof (buf
), "%s %2x", buf
, *p
++);
235 zlog_debug (" %s", buf
);
236 memset (buf
, 0, sizeof (buf
));
241 zlog_debug (" %s", buf
);
246 ospf6_lsack_print (struct ospf6_header
*oh
)
250 ospf6_header_print (oh
);
251 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
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
);
258 if (p
!= OSPF6_MESSAGE_END (oh
))
259 zlog_debug ("Trailing garbage exists");
263 ospf6_hello_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
264 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
266 struct ospf6_hello
*hello
;
267 struct ospf6_neighbor
*on
;
270 int neighborchange
= 0;
273 hello
= (struct ospf6_hello
*)
274 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
276 /* HelloInterval check */
277 if (ntohs (hello
->hello_interval
) != oi
->hello_interval
)
279 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
280 zlog_debug ("HelloInterval mismatch");
284 /* RouterDeadInterval check */
285 if (ntohs (hello
->dead_interval
) != oi
->dead_interval
)
287 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
288 zlog_debug ("RouterDeadInterval mismatch");
293 if (OSPF6_OPT_ISSET (hello
->options
, OSPF6_OPT_E
) !=
294 OSPF6_OPT_ISSET (oi
->area
->options
, OSPF6_OPT_E
))
296 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
297 zlog_debug ("E-bit mismatch");
301 /* Find neighbor, create if not exist */
302 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
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
;
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
));
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
))
320 u_int32_t
*router_id
= (u_int32_t
*) p
;
322 if (*router_id
== oi
->area
->ospf6
->router_id
)
326 if (p
!= OSPF6_MESSAGE_END (oh
))
328 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
329 zlog_debug ("Trailing garbage ignored");
332 /* RouterPriority check */
333 if (on
->priority
!= hello
->priority
)
335 on
->priority
= hello
->priority
;
340 if (on
->drouter
!= hello
->drouter
)
342 on
->prev_drouter
= on
->drouter
;
343 on
->drouter
= hello
->drouter
;
344 if (on
->prev_drouter
== on
->router_id
|| on
->drouter
== on
->router_id
)
349 if (on
->bdrouter
!= hello
->bdrouter
)
351 on
->prev_bdrouter
= on
->bdrouter
;
352 on
->bdrouter
= hello
->bdrouter
;
353 if (on
->prev_bdrouter
== on
->router_id
|| on
->bdrouter
== on
->router_id
)
357 /* BackupSeen check */
358 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
360 if (hello
->bdrouter
== on
->router_id
)
362 else if (hello
->drouter
== on
->router_id
&& hello
->bdrouter
== htonl (0))
366 /* Execute neighbor events */
367 thread_execute (master
, hello_received
, on
, 0);
369 thread_execute (master
, twoway_received
, on
, 0);
371 thread_execute (master
, oneway_received
, on
, 0);
373 /* Schedule interface events */
375 thread_add_event (master
, backup_seen
, oi
, 0);
377 thread_add_event (master
, neighbor_change
, oi
, 0);
381 ospf6_dbdesc_recv_master (struct ospf6_header
*oh
,
382 struct ospf6_neighbor
*on
)
384 struct ospf6_dbdesc
*dbdesc
;
387 dbdesc
= (struct ospf6_dbdesc
*)
388 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
390 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
392 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
393 zlog_debug ("Neighbor state less than Init, ignore");
399 case OSPF6_NEIGHBOR_TWOWAY
:
400 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
401 zlog_debug ("Neighbor state is 2-Way, ignore");
404 case OSPF6_NEIGHBOR_INIT
:
405 thread_execute (master
, twoway_received
, on
, 0);
406 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
)
408 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
409 zlog_debug ("Neighbor state is not ExStart, ignore");
412 /* else fall through to ExStart */
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
)
421 /* execute NegotiationDone */
422 thread_execute (master
, negotiation_done
, on
, 0);
424 /* Record neighbor options */
425 memcpy (on
->options
, dbdesc
->options
, sizeof (on
->options
));
429 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
430 zlog_debug ("Negotiation failed");
433 /* fall through to exchange */
435 case OSPF6_NEIGHBOR_EXCHANGE
:
436 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
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");
444 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
))
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);
452 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
))
454 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
455 zlog_debug ("Initialize bit mismatch");
456 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
460 if (memcmp (on
->options
, dbdesc
->options
, sizeof (on
->options
)))
462 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
463 zlog_debug ("Option field mismatch");
464 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
468 if (ntohl (dbdesc
->seqnum
) != on
->dbdesc_seqnum
)
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);
478 case OSPF6_NEIGHBOR_LOADING
:
479 case OSPF6_NEIGHBOR_FULL
:
480 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
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");
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);
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
))
504 struct ospf6_lsa
*his
, *mine
;
505 struct ospf6_lsdb
*lsdb
= NULL
;
507 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
509 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
510 zlog_debug ("%s", his
->name
);
512 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
514 case OSPF6_SCOPE_LINKLOCAL
:
515 lsdb
= on
->ospf6_if
->lsdb
;
517 case OSPF6_SCOPE_AREA
:
518 lsdb
= on
->ospf6_if
->area
->lsdb
;
521 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
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
);
531 if (ntohs (his
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
532 IS_AREA_STUB (on
->ospf6_if
->area
))
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);
541 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
542 his
->header
->adv_router
, lsdb
);
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
);
549 else if (ospf6_lsa_compare (his
, mine
) < 0)
551 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
552 zlog_debug ("Add request (Received MoreRecent)");
553 ospf6_lsdb_add (his
, on
->request_list
);
557 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
558 zlog_debug ("Discard (Existing MoreRecent)");
559 ospf6_lsa_delete (his
);
563 if (p
!= OSPF6_MESSAGE_END (oh
))
565 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
566 zlog_debug ("Trailing garbage ignored");
569 /* Increment sequence number */
570 on
->dbdesc_seqnum
++;
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);
577 THREAD_OFF (on
->thread_send_dbdesc
);
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);
584 on
->thread_send_dbdesc
=
585 thread_add_event (master
, ospf6_dbdesc_send_newone
, on
, 0);
587 /* save last received dbdesc */
588 memcpy (&on
->dbdesc_last
, dbdesc
, sizeof (struct ospf6_dbdesc
));
592 ospf6_dbdesc_recv_slave (struct ospf6_header
*oh
,
593 struct ospf6_neighbor
*on
)
595 struct ospf6_dbdesc
*dbdesc
;
598 dbdesc
= (struct ospf6_dbdesc
*)
599 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
601 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
603 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
604 zlog_debug ("Neighbor state less than Init, ignore");
610 case OSPF6_NEIGHBOR_TWOWAY
:
611 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
612 zlog_debug ("Neighbor state is 2-Way, ignore");
615 case OSPF6_NEIGHBOR_INIT
:
616 thread_execute (master
, twoway_received
, on
, 0);
617 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
)
619 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
620 zlog_debug ("Neighbor state is not ExStart, ignore");
623 /* else fall through to ExStart */
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
))
634 /* set the master/slave bit to slave */
635 UNSET_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
);
637 /* set the DD sequence number to one specified by master */
638 on
->dbdesc_seqnum
= ntohl (dbdesc
->seqnum
);
640 /* schedule NegotiationDone */
641 thread_execute (master
, negotiation_done
, on
, 0);
643 /* Record neighbor options */
644 memcpy (on
->options
, dbdesc
->options
, sizeof (on
->options
));
648 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
649 zlog_debug ("Negotiation failed");
654 case OSPF6_NEIGHBOR_EXCHANGE
:
655 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
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);
666 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
))
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);
674 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
))
676 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
677 zlog_debug ("Initialize bit mismatch");
678 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
682 if (memcmp (on
->options
, dbdesc
->options
, sizeof (on
->options
)))
684 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
685 zlog_debug ("Option field mismatch");
686 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
690 if (ntohl (dbdesc
->seqnum
) != on
->dbdesc_seqnum
+ 1)
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);
700 case OSPF6_NEIGHBOR_LOADING
:
701 case OSPF6_NEIGHBOR_FULL
:
702 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
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);
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);
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
))
729 struct ospf6_lsa
*his
, *mine
;
730 struct ospf6_lsdb
*lsdb
= NULL
;
732 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
734 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
736 case OSPF6_SCOPE_LINKLOCAL
:
737 lsdb
= on
->ospf6_if
->lsdb
;
739 case OSPF6_SCOPE_AREA
:
740 lsdb
= on
->ospf6_if
->area
->lsdb
;
743 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
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
);
753 if (OSPF6_LSA_SCOPE (his
->header
->type
) == OSPF6_SCOPE_AS
&&
754 IS_AREA_STUB (on
->ospf6_if
->area
))
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);
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)
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
);
772 ospf6_lsa_delete (his
);
775 if (p
!= OSPF6_MESSAGE_END (oh
))
777 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
778 zlog_debug ("Trailing garbage ignored");
781 /* Set sequence number to Master's */
782 on
->dbdesc_seqnum
= ntohl (dbdesc
->seqnum
);
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);
789 THREAD_OFF (on
->thread_send_dbdesc
);
790 on
->thread_send_dbdesc
=
791 thread_add_event (master
, ospf6_dbdesc_send_newone
, on
, 0);
793 /* save last received dbdesc */
794 memcpy (&on
->dbdesc_last
, dbdesc
, sizeof (struct ospf6_dbdesc
));
798 ospf6_dbdesc_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
799 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
801 struct ospf6_neighbor
*on
;
802 struct ospf6_dbdesc
*dbdesc
;
804 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
807 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
808 zlog_debug ("Neighbor not found, ignore");
812 dbdesc
= (struct ospf6_dbdesc
*)
813 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
815 /* Interface MTU check */
816 if (!oi
->mtu_ignore
&& ntohs (dbdesc
->ifmtu
) != oi
->ifmtu
)
818 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
819 zlog_debug ("I/F MTU mismatch");
823 if (dbdesc
->reserved1
|| dbdesc
->reserved2
)
825 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
826 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
828 dbdesc
->reserved1
= 0;
829 dbdesc
->reserved2
= 0;
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
);
838 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
839 zlog_debug ("Can't decide which is master, ignore");
844 ospf6_lsreq_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
845 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
847 struct ospf6_neighbor
*on
;
849 struct ospf6_lsreq_entry
*e
;
850 struct ospf6_lsdb
*lsdb
= NULL
;
851 struct ospf6_lsa
*lsa
;
853 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
856 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
857 zlog_debug ("Neighbor not found, ignore");
861 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
862 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
863 on
->state
!= OSPF6_NEIGHBOR_FULL
)
865 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
866 zlog_debug ("Neighbor state less than Exchange, ignore");
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
))
875 e
= (struct ospf6_lsreq_entry
*) p
;
877 switch (OSPF6_LSA_SCOPE (e
->type
))
879 case OSPF6_SCOPE_LINKLOCAL
:
880 lsdb
= on
->ospf6_if
->lsdb
;
882 case OSPF6_SCOPE_AREA
:
883 lsdb
= on
->ospf6_if
->area
->lsdb
;
886 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
889 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
890 zlog_debug ("Ignoring LSA of reserved scope");
895 /* Find database copy */
896 lsa
= ospf6_lsdb_lookup (e
->type
, e
->id
, e
->adv_router
, lsdb
);
899 char id
[16], adv_router
[16];
900 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
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
);
908 thread_add_event (master
, bad_lsreq
, on
, 0);
912 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->lsupdate_list
);
915 if (p
!= OSPF6_MESSAGE_END (oh
))
917 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
918 zlog_debug ("Trailing garbage ignored");
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);
927 /* Verify, that the specified memory area contains exactly N valid IPv6
928 prefixes as specified by RFC5340, A.4.1. */
930 ospf6_prefixes_examin
932 struct ospf6_prefix
*current
, /* start of buffer */
934 const u_int32_t req_num_pfxs
/* always compared with the actual number of prefixes */
937 u_char requested_pfx_bytes
;
938 u_int32_t real_num_pfxs
= 0;
942 if (length
< OSPF6_PREFIX_MIN_SIZE
)
944 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
945 zlog_debug ("%s: undersized IPv6 prefix header", __func__
);
948 /* safe to look deeper */
949 if (current
->prefix_length
> IPV6_MAX_BITLEN
)
951 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
952 zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__
, current
->prefix_length
);
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
)
959 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
960 zlog_debug ("%s: undersized IPv6 prefix", __func__
);
964 length
-= requested_pfx_bytes
;
965 current
= (struct ospf6_prefix
*) ((caddr_t
) current
+ requested_pfx_bytes
);
968 if (real_num_pfxs
!= req_num_pfxs
)
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
);
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. */
984 ospf6_lsa_examin (struct ospf6_lsa_header
*lsah
, const u_int16_t lsalen
, const u_char headeronly
)
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
;
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
;
999 ltindex
< OSPF6_LSTYPE_SIZE
&&
1000 ospf6_lsa_minlen
[ltindex
] &&
1001 lsalen
< ospf6_lsa_minlen
[ltindex
] + OSPF6_LSA_HEADER_SIZE
1004 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1005 zlog_debug ("%s: undersized (%u B) LSA", __func__
, lsalen
);
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
)
1015 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1016 zlog_debug ("%s: interface description alignment error", __func__
);
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
)
1025 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1026 zlog_debug ("%s: router description alignment error", __func__
);
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. */
1035 return ospf6_prefixes_examin
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
,
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
)
1045 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1046 zlog_debug ("%s: oversized (%u B) LSA", __func__
, lsalen
);
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. */
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
)
1065 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1066 zlog_debug ("%s: undersized (%u B) LSA header", __func__
, lsalen
);
1069 /* forwarding address */
1070 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
))
1072 /* external route tag */
1073 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
))
1075 /* referenced link state ID */
1076 if (as_external_lsa
->prefix
.u
._prefix_referenced_lstype
)
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
)
1082 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1083 zlog_debug ("%s: undersized (%u B) LSA header", __func__
, lsalen
);
1086 /* The last call completely covers the remainder (IPv6 prefix). */
1087 return ospf6_prefixes_examin
1089 (struct ospf6_prefix
*) ((caddr_t
) as_external_lsa
+ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
),
1090 lsalen
- exp_length
,
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). */
1098 link_lsa
= (struct ospf6_link_lsa
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1099 return ospf6_prefixes_examin
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 */
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). */
1110 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1111 return ospf6_prefixes_examin
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 */
1118 /* No additional validation is possible for unknown LSA types, which are
1119 themselves valid in OPSFv3, hence the default decision is to accept. */
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. */
1129 struct ospf6_lsa_header
*lsah
, /* start of buffered data */
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
1137 u_int32_t counted_lsas
= 0;
1142 if (length
< OSPF6_LSA_HEADER_SIZE
)
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
);
1149 /* save on ntohs() calls here and in the LSA validator */
1150 lsalen
= OSPF6_LSA_SIZE (lsah
);
1151 if (lsalen
< OSPF6_LSA_HEADER_SIZE
)
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
);
1160 /* less checks here and in ospf6_lsa_examin() */
1161 if (MSG_OK
!= ospf6_lsa_examin (lsah
, lsalen
, 1))
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
);
1168 lsah
= (struct ospf6_lsa_header
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1169 length
-= OSPF6_LSA_HEADER_SIZE
;
1173 /* make sure the input buffer is deep enough before further checks */
1174 if (lsalen
> length
)
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
);
1181 if (MSG_OK
!= ospf6_lsa_examin (lsah
, lsalen
, 0))
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
);
1188 lsah
= (struct ospf6_lsa_header
*) ((caddr_t
) lsah
+ lsalen
);
1194 if (declared_num_lsas
&& counted_lsas
!= declared_num_lsas
)
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
);
1204 /* Verify a complete OSPF packet for proper sizing/alignment. */
1206 ospf6_packet_examin (struct ospf6_header
*oh
, const unsigned bytesonwire
)
1208 struct ospf6_lsupdate
*lsupd
;
1211 /* length, 1st approximation */
1212 if (bytesonwire
< OSPF6_HEADER_SIZE
)
1214 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1215 zlog_debug ("%s: undersized (%u B) packet", __func__
, bytesonwire
);
1218 /* Now it is safe to access header fields. */
1219 if (bytesonwire
!= ntohs (oh
->length
))
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
));
1227 if (oh
->version
!= OSPFV3_VERSION
)
1229 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1230 zlog_debug ("%s: invalid (%u) protocol version", __func__
, oh
->version
);
1233 /* length, 2nd approximation */
1236 oh
->type
< OSPF6_MESSAGE_TYPE_ALL
&&
1237 ospf6_packet_minlen
[oh
->type
] &&
1238 bytesonwire
< OSPF6_HEADER_SIZE
+ ospf6_packet_minlen
[oh
->type
]
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
]);
1246 /* type-specific deeper validation */
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)
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
]);
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
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
,
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
)
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
]);
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
1283 (struct ospf6_lsa_header
*) ((caddr_t
) lsupd
+ OSPF6_LS_UPD_MIN_SIZE
),
1284 bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_UPD_MIN_SIZE
,
1286 ntohl (lsupd
->lsa_number
) /* 32 bits */
1289 case OSPF6_MESSAGE_TYPE_LSACK
:
1290 /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1291 test
= ospf6_lsaseq_examin
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
,
1300 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1301 zlog_debug ("%s: invalid (%u) message type", __func__
, oh
->type
);
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
]);
1309 /* Verify particular fields of otherwise correct received OSPF packet to
1310 meet the requirements of RFC. */
1312 ospf6_rxpacket_examin (struct ospf6_interface
*oi
, struct ospf6_header
*oh
, const unsigned bytesonwire
)
1314 char buf
[2][INET_ADDRSTRLEN
];
1316 if (MSG_OK
!= ospf6_packet_examin (oh
, bytesonwire
))
1320 if (oh
->area_id
!= oi
->area
->area_id
)
1322 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1324 if (oh
->area_id
== BACKBONE_AREA_ID
)
1325 zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__
);
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
)
1337 /* Instance-ID check */
1338 if (oh
->instance_id
!= oi
->instance_id
)
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
);
1345 /* Router-ID check */
1346 if (oh
->router_id
== oi
->area
->ospf6
->router_id
)
1348 zlog_warn ("%s: Duplicate Router-ID (%s)", __func__
, inet_ntop (AF_INET
, &oh
->router_id
, buf
[0], INET_ADDRSTRLEN
));
1355 ospf6_lsupdate_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
1356 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1358 struct ospf6_neighbor
*on
;
1359 struct ospf6_lsupdate
*lsupdate
;
1363 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
1366 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1367 zlog_debug ("Neighbor not found, ignore");
1371 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1372 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
1373 on
->state
!= OSPF6_NEIGHBOR_FULL
)
1375 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1376 zlog_debug ("Neighbor state less than Exchange, ignore");
1380 lsupdate
= (struct ospf6_lsupdate
*)
1381 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1383 num
= ntohl (lsupdate
->lsa_number
);
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
))
1393 if (OSPF6_LSA_SIZE (p
) < sizeof (struct ospf6_lsa_header
))
1395 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1396 zlog_debug ("Malformed LSA length, quit processing");
1400 ospf6_receive_lsa (on
, (struct ospf6_lsa_header
*) p
);
1406 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1407 zlog_debug ("Malformed LSA number or LSA length");
1409 if (p
!= OSPF6_MESSAGE_END (oh
))
1411 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1412 zlog_debug ("Trailing garbage ignored");
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
))
1424 THREAD_OFF (on
->thread_send_lsreq
);
1425 on
->thread_send_lsreq
=
1426 thread_add_event (master
, ospf6_lsreq_send
, on
, 0);
1431 ospf6_lsack_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
1432 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1434 struct ospf6_neighbor
*on
;
1436 struct ospf6_lsa
*his
, *mine
;
1437 struct ospf6_lsdb
*lsdb
= NULL
;
1439 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
1441 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
1444 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1445 zlog_debug ("Neighbor not found, ignore");
1449 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1450 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
1451 on
->state
!= OSPF6_NEIGHBOR_FULL
)
1453 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1454 zlog_debug ("Neighbor state less than Exchange, ignore");
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
))
1462 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
1464 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
1466 case OSPF6_SCOPE_LINKLOCAL
:
1467 lsdb
= on
->ospf6_if
->lsdb
;
1469 case OSPF6_SCOPE_AREA
:
1470 lsdb
= on
->ospf6_if
->area
->lsdb
;
1472 case OSPF6_SCOPE_AS
:
1473 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
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
);
1483 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1484 zlog_debug ("%s acknowledged by %s", his
->name
, on
->name
);
1486 /* Find database copy */
1487 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
1488 his
->header
->adv_router
, lsdb
);
1491 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1492 zlog_debug ("No database copy");
1493 ospf6_lsa_delete (his
);
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
);
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
);
1508 if (ospf6_lsa_compare (his
, mine
) != 0)
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
);
1518 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1519 zlog_debug ("Acknowledged, remove from %s's retrans-list",
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
);
1529 if (p
!= OSPF6_MESSAGE_END (oh
))
1531 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1532 zlog_debug ("Trailing garbage ignored");
1536 static u_char
*recvbuf
= NULL
;
1537 static u_char
*sendbuf
= NULL
;
1538 static unsigned int iobuflen
= 0;
1541 ospf6_iobuf_size (unsigned int size
)
1543 u_char
*recvnew
, *sendnew
;
1545 if (size
<= iobuflen
)
1548 recvnew
= XMALLOC (MTYPE_OSPF6_MESSAGE
, size
);
1549 sendnew
= XMALLOC (MTYPE_OSPF6_MESSAGE
, size
);
1550 if (recvnew
== NULL
|| sendnew
== NULL
)
1553 XFREE (MTYPE_OSPF6_MESSAGE
, recvnew
);
1555 XFREE (MTYPE_OSPF6_MESSAGE
, sendnew
);
1556 zlog_debug ("Could not allocate I/O buffer of size %d.", size
);
1561 XFREE (MTYPE_OSPF6_MESSAGE
, recvbuf
);
1563 XFREE (MTYPE_OSPF6_MESSAGE
, sendbuf
);
1572 ospf6_receive (struct thread
*thread
)
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
;
1583 /* add next read thread */
1584 sockfd
= THREAD_FD (thread
);
1585 thread_add_read (master
, ospf6_receive
, NULL
, sockfd
);
1588 memset (&src
, 0, sizeof (src
));
1589 memset (&dst
, 0, sizeof (dst
));
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;
1597 /* receive message */
1598 len
= ospf6_recvmsg (&src
, &dst
, &ifindex
, iovector
);
1601 zlog_err ("Excess message read");
1605 oi
= ospf6_interface_lookup_by_ifindex (ifindex
);
1606 if (oi
== NULL
|| oi
->area
== NULL
)
1608 zlog_debug ("Message received on disabled interface");
1611 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
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
);
1619 oh
= (struct ospf6_header
*) recvbuf
;
1620 if (ospf6_rxpacket_examin (oi
, oh
, len
) != MSG_OK
)
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. */
1629 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
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
);
1642 case OSPF6_MESSAGE_TYPE_HELLO
:
1643 ospf6_hello_print (oh
);
1645 case OSPF6_MESSAGE_TYPE_DBDESC
:
1646 ospf6_dbdesc_print (oh
);
1648 case OSPF6_MESSAGE_TYPE_LSREQ
:
1649 ospf6_lsreq_print (oh
);
1651 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1652 ospf6_lsupdate_print (oh
);
1654 case OSPF6_MESSAGE_TYPE_LSACK
:
1655 ospf6_lsack_print (oh
);
1658 zlog_debug ("Unknown message");
1665 case OSPF6_MESSAGE_TYPE_HELLO
:
1666 ospf6_hello_recv (&src
, &dst
, oi
, oh
);
1669 case OSPF6_MESSAGE_TYPE_DBDESC
:
1670 ospf6_dbdesc_recv (&src
, &dst
, oi
, oh
);
1673 case OSPF6_MESSAGE_TYPE_LSREQ
:
1674 ospf6_lsreq_recv (&src
, &dst
, oi
, oh
);
1677 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1678 ospf6_lsupdate_recv (&src
, &dst
, oi
, oh
);
1681 case OSPF6_MESSAGE_TYPE_LSACK
:
1682 ospf6_lsack_recv (&src
, &dst
, oi
, oh
);
1686 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1687 zlog_debug ("Unknown message");
1695 ospf6_send (struct in6_addr
*src
, struct in6_addr
*dst
,
1696 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1699 char srcname
[64], dstname
[64];
1700 struct iovec iovector
[2];
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;
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
;
1719 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, SEND
))
1721 inet_ntop (AF_INET6
, dst
, dstname
, sizeof (dstname
));
1723 inet_ntop (AF_INET6
, src
, srcname
, sizeof (srcname
));
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
);
1733 case OSPF6_MESSAGE_TYPE_HELLO
:
1734 ospf6_hello_print (oh
);
1736 case OSPF6_MESSAGE_TYPE_DBDESC
:
1737 ospf6_dbdesc_print (oh
);
1739 case OSPF6_MESSAGE_TYPE_LSREQ
:
1740 ospf6_lsreq_print (oh
);
1742 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1743 ospf6_lsupdate_print (oh
);
1745 case OSPF6_MESSAGE_TYPE_LSACK
:
1746 ospf6_lsack_print (oh
);
1749 zlog_debug ("Unknown 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");
1762 ospf6_packet_max(struct ospf6_interface
*oi
)
1764 return oi
->ifmtu
- sizeof(struct ip6_hdr
);
1768 ospf6_hello_send (struct thread
*thread
)
1770 struct ospf6_interface
*oi
;
1771 struct ospf6_header
*oh
;
1772 struct ospf6_hello
*hello
;
1774 struct listnode
*node
, *nnode
;
1775 struct ospf6_neighbor
*on
;
1777 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1778 oi
->thread_send_hello
= (struct thread
*) NULL
;
1780 if (oi
->state
<= OSPF6_INTERFACE_DOWN
)
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
);
1788 /* set next thread */
1789 oi
->thread_send_hello
= thread_add_timer (master
, ospf6_hello_send
,
1790 oi
, oi
->hello_interval
);
1792 memset (sendbuf
, 0, iobuflen
);
1793 oh
= (struct ospf6_header
*) sendbuf
;
1794 hello
= (struct ospf6_hello
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
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
;
1806 p
= (u_char
*)((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
1808 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
1810 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
1813 if (p
- sendbuf
+ sizeof (u_int32_t
) > ospf6_packet_max(oi
))
1815 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO
, SEND
))
1816 zlog_debug ("sending Hello message: exceeds I/F MTU");
1820 memcpy (p
, &on
->router_id
, sizeof (u_int32_t
));
1821 p
+= sizeof (u_int32_t
);
1824 oh
->type
= OSPF6_MESSAGE_TYPE_HELLO
;
1825 oh
->length
= htons (p
- sendbuf
);
1827 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
1832 ospf6_dbdesc_send (struct thread
*thread
)
1834 struct ospf6_neighbor
*on
;
1835 struct ospf6_header
*oh
;
1836 struct ospf6_dbdesc
*dbdesc
;
1838 struct ospf6_lsa
*lsa
;
1840 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1841 on
->thread_send_dbdesc
= (struct thread
*) NULL
;
1843 if (on
->state
< OSPF6_NEIGHBOR_EXSTART
)
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
]);
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
);
1857 memset (sendbuf
, 0, iobuflen
);
1858 oh
= (struct ospf6_header
*) sendbuf
;
1859 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
) oh
+
1860 sizeof (struct ospf6_header
));
1862 /* if this is initial one, initialize sequence number for DbDesc */
1863 if (CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
))
1866 if (quagga_gettime (QUAGGA_CLK_MONOTONIC
, &tv
) < 0)
1868 on
->dbdesc_seqnum
= tv
.tv_sec
;
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
);
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
))
1882 for (lsa
= ospf6_lsdb_head (on
->dbdesc_list
); lsa
;
1883 lsa
= ospf6_lsdb_next (lsa
))
1885 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
1888 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) >
1889 ospf6_packet_max(on
->ospf6_if
))
1891 ospf6_lsa_unlock (lsa
);
1894 memcpy (p
, lsa
->header
, sizeof (struct ospf6_lsa_header
));
1895 p
+= sizeof (struct ospf6_lsa_header
);
1899 oh
->type
= OSPF6_MESSAGE_TYPE_DBDESC
;
1900 oh
->length
= htons (p
- sendbuf
);
1902 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
1908 ospf6_dbdesc_send_newone (struct thread
*thread
)
1910 struct ospf6_neighbor
*on
;
1911 struct ospf6_lsa
*lsa
;
1912 unsigned int size
= 0;
1914 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1915 ospf6_lsdb_remove_all (on
->dbdesc_list
);
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
))
1923 if (size
+ sizeof (struct ospf6_lsa_header
) > ospf6_packet_max(on
->ospf6_if
))
1925 ospf6_lsa_unlock (lsa
);
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
);
1934 if (on
->summary_list
->count
== 0)
1935 UNSET_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
);
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);
1943 thread_execute (master
, ospf6_dbdesc_send
, on
, 0);
1948 ospf6_lsreq_send (struct thread
*thread
)
1950 struct ospf6_neighbor
*on
;
1951 struct ospf6_header
*oh
;
1952 struct ospf6_lsreq_entry
*e
;
1954 struct ospf6_lsa
*lsa
;
1956 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1957 on
->thread_send_lsreq
= (struct thread
*) NULL
;
1959 /* LSReq will be sent only in ExStart or Loading */
1960 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1961 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
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
]);
1969 /* schedule loading_done if request list is empty */
1970 if (on
->request_list
->count
== 0)
1972 thread_add_event (master
, loading_done
, on
, 0);
1976 /* set next thread */
1977 on
->thread_send_lsreq
=
1978 thread_add_timer (master
, ospf6_lsreq_send
, on
,
1979 on
->ospf6_if
->rxmt_interval
);
1981 memset (sendbuf
, 0, iobuflen
);
1982 oh
= (struct ospf6_header
*) sendbuf
;
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
))
1990 if (p
- sendbuf
+ sizeof (struct ospf6_lsreq_entry
) > ospf6_packet_max(on
->ospf6_if
))
1992 ospf6_lsa_unlock (lsa
);
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
);
2003 oh
->type
= OSPF6_MESSAGE_TYPE_LSREQ
;
2004 oh
->length
= htons (p
- sendbuf
);
2006 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
2012 ospf6_lsupdate_send_neighbor (struct thread
*thread
)
2014 struct ospf6_neighbor
*on
;
2015 struct ospf6_header
*oh
;
2016 struct ospf6_lsupdate
*lsupdate
;
2019 struct ospf6_lsa
*lsa
;
2021 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
2022 on
->thread_send_lsupdate
= (struct thread
*) NULL
;
2024 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
2025 zlog_debug ("LSUpdate to neighbor %s", on
->name
);
2027 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
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
]);
2035 /* if we have nothing to send, return */
2036 if (on
->lsupdate_list
->count
== 0 &&
2037 on
->retrans_list
->count
== 0)
2039 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
2040 zlog_debug ("Quit to send (nothing to send)");
2044 memset (sendbuf
, 0, iobuflen
);
2045 oh
= (struct ospf6_header
*) sendbuf
;
2046 lsupdate
= (struct ospf6_lsupdate
*)
2047 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2049 p
= (u_char
*)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
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
))
2058 if ( (p
- sendbuf
+ (unsigned int)OSPF6_LSA_SIZE (lsa
->header
))
2059 > ospf6_packet_max(on
->ospf6_if
))
2061 ospf6_lsa_unlock (lsa
);
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
);
2070 assert (lsa
->lock
== 2);
2071 ospf6_lsdb_remove (lsa
, on
->lsupdate_list
);
2074 for (lsa
= ospf6_lsdb_head (on
->retrans_list
); lsa
;
2075 lsa
= ospf6_lsdb_next (lsa
))
2078 if ( (p
- sendbuf
+ (unsigned int)OSPF6_LSA_SIZE (lsa
->header
))
2079 > ospf6_packet_max(on
->ospf6_if
))
2081 ospf6_lsa_unlock (lsa
);
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
);
2091 lsupdate
->lsa_number
= htonl (num
);
2093 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2094 oh
->length
= htons (p
- sendbuf
);
2096 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
2099 if (on
->lsupdate_list
->count
!= 0 ||
2100 on
->retrans_list
->count
!= 0)
2102 if (on
->lsupdate_list
->count
!= 0)
2103 on
->thread_send_lsupdate
=
2104 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, on
, 0);
2106 on
->thread_send_lsupdate
=
2107 thread_add_timer (master
, ospf6_lsupdate_send_neighbor
, on
,
2108 on
->ospf6_if
->rxmt_interval
);
2115 ospf6_lsupdate_send_interface (struct thread
*thread
)
2117 struct ospf6_interface
*oi
;
2118 struct ospf6_header
*oh
;
2119 struct ospf6_lsupdate
*lsupdate
;
2122 struct ospf6_lsa
*lsa
;
2124 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
2125 oi
->thread_send_lsupdate
= (struct thread
*) NULL
;
2127 if (oi
->state
<= OSPF6_INTERFACE_WAITING
)
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
]);
2135 /* if we have nothing to send, return */
2136 if (oi
->lsupdate_list
->count
== 0)
2139 memset (sendbuf
, 0, iobuflen
);
2140 oh
= (struct ospf6_header
*) sendbuf
;
2141 lsupdate
= (struct ospf6_lsupdate
*)((caddr_t
) oh
+
2142 sizeof (struct ospf6_header
));
2144 p
= (u_char
*)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
2147 for (lsa
= ospf6_lsdb_head (oi
->lsupdate_list
); lsa
;
2148 lsa
= ospf6_lsdb_next (lsa
))
2151 if ( (p
- sendbuf
+ ((unsigned int)OSPF6_LSA_SIZE (lsa
->header
)))
2152 > ospf6_packet_max(oi
))
2154 ospf6_lsa_unlock (lsa
);
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
);
2163 assert (lsa
->lock
== 2);
2164 ospf6_lsdb_remove (lsa
, oi
->lsupdate_list
);
2167 lsupdate
->lsa_number
= htonl (num
);
2169 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2170 oh
->length
= htons (p
- sendbuf
);
2172 if (oi
->state
== OSPF6_INTERFACE_DR
||
2173 oi
->state
== OSPF6_INTERFACE_BDR
)
2174 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
2176 ospf6_send (oi
->linklocal_addr
, &alldrouters6
, oi
, oh
);
2178 if (oi
->lsupdate_list
->count
> 0)
2180 oi
->thread_send_lsupdate
=
2181 thread_add_event (master
, ospf6_lsupdate_send_interface
, oi
, 0);
2188 ospf6_lsack_send_neighbor (struct thread
*thread
)
2190 struct ospf6_neighbor
*on
;
2191 struct ospf6_header
*oh
;
2193 struct ospf6_lsa
*lsa
;
2195 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
2196 on
->thread_send_lsack
= (struct thread
*) NULL
;
2198 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
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
]);
2206 /* if we have nothing to send, return */
2207 if (on
->lsack_list
->count
== 0)
2210 memset (sendbuf
, 0, iobuflen
);
2211 oh
= (struct ospf6_header
*) sendbuf
;
2213 p
= (u_char
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2215 for (lsa
= ospf6_lsdb_head (on
->lsack_list
); lsa
;
2216 lsa
= ospf6_lsdb_next (lsa
))
2219 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) > ospf6_packet_max(on
->ospf6_if
))
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);
2227 ospf6_lsa_unlock (lsa
);
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
);
2235 assert (lsa
->lock
== 2);
2236 ospf6_lsdb_remove (lsa
, on
->lsack_list
);
2239 oh
->type
= OSPF6_MESSAGE_TYPE_LSACK
;
2240 oh
->length
= htons (p
- sendbuf
);
2242 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
2248 ospf6_lsack_send_interface (struct thread
*thread
)
2250 struct ospf6_interface
*oi
;
2251 struct ospf6_header
*oh
;
2253 struct ospf6_lsa
*lsa
;
2255 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
2256 oi
->thread_send_lsack
= (struct thread
*) NULL
;
2258 if (oi
->state
<= OSPF6_INTERFACE_WAITING
)
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
]);
2266 /* if we have nothing to send, return */
2267 if (oi
->lsack_list
->count
== 0)
2270 memset (sendbuf
, 0, iobuflen
);
2271 oh
= (struct ospf6_header
*) sendbuf
;
2273 p
= (u_char
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2275 for (lsa
= ospf6_lsdb_head (oi
->lsack_list
); lsa
;
2276 lsa
= ospf6_lsdb_next (lsa
))
2279 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) > ospf6_packet_max(oi
))
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);
2287 ospf6_lsa_unlock (lsa
);
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
);
2295 assert (lsa
->lock
== 2);
2296 ospf6_lsdb_remove (lsa
, oi
->lsack_list
);
2299 oh
->type
= OSPF6_MESSAGE_TYPE_LSACK
;
2300 oh
->length
= htons (p
- sendbuf
);
2302 if (oi
->state
== OSPF6_INTERFACE_DR
||
2303 oi
->state
== OSPF6_INTERFACE_BDR
)
2304 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
2306 ospf6_send (oi
->linklocal_addr
, &alldrouters6
, oi
, oh
);
2308 if (oi
->thread_send_lsack
== NULL
&& oi
->lsack_list
->count
> 0)
2310 oi
->thread_send_lsack
=
2311 thread_add_event (master
, ospf6_lsack_send_interface
, oi
, 0);
2319 DEFUN (debug_ospf6_message
,
2320 debug_ospf6_message_cmd
,
2321 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
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"
2334 unsigned char level
= 0;
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
;
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
;
2363 if (type
== OSPF6_MESSAGE_TYPE_ALL
)
2365 for (i
= 0; i
< 6; i
++)
2366 OSPF6_DEBUG_MESSAGE_ON (i
, level
);
2369 OSPF6_DEBUG_MESSAGE_ON (type
, level
);
2374 ALIAS (debug_ospf6_message
,
2375 debug_ospf6_message_sendrecv_cmd
,
2376 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
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"
2392 DEFUN (no_debug_ospf6_message
,
2393 no_debug_ospf6_message_cmd
,
2394 "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
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"
2408 unsigned char level
= 0;
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
;
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
;
2437 if (type
== OSPF6_MESSAGE_TYPE_ALL
)
2439 for (i
= 0; i
< 6; i
++)
2440 OSPF6_DEBUG_MESSAGE_OFF (i
, level
);
2443 OSPF6_DEBUG_MESSAGE_OFF (type
, level
);
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)",
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"
2468 config_write_ospf6_debug_message (struct vty
*vty
)
2470 const char *type_str
[] = {"unknown", "hello", "dbdesc",
2471 "lsreq", "lsupdate", "lsack"};
2472 unsigned char s
= 0, r
= 0;
2475 for (i
= 0; i
< 6; i
++)
2477 if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
))
2479 if (IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2483 if (s
== 0x3f && r
== 0x3f)
2485 vty_out (vty
, "debug ospf6 message all%s", VNL
);
2489 if (s
== 0x3f && r
== 0)
2491 vty_out (vty
, "debug ospf6 message all send%s", VNL
);
2494 else if (s
== 0 && r
== 0x3f)
2496 vty_out (vty
, "debug ospf6 message all recv%s", VNL
);
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
);
2509 for (i
= 1; i
< 6; i
++)
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
],
2517 else if (IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2518 vty_out (vty
, "debug ospf6 message %s recv%s", type_str
[i
],
2526 install_element_ospf6_debug_message (void)
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
);