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