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