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