blob: 5952d184e13b32ceb577c07dc73acc67768398c9 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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"
paul2dd8bb42004-07-23 15:13:48 +000034#include "sockopt.h"
paul718e3742002-12-13 20:15:29 +000035#include "md5-gnu.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_flood.h"
49#include "ospfd/ospf_dump.h"
50
hasso52dc7ee2004-09-23 19:18:23 +000051static void ospf_ls_ack_send_list (struct ospf_interface *, struct list *,
paul718e3742002-12-13 20:15:29 +000052 struct in_addr);
53
54/* Packet Type String. */
55char *ospf_packet_type_str[] =
56{
57 "unknown",
58 "Hello",
59 "Database Description",
60 "Link State Request",
61 "Link State Update",
62 "Link State Acknowledgment",
63};
64
65extern int in_cksum (void *ptr, int nbytes);
66
67/* OSPF authentication checking function */
68int
69ospf_auth_type (struct ospf_interface *oi)
70{
71 int auth_type;
72
73 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
74 auth_type = oi->area->auth_type;
75 else
76 auth_type = OSPF_IF_PARAM (oi, auth_type);
77
78 /* Handle case where MD5 key list is not configured aka Cisco */
79 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
80 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
81 return OSPF_AUTH_NULL;
82
83 return auth_type;
84
85}
86
87/* forward output pointer. */
88void
89ospf_output_forward (struct stream *s, int size)
90{
91 s->putp += size;
92}
93
94struct ospf_packet *
95ospf_packet_new (size_t size)
96{
97 struct ospf_packet *new;
98
99 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
100 new->s = stream_new (size);
101
102 return new;
103}
104
105void
106ospf_packet_free (struct ospf_packet *op)
107{
108 if (op->s)
109 stream_free (op->s);
110
111 XFREE (MTYPE_OSPF_PACKET, op);
112
113 op = NULL;
114}
115
116struct ospf_fifo *
117ospf_fifo_new ()
118{
119 struct ospf_fifo *new;
120
121 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
122 return new;
123}
124
125/* Add new packet to fifo. */
126void
127ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
128{
129 if (fifo->tail)
130 fifo->tail->next = op;
131 else
132 fifo->head = op;
133
134 fifo->tail = op;
135
136 fifo->count++;
137}
138
139/* Delete first packet from fifo. */
140struct ospf_packet *
141ospf_fifo_pop (struct ospf_fifo *fifo)
142{
143 struct ospf_packet *op;
144
145 op = fifo->head;
146
147 if (op)
148 {
149 fifo->head = op->next;
150
151 if (fifo->head == NULL)
152 fifo->tail = NULL;
153
154 fifo->count--;
155 }
156
157 return op;
158}
159
160/* Return first fifo entry. */
161struct ospf_packet *
162ospf_fifo_head (struct ospf_fifo *fifo)
163{
164 return fifo->head;
165}
166
167/* Flush ospf packet fifo. */
168void
169ospf_fifo_flush (struct ospf_fifo *fifo)
170{
171 struct ospf_packet *op;
172 struct ospf_packet *next;
173
174 for (op = fifo->head; op; op = next)
175 {
176 next = op->next;
177 ospf_packet_free (op);
178 }
179 fifo->head = fifo->tail = NULL;
180 fifo->count = 0;
181}
182
183/* Free ospf packet fifo. */
184void
185ospf_fifo_free (struct ospf_fifo *fifo)
186{
187 ospf_fifo_flush (fifo);
188
189 XFREE (MTYPE_OSPF_FIFO, fifo);
190}
191
192void
193ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
194{
195 /* Add packet to end of queue. */
196 ospf_fifo_push (oi->obuf, op);
197
198 /* Debug of packet fifo*/
199 /* ospf_fifo_debug (oi->obuf); */
200}
201
202void
203ospf_packet_delete (struct ospf_interface *oi)
204{
205 struct ospf_packet *op;
206
207 op = ospf_fifo_pop (oi->obuf);
208
209 if (op)
210 ospf_packet_free (op);
211}
212
213struct stream *
214ospf_stream_copy (struct stream *new, struct stream *s)
215{
216 new->endp = s->endp;
217 new->putp = s->putp;
218 new->getp = s->getp;
219
220 memcpy (new->data, s->data, stream_get_endp (s));
221
222 return new;
223}
224
225struct ospf_packet *
226ospf_packet_dup (struct ospf_packet *op)
227{
228 struct ospf_packet *new;
229
paul37163d62003-02-03 18:40:56 +0000230 if (stream_get_endp(op->s) != op->length)
231 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000232 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000233
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);
paul718e3742002-12-13 20:15:29 +0000236 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)
paul68b73392004-09-12 14:21:37 +0000250 max = oi->ifp->mtu - OSPF_AUTH_MD5_SIZE;
paul718e3742002-12-13 20:15:29 +0000251 else
paul68b73392004-09-12 14:21:37 +0000252 max = oi->ifp->mtu;
253
254 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000255
256 return max;
257}
258
259
260int
261ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
262 u_int16_t length)
263{
264 void *ibuf;
265 struct md5_ctx ctx;
266 unsigned char digest[OSPF_AUTH_MD5_SIZE];
267 unsigned char *pdigest;
268 struct crypt_key *ck;
269 struct ospf_header *ospfh;
270 struct ospf_neighbor *nbr;
271
272
273 ibuf = STREAM_PNT (s);
274 ospfh = (struct ospf_header *) ibuf;
275
276 /* Get pointer to the end of the packet. */
277 pdigest = ibuf + length;
278
279 /* Get secret key. */
280 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
281 ospfh->u.crypt.key_id);
282 if (ck == NULL)
283 {
284 zlog_warn ("interface %s: ospf_check_md5 no key %d",
285 IF_NAME (oi), ospfh->u.crypt.key_id);
286 return 0;
287 }
288
289 /* check crypto seqnum. */
290 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
291
292 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
293 {
294 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
295 IF_NAME (oi),
296 ntohl(ospfh->u.crypt.crypt_seqnum),
297 ntohl(nbr->crypt_seqnum));
298 return 0;
299 }
300
301 /* Generate a digest for the ospf packet - their digest + our digest. */
302 md5_init_ctx (&ctx);
303 md5_process_bytes (ibuf, length, &ctx);
304 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
305 md5_finish_ctx (&ctx, digest);
306
307 /* compare the two */
308 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
309 {
310 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
311 IF_NAME (oi));
312 return 0;
313 }
314
315 /* save neighbor's crypt_seqnum */
316 if (nbr)
317 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
318 return 1;
319}
320
321/* This function is called from ospf_write(), it will detect the
322 authentication scheme and if it is MD5, it will change the sequence
323 and update the MD5 digest. */
324int
325ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
326{
327 struct ospf_header *ospfh;
328 unsigned char digest[OSPF_AUTH_MD5_SIZE];
329 struct md5_ctx ctx;
330 void *ibuf;
331 unsigned long oldputp;
paul9483e152002-12-13 20:55:25 +0000332 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000333 struct crypt_key *ck;
334 char *auth_key;
335
336 ibuf = STREAM_DATA (op->s);
337 ospfh = (struct ospf_header *) ibuf;
338
339 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
340 return 0;
341
342 /* We do this here so when we dup a packet, we don't have to
343 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000344 t = (time(NULL) & 0xFFFFFFFF);
345 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
346 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000347
348 /* Get MD5 Authentication key from auth_key list. */
349 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
350 auth_key = "";
351 else
352 {
353 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
354 auth_key = ck->auth_key;
355 }
356
357 /* Generate a digest for the entire packet + our secret key. */
358 md5_init_ctx (&ctx);
359 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
360 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
361 md5_finish_ctx (&ctx, digest);
362
363 /* Append md5 digest to the end of the stream. */
364 oldputp = stream_get_putp (op->s);
365 stream_set_putp (op->s, ntohs (ospfh->length));
366 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
367 stream_set_putp (op->s, oldputp);
368
369 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000370 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
371
paul37163d62003-02-03 18:40:56 +0000372 if (stream_get_endp(op->s) != op->length)
373 zlog_warn("ospf_make_md5_digest: length mismatch stream %ld ospf_packet %d", stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000374
375 return OSPF_AUTH_MD5_SIZE;
376}
377
378
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 {
hasso52dc7ee2004-09-23 19:18:23 +0000421 struct list *update;
paul718e3742002-12-13 20:15:29 +0000422 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
paul68b73392004-09-12 14:21:37 +0000485/* swab ip header fields to required order for sendmsg */
486void
487ospf_swab_iph_ton (struct ip *iph)
488{
489 /* BSD and derived take iph in network order, except for
490 * ip_len and ip_off
491 */
492#ifdef GNU_LINUX
493 iph->ip_len = htons(iph->ip_len);
494 iph->ip_off = htons(iph->ip_off);
495#endif
496 iph->ip_id = htons(iph->ip_id);
497}
498
499/* swab ip header fields to host order, as required */
500void
501ospf_swab_iph_toh (struct ip *iph)
502{
503#ifdef GNU_LINUX
504 iph->ip_len = ntohs(iph->ip_len);
505 iph->ip_off = ntohs(iph->ip_off);
506#endif
507 iph->ip_id = ntohs(iph->ip_id);
508}
509
paul0bfeca32004-09-24 08:07:54 +0000510#ifdef WANT_OSPF_WRITE_FRAGMENT
511void
512ospf_write_frags (struct ospf_packet *op, struct ip *ip, struct msghdr *msg,
513 struct iovec *iov, int maxdatasize);
514{
515#define OSPF_WRITE_FRAG_SHIFT 3
516
517 assert ( op->length == stream_get_endp(op->s) );
518
519 /* we can but try.
520 *
521 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
522 * well as the IP_MF flag, making this all quite pointless.
523 *
524 * However, for a system on which IP_MF is left alone, and ip_id left
525 * alone or else which sets same ip_id for each fragment this might
526 * work, eg linux.
527 *
528 * XXX-TODO: It would be much nicer to have the kernel's use their
529 * existing fragmentation support to do this for us. Bugs/RFEs need to
530 * be raised against the various kernels.
531 */
532
533 /* set More Frag */
534 iph->ip_off |= IP_MF;
535
536 /* ip frag offset is expressed in units of 8byte words */
537 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
538
539 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
540 > maxdatasize )
541 {
542 /* data length of this frag is to next offset value */
543 iov[1]->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
544 iph->ip_len = iov[1]->iov_len + sizeof (struct ip);
545 assert (iph->ip_len <= oi->ifp->mtu);
546
547 ospf_swab_iph_ton (iph);
548
549 ret = sendmsg (ospf->fd, msg, flags);
550
551 ospf_swab_iph_toh (iph);
552
553 if (ret < 0)
554 zlog_warn ("*** sendmsg in ospf_write to %s,"
555 " id %d, off %d, len %d failed with %s",
556 inet_ntoa (iph->ip_dst),
557 iph->ip_id,
558 iph->ip_off,
559 iph->ip_len,
560 strerror (errno));
561
562 iph->ip_off += offset;
563 stream_forward (op->s, iov[1]->iov_len);
564 iov[1]->iov_base = STREAM_PNT (op->s);
565 }
566
567 /* setup for final fragment */
568 iov[1]->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
569 iph->ip_len = iov[1]->iov_len + sizeof (struct ip);
570 iph->ip_off &= (~IP_MF);
571}
572#endif /* WANT_OSPF_WRITE_FRAGMENT */
573
paul718e3742002-12-13 20:15:29 +0000574int
575ospf_write (struct thread *thread)
576{
paul68980082003-03-25 05:07:42 +0000577 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000578 struct ospf_interface *oi;
579 struct ospf_packet *op;
580 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000581 struct ip iph;
582 struct msghdr msg;
583 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000584 u_char type;
585 int ret;
586 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000587 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000588#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000589 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000590#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000591 u_int16_t maxdatasize, offset;
592#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000593
paul68980082003-03-25 05:07:42 +0000594 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000595
paul68980082003-03-25 05:07:42 +0000596 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000597 assert (node);
598 oi = getdata (node);
599 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000600
601#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000602 /* seed ipid static with low order bits of time */
603 if (ipid == 0)
604 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000605#endif /* WANT_OSPF_WRITE_FRAGMENT */
606
paul68b73392004-09-12 14:21:37 +0000607 /* convenience - max OSPF data per packet */
608 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
609
paul718e3742002-12-13 20:15:29 +0000610 /* Get one packet from queue. */
611 op = ospf_fifo_head (oi->obuf);
612 assert (op);
613 assert (op->length >= OSPF_HEADER_SIZE);
614
paul68980082003-03-25 05:07:42 +0000615 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
616 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000617 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
618
paul718e3742002-12-13 20:15:29 +0000619 /* Rewrite the md5 signature & update the seq */
620 ospf_make_md5_digest (oi, op);
621
paul68b73392004-09-12 14:21:37 +0000622 /* reset get pointer */
623 stream_set_getp (op->s, 0);
624
625 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000626 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000627
paul718e3742002-12-13 20:15:29 +0000628 sa_dst.sin_family = AF_INET;
629#ifdef HAVE_SIN_LEN
630 sa_dst.sin_len = sizeof(sa_dst);
631#endif /* HAVE_SIN_LEN */
632 sa_dst.sin_addr = op->dst;
633 sa_dst.sin_port = htons (0);
634
635 /* Set DONTROUTE flag if dst is unicast. */
636 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
637 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
638 flags = MSG_DONTROUTE;
639
paul68b73392004-09-12 14:21:37 +0000640 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
641 /* it'd be very strange for header to not be 4byte-word aligned but.. */
642 if ( sizeof (struct ip) > (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
643 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
644
paul718e3742002-12-13 20:15:29 +0000645 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000646 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000647 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000648
paul0bfeca32004-09-24 08:07:54 +0000649#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000650 /* XXX-MT: not thread-safe at all..
651 * XXX: this presumes this is only programme sending OSPF packets
652 * otherwise, no guarantee ipid will be unique
653 */
654 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000655#endif /* WANT_OSPF_WRITE_FRAGMENT */
656
paul718e3742002-12-13 20:15:29 +0000657 iph.ip_off = 0;
658 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
659 iph.ip_ttl = OSPF_VL_IP_TTL;
660 else
661 iph.ip_ttl = OSPF_IP_TTL;
662 iph.ip_p = IPPROTO_OSPFIGP;
663 iph.ip_sum = 0;
664 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
665 iph.ip_dst.s_addr = op->dst.s_addr;
666
667 memset (&msg, 0, sizeof (msg));
668 msg.msg_name = &sa_dst;
669 msg.msg_namelen = sizeof (sa_dst);
670 msg.msg_iov = iov;
671 msg.msg_iovlen = 2;
672 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000673 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
674 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000675 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000676
677 /* Sadly we can not rely on kernels to fragment packets because of either
678 * IP_HDRINCL and/or multicast destination being set.
679 */
paul0bfeca32004-09-24 08:07:54 +0000680#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000681 if ( op->length > maxdatasize )
paul0bfeca32004-09-24 08:07:54 +0000682 ospf_write_frags (&op, &ip, &msg, &iov, maxdatasize);
683#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000684
685 /* send final fragment (could be first) */
686 ospf_swab_iph_ton (&iph);
paul68980082003-03-25 05:07:42 +0000687 ret = sendmsg (ospf->fd, &msg, flags);
paul68b73392004-09-12 14:21:37 +0000688 ospf_swab_iph_toh (&iph);
paul718e3742002-12-13 20:15:29 +0000689
690 if (ret < 0)
paul68b73392004-09-12 14:21:37 +0000691 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
692 inet_ntoa (iph.ip_dst), strerror (errno));
paul718e3742002-12-13 20:15:29 +0000693
694 /* Retrieve OSPF packet type. */
695 stream_set_getp (op->s, 1);
696 type = stream_getc (op->s);
697
698 /* Show debug sending packet. */
699 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
700 {
701 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
702 {
703 zlog_info ("-----------------------------------------------------");
704 stream_set_getp (op->s, 0);
705 ospf_packet_dump (op->s);
706 }
707
708 zlog_info ("%s sent to [%s] via [%s].",
709 ospf_packet_type_str[type], inet_ntoa (op->dst),
710 IF_NAME (oi));
711
712 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
713 zlog_info ("-----------------------------------------------------");
714 }
715
716 /* Now delete packet from queue. */
717 ospf_packet_delete (oi);
718
719 if (ospf_fifo_head (oi->obuf) == NULL)
720 {
721 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000722 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000723 }
724
725 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000726 if (!list_isempty (ospf->oi_write_q))
727 ospf->t_write =
728 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000729
730 return 0;
731}
732
733/* OSPF Hello message read -- RFC2328 Section 10.5. */
734void
735ospf_hello (struct ip *iph, struct ospf_header *ospfh,
736 struct stream * s, struct ospf_interface *oi, int size)
737{
738 struct ospf_hello *hello;
739 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000740 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000741 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000742
743 /* increment statistics. */
744 oi->hello_in++;
745
746 hello = (struct ospf_hello *) STREAM_PNT (s);
747
748 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000749 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000750 {
751 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
752 {
753 zlog_info ("ospf_header[%s/%s]: selforiginated, "
754 "dropping.",
755 ospf_packet_type_str[ospfh->type],
756 inet_ntoa (iph->ip_src));
757 }
758 return;
759 }
paul718e3742002-12-13 20:15:29 +0000760
761 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000762 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
paulc2191ea2003-04-18 23:59:35 +0000763 zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
764 inet_ntoa (ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000765 return;
paulf2c80652002-12-13 21:44:27 +0000766 }
paul718e3742002-12-13 20:15:29 +0000767
768 /* get neighbor prefix. */
769 p.family = AF_INET;
770 p.prefixlen = ip_masklen (hello->network_mask);
771 p.u.prefix4 = iph->ip_src;
772
773 /* Compare network mask. */
774 /* Checking is ignored for Point-to-Point and Virtual link. */
775 if (oi->type != OSPF_IFTYPE_POINTOPOINT
776 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
777 if (oi->address->prefixlen != p.prefixlen)
778 {
779 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
780 inet_ntoa (ospfh->router_id));
781 return;
782 }
783
784 /* Compare Hello Interval. */
785 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
786 {
787 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
788 inet_ntoa (ospfh->router_id));
789 return;
790 }
791
792 /* Compare Router Dead Interval. */
793 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
794 {
795 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
796 inet_ntoa (ospfh->router_id));
797 return;
798 }
799
800 if (IS_DEBUG_OSPF_EVENT)
801 zlog_info ("Packet %s [Hello:RECV]: Options %s",
802 inet_ntoa (ospfh->router_id),
803 ospf_options_dump (hello->options));
804
805 /* Compare options. */
806#define REJECT_IF_TBIT_ON 1 /* XXX */
807#ifdef REJECT_IF_TBIT_ON
808 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
809 {
810 /*
811 * This router does not support non-zero TOS.
812 * Drop this Hello packet not to establish neighbor relationship.
813 */
814 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
815 inet_ntoa (ospfh->router_id));
816 return;
817 }
818#endif /* REJECT_IF_TBIT_ON */
819
820#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000821 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000822 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
823 {
824 /*
825 * This router does know the correct usage of O-bit
826 * the bit should be set in DD packet only.
827 */
828 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
829 inet_ntoa (ospfh->router_id));
830#ifdef STRICT_OBIT_USAGE_CHECK
831 return; /* Reject this packet. */
832#else /* STRICT_OBIT_USAGE_CHECK */
833 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
834#endif /* STRICT_OBIT_USAGE_CHECK */
835 }
836#endif /* HAVE_OPAQUE_LSA */
837
838 /* new for NSSA is to ensure that NP is on and E is off */
839
paul718e3742002-12-13 20:15:29 +0000840 if (oi->area->external_routing == OSPF_AREA_NSSA)
841 {
842 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
843 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
844 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
845 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
846 {
847 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
848 return;
849 }
850 if (IS_DEBUG_OSPF_NSSA)
851 zlog_info ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
852 }
853 else
paul718e3742002-12-13 20:15:29 +0000854 /* The setting of the E-bit found in the Hello Packet's Options
855 field must match this area's ExternalRoutingCapability A
856 mismatch causes processing to stop and the packet to be
857 dropped. The setting of the rest of the bits in the Hello
858 Packet's Options field should be ignored. */
859 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
860 CHECK_FLAG (hello->options, OSPF_OPTION_E))
861 {
862 zlog_warn ("Packet[Hello:RECV]: my options: %x, his options %x",
863 OPTIONS (oi), hello->options);
864 return;
865 }
paul718e3742002-12-13 20:15:29 +0000866
pauld3f0d622004-05-05 15:27:15 +0000867 /* get neighbour struct */
868 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
869
870 /* neighbour must be valid, ospf_nbr_get creates if none existed */
871 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000872
873 old_state = nbr->state;
874
875 /* Add event to thread. */
876 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
877
878 /* RFC2328 Section 9.5.1
879 If the router is not eligible to become Designated Router,
880 (snip) It must also send an Hello Packet in reply to an
881 Hello Packet received from any eligible neighbor (other than
882 the current Designated Router and Backup Designated Router). */
883 if (oi->type == OSPF_IFTYPE_NBMA)
884 if (PRIORITY(oi) == 0 && hello->priority > 0
885 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
886 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
887 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
888 OSPF_HELLO_REPLY_DELAY);
889
890 /* on NBMA network type, it happens to receive bidirectional Hello packet
891 without advance 1-Way Received event.
892 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
893 if (oi->type == OSPF_IFTYPE_NBMA &&
894 (old_state == NSM_Down || old_state == NSM_Attempt))
895 {
896 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
897 nbr->priority = hello->priority;
898 nbr->d_router = hello->d_router;
899 nbr->bd_router = hello->bd_router;
900 return;
901 }
902
paul68980082003-03-25 05:07:42 +0000903 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000904 size - OSPF_HELLO_MIN_SIZE))
905 {
906 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
907 nbr->options |= hello->options;
908 }
909 else
910 {
911 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
912 /* Set neighbor information. */
913 nbr->priority = hello->priority;
914 nbr->d_router = hello->d_router;
915 nbr->bd_router = hello->bd_router;
916 return;
917 }
918
919 /* If neighbor itself declares DR and no BDR exists,
920 cause event BackupSeen */
921 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
922 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
923 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
924
925 /* neighbor itself declares BDR. */
926 if (oi->state == ISM_Waiting &&
927 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
928 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
929
930 /* had not previously. */
931 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
932 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
933 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
934 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
935 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
936
937 /* had not previously. */
938 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
939 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
940 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
941 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
942 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
943
944 /* Neighbor priority check. */
945 if (nbr->priority >= 0 && nbr->priority != hello->priority)
946 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
947
948 /* Set neighbor information. */
949 nbr->priority = hello->priority;
950 nbr->d_router = hello->d_router;
951 nbr->bd_router = hello->bd_router;
952}
953
954/* Save DD flags/options/Seqnum received. */
955void
956ospf_db_desc_save_current (struct ospf_neighbor *nbr,
957 struct ospf_db_desc *dd)
958{
959 nbr->last_recv.flags = dd->flags;
960 nbr->last_recv.options = dd->options;
961 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
962}
963
964/* Process rest of DD packet. */
965static void
966ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
967 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
968 u_int16_t size)
969{
970 struct ospf_lsa *new, *find;
971 struct lsa_header *lsah;
972
973 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
974 for (size -= OSPF_DB_DESC_MIN_SIZE;
975 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
976 {
977 lsah = (struct lsa_header *) STREAM_PNT (s);
978 stream_forward (s, OSPF_LSA_HEADER_SIZE);
979
980 /* Unknown LS type. */
981 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
982 {
983 zlog_warn ("Pakcet [DD:RECV]: Unknown LS type %d.", lsah->type);
984 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
985 return;
986 }
987
988#ifdef HAVE_OPAQUE_LSA
989 if (IS_OPAQUE_LSA (lsah->type)
990 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
991 {
992 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
993 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
994 return;
995 }
996#endif /* HAVE_OPAQUE_LSA */
997
998 switch (lsah->type)
999 {
1000 case OSPF_AS_EXTERNAL_LSA:
1001#ifdef HAVE_OPAQUE_LSA
1002 case OSPF_OPAQUE_AS_LSA:
1003#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001004 /* Check for stub area. Reject if AS-External from stub but
1005 allow if from NSSA. */
1006 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001007 {
1008 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1009 lsah->type, inet_ntoa (lsah->id),
1010 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1011 "STUB" : "NSSA");
1012 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1013 return;
1014 }
1015 break;
1016 default:
1017 break;
1018 }
1019
1020 /* Create LS-request object. */
1021 new = ospf_ls_request_new (lsah);
1022
1023 /* Lookup received LSA, then add LS request list. */
1024 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1025 if (!find || ospf_lsa_more_recent (find, new) < 0)
1026 {
1027 ospf_ls_request_add (nbr, new);
1028 ospf_lsa_discard (new);
1029 }
1030 else
1031 {
1032 /* Received LSA is not recent. */
1033 if (IS_DEBUG_OSPF_EVENT)
1034 zlog_info ("Packet [DD:RECV]: LSA received Type %d, "
1035 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1036 ospf_lsa_discard (new);
1037 continue;
1038 }
1039 }
1040
1041 /* Master */
1042 if (IS_SET_DD_MS (nbr->dd_flags))
1043 {
1044 nbr->dd_seqnum++;
1045 /* Entire DD packet sent. */
1046 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1047 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1048 else
1049 /* Send new DD packet. */
1050 ospf_db_desc_send (nbr);
1051 }
1052 /* Slave */
1053 else
1054 {
1055 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1056
1057 /* When master's more flags is not set. */
1058 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1059 {
1060 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1061 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1062 }
1063
1064 /* Send DD pakcet in reply. */
1065 ospf_db_desc_send (nbr);
1066 }
1067
1068 /* Save received neighbor values from DD. */
1069 ospf_db_desc_save_current (nbr, dd);
1070}
1071
1072int
1073ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1074{
1075 /* Is DD duplicated? */
1076 if (dd->options == nbr->last_recv.options &&
1077 dd->flags == nbr->last_recv.flags &&
1078 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1079 return 1;
1080
1081 return 0;
1082}
1083
1084/* OSPF Database Description message read -- RFC2328 Section 10.6. */
1085void
1086ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1087 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1088{
1089 struct ospf_db_desc *dd;
1090 struct ospf_neighbor *nbr;
1091
1092 /* Increment statistics. */
1093 oi->db_desc_in++;
1094
1095 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001096
pauld3f0d622004-05-05 15:27:15 +00001097 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001098 if (nbr == NULL)
1099 {
1100 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1101 inet_ntoa (ospfh->router_id));
1102 return;
1103 }
1104
1105 /* Check MTU. */
1106 if (ntohs (dd->mtu) > oi->ifp->mtu)
1107 {
1108 zlog_warn ("Packet[DD]: MTU is larger than [%s]'s MTU", IF_NAME (oi));
1109 return;
1110 }
1111
pauld363df22003-06-19 00:26:34 +00001112 /*
1113 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1114 * required. In fact at least JunOS sends DD packets with P bit clear.
1115 * Until proper solution is developped, this hack should help.
1116 *
1117 * Update: According to the RFCs, N bit is specified /only/ for Hello
1118 * options, unfortunately its use in DD options is not specified. Hence some
1119 * implementations follow E-bit semantics and set it in DD options, and some
1120 * treat it as unspecified and hence follow the directive "default for
1121 * options is clear", ie unset.
1122 *
1123 * Reset the flag, as ospfd follows E-bit semantics.
1124 */
1125 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1126 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1127 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1128 {
1129 if (IS_DEBUG_OSPF_EVENT)
paul3db0a772003-06-19 01:07:40 +00001130 zlog_notice ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001131 inet_ntoa (nbr->router_id) );
1132 SET_FLAG (dd->options, OSPF_OPTION_NP);
1133 }
pauld363df22003-06-19 00:26:34 +00001134
paul718e3742002-12-13 20:15:29 +00001135#ifdef REJECT_IF_TBIT_ON
1136 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1137 {
1138 /*
1139 * In Hello protocol, optional capability must have checked
1140 * to prevent this T-bit enabled router be my neighbor.
1141 */
1142 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1143 return;
1144 }
1145#endif /* REJECT_IF_TBIT_ON */
1146
1147#ifdef HAVE_OPAQUE_LSA
1148 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001149 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001150 {
1151 /*
1152 * This node is not configured to handle O-bit, for now.
1153 * Clear it to ignore unsupported capability proposed by neighbor.
1154 */
1155 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1156 }
1157#endif /* HAVE_OPAQUE_LSA */
1158
1159 /* Process DD packet by neighbor status. */
1160 switch (nbr->state)
1161 {
1162 case NSM_Down:
1163 case NSM_Attempt:
1164 case NSM_TwoWay:
1165 zlog_warn ("Packet[DD]: Neighbor state is %s, packet discarded.",
1166 LOOKUP (ospf_nsm_state_msg, nbr->state));
1167 break;
1168 case NSM_Init:
1169 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1170 /* If the new state is ExStart, the processing of the current
1171 packet should then continue in this new state by falling
1172 through to case ExStart below. */
1173 if (nbr->state != NSM_ExStart)
1174 break;
1175 case NSM_ExStart:
1176 /* Initial DBD */
1177 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1178 (size == OSPF_DB_DESC_MIN_SIZE))
1179 {
paul68980082003-03-25 05:07:42 +00001180 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001181 {
1182 /* We're Slave---obey */
1183 zlog_warn ("Packet[DD]: Negotiation done (Slave).");
1184 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1185 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1186 }
1187 else
1188 {
1189 /* We're Master, ignore the initial DBD from Slave */
1190 zlog_warn ("Packet[DD]: Initial DBD from Slave, ignoring.");
1191 break;
1192 }
1193 }
1194 /* Ack from the Slave */
1195 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1196 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001197 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001198 {
1199 zlog_warn ("Packet[DD]: Negotiation done (Master).");
1200 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1201 }
1202 else
1203 {
1204 zlog_warn ("Packet[DD]: Negotiation fails.");
1205 break;
1206 }
1207
1208 /* This is where the real Options are saved */
1209 nbr->options = dd->options;
1210
1211#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001212 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001213 {
1214 if (IS_DEBUG_OSPF_EVENT)
1215 zlog_info ("Neighbor[%s] is %sOpaque-capable.",
1216 inet_ntoa (nbr->router_id),
1217 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1218
1219 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1220 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1221 {
1222 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1223 /* This situation is undesirable, but not a real error. */
1224 }
1225 }
1226#endif /* HAVE_OPAQUE_LSA */
1227
1228 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1229
1230 /* continue processing rest of packet. */
1231 ospf_db_desc_proc (s, oi, nbr, dd, size);
1232 break;
1233 case NSM_Exchange:
1234 if (ospf_db_desc_is_dup (dd, nbr))
1235 {
1236 if (IS_SET_DD_MS (nbr->dd_flags))
1237 /* Master: discard duplicated DD packet. */
1238 zlog_warn ("Packet[DD] (Master): packet duplicated.");
1239 else
1240 /* Slave: cause to retransmit the last Database Description. */
1241 {
1242 zlog_warn ("Packet[DD] [Slave]: packet duplicated.");
1243 ospf_db_desc_resend (nbr);
1244 }
1245 break;
1246 }
1247
1248 /* Otherwise DD packet should be checked. */
1249 /* Check Master/Slave bit mismatch */
1250 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1251 {
1252 zlog_warn ("Packet[DD]: MS-bit mismatch.");
1253 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1254 if (IS_DEBUG_OSPF_EVENT)
1255 zlog_info ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1256 dd->flags, nbr->dd_flags);
1257 break;
1258 }
1259
1260 /* Check initialize bit is set. */
1261 if (IS_SET_DD_I (dd->flags))
1262 {
1263 zlog_warn ("Packet[DD]: I-bit set.");
1264 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1265 break;
1266 }
1267
1268 /* Check DD Options. */
1269 if (dd->options != nbr->options)
1270 {
1271#ifdef ORIGINAL_CODING
1272 /* Save the new options for debugging */
1273 nbr->options = dd->options;
1274#endif /* ORIGINAL_CODING */
1275 zlog_warn ("Packet[DD]: options mismatch.");
1276 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1277 break;
1278 }
1279
1280 /* Check DD sequence number. */
1281 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1282 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1283 (!IS_SET_DD_MS (nbr->dd_flags) &&
1284 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1285 {
1286 zlog_warn ("Pakcet[DD]: sequence number mismatch.");
1287 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1288 break;
1289 }
1290
1291 /* Continue processing rest of packet. */
1292 ospf_db_desc_proc (s, oi, nbr, dd, size);
1293 break;
1294 case NSM_Loading:
1295 case NSM_Full:
1296 if (ospf_db_desc_is_dup (dd, nbr))
1297 {
1298 if (IS_SET_DD_MS (nbr->dd_flags))
1299 {
1300 /* Master should discard duplicate DD packet. */
1301 zlog_warn ("Pakcet[DD]: duplicated, packet discarded.");
1302 break;
1303 }
1304 else
1305 {
1306 struct timeval t, now;
1307 gettimeofday (&now, NULL);
1308 t = tv_sub (now, nbr->last_send_ts);
1309 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1310 {
1311 /* In states Loading and Full the slave must resend
1312 its last Database Description packet in response to
1313 duplicate Database Description packets received
1314 from the master. For this reason the slave must
1315 wait RouterDeadInterval seconds before freeing the
1316 last Database Description packet. Reception of a
1317 Database Description packet from the master after
1318 this interval will generate a SeqNumberMismatch
1319 neighbor event. RFC2328 Section 10.8 */
1320 ospf_db_desc_resend (nbr);
1321 break;
1322 }
1323 }
1324 }
1325
1326 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1327 break;
1328 default:
1329 zlog_warn ("Packet[DD]: NSM illegal status.");
1330 break;
1331 }
1332}
1333
1334#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1335
1336/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1337void
1338ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1339 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1340{
1341 struct ospf_neighbor *nbr;
1342 u_int32_t ls_type;
1343 struct in_addr ls_id;
1344 struct in_addr adv_router;
1345 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001346 struct list *ls_upd;
paul718e3742002-12-13 20:15:29 +00001347 int length;
1348
1349 /* Increment statistics. */
1350 oi->ls_req_in++;
1351
pauld3f0d622004-05-05 15:27:15 +00001352 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001353 if (nbr == NULL)
1354 {
1355 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1356 inet_ntoa (ospfh->router_id));
1357 return;
1358 }
1359
1360 /* Neighbor State should be Exchange or later. */
1361 if (nbr->state != NSM_Exchange &&
1362 nbr->state != NSM_Loading &&
1363 nbr->state != NSM_Full)
1364 {
1365 zlog_warn ("Link State Request: Neighbor state is %s, packet discarded.",
1366 LOOKUP (ospf_nsm_state_msg, nbr->state));
1367 return;
1368 }
1369
1370 /* Send Link State Update for ALL requested LSAs. */
1371 ls_upd = list_new ();
1372 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1373
1374 while (size >= OSPF_LSA_KEY_SIZE)
1375 {
1376 /* Get one slice of Link State Request. */
1377 ls_type = stream_getl (s);
1378 ls_id.s_addr = stream_get_ipv4 (s);
1379 adv_router.s_addr = stream_get_ipv4 (s);
1380
1381 /* Verify LSA type. */
1382 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1383 {
1384 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1385 list_delete (ls_upd);
1386 return;
1387 }
1388
1389 /* Search proper LSA in LSDB. */
1390 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1391 if (find == NULL)
1392 {
1393 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1394 list_delete (ls_upd);
1395 return;
1396 }
1397
1398 /* Packet overflows MTU size, send immediatly. */
1399 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1400 {
1401 if (oi->type == OSPF_IFTYPE_NBMA)
1402 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1403 else
1404 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1405
1406 /* Only remove list contents. Keep ls_upd. */
1407 list_delete_all_node (ls_upd);
1408
1409 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1410 }
1411
1412 /* Append LSA to update list. */
1413 listnode_add (ls_upd, find);
1414 length += ntohs (find->data->length);
1415
1416 size -= OSPF_LSA_KEY_SIZE;
1417 }
1418
1419 /* Send rest of Link State Update. */
1420 if (listcount (ls_upd) > 0)
1421 {
1422 if (oi->type == OSPF_IFTYPE_NBMA)
1423 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1424 else
1425 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1426
1427 list_delete (ls_upd);
1428 }
1429 else
1430 list_free (ls_upd);
1431}
1432
1433/* Get the list of LSAs from Link State Update packet.
1434 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001435static struct list *
paul718e3742002-12-13 20:15:29 +00001436ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1437 struct ospf_interface *oi, size_t size)
1438{
1439 u_int16_t count, sum;
1440 u_int32_t length;
1441 struct lsa_header *lsah;
1442 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001443 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001444
1445 lsas = list_new ();
1446
1447 count = stream_getl (s);
1448 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1449
1450 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1451 size -= length, stream_forward (s, length), count--)
1452 {
1453 lsah = (struct lsa_header *) STREAM_PNT (s);
1454 length = ntohs (lsah->length);
1455
1456 if (length > size)
1457 {
1458 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1459 break;
1460 }
1461
1462 /* Validate the LSA's LS checksum. */
1463 sum = lsah->checksum;
1464 if (sum != ospf_lsa_checksum (lsah))
1465 {
1466 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1467 sum, lsah->checksum);
1468 continue;
1469 }
1470
1471 /* Examine the LSA's LS type. */
1472 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1473 {
1474 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1475 continue;
1476 }
1477
1478 /*
1479 * What if the received LSA's age is greater than MaxAge?
1480 * Treat it as a MaxAge case -- endo.
1481 */
1482 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1483 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1484
1485#ifdef HAVE_OPAQUE_LSA
1486 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1487 {
1488#ifdef STRICT_OBIT_USAGE_CHECK
1489 if ((IS_OPAQUE_LSA(lsah->type) &&
1490 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1491 || (! IS_OPAQUE_LSA(lsah->type) &&
1492 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1493 {
1494 /*
1495 * This neighbor must know the exact usage of O-bit;
1496 * the bit will be set in Type-9,10,11 LSAs only.
1497 */
1498 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1499 continue;
1500 }
1501#endif /* STRICT_OBIT_USAGE_CHECK */
1502
1503 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1504 if (lsah->type == OSPF_OPAQUE_AS_LSA
1505 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1506 {
1507 if (IS_DEBUG_OSPF_EVENT)
1508 zlog_info ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1509 continue;
1510 }
1511 }
1512 else if (IS_OPAQUE_LSA(lsah->type))
1513 {
1514 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1515 continue;
1516 }
1517#endif /* HAVE_OPAQUE_LSA */
1518
1519 /* Create OSPF LSA instance. */
1520 lsa = ospf_lsa_new ();
1521
1522 /* We may wish to put some error checking if type NSSA comes in
1523 and area not in NSSA mode */
1524 switch (lsah->type)
1525 {
1526 case OSPF_AS_EXTERNAL_LSA:
1527#ifdef HAVE_OPAQUE_LSA
1528 case OSPF_OPAQUE_AS_LSA:
1529 lsa->area = NULL;
1530 break;
1531 case OSPF_OPAQUE_LINK_LSA:
1532 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1533 /* Fallthrough */
1534#endif /* HAVE_OPAQUE_LSA */
1535 default:
1536 lsa->area = oi->area;
1537 break;
1538 }
1539
1540 lsa->data = ospf_lsa_data_new (length);
1541 memcpy (lsa->data, lsah, length);
1542
1543 if (IS_DEBUG_OSPF_EVENT)
1544 zlog_info("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1545 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1546 listnode_add (lsas, lsa);
1547 }
1548
1549 return lsas;
1550}
1551
1552/* Cleanup Update list. */
1553void
hasso52dc7ee2004-09-23 19:18:23 +00001554ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001555{
hasso52dc7ee2004-09-23 19:18:23 +00001556 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001557 struct ospf_lsa *lsa;
1558
1559 for (node = listhead (lsas); node; nextnode (node))
1560 if ((lsa = getdata (node)) != NULL)
1561 ospf_lsa_discard (lsa);
1562
1563 list_delete (lsas);
1564}
1565
1566/* OSPF Link State Update message read -- RFC2328 Section 13. */
1567void
1568ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1569 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1570{
1571 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001572 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001573#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001574 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001575#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001576 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001577 struct ospf_lsa *lsa = NULL;
1578 /* unsigned long ls_req_found = 0; */
1579
1580 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1581
1582 /* Increment statistics. */
1583 oi->ls_upd_in++;
1584
1585 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001586 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001587 if (nbr == NULL)
1588 {
1589 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1590 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1591 return;
1592 }
1593
1594 /* Check neighbor state. */
1595 if (nbr->state < NSM_Exchange)
1596 {
1597 zlog_warn ("Link State Update: Neighbor[%s] state is less than Exchange",
1598 inet_ntoa (ospfh->router_id));
1599 return;
1600 }
1601
1602 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1603 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1604 * of section 13.
1605 */
1606 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1607
1608#ifdef HAVE_OPAQUE_LSA
1609 /*
1610 * Prepare two kinds of lists to clean up unwanted self-originated
1611 * Opaque-LSAs from the routing domain as soon as possible.
1612 */
1613 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1614 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1615
1616 /*
1617 * If self-originated Opaque-LSAs that have flooded before restart
1618 * are contained in the received LSUpd message, corresponding LSReq
1619 * messages to be sent may have to be modified.
1620 * To eliminate possible race conditions such that flushing and normal
1621 * updating for the same LSA would take place alternately, this trick
1622 * must be done before entering to the loop below.
1623 */
1624 ospf_opaque_adjust_lsreq (nbr, lsas);
1625#endif /* HAVE_OPAQUE_LSA */
1626
1627#define DISCARD_LSA(L,N) {\
1628 if (IS_DEBUG_OSPF_EVENT) \
1629 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1630 ospf_lsa_discard (L); \
1631 continue; }
1632
1633 /* Process each LSA received in the one packet. */
1634 for (node = listhead (lsas); node; node = next)
1635 {
1636 struct ospf_lsa *ls_ret, *current;
1637 int ret = 1;
1638
1639 next = node->next;
1640
1641 lsa = getdata (node);
1642
paul718e3742002-12-13 20:15:29 +00001643 if (IS_DEBUG_OSPF_NSSA)
1644 {
1645 char buf1[INET_ADDRSTRLEN];
1646 char buf2[INET_ADDRSTRLEN];
1647 char buf3[INET_ADDRSTRLEN];
1648
1649 zlog_info("LSA Type-%d from %s, ID: %s, ADV: %s",
1650 lsa->data->type,
1651 inet_ntop (AF_INET, &ospfh->router_id,
1652 buf1, INET_ADDRSTRLEN),
1653 inet_ntop (AF_INET, &lsa->data->id,
1654 buf2, INET_ADDRSTRLEN),
1655 inet_ntop (AF_INET, &lsa->data->adv_router,
1656 buf3, INET_ADDRSTRLEN));
1657 }
paul718e3742002-12-13 20:15:29 +00001658
1659 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1660
1661 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1662
1663 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1664
1665 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1666
1667 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1668
1669 /* Do take in Type-7's if we are an NSSA */
1670
1671 /* If we are also an ABR, later translate them to a Type-5 packet */
1672
1673 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1674 translate them to a separate Type-5 packet. */
1675
1676 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1677 /* Reject from STUB or NSSA */
1678 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1679 {
1680 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001681 if (IS_DEBUG_OSPF_NSSA)
1682 zlog_info("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001683 }
1684
paul718e3742002-12-13 20:15:29 +00001685 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1686 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1687 {
1688 DISCARD_LSA (lsa,2);
1689 if (IS_DEBUG_OSPF_NSSA)
1690 zlog_info("Incoming NSSA LSA Discarded: Not NSSA Area");
1691 }
paul718e3742002-12-13 20:15:29 +00001692
1693 /* Find the LSA in the current database. */
1694
1695 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1696
1697 /* If the LSA's LS age is equal to MaxAge, and there is currently
1698 no instance of the LSA in the router's link state database,
1699 and none of router's neighbors are in states Exchange or Loading,
1700 then take the following actions. */
1701
1702 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001703 (ospf_nbr_count (oi, NSM_Exchange) +
1704 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001705 {
1706 /* Response Link State Acknowledgment. */
1707 ospf_ls_ack_send (nbr, lsa);
1708
1709 /* Discard LSA. */
1710 zlog_warn ("Link State Update: LS age is equal to MaxAge.");
1711 DISCARD_LSA (lsa, 3);
1712 }
1713
1714#ifdef HAVE_OPAQUE_LSA
1715 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001716 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001717 {
1718 /*
1719 * Even if initial flushing seems to be completed, there might
1720 * be a case that self-originated LSA with MaxAge still remain
1721 * in the routing domain.
1722 * Just send an LSAck message to cease retransmission.
1723 */
1724 if (IS_LSA_MAXAGE (lsa))
1725 {
1726 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1727 ospf_ls_ack_send (nbr, lsa);
1728 ospf_lsa_discard (lsa);
1729
1730 if (current != NULL && ! IS_LSA_MAXAGE (current))
1731 ospf_opaque_lsa_refresh_schedule (current);
1732 continue;
1733 }
1734
1735 /*
1736 * If an instance of self-originated Opaque-LSA is not found
1737 * in the LSDB, there are some possible cases here.
1738 *
1739 * 1) This node lost opaque-capability after restart.
1740 * 2) Else, a part of opaque-type is no more supported.
1741 * 3) Else, a part of opaque-id is no more supported.
1742 *
1743 * Anyway, it is still this node's responsibility to flush it.
1744 * Otherwise, the LSA instance remains in the routing domain
1745 * until its age reaches to MaxAge.
1746 */
1747 if (current == NULL)
1748 {
1749 if (IS_DEBUG_OSPF_EVENT)
1750 zlog_info ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
1751
1752 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1753 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1754 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1755 continue;
1756 }
1757 }
1758#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001759 /* It might be happen that received LSA is self-originated network LSA, but
1760 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1761 * Link State ID is one of the router's own IP interface addresses but whose
1762 * Advertising Router is not equal to the router's own Router ID
1763 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1764 */
1765
1766 if(lsa->data->type == OSPF_NETWORK_LSA)
1767 {
hasso52dc7ee2004-09-23 19:18:23 +00001768 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001769 int Flag = 0;
1770
1771 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1772 {
1773 struct ospf_interface *out_if = getdata(oi_node);
1774 if(out_if == NULL)
1775 break;
1776
1777 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1778 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1779 {
1780 if(out_if->network_lsa_self)
1781 {
1782 ospf_lsa_flush_area(lsa,out_if->area);
1783 if(IS_DEBUG_OSPF_EVENT)
1784 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
1785 lsa, (int) lsa->data->type);
1786 ospf_lsa_discard (lsa);
1787 Flag = 1;
1788 }
1789 break;
1790 }
1791 }
1792 if(Flag)
1793 continue;
1794 }
paul718e3742002-12-13 20:15:29 +00001795
1796 /* (5) Find the instance of this LSA that is currently contained
1797 in the router's link state database. If there is no
1798 database copy, or the received LSA is more recent than
1799 the database copy the following steps must be performed. */
1800
1801 if (current == NULL ||
1802 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1803 {
1804 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001805 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001806 DISCARD_LSA (lsa, 4);
1807 continue;
1808 }
1809
1810 /* (6) Else, If there is an instance of the LSA on the sending
1811 neighbor's Link state request list, an error has occurred in
1812 the Database Exchange process. In this case, restart the
1813 Database Exchange process by generating the neighbor event
1814 BadLSReq for the sending neighbor and stop processing the
1815 Link State Update packet. */
1816
1817 if (ospf_ls_request_lookup (nbr, lsa))
1818 {
1819 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1820 zlog_warn ("LSA instance exists on Link state request list");
1821
1822 /* Clean list of LSAs. */
1823 ospf_upd_list_clean (lsas);
1824 /* this lsa is not on lsas list already. */
1825 ospf_lsa_discard (lsa);
1826#ifdef HAVE_OPAQUE_LSA
1827 list_delete (mylsa_acks);
1828 list_delete (mylsa_upds);
1829#endif /* HAVE_OPAQUE_LSA */
1830 return;
1831 }
1832
1833 /* If the received LSA is the same instance as the database copy
1834 (i.e., neither one is more recent) the following two steps
1835 should be performed: */
1836
1837 if (ret == 0)
1838 {
1839 /* If the LSA is listed in the Link state retransmission list
1840 for the receiving adjacency, the router itself is expecting
1841 an acknowledgment for this LSA. The router should treat the
1842 received LSA as an acknowledgment by removing the LSA from
1843 the Link state retransmission list. This is termed an
1844 "implied acknowledgment". */
1845
1846 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1847
1848 if (ls_ret != NULL)
1849 {
1850 ospf_ls_retransmit_delete (nbr, ls_ret);
1851
1852 /* Delayed acknowledgment sent if advertisement received
1853 from Designated Router, otherwise do nothing. */
1854 if (oi->state == ISM_Backup)
1855 if (NBR_IS_DR (nbr))
1856 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1857
1858 DISCARD_LSA (lsa, 5);
1859 }
1860 else
1861 /* Acknowledge the receipt of the LSA by sending a
1862 Link State Acknowledgment packet back out the receiving
1863 interface. */
1864 {
1865 ospf_ls_ack_send (nbr, lsa);
1866 DISCARD_LSA (lsa, 6);
1867 }
1868 }
1869
1870 /* The database copy is more recent. If the database copy
1871 has LS age equal to MaxAge and LS sequence number equal to
1872 MaxSequenceNumber, simply discard the received LSA without
1873 acknowledging it. (In this case, the LSA's LS sequence number is
1874 wrapping, and the MaxSequenceNumber LSA must be completely
1875 flushed before any new LSA instance can be introduced). */
1876
1877 else if (ret > 0) /* Database copy is more recent */
1878 {
1879 if (IS_LSA_MAXAGE (current) &&
1880 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1881 {
1882 DISCARD_LSA (lsa, 7);
1883 }
1884 /* Otherwise, as long as the database copy has not been sent in a
1885 Link State Update within the last MinLSArrival seconds, send the
1886 database copy back to the sending neighbor, encapsulated within
1887 a Link State Update Packet. The Link State Update Packet should
1888 be sent directly to the neighbor. In so doing, do not put the
1889 database copy of the LSA on the neighbor's link state
1890 retransmission list, and do not acknowledge the received (less
1891 recent) LSA instance. */
1892 else
1893 {
1894 struct timeval now;
1895
1896 gettimeofday (&now, NULL);
1897
1898 if (tv_cmp (tv_sub (now, current->tv_orig),
1899 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1900 /* Trap NSSA type later.*/
1901 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1902 DISCARD_LSA (lsa, 8);
1903 }
1904 }
1905 }
1906
1907#ifdef HAVE_OPAQUE_LSA
1908 /*
1909 * Now that previously originated Opaque-LSAs those which not yet
1910 * installed into LSDB are captured, take several steps to clear
1911 * them completely from the routing domain, before proceeding to
1912 * origination for the current target Opaque-LSAs.
1913 */
1914 while (listcount (mylsa_acks) > 0)
1915 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1916
1917 if (listcount (mylsa_upds) > 0)
1918 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1919
1920 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001921 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001922#endif /* HAVE_OPAQUE_LSA */
1923
1924 assert (listcount (lsas) == 0);
1925 list_delete (lsas);
1926}
1927
1928/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1929void
1930ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1931 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1932{
1933 struct ospf_neighbor *nbr;
1934#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001935 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001936#endif /* HAVE_OPAQUE_LSA */
1937
1938 /* increment statistics. */
1939 oi->ls_ack_in++;
1940
pauld3f0d622004-05-05 15:27:15 +00001941 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001942 if (nbr == NULL)
1943 {
1944 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1945 inet_ntoa (ospfh->router_id));
1946 return;
1947 }
1948
1949 if (nbr->state < NSM_Exchange)
1950 {
1951 zlog_warn ("Link State Acknowledgment: State is less than Exchange.");
1952 return;
1953 }
1954
1955#ifdef HAVE_OPAQUE_LSA
1956 opaque_acks = list_new ();
1957#endif /* HAVE_OPAQUE_LSA */
1958
1959 while (size >= OSPF_LSA_HEADER_SIZE)
1960 {
1961 struct ospf_lsa *lsa, *lsr;
1962
1963 lsa = ospf_lsa_new ();
1964 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1965
1966 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1967 size -= OSPF_LSA_HEADER_SIZE;
1968 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1969
1970 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1971 {
1972 lsa->data = NULL;
1973 ospf_lsa_discard (lsa);
1974 continue;
1975 }
1976
1977 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1978
1979 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1980 {
1981#ifdef HAVE_OPAQUE_LSA
1982 /* Keep this LSA entry for later reference. */
1983 if (IS_OPAQUE_LSA (lsr->data->type))
1984 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
1985#endif /* HAVE_OPAQUE_LSA */
1986
1987 ospf_ls_retransmit_delete (nbr, lsr);
1988 }
1989
1990 lsa->data = NULL;
1991 ospf_lsa_discard (lsa);
1992 }
1993
1994#ifdef HAVE_OPAQUE_LSA
1995 if (listcount (opaque_acks) > 0)
1996 ospf_opaque_ls_ack_received (nbr, opaque_acks);
1997
1998 list_delete (opaque_acks);
1999 return;
2000#endif /* HAVE_OPAQUE_LSA */
2001}
2002
2003struct stream *
2004ospf_recv_packet (int fd, struct interface **ifp)
2005{
2006 int ret;
2007 struct ip iph;
2008 u_int16_t ip_len;
2009 struct stream *ibuf;
2010 unsigned int ifindex = 0;
2011 struct iovec iov;
2012 struct cmsghdr *cmsg;
gdtd0deca62004-08-26 13:14:07 +00002013#if defined(CMSG_SPACE)
2014 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002015 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
gdtd0deca62004-08-26 13:14:07 +00002016#else
2017 char buff [sizeof (*cmsg) + SOPT_SIZE_CMSG_IFINDEX_IPV4()];
2018#endif
paul2dd8bb42004-07-23 15:13:48 +00002019 struct msghdr msgh;
2020
2021 msgh.msg_name = NULL;
2022 msgh.msg_namelen = 0;
2023 msgh.msg_iov = &iov;
2024 msgh.msg_iovlen = 1;
2025 msgh.msg_control = (caddr_t) buff;
2026 msgh.msg_controllen = sizeof (buff);
2027 msgh.msg_flags = 0;
2028
paul718e3742002-12-13 20:15:29 +00002029 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2030
2031 if (ret != sizeof (iph))
2032 {
2033 zlog_warn ("ospf_recv_packet packet smaller than ip header");
2034 return NULL;
2035 }
2036
paul239aecc2003-12-08 10:34:54 +00002037#if defined(__NetBSD__) || defined(__FreeBSD__) || (defined(__OpenBSD__) && (OpenBSD < 200311))
paul718e3742002-12-13 20:15:29 +00002038 ip_len = iph.ip_len;
2039#else
2040 ip_len = ntohs (iph.ip_len);
2041#endif
2042
paul239aecc2003-12-08 10:34:54 +00002043#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002044 /*
2045 * Kernel network code touches incoming IP header parameters,
2046 * before protocol specific processing.
2047 *
2048 * 1) Convert byteorder to host representation.
2049 * --> ip_len, ip_id, ip_off
2050 *
2051 * 2) Adjust ip_len to strip IP header size!
2052 * --> If user process receives entire IP packet via RAW
2053 * socket, it must consider adding IP header size to
2054 * the "ip_len" field of "ip" structure.
2055 *
2056 * For more details, see <netinet/ip_input.c>.
2057 */
2058 ip_len = ip_len + (iph.ip_hl << 2);
2059#endif
2060
2061 ibuf = stream_new (ip_len);
2062 iov.iov_base = STREAM_DATA (ibuf);
2063 iov.iov_len = ip_len;
2064 ret = recvmsg (fd, &msgh, 0);
2065
paul863082d2004-08-19 04:43:43 +00002066 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002067
2068 *ifp = if_lookup_by_index (ifindex);
2069
2070 if (ret != ip_len)
2071 {
2072 zlog_warn ("ospf_recv_packet short read. "
2073 "ip_len %d bytes read %d", ip_len, ret);
2074 stream_free (ibuf);
2075 return NULL;
2076 }
2077
2078 return ibuf;
2079}
2080
2081struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002082ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002083 struct ip *iph, struct ospf_header *ospfh)
2084{
2085 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002086 struct ospf_vl_data *vl_data;
2087 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002088 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002089
2090 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2091 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002092 return NULL;
paul718e3742002-12-13 20:15:29 +00002093
pauld3f0d622004-05-05 15:27:15 +00002094 /* look for local OSPF interface matching the destination
2095 * to determine Area ID. We presume therefore the destination address
2096 * is unique, or at least (for "unnumbered" links), not used in other
2097 * areas
2098 */
2099 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2100 iph->ip_dst)) == NULL)
2101 return NULL;
paul718e3742002-12-13 20:15:29 +00002102
paul020709f2003-04-04 02:44:16 +00002103 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002104 {
2105 if ((vl_data = getdata (node)) == NULL)
2106 continue;
2107
paul020709f2003-04-04 02:44:16 +00002108 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002109 if (!vl_area)
2110 continue;
2111
2112 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2113 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2114 {
2115 if (IS_DEBUG_OSPF_EVENT)
2116 zlog_info ("associating packet with %s",
2117 IF_NAME (vl_data->vl_oi));
2118 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2119 {
2120 if (IS_DEBUG_OSPF_EVENT)
2121 zlog_info ("This VL is not up yet, sorry");
2122 return NULL;
2123 }
2124
2125 return vl_data->vl_oi;
2126 }
2127 }
2128
2129 if (IS_DEBUG_OSPF_EVENT)
2130 zlog_info ("couldn't find any VL to associate the packet with");
2131
pauld3f0d622004-05-05 15:27:15 +00002132 return NULL;
paul718e3742002-12-13 20:15:29 +00002133}
2134
2135int
2136ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2137{
2138 /* Check match the Area ID of the receiving interface. */
2139 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2140 return 1;
2141
2142 return 0;
2143}
2144
2145/* Unbound socket will accept any Raw IP packets if proto is matched.
2146 To prevent it, compare src IP address and i/f address with masking
2147 i/f network mask. */
2148int
2149ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2150{
2151 struct in_addr mask, me, him;
2152
2153 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2154 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2155 return 1;
2156
2157 masklen2ip (oi->address->prefixlen, &mask);
2158
2159 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2160 him.s_addr = ip_src.s_addr & mask.s_addr;
2161
2162 if (IPV4_ADDR_SAME (&me, &him))
2163 return 1;
2164
2165 return 0;
2166}
2167
2168int
2169ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2170 struct ospf_header *ospfh)
2171{
2172 int ret = 0;
2173 struct crypt_key *ck;
2174
2175 switch (ntohs (ospfh->auth_type))
2176 {
2177 case OSPF_AUTH_NULL:
2178 ret = 1;
2179 break;
2180 case OSPF_AUTH_SIMPLE:
2181 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2182 ret = 1;
2183 else
2184 ret = 0;
2185 break;
2186 case OSPF_AUTH_CRYPTOGRAPHIC:
2187 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2188 {
2189 ret = 0;
2190 break;
2191 }
2192
2193 /* This is very basic, the digest processing is elsewhere */
2194 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2195 ospfh->u.crypt.key_id == ck->key_id &&
2196 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2197 ret = 1;
2198 else
2199 ret = 0;
2200 break;
2201 default:
2202 ret = 0;
2203 break;
2204 }
2205
2206 return ret;
2207}
2208
2209int
2210ospf_check_sum (struct ospf_header *ospfh)
2211{
2212 u_int32_t ret;
2213 u_int16_t sum;
2214 int in_cksum (void *ptr, int nbytes);
2215
2216 /* clear auth_data for checksum. */
2217 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2218
2219 /* keep checksum and clear. */
2220 sum = ospfh->checksum;
2221 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2222
2223 /* calculate checksum. */
2224 ret = in_cksum (ospfh, ntohs (ospfh->length));
2225
2226 if (ret != sum)
2227 {
2228 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2229 ret, sum);
2230 return 0;
2231 }
2232
2233 return 1;
2234}
2235
2236/* OSPF Header verification. */
2237int
2238ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2239 struct ip *iph, struct ospf_header *ospfh)
2240{
2241 /* check version. */
2242 if (ospfh->version != OSPF_VERSION)
2243 {
2244 zlog_warn ("interface %s: ospf_read version number mismatch.",
2245 IF_NAME (oi));
2246 return -1;
2247 }
2248
2249 /* Check Area ID. */
2250 if (!ospf_check_area_id (oi, ospfh))
2251 {
2252 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2253 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2254 return -1;
2255 }
2256
2257 /* Check network mask, Silently discarded. */
2258 if (! ospf_check_network_mask (oi, iph->ip_src))
2259 {
2260 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2261 IF_NAME (oi), inet_ntoa (iph->ip_src));
2262 return -1;
2263 }
2264
2265 /* Check authentication. */
2266 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2267 {
2268 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2269 IF_NAME (oi));
2270 return -1;
2271 }
2272
2273 if (! ospf_check_auth (oi, ibuf, ospfh))
2274 {
2275 zlog_warn ("interface %s: ospf_read authentication failed.",
2276 IF_NAME (oi));
2277 return -1;
2278 }
2279
2280 /* if check sum is invalid, packet is discarded. */
2281 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2282 {
2283 if (! ospf_check_sum (ospfh))
2284 {
2285 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2286 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2287 return -1;
2288 }
2289 }
2290 else
2291 {
2292 if (ospfh->checksum != 0)
2293 return -1;
2294 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2295 {
2296 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2297 IF_NAME (oi));
2298 return -1;
2299 }
2300 }
2301
2302 return 0;
2303}
2304
2305/* Starting point of packet process function. */
2306int
2307ospf_read (struct thread *thread)
2308{
2309 int ret;
2310 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002311 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002312 struct ospf_interface *oi;
2313 struct ip *iph;
2314 struct ospf_header *ospfh;
2315 u_int16_t length;
2316 struct interface *ifp;
2317
2318 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002319 ospf = THREAD_ARG (thread);
2320 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002321
2322 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002323 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002324 if (ibuf == NULL)
2325 return -1;
2326
pauld3f0d622004-05-05 15:27:15 +00002327 if (ifp == NULL)
2328 {
2329 stream_free (ibuf);
2330 return 0;
2331 }
2332
paul718e3742002-12-13 20:15:29 +00002333 iph = (struct ip *) STREAM_DATA (ibuf);
2334
2335 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002336 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002337
2338 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002339 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul7d95c612003-01-27 12:00:55 +00002340 ospf_ip_header_dump (ibuf);
2341
paul718e3742002-12-13 20:15:29 +00002342 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002343 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002344 {
pauld3241812003-09-29 12:42:39 +00002345 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2346 {
2347 zlog_info ("ospf_read[%s]: Dropping self-originated packet",
2348 inet_ntoa (iph->ip_src));
2349 }
paul718e3742002-12-13 20:15:29 +00002350 stream_free (ibuf);
2351 return 0;
2352 }
2353
2354 /* Adjust size to message length. */
2355 stream_forward (ibuf, iph->ip_hl * 4);
2356
2357 /* Get ospf packet header. */
2358 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2359
2360 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002361 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002362
2363 /* if no local ospf_interface,
2364 * or header area is backbone but ospf_interface is not
2365 * check for VLINK interface
2366 */
2367 if ( (oi == NULL) ||
2368 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2369 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2370 )
2371 {
2372 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2373 {
2374 zlog_warn ("Packet from [%s] received on link %s"
2375 " but no ospf_interface",
2376 inet_ntoa (iph->ip_src), ifp->name);
2377 stream_free (ibuf);
2378 return 0;
2379 }
2380 }
2381
2382 /* else it must be a local ospf interface, check it was received on
2383 * correct link
2384 */
2385 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002386 {
2387 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002388 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002389 stream_free (ibuf);
2390 return 0;
2391 }
paul718e3742002-12-13 20:15:29 +00002392
2393 /*
2394 * If the received packet is destined for AllDRouters, the packet
2395 * should be accepted only if the received ospf interface state is
2396 * either DR or Backup -- endo.
2397 */
2398 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2399 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2400 {
2401 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2402 inet_ntoa (iph->ip_src), IF_NAME (oi),
2403 LOOKUP (ospf_ism_state_msg, oi->state));
2404 stream_free (ibuf);
2405 return 0;
2406 }
2407
2408 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002409 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2410 {
paul718e3742002-12-13 20:15:29 +00002411 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002412 {
2413 zlog_info ("-----------------------------------------------------");
2414 ospf_packet_dump (ibuf);
2415 }
paul718e3742002-12-13 20:15:29 +00002416
2417 zlog_info ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002418 ospf_packet_type_str[ospfh->type],
2419 inet_ntoa (ospfh->router_id), IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +00002420 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2421 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2422
2423 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2424 zlog_info ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002425 }
paul718e3742002-12-13 20:15:29 +00002426
2427 /* Some header verification. */
2428 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2429 if (ret < 0)
2430 {
pauld3241812003-09-29 12:42:39 +00002431 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2432 {
2433 zlog_info ("ospf_read[%s/%s]: Header check failed, "
2434 "dropping.",
2435 ospf_packet_type_str[ospfh->type],
2436 inet_ntoa (iph->ip_src));
2437 }
paul718e3742002-12-13 20:15:29 +00002438 stream_free (ibuf);
2439 return ret;
2440 }
2441
2442 stream_forward (ibuf, OSPF_HEADER_SIZE);
2443
2444 /* Adjust size to message length. */
2445 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2446
2447 /* Read rest of the packet and call each sort of packet routine. */
2448 switch (ospfh->type)
2449 {
2450 case OSPF_MSG_HELLO:
2451 ospf_hello (iph, ospfh, ibuf, oi, length);
2452 break;
2453 case OSPF_MSG_DB_DESC:
2454 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2455 break;
2456 case OSPF_MSG_LS_REQ:
2457 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2458 break;
2459 case OSPF_MSG_LS_UPD:
2460 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2461 break;
2462 case OSPF_MSG_LS_ACK:
2463 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2464 break;
2465 default:
2466 zlog (NULL, LOG_WARNING,
2467 "interface %s: OSPF packet header type %d is illegal",
2468 IF_NAME (oi), ospfh->type);
2469 break;
2470 }
2471
2472 stream_free (ibuf);
2473 return 0;
2474}
2475
2476/* Make OSPF header. */
2477void
2478ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2479{
2480 struct ospf_header *ospfh;
2481
2482 ospfh = (struct ospf_header *) STREAM_DATA (s);
2483
2484 ospfh->version = (u_char) OSPF_VERSION;
2485 ospfh->type = (u_char) type;
2486
paul68980082003-03-25 05:07:42 +00002487 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002488
2489 ospfh->checksum = 0;
2490 ospfh->area_id = oi->area->area_id;
2491 ospfh->auth_type = htons (ospf_auth_type (oi));
2492
2493 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2494
2495 ospf_output_forward (s, OSPF_HEADER_SIZE);
2496}
2497
2498/* Make Authentication Data. */
2499int
2500ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2501{
2502 struct crypt_key *ck;
2503
2504 switch (ospf_auth_type (oi))
2505 {
2506 case OSPF_AUTH_NULL:
2507 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2508 break;
2509 case OSPF_AUTH_SIMPLE:
2510 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2511 OSPF_AUTH_SIMPLE_SIZE);
2512 break;
2513 case OSPF_AUTH_CRYPTOGRAPHIC:
2514 /* If key is not set, then set 0. */
2515 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2516 {
2517 ospfh->u.crypt.zero = 0;
2518 ospfh->u.crypt.key_id = 0;
2519 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2520 }
2521 else
2522 {
2523 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2524 ospfh->u.crypt.zero = 0;
2525 ospfh->u.crypt.key_id = ck->key_id;
2526 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2527 }
2528 /* note: the seq is done in ospf_make_md5_digest() */
2529 break;
2530 default:
2531 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2532 break;
2533 }
2534
2535 return 0;
2536}
2537
2538/* Fill rest of OSPF header. */
2539void
2540ospf_fill_header (struct ospf_interface *oi,
2541 struct stream *s, u_int16_t length)
2542{
2543 struct ospf_header *ospfh;
2544
2545 ospfh = (struct ospf_header *) STREAM_DATA (s);
2546
2547 /* Fill length. */
2548 ospfh->length = htons (length);
2549
2550 /* Calculate checksum. */
2551 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2552 ospfh->checksum = in_cksum (ospfh, length);
2553 else
2554 ospfh->checksum = 0;
2555
2556 /* Add Authentication Data. */
2557 ospf_make_auth (oi, ospfh);
2558}
2559
2560int
2561ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2562{
2563 struct ospf_neighbor *nbr;
2564 struct route_node *rn;
2565 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2566 struct in_addr mask;
2567 unsigned long p;
2568 int flag = 0;
2569
2570 /* Set netmask of interface. */
2571 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2572 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2573 masklen2ip (oi->address->prefixlen, &mask);
2574 else
2575 memset ((char *) &mask, 0, sizeof (struct in_addr));
2576 stream_put_ipv4 (s, mask.s_addr);
2577
2578 /* Set Hello Interval. */
2579 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2580
2581 if (IS_DEBUG_OSPF_EVENT)
2582 zlog_info ("make_hello: options: %x, int: %s",
2583 OPTIONS(oi), IF_NAME (oi));
2584
2585 /* Set Options. */
2586 stream_putc (s, OPTIONS (oi));
2587
2588 /* Set Router Priority. */
2589 stream_putc (s, PRIORITY (oi));
2590
2591 /* Set Router Dead Interval. */
2592 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2593
2594 /* Set Designated Router. */
2595 stream_put_ipv4 (s, DR (oi).s_addr);
2596
2597 p = s->putp;
2598
2599 /* Set Backup Designated Router. */
2600 stream_put_ipv4 (s, BDR (oi).s_addr);
2601
2602 /* Add neighbor seen. */
2603 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002604 if ((nbr = rn->info))
2605 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2606 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2607 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2608 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002609 {
2610 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002611 if (nbr->d_router.s_addr != 0
2612 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2613 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2614 flag = 1;
paul718e3742002-12-13 20:15:29 +00002615
2616 stream_put_ipv4 (s, nbr->router_id.s_addr);
2617 length += 4;
2618 }
2619
2620 /* Let neighbor generate BackupSeen. */
2621 if (flag == 1)
2622 {
2623 stream_set_putp (s, p);
2624 stream_put_ipv4 (s, 0);
2625 }
2626
2627 return length;
2628}
2629
2630int
2631ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2632 struct stream *s)
2633{
2634 struct ospf_lsa *lsa;
2635 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2636 u_char options;
2637 unsigned long pp;
2638 int i;
2639 struct ospf_lsdb *lsdb;
2640
2641 /* Set Interface MTU. */
2642 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2643 stream_putw (s, 0);
2644 else
2645 stream_putw (s, oi->ifp->mtu);
2646
2647 /* Set Options. */
2648 options = OPTIONS (oi);
2649#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002650 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002651 {
2652 if (IS_SET_DD_I (nbr->dd_flags)
2653 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2654 /*
2655 * Set O-bit in the outgoing DD packet for capablity negotiation,
2656 * if one of following case is applicable.
2657 *
2658 * 1) WaitTimer expiration event triggered the neighbor state to
2659 * change to Exstart, but no (valid) DD packet has received
2660 * from the neighbor yet.
2661 *
2662 * 2) At least one DD packet with O-bit on has received from the
2663 * neighbor.
2664 */
2665 SET_FLAG (options, OSPF_OPTION_O);
2666 }
2667#endif /* HAVE_OPAQUE_LSA */
2668 stream_putc (s, options);
2669
2670 /* Keep pointer to flags. */
2671 pp = stream_get_putp (s);
2672 stream_putc (s, nbr->dd_flags);
2673
2674 /* Set DD Sequence Number. */
2675 stream_putl (s, nbr->dd_seqnum);
2676
2677 if (ospf_db_summary_isempty (nbr))
2678 {
2679 if (nbr->state >= NSM_Exchange)
2680 {
2681 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2682 /* Set DD flags again */
2683 stream_set_putp (s, pp);
2684 stream_putc (s, nbr->dd_flags);
2685 }
2686 return length;
2687 }
2688
2689 /* Describe LSA Header from Database Summary List. */
2690 lsdb = &nbr->db_sum;
2691
2692 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2693 {
2694 struct route_table *table = lsdb->type[i].db;
2695 struct route_node *rn;
2696
2697 for (rn = route_top (table); rn; rn = route_next (rn))
2698 if ((lsa = rn->info) != NULL)
2699 {
2700#ifdef HAVE_OPAQUE_LSA
2701 if (IS_OPAQUE_LSA (lsa->data->type)
2702 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2703 {
2704 /* Suppress advertising opaque-informations. */
2705 /* Remove LSA from DB summary list. */
2706 ospf_lsdb_delete (lsdb, lsa);
2707 continue;
2708 }
2709#endif /* HAVE_OPAQUE_LSA */
2710
2711 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2712 {
2713 struct lsa_header *lsah;
2714 u_int16_t ls_age;
2715
2716 /* DD packet overflows interface MTU. */
2717 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2718 break;
2719
2720 /* Keep pointer to LS age. */
2721 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2722 stream_get_putp (s));
2723
2724 /* Proceed stream pointer. */
2725 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2726 length += OSPF_LSA_HEADER_SIZE;
2727
2728 /* Set LS age. */
2729 ls_age = LS_AGE (lsa);
2730 lsah->ls_age = htons (ls_age);
2731
2732 }
2733
2734 /* Remove LSA from DB summary list. */
2735 ospf_lsdb_delete (lsdb, lsa);
2736 }
2737 }
2738
2739 return length;
2740}
2741
2742int
2743ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2744 unsigned long delta, struct ospf_neighbor *nbr,
2745 struct ospf_lsa *lsa)
2746{
2747 struct ospf_interface *oi;
2748
2749 oi = nbr->oi;
2750
2751 /* LS Request packet overflows interface MTU. */
2752 if (*length + delta > OSPF_PACKET_MAX(oi))
2753 return 0;
2754
2755 stream_putl (s, lsa->data->type);
2756 stream_put_ipv4 (s, lsa->data->id.s_addr);
2757 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2758
2759 ospf_lsa_unlock (nbr->ls_req_last);
2760 nbr->ls_req_last = ospf_lsa_lock (lsa);
2761
2762 *length += 12;
2763 return 1;
2764}
2765
2766int
2767ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2768{
2769 struct ospf_lsa *lsa;
2770 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2771 unsigned long delta = stream_get_putp(s)+12;
2772 struct route_table *table;
2773 struct route_node *rn;
2774 int i;
2775 struct ospf_lsdb *lsdb;
2776
2777 lsdb = &nbr->ls_req;
2778
2779 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2780 {
2781 table = lsdb->type[i].db;
2782 for (rn = route_top (table); rn; rn = route_next (rn))
2783 if ((lsa = (rn->info)) != NULL)
2784 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2785 {
2786 route_unlock_node (rn);
2787 break;
2788 }
2789 }
2790 return length;
2791}
2792
2793int
2794ls_age_increment (struct ospf_lsa *lsa, int delay)
2795{
2796 int age;
2797
2798 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2799
2800 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2801}
2802
2803int
hasso52dc7ee2004-09-23 19:18:23 +00002804ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002805{
2806 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002807 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002808 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2809 unsigned long delta = stream_get_putp (s);
2810 unsigned long pp;
2811 int count = 0;
2812
2813 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002814 zlog_info ("ospf_make_ls_upd: Start");
2815
paul718e3742002-12-13 20:15:29 +00002816 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002817 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002818
2819 while ((node = listhead (update)) != NULL)
2820 {
2821 struct lsa_header *lsah;
2822 u_int16_t ls_age;
2823
2824 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002825 zlog_info ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002826
2827 lsa = getdata (node);
2828 assert (lsa);
2829 assert (lsa->data);
2830
paul68b73392004-09-12 14:21:37 +00002831 /* Will it fit? */
2832 if (length + delta + ntohs (lsa->data->length) > stream_get_size (s))
paul59ea14c2004-07-14 20:50:36 +00002833 break;
2834
paul718e3742002-12-13 20:15:29 +00002835 /* Keep pointer to LS age. */
2836 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2837
2838 /* Put LSA to Link State Request. */
2839 stream_put (s, lsa->data, ntohs (lsa->data->length));
2840
2841 /* Set LS age. */
2842 /* each hop must increment an lsa_age by transmit_delay
2843 of OSPF interface */
2844 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2845 lsah->ls_age = htons (ls_age);
2846
2847 length += ntohs (lsa->data->length);
2848 count++;
2849
2850 list_delete_node (update, node);
2851 ospf_lsa_unlock (lsa);
2852 }
2853
2854 /* Now set #LSAs. */
2855 stream_set_putp (s, pp);
2856 stream_putl (s, count);
2857
2858 stream_set_putp (s, s->endp);
2859
2860 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002861 zlog_info ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002862 return length;
2863}
2864
2865int
hasso52dc7ee2004-09-23 19:18:23 +00002866ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002867{
hasso52dc7ee2004-09-23 19:18:23 +00002868 struct list *rm_list;
2869 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002870 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2871 unsigned long delta = stream_get_putp(s) + 24;
2872 struct ospf_lsa *lsa;
2873
2874 rm_list = list_new ();
2875
2876 for (node = listhead (ack); node; nextnode (node))
2877 {
2878 lsa = getdata (node);
2879 assert (lsa);
2880
2881 if (length + delta > OSPF_PACKET_MAX (oi))
2882 break;
2883
2884 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2885 length += OSPF_LSA_HEADER_SIZE;
2886
2887 listnode_add (rm_list, lsa);
2888 }
2889
2890 /* Remove LSA from LS-Ack list. */
2891 for (node = listhead (rm_list); node; nextnode (node))
2892 {
2893 lsa = (struct ospf_lsa *) getdata (node);
2894
2895 listnode_delete (ack, lsa);
2896 ospf_lsa_unlock (lsa);
2897 }
2898
2899 list_delete (rm_list);
2900
2901 return length;
2902}
2903
2904void
2905ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2906{
2907 struct ospf_packet *op;
2908 u_int16_t length = OSPF_HEADER_SIZE;
2909
2910 op = ospf_packet_new (oi->ifp->mtu);
2911
2912 /* Prepare OSPF common header. */
2913 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2914
2915 /* Prepare OSPF Hello body. */
2916 length += ospf_make_hello (oi, op->s);
2917
2918 /* Fill OSPF header. */
2919 ospf_fill_header (oi, op->s, length);
2920
2921 /* Set packet length. */
2922 op->length = length;
2923
2924 op->dst.s_addr = addr->s_addr;
2925
2926 /* Add packet to the interface output queue. */
2927 ospf_packet_add (oi, op);
2928
2929 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002930 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002931}
2932
2933void
2934ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2935{
2936 struct ospf_interface *oi;
2937
2938 oi = nbr_nbma->oi;
2939 assert(oi);
2940
2941 /* If this is passive interface, do not send OSPF Hello. */
2942 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2943 return;
2944
2945 if (oi->type != OSPF_IFTYPE_NBMA)
2946 return;
2947
2948 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2949 return;
2950
2951 if (PRIORITY(oi) == 0)
2952 return;
2953
2954 if (nbr_nbma->priority == 0
2955 && oi->state != ISM_DR && oi->state != ISM_Backup)
2956 return;
2957
2958 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2959}
2960
2961int
2962ospf_poll_timer (struct thread *thread)
2963{
2964 struct ospf_nbr_nbma *nbr_nbma;
2965
2966 nbr_nbma = THREAD_ARG (thread);
2967 nbr_nbma->t_poll = NULL;
2968
2969 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2970 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2971 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2972
2973 ospf_poll_send (nbr_nbma);
2974
2975 if (nbr_nbma->v_poll > 0)
2976 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2977 nbr_nbma->v_poll);
2978
2979 return 0;
2980}
2981
2982
2983int
2984ospf_hello_reply_timer (struct thread *thread)
2985{
2986 struct ospf_neighbor *nbr;
2987
2988 nbr = THREAD_ARG (thread);
2989 nbr->t_hello_reply = NULL;
2990
2991 assert (nbr->oi);
2992
2993 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2994 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2995 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2996
2997 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2998
2999 return 0;
3000}
3001
3002/* Send OSPF Hello. */
3003void
3004ospf_hello_send (struct ospf_interface *oi)
3005{
3006 struct ospf_packet *op;
3007 u_int16_t length = OSPF_HEADER_SIZE;
3008
3009 /* If this is passive interface, do not send OSPF Hello. */
3010 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3011 return;
3012
3013 op = ospf_packet_new (oi->ifp->mtu);
3014
3015 /* Prepare OSPF common header. */
3016 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3017
3018 /* Prepare OSPF Hello body. */
3019 length += ospf_make_hello (oi, op->s);
3020
3021 /* Fill OSPF header. */
3022 ospf_fill_header (oi, op->s, length);
3023
3024 /* Set packet length. */
3025 op->length = length;
3026
3027 if (oi->type == OSPF_IFTYPE_NBMA)
3028 {
3029 struct ospf_neighbor *nbr;
3030 struct route_node *rn;
3031
3032 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3033 if ((nbr = rn->info))
3034 if (nbr != oi->nbr_self)
3035 if (nbr->state != NSM_Down)
3036 {
3037 /* RFC 2328 Section 9.5.1
3038 If the router is not eligible to become Designated Router,
3039 it must periodically send Hello Packets to both the
3040 Designated Router and the Backup Designated Router (if they
3041 exist). */
3042 if (PRIORITY(oi) == 0 &&
3043 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3044 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3045 continue;
3046
3047 /* If the router is eligible to become Designated Router, it
3048 must periodically send Hello Packets to all neighbors that
3049 are also eligible. In addition, if the router is itself the
3050 Designated Router or Backup Designated Router, it must also
3051 send periodic Hello Packets to all other neighbors. */
3052
3053 if (nbr->priority == 0 && oi->state == ISM_DROther)
3054 continue;
3055 /* if oi->state == Waiting, send hello to all neighbors */
3056 {
3057 struct ospf_packet *op_dup;
3058
3059 op_dup = ospf_packet_dup(op);
3060 op_dup->dst = nbr->address.u.prefix4;
3061
3062 /* Add packet to the interface output queue. */
3063 ospf_packet_add (oi, op_dup);
3064
paul020709f2003-04-04 02:44:16 +00003065 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003066 }
3067
3068 }
3069 ospf_packet_free (op);
3070 }
3071 else
3072 {
3073 /* Decide destination address. */
3074 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3075 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3076 else
3077 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3078
3079 /* Add packet to the interface output queue. */
3080 ospf_packet_add (oi, op);
3081
3082 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003083 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003084 }
3085}
3086
3087/* Send OSPF Database Description. */
3088void
3089ospf_db_desc_send (struct ospf_neighbor *nbr)
3090{
3091 struct ospf_interface *oi;
3092 struct ospf_packet *op;
3093 u_int16_t length = OSPF_HEADER_SIZE;
3094
3095 oi = nbr->oi;
3096 op = ospf_packet_new (oi->ifp->mtu);
3097
3098 /* Prepare OSPF common header. */
3099 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3100
3101 /* Prepare OSPF Database Description body. */
3102 length += ospf_make_db_desc (oi, nbr, op->s);
3103
3104 /* Fill OSPF header. */
3105 ospf_fill_header (oi, op->s, length);
3106
3107 /* Set packet length. */
3108 op->length = length;
3109
3110 /* Decide destination address. */
3111 op->dst = nbr->address.u.prefix4;
3112
3113 /* Add packet to the interface output queue. */
3114 ospf_packet_add (oi, op);
3115
3116 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003117 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003118
3119 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3120 if (nbr->last_send)
3121 ospf_packet_free (nbr->last_send);
3122 nbr->last_send = ospf_packet_dup (op);
3123 gettimeofday (&nbr->last_send_ts, NULL);
3124}
3125
3126/* Re-send Database Description. */
3127void
3128ospf_db_desc_resend (struct ospf_neighbor *nbr)
3129{
3130 struct ospf_interface *oi;
3131
3132 oi = nbr->oi;
3133
3134 /* Add packet to the interface output queue. */
3135 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3136
3137 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003138 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003139}
3140
3141/* Send Link State Request. */
3142void
3143ospf_ls_req_send (struct ospf_neighbor *nbr)
3144{
3145 struct ospf_interface *oi;
3146 struct ospf_packet *op;
3147 u_int16_t length = OSPF_HEADER_SIZE;
3148
3149 oi = nbr->oi;
3150 op = ospf_packet_new (oi->ifp->mtu);
3151
3152 /* Prepare OSPF common header. */
3153 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3154
3155 /* Prepare OSPF Link State Request body. */
3156 length += ospf_make_ls_req (nbr, op->s);
3157 if (length == OSPF_HEADER_SIZE)
3158 {
3159 ospf_packet_free (op);
3160 return;
3161 }
3162
3163 /* Fill OSPF header. */
3164 ospf_fill_header (oi, op->s, length);
3165
3166 /* Set packet length. */
3167 op->length = length;
3168
3169 /* Decide destination address. */
3170 op->dst = nbr->address.u.prefix4;
3171
3172 /* Add packet to the interface output queue. */
3173 ospf_packet_add (oi, op);
3174
3175 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003176 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003177
3178 /* Add Link State Request Retransmission Timer. */
3179 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3180}
3181
3182/* Send Link State Update with an LSA. */
3183void
3184ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3185 int flag)
3186{
hasso52dc7ee2004-09-23 19:18:23 +00003187 struct list *update;
paul718e3742002-12-13 20:15:29 +00003188
3189 update = list_new ();
3190
3191 listnode_add (update, lsa);
3192 ospf_ls_upd_send (nbr, update, flag);
3193
3194 list_delete (update);
3195}
3196
paul68b73392004-09-12 14:21:37 +00003197/* Determine size for packet. Must be at least big enough to accomodate next
3198 * LSA on list, which may be bigger than MTU size.
3199 *
3200 * Return pointer to new ospf_packet
3201 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3202 * on packet sizes (in which case offending LSA is deleted from update list)
3203 */
3204static struct ospf_packet *
3205ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3206{
3207 struct ospf_lsa *lsa;
3208 struct listnode *ln;
3209 size_t size;
3210 static char warned = 0;
3211
3212 ln = listhead (update);
3213 lsa = getdata (ln);
3214 assert (lsa);
3215 assert (lsa->data);
3216
3217 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3218 > ospf_packet_max (oi))
3219 {
3220 if (!warned)
3221 {
3222 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3223 "will need to fragment. Not optimal. Try divide up"
3224 " your network with areas. Use 'debug ospf packet send'"
3225 " to see details, or look at 'show ip ospf database ..'");
3226 warned = 1;
3227 }
3228
3229 if (IS_DEBUG_OSPF_PACKET (0, SEND))
3230 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3231 " %d bytes originated by %s, will be fragmented!",
3232 inet_ntoa (lsa->data->id),
3233 ntohs (lsa->data->length),
3234 inet_ntoa (lsa->data->adv_router));
3235
3236 /*
3237 * Allocate just enough to fit this LSA only, to avoid including other
3238 * LSAs in fragmented LSA Updates.
3239 */
3240 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3241 + OSPF_LS_UPD_MIN_SIZE;
3242 }
3243 else
3244 size = oi->ifp->mtu;
3245
3246 if (size > OSPF_MAX_PACKET_SIZE)
3247 {
3248 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3249 " %d bytes, dropping it completely."
3250 " OSPF routing is broken!",
3251 inet_ntoa (lsa->data->id), ntohs (lsa->data->length));
3252 list_delete_node (update, ln);
3253 return NULL;
3254 }
3255
3256 return ospf_packet_new (size);
3257}
3258
paul718e3742002-12-13 20:15:29 +00003259static void
hasso52dc7ee2004-09-23 19:18:23 +00003260ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003261 struct in_addr addr)
3262{
3263 struct ospf_packet *op;
3264 u_int16_t length = OSPF_HEADER_SIZE;
3265
3266 if (IS_DEBUG_OSPF_EVENT)
3267 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003268
3269 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003270
3271 /* Prepare OSPF common header. */
3272 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3273
paul59ea14c2004-07-14 20:50:36 +00003274 /* Prepare OSPF Link State Update body.
3275 * Includes Type-7 translation.
3276 */
paul718e3742002-12-13 20:15:29 +00003277 length += ospf_make_ls_upd (oi, update, op->s);
3278
3279 /* Fill OSPF header. */
3280 ospf_fill_header (oi, op->s, length);
3281
3282 /* Set packet length. */
3283 op->length = length;
3284
3285 /* Decide destination address. */
3286 op->dst.s_addr = addr.s_addr;
3287
3288 /* Add packet to the interface output queue. */
3289 ospf_packet_add (oi, op);
3290
3291 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003292 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003293}
3294
3295static int
3296ospf_ls_upd_send_queue_event (struct thread *thread)
3297{
3298 struct ospf_interface *oi = THREAD_ARG(thread);
3299 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003300 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003301 struct list *update;
paul68b73392004-09-12 14:21:37 +00003302 char again = 0;
paul718e3742002-12-13 20:15:29 +00003303
3304 oi->t_ls_upd_event = NULL;
3305
3306 if (IS_DEBUG_OSPF_EVENT)
3307 zlog_info ("ospf_ls_upd_send_queue start");
3308
paul736d3442003-07-24 23:22:57 +00003309 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003310 {
paul736d3442003-07-24 23:22:57 +00003311 rnext = route_next (rn);
3312
paul718e3742002-12-13 20:15:29 +00003313 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003314 continue;
paul68b73392004-09-12 14:21:37 +00003315
3316 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003317
paul48fe13b2004-07-27 17:40:44 +00003318 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003319
paul68b73392004-09-12 14:21:37 +00003320 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003321 if (listcount(update) == 0)
3322 {
3323 list_delete (rn->info);
3324 rn->info = NULL;
3325 route_unlock_node (rn);
3326 }
3327 else
paul68b73392004-09-12 14:21:37 +00003328 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003329 }
3330
3331 if (again != 0)
3332 {
3333 if (IS_DEBUG_OSPF_EVENT)
3334 zlog_info ("ospf_ls_upd_send_queue: update lists not cleared,"
3335 " %d nodes to try again, raising new event", again);
3336 oi->t_ls_upd_event =
3337 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003338 }
3339
3340 if (IS_DEBUG_OSPF_EVENT)
3341 zlog_info ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003342
paul718e3742002-12-13 20:15:29 +00003343 return 0;
3344}
3345
3346void
hasso52dc7ee2004-09-23 19:18:23 +00003347ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003348{
3349 struct ospf_interface *oi;
3350 struct prefix_ipv4 p;
3351 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003352 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003353
3354 oi = nbr->oi;
3355
3356 p.family = AF_INET;
3357 p.prefixlen = IPV4_MAX_BITLEN;
3358
3359 /* Decide destination address. */
3360 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3361 p.prefix = oi->vl_data->peer_addr;
3362 else if (flag == OSPF_SEND_PACKET_DIRECT)
3363 p.prefix = nbr->address.u.prefix4;
3364 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3365 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3366 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3367 && (flag == OSPF_SEND_PACKET_INDIRECT))
3368 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003369 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3370 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003371 else
3372 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3373
3374 if (oi->type == OSPF_IFTYPE_NBMA)
3375 {
3376 if (flag == OSPF_SEND_PACKET_INDIRECT)
3377 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3378 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3379 zlog_warn ("* LS-Update is sent to myself.");
3380 }
3381
3382 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3383
3384 if (rn->info == NULL)
3385 rn->info = list_new ();
3386
3387 for (n = listhead (update); n; nextnode (n))
3388 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3389
3390 if (oi->t_ls_upd_event == NULL)
3391 oi->t_ls_upd_event =
3392 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3393}
3394
3395static void
hasso52dc7ee2004-09-23 19:18:23 +00003396ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3397 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003398{
3399 struct ospf_packet *op;
3400 u_int16_t length = OSPF_HEADER_SIZE;
3401
3402 op = ospf_packet_new (oi->ifp->mtu);
3403
3404 /* Prepare OSPF common header. */
3405 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3406
3407 /* Prepare OSPF Link State Acknowledgment body. */
3408 length += ospf_make_ls_ack (oi, ack, op->s);
3409
3410 /* Fill OSPF header. */
3411 ospf_fill_header (oi, op->s, length);
3412
3413 /* Set packet length. */
3414 op->length = length;
3415
3416 /* Set destination IP address. */
3417 op->dst = dst;
3418
3419 /* Add packet to the interface output queue. */
3420 ospf_packet_add (oi, op);
3421
3422 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003423 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003424}
3425
3426static int
3427ospf_ls_ack_send_event (struct thread *thread)
3428{
3429 struct ospf_interface *oi = THREAD_ARG (thread);
3430
3431 oi->t_ls_ack_direct = NULL;
3432
3433 while (listcount (oi->ls_ack_direct.ls_ack))
3434 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3435 oi->ls_ack_direct.dst);
3436
3437 return 0;
3438}
3439
3440void
3441ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3442{
3443 struct ospf_interface *oi = nbr->oi;
3444
3445 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3446 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3447
3448 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3449
3450 if (oi->t_ls_ack_direct == NULL)
3451 oi->t_ls_ack_direct =
3452 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3453}
3454
3455/* Send Link State Acknowledgment delayed. */
3456void
3457ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3458{
3459 struct in_addr dst;
3460
3461 /* Decide destination address. */
3462 /* RFC2328 Section 13.5 On non-broadcast
3463 networks, delayed Link State Acknowledgment packets must be
3464 unicast separately over each adjacency (i.e., neighbor whose
3465 state is >= Exchange). */
3466 if (oi->type == OSPF_IFTYPE_NBMA)
3467 {
3468 struct ospf_neighbor *nbr;
3469 struct route_node *rn;
3470
3471 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3472 if ((nbr = rn->info) != NULL)
3473 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3474 while (listcount (oi->ls_ack))
3475 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3476 return;
3477 }
3478 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3479 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3480 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3481 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3482 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3483 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003484 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3485 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003486 else
3487 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3488
3489 while (listcount (oi->ls_ack))
3490 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3491}