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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "ospf6_proto.h"
31 #include "ospf6_lsa.h"
32 #include "ospf6_lsdb.h"
33 #include "ospf6_network.h"
34 #include "ospf6_message.h"
36 #include "ospf6_top.h"
37 #include "ospf6_area.h"
38 #include "ospf6_neighbor.h"
39 #include "ospf6_interface.h"
41 /* for structures and macros ospf6_lsa_examin() needs */
42 #include "ospf6_abr.h"
43 #include "ospf6_asbr.h"
44 #include "ospf6_intra.h"
46 #include "ospf6_flood.h"
49 #include <netinet/ip6.h>
51 unsigned char conf_debug_ospf6_message
[6] = {0x03, 0, 0, 0, 0, 0};
52 static const struct message ospf6_message_type_str
[] =
54 { OSPF6_MESSAGE_TYPE_HELLO
, "Hello" },
55 { OSPF6_MESSAGE_TYPE_DBDESC
, "DbDesc" },
56 { OSPF6_MESSAGE_TYPE_LSREQ
, "LSReq" },
57 { OSPF6_MESSAGE_TYPE_LSUPDATE
, "LSUpdate" },
58 { OSPF6_MESSAGE_TYPE_LSACK
, "LSAck" },
62 /* Minimum (besides the standard OSPF packet header) lengths for OSPF
63 packets of particular types, offset is the "type" field. */
64 const u_int16_t ospf6_packet_minlen
[OSPF6_MESSAGE_TYPE_ALL
] =
68 OSPF6_DB_DESC_MIN_SIZE
,
69 OSPF6_LS_REQ_MIN_SIZE
,
70 OSPF6_LS_UPD_MIN_SIZE
,
74 /* Minimum (besides the standard LSA header) lengths for LSAs of particular
75 types, offset is the "LSA function code" portion of "LSA type" field. */
76 const u_int16_t ospf6_lsa_minlen
[OSPF6_LSTYPE_SIZE
] =
79 /* 0x2001 */ OSPF6_ROUTER_LSA_MIN_SIZE
,
80 /* 0x2002 */ OSPF6_NETWORK_LSA_MIN_SIZE
,
81 /* 0x2003 */ OSPF6_INTER_PREFIX_LSA_MIN_SIZE
,
82 /* 0x2004 */ OSPF6_INTER_ROUTER_LSA_FIX_SIZE
,
83 /* 0x4005 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
,
85 /* 0x2007 */ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
,
86 /* 0x0008 */ OSPF6_LINK_LSA_MIN_SIZE
,
87 /* 0x2009 */ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
93 ospf6_header_print (struct ospf6_header
*oh
)
95 char router_id
[16], area_id
[16];
96 inet_ntop (AF_INET
, &oh
->router_id
, router_id
, sizeof (router_id
));
97 inet_ntop (AF_INET
, &oh
->area_id
, area_id
, sizeof (area_id
));
99 zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s",
100 oh
->version
, oh
->type
, ntohs (oh
->length
), router_id
);
101 zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d",
102 area_id
, ntohs (oh
->checksum
), oh
->instance_id
);
106 ospf6_hello_print (struct ospf6_header
*oh
)
108 struct ospf6_hello
*hello
;
110 char drouter
[16], bdrouter
[16], neighbor
[16];
113 ospf6_header_print (oh
);
114 assert (oh
->type
== OSPF6_MESSAGE_TYPE_HELLO
);
116 hello
= (struct ospf6_hello
*)
117 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
119 inet_ntop (AF_INET
, &hello
->drouter
, drouter
, sizeof (drouter
));
120 inet_ntop (AF_INET
, &hello
->bdrouter
, bdrouter
, sizeof (bdrouter
));
121 ospf6_options_printbuf (hello
->options
, options
, sizeof (options
));
123 zlog_debug (" I/F-Id:%ld Priority:%d Option:%s",
124 (u_long
) ntohl (hello
->interface_id
), hello
->priority
, options
);
125 zlog_debug (" HelloInterval:%hu DeadInterval:%hu",
126 ntohs (hello
->hello_interval
), ntohs (hello
->dead_interval
));
127 zlog_debug (" DR:%s BDR:%s", drouter
, bdrouter
);
129 for (p
= (char *) ((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
130 p
+ sizeof (u_int32_t
) <= OSPF6_MESSAGE_END (oh
);
131 p
+= sizeof (u_int32_t
))
133 inet_ntop (AF_INET
, (void *) p
, neighbor
, sizeof (neighbor
));
134 zlog_debug (" Neighbor: %s", neighbor
);
137 assert (p
== OSPF6_MESSAGE_END (oh
));
141 ospf6_dbdesc_print (struct ospf6_header
*oh
)
143 struct ospf6_dbdesc
*dbdesc
;
147 ospf6_header_print (oh
);
148 assert (oh
->type
== OSPF6_MESSAGE_TYPE_DBDESC
);
150 dbdesc
= (struct ospf6_dbdesc
*)
151 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
153 ospf6_options_printbuf (dbdesc
->options
, options
, sizeof (options
));
155 zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu",
156 dbdesc
->reserved1
, options
, ntohs (dbdesc
->ifmtu
));
157 zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
159 (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
) ? "I" : "-"),
160 (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MBIT
) ? "M" : "-"),
161 (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) ? "m" : "s"),
162 (u_long
) ntohl (dbdesc
->seqnum
));
164 for (p
= (char *) ((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
165 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
166 p
+= sizeof (struct ospf6_lsa_header
))
167 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
169 assert (p
== OSPF6_MESSAGE_END (oh
));
173 ospf6_lsreq_print (struct ospf6_header
*oh
)
175 char id
[16], adv_router
[16];
178 ospf6_header_print (oh
);
179 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSREQ
);
181 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
182 p
+ sizeof (struct ospf6_lsreq_entry
) <= OSPF6_MESSAGE_END (oh
);
183 p
+= sizeof (struct ospf6_lsreq_entry
))
185 struct ospf6_lsreq_entry
*e
= (struct ospf6_lsreq_entry
*) p
;
186 inet_ntop (AF_INET
, &e
->adv_router
, adv_router
, sizeof (adv_router
));
187 inet_ntop (AF_INET
, &e
->id
, id
, sizeof (id
));
188 zlog_debug (" [%s Id:%s Adv:%s]",
189 ospf6_lstype_name (e
->type
), id
, adv_router
);
192 assert (p
== OSPF6_MESSAGE_END (oh
));
196 ospf6_lsupdate_print (struct ospf6_header
*oh
)
198 struct ospf6_lsupdate
*lsupdate
;
202 ospf6_header_print (oh
);
203 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSUPDATE
);
205 lsupdate
= (struct ospf6_lsupdate
*)
206 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
208 num
= ntohl (lsupdate
->lsa_number
);
209 zlog_debug (" Number of LSA: %ld", num
);
211 for (p
= (char *) ((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
212 p
< OSPF6_MESSAGE_END (oh
) &&
213 p
+ OSPF6_LSA_SIZE (p
) <= OSPF6_MESSAGE_END (oh
);
214 p
+= OSPF6_LSA_SIZE (p
))
216 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
219 assert (p
== OSPF6_MESSAGE_END (oh
));
223 ospf6_lsack_print (struct ospf6_header
*oh
)
227 ospf6_header_print (oh
);
228 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
230 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
231 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
232 p
+= sizeof (struct ospf6_lsa_header
))
233 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
235 assert (p
== OSPF6_MESSAGE_END (oh
));
239 ospf6_hello_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
240 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
242 struct ospf6_hello
*hello
;
243 struct ospf6_neighbor
*on
;
246 int neighborchange
= 0;
247 int neighbor_ifindex_change
= 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 */
289 memcpy (&on
->linklocal_addr
, src
, sizeof (struct in6_addr
));
291 /* Neighbor ifindex check */
292 if (on
->ifindex
!= (ifindex_t
)ntohl (hello
->interface_id
))
294 on
->ifindex
= ntohl (hello
->interface_id
);
295 neighbor_ifindex_change
++;
299 for (p
= (char *) ((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
300 p
+ sizeof (u_int32_t
) <= OSPF6_MESSAGE_END (oh
);
301 p
+= sizeof (u_int32_t
))
303 u_int32_t
*router_id
= (u_int32_t
*) p
;
305 if (*router_id
== oi
->area
->ospf6
->router_id
)
309 assert (p
== OSPF6_MESSAGE_END (oh
));
311 /* RouterPriority check */
312 if (on
->priority
!= hello
->priority
)
314 on
->priority
= hello
->priority
;
319 if (on
->drouter
!= hello
->drouter
)
321 on
->prev_drouter
= on
->drouter
;
322 on
->drouter
= hello
->drouter
;
323 if (on
->prev_drouter
== on
->router_id
|| on
->drouter
== on
->router_id
)
328 if (on
->bdrouter
!= hello
->bdrouter
)
330 on
->prev_bdrouter
= on
->bdrouter
;
331 on
->bdrouter
= hello
->bdrouter
;
332 if (on
->prev_bdrouter
== on
->router_id
|| on
->bdrouter
== on
->router_id
)
336 /* BackupSeen check */
337 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
339 if (hello
->bdrouter
== on
->router_id
)
341 else if (hello
->drouter
== on
->router_id
&& hello
->bdrouter
== htonl (0))
345 /* Execute neighbor events */
346 thread_execute (master
, hello_received
, on
, 0);
348 thread_execute (master
, twoway_received
, on
, 0);
350 thread_execute (master
, oneway_received
, on
, 0);
352 /* Schedule interface events */
354 thread_add_event (master
, backup_seen
, oi
, 0, NULL
);
356 thread_add_event (master
, neighbor_change
, oi
, 0, NULL
);
358 if (neighbor_ifindex_change
&& on
->state
== OSPF6_NEIGHBOR_FULL
)
359 OSPF6_ROUTER_LSA_SCHEDULE (oi
->area
);
363 ospf6_dbdesc_recv_master (struct ospf6_header
*oh
,
364 struct ospf6_neighbor
*on
)
366 struct ospf6_dbdesc
*dbdesc
;
369 dbdesc
= (struct ospf6_dbdesc
*)
370 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
372 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
374 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
375 zlog_debug ("Neighbor state less than Init, ignore");
381 case OSPF6_NEIGHBOR_TWOWAY
:
382 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
383 zlog_debug ("Neighbor state is 2-Way, ignore");
386 case OSPF6_NEIGHBOR_INIT
:
387 thread_execute (master
, twoway_received
, on
, 0);
388 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
)
390 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
391 zlog_debug ("Neighbor state is not ExStart, ignore");
394 /* else fall through to ExStart */
396 case OSPF6_NEIGHBOR_EXSTART
:
397 /* if neighbor obeys us as our slave, schedule negotiation_done
398 and process LSA Headers. Otherwise, ignore this message */
399 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) &&
400 ! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
) &&
401 ntohl (dbdesc
->seqnum
) == on
->dbdesc_seqnum
)
403 /* execute NegotiationDone */
404 thread_execute (master
, negotiation_done
, on
, 0);
406 /* Record neighbor options */
407 memcpy (on
->options
, dbdesc
->options
, sizeof (on
->options
));
411 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
412 zlog_debug ("Negotiation failed");
415 /* fall through to exchange */
417 case OSPF6_NEIGHBOR_EXCHANGE
:
418 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
420 /* Duplicated DatabaseDescription is dropped by master */
421 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
422 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
426 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
))
428 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
429 zlog_debug ("Master/Slave bit mismatch");
430 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
434 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
))
436 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
437 zlog_debug ("Initialize bit mismatch");
438 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
442 if (memcmp (on
->options
, dbdesc
->options
, sizeof (on
->options
)))
444 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
445 zlog_debug ("Option field mismatch");
446 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
450 if (ntohl (dbdesc
->seqnum
) != on
->dbdesc_seqnum
)
452 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
453 zlog_debug ("Sequence number mismatch (%#lx expected)",
454 (u_long
) on
->dbdesc_seqnum
);
455 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
460 case OSPF6_NEIGHBOR_LOADING
:
461 case OSPF6_NEIGHBOR_FULL
:
462 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
464 /* Duplicated DatabaseDescription is dropped by master */
465 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
466 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
470 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
471 zlog_debug ("Not duplicate dbdesc in state %s",
472 ospf6_neighbor_state_str
[on
->state
]);
473 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
481 /* Process LSA headers */
482 for (p
= (char *) ((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
483 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
484 p
+= sizeof (struct ospf6_lsa_header
))
486 struct ospf6_lsa
*his
, *mine
;
487 struct ospf6_lsdb
*lsdb
= NULL
;
489 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
491 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
492 zlog_debug ("%s", his
->name
);
494 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
496 case OSPF6_SCOPE_LINKLOCAL
:
497 lsdb
= on
->ospf6_if
->lsdb
;
499 case OSPF6_SCOPE_AREA
:
500 lsdb
= on
->ospf6_if
->area
->lsdb
;
503 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
505 case OSPF6_SCOPE_RESERVED
:
506 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
507 zlog_debug ("Ignoring LSA of reserved scope");
508 ospf6_lsa_delete (his
);
513 if (ntohs (his
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
514 IS_AREA_STUB (on
->ospf6_if
->area
))
516 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
517 zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
518 ospf6_lsa_delete (his
);
519 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
523 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
524 his
->header
->adv_router
, lsdb
);
527 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
528 zlog_debug ("Add request (No database copy)");
529 ospf6_lsdb_add (ospf6_lsa_copy(his
), on
->request_list
);
531 else if (ospf6_lsa_compare (his
, mine
) < 0)
533 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
534 zlog_debug ("Add request (Received MoreRecent)");
535 ospf6_lsdb_add (ospf6_lsa_copy(his
), on
->request_list
);
539 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
540 zlog_debug ("Discard (Existing MoreRecent)");
542 ospf6_lsa_delete (his
);
545 assert (p
== OSPF6_MESSAGE_END (oh
));
547 /* Increment sequence number */
548 on
->dbdesc_seqnum
++;
550 /* schedule send lsreq */
551 if (on
->request_list
->count
)
552 thread_add_event (master
, ospf6_lsreq_send
, on
, 0, &on
->thread_send_lsreq
);
554 THREAD_OFF (on
->thread_send_dbdesc
);
557 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MBIT
) &&
558 ! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
))
559 thread_add_event (master
, exchange_done
, on
, 0, NULL
);
561 on
->thread_send_dbdesc
= NULL
;
562 thread_add_event(master
, ospf6_dbdesc_send_newone
, on
, 0,
563 &on
->thread_send_dbdesc
);
566 /* save last received dbdesc */
567 memcpy (&on
->dbdesc_last
, dbdesc
, sizeof (struct ospf6_dbdesc
));
571 ospf6_dbdesc_recv_slave (struct ospf6_header
*oh
,
572 struct ospf6_neighbor
*on
)
574 struct ospf6_dbdesc
*dbdesc
;
577 dbdesc
= (struct ospf6_dbdesc
*)
578 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
580 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
582 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
583 zlog_debug ("Neighbor state less than Init, ignore");
589 case OSPF6_NEIGHBOR_TWOWAY
:
590 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
591 zlog_debug ("Neighbor state is 2-Way, ignore");
594 case OSPF6_NEIGHBOR_INIT
:
595 thread_execute (master
, twoway_received
, on
, 0);
596 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
)
598 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
599 zlog_debug ("Neighbor state is not ExStart, ignore");
602 /* else fall through to ExStart */
604 case OSPF6_NEIGHBOR_EXSTART
:
605 /* If the neighbor is Master, act as Slave. Schedule negotiation_done
606 and process LSA Headers. Otherwise, ignore this message */
607 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
) &&
608 CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MBIT
) &&
609 CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) &&
610 ntohs (oh
->length
) == sizeof (struct ospf6_header
) +
611 sizeof (struct ospf6_dbdesc
))
613 /* set the master/slave bit to slave */
614 UNSET_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
);
616 /* set the DD sequence number to one specified by master */
617 on
->dbdesc_seqnum
= ntohl (dbdesc
->seqnum
);
619 /* schedule NegotiationDone */
620 thread_execute (master
, negotiation_done
, on
, 0);
622 /* Record neighbor options */
623 memcpy (on
->options
, dbdesc
->options
, sizeof (on
->options
));
627 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
628 zlog_debug ("Negotiation failed");
633 case OSPF6_NEIGHBOR_EXCHANGE
:
634 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
636 /* Duplicated DatabaseDescription causes slave to retransmit */
637 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
638 zlog_debug ("Duplicated dbdesc causes retransmit");
639 THREAD_OFF (on
->thread_send_dbdesc
);
640 on
->thread_send_dbdesc
= NULL
;
641 thread_add_event(master
, ospf6_dbdesc_send
, on
, 0,
642 &on
->thread_send_dbdesc
);
646 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
))
648 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
649 zlog_debug ("Master/Slave bit mismatch");
650 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
654 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
))
656 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
657 zlog_debug ("Initialize bit mismatch");
658 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
662 if (memcmp (on
->options
, dbdesc
->options
, sizeof (on
->options
)))
664 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
665 zlog_debug ("Option field mismatch");
666 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
670 if (ntohl (dbdesc
->seqnum
) != on
->dbdesc_seqnum
+ 1)
672 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
673 zlog_debug ("Sequence number mismatch (%#lx expected)",
674 (u_long
) on
->dbdesc_seqnum
+ 1);
675 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
680 case OSPF6_NEIGHBOR_LOADING
:
681 case OSPF6_NEIGHBOR_FULL
:
682 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
684 /* Duplicated DatabaseDescription causes slave to retransmit */
685 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
686 zlog_debug ("Duplicated dbdesc causes retransmit");
687 THREAD_OFF (on
->thread_send_dbdesc
);
688 thread_add_event (master
, ospf6_dbdesc_send
, on
, 0, &on
->thread_send_dbdesc
);
692 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
693 zlog_debug ("Not duplicate dbdesc in state %s",
694 ospf6_neighbor_state_str
[on
->state
]);
695 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
703 /* Process LSA headers */
704 for (p
= (char *) ((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
705 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
706 p
+= sizeof (struct ospf6_lsa_header
))
708 struct ospf6_lsa
*his
, *mine
;
709 struct ospf6_lsdb
*lsdb
= NULL
;
711 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
713 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
715 case OSPF6_SCOPE_LINKLOCAL
:
716 lsdb
= on
->ospf6_if
->lsdb
;
718 case OSPF6_SCOPE_AREA
:
719 lsdb
= on
->ospf6_if
->area
->lsdb
;
722 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
724 case OSPF6_SCOPE_RESERVED
:
725 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
726 zlog_debug ("Ignoring LSA of reserved scope");
727 ospf6_lsa_delete (his
);
732 if (OSPF6_LSA_SCOPE (his
->header
->type
) == OSPF6_SCOPE_AS
&&
733 IS_AREA_STUB (on
->ospf6_if
->area
))
735 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
736 zlog_debug ("E-bit mismatch with LSA Headers");
737 ospf6_lsa_delete (his
);
738 thread_add_event (master
, seqnumber_mismatch
, on
, 0, NULL
);
742 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
743 his
->header
->adv_router
, lsdb
);
744 if (mine
== NULL
|| ospf6_lsa_compare (his
, mine
) < 0)
746 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
747 zlog_debug ("Add request-list: %s", his
->name
);
748 ospf6_lsdb_add (ospf6_lsa_copy(his
), on
->request_list
);
750 ospf6_lsa_delete (his
);
753 assert (p
== OSPF6_MESSAGE_END (oh
));
755 /* Set sequence number to Master's */
756 on
->dbdesc_seqnum
= ntohl (dbdesc
->seqnum
);
758 /* schedule send lsreq */
759 if (on
->request_list
->count
)
760 thread_add_event (master
, ospf6_lsreq_send
, on
, 0, &on
->thread_send_lsreq
);
762 THREAD_OFF (on
->thread_send_dbdesc
);
763 thread_add_event (master
, ospf6_dbdesc_send_newone
, on
, 0, &on
->thread_send_dbdesc
);
765 /* save last received dbdesc */
766 memcpy (&on
->dbdesc_last
, dbdesc
, sizeof (struct ospf6_dbdesc
));
770 ospf6_dbdesc_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
771 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
773 struct ospf6_neighbor
*on
;
774 struct ospf6_dbdesc
*dbdesc
;
776 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
779 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
780 zlog_debug ("Neighbor not found, ignore");
784 dbdesc
= (struct ospf6_dbdesc
*)
785 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
787 /* Interface MTU check */
788 if (!oi
->mtu_ignore
&& ntohs (dbdesc
->ifmtu
) != oi
->ifmtu
)
790 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
791 zlog_debug ("I/F MTU mismatch");
795 if (dbdesc
->reserved1
|| dbdesc
->reserved2
)
797 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
798 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
800 dbdesc
->reserved1
= 0;
801 dbdesc
->reserved2
= 0;
804 if (ntohl (oh
->router_id
) < ntohl (ospf6
->router_id
))
805 ospf6_dbdesc_recv_master (oh
, on
);
806 else if (ntohl (ospf6
->router_id
) < ntohl (oh
->router_id
))
807 ospf6_dbdesc_recv_slave (oh
, on
);
810 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
811 zlog_debug ("Can't decide which is master, ignore");
816 ospf6_lsreq_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
817 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
819 struct ospf6_neighbor
*on
;
821 struct ospf6_lsreq_entry
*e
;
822 struct ospf6_lsdb
*lsdb
= NULL
;
823 struct ospf6_lsa
*lsa
;
825 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
828 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
829 zlog_debug ("Neighbor not found, ignore");
833 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
834 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
835 on
->state
!= OSPF6_NEIGHBOR_FULL
)
837 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
838 zlog_debug ("Neighbor state less than Exchange, ignore");
842 /* Process each request */
843 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
844 p
+ sizeof (struct ospf6_lsreq_entry
) <= OSPF6_MESSAGE_END (oh
);
845 p
+= sizeof (struct ospf6_lsreq_entry
))
847 e
= (struct ospf6_lsreq_entry
*) p
;
849 switch (OSPF6_LSA_SCOPE (e
->type
))
851 case OSPF6_SCOPE_LINKLOCAL
:
852 lsdb
= on
->ospf6_if
->lsdb
;
854 case OSPF6_SCOPE_AREA
:
855 lsdb
= on
->ospf6_if
->area
->lsdb
;
858 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
861 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
862 zlog_debug ("Ignoring LSA of reserved scope");
867 /* Find database copy */
868 lsa
= ospf6_lsdb_lookup (e
->type
, e
->id
, e
->adv_router
, lsdb
);
871 char id
[16], adv_router
[16];
872 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
874 inet_ntop (AF_INET
, &e
->id
, id
, sizeof (id
));
875 inet_ntop (AF_INET
, &e
->adv_router
, adv_router
,
876 sizeof (adv_router
));
877 zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
878 ospf6_lstype_name (e
->type
), id
, adv_router
);
880 thread_add_event (master
, bad_lsreq
, on
, 0, NULL
);
884 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->lsupdate_list
);
887 assert (p
== OSPF6_MESSAGE_END (oh
));
889 /* schedule send lsupdate */
890 THREAD_OFF (on
->thread_send_lsupdate
);
891 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, on
, 0, &on
->thread_send_lsupdate
);
894 /* Verify, that the specified memory area contains exactly N valid IPv6
895 prefixes as specified by RFC5340, A.4.1. */
897 ospf6_prefixes_examin
899 struct ospf6_prefix
*current
, /* start of buffer */
901 const u_int32_t req_num_pfxs
/* always compared with the actual number of prefixes */
904 u_char requested_pfx_bytes
;
905 u_int32_t real_num_pfxs
= 0;
909 if (length
< OSPF6_PREFIX_MIN_SIZE
)
911 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
912 zlog_debug ("%s: undersized IPv6 prefix header", __func__
);
915 /* safe to look deeper */
916 if (current
->prefix_length
> IPV6_MAX_BITLEN
)
918 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
919 zlog_debug ("%s: invalid PrefixLength (%u bits)", __func__
, current
->prefix_length
);
922 /* covers both fixed- and variable-sized fields */
923 requested_pfx_bytes
= OSPF6_PREFIX_MIN_SIZE
+ OSPF6_PREFIX_SPACE (current
->prefix_length
);
924 if (requested_pfx_bytes
> length
)
926 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
927 zlog_debug ("%s: undersized IPv6 prefix", __func__
);
931 length
-= requested_pfx_bytes
;
932 current
= (struct ospf6_prefix
*) ((caddr_t
) current
+ requested_pfx_bytes
);
935 if (real_num_pfxs
!= req_num_pfxs
)
937 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
938 zlog_debug ("%s: IPv6 prefix number mismatch (%u required, %u real)",
939 __func__
, req_num_pfxs
, real_num_pfxs
);
945 /* Verify an LSA to have a valid length and dispatch further (where
946 appropriate) to check if the contents, including nested IPv6 prefixes,
947 is properly sized/aligned within the LSA. Note that this function gets
948 LSA type in network byte order, uses in host byte order and passes to
949 ospf6_lstype_name() in network byte order again. */
951 ospf6_lsa_examin (struct ospf6_lsa_header
*lsah
, const u_int16_t lsalen
, const u_char headeronly
)
953 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
954 struct ospf6_as_external_lsa
*as_external_lsa
;
955 struct ospf6_link_lsa
*link_lsa
;
960 /* In case an additional minimum length constraint is defined for current
961 LSA type, make sure that this constraint is met. */
962 lsatype
= ntohs (lsah
->type
);
963 ltindex
= lsatype
& OSPF6_LSTYPE_FCODE_MASK
;
966 ltindex
< OSPF6_LSTYPE_SIZE
&&
967 ospf6_lsa_minlen
[ltindex
] &&
968 lsalen
< ospf6_lsa_minlen
[ltindex
] + OSPF6_LSA_HEADER_SIZE
971 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
972 zlog_debug ("%s: undersized (%u B) LSA", __func__
, lsalen
);
977 case OSPF6_LSTYPE_ROUTER
:
978 /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes followed
979 by N>=0 interface descriptions. */
980 if ((lsalen
- OSPF6_LSA_HEADER_SIZE
- OSPF6_ROUTER_LSA_MIN_SIZE
) % OSPF6_ROUTER_LSDESC_FIX_SIZE
)
982 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
983 zlog_debug ("%s: interface description alignment error", __func__
);
987 case OSPF6_LSTYPE_NETWORK
:
988 /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
989 followed by N>=0 attached router descriptions. */
990 if ((lsalen
- OSPF6_LSA_HEADER_SIZE
- OSPF6_NETWORK_LSA_MIN_SIZE
) % OSPF6_NETWORK_LSDESC_FIX_SIZE
)
992 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
993 zlog_debug ("%s: router description alignment error", __func__
);
997 case OSPF6_LSTYPE_INTER_PREFIX
:
998 /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE bytes
999 followed by 3-4 fields of a single IPv6 prefix. */
1002 return ospf6_prefixes_examin
1004 (struct ospf6_prefix
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
+ OSPF6_INTER_PREFIX_LSA_MIN_SIZE
),
1005 lsalen
- OSPF6_LSA_HEADER_SIZE
- OSPF6_INTER_PREFIX_LSA_MIN_SIZE
,
1008 case OSPF6_LSTYPE_INTER_ROUTER
:
1009 /* RFC5340 A.4.6, fixed-size LSA. */
1010 if (lsalen
> OSPF6_LSA_HEADER_SIZE
+ OSPF6_INTER_ROUTER_LSA_FIX_SIZE
)
1012 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1013 zlog_debug ("%s: oversized (%u B) LSA", __func__
, lsalen
);
1017 case OSPF6_LSTYPE_AS_EXTERNAL
: /* RFC5340 A.4.7, same as A.4.8. */
1018 case OSPF6_LSTYPE_TYPE_7
:
1019 /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE bytes
1020 followed by 3-4 fields of IPv6 prefix and 3 conditional LSA fields:
1021 16 bytes of forwarding address, 4 bytes of external route tag,
1022 4 bytes of referenced link state ID. */
1025 as_external_lsa
= (struct ospf6_as_external_lsa
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1026 exp_length
= OSPF6_LSA_HEADER_SIZE
+ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
;
1027 /* To find out if the last optional field (Referenced Link State ID) is
1028 assumed in this LSA, we need to access fixed fields of the IPv6
1029 prefix before ospf6_prefix_examin() confirms its sizing. */
1030 if (exp_length
+ OSPF6_PREFIX_MIN_SIZE
> lsalen
)
1032 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1033 zlog_debug ("%s: undersized (%u B) LSA header", __func__
, lsalen
);
1036 /* forwarding address */
1037 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
))
1039 /* external route tag */
1040 if (CHECK_FLAG (as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
))
1042 /* referenced link state ID */
1043 if (as_external_lsa
->prefix
.u
._prefix_referenced_lstype
)
1045 /* All the fixed-size fields (mandatory and optional) must fit. I.e.,
1046 this check does not include any IPv6 prefix fields. */
1047 if (exp_length
> lsalen
)
1049 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1050 zlog_debug ("%s: undersized (%u B) LSA header", __func__
, lsalen
);
1053 /* The last call completely covers the remainder (IPv6 prefix). */
1054 return ospf6_prefixes_examin
1056 (struct ospf6_prefix
*) ((caddr_t
) as_external_lsa
+ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
),
1057 lsalen
- exp_length
,
1060 case OSPF6_LSTYPE_LINK
:
1061 /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes followed
1062 by N>=0 IPv6 prefix blocks (with N declared beforehand). */
1065 link_lsa
= (struct ospf6_link_lsa
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1066 return ospf6_prefixes_examin
1068 (struct ospf6_prefix
*) ((caddr_t
) link_lsa
+ OSPF6_LINK_LSA_MIN_SIZE
),
1069 lsalen
- OSPF6_LSA_HEADER_SIZE
- OSPF6_LINK_LSA_MIN_SIZE
,
1070 ntohl (link_lsa
->prefix_num
) /* 32 bits */
1072 case OSPF6_LSTYPE_INTRA_PREFIX
:
1073 /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE bytes
1074 followed by N>=0 IPv6 prefixes (with N declared beforehand). */
1077 intra_prefix_lsa
= (struct ospf6_intra_prefix_lsa
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1078 return ospf6_prefixes_examin
1080 (struct ospf6_prefix
*) ((caddr_t
) intra_prefix_lsa
+ OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
),
1081 lsalen
- OSPF6_LSA_HEADER_SIZE
- OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
,
1082 ntohs (intra_prefix_lsa
->prefix_num
) /* 16 bits */
1085 /* No additional validation is possible for unknown LSA types, which are
1086 themselves valid in OPSFv3, hence the default decision is to accept. */
1090 /* Verify if the provided input buffer is a valid sequence of LSAs. This
1091 includes verification of LSA blocks length/alignment and dispatching
1092 of deeper-level checks. */
1096 struct ospf6_lsa_header
*lsah
, /* start of buffered data */
1098 const u_char headeronly
,
1099 /* When declared_num_lsas is not 0, compare it to the real number of LSAs
1100 and treat the difference as an error. */
1101 const u_int32_t declared_num_lsas
1104 u_int32_t counted_lsas
= 0;
1109 if (length
< OSPF6_LSA_HEADER_SIZE
)
1111 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1112 zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header",
1113 __func__
, length
, counted_lsas
);
1116 /* save on ntohs() calls here and in the LSA validator */
1117 lsalen
= OSPF6_LSA_SIZE (lsah
);
1118 if (lsalen
< OSPF6_LSA_HEADER_SIZE
)
1120 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1121 zlog_debug ("%s: malformed LSA header #%u, declared length is %u B",
1122 __func__
, counted_lsas
, lsalen
);
1127 /* less checks here and in ospf6_lsa_examin() */
1128 if (MSG_OK
!= ospf6_lsa_examin (lsah
, lsalen
, 1))
1130 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1131 zlog_debug ("%s: anomaly in header-only %s LSA #%u", __func__
,
1132 ospf6_lstype_name (lsah
->type
), counted_lsas
);
1135 lsah
= (struct ospf6_lsa_header
*) ((caddr_t
) lsah
+ OSPF6_LSA_HEADER_SIZE
);
1136 length
-= OSPF6_LSA_HEADER_SIZE
;
1140 /* make sure the input buffer is deep enough before further checks */
1141 if (lsalen
> length
)
1143 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1144 zlog_debug ("%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
1145 __func__
, ospf6_lstype_name (lsah
->type
), counted_lsas
, lsalen
, length
);
1148 if (MSG_OK
!= ospf6_lsa_examin (lsah
, lsalen
, 0))
1150 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1151 zlog_debug ("%s: anomaly in %s LSA #%u", __func__
,
1152 ospf6_lstype_name (lsah
->type
), counted_lsas
);
1155 lsah
= (struct ospf6_lsa_header
*) ((caddr_t
) lsah
+ lsalen
);
1161 if (declared_num_lsas
&& counted_lsas
!= declared_num_lsas
)
1163 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1164 zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)",
1165 __func__
, declared_num_lsas
, counted_lsas
);
1171 /* Verify a complete OSPF packet for proper sizing/alignment. */
1173 ospf6_packet_examin (struct ospf6_header
*oh
, const unsigned bytesonwire
)
1175 struct ospf6_lsupdate
*lsupd
;
1178 /* length, 1st approximation */
1179 if (bytesonwire
< OSPF6_HEADER_SIZE
)
1181 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1182 zlog_debug ("%s: undersized (%u B) packet", __func__
, bytesonwire
);
1185 /* Now it is safe to access header fields. */
1186 if (bytesonwire
!= ntohs (oh
->length
))
1188 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1189 zlog_debug ("%s: packet length error (%u real, %u declared)",
1190 __func__
, bytesonwire
, ntohs (oh
->length
));
1194 if (oh
->version
!= OSPFV3_VERSION
)
1196 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1197 zlog_debug ("%s: invalid (%u) protocol version", __func__
, oh
->version
);
1200 /* length, 2nd approximation */
1203 oh
->type
< OSPF6_MESSAGE_TYPE_ALL
&&
1204 ospf6_packet_minlen
[oh
->type
] &&
1205 bytesonwire
< OSPF6_HEADER_SIZE
+ ospf6_packet_minlen
[oh
->type
]
1208 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1209 zlog_debug ("%s: undersized (%u B) %s packet", __func__
,
1210 bytesonwire
, lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1213 /* type-specific deeper validation */
1216 case OSPF6_MESSAGE_TYPE_HELLO
:
1217 /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes followed
1218 by N>=0 router-IDs. */
1219 if (0 == (bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_HELLO_MIN_SIZE
) % 4)
1221 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1222 zlog_debug ("%s: alignment error in %s packet",
1223 __func__
, lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1225 case OSPF6_MESSAGE_TYPE_DBDESC
:
1226 /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes followed
1227 by N>=0 header-only LSAs. */
1228 test
= ospf6_lsaseq_examin
1230 (struct ospf6_lsa_header
*) ((caddr_t
) oh
+ OSPF6_HEADER_SIZE
+ OSPF6_DB_DESC_MIN_SIZE
),
1231 bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_DB_DESC_MIN_SIZE
,
1236 case OSPF6_MESSAGE_TYPE_LSREQ
:
1237 /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
1238 if (0 == (bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_REQ_MIN_SIZE
) % OSPF6_LSREQ_LSDESC_FIX_SIZE
)
1240 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1241 zlog_debug ("%s: alignment error in %s packet",
1242 __func__
, lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1244 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1245 /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes followed
1246 by N>=0 full LSAs (with N declared beforehand). */
1247 lsupd
= (struct ospf6_lsupdate
*) ((caddr_t
) oh
+ OSPF6_HEADER_SIZE
);
1248 test
= ospf6_lsaseq_examin
1250 (struct ospf6_lsa_header
*) ((caddr_t
) lsupd
+ OSPF6_LS_UPD_MIN_SIZE
),
1251 bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_UPD_MIN_SIZE
,
1253 ntohl (lsupd
->lsa_number
) /* 32 bits */
1256 case OSPF6_MESSAGE_TYPE_LSACK
:
1257 /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1258 test
= ospf6_lsaseq_examin
1260 (struct ospf6_lsa_header
*) ((caddr_t
) oh
+ OSPF6_HEADER_SIZE
+ OSPF6_LS_ACK_MIN_SIZE
),
1261 bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_ACK_MIN_SIZE
,
1267 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1268 zlog_debug ("%s: invalid (%u) message type", __func__
, oh
->type
);
1271 if (test
!= MSG_OK
&& IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1272 zlog_debug ("%s: anomaly in %s packet", __func__
, lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1276 /* Verify particular fields of otherwise correct received OSPF packet to
1277 meet the requirements of RFC. */
1279 ospf6_rxpacket_examin (struct ospf6_interface
*oi
, struct ospf6_header
*oh
, const unsigned bytesonwire
)
1281 char buf
[2][INET_ADDRSTRLEN
];
1283 if (MSG_OK
!= ospf6_packet_examin (oh
, bytesonwire
))
1287 if (oh
->area_id
!= oi
->area
->area_id
)
1289 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1291 if (oh
->area_id
== OSPF_AREA_BACKBONE
)
1292 zlog_debug ("%s: Message may be via Virtual Link: not supported", __func__
);
1296 "%s: Area-ID mismatch (my %s, rcvd %s)", __func__
,
1297 inet_ntop (AF_INET
, &oi
->area
->area_id
, buf
[0], INET_ADDRSTRLEN
),
1298 inet_ntop (AF_INET
, &oh
->area_id
, buf
[1], INET_ADDRSTRLEN
)
1304 /* Instance-ID check */
1305 if (oh
->instance_id
!= oi
->instance_id
)
1307 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1308 zlog_debug ("%s: Instance-ID mismatch (my %u, rcvd %u)", __func__
, oi
->instance_id
, oh
->instance_id
);
1312 /* Router-ID check */
1313 if (oh
->router_id
== oi
->area
->ospf6
->router_id
)
1315 zlog_warn ("%s: Duplicate Router-ID (%s)", __func__
, inet_ntop (AF_INET
, &oh
->router_id
, buf
[0], INET_ADDRSTRLEN
));
1322 ospf6_lsupdate_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
1323 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1325 struct ospf6_neighbor
*on
;
1326 struct ospf6_lsupdate
*lsupdate
;
1329 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
1332 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1333 zlog_debug ("Neighbor not found, ignore");
1337 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1338 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
1339 on
->state
!= OSPF6_NEIGHBOR_FULL
)
1341 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1342 zlog_debug ("Neighbor state less than Exchange, ignore");
1346 lsupdate
= (struct ospf6_lsupdate
*)
1347 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1350 for (p
= (char *) ((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
1351 p
< OSPF6_MESSAGE_END (oh
) &&
1352 p
+ OSPF6_LSA_SIZE (p
) <= OSPF6_MESSAGE_END (oh
);
1353 p
+= OSPF6_LSA_SIZE (p
))
1355 ospf6_receive_lsa (on
, (struct ospf6_lsa_header
*) p
);
1358 assert (p
== OSPF6_MESSAGE_END (oh
));
1363 ospf6_lsack_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
1364 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1366 struct ospf6_neighbor
*on
;
1368 struct ospf6_lsa
*his
, *mine
;
1369 struct ospf6_lsdb
*lsdb
= NULL
;
1371 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
1373 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
1376 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1377 zlog_debug ("Neighbor not found, ignore");
1381 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1382 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
1383 on
->state
!= OSPF6_NEIGHBOR_FULL
)
1385 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1386 zlog_debug ("Neighbor state less than Exchange, ignore");
1390 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1391 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
1392 p
+= sizeof (struct ospf6_lsa_header
))
1394 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
1396 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
1398 case OSPF6_SCOPE_LINKLOCAL
:
1399 lsdb
= on
->ospf6_if
->lsdb
;
1401 case OSPF6_SCOPE_AREA
:
1402 lsdb
= on
->ospf6_if
->area
->lsdb
;
1404 case OSPF6_SCOPE_AS
:
1405 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
1407 case OSPF6_SCOPE_RESERVED
:
1408 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1409 zlog_debug ("Ignoring LSA of reserved scope");
1410 ospf6_lsa_delete (his
);
1415 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1416 zlog_debug ("%s acknowledged by %s", his
->name
, on
->name
);
1418 /* Find database copy */
1419 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
1420 his
->header
->adv_router
, lsdb
);
1423 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1424 zlog_debug ("No database copy");
1425 ospf6_lsa_delete (his
);
1429 /* Check if the LSA is on his retrans-list */
1430 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
1431 his
->header
->adv_router
, on
->retrans_list
);
1434 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1435 zlog_debug ("Not on %s's retrans-list", on
->name
);
1436 ospf6_lsa_delete (his
);
1440 if (ospf6_lsa_compare (his
, mine
) != 0)
1442 /* Log this questionable acknowledgement,
1443 and examine the next one. */
1444 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1445 zlog_debug ("Questionable acknowledgement");
1446 ospf6_lsa_delete (his
);
1450 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1451 zlog_debug ("Acknowledged, remove from %s's retrans-list",
1454 ospf6_decrement_retrans_count (mine
);
1455 if (OSPF6_LSA_IS_MAXAGE (mine
))
1456 ospf6_maxage_remove (on
->ospf6_if
->area
->ospf6
);
1457 ospf6_lsdb_remove (mine
, on
->retrans_list
);
1458 ospf6_lsa_delete (his
);
1461 assert (p
== OSPF6_MESSAGE_END (oh
));
1464 static u_char
*recvbuf
= NULL
;
1465 static u_char
*sendbuf
= NULL
;
1466 static unsigned int iobuflen
= 0;
1469 ospf6_iobuf_size (unsigned int size
)
1471 u_char
*recvnew
, *sendnew
;
1473 if (size
<= iobuflen
)
1476 recvnew
= XMALLOC (MTYPE_OSPF6_MESSAGE
, size
);
1477 sendnew
= XMALLOC (MTYPE_OSPF6_MESSAGE
, size
);
1478 if (recvnew
== NULL
|| sendnew
== NULL
)
1481 XFREE (MTYPE_OSPF6_MESSAGE
, recvnew
);
1483 XFREE (MTYPE_OSPF6_MESSAGE
, sendnew
);
1484 zlog_debug ("Could not allocate I/O buffer of size %d.", size
);
1489 XFREE (MTYPE_OSPF6_MESSAGE
, recvbuf
);
1491 XFREE (MTYPE_OSPF6_MESSAGE
, sendbuf
);
1500 ospf6_message_terminate (void)
1504 XFREE (MTYPE_OSPF6_MESSAGE
, recvbuf
);
1510 XFREE (MTYPE_OSPF6_MESSAGE
, sendbuf
);
1518 ospf6_receive (struct thread
*thread
)
1522 char srcname
[64], dstname
[64];
1523 struct in6_addr src
, dst
;
1525 struct iovec iovector
[2];
1526 struct ospf6_interface
*oi
;
1527 struct ospf6_header
*oh
;
1529 /* add next read thread */
1530 sockfd
= THREAD_FD (thread
);
1531 thread_add_read (master
, ospf6_receive
, NULL
, sockfd
, NULL
);
1534 memset (&src
, 0, sizeof (src
));
1535 memset (&dst
, 0, sizeof (dst
));
1537 memset (recvbuf
, 0, iobuflen
);
1538 iovector
[0].iov_base
= recvbuf
;
1539 iovector
[0].iov_len
= iobuflen
;
1540 iovector
[1].iov_base
= NULL
;
1541 iovector
[1].iov_len
= 0;
1543 /* receive message */
1544 len
= ospf6_recvmsg (&src
, &dst
, &ifindex
, iovector
);
1547 zlog_err ("Excess message read");
1551 oi
= ospf6_interface_lookup_by_ifindex (ifindex
);
1552 if (oi
== NULL
|| oi
->area
== NULL
|| CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
))
1554 zlog_debug ("Message received on disabled interface");
1557 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1559 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1560 zlog_debug ("%s: Ignore message on passive interface %s",
1561 __func__
, oi
->interface
->name
);
1565 oh
= (struct ospf6_header
*) recvbuf
;
1566 if (ospf6_rxpacket_examin (oi
, oh
, len
) != MSG_OK
)
1569 /* Being here means, that no sizing/alignment issues were detected in
1570 the input packet. This renders the additional checks performed below
1571 and also in the type-specific dispatching functions a dead code,
1572 which can be dismissed in a cleanup-focused review round later. */
1575 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1577 inet_ntop (AF_INET6
, &src
, srcname
, sizeof (srcname
));
1578 inet_ntop (AF_INET6
, &dst
, dstname
, sizeof (dstname
));
1579 zlog_debug ("%s received on %s",
1580 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
), oi
->interface
->name
);
1581 zlog_debug (" src: %s", srcname
);
1582 zlog_debug (" dst: %s", dstname
);
1586 case OSPF6_MESSAGE_TYPE_HELLO
:
1587 ospf6_hello_print (oh
);
1589 case OSPF6_MESSAGE_TYPE_DBDESC
:
1590 ospf6_dbdesc_print (oh
);
1592 case OSPF6_MESSAGE_TYPE_LSREQ
:
1593 ospf6_lsreq_print (oh
);
1595 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1596 ospf6_lsupdate_print (oh
);
1598 case OSPF6_MESSAGE_TYPE_LSACK
:
1599 ospf6_lsack_print (oh
);
1608 case OSPF6_MESSAGE_TYPE_HELLO
:
1609 ospf6_hello_recv (&src
, &dst
, oi
, oh
);
1612 case OSPF6_MESSAGE_TYPE_DBDESC
:
1613 ospf6_dbdesc_recv (&src
, &dst
, oi
, oh
);
1616 case OSPF6_MESSAGE_TYPE_LSREQ
:
1617 ospf6_lsreq_recv (&src
, &dst
, oi
, oh
);
1620 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1621 ospf6_lsupdate_recv (&src
, &dst
, oi
, oh
);
1624 case OSPF6_MESSAGE_TYPE_LSACK
:
1625 ospf6_lsack_recv (&src
, &dst
, oi
, oh
);
1636 ospf6_send (struct in6_addr
*src
, struct in6_addr
*dst
,
1637 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1640 char srcname
[64], dstname
[64];
1641 struct iovec iovector
[2];
1644 iovector
[0].iov_base
= (caddr_t
) oh
;
1645 iovector
[0].iov_len
= ntohs (oh
->length
);
1646 iovector
[1].iov_base
= NULL
;
1647 iovector
[1].iov_len
= 0;
1649 /* fill OSPF header */
1650 oh
->version
= OSPFV3_VERSION
;
1651 /* message type must be set before */
1652 /* message length must be set before */
1653 oh
->router_id
= oi
->area
->ospf6
->router_id
;
1654 oh
->area_id
= oi
->area
->area_id
;
1655 /* checksum is calculated by kernel */
1656 oh
->instance_id
= oi
->instance_id
;
1660 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, SEND
))
1662 inet_ntop (AF_INET6
, dst
, dstname
, sizeof (dstname
));
1664 inet_ntop (AF_INET6
, src
, srcname
, sizeof (srcname
));
1666 memset (srcname
, 0, sizeof (srcname
));
1667 zlog_debug ("%s send on %s",
1668 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
), oi
->interface
->name
);
1669 zlog_debug (" src: %s", srcname
);
1670 zlog_debug (" dst: %s", dstname
);
1674 case OSPF6_MESSAGE_TYPE_HELLO
:
1675 ospf6_hello_print (oh
);
1677 case OSPF6_MESSAGE_TYPE_DBDESC
:
1678 ospf6_dbdesc_print (oh
);
1680 case OSPF6_MESSAGE_TYPE_LSREQ
:
1681 ospf6_lsreq_print (oh
);
1683 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1684 ospf6_lsupdate_print (oh
);
1686 case OSPF6_MESSAGE_TYPE_LSACK
:
1687 ospf6_lsack_print (oh
);
1690 zlog_debug ("Unknown message");
1697 len
= ospf6_sendmsg (src
, dst
, &oi
->interface
->ifindex
, iovector
);
1698 if (len
!= ntohs (oh
->length
))
1699 zlog_err ("Could not send entire message");
1703 ospf6_packet_max(struct ospf6_interface
*oi
)
1705 assert (oi
->ifmtu
> sizeof (struct ip6_hdr
));
1706 return oi
->ifmtu
- (sizeof (struct ip6_hdr
));
1710 ospf6_hello_send (struct thread
*thread
)
1712 struct ospf6_interface
*oi
;
1713 struct ospf6_header
*oh
;
1714 struct ospf6_hello
*hello
;
1716 struct listnode
*node
, *nnode
;
1717 struct ospf6_neighbor
*on
;
1719 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1720 oi
->thread_send_hello
= (struct thread
*) NULL
;
1722 if (oi
->state
<= OSPF6_INTERFACE_DOWN
)
1724 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO
, SEND
))
1725 zlog_debug ("Unable to send Hello on down interface %s",
1726 oi
->interface
->name
);
1732 zlog_debug ("Unable to send Hello on interface %s iobuflen is 0",
1733 oi
->interface
->name
);
1737 /* set next thread */
1738 thread_add_timer (master
, ospf6_hello_send
, oi
, oi
->hello_interval
, &oi
->thread_send_hello
);
1740 memset (sendbuf
, 0, iobuflen
);
1741 oh
= (struct ospf6_header
*) sendbuf
;
1742 hello
= (struct ospf6_hello
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1744 hello
->interface_id
= htonl (oi
->interface
->ifindex
);
1745 hello
->priority
= oi
->priority
;
1746 hello
->options
[0] = oi
->area
->options
[0];
1747 hello
->options
[1] = oi
->area
->options
[1];
1748 hello
->options
[2] = oi
->area
->options
[2];
1749 hello
->hello_interval
= htons (oi
->hello_interval
);
1750 hello
->dead_interval
= htons (oi
->dead_interval
);
1751 hello
->drouter
= oi
->drouter
;
1752 hello
->bdrouter
= oi
->bdrouter
;
1754 p
= (u_char
*)((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
1756 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
1758 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
1761 if (p
- sendbuf
+ sizeof (u_int32_t
) > ospf6_packet_max(oi
))
1763 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO
, SEND
))
1764 zlog_debug ("sending Hello message: exceeds I/F MTU");
1768 memcpy (p
, &on
->router_id
, sizeof (u_int32_t
));
1769 p
+= sizeof (u_int32_t
);
1772 oh
->type
= OSPF6_MESSAGE_TYPE_HELLO
;
1773 oh
->length
= htons (p
- sendbuf
);
1775 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
1780 ospf6_dbdesc_send (struct thread
*thread
)
1782 struct ospf6_neighbor
*on
;
1783 struct ospf6_header
*oh
;
1784 struct ospf6_dbdesc
*dbdesc
;
1786 struct ospf6_lsa
*lsa
;
1787 struct in6_addr
*dst
;
1789 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1790 on
->thread_send_dbdesc
= (struct thread
*) NULL
;
1792 if (on
->state
< OSPF6_NEIGHBOR_EXSTART
)
1794 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC
, SEND
))
1795 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1796 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
1800 /* set next thread if master */
1801 if (CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
))
1802 thread_add_timer (master
, ospf6_dbdesc_send
, on
,
1803 on
->ospf6_if
->rxmt_interval
,
1804 &on
->thread_send_dbdesc
);
1806 memset (sendbuf
, 0, iobuflen
);
1807 oh
= (struct ospf6_header
*) sendbuf
;
1808 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
) oh
+
1809 sizeof (struct ospf6_header
));
1811 /* if this is initial one, initialize sequence number for DbDesc */
1812 if (CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
) &&
1813 (on
->dbdesc_seqnum
== 0))
1815 on
->dbdesc_seqnum
= monotime(NULL
);
1818 dbdesc
->options
[0] = on
->ospf6_if
->area
->options
[0];
1819 dbdesc
->options
[1] = on
->ospf6_if
->area
->options
[1];
1820 dbdesc
->options
[2] = on
->ospf6_if
->area
->options
[2];
1821 dbdesc
->ifmtu
= htons (on
->ospf6_if
->ifmtu
);
1822 dbdesc
->bits
= on
->dbdesc_bits
;
1823 dbdesc
->seqnum
= htonl (on
->dbdesc_seqnum
);
1825 /* if this is not initial one, set LSA headers in dbdesc */
1826 p
= (u_char
*)((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
1827 if (! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
))
1829 for (lsa
= ospf6_lsdb_head (on
->dbdesc_list
); lsa
;
1830 lsa
= ospf6_lsdb_next (lsa
))
1832 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
1835 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) >
1836 ospf6_packet_max(on
->ospf6_if
))
1838 ospf6_lsdb_lsa_unlock (lsa
);
1841 memcpy (p
, lsa
->header
, sizeof (struct ospf6_lsa_header
));
1842 p
+= sizeof (struct ospf6_lsa_header
);
1846 oh
->type
= OSPF6_MESSAGE_TYPE_DBDESC
;
1847 oh
->length
= htons (p
- sendbuf
);
1850 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
1851 dst
= &allspfrouters6
;
1853 dst
= &on
->linklocal_addr
;
1855 ospf6_send (on
->ospf6_if
->linklocal_addr
, dst
, on
->ospf6_if
, oh
);
1861 ospf6_dbdesc_send_newone (struct thread
*thread
)
1863 struct ospf6_neighbor
*on
;
1864 struct ospf6_lsa
*lsa
;
1865 unsigned int size
= 0;
1867 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1868 ospf6_lsdb_remove_all (on
->dbdesc_list
);
1870 /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1871 so that ospf6_send_dbdesc () can send those LSAs */
1872 size
= sizeof (struct ospf6_lsa_header
) + sizeof (struct ospf6_dbdesc
);
1873 for (lsa
= ospf6_lsdb_head (on
->summary_list
); lsa
;
1874 lsa
= ospf6_lsdb_next (lsa
))
1876 if (size
+ sizeof (struct ospf6_lsa_header
) > ospf6_packet_max(on
->ospf6_if
))
1878 ospf6_lsdb_lsa_unlock (lsa
);
1882 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->dbdesc_list
);
1883 ospf6_lsdb_remove (lsa
, on
->summary_list
);
1884 size
+= sizeof (struct ospf6_lsa_header
);
1887 if (on
->summary_list
->count
== 0)
1888 UNSET_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
);
1890 /* If slave, More bit check must be done here */
1891 if (! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
) && /* Slave */
1892 ! CHECK_FLAG (on
->dbdesc_last
.bits
, OSPF6_DBDESC_MBIT
) &&
1893 ! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
))
1894 thread_add_event (master
, exchange_done
, on
, 0, NULL
);
1896 thread_execute (master
, ospf6_dbdesc_send
, on
, 0);
1901 ospf6_lsreq_send (struct thread
*thread
)
1903 struct ospf6_neighbor
*on
;
1904 struct ospf6_header
*oh
;
1905 struct ospf6_lsreq_entry
*e
;
1907 struct ospf6_lsa
*lsa
, *last_req
;
1909 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1910 on
->thread_send_lsreq
= (struct thread
*) NULL
;
1912 /* LSReq will be sent only in ExStart or Loading */
1913 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1914 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
1916 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ
, SEND
))
1917 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1918 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
1922 /* schedule loading_done if request list is empty */
1923 if (on
->request_list
->count
== 0)
1925 thread_add_event (master
, loading_done
, on
, 0, NULL
);
1929 memset (sendbuf
, 0, iobuflen
);
1930 oh
= (struct ospf6_header
*) sendbuf
;
1933 /* set Request entries in lsreq */
1934 p
= (u_char
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1935 for (lsa
= ospf6_lsdb_head (on
->request_list
); lsa
;
1936 lsa
= ospf6_lsdb_next (lsa
))
1939 if (p
- sendbuf
+ sizeof (struct ospf6_lsreq_entry
) > ospf6_packet_max(on
->ospf6_if
))
1941 ospf6_lsdb_lsa_unlock (lsa
);
1945 e
= (struct ospf6_lsreq_entry
*) p
;
1946 e
->type
= lsa
->header
->type
;
1947 e
->id
= lsa
->header
->id
;
1948 e
->adv_router
= lsa
->header
->adv_router
;
1949 p
+= sizeof (struct ospf6_lsreq_entry
);
1953 if (last_req
!= NULL
)
1955 if (on
->last_ls_req
!= NULL
)
1957 ospf6_lsa_unlock (on
->last_ls_req
);
1959 ospf6_lsa_lock (last_req
);
1960 on
->last_ls_req
= last_req
;
1963 oh
->type
= OSPF6_MESSAGE_TYPE_LSREQ
;
1964 oh
->length
= htons (p
- sendbuf
);
1966 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
1967 ospf6_send (on
->ospf6_if
->linklocal_addr
, &allspfrouters6
,
1970 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
1973 /* set next thread */
1974 if (on
->request_list
->count
!= 0)
1976 on
->thread_send_lsreq
= NULL
;
1977 thread_add_timer(master
, ospf6_lsreq_send
, on
, on
->ospf6_if
->rxmt_interval
,
1978 &on
->thread_send_lsreq
);
1985 ospf6_lsupdate_send_neighbor (struct thread
*thread
)
1987 struct ospf6_neighbor
*on
;
1988 struct ospf6_header
*oh
;
1989 struct ospf6_lsupdate
*lsupdate
;
1992 struct ospf6_lsa
*lsa
;
1994 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1995 on
->thread_send_lsupdate
= (struct thread
*) NULL
;
1997 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
1998 zlog_debug ("LSUpdate to neighbor %s", on
->name
);
2000 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
2002 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
2003 zlog_debug ("Quit to send (neighbor state %s)",
2004 ospf6_neighbor_state_str
[on
->state
]);
2008 memset (sendbuf
, 0, iobuflen
);
2009 oh
= (struct ospf6_header
*) sendbuf
;
2010 lsupdate
= (struct ospf6_lsupdate
*)
2011 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2013 p
= (u_char
*)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
2016 /* lsupdate_list lists those LSA which doesn't need to be
2017 retransmitted. remove those from the list */
2018 for (lsa
= ospf6_lsdb_head (on
->lsupdate_list
); lsa
;
2019 lsa
= ospf6_lsdb_next (lsa
))
2022 if ( (p
- sendbuf
+ (unsigned int)OSPF6_LSA_SIZE (lsa
->header
))
2023 > ospf6_packet_max(on
->ospf6_if
))
2025 ospf6_lsdb_lsa_unlock (lsa
);
2029 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
2030 memcpy (p
, lsa
->header
, OSPF6_LSA_SIZE (lsa
->header
));
2031 p
+= OSPF6_LSA_SIZE (lsa
->header
);
2034 assert (lsa
->lock
== 2);
2035 ospf6_lsdb_remove (lsa
, on
->lsupdate_list
);
2040 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2041 oh
->length
= htons (p
- sendbuf
);
2042 lsupdate
->lsa_number
= htonl (lsa_cnt
);
2044 if ((on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
) ||
2045 (on
->ospf6_if
->state
== OSPF6_INTERFACE_DR
) ||
2046 (on
->ospf6_if
->state
== OSPF6_INTERFACE_BDR
))
2047 ospf6_send (on
->ospf6_if
->linklocal_addr
, &allspfrouters6
,
2050 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
2054 /* The addresses used for retransmissions are different from those sent the
2055 first time and so we need to separate them here.
2057 memset (sendbuf
, 0, iobuflen
);
2058 oh
= (struct ospf6_header
*) sendbuf
;
2059 lsupdate
= (struct ospf6_lsupdate
*)
2060 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2061 p
= (u_char
*)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
2064 for (lsa
= ospf6_lsdb_head (on
->retrans_list
); lsa
;
2065 lsa
= ospf6_lsdb_next (lsa
))
2068 if ( (p
- sendbuf
+ (unsigned int)OSPF6_LSA_SIZE (lsa
->header
))
2069 > ospf6_packet_max(on
->ospf6_if
))
2071 ospf6_lsdb_lsa_unlock (lsa
);
2075 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
2076 memcpy (p
, lsa
->header
, OSPF6_LSA_SIZE (lsa
->header
));
2077 p
+= OSPF6_LSA_SIZE (lsa
->header
);
2083 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2084 oh
->length
= htons (p
- sendbuf
);
2085 lsupdate
->lsa_number
= htonl (lsa_cnt
);
2087 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2088 ospf6_send (on
->ospf6_if
->linklocal_addr
, &allspfrouters6
,
2091 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
2095 if (on
->lsupdate_list
->count
!= 0) {
2096 on
->thread_send_lsupdate
= NULL
;
2097 thread_add_event(master
, ospf6_lsupdate_send_neighbor
, on
, 0,
2098 &on
->thread_send_lsupdate
);
2100 else if (on
->retrans_list
->count
!= 0) {
2101 on
->thread_send_lsupdate
= NULL
;
2102 thread_add_timer(master
, ospf6_lsupdate_send_neighbor
, on
, on
->ospf6_if
->rxmt_interval
,
2103 &on
->thread_send_lsupdate
);
2109 ospf6_lsupdate_send_interface (struct thread
*thread
)
2111 struct ospf6_interface
*oi
;
2112 struct ospf6_header
*oh
;
2113 struct ospf6_lsupdate
*lsupdate
;
2116 struct ospf6_lsa
*lsa
;
2118 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
2119 oi
->thread_send_lsupdate
= (struct thread
*) NULL
;
2121 if (oi
->state
<= OSPF6_INTERFACE_WAITING
)
2123 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
2124 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
2125 oi
->interface
->name
, ospf6_interface_state_str
[oi
->state
]);
2129 /* if we have nothing to send, return */
2130 if (oi
->lsupdate_list
->count
== 0)
2133 memset (sendbuf
, 0, iobuflen
);
2134 oh
= (struct ospf6_header
*) sendbuf
;
2135 lsupdate
= (struct ospf6_lsupdate
*)((caddr_t
) oh
+
2136 sizeof (struct ospf6_header
));
2138 p
= (u_char
*)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
2141 for (lsa
= ospf6_lsdb_head (oi
->lsupdate_list
); lsa
;
2142 lsa
= ospf6_lsdb_next (lsa
))
2145 if ( (p
- sendbuf
+ ((unsigned int)OSPF6_LSA_SIZE (lsa
->header
)))
2146 > ospf6_packet_max(oi
))
2148 ospf6_lsdb_lsa_unlock (lsa
);
2152 ospf6_lsa_age_update_to_send (lsa
, oi
->transdelay
);
2153 memcpy (p
, lsa
->header
, OSPF6_LSA_SIZE (lsa
->header
));
2154 p
+= OSPF6_LSA_SIZE (lsa
->header
);
2157 assert (lsa
->lock
== 2);
2158 ospf6_lsdb_remove (lsa
, oi
->lsupdate_list
);
2163 lsupdate
->lsa_number
= htonl (lsa_cnt
);
2165 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2166 oh
->length
= htons (p
- sendbuf
);
2168 if ((oi
->state
== OSPF6_INTERFACE_POINTTOPOINT
) ||
2169 (oi
->state
== OSPF6_INTERFACE_DR
) ||
2170 (oi
->state
== OSPF6_INTERFACE_BDR
))
2171 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
2173 ospf6_send (oi
->linklocal_addr
, &alldrouters6
, oi
, oh
);
2177 if (oi
->lsupdate_list
->count
> 0)
2179 oi
->thread_send_lsupdate
= NULL
;
2180 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
2181 &oi
->thread_send_lsupdate
);
2188 ospf6_lsack_send_neighbor (struct thread
*thread
)
2190 struct ospf6_neighbor
*on
;
2191 struct ospf6_header
*oh
;
2193 struct ospf6_lsa
*lsa
;
2196 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
2197 on
->thread_send_lsack
= (struct thread
*) NULL
;
2199 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
2201 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK
, SEND
))
2202 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
2203 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
2207 /* if we have nothing to send, return */
2208 if (on
->lsack_list
->count
== 0)
2211 memset (sendbuf
, 0, iobuflen
);
2212 oh
= (struct ospf6_header
*) sendbuf
;
2214 p
= (u_char
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2216 for (lsa
= ospf6_lsdb_head (on
->lsack_list
); lsa
;
2217 lsa
= ospf6_lsdb_next (lsa
))
2220 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) > ospf6_packet_max(on
->ospf6_if
))
2222 /* if we run out of packet size/space here,
2223 better to try again soon. */
2224 THREAD_OFF (on
->thread_send_lsack
);
2225 thread_add_event (master
, ospf6_lsack_send_neighbor
, on
, 0, &on
->thread_send_lsack
);
2227 ospf6_lsdb_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
);
2242 oh
->type
= OSPF6_MESSAGE_TYPE_LSACK
;
2243 oh
->length
= htons (p
- sendbuf
);
2245 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
2249 if (on
->lsack_list
->count
> 0)
2250 thread_add_event (master
, ospf6_lsack_send_neighbor
, on
, 0, &on
->thread_send_lsack
);
2256 ospf6_lsack_send_interface (struct thread
*thread
)
2258 struct ospf6_interface
*oi
;
2259 struct ospf6_header
*oh
;
2261 struct ospf6_lsa
*lsa
;
2264 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
2265 oi
->thread_send_lsack
= (struct thread
*) NULL
;
2267 if (oi
->state
<= OSPF6_INTERFACE_WAITING
)
2269 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK
, SEND
))
2270 zlog_debug ("Quit to send LSAck to interface %s state %s",
2271 oi
->interface
->name
, ospf6_interface_state_str
[oi
->state
]);
2275 /* if we have nothing to send, return */
2276 if (oi
->lsack_list
->count
== 0)
2279 memset (sendbuf
, 0, iobuflen
);
2280 oh
= (struct ospf6_header
*) sendbuf
;
2282 p
= (u_char
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
2284 for (lsa
= ospf6_lsdb_head (oi
->lsack_list
); lsa
;
2285 lsa
= ospf6_lsdb_next (lsa
))
2288 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) > ospf6_packet_max(oi
))
2290 /* if we run out of packet size/space here,
2291 better to try again soon. */
2292 THREAD_OFF (oi
->thread_send_lsack
);
2293 thread_add_event (master
, ospf6_lsack_send_interface
, oi
, 0,
2294 &oi
->thread_send_lsack
);
2296 ospf6_lsdb_lsa_unlock (lsa
);
2300 ospf6_lsa_age_update_to_send (lsa
, oi
->transdelay
);
2301 memcpy (p
, lsa
->header
, sizeof (struct ospf6_lsa_header
));
2302 p
+= sizeof (struct ospf6_lsa_header
);
2304 assert (lsa
->lock
== 2);
2305 ospf6_lsdb_remove (lsa
, oi
->lsack_list
);
2311 oh
->type
= OSPF6_MESSAGE_TYPE_LSACK
;
2312 oh
->length
= htons (p
- sendbuf
);
2314 if ((oi
->state
== OSPF6_INTERFACE_POINTTOPOINT
) ||
2315 (oi
->state
== OSPF6_INTERFACE_DR
) ||
2316 (oi
->state
== OSPF6_INTERFACE_BDR
))
2317 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
2319 ospf6_send (oi
->linklocal_addr
, &alldrouters6
, oi
, oh
);
2322 if (oi
->lsack_list
->count
> 0)
2323 thread_add_event (master
, ospf6_lsack_send_interface
, oi
, 0, &oi
->thread_send_lsack
);
2330 DEFUN (debug_ospf6_message
,
2331 debug_ospf6_message_cmd
,
2332 "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv>]",
2335 "Debug OSPFv3 message\n"
2336 "Debug Unknown message\n"
2337 "Debug Hello message\n"
2338 "Debug Database Description message\n"
2339 "Debug Link State Request message\n"
2340 "Debug Link State Update message\n"
2341 "Debug Link State Acknowledgement message\n"
2342 "Debug All message\n"
2343 "Debug only sending message\n"
2344 "Debug only receiving message\n")
2347 int idx_send_recv
= 4;
2348 unsigned char level
= 0;
2353 if (! strncmp (argv
[idx_packet
]->arg
, "u", 1))
2354 type
= OSPF6_MESSAGE_TYPE_UNKNOWN
;
2355 else if (! strncmp (argv
[idx_packet
]->arg
, "h", 1))
2356 type
= OSPF6_MESSAGE_TYPE_HELLO
;
2357 else if (! strncmp (argv
[idx_packet
]->arg
, "d", 1))
2358 type
= OSPF6_MESSAGE_TYPE_DBDESC
;
2359 else if (! strncmp (argv
[idx_packet
]->arg
, "lsr", 3))
2360 type
= OSPF6_MESSAGE_TYPE_LSREQ
;
2361 else if (! strncmp (argv
[idx_packet
]->arg
, "lsu", 3))
2362 type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2363 else if (! strncmp (argv
[idx_packet
]->arg
, "lsa", 3))
2364 type
= OSPF6_MESSAGE_TYPE_LSACK
;
2365 else if (! strncmp (argv
[idx_packet
]->arg
, "a", 1))
2366 type
= OSPF6_MESSAGE_TYPE_ALL
;
2369 level
= OSPF6_DEBUG_MESSAGE_SEND
| OSPF6_DEBUG_MESSAGE_RECV
;
2370 else if (! strncmp (argv
[idx_send_recv
]->arg
, "s", 1))
2371 level
= OSPF6_DEBUG_MESSAGE_SEND
;
2372 else if (! strncmp (argv
[idx_send_recv
]->arg
, "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 DEFUN (no_debug_ospf6_message
,
2387 no_debug_ospf6_message_cmd
,
2388 "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv>]",
2392 "Debug OSPFv3 message\n"
2393 "Debug Unknown message\n"
2394 "Debug Hello message\n"
2395 "Debug Database Description message\n"
2396 "Debug Link State Request message\n"
2397 "Debug Link State Update message\n"
2398 "Debug Link State Acknowledgement message\n"
2399 "Debug All message\n"
2400 "Debug only sending message\n"
2401 "Debug only receiving message\n")
2404 int idx_send_recv
= 5;
2405 unsigned char level
= 0;
2410 if (! strncmp (argv
[idx_packet
]->arg
, "u", 1))
2411 type
= OSPF6_MESSAGE_TYPE_UNKNOWN
;
2412 else if (! strncmp (argv
[idx_packet
]->arg
, "h", 1))
2413 type
= OSPF6_MESSAGE_TYPE_HELLO
;
2414 else if (! strncmp (argv
[idx_packet
]->arg
, "d", 1))
2415 type
= OSPF6_MESSAGE_TYPE_DBDESC
;
2416 else if (! strncmp (argv
[idx_packet
]->arg
, "lsr", 3))
2417 type
= OSPF6_MESSAGE_TYPE_LSREQ
;
2418 else if (! strncmp (argv
[idx_packet
]->arg
, "lsu", 3))
2419 type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2420 else if (! strncmp (argv
[idx_packet
]->arg
, "lsa", 3))
2421 type
= OSPF6_MESSAGE_TYPE_LSACK
;
2422 else if (! strncmp (argv
[idx_packet
]->arg
, "a", 1))
2423 type
= OSPF6_MESSAGE_TYPE_ALL
;
2426 level
= OSPF6_DEBUG_MESSAGE_SEND
| OSPF6_DEBUG_MESSAGE_RECV
;
2427 else if (! strncmp (argv
[idx_send_recv
]->arg
, "s", 1))
2428 level
= OSPF6_DEBUG_MESSAGE_SEND
;
2429 else if (! strncmp (argv
[idx_send_recv
]->arg
, "r", 1))
2430 level
= OSPF6_DEBUG_MESSAGE_RECV
;
2432 if (type
== OSPF6_MESSAGE_TYPE_ALL
)
2434 for (i
= 0; i
< 6; i
++)
2435 OSPF6_DEBUG_MESSAGE_OFF (i
, level
);
2438 OSPF6_DEBUG_MESSAGE_OFF (type
, level
);
2445 config_write_ospf6_debug_message (struct vty
*vty
)
2447 const char *type_str
[] = {"unknown", "hello", "dbdesc",
2448 "lsreq", "lsupdate", "lsack"};
2449 unsigned char s
= 0, r
= 0;
2452 for (i
= 0; i
< 6; i
++)
2454 if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
))
2456 if (IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2460 if (s
== 0x3f && r
== 0x3f)
2462 vty_out (vty
, "debug ospf6 message all%s", VNL
);
2466 if (s
== 0x3f && r
== 0)
2468 vty_out (vty
, "debug ospf6 message all send%s", VNL
);
2471 else if (s
== 0 && r
== 0x3f)
2473 vty_out (vty
, "debug ospf6 message all recv%s", VNL
);
2477 /* Unknown message is logged by default */
2478 if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, SEND
) &&
2479 ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
2480 vty_out (vty
, "no debug ospf6 message unknown%s", VNL
);
2481 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, SEND
))
2482 vty_out (vty
, "no debug ospf6 message unknown send%s", VNL
);
2483 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
2484 vty_out (vty
, "no debug ospf6 message unknown recv%s", VNL
);
2486 for (i
= 1; i
< 6; i
++)
2488 if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
) &&
2489 IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2490 vty_out (vty
, "debug ospf6 message %s%s", type_str
[i
], VNL
);
2491 else if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
))
2492 vty_out (vty
, "debug ospf6 message %s send%s", type_str
[i
],
2494 else if (IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2495 vty_out (vty
, "debug ospf6 message %s recv%s", type_str
[i
],
2503 install_element_ospf6_debug_message (void)
2505 install_element (ENABLE_NODE
, &debug_ospf6_message_cmd
);
2506 install_element (ENABLE_NODE
, &no_debug_ospf6_message_cmd
);
2507 install_element (CONFIG_NODE
, &debug_ospf6_message_cmd
);
2508 install_element (CONFIG_NODE
, &no_debug_ospf6_message_cmd
);