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
, OSPF_SEND_PACKET_DIRECT
,
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 */
648 #define OSPF_WRITE_IPHL_SHIFT 2
652 unsigned char cmsgbuf
[64] = {};
653 struct cmsghdr
*cm
= (struct cmsghdr
*)cmsgbuf
;
654 struct in_pktinfo
*pi
;
657 ospf
->t_write
= NULL
;
659 node
= listhead(ospf
->oi_write_q
);
661 oi
= listgetdata(node
);
664 #ifdef WANT_OSPF_WRITE_FRAGMENT
665 /* seed ipid static with low order bits of time */
667 ipid
= (time(NULL
) & 0xffff);
668 #endif /* WANT_OSPF_WRITE_FRAGMENT */
670 while ((pkt_count
< ospf
->write_oi_count
) && oi
671 && (last_serviced_oi
!= oi
)) {
672 /* If there is only packet in the queue, the oi is removed from
673 write-q, so fix up the last interface that was serviced */
674 if (last_serviced_oi
== NULL
) {
675 last_serviced_oi
= oi
;
678 #ifdef WANT_OSPF_WRITE_FRAGMENT
679 /* convenience - max OSPF data per packet */
680 maxdatasize
= oi
->ifp
->mtu
- sizeof(struct ip
);
681 #endif /* WANT_OSPF_WRITE_FRAGMENT */
682 /* Get one packet from queue. */
683 op
= ospf_fifo_head(oi
->obuf
);
685 assert(op
->length
>= OSPF_HEADER_SIZE
);
687 if (op
->dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
)
688 || op
->dst
.s_addr
== htonl(OSPF_ALLDROUTERS
))
689 ospf_if_ipmulticast(ospf
, oi
->address
,
692 /* Rewrite the md5 signature & update the seq */
693 ospf_make_md5_digest(oi
, op
);
695 /* Retrieve OSPF packet type. */
696 stream_set_getp(op
->s
, 1);
697 type
= stream_getc(op
->s
);
699 /* reset get pointer */
700 stream_set_getp(op
->s
, 0);
702 memset(&iph
, 0, sizeof(struct ip
));
703 memset(&sa_dst
, 0, sizeof(sa_dst
));
705 sa_dst
.sin_family
= AF_INET
;
706 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
707 sa_dst
.sin_len
= sizeof(sa_dst
);
708 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
709 sa_dst
.sin_addr
= op
->dst
;
710 sa_dst
.sin_port
= htons(0);
712 /* Set DONTROUTE flag if dst is unicast. */
713 if (oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
714 if (!IN_MULTICAST(htonl(op
->dst
.s_addr
)))
715 flags
= MSG_DONTROUTE
;
717 iph
.ip_hl
= sizeof(struct ip
) >> OSPF_WRITE_IPHL_SHIFT
;
718 /* it'd be very strange for header to not be 4byte-word aligned
720 if (sizeof(struct ip
)
721 > (unsigned int)(iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
))
722 iph
.ip_hl
++; /* we presume sizeof struct ip cant
725 iph
.ip_v
= IPVERSION
;
726 iph
.ip_tos
= IPTOS_PREC_INTERNETCONTROL
;
727 iph
.ip_len
= (iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
) + op
->length
;
729 #if defined(__DragonFly__)
731 * DragonFly's raw socket expects ip_len/ip_off in network byte
734 iph
.ip_len
= htons(iph
.ip_len
);
737 #ifdef WANT_OSPF_WRITE_FRAGMENT
738 /* XXX-MT: not thread-safe at all..
739 * XXX: this presumes this is only programme sending OSPF
741 * otherwise, no guarantee ipid will be unique
744 #endif /* WANT_OSPF_WRITE_FRAGMENT */
747 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
748 iph
.ip_ttl
= OSPF_VL_IP_TTL
;
750 iph
.ip_ttl
= OSPF_IP_TTL
;
751 iph
.ip_p
= IPPROTO_OSPFIGP
;
753 iph
.ip_src
.s_addr
= oi
->address
->u
.prefix4
.s_addr
;
754 iph
.ip_dst
.s_addr
= op
->dst
.s_addr
;
756 memset(&msg
, 0, sizeof(msg
));
757 msg
.msg_name
= (caddr_t
)&sa_dst
;
758 msg
.msg_namelen
= sizeof(sa_dst
);
762 iov
[0].iov_base
= (char *)&iph
;
763 iov
[0].iov_len
= iph
.ip_hl
<< OSPF_WRITE_IPHL_SHIFT
;
764 iov
[1].iov_base
= stream_pnt(op
->s
);
765 iov
[1].iov_len
= op
->length
;
768 msg
.msg_control
= (caddr_t
)cm
;
769 cm
->cmsg_level
= SOL_IP
;
770 cm
->cmsg_type
= IP_PKTINFO
;
771 cm
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
772 pi
= (struct in_pktinfo
*)CMSG_DATA(cm
);
773 pi
->ipi_ifindex
= oi
->ifp
->ifindex
;
775 msg
.msg_controllen
= cm
->cmsg_len
;
778 /* Sadly we can not rely on kernels to fragment packets
779 * because of either IP_HDRINCL and/or multicast
780 * destination being set.
783 #ifdef WANT_OSPF_WRITE_FRAGMENT
784 if (op
->length
> maxdatasize
)
785 ospf_write_frags(ospf
->fd
, op
, &iph
, &msg
, maxdatasize
,
786 oi
->ifp
->mtu
, flags
, type
);
787 #endif /* WANT_OSPF_WRITE_FRAGMENT */
789 /* send final fragment (could be first) */
790 sockopt_iphdrincl_swab_htosys(&iph
);
791 ret
= sendmsg(ospf
->fd
, &msg
, flags
);
792 sockopt_iphdrincl_swab_systoh(&iph
);
793 if (IS_DEBUG_OSPF_EVENT
)
796 "id %d, off %d, len %d, interface %s, mtu %u:",
797 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
,
798 iph
.ip_len
, oi
->ifp
->name
, oi
->ifp
->mtu
);
802 "*** sendmsg in ospf_write failed to %s, "
803 "id %d, off %d, len %d, interface %s, mtu %u: %s",
804 inet_ntoa(iph
.ip_dst
), iph
.ip_id
, iph
.ip_off
,
805 iph
.ip_len
, oi
->ifp
->name
, oi
->ifp
->mtu
,
806 safe_strerror(errno
));
808 /* Show debug sending packet. */
809 if (IS_DEBUG_OSPF_PACKET(type
- 1, SEND
)) {
810 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
)) {
812 "-----------------------------------------------------");
813 ospf_ip_header_dump(&iph
);
814 stream_set_getp(op
->s
, 0);
815 ospf_packet_dump(op
->s
);
818 zlog_debug("%s sent to [%s] via [%s].",
819 lookup_msg(ospf_packet_type_str
, type
, NULL
),
820 inet_ntoa(op
->dst
), IF_NAME(oi
));
822 if (IS_DEBUG_OSPF_PACKET(type
- 1, DETAIL
))
824 "-----------------------------------------------------");
831 case OSPF_MSG_DB_DESC
:
834 case OSPF_MSG_LS_REQ
:
837 case OSPF_MSG_LS_UPD
:
840 case OSPF_MSG_LS_ACK
:
847 /* Now delete packet from queue. */
848 ospf_packet_delete(oi
);
850 /* Move this interface to the tail of write_q to
851 serve everyone in a round robin fashion */
852 list_delete_node(ospf
->oi_write_q
, node
);
853 if (ospf_fifo_head(oi
->obuf
) == NULL
) {
855 last_serviced_oi
= NULL
;
858 listnode_add(ospf
->oi_write_q
, oi
);
861 /* Setup to service from the head of the queue again */
862 if (!list_isempty(ospf
->oi_write_q
)) {
863 node
= listhead(ospf
->oi_write_q
);
865 oi
= listgetdata(node
);
870 /* If packets still remain in queue, call write thread. */
871 if (!list_isempty(ospf
->oi_write_q
)) {
872 ospf
->t_write
= NULL
;
873 thread_add_write(master
, ospf_write
, ospf
, ospf
->fd
,
880 /* OSPF Hello message read -- RFC2328 Section 10.5. */
881 static void ospf_hello(struct ip
*iph
, struct ospf_header
*ospfh
,
882 struct stream
*s
, struct ospf_interface
*oi
, int size
)
884 struct ospf_hello
*hello
;
885 struct ospf_neighbor
*nbr
;
889 /* increment statistics. */
892 hello
= (struct ospf_hello
*)stream_pnt(s
);
894 /* If Hello is myself, silently discard. */
895 if (IPV4_ADDR_SAME(&ospfh
->router_id
, &oi
->ospf
->router_id
)) {
896 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
)) {
898 "ospf_header[%s/%s]: selforiginated, "
900 lookup_msg(ospf_packet_type_str
, ospfh
->type
,
902 inet_ntoa(iph
->ip_src
));
907 /* get neighbor prefix. */
909 p
.prefixlen
= ip_masklen(hello
->network_mask
);
910 p
.u
.prefix4
= iph
->ip_src
;
912 /* Compare network mask. */
913 /* Checking is ignored for Point-to-Point and Virtual link. */
914 if (oi
->type
!= OSPF_IFTYPE_POINTOPOINT
915 && oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
916 if (oi
->address
->prefixlen
!= p
.prefixlen
) {
918 "Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
919 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
),
920 (int)oi
->address
->prefixlen
, (int)p
.prefixlen
);
924 /* Compare Router Dead Interval. */
925 if (OSPF_IF_PARAM(oi
, v_wait
) != ntohl(hello
->dead_interval
)) {
927 "Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
928 "(expected %u, but received %u).",
929 inet_ntoa(ospfh
->router_id
), OSPF_IF_PARAM(oi
, v_wait
),
930 ntohl(hello
->dead_interval
));
934 /* Compare Hello Interval - ignored if fast-hellos are set. */
935 if (OSPF_IF_PARAM(oi
, fast_hello
) == 0) {
936 if (OSPF_IF_PARAM(oi
, v_hello
)
937 != ntohs(hello
->hello_interval
)) {
939 "Packet %s [Hello:RECV]: HelloInterval mismatch "
940 "(expected %u, but received %u).",
941 inet_ntoa(ospfh
->router_id
),
942 OSPF_IF_PARAM(oi
, v_hello
),
943 ntohs(hello
->hello_interval
));
948 if (IS_DEBUG_OSPF_EVENT
)
949 zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
950 inet_ntoa(ospfh
->router_id
),
951 ospf_options_dump(hello
->options
),
952 ospf_vrf_id_to_name(oi
->ospf
->vrf_id
));
954 /* Compare options. */
955 #define REJECT_IF_TBIT_ON 1 /* XXX */
956 #ifdef REJECT_IF_TBIT_ON
957 if (CHECK_FLAG(hello
->options
, OSPF_OPTION_MT
)) {
959 * This router does not support non-zero TOS.
960 * Drop this Hello packet not to establish neighbor
963 zlog_warn("Packet %s [Hello:RECV]: T-bit on, drop it.",
964 inet_ntoa(ospfh
->router_id
));
967 #endif /* REJECT_IF_TBIT_ON */
969 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)
970 && CHECK_FLAG(hello
->options
, OSPF_OPTION_O
)) {
972 * This router does know the correct usage of O-bit
973 * the bit should be set in DD packet only.
975 zlog_warn("Packet %s [Hello:RECV]: O-bit abuse?",
976 inet_ntoa(ospfh
->router_id
));
977 #ifdef STRICT_OBIT_USAGE_CHECK
978 return; /* Reject this packet. */
979 #else /* STRICT_OBIT_USAGE_CHECK */
980 UNSET_FLAG(hello
->options
, OSPF_OPTION_O
); /* Ignore O-bit. */
981 #endif /* STRICT_OBIT_USAGE_CHECK */
984 /* new for NSSA is to ensure that NP is on and E is off */
986 if (oi
->area
->external_routing
== OSPF_AREA_NSSA
) {
987 if (!(CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_NP
)
988 && CHECK_FLAG(hello
->options
, OSPF_OPTION_NP
)
989 && !CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_E
)
990 && !CHECK_FLAG(hello
->options
, OSPF_OPTION_E
))) {
992 "NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x",
993 inet_ntoa(ospfh
->router_id
), OPTIONS(oi
),
997 if (IS_DEBUG_OSPF_NSSA
)
998 zlog_debug("NSSA-Hello:RECV:Packet from %s:",
999 inet_ntoa(ospfh
->router_id
));
1001 /* The setting of the E-bit found in the Hello Packet's Options
1002 field must match this area's ExternalRoutingCapability A
1003 mismatch causes processing to stop and the packet to be
1004 dropped. The setting of the rest of the bits in the Hello
1005 Packet's Options field should be ignored. */
1006 if (CHECK_FLAG(OPTIONS(oi
), OSPF_OPTION_E
)
1007 != CHECK_FLAG(hello
->options
, OSPF_OPTION_E
)) {
1009 "Packet %s [Hello:RECV]: my options: %x, his options %x",
1010 inet_ntoa(ospfh
->router_id
), OPTIONS(oi
),
1015 /* get neighbour struct */
1016 nbr
= ospf_nbr_get(oi
, ospfh
, iph
, &p
);
1018 /* neighbour must be valid, ospf_nbr_get creates if none existed */
1021 old_state
= nbr
->state
;
1023 /* Add event to thread. */
1024 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1026 /* RFC2328 Section 9.5.1
1027 If the router is not eligible to become Designated Router,
1028 (snip) It must also send an Hello Packet in reply to an
1029 Hello Packet received from any eligible neighbor (other than
1030 the current Designated Router and Backup Designated Router). */
1031 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1032 if (PRIORITY(oi
) == 0 && hello
->priority
> 0
1033 && IPV4_ADDR_CMP(&DR(oi
), &iph
->ip_src
)
1034 && IPV4_ADDR_CMP(&BDR(oi
), &iph
->ip_src
))
1035 OSPF_NSM_TIMER_ON(nbr
->t_hello_reply
,
1036 ospf_hello_reply_timer
,
1037 OSPF_HELLO_REPLY_DELAY
);
1039 /* on NBMA network type, it happens to receive bidirectional Hello
1041 without advance 1-Way Received event.
1042 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
1043 if (oi
->type
== OSPF_IFTYPE_NBMA
1044 && (old_state
== NSM_Down
|| old_state
== NSM_Attempt
)) {
1045 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_OneWayReceived
);
1046 nbr
->priority
= hello
->priority
;
1047 nbr
->d_router
= hello
->d_router
;
1048 nbr
->bd_router
= hello
->bd_router
;
1052 if (ospf_nbr_bidirectional(&oi
->ospf
->router_id
, hello
->neighbors
,
1053 size
- OSPF_HELLO_MIN_SIZE
)) {
1054 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_TwoWayReceived
);
1055 nbr
->options
|= hello
->options
;
1057 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_OneWayReceived
);
1058 /* Set neighbor information. */
1059 nbr
->priority
= hello
->priority
;
1060 nbr
->d_router
= hello
->d_router
;
1061 nbr
->bd_router
= hello
->bd_router
;
1065 /* If neighbor itself declares DR and no BDR exists,
1066 cause event BackupSeen */
1067 if (IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->d_router
))
1068 if (hello
->bd_router
.s_addr
== 0 && oi
->state
== ISM_Waiting
)
1069 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_BackupSeen
);
1071 /* neighbor itself declares BDR. */
1072 if (oi
->state
== ISM_Waiting
1073 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->bd_router
))
1074 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_BackupSeen
);
1076 /* had not previously. */
1077 if ((IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->d_router
)
1078 && IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &nbr
->d_router
))
1079 || (IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &hello
->d_router
)
1080 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &nbr
->d_router
)))
1081 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1083 /* had not previously. */
1084 if ((IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &hello
->bd_router
)
1085 && IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &nbr
->bd_router
))
1086 || (IPV4_ADDR_CMP(&nbr
->address
.u
.prefix4
, &hello
->bd_router
)
1087 && IPV4_ADDR_SAME(&nbr
->address
.u
.prefix4
, &nbr
->bd_router
)))
1088 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1090 /* Neighbor priority check. */
1091 if (nbr
->priority
>= 0 && nbr
->priority
!= hello
->priority
)
1092 OSPF_ISM_EVENT_SCHEDULE(oi
, ISM_NeighborChange
);
1094 /* Set neighbor information. */
1095 nbr
->priority
= hello
->priority
;
1096 nbr
->d_router
= hello
->d_router
;
1097 nbr
->bd_router
= hello
->bd_router
;
1100 /* Save DD flags/options/Seqnum received. */
1101 static void ospf_db_desc_save_current(struct ospf_neighbor
*nbr
,
1102 struct ospf_db_desc
*dd
)
1104 nbr
->last_recv
.flags
= dd
->flags
;
1105 nbr
->last_recv
.options
= dd
->options
;
1106 nbr
->last_recv
.dd_seqnum
= ntohl(dd
->dd_seqnum
);
1109 /* Process rest of DD packet. */
1110 static void ospf_db_desc_proc(struct stream
*s
, struct ospf_interface
*oi
,
1111 struct ospf_neighbor
*nbr
,
1112 struct ospf_db_desc
*dd
, u_int16_t size
)
1114 struct ospf_lsa
*new, *find
;
1115 struct lsa_header
*lsah
;
1117 stream_forward_getp(s
, OSPF_DB_DESC_MIN_SIZE
);
1118 for (size
-= OSPF_DB_DESC_MIN_SIZE
; size
>= OSPF_LSA_HEADER_SIZE
;
1119 size
-= OSPF_LSA_HEADER_SIZE
) {
1120 lsah
= (struct lsa_header
*)stream_pnt(s
);
1121 stream_forward_getp(s
, OSPF_LSA_HEADER_SIZE
);
1123 /* Unknown LS type. */
1124 if (lsah
->type
< OSPF_MIN_LSA
|| lsah
->type
>= OSPF_MAX_LSA
) {
1125 zlog_warn("Packet [DD:RECV]: Unknown LS type %d.",
1127 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1131 if (IS_OPAQUE_LSA(lsah
->type
)
1132 && !CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)) {
1133 zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
1134 lsah
->type
, inet_ntoa(lsah
->id
));
1135 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1139 switch (lsah
->type
) {
1140 case OSPF_AS_EXTERNAL_LSA
:
1141 case OSPF_OPAQUE_AS_LSA
:
1142 /* Check for stub area. Reject if AS-External from stub
1144 allow if from NSSA. */
1145 if (oi
->area
->external_routing
== OSPF_AREA_STUB
) {
1147 "Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1148 lsah
->type
, inet_ntoa(lsah
->id
),
1149 (oi
->area
->external_routing
1153 OSPF_NSM_EVENT_SCHEDULE(nbr
,
1154 NSM_SeqNumberMismatch
);
1162 /* Create LS-request object. */
1163 new = ospf_ls_request_new(lsah
);
1165 /* Lookup received LSA, then add LS request list. */
1166 find
= ospf_lsa_lookup_by_header(oi
->area
, lsah
);
1168 /* ospf_lsa_more_recent is fine with NULL pointers */
1169 switch (ospf_lsa_more_recent(find
, new)) {
1171 /* Neighbour has a more recent LSA, we must request it
1173 ospf_ls_request_add(nbr
, new);
1176 /* If we have a copy of this LSA, it's either less
1178 * and we're requesting it from neighbour (the case
1180 * it's as recent and we both have same copy (this
1183 * In neither of these two cases is there any point in
1184 * describing our copy of the LSA to the neighbour in a
1185 * DB-Summary packet, if we're still intending to do so.
1187 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1188 * backward compatible optimisation to OSPF DB Exchange
1190 * DB Description process implemented here.
1193 ospf_lsdb_delete(&nbr
->db_sum
, find
);
1194 ospf_lsa_discard(new);
1197 /* We have the more recent copy, nothing specific to do:
1198 * - no need to request neighbours stale copy
1199 * - must leave DB summary list copy alone
1201 if (IS_DEBUG_OSPF_EVENT
)
1203 "Packet [DD:RECV]: LSA received Type %d, "
1204 "ID %s is not recent.",
1205 lsah
->type
, inet_ntoa(lsah
->id
));
1206 ospf_lsa_discard(new);
1211 if (IS_SET_DD_MS(nbr
->dd_flags
)) {
1214 /* Both sides have no More, then we're done with Exchange */
1215 if (!IS_SET_DD_M(dd
->flags
) && !IS_SET_DD_M(nbr
->dd_flags
))
1216 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_ExchangeDone
);
1218 ospf_db_desc_send(nbr
);
1222 nbr
->dd_seqnum
= ntohl(dd
->dd_seqnum
);
1224 /* Send DD packet in reply.
1226 * Must be done to acknowledge the Master's DD, regardless of
1227 * whether we have more LSAs ourselves to describe.
1229 * This function will clear the 'More' bit, if after this DD
1230 * we have no more LSAs to describe to the master..
1232 ospf_db_desc_send(nbr
);
1234 /* Slave can raise ExchangeDone now, if master is also done */
1235 if (!IS_SET_DD_M(dd
->flags
) && !IS_SET_DD_M(nbr
->dd_flags
))
1236 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_ExchangeDone
);
1239 /* Save received neighbor values from DD. */
1240 ospf_db_desc_save_current(nbr
, dd
);
1243 ospf_ls_req_send(nbr
);
1246 static int ospf_db_desc_is_dup(struct ospf_db_desc
*dd
,
1247 struct ospf_neighbor
*nbr
)
1249 /* Is DD duplicated? */
1250 if (dd
->options
== nbr
->last_recv
.options
1251 && dd
->flags
== nbr
->last_recv
.flags
1252 && dd
->dd_seqnum
== htonl(nbr
->last_recv
.dd_seqnum
))
1258 /* OSPF Database Description message read -- RFC2328 Section 10.6. */
1259 static void ospf_db_desc(struct ip
*iph
, struct ospf_header
*ospfh
,
1260 struct stream
*s
, struct ospf_interface
*oi
,
1263 struct ospf_db_desc
*dd
;
1264 struct ospf_neighbor
*nbr
;
1266 /* Increment statistics. */
1269 dd
= (struct ospf_db_desc
*)stream_pnt(s
);
1271 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1273 zlog_warn("Packet[DD]: Unknown Neighbor %s",
1274 inet_ntoa(ospfh
->router_id
));
1279 if ((OSPF_IF_PARAM(oi
, mtu_ignore
) == 0)
1280 && (ntohs(dd
->mtu
) > oi
->ifp
->mtu
)) {
1282 "Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1283 inet_ntoa(nbr
->router_id
), ntohs(dd
->mtu
), IF_NAME(oi
),
1289 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is
1291 * required. In fact at least JunOS sends DD packets with P bit clear.
1292 * Until proper solution is developped, this hack should help.
1294 * Update: According to the RFCs, N bit is specified /only/ for Hello
1295 * options, unfortunately its use in DD options is not specified. Hence
1297 * implementations follow E-bit semantics and set it in DD options, and
1299 * treat it as unspecified and hence follow the directive "default for
1300 * options is clear", ie unset.
1302 * Reset the flag, as ospfd follows E-bit semantics.
1304 if ((oi
->area
->external_routing
== OSPF_AREA_NSSA
)
1305 && (CHECK_FLAG(nbr
->options
, OSPF_OPTION_NP
))
1306 && (!CHECK_FLAG(dd
->options
, OSPF_OPTION_NP
))) {
1307 if (IS_DEBUG_OSPF_EVENT
)
1309 "Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
1310 inet_ntoa(nbr
->router_id
));
1311 SET_FLAG(dd
->options
, OSPF_OPTION_NP
);
1314 #ifdef REJECT_IF_TBIT_ON
1315 if (CHECK_FLAG(dd
->options
, OSPF_OPTION_MT
)) {
1317 * In Hello protocol, optional capability must have checked
1318 * to prevent this T-bit enabled router be my neighbor.
1320 zlog_warn("Packet[DD]: Neighbor %s: T-bit on?",
1321 inet_ntoa(nbr
->router_id
));
1324 #endif /* REJECT_IF_TBIT_ON */
1326 if (CHECK_FLAG(dd
->options
, OSPF_OPTION_O
)
1327 && !CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)) {
1329 * This node is not configured to handle O-bit, for now.
1330 * Clear it to ignore unsupported capability proposed by
1333 UNSET_FLAG(dd
->options
, OSPF_OPTION_O
);
1336 /* Add event to thread. */
1337 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1339 /* Process DD packet by neighbor status. */
1340 switch (nbr
->state
) {
1345 "Packet[DD]: Neighbor %s state is %s, packet discarded.",
1346 inet_ntoa(nbr
->router_id
),
1347 lookup_msg(ospf_nsm_state_msg
, nbr
->state
, NULL
));
1350 OSPF_NSM_EVENT_EXECUTE(nbr
, NSM_TwoWayReceived
);
1351 /* If the new state is ExStart, the processing of the current
1352 packet should then continue in this new state by falling
1353 through to case ExStart below. */
1354 if (nbr
->state
!= NSM_ExStart
)
1359 if ((IS_SET_DD_ALL(dd
->flags
) == OSPF_DD_FLAG_ALL
)
1360 && (size
== OSPF_DB_DESC_MIN_SIZE
)) {
1361 if (IPV4_ADDR_CMP(&nbr
->router_id
, &oi
->ospf
->router_id
)
1363 /* We're Slave---obey */
1364 if (CHECK_FLAG(oi
->ospf
->config
,
1365 OSPF_LOG_ADJACENCY_DETAIL
))
1367 "Packet[DD]: Neighbor %s Negotiation done (Slave).",
1368 inet_ntoa(nbr
->router_id
));
1370 nbr
->dd_seqnum
= ntohl(dd
->dd_seqnum
);
1373 UNSET_FLAG(nbr
->dd_flags
,
1374 (OSPF_DD_FLAG_MS
| OSPF_DD_FLAG_I
));
1376 /* We're Master, ignore the initial DBD from
1378 if (CHECK_FLAG(oi
->ospf
->config
,
1379 OSPF_LOG_ADJACENCY_DETAIL
))
1381 "Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1383 inet_ntoa(nbr
->router_id
));
1387 /* Ack from the Slave */
1388 else if (!IS_SET_DD_MS(dd
->flags
) && !IS_SET_DD_I(dd
->flags
)
1389 && ntohl(dd
->dd_seqnum
) == nbr
->dd_seqnum
1390 && IPV4_ADDR_CMP(&nbr
->router_id
, &oi
->ospf
->router_id
)
1393 "Packet[DD]: Neighbor %s Negotiation done (Master).",
1394 inet_ntoa(nbr
->router_id
));
1395 /* Reset I, leaving MS */
1396 UNSET_FLAG(nbr
->dd_flags
, OSPF_DD_FLAG_I
);
1398 zlog_warn("Packet[DD]: Neighbor %s Negotiation fails.",
1399 inet_ntoa(nbr
->router_id
));
1403 /* This is where the real Options are saved */
1404 nbr
->options
= dd
->options
;
1406 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
)) {
1407 if (IS_DEBUG_OSPF_EVENT
)
1409 "Neighbor[%s] is %sOpaque-capable.",
1410 inet_ntoa(nbr
->router_id
),
1411 CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)
1415 if (!CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)
1416 && IPV4_ADDR_SAME(&DR(oi
),
1417 &nbr
->address
.u
.prefix4
)) {
1419 "DR-neighbor[%s] is NOT opaque-capable; "
1420 "Opaque-LSAs cannot be reliably advertised "
1422 inet_ntoa(nbr
->router_id
));
1423 /* This situation is undesirable, but not a real
1428 OSPF_NSM_EVENT_EXECUTE(nbr
, NSM_NegotiationDone
);
1430 /* continue processing rest of packet. */
1431 ospf_db_desc_proc(s
, oi
, nbr
, dd
, size
);
1434 if (ospf_db_desc_is_dup(dd
, nbr
)) {
1435 if (IS_SET_DD_MS(nbr
->dd_flags
))
1436 /* Master: discard duplicated DD packet. */
1438 "Packet[DD] (Master): Neighbor %s packet duplicated.",
1439 inet_ntoa(nbr
->router_id
));
1441 /* Slave: cause to retransmit the last Database
1445 "Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1446 inet_ntoa(nbr
->router_id
));
1447 ospf_db_desc_resend(nbr
);
1452 /* Otherwise DD packet should be checked. */
1453 /* Check Master/Slave bit mismatch */
1454 if (IS_SET_DD_MS(dd
->flags
)
1455 != IS_SET_DD_MS(nbr
->last_recv
.flags
)) {
1456 zlog_warn("Packet[DD]: Neighbor %s MS-bit mismatch.",
1457 inet_ntoa(nbr
->router_id
));
1458 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1459 if (IS_DEBUG_OSPF_EVENT
)
1461 "Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1462 dd
->flags
, nbr
->dd_flags
);
1466 /* Check initialize bit is set. */
1467 if (IS_SET_DD_I(dd
->flags
)) {
1468 zlog_info("Packet[DD]: Neighbor %s I-bit set.",
1469 inet_ntoa(nbr
->router_id
));
1470 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1474 /* Check DD Options. */
1475 if (dd
->options
!= nbr
->options
) {
1476 #ifdef ORIGINAL_CODING
1477 /* Save the new options for debugging */
1478 nbr
->options
= dd
->options
;
1479 #endif /* ORIGINAL_CODING */
1480 zlog_warn("Packet[DD]: Neighbor %s options mismatch.",
1481 inet_ntoa(nbr
->router_id
));
1482 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1486 /* Check DD sequence number. */
1487 if ((IS_SET_DD_MS(nbr
->dd_flags
)
1488 && ntohl(dd
->dd_seqnum
) != nbr
->dd_seqnum
)
1489 || (!IS_SET_DD_MS(nbr
->dd_flags
)
1490 && ntohl(dd
->dd_seqnum
) != nbr
->dd_seqnum
+ 1)) {
1492 "Packet[DD]: Neighbor %s sequence number mismatch.",
1493 inet_ntoa(nbr
->router_id
));
1494 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1498 /* Continue processing rest of packet. */
1499 ospf_db_desc_proc(s
, oi
, nbr
, dd
, size
);
1503 if (ospf_db_desc_is_dup(dd
, nbr
)) {
1504 if (IS_SET_DD_MS(nbr
->dd_flags
)) {
1505 /* Master should discard duplicate DD packet. */
1507 "Packet[DD]: Neighbor %s duplicated, "
1508 "packet discarded.",
1509 inet_ntoa(nbr
->router_id
));
1512 if (monotime_since(&nbr
->last_send_ts
, NULL
)
1513 < nbr
->v_inactivity
* 1000000LL) {
1514 /* In states Loading and Full the slave
1516 its last Database Description packet
1518 duplicate Database Description
1520 from the master. For this reason the
1522 wait RouterDeadInterval seconds
1524 last Database Description packet.
1526 Database Description packet from the
1528 this interval will generate a
1530 neighbor event. RFC2328 Section 10.8
1532 ospf_db_desc_resend(nbr
);
1538 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_SeqNumberMismatch
);
1541 zlog_warn("Packet[DD]: Neighbor %s NSM illegal status %u.",
1542 inet_ntoa(nbr
->router_id
), nbr
->state
);
1547 #define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1549 /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1550 static void ospf_ls_req(struct ip
*iph
, struct ospf_header
*ospfh
,
1551 struct stream
*s
, struct ospf_interface
*oi
,
1554 struct ospf_neighbor
*nbr
;
1556 struct in_addr ls_id
;
1557 struct in_addr adv_router
;
1558 struct ospf_lsa
*find
;
1559 struct list
*ls_upd
;
1560 unsigned int length
;
1562 /* Increment statistics. */
1565 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1567 zlog_warn("Link State Request: Unknown Neighbor %s.",
1568 inet_ntoa(ospfh
->router_id
));
1572 /* Add event to thread. */
1573 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1575 /* Neighbor State should be Exchange or later. */
1576 if (nbr
->state
!= NSM_Exchange
&& nbr
->state
!= NSM_Loading
1577 && nbr
->state
!= NSM_Full
) {
1579 "Link State Request received from %s: "
1580 "Neighbor state is %s, packet discarded.",
1581 inet_ntoa(ospfh
->router_id
),
1582 lookup_msg(ospf_nsm_state_msg
, nbr
->state
, NULL
));
1586 /* Send Link State Update for ALL requested LSAs. */
1587 ls_upd
= list_new();
1588 length
= OSPF_HEADER_SIZE
+ OSPF_LS_UPD_MIN_SIZE
;
1590 while (size
>= OSPF_LSA_KEY_SIZE
) {
1591 /* Get one slice of Link State Request. */
1592 ls_type
= stream_getl(s
);
1593 ls_id
.s_addr
= stream_get_ipv4(s
);
1594 adv_router
.s_addr
= stream_get_ipv4(s
);
1596 /* Verify LSA type. */
1597 if (ls_type
< OSPF_MIN_LSA
|| ls_type
>= OSPF_MAX_LSA
) {
1598 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
1599 list_delete_and_null(&ls_upd
);
1603 /* Search proper LSA in LSDB. */
1604 find
= ospf_lsa_lookup(oi
->ospf
, oi
->area
, ls_type
, ls_id
,
1607 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
1608 list_delete_and_null(&ls_upd
);
1612 /* Packet overflows MTU size, send immediately. */
1613 if (length
+ ntohs(find
->data
->length
) > ospf_packet_max(oi
)) {
1614 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1615 ospf_ls_upd_send(nbr
, ls_upd
,
1616 OSPF_SEND_PACKET_DIRECT
, 0);
1618 ospf_ls_upd_send(nbr
, ls_upd
,
1619 OSPF_SEND_PACKET_INDIRECT
, 0);
1621 /* Only remove list contents. Keep ls_upd. */
1622 list_delete_all_node(ls_upd
);
1624 length
= OSPF_HEADER_SIZE
+ OSPF_LS_UPD_MIN_SIZE
;
1627 /* Append LSA to update list. */
1628 listnode_add(ls_upd
, find
);
1629 length
+= ntohs(find
->data
->length
);
1631 size
-= OSPF_LSA_KEY_SIZE
;
1634 /* Send rest of Link State Update. */
1635 if (listcount(ls_upd
) > 0) {
1636 if (oi
->type
== OSPF_IFTYPE_NBMA
)
1637 ospf_ls_upd_send(nbr
, ls_upd
, OSPF_SEND_PACKET_DIRECT
,
1640 ospf_ls_upd_send(nbr
, ls_upd
, OSPF_SEND_PACKET_INDIRECT
,
1643 list_delete_and_null(&ls_upd
);
1645 list_delete_and_null(&ls_upd
);
1648 /* Get the list of LSAs from Link State Update packet.
1649 And process some validation -- RFC2328 Section 13. (1)-(2). */
1650 static struct list
*ospf_ls_upd_list_lsa(struct ospf_neighbor
*nbr
,
1652 struct ospf_interface
*oi
, size_t size
)
1654 u_int16_t count
, sum
;
1656 struct lsa_header
*lsah
;
1657 struct ospf_lsa
*lsa
;
1662 count
= stream_getl(s
);
1663 size
-= OSPF_LS_UPD_MIN_SIZE
; /* # LSAs */
1665 for (; size
>= OSPF_LSA_HEADER_SIZE
&& count
> 0;
1666 size
-= length
, stream_forward_getp(s
, length
), count
--) {
1667 lsah
= (struct lsa_header
*)stream_pnt(s
);
1668 length
= ntohs(lsah
->length
);
1670 if (length
> size
) {
1672 "Link State Update: LSA length exceeds packet size.");
1676 /* Validate the LSA's LS checksum. */
1677 sum
= lsah
->checksum
;
1678 if (!ospf_lsa_checksum_valid(lsah
)) {
1679 /* (bug #685) more details in a one-line message make it
1681 * to identify problem source on the one hand and to
1683 * chance to compress repeated messages in syslog on the
1686 "Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1687 sum
, lsah
->checksum
, inet_ntoa(lsah
->id
),
1688 inet_ntoa(nbr
->src
), inet_ntoa(nbr
->router_id
),
1689 inet_ntoa(lsah
->adv_router
));
1693 /* Examine the LSA's LS type. */
1694 if (lsah
->type
< OSPF_MIN_LSA
|| lsah
->type
>= OSPF_MAX_LSA
) {
1695 zlog_warn("Link State Update: Unknown LS type %d",
1701 * What if the received LSA's age is greater than MaxAge?
1702 * Treat it as a MaxAge case -- endo.
1704 if (ntohs(lsah
->ls_age
) > OSPF_LSA_MAXAGE
)
1705 lsah
->ls_age
= htons(OSPF_LSA_MAXAGE
);
1707 if (CHECK_FLAG(nbr
->options
, OSPF_OPTION_O
)) {
1708 #ifdef STRICT_OBIT_USAGE_CHECK
1709 if ((IS_OPAQUE_LSA(lsah
->type
)
1710 && !CHECK_FLAG(lsah
->options
, OSPF_OPTION_O
))
1711 || (!IS_OPAQUE_LSA(lsah
->type
)
1712 && CHECK_FLAG(lsah
->options
, OSPF_OPTION_O
))) {
1714 * This neighbor must know the exact usage of
1716 * the bit will be set in Type-9,10,11 LSAs
1719 zlog_warn("LSA[Type%d:%s]: O-bit abuse?",
1720 lsah
->type
, inet_ntoa(lsah
->id
));
1723 #endif /* STRICT_OBIT_USAGE_CHECK */
1725 /* Do not take in AS External Opaque-LSAs if we are a
1727 if (lsah
->type
== OSPF_OPAQUE_AS_LSA
1728 && nbr
->oi
->area
->external_routing
1729 != OSPF_AREA_DEFAULT
) {
1730 if (IS_DEBUG_OSPF_EVENT
)
1732 "LSA[Type%d:%s]: We are a stub, don't take this LSA.",
1734 inet_ntoa(lsah
->id
));
1737 } else if (IS_OPAQUE_LSA(lsah
->type
)) {
1738 zlog_warn("LSA[Type%d:%s]: Opaque capability mismatch?",
1739 lsah
->type
, inet_ntoa(lsah
->id
));
1743 /* Create OSPF LSA instance. */
1744 lsa
= ospf_lsa_new();
1746 lsa
->vrf_id
= oi
->ospf
->vrf_id
;
1747 /* We may wish to put some error checking if type NSSA comes in
1748 and area not in NSSA mode */
1749 switch (lsah
->type
) {
1750 case OSPF_AS_EXTERNAL_LSA
:
1751 case OSPF_OPAQUE_AS_LSA
:
1754 case OSPF_OPAQUE_LINK_LSA
:
1755 lsa
->oi
= oi
; /* Remember incoming interface for
1756 flooding control. */
1759 lsa
->area
= oi
->area
;
1763 lsa
->data
= ospf_lsa_data_new(length
);
1764 memcpy(lsa
->data
, lsah
, length
);
1766 if (IS_DEBUG_OSPF_EVENT
)
1768 "LSA[Type%d:%s]: %p new LSA created with Link State Update",
1769 lsa
->data
->type
, inet_ntoa(lsa
->data
->id
),
1771 listnode_add(lsas
, lsa
);
1777 /* Cleanup Update list. */
1778 static void ospf_upd_list_clean(struct list
*lsas
)
1780 struct listnode
*node
, *nnode
;
1781 struct ospf_lsa
*lsa
;
1783 for (ALL_LIST_ELEMENTS(lsas
, node
, nnode
, lsa
))
1784 ospf_lsa_discard(lsa
);
1786 list_delete_and_null(&lsas
);
1789 /* OSPF Link State Update message read -- RFC2328 Section 13. */
1790 static void ospf_ls_upd(struct ospf
*ospf
, struct ip
*iph
,
1791 struct ospf_header
*ospfh
, struct stream
*s
,
1792 struct ospf_interface
*oi
, u_int16_t size
)
1794 struct ospf_neighbor
*nbr
;
1796 struct listnode
*node
, *nnode
;
1797 struct ospf_lsa
*lsa
= NULL
;
1798 /* unsigned long ls_req_found = 0; */
1800 /* Dis-assemble the stream, update each entry, re-encapsulate for
1803 /* Increment statistics. */
1806 /* Check neighbor. */
1807 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
1809 zlog_warn("Link State Update: Unknown Neighbor %s on int: %s",
1810 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
));
1814 /* Add event to thread. */
1815 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
1817 /* Check neighbor state. */
1818 if (nbr
->state
< NSM_Exchange
) {
1819 if (IS_DEBUG_OSPF(nsm
, NSM_EVENTS
))
1821 "Link State Update: "
1822 "Neighbor[%s] state %s is less than Exchange",
1823 inet_ntoa(ospfh
->router_id
),
1824 lookup_msg(ospf_nsm_state_msg
, nbr
->state
,
1829 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1830 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1833 lsas
= ospf_ls_upd_list_lsa(nbr
, s
, oi
, size
);
1837 #define DISCARD_LSA(L, N) \
1839 if (IS_DEBUG_OSPF_EVENT) \
1841 "ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p" \
1843 N, (void *)lsa, (int)lsa->data->type); \
1844 ospf_lsa_discard(L); \
1848 /* Process each LSA received in the one packet.
1850 * Numbers in parentheses, e.g. (1), (2), etc., and the corresponding
1851 * text below are from the steps in RFC 2328, Section 13.
1853 for (ALL_LIST_ELEMENTS(lsas
, node
, nnode
, lsa
)) {
1854 struct ospf_lsa
*ls_ret
, *current
;
1857 if (IS_DEBUG_OSPF_NSSA
) {
1858 char buf1
[INET_ADDRSTRLEN
];
1859 char buf2
[INET_ADDRSTRLEN
];
1860 char buf3
[INET_ADDRSTRLEN
];
1862 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
1864 inet_ntop(AF_INET
, &ospfh
->router_id
, buf1
,
1866 inet_ntop(AF_INET
, &lsa
->data
->id
, buf2
,
1868 inet_ntop(AF_INET
, &lsa
->data
->adv_router
,
1869 buf3
, INET_ADDRSTRLEN
));
1872 listnode_delete(lsas
,
1873 lsa
); /* We don't need it in list anymore */
1875 /* (1) Validate Checksum - Done above by ospf_ls_upd_list_lsa()
1878 /* (2) LSA Type - Done above by ospf_ls_upd_list_lsa() */
1880 /* (3) Do not take in AS External LSAs if we are a stub or NSSA.
1883 /* Do not take in AS NSSA if this neighbor and we are not NSSA
1886 /* Do take in Type-7's if we are an NSSA */
1888 /* If we are also an ABR, later translate them to a Type-5
1891 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1892 translate them to a separate Type-5 packet. */
1894 if (lsa
->data
->type
== OSPF_AS_EXTERNAL_LSA
)
1895 /* Reject from STUB or NSSA */
1896 if (nbr
->oi
->area
->external_routing
1897 != OSPF_AREA_DEFAULT
) {
1898 if (IS_DEBUG_OSPF_NSSA
)
1900 "Incoming External LSA Discarded: We are NSSA/STUB Area");
1901 DISCARD_LSA(lsa
, 1);
1904 if (lsa
->data
->type
== OSPF_AS_NSSA_LSA
)
1905 if (nbr
->oi
->area
->external_routing
!= OSPF_AREA_NSSA
) {
1906 if (IS_DEBUG_OSPF_NSSA
)
1908 "Incoming NSSA LSA Discarded: Not NSSA Area");
1909 DISCARD_LSA(lsa
, 2);
1912 /* VU229804: Router-LSA Adv-ID must be equal to LS-ID */
1913 if (lsa
->data
->type
== OSPF_ROUTER_LSA
)
1914 if (!IPV4_ADDR_SAME(&lsa
->data
->id
,
1915 &lsa
->data
->adv_router
)) {
1916 char buf1
[INET_ADDRSTRLEN
];
1917 char buf2
[INET_ADDRSTRLEN
];
1918 char buf3
[INET_ADDRSTRLEN
];
1921 "Incoming Router-LSA from %s with "
1922 "Adv-ID[%s] != LS-ID[%s]",
1923 inet_ntop(AF_INET
, &ospfh
->router_id
,
1924 buf1
, INET_ADDRSTRLEN
),
1925 inet_ntop(AF_INET
, &lsa
->data
->id
, buf2
,
1928 &lsa
->data
->adv_router
, buf3
,
1931 "OSPF domain compromised by attack or corruption. "
1932 "Verify correct operation of -ALL- OSPF routers.");
1933 DISCARD_LSA(lsa
, 0);
1936 /* Find the LSA in the current database. */
1938 current
= ospf_lsa_lookup_by_header(oi
->area
, lsa
->data
);
1940 /* (4) If the LSA's LS age is equal to MaxAge, and there is
1942 no instance of the LSA in the router's link state database,
1943 and none of router's neighbors are in states Exchange or
1945 then take the following actions: */
1947 if (IS_LSA_MAXAGE(lsa
) && !current
1948 && ospf_check_nbr_status(oi
->ospf
)) {
1949 /* (4a) Response Link State Acknowledgment. */
1950 ospf_ls_ack_send(nbr
, lsa
);
1952 /* (4b) Discard LSA. */
1953 if (IS_DEBUG_OSPF(lsa
, LSA
)) {
1955 "Link State Update[%s]: LS age is equal to MaxAge.",
1958 DISCARD_LSA(lsa
, 3);
1961 if (IS_OPAQUE_LSA(lsa
->data
->type
)
1962 && IPV4_ADDR_SAME(&lsa
->data
->adv_router
,
1963 &oi
->ospf
->router_id
)) {
1965 * Even if initial flushing seems to be completed, there
1967 * be a case that self-originated LSA with MaxAge still
1969 * in the routing domain.
1970 * Just send an LSAck message to cease retransmission.
1972 if (IS_LSA_MAXAGE(lsa
)) {
1973 zlog_warn("LSA[%s]: Boomerang effect?",
1975 ospf_ls_ack_send(nbr
, lsa
);
1976 ospf_lsa_discard(lsa
);
1978 if (current
!= NULL
&& !IS_LSA_MAXAGE(current
))
1979 ospf_opaque_lsa_refresh_schedule(
1985 * If an instance of self-originated Opaque-LSA is not
1987 * in the LSDB, there are some possible cases here.
1989 * 1) This node lost opaque-capability after restart.
1990 * 2) Else, a part of opaque-type is no more supported.
1991 * 3) Else, a part of opaque-id is no more supported.
1993 * Anyway, it is still this node's responsibility to
1995 * Otherwise, the LSA instance remains in the routing
1997 * until its age reaches to MaxAge.
1999 /* XXX: We should deal with this for *ALL* LSAs, not
2001 if (current
== NULL
) {
2002 if (IS_DEBUG_OSPF_EVENT
)
2004 "LSA[%s]: Previously originated Opaque-LSA,"
2005 "not found in the LSDB.",
2008 SET_FLAG(lsa
->flags
, OSPF_LSA_SELF
);
2010 ospf_opaque_self_originated_lsa_received(nbr
,
2012 ospf_ls_ack_send(nbr
, lsa
);
2018 /* It might be happen that received LSA is self-originated
2020 * router ID is changed. So, we should check if LSA is a
2022 * Link State ID is one of the router's own IP interface
2023 * addresses but whose
2024 * Advertising Router is not equal to the router's own Router ID
2025 * According to RFC 2328 12.4.2 and 13.4 this LSA should be
2029 if (lsa
->data
->type
== OSPF_NETWORK_LSA
) {
2030 struct listnode
*oinode
, *oinnode
;
2031 struct ospf_interface
*out_if
;
2034 for (ALL_LIST_ELEMENTS(oi
->ospf
->oiflist
, oinode
,
2039 if ((IPV4_ADDR_SAME(&out_if
->address
->u
.prefix4
,
2041 && (!(IPV4_ADDR_SAME(
2042 &oi
->ospf
->router_id
,
2043 &lsa
->data
->adv_router
)))) {
2044 if (out_if
->network_lsa_self
) {
2045 ospf_lsa_flush_area(
2047 if (IS_DEBUG_OSPF_EVENT
)
2049 "ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
2053 ospf_lsa_discard(lsa
);
2063 /* (5) Find the instance of this LSA that is currently contained
2064 in the router's link state database. If there is no
2065 database copy, or the received LSA is more recent than
2066 the database copy the following steps must be performed.
2067 (The sub steps from RFC 2328 section 13 step (5) will be
2072 || (ret
= ospf_lsa_more_recent(current
, lsa
)) < 0) {
2073 /* Actual flooding procedure. */
2074 if (ospf_flood(oi
->ospf
, nbr
, current
, lsa
)
2075 < 0) /* Trap NSSA later. */
2076 DISCARD_LSA(lsa
, 4);
2080 /* (6) Else, If there is an instance of the LSA on the sending
2081 neighbor's Link state request list, an error has occurred in
2082 the Database Exchange process. In this case, restart the
2083 Database Exchange process by generating the neighbor event
2084 BadLSReq for the sending neighbor and stop processing the
2085 Link State Update packet. */
2087 if (ospf_ls_request_lookup(nbr
, lsa
)) {
2088 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_BadLSReq
);
2090 "LSA[%s] instance exists on Link state request list",
2093 /* Clean list of LSAs. */
2094 ospf_upd_list_clean(lsas
);
2095 /* this lsa is not on lsas list already. */
2096 ospf_lsa_discard(lsa
);
2100 /* If the received LSA is the same instance as the database copy
2101 (i.e., neither one is more recent) the following two steps
2102 should be performed: */
2105 /* If the LSA is listed in the Link state retransmission
2107 for the receiving adjacency, the router itself is
2109 an acknowledgment for this LSA. The router should
2111 received LSA as an acknowledgment by removing the LSA
2113 the Link state retransmission list. This is termed
2115 "implied acknowledgment". */
2117 ls_ret
= ospf_ls_retransmit_lookup(nbr
, lsa
);
2119 if (ls_ret
!= NULL
) {
2120 ospf_ls_retransmit_delete(nbr
, ls_ret
);
2122 /* Delayed acknowledgment sent if advertisement
2124 from Designated Router, otherwise do nothing.
2126 if (oi
->state
== ISM_Backup
)
2130 ospf_lsa_lock(lsa
));
2132 DISCARD_LSA(lsa
, 5);
2134 /* Acknowledge the receipt of the LSA by sending a
2135 Link State Acknowledgment packet back out the
2139 ospf_ls_ack_send(nbr
, lsa
);
2140 DISCARD_LSA(lsa
, 6);
2144 /* The database copy is more recent. If the database copy
2145 has LS age equal to MaxAge and LS sequence number equal to
2146 MaxSequenceNumber, simply discard the received LSA without
2147 acknowledging it. (In this case, the LSA's LS sequence number
2149 wrapping, and the MaxSequenceNumber LSA must be completely
2150 flushed before any new LSA instance can be introduced). */
2152 else if (ret
> 0) /* Database copy is more recent */
2154 if (IS_LSA_MAXAGE(current
)
2155 && current
->data
->ls_seqnum
2156 == htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
2157 DISCARD_LSA(lsa
, 7);
2159 /* Otherwise, as long as the database copy has not been
2161 Link State Update within the last MinLSArrival
2163 database copy back to the sending neighbor,
2165 a Link State Update Packet. The Link State Update
2167 be sent directly to the neighbor. In so doing, do not
2169 database copy of the LSA on the neighbor's link state
2170 retransmission list, and do not acknowledge the
2172 recent) LSA instance. */
2174 if (monotime_since(¤t
->tv_orig
, NULL
)
2175 >= ospf
->min_ls_arrival
* 1000LL)
2176 /* Trap NSSA type later.*/
2177 ospf_ls_upd_send_lsa(
2179 OSPF_SEND_PACKET_DIRECT
);
2180 DISCARD_LSA(lsa
, 8);
2186 assert(listcount(lsas
) == 0);
2187 list_delete_and_null(&lsas
);
2190 /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
2191 static void ospf_ls_ack(struct ip
*iph
, struct ospf_header
*ospfh
,
2192 struct stream
*s
, struct ospf_interface
*oi
,
2195 struct ospf_neighbor
*nbr
;
2197 /* increment statistics. */
2200 nbr
= ospf_nbr_lookup(oi
, iph
, ospfh
);
2202 zlog_warn("Link State Acknowledgment: Unknown Neighbor %s.",
2203 inet_ntoa(ospfh
->router_id
));
2207 /* Add event to thread. */
2208 OSPF_NSM_EVENT_SCHEDULE(nbr
, NSM_PacketReceived
);
2210 if (nbr
->state
< NSM_Exchange
) {
2211 if (IS_DEBUG_OSPF(nsm
, NSM_EVENTS
))
2213 "Link State Acknowledgment: "
2214 "Neighbor[%s] state %s is less than Exchange",
2215 inet_ntoa(ospfh
->router_id
),
2216 lookup_msg(ospf_nsm_state_msg
, nbr
->state
,
2221 while (size
>= OSPF_LSA_HEADER_SIZE
) {
2222 struct ospf_lsa
*lsa
, *lsr
;
2224 lsa
= ospf_lsa_new();
2225 lsa
->data
= (struct lsa_header
*)stream_pnt(s
);
2226 lsa
->vrf_id
= oi
->ospf
->vrf_id
;
2228 /* lsah = (struct lsa_header *) stream_pnt (s); */
2229 size
-= OSPF_LSA_HEADER_SIZE
;
2230 stream_forward_getp(s
, OSPF_LSA_HEADER_SIZE
);
2232 if (lsa
->data
->type
< OSPF_MIN_LSA
2233 || lsa
->data
->type
>= OSPF_MAX_LSA
) {
2235 ospf_lsa_discard(lsa
);
2239 lsr
= ospf_ls_retransmit_lookup(nbr
, lsa
);
2241 if (lsr
!= NULL
&& ospf_lsa_more_recent(lsr
, lsa
) == 0)
2242 ospf_ls_retransmit_delete(nbr
, lsr
);
2245 ospf_lsa_discard(lsa
);
2251 static struct stream
*ospf_recv_packet(struct ospf
*ospf
, int fd
,
2252 struct interface
**ifp
,
2253 struct stream
*ibuf
)
2258 ifindex_t ifindex
= 0;
2260 /* Header and data both require alignment. */
2261 char buff
[CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2264 memset(&msgh
, 0, sizeof(struct msghdr
));
2265 msgh
.msg_iov
= &iov
;
2266 msgh
.msg_iovlen
= 1;
2267 msgh
.msg_control
= (caddr_t
)buff
;
2268 msgh
.msg_controllen
= sizeof(buff
);
2270 ret
= stream_recvmsg(ibuf
, fd
, &msgh
, 0, OSPF_MAX_PACKET_SIZE
+ 1);
2272 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno
));
2275 if ((unsigned int)ret
< sizeof(iph
)) /* ret must be > 0 now */
2278 "ospf_recv_packet: discarding runt packet of length %d "
2279 "(ip header size is %u)",
2280 ret
, (u_int
)sizeof(iph
));
2284 /* Note that there should not be alignment problems with this assignment
2285 because this is at the beginning of the stream data buffer. */
2286 iph
= (struct ip
*)STREAM_DATA(ibuf
);
2287 sockopt_iphdrincl_swab_systoh(iph
);
2289 ip_len
= iph
->ip_len
;
2291 #if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000)
2293 * Kernel network code touches incoming IP header parameters,
2294 * before protocol specific processing.
2296 * 1) Convert byteorder to host representation.
2297 * --> ip_len, ip_id, ip_off
2299 * 2) Adjust ip_len to strip IP header size!
2300 * --> If user process receives entire IP packet via RAW
2301 * socket, it must consider adding IP header size to
2302 * the "ip_len" field of "ip" structure.
2304 * For more details, see <netinet/ip_input.c>.
2306 ip_len
= ip_len
+ (iph
->ip_hl
<< 2);
2309 #if defined(__DragonFly__)
2311 * in DragonFly's raw socket, ip_len/ip_off are read
2312 * in network byte order.
2313 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2315 ip_len
= ntohs(iph
->ip_len
) + (iph
->ip_hl
<< 2);
2318 ifindex
= getsockopt_ifindex(AF_INET
, &msgh
);
2320 *ifp
= if_lookup_by_index(ifindex
, ospf
->vrf_id
);
2322 if (ret
!= ip_len
) {
2324 "ospf_recv_packet read length mismatch: ip_len is %d, "
2325 "but recvmsg returned %d",
2333 static struct ospf_interface
*
2334 ospf_associate_packet_vl(struct ospf
*ospf
, struct interface
*ifp
,
2335 struct ip
*iph
, struct ospf_header
*ospfh
)
2337 struct ospf_interface
*rcv_oi
;
2338 struct ospf_vl_data
*vl_data
;
2339 struct ospf_area
*vl_area
;
2340 struct listnode
*node
;
2342 if (IN_MULTICAST(ntohl(iph
->ip_dst
.s_addr
))
2343 || !OSPF_IS_AREA_BACKBONE(ospfh
))
2346 /* look for local OSPF interface matching the destination
2347 * to determine Area ID. We presume therefore the destination address
2348 * is unique, or at least (for "unnumbered" links), not used in other
2351 if ((rcv_oi
= ospf_if_lookup_by_local_addr(ospf
, NULL
, iph
->ip_dst
))
2355 for (ALL_LIST_ELEMENTS_RO(ospf
->vlinks
, node
, vl_data
)) {
2357 ospf_area_lookup_by_area_id(ospf
, vl_data
->vl_area_id
);
2361 if (OSPF_AREA_SAME(&vl_area
, &rcv_oi
->area
)
2362 && IPV4_ADDR_SAME(&vl_data
->vl_peer
, &ospfh
->router_id
)) {
2363 if (IS_DEBUG_OSPF_EVENT
)
2364 zlog_debug("associating packet with %s",
2365 IF_NAME(vl_data
->vl_oi
));
2366 if (!CHECK_FLAG(vl_data
->vl_oi
->ifp
->flags
, IFF_UP
)) {
2367 if (IS_DEBUG_OSPF_EVENT
)
2369 "This VL is not up yet, sorry");
2373 return vl_data
->vl_oi
;
2377 if (IS_DEBUG_OSPF_EVENT
)
2378 zlog_debug("couldn't find any VL to associate the packet with");
2383 static int ospf_check_area_id(struct ospf_interface
*oi
,
2384 struct ospf_header
*ospfh
)
2386 /* Check match the Area ID of the receiving interface. */
2387 if (OSPF_AREA_SAME(&oi
->area
, &ospfh
))
2393 /* Unbound socket will accept any Raw IP packets if proto is matched.
2394 To prevent it, compare src IP address and i/f address with masking
2395 i/f network mask. */
2396 static int ospf_check_network_mask(struct ospf_interface
*oi
,
2397 struct in_addr ip_src
)
2399 struct in_addr mask
, me
, him
;
2401 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
2402 || oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
2405 masklen2ip(oi
->address
->prefixlen
, &mask
);
2407 me
.s_addr
= oi
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
2408 him
.s_addr
= ip_src
.s_addr
& mask
.s_addr
;
2410 if (IPV4_ADDR_SAME(&me
, &him
))
2416 /* Return 1, if the packet is properly authenticated and checksummed,
2417 0 otherwise. In particular, check that AuType header field is valid and
2418 matches the locally configured AuType, and that D.5 requirements are met. */
2419 static int ospf_check_auth(struct ospf_interface
*oi
, struct ospf_header
*ospfh
)
2421 struct crypt_key
*ck
;
2422 u_int16_t iface_auth_type
;
2423 u_int16_t pkt_auth_type
= ntohs(ospfh
->auth_type
);
2425 switch (pkt_auth_type
) {
2426 case OSPF_AUTH_NULL
: /* RFC2328 D.5.1 */
2427 if (OSPF_AUTH_NULL
!= (iface_auth_type
= ospf_auth_type(oi
))) {
2428 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2430 "interface %s: auth-type mismatch, local %s, rcvd Null",
2432 lookup_msg(ospf_auth_type_str
,
2433 iface_auth_type
, NULL
));
2436 if (!ospf_check_sum(ospfh
)) {
2437 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2439 "interface %s: Null auth OK, but checksum error, Router-ID %s",
2441 inet_ntoa(ospfh
->router_id
));
2445 case OSPF_AUTH_SIMPLE
: /* RFC2328 D.5.2 */
2446 if (OSPF_AUTH_SIMPLE
2447 != (iface_auth_type
= ospf_auth_type(oi
))) {
2448 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2450 "interface %s: auth-type mismatch, local %s, rcvd Simple",
2452 lookup_msg(ospf_auth_type_str
,
2453 iface_auth_type
, NULL
));
2456 if (memcmp(OSPF_IF_PARAM(oi
, auth_simple
), ospfh
->u
.auth_data
,
2457 OSPF_AUTH_SIMPLE_SIZE
)) {
2458 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2459 zlog_warn("interface %s: Simple auth failed",
2463 if (!ospf_check_sum(ospfh
)) {
2464 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2466 "interface %s: Simple auth OK, checksum error, Router-ID %s",
2468 inet_ntoa(ospfh
->router_id
));
2472 case OSPF_AUTH_CRYPTOGRAPHIC
: /* RFC2328 D.5.3 */
2473 if (OSPF_AUTH_CRYPTOGRAPHIC
2474 != (iface_auth_type
= ospf_auth_type(oi
))) {
2475 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2477 "interface %s: auth-type mismatch, local %s, rcvd Cryptographic",
2479 lookup_msg(ospf_auth_type_str
,
2480 iface_auth_type
, NULL
));
2483 if (ospfh
->checksum
) {
2484 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2486 "interface %s: OSPF header checksum is not 0",
2490 /* only MD5 crypto method can pass ospf_packet_examin() */
2491 if (NULL
== (ck
= listgetdata(
2492 listtail(OSPF_IF_PARAM(oi
, auth_crypt
))))
2493 || ospfh
->u
.crypt
.key_id
!= ck
->key_id
||
2494 /* Condition above uses the last key ID on the list,
2496 different from what ospf_crypt_key_lookup() does. A
2498 !ospf_check_md5_digest(oi
, ospfh
)) {
2499 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2500 zlog_warn("interface %s: MD5 auth failed",
2506 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
))
2508 "interface %s: invalid packet auth-type (%02x)",
2509 IF_NAME(oi
), pkt_auth_type
);
2514 static int ospf_check_sum(struct ospf_header
*ospfh
)
2519 /* clear auth_data for checksum. */
2520 memset(ospfh
->u
.auth_data
, 0, OSPF_AUTH_SIMPLE_SIZE
);
2522 /* keep checksum and clear. */
2523 sum
= ospfh
->checksum
;
2524 memset(&ospfh
->checksum
, 0, sizeof(u_int16_t
));
2526 /* calculate checksum. */
2527 ret
= in_cksum(ospfh
, ntohs(ospfh
->length
));
2530 zlog_info("ospf_check_sum(): checksum mismatch, my %X, his %X",
2538 /* Verify, that given link/TOS records are properly sized/aligned and match
2539 Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */
2540 static unsigned ospf_router_lsa_links_examin(struct router_lsa_link
*link
,
2541 u_int16_t linkbytes
,
2542 const u_int16_t num_links
)
2544 unsigned counted_links
= 0, thislinklen
;
2548 OSPF_ROUTER_LSA_LINK_SIZE
+ 4 * link
->m
[0].tos_count
;
2549 if (thislinklen
> linkbytes
) {
2550 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2551 zlog_debug("%s: length error in link block #%u",
2552 __func__
, counted_links
);
2555 link
= (struct router_lsa_link
*)((caddr_t
)link
+ thislinklen
);
2556 linkbytes
-= thislinklen
;
2559 if (counted_links
!= num_links
) {
2560 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2561 zlog_debug("%s: %u link blocks declared, %u present",
2562 __func__
, num_links
, counted_links
);
2568 /* Verify, that the given LSA is properly sized/aligned (including type-specific
2569 minimum length constraint). */
2570 static unsigned ospf_lsa_examin(struct lsa_header
*lsah
, const u_int16_t lsalen
,
2571 const u_char headeronly
)
2574 struct router_lsa
*rlsa
;
2575 if (lsah
->type
< OSPF_MAX_LSA
&& ospf_lsa_minlen
[lsah
->type
]
2576 && lsalen
< OSPF_LSA_HEADER_SIZE
+ ospf_lsa_minlen
[lsah
->type
]) {
2577 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2578 zlog_debug("%s: undersized (%u B) %s", __func__
, lsalen
,
2579 lookup_msg(ospf_lsa_type_msg
, lsah
->type
,
2583 switch (lsah
->type
) {
2584 case OSPF_ROUTER_LSA
:
2585 /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1
2586 * (12+)-byte link blocks */
2588 ret
= (lsalen
- OSPF_LSA_HEADER_SIZE
2589 - OSPF_ROUTER_LSA_MIN_SIZE
)
2595 rlsa
= (struct router_lsa
*)lsah
;
2596 ret
= ospf_router_lsa_links_examin(
2597 (struct router_lsa_link
*)rlsa
->link
,
2598 lsalen
- OSPF_LSA_HEADER_SIZE
- 4, /* skip: basic
2601 ntohs(rlsa
->links
) /* 16 bits */
2604 case OSPF_AS_EXTERNAL_LSA
:
2605 /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long
2607 case OSPF_AS_NSSA_LSA
:
2608 /* RFC3101 C, idem */
2609 ret
= (lsalen
- OSPF_LSA_HEADER_SIZE
2610 - OSPF_AS_EXTERNAL_LSA_MIN_SIZE
)
2615 /* Following LSA types are considered OK length-wise as soon as their
2617 * length constraint is met and length of the whole LSA is a multiple of
2619 * (basic LSA header size is already a multiple of 4). */
2620 case OSPF_NETWORK_LSA
:
2621 /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */
2622 case OSPF_SUMMARY_LSA
:
2623 case OSPF_ASBR_SUMMARY_LSA
:
2624 /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS
2626 case OSPF_OPAQUE_LINK_LSA
:
2627 case OSPF_OPAQUE_AREA_LSA
:
2628 case OSPF_OPAQUE_AS_LSA
:
2629 /* RFC5250 A.2, "some number of octets (of application-specific
2630 * data) padded to 32-bit alignment." This is considered
2632 * to 4-byte alignment of all other LSA types, see
2633 * OSPF-ALIGNMENT.txt
2634 * file for the detailed analysis of this passage. */
2635 ret
= lsalen
% 4 ? MSG_NG
: MSG_OK
;
2638 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2639 zlog_debug("%s: unsupported LSA type 0x%02x", __func__
,
2643 if (ret
!= MSG_OK
&& IS_DEBUG_OSPF_PACKET(0, RECV
))
2644 zlog_debug("%s: alignment error in %s", __func__
,
2645 lookup_msg(ospf_lsa_type_msg
, lsah
->type
, NULL
));
2649 /* Verify if the provided input buffer is a valid sequence of LSAs. This
2650 includes verification of LSA blocks length/alignment and dispatching
2651 of deeper-level checks. */
2653 ospf_lsaseq_examin(struct lsa_header
*lsah
, /* start of buffered data */
2654 size_t length
, const u_char headeronly
,
2655 /* When declared_num_lsas is not 0, compare it to the real
2657 and treat the difference as an error. */
2658 const u_int32_t declared_num_lsas
)
2660 u_int32_t counted_lsas
= 0;
2664 if (length
< OSPF_LSA_HEADER_SIZE
) {
2665 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2667 "%s: undersized (%zu B) trailing (#%u) LSA header",
2668 __func__
, length
, counted_lsas
);
2671 /* save on ntohs() calls here and in the LSA validator */
2672 lsalen
= ntohs(lsah
->length
);
2673 if (lsalen
< OSPF_LSA_HEADER_SIZE
) {
2674 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2676 "%s: malformed LSA header #%u, declared length is %u B",
2677 __func__
, counted_lsas
, lsalen
);
2681 /* less checks here and in ospf_lsa_examin() */
2682 if (MSG_OK
!= ospf_lsa_examin(lsah
, lsalen
, 1)) {
2683 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2685 "%s: malformed header-only LSA #%u",
2686 __func__
, counted_lsas
);
2689 lsah
= (struct lsa_header
*)((caddr_t
)lsah
2690 + OSPF_LSA_HEADER_SIZE
);
2691 length
-= OSPF_LSA_HEADER_SIZE
;
2693 /* make sure the input buffer is deep enough before
2695 if (lsalen
> length
) {
2696 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2698 "%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B",
2699 __func__
, counted_lsas
, lsalen
,
2703 if (MSG_OK
!= ospf_lsa_examin(lsah
, lsalen
, 0)) {
2704 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2705 zlog_debug("%s: malformed LSA #%u",
2706 __func__
, counted_lsas
);
2709 lsah
= (struct lsa_header
*)((caddr_t
)lsah
+ lsalen
);
2715 if (declared_num_lsas
&& counted_lsas
!= declared_num_lsas
) {
2716 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2718 "%s: #LSAs declared (%u) does not match actual (%u)",
2719 __func__
, declared_num_lsas
, counted_lsas
);
2725 /* Verify a complete OSPF packet for proper sizing/alignment. */
2726 static unsigned ospf_packet_examin(struct ospf_header
*oh
,
2727 const unsigned bytesonwire
)
2729 u_int16_t bytesdeclared
, bytesauth
;
2731 struct ospf_ls_update
*lsupd
;
2733 /* Length, 1st approximation. */
2734 if (bytesonwire
< OSPF_HEADER_SIZE
) {
2735 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2736 zlog_debug("%s: undersized (%u B) packet", __func__
,
2740 /* Now it is safe to access header fields. Performing length check,
2742 * for possible extra bytes of crypto auth/padding, which are not
2744 * in the OSPF header "length" field. */
2745 if (oh
->version
!= OSPF_VERSION
) {
2746 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2747 zlog_debug("%s: invalid (%u) protocol version",
2748 __func__
, oh
->version
);
2751 bytesdeclared
= ntohs(oh
->length
);
2752 if (ntohs(oh
->auth_type
) != OSPF_AUTH_CRYPTOGRAPHIC
)
2755 if (oh
->u
.crypt
.auth_data_len
!= OSPF_AUTH_MD5_SIZE
) {
2756 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2758 "%s: unsupported crypto auth length (%u B)",
2759 __func__
, oh
->u
.crypt
.auth_data_len
);
2762 bytesauth
= OSPF_AUTH_MD5_SIZE
;
2764 if (bytesdeclared
+ bytesauth
> bytesonwire
) {
2765 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2767 "%s: packet length error (%u real, %u+%u declared)",
2768 __func__
, bytesonwire
, bytesdeclared
,
2772 /* Length, 2nd approximation. The type-specific constraint is checked
2773 against declared length, not amount of bytes on wire. */
2774 if (oh
->type
>= OSPF_MSG_HELLO
&& oh
->type
<= OSPF_MSG_LS_ACK
2776 < OSPF_HEADER_SIZE
+ ospf_packet_minlen
[oh
->type
]) {
2777 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2778 zlog_debug("%s: undersized (%u B) %s packet", __func__
,
2780 lookup_msg(ospf_packet_type_str
, oh
->type
,
2785 case OSPF_MSG_HELLO
:
2786 /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes
2788 by N>=0 router-IDs. */
2789 ret
= (bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_HELLO_MIN_SIZE
)
2794 case OSPF_MSG_DB_DESC
:
2795 /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes
2797 by N>=0 header-only LSAs. */
2798 ret
= ospf_lsaseq_examin(
2799 (struct lsa_header
*)((caddr_t
)oh
+ OSPF_HEADER_SIZE
2800 + OSPF_DB_DESC_MIN_SIZE
),
2801 bytesdeclared
- OSPF_HEADER_SIZE
2802 - OSPF_DB_DESC_MIN_SIZE
,
2803 1, /* header-only LSAs */
2806 case OSPF_MSG_LS_REQ
:
2807 /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes
2808 * request blocks. */
2809 ret
= (bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_LS_REQ_MIN_SIZE
)
2814 case OSPF_MSG_LS_UPD
:
2815 /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes
2817 by N>=0 full LSAs (with N declared beforehand). */
2818 lsupd
= (struct ospf_ls_update
*)((caddr_t
)oh
2819 + OSPF_HEADER_SIZE
);
2820 ret
= ospf_lsaseq_examin(
2821 (struct lsa_header
*)((caddr_t
)lsupd
2822 + OSPF_LS_UPD_MIN_SIZE
),
2823 bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_LS_UPD_MIN_SIZE
,
2825 ntohl(lsupd
->num_lsas
) /* 32 bits */
2828 case OSPF_MSG_LS_ACK
:
2829 /* RFC2328 A.3.6, packet header followed by N>=0 header-only
2831 ret
= ospf_lsaseq_examin(
2832 (struct lsa_header
*)((caddr_t
)oh
+ OSPF_HEADER_SIZE
2833 + OSPF_LS_ACK_MIN_SIZE
),
2834 bytesdeclared
- OSPF_HEADER_SIZE
- OSPF_LS_ACK_MIN_SIZE
,
2835 1, /* header-only LSAs */
2839 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2840 zlog_debug("%s: invalid packet type 0x%02x", __func__
,
2844 if (ret
!= MSG_OK
&& IS_DEBUG_OSPF_PACKET(0, RECV
))
2845 zlog_debug("%s: malformed %s packet", __func__
,
2846 lookup_msg(ospf_packet_type_str
, oh
->type
, NULL
));
2850 /* OSPF Header verification. */
2851 static int ospf_verify_header(struct stream
*ibuf
, struct ospf_interface
*oi
,
2852 struct ip
*iph
, struct ospf_header
*ospfh
)
2854 /* Check Area ID. */
2855 if (!ospf_check_area_id(oi
, ospfh
)) {
2856 zlog_warn("interface %s: ospf_read invalid Area ID %s.",
2857 IF_NAME(oi
), inet_ntoa(ospfh
->area_id
));
2861 /* Check network mask, Silently discarded. */
2862 if (!ospf_check_network_mask(oi
, iph
->ip_src
)) {
2864 "interface %s: ospf_read network address is not same [%s]",
2865 IF_NAME(oi
), inet_ntoa(iph
->ip_src
));
2869 /* Check authentication. The function handles logging actions, where
2871 if (!ospf_check_auth(oi
, ospfh
))
2877 /* Starting point of packet process function. */
2878 int ospf_read(struct thread
*thread
)
2881 struct stream
*ibuf
;
2883 struct ospf_interface
*oi
;
2885 struct ospf_header
*ospfh
;
2887 struct interface
*ifp
= NULL
;
2888 struct connected
*c
;
2890 /* first of all get interface pointer. */
2891 ospf
= THREAD_ARG(thread
);
2893 /* prepare for next packet. */
2894 ospf
->t_read
= NULL
;
2895 thread_add_read(master
, ospf_read
, ospf
, ospf
->fd
, &ospf
->t_read
);
2897 stream_reset(ospf
->ibuf
);
2898 ibuf
= ospf_recv_packet(ospf
, ospf
->fd
, &ifp
, ospf
->ibuf
);
2901 /* This raw packet is known to be at least as big as its IP header. */
2903 /* Note that there should not be alignment problems with this assignment
2904 because this is at the beginning of the stream data buffer. */
2905 iph
= (struct ip
*)STREAM_DATA(ibuf
);
2906 /* Note that sockopt_iphdrincl_swab_systoh was called in
2907 * ospf_recv_packet. */
2910 /* Handle cases where the platform does not support retrieving
2912 and also platforms (such as Solaris 8) that claim to support
2914 retrieval but do not. */
2915 c
= if_lookup_address((void *)&iph
->ip_src
, AF_INET
,
2923 /* IP Header dump. */
2924 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
2925 ospf_ip_header_dump(iph
);
2927 /* Self-originated packet should be discarded silently. */
2928 if (ospf_if_lookup_by_local_addr(ospf
, NULL
, iph
->ip_src
)) {
2929 if (IS_DEBUG_OSPF_PACKET(0, RECV
)) {
2931 "ospf_read[%s]: Dropping self-originated packet",
2932 inet_ntoa(iph
->ip_src
));
2937 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2938 by ospf_recv_packet() to be correct). */
2939 stream_forward_getp(ibuf
, iph
->ip_hl
* 4);
2941 ospfh
= (struct ospf_header
*)stream_pnt(ibuf
);
2943 != ospf_packet_examin(
2944 ospfh
, stream_get_endp(ibuf
) - stream_get_getp(ibuf
)))
2946 /* Now it is safe to access all fields of OSPF packet header. */
2948 /* associate packet with ospf interface */
2949 oi
= ospf_if_lookup_recv_if(ospf
, iph
->ip_src
, ifp
);
2951 /* ospf_verify_header() relies on a valid "oi" and thus can be called
2953 after the passive/backbone/other checks below are passed. These
2955 in turn access the fields of unverified "ospfh" structure for their
2957 purposes and must remain very accurate in doing this. */
2959 /* If incoming interface is passive one, ignore it. */
2960 if (oi
&& OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
) {
2961 char buf
[3][INET_ADDRSTRLEN
];
2963 if (IS_DEBUG_OSPF_EVENT
)
2965 "ignoring packet from router %s sent to %s, "
2966 "received on a passive interface, %s",
2967 inet_ntop(AF_INET
, &ospfh
->router_id
, buf
[0],
2969 inet_ntop(AF_INET
, &iph
->ip_dst
, buf
[1],
2971 inet_ntop(AF_INET
, &oi
->address
->u
.prefix4
,
2972 buf
[2], sizeof(buf
[2])));
2974 if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
)) {
2975 /* Try to fix multicast membership.
2976 * Some OS:es may have problems in this area,
2977 * make sure it is removed.
2979 OI_MEMBER_JOINED(oi
, MEMBER_ALLROUTERS
);
2980 ospf_if_set_multicast(oi
);
2986 /* if no local ospf_interface,
2987 * or header area is backbone but ospf_interface is not
2988 * check for VLINK interface
2990 if ((oi
== NULL
) || (OSPF_IS_AREA_ID_BACKBONE(ospfh
->area_id
)
2991 && !OSPF_IS_AREA_ID_BACKBONE(oi
->area
->area_id
))) {
2992 if ((oi
= ospf_associate_packet_vl(ospf
, ifp
, iph
, ospfh
))
2994 if (!ospf
->instance
&& IS_DEBUG_OSPF_EVENT
)
2996 "Packet from [%s] received on link %s"
2997 " but no ospf_interface",
2998 inet_ntoa(iph
->ip_src
), ifp
->name
);
3003 /* else it must be a local ospf interface, check it was received on
3006 else if (oi
->ifp
!= ifp
) {
3007 if (IS_DEBUG_OSPF_EVENT
)
3008 zlog_warn("Packet from [%s] received on wrong link %s",
3009 inet_ntoa(iph
->ip_src
), ifp
->name
);
3011 } else if (oi
->state
== ISM_Down
) {
3012 char buf
[2][INET_ADDRSTRLEN
];
3014 "Ignoring packet from %s to %s received on interface that is "
3015 "down [%s]; interface flags are %s",
3016 inet_ntop(AF_INET
, &iph
->ip_src
, buf
[0],
3018 inet_ntop(AF_INET
, &iph
->ip_dst
, buf
[1],
3020 ifp
->name
, if_flag_dump(ifp
->flags
));
3021 /* Fix multicast memberships? */
3022 if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLSPFROUTERS
))
3023 OI_MEMBER_JOINED(oi
, MEMBER_ALLROUTERS
);
3024 else if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLDROUTERS
))
3025 OI_MEMBER_JOINED(oi
, MEMBER_DROUTERS
);
3026 if (oi
->multicast_memberships
)
3027 ospf_if_set_multicast(oi
);
3032 * If the received packet is destined for AllDRouters, the packet
3033 * should be accepted only if the received ospf interface state is
3034 * either DR or Backup -- endo.
3036 if (iph
->ip_dst
.s_addr
== htonl(OSPF_ALLDROUTERS
)
3037 && (oi
->state
!= ISM_DR
&& oi
->state
!= ISM_Backup
)) {
3039 "Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
3040 inet_ntoa(iph
->ip_src
), IF_NAME(oi
),
3041 lookup_msg(ospf_ism_state_msg
, oi
->state
, NULL
));
3042 /* Try to fix multicast membership. */
3043 SET_FLAG(oi
->multicast_memberships
, MEMBER_DROUTERS
);
3044 ospf_if_set_multicast(oi
);
3048 /* Verify more OSPF header fields. */
3049 ret
= ospf_verify_header(ibuf
, oi
, iph
, ospfh
);
3051 if (IS_DEBUG_OSPF_PACKET(0, RECV
))
3053 "ospf_read[%s]: Header check failed, "
3055 inet_ntoa(iph
->ip_src
));
3059 /* Show debug receiving packet. */
3060 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, RECV
)) {
3061 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, DETAIL
)) {
3063 "-----------------------------------------------------");
3064 ospf_packet_dump(ibuf
);
3067 zlog_debug("%s received from [%s] via [%s]",
3068 lookup_msg(ospf_packet_type_str
, ospfh
->type
, NULL
),
3069 inet_ntoa(ospfh
->router_id
), IF_NAME(oi
));
3070 zlog_debug(" src [%s],", inet_ntoa(iph
->ip_src
));
3071 zlog_debug(" dst [%s]", inet_ntoa(iph
->ip_dst
));
3073 if (IS_DEBUG_OSPF_PACKET(ospfh
->type
- 1, DETAIL
))
3075 "-----------------------------------------------------");
3078 stream_forward_getp(ibuf
, OSPF_HEADER_SIZE
);
3080 /* Adjust size to message length. */
3081 length
= ntohs(ospfh
->length
) - OSPF_HEADER_SIZE
;
3083 /* Read rest of the packet and call each sort of packet routine. */
3084 switch (ospfh
->type
) {
3085 case OSPF_MSG_HELLO
:
3086 ospf_hello(iph
, ospfh
, ibuf
, oi
, length
);
3088 case OSPF_MSG_DB_DESC
:
3089 ospf_db_desc(iph
, ospfh
, ibuf
, oi
, length
);
3091 case OSPF_MSG_LS_REQ
:
3092 ospf_ls_req(iph
, ospfh
, ibuf
, oi
, length
);
3094 case OSPF_MSG_LS_UPD
:
3095 ospf_ls_upd(ospf
, iph
, ospfh
, ibuf
, oi
, length
);
3097 case OSPF_MSG_LS_ACK
:
3098 ospf_ls_ack(iph
, ospfh
, ibuf
, oi
, length
);
3101 zlog_warn("interface %s: OSPF packet header type %d is illegal",
3102 IF_NAME(oi
), ospfh
->type
);
3109 /* Make OSPF header. */
3110 static void ospf_make_header(int type
, struct ospf_interface
*oi
,
3113 struct ospf_header
*ospfh
;
3115 ospfh
= (struct ospf_header
*)STREAM_DATA(s
);
3117 ospfh
->version
= (u_char
)OSPF_VERSION
;
3118 ospfh
->type
= (u_char
)type
;
3120 ospfh
->router_id
= oi
->ospf
->router_id
;
3122 ospfh
->checksum
= 0;
3123 ospfh
->area_id
= oi
->area
->area_id
;
3124 ospfh
->auth_type
= htons(ospf_auth_type(oi
));
3126 memset(ospfh
->u
.auth_data
, 0, OSPF_AUTH_SIMPLE_SIZE
);
3128 stream_forward_endp(s
, OSPF_HEADER_SIZE
);
3131 /* Make Authentication Data. */
3132 static int ospf_make_auth(struct ospf_interface
*oi
, struct ospf_header
*ospfh
)
3134 struct crypt_key
*ck
;
3136 switch (ospf_auth_type(oi
)) {
3137 case OSPF_AUTH_NULL
:
3138 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data));
3141 case OSPF_AUTH_SIMPLE
:
3142 memcpy(ospfh
->u
.auth_data
, OSPF_IF_PARAM(oi
, auth_simple
),
3143 OSPF_AUTH_SIMPLE_SIZE
);
3145 case OSPF_AUTH_CRYPTOGRAPHIC
:
3146 /* If key is not set, then set 0. */
3147 if (list_isempty(OSPF_IF_PARAM(oi
, auth_crypt
))) {
3148 ospfh
->u
.crypt
.zero
= 0;
3149 ospfh
->u
.crypt
.key_id
= 0;
3150 ospfh
->u
.crypt
.auth_data_len
= OSPF_AUTH_MD5_SIZE
;
3153 listtail(OSPF_IF_PARAM(oi
, auth_crypt
)));
3154 ospfh
->u
.crypt
.zero
= 0;
3155 ospfh
->u
.crypt
.key_id
= ck
->key_id
;
3156 ospfh
->u
.crypt
.auth_data_len
= OSPF_AUTH_MD5_SIZE
;
3158 /* note: the seq is done in ospf_make_md5_digest() */
3161 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data));
3169 /* Fill rest of OSPF header. */
3170 static void ospf_fill_header(struct ospf_interface
*oi
, struct stream
*s
,
3173 struct ospf_header
*ospfh
;
3175 ospfh
= (struct ospf_header
*)STREAM_DATA(s
);
3178 ospfh
->length
= htons(length
);
3180 /* Calculate checksum. */
3181 if (ntohs(ospfh
->auth_type
) != OSPF_AUTH_CRYPTOGRAPHIC
)
3182 ospfh
->checksum
= in_cksum(ospfh
, length
);
3184 ospfh
->checksum
= 0;
3186 /* Add Authentication Data. */
3187 ospf_make_auth(oi
, ospfh
);
3190 static int ospf_make_hello(struct ospf_interface
*oi
, struct stream
*s
)
3192 struct ospf_neighbor
*nbr
;
3193 struct route_node
*rn
;
3194 u_int16_t length
= OSPF_HELLO_MIN_SIZE
;
3195 struct in_addr mask
;
3199 /* Set netmask of interface. */
3200 if (!(CHECK_FLAG(oi
->connected
->flags
, ZEBRA_IFA_UNNUMBERED
)
3201 && oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3202 && oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
3203 masklen2ip(oi
->address
->prefixlen
, &mask
);
3205 memset((char *)&mask
, 0, sizeof(struct in_addr
));
3206 stream_put_ipv4(s
, mask
.s_addr
);
3208 /* Set Hello Interval. */
3209 if (OSPF_IF_PARAM(oi
, fast_hello
) == 0)
3210 stream_putw(s
, OSPF_IF_PARAM(oi
, v_hello
));
3212 stream_putw(s
, 0); /* hello-interval of 0 for fast-hellos */
3214 if (IS_DEBUG_OSPF_EVENT
)
3215 zlog_debug("make_hello: options: %x, int: %s", OPTIONS(oi
),
3219 stream_putc(s
, OPTIONS(oi
));
3221 /* Set Router Priority. */
3222 stream_putc(s
, PRIORITY(oi
));
3224 /* Set Router Dead Interval. */
3225 stream_putl(s
, OSPF_IF_PARAM(oi
, v_wait
));
3227 /* Set Designated Router. */
3228 stream_put_ipv4(s
, DR(oi
).s_addr
);
3230 p
= stream_get_endp(s
);
3232 /* Set Backup Designated Router. */
3233 stream_put_ipv4(s
, BDR(oi
).s_addr
);
3235 /* Add neighbor seen. */
3236 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
3237 if ((nbr
= rn
->info
))
3238 if (nbr
->router_id
.s_addr
3239 != 0) /* Ignore 0.0.0.0 node. */
3241 != NSM_Attempt
) /* Ignore Down neighbor. */
3243 != NSM_Down
) /* This is myself for
3245 if (!IPV4_ADDR_SAME(
3247 &oi
->ospf
->router_id
)) {
3248 /* Check neighbor is
3250 if (nbr
->d_router
.s_addr
3271 /* Let neighbor generate BackupSeen. */
3273 stream_putl_at(s
, p
, 0); /* ipv4 address, normally */
3278 static int ospf_make_db_desc(struct ospf_interface
*oi
,
3279 struct ospf_neighbor
*nbr
, struct stream
*s
)
3281 struct ospf_lsa
*lsa
;
3282 u_int16_t length
= OSPF_DB_DESC_MIN_SIZE
;
3286 struct ospf_lsdb
*lsdb
;
3288 /* Set Interface MTU. */
3289 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
3292 stream_putw(s
, oi
->ifp
->mtu
);
3295 options
= OPTIONS(oi
);
3296 if (CHECK_FLAG(oi
->ospf
->config
, OSPF_OPAQUE_CAPABLE
))
3297 SET_FLAG(options
, OSPF_OPTION_O
);
3298 stream_putc(s
, options
);
3301 pp
= stream_get_endp(s
);
3302 stream_putc(s
, nbr
->dd_flags
);
3304 /* Set DD Sequence Number. */
3305 stream_putl(s
, nbr
->dd_seqnum
);
3307 /* shortcut unneeded walk of (empty) summary LSDBs */
3308 if (ospf_db_summary_isempty(nbr
))
3311 /* Describe LSA Header from Database Summary List. */
3312 lsdb
= &nbr
->db_sum
;
3314 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++) {
3315 struct route_table
*table
= lsdb
->type
[i
].db
;
3316 struct route_node
*rn
;
3318 for (rn
= route_top(table
); rn
; rn
= route_next(rn
))
3319 if ((lsa
= rn
->info
) != NULL
) {
3320 if (IS_OPAQUE_LSA(lsa
->data
->type
)
3321 && (!CHECK_FLAG(options
, OSPF_OPTION_O
))) {
3322 /* Suppress advertising
3323 * opaque-informations. */
3324 /* Remove LSA from DB summary list. */
3325 ospf_lsdb_delete(lsdb
, lsa
);
3329 if (!CHECK_FLAG(lsa
->flags
, OSPF_LSA_DISCARD
)) {
3330 struct lsa_header
*lsah
;
3333 /* DD packet overflows interface MTU. */
3334 if (length
+ OSPF_LSA_HEADER_SIZE
3335 > ospf_packet_max(oi
))
3338 /* Keep pointer to LS age. */
3339 lsah
= (struct lsa_header
3344 /* Proceed stream pointer. */
3345 stream_put(s
, lsa
->data
,
3346 OSPF_LSA_HEADER_SIZE
);
3347 length
+= OSPF_LSA_HEADER_SIZE
;
3350 ls_age
= LS_AGE(lsa
);
3351 lsah
->ls_age
= htons(ls_age
);
3354 /* Remove LSA from DB summary list. */
3355 ospf_lsdb_delete(lsdb
, lsa
);
3359 /* Update 'More' bit */
3360 if (ospf_db_summary_isempty(nbr
)) {
3362 if (nbr
->state
>= NSM_Exchange
) {
3363 UNSET_FLAG(nbr
->dd_flags
, OSPF_DD_FLAG_M
);
3364 /* Rewrite DD flags */
3365 stream_putc_at(s
, pp
, nbr
->dd_flags
);
3367 assert(IS_SET_DD_M(nbr
->dd_flags
));
3373 static int ospf_make_ls_req_func(struct stream
*s
, u_int16_t
*length
,
3374 unsigned long delta
, struct ospf_neighbor
*nbr
,
3375 struct ospf_lsa
*lsa
)
3377 struct ospf_interface
*oi
;
3381 /* LS Request packet overflows interface MTU. */
3382 if (*length
+ delta
> ospf_packet_max(oi
))
3385 stream_putl(s
, lsa
->data
->type
);
3386 stream_put_ipv4(s
, lsa
->data
->id
.s_addr
);
3387 stream_put_ipv4(s
, lsa
->data
->adv_router
.s_addr
);
3389 ospf_lsa_unlock(&nbr
->ls_req_last
);
3390 nbr
->ls_req_last
= ospf_lsa_lock(lsa
);
3396 static int ospf_make_ls_req(struct ospf_neighbor
*nbr
, struct stream
*s
)
3398 struct ospf_lsa
*lsa
;
3399 u_int16_t length
= OSPF_LS_REQ_MIN_SIZE
;
3400 unsigned long delta
= stream_get_endp(s
) + 12;
3401 struct route_table
*table
;
3402 struct route_node
*rn
;
3404 struct ospf_lsdb
*lsdb
;
3406 lsdb
= &nbr
->ls_req
;
3408 for (i
= OSPF_MIN_LSA
; i
< OSPF_MAX_LSA
; i
++) {
3409 table
= lsdb
->type
[i
].db
;
3410 for (rn
= route_top(table
); rn
; rn
= route_next(rn
))
3411 if ((lsa
= (rn
->info
)) != NULL
)
3412 if (ospf_make_ls_req_func(s
, &length
, delta
,
3415 route_unlock_node(rn
);
3422 static int ls_age_increment(struct ospf_lsa
*lsa
, int delay
)
3426 age
= IS_LSA_MAXAGE(lsa
) ? OSPF_LSA_MAXAGE
: LS_AGE(lsa
) + delay
;
3428 return (age
> OSPF_LSA_MAXAGE
? OSPF_LSA_MAXAGE
: age
);
3431 static int ospf_make_ls_upd(struct ospf_interface
*oi
, struct list
*update
,
3434 struct ospf_lsa
*lsa
;
3435 struct listnode
*node
;
3436 u_int16_t length
= 0;
3437 unsigned int size_noauth
;
3438 unsigned long delta
= stream_get_endp(s
);
3442 if (IS_DEBUG_OSPF_EVENT
)
3443 zlog_debug("ospf_make_ls_upd: Start");
3445 pp
= stream_get_endp(s
);
3446 stream_forward_endp(s
, OSPF_LS_UPD_MIN_SIZE
);
3447 length
+= OSPF_LS_UPD_MIN_SIZE
;
3449 /* Calculate amount of packet usable for data. */
3450 size_noauth
= stream_get_size(s
) - ospf_packet_authspace(oi
);
3452 while ((node
= listhead(update
)) != NULL
) {
3453 struct lsa_header
*lsah
;
3456 if (IS_DEBUG_OSPF_EVENT
)
3457 zlog_debug("ospf_make_ls_upd: List Iteration %d",
3460 lsa
= listgetdata(node
);
3465 if (length
+ delta
+ ntohs(lsa
->data
->length
) > size_noauth
)
3468 /* Keep pointer to LS age. */
3469 lsah
= (struct lsa_header
*)(STREAM_DATA(s
)
3470 + stream_get_endp(s
));
3472 /* Put LSA to Link State Request. */
3473 stream_put(s
, lsa
->data
, ntohs(lsa
->data
->length
));
3476 /* each hop must increment an lsa_age by transmit_delay
3477 of OSPF interface */
3478 ls_age
= ls_age_increment(lsa
,
3479 OSPF_IF_PARAM(oi
, transmit_delay
));
3480 lsah
->ls_age
= htons(ls_age
);
3482 length
+= ntohs(lsa
->data
->length
);
3485 list_delete_node(update
, node
);
3486 ospf_lsa_unlock(&lsa
); /* oi->ls_upd_queue */
3489 /* Now set #LSAs. */
3490 stream_putl_at(s
, pp
, count
);
3492 if (IS_DEBUG_OSPF_EVENT
)
3493 zlog_debug("ospf_make_ls_upd: Stop");
3497 static int ospf_make_ls_ack(struct ospf_interface
*oi
, struct list
*ack
,
3500 struct listnode
*node
, *nnode
;
3501 u_int16_t length
= OSPF_LS_ACK_MIN_SIZE
;
3502 unsigned long delta
= stream_get_endp(s
) + 24;
3503 struct ospf_lsa
*lsa
;
3505 for (ALL_LIST_ELEMENTS(ack
, node
, nnode
, lsa
)) {
3508 if (length
+ delta
> ospf_packet_max(oi
))
3511 stream_put(s
, lsa
->data
, OSPF_LSA_HEADER_SIZE
);
3512 length
+= OSPF_LSA_HEADER_SIZE
;
3514 listnode_delete(ack
, lsa
);
3515 ospf_lsa_unlock(&lsa
); /* oi->ls_ack_direct.ls_ack */
3521 static void ospf_hello_send_sub(struct ospf_interface
*oi
, in_addr_t addr
)
3523 struct ospf_packet
*op
;
3524 u_int16_t length
= OSPF_HEADER_SIZE
;
3526 op
= ospf_packet_new(oi
->ifp
->mtu
);
3528 /* Prepare OSPF common header. */
3529 ospf_make_header(OSPF_MSG_HELLO
, oi
, op
->s
);
3531 /* Prepare OSPF Hello body. */
3532 length
+= ospf_make_hello(oi
, op
->s
);
3534 /* Fill OSPF header. */
3535 ospf_fill_header(oi
, op
->s
, length
);
3537 /* Set packet length. */
3538 op
->length
= length
;
3540 op
->dst
.s_addr
= addr
;
3542 if (IS_DEBUG_OSPF_EVENT
) {
3543 if (oi
->ospf
->vrf_id
)
3545 "%s: Hello Tx interface %s ospf vrf %s id %u",
3546 __PRETTY_FUNCTION__
, oi
->ifp
->name
,
3547 ospf_vrf_id_to_name(oi
->ospf
->vrf_id
),
3550 /* Add packet to the top of the interface output queue, so that they
3551 * can't get delayed by things like long queues of LS Update packets
3553 ospf_packet_add_top(oi
, op
);
3555 /* Hook thread to write packet. */
3556 OSPF_ISM_WRITE_ON(oi
->ospf
);
3559 static void ospf_poll_send(struct ospf_nbr_nbma
*nbr_nbma
)
3561 struct ospf_interface
*oi
;
3566 /* If this is passive interface, do not send OSPF Hello. */
3567 if (OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
)
3570 if (oi
->type
!= OSPF_IFTYPE_NBMA
)
3573 if (nbr_nbma
->nbr
!= NULL
&& nbr_nbma
->nbr
->state
!= NSM_Down
)
3576 if (PRIORITY(oi
) == 0)
3579 if (nbr_nbma
->priority
== 0 && oi
->state
!= ISM_DR
3580 && oi
->state
!= ISM_Backup
)
3583 ospf_hello_send_sub(oi
, nbr_nbma
->addr
.s_addr
);
3586 int ospf_poll_timer(struct thread
*thread
)
3588 struct ospf_nbr_nbma
*nbr_nbma
;
3590 nbr_nbma
= THREAD_ARG(thread
);
3591 nbr_nbma
->t_poll
= NULL
;
3593 if (IS_DEBUG_OSPF(nsm
, NSM_TIMERS
))
3594 zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)",
3595 IF_NAME(nbr_nbma
->oi
), inet_ntoa(nbr_nbma
->addr
));
3597 ospf_poll_send(nbr_nbma
);
3599 if (nbr_nbma
->v_poll
> 0)
3600 OSPF_POLL_TIMER_ON(nbr_nbma
->t_poll
, ospf_poll_timer
,
3607 int ospf_hello_reply_timer(struct thread
*thread
)
3609 struct ospf_neighbor
*nbr
;
3611 nbr
= THREAD_ARG(thread
);
3612 nbr
->t_hello_reply
= NULL
;
3616 if (IS_DEBUG_OSPF(nsm
, NSM_TIMERS
))
3617 zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)",
3618 IF_NAME(nbr
->oi
), inet_ntoa(nbr
->router_id
));
3620 ospf_hello_send_sub(nbr
->oi
, nbr
->address
.u
.prefix4
.s_addr
);
3625 /* Send OSPF Hello. */
3626 void ospf_hello_send(struct ospf_interface
*oi
)
3628 /* If this is passive interface, do not send OSPF Hello. */
3629 if (OSPF_IF_PASSIVE_STATUS(oi
) == OSPF_IF_PASSIVE
)
3632 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
3633 struct ospf_neighbor
*nbr
;
3634 struct route_node
*rn
;
3636 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
3637 if ((nbr
= rn
->info
))
3638 if (nbr
!= oi
->nbr_self
)
3639 if (nbr
->state
!= NSM_Down
) {
3640 /* RFC 2328 Section 9.5.1
3641 If the router is not
3642 eligible to become Designated
3644 it must periodically send
3645 Hello Packets to both the
3646 Designated Router and the
3647 Backup Designated Router (if
3650 if (PRIORITY(oi
) == 0
3661 /* If the router is eligible to
3662 become Designated Router, it
3663 must periodically send Hello
3664 Packets to all neighbors that
3665 are also eligible. In
3666 addition, if the router is
3668 Designated Router or Backup
3669 Designated Router, it must
3671 send periodic Hello Packets
3672 to all other neighbors. */
3674 if (nbr
->priority
== 0
3675 && oi
->state
== ISM_DROther
)
3677 /* if oi->state == Waiting, send
3678 * hello to all neighbors */
3679 ospf_hello_send_sub(
3681 nbr
->address
.u
.prefix4
3685 /* Decide destination address. */
3686 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
3687 ospf_hello_send_sub(oi
, oi
->vl_data
->peer_addr
.s_addr
);
3689 ospf_hello_send_sub(oi
, htonl(OSPF_ALLSPFROUTERS
));
3693 /* Send OSPF Database Description. */
3694 void ospf_db_desc_send(struct ospf_neighbor
*nbr
)
3696 struct ospf_interface
*oi
;
3697 struct ospf_packet
*op
;
3698 u_int16_t length
= OSPF_HEADER_SIZE
;
3701 op
= ospf_packet_new(oi
->ifp
->mtu
);
3703 /* Prepare OSPF common header. */
3704 ospf_make_header(OSPF_MSG_DB_DESC
, oi
, op
->s
);
3706 /* Prepare OSPF Database Description body. */
3707 length
+= ospf_make_db_desc(oi
, nbr
, op
->s
);
3709 /* Fill OSPF header. */
3710 ospf_fill_header(oi
, op
->s
, length
);
3712 /* Set packet length. */
3713 op
->length
= length
;
3715 /* Decide destination address. */
3716 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3717 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3719 op
->dst
= nbr
->address
.u
.prefix4
;
3721 /* Add packet to the interface output queue. */
3722 ospf_packet_add(oi
, op
);
3724 /* Hook thread to write packet. */
3725 OSPF_ISM_WRITE_ON(oi
->ospf
);
3727 /* Remove old DD packet, then copy new one and keep in neighbor
3730 ospf_packet_free(nbr
->last_send
);
3731 nbr
->last_send
= ospf_packet_dup(op
);
3732 monotime(&nbr
->last_send_ts
);
3735 /* Re-send Database Description. */
3736 void ospf_db_desc_resend(struct ospf_neighbor
*nbr
)
3738 struct ospf_interface
*oi
;
3742 /* Add packet to the interface output queue. */
3743 ospf_packet_add(oi
, ospf_packet_dup(nbr
->last_send
));
3745 /* Hook thread to write packet. */
3746 OSPF_ISM_WRITE_ON(oi
->ospf
);
3749 /* Send Link State Request. */
3750 void ospf_ls_req_send(struct ospf_neighbor
*nbr
)
3752 struct ospf_interface
*oi
;
3753 struct ospf_packet
*op
;
3754 u_int16_t length
= OSPF_HEADER_SIZE
;
3757 op
= ospf_packet_new(oi
->ifp
->mtu
);
3759 /* Prepare OSPF common header. */
3760 ospf_make_header(OSPF_MSG_LS_REQ
, oi
, op
->s
);
3762 /* Prepare OSPF Link State Request body. */
3763 length
+= ospf_make_ls_req(nbr
, op
->s
);
3764 if (length
== OSPF_HEADER_SIZE
) {
3765 ospf_packet_free(op
);
3769 /* Fill OSPF header. */
3770 ospf_fill_header(oi
, op
->s
, length
);
3772 /* Set packet length. */
3773 op
->length
= length
;
3775 /* Decide destination address. */
3776 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3777 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3779 op
->dst
= nbr
->address
.u
.prefix4
;
3781 /* Add packet to the interface output queue. */
3782 ospf_packet_add(oi
, op
);
3784 /* Hook thread to write packet. */
3785 OSPF_ISM_WRITE_ON(oi
->ospf
);
3787 /* Add Link State Request Retransmission Timer. */
3788 OSPF_NSM_TIMER_ON(nbr
->t_ls_req
, ospf_ls_req_timer
, nbr
->v_ls_req
);
3791 /* Send Link State Update with an LSA. */
3792 void ospf_ls_upd_send_lsa(struct ospf_neighbor
*nbr
, struct ospf_lsa
*lsa
,
3795 struct list
*update
;
3797 update
= list_new();
3799 listnode_add(update
, lsa
);
3801 /*ospf instance is going down, send self originated
3802 * MAXAGE LSA update to neighbors to remove from LSDB */
3803 if (nbr
->oi
->ospf
->inst_shutdown
&& IS_LSA_MAXAGE(lsa
))
3804 ospf_ls_upd_send(nbr
, update
, flag
, 1);
3806 ospf_ls_upd_send(nbr
, update
, flag
, 0);
3808 list_delete_and_null(&update
);
3811 /* Determine size for packet. Must be at least big enough to accomodate next
3812 * LSA on list, which may be bigger than MTU size.
3814 * Return pointer to new ospf_packet
3815 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3816 * on packet sizes (in which case offending LSA is deleted from update list)
3818 static struct ospf_packet
*ospf_ls_upd_packet_new(struct list
*update
,
3819 struct ospf_interface
*oi
)
3821 struct ospf_lsa
*lsa
;
3822 struct listnode
*ln
;
3824 static char warned
= 0;
3826 lsa
= listgetdata((ln
= listhead(update
)));
3829 if ((OSPF_LS_UPD_MIN_SIZE
+ ntohs(lsa
->data
->length
))
3830 > ospf_packet_max(oi
)) {
3833 "ospf_ls_upd_packet_new: oversized LSA encountered!"
3834 "will need to fragment. Not optimal. Try divide up"
3835 " your network with areas. Use 'debug ospf packet send'"
3836 " to see details, or look at 'show ip ospf database ..'");
3840 if (IS_DEBUG_OSPF_PACKET(0, SEND
))
3842 "ospf_ls_upd_packet_new: oversized LSA id:%s,"
3843 " %d bytes originated by %s, will be fragmented!",
3844 inet_ntoa(lsa
->data
->id
),
3845 ntohs(lsa
->data
->length
),
3846 inet_ntoa(lsa
->data
->adv_router
));
3849 * Allocate just enough to fit this LSA only, to avoid including
3851 * LSAs in fragmented LSA Updates.
3853 size
= ntohs(lsa
->data
->length
)
3854 + (oi
->ifp
->mtu
- ospf_packet_max(oi
))
3855 + OSPF_LS_UPD_MIN_SIZE
;
3857 size
= oi
->ifp
->mtu
;
3859 if (size
> OSPF_MAX_PACKET_SIZE
) {
3861 "ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3862 " %d bytes, packet size %ld, dropping it completely."
3863 " OSPF routing is broken!",
3864 inet_ntoa(lsa
->data
->id
), ntohs(lsa
->data
->length
),
3866 list_delete_node(update
, ln
);
3870 /* IP header is built up separately by ospf_write(). This means, that we
3872 * reduce the "affordable" size just calculated by length of an IP
3874 * This makes sure, that even if we manage to fill the payload with LSA
3876 * completely, the final packet (our data plus IP header) still fits
3878 * outgoing interface MTU. This correction isn't really meaningful for
3880 * oversized LSA, but for consistency the correction is done for both
3883 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3885 return ospf_packet_new(size
- sizeof(struct ip
));
3888 static void ospf_ls_upd_queue_send(struct ospf_interface
*oi
,
3889 struct list
*update
, struct in_addr addr
,
3892 struct ospf_packet
*op
;
3893 u_int16_t length
= OSPF_HEADER_SIZE
;
3895 if (IS_DEBUG_OSPF_EVENT
)
3896 zlog_debug("listcount = %d, [%s]dst %s", listcount(update
),
3897 IF_NAME(oi
), inet_ntoa(addr
));
3899 /* Check that we have really something to process */
3900 if (listcount(update
) == 0)
3903 op
= ospf_ls_upd_packet_new(update
, oi
);
3905 /* Prepare OSPF common header. */
3906 ospf_make_header(OSPF_MSG_LS_UPD
, oi
, op
->s
);
3908 /* Prepare OSPF Link State Update body.
3909 * Includes Type-7 translation.
3911 length
+= ospf_make_ls_upd(oi
, update
, op
->s
);
3913 /* Fill OSPF header. */
3914 ospf_fill_header(oi
, op
->s
, length
);
3916 /* Set packet length. */
3917 op
->length
= length
;
3919 /* Decide destination address. */
3920 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
3921 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
3923 op
->dst
.s_addr
= addr
.s_addr
;
3925 /* Add packet to the interface output queue. */
3926 ospf_packet_add(oi
, op
);
3927 /* Call ospf_write() right away to send ospf packets to neighbors */
3928 if (send_lsupd_now
) {
3929 struct thread os_packet_thd
;
3931 os_packet_thd
.arg
= (void *)oi
->ospf
;
3932 if (oi
->on_write_q
== 0) {
3933 listnode_add(oi
->ospf
->oi_write_q
, oi
);
3936 ospf_write(&os_packet_thd
);
3938 /* Hook thread to write packet. */
3939 OSPF_ISM_WRITE_ON(oi
->ospf
);
3943 static int ospf_ls_upd_send_queue_event(struct thread
*thread
)
3945 struct ospf_interface
*oi
= THREAD_ARG(thread
);
3946 struct route_node
*rn
;
3947 struct route_node
*rnext
;
3948 struct list
*update
;
3951 oi
->t_ls_upd_event
= NULL
;
3953 if (IS_DEBUG_OSPF_EVENT
)
3954 zlog_debug("ospf_ls_upd_send_queue start");
3956 for (rn
= route_top(oi
->ls_upd_queue
); rn
; rn
= rnext
) {
3957 rnext
= route_next(rn
);
3959 if (rn
->info
== NULL
)
3962 update
= (struct list
*)rn
->info
;
3964 ospf_ls_upd_queue_send(oi
, update
, rn
->p
.u
.prefix4
, 0);
3966 /* list might not be empty. */
3967 if (listcount(update
) == 0) {
3968 list_delete_and_null((struct list
**)&rn
->info
);
3969 route_unlock_node(rn
);
3975 if (IS_DEBUG_OSPF_EVENT
)
3977 "ospf_ls_upd_send_queue: update lists not cleared,"
3978 " %d nodes to try again, raising new event",
3980 oi
->t_ls_upd_event
= NULL
;
3981 thread_add_event(master
, ospf_ls_upd_send_queue_event
, oi
, 0,
3982 &oi
->t_ls_upd_event
);
3985 if (IS_DEBUG_OSPF_EVENT
)
3986 zlog_debug("ospf_ls_upd_send_queue stop");
3991 void ospf_ls_upd_send(struct ospf_neighbor
*nbr
, struct list
*update
, int flag
,
3994 struct ospf_interface
*oi
;
3995 struct ospf_lsa
*lsa
;
3996 struct prefix_ipv4 p
;
3997 struct route_node
*rn
;
3998 struct listnode
*node
;
4003 p
.prefixlen
= IPV4_MAX_BITLEN
;
4005 /* Decide destination address. */
4006 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
4007 p
.prefix
= oi
->vl_data
->peer_addr
;
4008 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4009 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4010 else if (flag
== OSPF_SEND_PACKET_DIRECT
)
4011 p
.prefix
= nbr
->address
.u
.prefix4
;
4012 else if (oi
->state
== ISM_DR
|| oi
->state
== ISM_Backup
)
4013 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4014 else if (oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
4015 p
.prefix
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4017 p
.prefix
.s_addr
= htonl(OSPF_ALLDROUTERS
);
4019 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
4020 if (flag
== OSPF_SEND_PACKET_INDIRECT
)
4022 "* LS-Update is directly sent on NBMA network.");
4023 if (IPV4_ADDR_SAME(&oi
->address
->u
.prefix4
, &p
.prefix
))
4024 zlog_warn("* LS-Update is sent to myself.");
4027 rn
= route_node_get(oi
->ls_upd_queue
, (struct prefix
*)&p
);
4029 if (rn
->info
== NULL
)
4030 rn
->info
= list_new();
4032 route_unlock_node(rn
);
4034 for (ALL_LIST_ELEMENTS_RO(update
, node
, lsa
))
4035 listnode_add(rn
->info
,
4036 ospf_lsa_lock(lsa
)); /* oi->ls_upd_queue */
4037 if (send_lsupd_now
) {
4038 struct list
*send_update_list
;
4039 struct route_node
*rn
, *rnext
;
4041 for (rn
= route_top(oi
->ls_upd_queue
); rn
; rn
= rnext
) {
4042 rnext
= route_next(rn
);
4044 if (rn
->info
== NULL
)
4047 send_update_list
= (struct list
*)rn
->info
;
4049 ospf_ls_upd_queue_send(oi
, send_update_list
,
4050 rn
->p
.u
.prefix4
, 1);
4053 thread_add_event(master
, ospf_ls_upd_send_queue_event
, oi
, 0,
4054 &oi
->t_ls_upd_event
);
4057 static void ospf_ls_ack_send_list(struct ospf_interface
*oi
, struct list
*ack
,
4060 struct ospf_packet
*op
;
4061 u_int16_t length
= OSPF_HEADER_SIZE
;
4063 op
= ospf_packet_new(oi
->ifp
->mtu
);
4065 /* Prepare OSPF common header. */
4066 ospf_make_header(OSPF_MSG_LS_ACK
, oi
, op
->s
);
4068 /* Prepare OSPF Link State Acknowledgment body. */
4069 length
+= ospf_make_ls_ack(oi
, ack
, op
->s
);
4071 /* Fill OSPF header. */
4072 ospf_fill_header(oi
, op
->s
, length
);
4074 /* Set packet length. */
4075 op
->length
= length
;
4077 /* Decide destination address. */
4078 if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4079 op
->dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4081 op
->dst
.s_addr
= dst
.s_addr
;
4083 /* Add packet to the interface output queue. */
4084 ospf_packet_add(oi
, op
);
4086 /* Hook thread to write packet. */
4087 OSPF_ISM_WRITE_ON(oi
->ospf
);
4090 static int ospf_ls_ack_send_event(struct thread
*thread
)
4092 struct ospf_interface
*oi
= THREAD_ARG(thread
);
4094 oi
->t_ls_ack_direct
= NULL
;
4096 while (listcount(oi
->ls_ack_direct
.ls_ack
))
4097 ospf_ls_ack_send_list(oi
, oi
->ls_ack_direct
.ls_ack
,
4098 oi
->ls_ack_direct
.dst
);
4103 void ospf_ls_ack_send(struct ospf_neighbor
*nbr
, struct ospf_lsa
*lsa
)
4105 struct ospf_interface
*oi
= nbr
->oi
;
4107 if (listcount(oi
->ls_ack_direct
.ls_ack
) == 0)
4108 oi
->ls_ack_direct
.dst
= nbr
->address
.u
.prefix4
;
4110 listnode_add(oi
->ls_ack_direct
.ls_ack
, ospf_lsa_lock(lsa
));
4112 thread_add_event(master
, ospf_ls_ack_send_event
, oi
, 0,
4113 &oi
->t_ls_ack_direct
);
4116 /* Send Link State Acknowledgment delayed. */
4117 void ospf_ls_ack_send_delayed(struct ospf_interface
*oi
)
4121 /* Decide destination address. */
4122 /* RFC2328 Section 13.5 On non-broadcast
4123 networks, delayed Link State Acknowledgment packets must be
4124 unicast separately over each adjacency (i.e., neighbor whose
4125 state is >= Exchange). */
4126 if (oi
->type
== OSPF_IFTYPE_NBMA
) {
4127 struct ospf_neighbor
*nbr
;
4128 struct route_node
*rn
;
4130 for (rn
= route_top(oi
->nbrs
); rn
; rn
= route_next(rn
))
4131 if ((nbr
= rn
->info
) != NULL
)
4132 if (nbr
!= oi
->nbr_self
4133 && nbr
->state
>= NSM_Exchange
)
4134 while (listcount(oi
->ls_ack
))
4135 ospf_ls_ack_send_list(
4137 nbr
->address
.u
.prefix4
);
4140 if (oi
->type
== OSPF_IFTYPE_VIRTUALLINK
)
4141 dst
.s_addr
= oi
->vl_data
->peer_addr
.s_addr
;
4142 else if (oi
->state
== ISM_DR
|| oi
->state
== ISM_Backup
)
4143 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4144 else if (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)
4145 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4146 else if (oi
->type
== OSPF_IFTYPE_POINTOMULTIPOINT
)
4147 dst
.s_addr
= htonl(OSPF_ALLSPFROUTERS
);
4149 dst
.s_addr
= htonl(OSPF_ALLDROUTERS
);
4151 while (listcount(oi
->ls_ack
))
4152 ospf_ls_ack_send_list(oi
, oi
->ls_ack
, dst
);
4156 * On pt-to-pt links, all OSPF control packets are sent to the multicast
4157 * address. As a result, the kernel does not need to learn the interface
4158 * MAC of the OSPF neighbor. However, in our world, this will delay
4159 * convergence. Take the case when due to a link flap, all routes now
4160 * want to use an interface which was deemed to be costlier prior to this
4161 * event. For routes that will be installed, the missing MAC will have
4162 * punt-to-CPU set on them. This may overload the CPU control path that
4163 * can be avoided if the MAC was known apriori.
4165 #define OSPF_PING_NBR_STR_MAX (BUFSIZ)
4166 void ospf_proactively_arp(struct ospf_neighbor
*nbr
)
4168 char ping_nbr
[OSPF_PING_NBR_STR_MAX
];
4171 if (!nbr
|| !nbr
->oi
|| !nbr
->oi
->ifp
)
4174 snprintf(ping_nbr
, sizeof(ping_nbr
),
4175 "ping -c 1 -I %s %s > /dev/null 2>&1 &", nbr
->oi
->ifp
->name
,
4176 inet_ntoa(nbr
->address
.u
.prefix4
));
4178 ret
= system(ping_nbr
);
4179 if (IS_DEBUG_OSPF_EVENT
)
4180 zlog_debug("Executed %s %s", ping_nbr
,
4181 ((ret
== 0) ? "successfully" : "but failed"));