+ initial edition of meta-queue for RIB updates processing (bug #431)
[jleu-quagga.git] / ospfd / ospf_packet.c
bloba778a50b5e58113d263f0e242004b80b0ca81ba6
1 /*
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
10 * later version.
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
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
23 #include <zebra.h>
25 #include "thread.h"
26 #include "memory.h"
27 #include "linklist.h"
28 #include "prefix.h"
29 #include "if.h"
30 #include "table.h"
31 #include "sockunion.h"
32 #include "stream.h"
33 #include "log.h"
34 #include "sockopt.h"
35 #include "checksum.h"
36 #include "md5.h"
38 #include "ospfd/ospfd.h"
39 #include "ospfd/ospf_network.h"
40 #include "ospfd/ospf_interface.h"
41 #include "ospfd/ospf_ism.h"
42 #include "ospfd/ospf_asbr.h"
43 #include "ospfd/ospf_lsa.h"
44 #include "ospfd/ospf_lsdb.h"
45 #include "ospfd/ospf_neighbor.h"
46 #include "ospfd/ospf_nsm.h"
47 #include "ospfd/ospf_packet.h"
48 #include "ospfd/ospf_spf.h"
49 #include "ospfd/ospf_flood.h"
50 #include "ospfd/ospf_dump.h"
52 /* Packet Type String. */
53 const char *ospf_packet_type_str[] =
55 "unknown",
56 "Hello",
57 "Database Description",
58 "Link State Request",
59 "Link State Update",
60 "Link State Acknowledgment",
63 /* OSPF authentication checking function */
64 static int
65 ospf_auth_type (struct ospf_interface *oi)
67 int auth_type;
69 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
70 auth_type = oi->area->auth_type;
71 else
72 auth_type = OSPF_IF_PARAM (oi, auth_type);
74 /* Handle case where MD5 key list is not configured aka Cisco */
75 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
76 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
77 return OSPF_AUTH_NULL;
79 return auth_type;
83 struct ospf_packet *
84 ospf_packet_new (size_t size)
86 struct ospf_packet *new;
88 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
89 new->s = stream_new (size);
91 return new;
94 void
95 ospf_packet_free (struct ospf_packet *op)
97 if (op->s)
98 stream_free (op->s);
100 XFREE (MTYPE_OSPF_PACKET, op);
102 op = NULL;
105 struct ospf_fifo *
106 ospf_fifo_new ()
108 struct ospf_fifo *new;
110 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
111 return new;
114 /* Add new packet to fifo. */
115 void
116 ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
118 if (fifo->tail)
119 fifo->tail->next = op;
120 else
121 fifo->head = op;
123 fifo->tail = op;
125 fifo->count++;
128 /* Delete first packet from fifo. */
129 struct ospf_packet *
130 ospf_fifo_pop (struct ospf_fifo *fifo)
132 struct ospf_packet *op;
134 op = fifo->head;
136 if (op)
138 fifo->head = op->next;
140 if (fifo->head == NULL)
141 fifo->tail = NULL;
143 fifo->count--;
146 return op;
149 /* Return first fifo entry. */
150 struct ospf_packet *
151 ospf_fifo_head (struct ospf_fifo *fifo)
153 return fifo->head;
156 /* Flush ospf packet fifo. */
157 void
158 ospf_fifo_flush (struct ospf_fifo *fifo)
160 struct ospf_packet *op;
161 struct ospf_packet *next;
163 for (op = fifo->head; op; op = next)
165 next = op->next;
166 ospf_packet_free (op);
168 fifo->head = fifo->tail = NULL;
169 fifo->count = 0;
172 /* Free ospf packet fifo. */
173 void
174 ospf_fifo_free (struct ospf_fifo *fifo)
176 ospf_fifo_flush (fifo);
178 XFREE (MTYPE_OSPF_FIFO, fifo);
181 void
182 ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
184 if (!oi->obuf)
186 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
187 "destination %s) called with NULL obuf, ignoring "
188 "(please report this bug)!\n",
189 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
190 ospf_packet_type_str[stream_getc_from(op->s, 1)],
191 inet_ntoa (op->dst));
192 return;
195 /* Add packet to end of queue. */
196 ospf_fifo_push (oi->obuf, op);
198 /* Debug of packet fifo*/
199 /* ospf_fifo_debug (oi->obuf); */
202 void
203 ospf_packet_delete (struct ospf_interface *oi)
205 struct ospf_packet *op;
207 op = ospf_fifo_pop (oi->obuf);
209 if (op)
210 ospf_packet_free (op);
213 struct ospf_packet *
214 ospf_packet_dup (struct ospf_packet *op)
216 struct ospf_packet *new;
218 if (stream_get_endp(op->s) != op->length)
219 /* XXX size_t */
220 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
221 (u_long)STREAM_SIZE(op->s), op->length);
223 /* Reserve space for MD5 authentication that may be added later. */
224 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
225 stream_copy (new->s, op->s);
227 new->dst = op->dst;
228 new->length = op->length;
230 return new;
233 /* XXX inline */
234 static inline unsigned int
235 ospf_packet_authspace (struct ospf_interface *oi)
237 int auth = 0;
239 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
240 auth = OSPF_AUTH_MD5_SIZE;
242 return auth;
245 static unsigned int
246 ospf_packet_max (struct ospf_interface *oi)
248 int max;
250 max = oi->ifp->mtu - ospf_packet_authspace(oi);
252 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
254 return max;
258 static int
259 ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
260 u_int16_t length)
262 unsigned char *ibuf;
263 MD5_CTX ctx;
264 unsigned char digest[OSPF_AUTH_MD5_SIZE];
265 unsigned char *pdigest;
266 struct crypt_key *ck;
267 struct ospf_header *ospfh;
268 struct ospf_neighbor *nbr;
271 ibuf = STREAM_PNT (s);
272 ospfh = (struct ospf_header *) ibuf;
274 /* Get pointer to the end of the packet. */
275 pdigest = ibuf + length;
277 /* Get secret key. */
278 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
279 ospfh->u.crypt.key_id);
280 if (ck == NULL)
282 zlog_warn ("interface %s: ospf_check_md5 no key %d",
283 IF_NAME (oi), ospfh->u.crypt.key_id);
284 return 0;
287 /* check crypto seqnum. */
288 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
290 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
292 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
293 IF_NAME (oi),
294 ntohl(ospfh->u.crypt.crypt_seqnum),
295 ntohl(nbr->crypt_seqnum));
296 return 0;
299 /* Generate a digest for the ospf packet - their digest + our digest. */
300 memset(&ctx, 0, sizeof(ctx));
301 MD5Init(&ctx);
302 MD5Update(&ctx, ibuf, length);
303 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
304 MD5Final(digest, &ctx);
306 /* compare the two */
307 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
309 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
310 IF_NAME (oi));
311 return 0;
314 /* save neighbor's crypt_seqnum */
315 if (nbr)
316 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
317 return 1;
320 /* This function is called from ospf_write(), it will detect the
321 authentication scheme and if it is MD5, it will change the sequence
322 and update the MD5 digest. */
323 static int
324 ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
326 struct ospf_header *ospfh;
327 unsigned char digest[OSPF_AUTH_MD5_SIZE];
328 MD5_CTX ctx;
329 void *ibuf;
330 u_int32_t t;
331 struct crypt_key *ck;
332 const u_int8_t *auth_key;
334 ibuf = STREAM_DATA (op->s);
335 ospfh = (struct ospf_header *) ibuf;
337 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
338 return 0;
340 /* We do this here so when we dup a packet, we don't have to
341 waste CPU rewriting other headers.
343 Note that quagga_time /deliberately/ is not used here */
344 t = (time(NULL) & 0xFFFFFFFF);
345 if (t > oi->crypt_seqnum)
346 oi->crypt_seqnum = t;
347 else
348 oi->crypt_seqnum++;
350 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
352 /* Get MD5 Authentication key from auth_key list. */
353 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
354 auth_key = (const u_int8_t *) "";
355 else
357 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
358 auth_key = ck->auth_key;
361 /* Generate a digest for the entire packet + our secret key. */
362 memset(&ctx, 0, sizeof(ctx));
363 MD5Init(&ctx);
364 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
365 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
366 MD5Final(digest, &ctx);
368 /* Append md5 digest to the end of the stream. */
369 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
371 /* We do *NOT* increment the OSPF header length. */
372 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
374 if (stream_get_endp(op->s) != op->length)
375 /* XXX size_t */
376 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
377 (u_long)stream_get_endp(op->s), op->length);
379 return OSPF_AUTH_MD5_SIZE;
383 static int
384 ospf_ls_req_timer (struct thread *thread)
386 struct ospf_neighbor *nbr;
388 nbr = THREAD_ARG (thread);
389 nbr->t_ls_req = NULL;
391 /* Send Link State Request. */
392 if (ospf_ls_request_count (nbr))
393 ospf_ls_req_send (nbr);
395 /* Set Link State Request retransmission timer. */
396 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
398 return 0;
401 void
402 ospf_ls_req_event (struct ospf_neighbor *nbr)
404 if (nbr->t_ls_req)
406 thread_cancel (nbr->t_ls_req);
407 nbr->t_ls_req = NULL;
409 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
412 /* Cyclic timer function. Fist registered in ospf_nbr_new () in
413 ospf_neighbor.c */
415 ospf_ls_upd_timer (struct thread *thread)
417 struct ospf_neighbor *nbr;
419 nbr = THREAD_ARG (thread);
420 nbr->t_ls_upd = NULL;
422 /* Send Link State Update. */
423 if (ospf_ls_retransmit_count (nbr) > 0)
425 struct list *update;
426 struct ospf_lsdb *lsdb;
427 int i;
428 int retransmit_interval;
430 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
432 lsdb = &nbr->ls_rxmt;
433 update = list_new ();
435 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
437 struct route_table *table = lsdb->type[i].db;
438 struct route_node *rn;
440 for (rn = route_top (table); rn; rn = route_next (rn))
442 struct ospf_lsa *lsa;
444 if ((lsa = rn->info) != NULL)
445 /* Don't retransmit an LSA if we received it within
446 the last RxmtInterval seconds - this is to allow the
447 neighbour a chance to acknowledge the LSA as it may
448 have ben just received before the retransmit timer
449 fired. This is a small tweak to what is in the RFC,
450 but it will cut out out a lot of retransmit traffic
451 - MAG */
452 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
453 int2tv (retransmit_interval)) >= 0)
454 listnode_add (update, rn->info);
458 if (listcount (update) > 0)
459 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
460 list_delete (update);
463 /* Set LS Update retransmission timer. */
464 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
466 return 0;
470 ospf_ls_ack_timer (struct thread *thread)
472 struct ospf_interface *oi;
474 oi = THREAD_ARG (thread);
475 oi->t_ls_ack = NULL;
477 /* Send Link State Acknowledgment. */
478 if (listcount (oi->ls_ack) > 0)
479 ospf_ls_ack_send_delayed (oi);
481 /* Set LS Ack timer. */
482 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
484 return 0;
487 #ifdef WANT_OSPF_WRITE_FRAGMENT
488 static void
489 ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
490 struct msghdr *msg, unsigned int maxdatasize,
491 unsigned int mtu, int flags, u_char type)
493 #define OSPF_WRITE_FRAG_SHIFT 3
494 u_int16_t offset;
495 struct iovec *iovp;
496 int ret;
498 assert ( op->length == stream_get_endp(op->s) );
499 assert (msg->msg_iovlen == 2);
501 /* we can but try.
503 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
504 * well as the IP_MF flag, making this all quite pointless.
506 * However, for a system on which IP_MF is left alone, and ip_id left
507 * alone or else which sets same ip_id for each fragment this might
508 * work, eg linux.
510 * XXX-TODO: It would be much nicer to have the kernel's use their
511 * existing fragmentation support to do this for us. Bugs/RFEs need to
512 * be raised against the various kernels.
515 /* set More Frag */
516 iph->ip_off |= IP_MF;
518 /* ip frag offset is expressed in units of 8byte words */
519 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
521 iovp = &msg->msg_iov[1];
523 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
524 > maxdatasize )
526 /* data length of this frag is to next offset value */
527 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
528 iph->ip_len = iovp->iov_len + sizeof (struct ip);
529 assert (iph->ip_len <= mtu);
531 sockopt_iphdrincl_swab_htosys (iph);
533 ret = sendmsg (fd, msg, flags);
535 sockopt_iphdrincl_swab_systoh (iph);
537 if (ret < 0)
538 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
539 " id %d, off %d, len %d, mtu %u failed with %s",
540 inet_ntoa (iph->ip_dst),
541 iph->ip_id,
542 iph->ip_off,
543 iph->ip_len,
544 mtu,
545 safe_strerror (errno));
547 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
549 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
550 iph->ip_id, iph->ip_off, iph->ip_len,
551 inet_ntoa (iph->ip_dst));
552 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
554 zlog_debug ("-----------------IP Header Dump----------------------");
555 ospf_ip_header_dump (iph);
556 zlog_debug ("-----------------------------------------------------");
560 iph->ip_off += offset;
561 stream_forward_getp (op->s, iovp->iov_len);
562 iovp->iov_base = STREAM_PNT (op->s);
565 /* setup for final fragment */
566 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
567 iph->ip_len = iovp->iov_len + sizeof (struct ip);
568 iph->ip_off &= (~IP_MF);
570 #endif /* WANT_OSPF_WRITE_FRAGMENT */
572 static int
573 ospf_write (struct thread *thread)
575 struct ospf *ospf = THREAD_ARG (thread);
576 struct ospf_interface *oi;
577 struct ospf_packet *op;
578 struct sockaddr_in sa_dst;
579 struct ip iph;
580 struct msghdr msg;
581 struct iovec iov[2];
582 u_char type;
583 int ret;
584 int flags = 0;
585 struct listnode *node;
586 #ifdef WANT_OSPF_WRITE_FRAGMENT
587 static u_int16_t ipid = 0;
588 #endif /* WANT_OSPF_WRITE_FRAGMENT */
589 u_int16_t maxdatasize;
590 #define OSPF_WRITE_IPHL_SHIFT 2
592 ospf->t_write = NULL;
594 node = listhead (ospf->oi_write_q);
595 assert (node);
596 oi = listgetdata (node);
597 assert (oi);
599 #ifdef WANT_OSPF_WRITE_FRAGMENT
600 /* seed ipid static with low order bits of time */
601 if (ipid == 0)
602 ipid = (time(NULL) & 0xffff);
603 #endif /* WANT_OSPF_WRITE_FRAGMENT */
605 /* convenience - max OSPF data per packet,
606 * and reliability - not more data, than our
607 * socket can accept
609 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
610 sizeof (struct ip);
612 /* Get one packet from queue. */
613 op = ospf_fifo_head (oi->obuf);
614 assert (op);
615 assert (op->length >= OSPF_HEADER_SIZE);
617 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
618 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
619 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
621 /* Rewrite the md5 signature & update the seq */
622 ospf_make_md5_digest (oi, op);
624 /* Retrieve OSPF packet type. */
625 stream_set_getp (op->s, 1);
626 type = stream_getc (op->s);
628 /* reset get pointer */
629 stream_set_getp (op->s, 0);
631 memset (&iph, 0, sizeof (struct ip));
632 memset (&sa_dst, 0, sizeof (sa_dst));
634 sa_dst.sin_family = AF_INET;
635 #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
636 sa_dst.sin_len = sizeof(sa_dst);
637 #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
638 sa_dst.sin_addr = op->dst;
639 sa_dst.sin_port = htons (0);
641 /* Set DONTROUTE flag if dst is unicast. */
642 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
643 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
644 flags = MSG_DONTROUTE;
646 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
647 /* it'd be very strange for header to not be 4byte-word aligned but.. */
648 if ( sizeof (struct ip)
649 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
650 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
652 iph.ip_v = IPVERSION;
653 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
654 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
656 #ifdef WANT_OSPF_WRITE_FRAGMENT
657 /* XXX-MT: not thread-safe at all..
658 * XXX: this presumes this is only programme sending OSPF packets
659 * otherwise, no guarantee ipid will be unique
661 iph.ip_id = ++ipid;
662 #endif /* WANT_OSPF_WRITE_FRAGMENT */
664 iph.ip_off = 0;
665 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
666 iph.ip_ttl = OSPF_VL_IP_TTL;
667 else
668 iph.ip_ttl = OSPF_IP_TTL;
669 iph.ip_p = IPPROTO_OSPFIGP;
670 iph.ip_sum = 0;
671 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
672 iph.ip_dst.s_addr = op->dst.s_addr;
674 memset (&msg, 0, sizeof (msg));
675 msg.msg_name = (caddr_t) &sa_dst;
676 msg.msg_namelen = sizeof (sa_dst);
677 msg.msg_iov = iov;
678 msg.msg_iovlen = 2;
679 iov[0].iov_base = (char*)&iph;
680 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
681 iov[1].iov_base = STREAM_PNT (op->s);
682 iov[1].iov_len = op->length;
684 /* Sadly we can not rely on kernels to fragment packets because of either
685 * IP_HDRINCL and/or multicast destination being set.
687 #ifdef WANT_OSPF_WRITE_FRAGMENT
688 if ( op->length > maxdatasize )
689 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
690 oi->ifp->mtu, flags, type);
691 #endif /* WANT_OSPF_WRITE_FRAGMENT */
693 /* send final fragment (could be first) */
694 sockopt_iphdrincl_swab_htosys (&iph);
695 ret = sendmsg (ospf->fd, &msg, flags);
696 sockopt_iphdrincl_swab_systoh (&iph);
698 if (ret < 0)
699 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
700 "id %d, off %d, len %d, interface %s, mtu %u: %s",
701 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
702 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
704 /* Show debug sending packet. */
705 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
707 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
709 zlog_debug ("-----------------------------------------------------");
710 ospf_ip_header_dump (&iph);
711 stream_set_getp (op->s, 0);
712 ospf_packet_dump (op->s);
715 zlog_debug ("%s sent to [%s] via [%s].",
716 ospf_packet_type_str[type], inet_ntoa (op->dst),
717 IF_NAME (oi));
719 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
720 zlog_debug ("-----------------------------------------------------");
723 /* Now delete packet from queue. */
724 ospf_packet_delete (oi);
726 if (ospf_fifo_head (oi->obuf) == NULL)
728 oi->on_write_q = 0;
729 list_delete_node (ospf->oi_write_q, node);
732 /* If packets still remain in queue, call write thread. */
733 if (!list_isempty (ospf->oi_write_q))
734 ospf->t_write =
735 thread_add_write (master, ospf_write, ospf, ospf->fd);
737 return 0;
740 /* OSPF Hello message read -- RFC2328 Section 10.5. */
741 static void
742 ospf_hello (struct ip *iph, struct ospf_header *ospfh,
743 struct stream * s, struct ospf_interface *oi, int size)
745 struct ospf_hello *hello;
746 struct ospf_neighbor *nbr;
747 int old_state;
748 struct prefix p;
750 /* increment statistics. */
751 oi->hello_in++;
753 hello = (struct ospf_hello *) STREAM_PNT (s);
755 /* If Hello is myself, silently discard. */
756 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
758 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
760 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
761 "dropping.",
762 ospf_packet_type_str[ospfh->type],
763 inet_ntoa (iph->ip_src));
765 return;
768 /* If incoming interface is passive one, ignore Hello. */
769 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) {
770 char buf[3][INET_ADDRSTRLEN];
771 zlog_debug ("ignoring HELLO from router %s sent to %s, "
772 "received on a passive interface, %s",
773 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
774 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
775 inet_ntop(AF_INET, &oi->address->u.prefix4,
776 buf[2], sizeof(buf[2])));
777 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
779 /* Try to fix multicast membership. */
780 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
781 ospf_if_set_multicast(oi);
783 return;
786 /* get neighbor prefix. */
787 p.family = AF_INET;
788 p.prefixlen = ip_masklen (hello->network_mask);
789 p.u.prefix4 = iph->ip_src;
791 /* Compare network mask. */
792 /* Checking is ignored for Point-to-Point and Virtual link. */
793 if (oi->type != OSPF_IFTYPE_POINTOPOINT
794 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
795 if (oi->address->prefixlen != p.prefixlen)
797 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
798 inet_ntoa(ospfh->router_id), IF_NAME(oi),
799 (int)oi->address->prefixlen, (int)p.prefixlen);
800 return;
803 /* Compare Router Dead Interval. */
804 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
806 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
807 "(expected %u, but received %u).",
808 inet_ntoa(ospfh->router_id),
809 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
810 return;
813 /* Compare Hello Interval - ignored if fast-hellos are set. */
814 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
816 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
818 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
819 "(expected %u, but received %u).",
820 inet_ntoa(ospfh->router_id),
821 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
822 return;
826 if (IS_DEBUG_OSPF_EVENT)
827 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
828 inet_ntoa (ospfh->router_id),
829 ospf_options_dump (hello->options));
831 /* Compare options. */
832 #define REJECT_IF_TBIT_ON 1 /* XXX */
833 #ifdef REJECT_IF_TBIT_ON
834 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
837 * This router does not support non-zero TOS.
838 * Drop this Hello packet not to establish neighbor relationship.
840 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
841 inet_ntoa (ospfh->router_id));
842 return;
844 #endif /* REJECT_IF_TBIT_ON */
846 #ifdef HAVE_OPAQUE_LSA
847 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
848 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
851 * This router does know the correct usage of O-bit
852 * the bit should be set in DD packet only.
854 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
855 inet_ntoa (ospfh->router_id));
856 #ifdef STRICT_OBIT_USAGE_CHECK
857 return; /* Reject this packet. */
858 #else /* STRICT_OBIT_USAGE_CHECK */
859 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
860 #endif /* STRICT_OBIT_USAGE_CHECK */
862 #endif /* HAVE_OPAQUE_LSA */
864 /* new for NSSA is to ensure that NP is on and E is off */
866 if (oi->area->external_routing == OSPF_AREA_NSSA)
868 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
869 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
870 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
871 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
873 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
874 return;
876 if (IS_DEBUG_OSPF_NSSA)
877 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
879 else
880 /* The setting of the E-bit found in the Hello Packet's Options
881 field must match this area's ExternalRoutingCapability A
882 mismatch causes processing to stop and the packet to be
883 dropped. The setting of the rest of the bits in the Hello
884 Packet's Options field should be ignored. */
885 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
886 CHECK_FLAG (hello->options, OSPF_OPTION_E))
888 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
889 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
890 return;
893 /* get neighbour struct */
894 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
896 /* neighbour must be valid, ospf_nbr_get creates if none existed */
897 assert (nbr);
899 old_state = nbr->state;
901 /* Add event to thread. */
902 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
904 /* RFC2328 Section 9.5.1
905 If the router is not eligible to become Designated Router,
906 (snip) It must also send an Hello Packet in reply to an
907 Hello Packet received from any eligible neighbor (other than
908 the current Designated Router and Backup Designated Router). */
909 if (oi->type == OSPF_IFTYPE_NBMA)
910 if (PRIORITY(oi) == 0 && hello->priority > 0
911 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
912 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
913 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
914 OSPF_HELLO_REPLY_DELAY);
916 /* on NBMA network type, it happens to receive bidirectional Hello packet
917 without advance 1-Way Received event.
918 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
919 if (oi->type == OSPF_IFTYPE_NBMA &&
920 (old_state == NSM_Down || old_state == NSM_Attempt))
922 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
923 nbr->priority = hello->priority;
924 nbr->d_router = hello->d_router;
925 nbr->bd_router = hello->bd_router;
926 return;
929 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
930 size - OSPF_HELLO_MIN_SIZE))
932 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
933 nbr->options |= hello->options;
935 else
937 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
938 /* Set neighbor information. */
939 nbr->priority = hello->priority;
940 nbr->d_router = hello->d_router;
941 nbr->bd_router = hello->bd_router;
942 return;
945 /* If neighbor itself declares DR and no BDR exists,
946 cause event BackupSeen */
947 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
948 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
949 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
951 /* neighbor itself declares BDR. */
952 if (oi->state == ISM_Waiting &&
953 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
956 /* had not previously. */
957 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
958 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
959 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
960 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
961 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
963 /* had not previously. */
964 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
965 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
966 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
967 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
968 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
970 /* Neighbor priority check. */
971 if (nbr->priority >= 0 && nbr->priority != hello->priority)
972 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
974 /* Set neighbor information. */
975 nbr->priority = hello->priority;
976 nbr->d_router = hello->d_router;
977 nbr->bd_router = hello->bd_router;
980 /* Save DD flags/options/Seqnum received. */
981 static void
982 ospf_db_desc_save_current (struct ospf_neighbor *nbr,
983 struct ospf_db_desc *dd)
985 nbr->last_recv.flags = dd->flags;
986 nbr->last_recv.options = dd->options;
987 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
990 /* Process rest of DD packet. */
991 static void
992 ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
993 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
994 u_int16_t size)
996 struct ospf_lsa *new, *find;
997 struct lsa_header *lsah;
999 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
1000 for (size -= OSPF_DB_DESC_MIN_SIZE;
1001 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
1003 lsah = (struct lsa_header *) STREAM_PNT (s);
1004 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
1006 /* Unknown LS type. */
1007 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1009 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
1010 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1011 return;
1014 #ifdef HAVE_OPAQUE_LSA
1015 if (IS_OPAQUE_LSA (lsah->type)
1016 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1018 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1019 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1020 return;
1022 #endif /* HAVE_OPAQUE_LSA */
1024 switch (lsah->type)
1026 case OSPF_AS_EXTERNAL_LSA:
1027 #ifdef HAVE_OPAQUE_LSA
1028 case OSPF_OPAQUE_AS_LSA:
1029 #endif /* HAVE_OPAQUE_LSA */
1030 /* Check for stub area. Reject if AS-External from stub but
1031 allow if from NSSA. */
1032 if (oi->area->external_routing == OSPF_AREA_STUB)
1034 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1035 lsah->type, inet_ntoa (lsah->id),
1036 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1037 "STUB" : "NSSA");
1038 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1039 return;
1041 break;
1042 default:
1043 break;
1046 /* Create LS-request object. */
1047 new = ospf_ls_request_new (lsah);
1049 /* Lookup received LSA, then add LS request list. */
1050 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1052 /* ospf_lsa_more_recent is fine with NULL pointers */
1053 switch (ospf_lsa_more_recent (find, new))
1055 case -1:
1056 /* Neighbour has a more recent LSA, we must request it */
1057 ospf_ls_request_add (nbr, new);
1058 case 0:
1059 /* If we have a copy of this LSA, it's either less recent
1060 * and we're requesting it from neighbour (the case above), or
1061 * it's as recent and we both have same copy (this case).
1063 * In neither of these two cases is there any point in
1064 * describing our copy of the LSA to the neighbour in a
1065 * DB-Summary packet, if we're still intending to do so.
1067 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1068 * backward compatible optimisation to OSPF DB Exchange /
1069 * DB Description process implemented here.
1071 if (find)
1072 ospf_lsdb_delete (&nbr->db_sum, find);
1073 ospf_lsa_discard (new);
1074 break;
1075 default:
1076 /* We have the more recent copy, nothing specific to do:
1077 * - no need to request neighbours stale copy
1078 * - must leave DB summary list copy alone
1080 if (IS_DEBUG_OSPF_EVENT)
1081 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1082 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1083 ospf_lsa_discard (new);
1087 /* Master */
1088 if (IS_SET_DD_MS (nbr->dd_flags))
1090 nbr->dd_seqnum++;
1092 /* Both sides have no More, then we're done with Exchange */
1093 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1094 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1095 else
1096 ospf_db_desc_send (nbr);
1098 /* Slave */
1099 else
1101 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1103 /* Send DD packet in reply.
1105 * Must be done to acknowledge the Master's DD, regardless of
1106 * whether we have more LSAs ourselves to describe.
1108 * This function will clear the 'More' bit, if after this DD
1109 * we have no more LSAs to describe to the master..
1111 ospf_db_desc_send (nbr);
1113 /* Slave can raise ExchangeDone now, if master is also done */
1114 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1115 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1118 /* Save received neighbor values from DD. */
1119 ospf_db_desc_save_current (nbr, dd);
1122 static int
1123 ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1125 /* Is DD duplicated? */
1126 if (dd->options == nbr->last_recv.options &&
1127 dd->flags == nbr->last_recv.flags &&
1128 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1129 return 1;
1131 return 0;
1134 /* OSPF Database Description message read -- RFC2328 Section 10.6. */
1135 static void
1136 ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1137 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1139 struct ospf_db_desc *dd;
1140 struct ospf_neighbor *nbr;
1142 /* Increment statistics. */
1143 oi->db_desc_in++;
1145 dd = (struct ospf_db_desc *) STREAM_PNT (s);
1147 nbr = ospf_nbr_lookup (oi, iph, ospfh);
1148 if (nbr == NULL)
1150 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1151 inet_ntoa (ospfh->router_id));
1152 return;
1155 /* Check MTU. */
1156 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1157 (ntohs (dd->mtu) > oi->ifp->mtu))
1159 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1160 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1161 IF_NAME (oi), oi->ifp->mtu);
1162 return;
1166 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1167 * required. In fact at least JunOS sends DD packets with P bit clear.
1168 * Until proper solution is developped, this hack should help.
1170 * Update: According to the RFCs, N bit is specified /only/ for Hello
1171 * options, unfortunately its use in DD options is not specified. Hence some
1172 * implementations follow E-bit semantics and set it in DD options, and some
1173 * treat it as unspecified and hence follow the directive "default for
1174 * options is clear", ie unset.
1176 * Reset the flag, as ospfd follows E-bit semantics.
1178 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1179 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1180 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1182 if (IS_DEBUG_OSPF_EVENT)
1183 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
1184 inet_ntoa (nbr->router_id) );
1185 SET_FLAG (dd->options, OSPF_OPTION_NP);
1188 #ifdef REJECT_IF_TBIT_ON
1189 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1192 * In Hello protocol, optional capability must have checked
1193 * to prevent this T-bit enabled router be my neighbor.
1195 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1196 return;
1198 #endif /* REJECT_IF_TBIT_ON */
1200 #ifdef HAVE_OPAQUE_LSA
1201 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
1202 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
1205 * This node is not configured to handle O-bit, for now.
1206 * Clear it to ignore unsupported capability proposed by neighbor.
1208 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1210 #endif /* HAVE_OPAQUE_LSA */
1212 /* Process DD packet by neighbor status. */
1213 switch (nbr->state)
1215 case NSM_Down:
1216 case NSM_Attempt:
1217 case NSM_TwoWay:
1218 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
1219 inet_ntoa(nbr->router_id),
1220 LOOKUP (ospf_nsm_state_msg, nbr->state));
1221 break;
1222 case NSM_Init:
1223 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1224 /* If the new state is ExStart, the processing of the current
1225 packet should then continue in this new state by falling
1226 through to case ExStart below. */
1227 if (nbr->state != NSM_ExStart)
1228 break;
1229 case NSM_ExStart:
1230 /* Initial DBD */
1231 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1232 (size == OSPF_DB_DESC_MIN_SIZE))
1234 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
1236 /* We're Slave---obey */
1237 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
1238 inet_ntoa(nbr->router_id));
1239 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1241 /* Reset I/MS */
1242 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
1244 else
1246 /* We're Master, ignore the initial DBD from Slave */
1247 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1248 "ignoring.", inet_ntoa(nbr->router_id));
1249 break;
1252 /* Ack from the Slave */
1253 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1254 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
1255 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
1257 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
1258 inet_ntoa(nbr->router_id));
1259 /* Reset I, leaving MS */
1260 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
1262 else
1264 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1265 inet_ntoa(nbr->router_id));
1266 break;
1269 /* This is where the real Options are saved */
1270 nbr->options = dd->options;
1272 #ifdef HAVE_OPAQUE_LSA
1273 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
1275 if (IS_DEBUG_OSPF_EVENT)
1276 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
1277 inet_ntoa (nbr->router_id),
1278 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1280 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1281 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1283 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1284 "Opaque-LSAs cannot be reliably advertised "
1285 "in this network.",
1286 inet_ntoa (nbr->router_id));
1287 /* This situation is undesirable, but not a real error. */
1290 #endif /* HAVE_OPAQUE_LSA */
1292 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1294 /* continue processing rest of packet. */
1295 ospf_db_desc_proc (s, oi, nbr, dd, size);
1296 break;
1297 case NSM_Exchange:
1298 if (ospf_db_desc_is_dup (dd, nbr))
1300 if (IS_SET_DD_MS (nbr->dd_flags))
1301 /* Master: discard duplicated DD packet. */
1302 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1303 inet_ntoa (nbr->router_id));
1304 else
1305 /* Slave: cause to retransmit the last Database Description. */
1307 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1308 inet_ntoa (nbr->router_id));
1309 ospf_db_desc_resend (nbr);
1311 break;
1314 /* Otherwise DD packet should be checked. */
1315 /* Check Master/Slave bit mismatch */
1316 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1318 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1319 inet_ntoa(nbr->router_id));
1320 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1321 if (IS_DEBUG_OSPF_EVENT)
1322 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1323 dd->flags, nbr->dd_flags);
1324 break;
1327 /* Check initialize bit is set. */
1328 if (IS_SET_DD_I (dd->flags))
1330 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
1331 inet_ntoa(nbr->router_id));
1332 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1333 break;
1336 /* Check DD Options. */
1337 if (dd->options != nbr->options)
1339 #ifdef ORIGINAL_CODING
1340 /* Save the new options for debugging */
1341 nbr->options = dd->options;
1342 #endif /* ORIGINAL_CODING */
1343 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1344 inet_ntoa(nbr->router_id));
1345 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1346 break;
1349 /* Check DD sequence number. */
1350 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1351 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1352 (!IS_SET_DD_MS (nbr->dd_flags) &&
1353 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1355 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1356 inet_ntoa(nbr->router_id));
1357 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1358 break;
1361 /* Continue processing rest of packet. */
1362 ospf_db_desc_proc (s, oi, nbr, dd, size);
1363 break;
1364 case NSM_Loading:
1365 case NSM_Full:
1366 if (ospf_db_desc_is_dup (dd, nbr))
1368 if (IS_SET_DD_MS (nbr->dd_flags))
1370 /* Master should discard duplicate DD packet. */
1371 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1372 "packet discarded.",
1373 inet_ntoa(nbr->router_id));
1374 break;
1376 else
1378 struct timeval t, now;
1379 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1380 t = tv_sub (now, nbr->last_send_ts);
1381 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1383 /* In states Loading and Full the slave must resend
1384 its last Database Description packet in response to
1385 duplicate Database Description packets received
1386 from the master. For this reason the slave must
1387 wait RouterDeadInterval seconds before freeing the
1388 last Database Description packet. Reception of a
1389 Database Description packet from the master after
1390 this interval will generate a SeqNumberMismatch
1391 neighbor event. RFC2328 Section 10.8 */
1392 ospf_db_desc_resend (nbr);
1393 break;
1398 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1399 break;
1400 default:
1401 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1402 inet_ntoa(nbr->router_id), nbr->state);
1403 break;
1407 #define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1409 /* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1410 static void
1411 ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1412 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1414 struct ospf_neighbor *nbr;
1415 u_int32_t ls_type;
1416 struct in_addr ls_id;
1417 struct in_addr adv_router;
1418 struct ospf_lsa *find;
1419 struct list *ls_upd;
1420 unsigned int length;
1422 /* Increment statistics. */
1423 oi->ls_req_in++;
1425 nbr = ospf_nbr_lookup (oi, iph, ospfh);
1426 if (nbr == NULL)
1428 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1429 inet_ntoa (ospfh->router_id));
1430 return;
1433 /* Neighbor State should be Exchange or later. */
1434 if (nbr->state != NSM_Exchange &&
1435 nbr->state != NSM_Loading &&
1436 nbr->state != NSM_Full)
1438 zlog_warn ("Link State Request received from %s: "
1439 "Neighbor state is %s, packet discarded.",
1440 inet_ntoa (ospfh->router_id),
1441 LOOKUP (ospf_nsm_state_msg, nbr->state));
1442 return;
1445 /* Send Link State Update for ALL requested LSAs. */
1446 ls_upd = list_new ();
1447 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1449 while (size >= OSPF_LSA_KEY_SIZE)
1451 /* Get one slice of Link State Request. */
1452 ls_type = stream_getl (s);
1453 ls_id.s_addr = stream_get_ipv4 (s);
1454 adv_router.s_addr = stream_get_ipv4 (s);
1456 /* Verify LSA type. */
1457 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1459 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1460 list_delete (ls_upd);
1461 return;
1464 /* Search proper LSA in LSDB. */
1465 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1466 if (find == NULL)
1468 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1469 list_delete (ls_upd);
1470 return;
1473 /* Packet overflows MTU size, send immediately. */
1474 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
1476 if (oi->type == OSPF_IFTYPE_NBMA)
1477 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1478 else
1479 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1481 /* Only remove list contents. Keep ls_upd. */
1482 list_delete_all_node (ls_upd);
1484 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1487 /* Append LSA to update list. */
1488 listnode_add (ls_upd, find);
1489 length += ntohs (find->data->length);
1491 size -= OSPF_LSA_KEY_SIZE;
1494 /* Send rest of Link State Update. */
1495 if (listcount (ls_upd) > 0)
1497 if (oi->type == OSPF_IFTYPE_NBMA)
1498 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1499 else
1500 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1502 list_delete (ls_upd);
1504 else
1505 list_free (ls_upd);
1508 /* Get the list of LSAs from Link State Update packet.
1509 And process some validation -- RFC2328 Section 13. (1)-(2). */
1510 static struct list *
1511 ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1512 struct ospf_interface *oi, size_t size)
1514 u_int16_t count, sum;
1515 u_int32_t length;
1516 struct lsa_header *lsah;
1517 struct ospf_lsa *lsa;
1518 struct list *lsas;
1520 lsas = list_new ();
1522 count = stream_getl (s);
1523 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1525 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1526 size -= length, stream_forward_getp (s, length), count--)
1528 lsah = (struct lsa_header *) STREAM_PNT (s);
1529 length = ntohs (lsah->length);
1531 if (length > size)
1533 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1534 break;
1537 /* Validate the LSA's LS checksum. */
1538 sum = lsah->checksum;
1539 if (sum != ospf_lsa_checksum (lsah))
1541 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1542 sum, lsah->checksum);
1543 continue;
1546 /* Examine the LSA's LS type. */
1547 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1549 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1550 continue;
1554 * What if the received LSA's age is greater than MaxAge?
1555 * Treat it as a MaxAge case -- endo.
1557 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1558 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1560 #ifdef HAVE_OPAQUE_LSA
1561 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1563 #ifdef STRICT_OBIT_USAGE_CHECK
1564 if ((IS_OPAQUE_LSA(lsah->type) &&
1565 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1566 || (! IS_OPAQUE_LSA(lsah->type) &&
1567 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1570 * This neighbor must know the exact usage of O-bit;
1571 * the bit will be set in Type-9,10,11 LSAs only.
1573 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1574 continue;
1576 #endif /* STRICT_OBIT_USAGE_CHECK */
1578 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1579 if (lsah->type == OSPF_OPAQUE_AS_LSA
1580 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1582 if (IS_DEBUG_OSPF_EVENT)
1583 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1584 continue;
1587 else if (IS_OPAQUE_LSA(lsah->type))
1589 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1590 continue;
1592 #endif /* HAVE_OPAQUE_LSA */
1594 /* Create OSPF LSA instance. */
1595 lsa = ospf_lsa_new ();
1597 /* We may wish to put some error checking if type NSSA comes in
1598 and area not in NSSA mode */
1599 switch (lsah->type)
1601 case OSPF_AS_EXTERNAL_LSA:
1602 #ifdef HAVE_OPAQUE_LSA
1603 case OSPF_OPAQUE_AS_LSA:
1604 lsa->area = NULL;
1605 break;
1606 case OSPF_OPAQUE_LINK_LSA:
1607 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1608 /* Fallthrough */
1609 #endif /* HAVE_OPAQUE_LSA */
1610 default:
1611 lsa->area = oi->area;
1612 break;
1615 lsa->data = ospf_lsa_data_new (length);
1616 memcpy (lsa->data, lsah, length);
1618 if (IS_DEBUG_OSPF_EVENT)
1619 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1620 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1621 listnode_add (lsas, lsa);
1624 return lsas;
1627 /* Cleanup Update list. */
1628 static void
1629 ospf_upd_list_clean (struct list *lsas)
1631 struct listnode *node, *nnode;
1632 struct ospf_lsa *lsa;
1634 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1635 ospf_lsa_discard (lsa);
1637 list_delete (lsas);
1640 /* OSPF Link State Update message read -- RFC2328 Section 13. */
1641 static void
1642 ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1643 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1645 struct ospf_neighbor *nbr;
1646 struct list *lsas;
1647 struct listnode *node, *nnode;
1648 struct ospf_lsa *lsa = NULL;
1649 /* unsigned long ls_req_found = 0; */
1651 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1653 /* Increment statistics. */
1654 oi->ls_upd_in++;
1656 /* Check neighbor. */
1657 nbr = ospf_nbr_lookup (oi, iph, ospfh);
1658 if (nbr == NULL)
1660 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1661 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1662 return;
1665 /* Check neighbor state. */
1666 if (nbr->state < NSM_Exchange)
1668 zlog_warn ("Link State Update: "
1669 "Neighbor[%s] state %s is less than Exchange",
1670 inet_ntoa (ospfh->router_id),
1671 LOOKUP(ospf_nsm_state_msg, nbr->state));
1672 return;
1675 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1676 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1677 * of section 13.
1679 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1681 #ifdef HAVE_OPAQUE_LSA
1683 * If self-originated Opaque-LSAs that have flooded before restart
1684 * are contained in the received LSUpd message, corresponding LSReq
1685 * messages to be sent may have to be modified.
1686 * To eliminate possible race conditions such that flushing and normal
1687 * updating for the same LSA would take place alternately, this trick
1688 * must be done before entering to the loop below.
1690 /* XXX: Why is this Opaque specific? Either our core code is deficient
1691 * and this should be fixed generally, or Opaque is inventing strawman
1692 * problems */
1693 ospf_opaque_adjust_lsreq (nbr, lsas);
1694 #endif /* HAVE_OPAQUE_LSA */
1696 #define DISCARD_LSA(L,N) {\
1697 if (IS_DEBUG_OSPF_EVENT) \
1698 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1699 ospf_lsa_discard (L); \
1700 continue; }
1702 /* Process each LSA received in the one packet. */
1703 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1705 struct ospf_lsa *ls_ret, *current;
1706 int ret = 1;
1708 if (IS_DEBUG_OSPF_NSSA)
1710 char buf1[INET_ADDRSTRLEN];
1711 char buf2[INET_ADDRSTRLEN];
1712 char buf3[INET_ADDRSTRLEN];
1714 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
1715 lsa->data->type,
1716 inet_ntop (AF_INET, &ospfh->router_id,
1717 buf1, INET_ADDRSTRLEN),
1718 inet_ntop (AF_INET, &lsa->data->id,
1719 buf2, INET_ADDRSTRLEN),
1720 inet_ntop (AF_INET, &lsa->data->adv_router,
1721 buf3, INET_ADDRSTRLEN));
1724 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1726 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1728 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1730 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1732 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1734 /* Do take in Type-7's if we are an NSSA */
1736 /* If we are also an ABR, later translate them to a Type-5 packet */
1738 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1739 translate them to a separate Type-5 packet. */
1741 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1742 /* Reject from STUB or NSSA */
1743 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1745 DISCARD_LSA (lsa, 1);
1746 if (IS_DEBUG_OSPF_NSSA)
1747 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
1750 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1751 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1753 DISCARD_LSA (lsa,2);
1754 if (IS_DEBUG_OSPF_NSSA)
1755 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
1758 /* Find the LSA in the current database. */
1760 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1762 /* If the LSA's LS age is equal to MaxAge, and there is currently
1763 no instance of the LSA in the router's link state database,
1764 and none of router's neighbors are in states Exchange or Loading,
1765 then take the following actions. */
1767 if (IS_LSA_MAXAGE (lsa) && !current &&
1768 (ospf_nbr_count (oi, NSM_Exchange) +
1769 ospf_nbr_count (oi, NSM_Loading)) == 0)
1771 /* Response Link State Acknowledgment. */
1772 ospf_ls_ack_send (nbr, lsa);
1774 /* Discard LSA. */
1775 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1776 dump_lsa_key(lsa));
1777 DISCARD_LSA (lsa, 3);
1780 #ifdef HAVE_OPAQUE_LSA
1781 if (IS_OPAQUE_LSA (lsa->data->type)
1782 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
1785 * Even if initial flushing seems to be completed, there might
1786 * be a case that self-originated LSA with MaxAge still remain
1787 * in the routing domain.
1788 * Just send an LSAck message to cease retransmission.
1790 if (IS_LSA_MAXAGE (lsa))
1792 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1793 ospf_ls_ack_send (nbr, lsa);
1794 ospf_lsa_discard (lsa);
1796 if (current != NULL && ! IS_LSA_MAXAGE (current))
1797 ospf_opaque_lsa_refresh_schedule (current);
1798 continue;
1802 * If an instance of self-originated Opaque-LSA is not found
1803 * in the LSDB, there are some possible cases here.
1805 * 1) This node lost opaque-capability after restart.
1806 * 2) Else, a part of opaque-type is no more supported.
1807 * 3) Else, a part of opaque-id is no more supported.
1809 * Anyway, it is still this node's responsibility to flush it.
1810 * Otherwise, the LSA instance remains in the routing domain
1811 * until its age reaches to MaxAge.
1813 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
1814 if (current == NULL)
1816 if (IS_DEBUG_OSPF_EVENT)
1817 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1818 "not found in the LSDB.", dump_lsa_key (lsa));
1820 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1822 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1823 ospf_ls_ack_send (nbr, lsa);
1825 continue;
1828 #endif /* HAVE_OPAQUE_LSA */
1830 /* It might be happen that received LSA is self-originated network LSA, but
1831 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1832 * Link State ID is one of the router's own IP interface addresses but whose
1833 * Advertising Router is not equal to the router's own Router ID
1834 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1837 if(lsa->data->type == OSPF_NETWORK_LSA)
1839 struct listnode *oinode, *oinnode;
1840 struct ospf_interface *out_if;
1841 int Flag = 0;
1843 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
1845 if(out_if == NULL)
1846 break;
1848 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1849 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1851 if(out_if->network_lsa_self)
1853 ospf_lsa_flush_area(lsa,out_if->area);
1854 if(IS_DEBUG_OSPF_EVENT)
1855 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
1856 lsa, (int) lsa->data->type);
1857 ospf_lsa_discard (lsa);
1858 Flag = 1;
1860 break;
1863 if(Flag)
1864 continue;
1867 /* (5) Find the instance of this LSA that is currently contained
1868 in the router's link state database. If there is no
1869 database copy, or the received LSA is more recent than
1870 the database copy the following steps must be performed. */
1872 if (current == NULL ||
1873 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1875 /* Actual flooding procedure. */
1876 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
1877 DISCARD_LSA (lsa, 4);
1878 continue;
1881 /* (6) Else, If there is an instance of the LSA on the sending
1882 neighbor's Link state request list, an error has occurred in
1883 the Database Exchange process. In this case, restart the
1884 Database Exchange process by generating the neighbor event
1885 BadLSReq for the sending neighbor and stop processing the
1886 Link State Update packet. */
1888 if (ospf_ls_request_lookup (nbr, lsa))
1890 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1891 zlog_warn("LSA[%s] instance exists on Link state request list",
1892 dump_lsa_key(lsa));
1894 /* Clean list of LSAs. */
1895 ospf_upd_list_clean (lsas);
1896 /* this lsa is not on lsas list already. */
1897 ospf_lsa_discard (lsa);
1898 return;
1901 /* If the received LSA is the same instance as the database copy
1902 (i.e., neither one is more recent) the following two steps
1903 should be performed: */
1905 if (ret == 0)
1907 /* If the LSA is listed in the Link state retransmission list
1908 for the receiving adjacency, the router itself is expecting
1909 an acknowledgment for this LSA. The router should treat the
1910 received LSA as an acknowledgment by removing the LSA from
1911 the Link state retransmission list. This is termed an
1912 "implied acknowledgment". */
1914 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1916 if (ls_ret != NULL)
1918 ospf_ls_retransmit_delete (nbr, ls_ret);
1920 /* Delayed acknowledgment sent if advertisement received
1921 from Designated Router, otherwise do nothing. */
1922 if (oi->state == ISM_Backup)
1923 if (NBR_IS_DR (nbr))
1924 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1926 DISCARD_LSA (lsa, 5);
1928 else
1929 /* Acknowledge the receipt of the LSA by sending a
1930 Link State Acknowledgment packet back out the receiving
1931 interface. */
1933 ospf_ls_ack_send (nbr, lsa);
1934 DISCARD_LSA (lsa, 6);
1938 /* The database copy is more recent. If the database copy
1939 has LS age equal to MaxAge and LS sequence number equal to
1940 MaxSequenceNumber, simply discard the received LSA without
1941 acknowledging it. (In this case, the LSA's LS sequence number is
1942 wrapping, and the MaxSequenceNumber LSA must be completely
1943 flushed before any new LSA instance can be introduced). */
1945 else if (ret > 0) /* Database copy is more recent */
1947 if (IS_LSA_MAXAGE (current) &&
1948 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1950 DISCARD_LSA (lsa, 7);
1952 /* Otherwise, as long as the database copy has not been sent in a
1953 Link State Update within the last MinLSArrival seconds, send the
1954 database copy back to the sending neighbor, encapsulated within
1955 a Link State Update Packet. The Link State Update Packet should
1956 be sent directly to the neighbor. In so doing, do not put the
1957 database copy of the LSA on the neighbor's link state
1958 retransmission list, and do not acknowledge the received (less
1959 recent) LSA instance. */
1960 else
1962 struct timeval now;
1964 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
1966 if (tv_cmp (tv_sub (now, current->tv_orig),
1967 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1968 /* Trap NSSA type later.*/
1969 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1970 DISCARD_LSA (lsa, 8);
1975 assert (listcount (lsas) == 0);
1976 list_delete (lsas);
1979 /* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1980 static void
1981 ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1982 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1984 struct ospf_neighbor *nbr;
1986 /* increment statistics. */
1987 oi->ls_ack_in++;
1989 nbr = ospf_nbr_lookup (oi, iph, ospfh);
1990 if (nbr == NULL)
1992 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1993 inet_ntoa (ospfh->router_id));
1994 return;
1997 if (nbr->state < NSM_Exchange)
1999 zlog_warn ("Link State Acknowledgment: "
2000 "Neighbor[%s] state %s is less than Exchange",
2001 inet_ntoa (ospfh->router_id),
2002 LOOKUP(ospf_nsm_state_msg, nbr->state));
2003 return;
2006 while (size >= OSPF_LSA_HEADER_SIZE)
2008 struct ospf_lsa *lsa, *lsr;
2010 lsa = ospf_lsa_new ();
2011 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2013 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2014 size -= OSPF_LSA_HEADER_SIZE;
2015 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
2017 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2019 lsa->data = NULL;
2020 ospf_lsa_discard (lsa);
2021 continue;
2024 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2026 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2028 #ifdef HAVE_OPAQUE_LSA
2029 if (IS_OPAQUE_LSA (lsr->data->type))
2030 ospf_opaque_ls_ack_received (nbr, lsr);
2031 #endif /* HAVE_OPAQUE_LSA */
2033 ospf_ls_retransmit_delete (nbr, lsr);
2036 lsa->data = NULL;
2037 ospf_lsa_discard (lsa);
2040 return;
2043 static struct stream *
2044 ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
2046 int ret;
2047 struct ip *iph;
2048 u_int16_t ip_len;
2049 unsigned int ifindex = 0;
2050 struct iovec iov;
2051 /* Header and data both require alignment. */
2052 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
2053 struct msghdr msgh;
2055 memset (&msgh, 0, sizeof (struct msghdr));
2056 msgh.msg_iov = &iov;
2057 msgh.msg_iovlen = 1;
2058 msgh.msg_control = (caddr_t) buff;
2059 msgh.msg_controllen = sizeof (buff);
2061 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2062 if (ret < 0)
2064 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2065 return NULL;
2067 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
2069 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2070 "(ip header size is %u)",
2071 ret, (u_int)sizeof(iph));
2072 return NULL;
2075 /* Note that there should not be alignment problems with this assignment
2076 because this is at the beginning of the stream data buffer. */
2077 iph = (struct ip *) STREAM_DATA(ibuf);
2078 sockopt_iphdrincl_swab_systoh (iph);
2080 ip_len = iph->ip_len;
2082 #if !defined(GNU_LINUX) && (OpenBSD < 200311)
2084 * Kernel network code touches incoming IP header parameters,
2085 * before protocol specific processing.
2087 * 1) Convert byteorder to host representation.
2088 * --> ip_len, ip_id, ip_off
2090 * 2) Adjust ip_len to strip IP header size!
2091 * --> If user process receives entire IP packet via RAW
2092 * socket, it must consider adding IP header size to
2093 * the "ip_len" field of "ip" structure.
2095 * For more details, see <netinet/ip_input.c>.
2097 ip_len = ip_len + (iph->ip_hl << 2);
2098 #endif
2100 ifindex = getsockopt_ifindex (AF_INET, &msgh);
2102 *ifp = if_lookup_by_index (ifindex);
2104 if (ret != ip_len)
2106 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2107 "but recvmsg returned %d", ip_len, ret);
2108 return NULL;
2111 return ibuf;
2114 static struct ospf_interface *
2115 ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
2116 struct ip *iph, struct ospf_header *ospfh)
2118 struct ospf_interface *rcv_oi;
2119 struct ospf_vl_data *vl_data;
2120 struct ospf_area *vl_area;
2121 struct listnode *node;
2123 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2124 !OSPF_IS_AREA_BACKBONE (ospfh))
2125 return NULL;
2127 /* look for local OSPF interface matching the destination
2128 * to determine Area ID. We presume therefore the destination address
2129 * is unique, or at least (for "unnumbered" links), not used in other
2130 * areas
2132 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2133 iph->ip_dst)) == NULL)
2134 return NULL;
2136 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
2138 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
2139 if (!vl_area)
2140 continue;
2142 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2143 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2145 if (IS_DEBUG_OSPF_EVENT)
2146 zlog_debug ("associating packet with %s",
2147 IF_NAME (vl_data->vl_oi));
2148 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2150 if (IS_DEBUG_OSPF_EVENT)
2151 zlog_debug ("This VL is not up yet, sorry");
2152 return NULL;
2155 return vl_data->vl_oi;
2159 if (IS_DEBUG_OSPF_EVENT)
2160 zlog_debug ("couldn't find any VL to associate the packet with");
2162 return NULL;
2165 static inline int
2166 ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2168 /* Check match the Area ID of the receiving interface. */
2169 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2170 return 1;
2172 return 0;
2175 /* Unbound socket will accept any Raw IP packets if proto is matched.
2176 To prevent it, compare src IP address and i/f address with masking
2177 i/f network mask. */
2178 static int
2179 ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2181 struct in_addr mask, me, him;
2183 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2184 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2185 return 1;
2187 masklen2ip (oi->address->prefixlen, &mask);
2189 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2190 him.s_addr = ip_src.s_addr & mask.s_addr;
2192 if (IPV4_ADDR_SAME (&me, &him))
2193 return 1;
2195 return 0;
2198 static int
2199 ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2200 struct ospf_header *ospfh)
2202 int ret = 0;
2203 struct crypt_key *ck;
2205 switch (ntohs (ospfh->auth_type))
2207 case OSPF_AUTH_NULL:
2208 ret = 1;
2209 break;
2210 case OSPF_AUTH_SIMPLE:
2211 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2212 ret = 1;
2213 else
2214 ret = 0;
2215 break;
2216 case OSPF_AUTH_CRYPTOGRAPHIC:
2217 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
2219 ret = 0;
2220 break;
2223 /* This is very basic, the digest processing is elsewhere */
2224 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2225 ospfh->u.crypt.key_id == ck->key_id &&
2226 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2227 ret = 1;
2228 else
2229 ret = 0;
2230 break;
2231 default:
2232 ret = 0;
2233 break;
2236 return ret;
2239 static int
2240 ospf_check_sum (struct ospf_header *ospfh)
2242 u_int32_t ret;
2243 u_int16_t sum;
2245 /* clear auth_data for checksum. */
2246 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2248 /* keep checksum and clear. */
2249 sum = ospfh->checksum;
2250 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2252 /* calculate checksum. */
2253 ret = in_cksum (ospfh, ntohs (ospfh->length));
2255 if (ret != sum)
2257 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2258 ret, sum);
2259 return 0;
2262 return 1;
2265 /* OSPF Header verification. */
2266 static int
2267 ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2268 struct ip *iph, struct ospf_header *ospfh)
2270 /* check version. */
2271 if (ospfh->version != OSPF_VERSION)
2273 zlog_warn ("interface %s: ospf_read version number mismatch.",
2274 IF_NAME (oi));
2275 return -1;
2278 /* Check Area ID. */
2279 if (!ospf_check_area_id (oi, ospfh))
2281 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2282 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2283 return -1;
2286 /* Check network mask, Silently discarded. */
2287 if (! ospf_check_network_mask (oi, iph->ip_src))
2289 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2290 IF_NAME (oi), inet_ntoa (iph->ip_src));
2291 return -1;
2294 /* Check authentication. */
2295 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2297 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2298 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
2299 return -1;
2302 if (! ospf_check_auth (oi, ibuf, ospfh))
2304 zlog_warn ("interface %s: ospf_read authentication failed.",
2305 IF_NAME (oi));
2306 return -1;
2309 /* if check sum is invalid, packet is discarded. */
2310 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2312 if (! ospf_check_sum (ospfh))
2314 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2315 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2316 return -1;
2319 else
2321 if (ospfh->checksum != 0)
2322 return -1;
2323 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2325 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2326 IF_NAME (oi));
2327 return -1;
2331 return 0;
2334 /* Starting point of packet process function. */
2336 ospf_read (struct thread *thread)
2338 int ret;
2339 struct stream *ibuf;
2340 struct ospf *ospf;
2341 struct ospf_interface *oi;
2342 struct ip *iph;
2343 struct ospf_header *ospfh;
2344 u_int16_t length;
2345 struct interface *ifp;
2347 /* first of all get interface pointer. */
2348 ospf = THREAD_ARG (thread);
2350 /* prepare for next packet. */
2351 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
2353 /* read OSPF packet. */
2354 stream_reset(ospf->ibuf);
2355 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
2356 return -1;
2358 /* Note that there should not be alignment problems with this assignment
2359 because this is at the beginning of the stream data buffer. */
2360 iph = (struct ip *) STREAM_DATA (ibuf);
2361 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
2363 if (ifp == NULL)
2364 /* Handle cases where the platform does not support retrieving the ifindex,
2365 and also platforms (such as Solaris 8) that claim to support ifindex
2366 retrieval but do not. */
2367 ifp = if_lookup_address (iph->ip_src);
2369 if (ifp == NULL)
2370 return 0;
2372 /* IP Header dump. */
2373 if (IS_DEBUG_OSPF_PACKET(0, RECV))
2374 ospf_ip_header_dump (iph);
2376 /* Self-originated packet should be discarded silently. */
2377 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
2379 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2381 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
2382 inet_ntoa (iph->ip_src));
2384 return 0;
2387 /* Adjust size to message length. */
2388 stream_forward_getp (ibuf, iph->ip_hl * 4);
2390 /* Get ospf packet header. */
2391 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2393 /* associate packet with ospf interface */
2394 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
2396 /* if no local ospf_interface,
2397 * or header area is backbone but ospf_interface is not
2398 * check for VLINK interface
2400 if ( (oi == NULL) ||
2401 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2402 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2405 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2407 if (IS_DEBUG_OSPF_EVENT)
2408 zlog_debug ("Packet from [%s] received on link %s"
2409 " but no ospf_interface",
2410 inet_ntoa (iph->ip_src), ifp->name);
2411 return 0;
2415 /* else it must be a local ospf interface, check it was received on
2416 * correct link
2418 else if (oi->ifp != ifp)
2420 zlog_warn ("Packet from [%s] received on wrong link %s",
2421 inet_ntoa (iph->ip_src), ifp->name);
2422 return 0;
2424 else if (oi->state == ISM_Down)
2426 char buf[2][INET_ADDRSTRLEN];
2427 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
2428 "down [%s]; interface flags are %s",
2429 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2430 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2431 ifp->name, if_flag_dump(ifp->flags));
2432 /* Fix multicast memberships? */
2433 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2434 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2435 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2436 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
2437 if (oi->multicast_memberships)
2438 ospf_if_set_multicast(oi);
2439 return 0;
2443 * If the received packet is destined for AllDRouters, the packet
2444 * should be accepted only if the received ospf interface state is
2445 * either DR or Backup -- endo.
2447 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2448 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2450 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2451 inet_ntoa (iph->ip_src), IF_NAME (oi),
2452 LOOKUP (ospf_ism_state_msg, oi->state));
2453 /* Try to fix multicast membership. */
2454 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2455 ospf_if_set_multicast(oi);
2456 return 0;
2459 /* Show debug receiving packet. */
2460 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2462 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2464 zlog_debug ("-----------------------------------------------------");
2465 ospf_packet_dump (ibuf);
2468 zlog_debug ("%s received from [%s] via [%s]",
2469 ospf_packet_type_str[ospfh->type],
2470 inet_ntoa (ospfh->router_id), IF_NAME (oi));
2471 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2472 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
2474 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2475 zlog_debug ("-----------------------------------------------------");
2478 /* Some header verification. */
2479 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2480 if (ret < 0)
2482 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2484 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
2485 "dropping.",
2486 ospf_packet_type_str[ospfh->type],
2487 inet_ntoa (iph->ip_src));
2489 return ret;
2492 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
2494 /* Adjust size to message length. */
2495 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2497 /* Read rest of the packet and call each sort of packet routine. */
2498 switch (ospfh->type)
2500 case OSPF_MSG_HELLO:
2501 ospf_hello (iph, ospfh, ibuf, oi, length);
2502 break;
2503 case OSPF_MSG_DB_DESC:
2504 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2505 break;
2506 case OSPF_MSG_LS_REQ:
2507 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2508 break;
2509 case OSPF_MSG_LS_UPD:
2510 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2511 break;
2512 case OSPF_MSG_LS_ACK:
2513 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2514 break;
2515 default:
2516 zlog (NULL, LOG_WARNING,
2517 "interface %s: OSPF packet header type %d is illegal",
2518 IF_NAME (oi), ospfh->type);
2519 break;
2522 return 0;
2525 /* Make OSPF header. */
2526 static void
2527 ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2529 struct ospf_header *ospfh;
2531 ospfh = (struct ospf_header *) STREAM_DATA (s);
2533 ospfh->version = (u_char) OSPF_VERSION;
2534 ospfh->type = (u_char) type;
2536 ospfh->router_id = oi->ospf->router_id;
2538 ospfh->checksum = 0;
2539 ospfh->area_id = oi->area->area_id;
2540 ospfh->auth_type = htons (ospf_auth_type (oi));
2542 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2544 stream_forward_endp (s, OSPF_HEADER_SIZE);
2547 /* Make Authentication Data. */
2548 static int
2549 ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2551 struct crypt_key *ck;
2553 switch (ospf_auth_type (oi))
2555 case OSPF_AUTH_NULL:
2556 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2557 break;
2558 case OSPF_AUTH_SIMPLE:
2559 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2560 OSPF_AUTH_SIMPLE_SIZE);
2561 break;
2562 case OSPF_AUTH_CRYPTOGRAPHIC:
2563 /* If key is not set, then set 0. */
2564 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2566 ospfh->u.crypt.zero = 0;
2567 ospfh->u.crypt.key_id = 0;
2568 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2570 else
2572 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
2573 ospfh->u.crypt.zero = 0;
2574 ospfh->u.crypt.key_id = ck->key_id;
2575 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2577 /* note: the seq is done in ospf_make_md5_digest() */
2578 break;
2579 default:
2580 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2581 break;
2584 return 0;
2587 /* Fill rest of OSPF header. */
2588 static void
2589 ospf_fill_header (struct ospf_interface *oi,
2590 struct stream *s, u_int16_t length)
2592 struct ospf_header *ospfh;
2594 ospfh = (struct ospf_header *) STREAM_DATA (s);
2596 /* Fill length. */
2597 ospfh->length = htons (length);
2599 /* Calculate checksum. */
2600 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2601 ospfh->checksum = in_cksum (ospfh, length);
2602 else
2603 ospfh->checksum = 0;
2605 /* Add Authentication Data. */
2606 ospf_make_auth (oi, ospfh);
2609 static int
2610 ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2612 struct ospf_neighbor *nbr;
2613 struct route_node *rn;
2614 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2615 struct in_addr mask;
2616 unsigned long p;
2617 int flag = 0;
2619 /* Set netmask of interface. */
2620 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2621 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2622 masklen2ip (oi->address->prefixlen, &mask);
2623 else
2624 memset ((char *) &mask, 0, sizeof (struct in_addr));
2625 stream_put_ipv4 (s, mask.s_addr);
2627 /* Set Hello Interval. */
2628 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2629 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2630 else
2631 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
2633 if (IS_DEBUG_OSPF_EVENT)
2634 zlog_debug ("make_hello: options: %x, int: %s",
2635 OPTIONS(oi), IF_NAME (oi));
2637 /* Set Options. */
2638 stream_putc (s, OPTIONS (oi));
2640 /* Set Router Priority. */
2641 stream_putc (s, PRIORITY (oi));
2643 /* Set Router Dead Interval. */
2644 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2646 /* Set Designated Router. */
2647 stream_put_ipv4 (s, DR (oi).s_addr);
2649 p = stream_get_endp (s);
2651 /* Set Backup Designated Router. */
2652 stream_put_ipv4 (s, BDR (oi).s_addr);
2654 /* Add neighbor seen. */
2655 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2656 if ((nbr = rn->info))
2657 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2658 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2659 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2660 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
2662 /* Check neighbor is sane? */
2663 if (nbr->d_router.s_addr != 0
2664 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2665 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2666 flag = 1;
2668 stream_put_ipv4 (s, nbr->router_id.s_addr);
2669 length += 4;
2672 /* Let neighbor generate BackupSeen. */
2673 if (flag == 1)
2674 stream_putl_at (s, p, 0); /* ipv4 address, normally */
2676 return length;
2679 static int
2680 ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2681 struct stream *s)
2683 struct ospf_lsa *lsa;
2684 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2685 u_char options;
2686 unsigned long pp;
2687 int i;
2688 struct ospf_lsdb *lsdb;
2690 /* Set Interface MTU. */
2691 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2692 stream_putw (s, 0);
2693 else
2694 stream_putw (s, oi->ifp->mtu);
2696 /* Set Options. */
2697 options = OPTIONS (oi);
2698 #ifdef HAVE_OPAQUE_LSA
2699 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
2701 if (IS_SET_DD_I (nbr->dd_flags)
2702 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2704 * Set O-bit in the outgoing DD packet for capablity negotiation,
2705 * if one of following case is applicable.
2707 * 1) WaitTimer expiration event triggered the neighbor state to
2708 * change to Exstart, but no (valid) DD packet has received
2709 * from the neighbor yet.
2711 * 2) At least one DD packet with O-bit on has received from the
2712 * neighbor.
2714 SET_FLAG (options, OSPF_OPTION_O);
2716 #endif /* HAVE_OPAQUE_LSA */
2717 stream_putc (s, options);
2719 /* DD flags */
2720 pp = stream_get_endp (s);
2721 stream_putc (s, nbr->dd_flags);
2723 /* Set DD Sequence Number. */
2724 stream_putl (s, nbr->dd_seqnum);
2726 /* shortcut unneeded walk of (empty) summary LSDBs */
2727 if (ospf_db_summary_isempty (nbr))
2728 goto empty;
2730 /* Describe LSA Header from Database Summary List. */
2731 lsdb = &nbr->db_sum;
2733 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2735 struct route_table *table = lsdb->type[i].db;
2736 struct route_node *rn;
2738 for (rn = route_top (table); rn; rn = route_next (rn))
2739 if ((lsa = rn->info) != NULL)
2741 #ifdef HAVE_OPAQUE_LSA
2742 if (IS_OPAQUE_LSA (lsa->data->type)
2743 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2745 /* Suppress advertising opaque-informations. */
2746 /* Remove LSA from DB summary list. */
2747 ospf_lsdb_delete (lsdb, lsa);
2748 continue;
2750 #endif /* HAVE_OPAQUE_LSA */
2752 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2754 struct lsa_header *lsah;
2755 u_int16_t ls_age;
2757 /* DD packet overflows interface MTU. */
2758 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
2759 break;
2761 /* Keep pointer to LS age. */
2762 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2763 stream_get_endp (s));
2765 /* Proceed stream pointer. */
2766 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2767 length += OSPF_LSA_HEADER_SIZE;
2769 /* Set LS age. */
2770 ls_age = LS_AGE (lsa);
2771 lsah->ls_age = htons (ls_age);
2775 /* Remove LSA from DB summary list. */
2776 ospf_lsdb_delete (lsdb, lsa);
2780 /* Update 'More' bit */
2781 if (ospf_db_summary_isempty (nbr))
2783 empty:
2784 if (nbr->state >= NSM_Exchange)
2786 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2787 /* Rewrite DD flags */
2788 stream_putc_at (s, pp, nbr->dd_flags);
2790 else
2792 assert (IS_SET_DD_M(nbr->dd_flags));
2795 return length;
2798 static int
2799 ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2800 unsigned long delta, struct ospf_neighbor *nbr,
2801 struct ospf_lsa *lsa)
2803 struct ospf_interface *oi;
2805 oi = nbr->oi;
2807 /* LS Request packet overflows interface MTU. */
2808 if (*length + delta > ospf_packet_max(oi))
2809 return 0;
2811 stream_putl (s, lsa->data->type);
2812 stream_put_ipv4 (s, lsa->data->id.s_addr);
2813 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2815 ospf_lsa_unlock (&nbr->ls_req_last);
2816 nbr->ls_req_last = ospf_lsa_lock (lsa);
2818 *length += 12;
2819 return 1;
2822 static int
2823 ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2825 struct ospf_lsa *lsa;
2826 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2827 unsigned long delta = stream_get_endp(s)+12;
2828 struct route_table *table;
2829 struct route_node *rn;
2830 int i;
2831 struct ospf_lsdb *lsdb;
2833 lsdb = &nbr->ls_req;
2835 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2837 table = lsdb->type[i].db;
2838 for (rn = route_top (table); rn; rn = route_next (rn))
2839 if ((lsa = (rn->info)) != NULL)
2840 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2842 route_unlock_node (rn);
2843 break;
2846 return length;
2849 static int
2850 ls_age_increment (struct ospf_lsa *lsa, int delay)
2852 int age;
2854 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2856 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2859 static int
2860 ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
2862 struct ospf_lsa *lsa;
2863 struct listnode *node;
2864 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2865 unsigned int size_noauth;
2866 unsigned long delta = stream_get_endp (s);
2867 unsigned long pp;
2868 int count = 0;
2870 if (IS_DEBUG_OSPF_EVENT)
2871 zlog_debug ("ospf_make_ls_upd: Start");
2873 pp = stream_get_endp (s);
2874 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
2876 /* Calculate amount of packet usable for data. */
2877 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2879 while ((node = listhead (update)) != NULL)
2881 struct lsa_header *lsah;
2882 u_int16_t ls_age;
2884 if (IS_DEBUG_OSPF_EVENT)
2885 zlog_debug ("ospf_make_ls_upd: List Iteration");
2887 lsa = listgetdata (node);
2889 assert (lsa->data);
2891 /* Will it fit? */
2892 if (length + delta + ntohs (lsa->data->length) > size_noauth)
2893 break;
2895 /* Keep pointer to LS age. */
2896 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
2898 /* Put LSA to Link State Request. */
2899 stream_put (s, lsa->data, ntohs (lsa->data->length));
2901 /* Set LS age. */
2902 /* each hop must increment an lsa_age by transmit_delay
2903 of OSPF interface */
2904 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2905 lsah->ls_age = htons (ls_age);
2907 length += ntohs (lsa->data->length);
2908 count++;
2910 list_delete_node (update, node);
2911 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
2914 /* Now set #LSAs. */
2915 stream_putl_at (s, pp, count);
2917 if (IS_DEBUG_OSPF_EVENT)
2918 zlog_debug ("ospf_make_ls_upd: Stop");
2919 return length;
2922 static int
2923 ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
2925 struct listnode *node, *nnode;
2926 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2927 unsigned long delta = stream_get_endp(s) + 24;
2928 struct ospf_lsa *lsa;
2930 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
2932 assert (lsa);
2934 if (length + delta > ospf_packet_max (oi))
2935 break;
2937 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2938 length += OSPF_LSA_HEADER_SIZE;
2940 listnode_delete (ack, lsa);
2941 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
2944 return length;
2947 void
2948 ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2950 struct ospf_packet *op;
2951 u_int16_t length = OSPF_HEADER_SIZE;
2953 op = ospf_packet_new (oi->ifp->mtu);
2955 /* Prepare OSPF common header. */
2956 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2958 /* Prepare OSPF Hello body. */
2959 length += ospf_make_hello (oi, op->s);
2961 /* Fill OSPF header. */
2962 ospf_fill_header (oi, op->s, length);
2964 /* Set packet length. */
2965 op->length = length;
2967 op->dst.s_addr = addr->s_addr;
2969 /* Add packet to the interface output queue. */
2970 ospf_packet_add (oi, op);
2972 /* Hook thread to write packet. */
2973 OSPF_ISM_WRITE_ON (oi->ospf);
2976 static void
2977 ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2979 struct ospf_interface *oi;
2981 oi = nbr_nbma->oi;
2982 assert(oi);
2984 /* If this is passive interface, do not send OSPF Hello. */
2985 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2986 return;
2988 if (oi->type != OSPF_IFTYPE_NBMA)
2989 return;
2991 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2992 return;
2994 if (PRIORITY(oi) == 0)
2995 return;
2997 if (nbr_nbma->priority == 0
2998 && oi->state != ISM_DR && oi->state != ISM_Backup)
2999 return;
3001 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3005 ospf_poll_timer (struct thread *thread)
3007 struct ospf_nbr_nbma *nbr_nbma;
3009 nbr_nbma = THREAD_ARG (thread);
3010 nbr_nbma->t_poll = NULL;
3012 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
3013 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
3014 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3016 ospf_poll_send (nbr_nbma);
3018 if (nbr_nbma->v_poll > 0)
3019 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3020 nbr_nbma->v_poll);
3022 return 0;
3027 ospf_hello_reply_timer (struct thread *thread)
3029 struct ospf_neighbor *nbr;
3031 nbr = THREAD_ARG (thread);
3032 nbr->t_hello_reply = NULL;
3034 assert (nbr->oi);
3036 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
3037 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
3038 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3040 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3042 return 0;
3045 /* Send OSPF Hello. */
3046 void
3047 ospf_hello_send (struct ospf_interface *oi)
3049 struct ospf_packet *op;
3050 u_int16_t length = OSPF_HEADER_SIZE;
3052 /* If this is passive interface, do not send OSPF Hello. */
3053 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
3054 return;
3056 op = ospf_packet_new (oi->ifp->mtu);
3058 /* Prepare OSPF common header. */
3059 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3061 /* Prepare OSPF Hello body. */
3062 length += ospf_make_hello (oi, op->s);
3064 /* Fill OSPF header. */
3065 ospf_fill_header (oi, op->s, length);
3067 /* Set packet length. */
3068 op->length = length;
3070 if (oi->type == OSPF_IFTYPE_NBMA)
3072 struct ospf_neighbor *nbr;
3073 struct route_node *rn;
3075 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3076 if ((nbr = rn->info))
3077 if (nbr != oi->nbr_self)
3078 if (nbr->state != NSM_Down)
3080 /* RFC 2328 Section 9.5.1
3081 If the router is not eligible to become Designated Router,
3082 it must periodically send Hello Packets to both the
3083 Designated Router and the Backup Designated Router (if they
3084 exist). */
3085 if (PRIORITY(oi) == 0 &&
3086 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3087 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3088 continue;
3090 /* If the router is eligible to become Designated Router, it
3091 must periodically send Hello Packets to all neighbors that
3092 are also eligible. In addition, if the router is itself the
3093 Designated Router or Backup Designated Router, it must also
3094 send periodic Hello Packets to all other neighbors. */
3096 if (nbr->priority == 0 && oi->state == ISM_DROther)
3097 continue;
3098 /* if oi->state == Waiting, send hello to all neighbors */
3100 struct ospf_packet *op_dup;
3102 op_dup = ospf_packet_dup(op);
3103 op_dup->dst = nbr->address.u.prefix4;
3105 /* Add packet to the interface output queue. */
3106 ospf_packet_add (oi, op_dup);
3108 OSPF_ISM_WRITE_ON (oi->ospf);
3112 ospf_packet_free (op);
3114 else
3116 /* Decide destination address. */
3117 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3118 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3119 else
3120 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3122 /* Add packet to the interface output queue. */
3123 ospf_packet_add (oi, op);
3125 /* Hook thread to write packet. */
3126 OSPF_ISM_WRITE_ON (oi->ospf);
3130 /* Send OSPF Database Description. */
3131 void
3132 ospf_db_desc_send (struct ospf_neighbor *nbr)
3134 struct ospf_interface *oi;
3135 struct ospf_packet *op;
3136 u_int16_t length = OSPF_HEADER_SIZE;
3138 oi = nbr->oi;
3139 op = ospf_packet_new (oi->ifp->mtu);
3141 /* Prepare OSPF common header. */
3142 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3144 /* Prepare OSPF Database Description body. */
3145 length += ospf_make_db_desc (oi, nbr, op->s);
3147 /* Fill OSPF header. */
3148 ospf_fill_header (oi, op->s, length);
3150 /* Set packet length. */
3151 op->length = length;
3153 /* Decide destination address. */
3154 op->dst = nbr->address.u.prefix4;
3156 /* Add packet to the interface output queue. */
3157 ospf_packet_add (oi, op);
3159 /* Hook thread to write packet. */
3160 OSPF_ISM_WRITE_ON (oi->ospf);
3162 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3163 if (nbr->last_send)
3164 ospf_packet_free (nbr->last_send);
3165 nbr->last_send = ospf_packet_dup (op);
3166 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
3169 /* Re-send Database Description. */
3170 void
3171 ospf_db_desc_resend (struct ospf_neighbor *nbr)
3173 struct ospf_interface *oi;
3175 oi = nbr->oi;
3177 /* Add packet to the interface output queue. */
3178 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3180 /* Hook thread to write packet. */
3181 OSPF_ISM_WRITE_ON (oi->ospf);
3184 /* Send Link State Request. */
3185 void
3186 ospf_ls_req_send (struct ospf_neighbor *nbr)
3188 struct ospf_interface *oi;
3189 struct ospf_packet *op;
3190 u_int16_t length = OSPF_HEADER_SIZE;
3192 oi = nbr->oi;
3193 op = ospf_packet_new (oi->ifp->mtu);
3195 /* Prepare OSPF common header. */
3196 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3198 /* Prepare OSPF Link State Request body. */
3199 length += ospf_make_ls_req (nbr, op->s);
3200 if (length == OSPF_HEADER_SIZE)
3202 ospf_packet_free (op);
3203 return;
3206 /* Fill OSPF header. */
3207 ospf_fill_header (oi, op->s, length);
3209 /* Set packet length. */
3210 op->length = length;
3212 /* Decide destination address. */
3213 op->dst = nbr->address.u.prefix4;
3215 /* Add packet to the interface output queue. */
3216 ospf_packet_add (oi, op);
3218 /* Hook thread to write packet. */
3219 OSPF_ISM_WRITE_ON (oi->ospf);
3221 /* Add Link State Request Retransmission Timer. */
3222 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3225 /* Send Link State Update with an LSA. */
3226 void
3227 ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3228 int flag)
3230 struct list *update;
3232 update = list_new ();
3234 listnode_add (update, lsa);
3235 ospf_ls_upd_send (nbr, update, flag);
3237 list_delete (update);
3240 /* Determine size for packet. Must be at least big enough to accomodate next
3241 * LSA on list, which may be bigger than MTU size.
3243 * Return pointer to new ospf_packet
3244 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3245 * on packet sizes (in which case offending LSA is deleted from update list)
3247 static struct ospf_packet *
3248 ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3250 struct ospf_lsa *lsa;
3251 struct listnode *ln;
3252 size_t size;
3253 static char warned = 0;
3255 lsa = listgetdata((ln = listhead (update)));
3256 assert (lsa->data);
3258 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3259 > ospf_packet_max (oi))
3261 if (!warned)
3263 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3264 "will need to fragment. Not optimal. Try divide up"
3265 " your network with areas. Use 'debug ospf packet send'"
3266 " to see details, or look at 'show ip ospf database ..'");
3267 warned = 1;
3270 if (IS_DEBUG_OSPF_PACKET (0, SEND))
3271 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3272 " %d bytes originated by %s, will be fragmented!",
3273 inet_ntoa (lsa->data->id),
3274 ntohs (lsa->data->length),
3275 inet_ntoa (lsa->data->adv_router));
3278 * Allocate just enough to fit this LSA only, to avoid including other
3279 * LSAs in fragmented LSA Updates.
3281 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3282 + OSPF_LS_UPD_MIN_SIZE;
3284 else
3285 size = oi->ifp->mtu;
3287 /* XXX Should this be - sizeof(struct ip)?? -gdt */
3288 if (size > OSPF_MAX_PACKET_SIZE)
3290 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3291 " %d bytes, packet size %ld, dropping it completely."
3292 " OSPF routing is broken!",
3293 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
3294 (long int) size);
3295 list_delete_node (update, ln);
3296 return NULL;
3299 return ospf_packet_new (size);
3302 static void
3303 ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
3304 struct in_addr addr)
3306 struct ospf_packet *op;
3307 u_int16_t length = OSPF_HEADER_SIZE;
3309 if (IS_DEBUG_OSPF_EVENT)
3310 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
3312 op = ospf_ls_upd_packet_new (update, oi);
3314 /* Prepare OSPF common header. */
3315 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3317 /* Prepare OSPF Link State Update body.
3318 * Includes Type-7 translation.
3320 length += ospf_make_ls_upd (oi, update, op->s);
3322 /* Fill OSPF header. */
3323 ospf_fill_header (oi, op->s, length);
3325 /* Set packet length. */
3326 op->length = length;
3328 /* Decide destination address. */
3329 op->dst.s_addr = addr.s_addr;
3331 /* Add packet to the interface output queue. */
3332 ospf_packet_add (oi, op);
3334 /* Hook thread to write packet. */
3335 OSPF_ISM_WRITE_ON (oi->ospf);
3338 static int
3339 ospf_ls_upd_send_queue_event (struct thread *thread)
3341 struct ospf_interface *oi = THREAD_ARG(thread);
3342 struct route_node *rn;
3343 struct route_node *rnext;
3344 struct list *update;
3345 char again = 0;
3347 oi->t_ls_upd_event = NULL;
3349 if (IS_DEBUG_OSPF_EVENT)
3350 zlog_debug ("ospf_ls_upd_send_queue start");
3352 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
3354 rnext = route_next (rn);
3356 if (rn->info == NULL)
3357 continue;
3359 update = (struct list *)rn->info;
3361 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
3363 /* list might not be empty. */
3364 if (listcount(update) == 0)
3366 list_delete (rn->info);
3367 rn->info = NULL;
3368 route_unlock_node (rn);
3370 else
3371 again = 1;
3374 if (again != 0)
3376 if (IS_DEBUG_OSPF_EVENT)
3377 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
3378 " %d nodes to try again, raising new event", again);
3379 oi->t_ls_upd_event =
3380 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3383 if (IS_DEBUG_OSPF_EVENT)
3384 zlog_debug ("ospf_ls_upd_send_queue stop");
3386 return 0;
3389 void
3390 ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
3392 struct ospf_interface *oi;
3393 struct ospf_lsa *lsa;
3394 struct prefix_ipv4 p;
3395 struct route_node *rn;
3396 struct listnode *node;
3398 oi = nbr->oi;
3400 p.family = AF_INET;
3401 p.prefixlen = IPV4_MAX_BITLEN;
3403 /* Decide destination address. */
3404 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3405 p.prefix = oi->vl_data->peer_addr;
3406 else if (flag == OSPF_SEND_PACKET_DIRECT)
3407 p.prefix = nbr->address.u.prefix4;
3408 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3409 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3410 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3411 && (flag == OSPF_SEND_PACKET_INDIRECT))
3412 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3413 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3414 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3415 else
3416 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3418 if (oi->type == OSPF_IFTYPE_NBMA)
3420 if (flag == OSPF_SEND_PACKET_INDIRECT)
3421 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3422 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3423 zlog_warn ("* LS-Update is sent to myself.");
3426 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3428 if (rn->info == NULL)
3429 rn->info = list_new ();
3431 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3432 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
3434 if (oi->t_ls_upd_event == NULL)
3435 oi->t_ls_upd_event =
3436 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3439 static void
3440 ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3441 struct in_addr dst)
3443 struct ospf_packet *op;
3444 u_int16_t length = OSPF_HEADER_SIZE;
3446 op = ospf_packet_new (oi->ifp->mtu);
3448 /* Prepare OSPF common header. */
3449 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3451 /* Prepare OSPF Link State Acknowledgment body. */
3452 length += ospf_make_ls_ack (oi, ack, op->s);
3454 /* Fill OSPF header. */
3455 ospf_fill_header (oi, op->s, length);
3457 /* Set packet length. */
3458 op->length = length;
3460 /* Set destination IP address. */
3461 op->dst = dst;
3463 /* Add packet to the interface output queue. */
3464 ospf_packet_add (oi, op);
3466 /* Hook thread to write packet. */
3467 OSPF_ISM_WRITE_ON (oi->ospf);
3470 static int
3471 ospf_ls_ack_send_event (struct thread *thread)
3473 struct ospf_interface *oi = THREAD_ARG (thread);
3475 oi->t_ls_ack_direct = NULL;
3477 while (listcount (oi->ls_ack_direct.ls_ack))
3478 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3479 oi->ls_ack_direct.dst);
3481 return 0;
3484 void
3485 ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3487 struct ospf_interface *oi = nbr->oi;
3489 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3490 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3492 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3494 if (oi->t_ls_ack_direct == NULL)
3495 oi->t_ls_ack_direct =
3496 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3499 /* Send Link State Acknowledgment delayed. */
3500 void
3501 ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3503 struct in_addr dst;
3505 /* Decide destination address. */
3506 /* RFC2328 Section 13.5 On non-broadcast
3507 networks, delayed Link State Acknowledgment packets must be
3508 unicast separately over each adjacency (i.e., neighbor whose
3509 state is >= Exchange). */
3510 if (oi->type == OSPF_IFTYPE_NBMA)
3512 struct ospf_neighbor *nbr;
3513 struct route_node *rn;
3515 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3516 if ((nbr = rn->info) != NULL)
3517 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3518 while (listcount (oi->ls_ack))
3519 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3520 return;
3522 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3523 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3524 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3525 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3526 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3527 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3528 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3529 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3530 else
3531 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3533 while (listcount (oi->ls_ack))
3534 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);