]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_packet.c
Initial revision
[mirror_frr.git] / ospfd / ospf_packet.c
CommitLineData
718e3744 1/*
2 * OSPF Sending and Receiving OSPF Packets.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
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.
11 *
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.
16 *
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.
21 */
22
23#include <zebra.h>
24
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 "md5-gnu.h"
35
36#include "ospfd/ospfd.h"
37#include "ospfd/ospf_network.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_packet.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_flood.h"
48#include "ospfd/ospf_dump.h"
49
50static void ospf_ls_ack_send_list (struct ospf_interface *, list,
51 struct in_addr);
52
53/* Packet Type String. */
54char *ospf_packet_type_str[] =
55{
56 "unknown",
57 "Hello",
58 "Database Description",
59 "Link State Request",
60 "Link State Update",
61 "Link State Acknowledgment",
62};
63
64extern int in_cksum (void *ptr, int nbytes);
65
66/* OSPF authentication checking function */
67int
68ospf_auth_type (struct ospf_interface *oi)
69{
70 int auth_type;
71
72 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
73 auth_type = oi->area->auth_type;
74 else
75 auth_type = OSPF_IF_PARAM (oi, auth_type);
76
77 /* Handle case where MD5 key list is not configured aka Cisco */
78 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
79 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
80 return OSPF_AUTH_NULL;
81
82 return auth_type;
83
84}
85
86/* forward output pointer. */
87void
88ospf_output_forward (struct stream *s, int size)
89{
90 s->putp += size;
91}
92
93struct ospf_packet *
94ospf_packet_new (size_t size)
95{
96 struct ospf_packet *new;
97
98 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
99 new->s = stream_new (size);
100
101 return new;
102}
103
104void
105ospf_packet_free (struct ospf_packet *op)
106{
107 if (op->s)
108 stream_free (op->s);
109
110 XFREE (MTYPE_OSPF_PACKET, op);
111
112 op = NULL;
113}
114
115struct ospf_fifo *
116ospf_fifo_new ()
117{
118 struct ospf_fifo *new;
119
120 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
121 return new;
122}
123
124/* Add new packet to fifo. */
125void
126ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
127{
128 if (fifo->tail)
129 fifo->tail->next = op;
130 else
131 fifo->head = op;
132
133 fifo->tail = op;
134
135 fifo->count++;
136}
137
138/* Delete first packet from fifo. */
139struct ospf_packet *
140ospf_fifo_pop (struct ospf_fifo *fifo)
141{
142 struct ospf_packet *op;
143
144 op = fifo->head;
145
146 if (op)
147 {
148 fifo->head = op->next;
149
150 if (fifo->head == NULL)
151 fifo->tail = NULL;
152
153 fifo->count--;
154 }
155
156 return op;
157}
158
159/* Return first fifo entry. */
160struct ospf_packet *
161ospf_fifo_head (struct ospf_fifo *fifo)
162{
163 return fifo->head;
164}
165
166/* Flush ospf packet fifo. */
167void
168ospf_fifo_flush (struct ospf_fifo *fifo)
169{
170 struct ospf_packet *op;
171 struct ospf_packet *next;
172
173 for (op = fifo->head; op; op = next)
174 {
175 next = op->next;
176 ospf_packet_free (op);
177 }
178 fifo->head = fifo->tail = NULL;
179 fifo->count = 0;
180}
181
182/* Free ospf packet fifo. */
183void
184ospf_fifo_free (struct ospf_fifo *fifo)
185{
186 ospf_fifo_flush (fifo);
187
188 XFREE (MTYPE_OSPF_FIFO, fifo);
189}
190
191void
192ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
193{
194 /* Add packet to end of queue. */
195 ospf_fifo_push (oi->obuf, op);
196
197 /* Debug of packet fifo*/
198 /* ospf_fifo_debug (oi->obuf); */
199}
200
201void
202ospf_packet_delete (struct ospf_interface *oi)
203{
204 struct ospf_packet *op;
205
206 op = ospf_fifo_pop (oi->obuf);
207
208 if (op)
209 ospf_packet_free (op);
210}
211
212struct stream *
213ospf_stream_copy (struct stream *new, struct stream *s)
214{
215 new->endp = s->endp;
216 new->putp = s->putp;
217 new->getp = s->getp;
218
219 memcpy (new->data, s->data, stream_get_endp (s));
220
221 return new;
222}
223
224struct ospf_packet *
225ospf_packet_dup (struct ospf_packet *op)
226{
227 struct ospf_packet *new;
228
30961a15 229 if (stream_get_endp(op->s) != op->length) {
230 zlog_warn ("ospf_packet_dup stream %d ospf_packet %d size mismatch",
231 STREAM_SIZE(op->s), op->length);
232 }
233
234 /* Reserve space for MD5 authentication that may be added later. */
235 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
718e3744 236 ospf_stream_copy (new->s, op->s);
237
238 new->dst = op->dst;
239 new->length = op->length;
240
241 return new;
242}
243
244int
245ospf_packet_max (struct ospf_interface *oi)
246{
247 int max;
248
249 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
250 max = oi->ifp->mtu - OSPF_AUTH_MD5_SIZE - 88;
251 else
252 max = oi->ifp->mtu - 88;
253
254 return max;
255}
256
257\f
258int
259ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
260 u_int16_t length)
261{
262 void *ibuf;
263 struct 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;
269
270
271 ibuf = STREAM_PNT (s);
272 ospfh = (struct ospf_header *) ibuf;
273
274 /* Get pointer to the end of the packet. */
275 pdigest = ibuf + length;
276
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)
281 {
282 zlog_warn ("interface %s: ospf_check_md5 no key %d",
283 IF_NAME (oi), ospfh->u.crypt.key_id);
284 return 0;
285 }
286
287 /* check crypto seqnum. */
288 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
289
290 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
291 {
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;
297 }
298
299 /* Generate a digest for the ospf packet - their digest + our digest. */
300 md5_init_ctx (&ctx);
301 md5_process_bytes (ibuf, length, &ctx);
302 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
303 md5_finish_ctx (&ctx, digest);
304
305 /* compare the two */
306 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
307 {
308 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
309 IF_NAME (oi));
310 return 0;
311 }
312
313 /* save neighbor's crypt_seqnum */
314 if (nbr)
315 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
316 return 1;
317}
318
319/* This function is called from ospf_write(), it will detect the
320 authentication scheme and if it is MD5, it will change the sequence
321 and update the MD5 digest. */
322int
323ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
324{
325 struct ospf_header *ospfh;
326 unsigned char digest[OSPF_AUTH_MD5_SIZE];
327 struct md5_ctx ctx;
328 void *ibuf;
329 unsigned long oldputp;
9483e155 330 u_int32_t t;
718e3744 331 struct crypt_key *ck;
332 char *auth_key;
333
334 ibuf = STREAM_DATA (op->s);
335 ospfh = (struct ospf_header *) ibuf;
336
337 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
338 return 0;
339
340 /* We do this here so when we dup a packet, we don't have to
341 waste CPU rewriting other headers. */
9483e155 342 t = (time(NULL) & 0xFFFFFFFF);
343 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
344 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
718e3744 345
346 /* Get MD5 Authentication key from auth_key list. */
347 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
348 auth_key = "";
349 else
350 {
351 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
352 auth_key = ck->auth_key;
353 }
354
355 /* Generate a digest for the entire packet + our secret key. */
356 md5_init_ctx (&ctx);
357 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
358 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
359 md5_finish_ctx (&ctx, digest);
360
361 /* Append md5 digest to the end of the stream. */
362 oldputp = stream_get_putp (op->s);
363 stream_set_putp (op->s, ntohs (ospfh->length));
364 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
365 stream_set_putp (op->s, oldputp);
366
367 /* We do *NOT* increment the OSPF header length. */
30961a15 368 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
369
370 if (stream_get_endp(op->s) != op->length) {
371 zlog_warn("ospf_make_md5_digest: length mismatch stream %d ospf_packet %d",
372 stream_get_endp(op->s), op->length);
373 }
718e3744 374
375 return OSPF_AUTH_MD5_SIZE;
376}
377
378\f
379int
380ospf_ls_req_timer (struct thread *thread)
381{
382 struct ospf_neighbor *nbr;
383
384 nbr = THREAD_ARG (thread);
385 nbr->t_ls_req = NULL;
386
387 /* Send Link State Request. */
388 if (ospf_ls_request_count (nbr))
389 ospf_ls_req_send (nbr);
390
391 /* Set Link State Request retransmission timer. */
392 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
393
394 return 0;
395}
396
397void
398ospf_ls_req_event (struct ospf_neighbor *nbr)
399{
400 if (nbr->t_ls_req)
401 {
402 thread_cancel (nbr->t_ls_req);
403 nbr->t_ls_req = NULL;
404 }
405 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
406}
407
408/* Cyclic timer function. Fist registered in ospf_nbr_new () in
409 ospf_neighbor.c */
410int
411ospf_ls_upd_timer (struct thread *thread)
412{
413 struct ospf_neighbor *nbr;
414
415 nbr = THREAD_ARG (thread);
416 nbr->t_ls_upd = NULL;
417
418 /* Send Link State Update. */
419 if (ospf_ls_retransmit_count (nbr) > 0)
420 {
421 list update;
422 struct ospf_lsdb *lsdb;
423 int i;
424 struct timeval now;
425 int retransmit_interval;
426
427 gettimeofday (&now, NULL);
428 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
429
430 lsdb = &nbr->ls_rxmt;
431 update = list_new ();
432
433 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
434 {
435 struct route_table *table = lsdb->type[i].db;
436 struct route_node *rn;
437
438 for (rn = route_top (table); rn; rn = route_next (rn))
439 {
440 struct ospf_lsa *lsa;
441
442 if ((lsa = rn->info) != NULL)
443 /* Don't retransmit an LSA if we received it within
444 the last RxmtInterval seconds - this is to allow the
445 neighbour a chance to acknowledge the LSA as it may
446 have ben just received before the retransmit timer
447 fired. This is a small tweak to what is in the RFC,
448 but it will cut out out a lot of retransmit traffic
449 - MAG */
450 if (tv_cmp (tv_sub (now, lsa->tv_recv),
451 int2tv (retransmit_interval)) >= 0)
452 listnode_add (update, rn->info);
453 }
454 }
455
456 if (listcount (update) > 0)
457 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
458 list_delete (update);
459 }
460
461 /* Set LS Update retransmission timer. */
462 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
463
464 return 0;
465}
466
467int
468ospf_ls_ack_timer (struct thread *thread)
469{
470 struct ospf_interface *oi;
471
472 oi = THREAD_ARG (thread);
473 oi->t_ls_ack = NULL;
474
475 /* Send Link State Acknowledgment. */
476 if (listcount (oi->ls_ack) > 0)
477 ospf_ls_ack_send_delayed (oi);
478
479 /* Set LS Ack timer. */
480 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
481
482 return 0;
483}
484
485int
486ospf_write (struct thread *thread)
487{
488 struct ospf_interface *oi;
489 struct ospf_packet *op;
490 struct sockaddr_in sa_dst;
491 u_char type;
492 int ret;
493 int flags = 0;
494 struct ip iph;
495 struct msghdr msg;
496 struct iovec iov[2];
497 struct ospf *top;
498 listnode node;
499
500 top = THREAD_ARG (thread);
501 top->t_write = NULL;
502
503 node = listhead (top->oi_write_q);
504 assert (node);
505 oi = getdata (node);
506 assert (oi);
507
508 /* Get one packet from queue. */
509 op = ospf_fifo_head (oi->obuf);
510 assert (op);
511 assert (op->length >= OSPF_HEADER_SIZE);
512
513 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS) ||
514 op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
515 ospf_if_ipmulticast (top, oi->address, oi->ifp->ifindex);
516
517 /* Rewrite the md5 signature & update the seq */
518 ospf_make_md5_digest (oi, op);
519
520 memset (&sa_dst, 0, sizeof (sa_dst));
521 sa_dst.sin_family = AF_INET;
522#ifdef HAVE_SIN_LEN
523 sa_dst.sin_len = sizeof(sa_dst);
524#endif /* HAVE_SIN_LEN */
525 sa_dst.sin_addr = op->dst;
526 sa_dst.sin_port = htons (0);
527
528 /* Set DONTROUTE flag if dst is unicast. */
529 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
530 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
531 flags = MSG_DONTROUTE;
532
533 iph.ip_hl = sizeof (struct ip) >> 2;
534 iph.ip_v = IPVERSION;
535 iph.ip_tos = 0;
536#if defined(__NetBSD__) || defined(__FreeBSD__)
537 iph.ip_len = iph.ip_hl*4 + op->length;
538#else
539 iph.ip_len = htons (iph.ip_hl*4 + op->length);
540#endif
541 iph.ip_id = 0;
542 iph.ip_off = 0;
543 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
544 iph.ip_ttl = OSPF_VL_IP_TTL;
545 else
546 iph.ip_ttl = OSPF_IP_TTL;
547 iph.ip_p = IPPROTO_OSPFIGP;
548 iph.ip_sum = 0;
549 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
550 iph.ip_dst.s_addr = op->dst.s_addr;
551
552 memset (&msg, 0, sizeof (msg));
553 msg.msg_name = &sa_dst;
554 msg.msg_namelen = sizeof (sa_dst);
555 msg.msg_iov = iov;
556 msg.msg_iovlen = 2;
557 iov[0].iov_base = (char*)&iph;
558 iov[0].iov_len = iph.ip_hl*4;
559 iov[1].iov_base = STREAM_DATA (op->s);
560 iov[1].iov_len = op->length;
561
562 ret = sendmsg (top->fd, &msg, flags);
563
564 if (ret < 0)
565 zlog_warn ("*** sendmsg in ospf_write failed with %s", strerror (errno));
566
567 /* Retrieve OSPF packet type. */
568 stream_set_getp (op->s, 1);
569 type = stream_getc (op->s);
570
571 /* Show debug sending packet. */
572 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
573 {
574 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
575 {
576 zlog_info ("-----------------------------------------------------");
577 stream_set_getp (op->s, 0);
578 ospf_packet_dump (op->s);
579 }
580
581 zlog_info ("%s sent to [%s] via [%s].",
582 ospf_packet_type_str[type], inet_ntoa (op->dst),
583 IF_NAME (oi));
584
585 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
586 zlog_info ("-----------------------------------------------------");
587 }
588
589 /* Now delete packet from queue. */
590 ospf_packet_delete (oi);
591
592 if (ospf_fifo_head (oi->obuf) == NULL)
593 {
594 oi->on_write_q = 0;
595 list_delete_node (top->oi_write_q, node);
596 }
597
598 /* If packets still remain in queue, call write thread. */
599 if (!list_isempty (top->oi_write_q))
600 ospf_top->t_write =
601 thread_add_write (master, ospf_write, top, top->fd);
602
603 return 0;
604}
605
606/* OSPF Hello message read -- RFC2328 Section 10.5. */
607void
608ospf_hello (struct ip *iph, struct ospf_header *ospfh,
609 struct stream * s, struct ospf_interface *oi, int size)
610{
611 struct ospf_hello *hello;
612 struct ospf_neighbor *nbr;
613 struct route_node *rn;
614 struct prefix p, key;
615 int old_state;
616
617 /* increment statistics. */
618 oi->hello_in++;
619
620 hello = (struct ospf_hello *) STREAM_PNT (s);
621
622 /* If Hello is myself, silently discard. */
f2c80652 623 if (IPV4_ADDR_SAME (&ospfh->router_id, &ospf_top->router_id)) {
624 zlog_info ("Packet %s [Hello:RECV]: router_id matches our router id");
718e3744 625 return;
f2c80652 626 }
718e3744 627
628 /* If incoming interface is passive one, ignore Hello. */
f2c80652 629 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
630 zlog_info ("Packet %s [HELLO:RECV]: oi is passive");
718e3744 631 return;
f2c80652 632 }
718e3744 633
634 /* get neighbor prefix. */
635 p.family = AF_INET;
636 p.prefixlen = ip_masklen (hello->network_mask);
637 p.u.prefix4 = iph->ip_src;
638
639 /* Compare network mask. */
640 /* Checking is ignored for Point-to-Point and Virtual link. */
641 if (oi->type != OSPF_IFTYPE_POINTOPOINT
642 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
643 if (oi->address->prefixlen != p.prefixlen)
644 {
645 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
646 inet_ntoa (ospfh->router_id));
647 return;
648 }
649
650 /* Compare Hello Interval. */
651 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
652 {
653 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
654 inet_ntoa (ospfh->router_id));
655 return;
656 }
657
658 /* Compare Router Dead Interval. */
659 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
660 {
661 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
662 inet_ntoa (ospfh->router_id));
663 return;
664 }
665
666 if (IS_DEBUG_OSPF_EVENT)
667 zlog_info ("Packet %s [Hello:RECV]: Options %s",
668 inet_ntoa (ospfh->router_id),
669 ospf_options_dump (hello->options));
670
671 /* Compare options. */
672#define REJECT_IF_TBIT_ON 1 /* XXX */
673#ifdef REJECT_IF_TBIT_ON
674 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
675 {
676 /*
677 * This router does not support non-zero TOS.
678 * Drop this Hello packet not to establish neighbor relationship.
679 */
680 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
681 inet_ntoa (ospfh->router_id));
682 return;
683 }
684#endif /* REJECT_IF_TBIT_ON */
685
686#ifdef HAVE_OPAQUE_LSA
687 if (CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE)
688 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
689 {
690 /*
691 * This router does know the correct usage of O-bit
692 * the bit should be set in DD packet only.
693 */
694 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
695 inet_ntoa (ospfh->router_id));
696#ifdef STRICT_OBIT_USAGE_CHECK
697 return; /* Reject this packet. */
698#else /* STRICT_OBIT_USAGE_CHECK */
699 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
700#endif /* STRICT_OBIT_USAGE_CHECK */
701 }
702#endif /* HAVE_OPAQUE_LSA */
703
704 /* new for NSSA is to ensure that NP is on and E is off */
705
706#ifdef HAVE_NSSA
707 if (oi->area->external_routing == OSPF_AREA_NSSA)
708 {
709 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
710 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
711 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
712 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
713 {
714 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
715 return;
716 }
717 if (IS_DEBUG_OSPF_NSSA)
718 zlog_info ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
719 }
720 else
721#endif /* HAVE_NSSA */
722 /* The setting of the E-bit found in the Hello Packet's Options
723 field must match this area's ExternalRoutingCapability A
724 mismatch causes processing to stop and the packet to be
725 dropped. The setting of the rest of the bits in the Hello
726 Packet's Options field should be ignored. */
727 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
728 CHECK_FLAG (hello->options, OSPF_OPTION_E))
729 {
730 zlog_warn ("Packet[Hello:RECV]: my options: %x, his options %x",
731 OPTIONS (oi), hello->options);
732 return;
733 }
734
735
736 /* Get neighbor information from table. */
737 key.family = AF_INET;
738 key.prefixlen = IPV4_MAX_BITLEN;
739 key.u.prefix4 = iph->ip_src;
740
741 rn = route_node_get (oi->nbrs, &key);
742 if (rn->info)
743 {
744 route_unlock_node (rn);
745 nbr = rn->info;
746
747 if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt)
748 {
749 nbr->src = iph->ip_src;
750 nbr->address = p;
751 }
752 }
753 else
754 {
755 /* Create new OSPF Neighbor structure. */
756 nbr = ospf_nbr_new (oi);
757 nbr->state = NSM_Down;
758 nbr->src = iph->ip_src;
759 nbr->address = p;
760
761 rn->info = nbr;
762
763 nbr->nbr_nbma = NULL;
764
765 if (oi->type == OSPF_IFTYPE_NBMA)
766 {
767 struct ospf_nbr_nbma *nbr_nbma;
768 listnode node;
769
770 for (node = listhead (oi->nbr_nbma); node; nextnode (node))
771 {
772 nbr_nbma = getdata (node);
773 assert (nbr_nbma);
774
775 if (IPV4_ADDR_SAME(&nbr_nbma->addr, &iph->ip_src))
776 {
777 nbr_nbma->nbr = nbr;
778 nbr->nbr_nbma = nbr_nbma;
779
780 if (nbr_nbma->t_poll)
781 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
782
783 nbr->state_change = nbr_nbma->state_change + 1;
784 }
785 }
786 }
787
788 /* New nbr, save the crypto sequence number if necessary */
789 if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
790 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
791
792 if (IS_DEBUG_OSPF_EVENT)
793 zlog_info ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
794 inet_ntoa (nbr->router_id));
795 }
796
797 nbr->router_id = ospfh->router_id;
798
799 old_state = nbr->state;
800
801 /* Add event to thread. */
802 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
803
804 /* RFC2328 Section 9.5.1
805 If the router is not eligible to become Designated Router,
806 (snip) It must also send an Hello Packet in reply to an
807 Hello Packet received from any eligible neighbor (other than
808 the current Designated Router and Backup Designated Router). */
809 if (oi->type == OSPF_IFTYPE_NBMA)
810 if (PRIORITY(oi) == 0 && hello->priority > 0
811 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
812 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
813 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
814 OSPF_HELLO_REPLY_DELAY);
815
816 /* on NBMA network type, it happens to receive bidirectional Hello packet
817 without advance 1-Way Received event.
818 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
819 if (oi->type == OSPF_IFTYPE_NBMA &&
820 (old_state == NSM_Down || old_state == NSM_Attempt))
821 {
822 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
823 nbr->priority = hello->priority;
824 nbr->d_router = hello->d_router;
825 nbr->bd_router = hello->bd_router;
826 return;
827 }
828
829 if (ospf_nbr_bidirectional (&ospf_top->router_id, hello->neighbors,
830 size - OSPF_HELLO_MIN_SIZE))
831 {
832 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
833 nbr->options |= hello->options;
834 }
835 else
836 {
837 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
838 /* Set neighbor information. */
839 nbr->priority = hello->priority;
840 nbr->d_router = hello->d_router;
841 nbr->bd_router = hello->bd_router;
842 return;
843 }
844
845 /* If neighbor itself declares DR and no BDR exists,
846 cause event BackupSeen */
847 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
848 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
849 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
850
851 /* neighbor itself declares BDR. */
852 if (oi->state == ISM_Waiting &&
853 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
854 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
855
856 /* had not previously. */
857 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
858 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
859 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
860 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
861 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
862
863 /* had not previously. */
864 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
865 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
866 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
867 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
868 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
869
870 /* Neighbor priority check. */
871 if (nbr->priority >= 0 && nbr->priority != hello->priority)
872 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
873
874 /* Set neighbor information. */
875 nbr->priority = hello->priority;
876 nbr->d_router = hello->d_router;
877 nbr->bd_router = hello->bd_router;
878}
879
880/* Save DD flags/options/Seqnum received. */
881void
882ospf_db_desc_save_current (struct ospf_neighbor *nbr,
883 struct ospf_db_desc *dd)
884{
885 nbr->last_recv.flags = dd->flags;
886 nbr->last_recv.options = dd->options;
887 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
888}
889
890/* Process rest of DD packet. */
891static void
892ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
893 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
894 u_int16_t size)
895{
896 struct ospf_lsa *new, *find;
897 struct lsa_header *lsah;
898
899 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
900 for (size -= OSPF_DB_DESC_MIN_SIZE;
901 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
902 {
903 lsah = (struct lsa_header *) STREAM_PNT (s);
904 stream_forward (s, OSPF_LSA_HEADER_SIZE);
905
906 /* Unknown LS type. */
907 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
908 {
909 zlog_warn ("Pakcet [DD:RECV]: Unknown LS type %d.", lsah->type);
910 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
911 return;
912 }
913
914#ifdef HAVE_OPAQUE_LSA
915 if (IS_OPAQUE_LSA (lsah->type)
916 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
917 {
918 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
919 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
920 return;
921 }
922#endif /* HAVE_OPAQUE_LSA */
923
924 switch (lsah->type)
925 {
926 case OSPF_AS_EXTERNAL_LSA:
927#ifdef HAVE_OPAQUE_LSA
928 case OSPF_OPAQUE_AS_LSA:
929#endif /* HAVE_OPAQUE_LSA */
930#ifdef HAVE_NSSA
931 /* Check for stub area. Reject if AS-External from stub but
932 allow if from NSSA. */
933 if (oi->area->external_routing == OSPF_AREA_STUB)
934#else /* ! HAVE_NSSA */
935 if (oi->area->external_routing != OSPF_AREA_DEFAULT)
936#endif /* HAVE_NSSA */
937 {
938 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
939 lsah->type, inet_ntoa (lsah->id),
940 (oi->area->external_routing == OSPF_AREA_STUB) ?\
941 "STUB" : "NSSA");
942 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
943 return;
944 }
945 break;
946 default:
947 break;
948 }
949
950 /* Create LS-request object. */
951 new = ospf_ls_request_new (lsah);
952
953 /* Lookup received LSA, then add LS request list. */
954 find = ospf_lsa_lookup_by_header (oi->area, lsah);
955 if (!find || ospf_lsa_more_recent (find, new) < 0)
956 {
957 ospf_ls_request_add (nbr, new);
958 ospf_lsa_discard (new);
959 }
960 else
961 {
962 /* Received LSA is not recent. */
963 if (IS_DEBUG_OSPF_EVENT)
964 zlog_info ("Packet [DD:RECV]: LSA received Type %d, "
965 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
966 ospf_lsa_discard (new);
967 continue;
968 }
969 }
970
971 /* Master */
972 if (IS_SET_DD_MS (nbr->dd_flags))
973 {
974 nbr->dd_seqnum++;
975 /* Entire DD packet sent. */
976 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
977 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
978 else
979 /* Send new DD packet. */
980 ospf_db_desc_send (nbr);
981 }
982 /* Slave */
983 else
984 {
985 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
986
987 /* When master's more flags is not set. */
988 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
989 {
990 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
991 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
992 }
993
994 /* Send DD pakcet in reply. */
995 ospf_db_desc_send (nbr);
996 }
997
998 /* Save received neighbor values from DD. */
999 ospf_db_desc_save_current (nbr, dd);
1000}
1001
1002int
1003ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1004{
1005 /* Is DD duplicated? */
1006 if (dd->options == nbr->last_recv.options &&
1007 dd->flags == nbr->last_recv.flags &&
1008 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1009 return 1;
1010
1011 return 0;
1012}
1013
1014/* OSPF Database Description message read -- RFC2328 Section 10.6. */
1015void
1016ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1017 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1018{
1019 struct ospf_db_desc *dd;
1020 struct ospf_neighbor *nbr;
1021
1022 /* Increment statistics. */
1023 oi->db_desc_in++;
1024
1025 dd = (struct ospf_db_desc *) STREAM_PNT (s);
1026
1027 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1028 if (nbr == NULL)
1029 {
1030 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1031 inet_ntoa (ospfh->router_id));
1032 return;
1033 }
1034
1035 /* Check MTU. */
1036 if (ntohs (dd->mtu) > oi->ifp->mtu)
1037 {
1038 zlog_warn ("Packet[DD]: MTU is larger than [%s]'s MTU", IF_NAME (oi));
1039 return;
1040 }
1041
1042#ifdef REJECT_IF_TBIT_ON
1043 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1044 {
1045 /*
1046 * In Hello protocol, optional capability must have checked
1047 * to prevent this T-bit enabled router be my neighbor.
1048 */
1049 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1050 return;
1051 }
1052#endif /* REJECT_IF_TBIT_ON */
1053
1054#ifdef HAVE_OPAQUE_LSA
1055 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
1056 && !CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE))
1057 {
1058 /*
1059 * This node is not configured to handle O-bit, for now.
1060 * Clear it to ignore unsupported capability proposed by neighbor.
1061 */
1062 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1063 }
1064#endif /* HAVE_OPAQUE_LSA */
1065
1066 /* Process DD packet by neighbor status. */
1067 switch (nbr->state)
1068 {
1069 case NSM_Down:
1070 case NSM_Attempt:
1071 case NSM_TwoWay:
1072 zlog_warn ("Packet[DD]: Neighbor state is %s, packet discarded.",
1073 LOOKUP (ospf_nsm_state_msg, nbr->state));
1074 break;
1075 case NSM_Init:
1076 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1077 /* If the new state is ExStart, the processing of the current
1078 packet should then continue in this new state by falling
1079 through to case ExStart below. */
1080 if (nbr->state != NSM_ExStart)
1081 break;
1082 case NSM_ExStart:
1083 /* Initial DBD */
1084 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1085 (size == OSPF_DB_DESC_MIN_SIZE))
1086 {
1087 if (IPV4_ADDR_CMP (&nbr->router_id, &ospf_top->router_id) > 0)
1088 {
1089 /* We're Slave---obey */
1090 zlog_warn ("Packet[DD]: Negotiation done (Slave).");
1091 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1092 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1093 }
1094 else
1095 {
1096 /* We're Master, ignore the initial DBD from Slave */
1097 zlog_warn ("Packet[DD]: Initial DBD from Slave, ignoring.");
1098 break;
1099 }
1100 }
1101 /* Ack from the Slave */
1102 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1103 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
1104 IPV4_ADDR_CMP (&nbr->router_id, &ospf_top->router_id) < 0)
1105 {
1106 zlog_warn ("Packet[DD]: Negotiation done (Master).");
1107 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1108 }
1109 else
1110 {
1111 zlog_warn ("Packet[DD]: Negotiation fails.");
1112 break;
1113 }
1114
1115 /* This is where the real Options are saved */
1116 nbr->options = dd->options;
1117
1118#ifdef HAVE_OPAQUE_LSA
1119 if (CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE))
1120 {
1121 if (IS_DEBUG_OSPF_EVENT)
1122 zlog_info ("Neighbor[%s] is %sOpaque-capable.",
1123 inet_ntoa (nbr->router_id),
1124 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1125
1126 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1127 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1128 {
1129 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1130 /* This situation is undesirable, but not a real error. */
1131 }
1132 }
1133#endif /* HAVE_OPAQUE_LSA */
1134
1135 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1136
1137 /* continue processing rest of packet. */
1138 ospf_db_desc_proc (s, oi, nbr, dd, size);
1139 break;
1140 case NSM_Exchange:
1141 if (ospf_db_desc_is_dup (dd, nbr))
1142 {
1143 if (IS_SET_DD_MS (nbr->dd_flags))
1144 /* Master: discard duplicated DD packet. */
1145 zlog_warn ("Packet[DD] (Master): packet duplicated.");
1146 else
1147 /* Slave: cause to retransmit the last Database Description. */
1148 {
1149 zlog_warn ("Packet[DD] [Slave]: packet duplicated.");
1150 ospf_db_desc_resend (nbr);
1151 }
1152 break;
1153 }
1154
1155 /* Otherwise DD packet should be checked. */
1156 /* Check Master/Slave bit mismatch */
1157 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1158 {
1159 zlog_warn ("Packet[DD]: MS-bit mismatch.");
1160 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1161 if (IS_DEBUG_OSPF_EVENT)
1162 zlog_info ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1163 dd->flags, nbr->dd_flags);
1164 break;
1165 }
1166
1167 /* Check initialize bit is set. */
1168 if (IS_SET_DD_I (dd->flags))
1169 {
1170 zlog_warn ("Packet[DD]: I-bit set.");
1171 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1172 break;
1173 }
1174
1175 /* Check DD Options. */
1176 if (dd->options != nbr->options)
1177 {
1178#ifdef ORIGINAL_CODING
1179 /* Save the new options for debugging */
1180 nbr->options = dd->options;
1181#endif /* ORIGINAL_CODING */
1182 zlog_warn ("Packet[DD]: options mismatch.");
1183 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1184 break;
1185 }
1186
1187 /* Check DD sequence number. */
1188 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1189 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1190 (!IS_SET_DD_MS (nbr->dd_flags) &&
1191 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1192 {
1193 zlog_warn ("Pakcet[DD]: sequence number mismatch.");
1194 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1195 break;
1196 }
1197
1198 /* Continue processing rest of packet. */
1199 ospf_db_desc_proc (s, oi, nbr, dd, size);
1200 break;
1201 case NSM_Loading:
1202 case NSM_Full:
1203 if (ospf_db_desc_is_dup (dd, nbr))
1204 {
1205 if (IS_SET_DD_MS (nbr->dd_flags))
1206 {
1207 /* Master should discard duplicate DD packet. */
1208 zlog_warn ("Pakcet[DD]: duplicated, packet discarded.");
1209 break;
1210 }
1211 else
1212 {
1213 struct timeval t, now;
1214 gettimeofday (&now, NULL);
1215 t = tv_sub (now, nbr->last_send_ts);
1216 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1217 {
1218 /* In states Loading and Full the slave must resend
1219 its last Database Description packet in response to
1220 duplicate Database Description packets received
1221 from the master. For this reason the slave must
1222 wait RouterDeadInterval seconds before freeing the
1223 last Database Description packet. Reception of a
1224 Database Description packet from the master after
1225 this interval will generate a SeqNumberMismatch
1226 neighbor event. RFC2328 Section 10.8 */
1227 ospf_db_desc_resend (nbr);
1228 break;
1229 }
1230 }
1231 }
1232
1233 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1234 break;
1235 default:
1236 zlog_warn ("Packet[DD]: NSM illegal status.");
1237 break;
1238 }
1239}
1240
1241#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1242
1243/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1244void
1245ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1246 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1247{
1248 struct ospf_neighbor *nbr;
1249 u_int32_t ls_type;
1250 struct in_addr ls_id;
1251 struct in_addr adv_router;
1252 struct ospf_lsa *find;
1253 list ls_upd;
1254 int length;
1255
1256 /* Increment statistics. */
1257 oi->ls_req_in++;
1258
1259 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1260 if (nbr == NULL)
1261 {
1262 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1263 inet_ntoa (ospfh->router_id));
1264 return;
1265 }
1266
1267 /* Neighbor State should be Exchange or later. */
1268 if (nbr->state != NSM_Exchange &&
1269 nbr->state != NSM_Loading &&
1270 nbr->state != NSM_Full)
1271 {
1272 zlog_warn ("Link State Request: Neighbor state is %s, packet discarded.",
1273 LOOKUP (ospf_nsm_state_msg, nbr->state));
1274 return;
1275 }
1276
1277 /* Send Link State Update for ALL requested LSAs. */
1278 ls_upd = list_new ();
1279 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1280
1281 while (size >= OSPF_LSA_KEY_SIZE)
1282 {
1283 /* Get one slice of Link State Request. */
1284 ls_type = stream_getl (s);
1285 ls_id.s_addr = stream_get_ipv4 (s);
1286 adv_router.s_addr = stream_get_ipv4 (s);
1287
1288 /* Verify LSA type. */
1289 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1290 {
1291 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1292 list_delete (ls_upd);
1293 return;
1294 }
1295
1296 /* Search proper LSA in LSDB. */
1297 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1298 if (find == NULL)
1299 {
1300 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1301 list_delete (ls_upd);
1302 return;
1303 }
1304
1305 /* Packet overflows MTU size, send immediatly. */
1306 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1307 {
1308 if (oi->type == OSPF_IFTYPE_NBMA)
1309 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1310 else
1311 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1312
1313 /* Only remove list contents. Keep ls_upd. */
1314 list_delete_all_node (ls_upd);
1315
1316 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1317 }
1318
1319 /* Append LSA to update list. */
1320 listnode_add (ls_upd, find);
1321 length += ntohs (find->data->length);
1322
1323 size -= OSPF_LSA_KEY_SIZE;
1324 }
1325
1326 /* Send rest of Link State Update. */
1327 if (listcount (ls_upd) > 0)
1328 {
1329 if (oi->type == OSPF_IFTYPE_NBMA)
1330 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1331 else
1332 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1333
1334 list_delete (ls_upd);
1335 }
1336 else
1337 list_free (ls_upd);
1338}
1339
1340/* Get the list of LSAs from Link State Update packet.
1341 And process some validation -- RFC2328 Section 13. (1)-(2). */
1342static list
1343ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1344 struct ospf_interface *oi, size_t size)
1345{
1346 u_int16_t count, sum;
1347 u_int32_t length;
1348 struct lsa_header *lsah;
1349 struct ospf_lsa *lsa;
1350 list lsas;
1351
1352 lsas = list_new ();
1353
1354 count = stream_getl (s);
1355 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1356
1357 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1358 size -= length, stream_forward (s, length), count--)
1359 {
1360 lsah = (struct lsa_header *) STREAM_PNT (s);
1361 length = ntohs (lsah->length);
1362
1363 if (length > size)
1364 {
1365 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1366 break;
1367 }
1368
1369 /* Validate the LSA's LS checksum. */
1370 sum = lsah->checksum;
1371 if (sum != ospf_lsa_checksum (lsah))
1372 {
1373 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1374 sum, lsah->checksum);
1375 continue;
1376 }
1377
1378 /* Examine the LSA's LS type. */
1379 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1380 {
1381 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1382 continue;
1383 }
1384
1385 /*
1386 * What if the received LSA's age is greater than MaxAge?
1387 * Treat it as a MaxAge case -- endo.
1388 */
1389 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1390 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1391
1392#ifdef HAVE_OPAQUE_LSA
1393 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1394 {
1395#ifdef STRICT_OBIT_USAGE_CHECK
1396 if ((IS_OPAQUE_LSA(lsah->type) &&
1397 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1398 || (! IS_OPAQUE_LSA(lsah->type) &&
1399 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1400 {
1401 /*
1402 * This neighbor must know the exact usage of O-bit;
1403 * the bit will be set in Type-9,10,11 LSAs only.
1404 */
1405 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1406 continue;
1407 }
1408#endif /* STRICT_OBIT_USAGE_CHECK */
1409
1410 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1411 if (lsah->type == OSPF_OPAQUE_AS_LSA
1412 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1413 {
1414 if (IS_DEBUG_OSPF_EVENT)
1415 zlog_info ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1416 continue;
1417 }
1418 }
1419 else if (IS_OPAQUE_LSA(lsah->type))
1420 {
1421 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1422 continue;
1423 }
1424#endif /* HAVE_OPAQUE_LSA */
1425
1426 /* Create OSPF LSA instance. */
1427 lsa = ospf_lsa_new ();
1428
1429 /* We may wish to put some error checking if type NSSA comes in
1430 and area not in NSSA mode */
1431 switch (lsah->type)
1432 {
1433 case OSPF_AS_EXTERNAL_LSA:
1434#ifdef HAVE_OPAQUE_LSA
1435 case OSPF_OPAQUE_AS_LSA:
1436 lsa->area = NULL;
1437 break;
1438 case OSPF_OPAQUE_LINK_LSA:
1439 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1440 /* Fallthrough */
1441#endif /* HAVE_OPAQUE_LSA */
1442 default:
1443 lsa->area = oi->area;
1444 break;
1445 }
1446
1447 lsa->data = ospf_lsa_data_new (length);
1448 memcpy (lsa->data, lsah, length);
1449
1450 if (IS_DEBUG_OSPF_EVENT)
1451 zlog_info("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1452 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1453 listnode_add (lsas, lsa);
1454 }
1455
1456 return lsas;
1457}
1458
1459/* Cleanup Update list. */
1460void
1461ospf_upd_list_clean (list lsas)
1462{
1463 listnode node;
1464 struct ospf_lsa *lsa;
1465
1466 for (node = listhead (lsas); node; nextnode (node))
1467 if ((lsa = getdata (node)) != NULL)
1468 ospf_lsa_discard (lsa);
1469
1470 list_delete (lsas);
1471}
1472
1473/* OSPF Link State Update message read -- RFC2328 Section 13. */
1474void
1475ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1476 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1477{
1478 struct ospf_neighbor *nbr;
1479 list lsas;
1480#ifdef HAVE_OPAQUE_LSA
1481 list mylsa_acks, mylsa_upds;
1482#endif /* HAVE_OPAQUE_LSA */
1483 listnode node, next;
1484 struct ospf_lsa *lsa = NULL;
1485 /* unsigned long ls_req_found = 0; */
1486
1487 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1488
1489 /* Increment statistics. */
1490 oi->ls_upd_in++;
1491
1492 /* Check neighbor. */
1493 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1494 if (nbr == NULL)
1495 {
1496 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1497 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1498 return;
1499 }
1500
1501 /* Check neighbor state. */
1502 if (nbr->state < NSM_Exchange)
1503 {
1504 zlog_warn ("Link State Update: Neighbor[%s] state is less than Exchange",
1505 inet_ntoa (ospfh->router_id));
1506 return;
1507 }
1508
1509 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1510 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1511 * of section 13.
1512 */
1513 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1514
1515#ifdef HAVE_OPAQUE_LSA
1516 /*
1517 * Prepare two kinds of lists to clean up unwanted self-originated
1518 * Opaque-LSAs from the routing domain as soon as possible.
1519 */
1520 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1521 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1522
1523 /*
1524 * If self-originated Opaque-LSAs that have flooded before restart
1525 * are contained in the received LSUpd message, corresponding LSReq
1526 * messages to be sent may have to be modified.
1527 * To eliminate possible race conditions such that flushing and normal
1528 * updating for the same LSA would take place alternately, this trick
1529 * must be done before entering to the loop below.
1530 */
1531 ospf_opaque_adjust_lsreq (nbr, lsas);
1532#endif /* HAVE_OPAQUE_LSA */
1533
1534#define DISCARD_LSA(L,N) {\
1535 if (IS_DEBUG_OSPF_EVENT) \
1536 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1537 ospf_lsa_discard (L); \
1538 continue; }
1539
1540 /* Process each LSA received in the one packet. */
1541 for (node = listhead (lsas); node; node = next)
1542 {
1543 struct ospf_lsa *ls_ret, *current;
1544 int ret = 1;
1545
1546 next = node->next;
1547
1548 lsa = getdata (node);
1549
1550#ifdef HAVE_NSSA
1551 if (IS_DEBUG_OSPF_NSSA)
1552 {
1553 char buf1[INET_ADDRSTRLEN];
1554 char buf2[INET_ADDRSTRLEN];
1555 char buf3[INET_ADDRSTRLEN];
1556
1557 zlog_info("LSA Type-%d from %s, ID: %s, ADV: %s",
1558 lsa->data->type,
1559 inet_ntop (AF_INET, &ospfh->router_id,
1560 buf1, INET_ADDRSTRLEN),
1561 inet_ntop (AF_INET, &lsa->data->id,
1562 buf2, INET_ADDRSTRLEN),
1563 inet_ntop (AF_INET, &lsa->data->adv_router,
1564 buf3, INET_ADDRSTRLEN));
1565 }
1566#endif /* HAVE_NSSA */
1567
1568 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1569
1570 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1571
1572 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1573
1574 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1575
1576 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1577
1578 /* Do take in Type-7's if we are an NSSA */
1579
1580 /* If we are also an ABR, later translate them to a Type-5 packet */
1581
1582 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1583 translate them to a separate Type-5 packet. */
1584
1585 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1586 /* Reject from STUB or NSSA */
1587 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1588 {
1589 DISCARD_LSA (lsa, 1);
1590#ifdef HAVE_NSSA
1591 if (IS_DEBUG_OSPF_NSSA)
1592 zlog_info("Incoming External LSA Discarded: We are NSSA/STUB Area");
1593#endif /* HAVE_NSSA */
1594 }
1595
1596#ifdef HAVE_NSSA
1597 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1598 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1599 {
1600 DISCARD_LSA (lsa,2);
1601 if (IS_DEBUG_OSPF_NSSA)
1602 zlog_info("Incoming NSSA LSA Discarded: Not NSSA Area");
1603 }
1604#endif /* HAVE_NSSA */
1605
1606 /* Find the LSA in the current database. */
1607
1608 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1609
1610 /* If the LSA's LS age is equal to MaxAge, and there is currently
1611 no instance of the LSA in the router's link state database,
1612 and none of router's neighbors are in states Exchange or Loading,
1613 then take the following actions. */
1614
1615 if (IS_LSA_MAXAGE (lsa) && !current &&
1616 (ospf_nbr_count (oi->nbrs, NSM_Exchange) +
1617 ospf_nbr_count (oi->nbrs, NSM_Loading)) == 0)
1618 {
1619 /* Response Link State Acknowledgment. */
1620 ospf_ls_ack_send (nbr, lsa);
1621
1622 /* Discard LSA. */
1623 zlog_warn ("Link State Update: LS age is equal to MaxAge.");
1624 DISCARD_LSA (lsa, 3);
1625 }
1626
1627#ifdef HAVE_OPAQUE_LSA
1628 if (IS_OPAQUE_LSA (lsa->data->type)
1629 && IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf_top->router_id))
1630 {
1631 /*
1632 * Even if initial flushing seems to be completed, there might
1633 * be a case that self-originated LSA with MaxAge still remain
1634 * in the routing domain.
1635 * Just send an LSAck message to cease retransmission.
1636 */
1637 if (IS_LSA_MAXAGE (lsa))
1638 {
1639 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1640 ospf_ls_ack_send (nbr, lsa);
1641 ospf_lsa_discard (lsa);
1642
1643 if (current != NULL && ! IS_LSA_MAXAGE (current))
1644 ospf_opaque_lsa_refresh_schedule (current);
1645 continue;
1646 }
1647
1648 /*
1649 * If an instance of self-originated Opaque-LSA is not found
1650 * in the LSDB, there are some possible cases here.
1651 *
1652 * 1) This node lost opaque-capability after restart.
1653 * 2) Else, a part of opaque-type is no more supported.
1654 * 3) Else, a part of opaque-id is no more supported.
1655 *
1656 * Anyway, it is still this node's responsibility to flush it.
1657 * Otherwise, the LSA instance remains in the routing domain
1658 * until its age reaches to MaxAge.
1659 */
1660 if (current == NULL)
1661 {
1662 if (IS_DEBUG_OSPF_EVENT)
1663 zlog_info ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
1664
1665 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1666 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1667 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1668 continue;
1669 }
1670 }
1671#endif /* HAVE_OPAQUE_LSA */
1672
1673 /* (5) Find the instance of this LSA that is currently contained
1674 in the router's link state database. If there is no
1675 database copy, or the received LSA is more recent than
1676 the database copy the following steps must be performed. */
1677
1678 if (current == NULL ||
1679 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1680 {
1681 /* Actual flooding procedure. */
1682 if (ospf_flood (nbr, current, lsa) < 0) /* Trap NSSA later. */
1683 DISCARD_LSA (lsa, 4);
1684 continue;
1685 }
1686
1687 /* (6) Else, If there is an instance of the LSA on the sending
1688 neighbor's Link state request list, an error has occurred in
1689 the Database Exchange process. In this case, restart the
1690 Database Exchange process by generating the neighbor event
1691 BadLSReq for the sending neighbor and stop processing the
1692 Link State Update packet. */
1693
1694 if (ospf_ls_request_lookup (nbr, lsa))
1695 {
1696 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1697 zlog_warn ("LSA instance exists on Link state request list");
1698
1699 /* Clean list of LSAs. */
1700 ospf_upd_list_clean (lsas);
1701 /* this lsa is not on lsas list already. */
1702 ospf_lsa_discard (lsa);
1703#ifdef HAVE_OPAQUE_LSA
1704 list_delete (mylsa_acks);
1705 list_delete (mylsa_upds);
1706#endif /* HAVE_OPAQUE_LSA */
1707 return;
1708 }
1709
1710 /* If the received LSA is the same instance as the database copy
1711 (i.e., neither one is more recent) the following two steps
1712 should be performed: */
1713
1714 if (ret == 0)
1715 {
1716 /* If the LSA is listed in the Link state retransmission list
1717 for the receiving adjacency, the router itself is expecting
1718 an acknowledgment for this LSA. The router should treat the
1719 received LSA as an acknowledgment by removing the LSA from
1720 the Link state retransmission list. This is termed an
1721 "implied acknowledgment". */
1722
1723 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1724
1725 if (ls_ret != NULL)
1726 {
1727 ospf_ls_retransmit_delete (nbr, ls_ret);
1728
1729 /* Delayed acknowledgment sent if advertisement received
1730 from Designated Router, otherwise do nothing. */
1731 if (oi->state == ISM_Backup)
1732 if (NBR_IS_DR (nbr))
1733 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1734
1735 DISCARD_LSA (lsa, 5);
1736 }
1737 else
1738 /* Acknowledge the receipt of the LSA by sending a
1739 Link State Acknowledgment packet back out the receiving
1740 interface. */
1741 {
1742 ospf_ls_ack_send (nbr, lsa);
1743 DISCARD_LSA (lsa, 6);
1744 }
1745 }
1746
1747 /* The database copy is more recent. If the database copy
1748 has LS age equal to MaxAge and LS sequence number equal to
1749 MaxSequenceNumber, simply discard the received LSA without
1750 acknowledging it. (In this case, the LSA's LS sequence number is
1751 wrapping, and the MaxSequenceNumber LSA must be completely
1752 flushed before any new LSA instance can be introduced). */
1753
1754 else if (ret > 0) /* Database copy is more recent */
1755 {
1756 if (IS_LSA_MAXAGE (current) &&
1757 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1758 {
1759 DISCARD_LSA (lsa, 7);
1760 }
1761 /* Otherwise, as long as the database copy has not been sent in a
1762 Link State Update within the last MinLSArrival seconds, send the
1763 database copy back to the sending neighbor, encapsulated within
1764 a Link State Update Packet. The Link State Update Packet should
1765 be sent directly to the neighbor. In so doing, do not put the
1766 database copy of the LSA on the neighbor's link state
1767 retransmission list, and do not acknowledge the received (less
1768 recent) LSA instance. */
1769 else
1770 {
1771 struct timeval now;
1772
1773 gettimeofday (&now, NULL);
1774
1775 if (tv_cmp (tv_sub (now, current->tv_orig),
1776 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1777 /* Trap NSSA type later.*/
1778 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1779 DISCARD_LSA (lsa, 8);
1780 }
1781 }
1782 }
1783
1784#ifdef HAVE_OPAQUE_LSA
1785 /*
1786 * Now that previously originated Opaque-LSAs those which not yet
1787 * installed into LSDB are captured, take several steps to clear
1788 * them completely from the routing domain, before proceeding to
1789 * origination for the current target Opaque-LSAs.
1790 */
1791 while (listcount (mylsa_acks) > 0)
1792 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1793
1794 if (listcount (mylsa_upds) > 0)
1795 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1796
1797 list_delete (mylsa_upds);
1798#endif /* HAVE_OPAQUE_LSA */
1799
1800 assert (listcount (lsas) == 0);
1801 list_delete (lsas);
1802}
1803
1804/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1805void
1806ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1807 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1808{
1809 struct ospf_neighbor *nbr;
1810#ifdef HAVE_OPAQUE_LSA
1811 list opaque_acks;
1812#endif /* HAVE_OPAQUE_LSA */
1813
1814 /* increment statistics. */
1815 oi->ls_ack_in++;
1816
1817 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1818 if (nbr == NULL)
1819 {
1820 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1821 inet_ntoa (ospfh->router_id));
1822 return;
1823 }
1824
1825 if (nbr->state < NSM_Exchange)
1826 {
1827 zlog_warn ("Link State Acknowledgment: State is less than Exchange.");
1828 return;
1829 }
1830
1831#ifdef HAVE_OPAQUE_LSA
1832 opaque_acks = list_new ();
1833#endif /* HAVE_OPAQUE_LSA */
1834
1835 while (size >= OSPF_LSA_HEADER_SIZE)
1836 {
1837 struct ospf_lsa *lsa, *lsr;
1838
1839 lsa = ospf_lsa_new ();
1840 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1841
1842 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1843 size -= OSPF_LSA_HEADER_SIZE;
1844 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1845
1846 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1847 {
1848 lsa->data = NULL;
1849 ospf_lsa_discard (lsa);
1850 continue;
1851 }
1852
1853 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1854
1855 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1856 {
1857#ifdef HAVE_OPAQUE_LSA
1858 /* Keep this LSA entry for later reference. */
1859 if (IS_OPAQUE_LSA (lsr->data->type))
1860 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
1861#endif /* HAVE_OPAQUE_LSA */
1862
1863 ospf_ls_retransmit_delete (nbr, lsr);
1864 }
1865
1866 lsa->data = NULL;
1867 ospf_lsa_discard (lsa);
1868 }
1869
1870#ifdef HAVE_OPAQUE_LSA
1871 if (listcount (opaque_acks) > 0)
1872 ospf_opaque_ls_ack_received (nbr, opaque_acks);
1873
1874 list_delete (opaque_acks);
1875 return;
1876#endif /* HAVE_OPAQUE_LSA */
1877}
1878\f
1879struct stream *
1880ospf_recv_packet (int fd, struct interface **ifp)
1881{
1882 int ret;
1883 struct ip iph;
1884 u_int16_t ip_len;
1885 struct stream *ibuf;
1886 unsigned int ifindex = 0;
1887 struct iovec iov;
1888 struct cmsghdr *cmsg;
1889#if defined (IP_PKTINFO)
1890 struct in_pktinfo *pktinfo;
1891#elif defined (IP_RECVIF)
1892 struct sockaddr_dl *pktinfo;
1893#else
1894 char *pktinfo; /* dummy */
1895#endif
1896 char buff [sizeof (*cmsg) + sizeof (*pktinfo)];
1897 struct msghdr msgh = {NULL, 0, &iov, 1, buff,
1898 sizeof (*cmsg) + sizeof (*pktinfo), 0};
1899
1900 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
1901
1902 if (ret != sizeof (iph))
1903 {
1904 zlog_warn ("ospf_recv_packet packet smaller than ip header");
1905 return NULL;
1906 }
1907
1908#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1909 ip_len = iph.ip_len;
1910#else
1911 ip_len = ntohs (iph.ip_len);
1912#endif
1913
1914#if !defined(GNU_LINUX)
1915 /*
1916 * Kernel network code touches incoming IP header parameters,
1917 * before protocol specific processing.
1918 *
1919 * 1) Convert byteorder to host representation.
1920 * --> ip_len, ip_id, ip_off
1921 *
1922 * 2) Adjust ip_len to strip IP header size!
1923 * --> If user process receives entire IP packet via RAW
1924 * socket, it must consider adding IP header size to
1925 * the "ip_len" field of "ip" structure.
1926 *
1927 * For more details, see <netinet/ip_input.c>.
1928 */
1929 ip_len = ip_len + (iph.ip_hl << 2);
1930#endif
1931
1932 ibuf = stream_new (ip_len);
1933 iov.iov_base = STREAM_DATA (ibuf);
1934 iov.iov_len = ip_len;
1935 ret = recvmsg (fd, &msgh, 0);
1936
1937 cmsg = CMSG_FIRSTHDR (&msgh);
1938
1939 if (cmsg != NULL && //cmsg->cmsg_len == sizeof (*pktinfo) &&
1940 cmsg->cmsg_level == IPPROTO_IP &&
1941#if defined (IP_PKTINFO)
1942 cmsg->cmsg_type == IP_PKTINFO
1943#elif defined (IP_RECVIF)
1944 cmsg->cmsg_type == IP_RECVIF
1945#else
1946 0
1947#endif
1948 )
1949 {
1950#if defined (IP_PKTINFO)
1951 pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
1952 ifindex = pktinfo->ipi_ifindex;
1953#elif defined (IP_RECVIF)
1954 pktinfo = (struct sockaddr_dl *)CMSG_DATA(cmsg);
1955 ifindex = pktinfo->sdl_index;
1956#else
1957 ifindex = 0;
1958#endif
1959 }
1960
1961 *ifp = if_lookup_by_index (ifindex);
1962
1963 if (ret != ip_len)
1964 {
1965 zlog_warn ("ospf_recv_packet short read. "
1966 "ip_len %d bytes read %d", ip_len, ret);
1967 stream_free (ibuf);
1968 return NULL;
1969 }
1970
1971 return ibuf;
1972}
1973
1974struct ospf_interface *
1975ospf_associate_packet_vl (struct interface *ifp, struct ospf_interface *oi,
1976 struct ip *iph, struct ospf_header *ospfh)
1977{
1978 struct ospf_interface *rcv_oi;
1979 listnode node;
1980 struct ospf_vl_data *vl_data;
1981 struct ospf_area *vl_area;
1982
1983 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
1984 !OSPF_IS_AREA_BACKBONE (ospfh))
1985 return oi;
1986
1987 if ((rcv_oi = oi) == NULL)
1988 {
1989 if ((rcv_oi = ospf_if_lookup_by_local_addr (ifp, iph->ip_dst)) == NULL)
1990 return NULL;
1991 }
1992
1993 for (node = listhead (ospf_top->vlinks); node; nextnode (node))
1994 {
1995 if ((vl_data = getdata (node)) == NULL)
1996 continue;
1997
1998 vl_area = ospf_area_lookup_by_area_id (vl_data->vl_area_id);
1999 if (!vl_area)
2000 continue;
2001
2002 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2003 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2004 {
2005 if (IS_DEBUG_OSPF_EVENT)
2006 zlog_info ("associating packet with %s",
2007 IF_NAME (vl_data->vl_oi));
2008 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2009 {
2010 if (IS_DEBUG_OSPF_EVENT)
2011 zlog_info ("This VL is not up yet, sorry");
2012 return NULL;
2013 }
2014
2015 return vl_data->vl_oi;
2016 }
2017 }
2018
2019 if (IS_DEBUG_OSPF_EVENT)
2020 zlog_info ("couldn't find any VL to associate the packet with");
2021
2022 return oi;
2023}
2024
2025int
2026ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2027{
2028 /* Check match the Area ID of the receiving interface. */
2029 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2030 return 1;
2031
2032 return 0;
2033}
2034
2035/* Unbound socket will accept any Raw IP packets if proto is matched.
2036 To prevent it, compare src IP address and i/f address with masking
2037 i/f network mask. */
2038int
2039ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2040{
2041 struct in_addr mask, me, him;
2042
2043 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2044 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2045 return 1;
2046
2047 masklen2ip (oi->address->prefixlen, &mask);
2048
2049 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2050 him.s_addr = ip_src.s_addr & mask.s_addr;
2051
2052 if (IPV4_ADDR_SAME (&me, &him))
2053 return 1;
2054
2055 return 0;
2056}
2057
2058int
2059ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2060 struct ospf_header *ospfh)
2061{
2062 int ret = 0;
2063 struct crypt_key *ck;
2064
2065 switch (ntohs (ospfh->auth_type))
2066 {
2067 case OSPF_AUTH_NULL:
2068 ret = 1;
2069 break;
2070 case OSPF_AUTH_SIMPLE:
2071 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2072 ret = 1;
2073 else
2074 ret = 0;
2075 break;
2076 case OSPF_AUTH_CRYPTOGRAPHIC:
2077 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2078 {
2079 ret = 0;
2080 break;
2081 }
2082
2083 /* This is very basic, the digest processing is elsewhere */
2084 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2085 ospfh->u.crypt.key_id == ck->key_id &&
2086 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2087 ret = 1;
2088 else
2089 ret = 0;
2090 break;
2091 default:
2092 ret = 0;
2093 break;
2094 }
2095
2096 return ret;
2097}
2098
2099int
2100ospf_check_sum (struct ospf_header *ospfh)
2101{
2102 u_int32_t ret;
2103 u_int16_t sum;
2104 int in_cksum (void *ptr, int nbytes);
2105
2106 /* clear auth_data for checksum. */
2107 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2108
2109 /* keep checksum and clear. */
2110 sum = ospfh->checksum;
2111 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2112
2113 /* calculate checksum. */
2114 ret = in_cksum (ospfh, ntohs (ospfh->length));
2115
2116 if (ret != sum)
2117 {
2118 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2119 ret, sum);
2120 return 0;
2121 }
2122
2123 return 1;
2124}
2125
2126/* OSPF Header verification. */
2127int
2128ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2129 struct ip *iph, struct ospf_header *ospfh)
2130{
2131 /* check version. */
2132 if (ospfh->version != OSPF_VERSION)
2133 {
2134 zlog_warn ("interface %s: ospf_read version number mismatch.",
2135 IF_NAME (oi));
2136 return -1;
2137 }
2138
2139 /* Check Area ID. */
2140 if (!ospf_check_area_id (oi, ospfh))
2141 {
2142 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2143 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2144 return -1;
2145 }
2146
2147 /* Check network mask, Silently discarded. */
2148 if (! ospf_check_network_mask (oi, iph->ip_src))
2149 {
2150 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2151 IF_NAME (oi), inet_ntoa (iph->ip_src));
2152 return -1;
2153 }
2154
2155 /* Check authentication. */
2156 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2157 {
2158 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2159 IF_NAME (oi));
2160 return -1;
2161 }
2162
2163 if (! ospf_check_auth (oi, ibuf, ospfh))
2164 {
2165 zlog_warn ("interface %s: ospf_read authentication failed.",
2166 IF_NAME (oi));
2167 return -1;
2168 }
2169
2170 /* if check sum is invalid, packet is discarded. */
2171 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2172 {
2173 if (! ospf_check_sum (ospfh))
2174 {
2175 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2176 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2177 return -1;
2178 }
2179 }
2180 else
2181 {
2182 if (ospfh->checksum != 0)
2183 return -1;
2184 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2185 {
2186 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2187 IF_NAME (oi));
2188 return -1;
2189 }
2190 }
2191
2192 return 0;
2193}
2194
2195/* Starting point of packet process function. */
2196int
2197ospf_read (struct thread *thread)
2198{
2199 int ret;
2200 struct stream *ibuf;
2201 struct ospf *top;
2202 struct ospf_interface *oi;
2203 struct ip *iph;
2204 struct ospf_header *ospfh;
2205 u_int16_t length;
2206 struct interface *ifp;
2207
2208 /* first of all get interface pointer. */
2209 top = THREAD_ARG (thread);
2210 top->t_read = NULL;
2211
2212 /* read OSPF packet. */
2213 ibuf = ospf_recv_packet (top->fd, &ifp);
2214 if (ibuf == NULL)
2215 return -1;
2216
2217 iph = (struct ip *) STREAM_DATA (ibuf);
2218
2219 /* prepare for next packet. */
2220 top->t_read = thread_add_read (master, ospf_read, top, top->fd);
2221
2222 /* IP Header dump. */
7d95c611 2223 if (ospf_debug_packet & OSPF_DEBUG_RECV)
2224 ospf_ip_header_dump (ibuf);
2225
718e3744 2226 /* Self-originated packet should be discarded silently. */
2227 if (ospf_if_lookup_by_local_addr (NULL, iph->ip_src))
2228 {
2229 stream_free (ibuf);
2230 return 0;
2231 }
2232
2233 /* Adjust size to message length. */
2234 stream_forward (ibuf, iph->ip_hl * 4);
2235
2236 /* Get ospf packet header. */
2237 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2238
2239 /* associate packet with ospf interface */
2240 oi = ospf_if_lookup_recv_interface (iph->ip_src);
2241 if (ifp && oi && oi->ifp != ifp)
2242 {
2243 zlog_warn ("Packet from [%s] received on wrong link %s",
2244 inet_ntoa (iph->ip_src), ifp->name);
2245 stream_free (ibuf);
2246 return 0;
2247 }
2248
2249 if ((oi = ospf_associate_packet_vl (ifp, oi, iph, ospfh)) == NULL)
2250 {
2251 stream_free (ibuf);
2252 return 0;
2253 }
2254
2255 /*
2256 * If the received packet is destined for AllDRouters, the packet
2257 * should be accepted only if the received ospf interface state is
2258 * either DR or Backup -- endo.
2259 */
2260 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2261 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2262 {
2263 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2264 inet_ntoa (iph->ip_src), IF_NAME (oi),
2265 LOOKUP (ospf_ism_state_msg, oi->state));
2266 stream_free (ibuf);
2267 return 0;
2268 }
2269
2270 /* Show debug receiving packet. */
f2c80652 2271 /* if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2272 {*/
718e3744 2273 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2274 {
2275 zlog_info ("-----------------------------------------------------");
2276 ospf_packet_dump (ibuf);
2277 }
2278
2279 zlog_info ("%s received from [%s] via [%s]",
2280 ospf_packet_type_str[ospfh->type],
2281 inet_ntoa (ospfh->router_id), IF_NAME (oi));
2282 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2283 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2284
2285 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2286 zlog_info ("-----------------------------------------------------");
f2c80652 2287 /* }*/
718e3744 2288
2289 /* Some header verification. */
2290 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2291 if (ret < 0)
2292 {
2293 stream_free (ibuf);
2294 return ret;
2295 }
2296
2297 stream_forward (ibuf, OSPF_HEADER_SIZE);
2298
2299 /* Adjust size to message length. */
2300 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2301
2302 /* Read rest of the packet and call each sort of packet routine. */
2303 switch (ospfh->type)
2304 {
2305 case OSPF_MSG_HELLO:
2306 ospf_hello (iph, ospfh, ibuf, oi, length);
2307 break;
2308 case OSPF_MSG_DB_DESC:
2309 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2310 break;
2311 case OSPF_MSG_LS_REQ:
2312 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2313 break;
2314 case OSPF_MSG_LS_UPD:
2315 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2316 break;
2317 case OSPF_MSG_LS_ACK:
2318 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2319 break;
2320 default:
2321 zlog (NULL, LOG_WARNING,
2322 "interface %s: OSPF packet header type %d is illegal",
2323 IF_NAME (oi), ospfh->type);
2324 break;
2325 }
2326
2327 stream_free (ibuf);
2328 return 0;
2329}
2330
2331/* Make OSPF header. */
2332void
2333ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2334{
2335 struct ospf_header *ospfh;
2336
2337 ospfh = (struct ospf_header *) STREAM_DATA (s);
2338
2339 ospfh->version = (u_char) OSPF_VERSION;
2340 ospfh->type = (u_char) type;
2341
2342 ospfh->router_id = ospf_top->router_id;
2343
2344 ospfh->checksum = 0;
2345 ospfh->area_id = oi->area->area_id;
2346 ospfh->auth_type = htons (ospf_auth_type (oi));
2347
2348 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2349
2350 ospf_output_forward (s, OSPF_HEADER_SIZE);
2351}
2352
2353/* Make Authentication Data. */
2354int
2355ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2356{
2357 struct crypt_key *ck;
2358
2359 switch (ospf_auth_type (oi))
2360 {
2361 case OSPF_AUTH_NULL:
2362 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2363 break;
2364 case OSPF_AUTH_SIMPLE:
2365 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2366 OSPF_AUTH_SIMPLE_SIZE);
2367 break;
2368 case OSPF_AUTH_CRYPTOGRAPHIC:
2369 /* If key is not set, then set 0. */
2370 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2371 {
2372 ospfh->u.crypt.zero = 0;
2373 ospfh->u.crypt.key_id = 0;
2374 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2375 }
2376 else
2377 {
2378 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2379 ospfh->u.crypt.zero = 0;
2380 ospfh->u.crypt.key_id = ck->key_id;
2381 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2382 }
2383 /* note: the seq is done in ospf_make_md5_digest() */
2384 break;
2385 default:
2386 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2387 break;
2388 }
2389
2390 return 0;
2391}
2392
2393/* Fill rest of OSPF header. */
2394void
2395ospf_fill_header (struct ospf_interface *oi,
2396 struct stream *s, u_int16_t length)
2397{
2398 struct ospf_header *ospfh;
2399
2400 ospfh = (struct ospf_header *) STREAM_DATA (s);
2401
2402 /* Fill length. */
2403 ospfh->length = htons (length);
2404
2405 /* Calculate checksum. */
2406 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2407 ospfh->checksum = in_cksum (ospfh, length);
2408 else
2409 ospfh->checksum = 0;
2410
2411 /* Add Authentication Data. */
2412 ospf_make_auth (oi, ospfh);
2413}
2414
2415int
2416ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2417{
2418 struct ospf_neighbor *nbr;
2419 struct route_node *rn;
2420 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2421 struct in_addr mask;
2422 unsigned long p;
2423 int flag = 0;
2424
2425 /* Set netmask of interface. */
2426 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2427 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2428 masklen2ip (oi->address->prefixlen, &mask);
2429 else
2430 memset ((char *) &mask, 0, sizeof (struct in_addr));
2431 stream_put_ipv4 (s, mask.s_addr);
2432
2433 /* Set Hello Interval. */
2434 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2435
2436 if (IS_DEBUG_OSPF_EVENT)
2437 zlog_info ("make_hello: options: %x, int: %s",
2438 OPTIONS(oi), IF_NAME (oi));
2439
2440 /* Set Options. */
2441 stream_putc (s, OPTIONS (oi));
2442
2443 /* Set Router Priority. */
2444 stream_putc (s, PRIORITY (oi));
2445
2446 /* Set Router Dead Interval. */
2447 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2448
2449 /* Set Designated Router. */
2450 stream_put_ipv4 (s, DR (oi).s_addr);
2451
2452 p = s->putp;
2453
2454 /* Set Backup Designated Router. */
2455 stream_put_ipv4 (s, BDR (oi).s_addr);
2456
2457 /* Add neighbor seen. */
2458 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
f2c80652 2459 if ((nbr = rn->info) != NULL) {
718e3744 2460 /* ignore 0.0.0.0 node. */
2461 if (nbr->router_id.s_addr != 0)
2462 if (nbr->state != NSM_Attempt)
2463 /* ignore Down neighbor. */
2464 if (nbr->state != NSM_Down)
2465 /* this is myself for DR election. */
2466 if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
2467 {
2468 /* Check neighbor is sane? */
2469 if (nbr->d_router.s_addr != 0 &&
2470 IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4) &&
2471 IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
f2c80652 2472 flag = 0;
718e3744 2473
2474 stream_put_ipv4 (s, nbr->router_id.s_addr);
2475 length += 4;
2476 }
f2c80652 2477 }
718e3744 2478
2479 /* Let neighbor generate BackupSeen. */
2480 if (flag == 1)
2481 {
2482 stream_set_putp (s, p);
2483 stream_put_ipv4 (s, 0);
2484 }
2485
2486 return length;
2487}
2488
2489int
2490ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2491 struct stream *s)
2492{
2493 struct ospf_lsa *lsa;
2494 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2495 u_char options;
2496 unsigned long pp;
2497 int i;
2498 struct ospf_lsdb *lsdb;
2499
2500 /* Set Interface MTU. */
2501 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2502 stream_putw (s, 0);
2503 else
2504 stream_putw (s, oi->ifp->mtu);
2505
2506 /* Set Options. */
2507 options = OPTIONS (oi);
2508#ifdef HAVE_OPAQUE_LSA
2509 if (CHECK_FLAG (ospf_top->config, OSPF_OPAQUE_CAPABLE))
2510 {
2511 if (IS_SET_DD_I (nbr->dd_flags)
2512 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2513 /*
2514 * Set O-bit in the outgoing DD packet for capablity negotiation,
2515 * if one of following case is applicable.
2516 *
2517 * 1) WaitTimer expiration event triggered the neighbor state to
2518 * change to Exstart, but no (valid) DD packet has received
2519 * from the neighbor yet.
2520 *
2521 * 2) At least one DD packet with O-bit on has received from the
2522 * neighbor.
2523 */
2524 SET_FLAG (options, OSPF_OPTION_O);
2525 }
2526#endif /* HAVE_OPAQUE_LSA */
2527 stream_putc (s, options);
2528
2529 /* Keep pointer to flags. */
2530 pp = stream_get_putp (s);
2531 stream_putc (s, nbr->dd_flags);
2532
2533 /* Set DD Sequence Number. */
2534 stream_putl (s, nbr->dd_seqnum);
2535
2536 if (ospf_db_summary_isempty (nbr))
2537 {
2538 if (nbr->state >= NSM_Exchange)
2539 {
2540 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2541 /* Set DD flags again */
2542 stream_set_putp (s, pp);
2543 stream_putc (s, nbr->dd_flags);
2544 }
2545 return length;
2546 }
2547
2548 /* Describe LSA Header from Database Summary List. */
2549 lsdb = &nbr->db_sum;
2550
2551 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2552 {
2553 struct route_table *table = lsdb->type[i].db;
2554 struct route_node *rn;
2555
2556 for (rn = route_top (table); rn; rn = route_next (rn))
2557 if ((lsa = rn->info) != NULL)
2558 {
2559#ifdef HAVE_OPAQUE_LSA
2560 if (IS_OPAQUE_LSA (lsa->data->type)
2561 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2562 {
2563 /* Suppress advertising opaque-informations. */
2564 /* Remove LSA from DB summary list. */
2565 ospf_lsdb_delete (lsdb, lsa);
2566 continue;
2567 }
2568#endif /* HAVE_OPAQUE_LSA */
2569
2570 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2571 {
2572 struct lsa_header *lsah;
2573 u_int16_t ls_age;
2574
2575 /* DD packet overflows interface MTU. */
2576 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2577 break;
2578
2579 /* Keep pointer to LS age. */
2580 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2581 stream_get_putp (s));
2582
2583 /* Proceed stream pointer. */
2584 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2585 length += OSPF_LSA_HEADER_SIZE;
2586
2587 /* Set LS age. */
2588 ls_age = LS_AGE (lsa);
2589 lsah->ls_age = htons (ls_age);
2590
2591 }
2592
2593 /* Remove LSA from DB summary list. */
2594 ospf_lsdb_delete (lsdb, lsa);
2595 }
2596 }
2597
2598 return length;
2599}
2600
2601int
2602ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2603 unsigned long delta, struct ospf_neighbor *nbr,
2604 struct ospf_lsa *lsa)
2605{
2606 struct ospf_interface *oi;
2607
2608 oi = nbr->oi;
2609
2610 /* LS Request packet overflows interface MTU. */
2611 if (*length + delta > OSPF_PACKET_MAX(oi))
2612 return 0;
2613
2614 stream_putl (s, lsa->data->type);
2615 stream_put_ipv4 (s, lsa->data->id.s_addr);
2616 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2617
2618 ospf_lsa_unlock (nbr->ls_req_last);
2619 nbr->ls_req_last = ospf_lsa_lock (lsa);
2620
2621 *length += 12;
2622 return 1;
2623}
2624
2625int
2626ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2627{
2628 struct ospf_lsa *lsa;
2629 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2630 unsigned long delta = stream_get_putp(s)+12;
2631 struct route_table *table;
2632 struct route_node *rn;
2633 int i;
2634 struct ospf_lsdb *lsdb;
2635
2636 lsdb = &nbr->ls_req;
2637
2638 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2639 {
2640 table = lsdb->type[i].db;
2641 for (rn = route_top (table); rn; rn = route_next (rn))
2642 if ((lsa = (rn->info)) != NULL)
2643 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2644 {
2645 route_unlock_node (rn);
2646 break;
2647 }
2648 }
2649 return length;
2650}
2651
2652int
2653ls_age_increment (struct ospf_lsa *lsa, int delay)
2654{
2655 int age;
2656
2657 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2658
2659 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2660}
2661
2662int
2663ospf_make_ls_upd (struct ospf_interface *oi, list update, struct stream *s)
2664{
2665 struct ospf_lsa *lsa;
2666 listnode node;
2667 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2668 unsigned long delta = stream_get_putp (s);
2669 unsigned long pp;
2670 int count = 0;
2671
2672 if (IS_DEBUG_OSPF_EVENT)
2673 zlog_info("ospf_make_ls_upd: Start");
2674
2675 pp = stream_get_putp (s);
2676 ospf_output_forward (s, 4);
2677
2678 while ((node = listhead (update)) != NULL)
2679 {
2680 struct lsa_header *lsah;
2681 u_int16_t ls_age;
2682
2683 if (IS_DEBUG_OSPF_EVENT)
2684 zlog_info("ospf_make_ls_upd: List Iteration");
2685
2686 lsa = getdata (node);
2687 assert (lsa);
2688 assert (lsa->data);
2689
2690 /* Check packet size. */
2691 if (length + delta + ntohs (lsa->data->length) > OSPF_PACKET_MAX (oi))
2692 break;
2693
2694 /* Keep pointer to LS age. */
2695 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2696
2697 /* Put LSA to Link State Request. */
2698 stream_put (s, lsa->data, ntohs (lsa->data->length));
2699
2700 /* Set LS age. */
2701 /* each hop must increment an lsa_age by transmit_delay
2702 of OSPF interface */
2703 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2704 lsah->ls_age = htons (ls_age);
2705
2706 length += ntohs (lsa->data->length);
2707 count++;
2708
2709 list_delete_node (update, node);
2710 ospf_lsa_unlock (lsa);
2711 }
2712
2713 /* Now set #LSAs. */
2714 stream_set_putp (s, pp);
2715 stream_putl (s, count);
2716
2717 stream_set_putp (s, s->endp);
2718
2719 if (IS_DEBUG_OSPF_EVENT)
2720 zlog_info("ospf_make_ls_upd: Stop");
2721 return length;
2722}
2723
2724int
2725ospf_make_ls_ack (struct ospf_interface *oi, list ack, struct stream *s)
2726{
2727 list rm_list;
2728 listnode node;
2729 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2730 unsigned long delta = stream_get_putp(s) + 24;
2731 struct ospf_lsa *lsa;
2732
2733 rm_list = list_new ();
2734
2735 for (node = listhead (ack); node; nextnode (node))
2736 {
2737 lsa = getdata (node);
2738 assert (lsa);
2739
2740 if (length + delta > OSPF_PACKET_MAX (oi))
2741 break;
2742
2743 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2744 length += OSPF_LSA_HEADER_SIZE;
2745
2746 listnode_add (rm_list, lsa);
2747 }
2748
2749 /* Remove LSA from LS-Ack list. */
2750 for (node = listhead (rm_list); node; nextnode (node))
2751 {
2752 lsa = (struct ospf_lsa *) getdata (node);
2753
2754 listnode_delete (ack, lsa);
2755 ospf_lsa_unlock (lsa);
2756 }
2757
2758 list_delete (rm_list);
2759
2760 return length;
2761}
2762
2763void
2764ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2765{
2766 struct ospf_packet *op;
2767 u_int16_t length = OSPF_HEADER_SIZE;
2768
2769 op = ospf_packet_new (oi->ifp->mtu);
2770
2771 /* Prepare OSPF common header. */
2772 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2773
2774 /* Prepare OSPF Hello body. */
2775 length += ospf_make_hello (oi, op->s);
2776
2777 /* Fill OSPF header. */
2778 ospf_fill_header (oi, op->s, length);
2779
2780 /* Set packet length. */
2781 op->length = length;
2782
2783 op->dst.s_addr = addr->s_addr;
2784
2785 /* Add packet to the interface output queue. */
2786 ospf_packet_add (oi, op);
2787
2788 /* Hook thread to write packet. */
2789 OSPF_ISM_WRITE_ON ();
2790}
2791
2792void
2793ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2794{
2795 struct ospf_interface *oi;
2796
2797 oi = nbr_nbma->oi;
2798 assert(oi);
2799
2800 /* If this is passive interface, do not send OSPF Hello. */
2801 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2802 return;
2803
2804 if (oi->type != OSPF_IFTYPE_NBMA)
2805 return;
2806
2807 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2808 return;
2809
2810 if (PRIORITY(oi) == 0)
2811 return;
2812
2813 if (nbr_nbma->priority == 0
2814 && oi->state != ISM_DR && oi->state != ISM_Backup)
2815 return;
2816
2817 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2818}
2819
2820int
2821ospf_poll_timer (struct thread *thread)
2822{
2823 struct ospf_nbr_nbma *nbr_nbma;
2824
2825 nbr_nbma = THREAD_ARG (thread);
2826 nbr_nbma->t_poll = NULL;
2827
2828 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2829 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2830 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2831
2832 ospf_poll_send (nbr_nbma);
2833
2834 if (nbr_nbma->v_poll > 0)
2835 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2836 nbr_nbma->v_poll);
2837
2838 return 0;
2839}
2840
2841
2842int
2843ospf_hello_reply_timer (struct thread *thread)
2844{
2845 struct ospf_neighbor *nbr;
2846
2847 nbr = THREAD_ARG (thread);
2848 nbr->t_hello_reply = NULL;
2849
2850 assert (nbr->oi);
2851
2852 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2853 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2854 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2855
2856 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2857
2858 return 0;
2859}
2860
2861/* Send OSPF Hello. */
2862void
2863ospf_hello_send (struct ospf_interface *oi)
2864{
2865 struct ospf_packet *op;
2866 u_int16_t length = OSPF_HEADER_SIZE;
2867
2868 /* If this is passive interface, do not send OSPF Hello. */
2869 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2870 return;
2871
2872 op = ospf_packet_new (oi->ifp->mtu);
2873
2874 /* Prepare OSPF common header. */
2875 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2876
2877 /* Prepare OSPF Hello body. */
2878 length += ospf_make_hello (oi, op->s);
2879
2880 /* Fill OSPF header. */
2881 ospf_fill_header (oi, op->s, length);
2882
2883 /* Set packet length. */
2884 op->length = length;
2885
2886 if (oi->type == OSPF_IFTYPE_NBMA)
2887 {
2888 struct ospf_neighbor *nbr;
2889 struct route_node *rn;
2890
2891 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2892 if ((nbr = rn->info))
2893 if (nbr != oi->nbr_self)
2894 if (nbr->state != NSM_Down)
2895 {
2896 /* RFC 2328 Section 9.5.1
2897 If the router is not eligible to become Designated Router,
2898 it must periodically send Hello Packets to both the
2899 Designated Router and the Backup Designated Router (if they
2900 exist). */
2901 if (PRIORITY(oi) == 0 &&
2902 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
2903 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
2904 continue;
2905
2906 /* If the router is eligible to become Designated Router, it
2907 must periodically send Hello Packets to all neighbors that
2908 are also eligible. In addition, if the router is itself the
2909 Designated Router or Backup Designated Router, it must also
2910 send periodic Hello Packets to all other neighbors. */
2911
2912 if (nbr->priority == 0 && oi->state == ISM_DROther)
2913 continue;
2914 /* if oi->state == Waiting, send hello to all neighbors */
2915 {
2916 struct ospf_packet *op_dup;
2917
2918 op_dup = ospf_packet_dup(op);
2919 op_dup->dst = nbr->address.u.prefix4;
2920
2921 /* Add packet to the interface output queue. */
2922 ospf_packet_add (oi, op_dup);
2923
2924 OSPF_ISM_WRITE_ON ();
2925 }
2926
2927 }
2928 ospf_packet_free (op);
2929 }
2930 else
2931 {
2932 /* Decide destination address. */
2933 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2934 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
2935 else
2936 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
2937
2938 /* Add packet to the interface output queue. */
2939 ospf_packet_add (oi, op);
2940
2941 /* Hook thread to write packet. */
2942 OSPF_ISM_WRITE_ON ();
2943 }
2944}
2945
2946/* Send OSPF Database Description. */
2947void
2948ospf_db_desc_send (struct ospf_neighbor *nbr)
2949{
2950 struct ospf_interface *oi;
2951 struct ospf_packet *op;
2952 u_int16_t length = OSPF_HEADER_SIZE;
2953
2954 oi = nbr->oi;
2955 op = ospf_packet_new (oi->ifp->mtu);
2956
2957 /* Prepare OSPF common header. */
2958 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
2959
2960 /* Prepare OSPF Database Description body. */
2961 length += ospf_make_db_desc (oi, nbr, op->s);
2962
2963 /* Fill OSPF header. */
2964 ospf_fill_header (oi, op->s, length);
2965
2966 /* Set packet length. */
2967 op->length = length;
2968
2969 /* Decide destination address. */
2970 op->dst = nbr->address.u.prefix4;
2971
2972 /* Add packet to the interface output queue. */
2973 ospf_packet_add (oi, op);
2974
2975 /* Hook thread to write packet. */
2976 OSPF_ISM_WRITE_ON ();
2977
2978 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
2979 if (nbr->last_send)
2980 ospf_packet_free (nbr->last_send);
2981 nbr->last_send = ospf_packet_dup (op);
2982 gettimeofday (&nbr->last_send_ts, NULL);
2983}
2984
2985/* Re-send Database Description. */
2986void
2987ospf_db_desc_resend (struct ospf_neighbor *nbr)
2988{
2989 struct ospf_interface *oi;
2990
2991 oi = nbr->oi;
2992
2993 /* Add packet to the interface output queue. */
2994 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
2995
2996 /* Hook thread to write packet. */
2997 OSPF_ISM_WRITE_ON ();
2998}
2999
3000/* Send Link State Request. */
3001void
3002ospf_ls_req_send (struct ospf_neighbor *nbr)
3003{
3004 struct ospf_interface *oi;
3005 struct ospf_packet *op;
3006 u_int16_t length = OSPF_HEADER_SIZE;
3007
3008 oi = nbr->oi;
3009 op = ospf_packet_new (oi->ifp->mtu);
3010
3011 /* Prepare OSPF common header. */
3012 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3013
3014 /* Prepare OSPF Link State Request body. */
3015 length += ospf_make_ls_req (nbr, op->s);
3016 if (length == OSPF_HEADER_SIZE)
3017 {
3018 ospf_packet_free (op);
3019 return;
3020 }
3021
3022 /* Fill OSPF header. */
3023 ospf_fill_header (oi, op->s, length);
3024
3025 /* Set packet length. */
3026 op->length = length;
3027
3028 /* Decide destination address. */
3029 op->dst = nbr->address.u.prefix4;
3030
3031 /* Add packet to the interface output queue. */
3032 ospf_packet_add (oi, op);
3033
3034 /* Hook thread to write packet. */
3035 OSPF_ISM_WRITE_ON ();
3036
3037 /* Add Link State Request Retransmission Timer. */
3038 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3039}
3040
3041/* Send Link State Update with an LSA. */
3042void
3043ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3044 int flag)
3045{
3046 list update;
3047
3048 update = list_new ();
3049
3050 listnode_add (update, lsa);
3051 ospf_ls_upd_send (nbr, update, flag);
3052
3053 list_delete (update);
3054}
3055
3056static void
3057ospf_ls_upd_queue_send (struct ospf_interface *oi, list update,
3058 struct in_addr addr)
3059{
3060 struct ospf_packet *op;
3061 u_int16_t length = OSPF_HEADER_SIZE;
3062
3063 if (IS_DEBUG_OSPF_EVENT)
3064 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
3065
3066 op = ospf_packet_new (oi->ifp->mtu);
3067
3068 /* Prepare OSPF common header. */
3069 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3070
3071 /* Prepare OSPF Link State Update body. */
3072 /* Includes Type-7 translation. */
3073 length += ospf_make_ls_upd (oi, update, op->s);
3074
3075 /* Fill OSPF header. */
3076 ospf_fill_header (oi, op->s, length);
3077
3078 /* Set packet length. */
3079 op->length = length;
3080
3081 /* Decide destination address. */
3082 op->dst.s_addr = addr.s_addr;
3083
3084 /* Add packet to the interface output queue. */
3085 ospf_packet_add (oi, op);
3086
3087 /* Hook thread to write packet. */
3088 OSPF_ISM_WRITE_ON ();
3089}
3090
3091static int
3092ospf_ls_upd_send_queue_event (struct thread *thread)
3093{
3094 struct ospf_interface *oi = THREAD_ARG(thread);
3095 struct route_node *rn;
3096
3097 oi->t_ls_upd_event = NULL;
3098
3099 if (IS_DEBUG_OSPF_EVENT)
3100 zlog_info ("ospf_ls_upd_send_queue start");
3101
3102 for (rn = route_top (oi->ls_upd_queue); rn; rn = route_next (rn))
3103 {
3104 if (rn->info == NULL)
3105 continue;
3106
3107 while (!list_isempty ((list)rn->info))
3108 ospf_ls_upd_queue_send (oi, rn->info, rn->p.u.prefix4);
3109
3110 list_delete (rn->info);
3111 rn->info = NULL;
3112
3113 route_unlock_node (rn);
3114 }
3115
3116 if (IS_DEBUG_OSPF_EVENT)
3117 zlog_info ("ospf_ls_upd_send_queue stop");
3118 return 0;
3119}
3120
3121void
3122ospf_ls_upd_send (struct ospf_neighbor *nbr, list update, int flag)
3123{
3124 struct ospf_interface *oi;
3125 struct prefix_ipv4 p;
3126 struct route_node *rn;
3127 listnode n;
3128
3129 oi = nbr->oi;
3130
3131 p.family = AF_INET;
3132 p.prefixlen = IPV4_MAX_BITLEN;
3133
3134 /* Decide destination address. */
3135 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3136 p.prefix = oi->vl_data->peer_addr;
3137 else if (flag == OSPF_SEND_PACKET_DIRECT)
3138 p.prefix = nbr->address.u.prefix4;
3139 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3140 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3141 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3142 && (flag == OSPF_SEND_PACKET_INDIRECT))
3143 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
7afa08da 3144 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3145 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
718e3744 3146 else
3147 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3148
3149 if (oi->type == OSPF_IFTYPE_NBMA)
3150 {
3151 if (flag == OSPF_SEND_PACKET_INDIRECT)
3152 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3153 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3154 zlog_warn ("* LS-Update is sent to myself.");
3155 }
3156
3157 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3158
3159 if (rn->info == NULL)
3160 rn->info = list_new ();
3161
3162 for (n = listhead (update); n; nextnode (n))
3163 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3164
3165 if (oi->t_ls_upd_event == NULL)
3166 oi->t_ls_upd_event =
3167 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3168}
3169
3170static void
3171ospf_ls_ack_send_list (struct ospf_interface *oi, list ack, struct in_addr dst)
3172{
3173 struct ospf_packet *op;
3174 u_int16_t length = OSPF_HEADER_SIZE;
3175
3176 op = ospf_packet_new (oi->ifp->mtu);
3177
3178 /* Prepare OSPF common header. */
3179 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3180
3181 /* Prepare OSPF Link State Acknowledgment body. */
3182 length += ospf_make_ls_ack (oi, ack, op->s);
3183
3184 /* Fill OSPF header. */
3185 ospf_fill_header (oi, op->s, length);
3186
3187 /* Set packet length. */
3188 op->length = length;
3189
3190 /* Set destination IP address. */
3191 op->dst = dst;
3192
3193 /* Add packet to the interface output queue. */
3194 ospf_packet_add (oi, op);
3195
3196 /* Hook thread to write packet. */
3197 OSPF_ISM_WRITE_ON ();
3198}
3199
3200static int
3201ospf_ls_ack_send_event (struct thread *thread)
3202{
3203 struct ospf_interface *oi = THREAD_ARG (thread);
3204
3205 oi->t_ls_ack_direct = NULL;
3206
3207 while (listcount (oi->ls_ack_direct.ls_ack))
3208 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3209 oi->ls_ack_direct.dst);
3210
3211 return 0;
3212}
3213
3214void
3215ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3216{
3217 struct ospf_interface *oi = nbr->oi;
3218
3219 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3220 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3221
3222 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3223
3224 if (oi->t_ls_ack_direct == NULL)
3225 oi->t_ls_ack_direct =
3226 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3227}
3228
3229/* Send Link State Acknowledgment delayed. */
3230void
3231ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3232{
3233 struct in_addr dst;
3234
3235 /* Decide destination address. */
3236 /* RFC2328 Section 13.5 On non-broadcast
3237 networks, delayed Link State Acknowledgment packets must be
3238 unicast separately over each adjacency (i.e., neighbor whose
3239 state is >= Exchange). */
3240 if (oi->type == OSPF_IFTYPE_NBMA)
3241 {
3242 struct ospf_neighbor *nbr;
3243 struct route_node *rn;
3244
3245 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3246 if ((nbr = rn->info) != NULL)
3247 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3248 while (listcount (oi->ls_ack))
3249 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3250 return;
3251 }
3252 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3253 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3254 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3255 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3256 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3257 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3258 else
3259 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3260
3261 while (listcount (oi->ls_ack))
3262 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3263}