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