blob: d62a06edda66e056deeaf3a246cffb5bdce93a6a [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. */
hassoeb1ce602004-10-08 08:17:22 +000055const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000056{
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)))
hassoeb1ce602004-10-08 08:17:22 +0000350 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000351 else
352 {
353 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000354 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000355 }
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
paul0bfeca32004-09-24 08:07:54 +0000485#ifdef WANT_OSPF_WRITE_FRAGMENT
486void
paul6a99f832004-09-27 12:56:30 +0000487ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
488 struct msghdr *msg, struct iovec **iov,
489 int maxdatasize, int mtu, int flags)
paul0bfeca32004-09-24 08:07:54 +0000490{
491#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000492 u_int16_t offset;
493 int ret;
paul0bfeca32004-09-24 08:07:54 +0000494
495 assert ( op->length == stream_get_endp(op->s) );
496
497 /* we can but try.
498 *
499 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
500 * well as the IP_MF flag, making this all quite pointless.
501 *
502 * However, for a system on which IP_MF is left alone, and ip_id left
503 * alone or else which sets same ip_id for each fragment this might
504 * work, eg linux.
505 *
506 * XXX-TODO: It would be much nicer to have the kernel's use their
507 * existing fragmentation support to do this for us. Bugs/RFEs need to
508 * be raised against the various kernels.
509 */
510
511 /* set More Frag */
512 iph->ip_off |= IP_MF;
513
514 /* ip frag offset is expressed in units of 8byte words */
515 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
516
517 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
518 > maxdatasize )
519 {
520 /* data length of this frag is to next offset value */
521 iov[1]->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
522 iph->ip_len = iov[1]->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000523 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000524
paul18b12c32004-10-05 14:38:29 +0000525 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000526
paul6a99f832004-09-27 12:56:30 +0000527 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000528
paul18b12c32004-10-05 14:38:29 +0000529 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000530
531 if (ret < 0)
532 zlog_warn ("*** sendmsg in ospf_write to %s,"
533 " id %d, off %d, len %d failed with %s",
534 inet_ntoa (iph->ip_dst),
535 iph->ip_id,
536 iph->ip_off,
537 iph->ip_len,
538 strerror (errno));
539
540 iph->ip_off += offset;
541 stream_forward (op->s, iov[1]->iov_len);
542 iov[1]->iov_base = STREAM_PNT (op->s);
543 }
544
545 /* setup for final fragment */
546 iov[1]->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
547 iph->ip_len = iov[1]->iov_len + sizeof (struct ip);
548 iph->ip_off &= (~IP_MF);
549}
550#endif /* WANT_OSPF_WRITE_FRAGMENT */
551
paul718e3742002-12-13 20:15:29 +0000552int
553ospf_write (struct thread *thread)
554{
paul68980082003-03-25 05:07:42 +0000555 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000556 struct ospf_interface *oi;
557 struct ospf_packet *op;
558 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000559 struct ip iph;
560 struct msghdr msg;
paul6a99f832004-09-27 12:56:30 +0000561 struct iovec iov[2], *iovp;
paul68980082003-03-25 05:07:42 +0000562 u_char type;
563 int ret;
564 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000565 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000566#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000567 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000568#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000569 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000570#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000571
paul68980082003-03-25 05:07:42 +0000572 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000573
paul68980082003-03-25 05:07:42 +0000574 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000575 assert (node);
576 oi = getdata (node);
577 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000578
579#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000580 /* seed ipid static with low order bits of time */
581 if (ipid == 0)
582 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000583#endif /* WANT_OSPF_WRITE_FRAGMENT */
584
paul68b73392004-09-12 14:21:37 +0000585 /* convenience - max OSPF data per packet */
586 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
587
paul718e3742002-12-13 20:15:29 +0000588 /* Get one packet from queue. */
589 op = ospf_fifo_head (oi->obuf);
590 assert (op);
591 assert (op->length >= OSPF_HEADER_SIZE);
592
paul68980082003-03-25 05:07:42 +0000593 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
594 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000595 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
596
paul718e3742002-12-13 20:15:29 +0000597 /* Rewrite the md5 signature & update the seq */
598 ospf_make_md5_digest (oi, op);
599
paul68b73392004-09-12 14:21:37 +0000600 /* reset get pointer */
601 stream_set_getp (op->s, 0);
602
603 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000604 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000605
paul718e3742002-12-13 20:15:29 +0000606 sa_dst.sin_family = AF_INET;
607#ifdef HAVE_SIN_LEN
608 sa_dst.sin_len = sizeof(sa_dst);
609#endif /* HAVE_SIN_LEN */
610 sa_dst.sin_addr = op->dst;
611 sa_dst.sin_port = htons (0);
612
613 /* Set DONTROUTE flag if dst is unicast. */
614 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
615 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
616 flags = MSG_DONTROUTE;
617
paul68b73392004-09-12 14:21:37 +0000618 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
619 /* it'd be very strange for header to not be 4byte-word aligned but.. */
620 if ( sizeof (struct ip) > (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
621 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
622
paul718e3742002-12-13 20:15:29 +0000623 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000624 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000625 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000626
paul0bfeca32004-09-24 08:07:54 +0000627#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000628 /* XXX-MT: not thread-safe at all..
629 * XXX: this presumes this is only programme sending OSPF packets
630 * otherwise, no guarantee ipid will be unique
631 */
632 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000633#endif /* WANT_OSPF_WRITE_FRAGMENT */
634
paul718e3742002-12-13 20:15:29 +0000635 iph.ip_off = 0;
636 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
637 iph.ip_ttl = OSPF_VL_IP_TTL;
638 else
639 iph.ip_ttl = OSPF_IP_TTL;
640 iph.ip_p = IPPROTO_OSPFIGP;
641 iph.ip_sum = 0;
642 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
643 iph.ip_dst.s_addr = op->dst.s_addr;
644
645 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000646 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000647 msg.msg_namelen = sizeof (sa_dst);
648 msg.msg_iov = iov;
649 msg.msg_iovlen = 2;
650 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000651 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
652 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000653 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000654
655 /* Sadly we can not rely on kernels to fragment packets because of either
656 * IP_HDRINCL and/or multicast destination being set.
657 */
paul0bfeca32004-09-24 08:07:54 +0000658#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000659 if ( op->length > maxdatasize )
paul6a99f832004-09-27 12:56:30 +0000660 {
661 iovp = iov;
662 ospf_write_frags (ospf->fd, op, &iph, &msg, &iovp, maxdatasize,
663 oi->ifp->mtu, flags);
664 }
paul0bfeca32004-09-24 08:07:54 +0000665#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000666
667 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000668 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000669 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000670 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000671
672 if (ret < 0)
paul68b73392004-09-12 14:21:37 +0000673 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
674 inet_ntoa (iph.ip_dst), strerror (errno));
paul718e3742002-12-13 20:15:29 +0000675
676 /* Retrieve OSPF packet type. */
677 stream_set_getp (op->s, 1);
678 type = stream_getc (op->s);
679
680 /* Show debug sending packet. */
681 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
682 {
683 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
684 {
685 zlog_info ("-----------------------------------------------------");
686 stream_set_getp (op->s, 0);
687 ospf_packet_dump (op->s);
688 }
689
690 zlog_info ("%s sent to [%s] via [%s].",
691 ospf_packet_type_str[type], inet_ntoa (op->dst),
692 IF_NAME (oi));
693
694 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
695 zlog_info ("-----------------------------------------------------");
696 }
697
698 /* Now delete packet from queue. */
699 ospf_packet_delete (oi);
700
701 if (ospf_fifo_head (oi->obuf) == NULL)
702 {
703 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000704 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000705 }
706
707 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000708 if (!list_isempty (ospf->oi_write_q))
709 ospf->t_write =
710 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000711
712 return 0;
713}
714
715/* OSPF Hello message read -- RFC2328 Section 10.5. */
716void
717ospf_hello (struct ip *iph, struct ospf_header *ospfh,
718 struct stream * s, struct ospf_interface *oi, int size)
719{
720 struct ospf_hello *hello;
721 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000722 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000723 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000724
725 /* increment statistics. */
726 oi->hello_in++;
727
728 hello = (struct ospf_hello *) STREAM_PNT (s);
729
730 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000731 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000732 {
733 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
734 {
735 zlog_info ("ospf_header[%s/%s]: selforiginated, "
736 "dropping.",
737 ospf_packet_type_str[ospfh->type],
738 inet_ntoa (iph->ip_src));
739 }
740 return;
741 }
paul718e3742002-12-13 20:15:29 +0000742
743 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000744 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
paulc2191ea2003-04-18 23:59:35 +0000745 zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
746 inet_ntoa (ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000747 return;
paulf2c80652002-12-13 21:44:27 +0000748 }
paul718e3742002-12-13 20:15:29 +0000749
750 /* get neighbor prefix. */
751 p.family = AF_INET;
752 p.prefixlen = ip_masklen (hello->network_mask);
753 p.u.prefix4 = iph->ip_src;
754
755 /* Compare network mask. */
756 /* Checking is ignored for Point-to-Point and Virtual link. */
757 if (oi->type != OSPF_IFTYPE_POINTOPOINT
758 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
759 if (oi->address->prefixlen != p.prefixlen)
760 {
761 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
762 inet_ntoa (ospfh->router_id));
763 return;
764 }
765
766 /* Compare Hello Interval. */
767 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
768 {
769 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
770 inet_ntoa (ospfh->router_id));
771 return;
772 }
773
774 /* Compare Router Dead Interval. */
775 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
776 {
777 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
778 inet_ntoa (ospfh->router_id));
779 return;
780 }
781
782 if (IS_DEBUG_OSPF_EVENT)
783 zlog_info ("Packet %s [Hello:RECV]: Options %s",
784 inet_ntoa (ospfh->router_id),
785 ospf_options_dump (hello->options));
786
787 /* Compare options. */
788#define REJECT_IF_TBIT_ON 1 /* XXX */
789#ifdef REJECT_IF_TBIT_ON
790 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
791 {
792 /*
793 * This router does not support non-zero TOS.
794 * Drop this Hello packet not to establish neighbor relationship.
795 */
796 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
797 inet_ntoa (ospfh->router_id));
798 return;
799 }
800#endif /* REJECT_IF_TBIT_ON */
801
802#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000803 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000804 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
805 {
806 /*
807 * This router does know the correct usage of O-bit
808 * the bit should be set in DD packet only.
809 */
810 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
811 inet_ntoa (ospfh->router_id));
812#ifdef STRICT_OBIT_USAGE_CHECK
813 return; /* Reject this packet. */
814#else /* STRICT_OBIT_USAGE_CHECK */
815 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
816#endif /* STRICT_OBIT_USAGE_CHECK */
817 }
818#endif /* HAVE_OPAQUE_LSA */
819
820 /* new for NSSA is to ensure that NP is on and E is off */
821
paul718e3742002-12-13 20:15:29 +0000822 if (oi->area->external_routing == OSPF_AREA_NSSA)
823 {
824 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
825 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
826 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
827 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
828 {
829 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
830 return;
831 }
832 if (IS_DEBUG_OSPF_NSSA)
833 zlog_info ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
834 }
835 else
paul718e3742002-12-13 20:15:29 +0000836 /* The setting of the E-bit found in the Hello Packet's Options
837 field must match this area's ExternalRoutingCapability A
838 mismatch causes processing to stop and the packet to be
839 dropped. The setting of the rest of the bits in the Hello
840 Packet's Options field should be ignored. */
841 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
842 CHECK_FLAG (hello->options, OSPF_OPTION_E))
843 {
844 zlog_warn ("Packet[Hello:RECV]: my options: %x, his options %x",
845 OPTIONS (oi), hello->options);
846 return;
847 }
paul718e3742002-12-13 20:15:29 +0000848
pauld3f0d622004-05-05 15:27:15 +0000849 /* get neighbour struct */
850 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
851
852 /* neighbour must be valid, ospf_nbr_get creates if none existed */
853 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000854
855 old_state = nbr->state;
856
857 /* Add event to thread. */
858 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
859
860 /* RFC2328 Section 9.5.1
861 If the router is not eligible to become Designated Router,
862 (snip) It must also send an Hello Packet in reply to an
863 Hello Packet received from any eligible neighbor (other than
864 the current Designated Router and Backup Designated Router). */
865 if (oi->type == OSPF_IFTYPE_NBMA)
866 if (PRIORITY(oi) == 0 && hello->priority > 0
867 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
868 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
869 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
870 OSPF_HELLO_REPLY_DELAY);
871
872 /* on NBMA network type, it happens to receive bidirectional Hello packet
873 without advance 1-Way Received event.
874 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
875 if (oi->type == OSPF_IFTYPE_NBMA &&
876 (old_state == NSM_Down || old_state == NSM_Attempt))
877 {
878 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
879 nbr->priority = hello->priority;
880 nbr->d_router = hello->d_router;
881 nbr->bd_router = hello->bd_router;
882 return;
883 }
884
paul68980082003-03-25 05:07:42 +0000885 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000886 size - OSPF_HELLO_MIN_SIZE))
887 {
888 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
889 nbr->options |= hello->options;
890 }
891 else
892 {
893 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
894 /* Set neighbor information. */
895 nbr->priority = hello->priority;
896 nbr->d_router = hello->d_router;
897 nbr->bd_router = hello->bd_router;
898 return;
899 }
900
901 /* If neighbor itself declares DR and no BDR exists,
902 cause event BackupSeen */
903 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
904 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
905 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
906
907 /* neighbor itself declares BDR. */
908 if (oi->state == ISM_Waiting &&
909 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
910 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
911
912 /* had not previously. */
913 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
914 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
915 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
916 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
917 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
918
919 /* had not previously. */
920 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
921 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
922 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
923 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
924 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
925
926 /* Neighbor priority check. */
927 if (nbr->priority >= 0 && nbr->priority != hello->priority)
928 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
929
930 /* Set neighbor information. */
931 nbr->priority = hello->priority;
932 nbr->d_router = hello->d_router;
933 nbr->bd_router = hello->bd_router;
934}
935
936/* Save DD flags/options/Seqnum received. */
937void
938ospf_db_desc_save_current (struct ospf_neighbor *nbr,
939 struct ospf_db_desc *dd)
940{
941 nbr->last_recv.flags = dd->flags;
942 nbr->last_recv.options = dd->options;
943 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
944}
945
946/* Process rest of DD packet. */
947static void
948ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
949 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
950 u_int16_t size)
951{
952 struct ospf_lsa *new, *find;
953 struct lsa_header *lsah;
954
955 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
956 for (size -= OSPF_DB_DESC_MIN_SIZE;
957 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
958 {
959 lsah = (struct lsa_header *) STREAM_PNT (s);
960 stream_forward (s, OSPF_LSA_HEADER_SIZE);
961
962 /* Unknown LS type. */
963 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
964 {
965 zlog_warn ("Pakcet [DD:RECV]: Unknown LS type %d.", lsah->type);
966 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
967 return;
968 }
969
970#ifdef HAVE_OPAQUE_LSA
971 if (IS_OPAQUE_LSA (lsah->type)
972 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
973 {
974 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
975 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
976 return;
977 }
978#endif /* HAVE_OPAQUE_LSA */
979
980 switch (lsah->type)
981 {
982 case OSPF_AS_EXTERNAL_LSA:
983#ifdef HAVE_OPAQUE_LSA
984 case OSPF_OPAQUE_AS_LSA:
985#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +0000986 /* Check for stub area. Reject if AS-External from stub but
987 allow if from NSSA. */
988 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +0000989 {
990 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
991 lsah->type, inet_ntoa (lsah->id),
992 (oi->area->external_routing == OSPF_AREA_STUB) ?\
993 "STUB" : "NSSA");
994 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
995 return;
996 }
997 break;
998 default:
999 break;
1000 }
1001
1002 /* Create LS-request object. */
1003 new = ospf_ls_request_new (lsah);
1004
1005 /* Lookup received LSA, then add LS request list. */
1006 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1007 if (!find || ospf_lsa_more_recent (find, new) < 0)
1008 {
1009 ospf_ls_request_add (nbr, new);
1010 ospf_lsa_discard (new);
1011 }
1012 else
1013 {
1014 /* Received LSA is not recent. */
1015 if (IS_DEBUG_OSPF_EVENT)
1016 zlog_info ("Packet [DD:RECV]: LSA received Type %d, "
1017 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1018 ospf_lsa_discard (new);
1019 continue;
1020 }
1021 }
1022
1023 /* Master */
1024 if (IS_SET_DD_MS (nbr->dd_flags))
1025 {
1026 nbr->dd_seqnum++;
1027 /* Entire DD packet sent. */
1028 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1029 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1030 else
1031 /* Send new DD packet. */
1032 ospf_db_desc_send (nbr);
1033 }
1034 /* Slave */
1035 else
1036 {
1037 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1038
1039 /* When master's more flags is not set. */
1040 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1041 {
1042 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1043 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1044 }
1045
1046 /* Send DD pakcet in reply. */
1047 ospf_db_desc_send (nbr);
1048 }
1049
1050 /* Save received neighbor values from DD. */
1051 ospf_db_desc_save_current (nbr, dd);
1052}
1053
1054int
1055ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1056{
1057 /* Is DD duplicated? */
1058 if (dd->options == nbr->last_recv.options &&
1059 dd->flags == nbr->last_recv.flags &&
1060 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1061 return 1;
1062
1063 return 0;
1064}
1065
1066/* OSPF Database Description message read -- RFC2328 Section 10.6. */
1067void
1068ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1069 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1070{
1071 struct ospf_db_desc *dd;
1072 struct ospf_neighbor *nbr;
1073
1074 /* Increment statistics. */
1075 oi->db_desc_in++;
1076
1077 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001078
pauld3f0d622004-05-05 15:27:15 +00001079 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001080 if (nbr == NULL)
1081 {
1082 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1083 inet_ntoa (ospfh->router_id));
1084 return;
1085 }
1086
1087 /* Check MTU. */
1088 if (ntohs (dd->mtu) > oi->ifp->mtu)
1089 {
1090 zlog_warn ("Packet[DD]: MTU is larger than [%s]'s MTU", IF_NAME (oi));
1091 return;
1092 }
1093
pauld363df22003-06-19 00:26:34 +00001094 /*
1095 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1096 * required. In fact at least JunOS sends DD packets with P bit clear.
1097 * Until proper solution is developped, this hack should help.
1098 *
1099 * Update: According to the RFCs, N bit is specified /only/ for Hello
1100 * options, unfortunately its use in DD options is not specified. Hence some
1101 * implementations follow E-bit semantics and set it in DD options, and some
1102 * treat it as unspecified and hence follow the directive "default for
1103 * options is clear", ie unset.
1104 *
1105 * Reset the flag, as ospfd follows E-bit semantics.
1106 */
1107 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1108 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1109 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1110 {
1111 if (IS_DEBUG_OSPF_EVENT)
paul3db0a772003-06-19 01:07:40 +00001112 zlog_notice ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001113 inet_ntoa (nbr->router_id) );
1114 SET_FLAG (dd->options, OSPF_OPTION_NP);
1115 }
pauld363df22003-06-19 00:26:34 +00001116
paul718e3742002-12-13 20:15:29 +00001117#ifdef REJECT_IF_TBIT_ON
1118 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1119 {
1120 /*
1121 * In Hello protocol, optional capability must have checked
1122 * to prevent this T-bit enabled router be my neighbor.
1123 */
1124 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1125 return;
1126 }
1127#endif /* REJECT_IF_TBIT_ON */
1128
1129#ifdef HAVE_OPAQUE_LSA
1130 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001131 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001132 {
1133 /*
1134 * This node is not configured to handle O-bit, for now.
1135 * Clear it to ignore unsupported capability proposed by neighbor.
1136 */
1137 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1138 }
1139#endif /* HAVE_OPAQUE_LSA */
1140
1141 /* Process DD packet by neighbor status. */
1142 switch (nbr->state)
1143 {
1144 case NSM_Down:
1145 case NSM_Attempt:
1146 case NSM_TwoWay:
1147 zlog_warn ("Packet[DD]: Neighbor state is %s, packet discarded.",
1148 LOOKUP (ospf_nsm_state_msg, nbr->state));
1149 break;
1150 case NSM_Init:
1151 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1152 /* If the new state is ExStart, the processing of the current
1153 packet should then continue in this new state by falling
1154 through to case ExStart below. */
1155 if (nbr->state != NSM_ExStart)
1156 break;
1157 case NSM_ExStart:
1158 /* Initial DBD */
1159 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1160 (size == OSPF_DB_DESC_MIN_SIZE))
1161 {
paul68980082003-03-25 05:07:42 +00001162 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001163 {
1164 /* We're Slave---obey */
1165 zlog_warn ("Packet[DD]: Negotiation done (Slave).");
1166 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1167 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1168 }
1169 else
1170 {
1171 /* We're Master, ignore the initial DBD from Slave */
1172 zlog_warn ("Packet[DD]: Initial DBD from Slave, ignoring.");
1173 break;
1174 }
1175 }
1176 /* Ack from the Slave */
1177 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1178 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001179 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001180 {
1181 zlog_warn ("Packet[DD]: Negotiation done (Master).");
1182 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1183 }
1184 else
1185 {
1186 zlog_warn ("Packet[DD]: Negotiation fails.");
1187 break;
1188 }
1189
1190 /* This is where the real Options are saved */
1191 nbr->options = dd->options;
1192
1193#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001194 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001195 {
1196 if (IS_DEBUG_OSPF_EVENT)
1197 zlog_info ("Neighbor[%s] is %sOpaque-capable.",
1198 inet_ntoa (nbr->router_id),
1199 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1200
1201 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1202 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1203 {
1204 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1205 /* This situation is undesirable, but not a real error. */
1206 }
1207 }
1208#endif /* HAVE_OPAQUE_LSA */
1209
1210 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1211
1212 /* continue processing rest of packet. */
1213 ospf_db_desc_proc (s, oi, nbr, dd, size);
1214 break;
1215 case NSM_Exchange:
1216 if (ospf_db_desc_is_dup (dd, nbr))
1217 {
1218 if (IS_SET_DD_MS (nbr->dd_flags))
1219 /* Master: discard duplicated DD packet. */
1220 zlog_warn ("Packet[DD] (Master): packet duplicated.");
1221 else
1222 /* Slave: cause to retransmit the last Database Description. */
1223 {
1224 zlog_warn ("Packet[DD] [Slave]: packet duplicated.");
1225 ospf_db_desc_resend (nbr);
1226 }
1227 break;
1228 }
1229
1230 /* Otherwise DD packet should be checked. */
1231 /* Check Master/Slave bit mismatch */
1232 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1233 {
1234 zlog_warn ("Packet[DD]: MS-bit mismatch.");
1235 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1236 if (IS_DEBUG_OSPF_EVENT)
1237 zlog_info ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1238 dd->flags, nbr->dd_flags);
1239 break;
1240 }
1241
1242 /* Check initialize bit is set. */
1243 if (IS_SET_DD_I (dd->flags))
1244 {
1245 zlog_warn ("Packet[DD]: I-bit set.");
1246 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1247 break;
1248 }
1249
1250 /* Check DD Options. */
1251 if (dd->options != nbr->options)
1252 {
1253#ifdef ORIGINAL_CODING
1254 /* Save the new options for debugging */
1255 nbr->options = dd->options;
1256#endif /* ORIGINAL_CODING */
1257 zlog_warn ("Packet[DD]: options mismatch.");
1258 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1259 break;
1260 }
1261
1262 /* Check DD sequence number. */
1263 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1264 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1265 (!IS_SET_DD_MS (nbr->dd_flags) &&
1266 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1267 {
1268 zlog_warn ("Pakcet[DD]: sequence number mismatch.");
1269 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1270 break;
1271 }
1272
1273 /* Continue processing rest of packet. */
1274 ospf_db_desc_proc (s, oi, nbr, dd, size);
1275 break;
1276 case NSM_Loading:
1277 case NSM_Full:
1278 if (ospf_db_desc_is_dup (dd, nbr))
1279 {
1280 if (IS_SET_DD_MS (nbr->dd_flags))
1281 {
1282 /* Master should discard duplicate DD packet. */
1283 zlog_warn ("Pakcet[DD]: duplicated, packet discarded.");
1284 break;
1285 }
1286 else
1287 {
1288 struct timeval t, now;
1289 gettimeofday (&now, NULL);
1290 t = tv_sub (now, nbr->last_send_ts);
1291 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1292 {
1293 /* In states Loading and Full the slave must resend
1294 its last Database Description packet in response to
1295 duplicate Database Description packets received
1296 from the master. For this reason the slave must
1297 wait RouterDeadInterval seconds before freeing the
1298 last Database Description packet. Reception of a
1299 Database Description packet from the master after
1300 this interval will generate a SeqNumberMismatch
1301 neighbor event. RFC2328 Section 10.8 */
1302 ospf_db_desc_resend (nbr);
1303 break;
1304 }
1305 }
1306 }
1307
1308 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1309 break;
1310 default:
1311 zlog_warn ("Packet[DD]: NSM illegal status.");
1312 break;
1313 }
1314}
1315
1316#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1317
1318/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1319void
1320ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1321 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1322{
1323 struct ospf_neighbor *nbr;
1324 u_int32_t ls_type;
1325 struct in_addr ls_id;
1326 struct in_addr adv_router;
1327 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001328 struct list *ls_upd;
paul718e3742002-12-13 20:15:29 +00001329 int length;
1330
1331 /* Increment statistics. */
1332 oi->ls_req_in++;
1333
pauld3f0d622004-05-05 15:27:15 +00001334 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001335 if (nbr == NULL)
1336 {
1337 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1338 inet_ntoa (ospfh->router_id));
1339 return;
1340 }
1341
1342 /* Neighbor State should be Exchange or later. */
1343 if (nbr->state != NSM_Exchange &&
1344 nbr->state != NSM_Loading &&
1345 nbr->state != NSM_Full)
1346 {
1347 zlog_warn ("Link State Request: Neighbor state is %s, packet discarded.",
1348 LOOKUP (ospf_nsm_state_msg, nbr->state));
1349 return;
1350 }
1351
1352 /* Send Link State Update for ALL requested LSAs. */
1353 ls_upd = list_new ();
1354 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1355
1356 while (size >= OSPF_LSA_KEY_SIZE)
1357 {
1358 /* Get one slice of Link State Request. */
1359 ls_type = stream_getl (s);
1360 ls_id.s_addr = stream_get_ipv4 (s);
1361 adv_router.s_addr = stream_get_ipv4 (s);
1362
1363 /* Verify LSA type. */
1364 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1365 {
1366 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1367 list_delete (ls_upd);
1368 return;
1369 }
1370
1371 /* Search proper LSA in LSDB. */
1372 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1373 if (find == NULL)
1374 {
1375 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1376 list_delete (ls_upd);
1377 return;
1378 }
1379
1380 /* Packet overflows MTU size, send immediatly. */
1381 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1382 {
1383 if (oi->type == OSPF_IFTYPE_NBMA)
1384 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1385 else
1386 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1387
1388 /* Only remove list contents. Keep ls_upd. */
1389 list_delete_all_node (ls_upd);
1390
1391 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1392 }
1393
1394 /* Append LSA to update list. */
1395 listnode_add (ls_upd, find);
1396 length += ntohs (find->data->length);
1397
1398 size -= OSPF_LSA_KEY_SIZE;
1399 }
1400
1401 /* Send rest of Link State Update. */
1402 if (listcount (ls_upd) > 0)
1403 {
1404 if (oi->type == OSPF_IFTYPE_NBMA)
1405 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1406 else
1407 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1408
1409 list_delete (ls_upd);
1410 }
1411 else
1412 list_free (ls_upd);
1413}
1414
1415/* Get the list of LSAs from Link State Update packet.
1416 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001417static struct list *
paul718e3742002-12-13 20:15:29 +00001418ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1419 struct ospf_interface *oi, size_t size)
1420{
1421 u_int16_t count, sum;
1422 u_int32_t length;
1423 struct lsa_header *lsah;
1424 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001425 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001426
1427 lsas = list_new ();
1428
1429 count = stream_getl (s);
1430 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1431
1432 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1433 size -= length, stream_forward (s, length), count--)
1434 {
1435 lsah = (struct lsa_header *) STREAM_PNT (s);
1436 length = ntohs (lsah->length);
1437
1438 if (length > size)
1439 {
1440 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1441 break;
1442 }
1443
1444 /* Validate the LSA's LS checksum. */
1445 sum = lsah->checksum;
1446 if (sum != ospf_lsa_checksum (lsah))
1447 {
1448 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1449 sum, lsah->checksum);
1450 continue;
1451 }
1452
1453 /* Examine the LSA's LS type. */
1454 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1455 {
1456 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1457 continue;
1458 }
1459
1460 /*
1461 * What if the received LSA's age is greater than MaxAge?
1462 * Treat it as a MaxAge case -- endo.
1463 */
1464 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1465 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1466
1467#ifdef HAVE_OPAQUE_LSA
1468 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1469 {
1470#ifdef STRICT_OBIT_USAGE_CHECK
1471 if ((IS_OPAQUE_LSA(lsah->type) &&
1472 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1473 || (! IS_OPAQUE_LSA(lsah->type) &&
1474 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1475 {
1476 /*
1477 * This neighbor must know the exact usage of O-bit;
1478 * the bit will be set in Type-9,10,11 LSAs only.
1479 */
1480 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1481 continue;
1482 }
1483#endif /* STRICT_OBIT_USAGE_CHECK */
1484
1485 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1486 if (lsah->type == OSPF_OPAQUE_AS_LSA
1487 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1488 {
1489 if (IS_DEBUG_OSPF_EVENT)
1490 zlog_info ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1491 continue;
1492 }
1493 }
1494 else if (IS_OPAQUE_LSA(lsah->type))
1495 {
1496 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1497 continue;
1498 }
1499#endif /* HAVE_OPAQUE_LSA */
1500
1501 /* Create OSPF LSA instance. */
1502 lsa = ospf_lsa_new ();
1503
1504 /* We may wish to put some error checking if type NSSA comes in
1505 and area not in NSSA mode */
1506 switch (lsah->type)
1507 {
1508 case OSPF_AS_EXTERNAL_LSA:
1509#ifdef HAVE_OPAQUE_LSA
1510 case OSPF_OPAQUE_AS_LSA:
1511 lsa->area = NULL;
1512 break;
1513 case OSPF_OPAQUE_LINK_LSA:
1514 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1515 /* Fallthrough */
1516#endif /* HAVE_OPAQUE_LSA */
1517 default:
1518 lsa->area = oi->area;
1519 break;
1520 }
1521
1522 lsa->data = ospf_lsa_data_new (length);
1523 memcpy (lsa->data, lsah, length);
1524
1525 if (IS_DEBUG_OSPF_EVENT)
1526 zlog_info("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1527 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1528 listnode_add (lsas, lsa);
1529 }
1530
1531 return lsas;
1532}
1533
1534/* Cleanup Update list. */
1535void
hasso52dc7ee2004-09-23 19:18:23 +00001536ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001537{
hasso52dc7ee2004-09-23 19:18:23 +00001538 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001539 struct ospf_lsa *lsa;
1540
1541 for (node = listhead (lsas); node; nextnode (node))
1542 if ((lsa = getdata (node)) != NULL)
1543 ospf_lsa_discard (lsa);
1544
1545 list_delete (lsas);
1546}
1547
1548/* OSPF Link State Update message read -- RFC2328 Section 13. */
1549void
1550ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1551 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1552{
1553 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001554 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001555#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001556 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001557#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001558 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001559 struct ospf_lsa *lsa = NULL;
1560 /* unsigned long ls_req_found = 0; */
1561
1562 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1563
1564 /* Increment statistics. */
1565 oi->ls_upd_in++;
1566
1567 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001568 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001569 if (nbr == NULL)
1570 {
1571 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1572 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1573 return;
1574 }
1575
1576 /* Check neighbor state. */
1577 if (nbr->state < NSM_Exchange)
1578 {
1579 zlog_warn ("Link State Update: Neighbor[%s] state is less than Exchange",
1580 inet_ntoa (ospfh->router_id));
1581 return;
1582 }
1583
1584 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1585 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1586 * of section 13.
1587 */
1588 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1589
1590#ifdef HAVE_OPAQUE_LSA
1591 /*
1592 * Prepare two kinds of lists to clean up unwanted self-originated
1593 * Opaque-LSAs from the routing domain as soon as possible.
1594 */
1595 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1596 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1597
1598 /*
1599 * If self-originated Opaque-LSAs that have flooded before restart
1600 * are contained in the received LSUpd message, corresponding LSReq
1601 * messages to be sent may have to be modified.
1602 * To eliminate possible race conditions such that flushing and normal
1603 * updating for the same LSA would take place alternately, this trick
1604 * must be done before entering to the loop below.
1605 */
1606 ospf_opaque_adjust_lsreq (nbr, lsas);
1607#endif /* HAVE_OPAQUE_LSA */
1608
1609#define DISCARD_LSA(L,N) {\
1610 if (IS_DEBUG_OSPF_EVENT) \
1611 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1612 ospf_lsa_discard (L); \
1613 continue; }
1614
1615 /* Process each LSA received in the one packet. */
1616 for (node = listhead (lsas); node; node = next)
1617 {
1618 struct ospf_lsa *ls_ret, *current;
1619 int ret = 1;
1620
1621 next = node->next;
1622
1623 lsa = getdata (node);
1624
paul718e3742002-12-13 20:15:29 +00001625 if (IS_DEBUG_OSPF_NSSA)
1626 {
1627 char buf1[INET_ADDRSTRLEN];
1628 char buf2[INET_ADDRSTRLEN];
1629 char buf3[INET_ADDRSTRLEN];
1630
1631 zlog_info("LSA Type-%d from %s, ID: %s, ADV: %s",
1632 lsa->data->type,
1633 inet_ntop (AF_INET, &ospfh->router_id,
1634 buf1, INET_ADDRSTRLEN),
1635 inet_ntop (AF_INET, &lsa->data->id,
1636 buf2, INET_ADDRSTRLEN),
1637 inet_ntop (AF_INET, &lsa->data->adv_router,
1638 buf3, INET_ADDRSTRLEN));
1639 }
paul718e3742002-12-13 20:15:29 +00001640
1641 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1642
1643 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1644
1645 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1646
1647 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1648
1649 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1650
1651 /* Do take in Type-7's if we are an NSSA */
1652
1653 /* If we are also an ABR, later translate them to a Type-5 packet */
1654
1655 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1656 translate them to a separate Type-5 packet. */
1657
1658 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1659 /* Reject from STUB or NSSA */
1660 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1661 {
1662 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001663 if (IS_DEBUG_OSPF_NSSA)
1664 zlog_info("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001665 }
1666
paul718e3742002-12-13 20:15:29 +00001667 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1668 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1669 {
1670 DISCARD_LSA (lsa,2);
1671 if (IS_DEBUG_OSPF_NSSA)
1672 zlog_info("Incoming NSSA LSA Discarded: Not NSSA Area");
1673 }
paul718e3742002-12-13 20:15:29 +00001674
1675 /* Find the LSA in the current database. */
1676
1677 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1678
1679 /* If the LSA's LS age is equal to MaxAge, and there is currently
1680 no instance of the LSA in the router's link state database,
1681 and none of router's neighbors are in states Exchange or Loading,
1682 then take the following actions. */
1683
1684 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001685 (ospf_nbr_count (oi, NSM_Exchange) +
1686 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001687 {
1688 /* Response Link State Acknowledgment. */
1689 ospf_ls_ack_send (nbr, lsa);
1690
1691 /* Discard LSA. */
1692 zlog_warn ("Link State Update: LS age is equal to MaxAge.");
1693 DISCARD_LSA (lsa, 3);
1694 }
1695
1696#ifdef HAVE_OPAQUE_LSA
1697 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001698 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001699 {
1700 /*
1701 * Even if initial flushing seems to be completed, there might
1702 * be a case that self-originated LSA with MaxAge still remain
1703 * in the routing domain.
1704 * Just send an LSAck message to cease retransmission.
1705 */
1706 if (IS_LSA_MAXAGE (lsa))
1707 {
1708 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1709 ospf_ls_ack_send (nbr, lsa);
1710 ospf_lsa_discard (lsa);
1711
1712 if (current != NULL && ! IS_LSA_MAXAGE (current))
1713 ospf_opaque_lsa_refresh_schedule (current);
1714 continue;
1715 }
1716
1717 /*
1718 * If an instance of self-originated Opaque-LSA is not found
1719 * in the LSDB, there are some possible cases here.
1720 *
1721 * 1) This node lost opaque-capability after restart.
1722 * 2) Else, a part of opaque-type is no more supported.
1723 * 3) Else, a part of opaque-id is no more supported.
1724 *
1725 * Anyway, it is still this node's responsibility to flush it.
1726 * Otherwise, the LSA instance remains in the routing domain
1727 * until its age reaches to MaxAge.
1728 */
1729 if (current == NULL)
1730 {
1731 if (IS_DEBUG_OSPF_EVENT)
1732 zlog_info ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
1733
1734 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1735 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1736 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1737 continue;
1738 }
1739 }
1740#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001741 /* It might be happen that received LSA is self-originated network LSA, but
1742 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1743 * Link State ID is one of the router's own IP interface addresses but whose
1744 * Advertising Router is not equal to the router's own Router ID
1745 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1746 */
1747
1748 if(lsa->data->type == OSPF_NETWORK_LSA)
1749 {
hasso52dc7ee2004-09-23 19:18:23 +00001750 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001751 int Flag = 0;
1752
1753 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1754 {
1755 struct ospf_interface *out_if = getdata(oi_node);
1756 if(out_if == NULL)
1757 break;
1758
1759 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1760 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1761 {
1762 if(out_if->network_lsa_self)
1763 {
1764 ospf_lsa_flush_area(lsa,out_if->area);
1765 if(IS_DEBUG_OSPF_EVENT)
1766 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
1767 lsa, (int) lsa->data->type);
1768 ospf_lsa_discard (lsa);
1769 Flag = 1;
1770 }
1771 break;
1772 }
1773 }
1774 if(Flag)
1775 continue;
1776 }
paul718e3742002-12-13 20:15:29 +00001777
1778 /* (5) Find the instance of this LSA that is currently contained
1779 in the router's link state database. If there is no
1780 database copy, or the received LSA is more recent than
1781 the database copy the following steps must be performed. */
1782
1783 if (current == NULL ||
1784 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1785 {
1786 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001787 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001788 DISCARD_LSA (lsa, 4);
1789 continue;
1790 }
1791
1792 /* (6) Else, If there is an instance of the LSA on the sending
1793 neighbor's Link state request list, an error has occurred in
1794 the Database Exchange process. In this case, restart the
1795 Database Exchange process by generating the neighbor event
1796 BadLSReq for the sending neighbor and stop processing the
1797 Link State Update packet. */
1798
1799 if (ospf_ls_request_lookup (nbr, lsa))
1800 {
1801 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1802 zlog_warn ("LSA instance exists on Link state request list");
1803
1804 /* Clean list of LSAs. */
1805 ospf_upd_list_clean (lsas);
1806 /* this lsa is not on lsas list already. */
1807 ospf_lsa_discard (lsa);
1808#ifdef HAVE_OPAQUE_LSA
1809 list_delete (mylsa_acks);
1810 list_delete (mylsa_upds);
1811#endif /* HAVE_OPAQUE_LSA */
1812 return;
1813 }
1814
1815 /* If the received LSA is the same instance as the database copy
1816 (i.e., neither one is more recent) the following two steps
1817 should be performed: */
1818
1819 if (ret == 0)
1820 {
1821 /* If the LSA is listed in the Link state retransmission list
1822 for the receiving adjacency, the router itself is expecting
1823 an acknowledgment for this LSA. The router should treat the
1824 received LSA as an acknowledgment by removing the LSA from
1825 the Link state retransmission list. This is termed an
1826 "implied acknowledgment". */
1827
1828 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1829
1830 if (ls_ret != NULL)
1831 {
1832 ospf_ls_retransmit_delete (nbr, ls_ret);
1833
1834 /* Delayed acknowledgment sent if advertisement received
1835 from Designated Router, otherwise do nothing. */
1836 if (oi->state == ISM_Backup)
1837 if (NBR_IS_DR (nbr))
1838 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1839
1840 DISCARD_LSA (lsa, 5);
1841 }
1842 else
1843 /* Acknowledge the receipt of the LSA by sending a
1844 Link State Acknowledgment packet back out the receiving
1845 interface. */
1846 {
1847 ospf_ls_ack_send (nbr, lsa);
1848 DISCARD_LSA (lsa, 6);
1849 }
1850 }
1851
1852 /* The database copy is more recent. If the database copy
1853 has LS age equal to MaxAge and LS sequence number equal to
1854 MaxSequenceNumber, simply discard the received LSA without
1855 acknowledging it. (In this case, the LSA's LS sequence number is
1856 wrapping, and the MaxSequenceNumber LSA must be completely
1857 flushed before any new LSA instance can be introduced). */
1858
1859 else if (ret > 0) /* Database copy is more recent */
1860 {
1861 if (IS_LSA_MAXAGE (current) &&
1862 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1863 {
1864 DISCARD_LSA (lsa, 7);
1865 }
1866 /* Otherwise, as long as the database copy has not been sent in a
1867 Link State Update within the last MinLSArrival seconds, send the
1868 database copy back to the sending neighbor, encapsulated within
1869 a Link State Update Packet. The Link State Update Packet should
1870 be sent directly to the neighbor. In so doing, do not put the
1871 database copy of the LSA on the neighbor's link state
1872 retransmission list, and do not acknowledge the received (less
1873 recent) LSA instance. */
1874 else
1875 {
1876 struct timeval now;
1877
1878 gettimeofday (&now, NULL);
1879
1880 if (tv_cmp (tv_sub (now, current->tv_orig),
1881 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1882 /* Trap NSSA type later.*/
1883 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1884 DISCARD_LSA (lsa, 8);
1885 }
1886 }
1887 }
1888
1889#ifdef HAVE_OPAQUE_LSA
1890 /*
1891 * Now that previously originated Opaque-LSAs those which not yet
1892 * installed into LSDB are captured, take several steps to clear
1893 * them completely from the routing domain, before proceeding to
1894 * origination for the current target Opaque-LSAs.
1895 */
1896 while (listcount (mylsa_acks) > 0)
1897 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1898
1899 if (listcount (mylsa_upds) > 0)
1900 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1901
1902 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001903 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001904#endif /* HAVE_OPAQUE_LSA */
1905
1906 assert (listcount (lsas) == 0);
1907 list_delete (lsas);
1908}
1909
1910/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1911void
1912ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1913 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1914{
1915 struct ospf_neighbor *nbr;
1916#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001917 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001918#endif /* HAVE_OPAQUE_LSA */
1919
1920 /* increment statistics. */
1921 oi->ls_ack_in++;
1922
pauld3f0d622004-05-05 15:27:15 +00001923 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001924 if (nbr == NULL)
1925 {
1926 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1927 inet_ntoa (ospfh->router_id));
1928 return;
1929 }
1930
1931 if (nbr->state < NSM_Exchange)
1932 {
1933 zlog_warn ("Link State Acknowledgment: State is less than Exchange.");
1934 return;
1935 }
1936
1937#ifdef HAVE_OPAQUE_LSA
1938 opaque_acks = list_new ();
1939#endif /* HAVE_OPAQUE_LSA */
1940
1941 while (size >= OSPF_LSA_HEADER_SIZE)
1942 {
1943 struct ospf_lsa *lsa, *lsr;
1944
1945 lsa = ospf_lsa_new ();
1946 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1947
1948 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1949 size -= OSPF_LSA_HEADER_SIZE;
1950 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1951
1952 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1953 {
1954 lsa->data = NULL;
1955 ospf_lsa_discard (lsa);
1956 continue;
1957 }
1958
1959 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1960
1961 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1962 {
1963#ifdef HAVE_OPAQUE_LSA
1964 /* Keep this LSA entry for later reference. */
1965 if (IS_OPAQUE_LSA (lsr->data->type))
1966 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
1967#endif /* HAVE_OPAQUE_LSA */
1968
1969 ospf_ls_retransmit_delete (nbr, lsr);
1970 }
1971
1972 lsa->data = NULL;
1973 ospf_lsa_discard (lsa);
1974 }
1975
1976#ifdef HAVE_OPAQUE_LSA
1977 if (listcount (opaque_acks) > 0)
1978 ospf_opaque_ls_ack_received (nbr, opaque_acks);
1979
1980 list_delete (opaque_acks);
1981 return;
1982#endif /* HAVE_OPAQUE_LSA */
1983}
1984
1985struct stream *
1986ospf_recv_packet (int fd, struct interface **ifp)
1987{
1988 int ret;
1989 struct ip iph;
1990 u_int16_t ip_len;
1991 struct stream *ibuf;
1992 unsigned int ifindex = 0;
1993 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00001994#if defined(CMSG_SPACE)
1995 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00001996 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
gdtd0deca62004-08-26 13:14:07 +00001997#else
hassoeb1ce602004-10-08 08:17:22 +00001998 char buff [sizeof (struct cmsghdr) + SOPT_SIZE_CMSG_IFINDEX_IPV4()];
gdtd0deca62004-08-26 13:14:07 +00001999#endif
paul2dd8bb42004-07-23 15:13:48 +00002000 struct msghdr msgh;
2001
paul68defd62004-09-27 07:27:13 +00002002 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002003 msgh.msg_iov = &iov;
2004 msgh.msg_iovlen = 1;
2005 msgh.msg_control = (caddr_t) buff;
2006 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002007
paul718e3742002-12-13 20:15:29 +00002008 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2009
2010 if (ret != sizeof (iph))
2011 {
2012 zlog_warn ("ospf_recv_packet packet smaller than ip header");
2013 return NULL;
2014 }
paul18b12c32004-10-05 14:38:29 +00002015
2016 sockopt_iphdrincl_swab_systoh (&iph);
2017
paul6b333612004-10-11 10:11:25 +00002018 ip_len = iph.ip_len;
2019
paul239aecc2003-12-08 10:34:54 +00002020#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002021 /*
2022 * Kernel network code touches incoming IP header parameters,
2023 * before protocol specific processing.
2024 *
2025 * 1) Convert byteorder to host representation.
2026 * --> ip_len, ip_id, ip_off
2027 *
2028 * 2) Adjust ip_len to strip IP header size!
2029 * --> If user process receives entire IP packet via RAW
2030 * socket, it must consider adding IP header size to
2031 * the "ip_len" field of "ip" structure.
2032 *
2033 * For more details, see <netinet/ip_input.c>.
2034 */
2035 ip_len = ip_len + (iph.ip_hl << 2);
2036#endif
2037
2038 ibuf = stream_new (ip_len);
2039 iov.iov_base = STREAM_DATA (ibuf);
2040 iov.iov_len = ip_len;
2041 ret = recvmsg (fd, &msgh, 0);
2042
paul863082d2004-08-19 04:43:43 +00002043 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002044
2045 *ifp = if_lookup_by_index (ifindex);
2046
2047 if (ret != ip_len)
2048 {
2049 zlog_warn ("ospf_recv_packet short read. "
2050 "ip_len %d bytes read %d", ip_len, ret);
2051 stream_free (ibuf);
2052 return NULL;
2053 }
2054
2055 return ibuf;
2056}
2057
2058struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002059ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002060 struct ip *iph, struct ospf_header *ospfh)
2061{
2062 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002063 struct ospf_vl_data *vl_data;
2064 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002065 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002066
2067 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2068 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002069 return NULL;
paul718e3742002-12-13 20:15:29 +00002070
pauld3f0d622004-05-05 15:27:15 +00002071 /* look for local OSPF interface matching the destination
2072 * to determine Area ID. We presume therefore the destination address
2073 * is unique, or at least (for "unnumbered" links), not used in other
2074 * areas
2075 */
2076 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2077 iph->ip_dst)) == NULL)
2078 return NULL;
paul718e3742002-12-13 20:15:29 +00002079
paul020709f2003-04-04 02:44:16 +00002080 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002081 {
2082 if ((vl_data = getdata (node)) == NULL)
2083 continue;
2084
paul020709f2003-04-04 02:44:16 +00002085 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002086 if (!vl_area)
2087 continue;
2088
2089 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2090 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2091 {
2092 if (IS_DEBUG_OSPF_EVENT)
2093 zlog_info ("associating packet with %s",
2094 IF_NAME (vl_data->vl_oi));
2095 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2096 {
2097 if (IS_DEBUG_OSPF_EVENT)
2098 zlog_info ("This VL is not up yet, sorry");
2099 return NULL;
2100 }
2101
2102 return vl_data->vl_oi;
2103 }
2104 }
2105
2106 if (IS_DEBUG_OSPF_EVENT)
2107 zlog_info ("couldn't find any VL to associate the packet with");
2108
pauld3f0d622004-05-05 15:27:15 +00002109 return NULL;
paul718e3742002-12-13 20:15:29 +00002110}
2111
2112int
2113ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2114{
2115 /* Check match the Area ID of the receiving interface. */
2116 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2117 return 1;
2118
2119 return 0;
2120}
2121
2122/* Unbound socket will accept any Raw IP packets if proto is matched.
2123 To prevent it, compare src IP address and i/f address with masking
2124 i/f network mask. */
2125int
2126ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2127{
2128 struct in_addr mask, me, him;
2129
2130 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2131 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2132 return 1;
2133
2134 masklen2ip (oi->address->prefixlen, &mask);
2135
2136 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2137 him.s_addr = ip_src.s_addr & mask.s_addr;
2138
2139 if (IPV4_ADDR_SAME (&me, &him))
2140 return 1;
2141
2142 return 0;
2143}
2144
2145int
2146ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2147 struct ospf_header *ospfh)
2148{
2149 int ret = 0;
2150 struct crypt_key *ck;
2151
2152 switch (ntohs (ospfh->auth_type))
2153 {
2154 case OSPF_AUTH_NULL:
2155 ret = 1;
2156 break;
2157 case OSPF_AUTH_SIMPLE:
2158 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2159 ret = 1;
2160 else
2161 ret = 0;
2162 break;
2163 case OSPF_AUTH_CRYPTOGRAPHIC:
2164 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2165 {
2166 ret = 0;
2167 break;
2168 }
2169
2170 /* This is very basic, the digest processing is elsewhere */
2171 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2172 ospfh->u.crypt.key_id == ck->key_id &&
2173 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2174 ret = 1;
2175 else
2176 ret = 0;
2177 break;
2178 default:
2179 ret = 0;
2180 break;
2181 }
2182
2183 return ret;
2184}
2185
2186int
2187ospf_check_sum (struct ospf_header *ospfh)
2188{
2189 u_int32_t ret;
2190 u_int16_t sum;
2191 int in_cksum (void *ptr, int nbytes);
2192
2193 /* clear auth_data for checksum. */
2194 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2195
2196 /* keep checksum and clear. */
2197 sum = ospfh->checksum;
2198 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2199
2200 /* calculate checksum. */
2201 ret = in_cksum (ospfh, ntohs (ospfh->length));
2202
2203 if (ret != sum)
2204 {
2205 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2206 ret, sum);
2207 return 0;
2208 }
2209
2210 return 1;
2211}
2212
2213/* OSPF Header verification. */
2214int
2215ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2216 struct ip *iph, struct ospf_header *ospfh)
2217{
2218 /* check version. */
2219 if (ospfh->version != OSPF_VERSION)
2220 {
2221 zlog_warn ("interface %s: ospf_read version number mismatch.",
2222 IF_NAME (oi));
2223 return -1;
2224 }
2225
2226 /* Check Area ID. */
2227 if (!ospf_check_area_id (oi, ospfh))
2228 {
2229 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2230 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2231 return -1;
2232 }
2233
2234 /* Check network mask, Silently discarded. */
2235 if (! ospf_check_network_mask (oi, iph->ip_src))
2236 {
2237 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2238 IF_NAME (oi), inet_ntoa (iph->ip_src));
2239 return -1;
2240 }
2241
2242 /* Check authentication. */
2243 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2244 {
2245 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2246 IF_NAME (oi));
2247 return -1;
2248 }
2249
2250 if (! ospf_check_auth (oi, ibuf, ospfh))
2251 {
2252 zlog_warn ("interface %s: ospf_read authentication failed.",
2253 IF_NAME (oi));
2254 return -1;
2255 }
2256
2257 /* if check sum is invalid, packet is discarded. */
2258 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2259 {
2260 if (! ospf_check_sum (ospfh))
2261 {
2262 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2263 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2264 return -1;
2265 }
2266 }
2267 else
2268 {
2269 if (ospfh->checksum != 0)
2270 return -1;
2271 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2272 {
2273 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2274 IF_NAME (oi));
2275 return -1;
2276 }
2277 }
2278
2279 return 0;
2280}
2281
2282/* Starting point of packet process function. */
2283int
2284ospf_read (struct thread *thread)
2285{
2286 int ret;
2287 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002288 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002289 struct ospf_interface *oi;
2290 struct ip *iph;
2291 struct ospf_header *ospfh;
2292 u_int16_t length;
2293 struct interface *ifp;
2294
2295 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002296 ospf = THREAD_ARG (thread);
2297 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002298
2299 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002300 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002301 if (ibuf == NULL)
2302 return -1;
2303
pauld3f0d622004-05-05 15:27:15 +00002304 if (ifp == NULL)
2305 {
2306 stream_free (ibuf);
2307 return 0;
2308 }
2309
paul718e3742002-12-13 20:15:29 +00002310 iph = (struct ip *) STREAM_DATA (ibuf);
paul6b333612004-10-11 10:11:25 +00002311 sockopt_iphdrincl_swab_systoh (iph);
2312
paul718e3742002-12-13 20:15:29 +00002313 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002314 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002315
2316 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002317 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002318 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002319
paul718e3742002-12-13 20:15:29 +00002320 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002321 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002322 {
pauld3241812003-09-29 12:42:39 +00002323 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2324 {
2325 zlog_info ("ospf_read[%s]: Dropping self-originated packet",
2326 inet_ntoa (iph->ip_src));
2327 }
paul718e3742002-12-13 20:15:29 +00002328 stream_free (ibuf);
2329 return 0;
2330 }
2331
2332 /* Adjust size to message length. */
2333 stream_forward (ibuf, iph->ip_hl * 4);
2334
2335 /* Get ospf packet header. */
2336 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2337
2338 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002339 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002340
2341 /* if no local ospf_interface,
2342 * or header area is backbone but ospf_interface is not
2343 * check for VLINK interface
2344 */
2345 if ( (oi == NULL) ||
2346 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2347 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2348 )
2349 {
2350 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2351 {
2352 zlog_warn ("Packet from [%s] received on link %s"
2353 " but no ospf_interface",
2354 inet_ntoa (iph->ip_src), ifp->name);
2355 stream_free (ibuf);
2356 return 0;
2357 }
2358 }
2359
2360 /* else it must be a local ospf interface, check it was received on
2361 * correct link
2362 */
2363 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002364 {
2365 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002366 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002367 stream_free (ibuf);
2368 return 0;
2369 }
paul718e3742002-12-13 20:15:29 +00002370
2371 /*
2372 * If the received packet is destined for AllDRouters, the packet
2373 * should be accepted only if the received ospf interface state is
2374 * either DR or Backup -- endo.
2375 */
2376 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2377 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2378 {
2379 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2380 inet_ntoa (iph->ip_src), IF_NAME (oi),
2381 LOOKUP (ospf_ism_state_msg, oi->state));
2382 stream_free (ibuf);
2383 return 0;
2384 }
2385
2386 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002387 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2388 {
paul718e3742002-12-13 20:15:29 +00002389 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002390 {
2391 zlog_info ("-----------------------------------------------------");
2392 ospf_packet_dump (ibuf);
2393 }
paul718e3742002-12-13 20:15:29 +00002394
2395 zlog_info ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002396 ospf_packet_type_str[ospfh->type],
2397 inet_ntoa (ospfh->router_id), IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +00002398 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2399 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2400
2401 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2402 zlog_info ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002403 }
paul718e3742002-12-13 20:15:29 +00002404
2405 /* Some header verification. */
2406 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2407 if (ret < 0)
2408 {
pauld3241812003-09-29 12:42:39 +00002409 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2410 {
2411 zlog_info ("ospf_read[%s/%s]: Header check failed, "
2412 "dropping.",
2413 ospf_packet_type_str[ospfh->type],
2414 inet_ntoa (iph->ip_src));
2415 }
paul718e3742002-12-13 20:15:29 +00002416 stream_free (ibuf);
2417 return ret;
2418 }
2419
2420 stream_forward (ibuf, OSPF_HEADER_SIZE);
2421
2422 /* Adjust size to message length. */
2423 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2424
2425 /* Read rest of the packet and call each sort of packet routine. */
2426 switch (ospfh->type)
2427 {
2428 case OSPF_MSG_HELLO:
2429 ospf_hello (iph, ospfh, ibuf, oi, length);
2430 break;
2431 case OSPF_MSG_DB_DESC:
2432 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2433 break;
2434 case OSPF_MSG_LS_REQ:
2435 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2436 break;
2437 case OSPF_MSG_LS_UPD:
2438 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2439 break;
2440 case OSPF_MSG_LS_ACK:
2441 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2442 break;
2443 default:
2444 zlog (NULL, LOG_WARNING,
2445 "interface %s: OSPF packet header type %d is illegal",
2446 IF_NAME (oi), ospfh->type);
2447 break;
2448 }
2449
2450 stream_free (ibuf);
2451 return 0;
2452}
2453
2454/* Make OSPF header. */
2455void
2456ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2457{
2458 struct ospf_header *ospfh;
2459
2460 ospfh = (struct ospf_header *) STREAM_DATA (s);
2461
2462 ospfh->version = (u_char) OSPF_VERSION;
2463 ospfh->type = (u_char) type;
2464
paul68980082003-03-25 05:07:42 +00002465 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002466
2467 ospfh->checksum = 0;
2468 ospfh->area_id = oi->area->area_id;
2469 ospfh->auth_type = htons (ospf_auth_type (oi));
2470
2471 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2472
2473 ospf_output_forward (s, OSPF_HEADER_SIZE);
2474}
2475
2476/* Make Authentication Data. */
2477int
2478ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2479{
2480 struct crypt_key *ck;
2481
2482 switch (ospf_auth_type (oi))
2483 {
2484 case OSPF_AUTH_NULL:
2485 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2486 break;
2487 case OSPF_AUTH_SIMPLE:
2488 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2489 OSPF_AUTH_SIMPLE_SIZE);
2490 break;
2491 case OSPF_AUTH_CRYPTOGRAPHIC:
2492 /* If key is not set, then set 0. */
2493 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2494 {
2495 ospfh->u.crypt.zero = 0;
2496 ospfh->u.crypt.key_id = 0;
2497 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2498 }
2499 else
2500 {
2501 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2502 ospfh->u.crypt.zero = 0;
2503 ospfh->u.crypt.key_id = ck->key_id;
2504 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2505 }
2506 /* note: the seq is done in ospf_make_md5_digest() */
2507 break;
2508 default:
2509 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2510 break;
2511 }
2512
2513 return 0;
2514}
2515
2516/* Fill rest of OSPF header. */
2517void
2518ospf_fill_header (struct ospf_interface *oi,
2519 struct stream *s, u_int16_t length)
2520{
2521 struct ospf_header *ospfh;
2522
2523 ospfh = (struct ospf_header *) STREAM_DATA (s);
2524
2525 /* Fill length. */
2526 ospfh->length = htons (length);
2527
2528 /* Calculate checksum. */
2529 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2530 ospfh->checksum = in_cksum (ospfh, length);
2531 else
2532 ospfh->checksum = 0;
2533
2534 /* Add Authentication Data. */
2535 ospf_make_auth (oi, ospfh);
2536}
2537
2538int
2539ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2540{
2541 struct ospf_neighbor *nbr;
2542 struct route_node *rn;
2543 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2544 struct in_addr mask;
2545 unsigned long p;
2546 int flag = 0;
2547
2548 /* Set netmask of interface. */
2549 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2550 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2551 masklen2ip (oi->address->prefixlen, &mask);
2552 else
2553 memset ((char *) &mask, 0, sizeof (struct in_addr));
2554 stream_put_ipv4 (s, mask.s_addr);
2555
2556 /* Set Hello Interval. */
2557 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2558
2559 if (IS_DEBUG_OSPF_EVENT)
2560 zlog_info ("make_hello: options: %x, int: %s",
2561 OPTIONS(oi), IF_NAME (oi));
2562
2563 /* Set Options. */
2564 stream_putc (s, OPTIONS (oi));
2565
2566 /* Set Router Priority. */
2567 stream_putc (s, PRIORITY (oi));
2568
2569 /* Set Router Dead Interval. */
2570 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2571
2572 /* Set Designated Router. */
2573 stream_put_ipv4 (s, DR (oi).s_addr);
2574
2575 p = s->putp;
2576
2577 /* Set Backup Designated Router. */
2578 stream_put_ipv4 (s, BDR (oi).s_addr);
2579
2580 /* Add neighbor seen. */
2581 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002582 if ((nbr = rn->info))
2583 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2584 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2585 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2586 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002587 {
2588 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002589 if (nbr->d_router.s_addr != 0
2590 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2591 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2592 flag = 1;
paul718e3742002-12-13 20:15:29 +00002593
2594 stream_put_ipv4 (s, nbr->router_id.s_addr);
2595 length += 4;
2596 }
2597
2598 /* Let neighbor generate BackupSeen. */
2599 if (flag == 1)
2600 {
2601 stream_set_putp (s, p);
2602 stream_put_ipv4 (s, 0);
2603 }
2604
2605 return length;
2606}
2607
2608int
2609ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2610 struct stream *s)
2611{
2612 struct ospf_lsa *lsa;
2613 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2614 u_char options;
2615 unsigned long pp;
2616 int i;
2617 struct ospf_lsdb *lsdb;
2618
2619 /* Set Interface MTU. */
2620 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2621 stream_putw (s, 0);
2622 else
2623 stream_putw (s, oi->ifp->mtu);
2624
2625 /* Set Options. */
2626 options = OPTIONS (oi);
2627#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002628 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002629 {
2630 if (IS_SET_DD_I (nbr->dd_flags)
2631 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2632 /*
2633 * Set O-bit in the outgoing DD packet for capablity negotiation,
2634 * if one of following case is applicable.
2635 *
2636 * 1) WaitTimer expiration event triggered the neighbor state to
2637 * change to Exstart, but no (valid) DD packet has received
2638 * from the neighbor yet.
2639 *
2640 * 2) At least one DD packet with O-bit on has received from the
2641 * neighbor.
2642 */
2643 SET_FLAG (options, OSPF_OPTION_O);
2644 }
2645#endif /* HAVE_OPAQUE_LSA */
2646 stream_putc (s, options);
2647
2648 /* Keep pointer to flags. */
2649 pp = stream_get_putp (s);
2650 stream_putc (s, nbr->dd_flags);
2651
2652 /* Set DD Sequence Number. */
2653 stream_putl (s, nbr->dd_seqnum);
2654
2655 if (ospf_db_summary_isempty (nbr))
2656 {
2657 if (nbr->state >= NSM_Exchange)
2658 {
2659 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2660 /* Set DD flags again */
2661 stream_set_putp (s, pp);
2662 stream_putc (s, nbr->dd_flags);
2663 }
2664 return length;
2665 }
2666
2667 /* Describe LSA Header from Database Summary List. */
2668 lsdb = &nbr->db_sum;
2669
2670 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2671 {
2672 struct route_table *table = lsdb->type[i].db;
2673 struct route_node *rn;
2674
2675 for (rn = route_top (table); rn; rn = route_next (rn))
2676 if ((lsa = rn->info) != NULL)
2677 {
2678#ifdef HAVE_OPAQUE_LSA
2679 if (IS_OPAQUE_LSA (lsa->data->type)
2680 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2681 {
2682 /* Suppress advertising opaque-informations. */
2683 /* Remove LSA from DB summary list. */
2684 ospf_lsdb_delete (lsdb, lsa);
2685 continue;
2686 }
2687#endif /* HAVE_OPAQUE_LSA */
2688
2689 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2690 {
2691 struct lsa_header *lsah;
2692 u_int16_t ls_age;
2693
2694 /* DD packet overflows interface MTU. */
2695 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2696 break;
2697
2698 /* Keep pointer to LS age. */
2699 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2700 stream_get_putp (s));
2701
2702 /* Proceed stream pointer. */
2703 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2704 length += OSPF_LSA_HEADER_SIZE;
2705
2706 /* Set LS age. */
2707 ls_age = LS_AGE (lsa);
2708 lsah->ls_age = htons (ls_age);
2709
2710 }
2711
2712 /* Remove LSA from DB summary list. */
2713 ospf_lsdb_delete (lsdb, lsa);
2714 }
2715 }
2716
2717 return length;
2718}
2719
2720int
2721ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2722 unsigned long delta, struct ospf_neighbor *nbr,
2723 struct ospf_lsa *lsa)
2724{
2725 struct ospf_interface *oi;
2726
2727 oi = nbr->oi;
2728
2729 /* LS Request packet overflows interface MTU. */
2730 if (*length + delta > OSPF_PACKET_MAX(oi))
2731 return 0;
2732
2733 stream_putl (s, lsa->data->type);
2734 stream_put_ipv4 (s, lsa->data->id.s_addr);
2735 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2736
2737 ospf_lsa_unlock (nbr->ls_req_last);
2738 nbr->ls_req_last = ospf_lsa_lock (lsa);
2739
2740 *length += 12;
2741 return 1;
2742}
2743
2744int
2745ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2746{
2747 struct ospf_lsa *lsa;
2748 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2749 unsigned long delta = stream_get_putp(s)+12;
2750 struct route_table *table;
2751 struct route_node *rn;
2752 int i;
2753 struct ospf_lsdb *lsdb;
2754
2755 lsdb = &nbr->ls_req;
2756
2757 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2758 {
2759 table = lsdb->type[i].db;
2760 for (rn = route_top (table); rn; rn = route_next (rn))
2761 if ((lsa = (rn->info)) != NULL)
2762 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2763 {
2764 route_unlock_node (rn);
2765 break;
2766 }
2767 }
2768 return length;
2769}
2770
2771int
2772ls_age_increment (struct ospf_lsa *lsa, int delay)
2773{
2774 int age;
2775
2776 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2777
2778 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2779}
2780
2781int
hasso52dc7ee2004-09-23 19:18:23 +00002782ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002783{
2784 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002785 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002786 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2787 unsigned long delta = stream_get_putp (s);
2788 unsigned long pp;
2789 int count = 0;
2790
2791 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002792 zlog_info ("ospf_make_ls_upd: Start");
2793
paul718e3742002-12-13 20:15:29 +00002794 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002795 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002796
2797 while ((node = listhead (update)) != NULL)
2798 {
2799 struct lsa_header *lsah;
2800 u_int16_t ls_age;
2801
2802 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002803 zlog_info ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002804
2805 lsa = getdata (node);
2806 assert (lsa);
2807 assert (lsa->data);
2808
paul68b73392004-09-12 14:21:37 +00002809 /* Will it fit? */
2810 if (length + delta + ntohs (lsa->data->length) > stream_get_size (s))
paul59ea14c2004-07-14 20:50:36 +00002811 break;
2812
paul718e3742002-12-13 20:15:29 +00002813 /* Keep pointer to LS age. */
2814 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2815
2816 /* Put LSA to Link State Request. */
2817 stream_put (s, lsa->data, ntohs (lsa->data->length));
2818
2819 /* Set LS age. */
2820 /* each hop must increment an lsa_age by transmit_delay
2821 of OSPF interface */
2822 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2823 lsah->ls_age = htons (ls_age);
2824
2825 length += ntohs (lsa->data->length);
2826 count++;
2827
2828 list_delete_node (update, node);
2829 ospf_lsa_unlock (lsa);
2830 }
2831
2832 /* Now set #LSAs. */
2833 stream_set_putp (s, pp);
2834 stream_putl (s, count);
2835
2836 stream_set_putp (s, s->endp);
2837
2838 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002839 zlog_info ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002840 return length;
2841}
2842
2843int
hasso52dc7ee2004-09-23 19:18:23 +00002844ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002845{
hasso52dc7ee2004-09-23 19:18:23 +00002846 struct list *rm_list;
2847 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002848 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2849 unsigned long delta = stream_get_putp(s) + 24;
2850 struct ospf_lsa *lsa;
2851
2852 rm_list = list_new ();
2853
2854 for (node = listhead (ack); node; nextnode (node))
2855 {
2856 lsa = getdata (node);
2857 assert (lsa);
2858
2859 if (length + delta > OSPF_PACKET_MAX (oi))
2860 break;
2861
2862 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2863 length += OSPF_LSA_HEADER_SIZE;
2864
2865 listnode_add (rm_list, lsa);
2866 }
2867
2868 /* Remove LSA from LS-Ack list. */
2869 for (node = listhead (rm_list); node; nextnode (node))
2870 {
2871 lsa = (struct ospf_lsa *) getdata (node);
2872
2873 listnode_delete (ack, lsa);
2874 ospf_lsa_unlock (lsa);
2875 }
2876
2877 list_delete (rm_list);
2878
2879 return length;
2880}
2881
2882void
2883ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2884{
2885 struct ospf_packet *op;
2886 u_int16_t length = OSPF_HEADER_SIZE;
2887
2888 op = ospf_packet_new (oi->ifp->mtu);
2889
2890 /* Prepare OSPF common header. */
2891 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2892
2893 /* Prepare OSPF Hello body. */
2894 length += ospf_make_hello (oi, op->s);
2895
2896 /* Fill OSPF header. */
2897 ospf_fill_header (oi, op->s, length);
2898
2899 /* Set packet length. */
2900 op->length = length;
2901
2902 op->dst.s_addr = addr->s_addr;
2903
2904 /* Add packet to the interface output queue. */
2905 ospf_packet_add (oi, op);
2906
2907 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002908 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002909}
2910
2911void
2912ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2913{
2914 struct ospf_interface *oi;
2915
2916 oi = nbr_nbma->oi;
2917 assert(oi);
2918
2919 /* If this is passive interface, do not send OSPF Hello. */
2920 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2921 return;
2922
2923 if (oi->type != OSPF_IFTYPE_NBMA)
2924 return;
2925
2926 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2927 return;
2928
2929 if (PRIORITY(oi) == 0)
2930 return;
2931
2932 if (nbr_nbma->priority == 0
2933 && oi->state != ISM_DR && oi->state != ISM_Backup)
2934 return;
2935
2936 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2937}
2938
2939int
2940ospf_poll_timer (struct thread *thread)
2941{
2942 struct ospf_nbr_nbma *nbr_nbma;
2943
2944 nbr_nbma = THREAD_ARG (thread);
2945 nbr_nbma->t_poll = NULL;
2946
2947 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2948 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2949 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2950
2951 ospf_poll_send (nbr_nbma);
2952
2953 if (nbr_nbma->v_poll > 0)
2954 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2955 nbr_nbma->v_poll);
2956
2957 return 0;
2958}
2959
2960
2961int
2962ospf_hello_reply_timer (struct thread *thread)
2963{
2964 struct ospf_neighbor *nbr;
2965
2966 nbr = THREAD_ARG (thread);
2967 nbr->t_hello_reply = NULL;
2968
2969 assert (nbr->oi);
2970
2971 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2972 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2973 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2974
2975 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2976
2977 return 0;
2978}
2979
2980/* Send OSPF Hello. */
2981void
2982ospf_hello_send (struct ospf_interface *oi)
2983{
2984 struct ospf_packet *op;
2985 u_int16_t length = OSPF_HEADER_SIZE;
2986
2987 /* If this is passive interface, do not send OSPF Hello. */
2988 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2989 return;
2990
2991 op = ospf_packet_new (oi->ifp->mtu);
2992
2993 /* Prepare OSPF common header. */
2994 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2995
2996 /* Prepare OSPF Hello body. */
2997 length += ospf_make_hello (oi, op->s);
2998
2999 /* Fill OSPF header. */
3000 ospf_fill_header (oi, op->s, length);
3001
3002 /* Set packet length. */
3003 op->length = length;
3004
3005 if (oi->type == OSPF_IFTYPE_NBMA)
3006 {
3007 struct ospf_neighbor *nbr;
3008 struct route_node *rn;
3009
3010 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3011 if ((nbr = rn->info))
3012 if (nbr != oi->nbr_self)
3013 if (nbr->state != NSM_Down)
3014 {
3015 /* RFC 2328 Section 9.5.1
3016 If the router is not eligible to become Designated Router,
3017 it must periodically send Hello Packets to both the
3018 Designated Router and the Backup Designated Router (if they
3019 exist). */
3020 if (PRIORITY(oi) == 0 &&
3021 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3022 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3023 continue;
3024
3025 /* If the router is eligible to become Designated Router, it
3026 must periodically send Hello Packets to all neighbors that
3027 are also eligible. In addition, if the router is itself the
3028 Designated Router or Backup Designated Router, it must also
3029 send periodic Hello Packets to all other neighbors. */
3030
3031 if (nbr->priority == 0 && oi->state == ISM_DROther)
3032 continue;
3033 /* if oi->state == Waiting, send hello to all neighbors */
3034 {
3035 struct ospf_packet *op_dup;
3036
3037 op_dup = ospf_packet_dup(op);
3038 op_dup->dst = nbr->address.u.prefix4;
3039
3040 /* Add packet to the interface output queue. */
3041 ospf_packet_add (oi, op_dup);
3042
paul020709f2003-04-04 02:44:16 +00003043 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003044 }
3045
3046 }
3047 ospf_packet_free (op);
3048 }
3049 else
3050 {
3051 /* Decide destination address. */
3052 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3053 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3054 else
3055 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3056
3057 /* Add packet to the interface output queue. */
3058 ospf_packet_add (oi, op);
3059
3060 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003061 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003062 }
3063}
3064
3065/* Send OSPF Database Description. */
3066void
3067ospf_db_desc_send (struct ospf_neighbor *nbr)
3068{
3069 struct ospf_interface *oi;
3070 struct ospf_packet *op;
3071 u_int16_t length = OSPF_HEADER_SIZE;
3072
3073 oi = nbr->oi;
3074 op = ospf_packet_new (oi->ifp->mtu);
3075
3076 /* Prepare OSPF common header. */
3077 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3078
3079 /* Prepare OSPF Database Description body. */
3080 length += ospf_make_db_desc (oi, nbr, op->s);
3081
3082 /* Fill OSPF header. */
3083 ospf_fill_header (oi, op->s, length);
3084
3085 /* Set packet length. */
3086 op->length = length;
3087
3088 /* Decide destination address. */
3089 op->dst = nbr->address.u.prefix4;
3090
3091 /* Add packet to the interface output queue. */
3092 ospf_packet_add (oi, op);
3093
3094 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003095 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003096
3097 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3098 if (nbr->last_send)
3099 ospf_packet_free (nbr->last_send);
3100 nbr->last_send = ospf_packet_dup (op);
3101 gettimeofday (&nbr->last_send_ts, NULL);
3102}
3103
3104/* Re-send Database Description. */
3105void
3106ospf_db_desc_resend (struct ospf_neighbor *nbr)
3107{
3108 struct ospf_interface *oi;
3109
3110 oi = nbr->oi;
3111
3112 /* Add packet to the interface output queue. */
3113 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3114
3115 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003116 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003117}
3118
3119/* Send Link State Request. */
3120void
3121ospf_ls_req_send (struct ospf_neighbor *nbr)
3122{
3123 struct ospf_interface *oi;
3124 struct ospf_packet *op;
3125 u_int16_t length = OSPF_HEADER_SIZE;
3126
3127 oi = nbr->oi;
3128 op = ospf_packet_new (oi->ifp->mtu);
3129
3130 /* Prepare OSPF common header. */
3131 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3132
3133 /* Prepare OSPF Link State Request body. */
3134 length += ospf_make_ls_req (nbr, op->s);
3135 if (length == OSPF_HEADER_SIZE)
3136 {
3137 ospf_packet_free (op);
3138 return;
3139 }
3140
3141 /* Fill OSPF header. */
3142 ospf_fill_header (oi, op->s, length);
3143
3144 /* Set packet length. */
3145 op->length = length;
3146
3147 /* Decide destination address. */
3148 op->dst = nbr->address.u.prefix4;
3149
3150 /* Add packet to the interface output queue. */
3151 ospf_packet_add (oi, op);
3152
3153 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003154 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003155
3156 /* Add Link State Request Retransmission Timer. */
3157 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3158}
3159
3160/* Send Link State Update with an LSA. */
3161void
3162ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3163 int flag)
3164{
hasso52dc7ee2004-09-23 19:18:23 +00003165 struct list *update;
paul718e3742002-12-13 20:15:29 +00003166
3167 update = list_new ();
3168
3169 listnode_add (update, lsa);
3170 ospf_ls_upd_send (nbr, update, flag);
3171
3172 list_delete (update);
3173}
3174
paul68b73392004-09-12 14:21:37 +00003175/* Determine size for packet. Must be at least big enough to accomodate next
3176 * LSA on list, which may be bigger than MTU size.
3177 *
3178 * Return pointer to new ospf_packet
3179 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3180 * on packet sizes (in which case offending LSA is deleted from update list)
3181 */
3182static struct ospf_packet *
3183ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3184{
3185 struct ospf_lsa *lsa;
3186 struct listnode *ln;
3187 size_t size;
3188 static char warned = 0;
3189
3190 ln = listhead (update);
3191 lsa = getdata (ln);
3192 assert (lsa);
3193 assert (lsa->data);
3194
3195 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3196 > ospf_packet_max (oi))
3197 {
3198 if (!warned)
3199 {
3200 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3201 "will need to fragment. Not optimal. Try divide up"
3202 " your network with areas. Use 'debug ospf packet send'"
3203 " to see details, or look at 'show ip ospf database ..'");
3204 warned = 1;
3205 }
3206
3207 if (IS_DEBUG_OSPF_PACKET (0, SEND))
3208 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3209 " %d bytes originated by %s, will be fragmented!",
3210 inet_ntoa (lsa->data->id),
3211 ntohs (lsa->data->length),
3212 inet_ntoa (lsa->data->adv_router));
3213
3214 /*
3215 * Allocate just enough to fit this LSA only, to avoid including other
3216 * LSAs in fragmented LSA Updates.
3217 */
3218 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3219 + OSPF_LS_UPD_MIN_SIZE;
3220 }
3221 else
3222 size = oi->ifp->mtu;
3223
3224 if (size > OSPF_MAX_PACKET_SIZE)
3225 {
3226 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
3227 " %d bytes, dropping it completely."
3228 " OSPF routing is broken!",
3229 inet_ntoa (lsa->data->id), ntohs (lsa->data->length));
3230 list_delete_node (update, ln);
3231 return NULL;
3232 }
3233
3234 return ospf_packet_new (size);
3235}
3236
paul718e3742002-12-13 20:15:29 +00003237static void
hasso52dc7ee2004-09-23 19:18:23 +00003238ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003239 struct in_addr addr)
3240{
3241 struct ospf_packet *op;
3242 u_int16_t length = OSPF_HEADER_SIZE;
3243
3244 if (IS_DEBUG_OSPF_EVENT)
3245 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003246
3247 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003248
3249 /* Prepare OSPF common header. */
3250 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3251
paul59ea14c2004-07-14 20:50:36 +00003252 /* Prepare OSPF Link State Update body.
3253 * Includes Type-7 translation.
3254 */
paul718e3742002-12-13 20:15:29 +00003255 length += ospf_make_ls_upd (oi, update, op->s);
3256
3257 /* Fill OSPF header. */
3258 ospf_fill_header (oi, op->s, length);
3259
3260 /* Set packet length. */
3261 op->length = length;
3262
3263 /* Decide destination address. */
3264 op->dst.s_addr = addr.s_addr;
3265
3266 /* Add packet to the interface output queue. */
3267 ospf_packet_add (oi, op);
3268
3269 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003270 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003271}
3272
3273static int
3274ospf_ls_upd_send_queue_event (struct thread *thread)
3275{
3276 struct ospf_interface *oi = THREAD_ARG(thread);
3277 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003278 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003279 struct list *update;
paul68b73392004-09-12 14:21:37 +00003280 char again = 0;
paul718e3742002-12-13 20:15:29 +00003281
3282 oi->t_ls_upd_event = NULL;
3283
3284 if (IS_DEBUG_OSPF_EVENT)
3285 zlog_info ("ospf_ls_upd_send_queue start");
3286
paul736d3442003-07-24 23:22:57 +00003287 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003288 {
paul736d3442003-07-24 23:22:57 +00003289 rnext = route_next (rn);
3290
paul718e3742002-12-13 20:15:29 +00003291 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003292 continue;
paul68b73392004-09-12 14:21:37 +00003293
3294 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003295
paul48fe13b2004-07-27 17:40:44 +00003296 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003297
paul68b73392004-09-12 14:21:37 +00003298 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003299 if (listcount(update) == 0)
3300 {
3301 list_delete (rn->info);
3302 rn->info = NULL;
3303 route_unlock_node (rn);
3304 }
3305 else
paul68b73392004-09-12 14:21:37 +00003306 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003307 }
3308
3309 if (again != 0)
3310 {
3311 if (IS_DEBUG_OSPF_EVENT)
3312 zlog_info ("ospf_ls_upd_send_queue: update lists not cleared,"
3313 " %d nodes to try again, raising new event", again);
3314 oi->t_ls_upd_event =
3315 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003316 }
3317
3318 if (IS_DEBUG_OSPF_EVENT)
3319 zlog_info ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003320
paul718e3742002-12-13 20:15:29 +00003321 return 0;
3322}
3323
3324void
hasso52dc7ee2004-09-23 19:18:23 +00003325ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003326{
3327 struct ospf_interface *oi;
3328 struct prefix_ipv4 p;
3329 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003330 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003331
3332 oi = nbr->oi;
3333
3334 p.family = AF_INET;
3335 p.prefixlen = IPV4_MAX_BITLEN;
3336
3337 /* Decide destination address. */
3338 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3339 p.prefix = oi->vl_data->peer_addr;
3340 else if (flag == OSPF_SEND_PACKET_DIRECT)
3341 p.prefix = nbr->address.u.prefix4;
3342 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3343 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3344 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3345 && (flag == OSPF_SEND_PACKET_INDIRECT))
3346 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003347 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3348 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003349 else
3350 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3351
3352 if (oi->type == OSPF_IFTYPE_NBMA)
3353 {
3354 if (flag == OSPF_SEND_PACKET_INDIRECT)
3355 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3356 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3357 zlog_warn ("* LS-Update is sent to myself.");
3358 }
3359
3360 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3361
3362 if (rn->info == NULL)
3363 rn->info = list_new ();
3364
3365 for (n = listhead (update); n; nextnode (n))
3366 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3367
3368 if (oi->t_ls_upd_event == NULL)
3369 oi->t_ls_upd_event =
3370 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3371}
3372
3373static void
hasso52dc7ee2004-09-23 19:18:23 +00003374ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3375 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003376{
3377 struct ospf_packet *op;
3378 u_int16_t length = OSPF_HEADER_SIZE;
3379
3380 op = ospf_packet_new (oi->ifp->mtu);
3381
3382 /* Prepare OSPF common header. */
3383 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3384
3385 /* Prepare OSPF Link State Acknowledgment body. */
3386 length += ospf_make_ls_ack (oi, ack, op->s);
3387
3388 /* Fill OSPF header. */
3389 ospf_fill_header (oi, op->s, length);
3390
3391 /* Set packet length. */
3392 op->length = length;
3393
3394 /* Set destination IP address. */
3395 op->dst = dst;
3396
3397 /* Add packet to the interface output queue. */
3398 ospf_packet_add (oi, op);
3399
3400 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003401 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003402}
3403
3404static int
3405ospf_ls_ack_send_event (struct thread *thread)
3406{
3407 struct ospf_interface *oi = THREAD_ARG (thread);
3408
3409 oi->t_ls_ack_direct = NULL;
3410
3411 while (listcount (oi->ls_ack_direct.ls_ack))
3412 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3413 oi->ls_ack_direct.dst);
3414
3415 return 0;
3416}
3417
3418void
3419ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3420{
3421 struct ospf_interface *oi = nbr->oi;
3422
3423 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3424 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3425
3426 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3427
3428 if (oi->t_ls_ack_direct == NULL)
3429 oi->t_ls_ack_direct =
3430 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3431}
3432
3433/* Send Link State Acknowledgment delayed. */
3434void
3435ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3436{
3437 struct in_addr dst;
3438
3439 /* Decide destination address. */
3440 /* RFC2328 Section 13.5 On non-broadcast
3441 networks, delayed Link State Acknowledgment packets must be
3442 unicast separately over each adjacency (i.e., neighbor whose
3443 state is >= Exchange). */
3444 if (oi->type == OSPF_IFTYPE_NBMA)
3445 {
3446 struct ospf_neighbor *nbr;
3447 struct route_node *rn;
3448
3449 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3450 if ((nbr = rn->info) != NULL)
3451 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3452 while (listcount (oi->ls_ack))
3453 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3454 return;
3455 }
3456 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3457 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3458 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3459 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3460 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3461 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003462 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3463 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003464 else
3465 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3466
3467 while (listcount (oi->ls_ack))
3468 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3469}