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
29 #include "lib_errors.h"
31 #include "ospf6_proto.h"
32 #include "ospf6_lsa.h"
33 #include "ospf6_lsdb.h"
34 #include "ospf6_top.h"
35 #include "ospf6_network.h"
36 #include "ospf6_message.h"
38 #include "ospf6_area.h"
39 #include "ospf6_neighbor.h"
40 #include "ospf6_interface.h"
42 /* for structures and macros ospf6_lsa_examin() needs */
43 #include "ospf6_abr.h"
44 #include "ospf6_asbr.h"
45 #include "ospf6_intra.h"
47 #include "ospf6_flood.h"
50 #include <netinet/ip6.h>
52 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_MESSAGE
, "OSPF6 message");
53 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_PACKET
, "OSPF6 packet");
54 DEFINE_MTYPE_STATIC(OSPF6D
, OSPF6_FIFO
, "OSPF6 FIFO queue");
56 unsigned char conf_debug_ospf6_message
[6] = {0x03, 0, 0, 0, 0, 0};
57 static const struct message ospf6_message_type_str
[] = {
58 {OSPF6_MESSAGE_TYPE_HELLO
, "Hello"},
59 {OSPF6_MESSAGE_TYPE_DBDESC
, "DbDesc"},
60 {OSPF6_MESSAGE_TYPE_LSREQ
, "LSReq"},
61 {OSPF6_MESSAGE_TYPE_LSUPDATE
, "LSUpdate"},
62 {OSPF6_MESSAGE_TYPE_LSACK
, "LSAck"},
65 /* Minimum (besides the standard OSPF packet header) lengths for OSPF
66 packets of particular types, offset is the "type" field. */
67 const uint16_t ospf6_packet_minlen
[OSPF6_MESSAGE_TYPE_ALL
] = {
70 OSPF6_DB_DESC_MIN_SIZE
,
71 OSPF6_LS_REQ_MIN_SIZE
,
72 OSPF6_LS_UPD_MIN_SIZE
,
73 OSPF6_LS_ACK_MIN_SIZE
};
75 /* Minimum (besides the standard LSA header) lengths for LSAs of particular
76 types, offset is the "LSA function code" portion of "LSA type" field. */
77 const uint16_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
};
91 static void ospf6_header_print(struct ospf6_header
*oh
)
93 zlog_debug(" OSPFv%d Type:%d Len:%hu Router-ID:%pI4", oh
->version
,
94 oh
->type
, ntohs(oh
->length
), &oh
->router_id
);
95 zlog_debug(" Area-ID:%pI4 Cksum:%hx Instance-ID:%d", &oh
->area_id
,
96 ntohs(oh
->checksum
), oh
->instance_id
);
99 void ospf6_hello_print(struct ospf6_header
*oh
, int action
)
101 struct ospf6_hello
*hello
;
105 ospf6_header_print(oh
);
106 assert(oh
->type
== OSPF6_MESSAGE_TYPE_HELLO
);
108 hello
= (struct ospf6_hello
*)((caddr_t
)oh
109 + sizeof(struct ospf6_header
));
111 ospf6_options_printbuf(hello
->options
, options
, sizeof(options
));
113 zlog_debug(" I/F-Id:%ld Priority:%d Option:%s",
114 (unsigned long)ntohl(hello
->interface_id
), hello
->priority
,
116 zlog_debug(" HelloInterval:%hu DeadInterval:%hu",
117 ntohs(hello
->hello_interval
), ntohs(hello
->dead_interval
));
118 zlog_debug(" DR:%pI4 BDR:%pI4", &hello
->drouter
, &hello
->bdrouter
);
120 if ((IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
)
121 && action
== OSPF6_ACTION_RECV
)
122 || (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, SEND
)
123 && action
== OSPF6_ACTION_SEND
)) {
125 for (p
= (char *)((caddr_t
)hello
+ sizeof(struct ospf6_hello
));
126 p
+ sizeof(uint32_t) <= OSPF6_MESSAGE_END(oh
);
127 p
+= sizeof(uint32_t))
128 zlog_debug(" Neighbor: %pI4", (in_addr_t
*)p
);
130 assert(p
== OSPF6_MESSAGE_END(oh
));
134 void ospf6_dbdesc_print(struct ospf6_header
*oh
, int action
)
136 struct ospf6_dbdesc
*dbdesc
;
140 ospf6_header_print(oh
);
141 assert(oh
->type
== OSPF6_MESSAGE_TYPE_DBDESC
);
143 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
)oh
144 + sizeof(struct ospf6_header
));
146 ospf6_options_printbuf(dbdesc
->options
, options
, sizeof(options
));
148 zlog_debug(" MBZ: %#x Option: %s IfMTU: %hu", dbdesc
->reserved1
,
149 options
, ntohs(dbdesc
->ifmtu
));
150 zlog_debug(" MBZ: %#x Bits: %s%s%s SeqNum: %#lx", dbdesc
->reserved2
,
151 (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_IBIT
) ? "I" : "-"),
152 (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MBIT
) ? "M" : "-"),
153 (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MSBIT
) ? "m" : "s"),
154 (unsigned long)ntohl(dbdesc
->seqnum
));
156 if ((IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
)
157 && action
== OSPF6_ACTION_RECV
)
158 || (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, SEND
)
159 && action
== OSPF6_ACTION_SEND
)) {
161 for (p
= (char *)((caddr_t
)dbdesc
162 + sizeof(struct ospf6_dbdesc
));
163 p
+ sizeof(struct ospf6_lsa_header
)
164 <= OSPF6_MESSAGE_END(oh
);
165 p
+= sizeof(struct ospf6_lsa_header
))
166 ospf6_lsa_header_print_raw(
167 (struct ospf6_lsa_header
*)p
);
169 assert(p
== OSPF6_MESSAGE_END(oh
));
173 void ospf6_lsreq_print(struct ospf6_header
*oh
, int action
)
177 ospf6_header_print(oh
);
178 assert(oh
->type
== OSPF6_MESSAGE_TYPE_LSREQ
);
180 if ((IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
)
181 && action
== OSPF6_ACTION_RECV
)
182 || (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, SEND
)
183 && action
== OSPF6_ACTION_SEND
)) {
185 for (p
= (char *)((caddr_t
)oh
+ sizeof(struct ospf6_header
));
186 p
+ sizeof(struct ospf6_lsreq_entry
)
187 <= OSPF6_MESSAGE_END(oh
);
188 p
+= sizeof(struct ospf6_lsreq_entry
)) {
189 struct ospf6_lsreq_entry
*e
=
190 (struct ospf6_lsreq_entry
*)p
;
192 zlog_debug(" [%s Id:%pI4 Adv:%pI4]",
193 ospf6_lstype_name(e
->type
), &e
->id
,
197 assert(p
== OSPF6_MESSAGE_END(oh
));
201 void ospf6_lsupdate_print(struct ospf6_header
*oh
, int action
)
203 struct ospf6_lsupdate
*lsupdate
;
207 ospf6_header_print(oh
);
208 assert(oh
->type
== OSPF6_MESSAGE_TYPE_LSUPDATE
);
210 lsupdate
= (struct ospf6_lsupdate
*)((caddr_t
)oh
211 + sizeof(struct ospf6_header
));
213 num
= ntohl(lsupdate
->lsa_number
);
214 zlog_debug(" Number of LSA: %ld", num
);
216 if ((IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
)
217 && action
== OSPF6_ACTION_RECV
)
218 || (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, SEND
)
219 && action
== OSPF6_ACTION_SEND
)) {
221 for (p
= (char *)((caddr_t
)lsupdate
222 + sizeof(struct ospf6_lsupdate
));
223 p
< OSPF6_MESSAGE_END(oh
)
224 && p
+ OSPF6_LSA_SIZE(p
) <= OSPF6_MESSAGE_END(oh
);
225 p
+= OSPF6_LSA_SIZE(p
)) {
226 ospf6_lsa_header_print_raw(
227 (struct ospf6_lsa_header
*)p
);
230 assert(p
== OSPF6_MESSAGE_END(oh
));
234 void ospf6_lsack_print(struct ospf6_header
*oh
, int action
)
238 ospf6_header_print(oh
);
239 assert(oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
241 if ((IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
)
242 && action
== OSPF6_ACTION_RECV
)
243 || (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, SEND
)
244 && action
== OSPF6_ACTION_SEND
)) {
246 for (p
= (char *)((caddr_t
)oh
+ sizeof(struct ospf6_header
));
247 p
+ sizeof(struct ospf6_lsa_header
)
248 <= OSPF6_MESSAGE_END(oh
);
249 p
+= sizeof(struct ospf6_lsa_header
))
250 ospf6_lsa_header_print_raw(
251 (struct ospf6_lsa_header
*)p
);
253 assert(p
== OSPF6_MESSAGE_END(oh
));
257 static struct ospf6_packet
*ospf6_packet_new(size_t size
)
259 struct ospf6_packet
*new;
261 new = XCALLOC(MTYPE_OSPF6_PACKET
, sizeof(struct ospf6_packet
));
262 new->s
= stream_new(size
);
267 static void ospf6_packet_free(struct ospf6_packet
*op
)
272 XFREE(MTYPE_OSPF6_PACKET
, op
);
275 struct ospf6_fifo
*ospf6_fifo_new(void)
277 struct ospf6_fifo
*new;
279 new = XCALLOC(MTYPE_OSPF6_FIFO
, sizeof(struct ospf6_fifo
));
283 /* Add new packet to fifo. */
284 static void ospf6_fifo_push(struct ospf6_fifo
*fifo
, struct ospf6_packet
*op
)
287 fifo
->tail
->next
= op
;
296 /* Add new packet to head of fifo. */
297 static void ospf6_fifo_push_head(struct ospf6_fifo
*fifo
,
298 struct ospf6_packet
*op
)
300 op
->next
= fifo
->head
;
302 if (fifo
->tail
== NULL
)
310 /* Delete first packet from fifo. */
311 static struct ospf6_packet
*ospf6_fifo_pop(struct ospf6_fifo
*fifo
)
313 struct ospf6_packet
*op
;
318 fifo
->head
= op
->next
;
320 if (fifo
->head
== NULL
)
329 /* Return first fifo entry. */
330 static struct ospf6_packet
*ospf6_fifo_head(struct ospf6_fifo
*fifo
)
335 /* Flush ospf packet fifo. */
336 void ospf6_fifo_flush(struct ospf6_fifo
*fifo
)
338 struct ospf6_packet
*op
;
339 struct ospf6_packet
*next
;
341 for (op
= fifo
->head
; op
; op
= next
) {
343 ospf6_packet_free(op
);
345 fifo
->head
= fifo
->tail
= NULL
;
349 /* Free ospf packet fifo. */
350 void ospf6_fifo_free(struct ospf6_fifo
*fifo
)
352 ospf6_fifo_flush(fifo
);
354 XFREE(MTYPE_OSPF6_FIFO
, fifo
);
357 static void ospf6_packet_add(struct ospf6_interface
*oi
,
358 struct ospf6_packet
*op
)
360 /* Add packet to end of queue. */
361 ospf6_fifo_push(oi
->obuf
, op
);
363 /* Debug of packet fifo*/
364 /* ospf_fifo_debug (oi->obuf); */
367 static void ospf6_packet_add_top(struct ospf6_interface
*oi
,
368 struct ospf6_packet
*op
)
370 /* Add packet to head of queue. */
371 ospf6_fifo_push_head(oi
->obuf
, op
);
373 /* Debug of packet fifo*/
374 /* ospf_fifo_debug (oi->obuf); */
377 static void ospf6_packet_delete(struct ospf6_interface
*oi
)
379 struct ospf6_packet
*op
;
381 op
= ospf6_fifo_pop(oi
->obuf
);
384 ospf6_packet_free(op
);
388 static void ospf6_hello_recv(struct in6_addr
*src
, struct in6_addr
*dst
,
389 struct ospf6_interface
*oi
,
390 struct ospf6_header
*oh
)
392 struct ospf6_hello
*hello
;
393 struct ospf6_neighbor
*on
;
396 int neighborchange
= 0;
397 int neighbor_ifindex_change
= 0;
400 struct timeval timestamp
;
402 monotime(×tamp
);
403 hello
= (struct ospf6_hello
*)((caddr_t
)oh
404 + sizeof(struct ospf6_header
));
406 /* HelloInterval check */
407 if (ntohs(hello
->hello_interval
) != oi
->hello_interval
) {
409 "VRF %s: I/F %s HelloInterval mismatch: (my %d, rcvd %d)",
410 vrf_id_to_name(oi
->interface
->vrf_id
),
411 oi
->interface
->name
, oi
->hello_interval
,
412 ntohs(hello
->hello_interval
));
416 /* RouterDeadInterval check */
417 if (ntohs(hello
->dead_interval
) != oi
->dead_interval
) {
419 "VRF %s: I/F %s DeadInterval mismatch: (my %d, rcvd %d)",
420 vrf_id_to_name(oi
->interface
->vrf_id
),
421 oi
->interface
->name
, oi
->dead_interval
,
422 ntohs(hello
->dead_interval
));
427 if (OSPF6_OPT_ISSET(hello
->options
, OSPF6_OPT_E
)
428 != OSPF6_OPT_ISSET(oi
->area
->options
, OSPF6_OPT_E
)) {
429 zlog_warn("VRF %s: IF %s E-bit mismatch",
430 vrf_id_to_name(oi
->interface
->vrf_id
),
431 oi
->interface
->name
);
435 /* Find neighbor, create if not exist */
436 on
= ospf6_neighbor_lookup(oh
->router_id
, oi
);
438 on
= ospf6_neighbor_create(oh
->router_id
, oi
);
439 on
->prev_drouter
= on
->drouter
= hello
->drouter
;
440 on
->prev_bdrouter
= on
->bdrouter
= hello
->bdrouter
;
441 on
->priority
= hello
->priority
;
444 /* check latency against hello period */
446 latency
= monotime_since(&on
->last_hello
, NULL
)
447 - (oi
->hello_interval
* 1000000);
448 /* log if latency exceeds the hello period */
449 if (latency
> (oi
->hello_interval
* 1000000))
450 zlog_warn("%s RX %pI4 high latency %" PRId64
"us.", __func__
,
451 &on
->router_id
, latency
);
452 on
->last_hello
= timestamp
;
455 /* Always override neighbor's source address */
456 memcpy(&on
->linklocal_addr
, src
, sizeof(struct in6_addr
));
458 /* Neighbor ifindex check */
459 if (on
->ifindex
!= (ifindex_t
)ntohl(hello
->interface_id
)) {
460 on
->ifindex
= ntohl(hello
->interface_id
);
461 neighbor_ifindex_change
++;
465 for (p
= (char *)((caddr_t
)hello
+ sizeof(struct ospf6_hello
));
466 p
+ sizeof(uint32_t) <= OSPF6_MESSAGE_END(oh
);
467 p
+= sizeof(uint32_t)) {
468 uint32_t *router_id
= (uint32_t *)p
;
470 if (*router_id
== oi
->area
->ospf6
->router_id
)
474 assert(p
== OSPF6_MESSAGE_END(oh
));
476 /* RouterPriority check */
477 if (on
->priority
!= hello
->priority
) {
478 on
->priority
= hello
->priority
;
483 if (on
->drouter
!= hello
->drouter
) {
484 on
->prev_drouter
= on
->drouter
;
485 on
->drouter
= hello
->drouter
;
486 if (on
->prev_drouter
== on
->router_id
487 || on
->drouter
== on
->router_id
)
492 if (on
->bdrouter
!= hello
->bdrouter
) {
493 on
->prev_bdrouter
= on
->bdrouter
;
494 on
->bdrouter
= hello
->bdrouter
;
495 if (on
->prev_bdrouter
== on
->router_id
496 || on
->bdrouter
== on
->router_id
)
500 /* BackupSeen check */
501 if (oi
->state
== OSPF6_INTERFACE_WAITING
) {
502 if (hello
->bdrouter
== on
->router_id
)
504 else if (hello
->drouter
== on
->router_id
505 && hello
->bdrouter
== htonl(0))
511 /* Execute neighbor events */
512 thread_execute(master
, hello_received
, on
, 0);
514 thread_execute(master
, twoway_received
, on
, 0);
516 thread_execute(master
, oneway_received
, on
, 0);
518 /* Schedule interface events */
520 thread_add_event(master
, backup_seen
, oi
, 0, NULL
);
522 thread_add_event(master
, neighbor_change
, oi
, 0, NULL
);
524 if (neighbor_ifindex_change
&& on
->state
== OSPF6_NEIGHBOR_FULL
)
525 OSPF6_ROUTER_LSA_SCHEDULE(oi
->area
);
528 static void ospf6_dbdesc_recv_master(struct ospf6_header
*oh
,
529 struct ospf6_neighbor
*on
)
531 struct ospf6_dbdesc
*dbdesc
;
534 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
)oh
535 + sizeof(struct ospf6_header
));
537 if (on
->state
< OSPF6_NEIGHBOR_INIT
) {
538 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
539 zlog_debug("Neighbor state less than Init, ignore");
544 case OSPF6_NEIGHBOR_TWOWAY
:
545 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
546 zlog_debug("Neighbor state is 2-Way, ignore");
549 case OSPF6_NEIGHBOR_INIT
:
550 thread_execute(master
, twoway_received
, on
, 0);
551 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
) {
552 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
554 "Neighbor state is not ExStart, ignore");
557 /* else fall through to ExStart */
559 case OSPF6_NEIGHBOR_EXSTART
:
560 /* if neighbor obeys us as our slave, schedule negotiation_done
561 and process LSA Headers. Otherwise, ignore this message */
562 if (!CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MSBIT
)
563 && !CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_IBIT
)
564 && ntohl(dbdesc
->seqnum
) == on
->dbdesc_seqnum
) {
565 /* execute NegotiationDone */
566 thread_execute(master
, negotiation_done
, on
, 0);
568 /* Record neighbor options */
569 memcpy(on
->options
, dbdesc
->options
,
570 sizeof(on
->options
));
573 "VRF %s: Nbr %s: Negotiation failed",
574 vrf_id_to_name(on
->ospf6_if
->interface
->vrf_id
),
578 /* fall through to exchange */
580 case OSPF6_NEIGHBOR_EXCHANGE
:
581 if (!memcmp(dbdesc
, &on
->dbdesc_last
,
582 sizeof(struct ospf6_dbdesc
))) {
583 /* Duplicated DatabaseDescription is dropped by master
585 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
587 "Duplicated dbdesc discarded by Master, ignore");
591 if (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MSBIT
)) {
593 "DbDesc recv: Master/Slave bit mismatch Nbr %s",
595 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
600 if (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_IBIT
)) {
601 zlog_warn("DbDesc recv: Initialize bit mismatch Nbr %s",
603 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
608 if (memcmp(on
->options
, dbdesc
->options
, sizeof(on
->options
))) {
609 zlog_warn("DbDesc recv: Option field mismatch Nbr %s",
611 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
616 if (ntohl(dbdesc
->seqnum
) != on
->dbdesc_seqnum
) {
618 "DbDesc recv: Sequence number mismatch Nbr %s (%#lx expected)",
619 on
->name
, (unsigned long)on
->dbdesc_seqnum
);
620 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
626 case OSPF6_NEIGHBOR_LOADING
:
627 case OSPF6_NEIGHBOR_FULL
:
628 if (!memcmp(dbdesc
, &on
->dbdesc_last
,
629 sizeof(struct ospf6_dbdesc
))) {
630 /* Duplicated DatabaseDescription is dropped by master
632 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
634 "Duplicated dbdesc discarded by Master, ignore");
639 "DbDesc recv: Not duplicate dbdesc in state %s Nbr %s",
640 ospf6_neighbor_state_str
[on
->state
], on
->name
);
641 thread_add_event(master
, seqnumber_mismatch
, on
, 0, NULL
);
649 /* Process LSA headers */
650 for (p
= (char *)((caddr_t
)dbdesc
+ sizeof(struct ospf6_dbdesc
));
651 p
+ sizeof(struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END(oh
);
652 p
+= sizeof(struct ospf6_lsa_header
)) {
653 struct ospf6_lsa
*his
, *mine
;
654 struct ospf6_lsdb
*lsdb
= NULL
;
656 his
= ospf6_lsa_create_headeronly((struct ospf6_lsa_header
*)p
);
658 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
659 zlog_debug("%s", his
->name
);
661 switch (OSPF6_LSA_SCOPE(his
->header
->type
)) {
662 case OSPF6_SCOPE_LINKLOCAL
:
663 lsdb
= on
->ospf6_if
->lsdb
;
665 case OSPF6_SCOPE_AREA
:
666 lsdb
= on
->ospf6_if
->area
->lsdb
;
669 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
671 case OSPF6_SCOPE_RESERVED
:
672 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
673 zlog_debug("Ignoring LSA of reserved scope");
674 ospf6_lsa_delete(his
);
679 if (ntohs(his
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
680 && (IS_AREA_STUB(on
->ospf6_if
->area
)
681 || IS_AREA_NSSA(on
->ospf6_if
->area
))) {
682 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
684 "SeqNumMismatch (E-bit mismatch), discard");
685 ospf6_lsa_delete(his
);
686 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
691 mine
= ospf6_lsdb_lookup(his
->header
->type
, his
->header
->id
,
692 his
->header
->adv_router
, lsdb
);
694 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
695 zlog_debug("Add request (No database copy)");
696 ospf6_lsdb_add(ospf6_lsa_copy(his
), on
->request_list
);
697 } else if (ospf6_lsa_compare(his
, mine
) < 0) {
698 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
699 zlog_debug("Add request (Received MoreRecent)");
700 ospf6_lsdb_add(ospf6_lsa_copy(his
), on
->request_list
);
702 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
703 zlog_debug("Discard (Existing MoreRecent)");
705 ospf6_lsa_delete(his
);
708 assert(p
== OSPF6_MESSAGE_END(oh
));
710 /* Increment sequence number */
713 /* schedule send lsreq */
714 if (on
->request_list
->count
)
715 thread_add_event(master
, ospf6_lsreq_send
, on
, 0,
716 &on
->thread_send_lsreq
);
718 THREAD_OFF(on
->thread_send_dbdesc
);
721 if (!CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MBIT
)
722 && !CHECK_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
))
723 thread_add_event(master
, exchange_done
, on
, 0, NULL
);
725 on
->thread_send_dbdesc
= NULL
;
726 thread_add_event(master
, ospf6_dbdesc_send_newone
, on
, 0,
727 &on
->thread_send_dbdesc
);
730 /* save last received dbdesc */
731 memcpy(&on
->dbdesc_last
, dbdesc
, sizeof(struct ospf6_dbdesc
));
734 static void ospf6_dbdesc_recv_slave(struct ospf6_header
*oh
,
735 struct ospf6_neighbor
*on
)
737 struct ospf6_dbdesc
*dbdesc
;
740 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
)oh
741 + sizeof(struct ospf6_header
));
743 if (on
->state
< OSPF6_NEIGHBOR_INIT
) {
744 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
745 zlog_debug("Neighbor state less than Init, ignore");
750 case OSPF6_NEIGHBOR_TWOWAY
:
751 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
752 zlog_debug("Neighbor state is 2-Way, ignore");
755 case OSPF6_NEIGHBOR_INIT
:
756 thread_execute(master
, twoway_received
, on
, 0);
757 if (on
->state
!= OSPF6_NEIGHBOR_EXSTART
) {
758 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
760 "Neighbor state is not ExStart, ignore");
763 /* else fall through to ExStart */
765 case OSPF6_NEIGHBOR_EXSTART
:
766 /* If the neighbor is Master, act as Slave. Schedule
768 and process LSA Headers. Otherwise, ignore this message */
769 if (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_IBIT
)
770 && CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MBIT
)
771 && CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MSBIT
)
773 == sizeof(struct ospf6_header
)
774 + sizeof(struct ospf6_dbdesc
)) {
775 /* set the master/slave bit to slave */
776 UNSET_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
);
778 /* set the DD sequence number to one specified by master
780 on
->dbdesc_seqnum
= ntohl(dbdesc
->seqnum
);
782 /* schedule NegotiationDone */
783 thread_execute(master
, negotiation_done
, on
, 0);
785 /* Record neighbor options */
786 memcpy(on
->options
, dbdesc
->options
,
787 sizeof(on
->options
));
790 "VRF %s: Nbr %s Negotiation failed",
791 vrf_id_to_name(on
->ospf6_if
->interface
->vrf_id
),
797 case OSPF6_NEIGHBOR_EXCHANGE
:
798 if (!memcmp(dbdesc
, &on
->dbdesc_last
,
799 sizeof(struct ospf6_dbdesc
))) {
800 /* Duplicated DatabaseDescription causes slave to
802 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
804 "Duplicated dbdesc causes retransmit");
805 THREAD_OFF(on
->thread_send_dbdesc
);
806 on
->thread_send_dbdesc
= NULL
;
807 thread_add_event(master
, ospf6_dbdesc_send
, on
, 0,
808 &on
->thread_send_dbdesc
);
812 if (!CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_MSBIT
)) {
814 "DbDesc slave recv: Master/Slave bit mismatch Nbr %s",
816 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
821 if (CHECK_FLAG(dbdesc
->bits
, OSPF6_DBDESC_IBIT
)) {
823 "DbDesc slave recv: Initialize bit mismatch Nbr %s",
825 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
830 if (memcmp(on
->options
, dbdesc
->options
, sizeof(on
->options
))) {
832 "DbDesc slave recv: Option field mismatch Nbr %s",
834 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
839 if (ntohl(dbdesc
->seqnum
) != on
->dbdesc_seqnum
+ 1) {
841 "DbDesc slave recv: Sequence number mismatch Nbr %s (%#lx expected)",
842 on
->name
, (unsigned long)on
->dbdesc_seqnum
+ 1);
843 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
849 case OSPF6_NEIGHBOR_LOADING
:
850 case OSPF6_NEIGHBOR_FULL
:
851 if (!memcmp(dbdesc
, &on
->dbdesc_last
,
852 sizeof(struct ospf6_dbdesc
))) {
853 /* Duplicated DatabaseDescription causes slave to
855 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
857 "Duplicated dbdesc causes retransmit");
858 THREAD_OFF(on
->thread_send_dbdesc
);
859 thread_add_event(master
, ospf6_dbdesc_send
, on
, 0,
860 &on
->thread_send_dbdesc
);
865 "DbDesc slave recv: Not duplicate dbdesc in state %s Nbr %s",
866 ospf6_neighbor_state_str
[on
->state
], on
->name
);
867 thread_add_event(master
, seqnumber_mismatch
, on
, 0, NULL
);
875 /* Process LSA headers */
876 for (p
= (char *)((caddr_t
)dbdesc
+ sizeof(struct ospf6_dbdesc
));
877 p
+ sizeof(struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END(oh
);
878 p
+= sizeof(struct ospf6_lsa_header
)) {
879 struct ospf6_lsa
*his
, *mine
;
880 struct ospf6_lsdb
*lsdb
= NULL
;
882 his
= ospf6_lsa_create_headeronly((struct ospf6_lsa_header
*)p
);
884 switch (OSPF6_LSA_SCOPE(his
->header
->type
)) {
885 case OSPF6_SCOPE_LINKLOCAL
:
886 lsdb
= on
->ospf6_if
->lsdb
;
888 case OSPF6_SCOPE_AREA
:
889 lsdb
= on
->ospf6_if
->area
->lsdb
;
892 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
894 case OSPF6_SCOPE_RESERVED
:
895 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
896 zlog_debug("Ignoring LSA of reserved scope");
897 ospf6_lsa_delete(his
);
902 if (OSPF6_LSA_SCOPE(his
->header
->type
) == OSPF6_SCOPE_AS
903 && (IS_AREA_STUB(on
->ospf6_if
->area
)
904 || IS_AREA_NSSA(on
->ospf6_if
->area
))) {
905 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
906 zlog_debug("E-bit mismatch with LSA Headers");
907 ospf6_lsa_delete(his
);
908 thread_add_event(master
, seqnumber_mismatch
, on
, 0,
913 mine
= ospf6_lsdb_lookup(his
->header
->type
, his
->header
->id
,
914 his
->header
->adv_router
, lsdb
);
915 if (mine
== NULL
|| ospf6_lsa_compare(his
, mine
) < 0) {
916 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
917 zlog_debug("Add request-list: %s", his
->name
);
918 ospf6_lsdb_add(ospf6_lsa_copy(his
), on
->request_list
);
920 ospf6_lsa_delete(his
);
923 assert(p
== OSPF6_MESSAGE_END(oh
));
925 /* Set sequence number to Master's */
926 on
->dbdesc_seqnum
= ntohl(dbdesc
->seqnum
);
928 /* schedule send lsreq */
929 if (on
->request_list
->count
)
930 thread_add_event(master
, ospf6_lsreq_send
, on
, 0,
931 &on
->thread_send_lsreq
);
933 THREAD_OFF(on
->thread_send_dbdesc
);
934 thread_add_event(master
, ospf6_dbdesc_send_newone
, on
, 0,
935 &on
->thread_send_dbdesc
);
937 /* save last received dbdesc */
938 memcpy(&on
->dbdesc_last
, dbdesc
, sizeof(struct ospf6_dbdesc
));
941 static void ospf6_dbdesc_recv(struct in6_addr
*src
, struct in6_addr
*dst
,
942 struct ospf6_interface
*oi
,
943 struct ospf6_header
*oh
)
945 struct ospf6_neighbor
*on
;
946 struct ospf6_dbdesc
*dbdesc
;
948 on
= ospf6_neighbor_lookup(oh
->router_id
, oi
);
950 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
951 zlog_debug("Neighbor not found, ignore");
955 dbdesc
= (struct ospf6_dbdesc
*)((caddr_t
)oh
956 + sizeof(struct ospf6_header
));
958 /* Interface MTU check */
959 if (!oi
->mtu_ignore
&& ntohs(dbdesc
->ifmtu
) != oi
->ifmtu
) {
960 zlog_warn("VRF %s: I/F %s MTU mismatch (my %d rcvd %d)",
961 vrf_id_to_name(oi
->interface
->vrf_id
),
962 oi
->interface
->name
, oi
->ifmtu
, ntohs(dbdesc
->ifmtu
));
966 if (dbdesc
->reserved1
|| dbdesc
->reserved2
) {
967 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
969 "Non-0 reserved field in %s's DbDesc, correct",
971 dbdesc
->reserved1
= 0;
972 dbdesc
->reserved2
= 0;
977 if (ntohl(oh
->router_id
) < ntohl(oi
->area
->ospf6
->router_id
))
978 ospf6_dbdesc_recv_master(oh
, on
);
979 else if (ntohl(oi
->area
->ospf6
->router_id
) < ntohl(oh
->router_id
))
980 ospf6_dbdesc_recv_slave(oh
, on
);
982 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
983 zlog_debug("Can't decide which is master, ignore");
987 static void ospf6_lsreq_recv(struct in6_addr
*src
, struct in6_addr
*dst
,
988 struct ospf6_interface
*oi
,
989 struct ospf6_header
*oh
)
991 struct ospf6_neighbor
*on
;
993 struct ospf6_lsreq_entry
*e
;
994 struct ospf6_lsdb
*lsdb
= NULL
;
995 struct ospf6_lsa
*lsa
;
997 on
= ospf6_neighbor_lookup(oh
->router_id
, oi
);
999 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
1000 zlog_debug("Neighbor not found, ignore");
1004 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
1005 && on
->state
!= OSPF6_NEIGHBOR_LOADING
1006 && on
->state
!= OSPF6_NEIGHBOR_FULL
) {
1007 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
1008 zlog_debug("Neighbor state less than Exchange, ignore");
1014 /* Process each request */
1015 for (p
= (char *)((caddr_t
)oh
+ sizeof(struct ospf6_header
));
1016 p
+ sizeof(struct ospf6_lsreq_entry
) <= OSPF6_MESSAGE_END(oh
);
1017 p
+= sizeof(struct ospf6_lsreq_entry
)) {
1018 e
= (struct ospf6_lsreq_entry
*)p
;
1020 switch (OSPF6_LSA_SCOPE(e
->type
)) {
1021 case OSPF6_SCOPE_LINKLOCAL
:
1022 lsdb
= on
->ospf6_if
->lsdb
;
1024 case OSPF6_SCOPE_AREA
:
1025 lsdb
= on
->ospf6_if
->area
->lsdb
;
1027 case OSPF6_SCOPE_AS
:
1028 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
1031 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1032 zlog_debug("Ignoring LSA of reserved scope");
1037 /* Find database copy */
1038 lsa
= ospf6_lsdb_lookup(e
->type
, e
->id
, e
->adv_router
, lsdb
);
1041 "Can't find requested lsa [%s Id:%pI4 Adv:%pI4] send badLSReq",
1042 ospf6_lstype_name(e
->type
), &e
->id
,
1044 thread_add_event(master
, bad_lsreq
, on
, 0, NULL
);
1048 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), on
->lsupdate_list
);
1051 assert(p
== OSPF6_MESSAGE_END(oh
));
1053 /* schedule send lsupdate */
1054 THREAD_OFF(on
->thread_send_lsupdate
);
1055 thread_add_event(master
, ospf6_lsupdate_send_neighbor
, on
, 0,
1056 &on
->thread_send_lsupdate
);
1059 /* Verify, that the specified memory area contains exactly N valid IPv6
1060 prefixes as specified by RFC5340, A.4.1. */
1061 static unsigned ospf6_prefixes_examin(
1062 struct ospf6_prefix
*current
, /* start of buffer */
1064 const uint32_t req_num_pfxs
/* always compared with the actual number
1068 uint8_t requested_pfx_bytes
;
1069 uint32_t real_num_pfxs
= 0;
1072 if (length
< OSPF6_PREFIX_MIN_SIZE
) {
1073 zlog_warn("%s: undersized IPv6 prefix header",
1077 /* safe to look deeper */
1078 if (current
->prefix_length
> IPV6_MAX_BITLEN
) {
1079 zlog_warn("%s: invalid PrefixLength (%u bits)",
1080 __func__
, current
->prefix_length
);
1083 /* covers both fixed- and variable-sized fields */
1084 requested_pfx_bytes
=
1085 OSPF6_PREFIX_MIN_SIZE
1086 + OSPF6_PREFIX_SPACE(current
->prefix_length
);
1087 if (requested_pfx_bytes
> length
) {
1088 zlog_warn("%s: undersized IPv6 prefix", __func__
);
1092 length
-= requested_pfx_bytes
;
1093 current
= (struct ospf6_prefix
*)((caddr_t
)current
1094 + requested_pfx_bytes
);
1097 if (real_num_pfxs
!= req_num_pfxs
) {
1099 "%s: IPv6 prefix number mismatch (%u required, %u real)",
1100 __func__
, req_num_pfxs
, real_num_pfxs
);
1106 /* Verify an LSA to have a valid length and dispatch further (where
1107 appropriate) to check if the contents, including nested IPv6 prefixes,
1108 is properly sized/aligned within the LSA. Note that this function gets
1109 LSA type in network byte order, uses in host byte order and passes to
1110 ospf6_lstype_name() in network byte order again. */
1111 static unsigned ospf6_lsa_examin(struct ospf6_lsa_header
*lsah
,
1112 const uint16_t lsalen
,
1113 const uint8_t headeronly
)
1115 struct ospf6_intra_prefix_lsa
*intra_prefix_lsa
;
1116 struct ospf6_as_external_lsa
*as_external_lsa
;
1117 struct ospf6_link_lsa
*link_lsa
;
1118 unsigned exp_length
;
1122 /* In case an additional minimum length constraint is defined for
1124 LSA type, make sure that this constraint is met. */
1125 lsatype
= ntohs(lsah
->type
);
1126 ltindex
= lsatype
& OSPF6_LSTYPE_FCODE_MASK
;
1127 if (ltindex
< OSPF6_LSTYPE_SIZE
&& ospf6_lsa_minlen
[ltindex
]
1128 && lsalen
< ospf6_lsa_minlen
[ltindex
] + OSPF6_LSA_HEADER_SIZE
) {
1129 zlog_warn("%s: undersized (%u B) LSA", __func__
, lsalen
);
1133 case OSPF6_LSTYPE_ROUTER
:
1134 /* RFC5340 A.4.3, LSA header + OSPF6_ROUTER_LSA_MIN_SIZE bytes
1136 by N>=0 interface descriptions. */
1137 if ((lsalen
- OSPF6_LSA_HEADER_SIZE
- OSPF6_ROUTER_LSA_MIN_SIZE
)
1138 % OSPF6_ROUTER_LSDESC_FIX_SIZE
) {
1140 "%s: Router LSA interface description alignment error",
1145 case OSPF6_LSTYPE_NETWORK
:
1146 /* RFC5340 A.4.4, LSA header + OSPF6_NETWORK_LSA_MIN_SIZE bytes
1147 followed by N>=0 attached router descriptions. */
1148 if ((lsalen
- OSPF6_LSA_HEADER_SIZE
1149 - OSPF6_NETWORK_LSA_MIN_SIZE
)
1150 % OSPF6_NETWORK_LSDESC_FIX_SIZE
) {
1152 "%s: Network LSA router description alignment error",
1157 case OSPF6_LSTYPE_INTER_PREFIX
:
1158 /* RFC5340 A.4.5, LSA header + OSPF6_INTER_PREFIX_LSA_MIN_SIZE
1160 followed by 3-4 fields of a single IPv6 prefix. */
1163 return ospf6_prefixes_examin(
1164 (struct ospf6_prefix
1165 *)((caddr_t
)lsah
+ OSPF6_LSA_HEADER_SIZE
1166 + OSPF6_INTER_PREFIX_LSA_MIN_SIZE
),
1167 lsalen
- OSPF6_LSA_HEADER_SIZE
1168 - OSPF6_INTER_PREFIX_LSA_MIN_SIZE
,
1170 case OSPF6_LSTYPE_INTER_ROUTER
:
1171 /* RFC5340 A.4.6, fixed-size LSA. */
1173 > OSPF6_LSA_HEADER_SIZE
+ OSPF6_INTER_ROUTER_LSA_FIX_SIZE
) {
1174 zlog_warn("%s: Inter Router LSA oversized (%u B) LSA",
1179 case OSPF6_LSTYPE_AS_EXTERNAL
: /* RFC5340 A.4.7, same as A.4.8. */
1180 case OSPF6_LSTYPE_TYPE_7
:
1181 /* RFC5340 A.4.8, LSA header + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
1183 followed by 3-4 fields of IPv6 prefix and 3 conditional LSA
1185 16 bytes of forwarding address, 4 bytes of external route
1187 4 bytes of referenced link state ID. */
1191 (struct ospf6_as_external_lsa
1192 *)((caddr_t
)lsah
+ OSPF6_LSA_HEADER_SIZE
);
1194 OSPF6_LSA_HEADER_SIZE
+ OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
;
1195 /* To find out if the last optional field (Referenced Link State
1197 assumed in this LSA, we need to access fixed fields of the
1199 prefix before ospf6_prefix_examin() confirms its sizing. */
1200 if (exp_length
+ OSPF6_PREFIX_MIN_SIZE
> lsalen
) {
1202 "%s: AS External undersized (%u B) LSA header",
1206 /* forwarding address */
1207 if (CHECK_FLAG(as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_F
))
1209 /* external route tag */
1210 if (CHECK_FLAG(as_external_lsa
->bits_metric
, OSPF6_ASBR_BIT_T
))
1212 /* referenced link state ID */
1213 if (as_external_lsa
->prefix
.u
._prefix_referenced_lstype
)
1215 /* All the fixed-size fields (mandatory and optional) must fit.
1217 this check does not include any IPv6 prefix fields. */
1218 if (exp_length
> lsalen
) {
1220 "%s: AS External undersized (%u B) LSA header",
1224 /* The last call completely covers the remainder (IPv6 prefix).
1226 return ospf6_prefixes_examin(
1227 (struct ospf6_prefix
1228 *)((caddr_t
)as_external_lsa
1229 + OSPF6_AS_EXTERNAL_LSA_MIN_SIZE
),
1230 lsalen
- exp_length
, 1);
1231 case OSPF6_LSTYPE_LINK
:
1232 /* RFC5340 A.4.9, LSA header + OSPF6_LINK_LSA_MIN_SIZE bytes
1234 by N>=0 IPv6 prefix blocks (with N declared beforehand). */
1237 link_lsa
= (struct ospf6_link_lsa
*)((caddr_t
)lsah
1238 + OSPF6_LSA_HEADER_SIZE
);
1239 return ospf6_prefixes_examin(
1240 (struct ospf6_prefix
*)((caddr_t
)link_lsa
1241 + OSPF6_LINK_LSA_MIN_SIZE
),
1242 lsalen
- OSPF6_LSA_HEADER_SIZE
1243 - OSPF6_LINK_LSA_MIN_SIZE
,
1244 ntohl(link_lsa
->prefix_num
) /* 32 bits */
1246 case OSPF6_LSTYPE_INTRA_PREFIX
:
1247 /* RFC5340 A.4.10, LSA header + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
1249 followed by N>=0 IPv6 prefixes (with N declared beforehand).
1254 (struct ospf6_intra_prefix_lsa
1255 *)((caddr_t
)lsah
+ OSPF6_LSA_HEADER_SIZE
);
1256 return ospf6_prefixes_examin(
1257 (struct ospf6_prefix
1258 *)((caddr_t
)intra_prefix_lsa
1259 + OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
),
1260 lsalen
- OSPF6_LSA_HEADER_SIZE
1261 - OSPF6_INTRA_PREFIX_LSA_MIN_SIZE
,
1262 ntohs(intra_prefix_lsa
->prefix_num
) /* 16 bits */
1265 /* No additional validation is possible for unknown LSA types, which are
1266 themselves valid in OPSFv3, hence the default decision is to accept.
1271 /* Verify if the provided input buffer is a valid sequence of LSAs. This
1272 includes verification of LSA blocks length/alignment and dispatching
1273 of deeper-level checks. */
1275 ospf6_lsaseq_examin(struct ospf6_lsa_header
*lsah
, /* start of buffered data */
1276 size_t length
, const uint8_t headeronly
,
1277 /* When declared_num_lsas is not 0, compare it to the real
1279 and treat the difference as an error. */
1280 const uint32_t declared_num_lsas
)
1282 uint32_t counted_lsas
= 0;
1286 if (length
< OSPF6_LSA_HEADER_SIZE
) {
1288 "%s: undersized (%zu B) trailing (#%u) LSA header",
1289 __func__
, length
, counted_lsas
);
1292 /* save on ntohs() calls here and in the LSA validator */
1293 lsalen
= OSPF6_LSA_SIZE(lsah
);
1294 if (lsalen
< OSPF6_LSA_HEADER_SIZE
) {
1296 "%s: malformed LSA header #%u, declared length is %u B",
1297 __func__
, counted_lsas
, lsalen
);
1301 /* less checks here and in ospf6_lsa_examin() */
1302 if (MSG_OK
!= ospf6_lsa_examin(lsah
, lsalen
, 1)) {
1304 "%s: anomaly in header-only %s LSA #%u",
1305 __func__
, ospf6_lstype_name(lsah
->type
),
1309 lsah
= (struct ospf6_lsa_header
1311 + OSPF6_LSA_HEADER_SIZE
);
1312 length
-= OSPF6_LSA_HEADER_SIZE
;
1314 /* make sure the input buffer is deep enough before
1316 if (lsalen
> length
) {
1318 "%s: anomaly in %s LSA #%u: declared length is %u B, buffered length is %zu B",
1319 __func__
, ospf6_lstype_name(lsah
->type
),
1320 counted_lsas
, lsalen
, length
);
1323 if (MSG_OK
!= ospf6_lsa_examin(lsah
, lsalen
, 0)) {
1324 zlog_warn("%s: anomaly in %s LSA #%u", __func__
,
1325 ospf6_lstype_name(lsah
->type
),
1329 lsah
= (struct ospf6_lsa_header
*)((caddr_t
)lsah
1336 if (declared_num_lsas
&& counted_lsas
!= declared_num_lsas
) {
1337 zlog_warn("%s: #LSAs declared (%u) does not match actual (%u)",
1338 __func__
, declared_num_lsas
, counted_lsas
);
1344 /* Verify a complete OSPF packet for proper sizing/alignment. */
1345 static unsigned ospf6_packet_examin(struct ospf6_header
*oh
,
1346 const unsigned bytesonwire
)
1348 struct ospf6_lsupdate
*lsupd
;
1351 /* length, 1st approximation */
1352 if (bytesonwire
< OSPF6_HEADER_SIZE
) {
1353 zlog_warn("%s: undersized (%u B) packet", __func__
,
1357 /* Now it is safe to access header fields. */
1358 if (bytesonwire
!= ntohs(oh
->length
)) {
1359 zlog_warn("%s: %s packet length error (%u real, %u declared)",
1361 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
),
1362 bytesonwire
, ntohs(oh
->length
));
1366 if (oh
->version
!= OSPFV3_VERSION
) {
1367 zlog_warn("%s: invalid (%u) protocol version", __func__
,
1371 /* length, 2nd approximation */
1372 if (oh
->type
< OSPF6_MESSAGE_TYPE_ALL
&& ospf6_packet_minlen
[oh
->type
]
1374 < OSPF6_HEADER_SIZE
+ ospf6_packet_minlen
[oh
->type
]) {
1375 zlog_warn("%s: undersized (%u B) %s packet", __func__
,
1377 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1380 /* type-specific deeper validation */
1382 case OSPF6_MESSAGE_TYPE_HELLO
:
1383 /* RFC5340 A.3.2, packet header + OSPF6_HELLO_MIN_SIZE bytes
1385 by N>=0 router-IDs. */
1387 == (bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_HELLO_MIN_SIZE
)
1390 zlog_warn("%s: alignment error in %s packet", __func__
,
1391 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1393 case OSPF6_MESSAGE_TYPE_DBDESC
:
1394 /* RFC5340 A.3.3, packet header + OSPF6_DB_DESC_MIN_SIZE bytes
1396 by N>=0 header-only LSAs. */
1397 test
= ospf6_lsaseq_examin(
1398 (struct ospf6_lsa_header
*)((caddr_t
)oh
1400 + OSPF6_DB_DESC_MIN_SIZE
),
1401 bytesonwire
- OSPF6_HEADER_SIZE
1402 - OSPF6_DB_DESC_MIN_SIZE
,
1405 case OSPF6_MESSAGE_TYPE_LSREQ
:
1406 /* RFC5340 A.3.4, packet header + N>=0 LS description blocks. */
1408 == (bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_REQ_MIN_SIZE
)
1409 % OSPF6_LSREQ_LSDESC_FIX_SIZE
)
1411 zlog_warn("%s: alignment error in %s packet", __func__
,
1412 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1414 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1415 /* RFC5340 A.3.5, packet header + OSPF6_LS_UPD_MIN_SIZE bytes
1417 by N>=0 full LSAs (with N declared beforehand). */
1418 lsupd
= (struct ospf6_lsupdate
*)((caddr_t
)oh
1419 + OSPF6_HEADER_SIZE
);
1420 test
= ospf6_lsaseq_examin(
1421 (struct ospf6_lsa_header
*)((caddr_t
)lsupd
1422 + OSPF6_LS_UPD_MIN_SIZE
),
1423 bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_UPD_MIN_SIZE
,
1424 0, ntohl(lsupd
->lsa_number
) /* 32 bits */
1427 case OSPF6_MESSAGE_TYPE_LSACK
:
1428 /* RFC5340 A.3.6, packet header + N>=0 header-only LSAs. */
1429 test
= ospf6_lsaseq_examin(
1430 (struct ospf6_lsa_header
*)((caddr_t
)oh
1432 + OSPF6_LS_ACK_MIN_SIZE
),
1433 bytesonwire
- OSPF6_HEADER_SIZE
- OSPF6_LS_ACK_MIN_SIZE
,
1437 zlog_warn("%s: invalid (%u) message type", __func__
, oh
->type
);
1441 zlog_warn("%s: anomaly in %s packet", __func__
,
1442 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
));
1446 /* Verify particular fields of otherwise correct received OSPF packet to
1447 meet the requirements of RFC. */
1448 static int ospf6_rxpacket_examin(struct ospf6_interface
*oi
,
1449 struct ospf6_header
*oh
,
1450 const unsigned bytesonwire
)
1453 if (MSG_OK
!= ospf6_packet_examin(oh
, bytesonwire
))
1457 if (oh
->area_id
!= oi
->area
->area_id
) {
1458 if (oh
->area_id
== OSPF_AREA_BACKBONE
)
1460 "VRF %s: I/F %s Message may be via Virtual Link: not supported",
1461 vrf_id_to_name(oi
->interface
->vrf_id
),
1462 oi
->interface
->name
);
1465 "VRF %s: I/F %s Area-ID mismatch (my %pI4, rcvd %pI4)",
1466 vrf_id_to_name(oi
->interface
->vrf_id
),
1467 oi
->interface
->name
, &oi
->area
->area_id
,
1472 /* Instance-ID check */
1473 if (oh
->instance_id
!= oi
->instance_id
) {
1475 "VRF %s: I/F %s Instance-ID mismatch (my %u, rcvd %u)",
1476 vrf_id_to_name(oi
->interface
->vrf_id
),
1477 oi
->interface
->name
, oi
->instance_id
, oh
->instance_id
);
1481 /* Router-ID check */
1482 if (oh
->router_id
== oi
->area
->ospf6
->router_id
) {
1483 zlog_warn("VRF %s: I/F %s Duplicate Router-ID (%pI4)",
1484 vrf_id_to_name(oi
->interface
->vrf_id
),
1485 oi
->interface
->name
, &oh
->router_id
);
1491 static void ospf6_lsupdate_recv(struct in6_addr
*src
, struct in6_addr
*dst
,
1492 struct ospf6_interface
*oi
,
1493 struct ospf6_header
*oh
)
1495 struct ospf6_neighbor
*on
;
1496 struct ospf6_lsupdate
*lsupdate
;
1499 on
= ospf6_neighbor_lookup(oh
->router_id
, oi
);
1501 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
1502 zlog_debug("Neighbor not found, ignore");
1506 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
1507 && on
->state
!= OSPF6_NEIGHBOR_LOADING
1508 && on
->state
!= OSPF6_NEIGHBOR_FULL
) {
1509 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
1510 zlog_debug("Neighbor state less than Exchange, ignore");
1514 lsupdate
= (struct ospf6_lsupdate
*)((caddr_t
)oh
1515 + sizeof(struct ospf6_header
));
1520 for (p
= (char *)((caddr_t
)lsupdate
+ sizeof(struct ospf6_lsupdate
));
1521 p
< OSPF6_MESSAGE_END(oh
)
1522 && p
+ OSPF6_LSA_SIZE(p
) <= OSPF6_MESSAGE_END(oh
);
1523 p
+= OSPF6_LSA_SIZE(p
)) {
1524 ospf6_receive_lsa(on
, (struct ospf6_lsa_header
*)p
);
1527 assert(p
== OSPF6_MESSAGE_END(oh
));
1530 static void ospf6_lsack_recv(struct in6_addr
*src
, struct in6_addr
*dst
,
1531 struct ospf6_interface
*oi
,
1532 struct ospf6_header
*oh
)
1534 struct ospf6_neighbor
*on
;
1536 struct ospf6_lsa
*his
, *mine
;
1537 struct ospf6_lsdb
*lsdb
= NULL
;
1539 assert(oh
->type
== OSPF6_MESSAGE_TYPE_LSACK
);
1541 on
= ospf6_neighbor_lookup(oh
->router_id
, oi
);
1543 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
1544 zlog_debug("Neighbor not found, ignore");
1548 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
1549 && on
->state
!= OSPF6_NEIGHBOR_LOADING
1550 && on
->state
!= OSPF6_NEIGHBOR_FULL
) {
1551 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
))
1552 zlog_debug("Neighbor state less than Exchange, ignore");
1558 for (p
= (char *)((caddr_t
)oh
+ sizeof(struct ospf6_header
));
1559 p
+ sizeof(struct ospf6_lsa_header
) <= OSPF6_MESSAGE_END(oh
);
1560 p
+= sizeof(struct ospf6_lsa_header
)) {
1561 his
= ospf6_lsa_create_headeronly((struct ospf6_lsa_header
*)p
);
1563 switch (OSPF6_LSA_SCOPE(his
->header
->type
)) {
1564 case OSPF6_SCOPE_LINKLOCAL
:
1565 lsdb
= on
->ospf6_if
->lsdb
;
1567 case OSPF6_SCOPE_AREA
:
1568 lsdb
= on
->ospf6_if
->area
->lsdb
;
1570 case OSPF6_SCOPE_AS
:
1571 lsdb
= on
->ospf6_if
->area
->ospf6
->lsdb
;
1573 case OSPF6_SCOPE_RESERVED
:
1574 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1575 zlog_debug("Ignoring LSA of reserved scope");
1576 ospf6_lsa_delete(his
);
1581 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1582 zlog_debug("%s acknowledged by %s", his
->name
,
1585 /* Find database copy */
1586 mine
= ospf6_lsdb_lookup(his
->header
->type
, his
->header
->id
,
1587 his
->header
->adv_router
, lsdb
);
1589 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1590 zlog_debug("No database copy");
1591 ospf6_lsa_delete(his
);
1595 /* Check if the LSA is on his retrans-list */
1596 mine
= ospf6_lsdb_lookup(his
->header
->type
, his
->header
->id
,
1597 his
->header
->adv_router
,
1600 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1601 zlog_debug("Not on %s's retrans-list",
1603 ospf6_lsa_delete(his
);
1607 if (ospf6_lsa_compare(his
, mine
) != 0) {
1608 /* Log this questionable acknowledgement,
1609 and examine the next one. */
1610 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1611 zlog_debug("Questionable acknowledgement");
1612 ospf6_lsa_delete(his
);
1616 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV
))
1618 "Acknowledged, remove from %s's retrans-list",
1621 ospf6_decrement_retrans_count(mine
);
1622 if (OSPF6_LSA_IS_MAXAGE(mine
))
1623 ospf6_maxage_remove(on
->ospf6_if
->area
->ospf6
);
1624 ospf6_lsdb_remove(mine
, on
->retrans_list
);
1625 ospf6_lsa_delete(his
);
1628 assert(p
== OSPF6_MESSAGE_END(oh
));
1631 static uint8_t *recvbuf
= NULL
;
1632 static uint8_t *sendbuf
= NULL
;
1633 static unsigned int iobuflen
= 0;
1635 int ospf6_iobuf_size(unsigned int size
)
1637 uint8_t *recvnew
, *sendnew
;
1639 if (size
<= iobuflen
)
1642 recvnew
= XMALLOC(MTYPE_OSPF6_MESSAGE
, size
);
1643 sendnew
= XMALLOC(MTYPE_OSPF6_MESSAGE
, size
);
1645 XFREE(MTYPE_OSPF6_MESSAGE
, recvbuf
);
1646 XFREE(MTYPE_OSPF6_MESSAGE
, sendbuf
);
1654 void ospf6_message_terminate(void)
1656 XFREE(MTYPE_OSPF6_MESSAGE
, recvbuf
);
1657 XFREE(MTYPE_OSPF6_MESSAGE
, sendbuf
);
1662 enum ospf6_read_return_enum
{
1664 OSPF6_READ_CONTINUE
,
1667 static int ospf6_read_helper(int sockfd
, struct ospf6
*ospf6
)
1670 struct in6_addr src
, dst
;
1672 struct iovec iovector
[2];
1673 struct ospf6_interface
*oi
;
1674 struct ospf6_header
*oh
;
1677 memset(&src
, 0, sizeof(src
));
1678 memset(&dst
, 0, sizeof(dst
));
1680 memset(recvbuf
, 0, iobuflen
);
1681 iovector
[0].iov_base
= recvbuf
;
1682 iovector
[0].iov_len
= iobuflen
;
1683 iovector
[1].iov_base
= NULL
;
1684 iovector
[1].iov_len
= 0;
1686 /* receive message */
1687 len
= ospf6_recvmsg(&src
, &dst
, &ifindex
, iovector
, sockfd
);
1689 return OSPF6_READ_ERROR
;
1691 if ((uint
)len
> iobuflen
) {
1692 flog_err(EC_LIB_DEVELOPMENT
, "Excess message read");
1693 return OSPF6_READ_ERROR
;
1696 oi
= ospf6_interface_lookup_by_ifindex(ifindex
, ospf6
->vrf_id
);
1697 if (oi
== NULL
|| oi
->area
== NULL
1698 || CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_DISABLE
)) {
1699 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN
,
1701 zlog_debug("Message received on disabled interface");
1702 return OSPF6_READ_CONTINUE
;
1704 if (CHECK_FLAG(oi
->flag
, OSPF6_INTERFACE_PASSIVE
)) {
1705 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN
,
1707 zlog_debug("%s: Ignore message on passive interface %s",
1708 __func__
, oi
->interface
->name
);
1709 return OSPF6_READ_CONTINUE
;
1712 oh
= (struct ospf6_header
*)recvbuf
;
1713 if (ospf6_rxpacket_examin(oi
, oh
, len
) != MSG_OK
)
1714 return OSPF6_READ_CONTINUE
;
1716 /* Being here means, that no sizing/alignment issues were detected in
1717 the input packet. This renders the additional checks performed below
1718 and also in the type-specific dispatching functions a dead code,
1719 which can be dismissed in a cleanup-focused review round later. */
1722 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, RECV_HDR
)) {
1723 zlog_debug("%s received on %s",
1724 lookup_msg(ospf6_message_type_str
, oh
->type
, NULL
),
1725 oi
->interface
->name
);
1726 zlog_debug(" src: %pI6", &src
);
1727 zlog_debug(" dst: %pI6", &dst
);
1730 case OSPF6_MESSAGE_TYPE_HELLO
:
1731 ospf6_hello_print(oh
, OSPF6_ACTION_RECV
);
1733 case OSPF6_MESSAGE_TYPE_DBDESC
:
1734 ospf6_dbdesc_print(oh
, OSPF6_ACTION_RECV
);
1736 case OSPF6_MESSAGE_TYPE_LSREQ
:
1737 ospf6_lsreq_print(oh
, OSPF6_ACTION_RECV
);
1739 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1740 ospf6_lsupdate_print(oh
, OSPF6_ACTION_RECV
);
1742 case OSPF6_MESSAGE_TYPE_LSACK
:
1743 ospf6_lsack_print(oh
, OSPF6_ACTION_RECV
);
1751 case OSPF6_MESSAGE_TYPE_HELLO
:
1752 ospf6_hello_recv(&src
, &dst
, oi
, oh
);
1755 case OSPF6_MESSAGE_TYPE_DBDESC
:
1756 ospf6_dbdesc_recv(&src
, &dst
, oi
, oh
);
1759 case OSPF6_MESSAGE_TYPE_LSREQ
:
1760 ospf6_lsreq_recv(&src
, &dst
, oi
, oh
);
1763 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1764 ospf6_lsupdate_recv(&src
, &dst
, oi
, oh
);
1767 case OSPF6_MESSAGE_TYPE_LSACK
:
1768 ospf6_lsack_recv(&src
, &dst
, oi
, oh
);
1775 return OSPF6_READ_CONTINUE
;
1778 int ospf6_receive(struct thread
*thread
)
1781 struct ospf6
*ospf6
;
1784 /* add next read thread */
1785 ospf6
= THREAD_ARG(thread
);
1786 sockfd
= THREAD_FD(thread
);
1788 thread_add_read(master
, ospf6_receive
, ospf6
, ospf6
->fd
,
1789 &ospf6
->t_ospf6_receive
);
1791 while (count
< ospf6
->write_oi_count
) {
1793 switch (ospf6_read_helper(sockfd
, ospf6
)) {
1794 case OSPF6_READ_ERROR
:
1796 case OSPF6_READ_CONTINUE
:
1804 static void ospf6_make_header(uint8_t type
, struct ospf6_interface
*oi
,
1807 struct ospf6_header
*oh
;
1809 oh
= (struct ospf6_header
*)STREAM_DATA(s
);
1811 oh
->version
= (uint8_t)OSPFV3_VERSION
;
1814 oh
->router_id
= oi
->area
->ospf6
->router_id
;
1815 oh
->area_id
= oi
->area
->area_id
;
1816 oh
->instance_id
= oi
->instance_id
;
1818 stream_forward_endp(s
, OSPF6_HEADER_SIZE
);
1821 static void ospf6_fill_header(struct ospf6_interface
*oi
, struct stream
*s
,
1824 struct ospf6_header
*oh
;
1826 oh
= (struct ospf6_header
*)STREAM_DATA(s
);
1828 oh
->length
= htons(length
);
1831 static void ospf6_fill_lsupdate_header(struct stream
*s
, uint32_t lsa_num
)
1833 struct ospf6_header
*oh
;
1834 struct ospf6_lsupdate
*lsu
;
1836 oh
= (struct ospf6_header
*)STREAM_DATA(s
);
1838 lsu
= (struct ospf6_lsupdate
*)((caddr_t
)oh
1839 + sizeof(struct ospf6_header
));
1840 lsu
->lsa_number
= htonl(lsa_num
);
1843 static uint32_t ospf6_packet_max(struct ospf6_interface
*oi
)
1845 assert(oi
->ifmtu
> sizeof(struct ip6_hdr
));
1846 return oi
->ifmtu
- (sizeof(struct ip6_hdr
));
1849 static uint16_t ospf6_make_hello(struct ospf6_interface
*oi
, struct stream
*s
)
1851 struct listnode
*node
, *nnode
;
1852 struct ospf6_neighbor
*on
;
1853 uint16_t length
= OSPF6_HELLO_MIN_SIZE
;
1855 stream_putl(s
, oi
->interface
->ifindex
);
1856 stream_putc(s
, oi
->priority
);
1857 stream_putc(s
, oi
->area
->options
[0]);
1858 stream_putc(s
, oi
->area
->options
[1]);
1859 stream_putc(s
, oi
->area
->options
[2]);
1860 stream_putw(s
, oi
->hello_interval
);
1861 stream_putw(s
, oi
->dead_interval
);
1862 stream_put_ipv4(s
, oi
->drouter
);
1863 stream_put_ipv4(s
, oi
->bdrouter
);
1865 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
1866 if (on
->state
< OSPF6_NEIGHBOR_INIT
)
1869 if ((length
+ sizeof(uint32_t) + OSPF6_HEADER_SIZE
)
1870 > ospf6_packet_max(oi
)) {
1871 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO
,
1874 "sending Hello message: exceeds I/F MTU");
1878 stream_put_ipv4(s
, on
->router_id
);
1879 length
+= sizeof(uint32_t);
1885 static int ospf6_write(struct thread
*thread
)
1887 struct ospf6
*ospf6
= THREAD_ARG(thread
);
1888 struct ospf6_interface
*oi
;
1889 struct ospf6_interface
*last_serviced_oi
= NULL
;
1890 struct ospf6_header
*oh
;
1891 struct ospf6_packet
*op
;
1892 struct listnode
*node
;
1893 char srcname
[64], dstname
[64];
1894 struct iovec iovector
[2];
1897 int64_t latency
= 0;
1898 struct timeval timestamp
;
1900 if (ospf6
->fd
< 0) {
1901 zlog_warn("ospf6_write failed to send, fd %d", ospf6
->fd
);
1905 node
= listhead(ospf6
->oi_write_q
);
1907 oi
= listgetdata(node
);
1909 while ((pkt_count
< ospf6
->write_oi_count
) && oi
1910 && (last_serviced_oi
!= oi
)) {
1912 op
= ospf6_fifo_head(oi
->obuf
);
1914 assert(op
->length
>= OSPF6_HEADER_SIZE
);
1916 iovector
[0].iov_base
= (caddr_t
)stream_pnt(op
->s
);
1917 iovector
[0].iov_len
= op
->length
;
1918 iovector
[1].iov_base
= NULL
;
1919 iovector
[1].iov_len
= 0;
1921 oh
= (struct ospf6_header
*)STREAM_DATA(op
->s
);
1923 len
= ospf6_sendmsg(oi
->linklocal_addr
, &op
->dst
,
1924 oi
->interface
->ifindex
, iovector
,
1926 if (len
!= op
->length
)
1927 flog_err(EC_LIB_DEVELOPMENT
,
1928 "Could not send entire message");
1930 if (IS_OSPF6_DEBUG_MESSAGE(oh
->type
, SEND
)) {
1931 inet_ntop(AF_INET6
, &op
->dst
, dstname
, sizeof(dstname
));
1932 inet_ntop(AF_INET6
, oi
->linklocal_addr
, srcname
,
1934 zlog_debug("%s send on %s",
1935 lookup_msg(ospf6_message_type_str
, oh
->type
,
1937 oi
->interface
->name
);
1938 zlog_debug(" src: %s", srcname
);
1939 zlog_debug(" dst: %s", dstname
);
1942 case OSPF6_MESSAGE_TYPE_HELLO
:
1943 monotime(×tamp
);
1945 latency
= monotime_since(&oi
->last_hello
, NULL
)
1946 - (oi
->hello_interval
* 1000000);
1948 /* log if latency exceeds the hello period */
1949 if (latency
> (oi
->hello_interval
* 1000000))
1950 zlog_warn("%s hello TX high latency %" PRId64
1953 oi
->last_hello
= timestamp
;
1955 ospf6_hello_print(oh
, OSPF6_ACTION_SEND
);
1957 case OSPF6_MESSAGE_TYPE_DBDESC
:
1959 ospf6_dbdesc_print(oh
, OSPF6_ACTION_SEND
);
1961 case OSPF6_MESSAGE_TYPE_LSREQ
:
1963 ospf6_lsreq_print(oh
, OSPF6_ACTION_SEND
);
1965 case OSPF6_MESSAGE_TYPE_LSUPDATE
:
1967 ospf6_lsupdate_print(oh
, OSPF6_ACTION_SEND
);
1969 case OSPF6_MESSAGE_TYPE_LSACK
:
1971 ospf6_lsack_print(oh
, OSPF6_ACTION_SEND
);
1974 zlog_debug("Unknown message");
1978 /* Now delete packet from queue. */
1979 ospf6_packet_delete(oi
);
1981 /* Move this interface to the tail of write_q to
1982 serve everyone in a round robin fashion */
1983 list_delete_node(ospf6
->oi_write_q
, node
);
1984 if (ospf6_fifo_head(oi
->obuf
) == NULL
) {
1986 last_serviced_oi
= NULL
;
1989 listnode_add(ospf6
->oi_write_q
, oi
);
1992 /* Setup to service from the head of the queue again */
1993 if (!list_isempty(ospf6
->oi_write_q
)) {
1994 node
= listhead(ospf6
->oi_write_q
);
1995 oi
= listgetdata(node
);
1999 /* If packets still remain in queue, call write thread. */
2000 if (!list_isempty(ospf6
->oi_write_q
))
2001 thread_add_write(master
, ospf6_write
, ospf6
, ospf6
->fd
,
2007 int ospf6_hello_send(struct thread
*thread
)
2009 struct ospf6_interface
*oi
;
2010 struct ospf6_packet
*op
;
2011 uint16_t length
= OSPF6_HEADER_SIZE
;
2013 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
2014 oi
->thread_send_hello
= (struct thread
*)NULL
;
2016 if (oi
->state
<= OSPF6_INTERFACE_DOWN
) {
2017 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_HELLO
, SEND_HDR
))
2018 zlog_debug("Unable to send Hello on down interface %s",
2019 oi
->interface
->name
);
2023 op
= ospf6_packet_new(oi
->ifmtu
);
2025 ospf6_make_header(OSPF6_MESSAGE_TYPE_HELLO
, oi
, op
->s
);
2027 /* Prepare OSPF Hello body */
2028 length
+= ospf6_make_hello(oi
, op
->s
);
2029 if (length
== OSPF6_HEADER_SIZE
) {
2030 /* Hello overshooting MTU */
2031 ospf6_packet_free(op
);
2035 /* Fill OSPF header. */
2036 ospf6_fill_header(oi
, op
->s
, length
);
2038 /* Set packet length. */
2039 op
->length
= length
;
2041 op
->dst
= allspfrouters6
;
2043 /* Add packet to the top of the interface output queue, so that they
2044 * can't get delayed by things like long queues of LS Update packets
2046 ospf6_packet_add_top(oi
, op
);
2048 /* set next thread */
2049 thread_add_timer(master
, ospf6_hello_send
, oi
, oi
->hello_interval
,
2050 &oi
->thread_send_hello
);
2052 OSPF6_MESSAGE_WRITE_ON(oi
);
2057 static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor
*on
, struct stream
*s
)
2059 uint16_t length
= OSPF6_DB_DESC_MIN_SIZE
;
2060 struct ospf6_lsa
*lsa
, *lsanext
;
2062 /* if this is initial one, initialize sequence number for DbDesc */
2063 if (CHECK_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
)
2064 && (on
->dbdesc_seqnum
== 0)) {
2065 on
->dbdesc_seqnum
= monotime(NULL
);
2069 stream_putc(s
, 0); /* reserved 1 */
2070 stream_putc(s
, on
->ospf6_if
->area
->options
[0]);
2071 stream_putc(s
, on
->ospf6_if
->area
->options
[1]);
2072 stream_putc(s
, on
->ospf6_if
->area
->options
[2]);
2073 stream_putw(s
, on
->ospf6_if
->ifmtu
);
2074 stream_putc(s
, 0); /* reserved 2 */
2075 stream_putc(s
, on
->dbdesc_bits
);
2076 stream_putl(s
, on
->dbdesc_seqnum
);
2078 /* if this is not initial one, set LSA headers in dbdesc */
2079 if (!CHECK_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_IBIT
)) {
2080 for (ALL_LSDB(on
->dbdesc_list
, lsa
, lsanext
)) {
2081 ospf6_lsa_age_update_to_send(lsa
,
2082 on
->ospf6_if
->transdelay
);
2085 if ((length
+ sizeof(struct ospf6_lsa_header
)
2086 + OSPF6_HEADER_SIZE
)
2087 > ospf6_packet_max(on
->ospf6_if
)) {
2088 ospf6_lsa_unlock(lsa
);
2090 ospf6_lsa_unlock(lsanext
);
2093 stream_put(s
, lsa
->header
,
2094 sizeof(struct ospf6_lsa_header
));
2095 length
+= sizeof(struct ospf6_lsa_header
);
2101 int ospf6_dbdesc_send(struct thread
*thread
)
2103 struct ospf6_neighbor
*on
;
2104 uint16_t length
= OSPF6_HEADER_SIZE
;
2105 struct ospf6_packet
*op
;
2107 on
= (struct ospf6_neighbor
*)THREAD_ARG(thread
);
2108 on
->thread_send_dbdesc
= (struct thread
*)NULL
;
2110 if (on
->state
< OSPF6_NEIGHBOR_EXSTART
) {
2111 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_DBDESC
, SEND
))
2113 "Quit to send DbDesc to neighbor %s state %s",
2114 on
->name
, ospf6_neighbor_state_str
[on
->state
]);
2118 /* set next thread if master */
2119 if (CHECK_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
))
2120 thread_add_timer(master
, ospf6_dbdesc_send
, on
,
2121 on
->ospf6_if
->rxmt_interval
,
2122 &on
->thread_send_dbdesc
);
2124 op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2125 ospf6_make_header(OSPF6_MESSAGE_TYPE_DBDESC
, on
->ospf6_if
, op
->s
);
2127 length
+= ospf6_make_dbdesc(on
, op
->s
);
2128 ospf6_fill_header(on
->ospf6_if
, op
->s
, length
);
2130 /* Set packet length. */
2131 op
->length
= length
;
2133 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2134 op
->dst
= allspfrouters6
;
2136 op
->dst
= on
->linklocal_addr
;
2138 ospf6_packet_add(on
->ospf6_if
, op
);
2140 OSPF6_MESSAGE_WRITE_ON(on
->ospf6_if
);
2145 int ospf6_dbdesc_send_newone(struct thread
*thread
)
2147 struct ospf6_neighbor
*on
;
2148 struct ospf6_lsa
*lsa
, *lsanext
;
2149 unsigned int size
= 0;
2151 on
= (struct ospf6_neighbor
*)THREAD_ARG(thread
);
2152 ospf6_lsdb_remove_all(on
->dbdesc_list
);
2154 /* move LSAs from summary_list to dbdesc_list (within neighbor
2156 so that ospf6_send_dbdesc () can send those LSAs */
2157 size
= sizeof(struct ospf6_lsa_header
) + sizeof(struct ospf6_dbdesc
);
2158 for (ALL_LSDB(on
->summary_list
, lsa
, lsanext
)) {
2159 /* if stub area then don't advertise AS-External LSAs */
2160 if ((IS_AREA_STUB(on
->ospf6_if
->area
)
2161 || IS_AREA_NSSA(on
->ospf6_if
->area
))
2162 && ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
) {
2163 ospf6_lsdb_remove(lsa
, on
->summary_list
);
2167 if (size
+ sizeof(struct ospf6_lsa_header
)
2168 > ospf6_packet_max(on
->ospf6_if
)) {
2169 ospf6_lsa_unlock(lsa
);
2171 ospf6_lsa_unlock(lsanext
);
2175 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), on
->dbdesc_list
);
2176 ospf6_lsdb_remove(lsa
, on
->summary_list
);
2177 size
+= sizeof(struct ospf6_lsa_header
);
2180 if (on
->summary_list
->count
== 0)
2181 UNSET_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
);
2183 /* If slave, More bit check must be done here */
2184 if (!CHECK_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_MSBIT
) && /* Slave */
2185 !CHECK_FLAG(on
->dbdesc_last
.bits
, OSPF6_DBDESC_MBIT
)
2186 && !CHECK_FLAG(on
->dbdesc_bits
, OSPF6_DBDESC_MBIT
))
2187 thread_add_event(master
, exchange_done
, on
, 0, NULL
);
2189 thread_execute(master
, ospf6_dbdesc_send
, on
, 0);
2193 static uint16_t ospf6_make_lsreq(struct ospf6_neighbor
*on
, struct stream
*s
)
2195 uint16_t length
= 0;
2196 struct ospf6_lsa
*lsa
, *lsanext
, *last_req
= NULL
;
2198 for (ALL_LSDB(on
->request_list
, lsa
, lsanext
)) {
2199 if ((length
+ OSPF6_HEADER_SIZE
)
2200 > ospf6_packet_max(on
->ospf6_if
)) {
2201 ospf6_lsa_unlock(lsa
);
2203 ospf6_lsa_unlock(lsanext
);
2206 stream_putw(s
, 0); /* reserved */
2207 stream_putw(s
, ntohs(lsa
->header
->type
));
2208 stream_putl(s
, ntohl(lsa
->header
->id
));
2209 stream_putl(s
, ntohl(lsa
->header
->adv_router
));
2210 length
+= sizeof(struct ospf6_lsreq_entry
);
2214 if (last_req
!= NULL
) {
2215 if (on
->last_ls_req
!= NULL
)
2216 on
->last_ls_req
= ospf6_lsa_unlock(on
->last_ls_req
);
2218 ospf6_lsa_lock(last_req
);
2219 on
->last_ls_req
= last_req
;
2225 static uint16_t ospf6_make_lsack_neighbor(struct ospf6_neighbor
*on
,
2226 struct ospf6_packet
**op
)
2228 uint16_t length
= 0;
2229 struct ospf6_lsa
*lsa
, *lsanext
;
2232 for (ALL_LSDB(on
->lsack_list
, lsa
, lsanext
)) {
2233 if ((length
+ sizeof(struct ospf6_lsa_header
)
2234 + OSPF6_HEADER_SIZE
)
2235 > ospf6_packet_max(on
->ospf6_if
)) {
2236 /* if we run out of packet size/space here,
2237 better to try again soon. */
2239 ospf6_fill_header(on
->ospf6_if
, (*op
)->s
,
2240 length
+ OSPF6_HEADER_SIZE
);
2242 (*op
)->length
= length
+ OSPF6_HEADER_SIZE
;
2243 (*op
)->dst
= on
->linklocal_addr
;
2244 ospf6_packet_add(on
->ospf6_if
, *op
);
2245 OSPF6_MESSAGE_WRITE_ON(on
->ospf6_if
);
2247 *op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2248 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSACK
,
2249 on
->ospf6_if
, (*op
)->s
);
2254 ospf6_lsa_age_update_to_send(lsa
, on
->ospf6_if
->transdelay
);
2255 stream_put((*op
)->s
, lsa
->header
,
2256 sizeof(struct ospf6_lsa_header
));
2257 length
+= sizeof(struct ospf6_lsa_header
);
2259 assert(lsa
->lock
== 2);
2260 ospf6_lsdb_remove(lsa
, on
->lsack_list
);
2266 int ospf6_lsreq_send(struct thread
*thread
)
2268 struct ospf6_neighbor
*on
;
2269 struct ospf6_packet
*op
;
2270 uint16_t length
= OSPF6_HEADER_SIZE
;
2272 on
= (struct ospf6_neighbor
*)THREAD_ARG(thread
);
2273 on
->thread_send_lsreq
= (struct thread
*)NULL
;
2275 /* LSReq will be sent only in ExStart or Loading */
2276 if (on
->state
!= OSPF6_NEIGHBOR_EXCHANGE
2277 && on
->state
!= OSPF6_NEIGHBOR_LOADING
) {
2278 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSREQ
, SEND_HDR
))
2279 zlog_debug("Quit to send LSReq to neighbor %s state %s",
2281 ospf6_neighbor_state_str
[on
->state
]);
2285 /* schedule loading_done if request list is empty */
2286 if (on
->request_list
->count
== 0) {
2287 thread_add_event(master
, loading_done
, on
, 0, NULL
);
2291 op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2292 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSREQ
, on
->ospf6_if
, op
->s
);
2294 length
+= ospf6_make_lsreq(on
, op
->s
);
2296 if (length
== OSPF6_HEADER_SIZE
) {
2297 /* Hello overshooting MTU */
2298 ospf6_packet_free(op
);
2302 /* Fill OSPF header. */
2303 ospf6_fill_header(on
->ospf6_if
, op
->s
, length
);
2305 /* Set packet length */
2306 op
->length
= length
;
2308 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2309 op
->dst
= allspfrouters6
;
2311 op
->dst
= on
->linklocal_addr
;
2313 ospf6_packet_add(on
->ospf6_if
, op
);
2315 OSPF6_MESSAGE_WRITE_ON(on
->ospf6_if
);
2317 /* set next thread */
2318 if (on
->request_list
->count
!= 0) {
2319 on
->thread_send_lsreq
= NULL
;
2320 thread_add_timer(master
, ospf6_lsreq_send
, on
,
2321 on
->ospf6_if
->rxmt_interval
,
2322 &on
->thread_send_lsreq
);
2328 static void ospf6_send_lsupdate(struct ospf6_neighbor
*on
,
2329 struct ospf6_interface
*oi
,
2330 struct ospf6_packet
*op
)
2335 if ((on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2336 || (on
->ospf6_if
->state
== OSPF6_INTERFACE_DR
)
2337 || (on
->ospf6_if
->state
== OSPF6_INTERFACE_BDR
))
2338 op
->dst
= allspfrouters6
;
2340 op
->dst
= on
->linklocal_addr
;
2343 if ((oi
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2344 || (oi
->state
== OSPF6_INTERFACE_DR
)
2345 || (oi
->state
== OSPF6_INTERFACE_BDR
))
2346 op
->dst
= allspfrouters6
;
2348 op
->dst
= alldrouters6
;
2351 ospf6_packet_add(oi
, op
);
2352 OSPF6_MESSAGE_WRITE_ON(oi
);
2356 static uint16_t ospf6_make_lsupdate_list(struct ospf6_neighbor
*on
,
2357 struct ospf6_packet
**op
, int *lsa_cnt
)
2359 uint16_t length
= OSPF6_LS_UPD_MIN_SIZE
;
2360 struct ospf6_lsa
*lsa
, *lsanext
;
2362 /* skip over fixed header */
2363 stream_forward_endp((*op
)->s
, OSPF6_LS_UPD_MIN_SIZE
);
2365 for (ALL_LSDB(on
->lsupdate_list
, lsa
, lsanext
)) {
2366 if ((length
+ (unsigned int)OSPF6_LSA_SIZE(lsa
->header
)
2367 + OSPF6_HEADER_SIZE
)
2368 > ospf6_packet_max(on
->ospf6_if
)) {
2369 ospf6_fill_header(on
->ospf6_if
, (*op
)->s
,
2370 length
+ OSPF6_HEADER_SIZE
);
2371 (*op
)->length
= length
+ OSPF6_HEADER_SIZE
;
2372 ospf6_fill_lsupdate_header((*op
)->s
, *lsa_cnt
);
2373 ospf6_send_lsupdate(on
, NULL
, *op
);
2375 /* refresh packet */
2376 *op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2377 length
= OSPF6_LS_UPD_MIN_SIZE
;
2379 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
,
2380 on
->ospf6_if
, (*op
)->s
);
2381 stream_forward_endp((*op
)->s
, OSPF6_LS_UPD_MIN_SIZE
);
2383 ospf6_lsa_age_update_to_send(lsa
, on
->ospf6_if
->transdelay
);
2384 stream_put((*op
)->s
, lsa
->header
, OSPF6_LSA_SIZE(lsa
->header
));
2386 length
+= OSPF6_LSA_SIZE(lsa
->header
);
2387 assert(lsa
->lock
== 2);
2388 ospf6_lsdb_remove(lsa
, on
->lsupdate_list
);
2393 static uint16_t ospf6_make_ls_retrans_list(struct ospf6_neighbor
*on
,
2394 struct ospf6_packet
**op
,
2397 uint16_t length
= OSPF6_LS_UPD_MIN_SIZE
;
2398 struct ospf6_lsa
*lsa
, *lsanext
;
2400 /* skip over fixed header */
2401 stream_forward_endp((*op
)->s
, OSPF6_LS_UPD_MIN_SIZE
);
2403 for (ALL_LSDB(on
->retrans_list
, lsa
, lsanext
)) {
2404 if ((length
+ (unsigned int)OSPF6_LSA_SIZE(lsa
->header
)
2405 + OSPF6_HEADER_SIZE
)
2406 > ospf6_packet_max(on
->ospf6_if
)) {
2407 ospf6_fill_header(on
->ospf6_if
, (*op
)->s
,
2408 length
+ OSPF6_HEADER_SIZE
);
2409 (*op
)->length
= length
+ OSPF6_HEADER_SIZE
;
2410 ospf6_fill_lsupdate_header((*op
)->s
, *lsa_cnt
);
2411 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2412 (*op
)->dst
= allspfrouters6
;
2414 (*op
)->dst
= on
->linklocal_addr
;
2416 ospf6_packet_add(on
->ospf6_if
, *op
);
2417 OSPF6_MESSAGE_WRITE_ON(on
->ospf6_if
);
2419 /* refresh packet */
2420 *op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2421 length
= OSPF6_LS_UPD_MIN_SIZE
;
2423 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
,
2424 on
->ospf6_if
, (*op
)->s
);
2425 stream_forward_endp((*op
)->s
, OSPF6_LS_UPD_MIN_SIZE
);
2427 ospf6_lsa_age_update_to_send(lsa
, on
->ospf6_if
->transdelay
);
2428 stream_put((*op
)->s
, lsa
->header
, OSPF6_LSA_SIZE(lsa
->header
));
2430 length
+= OSPF6_LSA_SIZE(lsa
->header
);
2435 int ospf6_lsupdate_send_neighbor(struct thread
*thread
)
2437 struct ospf6_neighbor
*on
;
2438 struct ospf6_packet
*op
;
2439 uint16_t length
= OSPF6_HEADER_SIZE
;
2442 on
= (struct ospf6_neighbor
*)THREAD_ARG(thread
);
2443 on
->thread_send_lsupdate
= (struct thread
*)NULL
;
2445 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND_HDR
))
2446 zlog_debug("LSUpdate to neighbor %s", on
->name
);
2448 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
2449 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE
,
2451 zlog_debug("Quit to send (neighbor state %s)",
2452 ospf6_neighbor_state_str
[on
->state
]);
2456 /* first do lsupdate_list */
2457 op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2458 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
, on
->ospf6_if
, op
->s
);
2459 length
+= ospf6_make_lsupdate_list(on
, &op
, &lsa_cnt
);
2461 /* Fill OSPF header. */
2462 ospf6_fill_header(on
->ospf6_if
, op
->s
, length
);
2463 ospf6_fill_lsupdate_header(op
->s
, lsa_cnt
);
2464 op
->length
= length
;
2465 ospf6_send_lsupdate(on
, NULL
, op
);
2467 /* prepare new packet */
2468 op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2469 length
= OSPF6_HEADER_SIZE
;
2472 stream_reset(op
->s
);
2473 length
= OSPF6_HEADER_SIZE
;
2476 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
, on
->ospf6_if
, op
->s
);
2477 /* now do retransmit list */
2478 length
+= ospf6_make_ls_retrans_list(on
, &op
, &lsa_cnt
);
2480 ospf6_fill_header(on
->ospf6_if
, op
->s
, length
);
2481 ospf6_fill_lsupdate_header(op
->s
, lsa_cnt
);
2482 op
->length
= length
;
2483 if (on
->ospf6_if
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2484 op
->dst
= allspfrouters6
;
2486 op
->dst
= on
->linklocal_addr
;
2487 ospf6_packet_add(on
->ospf6_if
, op
);
2488 OSPF6_MESSAGE_WRITE_ON(on
->ospf6_if
);
2490 ospf6_packet_free(op
);
2492 if (on
->lsupdate_list
->count
!= 0) {
2493 on
->thread_send_lsupdate
= NULL
;
2494 thread_add_event(master
, ospf6_lsupdate_send_neighbor
, on
, 0,
2495 &on
->thread_send_lsupdate
);
2496 } else if (on
->retrans_list
->count
!= 0) {
2497 on
->thread_send_lsupdate
= NULL
;
2498 thread_add_timer(master
, ospf6_lsupdate_send_neighbor
, on
,
2499 on
->ospf6_if
->rxmt_interval
,
2500 &on
->thread_send_lsupdate
);
2505 int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor
*on
,
2506 struct ospf6_lsa
*lsa
)
2508 struct ospf6_packet
*op
;
2509 uint16_t length
= OSPF6_HEADER_SIZE
;
2511 op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2512 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
, on
->ospf6_if
, op
->s
);
2514 /* skip over fixed header */
2515 stream_forward_endp(op
->s
, OSPF6_LS_UPD_MIN_SIZE
);
2516 ospf6_lsa_age_update_to_send(lsa
, on
->ospf6_if
->transdelay
);
2517 stream_put(op
->s
, lsa
->header
, OSPF6_LSA_SIZE(lsa
->header
));
2518 length
= OSPF6_HEADER_SIZE
+ OSPF6_LS_UPD_MIN_SIZE
2519 + OSPF6_LSA_SIZE(lsa
->header
);
2520 ospf6_fill_header(on
->ospf6_if
, op
->s
, length
);
2521 ospf6_fill_lsupdate_header(op
->s
, 1);
2522 op
->length
= length
;
2524 if (IS_OSPF6_DEBUG_FLOODING
2525 || IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE
, SEND_HDR
))
2526 zlog_debug("%s: Send lsupdate with lsa %s (age %u)", __func__
,
2527 lsa
->name
, ntohs(lsa
->header
->age
));
2529 ospf6_send_lsupdate(on
, NULL
, op
);
2534 static uint16_t ospf6_make_lsupdate_interface(struct ospf6_interface
*oi
,
2535 struct ospf6_packet
**op
,
2538 uint16_t length
= OSPF6_LS_UPD_MIN_SIZE
;
2539 struct ospf6_lsa
*lsa
, *lsanext
;
2541 /* skip over fixed header */
2542 stream_forward_endp((*op
)->s
, OSPF6_LS_UPD_MIN_SIZE
);
2544 for (ALL_LSDB(oi
->lsupdate_list
, lsa
, lsanext
)) {
2545 if (length
+ (unsigned int)OSPF6_LSA_SIZE(lsa
->header
)
2547 > ospf6_packet_max(oi
)) {
2548 ospf6_fill_header(oi
, (*op
)->s
,
2549 length
+ OSPF6_HEADER_SIZE
);
2550 (*op
)->length
= length
+ OSPF6_HEADER_SIZE
;
2551 ospf6_fill_lsupdate_header((*op
)->s
, *lsa_cnt
);
2552 ospf6_send_lsupdate(NULL
, oi
, *op
);
2554 /* refresh packet */
2555 *op
= ospf6_packet_new(oi
->ifmtu
);
2556 length
= OSPF6_LS_UPD_MIN_SIZE
;
2558 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
, oi
,
2560 stream_forward_endp((*op
)->s
, OSPF6_LS_UPD_MIN_SIZE
);
2563 ospf6_lsa_age_update_to_send(lsa
, oi
->transdelay
);
2564 stream_put((*op
)->s
, lsa
->header
, OSPF6_LSA_SIZE(lsa
->header
));
2566 length
+= OSPF6_LSA_SIZE(lsa
->header
);
2568 assert(lsa
->lock
== 2);
2569 ospf6_lsdb_remove(lsa
, oi
->lsupdate_list
);
2574 int ospf6_lsupdate_send_interface(struct thread
*thread
)
2576 struct ospf6_interface
*oi
;
2577 struct ospf6_packet
*op
;
2578 uint16_t length
= OSPF6_HEADER_SIZE
;
2581 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
2582 oi
->thread_send_lsupdate
= (struct thread
*)NULL
;
2584 if (oi
->state
<= OSPF6_INTERFACE_WAITING
) {
2585 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSUPDATE
,
2588 "Quit to send LSUpdate to interface %s state %s",
2589 oi
->interface
->name
,
2590 ospf6_interface_state_str
[oi
->state
]);
2594 /* if we have nothing to send, return */
2595 if (oi
->lsupdate_list
->count
== 0)
2598 op
= ospf6_packet_new(oi
->ifmtu
);
2599 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSUPDATE
, oi
, op
->s
);
2600 length
+= ospf6_make_lsupdate_interface(oi
, &op
, &lsa_cnt
);
2602 /* Fill OSPF header. */
2603 ospf6_fill_header(oi
, op
->s
, length
);
2604 ospf6_fill_lsupdate_header(op
->s
, lsa_cnt
);
2605 op
->length
= length
;
2606 ospf6_send_lsupdate(NULL
, oi
, op
);
2608 ospf6_packet_free(op
);
2610 if (oi
->lsupdate_list
->count
> 0) {
2611 oi
->thread_send_lsupdate
= NULL
;
2612 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
2613 &oi
->thread_send_lsupdate
);
2619 int ospf6_lsack_send_neighbor(struct thread
*thread
)
2621 struct ospf6_neighbor
*on
;
2622 struct ospf6_packet
*op
;
2623 uint16_t length
= OSPF6_HEADER_SIZE
;
2625 on
= (struct ospf6_neighbor
*)THREAD_ARG(thread
);
2626 on
->thread_send_lsack
= (struct thread
*)NULL
;
2628 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
2629 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK
, SEND_HDR
))
2630 zlog_debug("Quit to send LSAck to neighbor %s state %s",
2632 ospf6_neighbor_state_str
[on
->state
]);
2636 /* if we have nothing to send, return */
2637 if (on
->lsack_list
->count
== 0)
2640 op
= ospf6_packet_new(on
->ospf6_if
->ifmtu
);
2641 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSACK
, on
->ospf6_if
, op
->s
);
2643 length
+= ospf6_make_lsack_neighbor(on
, &op
);
2645 if (length
== OSPF6_HEADER_SIZE
) {
2646 ospf6_packet_free(op
);
2650 /* Fill OSPF header. */
2651 ospf6_fill_header(on
->ospf6_if
, op
->s
, length
);
2653 /* Set packet length, dst and queue to FIFO. */
2654 op
->length
= length
;
2655 op
->dst
= on
->linklocal_addr
;
2656 ospf6_packet_add(on
->ospf6_if
, op
);
2657 OSPF6_MESSAGE_WRITE_ON(on
->ospf6_if
);
2659 if (on
->lsack_list
->count
> 0)
2660 thread_add_event(master
, ospf6_lsack_send_neighbor
, on
, 0,
2661 &on
->thread_send_lsack
);
2666 static uint16_t ospf6_make_lsack_interface(struct ospf6_interface
*oi
,
2667 struct ospf6_packet
*op
)
2669 uint16_t length
= 0;
2670 struct ospf6_lsa
*lsa
, *lsanext
;
2672 for (ALL_LSDB(oi
->lsack_list
, lsa
, lsanext
)) {
2673 if ((length
+ sizeof(struct ospf6_lsa_header
)
2674 + OSPF6_HEADER_SIZE
)
2675 > ospf6_packet_max(oi
)) {
2676 /* if we run out of packet size/space here,
2677 better to try again soon. */
2678 THREAD_OFF(oi
->thread_send_lsack
);
2679 thread_add_event(master
, ospf6_lsack_send_interface
, oi
,
2680 0, &oi
->thread_send_lsack
);
2682 ospf6_lsa_unlock(lsa
);
2684 ospf6_lsa_unlock(lsanext
);
2687 ospf6_lsa_age_update_to_send(lsa
, oi
->transdelay
);
2688 stream_put(op
->s
, lsa
->header
, sizeof(struct ospf6_lsa_header
));
2689 length
+= sizeof(struct ospf6_lsa_header
);
2691 assert(lsa
->lock
== 2);
2692 ospf6_lsdb_remove(lsa
, oi
->lsack_list
);
2697 int ospf6_lsack_send_interface(struct thread
*thread
)
2699 struct ospf6_interface
*oi
;
2700 struct ospf6_packet
*op
;
2701 uint16_t length
= OSPF6_HEADER_SIZE
;
2703 oi
= (struct ospf6_interface
*)THREAD_ARG(thread
);
2704 oi
->thread_send_lsack
= (struct thread
*)NULL
;
2706 if (oi
->state
<= OSPF6_INTERFACE_WAITING
) {
2707 if (IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_LSACK
, SEND_HDR
))
2709 "Quit to send LSAck to interface %s state %s",
2710 oi
->interface
->name
,
2711 ospf6_interface_state_str
[oi
->state
]);
2715 /* if we have nothing to send, return */
2716 if (oi
->lsack_list
->count
== 0)
2719 op
= ospf6_packet_new(oi
->ifmtu
);
2720 ospf6_make_header(OSPF6_MESSAGE_TYPE_LSACK
, oi
, op
->s
);
2722 length
+= ospf6_make_lsack_interface(oi
, op
);
2724 if (length
== OSPF6_HEADER_SIZE
) {
2725 ospf6_packet_free(op
);
2728 /* Fill OSPF header. */
2729 ospf6_fill_header(oi
, op
->s
, length
);
2731 /* Set packet length, dst and queue to FIFO. */
2732 op
->length
= length
;
2733 if ((oi
->state
== OSPF6_INTERFACE_POINTTOPOINT
)
2734 || (oi
->state
== OSPF6_INTERFACE_DR
)
2735 || (oi
->state
== OSPF6_INTERFACE_BDR
))
2736 op
->dst
= allspfrouters6
;
2738 op
->dst
= alldrouters6
;
2740 ospf6_packet_add(oi
, op
);
2741 OSPF6_MESSAGE_WRITE_ON(oi
);
2743 if (oi
->lsack_list
->count
> 0)
2744 thread_add_event(master
, ospf6_lsack_send_interface
, oi
, 0,
2745 &oi
->thread_send_lsack
);
2751 DEFUN(debug_ospf6_message
, debug_ospf6_message_cmd
,
2752 "debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv|send-hdr|recv-hdr>]",
2754 "Debug OSPFv3 message\n"
2755 "Debug Unknown message\n"
2756 "Debug Hello message\n"
2757 "Debug Database Description message\n"
2758 "Debug Link State Request message\n"
2759 "Debug Link State Update message\n"
2760 "Debug Link State Acknowledgement message\n"
2761 "Debug All message\n"
2762 "Debug only sending message, entire packet\n"
2763 "Debug only receiving message, entire packet\n"
2764 "Debug only sending message, header only\n"
2765 "Debug only receiving message, header only\n")
2768 int idx_send_recv
= 4;
2769 unsigned char level
= 0;
2774 if (!strncmp(argv
[idx_packet
]->arg
, "u", 1))
2775 type
= OSPF6_MESSAGE_TYPE_UNKNOWN
;
2776 else if (!strncmp(argv
[idx_packet
]->arg
, "h", 1))
2777 type
= OSPF6_MESSAGE_TYPE_HELLO
;
2778 else if (!strncmp(argv
[idx_packet
]->arg
, "d", 1))
2779 type
= OSPF6_MESSAGE_TYPE_DBDESC
;
2780 else if (!strncmp(argv
[idx_packet
]->arg
, "lsr", 3))
2781 type
= OSPF6_MESSAGE_TYPE_LSREQ
;
2782 else if (!strncmp(argv
[idx_packet
]->arg
, "lsu", 3))
2783 type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2784 else if (!strncmp(argv
[idx_packet
]->arg
, "lsa", 3))
2785 type
= OSPF6_MESSAGE_TYPE_LSACK
;
2786 else if (!strncmp(argv
[idx_packet
]->arg
, "a", 1))
2787 type
= OSPF6_MESSAGE_TYPE_ALL
;
2790 level
= OSPF6_DEBUG_MESSAGE_SEND
| OSPF6_DEBUG_MESSAGE_RECV
;
2791 else if (!strncmp(argv
[idx_send_recv
]->arg
, "send-h", 6))
2792 level
= OSPF6_DEBUG_MESSAGE_SEND_HDR
;
2793 else if (!strncmp(argv
[idx_send_recv
]->arg
, "s", 1))
2794 level
= OSPF6_DEBUG_MESSAGE_SEND
;
2795 else if (!strncmp(argv
[idx_send_recv
]->arg
, "recv-h", 6))
2796 level
= OSPF6_DEBUG_MESSAGE_RECV_HDR
;
2797 else if (!strncmp(argv
[idx_send_recv
]->arg
, "r", 1))
2798 level
= OSPF6_DEBUG_MESSAGE_RECV
;
2800 if (type
== OSPF6_MESSAGE_TYPE_ALL
) {
2801 for (i
= 0; i
< 6; i
++)
2802 OSPF6_DEBUG_MESSAGE_ON(i
, level
);
2804 OSPF6_DEBUG_MESSAGE_ON(type
, level
);
2809 DEFUN(no_debug_ospf6_message
, no_debug_ospf6_message_cmd
,
2810 "no debug ospf6 message <unknown|hello|dbdesc|lsreq|lsupdate|lsack|all> [<send|recv|send-hdr|recv-hdr>]",
2811 NO_STR DEBUG_STR OSPF6_STR
2812 "Debug OSPFv3 message\n"
2813 "Debug Unknown message\n"
2814 "Debug Hello message\n"
2815 "Debug Database Description message\n"
2816 "Debug Link State Request message\n"
2817 "Debug Link State Update message\n"
2818 "Debug Link State Acknowledgement message\n"
2819 "Debug All message\n"
2820 "Debug only sending message, entire pkt\n"
2821 "Debug only receiving message, entire pkt\n"
2822 "Debug only sending message, header only\n"
2823 "Debug only receiving message, header only\n")
2826 int idx_send_recv
= 5;
2827 unsigned char level
= 0;
2832 if (!strncmp(argv
[idx_packet
]->arg
, "u", 1))
2833 type
= OSPF6_MESSAGE_TYPE_UNKNOWN
;
2834 else if (!strncmp(argv
[idx_packet
]->arg
, "h", 1))
2835 type
= OSPF6_MESSAGE_TYPE_HELLO
;
2836 else if (!strncmp(argv
[idx_packet
]->arg
, "d", 1))
2837 type
= OSPF6_MESSAGE_TYPE_DBDESC
;
2838 else if (!strncmp(argv
[idx_packet
]->arg
, "lsr", 3))
2839 type
= OSPF6_MESSAGE_TYPE_LSREQ
;
2840 else if (!strncmp(argv
[idx_packet
]->arg
, "lsu", 3))
2841 type
= OSPF6_MESSAGE_TYPE_LSUPDATE
;
2842 else if (!strncmp(argv
[idx_packet
]->arg
, "lsa", 3))
2843 type
= OSPF6_MESSAGE_TYPE_LSACK
;
2844 else if (!strncmp(argv
[idx_packet
]->arg
, "a", 1))
2845 type
= OSPF6_MESSAGE_TYPE_ALL
;
2848 level
= OSPF6_DEBUG_MESSAGE_SEND
| OSPF6_DEBUG_MESSAGE_RECV
2849 | OSPF6_DEBUG_MESSAGE_SEND_HDR
2850 | OSPF6_DEBUG_MESSAGE_RECV_HDR
;
2851 else if (!strncmp(argv
[idx_send_recv
]->arg
, "send-h", 6))
2852 level
= OSPF6_DEBUG_MESSAGE_SEND_HDR
;
2853 else if (!strncmp(argv
[idx_send_recv
]->arg
, "s", 1))
2854 level
= OSPF6_DEBUG_MESSAGE_SEND
;
2855 else if (!strncmp(argv
[idx_send_recv
]->arg
, "recv-h", 6))
2856 level
= OSPF6_DEBUG_MESSAGE_RECV_HDR
;
2857 else if (!strncmp(argv
[idx_send_recv
]->arg
, "r", 1))
2858 level
= OSPF6_DEBUG_MESSAGE_RECV
;
2860 if (type
== OSPF6_MESSAGE_TYPE_ALL
) {
2861 for (i
= 0; i
< 6; i
++)
2862 OSPF6_DEBUG_MESSAGE_OFF(i
, level
);
2864 OSPF6_DEBUG_MESSAGE_OFF(type
, level
);
2870 int config_write_ospf6_debug_message(struct vty
*vty
)
2872 const char *type_str
[] = {"unknown", "hello", "dbdesc",
2873 "lsreq", "lsupdate", "lsack"};
2874 unsigned char s
= 0, r
= 0, sh
= 0, rh
= 0;
2877 for (i
= 0; i
< 6; i
++) {
2878 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, SEND
))
2880 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, RECV
))
2884 for (i
= 0; i
< 6; i
++) {
2885 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, SEND_HDR
))
2887 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, RECV_HDR
))
2891 if (s
== 0x3f && r
== 0x3f) {
2892 vty_out(vty
, "debug ospf6 message all\n");
2896 if (s
== 0x3f && r
== 0) {
2897 vty_out(vty
, "debug ospf6 message all send\n");
2899 } else if (s
== 0 && r
== 0x3f) {
2900 vty_out(vty
, "debug ospf6 message all recv\n");
2904 if (sh
== 0x3f && rh
== 0) {
2905 vty_out(vty
, "debug ospf6 message all send-hdr\n");
2907 } else if (sh
== 0 && rh
== 0x3f) {
2908 vty_out(vty
, "debug ospf6 message all recv-hdr\n");
2912 /* Unknown message is logged by default */
2913 if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN
, SEND
)
2914 && !IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
2915 vty_out(vty
, "no debug ospf6 message unknown\n");
2916 else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN
, SEND
))
2917 vty_out(vty
, "no debug ospf6 message unknown send\n");
2918 else if (!IS_OSPF6_DEBUG_MESSAGE(OSPF6_MESSAGE_TYPE_UNKNOWN
, RECV
))
2919 vty_out(vty
, "no debug ospf6 message unknown recv\n");
2921 for (i
= 1; i
< 6; i
++) {
2922 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, SEND
)
2923 && IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, RECV
)) {
2924 vty_out(vty
, "debug ospf6 message %s\n", type_str
[i
]);
2928 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, SEND
))
2929 vty_out(vty
, "debug ospf6 message %s send\n",
2931 else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, SEND_HDR
))
2932 vty_out(vty
, "debug ospf6 message %s send-hdr\n",
2935 if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, RECV
))
2936 vty_out(vty
, "debug ospf6 message %s recv\n",
2938 else if (IS_OSPF6_DEBUG_MESSAGE_ENABLED(i
, RECV_HDR
))
2939 vty_out(vty
, "debug ospf6 message %s recv-hdr\n",
2946 void install_element_ospf6_debug_message(void)
2948 install_element(ENABLE_NODE
, &debug_ospf6_message_cmd
);
2949 install_element(ENABLE_NODE
, &no_debug_ospf6_message_cmd
);
2950 install_element(CONFIG_NODE
, &debug_ospf6_message_cmd
);
2951 install_element(CONFIG_NODE
, &no_debug_ospf6_message_cmd
);