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 u_int16_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 u_int16_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
);
151 struct ospf_fifo
*ospf_fifo_new()
153 struct ospf_fifo
*new;
155 new = XCALLOC(MTYPE_OSPF_FIFO
, sizeof(struct ospf_fifo
));
159 /* Add new packet to fifo. */
160 void ospf_fifo_push(struct ospf_fifo
*fifo
, struct ospf_packet
*op
)
163 fifo
->tail
->next
= op
;
172 /* Add new packet to head of fifo. */
173 static void ospf_fifo_push_head(struct ospf_fifo
*fifo
, struct ospf_packet
*op
)
175 op
->next
= fifo
->head
;
177 if (fifo
->tail
== NULL
)
185 /* Delete first packet from fifo. */
186 struct ospf_packet
*ospf_fifo_pop(struct ospf_fifo
*fifo
)
188 struct ospf_packet
*op
;
193 fifo
->head
= op
->next
;
195 if (fifo
->head
== NULL
)
204 /* Return first fifo entry. */
205 struct ospf_packet
*ospf_fifo_head(struct ospf_fifo
*fifo
)
210 /* Flush ospf packet fifo. */
211 void ospf_fifo_flush(struct ospf_fifo
*fifo
)
213 struct ospf_packet
*op
;
214 struct ospf_packet
*next
;
216 for (op
= fifo
->head
; op
; op
= next
) {
218 ospf_packet_free(op
);
220 fifo
->head
= fifo
->tail
= NULL
;
224 /* Free ospf packet fifo. */
225 void ospf_fifo_free(struct ospf_fifo
*fifo
)
227 ospf_fifo_flush(fifo
);
229 XFREE(MTYPE_OSPF_FIFO
, fifo
);
232 void ospf_packet_add(struct ospf_interface
*oi
, struct ospf_packet
*op
)
236 "ospf_packet_add(interface %s in state %d [%s], packet type %s, "
237 "destination %s) called with NULL obuf, ignoring "
238 "(please report this bug)!\n",
239 IF_NAME(oi
), oi
->state
,
240 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
),
241 lookup_msg(ospf_packet_type_str
,
242 stream_getc_from(op
->s
, 1), NULL
),
247 /* Add packet to end of queue. */
248 ospf_fifo_push(oi
->obuf
, op
);
250 /* Debug of packet fifo*/
251 /* ospf_fifo_debug (oi->obuf); */
254 static void ospf_packet_add_top(struct ospf_interface
*oi
,
255 struct ospf_packet
*op
)
259 "ospf_packet_add(interface %s in state %d [%s], packet type %s, "
260 "destination %s) called with NULL obuf, ignoring "
261 "(please report this bug)!\n",
262 IF_NAME(oi
), oi
->state
,
263 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
),
264 lookup_msg(ospf_packet_type_str
,
265 stream_getc_from(op
->s
, 1), NULL
),
270 /* Add packet to head of queue. */
271 ospf_fifo_push_head(oi
->obuf
, op
);
273 /* Debug of packet fifo*/
274 /* ospf_fifo_debug (oi->obuf); */
277 void ospf_packet_delete(struct ospf_interface
*oi
)
279 struct ospf_packet
*op
;
281 op
= ospf_fifo_pop(oi
->obuf
);
284 ospf_packet_free(op
);
287 struct ospf_packet
*ospf_packet_dup(struct ospf_packet
*op
)
289 struct ospf_packet
*new;
291 if (stream_get_endp(op
->s
) != op
->length
)
294 "ospf_packet_dup stream %lu ospf_packet %u size mismatch",
295 (u_long
)STREAM_SIZE(op
->s
), op
->length
);
297 /* Reserve space for MD5 authentication that may be added later. */
298 new = ospf_packet_new(stream_get_endp(op
->s
) + OSPF_AUTH_MD5_SIZE
);
299 stream_copy(new->s
, op
->s
);
302 new->length
= op
->length
;
308 static unsigned int ospf_packet_authspace(struct ospf_interface
*oi
)
312 if (ospf_auth_type(oi
) == OSPF_AUTH_CRYPTOGRAPHIC
)
313 auth
= OSPF_AUTH_MD5_SIZE
;
318 static unsigned int ospf_packet_max(struct ospf_interface
*oi
)
322 max
= oi
->ifp
->mtu
- ospf_packet_authspace(oi
);
324 max
-= (OSPF_HEADER_SIZE
+ sizeof(struct ip
));
330 static int ospf_check_md5_digest(struct ospf_interface
*oi
,
331 struct ospf_header
*ospfh
)
334 unsigned char digest
[OSPF_AUTH_MD5_SIZE
];
335 struct crypt_key
*ck
;
336 struct ospf_neighbor
*nbr
;
337 u_int16_t length
= ntohs(ospfh
->length
);
339 /* Get secret key. */
340 ck
= ospf_crypt_key_lookup(OSPF_IF_PARAM(oi
, auth_crypt
),
341 ospfh
->u
.crypt
.key_id
);
343 zlog_warn("interface %s: ospf_check_md5 no key %d", IF_NAME(oi
),
344 ospfh
->u
.crypt
.key_id
);
348 /* check crypto seqnum. */
349 nbr
= ospf_nbr_lookup_by_routerid(oi
->nbrs
, &ospfh
->router_id
);
352 && ntohl(nbr
->crypt_seqnum
) > ntohl(ospfh
->u
.crypt
.crypt_seqnum
)) {
354 "interface %s: ospf_check_md5 bad sequence %d (expect %d)",
355 IF_NAME(oi
), ntohl(ospfh
->u
.crypt
.crypt_seqnum
),
356 ntohl(nbr
->crypt_seqnum
));
360 /* Generate a digest for the ospf packet - their digest + our digest. */
361 memset(&ctx
, 0, sizeof(ctx
));
363 MD5Update(&ctx
, ospfh
, length
);
364 MD5Update(&ctx
, ck
->auth_key
, OSPF_AUTH_MD5_SIZE
);
365 MD5Final(digest
, &ctx
);
367 /* compare the two */
368 if (memcmp((caddr_t
)ospfh
+ length
, digest
, OSPF_AUTH_MD5_SIZE
)) {
369 zlog_warn("interface %s: ospf_check_md5 checksum mismatch",
374 /* save neighbor's crypt_seqnum */
376 nbr
->crypt_seqnum
= ospfh
->u
.crypt
.crypt_seqnum
;
380 /* This function is called from ospf_write(), it will detect the
381 authentication scheme and if it is MD5, it will change the sequence
382 and update the MD5 digest. */
383 static int ospf_make_md5_digest(struct ospf_interface
*oi
,
384 struct ospf_packet
*op
)
386 struct ospf_header
*ospfh
;
387 unsigned char digest
[OSPF_AUTH_MD5_SIZE
] = {0};
391 struct crypt_key
*ck
;
392 const u_int8_t
*auth_key
;
394 ibuf
= STREAM_DATA(op
->s
);
395 ospfh
= (struct ospf_header
*)ibuf
;
397 if (ntohs(ospfh
->auth_type
) != OSPF_AUTH_CRYPTOGRAPHIC
)
400 /* We do this here so when we dup a packet, we don't have to
401 waste CPU rewriting other headers.
403 Note that quagga_time /deliberately/ is not used here */
404 t
= (time(NULL
) & 0xFFFFFFFF);
405 if (t
> oi
->crypt_seqnum
)
406 oi
->crypt_seqnum
= t
;
410 ospfh
->u
.crypt
.crypt_seqnum
= htonl(oi
->crypt_seqnum
);
412 /* Get MD5 Authentication key from auth_key list. */
413 if (list_isempty(OSPF_IF_PARAM(oi
, auth_crypt
)))
414 auth_key
= (const u_int8_t
*)digest
;
416 ck
= listgetdata(listtail(OSPF_IF_PARAM(oi
, auth_crypt
)));
417 auth_key
= ck
->auth_key
;
420 /* Generate a digest for the entire packet + our secret key. */
421 memset(&ctx
, 0, sizeof(ctx
));
423 MD5Update(&ctx
, ibuf
, ntohs(ospfh
->length
));
424 MD5Update(&ctx
, auth_key
, OSPF_AUTH_MD5_SIZE
);
425 MD5Final(digest
, &ctx
);
427 /* Append md5 digest to the end of the stream. */
428 stream_put(op
->s
, digest
, OSPF_AUTH_MD5_SIZE
);
430 /* We do *NOT* increment the OSPF header length. */
431 op
->length
= ntohs(ospfh
->length
) + OSPF_AUTH_MD5_SIZE
;
433 if (stream_get_endp(op
->s
) != op
->length
)
436 "ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
437 (u_long
)stream_get_endp(op
->s
), op
->length
);
439 return OSPF_AUTH_MD5_SIZE
;
443 static int ospf_ls_req_timer(struct thread
*thread
)
445 struct ospf_neighbor
*nbr
;
447 nbr
= THREAD_ARG(thread
);
448 nbr
->t_ls_req
= NULL
;
450 /* Send Link State Request. */
451 if (ospf_ls_request_count(nbr
))
452 ospf_ls_req_send(nbr
);
454 /* Set Link State Request retransmission timer. */
455 OSPF_NSM_TIMER_ON(nbr
->t_ls_req
, ospf_ls_req_timer
, nbr
->v_ls_req
);
460 void ospf_ls_req_event(struct ospf_neighbor
*nbr
)
463 thread_cancel(nbr
->t_ls_req
);
464 nbr
->t_ls_req
= NULL
;
466 nbr
->t_ls_req
= NULL
;
467 thread_add_event(master
, ospf_ls_req_timer
, nbr
, 0, &nbr
->t_ls_req
);
470 /* Cyclic timer function. Fist registered in ospf_nbr_new () in
472 int ospf_ls_upd_timer(struct thread
*thread
)
474 struct ospf_neighbor
*nbr
;
476 nbr
= THREAD_ARG(thread
);
477 nbr
->t_ls_upd
= NULL
;
479 /* Send Link State Update. */
480 if (ospf_ls_retransmit_count(nbr
) > 0) {
482 struct ospf_lsdb
*lsdb
;
484 int retransmit_interval
;
486 retransmit_interval
=
487 OSPF_IF_PARAM(nbr
->oi
, retransmit_interval
);
489 lsdb
= &nbr
->ls_rxmt
;
492 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++) {
493 struct route_table
*table
= lsdb
->type
[i
].db
;
494 struct route_node
*rn
;
496 for (rn
= route_top(table
); rn
; rn
= route_next(rn
)) {
497 struct ospf_lsa
*lsa
;
499 if ((lsa
= rn
->info
) != NULL
) {
500 /* Don't retransmit an LSA if we
502 the last RxmtInterval seconds - this
504 neighbour a chance to acknowledge the
506 have ben just received before the
508 fired. This is a small tweak to what
510 but it will cut out out a lot of
513 if (monotime_since(&lsa
->tv_recv
, NULL
)
514 >= retransmit_interval
* 1000000LL)
515 listnode_add(update
, rn
->info
);
520 if (listcount(update
) > 0)
521 ospf_ls_upd_send(nbr
, update
,
522 OSPF_SEND_PACKET_DIRECT
, 0);
523 list_delete_and_null(&update
);
526 /* Set LS Update retransmission timer. */
527 OSPF_NSM_TIMER_ON(nbr
->t_ls_upd
, ospf_ls_upd_timer
, nbr
->v_ls_upd
);
532 int ospf_ls_ack_timer(struct thread
*thread
)
534 struct ospf_interface
*oi
;
536 oi
= THREAD_ARG(thread
);
539 /* Send Link State Acknowledgment. */
540 if (listcount(oi
->ls_ack
) > 0)
541 ospf_ls_ack_send_delayed(oi
);
543 /* Set LS Ack timer. */
544 OSPF_ISM_TIMER_ON(oi
->t_ls_ack
, ospf_ls_ack_timer
, oi
->v_ls_ack
);
549 #ifdef WANT_OSPF_WRITE_FRAGMENT
550 static void ospf_write_frags(int fd
, struct ospf_packet
*op
, struct ip
*iph
,
551 struct msghdr
*msg
, unsigned int maxdatasize
,
552 unsigned int mtu
, int flags
, u_char type
)
554 #define OSPF_WRITE_FRAG_SHIFT 3
559 assert(op
->length
== stream_get_endp(op
->s
));
560 assert(msg
->msg_iovlen
== 2);
564 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
565 * well as the IP_MF flag, making this all quite pointless.
567 * However, for a system on which IP_MF is left alone, and ip_id left
568 * alone or else which sets same ip_id for each fragment this might
571 * XXX-TODO: It would be much nicer to have the kernel's use their
572 * existing fragmentation support to do this for us. Bugs/RFEs need to
573 * be raised against the various kernels.
577 iph
->ip_off
|= IP_MF
;
579 /* ip frag offset is expressed in units of 8byte words */
580 offset
= maxdatasize
>> OSPF_WRITE_FRAG_SHIFT
;
582 iovp
= &msg
->msg_iov
[1];
584 while ((stream_get_endp(op
->s
) - stream_get_getp(op
->s
))
586 /* data length of this frag is to next offset value */
587 iovp
->iov_len
= offset
<< OSPF_WRITE_FRAG_SHIFT
;
588 iph
->ip_len
= iovp
->iov_len
+ sizeof(struct ip
);
589 assert(iph
->ip_len
<= mtu
);
591 sockopt_iphdrincl_swab_htosys(iph
);
593 ret
= sendmsg(fd
, msg
, flags
);
595 sockopt_iphdrincl_swab_systoh(iph
);
599 "*** ospf_write_frags: sendmsg failed to %s,"
600 " id %d, off %d, len %d, mtu %u failed with %s",
601 inet_ntoa(iph
->ip_dst
), iph
->ip_id
, iph
->ip_off
,
602 iph
->ip_len
, mtu
, safe_strerror(errno
));
604 if (IS_DEBUG_OSPF_PACKET(type
- 1, SEND
)) {
606 "ospf_write_frags: sent id %d, off %d, len %d to %s\n",
607 iph
->ip_id
, iph
->ip_off
, iph
->ip_len
,
608 inet_ntoa(iph
->ip_dst
));
609 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
)) {
611 "-----------------IP Header Dump----------------------");
612 ospf_ip_header_dump(iph
);
614 "-----------------------------------------------------");
618 iph
->ip_off
+= offset
;
619 stream_forward_getp(op
->s
, iovp
->iov_len
);
620 iovp
->iov_base
= STREAM_PNT(op
->s
);
623 /* setup for final fragment */
624 iovp
->iov_len
= stream_get_endp(op
->s
) - stream_get_getp(op
->s
);
625 iph
->ip_len
= iovp
->iov_len
+ sizeof(struct ip
);
626 iph
->ip_off
&= (~IP_MF
);
628 #endif /* WANT_OSPF_WRITE_FRAGMENT */
630 static int ospf_write(struct thread
*thread
)
632 struct ospf
*ospf
= THREAD_ARG(thread
);
633 struct ospf_interface
*oi
;
634 struct ospf_interface
*last_serviced_oi
= NULL
;
635 struct ospf_packet
*op
;
636 struct sockaddr_in sa_dst
;
643 struct listnode
*node
;
644 #ifdef WANT_OSPF_WRITE_FRAGMENT
645 static u_int16_t ipid
= 0;
646 u_int16_t maxdatasize
;
647 #endif /* WANT_OSPF_WRITE_FRAGMENT */
649 /* clang-format off */
650 #define OSPF_WRITE_IPHL_SHIFT 2
654 unsigned char cmsgbuf
[64] = {};
655 struct cmsghdr
*cm
= (struct cmsghdr
*)cmsgbuf
;
656 struct in_pktinfo
*pi
;
659 ospf
->t_write
= NULL
;
661 node
= listhead(ospf
->oi_write_q
);
663 oi
= listgetdata(node
);
666 #ifdef WANT_OSPF_WRITE_FRAGMENT
667 /* seed ipid static with low order bits of time */
669 ipid
= (time(NULL
) & 0xffff);
670 #endif /* WANT_OSPF_WRITE_FRAGMENT */
672 while ((pkt_count
< ospf
->write_oi_count
) && oi
673 && (last_serviced_oi
!= oi
)) {
674 /* If there is only packet in the queue, the oi is removed from
675 write-q, so fix up the last interface that was serviced */
676 if (last_serviced_oi
== NULL
) {
677 last_serviced_oi
= oi
;
680 #ifdef WANT_OSPF_WRITE_FRAGMENT
681 /* convenience - max OSPF data per packet */
682 maxdatasize
= oi
->ifp
->mtu
- sizeof(struct ip
);
683 #endif /* WANT_OSPF_WRITE_FRAGMENT */
684 /* Get one packet from queue. */
685 op
= ospf_fifo_head(oi
->obuf
);
687 assert(op
->length
>= OSPF_HEADER_SIZE
);
689 if (op
->dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
)
690 || op
->dst
.s_addr
== htonl(OSPF_ALLDROUTERS
))
691 ospf_if_ipmulticast(ospf
, oi
->address
,
694 /* Rewrite the md5 signature & update the seq */
695 ospf_make_md5_digest(oi
, op
);
697 /* Retrieve OSPF packet type. */
698 stream_set_getp(op
->s
, 1);
699 type
= stream_getc(op
->s
);
701 /* reset get pointer */
702 stream_set_getp(op
->s
, 0);
704 memset(&iph
, 0, sizeof(struct ip
));
705 memset(&sa_dst
, 0, sizeof(sa_dst
));
707 sa_dst
.sin_family
= AF_INET
;
708 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
709 sa_dst
.sin_len
= sizeof(sa_dst
);
710 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
711 sa_dst
.sin_addr
= op
->dst
;
712 sa_dst
.sin_port
= htons(0);
714 /* Set DONTROUTE flag if dst is unicast. */
715 if (oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
716 if (!IN_MULTICAST(htonl(op
->dst
.s_addr
)))
717 flags
= MSG_DONTROUTE
;
719 iph
.ip_hl
= sizeof(struct ip
) >> OSPF_WRITE_IPHL_SHIFT
;
720 /* it'd be very strange for header to not be 4byte-word aligned
722 if (sizeof(struct ip
)
723 > (unsigned int)(iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
))
724 iph
.ip_hl
++; /* we presume sizeof struct ip cant
727 iph
.ip_v
= IPVERSION
;
728 iph
.ip_tos
= IPTOS_PREC_INTERNETCONTROL
;
729 iph
.ip_len
= (iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
) + op
->length
;
731 #if defined(__DragonFly__)
733 * DragonFly's raw socket expects ip_len/ip_off in network byte
736 iph
.ip_len
= htons(iph
.ip_len
);
739 #ifdef WANT_OSPF_WRITE_FRAGMENT
740 /* XXX-MT: not thread-safe at all..
741 * XXX: this presumes this is only programme sending OSPF
743 * otherwise, no guarantee ipid will be unique
746 #endif /* WANT_OSPF_WRITE_FRAGMENT */
749 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
750 iph
.ip_ttl
= OSPF_VL_IP_TTL
;
752 iph
.ip_ttl
= OSPF_IP_TTL
;
753 iph
.ip_p
= IPPROTO_OSPFIGP
;
755 iph
.ip_src
.s_addr
= oi
->address
->u
.prefix4
.s_addr
;
756 iph
.ip_dst
.s_addr
= op
->dst
.s_addr
;
758 memset(&msg
, 0, sizeof(msg
));
759 msg
.msg_name
= (caddr_t
)&sa_dst
;
760 msg
.msg_namelen
= sizeof(sa_dst
);
764 iov
[0].iov_base
= (char *)&iph
;
765 iov
[0].iov_len
= iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
;
766 iov
[1].iov_base
= STREAM_PNT(op
->s
);
767 iov
[1].iov_len
= op
->length
;
770 msg
.msg_control
= (caddr_t
)cm
;
771 cm
->cmsg_level
= SOL_IP
;
772 cm
->cmsg_type
= IP_PKTINFO
;
773 cm
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
774 pi
= (struct in_pktinfo
*)CMSG_DATA(cm
);
775 pi
->ipi_ifindex
= oi
->ifp
->ifindex
;
777 msg
.msg_controllen
= cm
->cmsg_len
;
780 /* Sadly we can not rely on kernels to fragment packets
781 * because of either IP_HDRINCL and/or multicast
782 * destination being set.
785 #ifdef WANT_OSPF_WRITE_FRAGMENT
786 if (op
->length
> maxdatasize
)
787 ospf_write_frags(ospf
->fd
, op
, &iph
, &msg
, maxdatasize
,
788 oi
->ifp
->mtu
, flags
, type
);
789 #endif /* WANT_OSPF_WRITE_FRAGMENT */
791 /* send final fragment (could be first) */
792 sockopt_iphdrincl_swab_htosys(&iph
);
793 ret
= sendmsg(ospf
->fd
, &msg
, flags
);
794 sockopt_iphdrincl_swab_systoh(&iph
);
795 if (IS_DEBUG_OSPF_EVENT
)
798 "id %d, off %d, len %d, interface %s, mtu %u:",
799 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
,
800 iph
.ip_len
, oi
->ifp
->name
, oi
->ifp
->mtu
);
804 "*** sendmsg in ospf_write failed to %s, "
805 "id %d, off %d, len %d, interface %s, mtu %u: %s",
806 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
,
807 iph
.ip_len
, oi
->ifp
->name
, oi
->ifp
->mtu
,
808 safe_strerror(errno
));
810 /* Show debug sending packet. */
811 if (IS_DEBUG_OSPF_PACKET(type
- 1, SEND
)) {
812 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
)) {
814 "-----------------------------------------------------");
815 ospf_ip_header_dump(&iph
);
816 stream_set_getp(op
->s
, 0);
817 ospf_packet_dump(op
->s
);
820 zlog_debug("%s sent to [%s] via [%s].",
821 lookup_msg(ospf_packet_type_str
, type
, NULL
),
822 inet_ntoa(op
->dst
), IF_NAME(oi
));
824 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
))
826 "-----------------------------------------------------");
833 case OSPF_MSG_DB_DESC
:
836 case OSPF_MSG_LS_REQ
:
839 case OSPF_MSG_LS_UPD
:
842 case OSPF_MSG_LS_ACK
:
849 /* Now delete packet from queue. */
850 ospf_packet_delete(oi
);
852 /* Move this interface to the tail of write_q to
853 serve everyone in a round robin fashion */
854 list_delete_node(ospf
->oi_write_q
, node
);
855 if (ospf_fifo_head(oi
->obuf
) == NULL
) {
857 last_serviced_oi
= NULL
;
860 listnode_add(ospf
->oi_write_q
, oi
);
863 /* Setup to service from the head of the queue again */
864 if (!list_isempty(ospf
->oi_write_q
)) {
865 node
= listhead(ospf
->oi_write_q
);
867 oi
= listgetdata(node
);
872 /* If packets still remain in queue, call write thread. */
873 if (!list_isempty(ospf
->oi_write_q
)) {
874 ospf
->t_write
= NULL
;
875 thread_add_write(master
, ospf_write
, ospf
, ospf
->fd
,
882 /* OSPF Hello message read -- RFC2328 Section 10.5. */
883 static void ospf_hello(struct ip
*iph
, struct ospf_header
*ospfh
,
884 struct stream
*s
, struct ospf_interface
*oi
, int size
)
886 struct ospf_hello
*hello
;
887 struct ospf_neighbor
*nbr
;
891 /* increment statistics. */
894 hello
= (struct ospf_hello
*)STREAM_PNT(s
);
896 /* If Hello is myself, silently discard. */
897 if (IPV4_ADDR_SAME(&ospfh
->router_id
, &oi
->ospf
->router_id
)) {
898 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
)) {
900 "ospf_header[%s/%s]: selforiginated, "
902 lookup_msg(ospf_packet_type_str
, ospfh
->type
,
904 inet_ntoa(iph
->ip_src
));
909 /* get neighbor prefix. */
911 p
.prefixlen
= ip_masklen(hello
->network_mask
);
912 p
.u
.prefix4
= iph
->ip_src
;
914 /* Compare network mask. */
915 /* Checking is ignored for Point-to-Point and Virtual link. */
916 if (oi
->type
!= OSPF_IFTYPE_POINTOPOINT
917 && oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
918 if (oi
->address
->prefixlen
!= p
.prefixlen
) {
920 "Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
921 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
),
922 (int)oi
->address
->prefixlen
, (int)p
.prefixlen
);
926 /* Compare Router Dead Interval. */
927 if (OSPF_IF_PARAM(oi
, v_wait
) != ntohl(hello
->dead_interval
)) {
929 "Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
930 "(expected %u, but received %u).",
931 inet_ntoa(ospfh
->router_id
), OSPF_IF_PARAM(oi
, v_wait
),
932 ntohl(hello
->dead_interval
));
936 /* Compare Hello Interval - ignored if fast-hellos are set. */
937 if (OSPF_IF_PARAM(oi
, fast_hello
) == 0) {
938 if (OSPF_IF_PARAM(oi
, v_hello
)
939 != ntohs(hello
->hello_interval
)) {
941 "Packet %s [Hello:RECV]: HelloInterval mismatch "
942 "(expected %u, but received %u).",
943 inet_ntoa(ospfh
->router_id
),
944 OSPF_IF_PARAM(oi
, v_hello
),
945 ntohs(hello
->hello_interval
));
950 if (IS_DEBUG_OSPF_EVENT
)
951 zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
952 inet_ntoa(ospfh
->router_id
),
953 ospf_options_dump(hello
->options
),
954 ospf_vrf_id_to_name(oi
->ospf
->vrf_id
));
956 /* Compare options. */
957 #define REJECT_IF_TBIT_ON 1 /* XXX */
958 #ifdef REJECT_IF_TBIT_ON
959 if (CHECK_FLAG(hello
->options
, OSPF_OPTION_MT
)) {
961 * This router does not support non-zero TOS.
962 * Drop this Hello packet not to establish neighbor
965 zlog_warn("Packet %s [Hello:RECV]: T-bit on, drop it.",
966 inet_ntoa(ospfh
->router_id
));
969 #endif /* REJECT_IF_TBIT_ON */
971 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)
972 && CHECK_FLAG(hello
->options
, OSPF_OPTION_O
)) {
974 * This router does know the correct usage of O-bit
975 * the bit should be set in DD packet only.
977 zlog_warn("Packet %s [Hello:RECV]: O-bit abuse?",
978 inet_ntoa(ospfh
->router_id
));
979 #ifdef STRICT_OBIT_USAGE_CHECK
980 return; /* Reject this packet. */
981 #else /* STRICT_OBIT_USAGE_CHECK */
982 UNSET_FLAG(hello
->options
, OSPF_OPTION_O
); /* Ignore O-bit. */
983 #endif /* STRICT_OBIT_USAGE_CHECK */
986 /* new for NSSA is to ensure that NP is on and E is off */
988 if (oi
->area
->external_routing
== OSPF_AREA_NSSA
) {
989 if (!(CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_NP
)
990 && CHECK_FLAG(hello
->options
, OSPF_OPTION_NP
)
991 && !CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_E
)
992 && !CHECK_FLAG(hello
->options
, OSPF_OPTION_E
))) {
994 "NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x",
995 inet_ntoa(ospfh
->router_id
), OPTIONS(oi
),
999 if (IS_DEBUG_OSPF_NSSA
)
1000 zlog_debug("NSSA-Hello:RECV:Packet from %s:",
1001 inet_ntoa(ospfh
->router_id
));
1003 /* The setting of the E-bit found in the Hello Packet's Options
1004 field must match this area's ExternalRoutingCapability A
1005 mismatch causes processing to stop and the packet to be
1006 dropped. The setting of the rest of the bits in the Hello
1007 Packet's Options field should be ignored. */
1008 if (CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_E
)
1009 != CHECK_FLAG(hello
->options
, OSPF_OPTION_E
)) {
1011 "Packet %s [Hello:RECV]: my options: %x, his options %x",
1012 inet_ntoa(ospfh
->router_id
), OPTIONS(oi
),
1017 /* get neighbour struct */
1018 nbr
= ospf_nbr_get(oi
, ospfh
, iph
, &p
);
1020 /* neighbour must be valid, ospf_nbr_get creates if none existed */
1023 old_state
= nbr
->state
;
1025 /* Add event to thread. */
1026 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1028 /* RFC2328 Section 9.5.1
1029 If the router is not eligible to become Designated Router,
1030 (snip) It must also send an Hello Packet in reply to an
1031 Hello Packet received from any eligible neighbor (other than
1032 the current Designated Router and Backup Designated Router). */
1033 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1034 if (PRIORITY(oi
) == 0 && hello
->priority
> 0
1035 && IPV4_ADDR_CMP(&DR(oi
), &iph
->ip_src
)
1036 && IPV4_ADDR_CMP(&BDR(oi
), &iph
->ip_src
))
1037 OSPF_NSM_TIMER_ON(nbr
->t_hello_reply
,
1038 ospf_hello_reply_timer
,
1039 OSPF_HELLO_REPLY_DELAY
);
1041 /* on NBMA network type, it happens to receive bidirectional Hello
1043 without advance 1-Way Received event.
1044 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
1045 if (oi
->type
== OSPF_IFTYPE_NBMA
1046 && (old_state
== NSM_Down
|| old_state
== NSM_Attempt
)) {
1047 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_OneWayReceived
);
1048 nbr
->priority
= hello
->priority
;
1049 nbr
->d_router
= hello
->d_router
;
1050 nbr
->bd_router
= hello
->bd_router
;
1054 if (ospf_nbr_bidirectional(&oi
->ospf
->router_id
, hello
->neighbors
,
1055 size
- OSPF_HELLO_MIN_SIZE
)) {
1056 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_TwoWayReceived
);
1057 nbr
->options
|= hello
->options
;
1059 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_OneWayReceived
);
1060 /* Set neighbor information. */
1061 nbr
->priority
= hello
->priority
;
1062 nbr
->d_router
= hello
->d_router
;
1063 nbr
->bd_router
= hello
->bd_router
;
1067 /* If neighbor itself declares DR and no BDR exists,
1068 cause event BackupSeen */
1069 if (IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->d_router
))
1070 if (hello
->bd_router
.s_addr
== 0 && oi
->state
== ISM_Waiting
)
1071 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_BackupSeen
);
1073 /* neighbor itself declares BDR. */
1074 if (oi
->state
== ISM_Waiting
1075 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->bd_router
))
1076 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_BackupSeen
);
1078 /* had not previously. */
1079 if ((IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->d_router
)
1080 && IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &nbr
->d_router
))
1081 || (IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &hello
->d_router
)
1082 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &nbr
->d_router
)))
1083 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1085 /* had not previously. */
1086 if ((IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->bd_router
)
1087 && IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &nbr
->bd_router
))
1088 || (IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &hello
->bd_router
)
1089 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &nbr
->bd_router
)))
1090 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1092 /* Neighbor priority check. */
1093 if (nbr
->priority
>= 0 && nbr
->priority
!= hello
->priority
)
1094 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1096 /* Set neighbor information. */
1097 nbr
->priority
= hello
->priority
;
1098 nbr
->d_router
= hello
->d_router
;
1099 nbr
->bd_router
= hello
->bd_router
;
1102 /* Save DD flags/options/Seqnum received. */
1103 static void ospf_db_desc_save_current(struct ospf_neighbor
*nbr
,
1104 struct ospf_db_desc
*dd
)
1106 nbr
->last_recv
.flags
= dd
->flags
;
1107 nbr
->last_recv
.options
= dd
->options
;
1108 nbr
->last_recv
.dd_seqnum
= ntohl(dd
->dd_seqnum
);
1111 /* Process rest of DD packet. */
1112 static void ospf_db_desc_proc(struct stream
*s
, struct ospf_interface
*oi
,
1113 struct ospf_neighbor
*nbr
,
1114 struct ospf_db_desc
*dd
, u_int16_t size
)
1116 struct ospf_lsa
*new, *find
;
1117 struct lsa_header
*lsah
;
1119 stream_forward_getp(s
, OSPF_DB_DESC_MIN_SIZE
);
1120 for (size
-= OSPF_DB_DESC_MIN_SIZE
; size
>= OSPF_LSA_HEADER_SIZE
;
1121 size
-= OSPF_LSA_HEADER_SIZE
) {
1122 lsah
= (struct lsa_header
*)STREAM_PNT(s
);
1123 stream_forward_getp(s
, OSPF_LSA_HEADER_SIZE
);
1125 /* Unknown LS type. */
1126 if (lsah
->type
< OSPF_MIN_LSA
|| lsah
->type
>= OSPF_MAX_LSA
) {
1127 zlog_warn("Packet [DD:RECV]: Unknown LS type %d.",
1129 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1133 if (IS_OPAQUE_LSA(lsah
->type
)
1134 && !CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)) {
1135 zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
1136 lsah
->type
, inet_ntoa(lsah
->id
));
1137 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1141 switch (lsah
->type
) {
1142 case OSPF_AS_EXTERNAL_LSA
:
1143 case OSPF_OPAQUE_AS_LSA
:
1144 /* Check for stub area. Reject if AS-External from stub
1146 allow if from NSSA. */
1147 if (oi
->area
->external_routing
== OSPF_AREA_STUB
) {
1149 "Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1150 lsah
->type
, inet_ntoa(lsah
->id
),
1151 (oi
->area
->external_routing
1155 OSPF_NSM_EVENT_SCHEDULE(nbr
,
1156 NSM_SeqNumberMismatch
);
1164 /* Create LS-request object. */
1165 new = ospf_ls_request_new(lsah
);
1167 /* Lookup received LSA, then add LS request list. */
1168 find
= ospf_lsa_lookup_by_header(oi
->area
, lsah
);
1170 /* ospf_lsa_more_recent is fine with NULL pointers */
1171 switch (ospf_lsa_more_recent(find
, new)) {
1173 /* Neighbour has a more recent LSA, we must request it
1175 ospf_ls_request_add(nbr
, new);
1178 /* If we have a copy of this LSA, it's either less
1180 * and we're requesting it from neighbour (the case
1182 * it's as recent and we both have same copy (this
1185 * In neither of these two cases is there any point in
1186 * describing our copy of the LSA to the neighbour in a
1187 * DB-Summary packet, if we're still intending to do so.
1189 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1190 * backward compatible optimisation to OSPF DB Exchange
1192 * DB Description process implemented here.
1195 ospf_lsdb_delete(&nbr
->db_sum
, find
);
1196 ospf_lsa_discard(new);
1199 /* We have the more recent copy, nothing specific to do:
1200 * - no need to request neighbours stale copy
1201 * - must leave DB summary list copy alone
1203 if (IS_DEBUG_OSPF_EVENT
)
1205 "Packet [DD:RECV]: LSA received Type %d, "
1206 "ID %s is not recent.",
1207 lsah
->type
, inet_ntoa(lsah
->id
));
1208 ospf_lsa_discard(new);
1213 if (IS_SET_DD_MS(nbr
->dd_flags
)) {
1216 /* Both sides have no More, then we're done with Exchange */
1217 if (!IS_SET_DD_M(dd
->flags
) && !IS_SET_DD_M(nbr
->dd_flags
))
1218 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_ExchangeDone
);
1220 ospf_db_desc_send(nbr
);
1224 nbr
->dd_seqnum
= ntohl(dd
->dd_seqnum
);
1226 /* Send DD packet in reply.
1228 * Must be done to acknowledge the Master's DD, regardless of
1229 * whether we have more LSAs ourselves to describe.
1231 * This function will clear the 'More' bit, if after this DD
1232 * we have no more LSAs to describe to the master..
1234 ospf_db_desc_send(nbr
);
1236 /* Slave can raise ExchangeDone now, if master is also done */
1237 if (!IS_SET_DD_M(dd
->flags
) && !IS_SET_DD_M(nbr
->dd_flags
))
1238 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_ExchangeDone
);
1241 /* Save received neighbor values from DD. */
1242 ospf_db_desc_save_current(nbr
, dd
);
1245 ospf_ls_req_send(nbr
);
1248 static int ospf_db_desc_is_dup(struct ospf_db_desc
*dd
,
1249 struct ospf_neighbor
*nbr
)
1251 /* Is DD duplicated? */
1252 if (dd
->options
== nbr
->last_recv
.options
1253 && dd
->flags
== nbr
->last_recv
.flags
1254 && dd
->dd_seqnum
== htonl(nbr
->last_recv
.dd_seqnum
))
1260 /* OSPF Database Description message read -- RFC2328 Section 10.6. */
1261 static void ospf_db_desc(struct ip
*iph
, struct ospf_header
*ospfh
,
1262 struct stream
*s
, struct ospf_interface
*oi
,
1265 struct ospf_db_desc
*dd
;
1266 struct ospf_neighbor
*nbr
;
1268 /* Increment statistics. */
1271 dd
= (struct ospf_db_desc
*)STREAM_PNT(s
);
1273 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1275 zlog_warn("Packet[DD]: Unknown Neighbor %s",
1276 inet_ntoa(ospfh
->router_id
));
1281 if ((OSPF_IF_PARAM(oi
, mtu_ignore
) == 0)
1282 && (ntohs(dd
->mtu
) > oi
->ifp
->mtu
)) {
1284 "Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1285 inet_ntoa(nbr
->router_id
), ntohs(dd
->mtu
), IF_NAME(oi
),
1291 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is
1293 * required. In fact at least JunOS sends DD packets with P bit clear.
1294 * Until proper solution is developped, this hack should help.
1296 * Update: According to the RFCs, N bit is specified /only/ for Hello
1297 * options, unfortunately its use in DD options is not specified. Hence
1299 * implementations follow E-bit semantics and set it in DD options, and
1301 * treat it as unspecified and hence follow the directive "default for
1302 * options is clear", ie unset.
1304 * Reset the flag, as ospfd follows E-bit semantics.
1306 if ((oi
->area
->external_routing
== OSPF_AREA_NSSA
)
1307 && (CHECK_FLAG(nbr
->options
, OSPF_OPTION_NP
))
1308 && (!CHECK_FLAG(dd
->options
, OSPF_OPTION_NP
))) {
1309 if (IS_DEBUG_OSPF_EVENT
)
1311 "Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
1312 inet_ntoa(nbr
->router_id
));
1313 SET_FLAG(dd
->options
, OSPF_OPTION_NP
);
1316 #ifdef REJECT_IF_TBIT_ON
1317 if (CHECK_FLAG(dd
->options
, OSPF_OPTION_MT
)) {
1319 * In Hello protocol, optional capability must have checked
1320 * to prevent this T-bit enabled router be my neighbor.
1322 zlog_warn("Packet[DD]: Neighbor %s: T-bit on?",
1323 inet_ntoa(nbr
->router_id
));
1326 #endif /* REJECT_IF_TBIT_ON */
1328 if (CHECK_FLAG(dd
->options
, OSPF_OPTION_O
)
1329 && !CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)) {
1331 * This node is not configured to handle O-bit, for now.
1332 * Clear it to ignore unsupported capability proposed by
1335 UNSET_FLAG(dd
->options
, OSPF_OPTION_O
);
1338 /* Add event to thread. */
1339 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1341 /* Process DD packet by neighbor status. */
1342 switch (nbr
->state
) {
1347 "Packet[DD]: Neighbor %s state is %s, packet discarded.",
1348 inet_ntoa(nbr
->router_id
),
1349 lookup_msg(ospf_nsm_state_msg
, nbr
->state
, NULL
));
1352 OSPF_NSM_EVENT_EXECUTE(nbr
, NSM_TwoWayReceived
);
1353 /* If the new state is ExStart, the processing of the current
1354 packet should then continue in this new state by falling
1355 through to case ExStart below. */
1356 if (nbr
->state
!= NSM_ExStart
)
1361 if ((IS_SET_DD_ALL(dd
->flags
) == OSPF_DD_FLAG_ALL
)
1362 && (size
== OSPF_DB_DESC_MIN_SIZE
)) {
1363 if (IPV4_ADDR_CMP(&nbr
->router_id
, &oi
->ospf
->router_id
)
1365 /* We're Slave---obey */
1367 "Packet[DD]: Neighbor %s Negotiation done (Slave).",
1368 inet_ntoa(nbr
->router_id
));
1369 nbr
->dd_seqnum
= ntohl(dd
->dd_seqnum
);
1372 UNSET_FLAG(nbr
->dd_flags
,
1373 (OSPF_DD_FLAG_MS
| OSPF_DD_FLAG_I
));
1375 /* We're Master, ignore the initial DBD from
1378 "Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1380 inet_ntoa(nbr
->router_id
));
1384 /* Ack from the Slave */
1385 else if (!IS_SET_DD_MS(dd
->flags
) && !IS_SET_DD_I(dd
->flags
)
1386 && ntohl(dd
->dd_seqnum
) == nbr
->dd_seqnum
1387 && IPV4_ADDR_CMP(&nbr
->router_id
, &oi
->ospf
->router_id
)
1390 "Packet[DD]: Neighbor %s Negotiation done (Master).",
1391 inet_ntoa(nbr
->router_id
));
1392 /* Reset I, leaving MS */
1393 UNSET_FLAG(nbr
->dd_flags
, OSPF_DD_FLAG_I
);
1395 zlog_warn("Packet[DD]: Neighbor %s Negotiation fails.",
1396 inet_ntoa(nbr
->router_id
));
1400 /* This is where the real Options are saved */
1401 nbr
->options
= dd
->options
;
1403 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)) {
1404 if (IS_DEBUG_OSPF_EVENT
)
1406 "Neighbor[%s] is %sOpaque-capable.",
1407 inet_ntoa(nbr
->router_id
),
1408 CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)
1412 if (!CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)
1413 && IPV4_ADDR_SAME(&DR(oi
),
1414 &nbr
->address
.u
.prefix4
)) {
1416 "DR-neighbor[%s] is NOT opaque-capable; "
1417 "Opaque-LSAs cannot be reliably advertised "
1419 inet_ntoa(nbr
->router_id
));
1420 /* This situation is undesirable, but not a real
1425 OSPF_NSM_EVENT_EXECUTE(nbr
, NSM_NegotiationDone
);
1427 /* continue processing rest of packet. */
1428 ospf_db_desc_proc(s
, oi
, nbr
, dd
, size
);
1431 if (ospf_db_desc_is_dup(dd
, nbr
)) {
1432 if (IS_SET_DD_MS(nbr
->dd_flags
))
1433 /* Master: discard duplicated DD packet. */
1435 "Packet[DD] (Master): Neighbor %s packet duplicated.",
1436 inet_ntoa(nbr
->router_id
));
1438 /* Slave: cause to retransmit the last Database
1442 "Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1443 inet_ntoa(nbr
->router_id
));
1444 ospf_db_desc_resend(nbr
);
1449 /* Otherwise DD packet should be checked. */
1450 /* Check Master/Slave bit mismatch */
1451 if (IS_SET_DD_MS(dd
->flags
)
1452 != IS_SET_DD_MS(nbr
->last_recv
.flags
)) {
1453 zlog_warn("Packet[DD]: Neighbor %s MS-bit mismatch.",
1454 inet_ntoa(nbr
->router_id
));
1455 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1456 if (IS_DEBUG_OSPF_EVENT
)
1458 "Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1459 dd
->flags
, nbr
->dd_flags
);
1463 /* Check initialize bit is set. */
1464 if (IS_SET_DD_I(dd
->flags
)) {
1465 zlog_info("Packet[DD]: Neighbor %s I-bit set.",
1466 inet_ntoa(nbr
->router_id
));
1467 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1471 /* Check DD Options. */
1472 if (dd
->options
!= nbr
->options
) {
1473 #ifdef ORIGINAL_CODING
1474 /* Save the new options for debugging */
1475 nbr
->options
= dd
->options
;
1476 #endif /* ORIGINAL_CODING */
1477 zlog_warn("Packet[DD]: Neighbor %s options mismatch.",
1478 inet_ntoa(nbr
->router_id
));
1479 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1483 /* Check DD sequence number. */
1484 if ((IS_SET_DD_MS(nbr
->dd_flags
)
1485 && ntohl(dd
->dd_seqnum
) != nbr
->dd_seqnum
)
1486 || (!IS_SET_DD_MS(nbr
->dd_flags
)
1487 && ntohl(dd
->dd_seqnum
) != nbr
->dd_seqnum
+ 1)) {
1489 "Packet[DD]: Neighbor %s sequence number mismatch.",
1490 inet_ntoa(nbr
->router_id
));
1491 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1495 /* Continue processing rest of packet. */
1496 ospf_db_desc_proc(s
, oi
, nbr
, dd
, size
);
1500 if (ospf_db_desc_is_dup(dd
, nbr
)) {
1501 if (IS_SET_DD_MS(nbr
->dd_flags
)) {
1502 /* Master should discard duplicate DD packet. */
1504 "Packet[DD]: Neighbor %s duplicated, "
1505 "packet discarded.",
1506 inet_ntoa(nbr
->router_id
));
1509 if (monotime_since(&nbr
->last_send_ts
, NULL
)
1510 < nbr
->v_inactivity
* 1000000LL) {
1511 /* In states Loading and Full the slave
1513 its last Database Description packet
1515 duplicate Database Description
1517 from the master. For this reason the
1519 wait RouterDeadInterval seconds
1521 last Database Description packet.
1523 Database Description packet from the
1525 this interval will generate a
1527 neighbor event. RFC2328 Section 10.8
1529 ospf_db_desc_resend(nbr
);
1535 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1538 zlog_warn("Packet[DD]: Neighbor %s NSM illegal status %u.",
1539 inet_ntoa(nbr
->router_id
), nbr
->state
);
1544 #define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1546 /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1547 static void ospf_ls_req(struct ip
*iph
, struct ospf_header
*ospfh
,
1548 struct stream
*s
, struct ospf_interface
*oi
,
1551 struct ospf_neighbor
*nbr
;
1553 struct in_addr ls_id
;
1554 struct in_addr adv_router
;
1555 struct ospf_lsa
*find
;
1556 struct list
*ls_upd
;
1557 unsigned int length
;
1559 /* Increment statistics. */
1562 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1564 zlog_warn("Link State Request: Unknown Neighbor %s.",
1565 inet_ntoa(ospfh
->router_id
));
1569 /* Add event to thread. */
1570 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1572 /* Neighbor State should be Exchange or later. */
1573 if (nbr
->state
!= NSM_Exchange
&& nbr
->state
!= NSM_Loading
1574 && nbr
->state
!= NSM_Full
) {
1576 "Link State Request received from %s: "
1577 "Neighbor state is %s, packet discarded.",
1578 inet_ntoa(ospfh
->router_id
),
1579 lookup_msg(ospf_nsm_state_msg
, nbr
->state
, NULL
));
1583 /* Send Link State Update for ALL requested LSAs. */
1584 ls_upd
= list_new();
1585 length
= OSPF_HEADER_SIZE
+ OSPF_LS_UPD_MIN_SIZE
;
1587 while (size
>= OSPF_LSA_KEY_SIZE
) {
1588 /* Get one slice of Link State Request. */
1589 ls_type
= stream_getl(s
);
1590 ls_id
.s_addr
= stream_get_ipv4(s
);
1591 adv_router
.s_addr
= stream_get_ipv4(s
);
1593 /* Verify LSA type. */
1594 if (ls_type
< OSPF_MIN_LSA
|| ls_type
>= OSPF_MAX_LSA
) {
1595 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
1596 list_delete_and_null(&ls_upd
);
1600 /* Search proper LSA in LSDB. */
1601 find
= ospf_lsa_lookup(oi
->ospf
, oi
->area
, ls_type
, ls_id
,
1604 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
1605 list_delete_and_null(&ls_upd
);
1609 /* Packet overflows MTU size, send immediately. */
1610 if (length
+ ntohs(find
->data
->length
) > ospf_packet_max(oi
)) {
1611 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1612 ospf_ls_upd_send(nbr
, ls_upd
,
1613 OSPF_SEND_PACKET_DIRECT
, 0);
1615 ospf_ls_upd_send(nbr
, ls_upd
,
1616 OSPF_SEND_PACKET_INDIRECT
, 0);
1618 /* Only remove list contents. Keep ls_upd. */
1619 list_delete_all_node(ls_upd
);
1621 length
= OSPF_HEADER_SIZE
+ OSPF_LS_UPD_MIN_SIZE
;
1624 /* Append LSA to update list. */
1625 listnode_add(ls_upd
, find
);
1626 length
+= ntohs(find
->data
->length
);
1628 size
-= OSPF_LSA_KEY_SIZE
;
1631 /* Send rest of Link State Update. */
1632 if (listcount(ls_upd
) > 0) {
1633 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1634 ospf_ls_upd_send(nbr
, ls_upd
,
1635 OSPF_SEND_PACKET_DIRECT
, 0);
1637 ospf_ls_upd_send(nbr
, ls_upd
,
1638 OSPF_SEND_PACKET_INDIRECT
, 0);
1640 list_delete_and_null(&ls_upd
);
1642 list_delete_and_null(&ls_upd
);
1645 /* Get the list of LSAs from Link State Update packet.
1646 And process some validation -- RFC2328 Section 13. (1)-(2). */
1647 static struct list
*ospf_ls_upd_list_lsa(struct ospf_neighbor
*nbr
,
1649 struct ospf_interface
*oi
, size_t size
)
1651 u_int16_t count
, sum
;
1653 struct lsa_header
*lsah
;
1654 struct ospf_lsa
*lsa
;
1659 count
= stream_getl(s
);
1660 size
-= OSPF_LS_UPD_MIN_SIZE
; /* # LSAs */
1662 for (; size
>= OSPF_LSA_HEADER_SIZE
&& count
> 0;
1663 size
-= length
, stream_forward_getp(s
, length
), count
--) {
1664 lsah
= (struct lsa_header
*)STREAM_PNT(s
);
1665 length
= ntohs(lsah
->length
);
1667 if (length
> size
) {
1669 "Link State Update: LSA length exceeds packet size.");
1673 /* Validate the LSA's LS checksum. */
1674 sum
= lsah
->checksum
;
1675 if (!ospf_lsa_checksum_valid(lsah
)) {
1676 /* (bug #685) more details in a one-line message make it
1678 * to identify problem source on the one hand and to
1680 * chance to compress repeated messages in syslog on the
1683 "Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1684 sum
, lsah
->checksum
, inet_ntoa(lsah
->id
),
1685 inet_ntoa(nbr
->src
), inet_ntoa(nbr
->router_id
),
1686 inet_ntoa(lsah
->adv_router
));
1690 /* Examine the LSA's LS type. */
1691 if (lsah
->type
< OSPF_MIN_LSA
|| lsah
->type
>= OSPF_MAX_LSA
) {
1692 zlog_warn("Link State Update: Unknown LS type %d",
1698 * What if the received LSA's age is greater than MaxAge?
1699 * Treat it as a MaxAge case -- endo.
1701 if (ntohs(lsah
->ls_age
) > OSPF_LSA_MAXAGE
)
1702 lsah
->ls_age
= htons(OSPF_LSA_MAXAGE
);
1704 if (CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)) {
1705 #ifdef STRICT_OBIT_USAGE_CHECK
1706 if ((IS_OPAQUE_LSA(lsah
->type
)
1707 && !CHECK_FLAG(lsah
->options
, OSPF_OPTION_O
))
1708 || (!IS_OPAQUE_LSA(lsah
->type
)
1709 && CHECK_FLAG(lsah
->options
, OSPF_OPTION_O
))) {
1711 * This neighbor must know the exact usage of
1713 * the bit will be set in Type-9,10,11 LSAs
1716 zlog_warn("LSA[Type%d:%s]: O-bit abuse?",
1717 lsah
->type
, inet_ntoa(lsah
->id
));
1720 #endif /* STRICT_OBIT_USAGE_CHECK */
1722 /* Do not take in AS External Opaque-LSAs if we are a
1724 if (lsah
->type
== OSPF_OPAQUE_AS_LSA
1725 && nbr
->oi
->area
->external_routing
1726 != OSPF_AREA_DEFAULT
) {
1727 if (IS_DEBUG_OSPF_EVENT
)
1729 "LSA[Type%d:%s]: We are a stub, don't take this LSA.",
1731 inet_ntoa(lsah
->id
));
1734 } else if (IS_OPAQUE_LSA(lsah
->type
)) {
1735 zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
1736 lsah
->type
, inet_ntoa(lsah
->id
));
1740 /* Create OSPF LSA instance. */
1741 lsa
= ospf_lsa_new();
1743 lsa
->vrf_id
= oi
->ospf
->vrf_id
;
1744 /* We may wish to put some error checking if type NSSA comes in
1745 and area not in NSSA mode */
1746 switch (lsah
->type
) {
1747 case OSPF_AS_EXTERNAL_LSA
:
1748 case OSPF_OPAQUE_AS_LSA
:
1751 case OSPF_OPAQUE_LINK_LSA
:
1752 lsa
->oi
= oi
; /* Remember incoming interface for
1753 flooding control. */
1756 lsa
->area
= oi
->area
;
1760 lsa
->data
= ospf_lsa_data_new(length
);
1761 memcpy(lsa
->data
, lsah
, length
);
1763 if (IS_DEBUG_OSPF_EVENT
)
1765 "LSA[Type%d:%s]: %p new LSA created with Link State Update",
1766 lsa
->data
->type
, inet_ntoa(lsa
->data
->id
),
1768 listnode_add(lsas
, lsa
);
1774 /* Cleanup Update list. */
1775 static void ospf_upd_list_clean(struct list
*lsas
)
1777 struct listnode
*node
, *nnode
;
1778 struct ospf_lsa
*lsa
;
1780 for (ALL_LIST_ELEMENTS(lsas
, node
, nnode
, lsa
))
1781 ospf_lsa_discard(lsa
);
1783 list_delete_and_null(&lsas
);
1786 /* OSPF Link State Update message read -- RFC2328 Section 13. */
1787 static void ospf_ls_upd(struct ospf
*ospf
, struct ip
*iph
,
1788 struct ospf_header
*ospfh
, struct stream
*s
,
1789 struct ospf_interface
*oi
, u_int16_t size
)
1791 struct ospf_neighbor
*nbr
;
1793 struct listnode
*node
, *nnode
;
1794 struct ospf_lsa
*lsa
= NULL
;
1795 /* unsigned long ls_req_found = 0; */
1797 /* Dis-assemble the stream, update each entry, re-encapsulate for
1800 /* Increment statistics. */
1803 /* Check neighbor. */
1804 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1806 zlog_warn("Link State Update: Unknown Neighbor %s on int: %s",
1807 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
));
1811 /* Add event to thread. */
1812 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1814 /* Check neighbor state. */
1815 if (nbr
->state
< NSM_Exchange
) {
1816 if (IS_DEBUG_OSPF(nsm
, NSM_EVENTS
))
1818 "Link State Update: "
1819 "Neighbor[%s] state %s is less than Exchange",
1820 inet_ntoa(ospfh
->router_id
),
1821 lookup_msg(ospf_nsm_state_msg
, nbr
->state
,
1826 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1827 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1830 lsas
= ospf_ls_upd_list_lsa(nbr
, s
, oi
, size
);
1834 #define DISCARD_LSA(L, N) \
1836 if (IS_DEBUG_OSPF_EVENT) \
1838 "ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \
1840 N, (void *)lsa, (int)lsa->data->type); \
1841 ospf_lsa_discard(L); \
1845 /* Process each LSA received in the one packet.
1847 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
1848 * text below are from the steps in RFC 2328, Section 13.
1850 for (ALL_LIST_ELEMENTS(lsas
, node
, nnode
, lsa
)) {
1851 struct ospf_lsa
*ls_ret
, *current
;
1854 if (IS_DEBUG_OSPF_NSSA
) {
1855 char buf1
[INET_ADDRSTRLEN
];
1856 char buf2
[INET_ADDRSTRLEN
];
1857 char buf3
[INET_ADDRSTRLEN
];
1859 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
1861 inet_ntop(AF_INET
, &ospfh
->router_id
, buf1
,
1863 inet_ntop(AF_INET
, &lsa
->data
->id
, buf2
,
1865 inet_ntop(AF_INET
, &lsa
->data
->adv_router
,
1866 buf3
, INET_ADDRSTRLEN
));
1869 listnode_delete(lsas
,
1870 lsa
); /* We don't need it in list anymore */
1872 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa()
1875 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
1877 /* (3) Do not take in AS External LSAs if we are a stub or NSSA.
1880 /* Do not take in AS NSSA if this neighbor and we are not NSSA
1883 /* Do take in Type-7's if we are an NSSA */
1885 /* If we are also an ABR, later translate them to a Type-5
1888 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1889 translate them to a separate Type-5 packet. */
1891 if (lsa
->data
->type
== OSPF_AS_EXTERNAL_LSA
)
1892 /* Reject from STUB or NSSA */
1893 if (nbr
->oi
->area
->external_routing
1894 != OSPF_AREA_DEFAULT
) {
1895 if (IS_DEBUG_OSPF_NSSA
)
1897 "Incoming External LSA Discarded: We are NSSA/STUB Area");
1898 DISCARD_LSA(lsa
, 1);
1901 if (lsa
->data
->type
== OSPF_AS_NSSA_LSA
)
1902 if (nbr
->oi
->area
->external_routing
!= OSPF_AREA_NSSA
) {
1903 if (IS_DEBUG_OSPF_NSSA
)
1905 "Incoming NSSA LSA Discarded: Not NSSA Area");
1906 DISCARD_LSA(lsa
, 2);
1909 /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
1910 if (lsa
->data
->type
== OSPF_ROUTER_LSA
)
1911 if (!IPV4_ADDR_SAME(&lsa
->data
->id
,
1912 &lsa
->data
->adv_router
)) {
1913 char buf1
[INET_ADDRSTRLEN
];
1914 char buf2
[INET_ADDRSTRLEN
];
1915 char buf3
[INET_ADDRSTRLEN
];
1918 "Incoming Router-LSA from %s with "
1919 "Adv-ID[%s] != LS-ID[%s]",
1920 inet_ntop(AF_INET
, &ospfh
->router_id
,
1921 buf1
, INET_ADDRSTRLEN
),
1922 inet_ntop(AF_INET
, &lsa
->data
->id
, buf2
,
1925 &lsa
->data
->adv_router
, buf3
,
1928 "OSPF domain compromised by attack or corruption. "
1929 "Verify correct operation of -ALL- OSPF routers.");
1930 DISCARD_LSA(lsa
, 0);
1933 /* Find the LSA in the current database. */
1935 current
= ospf_lsa_lookup_by_header(oi
->area
, lsa
->data
);
1937 /* (4) If the LSA's LS age is equal to MaxAge, and there is
1939 no instance of the LSA in the router's link state database,
1940 and none of router's neighbors are in states Exchange or
1942 then take the following actions: */
1944 if (IS_LSA_MAXAGE(lsa
) && !current
1945 && ospf_check_nbr_status(oi
->ospf
)) {
1946 /* (4a) Response Link State Acknowledgment. */
1947 ospf_ls_ack_send(nbr
, lsa
);
1949 /* (4b) Discard LSA. */
1950 if (IS_DEBUG_OSPF(lsa
, LSA
)) {
1952 "Link State Update[%s]: LS age is equal to MaxAge.",
1955 DISCARD_LSA(lsa
, 3);
1958 if (IS_OPAQUE_LSA(lsa
->data
->type
)
1959 && IPV4_ADDR_SAME(&lsa
->data
->adv_router
,
1960 &oi
->ospf
->router_id
)) {
1962 * Even if initial flushing seems to be completed, there
1964 * be a case that self-originated LSA with MaxAge still
1966 * in the routing domain.
1967 * Just send an LSAck message to cease retransmission.
1969 if (IS_LSA_MAXAGE(lsa
)) {
1970 zlog_warn("LSA[%s]: Boomerang effect?",
1972 ospf_ls_ack_send(nbr
, lsa
);
1973 ospf_lsa_discard(lsa
);
1975 if (current
!= NULL
&& !IS_LSA_MAXAGE(current
))
1976 ospf_opaque_lsa_refresh_schedule(
1982 * If an instance of self-originated Opaque-LSA is not
1984 * in the LSDB, there are some possible cases here.
1986 * 1) This node lost opaque-capability after restart.
1987 * 2) Else, a part of opaque-type is no more supported.
1988 * 3) Else, a part of opaque-id is no more supported.
1990 * Anyway, it is still this node's responsibility to
1992 * Otherwise, the LSA instance remains in the routing
1994 * until its age reaches to MaxAge.
1996 /* XXX: We should deal with this for *ALL* LSAs, not
1998 if (current
== NULL
) {
1999 if (IS_DEBUG_OSPF_EVENT
)
2001 "LSA[%s]: Previously originated Opaque-LSA,"
2002 "not found in the LSDB.",
2005 SET_FLAG(lsa
->flags
, OSPF_LSA_SELF
);
2007 ospf_opaque_self_originated_lsa_received(nbr
,
2009 ospf_ls_ack_send(nbr
, lsa
);
2015 /* It might be happen that received LSA is self-originated
2017 * router ID is changed. So, we should check if LSA is a
2019 * Link State ID is one of the router's own IP interface
2020 * addresses but whose
2021 * Advertising Router is not equal to the router's own Router ID
2022 * According to RFC 2328 12.4.2 and 13.4 this LSA should be
2026 if (lsa
->data
->type
== OSPF_NETWORK_LSA
) {
2027 struct listnode
*oinode
, *oinnode
;
2028 struct ospf_interface
*out_if
;
2031 for (ALL_LIST_ELEMENTS(oi
->ospf
->oiflist
, oinode
,
2036 if ((IPV4_ADDR_SAME(&out_if
->address
->u
.prefix4
,
2038 && (!(IPV4_ADDR_SAME(
2039 &oi
->ospf
->router_id
,
2040 &lsa
->data
->adv_router
)))) {
2041 if (out_if
->network_lsa_self
) {
2042 ospf_lsa_flush_area(
2044 if (IS_DEBUG_OSPF_EVENT
)
2046 "ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
2050 ospf_lsa_discard(lsa
);
2060 /* (5) Find the instance of this LSA that is currently contained
2061 in the router's link state database. If there is no
2062 database copy, or the received LSA is more recent than
2063 the database copy the following steps must be performed.
2064 (The sub steps from RFC 2328 section 13 step (5) will be
2069 || (ret
= ospf_lsa_more_recent(current
, lsa
)) < 0) {
2070 /* Actual flooding procedure. */
2071 if (ospf_flood(oi
->ospf
, nbr
, current
, lsa
)
2072 < 0) /* Trap NSSA later. */
2073 DISCARD_LSA(lsa
, 4);
2077 /* (6) Else, If there is an instance of the LSA on the sending
2078 neighbor's Link state request list, an error has occurred in
2079 the Database Exchange process. In this case, restart the
2080 Database Exchange process by generating the neighbor event
2081 BadLSReq for the sending neighbor and stop processing the
2082 Link State Update packet. */
2084 if (ospf_ls_request_lookup(nbr
, lsa
)) {
2085 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
2087 "LSA[%s] instance exists on Link state request list",
2090 /* Clean list of LSAs. */
2091 ospf_upd_list_clean(lsas
);
2092 /* this lsa is not on lsas list already. */
2093 ospf_lsa_discard(lsa
);
2097 /* If the received LSA is the same instance as the database copy
2098 (i.e., neither one is more recent) the following two steps
2099 should be performed: */
2102 /* If the LSA is listed in the Link state retransmission
2104 for the receiving adjacency, the router itself is
2106 an acknowledgment for this LSA. The router should
2108 received LSA as an acknowledgment by removing the LSA
2110 the Link state retransmission list. This is termed
2112 "implied acknowledgment". */
2114 ls_ret
= ospf_ls_retransmit_lookup(nbr
, lsa
);
2116 if (ls_ret
!= NULL
) {
2117 ospf_ls_retransmit_delete(nbr
, ls_ret
);
2119 /* Delayed acknowledgment sent if advertisement
2121 from Designated Router, otherwise do nothing.
2123 if (oi
->state
== ISM_Backup
)
2127 ospf_lsa_lock(lsa
));
2129 DISCARD_LSA(lsa
, 5);
2131 /* Acknowledge the receipt of the LSA by sending a
2132 Link State Acknowledgment packet back out the
2136 ospf_ls_ack_send(nbr
, lsa
);
2137 DISCARD_LSA(lsa
, 6);
2141 /* The database copy is more recent. If the database copy
2142 has LS age equal to MaxAge and LS sequence number equal to
2143 MaxSequenceNumber, simply discard the received LSA without
2144 acknowledging it. (In this case, the LSA's LS sequence number
2146 wrapping, and the MaxSequenceNumber LSA must be completely
2147 flushed before any new LSA instance can be introduced). */
2149 else if (ret
> 0) /* Database copy is more recent */
2151 if (IS_LSA_MAXAGE(current
)
2152 && current
->data
->ls_seqnum
2153 == htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
2154 DISCARD_LSA(lsa
, 7);
2156 /* Otherwise, as long as the database copy has not been
2158 Link State Update within the last MinLSArrival
2160 database copy back to the sending neighbor,
2162 a Link State Update Packet. The Link State Update
2164 be sent directly to the neighbor. In so doing, do not
2166 database copy of the LSA on the neighbor's link state
2167 retransmission list, and do not acknowledge the
2169 recent) LSA instance. */
2171 if (monotime_since(¤t
->tv_orig
, NULL
)
2172 >= ospf
->min_ls_arrival
* 1000LL)
2173 /* Trap NSSA type later.*/
2174 ospf_ls_upd_send_lsa(
2176 OSPF_SEND_PACKET_DIRECT
);
2177 DISCARD_LSA(lsa
, 8);
2183 assert(listcount(lsas
) == 0);
2184 list_delete_and_null(&lsas
);
2187 /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
2188 static void ospf_ls_ack(struct ip
*iph
, struct ospf_header
*ospfh
,
2189 struct stream
*s
, struct ospf_interface
*oi
,
2192 struct ospf_neighbor
*nbr
;
2194 /* increment statistics. */
2197 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
2199 zlog_warn("Link State Acknowledgment: Unknown Neighbor %s.",
2200 inet_ntoa(ospfh
->router_id
));
2204 /* Add event to thread. */
2205 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
2207 if (nbr
->state
< NSM_Exchange
) {
2208 if (IS_DEBUG_OSPF(nsm
, NSM_EVENTS
))
2210 "Link State Acknowledgment: "
2211 "Neighbor[%s] state %s is less than Exchange",
2212 inet_ntoa(ospfh
->router_id
),
2213 lookup_msg(ospf_nsm_state_msg
, nbr
->state
,
2218 while (size
>= OSPF_LSA_HEADER_SIZE
) {
2219 struct ospf_lsa
*lsa
, *lsr
;
2221 lsa
= ospf_lsa_new();
2222 lsa
->data
= (struct lsa_header
*)STREAM_PNT(s
);
2223 lsa
->vrf_id
= oi
->ospf
->vrf_id
;
2225 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2226 size
-= OSPF_LSA_HEADER_SIZE
;
2227 stream_forward_getp(s
, OSPF_LSA_HEADER_SIZE
);
2229 if (lsa
->data
->type
< OSPF_MIN_LSA
2230 || lsa
->data
->type
>= OSPF_MAX_LSA
) {
2232 ospf_lsa_discard(lsa
);
2236 lsr
= ospf_ls_retransmit_lookup(nbr
, lsa
);
2238 if (lsr
!= NULL
&& ospf_lsa_more_recent(lsr
, lsa
) == 0)
2239 ospf_ls_retransmit_delete(nbr
, lsr
);
2242 ospf_lsa_discard(lsa
);
2248 static struct stream
*ospf_recv_packet(struct ospf
*ospf
, int fd
,
2249 struct interface
**ifp
,
2250 struct stream
*ibuf
)
2255 ifindex_t ifindex
= 0;
2257 /* Header and data both require alignment. */
2258 char buff
[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2261 memset(&msgh
, 0, sizeof(struct msghdr
));
2262 msgh
.msg_iov
= &iov
;
2263 msgh
.msg_iovlen
= 1;
2264 msgh
.msg_control
= (caddr_t
)buff
;
2265 msgh
.msg_controllen
= sizeof(buff
);
2267 ret
= stream_recvmsg(ibuf
, fd
, &msgh
, 0, OSPF_MAX_PACKET_SIZE
+ 1);
2269 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno
));
2272 if ((unsigned int)ret
< sizeof(iph
)) /* ret must be > 0 now */
2275 "ospf_recv_packet: discarding runt packet of length %d "
2276 "(ip header size is %u)",
2277 ret
, (u_int
)sizeof(iph
));
2281 /* Note that there should not be alignment problems with this assignment
2282 because this is at the beginning of the stream data buffer. */
2283 iph
= (struct ip
*)STREAM_DATA(ibuf
);
2284 sockopt_iphdrincl_swab_systoh(iph
);
2286 ip_len
= iph
->ip_len
;
2288 #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
2290 * Kernel network code touches incoming IP header parameters,
2291 * before protocol specific processing.
2293 * 1) Convert byteorder to host representation.
2294 * --> ip_len, ip_id, ip_off
2296 * 2) Adjust ip_len to strip IP header size!
2297 * --> If user process receives entire IP packet via RAW
2298 * socket, it must consider adding IP header size to
2299 * the "ip_len" field of "ip" structure.
2301 * For more details, see <netinet/ip_input.c>.
2303 ip_len
= ip_len
+ (iph
->ip_hl
<< 2);
2306 #if defined(__DragonFly__)
2308 * in DragonFly's raw socket, ip_len/ip_off are read
2309 * in network byte order.
2310 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2312 ip_len
= ntohs(iph
->ip_len
) + (iph
->ip_hl
<< 2);
2315 ifindex
= getsockopt_ifindex(AF_INET
, &msgh
);
2317 *ifp
= if_lookup_by_index(ifindex
, ospf
->vrf_id
);
2319 if (ret
!= ip_len
) {
2321 "ospf_recv_packet read length mismatch: ip_len is %d, "
2322 "but recvmsg returned %d",
2330 static struct ospf_interface
*
2331 ospf_associate_packet_vl(struct ospf
*ospf
, struct interface
*ifp
,
2332 struct ip
*iph
, struct ospf_header
*ospfh
)
2334 struct ospf_interface
*rcv_oi
;
2335 struct ospf_vl_data
*vl_data
;
2336 struct ospf_area
*vl_area
;
2337 struct listnode
*node
;
2339 if (IN_MULTICAST(ntohl(iph
->ip_dst
.s_addr
))
2340 || !OSPF_IS_AREA_BACKBONE(ospfh
))
2343 /* look for local OSPF interface matching the destination
2344 * to determine Area ID. We presume therefore the destination address
2345 * is unique, or at least (for "unnumbered" links), not used in other
2348 if ((rcv_oi
= ospf_if_lookup_by_local_addr(ospf
, NULL
, iph
->ip_dst
))
2352 for (ALL_LIST_ELEMENTS_RO(ospf
->vlinks
, node
, vl_data
)) {
2354 ospf_area_lookup_by_area_id(ospf
, vl_data
->vl_area_id
);
2358 if (OSPF_AREA_SAME(&vl_area
, &rcv_oi
->area
)
2359 && IPV4_ADDR_SAME(&vl_data
->vl_peer
, &ospfh
->router_id
)) {
2360 if (IS_DEBUG_OSPF_EVENT
)
2361 zlog_debug("associating packet with %s",
2362 IF_NAME(vl_data
->vl_oi
));
2363 if (!CHECK_FLAG(vl_data
->vl_oi
->ifp
->flags
, IFF_UP
)) {
2364 if (IS_DEBUG_OSPF_EVENT
)
2366 "This VL is not up yet, sorry");
2370 return vl_data
->vl_oi
;
2374 if (IS_DEBUG_OSPF_EVENT
)
2375 zlog_debug("couldn't find any VL to associate the packet with");
2380 static int ospf_check_area_id(struct ospf_interface
*oi
,
2381 struct ospf_header
*ospfh
)
2383 /* Check match the Area ID of the receiving interface. */
2384 if (OSPF_AREA_SAME(&oi
->area
, &ospfh
))
2390 /* Unbound socket will accept any Raw IP packets if proto is matched.
2391 To prevent it, compare src IP address and i/f address with masking
2392 i/f network mask. */
2393 static int ospf_check_network_mask(struct ospf_interface
*oi
,
2394 struct in_addr ip_src
)
2396 struct in_addr mask
, me
, him
;
2398 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
2399 || oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2402 masklen2ip(oi
->address
->prefixlen
, &mask
);
2404 me
.s_addr
= oi
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
2405 him
.s_addr
= ip_src
.s_addr
& mask
.s_addr
;
2407 if (IPV4_ADDR_SAME(&me
, &him
))
2413 /* Return 1, if the packet is properly authenticated and checksummed,
2414 0 otherwise. In particular, check that AuType header field is valid and
2415 matches the locally configured AuType, and that D.5 requirements are met. */
2416 static int ospf_check_auth(struct ospf_interface
*oi
, struct ospf_header
*ospfh
)
2418 struct crypt_key
*ck
;
2419 u_int16_t iface_auth_type
;
2420 u_int16_t pkt_auth_type
= ntohs(ospfh
->auth_type
);
2422 switch (pkt_auth_type
) {
2423 case OSPF_AUTH_NULL
: /* RFC2328 D.5.1 */
2424 if (OSPF_AUTH_NULL
!= (iface_auth_type
= ospf_auth_type(oi
))) {
2425 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2427 "interface %s: auth-type mismatch, local %s, rcvd Null",
2429 lookup_msg(ospf_auth_type_str
,
2430 iface_auth_type
, NULL
));
2433 if (!ospf_check_sum(ospfh
)) {
2434 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2436 "interface %s: Null auth OK, but checksum error, Router-ID %s",
2438 inet_ntoa(ospfh
->router_id
));
2442 case OSPF_AUTH_SIMPLE
: /* RFC2328 D.5.2 */
2443 if (OSPF_AUTH_SIMPLE
2444 != (iface_auth_type
= ospf_auth_type(oi
))) {
2445 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2447 "interface %s: auth-type mismatch, local %s, rcvd Simple",
2449 lookup_msg(ospf_auth_type_str
,
2450 iface_auth_type
, NULL
));
2453 if (memcmp(OSPF_IF_PARAM(oi
, auth_simple
), ospfh
->u
.auth_data
,
2454 OSPF_AUTH_SIMPLE_SIZE
)) {
2455 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2456 zlog_warn("interface %s: Simple auth failed",
2460 if (!ospf_check_sum(ospfh
)) {
2461 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2463 "interface %s: Simple auth OK, checksum error, Router-ID %s",
2465 inet_ntoa(ospfh
->router_id
));
2469 case OSPF_AUTH_CRYPTOGRAPHIC
: /* RFC2328 D.5.3 */
2470 if (OSPF_AUTH_CRYPTOGRAPHIC
2471 != (iface_auth_type
= ospf_auth_type(oi
))) {
2472 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2474 "interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2476 lookup_msg(ospf_auth_type_str
,
2477 iface_auth_type
, NULL
));
2480 if (ospfh
->checksum
) {
2481 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2483 "interface %s: OSPF header checksum is not 0",
2487 /* only MD5 crypto method can pass ospf_packet_examin() */
2489 NULL
== (ck
= listgetdata(listtail(
2490 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(u_int16_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
,
2539 u_int16_t linkbytes
,
2540 const u_int16_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 u_int16_t lsalen
,
2569 const u_char 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 u_char headeronly
,
2653 /* When declared_num_lsas is not 0, compare it to the real
2655 and treat the difference as an error. */
2656 const u_int32_t declared_num_lsas
)
2658 u_int32_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 u_int16_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
= (u_char
)OSPF_VERSION
;
3116 ospfh
->type
= (u_char
)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 u_int16_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 u_int16_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
, u_int16_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 u_int16_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 u_int16_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 u_int16_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 u_int16_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
)
3542 zlog_debug("%s: Hello Tx interface %s ospf vrf %s id %u",
3543 __PRETTY_FUNCTION__
, oi
->ifp
->name
,
3544 ospf_vrf_id_to_name(oi
->ospf
->vrf_id
),
3547 /* Add packet to the top of the interface output queue, so that they
3548 * can't get delayed by things like long queues of LS Update packets
3550 ospf_packet_add_top(oi
, op
);
3552 /* Hook thread to write packet. */
3553 OSPF_ISM_WRITE_ON(oi
->ospf
);
3556 static void ospf_poll_send(struct ospf_nbr_nbma
*nbr_nbma
)
3558 struct ospf_interface
*oi
;
3563 /* If this is passive interface, do not send OSPF Hello. */
3564 if (OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
)
3567 if (oi
->type
!= OSPF_IFTYPE_NBMA
)
3570 if (nbr_nbma
->nbr
!= NULL
&& nbr_nbma
->nbr
->state
!= NSM_Down
)
3573 if (PRIORITY(oi
) == 0)
3576 if (nbr_nbma
->priority
== 0 && oi
->state
!= ISM_DR
3577 && oi
->state
!= ISM_Backup
)
3580 ospf_hello_send_sub(oi
, nbr_nbma
->addr
.s_addr
);
3583 int ospf_poll_timer(struct thread
*thread
)
3585 struct ospf_nbr_nbma
*nbr_nbma
;
3587 nbr_nbma
= THREAD_ARG(thread
);
3588 nbr_nbma
->t_poll
= NULL
;
3590 if (IS_DEBUG_OSPF(nsm
, NSM_TIMERS
))
3591 zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)",
3592 IF_NAME(nbr_nbma
->oi
), inet_ntoa(nbr_nbma
->addr
));
3594 ospf_poll_send(nbr_nbma
);
3596 if (nbr_nbma
->v_poll
> 0)
3597 OSPF_POLL_TIMER_ON(nbr_nbma
->t_poll
, ospf_poll_timer
,
3604 int ospf_hello_reply_timer(struct thread
*thread
)
3606 struct ospf_neighbor
*nbr
;
3608 nbr
= THREAD_ARG(thread
);
3609 nbr
->t_hello_reply
= NULL
;
3613 if (IS_DEBUG_OSPF(nsm
, NSM_TIMERS
))
3614 zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)",
3615 IF_NAME(nbr
->oi
), inet_ntoa(nbr
->router_id
));
3617 ospf_hello_send_sub(nbr
->oi
, nbr
->address
.u
.prefix4
.s_addr
);
3622 /* Send OSPF Hello. */
3623 void ospf_hello_send(struct ospf_interface
*oi
)
3625 /* If this is passive interface, do not send OSPF Hello. */
3626 if (OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
)
3629 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
3630 struct ospf_neighbor
*nbr
;
3631 struct route_node
*rn
;
3633 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
3634 if ((nbr
= rn
->info
))
3635 if (nbr
!= oi
->nbr_self
)
3636 if (nbr
->state
!= NSM_Down
) {
3637 /* RFC 2328 Section 9.5.1
3638 If the router is not
3639 eligible to become Designated
3641 it must periodically send
3642 Hello Packets to both the
3643 Designated Router and the
3644 Backup Designated Router (if
3647 if (PRIORITY(oi
) == 0
3658 /* If the router is eligible to
3659 become Designated Router, it
3660 must periodically send Hello
3661 Packets to all neighbors that
3662 are also eligible. In
3663 addition, if the router is
3665 Designated Router or Backup
3666 Designated Router, it must
3668 send periodic Hello Packets
3669 to all other neighbors. */
3671 if (nbr
->priority
== 0
3672 && oi
->state
== ISM_DROther
)
3674 /* if oi->state == Waiting, send
3675 * hello to all neighbors */
3676 ospf_hello_send_sub(
3678 nbr
->address
.u
.prefix4
3682 /* Decide destination address. */
3683 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
3684 ospf_hello_send_sub(oi
, oi
->vl_data
->peer_addr
.s_addr
);
3686 ospf_hello_send_sub(oi
, htonl(OSPF_ALLSPFROUTERS
));
3690 /* Send OSPF Database Description. */
3691 void ospf_db_desc_send(struct ospf_neighbor
*nbr
)
3693 struct ospf_interface
*oi
;
3694 struct ospf_packet
*op
;
3695 u_int16_t length
= OSPF_HEADER_SIZE
;
3698 op
= ospf_packet_new(oi
->ifp
->mtu
);
3700 /* Prepare OSPF common header. */
3701 ospf_make_header(OSPF_MSG_DB_DESC
, oi
, op
->s
);
3703 /* Prepare OSPF Database Description body. */
3704 length
+= ospf_make_db_desc(oi
, nbr
, op
->s
);
3706 /* Fill OSPF header. */
3707 ospf_fill_header(oi
, op
->s
, length
);
3709 /* Set packet length. */
3710 op
->length
= length
;
3712 /* Decide destination address. */
3713 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3714 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3716 op
->dst
= nbr
->address
.u
.prefix4
;
3718 /* Add packet to the interface output queue. */
3719 ospf_packet_add(oi
, op
);
3721 /* Hook thread to write packet. */
3722 OSPF_ISM_WRITE_ON(oi
->ospf
);
3724 /* Remove old DD packet, then copy new one and keep in neighbor
3727 ospf_packet_free(nbr
->last_send
);
3728 nbr
->last_send
= ospf_packet_dup(op
);
3729 monotime(&nbr
->last_send_ts
);
3732 /* Re-send Database Description. */
3733 void ospf_db_desc_resend(struct ospf_neighbor
*nbr
)
3735 struct ospf_interface
*oi
;
3739 /* Add packet to the interface output queue. */
3740 ospf_packet_add(oi
, ospf_packet_dup(nbr
->last_send
));
3742 /* Hook thread to write packet. */
3743 OSPF_ISM_WRITE_ON(oi
->ospf
);
3746 /* Send Link State Request. */
3747 void ospf_ls_req_send(struct ospf_neighbor
*nbr
)
3749 struct ospf_interface
*oi
;
3750 struct ospf_packet
*op
;
3751 u_int16_t length
= OSPF_HEADER_SIZE
;
3754 op
= ospf_packet_new(oi
->ifp
->mtu
);
3756 /* Prepare OSPF common header. */
3757 ospf_make_header(OSPF_MSG_LS_REQ
, oi
, op
->s
);
3759 /* Prepare OSPF Link State Request body. */
3760 length
+= ospf_make_ls_req(nbr
, op
->s
);
3761 if (length
== OSPF_HEADER_SIZE
) {
3762 ospf_packet_free(op
);
3766 /* Fill OSPF header. */
3767 ospf_fill_header(oi
, op
->s
, length
);
3769 /* Set packet length. */
3770 op
->length
= length
;
3772 /* Decide destination address. */
3773 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3774 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3776 op
->dst
= nbr
->address
.u
.prefix4
;
3778 /* Add packet to the interface output queue. */
3779 ospf_packet_add(oi
, op
);
3781 /* Hook thread to write packet. */
3782 OSPF_ISM_WRITE_ON(oi
->ospf
);
3784 /* Add Link State Request Retransmission Timer. */
3785 OSPF_NSM_TIMER_ON(nbr
->t_ls_req
, ospf_ls_req_timer
, nbr
->v_ls_req
);
3788 /* Send Link State Update with an LSA. */
3789 void ospf_ls_upd_send_lsa(struct ospf_neighbor
*nbr
, struct ospf_lsa
*lsa
,
3792 struct list
*update
;
3794 update
= list_new();
3796 listnode_add(update
, lsa
);
3798 /*ospf instance is going down, send self originated
3799 * MAXAGE LSA update to neighbors to remove from LSDB */
3800 if (nbr
->oi
->ospf
->inst_shutdown
&& IS_LSA_MAXAGE(lsa
))
3801 ospf_ls_upd_send(nbr
, update
, flag
, 1);
3803 ospf_ls_upd_send(nbr
, update
, flag
, 0);
3805 list_delete_and_null(&update
);
3808 /* Determine size for packet. Must be at least big enough to accomodate next
3809 * LSA on list, which may be bigger than MTU size.
3811 * Return pointer to new ospf_packet
3812 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3813 * on packet sizes (in which case offending LSA is deleted from update list)
3815 static struct ospf_packet
*ospf_ls_upd_packet_new(struct list
*update
,
3816 struct ospf_interface
*oi
)
3818 struct ospf_lsa
*lsa
;
3819 struct listnode
*ln
;
3821 static char warned
= 0;
3823 lsa
= listgetdata((ln
= listhead(update
)));
3826 if ((OSPF_LS_UPD_MIN_SIZE
+ ntohs(lsa
->data
->length
))
3827 > ospf_packet_max(oi
)) {
3830 "ospf_ls_upd_packet_new: oversized LSA encountered!"
3831 "will need to fragment. Not optimal. Try divide up"
3832 " your network with areas. Use 'debug ospf packet send'"
3833 " to see details, or look at 'show ip ospf database ..'");
3837 if (IS_DEBUG_OSPF_PACKET(0, SEND
))
3839 "ospf_ls_upd_packet_new: oversized LSA id:%s,"
3840 " %d bytes originated by %s, will be fragmented!",
3841 inet_ntoa(lsa
->data
->id
),
3842 ntohs(lsa
->data
->length
),
3843 inet_ntoa(lsa
->data
->adv_router
));
3846 * Allocate just enough to fit this LSA only, to avoid including
3848 * LSAs in fragmented LSA Updates.
3850 size
= ntohs(lsa
->data
->length
)
3851 + (oi
->ifp
->mtu
- ospf_packet_max(oi
))
3852 + OSPF_LS_UPD_MIN_SIZE
;
3854 size
= oi
->ifp
->mtu
;
3856 if (size
> OSPF_MAX_PACKET_SIZE
) {
3858 "ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3859 " %d bytes, packet size %ld, dropping it completely."
3860 " OSPF routing is broken!",
3861 inet_ntoa(lsa
->data
->id
), ntohs(lsa
->data
->length
),
3863 list_delete_node(update
, ln
);
3867 /* IP header is built up separately by ospf_write(). This means, that we
3869 * reduce the "affordable" size just calculated by length of an IP
3871 * This makes sure, that even if we manage to fill the payload with LSA
3873 * completely, the final packet (our data plus IP header) still fits
3875 * outgoing interface MTU. This correction isn't really meaningful for
3877 * oversized LSA, but for consistency the correction is done for both
3880 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3882 return ospf_packet_new(size
- sizeof(struct ip
));
3885 static void ospf_ls_upd_queue_send(struct ospf_interface
*oi
,
3886 struct list
*update
, struct in_addr addr
,
3889 struct ospf_packet
*op
;
3890 u_int16_t length
= OSPF_HEADER_SIZE
;
3892 if (IS_DEBUG_OSPF_EVENT
)
3893 zlog_debug("listcount = %d, [%s]dst %s", listcount(update
),
3894 IF_NAME(oi
), inet_ntoa(addr
));
3896 op
= ospf_ls_upd_packet_new(update
, oi
);
3898 /* Prepare OSPF common header. */
3899 ospf_make_header(OSPF_MSG_LS_UPD
, oi
, op
->s
);
3901 /* Prepare OSPF Link State Update body.
3902 * Includes Type-7 translation.
3904 length
+= ospf_make_ls_upd(oi
, update
, op
->s
);
3906 /* Fill OSPF header. */
3907 ospf_fill_header(oi
, op
->s
, length
);
3909 /* Set packet length. */
3910 op
->length
= length
;
3912 /* Decide destination address. */
3913 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3914 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3916 op
->dst
.s_addr
= addr
.s_addr
;
3918 /* Add packet to the interface output queue. */
3919 ospf_packet_add(oi
, op
);
3920 /* Call ospf_write() right away to send ospf packets to neighbors */
3921 if (send_lsupd_now
) {
3922 struct thread os_packet_thd
;
3924 os_packet_thd
.arg
= (void *)oi
->ospf
;
3925 if (oi
->on_write_q
== 0) {
3926 listnode_add(oi
->ospf
->oi_write_q
, oi
);
3929 ospf_write(&os_packet_thd
);
3931 /* Hook thread to write packet. */
3932 OSPF_ISM_WRITE_ON(oi
->ospf
);
3936 static int ospf_ls_upd_send_queue_event(struct thread
*thread
)
3938 struct ospf_interface
*oi
= THREAD_ARG(thread
);
3939 struct route_node
*rn
;
3940 struct route_node
*rnext
;
3941 struct list
*update
;
3944 oi
->t_ls_upd_event
= NULL
;
3946 if (IS_DEBUG_OSPF_EVENT
)
3947 zlog_debug("ospf_ls_upd_send_queue start");
3949 for (rn
= route_top(oi
->ls_upd_queue
); rn
; rn
= rnext
) {
3950 rnext
= route_next(rn
);
3952 if (rn
->info
== NULL
)
3955 update
= (struct list
*)rn
->info
;
3957 ospf_ls_upd_queue_send(oi
, update
, rn
->p
.u
.prefix4
, 0);
3959 /* list might not be empty. */
3960 if (listcount(update
) == 0) {
3961 list_delete_and_null((struct list
**)&rn
->info
);
3962 route_unlock_node(rn
);
3968 if (IS_DEBUG_OSPF_EVENT
)
3970 "ospf_ls_upd_send_queue: update lists not cleared,"
3971 " %d nodes to try again, raising new event",
3973 oi
->t_ls_upd_event
= NULL
;
3974 thread_add_event(master
, ospf_ls_upd_send_queue_event
, oi
, 0,
3975 &oi
->t_ls_upd_event
);
3978 if (IS_DEBUG_OSPF_EVENT
)
3979 zlog_debug("ospf_ls_upd_send_queue stop");
3984 void ospf_ls_upd_send(struct ospf_neighbor
*nbr
, struct list
*update
, int flag
,
3987 struct ospf_interface
*oi
;
3988 struct ospf_lsa
*lsa
;
3989 struct prefix_ipv4 p
;
3990 struct route_node
*rn
;
3991 struct listnode
*node
;
3996 p
.prefixlen
= IPV4_MAX_BITLEN
;
3998 /* Decide destination address. */
3999 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
4000 p
.prefix
= oi
->vl_data
->peer_addr
;
4001 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4002 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4003 else if (flag
== OSPF_SEND_PACKET_DIRECT
)
4004 p
.prefix
= nbr
->address
.u
.prefix4
;
4005 else if (oi
->state
== ISM_DR
|| oi
->state
== ISM_Backup
)
4006 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4007 else if (oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
4008 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4010 p
.prefix
.s_addr
= htonl(OSPF_ALLDROUTERS
);
4012 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
4013 if (flag
== OSPF_SEND_PACKET_INDIRECT
)
4015 "* LS-Update is directly sent on NBMA network.");
4016 if (IPV4_ADDR_SAME(&oi
->address
->u
.prefix4
, &p
.prefix
))
4017 zlog_warn("* LS-Update is sent to myself.");
4020 rn
= route_node_get(oi
->ls_upd_queue
, (struct prefix
*)&p
);
4022 if (rn
->info
== NULL
)
4023 rn
->info
= list_new();
4025 route_unlock_node(rn
);
4027 for (ALL_LIST_ELEMENTS_RO(update
, node
, lsa
))
4028 listnode_add(rn
->info
,
4029 ospf_lsa_lock(lsa
)); /* oi->ls_upd_queue */
4030 if (send_lsupd_now
) {
4031 struct list
*send_update_list
;
4032 struct route_node
*rn
, *rnext
;
4034 for (rn
= route_top(oi
->ls_upd_queue
); rn
; rn
= rnext
) {
4035 rnext
= route_next(rn
);
4037 if (rn
->info
== NULL
)
4040 send_update_list
= (struct list
*)rn
->info
;
4042 ospf_ls_upd_queue_send(oi
, send_update_list
,
4043 rn
->p
.u
.prefix4
, 1);
4047 thread_add_event(master
, ospf_ls_upd_send_queue_event
, oi
, 0,
4048 &oi
->t_ls_upd_event
);
4051 static void ospf_ls_ack_send_list(struct ospf_interface
*oi
, struct list
*ack
,
4054 struct ospf_packet
*op
;
4055 u_int16_t length
= OSPF_HEADER_SIZE
;
4057 op
= ospf_packet_new(oi
->ifp
->mtu
);
4059 /* Prepare OSPF common header. */
4060 ospf_make_header(OSPF_MSG_LS_ACK
, oi
, op
->s
);
4062 /* Prepare OSPF Link State Acknowledgment body. */
4063 length
+= ospf_make_ls_ack(oi
, ack
, op
->s
);
4065 /* Fill OSPF header. */
4066 ospf_fill_header(oi
, op
->s
, length
);
4068 /* Set packet length. */
4069 op
->length
= length
;
4071 /* Decide destination address. */
4072 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4073 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4075 op
->dst
.s_addr
= dst
.s_addr
;
4077 /* Add packet to the interface output queue. */
4078 ospf_packet_add(oi
, op
);
4080 /* Hook thread to write packet. */
4081 OSPF_ISM_WRITE_ON(oi
->ospf
);
4084 static int ospf_ls_ack_send_event(struct thread
*thread
)
4086 struct ospf_interface
*oi
= THREAD_ARG(thread
);
4088 oi
->t_ls_ack_direct
= NULL
;
4090 while (listcount(oi
->ls_ack_direct
.ls_ack
))
4091 ospf_ls_ack_send_list(oi
, oi
->ls_ack_direct
.ls_ack
,
4092 oi
->ls_ack_direct
.dst
);
4097 void ospf_ls_ack_send(struct ospf_neighbor
*nbr
, struct ospf_lsa
*lsa
)
4099 struct ospf_interface
*oi
= nbr
->oi
;
4101 if (listcount(oi
->ls_ack_direct
.ls_ack
) == 0)
4102 oi
->ls_ack_direct
.dst
= nbr
->address
.u
.prefix4
;
4104 listnode_add(oi
->ls_ack_direct
.ls_ack
, ospf_lsa_lock(lsa
));
4106 thread_add_event(master
, ospf_ls_ack_send_event
, oi
, 0,
4107 &oi
->t_ls_ack_direct
);
4110 /* Send Link State Acknowledgment delayed. */
4111 void ospf_ls_ack_send_delayed(struct ospf_interface
*oi
)
4115 /* Decide destination address. */
4116 /* RFC2328 Section 13.5 On non-broadcast
4117 networks, delayed Link State Acknowledgment packets must be
4118 unicast separately over each adjacency (i.e., neighbor whose
4119 state is >= Exchange). */
4120 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
4121 struct ospf_neighbor
*nbr
;
4122 struct route_node
*rn
;
4124 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
4125 if ((nbr
= rn
->info
) != NULL
)
4126 if (nbr
!= oi
->nbr_self
4127 && nbr
->state
>= NSM_Exchange
)
4128 while (listcount(oi
->ls_ack
))
4129 ospf_ls_ack_send_list(
4131 nbr
->address
.u
.prefix4
);
4134 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
4135 dst
.s_addr
= oi
->vl_data
->peer_addr
.s_addr
;
4136 else if (oi
->state
== ISM_DR
|| oi
->state
== ISM_Backup
)
4137 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4138 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4139 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4140 else if (oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
4141 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4143 dst
.s_addr
= htonl(OSPF_ALLDROUTERS
);
4145 while (listcount(oi
->ls_ack
))
4146 ospf_ls_ack_send_list(oi
, oi
->ls_ack
, dst
);
4150 * On pt-to-pt links, all OSPF control packets are sent to the multicast
4151 * address. As a result, the kernel does not need to learn the interface
4152 * MAC of the OSPF neighbor. However, in our world, this will delay
4153 * convergence. Take the case when due to a link flap, all routes now
4154 * want to use an interface which was deemed to be costlier prior to this
4155 * event. For routes that will be installed, the missing MAC will have
4156 * punt-to-CPU set on them. This may overload the CPU control path that
4157 * can be avoided if the MAC was known apriori.
4159 #define OSPF_PING_NBR_STR_MAX (BUFSIZ)
4160 void ospf_proactively_arp(struct ospf_neighbor
*nbr
)
4162 char ping_nbr
[OSPF_PING_NBR_STR_MAX
];
4165 if (!nbr
|| !nbr
->oi
|| !nbr
->oi
->ifp
)
4168 snprintf(ping_nbr
, sizeof(ping_nbr
),
4169 "ping -c 1 -I %s %s > /dev/null 2>&1 &",
4170 nbr
->oi
->ifp
->name
, inet_ntoa(nbr
->address
.u
.prefix4
));
4172 ret
= system(ping_nbr
);
4173 if (IS_DEBUG_OSPF_EVENT
)
4174 zlog_debug("Executed %s %s", ping_nbr
,
4175 ((ret
== 0) ? "successfully" : "but failed"));