2 * OSPF Sending and Receiving OSPF Packets.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include "sockunion.h"
39 #include "ospfd/ospfd.h"
40 #include "ospfd/ospf_network.h"
41 #include "ospfd/ospf_interface.h"
42 #include "ospfd/ospf_ism.h"
43 #include "ospfd/ospf_asbr.h"
44 #include "ospfd/ospf_lsa.h"
45 #include "ospfd/ospf_lsdb.h"
46 #include "ospfd/ospf_neighbor.h"
47 #include "ospfd/ospf_nsm.h"
48 #include "ospfd/ospf_packet.h"
49 #include "ospfd/ospf_spf.h"
50 #include "ospfd/ospf_flood.h"
51 #include "ospfd/ospf_dump.h"
54 * OSPF Fragmentation / fragmented writes
56 * ospfd can support writing fragmented packets, for cases where
57 * kernel will not fragment IP_HDRINCL and/or multicast destined
58 * packets (ie TTBOMK all kernels, BSD, SunOS, Linux). However,
59 * SunOS, probably BSD too, clobber the user supplied IP ID and IP
60 * flags fields, hence user-space fragmentation will not work.
61 * Only Linux is known to leave IP header unmolested.
62 * Further, fragmentation really should be done the kernel, which already
63 * supports it, and which avoids nasty IP ID state problems.
65 * Fragmentation of OSPF packets can be required on networks with router
66 * with many many interfaces active in one area, or on networks with links
70 #define WANT_OSPF_WRITE_FRAGMENT
73 /* Packet Type String. */
74 const struct message ospf_packet_type_str
[] = {
75 {OSPF_MSG_HELLO
, "Hello"},
76 {OSPF_MSG_DB_DESC
, "Database Description"},
77 {OSPF_MSG_LS_REQ
, "Link State Request"},
78 {OSPF_MSG_LS_UPD
, "Link State Update"},
79 {OSPF_MSG_LS_ACK
, "Link State Acknowledgment"},
82 /* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of
83 particular types, offset is the "type" field of a packet. */
84 static const uint16_t ospf_packet_minlen
[] = {
87 OSPF_DB_DESC_MIN_SIZE
,
93 /* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular
94 types, offset is the "LSA type" field. */
95 static const uint16_t ospf_lsa_minlen
[] = {
97 OSPF_ROUTER_LSA_MIN_SIZE
,
98 OSPF_NETWORK_LSA_MIN_SIZE
,
99 OSPF_SUMMARY_LSA_MIN_SIZE
,
100 OSPF_SUMMARY_LSA_MIN_SIZE
,
101 OSPF_AS_EXTERNAL_LSA_MIN_SIZE
,
103 OSPF_AS_EXTERNAL_LSA_MIN_SIZE
,
110 /* for ospf_check_auth() */
111 static int ospf_check_sum(struct ospf_header
*);
113 /* OSPF authentication checking function */
114 static int ospf_auth_type(struct ospf_interface
*oi
)
118 if (OSPF_IF_PARAM(oi
, auth_type
) == OSPF_AUTH_NOTSET
)
119 auth_type
= oi
->area
->auth_type
;
121 auth_type
= OSPF_IF_PARAM(oi
, auth_type
);
123 /* Handle case where MD5 key list is not configured aka Cisco */
124 if (auth_type
== OSPF_AUTH_CRYPTOGRAPHIC
125 && list_isempty(OSPF_IF_PARAM(oi
, auth_crypt
)))
126 return OSPF_AUTH_NULL
;
131 struct ospf_packet
*ospf_packet_new(size_t size
)
133 struct ospf_packet
*new;
135 new = XCALLOC(MTYPE_OSPF_PACKET
, sizeof(struct ospf_packet
));
136 new->s
= stream_new(size
);
141 void ospf_packet_free(struct ospf_packet
*op
)
146 XFREE(MTYPE_OSPF_PACKET
, op
);
149 struct ospf_fifo
*ospf_fifo_new()
151 struct ospf_fifo
*new;
153 new = XCALLOC(MTYPE_OSPF_FIFO
, sizeof(struct ospf_fifo
));
157 /* Add new packet to fifo. */
158 void ospf_fifo_push(struct ospf_fifo
*fifo
, struct ospf_packet
*op
)
161 fifo
->tail
->next
= op
;
170 /* Add new packet to head of fifo. */
171 static void ospf_fifo_push_head(struct ospf_fifo
*fifo
, struct ospf_packet
*op
)
173 op
->next
= fifo
->head
;
175 if (fifo
->tail
== NULL
)
183 /* Delete first packet from fifo. */
184 struct ospf_packet
*ospf_fifo_pop(struct ospf_fifo
*fifo
)
186 struct ospf_packet
*op
;
191 fifo
->head
= op
->next
;
193 if (fifo
->head
== NULL
)
202 /* Return first fifo entry. */
203 struct ospf_packet
*ospf_fifo_head(struct ospf_fifo
*fifo
)
208 /* Flush ospf packet fifo. */
209 void ospf_fifo_flush(struct ospf_fifo
*fifo
)
211 struct ospf_packet
*op
;
212 struct ospf_packet
*next
;
214 for (op
= fifo
->head
; op
; op
= next
) {
216 ospf_packet_free(op
);
218 fifo
->head
= fifo
->tail
= NULL
;
222 /* Free ospf packet fifo. */
223 void ospf_fifo_free(struct ospf_fifo
*fifo
)
225 ospf_fifo_flush(fifo
);
227 XFREE(MTYPE_OSPF_FIFO
, fifo
);
230 void ospf_packet_add(struct ospf_interface
*oi
, struct ospf_packet
*op
)
234 "ospf_packet_add(interface %s in state %d [%s], packet type %s, "
235 "destination %s) called with NULL obuf, ignoring "
236 "(please report this bug)!\n",
237 IF_NAME(oi
), oi
->state
,
238 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
),
239 lookup_msg(ospf_packet_type_str
,
240 stream_getc_from(op
->s
, 1), NULL
),
245 /* Add packet to end of queue. */
246 ospf_fifo_push(oi
->obuf
, op
);
248 /* Debug of packet fifo*/
249 /* ospf_fifo_debug (oi->obuf); */
252 static void ospf_packet_add_top(struct ospf_interface
*oi
,
253 struct ospf_packet
*op
)
257 "ospf_packet_add(interface %s in state %d [%s], packet type %s, "
258 "destination %s) called with NULL obuf, ignoring "
259 "(please report this bug)!\n",
260 IF_NAME(oi
), oi
->state
,
261 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
),
262 lookup_msg(ospf_packet_type_str
,
263 stream_getc_from(op
->s
, 1), NULL
),
268 /* Add packet to head of queue. */
269 ospf_fifo_push_head(oi
->obuf
, op
);
271 /* Debug of packet fifo*/
272 /* ospf_fifo_debug (oi->obuf); */
275 void ospf_packet_delete(struct ospf_interface
*oi
)
277 struct ospf_packet
*op
;
279 op
= ospf_fifo_pop(oi
->obuf
);
282 ospf_packet_free(op
);
285 struct ospf_packet
*ospf_packet_dup(struct ospf_packet
*op
)
287 struct ospf_packet
*new;
289 if (stream_get_endp(op
->s
) != op
->length
)
292 "ospf_packet_dup stream %lu ospf_packet %u size mismatch",
293 (unsigned long)STREAM_SIZE(op
->s
), op
->length
);
295 /* Reserve space for MD5 authentication that may be added later. */
296 new = ospf_packet_new(stream_get_endp(op
->s
) + OSPF_AUTH_MD5_SIZE
);
297 stream_copy(new->s
, op
->s
);
300 new->length
= op
->length
;
306 static unsigned int ospf_packet_authspace(struct ospf_interface
*oi
)
310 if (ospf_auth_type(oi
) == OSPF_AUTH_CRYPTOGRAPHIC
)
311 auth
= OSPF_AUTH_MD5_SIZE
;
316 static unsigned int ospf_packet_max(struct ospf_interface
*oi
)
320 max
= oi
->ifp
->mtu
- ospf_packet_authspace(oi
);
322 max
-= (OSPF_HEADER_SIZE
+ sizeof(struct ip
));
328 static int ospf_check_md5_digest(struct ospf_interface
*oi
,
329 struct ospf_header
*ospfh
)
332 unsigned char digest
[OSPF_AUTH_MD5_SIZE
];
333 struct crypt_key
*ck
;
334 struct ospf_neighbor
*nbr
;
335 uint16_t length
= ntohs(ospfh
->length
);
337 /* Get secret key. */
338 ck
= ospf_crypt_key_lookup(OSPF_IF_PARAM(oi
, auth_crypt
),
339 ospfh
->u
.crypt
.key_id
);
341 zlog_warn("interface %s: ospf_check_md5 no key %d", IF_NAME(oi
),
342 ospfh
->u
.crypt
.key_id
);
346 /* check crypto seqnum. */
347 nbr
= ospf_nbr_lookup_by_routerid(oi
->nbrs
, &ospfh
->router_id
);
350 && ntohl(nbr
->crypt_seqnum
) > ntohl(ospfh
->u
.crypt
.crypt_seqnum
)) {
352 "interface %s: ospf_check_md5 bad sequence %d (expect %d)",
353 IF_NAME(oi
), ntohl(ospfh
->u
.crypt
.crypt_seqnum
),
354 ntohl(nbr
->crypt_seqnum
));
358 /* Generate a digest for the ospf packet - their digest + our digest. */
359 memset(&ctx
, 0, sizeof(ctx
));
361 MD5Update(&ctx
, ospfh
, length
);
362 MD5Update(&ctx
, ck
->auth_key
, OSPF_AUTH_MD5_SIZE
);
363 MD5Final(digest
, &ctx
);
365 /* compare the two */
366 if (memcmp((caddr_t
)ospfh
+ length
, digest
, OSPF_AUTH_MD5_SIZE
)) {
367 zlog_warn("interface %s: ospf_check_md5 checksum mismatch",
372 /* save neighbor's crypt_seqnum */
374 nbr
->crypt_seqnum
= ospfh
->u
.crypt
.crypt_seqnum
;
378 /* This function is called from ospf_write(), it will detect the
379 authentication scheme and if it is MD5, it will change the sequence
380 and update the MD5 digest. */
381 static int ospf_make_md5_digest(struct ospf_interface
*oi
,
382 struct ospf_packet
*op
)
384 struct ospf_header
*ospfh
;
385 unsigned char digest
[OSPF_AUTH_MD5_SIZE
] = {0};
389 struct crypt_key
*ck
;
390 const uint8_t *auth_key
;
392 ibuf
= STREAM_DATA(op
->s
);
393 ospfh
= (struct ospf_header
*)ibuf
;
395 if (ntohs(ospfh
->auth_type
) != OSPF_AUTH_CRYPTOGRAPHIC
)
398 /* We do this here so when we dup a packet, we don't have to
399 waste CPU rewriting other headers.
401 Note that quagga_time /deliberately/ is not used here */
402 t
= (time(NULL
) & 0xFFFFFFFF);
403 if (t
> oi
->crypt_seqnum
)
404 oi
->crypt_seqnum
= t
;
408 ospfh
->u
.crypt
.crypt_seqnum
= htonl(oi
->crypt_seqnum
);
410 /* Get MD5 Authentication key from auth_key list. */
411 if (list_isempty(OSPF_IF_PARAM(oi
, auth_crypt
)))
412 auth_key
= (const uint8_t *)digest
;
414 ck
= listgetdata(listtail(OSPF_IF_PARAM(oi
, auth_crypt
)));
415 auth_key
= ck
->auth_key
;
418 /* Generate a digest for the entire packet + our secret key. */
419 memset(&ctx
, 0, sizeof(ctx
));
421 MD5Update(&ctx
, ibuf
, ntohs(ospfh
->length
));
422 MD5Update(&ctx
, auth_key
, OSPF_AUTH_MD5_SIZE
);
423 MD5Final(digest
, &ctx
);
425 /* Append md5 digest to the end of the stream. */
426 stream_put(op
->s
, digest
, OSPF_AUTH_MD5_SIZE
);
428 /* We do *NOT* increment the OSPF header length. */
429 op
->length
= ntohs(ospfh
->length
) + OSPF_AUTH_MD5_SIZE
;
431 if (stream_get_endp(op
->s
) != op
->length
)
434 "ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
435 (unsigned long)stream_get_endp(op
->s
), op
->length
);
437 return OSPF_AUTH_MD5_SIZE
;
441 static int ospf_ls_req_timer(struct thread
*thread
)
443 struct ospf_neighbor
*nbr
;
445 nbr
= THREAD_ARG(thread
);
446 nbr
->t_ls_req
= NULL
;
448 /* Send Link State Request. */
449 if (ospf_ls_request_count(nbr
))
450 ospf_ls_req_send(nbr
);
452 /* Set Link State Request retransmission timer. */
453 OSPF_NSM_TIMER_ON(nbr
->t_ls_req
, ospf_ls_req_timer
, nbr
->v_ls_req
);
458 void ospf_ls_req_event(struct ospf_neighbor
*nbr
)
461 thread_cancel(nbr
->t_ls_req
);
462 nbr
->t_ls_req
= NULL
;
464 nbr
->t_ls_req
= NULL
;
465 thread_add_event(master
, ospf_ls_req_timer
, nbr
, 0, &nbr
->t_ls_req
);
468 /* Cyclic timer function. Fist registered in ospf_nbr_new () in
470 int ospf_ls_upd_timer(struct thread
*thread
)
472 struct ospf_neighbor
*nbr
;
474 nbr
= THREAD_ARG(thread
);
475 nbr
->t_ls_upd
= NULL
;
477 /* Send Link State Update. */
478 if (ospf_ls_retransmit_count(nbr
) > 0) {
480 struct ospf_lsdb
*lsdb
;
482 int retransmit_interval
;
484 retransmit_interval
=
485 OSPF_IF_PARAM(nbr
->oi
, retransmit_interval
);
487 lsdb
= &nbr
->ls_rxmt
;
490 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++) {
491 struct route_table
*table
= lsdb
->type
[i
].db
;
492 struct route_node
*rn
;
494 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
495 struct ospf_lsa
*lsa
;
497 if ((lsa
= rn
->info
) != NULL
) {
498 /* Don't retransmit an LSA if we
500 the last RxmtInterval seconds - this
502 neighbour a chance to acknowledge the
504 have ben just received before the
506 fired. This is a small tweak to what
508 but it will cut out out a lot of
511 if (monotime_since(&lsa
->tv_recv
, NULL
)
512 >= retransmit_interval
* 1000000LL)
513 listnode_add(update
, rn
->info
);
518 if (listcount(update
) > 0)
519 ospf_ls_upd_send(nbr
, update
, OSPF_SEND_PACKET_DIRECT
,
521 list_delete_and_null(&update
);
524 /* Set LS Update retransmission timer. */
525 OSPF_NSM_TIMER_ON(nbr
->t_ls_upd
, ospf_ls_upd_timer
, nbr
->v_ls_upd
);
530 int ospf_ls_ack_timer(struct thread
*thread
)
532 struct ospf_interface
*oi
;
534 oi
= THREAD_ARG(thread
);
537 /* Send Link State Acknowledgment. */
538 if (listcount(oi
->ls_ack
) > 0)
539 ospf_ls_ack_send_delayed(oi
);
541 /* Set LS Ack timer. */
542 OSPF_ISM_TIMER_ON(oi
->t_ls_ack
, ospf_ls_ack_timer
, oi
->v_ls_ack
);
547 #ifdef WANT_OSPF_WRITE_FRAGMENT
548 static void ospf_write_frags(int fd
, struct ospf_packet
*op
, struct ip
*iph
,
549 struct msghdr
*msg
, unsigned int maxdatasize
,
550 unsigned int mtu
, int flags
, uint8_t type
)
552 #define OSPF_WRITE_FRAG_SHIFT 3
557 assert(op
->length
== stream_get_endp(op
->s
));
558 assert(msg
->msg_iovlen
== 2);
562 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
563 * well as the IP_MF flag, making this all quite pointless.
565 * However, for a system on which IP_MF is left alone, and ip_id left
566 * alone or else which sets same ip_id for each fragment this might
569 * XXX-TODO: It would be much nicer to have the kernel's use their
570 * existing fragmentation support to do this for us. Bugs/RFEs need to
571 * be raised against the various kernels.
575 iph
->ip_off
|= IP_MF
;
577 /* ip frag offset is expressed in units of 8byte words */
578 offset
= maxdatasize
>> OSPF_WRITE_FRAG_SHIFT
;
580 iovp
= &msg
->msg_iov
[1];
582 while ((stream_get_endp(op
->s
) - stream_get_getp(op
->s
))
584 /* data length of this frag is to next offset value */
585 iovp
->iov_len
= offset
<< OSPF_WRITE_FRAG_SHIFT
;
586 iph
->ip_len
= iovp
->iov_len
+ sizeof(struct ip
);
587 assert(iph
->ip_len
<= mtu
);
589 sockopt_iphdrincl_swab_htosys(iph
);
591 ret
= sendmsg(fd
, msg
, flags
);
593 sockopt_iphdrincl_swab_systoh(iph
);
597 "*** ospf_write_frags: sendmsg failed to %s,"
598 " id %d, off %d, len %d, mtu %u failed with %s",
599 inet_ntoa(iph
->ip_dst
), iph
->ip_id
, iph
->ip_off
,
600 iph
->ip_len
, mtu
, safe_strerror(errno
));
602 if (IS_DEBUG_OSPF_PACKET(type
- 1, SEND
)) {
604 "ospf_write_frags: sent id %d, off %d, len %d to %s\n",
605 iph
->ip_id
, iph
->ip_off
, iph
->ip_len
,
606 inet_ntoa(iph
->ip_dst
));
607 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
)) {
609 "-----------------IP Header Dump----------------------");
610 ospf_ip_header_dump(iph
);
612 "-----------------------------------------------------");
616 iph
->ip_off
+= offset
;
617 stream_forward_getp(op
->s
, iovp
->iov_len
);
618 iovp
->iov_base
= stream_pnt(op
->s
);
621 /* setup for final fragment */
622 iovp
->iov_len
= stream_get_endp(op
->s
) - stream_get_getp(op
->s
);
623 iph
->ip_len
= iovp
->iov_len
+ sizeof(struct ip
);
624 iph
->ip_off
&= (~IP_MF
);
626 #endif /* WANT_OSPF_WRITE_FRAGMENT */
628 static int ospf_write(struct thread
*thread
)
630 struct ospf
*ospf
= THREAD_ARG(thread
);
631 struct ospf_interface
*oi
;
632 struct ospf_interface
*last_serviced_oi
= NULL
;
633 struct ospf_packet
*op
;
634 struct sockaddr_in sa_dst
;
641 struct listnode
*node
;
642 #ifdef WANT_OSPF_WRITE_FRAGMENT
643 static uint16_t ipid
= 0;
644 uint16_t maxdatasize
;
645 #endif /* WANT_OSPF_WRITE_FRAGMENT */
646 #define OSPF_WRITE_IPHL_SHIFT 2
650 unsigned char cmsgbuf
[64] = {};
651 struct cmsghdr
*cm
= (struct cmsghdr
*)cmsgbuf
;
652 struct in_pktinfo
*pi
;
655 ospf
->t_write
= NULL
;
657 node
= listhead(ospf
->oi_write_q
);
659 oi
= listgetdata(node
);
662 #ifdef WANT_OSPF_WRITE_FRAGMENT
663 /* seed ipid static with low order bits of time */
665 ipid
= (time(NULL
) & 0xffff);
666 #endif /* WANT_OSPF_WRITE_FRAGMENT */
668 while ((pkt_count
< ospf
->write_oi_count
) && oi
669 && (last_serviced_oi
!= oi
)) {
670 /* If there is only packet in the queue, the oi is removed from
671 write-q, so fix up the last interface that was serviced */
672 if (last_serviced_oi
== NULL
) {
673 last_serviced_oi
= oi
;
676 #ifdef WANT_OSPF_WRITE_FRAGMENT
677 /* convenience - max OSPF data per packet */
678 maxdatasize
= oi
->ifp
->mtu
- sizeof(struct ip
);
679 #endif /* WANT_OSPF_WRITE_FRAGMENT */
680 /* Get one packet from queue. */
681 op
= ospf_fifo_head(oi
->obuf
);
683 assert(op
->length
>= OSPF_HEADER_SIZE
);
685 if (op
->dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
)
686 || op
->dst
.s_addr
== htonl(OSPF_ALLDROUTERS
))
687 ospf_if_ipmulticast(ospf
, oi
->address
,
690 /* Rewrite the md5 signature & update the seq */
691 ospf_make_md5_digest(oi
, op
);
693 /* Retrieve OSPF packet type. */
694 stream_set_getp(op
->s
, 1);
695 type
= stream_getc(op
->s
);
697 /* reset get pointer */
698 stream_set_getp(op
->s
, 0);
700 memset(&iph
, 0, sizeof(struct ip
));
701 memset(&sa_dst
, 0, sizeof(sa_dst
));
703 sa_dst
.sin_family
= AF_INET
;
704 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
705 sa_dst
.sin_len
= sizeof(sa_dst
);
706 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
707 sa_dst
.sin_addr
= op
->dst
;
708 sa_dst
.sin_port
= htons(0);
710 /* Set DONTROUTE flag if dst is unicast. */
711 if (oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
712 if (!IN_MULTICAST(htonl(op
->dst
.s_addr
)))
713 flags
= MSG_DONTROUTE
;
715 iph
.ip_hl
= sizeof(struct ip
) >> OSPF_WRITE_IPHL_SHIFT
;
716 /* it'd be very strange for header to not be 4byte-word aligned
718 if (sizeof(struct ip
)
719 > (unsigned int)(iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
))
720 iph
.ip_hl
++; /* we presume sizeof struct ip cant
723 iph
.ip_v
= IPVERSION
;
724 iph
.ip_tos
= IPTOS_PREC_INTERNETCONTROL
;
725 iph
.ip_len
= (iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
) + op
->length
;
727 #if defined(__DragonFly__)
729 * DragonFly's raw socket expects ip_len/ip_off in network byte
732 iph
.ip_len
= htons(iph
.ip_len
);
735 #ifdef WANT_OSPF_WRITE_FRAGMENT
736 /* XXX-MT: not thread-safe at all..
737 * XXX: this presumes this is only programme sending OSPF
739 * otherwise, no guarantee ipid will be unique
742 #endif /* WANT_OSPF_WRITE_FRAGMENT */
745 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
746 iph
.ip_ttl
= OSPF_VL_IP_TTL
;
748 iph
.ip_ttl
= OSPF_IP_TTL
;
749 iph
.ip_p
= IPPROTO_OSPFIGP
;
751 iph
.ip_src
.s_addr
= oi
->address
->u
.prefix4
.s_addr
;
752 iph
.ip_dst
.s_addr
= op
->dst
.s_addr
;
754 memset(&msg
, 0, sizeof(msg
));
755 msg
.msg_name
= (caddr_t
)&sa_dst
;
756 msg
.msg_namelen
= sizeof(sa_dst
);
760 iov
[0].iov_base
= (char *)&iph
;
761 iov
[0].iov_len
= iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
;
762 iov
[1].iov_base
= stream_pnt(op
->s
);
763 iov
[1].iov_len
= op
->length
;
766 msg
.msg_control
= (caddr_t
)cm
;
767 cm
->cmsg_level
= SOL_IP
;
768 cm
->cmsg_type
= IP_PKTINFO
;
769 cm
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
770 pi
= (struct in_pktinfo
*)CMSG_DATA(cm
);
771 pi
->ipi_ifindex
= oi
->ifp
->ifindex
;
773 msg
.msg_controllen
= cm
->cmsg_len
;
776 /* Sadly we can not rely on kernels to fragment packets
777 * because of either IP_HDRINCL and/or multicast
778 * destination being set.
781 #ifdef WANT_OSPF_WRITE_FRAGMENT
782 if (op
->length
> maxdatasize
)
783 ospf_write_frags(ospf
->fd
, op
, &iph
, &msg
, maxdatasize
,
784 oi
->ifp
->mtu
, flags
, type
);
785 #endif /* WANT_OSPF_WRITE_FRAGMENT */
787 /* send final fragment (could be first) */
788 sockopt_iphdrincl_swab_htosys(&iph
);
789 ret
= sendmsg(ospf
->fd
, &msg
, flags
);
790 sockopt_iphdrincl_swab_systoh(&iph
);
791 if (IS_DEBUG_OSPF_EVENT
)
794 "id %d, off %d, len %d, interface %s, mtu %u:",
795 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
,
796 iph
.ip_len
, oi
->ifp
->name
, oi
->ifp
->mtu
);
800 "*** sendmsg in ospf_write failed to %s, "
801 "id %d, off %d, len %d, interface %s, mtu %u: %s",
802 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
,
803 iph
.ip_len
, oi
->ifp
->name
, oi
->ifp
->mtu
,
804 safe_strerror(errno
));
806 /* Show debug sending packet. */
807 if (IS_DEBUG_OSPF_PACKET(type
- 1, SEND
)) {
808 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
)) {
810 "-----------------------------------------------------");
811 ospf_ip_header_dump(&iph
);
812 stream_set_getp(op
->s
, 0);
813 ospf_packet_dump(op
->s
);
816 zlog_debug("%s sent to [%s] via [%s].",
817 lookup_msg(ospf_packet_type_str
, type
, NULL
),
818 inet_ntoa(op
->dst
), IF_NAME(oi
));
820 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
))
822 "-----------------------------------------------------");
829 case OSPF_MSG_DB_DESC
:
832 case OSPF_MSG_LS_REQ
:
835 case OSPF_MSG_LS_UPD
:
838 case OSPF_MSG_LS_ACK
:
845 /* Now delete packet from queue. */
846 ospf_packet_delete(oi
);
848 /* Move this interface to the tail of write_q to
849 serve everyone in a round robin fashion */
850 list_delete_node(ospf
->oi_write_q
, node
);
851 if (ospf_fifo_head(oi
->obuf
) == NULL
) {
853 last_serviced_oi
= NULL
;
856 listnode_add(ospf
->oi_write_q
, oi
);
859 /* Setup to service from the head of the queue again */
860 if (!list_isempty(ospf
->oi_write_q
)) {
861 node
= listhead(ospf
->oi_write_q
);
863 oi
= listgetdata(node
);
868 /* If packets still remain in queue, call write thread. */
869 if (!list_isempty(ospf
->oi_write_q
)) {
870 ospf
->t_write
= NULL
;
871 thread_add_write(master
, ospf_write
, ospf
, ospf
->fd
,
878 /* OSPF Hello message read -- RFC2328 Section 10.5. */
879 static void ospf_hello(struct ip
*iph
, struct ospf_header
*ospfh
,
880 struct stream
*s
, struct ospf_interface
*oi
, int size
)
882 struct ospf_hello
*hello
;
883 struct ospf_neighbor
*nbr
;
887 /* increment statistics. */
890 hello
= (struct ospf_hello
*)stream_pnt(s
);
892 /* If Hello is myself, silently discard. */
893 if (IPV4_ADDR_SAME(&ospfh
->router_id
, &oi
->ospf
->router_id
)) {
894 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
)) {
896 "ospf_header[%s/%s]: selforiginated, "
898 lookup_msg(ospf_packet_type_str
, ospfh
->type
,
900 inet_ntoa(iph
->ip_src
));
905 /* get neighbor prefix. */
907 p
.prefixlen
= ip_masklen(hello
->network_mask
);
908 p
.u
.prefix4
= iph
->ip_src
;
910 /* Compare network mask. */
911 /* Checking is ignored for Point-to-Point and Virtual link. */
912 if (oi
->type
!= OSPF_IFTYPE_POINTOPOINT
913 && oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
914 if (oi
->address
->prefixlen
!= p
.prefixlen
) {
916 "Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
917 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
),
918 (int)oi
->address
->prefixlen
, (int)p
.prefixlen
);
922 /* Compare Router Dead Interval. */
923 if (OSPF_IF_PARAM(oi
, v_wait
) != ntohl(hello
->dead_interval
)) {
925 "Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
926 "(expected %u, but received %u).",
927 inet_ntoa(ospfh
->router_id
), OSPF_IF_PARAM(oi
, v_wait
),
928 ntohl(hello
->dead_interval
));
932 /* Compare Hello Interval - ignored if fast-hellos are set. */
933 if (OSPF_IF_PARAM(oi
, fast_hello
) == 0) {
934 if (OSPF_IF_PARAM(oi
, v_hello
)
935 != ntohs(hello
->hello_interval
)) {
937 "Packet %s [Hello:RECV]: HelloInterval mismatch "
938 "(expected %u, but received %u).",
939 inet_ntoa(ospfh
->router_id
),
940 OSPF_IF_PARAM(oi
, v_hello
),
941 ntohs(hello
->hello_interval
));
946 if (IS_DEBUG_OSPF_EVENT
)
947 zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
948 inet_ntoa(ospfh
->router_id
),
949 ospf_options_dump(hello
->options
),
950 ospf_vrf_id_to_name(oi
->ospf
->vrf_id
));
952 /* Compare options. */
953 #define REJECT_IF_TBIT_ON 1 /* XXX */
954 #ifdef REJECT_IF_TBIT_ON
955 if (CHECK_FLAG(hello
->options
, OSPF_OPTION_MT
)) {
957 * This router does not support non-zero TOS.
958 * Drop this Hello packet not to establish neighbor
961 zlog_warn("Packet %s [Hello:RECV]: T-bit on, drop it.",
962 inet_ntoa(ospfh
->router_id
));
965 #endif /* REJECT_IF_TBIT_ON */
967 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)
968 && CHECK_FLAG(hello
->options
, OSPF_OPTION_O
)) {
970 * This router does know the correct usage of O-bit
971 * the bit should be set in DD packet only.
973 zlog_warn("Packet %s [Hello:RECV]: O-bit abuse?",
974 inet_ntoa(ospfh
->router_id
));
975 #ifdef STRICT_OBIT_USAGE_CHECK
976 return; /* Reject this packet. */
977 #else /* STRICT_OBIT_USAGE_CHECK */
978 UNSET_FLAG(hello
->options
, OSPF_OPTION_O
); /* Ignore O-bit. */
979 #endif /* STRICT_OBIT_USAGE_CHECK */
982 /* new for NSSA is to ensure that NP is on and E is off */
984 if (oi
->area
->external_routing
== OSPF_AREA_NSSA
) {
985 if (!(CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_NP
)
986 && CHECK_FLAG(hello
->options
, OSPF_OPTION_NP
)
987 && !CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_E
)
988 && !CHECK_FLAG(hello
->options
, OSPF_OPTION_E
))) {
990 "NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x",
991 inet_ntoa(ospfh
->router_id
), OPTIONS(oi
),
995 if (IS_DEBUG_OSPF_NSSA
)
996 zlog_debug("NSSA-Hello:RECV:Packet from %s:",
997 inet_ntoa(ospfh
->router_id
));
999 /* The setting of the E-bit found in the Hello Packet's Options
1000 field must match this area's ExternalRoutingCapability A
1001 mismatch causes processing to stop and the packet to be
1002 dropped. The setting of the rest of the bits in the Hello
1003 Packet's Options field should be ignored. */
1004 if (CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_E
)
1005 != CHECK_FLAG(hello
->options
, OSPF_OPTION_E
)) {
1007 "Packet %s [Hello:RECV]: my options: %x, his options %x",
1008 inet_ntoa(ospfh
->router_id
), OPTIONS(oi
),
1013 /* get neighbour struct */
1014 nbr
= ospf_nbr_get(oi
, ospfh
, iph
, &p
);
1016 /* neighbour must be valid, ospf_nbr_get creates if none existed */
1019 old_state
= nbr
->state
;
1021 /* Add event to thread. */
1022 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1024 /* RFC2328 Section 9.5.1
1025 If the router is not eligible to become Designated Router,
1026 (snip) It must also send an Hello Packet in reply to an
1027 Hello Packet received from any eligible neighbor (other than
1028 the current Designated Router and Backup Designated Router). */
1029 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1030 if (PRIORITY(oi
) == 0 && hello
->priority
> 0
1031 && IPV4_ADDR_CMP(&DR(oi
), &iph
->ip_src
)
1032 && IPV4_ADDR_CMP(&BDR(oi
), &iph
->ip_src
))
1033 OSPF_NSM_TIMER_ON(nbr
->t_hello_reply
,
1034 ospf_hello_reply_timer
,
1035 OSPF_HELLO_REPLY_DELAY
);
1037 /* on NBMA network type, it happens to receive bidirectional Hello
1039 without advance 1-Way Received event.
1040 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
1041 if (oi
->type
== OSPF_IFTYPE_NBMA
1042 && (old_state
== NSM_Down
|| old_state
== NSM_Attempt
)) {
1043 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_OneWayReceived
);
1044 nbr
->priority
= hello
->priority
;
1045 nbr
->d_router
= hello
->d_router
;
1046 nbr
->bd_router
= hello
->bd_router
;
1050 if (ospf_nbr_bidirectional(&oi
->ospf
->router_id
, hello
->neighbors
,
1051 size
- OSPF_HELLO_MIN_SIZE
)) {
1052 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_TwoWayReceived
);
1053 nbr
->options
|= hello
->options
;
1055 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_OneWayReceived
);
1056 /* Set neighbor information. */
1057 nbr
->priority
= hello
->priority
;
1058 nbr
->d_router
= hello
->d_router
;
1059 nbr
->bd_router
= hello
->bd_router
;
1063 /* If neighbor itself declares DR and no BDR exists,
1064 cause event BackupSeen */
1065 if (IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->d_router
))
1066 if (hello
->bd_router
.s_addr
== 0 && oi
->state
== ISM_Waiting
)
1067 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_BackupSeen
);
1069 /* neighbor itself declares BDR. */
1070 if (oi
->state
== ISM_Waiting
1071 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->bd_router
))
1072 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_BackupSeen
);
1074 /* had not previously. */
1075 if ((IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->d_router
)
1076 && IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &nbr
->d_router
))
1077 || (IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &hello
->d_router
)
1078 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &nbr
->d_router
)))
1079 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1081 /* had not previously. */
1082 if ((IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->bd_router
)
1083 && IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &nbr
->bd_router
))
1084 || (IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &hello
->bd_router
)
1085 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &nbr
->bd_router
)))
1086 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1088 /* Neighbor priority check. */
1089 if (nbr
->priority
>= 0 && nbr
->priority
!= hello
->priority
)
1090 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1092 /* Set neighbor information. */
1093 nbr
->priority
= hello
->priority
;
1094 nbr
->d_router
= hello
->d_router
;
1095 nbr
->bd_router
= hello
->bd_router
;
1098 /* Save DD flags/options/Seqnum received. */
1099 static void ospf_db_desc_save_current(struct ospf_neighbor
*nbr
,
1100 struct ospf_db_desc
*dd
)
1102 nbr
->last_recv
.flags
= dd
->flags
;
1103 nbr
->last_recv
.options
= dd
->options
;
1104 nbr
->last_recv
.dd_seqnum
= ntohl(dd
->dd_seqnum
);
1107 /* Process rest of DD packet. */
1108 static void ospf_db_desc_proc(struct stream
*s
, struct ospf_interface
*oi
,
1109 struct ospf_neighbor
*nbr
,
1110 struct ospf_db_desc
*dd
, uint16_t size
)
1112 struct ospf_lsa
*new, *find
;
1113 struct lsa_header
*lsah
;
1115 stream_forward_getp(s
, OSPF_DB_DESC_MIN_SIZE
);
1116 for (size
-= OSPF_DB_DESC_MIN_SIZE
; size
>= OSPF_LSA_HEADER_SIZE
;
1117 size
-= OSPF_LSA_HEADER_SIZE
) {
1118 lsah
= (struct lsa_header
*)stream_pnt(s
);
1119 stream_forward_getp(s
, OSPF_LSA_HEADER_SIZE
);
1121 /* Unknown LS type. */
1122 if (lsah
->type
< OSPF_MIN_LSA
|| lsah
->type
>= OSPF_MAX_LSA
) {
1123 zlog_warn("Packet [DD:RECV]: Unknown LS type %d.",
1125 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1129 if (IS_OPAQUE_LSA(lsah
->type
)
1130 && !CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)) {
1131 zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
1132 lsah
->type
, inet_ntoa(lsah
->id
));
1133 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1137 switch (lsah
->type
) {
1138 case OSPF_AS_EXTERNAL_LSA
:
1139 case OSPF_OPAQUE_AS_LSA
:
1140 /* Check for stub area. Reject if AS-External from stub
1142 allow if from NSSA. */
1143 if (oi
->area
->external_routing
== OSPF_AREA_STUB
) {
1145 "Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1146 lsah
->type
, inet_ntoa(lsah
->id
),
1147 (oi
->area
->external_routing
1151 OSPF_NSM_EVENT_SCHEDULE(nbr
,
1152 NSM_SeqNumberMismatch
);
1160 /* Create LS-request object. */
1161 new = ospf_ls_request_new(lsah
);
1163 /* Lookup received LSA, then add LS request list. */
1164 find
= ospf_lsa_lookup_by_header(oi
->area
, lsah
);
1166 /* ospf_lsa_more_recent is fine with NULL pointers */
1167 switch (ospf_lsa_more_recent(find
, new)) {
1169 /* Neighbour has a more recent LSA, we must request it
1171 ospf_ls_request_add(nbr
, new);
1174 /* If we have a copy of this LSA, it's either less
1176 * and we're requesting it from neighbour (the case
1178 * it's as recent and we both have same copy (this
1181 * In neither of these two cases is there any point in
1182 * describing our copy of the LSA to the neighbour in a
1183 * DB-Summary packet, if we're still intending to do so.
1185 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1186 * backward compatible optimisation to OSPF DB Exchange
1188 * DB Description process implemented here.
1191 ospf_lsdb_delete(&nbr
->db_sum
, find
);
1192 ospf_lsa_discard(new);
1195 /* We have the more recent copy, nothing specific to do:
1196 * - no need to request neighbours stale copy
1197 * - must leave DB summary list copy alone
1199 if (IS_DEBUG_OSPF_EVENT
)
1201 "Packet [DD:RECV]: LSA received Type %d, "
1202 "ID %s is not recent.",
1203 lsah
->type
, inet_ntoa(lsah
->id
));
1204 ospf_lsa_discard(new);
1209 if (IS_SET_DD_MS(nbr
->dd_flags
)) {
1212 /* Both sides have no More, then we're done with Exchange */
1213 if (!IS_SET_DD_M(dd
->flags
) && !IS_SET_DD_M(nbr
->dd_flags
))
1214 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_ExchangeDone
);
1216 ospf_db_desc_send(nbr
);
1220 nbr
->dd_seqnum
= ntohl(dd
->dd_seqnum
);
1222 /* Send DD packet in reply.
1224 * Must be done to acknowledge the Master's DD, regardless of
1225 * whether we have more LSAs ourselves to describe.
1227 * This function will clear the 'More' bit, if after this DD
1228 * we have no more LSAs to describe to the master..
1230 ospf_db_desc_send(nbr
);
1232 /* Slave can raise ExchangeDone now, if master is also done */
1233 if (!IS_SET_DD_M(dd
->flags
) && !IS_SET_DD_M(nbr
->dd_flags
))
1234 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_ExchangeDone
);
1237 /* Save received neighbor values from DD. */
1238 ospf_db_desc_save_current(nbr
, dd
);
1241 ospf_ls_req_send(nbr
);
1244 static int ospf_db_desc_is_dup(struct ospf_db_desc
*dd
,
1245 struct ospf_neighbor
*nbr
)
1247 /* Is DD duplicated? */
1248 if (dd
->options
== nbr
->last_recv
.options
1249 && dd
->flags
== nbr
->last_recv
.flags
1250 && dd
->dd_seqnum
== htonl(nbr
->last_recv
.dd_seqnum
))
1256 /* OSPF Database Description message read -- RFC2328 Section 10.6. */
1257 static void ospf_db_desc(struct ip
*iph
, struct ospf_header
*ospfh
,
1258 struct stream
*s
, struct ospf_interface
*oi
,
1261 struct ospf_db_desc
*dd
;
1262 struct ospf_neighbor
*nbr
;
1264 /* Increment statistics. */
1267 dd
= (struct ospf_db_desc
*)stream_pnt(s
);
1269 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1271 zlog_warn("Packet[DD]: Unknown Neighbor %s",
1272 inet_ntoa(ospfh
->router_id
));
1277 if ((OSPF_IF_PARAM(oi
, mtu_ignore
) == 0)
1278 && (ntohs(dd
->mtu
) > oi
->ifp
->mtu
)) {
1280 "Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1281 inet_ntoa(nbr
->router_id
), ntohs(dd
->mtu
), IF_NAME(oi
),
1287 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is
1289 * required. In fact at least JunOS sends DD packets with P bit clear.
1290 * Until proper solution is developped, this hack should help.
1292 * Update: According to the RFCs, N bit is specified /only/ for Hello
1293 * options, unfortunately its use in DD options is not specified. Hence
1295 * implementations follow E-bit semantics and set it in DD options, and
1297 * treat it as unspecified and hence follow the directive "default for
1298 * options is clear", ie unset.
1300 * Reset the flag, as ospfd follows E-bit semantics.
1302 if ((oi
->area
->external_routing
== OSPF_AREA_NSSA
)
1303 && (CHECK_FLAG(nbr
->options
, OSPF_OPTION_NP
))
1304 && (!CHECK_FLAG(dd
->options
, OSPF_OPTION_NP
))) {
1305 if (IS_DEBUG_OSPF_EVENT
)
1307 "Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
1308 inet_ntoa(nbr
->router_id
));
1309 SET_FLAG(dd
->options
, OSPF_OPTION_NP
);
1312 #ifdef REJECT_IF_TBIT_ON
1313 if (CHECK_FLAG(dd
->options
, OSPF_OPTION_MT
)) {
1315 * In Hello protocol, optional capability must have checked
1316 * to prevent this T-bit enabled router be my neighbor.
1318 zlog_warn("Packet[DD]: Neighbor %s: T-bit on?",
1319 inet_ntoa(nbr
->router_id
));
1322 #endif /* REJECT_IF_TBIT_ON */
1324 if (CHECK_FLAG(dd
->options
, OSPF_OPTION_O
)
1325 && !CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)) {
1327 * This node is not configured to handle O-bit, for now.
1328 * Clear it to ignore unsupported capability proposed by
1331 UNSET_FLAG(dd
->options
, OSPF_OPTION_O
);
1334 /* Add event to thread. */
1335 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1337 /* Process DD packet by neighbor status. */
1338 switch (nbr
->state
) {
1343 "Packet[DD]: Neighbor %s state is %s, packet discarded.",
1344 inet_ntoa(nbr
->router_id
),
1345 lookup_msg(ospf_nsm_state_msg
, nbr
->state
, NULL
));
1348 OSPF_NSM_EVENT_EXECUTE(nbr
, NSM_TwoWayReceived
);
1349 /* If the new state is ExStart, the processing of the current
1350 packet should then continue in this new state by falling
1351 through to case ExStart below. */
1352 if (nbr
->state
!= NSM_ExStart
)
1357 if ((IS_SET_DD_ALL(dd
->flags
) == OSPF_DD_FLAG_ALL
)
1358 && (size
== OSPF_DB_DESC_MIN_SIZE
)) {
1359 if (IPV4_ADDR_CMP(&nbr
->router_id
, &oi
->ospf
->router_id
)
1361 /* We're Slave---obey */
1362 if (CHECK_FLAG(oi
->ospf
->config
,
1363 OSPF_LOG_ADJACENCY_DETAIL
))
1365 "Packet[DD]: Neighbor %s Negotiation done (Slave).",
1366 inet_ntoa(nbr
->router_id
));
1368 nbr
->dd_seqnum
= ntohl(dd
->dd_seqnum
);
1371 UNSET_FLAG(nbr
->dd_flags
,
1372 (OSPF_DD_FLAG_MS
| OSPF_DD_FLAG_I
));
1374 /* We're Master, ignore the initial DBD from
1376 if (CHECK_FLAG(oi
->ospf
->config
,
1377 OSPF_LOG_ADJACENCY_DETAIL
))
1379 "Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1381 inet_ntoa(nbr
->router_id
));
1385 /* Ack from the Slave */
1386 else if (!IS_SET_DD_MS(dd
->flags
) && !IS_SET_DD_I(dd
->flags
)
1387 && ntohl(dd
->dd_seqnum
) == nbr
->dd_seqnum
1388 && IPV4_ADDR_CMP(&nbr
->router_id
, &oi
->ospf
->router_id
)
1391 "Packet[DD]: Neighbor %s Negotiation done (Master).",
1392 inet_ntoa(nbr
->router_id
));
1393 /* Reset I, leaving MS */
1394 UNSET_FLAG(nbr
->dd_flags
, OSPF_DD_FLAG_I
);
1396 zlog_warn("Packet[DD]: Neighbor %s Negotiation fails.",
1397 inet_ntoa(nbr
->router_id
));
1401 /* This is where the real Options are saved */
1402 nbr
->options
= dd
->options
;
1404 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)) {
1405 if (IS_DEBUG_OSPF_EVENT
)
1407 "Neighbor[%s] is %sOpaque-capable.",
1408 inet_ntoa(nbr
->router_id
),
1409 CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)
1413 if (!CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)
1414 && IPV4_ADDR_SAME(&DR(oi
),
1415 &nbr
->address
.u
.prefix4
)) {
1417 "DR-neighbor[%s] is NOT opaque-capable; "
1418 "Opaque-LSAs cannot be reliably advertised "
1420 inet_ntoa(nbr
->router_id
));
1421 /* This situation is undesirable, but not a real
1426 OSPF_NSM_EVENT_EXECUTE(nbr
, NSM_NegotiationDone
);
1428 /* continue processing rest of packet. */
1429 ospf_db_desc_proc(s
, oi
, nbr
, dd
, size
);
1432 if (ospf_db_desc_is_dup(dd
, nbr
)) {
1433 if (IS_SET_DD_MS(nbr
->dd_flags
))
1434 /* Master: discard duplicated DD packet. */
1436 "Packet[DD] (Master): Neighbor %s packet duplicated.",
1437 inet_ntoa(nbr
->router_id
));
1439 /* Slave: cause to retransmit the last Database
1443 "Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1444 inet_ntoa(nbr
->router_id
));
1445 ospf_db_desc_resend(nbr
);
1450 /* Otherwise DD packet should be checked. */
1451 /* Check Master/Slave bit mismatch */
1452 if (IS_SET_DD_MS(dd
->flags
)
1453 != IS_SET_DD_MS(nbr
->last_recv
.flags
)) {
1454 zlog_warn("Packet[DD]: Neighbor %s MS-bit mismatch.",
1455 inet_ntoa(nbr
->router_id
));
1456 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1457 if (IS_DEBUG_OSPF_EVENT
)
1459 "Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1460 dd
->flags
, nbr
->dd_flags
);
1464 /* Check initialize bit is set. */
1465 if (IS_SET_DD_I(dd
->flags
)) {
1466 zlog_info("Packet[DD]: Neighbor %s I-bit set.",
1467 inet_ntoa(nbr
->router_id
));
1468 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1472 /* Check DD Options. */
1473 if (dd
->options
!= nbr
->options
) {
1474 #ifdef ORIGINAL_CODING
1475 /* Save the new options for debugging */
1476 nbr
->options
= dd
->options
;
1477 #endif /* ORIGINAL_CODING */
1478 zlog_warn("Packet[DD]: Neighbor %s options mismatch.",
1479 inet_ntoa(nbr
->router_id
));
1480 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1484 /* Check DD sequence number. */
1485 if ((IS_SET_DD_MS(nbr
->dd_flags
)
1486 && ntohl(dd
->dd_seqnum
) != nbr
->dd_seqnum
)
1487 || (!IS_SET_DD_MS(nbr
->dd_flags
)
1488 && ntohl(dd
->dd_seqnum
) != nbr
->dd_seqnum
+ 1)) {
1490 "Packet[DD]: Neighbor %s sequence number mismatch.",
1491 inet_ntoa(nbr
->router_id
));
1492 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1496 /* Continue processing rest of packet. */
1497 ospf_db_desc_proc(s
, oi
, nbr
, dd
, size
);
1501 if (ospf_db_desc_is_dup(dd
, nbr
)) {
1502 if (IS_SET_DD_MS(nbr
->dd_flags
)) {
1503 /* Master should discard duplicate DD packet. */
1505 "Packet[DD]: Neighbor %s duplicated, "
1506 "packet discarded.",
1507 inet_ntoa(nbr
->router_id
));
1510 if (monotime_since(&nbr
->last_send_ts
, NULL
)
1511 < nbr
->v_inactivity
* 1000000LL) {
1512 /* In states Loading and Full the slave
1514 its last Database Description packet
1516 duplicate Database Description
1518 from the master. For this reason the
1520 wait RouterDeadInterval seconds
1522 last Database Description packet.
1524 Database Description packet from the
1526 this interval will generate a
1528 neighbor event. RFC2328 Section 10.8
1530 ospf_db_desc_resend(nbr
);
1536 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1539 zlog_warn("Packet[DD]: Neighbor %s NSM illegal status %u.",
1540 inet_ntoa(nbr
->router_id
), nbr
->state
);
1545 #define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1547 /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1548 static void ospf_ls_req(struct ip
*iph
, struct ospf_header
*ospfh
,
1549 struct stream
*s
, struct ospf_interface
*oi
,
1552 struct ospf_neighbor
*nbr
;
1554 struct in_addr ls_id
;
1555 struct in_addr adv_router
;
1556 struct ospf_lsa
*find
;
1557 struct list
*ls_upd
;
1558 unsigned int length
;
1560 /* Increment statistics. */
1563 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1565 zlog_warn("Link State Request: Unknown Neighbor %s.",
1566 inet_ntoa(ospfh
->router_id
));
1570 /* Add event to thread. */
1571 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1573 /* Neighbor State should be Exchange or later. */
1574 if (nbr
->state
!= NSM_Exchange
&& nbr
->state
!= NSM_Loading
1575 && nbr
->state
!= NSM_Full
) {
1577 "Link State Request received from %s: "
1578 "Neighbor state is %s, packet discarded.",
1579 inet_ntoa(ospfh
->router_id
),
1580 lookup_msg(ospf_nsm_state_msg
, nbr
->state
, NULL
));
1584 /* Send Link State Update for ALL requested LSAs. */
1585 ls_upd
= list_new();
1586 length
= OSPF_HEADER_SIZE
+ OSPF_LS_UPD_MIN_SIZE
;
1588 while (size
>= OSPF_LSA_KEY_SIZE
) {
1589 /* Get one slice of Link State Request. */
1590 ls_type
= stream_getl(s
);
1591 ls_id
.s_addr
= stream_get_ipv4(s
);
1592 adv_router
.s_addr
= stream_get_ipv4(s
);
1594 /* Verify LSA type. */
1595 if (ls_type
< OSPF_MIN_LSA
|| ls_type
>= OSPF_MAX_LSA
) {
1596 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
1597 list_delete_and_null(&ls_upd
);
1601 /* Search proper LSA in LSDB. */
1602 find
= ospf_lsa_lookup(oi
->ospf
, oi
->area
, ls_type
, ls_id
,
1605 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
1606 list_delete_and_null(&ls_upd
);
1610 /* Packet overflows MTU size, send immediately. */
1611 if (length
+ ntohs(find
->data
->length
) > ospf_packet_max(oi
)) {
1612 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1613 ospf_ls_upd_send(nbr
, ls_upd
,
1614 OSPF_SEND_PACKET_DIRECT
, 0);
1616 ospf_ls_upd_send(nbr
, ls_upd
,
1617 OSPF_SEND_PACKET_INDIRECT
, 0);
1619 /* Only remove list contents. Keep ls_upd. */
1620 list_delete_all_node(ls_upd
);
1622 length
= OSPF_HEADER_SIZE
+ OSPF_LS_UPD_MIN_SIZE
;
1625 /* Append LSA to update list. */
1626 listnode_add(ls_upd
, find
);
1627 length
+= ntohs(find
->data
->length
);
1629 size
-= OSPF_LSA_KEY_SIZE
;
1632 /* Send rest of Link State Update. */
1633 if (listcount(ls_upd
) > 0) {
1634 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1635 ospf_ls_upd_send(nbr
, ls_upd
, OSPF_SEND_PACKET_DIRECT
,
1638 ospf_ls_upd_send(nbr
, ls_upd
, OSPF_SEND_PACKET_INDIRECT
,
1641 list_delete_and_null(&ls_upd
);
1643 list_delete_and_null(&ls_upd
);
1646 /* Get the list of LSAs from Link State Update packet.
1647 And process some validation -- RFC2328 Section 13. (1)-(2). */
1648 static struct list
*ospf_ls_upd_list_lsa(struct ospf_neighbor
*nbr
,
1650 struct ospf_interface
*oi
, size_t size
)
1652 uint16_t count
, sum
;
1654 struct lsa_header
*lsah
;
1655 struct ospf_lsa
*lsa
;
1660 count
= stream_getl(s
);
1661 size
-= OSPF_LS_UPD_MIN_SIZE
; /* # LSAs */
1663 for (; size
>= OSPF_LSA_HEADER_SIZE
&& count
> 0;
1664 size
-= length
, stream_forward_getp(s
, length
), count
--) {
1665 lsah
= (struct lsa_header
*)stream_pnt(s
);
1666 length
= ntohs(lsah
->length
);
1668 if (length
> size
) {
1670 "Link State Update: LSA length exceeds packet size.");
1674 /* Validate the LSA's LS checksum. */
1675 sum
= lsah
->checksum
;
1676 if (!ospf_lsa_checksum_valid(lsah
)) {
1677 /* (bug #685) more details in a one-line message make it
1679 * to identify problem source on the one hand and to
1681 * chance to compress repeated messages in syslog on the
1684 "Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1685 sum
, lsah
->checksum
, inet_ntoa(lsah
->id
),
1686 inet_ntoa(nbr
->src
), inet_ntoa(nbr
->router_id
),
1687 inet_ntoa(lsah
->adv_router
));
1691 /* Examine the LSA's LS type. */
1692 if (lsah
->type
< OSPF_MIN_LSA
|| lsah
->type
>= OSPF_MAX_LSA
) {
1693 zlog_warn("Link State Update: Unknown LS type %d",
1699 * What if the received LSA's age is greater than MaxAge?
1700 * Treat it as a MaxAge case -- endo.
1702 if (ntohs(lsah
->ls_age
) > OSPF_LSA_MAXAGE
)
1703 lsah
->ls_age
= htons(OSPF_LSA_MAXAGE
);
1705 if (CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)) {
1706 #ifdef STRICT_OBIT_USAGE_CHECK
1707 if ((IS_OPAQUE_LSA(lsah
->type
)
1708 && !CHECK_FLAG(lsah
->options
, OSPF_OPTION_O
))
1709 || (!IS_OPAQUE_LSA(lsah
->type
)
1710 && CHECK_FLAG(lsah
->options
, OSPF_OPTION_O
))) {
1712 * This neighbor must know the exact usage of
1714 * the bit will be set in Type-9,10,11 LSAs
1717 zlog_warn("LSA[Type%d:%s]: O-bit abuse?",
1718 lsah
->type
, inet_ntoa(lsah
->id
));
1721 #endif /* STRICT_OBIT_USAGE_CHECK */
1723 /* Do not take in AS External Opaque-LSAs if we are a
1725 if (lsah
->type
== OSPF_OPAQUE_AS_LSA
1726 && nbr
->oi
->area
->external_routing
1727 != OSPF_AREA_DEFAULT
) {
1728 if (IS_DEBUG_OSPF_EVENT
)
1730 "LSA[Type%d:%s]: We are a stub, don't take this LSA.",
1732 inet_ntoa(lsah
->id
));
1735 } else if (IS_OPAQUE_LSA(lsah
->type
)) {
1736 zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
1737 lsah
->type
, inet_ntoa(lsah
->id
));
1741 /* Create OSPF LSA instance. */
1742 lsa
= ospf_lsa_new();
1744 lsa
->vrf_id
= oi
->ospf
->vrf_id
;
1745 /* We may wish to put some error checking if type NSSA comes in
1746 and area not in NSSA mode */
1747 switch (lsah
->type
) {
1748 case OSPF_AS_EXTERNAL_LSA
:
1749 case OSPF_OPAQUE_AS_LSA
:
1752 case OSPF_OPAQUE_LINK_LSA
:
1753 lsa
->oi
= oi
; /* Remember incoming interface for
1754 flooding control. */
1757 lsa
->area
= oi
->area
;
1761 lsa
->data
= ospf_lsa_data_new(length
);
1762 memcpy(lsa
->data
, lsah
, length
);
1764 if (IS_DEBUG_OSPF_EVENT
)
1766 "LSA[Type%d:%s]: %p new LSA created with Link State Update",
1767 lsa
->data
->type
, inet_ntoa(lsa
->data
->id
),
1769 listnode_add(lsas
, lsa
);
1775 /* Cleanup Update list. */
1776 static void ospf_upd_list_clean(struct list
*lsas
)
1778 struct listnode
*node
, *nnode
;
1779 struct ospf_lsa
*lsa
;
1781 for (ALL_LIST_ELEMENTS(lsas
, node
, nnode
, lsa
))
1782 ospf_lsa_discard(lsa
);
1784 list_delete_and_null(&lsas
);
1787 /* OSPF Link State Update message read -- RFC2328 Section 13. */
1788 static void ospf_ls_upd(struct ospf
*ospf
, struct ip
*iph
,
1789 struct ospf_header
*ospfh
, struct stream
*s
,
1790 struct ospf_interface
*oi
, uint16_t size
)
1792 struct ospf_neighbor
*nbr
;
1794 struct listnode
*node
, *nnode
;
1795 struct ospf_lsa
*lsa
= NULL
;
1796 /* unsigned long ls_req_found = 0; */
1798 /* Dis-assemble the stream, update each entry, re-encapsulate for
1801 /* Increment statistics. */
1804 /* Check neighbor. */
1805 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1807 zlog_warn("Link State Update: Unknown Neighbor %s on int: %s",
1808 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
));
1812 /* Add event to thread. */
1813 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1815 /* Check neighbor state. */
1816 if (nbr
->state
< NSM_Exchange
) {
1817 if (IS_DEBUG_OSPF(nsm
, NSM_EVENTS
))
1819 "Link State Update: "
1820 "Neighbor[%s] state %s is less than Exchange",
1821 inet_ntoa(ospfh
->router_id
),
1822 lookup_msg(ospf_nsm_state_msg
, nbr
->state
,
1827 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1828 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1831 lsas
= ospf_ls_upd_list_lsa(nbr
, s
, oi
, size
);
1835 #define DISCARD_LSA(L, N) \
1837 if (IS_DEBUG_OSPF_EVENT) \
1839 "ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \
1841 N, (void *)lsa, (int)lsa->data->type); \
1842 ospf_lsa_discard(L); \
1846 /* Process each LSA received in the one packet.
1848 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
1849 * text below are from the steps in RFC 2328, Section 13.
1851 for (ALL_LIST_ELEMENTS(lsas
, node
, nnode
, lsa
)) {
1852 struct ospf_lsa
*ls_ret
, *current
;
1855 if (IS_DEBUG_OSPF_NSSA
) {
1856 char buf1
[INET_ADDRSTRLEN
];
1857 char buf2
[INET_ADDRSTRLEN
];
1858 char buf3
[INET_ADDRSTRLEN
];
1860 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
1862 inet_ntop(AF_INET
, &ospfh
->router_id
, buf1
,
1864 inet_ntop(AF_INET
, &lsa
->data
->id
, buf2
,
1866 inet_ntop(AF_INET
, &lsa
->data
->adv_router
,
1867 buf3
, INET_ADDRSTRLEN
));
1870 listnode_delete(lsas
,
1871 lsa
); /* We don't need it in list anymore */
1873 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa()
1876 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
1878 /* (3) Do not take in AS External LSAs if we are a stub or NSSA.
1881 /* Do not take in AS NSSA if this neighbor and we are not NSSA
1884 /* Do take in Type-7's if we are an NSSA */
1886 /* If we are also an ABR, later translate them to a Type-5
1889 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1890 translate them to a separate Type-5 packet. */
1892 if (lsa
->data
->type
== OSPF_AS_EXTERNAL_LSA
)
1893 /* Reject from STUB or NSSA */
1894 if (nbr
->oi
->area
->external_routing
1895 != OSPF_AREA_DEFAULT
) {
1896 if (IS_DEBUG_OSPF_NSSA
)
1898 "Incoming External LSA Discarded: We are NSSA/STUB Area");
1899 DISCARD_LSA(lsa
, 1);
1902 if (lsa
->data
->type
== OSPF_AS_NSSA_LSA
)
1903 if (nbr
->oi
->area
->external_routing
!= OSPF_AREA_NSSA
) {
1904 if (IS_DEBUG_OSPF_NSSA
)
1906 "Incoming NSSA LSA Discarded: Not NSSA Area");
1907 DISCARD_LSA(lsa
, 2);
1910 /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
1911 if (lsa
->data
->type
== OSPF_ROUTER_LSA
)
1912 if (!IPV4_ADDR_SAME(&lsa
->data
->id
,
1913 &lsa
->data
->adv_router
)) {
1914 char buf1
[INET_ADDRSTRLEN
];
1915 char buf2
[INET_ADDRSTRLEN
];
1916 char buf3
[INET_ADDRSTRLEN
];
1919 "Incoming Router-LSA from %s with "
1920 "Adv-ID[%s] != LS-ID[%s]",
1921 inet_ntop(AF_INET
, &ospfh
->router_id
,
1922 buf1
, INET_ADDRSTRLEN
),
1923 inet_ntop(AF_INET
, &lsa
->data
->id
, buf2
,
1926 &lsa
->data
->adv_router
, buf3
,
1929 "OSPF domain compromised by attack or corruption. "
1930 "Verify correct operation of -ALL- OSPF routers.");
1931 DISCARD_LSA(lsa
, 0);
1934 /* Find the LSA in the current database. */
1936 current
= ospf_lsa_lookup_by_header(oi
->area
, lsa
->data
);
1938 /* (4) If the LSA's LS age is equal to MaxAge, and there is
1940 no instance of the LSA in the router's link state database,
1941 and none of router's neighbors are in states Exchange or
1943 then take the following actions: */
1945 if (IS_LSA_MAXAGE(lsa
) && !current
1946 && ospf_check_nbr_status(oi
->ospf
)) {
1947 /* (4a) Response Link State Acknowledgment. */
1948 ospf_ls_ack_send(nbr
, lsa
);
1950 /* (4b) Discard LSA. */
1951 if (IS_DEBUG_OSPF(lsa
, LSA
)) {
1953 "Link State Update[%s]: LS age is equal to MaxAge.",
1956 DISCARD_LSA(lsa
, 3);
1959 if (IS_OPAQUE_LSA(lsa
->data
->type
)
1960 && IPV4_ADDR_SAME(&lsa
->data
->adv_router
,
1961 &oi
->ospf
->router_id
)) {
1963 * Even if initial flushing seems to be completed, there
1965 * be a case that self-originated LSA with MaxAge still
1967 * in the routing domain.
1968 * Just send an LSAck message to cease retransmission.
1970 if (IS_LSA_MAXAGE(lsa
)) {
1971 zlog_warn("LSA[%s]: Boomerang effect?",
1973 ospf_ls_ack_send(nbr
, lsa
);
1974 ospf_lsa_discard(lsa
);
1976 if (current
!= NULL
&& !IS_LSA_MAXAGE(current
))
1977 ospf_opaque_lsa_refresh_schedule(
1983 * If an instance of self-originated Opaque-LSA is not
1985 * in the LSDB, there are some possible cases here.
1987 * 1) This node lost opaque-capability after restart.
1988 * 2) Else, a part of opaque-type is no more supported.
1989 * 3) Else, a part of opaque-id is no more supported.
1991 * Anyway, it is still this node's responsibility to
1993 * Otherwise, the LSA instance remains in the routing
1995 * until its age reaches to MaxAge.
1997 /* XXX: We should deal with this for *ALL* LSAs, not
1999 if (current
== NULL
) {
2000 if (IS_DEBUG_OSPF_EVENT
)
2002 "LSA[%s]: Previously originated Opaque-LSA,"
2003 "not found in the LSDB.",
2006 SET_FLAG(lsa
->flags
, OSPF_LSA_SELF
);
2008 ospf_opaque_self_originated_lsa_received(nbr
,
2010 ospf_ls_ack_send(nbr
, lsa
);
2016 /* It might be happen that received LSA is self-originated
2018 * router ID is changed. So, we should check if LSA is a
2020 * Link State ID is one of the router's own IP interface
2021 * addresses but whose
2022 * Advertising Router is not equal to the router's own Router ID
2023 * According to RFC 2328 12.4.2 and 13.4 this LSA should be
2027 if (lsa
->data
->type
== OSPF_NETWORK_LSA
) {
2028 struct listnode
*oinode
, *oinnode
;
2029 struct ospf_interface
*out_if
;
2032 for (ALL_LIST_ELEMENTS(oi
->ospf
->oiflist
, oinode
,
2037 if ((IPV4_ADDR_SAME(&out_if
->address
->u
.prefix4
,
2039 && (!(IPV4_ADDR_SAME(
2040 &oi
->ospf
->router_id
,
2041 &lsa
->data
->adv_router
)))) {
2042 if (out_if
->network_lsa_self
) {
2043 ospf_lsa_flush_area(
2045 if (IS_DEBUG_OSPF_EVENT
)
2047 "ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
2051 ospf_lsa_discard(lsa
);
2061 /* (5) Find the instance of this LSA that is currently contained
2062 in the router's link state database. If there is no
2063 database copy, or the received LSA is more recent than
2064 the database copy the following steps must be performed.
2065 (The sub steps from RFC 2328 section 13 step (5) will be
2070 || (ret
= ospf_lsa_more_recent(current
, lsa
)) < 0) {
2071 /* Actual flooding procedure. */
2072 if (ospf_flood(oi
->ospf
, nbr
, current
, lsa
)
2073 < 0) /* Trap NSSA later. */
2074 DISCARD_LSA(lsa
, 4);
2078 /* (6) Else, If there is an instance of the LSA on the sending
2079 neighbor's Link state request list, an error has occurred in
2080 the Database Exchange process. In this case, restart the
2081 Database Exchange process by generating the neighbor event
2082 BadLSReq for the sending neighbor and stop processing the
2083 Link State Update packet. */
2085 if (ospf_ls_request_lookup(nbr
, lsa
)) {
2086 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
2088 "LSA[%s] instance exists on Link state request list",
2091 /* Clean list of LSAs. */
2092 ospf_upd_list_clean(lsas
);
2093 /* this lsa is not on lsas list already. */
2094 ospf_lsa_discard(lsa
);
2098 /* If the received LSA is the same instance as the database copy
2099 (i.e., neither one is more recent) the following two steps
2100 should be performed: */
2103 /* If the LSA is listed in the Link state retransmission
2105 for the receiving adjacency, the router itself is
2107 an acknowledgment for this LSA. The router should
2109 received LSA as an acknowledgment by removing the LSA
2111 the Link state retransmission list. This is termed
2113 "implied acknowledgment". */
2115 ls_ret
= ospf_ls_retransmit_lookup(nbr
, lsa
);
2117 if (ls_ret
!= NULL
) {
2118 ospf_ls_retransmit_delete(nbr
, ls_ret
);
2120 /* Delayed acknowledgment sent if advertisement
2122 from Designated Router, otherwise do nothing.
2124 if (oi
->state
== ISM_Backup
)
2128 ospf_lsa_lock(lsa
));
2130 DISCARD_LSA(lsa
, 5);
2132 /* Acknowledge the receipt of the LSA by sending a
2133 Link State Acknowledgment packet back out the
2137 ospf_ls_ack_send(nbr
, lsa
);
2138 DISCARD_LSA(lsa
, 6);
2142 /* The database copy is more recent. If the database copy
2143 has LS age equal to MaxAge and LS sequence number equal to
2144 MaxSequenceNumber, simply discard the received LSA without
2145 acknowledging it. (In this case, the LSA's LS sequence number
2147 wrapping, and the MaxSequenceNumber LSA must be completely
2148 flushed before any new LSA instance can be introduced). */
2150 else if (ret
> 0) /* Database copy is more recent */
2152 if (IS_LSA_MAXAGE(current
)
2153 && current
->data
->ls_seqnum
2154 == htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
2155 DISCARD_LSA(lsa
, 7);
2157 /* Otherwise, as long as the database copy has not been
2159 Link State Update within the last MinLSArrival
2161 database copy back to the sending neighbor,
2163 a Link State Update Packet. The Link State Update
2165 be sent directly to the neighbor. In so doing, do not
2167 database copy of the LSA on the neighbor's link state
2168 retransmission list, and do not acknowledge the
2170 recent) LSA instance. */
2172 if (monotime_since(¤t
->tv_orig
, NULL
)
2173 >= ospf
->min_ls_arrival
* 1000LL)
2174 /* Trap NSSA type later.*/
2175 ospf_ls_upd_send_lsa(
2177 OSPF_SEND_PACKET_DIRECT
);
2178 DISCARD_LSA(lsa
, 8);
2184 assert(listcount(lsas
) == 0);
2185 list_delete_and_null(&lsas
);
2188 /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
2189 static void ospf_ls_ack(struct ip
*iph
, struct ospf_header
*ospfh
,
2190 struct stream
*s
, struct ospf_interface
*oi
,
2193 struct ospf_neighbor
*nbr
;
2195 /* increment statistics. */
2198 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
2200 zlog_warn("Link State Acknowledgment: Unknown Neighbor %s.",
2201 inet_ntoa(ospfh
->router_id
));
2205 /* Add event to thread. */
2206 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
2208 if (nbr
->state
< NSM_Exchange
) {
2209 if (IS_DEBUG_OSPF(nsm
, NSM_EVENTS
))
2211 "Link State Acknowledgment: "
2212 "Neighbor[%s] state %s is less than Exchange",
2213 inet_ntoa(ospfh
->router_id
),
2214 lookup_msg(ospf_nsm_state_msg
, nbr
->state
,
2219 while (size
>= OSPF_LSA_HEADER_SIZE
) {
2220 struct ospf_lsa
*lsa
, *lsr
;
2222 lsa
= ospf_lsa_new();
2223 lsa
->data
= (struct lsa_header
*)stream_pnt(s
);
2224 lsa
->vrf_id
= oi
->ospf
->vrf_id
;
2226 /* lsah = (struct lsa_header *) stream_pnt (s); */
2227 size
-= OSPF_LSA_HEADER_SIZE
;
2228 stream_forward_getp(s
, OSPF_LSA_HEADER_SIZE
);
2230 if (lsa
->data
->type
< OSPF_MIN_LSA
2231 || lsa
->data
->type
>= OSPF_MAX_LSA
) {
2233 ospf_lsa_discard(lsa
);
2237 lsr
= ospf_ls_retransmit_lookup(nbr
, lsa
);
2239 if (lsr
!= NULL
&& ospf_lsa_more_recent(lsr
, lsa
) == 0)
2240 ospf_ls_retransmit_delete(nbr
, lsr
);
2243 ospf_lsa_discard(lsa
);
2249 static struct stream
*ospf_recv_packet(struct ospf
*ospf
, int fd
,
2250 struct interface
**ifp
,
2251 struct stream
*ibuf
)
2256 ifindex_t ifindex
= 0;
2258 /* Header and data both require alignment. */
2259 char buff
[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2262 memset(&msgh
, 0, sizeof(struct msghdr
));
2263 msgh
.msg_iov
= &iov
;
2264 msgh
.msg_iovlen
= 1;
2265 msgh
.msg_control
= (caddr_t
)buff
;
2266 msgh
.msg_controllen
= sizeof(buff
);
2268 ret
= stream_recvmsg(ibuf
, fd
, &msgh
, 0, OSPF_MAX_PACKET_SIZE
+ 1);
2270 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno
));
2273 if ((unsigned int)ret
< sizeof(iph
)) /* ret must be > 0 now */
2276 "ospf_recv_packet: discarding runt packet of length %d "
2277 "(ip header size is %u)",
2278 ret
, (unsigned int)sizeof(iph
));
2282 /* Note that there should not be alignment problems with this assignment
2283 because this is at the beginning of the stream data buffer. */
2284 iph
= (struct ip
*)STREAM_DATA(ibuf
);
2285 sockopt_iphdrincl_swab_systoh(iph
);
2287 ip_len
= iph
->ip_len
;
2289 #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
2291 * Kernel network code touches incoming IP header parameters,
2292 * before protocol specific processing.
2294 * 1) Convert byteorder to host representation.
2295 * --> ip_len, ip_id, ip_off
2297 * 2) Adjust ip_len to strip IP header size!
2298 * --> If user process receives entire IP packet via RAW
2299 * socket, it must consider adding IP header size to
2300 * the "ip_len" field of "ip" structure.
2302 * For more details, see <netinet/ip_input.c>.
2304 ip_len
= ip_len
+ (iph
->ip_hl
<< 2);
2307 #if defined(__DragonFly__)
2309 * in DragonFly's raw socket, ip_len/ip_off are read
2310 * in network byte order.
2311 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2313 ip_len
= ntohs(iph
->ip_len
) + (iph
->ip_hl
<< 2);
2316 ifindex
= getsockopt_ifindex(AF_INET
, &msgh
);
2318 *ifp
= if_lookup_by_index(ifindex
, ospf
->vrf_id
);
2320 if (ret
!= ip_len
) {
2322 "ospf_recv_packet read length mismatch: ip_len is %d, "
2323 "but recvmsg returned %d",
2331 static struct ospf_interface
*
2332 ospf_associate_packet_vl(struct ospf
*ospf
, struct interface
*ifp
,
2333 struct ip
*iph
, struct ospf_header
*ospfh
)
2335 struct ospf_interface
*rcv_oi
;
2336 struct ospf_vl_data
*vl_data
;
2337 struct ospf_area
*vl_area
;
2338 struct listnode
*node
;
2340 if (IN_MULTICAST(ntohl(iph
->ip_dst
.s_addr
))
2341 || !OSPF_IS_AREA_BACKBONE(ospfh
))
2344 /* look for local OSPF interface matching the destination
2345 * to determine Area ID. We presume therefore the destination address
2346 * is unique, or at least (for "unnumbered" links), not used in other
2349 if ((rcv_oi
= ospf_if_lookup_by_local_addr(ospf
, NULL
, iph
->ip_dst
))
2353 for (ALL_LIST_ELEMENTS_RO(ospf
->vlinks
, node
, vl_data
)) {
2355 ospf_area_lookup_by_area_id(ospf
, vl_data
->vl_area_id
);
2359 if (OSPF_AREA_SAME(&vl_area
, &rcv_oi
->area
)
2360 && IPV4_ADDR_SAME(&vl_data
->vl_peer
, &ospfh
->router_id
)) {
2361 if (IS_DEBUG_OSPF_EVENT
)
2362 zlog_debug("associating packet with %s",
2363 IF_NAME(vl_data
->vl_oi
));
2364 if (!CHECK_FLAG(vl_data
->vl_oi
->ifp
->flags
, IFF_UP
)) {
2365 if (IS_DEBUG_OSPF_EVENT
)
2367 "This VL is not up yet, sorry");
2371 return vl_data
->vl_oi
;
2375 if (IS_DEBUG_OSPF_EVENT
)
2376 zlog_debug("couldn't find any VL to associate the packet with");
2381 static int ospf_check_area_id(struct ospf_interface
*oi
,
2382 struct ospf_header
*ospfh
)
2384 /* Check match the Area ID of the receiving interface. */
2385 if (OSPF_AREA_SAME(&oi
->area
, &ospfh
))
2391 /* Unbound socket will accept any Raw IP packets if proto is matched.
2392 To prevent it, compare src IP address and i/f address with masking
2393 i/f network mask. */
2394 static int ospf_check_network_mask(struct ospf_interface
*oi
,
2395 struct in_addr ip_src
)
2397 struct in_addr mask
, me
, him
;
2399 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
2400 || oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2403 masklen2ip(oi
->address
->prefixlen
, &mask
);
2405 me
.s_addr
= oi
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
2406 him
.s_addr
= ip_src
.s_addr
& mask
.s_addr
;
2408 if (IPV4_ADDR_SAME(&me
, &him
))
2414 /* Return 1, if the packet is properly authenticated and checksummed,
2415 0 otherwise. In particular, check that AuType header field is valid and
2416 matches the locally configured AuType, and that D.5 requirements are met. */
2417 static int ospf_check_auth(struct ospf_interface
*oi
, struct ospf_header
*ospfh
)
2419 struct crypt_key
*ck
;
2420 uint16_t iface_auth_type
;
2421 uint16_t pkt_auth_type
= ntohs(ospfh
->auth_type
);
2423 switch (pkt_auth_type
) {
2424 case OSPF_AUTH_NULL
: /* RFC2328 D.5.1 */
2425 if (OSPF_AUTH_NULL
!= (iface_auth_type
= ospf_auth_type(oi
))) {
2426 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2428 "interface %s: auth-type mismatch, local %s, rcvd Null",
2430 lookup_msg(ospf_auth_type_str
,
2431 iface_auth_type
, NULL
));
2434 if (!ospf_check_sum(ospfh
)) {
2435 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2437 "interface %s: Null auth OK, but checksum error, Router-ID %s",
2439 inet_ntoa(ospfh
->router_id
));
2443 case OSPF_AUTH_SIMPLE
: /* RFC2328 D.5.2 */
2444 if (OSPF_AUTH_SIMPLE
2445 != (iface_auth_type
= ospf_auth_type(oi
))) {
2446 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2448 "interface %s: auth-type mismatch, local %s, rcvd Simple",
2450 lookup_msg(ospf_auth_type_str
,
2451 iface_auth_type
, NULL
));
2454 if (memcmp(OSPF_IF_PARAM(oi
, auth_simple
), ospfh
->u
.auth_data
,
2455 OSPF_AUTH_SIMPLE_SIZE
)) {
2456 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2457 zlog_warn("interface %s: Simple auth failed",
2461 if (!ospf_check_sum(ospfh
)) {
2462 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2464 "interface %s: Simple auth OK, checksum error, Router-ID %s",
2466 inet_ntoa(ospfh
->router_id
));
2470 case OSPF_AUTH_CRYPTOGRAPHIC
: /* RFC2328 D.5.3 */
2471 if (OSPF_AUTH_CRYPTOGRAPHIC
2472 != (iface_auth_type
= ospf_auth_type(oi
))) {
2473 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2475 "interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2477 lookup_msg(ospf_auth_type_str
,
2478 iface_auth_type
, NULL
));
2481 if (ospfh
->checksum
) {
2482 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2484 "interface %s: OSPF header checksum is not 0",
2488 /* only MD5 crypto method can pass ospf_packet_examin() */
2489 if (NULL
== (ck
= listgetdata(
2490 listtail(OSPF_IF_PARAM(oi
, auth_crypt
))))
2491 || ospfh
->u
.crypt
.key_id
!= ck
->key_id
||
2492 /* Condition above uses the last key ID on the list,
2494 different from what ospf_crypt_key_lookup() does. A
2496 !ospf_check_md5_digest(oi
, ospfh
)) {
2497 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2498 zlog_warn("interface %s: MD5 auth failed",
2504 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2506 "interface %s: invalid packet auth-type (%02x)",
2507 IF_NAME(oi
), pkt_auth_type
);
2512 static int ospf_check_sum(struct ospf_header
*ospfh
)
2517 /* clear auth_data for checksum. */
2518 memset(ospfh
->u
.auth_data
, 0, OSPF_AUTH_SIMPLE_SIZE
);
2520 /* keep checksum and clear. */
2521 sum
= ospfh
->checksum
;
2522 memset(&ospfh
->checksum
, 0, sizeof(uint16_t));
2524 /* calculate checksum. */
2525 ret
= in_cksum(ospfh
, ntohs(ospfh
->length
));
2528 zlog_info("ospf_check_sum(): checksum mismatch, my %X, his %X",
2536 /* Verify, that given link/TOS records are properly sized/aligned and match
2537 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2538 static unsigned ospf_router_lsa_links_examin(struct router_lsa_link
*link
,
2540 const uint16_t num_links
)
2542 unsigned counted_links
= 0, thislinklen
;
2546 OSPF_ROUTER_LSA_LINK_SIZE
+ 4 * link
->m
[0].tos_count
;
2547 if (thislinklen
> linkbytes
) {
2548 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2549 zlog_debug("%s: length error in link block #%u",
2550 __func__
, counted_links
);
2553 link
= (struct router_lsa_link
*)((caddr_t
)link
+ thislinklen
);
2554 linkbytes
-= thislinklen
;
2557 if (counted_links
!= num_links
) {
2558 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2559 zlog_debug("%s: %u link blocks declared, %u present",
2560 __func__
, num_links
, counted_links
);
2566 /* Verify, that the given LSA is properly sized/aligned (including type-specific
2567 minimum length constraint). */
2568 static unsigned ospf_lsa_examin(struct lsa_header
*lsah
, const uint16_t lsalen
,
2569 const uint8_t headeronly
)
2572 struct router_lsa
*rlsa
;
2573 if (lsah
->type
< OSPF_MAX_LSA
&& ospf_lsa_minlen
[lsah
->type
]
2574 && lsalen
< OSPF_LSA_HEADER_SIZE
+ ospf_lsa_minlen
[lsah
->type
]) {
2575 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2576 zlog_debug("%s: undersized (%u B) %s", __func__
, lsalen
,
2577 lookup_msg(ospf_lsa_type_msg
, lsah
->type
,
2581 switch (lsah
->type
) {
2582 case OSPF_ROUTER_LSA
:
2583 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1
2584 * (12+)-byte link blocks */
2586 ret
= (lsalen
- OSPF_LSA_HEADER_SIZE
2587 - OSPF_ROUTER_LSA_MIN_SIZE
)
2593 rlsa
= (struct router_lsa
*)lsah
;
2594 ret
= ospf_router_lsa_links_examin(
2595 (struct router_lsa_link
*)rlsa
->link
,
2596 lsalen
- OSPF_LSA_HEADER_SIZE
- 4, /* skip: basic
2599 ntohs(rlsa
->links
) /* 16 bits */
2602 case OSPF_AS_EXTERNAL_LSA
:
2603 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long
2605 case OSPF_AS_NSSA_LSA
:
2606 /* RFC3101 C, idem */
2607 ret
= (lsalen
- OSPF_LSA_HEADER_SIZE
2608 - OSPF_AS_EXTERNAL_LSA_MIN_SIZE
)
2613 /* Following LSA types are considered OK length-wise as soon as their
2615 * length constraint is met and length of the whole LSA is a multiple of
2617 * (basic LSA header size is already a multiple of 4). */
2618 case OSPF_NETWORK_LSA
:
2619 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2620 case OSPF_SUMMARY_LSA
:
2621 case OSPF_ASBR_SUMMARY_LSA
:
2622 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS
2624 case OSPF_OPAQUE_LINK_LSA
:
2625 case OSPF_OPAQUE_AREA_LSA
:
2626 case OSPF_OPAQUE_AS_LSA
:
2627 /* RFC5250 A.2, "some number of octets (of application-specific
2628 * data) padded to 32-bit alignment." This is considered
2630 * to 4-byte alignment of all other LSA types, see
2631 * OSPF-ALIGNMENT.txt
2632 * file for the detailed analysis of this passage. */
2633 ret
= lsalen
% 4 ? MSG_NG
: MSG_OK
;
2636 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2637 zlog_debug("%s: unsupported LSA type 0x%02x", __func__
,
2641 if (ret
!= MSG_OK
&& IS_DEBUG_OSPF_PACKET(0, RECV
))
2642 zlog_debug("%s: alignment error in %s", __func__
,
2643 lookup_msg(ospf_lsa_type_msg
, lsah
->type
, NULL
));
2647 /* Verify if the provided input buffer is a valid sequence of LSAs. This
2648 includes verification of LSA blocks length/alignment and dispatching
2649 of deeper-level checks. */
2651 ospf_lsaseq_examin(struct lsa_header
*lsah
, /* start of buffered data */
2652 size_t length
, const uint8_t headeronly
,
2653 /* When declared_num_lsas is not 0, compare it to the real
2655 and treat the difference as an error. */
2656 const uint32_t declared_num_lsas
)
2658 uint32_t counted_lsas
= 0;
2662 if (length
< OSPF_LSA_HEADER_SIZE
) {
2663 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2665 "%s: undersized (%zu B) trailing (#%u) LSA header",
2666 __func__
, length
, counted_lsas
);
2669 /* save on ntohs() calls here and in the LSA validator */
2670 lsalen
= ntohs(lsah
->length
);
2671 if (lsalen
< OSPF_LSA_HEADER_SIZE
) {
2672 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2674 "%s: malformed LSA header #%u, declared length is %u B",
2675 __func__
, counted_lsas
, lsalen
);
2679 /* less checks here and in ospf_lsa_examin() */
2680 if (MSG_OK
!= ospf_lsa_examin(lsah
, lsalen
, 1)) {
2681 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2683 "%s: malformed header-only LSA #%u",
2684 __func__
, counted_lsas
);
2687 lsah
= (struct lsa_header
*)((caddr_t
)lsah
2688 + OSPF_LSA_HEADER_SIZE
);
2689 length
-= OSPF_LSA_HEADER_SIZE
;
2691 /* make sure the input buffer is deep enough before
2693 if (lsalen
> length
) {
2694 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2696 "%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2697 __func__
, counted_lsas
, lsalen
,
2701 if (MSG_OK
!= ospf_lsa_examin(lsah
, lsalen
, 0)) {
2702 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2703 zlog_debug("%s: malformed LSA #%u",
2704 __func__
, counted_lsas
);
2707 lsah
= (struct lsa_header
*)((caddr_t
)lsah
+ lsalen
);
2713 if (declared_num_lsas
&& counted_lsas
!= declared_num_lsas
) {
2714 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2716 "%s: #LSAs declared (%u) does not match actual (%u)",
2717 __func__
, declared_num_lsas
, counted_lsas
);
2723 /* Verify a complete OSPF packet for proper sizing/alignment. */
2724 static unsigned ospf_packet_examin(struct ospf_header
*oh
,
2725 const unsigned bytesonwire
)
2727 uint16_t bytesdeclared
, bytesauth
;
2729 struct ospf_ls_update
*lsupd
;
2731 /* Length, 1st approximation. */
2732 if (bytesonwire
< OSPF_HEADER_SIZE
) {
2733 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2734 zlog_debug("%s: undersized (%u B) packet", __func__
,
2738 /* Now it is safe to access header fields. Performing length check,
2740 * for possible extra bytes of crypto auth/padding, which are not
2742 * in the OSPF header "length" field. */
2743 if (oh
->version
!= OSPF_VERSION
) {
2744 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2745 zlog_debug("%s: invalid (%u) protocol version",
2746 __func__
, oh
->version
);
2749 bytesdeclared
= ntohs(oh
->length
);
2750 if (ntohs(oh
->auth_type
) != OSPF_AUTH_CRYPTOGRAPHIC
)
2753 if (oh
->u
.crypt
.auth_data_len
!= OSPF_AUTH_MD5_SIZE
) {
2754 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2756 "%s: unsupported crypto auth length (%u B)",
2757 __func__
, oh
->u
.crypt
.auth_data_len
);
2760 bytesauth
= OSPF_AUTH_MD5_SIZE
;
2762 if (bytesdeclared
+ bytesauth
> bytesonwire
) {
2763 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2765 "%s: packet length error (%u real, %u+%u declared)",
2766 __func__
, bytesonwire
, bytesdeclared
,
2770 /* Length, 2nd approximation. The type-specific constraint is checked
2771 against declared length, not amount of bytes on wire. */
2772 if (oh
->type
>= OSPF_MSG_HELLO
&& oh
->type
<= OSPF_MSG_LS_ACK
2774 < OSPF_HEADER_SIZE
+ ospf_packet_minlen
[oh
->type
]) {
2775 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2776 zlog_debug("%s: undersized (%u B) %s packet", __func__
,
2778 lookup_msg(ospf_packet_type_str
, oh
->type
,
2783 case OSPF_MSG_HELLO
:
2784 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes
2786 by N>=0 router-IDs. */
2787 ret
= (bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_HELLO_MIN_SIZE
)
2792 case OSPF_MSG_DB_DESC
:
2793 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes
2795 by N>=0 header-only LSAs. */
2796 ret
= ospf_lsaseq_examin(
2797 (struct lsa_header
*)((caddr_t
)oh
+ OSPF_HEADER_SIZE
2798 + OSPF_DB_DESC_MIN_SIZE
),
2799 bytesdeclared
- OSPF_HEADER_SIZE
2800 - OSPF_DB_DESC_MIN_SIZE
,
2801 1, /* header-only LSAs */
2804 case OSPF_MSG_LS_REQ
:
2805 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes
2806 * request blocks. */
2807 ret
= (bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_LS_REQ_MIN_SIZE
)
2812 case OSPF_MSG_LS_UPD
:
2813 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes
2815 by N>=0 full LSAs (with N declared beforehand). */
2816 lsupd
= (struct ospf_ls_update
*)((caddr_t
)oh
2817 + OSPF_HEADER_SIZE
);
2818 ret
= ospf_lsaseq_examin(
2819 (struct lsa_header
*)((caddr_t
)lsupd
2820 + OSPF_LS_UPD_MIN_SIZE
),
2821 bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_LS_UPD_MIN_SIZE
,
2823 ntohl(lsupd
->num_lsas
) /* 32 bits */
2826 case OSPF_MSG_LS_ACK
:
2827 /* RFC2328 A.3.6, packet header followed by N>=0 header-only
2829 ret
= ospf_lsaseq_examin(
2830 (struct lsa_header
*)((caddr_t
)oh
+ OSPF_HEADER_SIZE
2831 + OSPF_LS_ACK_MIN_SIZE
),
2832 bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_LS_ACK_MIN_SIZE
,
2833 1, /* header-only LSAs */
2837 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2838 zlog_debug("%s: invalid packet type 0x%02x", __func__
,
2842 if (ret
!= MSG_OK
&& IS_DEBUG_OSPF_PACKET(0, RECV
))
2843 zlog_debug("%s: malformed %s packet", __func__
,
2844 lookup_msg(ospf_packet_type_str
, oh
->type
, NULL
));
2848 /* OSPF Header verification. */
2849 static int ospf_verify_header(struct stream
*ibuf
, struct ospf_interface
*oi
,
2850 struct ip
*iph
, struct ospf_header
*ospfh
)
2852 /* Check Area ID. */
2853 if (!ospf_check_area_id(oi
, ospfh
)) {
2854 zlog_warn("interface %s: ospf_read invalid Area ID %s.",
2855 IF_NAME(oi
), inet_ntoa(ospfh
->area_id
));
2859 /* Check network mask, Silently discarded. */
2860 if (!ospf_check_network_mask(oi
, iph
->ip_src
)) {
2862 "interface %s: ospf_read network address is not same [%s]",
2863 IF_NAME(oi
), inet_ntoa(iph
->ip_src
));
2867 /* Check authentication. The function handles logging actions, where
2869 if (!ospf_check_auth(oi
, ospfh
))
2875 /* Starting point of packet process function. */
2876 int ospf_read(struct thread
*thread
)
2879 struct stream
*ibuf
;
2881 struct ospf_interface
*oi
;
2883 struct ospf_header
*ospfh
;
2885 struct interface
*ifp
= NULL
;
2886 struct connected
*c
;
2888 /* first of all get interface pointer. */
2889 ospf
= THREAD_ARG(thread
);
2891 /* prepare for next packet. */
2892 ospf
->t_read
= NULL
;
2893 thread_add_read(master
, ospf_read
, ospf
, ospf
->fd
, &ospf
->t_read
);
2895 stream_reset(ospf
->ibuf
);
2896 ibuf
= ospf_recv_packet(ospf
, ospf
->fd
, &ifp
, ospf
->ibuf
);
2899 /* This raw packet is known to be at least as big as its IP header. */
2901 /* Note that there should not be alignment problems with this assignment
2902 because this is at the beginning of the stream data buffer. */
2903 iph
= (struct ip
*)STREAM_DATA(ibuf
);
2904 /* Note that sockopt_iphdrincl_swab_systoh was called in
2905 * ospf_recv_packet. */
2908 /* Handle cases where the platform does not support retrieving
2910 and also platforms (such as Solaris 8) that claim to support
2912 retrieval but do not. */
2913 c
= if_lookup_address((void *)&iph
->ip_src
, AF_INET
,
2921 /* IP Header dump. */
2922 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2923 ospf_ip_header_dump(iph
);
2925 /* Self-originated packet should be discarded silently. */
2926 if (ospf_if_lookup_by_local_addr(ospf
, NULL
, iph
->ip_src
)) {
2927 if (IS_DEBUG_OSPF_PACKET(0, RECV
)) {
2929 "ospf_read[%s]: Dropping self-originated packet",
2930 inet_ntoa(iph
->ip_src
));
2935 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2936 by ospf_recv_packet() to be correct). */
2937 stream_forward_getp(ibuf
, iph
->ip_hl
* 4);
2939 ospfh
= (struct ospf_header
*)stream_pnt(ibuf
);
2941 != ospf_packet_examin(
2942 ospfh
, stream_get_endp(ibuf
) - stream_get_getp(ibuf
)))
2944 /* Now it is safe to access all fields of OSPF packet header. */
2946 /* associate packet with ospf interface */
2947 oi
= ospf_if_lookup_recv_if(ospf
, iph
->ip_src
, ifp
);
2949 /* ospf_verify_header() relies on a valid "oi" and thus can be called
2951 after the passive/backbone/other checks below are passed. These
2953 in turn access the fields of unverified "ospfh" structure for their
2955 purposes and must remain very accurate in doing this. */
2957 /* If incoming interface is passive one, ignore it. */
2958 if (oi
&& OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
) {
2959 char buf
[3][INET_ADDRSTRLEN
];
2961 if (IS_DEBUG_OSPF_EVENT
)
2963 "ignoring packet from router %s sent to %s, "
2964 "received on a passive interface, %s",
2965 inet_ntop(AF_INET
, &ospfh
->router_id
, buf
[0],
2967 inet_ntop(AF_INET
, &iph
->ip_dst
, buf
[1],
2969 inet_ntop(AF_INET
, &oi
->address
->u
.prefix4
,
2970 buf
[2], sizeof(buf
[2])));
2972 if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
)) {
2973 /* Try to fix multicast membership.
2974 * Some OS:es may have problems in this area,
2975 * make sure it is removed.
2977 OI_MEMBER_JOINED(oi
, MEMBER_ALLROUTERS
);
2978 ospf_if_set_multicast(oi
);
2984 /* if no local ospf_interface,
2985 * or header area is backbone but ospf_interface is not
2986 * check for VLINK interface
2988 if ((oi
== NULL
) || (OSPF_IS_AREA_ID_BACKBONE(ospfh
->area_id
)
2989 && !OSPF_IS_AREA_ID_BACKBONE(oi
->area
->area_id
))) {
2990 if ((oi
= ospf_associate_packet_vl(ospf
, ifp
, iph
, ospfh
))
2992 if (!ospf
->instance
&& IS_DEBUG_OSPF_EVENT
)
2994 "Packet from [%s] received on link %s"
2995 " but no ospf_interface",
2996 inet_ntoa(iph
->ip_src
), ifp
->name
);
3001 /* else it must be a local ospf interface, check it was received on
3004 else if (oi
->ifp
!= ifp
) {
3005 if (IS_DEBUG_OSPF_EVENT
)
3006 zlog_warn("Packet from [%s] received on wrong link %s",
3007 inet_ntoa(iph
->ip_src
), ifp
->name
);
3009 } else if (oi
->state
== ISM_Down
) {
3010 char buf
[2][INET_ADDRSTRLEN
];
3012 "Ignoring packet from %s to %s received on interface that is "
3013 "down [%s]; interface flags are %s",
3014 inet_ntop(AF_INET
, &iph
->ip_src
, buf
[0],
3016 inet_ntop(AF_INET
, &iph
->ip_dst
, buf
[1],
3018 ifp
->name
, if_flag_dump(ifp
->flags
));
3019 /* Fix multicast memberships? */
3020 if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
))
3021 OI_MEMBER_JOINED(oi
, MEMBER_ALLROUTERS
);
3022 else if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLDROUTERS
))
3023 OI_MEMBER_JOINED(oi
, MEMBER_DROUTERS
);
3024 if (oi
->multicast_memberships
)
3025 ospf_if_set_multicast(oi
);
3030 * If the received packet is destined for AllDRouters, the packet
3031 * should be accepted only if the received ospf interface state is
3032 * either DR or Backup -- endo.
3034 if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLDROUTERS
)
3035 && (oi
->state
!= ISM_DR
&& oi
->state
!= ISM_Backup
)) {
3037 "Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
3038 inet_ntoa(iph
->ip_src
), IF_NAME(oi
),
3039 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
));
3040 /* Try to fix multicast membership. */
3041 SET_FLAG(oi
->multicast_memberships
, MEMBER_DROUTERS
);
3042 ospf_if_set_multicast(oi
);
3046 /* Verify more OSPF header fields. */
3047 ret
= ospf_verify_header(ibuf
, oi
, iph
, ospfh
);
3049 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
3051 "ospf_read[%s]: Header check failed, "
3053 inet_ntoa(iph
->ip_src
));
3057 /* Show debug receiving packet. */
3058 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
)) {
3059 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, DETAIL
)) {
3061 "-----------------------------------------------------");
3062 ospf_packet_dump(ibuf
);
3065 zlog_debug("%s received from [%s] via [%s]",
3066 lookup_msg(ospf_packet_type_str
, ospfh
->type
, NULL
),
3067 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
));
3068 zlog_debug(" src [%s],", inet_ntoa(iph
->ip_src
));
3069 zlog_debug(" dst [%s]", inet_ntoa(iph
->ip_dst
));
3071 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, DETAIL
))
3073 "-----------------------------------------------------");
3076 stream_forward_getp(ibuf
, OSPF_HEADER_SIZE
);
3078 /* Adjust size to message length. */
3079 length
= ntohs(ospfh
->length
) - OSPF_HEADER_SIZE
;
3081 /* Read rest of the packet and call each sort of packet routine. */
3082 switch (ospfh
->type
) {
3083 case OSPF_MSG_HELLO
:
3084 ospf_hello(iph
, ospfh
, ibuf
, oi
, length
);
3086 case OSPF_MSG_DB_DESC
:
3087 ospf_db_desc(iph
, ospfh
, ibuf
, oi
, length
);
3089 case OSPF_MSG_LS_REQ
:
3090 ospf_ls_req(iph
, ospfh
, ibuf
, oi
, length
);
3092 case OSPF_MSG_LS_UPD
:
3093 ospf_ls_upd(ospf
, iph
, ospfh
, ibuf
, oi
, length
);
3095 case OSPF_MSG_LS_ACK
:
3096 ospf_ls_ack(iph
, ospfh
, ibuf
, oi
, length
);
3099 zlog_warn("interface %s: OSPF packet header type %d is illegal",
3100 IF_NAME(oi
), ospfh
->type
);
3107 /* Make OSPF header. */
3108 static void ospf_make_header(int type
, struct ospf_interface
*oi
,
3111 struct ospf_header
*ospfh
;
3113 ospfh
= (struct ospf_header
*)STREAM_DATA(s
);
3115 ospfh
->version
= (uint8_t)OSPF_VERSION
;
3116 ospfh
->type
= (uint8_t)type
;
3118 ospfh
->router_id
= oi
->ospf
->router_id
;
3120 ospfh
->checksum
= 0;
3121 ospfh
->area_id
= oi
->area
->area_id
;
3122 ospfh
->auth_type
= htons(ospf_auth_type(oi
));
3124 memset(ospfh
->u
.auth_data
, 0, OSPF_AUTH_SIMPLE_SIZE
);
3126 stream_forward_endp(s
, OSPF_HEADER_SIZE
);
3129 /* Make Authentication Data. */
3130 static int ospf_make_auth(struct ospf_interface
*oi
, struct ospf_header
*ospfh
)
3132 struct crypt_key
*ck
;
3134 switch (ospf_auth_type(oi
)) {
3135 case OSPF_AUTH_NULL
:
3136 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data));
3139 case OSPF_AUTH_SIMPLE
:
3140 memcpy(ospfh
->u
.auth_data
, OSPF_IF_PARAM(oi
, auth_simple
),
3141 OSPF_AUTH_SIMPLE_SIZE
);
3143 case OSPF_AUTH_CRYPTOGRAPHIC
:
3144 /* If key is not set, then set 0. */
3145 if (list_isempty(OSPF_IF_PARAM(oi
, auth_crypt
))) {
3146 ospfh
->u
.crypt
.zero
= 0;
3147 ospfh
->u
.crypt
.key_id
= 0;
3148 ospfh
->u
.crypt
.auth_data_len
= OSPF_AUTH_MD5_SIZE
;
3151 listtail(OSPF_IF_PARAM(oi
, auth_crypt
)));
3152 ospfh
->u
.crypt
.zero
= 0;
3153 ospfh
->u
.crypt
.key_id
= ck
->key_id
;
3154 ospfh
->u
.crypt
.auth_data_len
= OSPF_AUTH_MD5_SIZE
;
3156 /* note: the seq is done in ospf_make_md5_digest() */
3159 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data));
3167 /* Fill rest of OSPF header. */
3168 static void ospf_fill_header(struct ospf_interface
*oi
, struct stream
*s
,
3171 struct ospf_header
*ospfh
;
3173 ospfh
= (struct ospf_header
*)STREAM_DATA(s
);
3176 ospfh
->length
= htons(length
);
3178 /* Calculate checksum. */
3179 if (ntohs(ospfh
->auth_type
) != OSPF_AUTH_CRYPTOGRAPHIC
)
3180 ospfh
->checksum
= in_cksum(ospfh
, length
);
3182 ospfh
->checksum
= 0;
3184 /* Add Authentication Data. */
3185 ospf_make_auth(oi
, ospfh
);
3188 static int ospf_make_hello(struct ospf_interface
*oi
, struct stream
*s
)
3190 struct ospf_neighbor
*nbr
;
3191 struct route_node
*rn
;
3192 uint16_t length
= OSPF_HELLO_MIN_SIZE
;
3193 struct in_addr mask
;
3197 /* Set netmask of interface. */
3198 if (!(CHECK_FLAG(oi
->connected
->flags
, ZEBRA_IFA_UNNUMBERED
)
3199 && oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3200 && oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
3201 masklen2ip(oi
->address
->prefixlen
, &mask
);
3203 memset((char *)&mask
, 0, sizeof(struct in_addr
));
3204 stream_put_ipv4(s
, mask
.s_addr
);
3206 /* Set Hello Interval. */
3207 if (OSPF_IF_PARAM(oi
, fast_hello
) == 0)
3208 stream_putw(s
, OSPF_IF_PARAM(oi
, v_hello
));
3210 stream_putw(s
, 0); /* hello-interval of 0 for fast-hellos */
3212 if (IS_DEBUG_OSPF_EVENT
)
3213 zlog_debug("make_hello: options: %x, int: %s", OPTIONS(oi
),
3217 stream_putc(s
, OPTIONS(oi
));
3219 /* Set Router Priority. */
3220 stream_putc(s
, PRIORITY(oi
));
3222 /* Set Router Dead Interval. */
3223 stream_putl(s
, OSPF_IF_PARAM(oi
, v_wait
));
3225 /* Set Designated Router. */
3226 stream_put_ipv4(s
, DR(oi
).s_addr
);
3228 p
= stream_get_endp(s
);
3230 /* Set Backup Designated Router. */
3231 stream_put_ipv4(s
, BDR(oi
).s_addr
);
3233 /* Add neighbor seen. */
3234 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
3235 if ((nbr
= rn
->info
))
3236 if (nbr
->router_id
.s_addr
3237 != 0) /* Ignore 0.0.0.0 node. */
3239 != NSM_Attempt
) /* Ignore Down neighbor. */
3241 != NSM_Down
) /* This is myself for
3243 if (!IPV4_ADDR_SAME(
3245 &oi
->ospf
->router_id
)) {
3246 /* Check neighbor is
3248 if (nbr
->d_router
.s_addr
3269 /* Let neighbor generate BackupSeen. */
3271 stream_putl_at(s
, p
, 0); /* ipv4 address, normally */
3276 static int ospf_make_db_desc(struct ospf_interface
*oi
,
3277 struct ospf_neighbor
*nbr
, struct stream
*s
)
3279 struct ospf_lsa
*lsa
;
3280 uint16_t length
= OSPF_DB_DESC_MIN_SIZE
;
3284 struct ospf_lsdb
*lsdb
;
3286 /* Set Interface MTU. */
3287 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
3290 stream_putw(s
, oi
->ifp
->mtu
);
3293 options
= OPTIONS(oi
);
3294 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
))
3295 SET_FLAG(options
, OSPF_OPTION_O
);
3296 stream_putc(s
, options
);
3299 pp
= stream_get_endp(s
);
3300 stream_putc(s
, nbr
->dd_flags
);
3302 /* Set DD Sequence Number. */
3303 stream_putl(s
, nbr
->dd_seqnum
);
3305 /* shortcut unneeded walk of (empty) summary LSDBs */
3306 if (ospf_db_summary_isempty(nbr
))
3309 /* Describe LSA Header from Database Summary List. */
3310 lsdb
= &nbr
->db_sum
;
3312 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++) {
3313 struct route_table
*table
= lsdb
->type
[i
].db
;
3314 struct route_node
*rn
;
3316 for (rn
= route_top(table
); rn
; rn
= route_next(rn
))
3317 if ((lsa
= rn
->info
) != NULL
) {
3318 if (IS_OPAQUE_LSA(lsa
->data
->type
)
3319 && (!CHECK_FLAG(options
, OSPF_OPTION_O
))) {
3320 /* Suppress advertising
3321 * opaque-informations. */
3322 /* Remove LSA from DB summary list. */
3323 ospf_lsdb_delete(lsdb
, lsa
);
3327 if (!CHECK_FLAG(lsa
->flags
, OSPF_LSA_DISCARD
)) {
3328 struct lsa_header
*lsah
;
3331 /* DD packet overflows interface MTU. */
3332 if (length
+ OSPF_LSA_HEADER_SIZE
3333 > ospf_packet_max(oi
))
3336 /* Keep pointer to LS age. */
3337 lsah
= (struct lsa_header
3342 /* Proceed stream pointer. */
3343 stream_put(s
, lsa
->data
,
3344 OSPF_LSA_HEADER_SIZE
);
3345 length
+= OSPF_LSA_HEADER_SIZE
;
3348 ls_age
= LS_AGE(lsa
);
3349 lsah
->ls_age
= htons(ls_age
);
3352 /* Remove LSA from DB summary list. */
3353 ospf_lsdb_delete(lsdb
, lsa
);
3357 /* Update 'More' bit */
3358 if (ospf_db_summary_isempty(nbr
)) {
3360 if (nbr
->state
>= NSM_Exchange
) {
3361 UNSET_FLAG(nbr
->dd_flags
, OSPF_DD_FLAG_M
);
3362 /* Rewrite DD flags */
3363 stream_putc_at(s
, pp
, nbr
->dd_flags
);
3365 assert(IS_SET_DD_M(nbr
->dd_flags
));
3371 static int ospf_make_ls_req_func(struct stream
*s
, uint16_t *length
,
3372 unsigned long delta
, struct ospf_neighbor
*nbr
,
3373 struct ospf_lsa
*lsa
)
3375 struct ospf_interface
*oi
;
3379 /* LS Request packet overflows interface MTU. */
3380 if (*length
+ delta
> ospf_packet_max(oi
))
3383 stream_putl(s
, lsa
->data
->type
);
3384 stream_put_ipv4(s
, lsa
->data
->id
.s_addr
);
3385 stream_put_ipv4(s
, lsa
->data
->adv_router
.s_addr
);
3387 ospf_lsa_unlock(&nbr
->ls_req_last
);
3388 nbr
->ls_req_last
= ospf_lsa_lock(lsa
);
3394 static int ospf_make_ls_req(struct ospf_neighbor
*nbr
, struct stream
*s
)
3396 struct ospf_lsa
*lsa
;
3397 uint16_t length
= OSPF_LS_REQ_MIN_SIZE
;
3398 unsigned long delta
= stream_get_endp(s
) + 12;
3399 struct route_table
*table
;
3400 struct route_node
*rn
;
3402 struct ospf_lsdb
*lsdb
;
3404 lsdb
= &nbr
->ls_req
;
3406 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++) {
3407 table
= lsdb
->type
[i
].db
;
3408 for (rn
= route_top(table
); rn
; rn
= route_next(rn
))
3409 if ((lsa
= (rn
->info
)) != NULL
)
3410 if (ospf_make_ls_req_func(s
, &length
, delta
,
3413 route_unlock_node(rn
);
3420 static int ls_age_increment(struct ospf_lsa
*lsa
, int delay
)
3424 age
= IS_LSA_MAXAGE(lsa
) ? OSPF_LSA_MAXAGE
: LS_AGE(lsa
) + delay
;
3426 return (age
> OSPF_LSA_MAXAGE
? OSPF_LSA_MAXAGE
: age
);
3429 static int ospf_make_ls_upd(struct ospf_interface
*oi
, struct list
*update
,
3432 struct ospf_lsa
*lsa
;
3433 struct listnode
*node
;
3434 uint16_t length
= 0;
3435 unsigned int size_noauth
;
3436 unsigned long delta
= stream_get_endp(s
);
3440 if (IS_DEBUG_OSPF_EVENT
)
3441 zlog_debug("ospf_make_ls_upd: Start");
3443 pp
= stream_get_endp(s
);
3444 stream_forward_endp(s
, OSPF_LS_UPD_MIN_SIZE
);
3445 length
+= OSPF_LS_UPD_MIN_SIZE
;
3447 /* Calculate amount of packet usable for data. */
3448 size_noauth
= stream_get_size(s
) - ospf_packet_authspace(oi
);
3450 while ((node
= listhead(update
)) != NULL
) {
3451 struct lsa_header
*lsah
;
3454 if (IS_DEBUG_OSPF_EVENT
)
3455 zlog_debug("ospf_make_ls_upd: List Iteration %d",
3458 lsa
= listgetdata(node
);
3463 if (length
+ delta
+ ntohs(lsa
->data
->length
) > size_noauth
)
3466 /* Keep pointer to LS age. */
3467 lsah
= (struct lsa_header
*)(STREAM_DATA(s
)
3468 + stream_get_endp(s
));
3470 /* Put LSA to Link State Request. */
3471 stream_put(s
, lsa
->data
, ntohs(lsa
->data
->length
));
3474 /* each hop must increment an lsa_age by transmit_delay
3475 of OSPF interface */
3476 ls_age
= ls_age_increment(lsa
,
3477 OSPF_IF_PARAM(oi
, transmit_delay
));
3478 lsah
->ls_age
= htons(ls_age
);
3480 length
+= ntohs(lsa
->data
->length
);
3483 list_delete_node(update
, node
);
3484 ospf_lsa_unlock(&lsa
); /* oi->ls_upd_queue */
3487 /* Now set #LSAs. */
3488 stream_putl_at(s
, pp
, count
);
3490 if (IS_DEBUG_OSPF_EVENT
)
3491 zlog_debug("ospf_make_ls_upd: Stop");
3495 static int ospf_make_ls_ack(struct ospf_interface
*oi
, struct list
*ack
,
3498 struct listnode
*node
, *nnode
;
3499 uint16_t length
= OSPF_LS_ACK_MIN_SIZE
;
3500 unsigned long delta
= stream_get_endp(s
) + 24;
3501 struct ospf_lsa
*lsa
;
3503 for (ALL_LIST_ELEMENTS(ack
, node
, nnode
, lsa
)) {
3506 if (length
+ delta
> ospf_packet_max(oi
))
3509 stream_put(s
, lsa
->data
, OSPF_LSA_HEADER_SIZE
);
3510 length
+= OSPF_LSA_HEADER_SIZE
;
3512 listnode_delete(ack
, lsa
);
3513 ospf_lsa_unlock(&lsa
); /* oi->ls_ack_direct.ls_ack */
3519 static void ospf_hello_send_sub(struct ospf_interface
*oi
, in_addr_t addr
)
3521 struct ospf_packet
*op
;
3522 uint16_t length
= OSPF_HEADER_SIZE
;
3524 op
= ospf_packet_new(oi
->ifp
->mtu
);
3526 /* Prepare OSPF common header. */
3527 ospf_make_header(OSPF_MSG_HELLO
, oi
, op
->s
);
3529 /* Prepare OSPF Hello body. */
3530 length
+= ospf_make_hello(oi
, op
->s
);
3532 /* Fill OSPF header. */
3533 ospf_fill_header(oi
, op
->s
, length
);
3535 /* Set packet length. */
3536 op
->length
= length
;
3538 op
->dst
.s_addr
= addr
;
3540 if (IS_DEBUG_OSPF_EVENT
) {
3541 if (oi
->ospf
->vrf_id
)
3543 "%s: Hello Tx interface %s ospf vrf %s id %u",
3544 __PRETTY_FUNCTION__
, oi
->ifp
->name
,
3545 ospf_vrf_id_to_name(oi
->ospf
->vrf_id
),
3548 /* Add packet to the top of the interface output queue, so that they
3549 * can't get delayed by things like long queues of LS Update packets
3551 ospf_packet_add_top(oi
, op
);
3553 /* Hook thread to write packet. */
3554 OSPF_ISM_WRITE_ON(oi
->ospf
);
3557 static void ospf_poll_send(struct ospf_nbr_nbma
*nbr_nbma
)
3559 struct ospf_interface
*oi
;
3564 /* If this is passive interface, do not send OSPF Hello. */
3565 if (OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
)
3568 if (oi
->type
!= OSPF_IFTYPE_NBMA
)
3571 if (nbr_nbma
->nbr
!= NULL
&& nbr_nbma
->nbr
->state
!= NSM_Down
)
3574 if (PRIORITY(oi
) == 0)
3577 if (nbr_nbma
->priority
== 0 && oi
->state
!= ISM_DR
3578 && oi
->state
!= ISM_Backup
)
3581 ospf_hello_send_sub(oi
, nbr_nbma
->addr
.s_addr
);
3584 int ospf_poll_timer(struct thread
*thread
)
3586 struct ospf_nbr_nbma
*nbr_nbma
;
3588 nbr_nbma
= THREAD_ARG(thread
);
3589 nbr_nbma
->t_poll
= NULL
;
3591 if (IS_DEBUG_OSPF(nsm
, NSM_TIMERS
))
3592 zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)",
3593 IF_NAME(nbr_nbma
->oi
), inet_ntoa(nbr_nbma
->addr
));
3595 ospf_poll_send(nbr_nbma
);
3597 if (nbr_nbma
->v_poll
> 0)
3598 OSPF_POLL_TIMER_ON(nbr_nbma
->t_poll
, ospf_poll_timer
,
3605 int ospf_hello_reply_timer(struct thread
*thread
)
3607 struct ospf_neighbor
*nbr
;
3609 nbr
= THREAD_ARG(thread
);
3610 nbr
->t_hello_reply
= NULL
;
3614 if (IS_DEBUG_OSPF(nsm
, NSM_TIMERS
))
3615 zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)",
3616 IF_NAME(nbr
->oi
), inet_ntoa(nbr
->router_id
));
3618 ospf_hello_send_sub(nbr
->oi
, nbr
->address
.u
.prefix4
.s_addr
);
3623 /* Send OSPF Hello. */
3624 void ospf_hello_send(struct ospf_interface
*oi
)
3626 /* If this is passive interface, do not send OSPF Hello. */
3627 if (OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
)
3630 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
3631 struct ospf_neighbor
*nbr
;
3632 struct route_node
*rn
;
3634 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
3635 if ((nbr
= rn
->info
))
3636 if (nbr
!= oi
->nbr_self
)
3637 if (nbr
->state
!= NSM_Down
) {
3638 /* RFC 2328 Section 9.5.1
3639 If the router is not
3640 eligible to become Designated
3642 it must periodically send
3643 Hello Packets to both the
3644 Designated Router and the
3645 Backup Designated Router (if
3648 if (PRIORITY(oi
) == 0
3659 /* If the router is eligible to
3660 become Designated Router, it
3661 must periodically send Hello
3662 Packets to all neighbors that
3663 are also eligible. In
3664 addition, if the router is
3666 Designated Router or Backup
3667 Designated Router, it must
3669 send periodic Hello Packets
3670 to all other neighbors. */
3672 if (nbr
->priority
== 0
3673 && oi
->state
== ISM_DROther
)
3675 /* if oi->state == Waiting, send
3676 * hello to all neighbors */
3677 ospf_hello_send_sub(
3679 nbr
->address
.u
.prefix4
3683 /* Decide destination address. */
3684 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
3685 ospf_hello_send_sub(oi
, oi
->vl_data
->peer_addr
.s_addr
);
3687 ospf_hello_send_sub(oi
, htonl(OSPF_ALLSPFROUTERS
));
3691 /* Send OSPF Database Description. */
3692 void ospf_db_desc_send(struct ospf_neighbor
*nbr
)
3694 struct ospf_interface
*oi
;
3695 struct ospf_packet
*op
;
3696 uint16_t length
= OSPF_HEADER_SIZE
;
3699 op
= ospf_packet_new(oi
->ifp
->mtu
);
3701 /* Prepare OSPF common header. */
3702 ospf_make_header(OSPF_MSG_DB_DESC
, oi
, op
->s
);
3704 /* Prepare OSPF Database Description body. */
3705 length
+= ospf_make_db_desc(oi
, nbr
, op
->s
);
3707 /* Fill OSPF header. */
3708 ospf_fill_header(oi
, op
->s
, length
);
3710 /* Set packet length. */
3711 op
->length
= length
;
3713 /* Decide destination address. */
3714 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3715 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3717 op
->dst
= nbr
->address
.u
.prefix4
;
3719 /* Add packet to the interface output queue. */
3720 ospf_packet_add(oi
, op
);
3722 /* Hook thread to write packet. */
3723 OSPF_ISM_WRITE_ON(oi
->ospf
);
3725 /* Remove old DD packet, then copy new one and keep in neighbor
3728 ospf_packet_free(nbr
->last_send
);
3729 nbr
->last_send
= ospf_packet_dup(op
);
3730 monotime(&nbr
->last_send_ts
);
3733 /* Re-send Database Description. */
3734 void ospf_db_desc_resend(struct ospf_neighbor
*nbr
)
3736 struct ospf_interface
*oi
;
3740 /* Add packet to the interface output queue. */
3741 ospf_packet_add(oi
, ospf_packet_dup(nbr
->last_send
));
3743 /* Hook thread to write packet. */
3744 OSPF_ISM_WRITE_ON(oi
->ospf
);
3747 /* Send Link State Request. */
3748 void ospf_ls_req_send(struct ospf_neighbor
*nbr
)
3750 struct ospf_interface
*oi
;
3751 struct ospf_packet
*op
;
3752 uint16_t length
= OSPF_HEADER_SIZE
;
3755 op
= ospf_packet_new(oi
->ifp
->mtu
);
3757 /* Prepare OSPF common header. */
3758 ospf_make_header(OSPF_MSG_LS_REQ
, oi
, op
->s
);
3760 /* Prepare OSPF Link State Request body. */
3761 length
+= ospf_make_ls_req(nbr
, op
->s
);
3762 if (length
== OSPF_HEADER_SIZE
) {
3763 ospf_packet_free(op
);
3767 /* Fill OSPF header. */
3768 ospf_fill_header(oi
, op
->s
, length
);
3770 /* Set packet length. */
3771 op
->length
= length
;
3773 /* Decide destination address. */
3774 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3775 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3777 op
->dst
= nbr
->address
.u
.prefix4
;
3779 /* Add packet to the interface output queue. */
3780 ospf_packet_add(oi
, op
);
3782 /* Hook thread to write packet. */
3783 OSPF_ISM_WRITE_ON(oi
->ospf
);
3785 /* Add Link State Request Retransmission Timer. */
3786 OSPF_NSM_TIMER_ON(nbr
->t_ls_req
, ospf_ls_req_timer
, nbr
->v_ls_req
);
3789 /* Send Link State Update with an LSA. */
3790 void ospf_ls_upd_send_lsa(struct ospf_neighbor
*nbr
, struct ospf_lsa
*lsa
,
3793 struct list
*update
;
3795 update
= list_new();
3797 listnode_add(update
, lsa
);
3799 /*ospf instance is going down, send self originated
3800 * MAXAGE LSA update to neighbors to remove from LSDB */
3801 if (nbr
->oi
->ospf
->inst_shutdown
&& IS_LSA_MAXAGE(lsa
))
3802 ospf_ls_upd_send(nbr
, update
, flag
, 1);
3804 ospf_ls_upd_send(nbr
, update
, flag
, 0);
3806 list_delete_and_null(&update
);
3809 /* Determine size for packet. Must be at least big enough to accomodate next
3810 * LSA on list, which may be bigger than MTU size.
3812 * Return pointer to new ospf_packet
3813 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3814 * on packet sizes (in which case offending LSA is deleted from update list)
3816 static struct ospf_packet
*ospf_ls_upd_packet_new(struct list
*update
,
3817 struct ospf_interface
*oi
)
3819 struct ospf_lsa
*lsa
;
3820 struct listnode
*ln
;
3822 static char warned
= 0;
3824 lsa
= listgetdata((ln
= listhead(update
)));
3827 if ((OSPF_LS_UPD_MIN_SIZE
+ ntohs(lsa
->data
->length
))
3828 > ospf_packet_max(oi
)) {
3831 "ospf_ls_upd_packet_new: oversized LSA encountered!"
3832 "will need to fragment. Not optimal. Try divide up"
3833 " your network with areas. Use 'debug ospf packet send'"
3834 " to see details, or look at 'show ip ospf database ..'");
3838 if (IS_DEBUG_OSPF_PACKET(0, SEND
))
3840 "ospf_ls_upd_packet_new: oversized LSA id:%s,"
3841 " %d bytes originated by %s, will be fragmented!",
3842 inet_ntoa(lsa
->data
->id
),
3843 ntohs(lsa
->data
->length
),
3844 inet_ntoa(lsa
->data
->adv_router
));
3847 * Allocate just enough to fit this LSA only, to avoid including
3849 * LSAs in fragmented LSA Updates.
3851 size
= ntohs(lsa
->data
->length
)
3852 + (oi
->ifp
->mtu
- ospf_packet_max(oi
))
3853 + OSPF_LS_UPD_MIN_SIZE
;
3855 size
= oi
->ifp
->mtu
;
3857 if (size
> OSPF_MAX_PACKET_SIZE
) {
3859 "ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3860 " %d bytes, packet size %ld, dropping it completely."
3861 " OSPF routing is broken!",
3862 inet_ntoa(lsa
->data
->id
), ntohs(lsa
->data
->length
),
3864 list_delete_node(update
, ln
);
3868 /* IP header is built up separately by ospf_write(). This means, that we
3870 * reduce the "affordable" size just calculated by length of an IP
3872 * This makes sure, that even if we manage to fill the payload with LSA
3874 * completely, the final packet (our data plus IP header) still fits
3876 * outgoing interface MTU. This correction isn't really meaningful for
3878 * oversized LSA, but for consistency the correction is done for both
3881 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3883 return ospf_packet_new(size
- sizeof(struct ip
));
3886 static void ospf_ls_upd_queue_send(struct ospf_interface
*oi
,
3887 struct list
*update
, struct in_addr addr
,
3890 struct ospf_packet
*op
;
3891 uint16_t length
= OSPF_HEADER_SIZE
;
3893 if (IS_DEBUG_OSPF_EVENT
)
3894 zlog_debug("listcount = %d, [%s]dst %s", listcount(update
),
3895 IF_NAME(oi
), inet_ntoa(addr
));
3897 /* Check that we have really something to process */
3898 if (listcount(update
) == 0)
3901 op
= ospf_ls_upd_packet_new(update
, oi
);
3903 /* Prepare OSPF common header. */
3904 ospf_make_header(OSPF_MSG_LS_UPD
, oi
, op
->s
);
3906 /* Prepare OSPF Link State Update body.
3907 * Includes Type-7 translation.
3909 length
+= ospf_make_ls_upd(oi
, update
, op
->s
);
3911 /* Fill OSPF header. */
3912 ospf_fill_header(oi
, op
->s
, length
);
3914 /* Set packet length. */
3915 op
->length
= length
;
3917 /* Decide destination address. */
3918 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3919 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3921 op
->dst
.s_addr
= addr
.s_addr
;
3923 /* Add packet to the interface output queue. */
3924 ospf_packet_add(oi
, op
);
3925 /* Call ospf_write() right away to send ospf packets to neighbors */
3926 if (send_lsupd_now
) {
3927 struct thread os_packet_thd
;
3929 os_packet_thd
.arg
= (void *)oi
->ospf
;
3930 if (oi
->on_write_q
== 0) {
3931 listnode_add(oi
->ospf
->oi_write_q
, oi
);
3934 ospf_write(&os_packet_thd
);
3936 /* Hook thread to write packet. */
3937 OSPF_ISM_WRITE_ON(oi
->ospf
);
3941 static int ospf_ls_upd_send_queue_event(struct thread
*thread
)
3943 struct ospf_interface
*oi
= THREAD_ARG(thread
);
3944 struct route_node
*rn
;
3945 struct route_node
*rnext
;
3946 struct list
*update
;
3949 oi
->t_ls_upd_event
= NULL
;
3951 if (IS_DEBUG_OSPF_EVENT
)
3952 zlog_debug("ospf_ls_upd_send_queue start");
3954 for (rn
= route_top(oi
->ls_upd_queue
); rn
; rn
= rnext
) {
3955 rnext
= route_next(rn
);
3957 if (rn
->info
== NULL
)
3960 update
= (struct list
*)rn
->info
;
3962 ospf_ls_upd_queue_send(oi
, update
, rn
->p
.u
.prefix4
, 0);
3964 /* list might not be empty. */
3965 if (listcount(update
) == 0) {
3966 list_delete_and_null((struct list
**)&rn
->info
);
3967 route_unlock_node(rn
);
3973 if (IS_DEBUG_OSPF_EVENT
)
3975 "ospf_ls_upd_send_queue: update lists not cleared,"
3976 " %d nodes to try again, raising new event",
3978 oi
->t_ls_upd_event
= NULL
;
3979 thread_add_event(master
, ospf_ls_upd_send_queue_event
, oi
, 0,
3980 &oi
->t_ls_upd_event
);
3983 if (IS_DEBUG_OSPF_EVENT
)
3984 zlog_debug("ospf_ls_upd_send_queue stop");
3989 void ospf_ls_upd_send(struct ospf_neighbor
*nbr
, struct list
*update
, int flag
,
3992 struct ospf_interface
*oi
;
3993 struct ospf_lsa
*lsa
;
3994 struct prefix_ipv4 p
;
3995 struct route_node
*rn
;
3996 struct listnode
*node
;
4001 p
.prefixlen
= IPV4_MAX_BITLEN
;
4003 /* Decide destination address. */
4004 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
4005 p
.prefix
= oi
->vl_data
->peer_addr
;
4006 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4007 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4008 else if (flag
== OSPF_SEND_PACKET_DIRECT
)
4009 p
.prefix
= nbr
->address
.u
.prefix4
;
4010 else if (oi
->state
== ISM_DR
|| oi
->state
== ISM_Backup
)
4011 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4012 else if (oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
4013 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4015 p
.prefix
.s_addr
= htonl(OSPF_ALLDROUTERS
);
4017 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
4018 if (flag
== OSPF_SEND_PACKET_INDIRECT
)
4020 "* LS-Update is directly sent on NBMA network.");
4021 if (IPV4_ADDR_SAME(&oi
->address
->u
.prefix4
, &p
.prefix
))
4022 zlog_warn("* LS-Update is sent to myself.");
4025 rn
= route_node_get(oi
->ls_upd_queue
, (struct prefix
*)&p
);
4027 if (rn
->info
== NULL
)
4028 rn
->info
= list_new();
4030 route_unlock_node(rn
);
4032 for (ALL_LIST_ELEMENTS_RO(update
, node
, lsa
))
4033 listnode_add(rn
->info
,
4034 ospf_lsa_lock(lsa
)); /* oi->ls_upd_queue */
4035 if (send_lsupd_now
) {
4036 struct list
*send_update_list
;
4037 struct route_node
*rn
, *rnext
;
4039 for (rn
= route_top(oi
->ls_upd_queue
); rn
; rn
= rnext
) {
4040 rnext
= route_next(rn
);
4042 if (rn
->info
== NULL
)
4045 send_update_list
= (struct list
*)rn
->info
;
4047 ospf_ls_upd_queue_send(oi
, send_update_list
,
4048 rn
->p
.u
.prefix4
, 1);
4051 thread_add_event(master
, ospf_ls_upd_send_queue_event
, oi
, 0,
4052 &oi
->t_ls_upd_event
);
4055 static void ospf_ls_ack_send_list(struct ospf_interface
*oi
, struct list
*ack
,
4058 struct ospf_packet
*op
;
4059 uint16_t length
= OSPF_HEADER_SIZE
;
4061 op
= ospf_packet_new(oi
->ifp
->mtu
);
4063 /* Prepare OSPF common header. */
4064 ospf_make_header(OSPF_MSG_LS_ACK
, oi
, op
->s
);
4066 /* Prepare OSPF Link State Acknowledgment body. */
4067 length
+= ospf_make_ls_ack(oi
, ack
, op
->s
);
4069 /* Fill OSPF header. */
4070 ospf_fill_header(oi
, op
->s
, length
);
4072 /* Set packet length. */
4073 op
->length
= length
;
4075 /* Decide destination address. */
4076 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4077 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4079 op
->dst
.s_addr
= dst
.s_addr
;
4081 /* Add packet to the interface output queue. */
4082 ospf_packet_add(oi
, op
);
4084 /* Hook thread to write packet. */
4085 OSPF_ISM_WRITE_ON(oi
->ospf
);
4088 static int ospf_ls_ack_send_event(struct thread
*thread
)
4090 struct ospf_interface
*oi
= THREAD_ARG(thread
);
4092 oi
->t_ls_ack_direct
= NULL
;
4094 while (listcount(oi
->ls_ack_direct
.ls_ack
))
4095 ospf_ls_ack_send_list(oi
, oi
->ls_ack_direct
.ls_ack
,
4096 oi
->ls_ack_direct
.dst
);
4101 void ospf_ls_ack_send(struct ospf_neighbor
*nbr
, struct ospf_lsa
*lsa
)
4103 struct ospf_interface
*oi
= nbr
->oi
;
4105 if (listcount(oi
->ls_ack_direct
.ls_ack
) == 0)
4106 oi
->ls_ack_direct
.dst
= nbr
->address
.u
.prefix4
;
4108 listnode_add(oi
->ls_ack_direct
.ls_ack
, ospf_lsa_lock(lsa
));
4110 thread_add_event(master
, ospf_ls_ack_send_event
, oi
, 0,
4111 &oi
->t_ls_ack_direct
);
4114 /* Send Link State Acknowledgment delayed. */
4115 void ospf_ls_ack_send_delayed(struct ospf_interface
*oi
)
4119 /* Decide destination address. */
4120 /* RFC2328 Section 13.5 On non-broadcast
4121 networks, delayed Link State Acknowledgment packets must be
4122 unicast separately over each adjacency (i.e., neighbor whose
4123 state is >= Exchange). */
4124 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
4125 struct ospf_neighbor
*nbr
;
4126 struct route_node
*rn
;
4128 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
4129 if ((nbr
= rn
->info
) != NULL
)
4130 if (nbr
!= oi
->nbr_self
4131 && nbr
->state
>= NSM_Exchange
)
4132 while (listcount(oi
->ls_ack
))
4133 ospf_ls_ack_send_list(
4135 nbr
->address
.u
.prefix4
);
4138 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
4139 dst
.s_addr
= oi
->vl_data
->peer_addr
.s_addr
;
4140 else if (oi
->state
== ISM_DR
|| oi
->state
== ISM_Backup
)
4141 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4142 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4143 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4144 else if (oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
4145 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4147 dst
.s_addr
= htonl(OSPF_ALLDROUTERS
);
4149 while (listcount(oi
->ls_ack
))
4150 ospf_ls_ack_send_list(oi
, oi
->ls_ack
, dst
);
4154 * On pt-to-pt links, all OSPF control packets are sent to the multicast
4155 * address. As a result, the kernel does not need to learn the interface
4156 * MAC of the OSPF neighbor. However, in our world, this will delay
4157 * convergence. Take the case when due to a link flap, all routes now
4158 * want to use an interface which was deemed to be costlier prior to this
4159 * event. For routes that will be installed, the missing MAC will have
4160 * punt-to-CPU set on them. This may overload the CPU control path that
4161 * can be avoided if the MAC was known apriori.
4163 #define OSPF_PING_NBR_STR_MAX (BUFSIZ)
4164 void ospf_proactively_arp(struct ospf_neighbor
*nbr
)
4166 char ping_nbr
[OSPF_PING_NBR_STR_MAX
];
4169 if (!nbr
|| !nbr
->oi
|| !nbr
->oi
->ifp
)
4172 snprintf(ping_nbr
, sizeof(ping_nbr
),
4173 "ping -c 1 -I %s %s > /dev/null 2>&1 &", nbr
->oi
->ifp
->name
,
4174 inet_ntoa(nbr
->address
.u
.prefix4
));
4176 ret
= system(ping_nbr
);
4177 if (IS_DEBUG_OSPF_EVENT
)
4178 zlog_debug("Executed %s %s", ping_nbr
,
4179 ((ret
== 0) ? "successfully" : "but failed"));