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 #include "ospf6_flood.h"
45 unsigned char conf_debug_ospf6_message
[6] = {0x03, 0, 0, 0, 0, 0};
46 const char *ospf6_message_type_str
[] =
47 { "Unknown", "Hello", "DbDesc", "LSReq", "LSUpdate", "LSAck" };
52 ospf6_header_print (struct ospf6_header
*oh
)
54 char router_id
[16], area_id
[16];
55 inet_ntop (AF_INET
, &oh
->router_id
, router_id
, sizeof (router_id
));
56 inet_ntop (AF_INET
, &oh
->area_id
, area_id
, sizeof (area_id
));
58 zlog_debug (" OSPFv%d Type:%d Len:%hu Router-ID:%s",
59 oh
->version
, oh
->type
, ntohs (oh
->length
), router_id
);
60 zlog_debug (" Area-ID:%s Cksum:%hx Instance-ID:%d",
61 area_id
, ntohs (oh
->checksum
), oh
->instance_id
);
65 ospf6_hello_print (struct ospf6_header
*oh
)
67 struct ospf6_hello
*hello
;
69 char drouter
[16], bdrouter
[16], neighbor
[16];
72 ospf6_header_print (oh
);
73 assert (oh
->type
== OSPF6_MESSAGE_TYPE_HELLO
);
75 hello
= (struct ospf6_hello
*)
76 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
78 inet_ntop (AF_INET
, &hello
->drouter
, drouter
, sizeof (drouter
));
79 inet_ntop (AF_INET
, &hello
->bdrouter
, bdrouter
, sizeof (bdrouter
));
80 ospf6_options_printbuf (hello
->options
, options
, sizeof (options
));
82 zlog_debug (" I/F-Id:%ld Priority:%d Option:%s",
83 (u_long
) ntohl (hello
->interface_id
), hello
->priority
, options
);
84 zlog_debug (" HelloInterval:%hu DeadInterval:%hu",
85 ntohs (hello
->hello_interval
), ntohs (hello
->dead_interval
));
86 zlog_debug (" DR:%s BDR:%s", drouter
, bdrouter
);
88 for (p
= (char *) ((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
89 p
+ sizeof (u_int32_t
) <= OSPF6_MESSAGE_END (oh
);
90 p
+= sizeof (u_int32_t
))
92 inet_ntop (AF_INET
, (void *) p
, neighbor
, sizeof (neighbor
));
93 zlog_debug (" Neighbor: %s", neighbor
);
96 if (p
!= OSPF6_MESSAGE_END (oh
))
97 zlog_debug ("Trailing garbage exists");
101 ospf6_dbdesc_print (struct ospf6_header
*oh
)
103 struct ospf6_dbdesc
*dbdesc
;
107 ospf6_header_print (oh
);
108 assert (oh
->type
== OSPF6_MESSAGE_TYPE_DBDESC
);
110 dbdesc
= (struct ospf6_dbdesc
*)
111 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
113 ospf6_options_printbuf (dbdesc
->options
, options
, sizeof (options
));
115 zlog_debug (" MBZ: %#x Option: %s IfMTU: %hu",
116 dbdesc
->reserved1
, options
, ntohs (dbdesc
->ifmtu
));
117 zlog_debug (" MBZ: %#x Bits: %s%s%s SeqNum: %#lx",
119 (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
) ? "I" : "-"),
120 (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MBIT
) ? "M" : "-"),
121 (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) ? "m" : "s"),
122 (u_long
) ntohl (dbdesc
->seqnum
));
124 for (p
= (char *) ((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
125 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
126 p
+= sizeof (struct ospf6_lsa_header
))
127 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
129 if (p
!= OSPF6_MESSAGE_END (oh
))
130 zlog_debug ("Trailing garbage exists");
134 ospf6_lsreq_print (struct ospf6_header
*oh
)
136 char id
[16], adv_router
[16];
139 ospf6_header_print (oh
);
140 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSREQ
);
142 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
143 p
+ sizeof (struct ospf6_lsreq_entry
) <= OSPF6_MESSAGE_END (oh
);
144 p
+= sizeof (struct ospf6_lsreq_entry
))
146 struct ospf6_lsreq_entry
*e
= (struct ospf6_lsreq_entry
*) p
;
147 inet_ntop (AF_INET
, &e
->adv_router
, adv_router
, sizeof (adv_router
));
148 inet_ntop (AF_INET
, &e
->id
, id
, sizeof (id
));
149 zlog_debug (" [%s Id:%s Adv:%s]",
150 ospf6_lstype_name (e
->type
), id
, adv_router
);
153 if (p
!= OSPF6_MESSAGE_END (oh
))
154 zlog_debug ("Trailing garbage exists");
158 ospf6_lsupdate_print (struct ospf6_header
*oh
)
160 struct ospf6_lsupdate
*lsupdate
;
164 ospf6_header_print (oh
);
165 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSUPDATE
);
167 lsupdate
= (struct ospf6_lsupdate
*)
168 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
170 num
= ntohl (lsupdate
->lsa_number
);
171 zlog_debug (" Number of LSA: %ld", num
);
173 for (p
= (char *) ((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
174 p
< OSPF6_MESSAGE_END (oh
) &&
175 p
+ OSPF6_LSA_SIZE (p
) <= OSPF6_MESSAGE_END (oh
);
176 p
+= OSPF6_LSA_SIZE (p
))
178 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
179 if (OSPF6_LSA_SIZE (p
) < sizeof (struct ospf6_lsa_header
))
181 zlog_debug (" Malformed LSA length, quit printing");
186 if (p
!= OSPF6_MESSAGE_END (oh
))
191 memset (buf
, 0, sizeof (buf
));
193 zlog_debug (" Trailing garbage exists");
194 while (p
< OSPF6_MESSAGE_END (oh
))
196 snprintf (buf
, sizeof (buf
), "%s %2x", buf
, *p
++);
200 zlog_debug (" %s", buf
);
201 memset (buf
, 0, sizeof (buf
));
206 zlog_debug (" %s", buf
);
211 ospf6_lsack_print (struct ospf6_header
*oh
)
215 ospf6_header_print (oh
);
216 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
218 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
219 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
220 p
+= sizeof (struct ospf6_lsa_header
))
221 ospf6_lsa_header_print_raw ((struct ospf6_lsa_header
*) p
);
223 if (p
!= OSPF6_MESSAGE_END (oh
))
224 zlog_debug ("Trailing garbage exists");
227 /* Receive function */
231 ospf6_header_examin (struct in6_addr
*src
, struct in6_addr
*dst
,
232 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
235 type
= OSPF6_MESSAGE_TYPE_CANONICAL (oh
->type
);
238 if (oh
->version
!= OSPFV3_VERSION
)
240 if (IS_OSPF6_DEBUG_MESSAGE (type
, RECV
))
241 zlog_debug ("Message with unknown version");
246 if (oh
->area_id
!= oi
->area
->area_id
)
248 if (oh
->area_id
== BACKBONE_AREA_ID
)
250 if (IS_OSPF6_DEBUG_MESSAGE (type
, RECV
))
251 zlog_debug ("Message may be via Virtual Link: not supported");
255 if (IS_OSPF6_DEBUG_MESSAGE (type
, RECV
))
256 zlog_debug ("Area-ID mismatch");
260 /* Instance-ID check */
261 if (oh
->instance_id
!= oi
->instance_id
)
263 if (IS_OSPF6_DEBUG_MESSAGE (type
, RECV
))
264 zlog_debug ("Instance-ID mismatch");
268 /* Router-ID check */
269 if (oh
->router_id
== oi
->area
->ospf6
->router_id
)
270 zlog_warn ("Detect duplicate Router-ID");
276 ospf6_hello_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
277 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
279 struct ospf6_hello
*hello
;
280 struct ospf6_neighbor
*on
;
283 int neighborchange
= 0;
286 if (ospf6_header_examin (src
, dst
, oi
, oh
) != MSG_OK
)
289 hello
= (struct ospf6_hello
*)
290 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
292 /* HelloInterval check */
293 if (ntohs (hello
->hello_interval
) != oi
->hello_interval
)
295 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
296 zlog_debug ("HelloInterval mismatch");
300 /* RouterDeadInterval check */
301 if (ntohs (hello
->dead_interval
) != oi
->dead_interval
)
303 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
304 zlog_debug ("RouterDeadInterval mismatch");
309 if (OSPF6_OPT_ISSET (hello
->options
, OSPF6_OPT_E
) !=
310 OSPF6_OPT_ISSET (oi
->area
->options
, OSPF6_OPT_E
))
312 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
313 zlog_debug ("E-bit mismatch");
317 /* Find neighbor, create if not exist */
318 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
321 on
= ospf6_neighbor_create (oh
->router_id
, oi
);
322 on
->prev_drouter
= on
->drouter
= hello
->drouter
;
323 on
->prev_bdrouter
= on
->bdrouter
= hello
->bdrouter
;
324 on
->priority
= hello
->priority
;
325 on
->ifindex
= ntohl (hello
->interface_id
);
326 memcpy (&on
->linklocal_addr
, src
, sizeof (struct in6_addr
));
330 for (p
= (char *) ((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
331 p
+ sizeof (u_int32_t
) <= OSPF6_MESSAGE_END (oh
);
332 p
+= sizeof (u_int32_t
))
334 u_int32_t
*router_id
= (u_int32_t
*) p
;
336 if (*router_id
== oi
->area
->ospf6
->router_id
)
340 if (p
!= OSPF6_MESSAGE_END (oh
))
342 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
343 zlog_debug ("Trailing garbage ignored");
346 /* RouterPriority check */
347 if (on
->priority
!= hello
->priority
)
349 on
->priority
= hello
->priority
;
354 if (on
->drouter
!= hello
->drouter
)
356 on
->prev_drouter
= on
->drouter
;
357 on
->drouter
= hello
->drouter
;
358 if (on
->prev_drouter
== on
->router_id
|| on
->drouter
== on
->router_id
)
363 if (on
->bdrouter
!= hello
->bdrouter
)
365 on
->prev_bdrouter
= on
->bdrouter
;
366 on
->bdrouter
= hello
->bdrouter
;
367 if (on
->prev_bdrouter
== on
->router_id
|| on
->bdrouter
== on
->router_id
)
371 /* BackupSeen check */
372 if (oi
->state
== OSPF6_INTERFACE_WAITING
)
374 if (hello
->bdrouter
== on
->router_id
)
376 else if (hello
->drouter
== on
->router_id
&& hello
->bdrouter
== htonl (0))
380 /* Execute neighbor events */
381 thread_execute (master
, hello_received
, on
, 0);
383 thread_execute (master
, twoway_received
, on
, 0);
385 thread_execute (master
, oneway_received
, on
, 0);
387 /* Schedule interface events */
389 thread_add_event (master
, backup_seen
, oi
, 0);
391 thread_add_event (master
, neighbor_change
, oi
, 0);
395 ospf6_dbdesc_recv_master (struct ospf6_header
*oh
,
396 struct ospf6_neighbor
*on
)
398 struct ospf6_dbdesc
*dbdesc
;
401 dbdesc
= (struct ospf6_dbdesc
*)
402 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
404 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
406 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
407 zlog_debug ("Neighbor state less than Init, ignore");
413 case OSPF6_NEIGHBOR_TWOWAY
:
414 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
415 zlog_debug ("Neighbor state is 2-Way, ignore");
418 case OSPF6_NEIGHBOR_INIT
:
419 thread_execute (master
, twoway_received
, on
, 0);
420 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
)
422 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
423 zlog_debug ("Neighbor state is not ExStart, ignore");
426 /* else fall through to ExStart */
428 case OSPF6_NEIGHBOR_EXSTART
:
429 /* if neighbor obeys us as our slave, schedule negotiation_done
430 and process LSA Headers. Otherwise, ignore this message */
431 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) &&
432 ! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
) &&
433 ntohl (dbdesc
->seqnum
) == on
->dbdesc_seqnum
)
435 /* execute NegotiationDone */
436 thread_execute (master
, negotiation_done
, on
, 0);
438 /* Record neighbor options */
439 memcpy (on
->options
, dbdesc
->options
, sizeof (on
->options
));
443 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
444 zlog_debug ("Negotiation failed");
447 /* fall through to exchange */
449 case OSPF6_NEIGHBOR_EXCHANGE
:
450 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
452 /* Duplicated DatabaseDescription is dropped by master */
453 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
454 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
458 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
))
460 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
461 zlog_debug ("Master/Slave bit mismatch");
462 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
466 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
))
468 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
469 zlog_debug ("Initialize bit mismatch");
470 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
474 if (memcmp (on
->options
, dbdesc
->options
, sizeof (on
->options
)))
476 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
477 zlog_debug ("Option field mismatch");
478 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
482 if (ntohl (dbdesc
->seqnum
) != on
->dbdesc_seqnum
)
484 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
485 zlog_debug ("Sequence number mismatch (%#lx expected)",
486 (u_long
) on
->dbdesc_seqnum
);
487 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
492 case OSPF6_NEIGHBOR_LOADING
:
493 case OSPF6_NEIGHBOR_FULL
:
494 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
496 /* Duplicated DatabaseDescription is dropped by master */
497 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
498 zlog_debug ("Duplicated dbdesc discarded by Master, ignore");
502 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
503 zlog_debug ("Not duplicate dbdesc in state %s",
504 ospf6_neighbor_state_str
[on
->state
]);
505 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
513 /* Process LSA headers */
514 for (p
= (char *) ((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
515 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
516 p
+= sizeof (struct ospf6_lsa_header
))
518 struct ospf6_lsa
*his
, *mine
;
519 struct ospf6_lsdb
*lsdb
= NULL
;
521 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
523 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
524 zlog_debug ("%s", his
->name
);
526 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
528 case OSPF6_SCOPE_LINKLOCAL
:
529 lsdb
= on
->ospf6_if
->lsdb
;
531 case OSPF6_SCOPE_AREA
:
532 lsdb
= on
->ospf6_if
->area
->lsdb
;
535 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
537 case OSPF6_SCOPE_RESERVED
:
538 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
539 zlog_debug ("Ignoring LSA of reserved scope");
540 ospf6_lsa_delete (his
);
545 if (ntohs (his
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
546 IS_AREA_STUB (on
->ospf6_if
->area
))
548 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
549 zlog_debug ("SeqNumMismatch (E-bit mismatch), discard");
550 ospf6_lsa_delete (his
);
551 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
555 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
556 his
->header
->adv_router
, lsdb
);
559 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
560 zlog_debug ("Add request (No database copy)");
561 ospf6_lsdb_add (his
, on
->request_list
);
563 else if (ospf6_lsa_compare (his
, mine
) < 0)
565 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
566 zlog_debug ("Add request (Received MoreRecent)");
567 ospf6_lsdb_add (his
, on
->request_list
);
571 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
572 zlog_debug ("Discard (Existing MoreRecent)");
573 ospf6_lsa_delete (his
);
577 if (p
!= OSPF6_MESSAGE_END (oh
))
579 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
580 zlog_debug ("Trailing garbage ignored");
583 /* Increment sequence number */
584 on
->dbdesc_seqnum
++;
586 /* schedule send lsreq */
587 if (on
->thread_send_lsreq
== NULL
)
588 on
->thread_send_lsreq
=
589 thread_add_event (master
, ospf6_lsreq_send
, on
, 0);
591 THREAD_OFF (on
->thread_send_dbdesc
);
594 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MBIT
) &&
595 ! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
))
596 thread_add_event (master
, exchange_done
, on
, 0);
598 on
->thread_send_dbdesc
=
599 thread_add_event (master
, ospf6_dbdesc_send_newone
, on
, 0);
601 /* save last received dbdesc */
602 memcpy (&on
->dbdesc_last
, dbdesc
, sizeof (struct ospf6_dbdesc
));
606 ospf6_dbdesc_recv_slave (struct ospf6_header
*oh
,
607 struct ospf6_neighbor
*on
)
609 struct ospf6_dbdesc
*dbdesc
;
612 dbdesc
= (struct ospf6_dbdesc
*)
613 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
615 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
617 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
618 zlog_debug ("Neighbor state less than Init, ignore");
624 case OSPF6_NEIGHBOR_TWOWAY
:
625 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
626 zlog_debug ("Neighbor state is 2-Way, ignore");
629 case OSPF6_NEIGHBOR_INIT
:
630 thread_execute (master
, twoway_received
, on
, 0);
631 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
)
633 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
634 zlog_debug ("Neighbor state is not ExStart, ignore");
637 /* else fall through to ExStart */
639 case OSPF6_NEIGHBOR_EXSTART
:
640 /* If the neighbor is Master, act as Slave. Schedule negotiation_done
641 and process LSA Headers. Otherwise, ignore this message */
642 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
) &&
643 CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MBIT
) &&
644 CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) &&
645 ntohs (oh
->length
) == sizeof (struct ospf6_header
) +
646 sizeof (struct ospf6_dbdesc
))
648 /* set the master/slave bit to slave */
649 UNSET_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
);
651 /* set the DD sequence number to one specified by master */
652 on
->dbdesc_seqnum
= ntohl (dbdesc
->seqnum
);
654 /* schedule NegotiationDone */
655 thread_execute (master
, negotiation_done
, on
, 0);
657 /* Record neighbor options */
658 memcpy (on
->options
, dbdesc
->options
, sizeof (on
->options
));
662 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
663 zlog_debug ("Negotiation failed");
668 case OSPF6_NEIGHBOR_EXCHANGE
:
669 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
671 /* Duplicated DatabaseDescription causes slave to retransmit */
672 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
673 zlog_debug ("Duplicated dbdesc causes retransmit");
674 THREAD_OFF (on
->thread_send_dbdesc
);
675 on
->thread_send_dbdesc
=
676 thread_add_event (master
, ospf6_dbdesc_send
, on
, 0);
680 if (! CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_MSBIT
))
682 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
683 zlog_debug ("Master/Slave bit mismatch");
684 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
688 if (CHECK_FLAG (dbdesc
->bits
, OSPF6_DBDESC_IBIT
))
690 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
691 zlog_debug ("Initialize bit mismatch");
692 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
696 if (memcmp (on
->options
, dbdesc
->options
, sizeof (on
->options
)))
698 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
699 zlog_debug ("Option field mismatch");
700 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
704 if (ntohl (dbdesc
->seqnum
) != on
->dbdesc_seqnum
+ 1)
706 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
707 zlog_debug ("Sequence number mismatch (%#lx expected)",
708 (u_long
) on
->dbdesc_seqnum
+ 1);
709 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
714 case OSPF6_NEIGHBOR_LOADING
:
715 case OSPF6_NEIGHBOR_FULL
:
716 if (! memcmp (dbdesc
, &on
->dbdesc_last
, sizeof (struct ospf6_dbdesc
)))
718 /* Duplicated DatabaseDescription causes slave to retransmit */
719 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
720 zlog_debug ("Duplicated dbdesc causes retransmit");
721 THREAD_OFF (on
->thread_send_dbdesc
);
722 on
->thread_send_dbdesc
=
723 thread_add_event (master
, ospf6_dbdesc_send
, on
, 0);
727 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
728 zlog_debug ("Not duplicate dbdesc in state %s",
729 ospf6_neighbor_state_str
[on
->state
]);
730 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
738 /* Process LSA headers */
739 for (p
= (char *) ((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
740 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
741 p
+= sizeof (struct ospf6_lsa_header
))
743 struct ospf6_lsa
*his
, *mine
;
744 struct ospf6_lsdb
*lsdb
= NULL
;
746 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
748 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
750 case OSPF6_SCOPE_LINKLOCAL
:
751 lsdb
= on
->ospf6_if
->lsdb
;
753 case OSPF6_SCOPE_AREA
:
754 lsdb
= on
->ospf6_if
->area
->lsdb
;
757 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
759 case OSPF6_SCOPE_RESERVED
:
760 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
761 zlog_debug ("Ignoring LSA of reserved scope");
762 ospf6_lsa_delete (his
);
767 if (OSPF6_LSA_SCOPE (his
->header
->type
) == OSPF6_SCOPE_AS
&&
768 IS_AREA_STUB (on
->ospf6_if
->area
))
770 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
771 zlog_debug ("E-bit mismatch with LSA Headers");
772 ospf6_lsa_delete (his
);
773 thread_add_event (master
, seqnumber_mismatch
, on
, 0);
777 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
778 his
->header
->adv_router
, lsdb
);
779 if (mine
== NULL
|| ospf6_lsa_compare (his
, mine
) < 0)
781 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
782 zlog_debug ("Add request-list: %s", his
->name
);
783 ospf6_lsdb_add (his
, on
->request_list
);
786 ospf6_lsa_delete (his
);
789 if (p
!= OSPF6_MESSAGE_END (oh
))
791 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
792 zlog_debug ("Trailing garbage ignored");
795 /* Set sequence number to Master's */
796 on
->dbdesc_seqnum
= ntohl (dbdesc
->seqnum
);
798 /* schedule send lsreq */
799 if (on
->thread_send_lsreq
== NULL
)
800 on
->thread_send_lsreq
=
801 thread_add_event (master
, ospf6_lsreq_send
, on
, 0);
803 THREAD_OFF (on
->thread_send_dbdesc
);
804 on
->thread_send_dbdesc
=
805 thread_add_event (master
, ospf6_dbdesc_send_newone
, on
, 0);
807 /* save last received dbdesc */
808 memcpy (&on
->dbdesc_last
, dbdesc
, sizeof (struct ospf6_dbdesc
));
812 ospf6_dbdesc_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
813 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
815 struct ospf6_neighbor
*on
;
816 struct ospf6_dbdesc
*dbdesc
;
818 if (ospf6_header_examin (src
, dst
, oi
, oh
) != MSG_OK
)
821 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
824 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
825 zlog_debug ("Neighbor not found, ignore");
829 if (memcmp (src
, &on
->linklocal_addr
, sizeof (struct in6_addr
)))
831 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
832 zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
836 dbdesc
= (struct ospf6_dbdesc
*)
837 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
839 /* Interface MTU check */
840 if (ntohs (dbdesc
->ifmtu
) != oi
->ifmtu
)
842 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
843 zlog_debug ("I/F MTU mismatch");
847 if (dbdesc
->reserved1
|| dbdesc
->reserved2
)
849 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
850 zlog_debug ("Non-0 reserved field in %s's DbDesc, correct",
852 dbdesc
->reserved1
= 0;
853 dbdesc
->reserved2
= 0;
856 if (ntohl (oh
->router_id
) < ntohl (ospf6
->router_id
))
857 ospf6_dbdesc_recv_master (oh
, on
);
858 else if (ntohl (ospf6
->router_id
) < ntohl (oh
->router_id
))
859 ospf6_dbdesc_recv_slave (oh
, on
);
862 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
863 zlog_debug ("Can't decide which is master, ignore");
868 ospf6_lsreq_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
869 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
871 struct ospf6_neighbor
*on
;
873 struct ospf6_lsreq_entry
*e
;
874 struct ospf6_lsdb
*lsdb
= NULL
;
875 struct ospf6_lsa
*lsa
;
877 if (ospf6_header_examin (src
, dst
, oi
, oh
) != MSG_OK
)
880 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
883 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
884 zlog_debug ("Neighbor not found, ignore");
888 if (memcmp (src
, &on
->linklocal_addr
, sizeof (struct in6_addr
)))
890 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
891 zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
895 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
896 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
897 on
->state
!= OSPF6_NEIGHBOR_FULL
)
899 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
900 zlog_debug ("Neighbor state less than Exchange, ignore");
904 /* Process each request */
905 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
906 p
+ sizeof (struct ospf6_lsreq_entry
) <= OSPF6_MESSAGE_END (oh
);
907 p
+= sizeof (struct ospf6_lsreq_entry
))
909 e
= (struct ospf6_lsreq_entry
*) p
;
911 switch (OSPF6_LSA_SCOPE (e
->type
))
913 case OSPF6_SCOPE_LINKLOCAL
:
914 lsdb
= on
->ospf6_if
->lsdb
;
916 case OSPF6_SCOPE_AREA
:
917 lsdb
= on
->ospf6_if
->area
->lsdb
;
920 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
923 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
924 zlog_debug ("Ignoring LSA of reserved scope");
929 /* Find database copy */
930 lsa
= ospf6_lsdb_lookup (e
->type
, e
->id
, e
->adv_router
, lsdb
);
933 char id
[16], adv_router
[16];
934 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
936 inet_ntop (AF_INET
, &e
->id
, id
, sizeof (id
));
937 inet_ntop (AF_INET
, &e
->adv_router
, adv_router
,
938 sizeof (adv_router
));
939 zlog_debug ("Can't find requested [%s Id:%s Adv:%s]",
940 ospf6_lstype_name (e
->type
), id
, adv_router
);
942 thread_add_event (master
, bad_lsreq
, on
, 0);
946 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->lsupdate_list
);
949 if (p
!= OSPF6_MESSAGE_END (oh
))
951 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
952 zlog_debug ("Trailing garbage ignored");
955 /* schedule send lsupdate */
956 THREAD_OFF (on
->thread_send_lsupdate
);
957 on
->thread_send_lsupdate
=
958 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, on
, 0);
962 ospf6_lsupdate_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
963 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
965 struct ospf6_neighbor
*on
;
966 struct ospf6_lsupdate
*lsupdate
;
970 if (ospf6_header_examin (src
, dst
, oi
, oh
) != MSG_OK
)
973 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
976 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
977 zlog_debug ("Neighbor not found, ignore");
981 if (memcmp (src
, &on
->linklocal_addr
, sizeof (struct in6_addr
)))
983 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
984 zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
988 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
989 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
990 on
->state
!= OSPF6_NEIGHBOR_FULL
)
992 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
993 zlog_debug ("Neighbor state less than Exchange, ignore");
997 lsupdate
= (struct ospf6_lsupdate
*)
998 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1000 num
= ntohl (lsupdate
->lsa_number
);
1003 for (p
= (char *) ((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
1004 p
< OSPF6_MESSAGE_END (oh
) &&
1005 p
+ OSPF6_LSA_SIZE (p
) <= OSPF6_MESSAGE_END (oh
);
1006 p
+= OSPF6_LSA_SIZE (p
))
1010 if (OSPF6_LSA_SIZE (p
) < sizeof (struct ospf6_lsa_header
))
1012 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1013 zlog_debug ("Malformed LSA length, quit processing");
1017 ospf6_receive_lsa (on
, (struct ospf6_lsa_header
*) p
);
1023 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1024 zlog_debug ("Malformed LSA number or LSA length");
1026 if (p
!= OSPF6_MESSAGE_END (oh
))
1028 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1029 zlog_debug ("Trailing garbage ignored");
1032 /* RFC2328 Section 10.9: When the neighbor responds to these requests
1033 with the proper Link State Update packet(s), the Link state request
1034 list is truncated and a new Link State Request packet is sent. */
1035 /* send new Link State Request packet if this LS Update packet
1036 can be recognized as a response to our previous LS Request */
1037 if (! IN6_IS_ADDR_MULTICAST (dst
) &&
1038 (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
||
1039 on
->state
== OSPF6_NEIGHBOR_LOADING
))
1041 THREAD_OFF (on
->thread_send_lsreq
);
1042 on
->thread_send_lsreq
=
1043 thread_add_event (master
, ospf6_lsreq_send
, on
, 0);
1048 ospf6_lsack_recv (struct in6_addr
*src
, struct in6_addr
*dst
,
1049 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1051 struct ospf6_neighbor
*on
;
1053 struct ospf6_lsa
*his
, *mine
;
1054 struct ospf6_lsdb
*lsdb
= NULL
;
1056 assert (oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
1057 if (ospf6_header_examin (src
, dst
, oi
, oh
) != MSG_OK
)
1060 on
= ospf6_neighbor_lookup (oh
->router_id
, oi
);
1063 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1064 zlog_debug ("Neighbor not found, ignore");
1068 if (memcmp (src
, &on
->linklocal_addr
, sizeof (struct in6_addr
)))
1070 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1071 zlog_debug ("Seems to be from Secondary I/F of the neighbor, ignore");
1075 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1076 on
->state
!= OSPF6_NEIGHBOR_LOADING
&&
1077 on
->state
!= OSPF6_NEIGHBOR_FULL
)
1079 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1080 zlog_debug ("Neighbor state less than Exchange, ignore");
1084 for (p
= (char *) ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1085 p
+ sizeof (struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END (oh
);
1086 p
+= sizeof (struct ospf6_lsa_header
))
1088 his
= ospf6_lsa_create_headeronly ((struct ospf6_lsa_header
*) p
);
1090 switch (OSPF6_LSA_SCOPE (his
->header
->type
))
1092 case OSPF6_SCOPE_LINKLOCAL
:
1093 lsdb
= on
->ospf6_if
->lsdb
;
1095 case OSPF6_SCOPE_AREA
:
1096 lsdb
= on
->ospf6_if
->area
->lsdb
;
1098 case OSPF6_SCOPE_AS
:
1099 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
1101 case OSPF6_SCOPE_RESERVED
:
1102 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1103 zlog_debug ("Ignoring LSA of reserved scope");
1104 ospf6_lsa_delete (his
);
1109 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1110 zlog_debug ("%s acknowledged by %s", his
->name
, on
->name
);
1112 /* Find database copy */
1113 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
1114 his
->header
->adv_router
, lsdb
);
1117 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1118 zlog_debug ("No database copy");
1119 ospf6_lsa_delete (his
);
1123 /* Check if the LSA is on his retrans-list */
1124 mine
= ospf6_lsdb_lookup (his
->header
->type
, his
->header
->id
,
1125 his
->header
->adv_router
, on
->retrans_list
);
1128 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1129 zlog_debug ("Not on %s's retrans-list", on
->name
);
1130 ospf6_lsa_delete (his
);
1134 if (ospf6_lsa_compare (his
, mine
) != 0)
1136 /* Log this questionable acknowledgement,
1137 and examine the next one. */
1138 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1139 zlog_debug ("Questionable acknowledgement");
1140 ospf6_lsa_delete (his
);
1144 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1145 zlog_debug ("Acknowledged, remove from %s's retrans-list",
1148 if (OSPF6_LSA_IS_MAXAGE (mine
))
1149 ospf6_maxage_remove (on
->ospf6_if
->area
->ospf6
);
1151 ospf6_decrement_retrans_count (mine
);
1152 ospf6_lsdb_remove (mine
, on
->retrans_list
);
1153 ospf6_lsa_delete (his
);
1156 if (p
!= OSPF6_MESSAGE_END (oh
))
1158 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1159 zlog_debug ("Trailing garbage ignored");
1163 u_char
*recvbuf
= NULL
;
1164 u_char
*sendbuf
= NULL
;
1165 unsigned int iobuflen
= 0;
1168 ospf6_iobuf_size (unsigned int size
)
1170 char *recvnew
, *sendnew
;
1172 if (size
<= iobuflen
)
1175 recvnew
= XMALLOC (MTYPE_OSPF6_MESSAGE
, size
);
1176 sendnew
= XMALLOC (MTYPE_OSPF6_MESSAGE
, size
);
1177 if (recvnew
== NULL
|| sendnew
== NULL
)
1180 XFREE (MTYPE_OSPF6_MESSAGE
, recvnew
);
1182 XFREE (MTYPE_OSPF6_MESSAGE
, sendnew
);
1183 zlog_debug ("Could not allocate I/O buffer of size %d.", size
);
1188 XFREE (MTYPE_OSPF6_MESSAGE
, recvbuf
);
1190 XFREE (MTYPE_OSPF6_MESSAGE
, sendbuf
);
1199 ospf6_receive (struct thread
*thread
)
1203 char srcname
[64], dstname
[64];
1204 struct in6_addr src
, dst
;
1205 unsigned int ifindex
;
1206 struct iovec iovector
[2];
1207 struct ospf6_interface
*oi
;
1208 struct ospf6_header
*oh
;
1210 /* add next read thread */
1211 sockfd
= THREAD_FD (thread
);
1212 thread_add_read (master
, ospf6_receive
, NULL
, sockfd
);
1215 memset (recvbuf
, 0, iobuflen
);
1216 iovector
[0].iov_base
= recvbuf
;
1217 iovector
[0].iov_len
= iobuflen
;
1218 iovector
[1].iov_base
= NULL
;
1219 iovector
[1].iov_len
= 0;
1221 /* receive message */
1222 len
= ospf6_recvmsg (&src
, &dst
, &ifindex
, iovector
);
1225 zlog_err ("Excess message read");
1228 else if (len
< sizeof (struct ospf6_header
))
1230 zlog_err ("Deficient message read");
1234 oi
= ospf6_interface_lookup_by_ifindex (ifindex
);
1235 if (oi
== NULL
|| oi
->area
== NULL
)
1237 zlog_debug ("Message received on disabled interface");
1241 oh
= (struct ospf6_header
*) recvbuf
;
1244 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1246 inet_ntop (AF_INET6
, &src
, srcname
, sizeof (srcname
));
1247 inet_ntop (AF_INET6
, &dst
, dstname
, sizeof (dstname
));
1248 zlog_debug ("%s received on %s",
1249 OSPF6_MESSAGE_TYPE_NAME (oh
->type
), oi
->interface
->name
);
1250 zlog_debug (" src: %s", srcname
);
1251 zlog_debug (" dst: %s", dstname
);
1252 if (len
!= ntohs (oh
->length
))
1253 zlog_debug ("Message length does not match actually received: %d", len
);
1257 case OSPF6_MESSAGE_TYPE_HELLO
:
1258 ospf6_hello_print (oh
);
1260 case OSPF6_MESSAGE_TYPE_DBDESC
:
1261 ospf6_dbdesc_print (oh
);
1263 case OSPF6_MESSAGE_TYPE_LSREQ
:
1264 ospf6_lsreq_print (oh
);
1266 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1267 ospf6_lsupdate_print (oh
);
1269 case OSPF6_MESSAGE_TYPE_LSACK
:
1270 ospf6_lsack_print (oh
);
1273 zlog_debug ("Unknown message");
1278 if (CHECK_FLAG (oi
->flag
, OSPF6_INTERFACE_PASSIVE
))
1280 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, RECV
))
1281 zlog_debug ("Ignore message on passive interface %s",
1282 oi
->interface
->name
);
1288 case OSPF6_MESSAGE_TYPE_HELLO
:
1289 ospf6_hello_recv (&src
, &dst
, oi
, oh
);
1292 case OSPF6_MESSAGE_TYPE_DBDESC
:
1293 ospf6_dbdesc_recv (&src
, &dst
, oi
, oh
);
1296 case OSPF6_MESSAGE_TYPE_LSREQ
:
1297 ospf6_lsreq_recv (&src
, &dst
, oi
, oh
);
1300 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1301 ospf6_lsupdate_recv (&src
, &dst
, oi
, oh
);
1304 case OSPF6_MESSAGE_TYPE_LSACK
:
1305 ospf6_lsack_recv (&src
, &dst
, oi
, oh
);
1309 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
1310 zlog_debug ("Unknown message");
1318 ospf6_send (struct in6_addr
*src
, struct in6_addr
*dst
,
1319 struct ospf6_interface
*oi
, struct ospf6_header
*oh
)
1322 char srcname
[64], dstname
[64];
1323 struct iovec iovector
[2];
1326 iovector
[0].iov_base
= (caddr_t
) oh
;
1327 iovector
[0].iov_len
= ntohs (oh
->length
);
1328 iovector
[1].iov_base
= NULL
;
1329 iovector
[1].iov_len
= 0;
1331 /* fill OSPF header */
1332 oh
->version
= OSPFV3_VERSION
;
1333 /* message type must be set before */
1334 /* message length must be set before */
1335 oh
->router_id
= oi
->area
->ospf6
->router_id
;
1336 oh
->area_id
= oi
->area
->area_id
;
1337 /* checksum is calculated by kernel */
1338 oh
->instance_id
= oi
->instance_id
;
1342 if (IS_OSPF6_DEBUG_MESSAGE (oh
->type
, SEND
))
1344 inet_ntop (AF_INET6
, dst
, dstname
, sizeof (dstname
));
1346 inet_ntop (AF_INET6
, src
, srcname
, sizeof (srcname
));
1348 memset (srcname
, 0, sizeof (srcname
));
1349 zlog_debug ("%s send on %s",
1350 OSPF6_MESSAGE_TYPE_NAME (oh
->type
), oi
->interface
->name
);
1351 zlog_debug (" src: %s", srcname
);
1352 zlog_debug (" dst: %s", dstname
);
1356 case OSPF6_MESSAGE_TYPE_HELLO
:
1357 ospf6_hello_print (oh
);
1359 case OSPF6_MESSAGE_TYPE_DBDESC
:
1360 ospf6_dbdesc_print (oh
);
1362 case OSPF6_MESSAGE_TYPE_LSREQ
:
1363 ospf6_lsreq_print (oh
);
1365 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1366 ospf6_lsupdate_print (oh
);
1368 case OSPF6_MESSAGE_TYPE_LSACK
:
1369 ospf6_lsack_print (oh
);
1372 zlog_debug ("Unknown message");
1379 len
= ospf6_sendmsg (src
, dst
, &oi
->interface
->ifindex
, iovector
);
1380 if (len
!= ntohs (oh
->length
))
1381 zlog_err ("Could not send entire message");
1385 ospf6_hello_send (struct thread
*thread
)
1387 struct ospf6_interface
*oi
;
1388 struct ospf6_header
*oh
;
1389 struct ospf6_hello
*hello
;
1391 struct listnode
*node
;
1392 struct ospf6_neighbor
*on
;
1394 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1395 oi
->thread_send_hello
= (struct thread
*) NULL
;
1397 if (oi
->state
<= OSPF6_INTERFACE_DOWN
)
1399 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO
, SEND
))
1400 zlog_debug ("Unable to send Hello on down interface %s",
1401 oi
->interface
->name
);
1405 /* set next thread */
1406 oi
->thread_send_hello
= thread_add_timer (master
, ospf6_hello_send
,
1407 oi
, oi
->hello_interval
);
1409 memset (sendbuf
, 0, iobuflen
);
1410 oh
= (struct ospf6_header
*) sendbuf
;
1411 hello
= (struct ospf6_hello
*)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1413 hello
->interface_id
= htonl (oi
->interface
->ifindex
);
1414 hello
->priority
= oi
->priority
;
1415 hello
->options
[0] = oi
->area
->options
[0];
1416 hello
->options
[1] = oi
->area
->options
[1];
1417 hello
->options
[2] = oi
->area
->options
[2];
1418 hello
->hello_interval
= htons (oi
->hello_interval
);
1419 hello
->dead_interval
= htons (oi
->dead_interval
);
1420 hello
->drouter
= oi
->drouter
;
1421 hello
->bdrouter
= oi
->bdrouter
;
1423 p
= (char *)((caddr_t
) hello
+ sizeof (struct ospf6_hello
));
1425 for (node
= listhead (oi
->neighbor_list
); node
; nextnode (node
))
1427 on
= (struct ospf6_neighbor
*) getdata (node
);
1429 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
1432 if (p
- sendbuf
+ sizeof (u_int32_t
) > oi
->ifmtu
)
1434 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_HELLO
, SEND
))
1435 zlog_debug ("sending Hello message: exceeds I/F MTU");
1439 memcpy (p
, &on
->router_id
, sizeof (u_int32_t
));
1440 p
+= sizeof (u_int32_t
);
1443 oh
->type
= OSPF6_MESSAGE_TYPE_HELLO
;
1444 oh
->length
= htons (p
- sendbuf
);
1446 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
1451 ospf6_dbdesc_send (struct thread
*thread
)
1453 struct ospf6_neighbor
*on
;
1454 struct ospf6_header
*oh
;
1455 struct ospf6_dbdesc
*dbdesc
;
1457 struct ospf6_lsa
*lsa
;
1459 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1460 on
->thread_send_dbdesc
= (struct thread
*) NULL
;
1462 if (on
->state
< OSPF6_NEIGHBOR_EXSTART
)
1464 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_DBDESC
, SEND
))
1465 zlog_debug ("Quit to send DbDesc to neighbor %s state %s",
1466 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
1470 /* set next thread if master */
1471 if (CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
))
1472 on
->thread_send_dbdesc
=
1473 thread_add_timer (master
, ospf6_dbdesc_send
, on
,
1474 on
->ospf6_if
->rxmt_interval
);
1476 memset (sendbuf
, 0, iobuflen
);
1477 oh
= (struct ospf6_header
*) sendbuf
;
1478 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
) oh
+
1479 sizeof (struct ospf6_header
));
1481 /* if this is initial one, initialize sequence number for DbDesc */
1482 if (CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
))
1485 if (gettimeofday (&tv
, (struct timezone
*) NULL
) < 0)
1487 on
->dbdesc_seqnum
= tv
.tv_sec
;
1490 dbdesc
->options
[0] = on
->ospf6_if
->area
->options
[0];
1491 dbdesc
->options
[1] = on
->ospf6_if
->area
->options
[1];
1492 dbdesc
->options
[2] = on
->ospf6_if
->area
->options
[2];
1493 dbdesc
->ifmtu
= htons (on
->ospf6_if
->ifmtu
);
1494 dbdesc
->bits
= on
->dbdesc_bits
;
1495 dbdesc
->seqnum
= htonl (on
->dbdesc_seqnum
);
1497 /* if this is not initial one, set LSA headers in dbdesc */
1498 p
= (char *)((caddr_t
) dbdesc
+ sizeof (struct ospf6_dbdesc
));
1499 if (! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
))
1501 for (lsa
= ospf6_lsdb_head (on
->dbdesc_list
); lsa
;
1502 lsa
= ospf6_lsdb_next (lsa
))
1504 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
1507 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) >
1508 on
->ospf6_if
->ifmtu
)
1510 ospf6_lsa_unlock (lsa
);
1513 memcpy (p
, lsa
->header
, sizeof (struct ospf6_lsa_header
));
1514 p
+= sizeof (struct ospf6_lsa_header
);
1518 oh
->type
= OSPF6_MESSAGE_TYPE_DBDESC
;
1519 oh
->length
= htons (p
- sendbuf
);
1521 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
1527 ospf6_dbdesc_send_newone (struct thread
*thread
)
1529 struct ospf6_neighbor
*on
;
1530 struct ospf6_lsa
*lsa
;
1531 unsigned int size
= 0;
1533 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1534 ospf6_lsdb_remove_all (on
->dbdesc_list
);
1536 /* move LSAs from summary_list to dbdesc_list (within neighbor structure)
1537 so that ospf6_send_dbdesc () can send those LSAs */
1538 size
= sizeof (struct ospf6_lsa_header
) + sizeof (struct ospf6_dbdesc
);
1539 for (lsa
= ospf6_lsdb_head (on
->summary_list
); lsa
;
1540 lsa
= ospf6_lsdb_next (lsa
))
1542 if (size
+ sizeof (struct ospf6_lsa_header
) > on
->ospf6_if
->ifmtu
)
1544 ospf6_lsa_unlock (lsa
);
1548 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->dbdesc_list
);
1549 ospf6_lsdb_remove (lsa
, on
->summary_list
);
1550 size
+= sizeof (struct ospf6_lsa_header
);
1553 if (on
->summary_list
->count
== 0)
1554 UNSET_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
);
1556 /* If slave, More bit check must be done here */
1557 if (! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
) && /* Slave */
1558 ! CHECK_FLAG (on
->dbdesc_last
.bits
, OSPF6_DBDESC_MBIT
) &&
1559 ! CHECK_FLAG (on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
))
1560 thread_add_event (master
, exchange_done
, on
, 0);
1562 thread_execute (master
, ospf6_dbdesc_send
, on
, 0);
1567 ospf6_lsreq_send (struct thread
*thread
)
1569 struct ospf6_neighbor
*on
;
1570 struct ospf6_header
*oh
;
1571 struct ospf6_lsreq_entry
*e
;
1573 struct ospf6_lsa
*lsa
;
1575 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1576 on
->thread_send_lsreq
= (struct thread
*) NULL
;
1578 /* LSReq will be sent only in ExStart or Loading */
1579 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
&&
1580 on
->state
!= OSPF6_NEIGHBOR_LOADING
)
1582 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSREQ
, SEND
))
1583 zlog_debug ("Quit to send LSReq to neighbor %s state %s",
1584 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
1588 /* schedule loading_done if request list is empty */
1589 if (on
->request_list
->count
== 0)
1591 thread_add_event (master
, loading_done
, on
, 0);
1595 /* set next thread */
1596 on
->thread_send_lsreq
=
1597 thread_add_timer (master
, ospf6_lsreq_send
, on
,
1598 on
->ospf6_if
->rxmt_interval
);
1600 memset (sendbuf
, 0, iobuflen
);
1601 oh
= (struct ospf6_header
*) sendbuf
;
1603 /* set Request entries in lsreq */
1604 p
= (char *)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1605 for (lsa
= ospf6_lsdb_head (on
->request_list
); lsa
;
1606 lsa
= ospf6_lsdb_next (lsa
))
1609 if (p
- sendbuf
+ sizeof (struct ospf6_lsreq_entry
) > on
->ospf6_if
->ifmtu
)
1611 ospf6_lsa_unlock (lsa
);
1615 e
= (struct ospf6_lsreq_entry
*) p
;
1616 e
->type
= lsa
->header
->type
;
1617 e
->id
= lsa
->header
->id
;
1618 e
->adv_router
= lsa
->header
->adv_router
;
1619 p
+= sizeof (struct ospf6_lsreq_entry
);
1622 oh
->type
= OSPF6_MESSAGE_TYPE_LSREQ
;
1623 oh
->length
= htons (p
- sendbuf
);
1625 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
1631 ospf6_lsupdate_send_neighbor (struct thread
*thread
)
1633 struct ospf6_neighbor
*on
;
1634 struct ospf6_header
*oh
;
1635 struct ospf6_lsupdate
*lsupdate
;
1638 struct ospf6_lsa
*lsa
;
1640 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1641 on
->thread_send_lsupdate
= (struct thread
*) NULL
;
1643 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
1644 zlog_debug ("LSUpdate to neighbor %s", on
->name
);
1646 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
1648 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
1649 zlog_debug ("Quit to send (neighbor state %s)",
1650 ospf6_neighbor_state_str
[on
->state
]);
1654 /* if we have nothing to send, return */
1655 if (on
->lsupdate_list
->count
== 0 &&
1656 on
->retrans_list
->count
== 0)
1658 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
1659 zlog_debug ("Quit to send (nothing to send)");
1663 memset (sendbuf
, 0, iobuflen
);
1664 oh
= (struct ospf6_header
*) sendbuf
;
1665 lsupdate
= (struct ospf6_lsupdate
*)
1666 ((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1668 p
= (char *)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
1671 /* lsupdate_list lists those LSA which doesn't need to be
1672 retransmitted. remove those from the list */
1673 for (lsa
= ospf6_lsdb_head (on
->lsupdate_list
); lsa
;
1674 lsa
= ospf6_lsdb_next (lsa
))
1677 if ( (p
- sendbuf
+ (unsigned int)OSPF6_LSA_SIZE (lsa
->header
))
1678 > on
->ospf6_if
->ifmtu
)
1680 ospf6_lsa_unlock (lsa
);
1684 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
1685 memcpy (p
, lsa
->header
, OSPF6_LSA_SIZE (lsa
->header
));
1686 p
+= OSPF6_LSA_SIZE (lsa
->header
);
1689 assert (lsa
->lock
== 2);
1690 ospf6_lsdb_remove (lsa
, on
->lsupdate_list
);
1693 for (lsa
= ospf6_lsdb_head (on
->retrans_list
); lsa
;
1694 lsa
= ospf6_lsdb_next (lsa
))
1697 if ( (p
- sendbuf
+ (unsigned int)OSPF6_LSA_SIZE (lsa
->header
))
1698 > on
->ospf6_if
->ifmtu
)
1700 ospf6_lsa_unlock (lsa
);
1704 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
1705 memcpy (p
, lsa
->header
, OSPF6_LSA_SIZE (lsa
->header
));
1706 p
+= OSPF6_LSA_SIZE (lsa
->header
);
1710 lsupdate
->lsa_number
= htonl (num
);
1712 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
1713 oh
->length
= htons (p
- sendbuf
);
1715 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
1718 if (on
->lsupdate_list
->count
!= 0 ||
1719 on
->retrans_list
->count
!= 0)
1721 if (on
->lsupdate_list
->count
!= 0)
1722 on
->thread_send_lsupdate
=
1723 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, on
, 0);
1725 on
->thread_send_lsupdate
=
1726 thread_add_timer (master
, ospf6_lsupdate_send_neighbor
, on
,
1727 on
->ospf6_if
->rxmt_interval
);
1734 ospf6_lsupdate_send_interface (struct thread
*thread
)
1736 struct ospf6_interface
*oi
;
1737 struct ospf6_header
*oh
;
1738 struct ospf6_lsupdate
*lsupdate
;
1741 struct ospf6_lsa
*lsa
;
1743 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1744 oi
->thread_send_lsupdate
= (struct thread
*) NULL
;
1746 if (oi
->state
<= OSPF6_INTERFACE_WAITING
)
1748 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND
))
1749 zlog_debug ("Quit to send LSUpdate to interface %s state %s",
1750 oi
->interface
->name
, ospf6_interface_state_str
[oi
->state
]);
1754 /* if we have nothing to send, return */
1755 if (oi
->lsupdate_list
->count
== 0)
1758 memset (sendbuf
, 0, iobuflen
);
1759 oh
= (struct ospf6_header
*) sendbuf
;
1760 lsupdate
= (struct ospf6_lsupdate
*)((caddr_t
) oh
+
1761 sizeof (struct ospf6_header
));
1763 p
= (char *)((caddr_t
) lsupdate
+ sizeof (struct ospf6_lsupdate
));
1766 for (lsa
= ospf6_lsdb_head (oi
->lsupdate_list
); lsa
;
1767 lsa
= ospf6_lsdb_next (lsa
))
1770 if ( (p
- sendbuf
+ ((unsigned int)OSPF6_LSA_SIZE (lsa
->header
)))
1773 ospf6_lsa_unlock (lsa
);
1777 ospf6_lsa_age_update_to_send (lsa
, oi
->transdelay
);
1778 memcpy (p
, lsa
->header
, OSPF6_LSA_SIZE (lsa
->header
));
1779 p
+= OSPF6_LSA_SIZE (lsa
->header
);
1782 assert (lsa
->lock
== 2);
1783 ospf6_lsdb_remove (lsa
, oi
->lsupdate_list
);
1786 lsupdate
->lsa_number
= htonl (num
);
1788 oh
->type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
1789 oh
->length
= htons (p
- sendbuf
);
1791 if (oi
->state
== OSPF6_INTERFACE_DR
||
1792 oi
->state
== OSPF6_INTERFACE_BDR
)
1793 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
1795 ospf6_send (oi
->linklocal_addr
, &alldrouters6
, oi
, oh
);
1797 if (oi
->lsupdate_list
->count
> 0)
1799 oi
->thread_send_lsupdate
=
1800 thread_add_event (master
, ospf6_lsupdate_send_interface
, oi
, 0);
1807 ospf6_lsack_send_neighbor (struct thread
*thread
)
1809 struct ospf6_neighbor
*on
;
1810 struct ospf6_header
*oh
;
1812 struct ospf6_lsa
*lsa
;
1814 on
= (struct ospf6_neighbor
*) THREAD_ARG (thread
);
1815 on
->thread_send_lsack
= (struct thread
*) NULL
;
1817 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
1819 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK
, SEND
))
1820 zlog_debug ("Quit to send LSAck to neighbor %s state %s",
1821 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
1825 /* if we have nothing to send, return */
1826 if (on
->lsack_list
->count
== 0)
1829 memset (sendbuf
, 0, iobuflen
);
1830 oh
= (struct ospf6_header
*) sendbuf
;
1832 p
= (char *)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1834 for (lsa
= ospf6_lsdb_head (on
->lsack_list
); lsa
;
1835 lsa
= ospf6_lsdb_next (lsa
))
1838 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) > on
->ospf6_if
->ifmtu
)
1840 /* if we run out of packet size/space here,
1841 better to try again soon. */
1842 THREAD_OFF (on
->thread_send_lsack
);
1843 on
->thread_send_lsack
=
1844 thread_add_event (master
, ospf6_lsack_send_neighbor
, on
, 0);
1846 ospf6_lsa_unlock (lsa
);
1850 ospf6_lsa_age_update_to_send (lsa
, on
->ospf6_if
->transdelay
);
1851 memcpy (p
, lsa
->header
, sizeof (struct ospf6_lsa_header
));
1852 p
+= sizeof (struct ospf6_lsa_header
);
1854 assert (lsa
->lock
== 2);
1855 ospf6_lsdb_remove (lsa
, on
->lsack_list
);
1858 oh
->type
= OSPF6_MESSAGE_TYPE_LSACK
;
1859 oh
->length
= htons (p
- sendbuf
);
1861 ospf6_send (on
->ospf6_if
->linklocal_addr
, &on
->linklocal_addr
,
1867 ospf6_lsack_send_interface (struct thread
*thread
)
1869 struct ospf6_interface
*oi
;
1870 struct ospf6_header
*oh
;
1872 struct ospf6_lsa
*lsa
;
1874 oi
= (struct ospf6_interface
*) THREAD_ARG (thread
);
1875 oi
->thread_send_lsack
= (struct thread
*) NULL
;
1877 if (oi
->state
<= OSPF6_INTERFACE_WAITING
)
1879 if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSACK
, SEND
))
1880 zlog_debug ("Quit to send LSAck to interface %s state %s",
1881 oi
->interface
->name
, ospf6_interface_state_str
[oi
->state
]);
1885 /* if we have nothing to send, return */
1886 if (oi
->lsack_list
->count
== 0)
1889 memset (sendbuf
, 0, iobuflen
);
1890 oh
= (struct ospf6_header
*) sendbuf
;
1892 p
= (char *)((caddr_t
) oh
+ sizeof (struct ospf6_header
));
1894 for (lsa
= ospf6_lsdb_head (oi
->lsack_list
); lsa
;
1895 lsa
= ospf6_lsdb_next (lsa
))
1898 if (p
- sendbuf
+ sizeof (struct ospf6_lsa_header
) > oi
->ifmtu
)
1900 /* if we run out of packet size/space here,
1901 better to try again soon. */
1902 THREAD_OFF (oi
->thread_send_lsack
);
1903 oi
->thread_send_lsack
=
1904 thread_add_event (master
, ospf6_lsack_send_interface
, oi
, 0);
1906 ospf6_lsa_unlock (lsa
);
1910 ospf6_lsa_age_update_to_send (lsa
, oi
->transdelay
);
1911 memcpy (p
, lsa
->header
, sizeof (struct ospf6_lsa_header
));
1912 p
+= sizeof (struct ospf6_lsa_header
);
1914 assert (lsa
->lock
== 2);
1915 ospf6_lsdb_remove (lsa
, oi
->lsack_list
);
1918 oh
->type
= OSPF6_MESSAGE_TYPE_LSACK
;
1919 oh
->length
= htons (p
- sendbuf
);
1921 if (oi
->state
== OSPF6_INTERFACE_DR
||
1922 oi
->state
== OSPF6_INTERFACE_BDR
)
1923 ospf6_send (oi
->linklocal_addr
, &allspfrouters6
, oi
, oh
);
1925 ospf6_send (oi
->linklocal_addr
, &alldrouters6
, oi
, oh
);
1927 if (oi
->thread_send_lsack
== NULL
&& oi
->lsack_list
->count
> 0)
1929 oi
->thread_send_lsack
=
1930 thread_add_event (master
, ospf6_lsack_send_interface
, oi
, 0);
1938 DEFUN (debug_ospf6_message
,
1939 debug_ospf6_message_cmd
,
1940 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
1943 "Debug OSPFv3 message\n"
1944 "Debug Unknown message\n"
1945 "Debug Hello message\n"
1946 "Debug Database Description message\n"
1947 "Debug Link State Request message\n"
1948 "Debug Link State Update message\n"
1949 "Debug Link State Acknowledgement message\n"
1950 "Debug All message\n"
1953 unsigned char level
= 0;
1960 if (! strncmp (argv
[0], "u", 1))
1961 type
= OSPF6_MESSAGE_TYPE_UNKNOWN
;
1962 else if (! strncmp (argv
[0], "h", 1))
1963 type
= OSPF6_MESSAGE_TYPE_HELLO
;
1964 else if (! strncmp (argv
[0], "d", 1))
1965 type
= OSPF6_MESSAGE_TYPE_DBDESC
;
1966 else if (! strncmp (argv
[0], "lsr", 3))
1967 type
= OSPF6_MESSAGE_TYPE_LSREQ
;
1968 else if (! strncmp (argv
[0], "lsu", 3))
1969 type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
1970 else if (! strncmp (argv
[0], "lsa", 3))
1971 type
= OSPF6_MESSAGE_TYPE_LSACK
;
1972 else if (! strncmp (argv
[0], "a", 1))
1973 type
= OSPF6_MESSAGE_TYPE_ALL
;
1976 level
= OSPF6_DEBUG_MESSAGE_SEND
| OSPF6_DEBUG_MESSAGE_RECV
;
1977 else if (! strncmp (argv
[1], "s", 1))
1978 level
= OSPF6_DEBUG_MESSAGE_SEND
;
1979 else if (! strncmp (argv
[1], "r", 1))
1980 level
= OSPF6_DEBUG_MESSAGE_RECV
;
1982 if (type
== OSPF6_MESSAGE_TYPE_ALL
)
1984 for (i
= 0; i
< 6; i
++)
1985 OSPF6_DEBUG_MESSAGE_ON (i
, level
);
1988 OSPF6_DEBUG_MESSAGE_ON (type
, level
);
1993 ALIAS (debug_ospf6_message
,
1994 debug_ospf6_message_sendrecv_cmd
,
1995 "debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
1998 "Debug OSPFv3 message\n"
1999 "Debug Unknown message\n"
2000 "Debug Hello message\n"
2001 "Debug Database Description message\n"
2002 "Debug Link State Request message\n"
2003 "Debug Link State Update message\n"
2004 "Debug Link State Acknowledgement message\n"
2005 "Debug All message\n"
2006 "Debug only sending message\n"
2007 "Debug only receiving message\n"
2011 DEFUN (no_debug_ospf6_message
,
2012 no_debug_ospf6_message_cmd
,
2013 "no debug ospf6 message (unknown|hello|dbdesc|lsreq|lsupdate|lsack|all)",
2017 "Debug OSPFv3 message\n"
2018 "Debug Unknown message\n"
2019 "Debug Hello message\n"
2020 "Debug Database Description message\n"
2021 "Debug Link State Request message\n"
2022 "Debug Link State Update message\n"
2023 "Debug Link State Acknowledgement message\n"
2024 "Debug All message\n"
2027 unsigned char level
= 0;
2034 if (! strncmp (argv
[0], "u", 1))
2035 type
= OSPF6_MESSAGE_TYPE_UNKNOWN
;
2036 else if (! strncmp (argv
[0], "h", 1))
2037 type
= OSPF6_MESSAGE_TYPE_HELLO
;
2038 else if (! strncmp (argv
[0], "d", 1))
2039 type
= OSPF6_MESSAGE_TYPE_DBDESC
;
2040 else if (! strncmp (argv
[0], "lsr", 3))
2041 type
= OSPF6_MESSAGE_TYPE_LSREQ
;
2042 else if (! strncmp (argv
[0], "lsu", 3))
2043 type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2044 else if (! strncmp (argv
[0], "lsa", 3))
2045 type
= OSPF6_MESSAGE_TYPE_LSACK
;
2046 else if (! strncmp (argv
[0], "a", 1))
2047 type
= OSPF6_MESSAGE_TYPE_ALL
;
2050 level
= OSPF6_DEBUG_MESSAGE_SEND
| OSPF6_DEBUG_MESSAGE_RECV
;
2051 else if (! strncmp (argv
[1], "s", 1))
2052 level
= OSPF6_DEBUG_MESSAGE_SEND
;
2053 else if (! strncmp (argv
[1], "r", 1))
2054 level
= OSPF6_DEBUG_MESSAGE_RECV
;
2056 if (type
== OSPF6_MESSAGE_TYPE_ALL
)
2058 for (i
= 0; i
< 6; i
++)
2059 OSPF6_DEBUG_MESSAGE_OFF (i
, level
);
2062 OSPF6_DEBUG_MESSAGE_OFF (type
, level
);
2067 ALIAS (no_debug_ospf6_message
,
2068 no_debug_ospf6_message_sendrecv_cmd
,
2069 "no debug ospf6 message "
2070 "(unknown|hello|dbdesc|lsreq|lsupdate|lsack|all) (send|recv)",
2074 "Debug OSPFv3 message\n"
2075 "Debug Unknown message\n"
2076 "Debug Hello message\n"
2077 "Debug Database Description message\n"
2078 "Debug Link State Request message\n"
2079 "Debug Link State Update message\n"
2080 "Debug Link State Acknowledgement message\n"
2081 "Debug All message\n"
2082 "Debug only sending message\n"
2083 "Debug only receiving message\n"
2087 config_write_ospf6_debug_message (struct vty
*vty
)
2089 const char *type_str
[] = {"unknown", "hello", "dbdesc",
2090 "lsreq", "lsupdate", "lsack"};
2091 unsigned char s
= 0, r
= 0;
2094 for (i
= 0; i
< 6; i
++)
2096 if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
))
2098 if (IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2102 if (s
== 0x3f && r
== 0x3f)
2104 vty_out (vty
, "debug ospf6 message all%s", VNL
);
2108 if (s
== 0x3f && r
== 0)
2110 vty_out (vty
, "debug ospf6 message all send%s", VNL
);
2113 else if (s
== 0 && r
== 0x3f)
2115 vty_out (vty
, "debug ospf6 message all recv%s", VNL
);
2119 /* Unknown message is logged by default */
2120 if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, SEND
) &&
2121 ! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
2122 vty_out (vty
, "no debug ospf6 message unknown%s", VNL
);
2123 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, SEND
))
2124 vty_out (vty
, "no debug ospf6 message unknown send%s", VNL
);
2125 else if (! IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
2126 vty_out (vty
, "no debug ospf6 message unknown recv%s", VNL
);
2128 for (i
= 1; i
< 6; i
++)
2130 if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
) &&
2131 IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2132 vty_out (vty
, "debug ospf6 message %s%s", type_str
[i
], VNL
);
2133 else if (IS_OSPF6_DEBUG_MESSAGE (i
, SEND
))
2134 vty_out (vty
, "debug ospf6 message %s send%s", type_str
[i
],
2136 else if (IS_OSPF6_DEBUG_MESSAGE (i
, RECV
))
2137 vty_out (vty
, "debug ospf6 message %s recv%s", type_str
[i
],
2145 install_element_ospf6_debug_message ()
2147 install_element (ENABLE_NODE
, &debug_ospf6_message_cmd
);
2148 install_element (ENABLE_NODE
, &no_debug_ospf6_message_cmd
);
2149 install_element (ENABLE_NODE
, &debug_ospf6_message_sendrecv_cmd
);
2150 install_element (ENABLE_NODE
, &no_debug_ospf6_message_sendrecv_cmd
);
2151 install_element (CONFIG_NODE
, &debug_ospf6_message_cmd
);
2152 install_element (CONFIG_NODE
, &no_debug_ospf6_message_cmd
);
2153 install_element (CONFIG_NODE
, &debug_ospf6_message_sendrecv_cmd
);
2154 install_element (CONFIG_NODE
, &no_debug_ospf6_message_sendrecv_cmd
);