blob: 66155215a4459d9e924f625a7104aac4ac194d7f [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)
561 zlog_warn ("*** sendmsg in ospf_write failed with %s", strerror (errno));
562
563 /* Retrieve OSPF packet type. */
564 stream_set_getp (op->s, 1);
565 type = stream_getc (op->s);
566
567 /* Show debug sending packet. */
568 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
569 {
570 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
571 {
572 zlog_info ("-----------------------------------------------------");
573 stream_set_getp (op->s, 0);
574 ospf_packet_dump (op->s);
575 }
576
577 zlog_info ("%s sent to [%s] via [%s].",
578 ospf_packet_type_str[type], inet_ntoa (op->dst),
579 IF_NAME (oi));
580
581 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
582 zlog_info ("-----------------------------------------------------");
583 }
584
585 /* Now delete packet from queue. */
586 ospf_packet_delete (oi);
587
588 if (ospf_fifo_head (oi->obuf) == NULL)
589 {
590 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000591 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000592 }
593
594 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000595 if (!list_isempty (ospf->oi_write_q))
596 ospf->t_write =
597 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000598
599 return 0;
600}
601
602/* OSPF Hello message read -- RFC2328 Section 10.5. */
603void
604ospf_hello (struct ip *iph, struct ospf_header *ospfh,
605 struct stream * s, struct ospf_interface *oi, int size)
606{
607 struct ospf_hello *hello;
608 struct ospf_neighbor *nbr;
609 struct route_node *rn;
610 struct prefix p, key;
611 int old_state;
612
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))
paul718e3742002-12-13 20:15:29 +0000620 return;
621
622 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000623 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
624 zlog_info ("Packet %s [HELLO:RECV]: oi is passive");
paul718e3742002-12-13 20:15:29 +0000625 return;
paulf2c80652002-12-13 21:44:27 +0000626 }
paul718e3742002-12-13 20:15:29 +0000627
628 /* get neighbor prefix. */
629 p.family = AF_INET;
630 p.prefixlen = ip_masklen (hello->network_mask);
631 p.u.prefix4 = iph->ip_src;
632
633 /* Compare network mask. */
634 /* Checking is ignored for Point-to-Point and Virtual link. */
635 if (oi->type != OSPF_IFTYPE_POINTOPOINT
636 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
637 if (oi->address->prefixlen != p.prefixlen)
638 {
639 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
640 inet_ntoa (ospfh->router_id));
641 return;
642 }
643
644 /* Compare Hello Interval. */
645 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
646 {
647 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
648 inet_ntoa (ospfh->router_id));
649 return;
650 }
651
652 /* Compare Router Dead Interval. */
653 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
654 {
655 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
656 inet_ntoa (ospfh->router_id));
657 return;
658 }
659
660 if (IS_DEBUG_OSPF_EVENT)
661 zlog_info ("Packet %s [Hello:RECV]: Options %s",
662 inet_ntoa (ospfh->router_id),
663 ospf_options_dump (hello->options));
664
665 /* Compare options. */
666#define REJECT_IF_TBIT_ON 1 /* XXX */
667#ifdef REJECT_IF_TBIT_ON
668 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
669 {
670 /*
671 * This router does not support non-zero TOS.
672 * Drop this Hello packet not to establish neighbor relationship.
673 */
674 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
675 inet_ntoa (ospfh->router_id));
676 return;
677 }
678#endif /* REJECT_IF_TBIT_ON */
679
680#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000681 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000682 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
683 {
684 /*
685 * This router does know the correct usage of O-bit
686 * the bit should be set in DD packet only.
687 */
688 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
689 inet_ntoa (ospfh->router_id));
690#ifdef STRICT_OBIT_USAGE_CHECK
691 return; /* Reject this packet. */
692#else /* STRICT_OBIT_USAGE_CHECK */
693 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
694#endif /* STRICT_OBIT_USAGE_CHECK */
695 }
696#endif /* HAVE_OPAQUE_LSA */
697
698 /* new for NSSA is to ensure that NP is on and E is off */
699
700#ifdef HAVE_NSSA
701 if (oi->area->external_routing == OSPF_AREA_NSSA)
702 {
703 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
704 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
705 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
706 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
707 {
708 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
709 return;
710 }
711 if (IS_DEBUG_OSPF_NSSA)
712 zlog_info ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
713 }
714 else
715#endif /* HAVE_NSSA */
716 /* The setting of the E-bit found in the Hello Packet's Options
717 field must match this area's ExternalRoutingCapability A
718 mismatch causes processing to stop and the packet to be
719 dropped. The setting of the rest of the bits in the Hello
720 Packet's Options field should be ignored. */
721 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
722 CHECK_FLAG (hello->options, OSPF_OPTION_E))
723 {
724 zlog_warn ("Packet[Hello:RECV]: my options: %x, his options %x",
725 OPTIONS (oi), hello->options);
726 return;
727 }
728
729
730 /* Get neighbor information from table. */
731 key.family = AF_INET;
732 key.prefixlen = IPV4_MAX_BITLEN;
733 key.u.prefix4 = iph->ip_src;
734
735 rn = route_node_get (oi->nbrs, &key);
736 if (rn->info)
737 {
738 route_unlock_node (rn);
739 nbr = rn->info;
740
741 if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt)
742 {
743 nbr->src = iph->ip_src;
744 nbr->address = p;
745 }
746 }
747 else
748 {
749 /* Create new OSPF Neighbor structure. */
750 nbr = ospf_nbr_new (oi);
751 nbr->state = NSM_Down;
752 nbr->src = iph->ip_src;
753 nbr->address = p;
754
755 rn->info = nbr;
756
757 nbr->nbr_nbma = NULL;
758
759 if (oi->type == OSPF_IFTYPE_NBMA)
760 {
761 struct ospf_nbr_nbma *nbr_nbma;
762 listnode node;
763
764 for (node = listhead (oi->nbr_nbma); node; nextnode (node))
765 {
766 nbr_nbma = getdata (node);
767 assert (nbr_nbma);
768
769 if (IPV4_ADDR_SAME(&nbr_nbma->addr, &iph->ip_src))
770 {
771 nbr_nbma->nbr = nbr;
772 nbr->nbr_nbma = nbr_nbma;
773
774 if (nbr_nbma->t_poll)
775 OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
776
777 nbr->state_change = nbr_nbma->state_change + 1;
778 }
779 }
780 }
781
782 /* New nbr, save the crypto sequence number if necessary */
783 if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
784 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
785
786 if (IS_DEBUG_OSPF_EVENT)
787 zlog_info ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
788 inet_ntoa (nbr->router_id));
789 }
790
791 nbr->router_id = ospfh->router_id;
792
793 old_state = nbr->state;
794
795 /* Add event to thread. */
796 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
797
798 /* RFC2328 Section 9.5.1
799 If the router is not eligible to become Designated Router,
800 (snip) It must also send an Hello Packet in reply to an
801 Hello Packet received from any eligible neighbor (other than
802 the current Designated Router and Backup Designated Router). */
803 if (oi->type == OSPF_IFTYPE_NBMA)
804 if (PRIORITY(oi) == 0 && hello->priority > 0
805 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
806 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
807 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
808 OSPF_HELLO_REPLY_DELAY);
809
810 /* on NBMA network type, it happens to receive bidirectional Hello packet
811 without advance 1-Way Received event.
812 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
813 if (oi->type == OSPF_IFTYPE_NBMA &&
814 (old_state == NSM_Down || old_state == NSM_Attempt))
815 {
816 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
817 nbr->priority = hello->priority;
818 nbr->d_router = hello->d_router;
819 nbr->bd_router = hello->bd_router;
820 return;
821 }
822
paul68980082003-03-25 05:07:42 +0000823 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000824 size - OSPF_HELLO_MIN_SIZE))
825 {
826 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
827 nbr->options |= hello->options;
828 }
829 else
830 {
831 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
832 /* Set neighbor information. */
833 nbr->priority = hello->priority;
834 nbr->d_router = hello->d_router;
835 nbr->bd_router = hello->bd_router;
836 return;
837 }
838
839 /* If neighbor itself declares DR and no BDR exists,
840 cause event BackupSeen */
841 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
842 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
843 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
844
845 /* neighbor itself declares BDR. */
846 if (oi->state == ISM_Waiting &&
847 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
848 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
849
850 /* had not previously. */
851 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
852 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
853 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
854 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
855 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
856
857 /* had not previously. */
858 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
859 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
860 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
861 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
862 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
863
864 /* Neighbor priority check. */
865 if (nbr->priority >= 0 && nbr->priority != hello->priority)
866 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
867
868 /* Set neighbor information. */
869 nbr->priority = hello->priority;
870 nbr->d_router = hello->d_router;
871 nbr->bd_router = hello->bd_router;
872}
873
874/* Save DD flags/options/Seqnum received. */
875void
876ospf_db_desc_save_current (struct ospf_neighbor *nbr,
877 struct ospf_db_desc *dd)
878{
879 nbr->last_recv.flags = dd->flags;
880 nbr->last_recv.options = dd->options;
881 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
882}
883
884/* Process rest of DD packet. */
885static void
886ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
887 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
888 u_int16_t size)
889{
890 struct ospf_lsa *new, *find;
891 struct lsa_header *lsah;
892
893 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
894 for (size -= OSPF_DB_DESC_MIN_SIZE;
895 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
896 {
897 lsah = (struct lsa_header *) STREAM_PNT (s);
898 stream_forward (s, OSPF_LSA_HEADER_SIZE);
899
900 /* Unknown LS type. */
901 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
902 {
903 zlog_warn ("Pakcet [DD:RECV]: Unknown LS type %d.", lsah->type);
904 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
905 return;
906 }
907
908#ifdef HAVE_OPAQUE_LSA
909 if (IS_OPAQUE_LSA (lsah->type)
910 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
911 {
912 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
913 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
914 return;
915 }
916#endif /* HAVE_OPAQUE_LSA */
917
918 switch (lsah->type)
919 {
920 case OSPF_AS_EXTERNAL_LSA:
921#ifdef HAVE_OPAQUE_LSA
922 case OSPF_OPAQUE_AS_LSA:
923#endif /* HAVE_OPAQUE_LSA */
924#ifdef HAVE_NSSA
925 /* Check for stub area. Reject if AS-External from stub but
926 allow if from NSSA. */
927 if (oi->area->external_routing == OSPF_AREA_STUB)
928#else /* ! HAVE_NSSA */
929 if (oi->area->external_routing != OSPF_AREA_DEFAULT)
930#endif /* HAVE_NSSA */
931 {
932 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
933 lsah->type, inet_ntoa (lsah->id),
934 (oi->area->external_routing == OSPF_AREA_STUB) ?\
935 "STUB" : "NSSA");
936 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
937 return;
938 }
939 break;
940 default:
941 break;
942 }
943
944 /* Create LS-request object. */
945 new = ospf_ls_request_new (lsah);
946
947 /* Lookup received LSA, then add LS request list. */
948 find = ospf_lsa_lookup_by_header (oi->area, lsah);
949 if (!find || ospf_lsa_more_recent (find, new) < 0)
950 {
951 ospf_ls_request_add (nbr, new);
952 ospf_lsa_discard (new);
953 }
954 else
955 {
956 /* Received LSA is not recent. */
957 if (IS_DEBUG_OSPF_EVENT)
958 zlog_info ("Packet [DD:RECV]: LSA received Type %d, "
959 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
960 ospf_lsa_discard (new);
961 continue;
962 }
963 }
964
965 /* Master */
966 if (IS_SET_DD_MS (nbr->dd_flags))
967 {
968 nbr->dd_seqnum++;
969 /* Entire DD packet sent. */
970 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
971 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
972 else
973 /* Send new DD packet. */
974 ospf_db_desc_send (nbr);
975 }
976 /* Slave */
977 else
978 {
979 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
980
981 /* When master's more flags is not set. */
982 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
983 {
984 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
985 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
986 }
987
988 /* Send DD pakcet in reply. */
989 ospf_db_desc_send (nbr);
990 }
991
992 /* Save received neighbor values from DD. */
993 ospf_db_desc_save_current (nbr, dd);
994}
995
996int
997ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
998{
999 /* Is DD duplicated? */
1000 if (dd->options == nbr->last_recv.options &&
1001 dd->flags == nbr->last_recv.flags &&
1002 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1003 return 1;
1004
1005 return 0;
1006}
1007
1008/* OSPF Database Description message read -- RFC2328 Section 10.6. */
1009void
1010ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1011 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1012{
1013 struct ospf_db_desc *dd;
1014 struct ospf_neighbor *nbr;
1015
1016 /* Increment statistics. */
1017 oi->db_desc_in++;
1018
1019 dd = (struct ospf_db_desc *) STREAM_PNT (s);
1020
1021 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1022 if (nbr == NULL)
1023 {
1024 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1025 inet_ntoa (ospfh->router_id));
1026 return;
1027 }
1028
1029 /* Check MTU. */
1030 if (ntohs (dd->mtu) > oi->ifp->mtu)
1031 {
1032 zlog_warn ("Packet[DD]: MTU is larger than [%s]'s MTU", IF_NAME (oi));
1033 return;
1034 }
1035
1036#ifdef REJECT_IF_TBIT_ON
1037 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1038 {
1039 /*
1040 * In Hello protocol, optional capability must have checked
1041 * to prevent this T-bit enabled router be my neighbor.
1042 */
1043 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1044 return;
1045 }
1046#endif /* REJECT_IF_TBIT_ON */
1047
1048#ifdef HAVE_OPAQUE_LSA
1049 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001050 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001051 {
1052 /*
1053 * This node is not configured to handle O-bit, for now.
1054 * Clear it to ignore unsupported capability proposed by neighbor.
1055 */
1056 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1057 }
1058#endif /* HAVE_OPAQUE_LSA */
1059
1060 /* Process DD packet by neighbor status. */
1061 switch (nbr->state)
1062 {
1063 case NSM_Down:
1064 case NSM_Attempt:
1065 case NSM_TwoWay:
1066 zlog_warn ("Packet[DD]: Neighbor state is %s, packet discarded.",
1067 LOOKUP (ospf_nsm_state_msg, nbr->state));
1068 break;
1069 case NSM_Init:
1070 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1071 /* If the new state is ExStart, the processing of the current
1072 packet should then continue in this new state by falling
1073 through to case ExStart below. */
1074 if (nbr->state != NSM_ExStart)
1075 break;
1076 case NSM_ExStart:
1077 /* Initial DBD */
1078 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1079 (size == OSPF_DB_DESC_MIN_SIZE))
1080 {
paul68980082003-03-25 05:07:42 +00001081 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001082 {
1083 /* We're Slave---obey */
1084 zlog_warn ("Packet[DD]: Negotiation done (Slave).");
1085 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1086 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1087 }
1088 else
1089 {
1090 /* We're Master, ignore the initial DBD from Slave */
1091 zlog_warn ("Packet[DD]: Initial DBD from Slave, ignoring.");
1092 break;
1093 }
1094 }
1095 /* Ack from the Slave */
1096 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1097 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001098 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001099 {
1100 zlog_warn ("Packet[DD]: Negotiation done (Master).");
1101 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1102 }
1103 else
1104 {
1105 zlog_warn ("Packet[DD]: Negotiation fails.");
1106 break;
1107 }
1108
1109 /* This is where the real Options are saved */
1110 nbr->options = dd->options;
1111
1112#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001113 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001114 {
1115 if (IS_DEBUG_OSPF_EVENT)
1116 zlog_info ("Neighbor[%s] is %sOpaque-capable.",
1117 inet_ntoa (nbr->router_id),
1118 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1119
1120 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1121 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1122 {
1123 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1124 /* This situation is undesirable, but not a real error. */
1125 }
1126 }
1127#endif /* HAVE_OPAQUE_LSA */
1128
1129 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1130
1131 /* continue processing rest of packet. */
1132 ospf_db_desc_proc (s, oi, nbr, dd, size);
1133 break;
1134 case NSM_Exchange:
1135 if (ospf_db_desc_is_dup (dd, nbr))
1136 {
1137 if (IS_SET_DD_MS (nbr->dd_flags))
1138 /* Master: discard duplicated DD packet. */
1139 zlog_warn ("Packet[DD] (Master): packet duplicated.");
1140 else
1141 /* Slave: cause to retransmit the last Database Description. */
1142 {
1143 zlog_warn ("Packet[DD] [Slave]: packet duplicated.");
1144 ospf_db_desc_resend (nbr);
1145 }
1146 break;
1147 }
1148
1149 /* Otherwise DD packet should be checked. */
1150 /* Check Master/Slave bit mismatch */
1151 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1152 {
1153 zlog_warn ("Packet[DD]: MS-bit mismatch.");
1154 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1155 if (IS_DEBUG_OSPF_EVENT)
1156 zlog_info ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1157 dd->flags, nbr->dd_flags);
1158 break;
1159 }
1160
1161 /* Check initialize bit is set. */
1162 if (IS_SET_DD_I (dd->flags))
1163 {
1164 zlog_warn ("Packet[DD]: I-bit set.");
1165 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1166 break;
1167 }
1168
1169 /* Check DD Options. */
1170 if (dd->options != nbr->options)
1171 {
1172#ifdef ORIGINAL_CODING
1173 /* Save the new options for debugging */
1174 nbr->options = dd->options;
1175#endif /* ORIGINAL_CODING */
1176 zlog_warn ("Packet[DD]: options mismatch.");
1177 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1178 break;
1179 }
1180
1181 /* Check DD sequence number. */
1182 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1183 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1184 (!IS_SET_DD_MS (nbr->dd_flags) &&
1185 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1186 {
1187 zlog_warn ("Pakcet[DD]: sequence number mismatch.");
1188 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1189 break;
1190 }
1191
1192 /* Continue processing rest of packet. */
1193 ospf_db_desc_proc (s, oi, nbr, dd, size);
1194 break;
1195 case NSM_Loading:
1196 case NSM_Full:
1197 if (ospf_db_desc_is_dup (dd, nbr))
1198 {
1199 if (IS_SET_DD_MS (nbr->dd_flags))
1200 {
1201 /* Master should discard duplicate DD packet. */
1202 zlog_warn ("Pakcet[DD]: duplicated, packet discarded.");
1203 break;
1204 }
1205 else
1206 {
1207 struct timeval t, now;
1208 gettimeofday (&now, NULL);
1209 t = tv_sub (now, nbr->last_send_ts);
1210 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1211 {
1212 /* In states Loading and Full the slave must resend
1213 its last Database Description packet in response to
1214 duplicate Database Description packets received
1215 from the master. For this reason the slave must
1216 wait RouterDeadInterval seconds before freeing the
1217 last Database Description packet. Reception of a
1218 Database Description packet from the master after
1219 this interval will generate a SeqNumberMismatch
1220 neighbor event. RFC2328 Section 10.8 */
1221 ospf_db_desc_resend (nbr);
1222 break;
1223 }
1224 }
1225 }
1226
1227 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1228 break;
1229 default:
1230 zlog_warn ("Packet[DD]: NSM illegal status.");
1231 break;
1232 }
1233}
1234
1235#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1236
1237/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1238void
1239ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1240 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1241{
1242 struct ospf_neighbor *nbr;
1243 u_int32_t ls_type;
1244 struct in_addr ls_id;
1245 struct in_addr adv_router;
1246 struct ospf_lsa *find;
1247 list ls_upd;
1248 int length;
1249
1250 /* Increment statistics. */
1251 oi->ls_req_in++;
1252
1253 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1254 if (nbr == NULL)
1255 {
1256 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1257 inet_ntoa (ospfh->router_id));
1258 return;
1259 }
1260
1261 /* Neighbor State should be Exchange or later. */
1262 if (nbr->state != NSM_Exchange &&
1263 nbr->state != NSM_Loading &&
1264 nbr->state != NSM_Full)
1265 {
1266 zlog_warn ("Link State Request: Neighbor state is %s, packet discarded.",
1267 LOOKUP (ospf_nsm_state_msg, nbr->state));
1268 return;
1269 }
1270
1271 /* Send Link State Update for ALL requested LSAs. */
1272 ls_upd = list_new ();
1273 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1274
1275 while (size >= OSPF_LSA_KEY_SIZE)
1276 {
1277 /* Get one slice of Link State Request. */
1278 ls_type = stream_getl (s);
1279 ls_id.s_addr = stream_get_ipv4 (s);
1280 adv_router.s_addr = stream_get_ipv4 (s);
1281
1282 /* Verify LSA type. */
1283 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1284 {
1285 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1286 list_delete (ls_upd);
1287 return;
1288 }
1289
1290 /* Search proper LSA in LSDB. */
1291 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1292 if (find == NULL)
1293 {
1294 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1295 list_delete (ls_upd);
1296 return;
1297 }
1298
1299 /* Packet overflows MTU size, send immediatly. */
1300 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1301 {
1302 if (oi->type == OSPF_IFTYPE_NBMA)
1303 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1304 else
1305 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1306
1307 /* Only remove list contents. Keep ls_upd. */
1308 list_delete_all_node (ls_upd);
1309
1310 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1311 }
1312
1313 /* Append LSA to update list. */
1314 listnode_add (ls_upd, find);
1315 length += ntohs (find->data->length);
1316
1317 size -= OSPF_LSA_KEY_SIZE;
1318 }
1319
1320 /* Send rest of Link State Update. */
1321 if (listcount (ls_upd) > 0)
1322 {
1323 if (oi->type == OSPF_IFTYPE_NBMA)
1324 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1325 else
1326 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1327
1328 list_delete (ls_upd);
1329 }
1330 else
1331 list_free (ls_upd);
1332}
1333
1334/* Get the list of LSAs from Link State Update packet.
1335 And process some validation -- RFC2328 Section 13. (1)-(2). */
1336static list
1337ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1338 struct ospf_interface *oi, size_t size)
1339{
1340 u_int16_t count, sum;
1341 u_int32_t length;
1342 struct lsa_header *lsah;
1343 struct ospf_lsa *lsa;
1344 list lsas;
1345
1346 lsas = list_new ();
1347
1348 count = stream_getl (s);
1349 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1350
1351 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1352 size -= length, stream_forward (s, length), count--)
1353 {
1354 lsah = (struct lsa_header *) STREAM_PNT (s);
1355 length = ntohs (lsah->length);
1356
1357 if (length > size)
1358 {
1359 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1360 break;
1361 }
1362
1363 /* Validate the LSA's LS checksum. */
1364 sum = lsah->checksum;
1365 if (sum != ospf_lsa_checksum (lsah))
1366 {
1367 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1368 sum, lsah->checksum);
1369 continue;
1370 }
1371
1372 /* Examine the LSA's LS type. */
1373 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1374 {
1375 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1376 continue;
1377 }
1378
1379 /*
1380 * What if the received LSA's age is greater than MaxAge?
1381 * Treat it as a MaxAge case -- endo.
1382 */
1383 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1384 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1385
1386#ifdef HAVE_OPAQUE_LSA
1387 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1388 {
1389#ifdef STRICT_OBIT_USAGE_CHECK
1390 if ((IS_OPAQUE_LSA(lsah->type) &&
1391 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1392 || (! IS_OPAQUE_LSA(lsah->type) &&
1393 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1394 {
1395 /*
1396 * This neighbor must know the exact usage of O-bit;
1397 * the bit will be set in Type-9,10,11 LSAs only.
1398 */
1399 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1400 continue;
1401 }
1402#endif /* STRICT_OBIT_USAGE_CHECK */
1403
1404 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1405 if (lsah->type == OSPF_OPAQUE_AS_LSA
1406 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1407 {
1408 if (IS_DEBUG_OSPF_EVENT)
1409 zlog_info ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1410 continue;
1411 }
1412 }
1413 else if (IS_OPAQUE_LSA(lsah->type))
1414 {
1415 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1416 continue;
1417 }
1418#endif /* HAVE_OPAQUE_LSA */
1419
1420 /* Create OSPF LSA instance. */
1421 lsa = ospf_lsa_new ();
1422
1423 /* We may wish to put some error checking if type NSSA comes in
1424 and area not in NSSA mode */
1425 switch (lsah->type)
1426 {
1427 case OSPF_AS_EXTERNAL_LSA:
1428#ifdef HAVE_OPAQUE_LSA
1429 case OSPF_OPAQUE_AS_LSA:
1430 lsa->area = NULL;
1431 break;
1432 case OSPF_OPAQUE_LINK_LSA:
1433 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1434 /* Fallthrough */
1435#endif /* HAVE_OPAQUE_LSA */
1436 default:
1437 lsa->area = oi->area;
1438 break;
1439 }
1440
1441 lsa->data = ospf_lsa_data_new (length);
1442 memcpy (lsa->data, lsah, length);
1443
1444 if (IS_DEBUG_OSPF_EVENT)
1445 zlog_info("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1446 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1447 listnode_add (lsas, lsa);
1448 }
1449
1450 return lsas;
1451}
1452
1453/* Cleanup Update list. */
1454void
1455ospf_upd_list_clean (list lsas)
1456{
1457 listnode node;
1458 struct ospf_lsa *lsa;
1459
1460 for (node = listhead (lsas); node; nextnode (node))
1461 if ((lsa = getdata (node)) != NULL)
1462 ospf_lsa_discard (lsa);
1463
1464 list_delete (lsas);
1465}
1466
1467/* OSPF Link State Update message read -- RFC2328 Section 13. */
1468void
1469ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1470 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1471{
1472 struct ospf_neighbor *nbr;
1473 list lsas;
1474#ifdef HAVE_OPAQUE_LSA
1475 list mylsa_acks, mylsa_upds;
1476#endif /* HAVE_OPAQUE_LSA */
1477 listnode node, next;
1478 struct ospf_lsa *lsa = NULL;
1479 /* unsigned long ls_req_found = 0; */
1480
1481 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1482
1483 /* Increment statistics. */
1484 oi->ls_upd_in++;
1485
1486 /* Check neighbor. */
1487 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1488 if (nbr == NULL)
1489 {
1490 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1491 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1492 return;
1493 }
1494
1495 /* Check neighbor state. */
1496 if (nbr->state < NSM_Exchange)
1497 {
1498 zlog_warn ("Link State Update: Neighbor[%s] state is less than Exchange",
1499 inet_ntoa (ospfh->router_id));
1500 return;
1501 }
1502
1503 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1504 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1505 * of section 13.
1506 */
1507 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1508
1509#ifdef HAVE_OPAQUE_LSA
1510 /*
1511 * Prepare two kinds of lists to clean up unwanted self-originated
1512 * Opaque-LSAs from the routing domain as soon as possible.
1513 */
1514 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1515 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1516
1517 /*
1518 * If self-originated Opaque-LSAs that have flooded before restart
1519 * are contained in the received LSUpd message, corresponding LSReq
1520 * messages to be sent may have to be modified.
1521 * To eliminate possible race conditions such that flushing and normal
1522 * updating for the same LSA would take place alternately, this trick
1523 * must be done before entering to the loop below.
1524 */
1525 ospf_opaque_adjust_lsreq (nbr, lsas);
1526#endif /* HAVE_OPAQUE_LSA */
1527
1528#define DISCARD_LSA(L,N) {\
1529 if (IS_DEBUG_OSPF_EVENT) \
1530 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1531 ospf_lsa_discard (L); \
1532 continue; }
1533
1534 /* Process each LSA received in the one packet. */
1535 for (node = listhead (lsas); node; node = next)
1536 {
1537 struct ospf_lsa *ls_ret, *current;
1538 int ret = 1;
1539
1540 next = node->next;
1541
1542 lsa = getdata (node);
1543
1544#ifdef HAVE_NSSA
1545 if (IS_DEBUG_OSPF_NSSA)
1546 {
1547 char buf1[INET_ADDRSTRLEN];
1548 char buf2[INET_ADDRSTRLEN];
1549 char buf3[INET_ADDRSTRLEN];
1550
1551 zlog_info("LSA Type-%d from %s, ID: %s, ADV: %s",
1552 lsa->data->type,
1553 inet_ntop (AF_INET, &ospfh->router_id,
1554 buf1, INET_ADDRSTRLEN),
1555 inet_ntop (AF_INET, &lsa->data->id,
1556 buf2, INET_ADDRSTRLEN),
1557 inet_ntop (AF_INET, &lsa->data->adv_router,
1558 buf3, INET_ADDRSTRLEN));
1559 }
1560#endif /* HAVE_NSSA */
1561
1562 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1563
1564 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1565
1566 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1567
1568 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1569
1570 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1571
1572 /* Do take in Type-7's if we are an NSSA */
1573
1574 /* If we are also an ABR, later translate them to a Type-5 packet */
1575
1576 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1577 translate them to a separate Type-5 packet. */
1578
1579 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1580 /* Reject from STUB or NSSA */
1581 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1582 {
1583 DISCARD_LSA (lsa, 1);
1584#ifdef HAVE_NSSA
1585 if (IS_DEBUG_OSPF_NSSA)
1586 zlog_info("Incoming External LSA Discarded: We are NSSA/STUB Area");
1587#endif /* HAVE_NSSA */
1588 }
1589
1590#ifdef HAVE_NSSA
1591 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1592 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1593 {
1594 DISCARD_LSA (lsa,2);
1595 if (IS_DEBUG_OSPF_NSSA)
1596 zlog_info("Incoming NSSA LSA Discarded: Not NSSA Area");
1597 }
1598#endif /* HAVE_NSSA */
1599
1600 /* Find the LSA in the current database. */
1601
1602 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1603
1604 /* If the LSA's LS age is equal to MaxAge, and there is currently
1605 no instance of the LSA in the router's link state database,
1606 and none of router's neighbors are in states Exchange or Loading,
1607 then take the following actions. */
1608
1609 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001610 (ospf_nbr_count (oi, NSM_Exchange) +
1611 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001612 {
1613 /* Response Link State Acknowledgment. */
1614 ospf_ls_ack_send (nbr, lsa);
1615
1616 /* Discard LSA. */
1617 zlog_warn ("Link State Update: LS age is equal to MaxAge.");
1618 DISCARD_LSA (lsa, 3);
1619 }
1620
1621#ifdef HAVE_OPAQUE_LSA
1622 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001623 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001624 {
1625 /*
1626 * Even if initial flushing seems to be completed, there might
1627 * be a case that self-originated LSA with MaxAge still remain
1628 * in the routing domain.
1629 * Just send an LSAck message to cease retransmission.
1630 */
1631 if (IS_LSA_MAXAGE (lsa))
1632 {
1633 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1634 ospf_ls_ack_send (nbr, lsa);
1635 ospf_lsa_discard (lsa);
1636
1637 if (current != NULL && ! IS_LSA_MAXAGE (current))
1638 ospf_opaque_lsa_refresh_schedule (current);
1639 continue;
1640 }
1641
1642 /*
1643 * If an instance of self-originated Opaque-LSA is not found
1644 * in the LSDB, there are some possible cases here.
1645 *
1646 * 1) This node lost opaque-capability after restart.
1647 * 2) Else, a part of opaque-type is no more supported.
1648 * 3) Else, a part of opaque-id is no more supported.
1649 *
1650 * Anyway, it is still this node's responsibility to flush it.
1651 * Otherwise, the LSA instance remains in the routing domain
1652 * until its age reaches to MaxAge.
1653 */
1654 if (current == NULL)
1655 {
1656 if (IS_DEBUG_OSPF_EVENT)
1657 zlog_info ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
1658
1659 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1660 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1661 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1662 continue;
1663 }
1664 }
1665#endif /* HAVE_OPAQUE_LSA */
1666
1667 /* (5) Find the instance of this LSA that is currently contained
1668 in the router's link state database. If there is no
1669 database copy, or the received LSA is more recent than
1670 the database copy the following steps must be performed. */
1671
1672 if (current == NULL ||
1673 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1674 {
1675 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001676 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001677 DISCARD_LSA (lsa, 4);
1678 continue;
1679 }
1680
1681 /* (6) Else, If there is an instance of the LSA on the sending
1682 neighbor's Link state request list, an error has occurred in
1683 the Database Exchange process. In this case, restart the
1684 Database Exchange process by generating the neighbor event
1685 BadLSReq for the sending neighbor and stop processing the
1686 Link State Update packet. */
1687
1688 if (ospf_ls_request_lookup (nbr, lsa))
1689 {
1690 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1691 zlog_warn ("LSA instance exists on Link state request list");
1692
1693 /* Clean list of LSAs. */
1694 ospf_upd_list_clean (lsas);
1695 /* this lsa is not on lsas list already. */
1696 ospf_lsa_discard (lsa);
1697#ifdef HAVE_OPAQUE_LSA
1698 list_delete (mylsa_acks);
1699 list_delete (mylsa_upds);
1700#endif /* HAVE_OPAQUE_LSA */
1701 return;
1702 }
1703
1704 /* If the received LSA is the same instance as the database copy
1705 (i.e., neither one is more recent) the following two steps
1706 should be performed: */
1707
1708 if (ret == 0)
1709 {
1710 /* If the LSA is listed in the Link state retransmission list
1711 for the receiving adjacency, the router itself is expecting
1712 an acknowledgment for this LSA. The router should treat the
1713 received LSA as an acknowledgment by removing the LSA from
1714 the Link state retransmission list. This is termed an
1715 "implied acknowledgment". */
1716
1717 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1718
1719 if (ls_ret != NULL)
1720 {
1721 ospf_ls_retransmit_delete (nbr, ls_ret);
1722
1723 /* Delayed acknowledgment sent if advertisement received
1724 from Designated Router, otherwise do nothing. */
1725 if (oi->state == ISM_Backup)
1726 if (NBR_IS_DR (nbr))
1727 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1728
1729 DISCARD_LSA (lsa, 5);
1730 }
1731 else
1732 /* Acknowledge the receipt of the LSA by sending a
1733 Link State Acknowledgment packet back out the receiving
1734 interface. */
1735 {
1736 ospf_ls_ack_send (nbr, lsa);
1737 DISCARD_LSA (lsa, 6);
1738 }
1739 }
1740
1741 /* The database copy is more recent. If the database copy
1742 has LS age equal to MaxAge and LS sequence number equal to
1743 MaxSequenceNumber, simply discard the received LSA without
1744 acknowledging it. (In this case, the LSA's LS sequence number is
1745 wrapping, and the MaxSequenceNumber LSA must be completely
1746 flushed before any new LSA instance can be introduced). */
1747
1748 else if (ret > 0) /* Database copy is more recent */
1749 {
1750 if (IS_LSA_MAXAGE (current) &&
1751 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1752 {
1753 DISCARD_LSA (lsa, 7);
1754 }
1755 /* Otherwise, as long as the database copy has not been sent in a
1756 Link State Update within the last MinLSArrival seconds, send the
1757 database copy back to the sending neighbor, encapsulated within
1758 a Link State Update Packet. The Link State Update Packet should
1759 be sent directly to the neighbor. In so doing, do not put the
1760 database copy of the LSA on the neighbor's link state
1761 retransmission list, and do not acknowledge the received (less
1762 recent) LSA instance. */
1763 else
1764 {
1765 struct timeval now;
1766
1767 gettimeofday (&now, NULL);
1768
1769 if (tv_cmp (tv_sub (now, current->tv_orig),
1770 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1771 /* Trap NSSA type later.*/
1772 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1773 DISCARD_LSA (lsa, 8);
1774 }
1775 }
1776 }
1777
1778#ifdef HAVE_OPAQUE_LSA
1779 /*
1780 * Now that previously originated Opaque-LSAs those which not yet
1781 * installed into LSDB are captured, take several steps to clear
1782 * them completely from the routing domain, before proceeding to
1783 * origination for the current target Opaque-LSAs.
1784 */
1785 while (listcount (mylsa_acks) > 0)
1786 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1787
1788 if (listcount (mylsa_upds) > 0)
1789 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1790
1791 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001792 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001793#endif /* HAVE_OPAQUE_LSA */
1794
1795 assert (listcount (lsas) == 0);
1796 list_delete (lsas);
1797}
1798
1799/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1800void
1801ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1802 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1803{
1804 struct ospf_neighbor *nbr;
1805#ifdef HAVE_OPAQUE_LSA
1806 list opaque_acks;
1807#endif /* HAVE_OPAQUE_LSA */
1808
1809 /* increment statistics. */
1810 oi->ls_ack_in++;
1811
1812 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1813 if (nbr == NULL)
1814 {
1815 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1816 inet_ntoa (ospfh->router_id));
1817 return;
1818 }
1819
1820 if (nbr->state < NSM_Exchange)
1821 {
1822 zlog_warn ("Link State Acknowledgment: State is less than Exchange.");
1823 return;
1824 }
1825
1826#ifdef HAVE_OPAQUE_LSA
1827 opaque_acks = list_new ();
1828#endif /* HAVE_OPAQUE_LSA */
1829
1830 while (size >= OSPF_LSA_HEADER_SIZE)
1831 {
1832 struct ospf_lsa *lsa, *lsr;
1833
1834 lsa = ospf_lsa_new ();
1835 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1836
1837 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1838 size -= OSPF_LSA_HEADER_SIZE;
1839 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1840
1841 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1842 {
1843 lsa->data = NULL;
1844 ospf_lsa_discard (lsa);
1845 continue;
1846 }
1847
1848 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1849
1850 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1851 {
1852#ifdef HAVE_OPAQUE_LSA
1853 /* Keep this LSA entry for later reference. */
1854 if (IS_OPAQUE_LSA (lsr->data->type))
1855 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
1856#endif /* HAVE_OPAQUE_LSA */
1857
1858 ospf_ls_retransmit_delete (nbr, lsr);
1859 }
1860
1861 lsa->data = NULL;
1862 ospf_lsa_discard (lsa);
1863 }
1864
1865#ifdef HAVE_OPAQUE_LSA
1866 if (listcount (opaque_acks) > 0)
1867 ospf_opaque_ls_ack_received (nbr, opaque_acks);
1868
1869 list_delete (opaque_acks);
1870 return;
1871#endif /* HAVE_OPAQUE_LSA */
1872}
1873
1874struct stream *
1875ospf_recv_packet (int fd, struct interface **ifp)
1876{
1877 int ret;
1878 struct ip iph;
1879 u_int16_t ip_len;
1880 struct stream *ibuf;
1881 unsigned int ifindex = 0;
1882 struct iovec iov;
1883 struct cmsghdr *cmsg;
1884#if defined (IP_PKTINFO)
1885 struct in_pktinfo *pktinfo;
1886#elif defined (IP_RECVIF)
1887 struct sockaddr_dl *pktinfo;
1888#else
1889 char *pktinfo; /* dummy */
1890#endif
1891 char buff [sizeof (*cmsg) + sizeof (*pktinfo)];
1892 struct msghdr msgh = {NULL, 0, &iov, 1, buff,
1893 sizeof (*cmsg) + sizeof (*pktinfo), 0};
1894
1895 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
1896
1897 if (ret != sizeof (iph))
1898 {
1899 zlog_warn ("ospf_recv_packet packet smaller than ip header");
1900 return NULL;
1901 }
1902
1903#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1904 ip_len = iph.ip_len;
1905#else
1906 ip_len = ntohs (iph.ip_len);
1907#endif
1908
1909#if !defined(GNU_LINUX)
1910 /*
1911 * Kernel network code touches incoming IP header parameters,
1912 * before protocol specific processing.
1913 *
1914 * 1) Convert byteorder to host representation.
1915 * --> ip_len, ip_id, ip_off
1916 *
1917 * 2) Adjust ip_len to strip IP header size!
1918 * --> If user process receives entire IP packet via RAW
1919 * socket, it must consider adding IP header size to
1920 * the "ip_len" field of "ip" structure.
1921 *
1922 * For more details, see <netinet/ip_input.c>.
1923 */
1924 ip_len = ip_len + (iph.ip_hl << 2);
1925#endif
1926
1927 ibuf = stream_new (ip_len);
1928 iov.iov_base = STREAM_DATA (ibuf);
1929 iov.iov_len = ip_len;
1930 ret = recvmsg (fd, &msgh, 0);
1931
1932 cmsg = CMSG_FIRSTHDR (&msgh);
1933
1934 if (cmsg != NULL && //cmsg->cmsg_len == sizeof (*pktinfo) &&
1935 cmsg->cmsg_level == IPPROTO_IP &&
1936#if defined (IP_PKTINFO)
1937 cmsg->cmsg_type == IP_PKTINFO
1938#elif defined (IP_RECVIF)
1939 cmsg->cmsg_type == IP_RECVIF
1940#else
1941 0
1942#endif
1943 )
1944 {
1945#if defined (IP_PKTINFO)
1946 pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
1947 ifindex = pktinfo->ipi_ifindex;
1948#elif defined (IP_RECVIF)
1949 pktinfo = (struct sockaddr_dl *)CMSG_DATA(cmsg);
1950 ifindex = pktinfo->sdl_index;
1951#else
1952 ifindex = 0;
1953#endif
1954 }
1955
1956 *ifp = if_lookup_by_index (ifindex);
1957
1958 if (ret != ip_len)
1959 {
1960 zlog_warn ("ospf_recv_packet short read. "
1961 "ip_len %d bytes read %d", ip_len, ret);
1962 stream_free (ibuf);
1963 return NULL;
1964 }
1965
1966 return ibuf;
1967}
1968
1969struct ospf_interface *
paul020709f2003-04-04 02:44:16 +00001970ospf_associate_packet_vl (struct ospf *ospf,
1971 struct interface *ifp, struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00001972 struct ip *iph, struct ospf_header *ospfh)
1973{
1974 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00001975 struct ospf_vl_data *vl_data;
1976 struct ospf_area *vl_area;
paul68980082003-03-25 05:07:42 +00001977 listnode node;
paul718e3742002-12-13 20:15:29 +00001978
1979 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
1980 !OSPF_IS_AREA_BACKBONE (ospfh))
1981 return oi;
1982
1983 if ((rcv_oi = oi) == NULL)
1984 {
paul020709f2003-04-04 02:44:16 +00001985 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, ifp,
paul68980082003-03-25 05:07:42 +00001986 iph->ip_dst)) == NULL)
paul718e3742002-12-13 20:15:29 +00001987 return NULL;
1988 }
1989
paul020709f2003-04-04 02:44:16 +00001990 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00001991 {
1992 if ((vl_data = getdata (node)) == NULL)
1993 continue;
1994
paul020709f2003-04-04 02:44:16 +00001995 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00001996 if (!vl_area)
1997 continue;
1998
1999 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2000 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2001 {
2002 if (IS_DEBUG_OSPF_EVENT)
2003 zlog_info ("associating packet with %s",
2004 IF_NAME (vl_data->vl_oi));
2005 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2006 {
2007 if (IS_DEBUG_OSPF_EVENT)
2008 zlog_info ("This VL is not up yet, sorry");
2009 return NULL;
2010 }
2011
2012 return vl_data->vl_oi;
2013 }
2014 }
2015
2016 if (IS_DEBUG_OSPF_EVENT)
2017 zlog_info ("couldn't find any VL to associate the packet with");
2018
2019 return oi;
2020}
2021
2022int
2023ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2024{
2025 /* Check match the Area ID of the receiving interface. */
2026 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2027 return 1;
2028
2029 return 0;
2030}
2031
2032/* Unbound socket will accept any Raw IP packets if proto is matched.
2033 To prevent it, compare src IP address and i/f address with masking
2034 i/f network mask. */
2035int
2036ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2037{
2038 struct in_addr mask, me, him;
2039
2040 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2041 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2042 return 1;
2043
2044 masklen2ip (oi->address->prefixlen, &mask);
2045
2046 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2047 him.s_addr = ip_src.s_addr & mask.s_addr;
2048
2049 if (IPV4_ADDR_SAME (&me, &him))
2050 return 1;
2051
2052 return 0;
2053}
2054
2055int
2056ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2057 struct ospf_header *ospfh)
2058{
2059 int ret = 0;
2060 struct crypt_key *ck;
2061
2062 switch (ntohs (ospfh->auth_type))
2063 {
2064 case OSPF_AUTH_NULL:
2065 ret = 1;
2066 break;
2067 case OSPF_AUTH_SIMPLE:
2068 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2069 ret = 1;
2070 else
2071 ret = 0;
2072 break;
2073 case OSPF_AUTH_CRYPTOGRAPHIC:
2074 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2075 {
2076 ret = 0;
2077 break;
2078 }
2079
2080 /* This is very basic, the digest processing is elsewhere */
2081 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2082 ospfh->u.crypt.key_id == ck->key_id &&
2083 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2084 ret = 1;
2085 else
2086 ret = 0;
2087 break;
2088 default:
2089 ret = 0;
2090 break;
2091 }
2092
2093 return ret;
2094}
2095
2096int
2097ospf_check_sum (struct ospf_header *ospfh)
2098{
2099 u_int32_t ret;
2100 u_int16_t sum;
2101 int in_cksum (void *ptr, int nbytes);
2102
2103 /* clear auth_data for checksum. */
2104 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2105
2106 /* keep checksum and clear. */
2107 sum = ospfh->checksum;
2108 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2109
2110 /* calculate checksum. */
2111 ret = in_cksum (ospfh, ntohs (ospfh->length));
2112
2113 if (ret != sum)
2114 {
2115 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2116 ret, sum);
2117 return 0;
2118 }
2119
2120 return 1;
2121}
2122
2123/* OSPF Header verification. */
2124int
2125ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2126 struct ip *iph, struct ospf_header *ospfh)
2127{
2128 /* check version. */
2129 if (ospfh->version != OSPF_VERSION)
2130 {
2131 zlog_warn ("interface %s: ospf_read version number mismatch.",
2132 IF_NAME (oi));
2133 return -1;
2134 }
2135
2136 /* Check Area ID. */
2137 if (!ospf_check_area_id (oi, ospfh))
2138 {
2139 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2140 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2141 return -1;
2142 }
2143
2144 /* Check network mask, Silently discarded. */
2145 if (! ospf_check_network_mask (oi, iph->ip_src))
2146 {
2147 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2148 IF_NAME (oi), inet_ntoa (iph->ip_src));
2149 return -1;
2150 }
2151
2152 /* Check authentication. */
2153 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2154 {
2155 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2156 IF_NAME (oi));
2157 return -1;
2158 }
2159
2160 if (! ospf_check_auth (oi, ibuf, ospfh))
2161 {
2162 zlog_warn ("interface %s: ospf_read authentication failed.",
2163 IF_NAME (oi));
2164 return -1;
2165 }
2166
2167 /* if check sum is invalid, packet is discarded. */
2168 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2169 {
2170 if (! ospf_check_sum (ospfh))
2171 {
2172 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2173 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2174 return -1;
2175 }
2176 }
2177 else
2178 {
2179 if (ospfh->checksum != 0)
2180 return -1;
2181 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2182 {
2183 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2184 IF_NAME (oi));
2185 return -1;
2186 }
2187 }
2188
2189 return 0;
2190}
2191
2192/* Starting point of packet process function. */
2193int
2194ospf_read (struct thread *thread)
2195{
2196 int ret;
2197 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002198 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002199 struct ospf_interface *oi;
2200 struct ip *iph;
2201 struct ospf_header *ospfh;
2202 u_int16_t length;
2203 struct interface *ifp;
2204
2205 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002206 ospf = THREAD_ARG (thread);
2207 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002208
2209 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002210 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002211 if (ibuf == NULL)
2212 return -1;
2213
2214 iph = (struct ip *) STREAM_DATA (ibuf);
2215
2216 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002217 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002218
2219 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002220 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul7d95c612003-01-27 12:00:55 +00002221 ospf_ip_header_dump (ibuf);
2222
paul718e3742002-12-13 20:15:29 +00002223 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002224 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002225 {
2226 stream_free (ibuf);
2227 return 0;
2228 }
2229
2230 /* Adjust size to message length. */
2231 stream_forward (ibuf, iph->ip_hl * 4);
2232
2233 /* Get ospf packet header. */
2234 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2235
2236 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002237 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
paul718e3742002-12-13 20:15:29 +00002238 if (ifp && oi && oi->ifp != ifp)
2239 {
2240 zlog_warn ("Packet from [%s] received on wrong link %s",
2241 inet_ntoa (iph->ip_src), ifp->name);
2242 stream_free (ibuf);
2243 return 0;
2244 }
2245
paul020709f2003-04-04 02:44:16 +00002246 if ((oi = ospf_associate_packet_vl (ospf, ifp, oi, iph, ospfh)) == NULL)
paul718e3742002-12-13 20:15:29 +00002247 {
2248 stream_free (ibuf);
2249 return 0;
2250 }
2251
2252 /*
2253 * If the received packet is destined for AllDRouters, the packet
2254 * should be accepted only if the received ospf interface state is
2255 * either DR or Backup -- endo.
2256 */
2257 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2258 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2259 {
2260 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2261 inet_ntoa (iph->ip_src), IF_NAME (oi),
2262 LOOKUP (ospf_ism_state_msg, oi->state));
2263 stream_free (ibuf);
2264 return 0;
2265 }
2266
2267 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002268 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2269 {
paul718e3742002-12-13 20:15:29 +00002270 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002271 {
2272 zlog_info ("-----------------------------------------------------");
2273 ospf_packet_dump (ibuf);
2274 }
paul718e3742002-12-13 20:15:29 +00002275
2276 zlog_info ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002277 ospf_packet_type_str[ospfh->type],
2278 inet_ntoa (ospfh->router_id), IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +00002279 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2280 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2281
2282 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2283 zlog_info ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002284 }
paul718e3742002-12-13 20:15:29 +00002285
2286 /* Some header verification. */
2287 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2288 if (ret < 0)
2289 {
2290 stream_free (ibuf);
2291 return ret;
2292 }
2293
2294 stream_forward (ibuf, OSPF_HEADER_SIZE);
2295
2296 /* Adjust size to message length. */
2297 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2298
2299 /* Read rest of the packet and call each sort of packet routine. */
2300 switch (ospfh->type)
2301 {
2302 case OSPF_MSG_HELLO:
2303 ospf_hello (iph, ospfh, ibuf, oi, length);
2304 break;
2305 case OSPF_MSG_DB_DESC:
2306 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2307 break;
2308 case OSPF_MSG_LS_REQ:
2309 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2310 break;
2311 case OSPF_MSG_LS_UPD:
2312 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2313 break;
2314 case OSPF_MSG_LS_ACK:
2315 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2316 break;
2317 default:
2318 zlog (NULL, LOG_WARNING,
2319 "interface %s: OSPF packet header type %d is illegal",
2320 IF_NAME (oi), ospfh->type);
2321 break;
2322 }
2323
2324 stream_free (ibuf);
2325 return 0;
2326}
2327
2328/* Make OSPF header. */
2329void
2330ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2331{
2332 struct ospf_header *ospfh;
2333
2334 ospfh = (struct ospf_header *) STREAM_DATA (s);
2335
2336 ospfh->version = (u_char) OSPF_VERSION;
2337 ospfh->type = (u_char) type;
2338
paul68980082003-03-25 05:07:42 +00002339 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002340
2341 ospfh->checksum = 0;
2342 ospfh->area_id = oi->area->area_id;
2343 ospfh->auth_type = htons (ospf_auth_type (oi));
2344
2345 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2346
2347 ospf_output_forward (s, OSPF_HEADER_SIZE);
2348}
2349
2350/* Make Authentication Data. */
2351int
2352ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2353{
2354 struct crypt_key *ck;
2355
2356 switch (ospf_auth_type (oi))
2357 {
2358 case OSPF_AUTH_NULL:
2359 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2360 break;
2361 case OSPF_AUTH_SIMPLE:
2362 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2363 OSPF_AUTH_SIMPLE_SIZE);
2364 break;
2365 case OSPF_AUTH_CRYPTOGRAPHIC:
2366 /* If key is not set, then set 0. */
2367 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2368 {
2369 ospfh->u.crypt.zero = 0;
2370 ospfh->u.crypt.key_id = 0;
2371 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2372 }
2373 else
2374 {
2375 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2376 ospfh->u.crypt.zero = 0;
2377 ospfh->u.crypt.key_id = ck->key_id;
2378 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2379 }
2380 /* note: the seq is done in ospf_make_md5_digest() */
2381 break;
2382 default:
2383 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2384 break;
2385 }
2386
2387 return 0;
2388}
2389
2390/* Fill rest of OSPF header. */
2391void
2392ospf_fill_header (struct ospf_interface *oi,
2393 struct stream *s, u_int16_t length)
2394{
2395 struct ospf_header *ospfh;
2396
2397 ospfh = (struct ospf_header *) STREAM_DATA (s);
2398
2399 /* Fill length. */
2400 ospfh->length = htons (length);
2401
2402 /* Calculate checksum. */
2403 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2404 ospfh->checksum = in_cksum (ospfh, length);
2405 else
2406 ospfh->checksum = 0;
2407
2408 /* Add Authentication Data. */
2409 ospf_make_auth (oi, ospfh);
2410}
2411
2412int
2413ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2414{
2415 struct ospf_neighbor *nbr;
2416 struct route_node *rn;
2417 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2418 struct in_addr mask;
2419 unsigned long p;
2420 int flag = 0;
2421
2422 /* Set netmask of interface. */
2423 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2424 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2425 masklen2ip (oi->address->prefixlen, &mask);
2426 else
2427 memset ((char *) &mask, 0, sizeof (struct in_addr));
2428 stream_put_ipv4 (s, mask.s_addr);
2429
2430 /* Set Hello Interval. */
2431 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2432
2433 if (IS_DEBUG_OSPF_EVENT)
2434 zlog_info ("make_hello: options: %x, int: %s",
2435 OPTIONS(oi), IF_NAME (oi));
2436
2437 /* Set Options. */
2438 stream_putc (s, OPTIONS (oi));
2439
2440 /* Set Router Priority. */
2441 stream_putc (s, PRIORITY (oi));
2442
2443 /* Set Router Dead Interval. */
2444 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2445
2446 /* Set Designated Router. */
2447 stream_put_ipv4 (s, DR (oi).s_addr);
2448
2449 p = s->putp;
2450
2451 /* Set Backup Designated Router. */
2452 stream_put_ipv4 (s, BDR (oi).s_addr);
2453
2454 /* Add neighbor seen. */
2455 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002456 if ((nbr = rn->info))
2457 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2458 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2459 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2460 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002461 {
2462 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002463 if (nbr->d_router.s_addr != 0
2464 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2465 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2466 flag = 1;
paul718e3742002-12-13 20:15:29 +00002467
2468 stream_put_ipv4 (s, nbr->router_id.s_addr);
2469 length += 4;
2470 }
2471
2472 /* Let neighbor generate BackupSeen. */
2473 if (flag == 1)
2474 {
2475 stream_set_putp (s, p);
2476 stream_put_ipv4 (s, 0);
2477 }
2478
2479 return length;
2480}
2481
2482int
2483ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2484 struct stream *s)
2485{
2486 struct ospf_lsa *lsa;
2487 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2488 u_char options;
2489 unsigned long pp;
2490 int i;
2491 struct ospf_lsdb *lsdb;
2492
2493 /* Set Interface MTU. */
2494 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2495 stream_putw (s, 0);
2496 else
2497 stream_putw (s, oi->ifp->mtu);
2498
2499 /* Set Options. */
2500 options = OPTIONS (oi);
2501#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002502 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002503 {
2504 if (IS_SET_DD_I (nbr->dd_flags)
2505 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2506 /*
2507 * Set O-bit in the outgoing DD packet for capablity negotiation,
2508 * if one of following case is applicable.
2509 *
2510 * 1) WaitTimer expiration event triggered the neighbor state to
2511 * change to Exstart, but no (valid) DD packet has received
2512 * from the neighbor yet.
2513 *
2514 * 2) At least one DD packet with O-bit on has received from the
2515 * neighbor.
2516 */
2517 SET_FLAG (options, OSPF_OPTION_O);
2518 }
2519#endif /* HAVE_OPAQUE_LSA */
2520 stream_putc (s, options);
2521
2522 /* Keep pointer to flags. */
2523 pp = stream_get_putp (s);
2524 stream_putc (s, nbr->dd_flags);
2525
2526 /* Set DD Sequence Number. */
2527 stream_putl (s, nbr->dd_seqnum);
2528
2529 if (ospf_db_summary_isempty (nbr))
2530 {
2531 if (nbr->state >= NSM_Exchange)
2532 {
2533 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2534 /* Set DD flags again */
2535 stream_set_putp (s, pp);
2536 stream_putc (s, nbr->dd_flags);
2537 }
2538 return length;
2539 }
2540
2541 /* Describe LSA Header from Database Summary List. */
2542 lsdb = &nbr->db_sum;
2543
2544 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2545 {
2546 struct route_table *table = lsdb->type[i].db;
2547 struct route_node *rn;
2548
2549 for (rn = route_top (table); rn; rn = route_next (rn))
2550 if ((lsa = rn->info) != NULL)
2551 {
2552#ifdef HAVE_OPAQUE_LSA
2553 if (IS_OPAQUE_LSA (lsa->data->type)
2554 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2555 {
2556 /* Suppress advertising opaque-informations. */
2557 /* Remove LSA from DB summary list. */
2558 ospf_lsdb_delete (lsdb, lsa);
2559 continue;
2560 }
2561#endif /* HAVE_OPAQUE_LSA */
2562
2563 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2564 {
2565 struct lsa_header *lsah;
2566 u_int16_t ls_age;
2567
2568 /* DD packet overflows interface MTU. */
2569 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2570 break;
2571
2572 /* Keep pointer to LS age. */
2573 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2574 stream_get_putp (s));
2575
2576 /* Proceed stream pointer. */
2577 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2578 length += OSPF_LSA_HEADER_SIZE;
2579
2580 /* Set LS age. */
2581 ls_age = LS_AGE (lsa);
2582 lsah->ls_age = htons (ls_age);
2583
2584 }
2585
2586 /* Remove LSA from DB summary list. */
2587 ospf_lsdb_delete (lsdb, lsa);
2588 }
2589 }
2590
2591 return length;
2592}
2593
2594int
2595ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2596 unsigned long delta, struct ospf_neighbor *nbr,
2597 struct ospf_lsa *lsa)
2598{
2599 struct ospf_interface *oi;
2600
2601 oi = nbr->oi;
2602
2603 /* LS Request packet overflows interface MTU. */
2604 if (*length + delta > OSPF_PACKET_MAX(oi))
2605 return 0;
2606
2607 stream_putl (s, lsa->data->type);
2608 stream_put_ipv4 (s, lsa->data->id.s_addr);
2609 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2610
2611 ospf_lsa_unlock (nbr->ls_req_last);
2612 nbr->ls_req_last = ospf_lsa_lock (lsa);
2613
2614 *length += 12;
2615 return 1;
2616}
2617
2618int
2619ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2620{
2621 struct ospf_lsa *lsa;
2622 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2623 unsigned long delta = stream_get_putp(s)+12;
2624 struct route_table *table;
2625 struct route_node *rn;
2626 int i;
2627 struct ospf_lsdb *lsdb;
2628
2629 lsdb = &nbr->ls_req;
2630
2631 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2632 {
2633 table = lsdb->type[i].db;
2634 for (rn = route_top (table); rn; rn = route_next (rn))
2635 if ((lsa = (rn->info)) != NULL)
2636 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2637 {
2638 route_unlock_node (rn);
2639 break;
2640 }
2641 }
2642 return length;
2643}
2644
2645int
2646ls_age_increment (struct ospf_lsa *lsa, int delay)
2647{
2648 int age;
2649
2650 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2651
2652 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2653}
2654
2655int
2656ospf_make_ls_upd (struct ospf_interface *oi, list update, struct stream *s)
2657{
2658 struct ospf_lsa *lsa;
2659 listnode node;
2660 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2661 unsigned long delta = stream_get_putp (s);
2662 unsigned long pp;
2663 int count = 0;
2664
2665 if (IS_DEBUG_OSPF_EVENT)
2666 zlog_info("ospf_make_ls_upd: Start");
2667
2668 pp = stream_get_putp (s);
2669 ospf_output_forward (s, 4);
2670
2671 while ((node = listhead (update)) != NULL)
2672 {
2673 struct lsa_header *lsah;
2674 u_int16_t ls_age;
2675
2676 if (IS_DEBUG_OSPF_EVENT)
2677 zlog_info("ospf_make_ls_upd: List Iteration");
2678
2679 lsa = getdata (node);
2680 assert (lsa);
2681 assert (lsa->data);
2682
2683 /* Check packet size. */
2684 if (length + delta + ntohs (lsa->data->length) > OSPF_PACKET_MAX (oi))
2685 break;
2686
2687 /* Keep pointer to LS age. */
2688 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2689
2690 /* Put LSA to Link State Request. */
2691 stream_put (s, lsa->data, ntohs (lsa->data->length));
2692
2693 /* Set LS age. */
2694 /* each hop must increment an lsa_age by transmit_delay
2695 of OSPF interface */
2696 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2697 lsah->ls_age = htons (ls_age);
2698
2699 length += ntohs (lsa->data->length);
2700 count++;
2701
2702 list_delete_node (update, node);
2703 ospf_lsa_unlock (lsa);
2704 }
2705
2706 /* Now set #LSAs. */
2707 stream_set_putp (s, pp);
2708 stream_putl (s, count);
2709
2710 stream_set_putp (s, s->endp);
2711
2712 if (IS_DEBUG_OSPF_EVENT)
2713 zlog_info("ospf_make_ls_upd: Stop");
2714 return length;
2715}
2716
2717int
2718ospf_make_ls_ack (struct ospf_interface *oi, list ack, struct stream *s)
2719{
2720 list rm_list;
2721 listnode node;
2722 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2723 unsigned long delta = stream_get_putp(s) + 24;
2724 struct ospf_lsa *lsa;
2725
2726 rm_list = list_new ();
2727
2728 for (node = listhead (ack); node; nextnode (node))
2729 {
2730 lsa = getdata (node);
2731 assert (lsa);
2732
2733 if (length + delta > OSPF_PACKET_MAX (oi))
2734 break;
2735
2736 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2737 length += OSPF_LSA_HEADER_SIZE;
2738
2739 listnode_add (rm_list, lsa);
2740 }
2741
2742 /* Remove LSA from LS-Ack list. */
2743 for (node = listhead (rm_list); node; nextnode (node))
2744 {
2745 lsa = (struct ospf_lsa *) getdata (node);
2746
2747 listnode_delete (ack, lsa);
2748 ospf_lsa_unlock (lsa);
2749 }
2750
2751 list_delete (rm_list);
2752
2753 return length;
2754}
2755
2756void
2757ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2758{
2759 struct ospf_packet *op;
2760 u_int16_t length = OSPF_HEADER_SIZE;
2761
2762 op = ospf_packet_new (oi->ifp->mtu);
2763
2764 /* Prepare OSPF common header. */
2765 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2766
2767 /* Prepare OSPF Hello body. */
2768 length += ospf_make_hello (oi, op->s);
2769
2770 /* Fill OSPF header. */
2771 ospf_fill_header (oi, op->s, length);
2772
2773 /* Set packet length. */
2774 op->length = length;
2775
2776 op->dst.s_addr = addr->s_addr;
2777
2778 /* Add packet to the interface output queue. */
2779 ospf_packet_add (oi, op);
2780
2781 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002782 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002783}
2784
2785void
2786ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2787{
2788 struct ospf_interface *oi;
2789
2790 oi = nbr_nbma->oi;
2791 assert(oi);
2792
2793 /* If this is passive interface, do not send OSPF Hello. */
2794 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2795 return;
2796
2797 if (oi->type != OSPF_IFTYPE_NBMA)
2798 return;
2799
2800 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2801 return;
2802
2803 if (PRIORITY(oi) == 0)
2804 return;
2805
2806 if (nbr_nbma->priority == 0
2807 && oi->state != ISM_DR && oi->state != ISM_Backup)
2808 return;
2809
2810 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2811}
2812
2813int
2814ospf_poll_timer (struct thread *thread)
2815{
2816 struct ospf_nbr_nbma *nbr_nbma;
2817
2818 nbr_nbma = THREAD_ARG (thread);
2819 nbr_nbma->t_poll = NULL;
2820
2821 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2822 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2823 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2824
2825 ospf_poll_send (nbr_nbma);
2826
2827 if (nbr_nbma->v_poll > 0)
2828 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2829 nbr_nbma->v_poll);
2830
2831 return 0;
2832}
2833
2834
2835int
2836ospf_hello_reply_timer (struct thread *thread)
2837{
2838 struct ospf_neighbor *nbr;
2839
2840 nbr = THREAD_ARG (thread);
2841 nbr->t_hello_reply = NULL;
2842
2843 assert (nbr->oi);
2844
2845 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2846 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2847 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2848
2849 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2850
2851 return 0;
2852}
2853
2854/* Send OSPF Hello. */
2855void
2856ospf_hello_send (struct ospf_interface *oi)
2857{
2858 struct ospf_packet *op;
2859 u_int16_t length = OSPF_HEADER_SIZE;
2860
2861 /* If this is passive interface, do not send OSPF Hello. */
2862 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2863 return;
2864
2865 op = ospf_packet_new (oi->ifp->mtu);
2866
2867 /* Prepare OSPF common header. */
2868 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2869
2870 /* Prepare OSPF Hello body. */
2871 length += ospf_make_hello (oi, op->s);
2872
2873 /* Fill OSPF header. */
2874 ospf_fill_header (oi, op->s, length);
2875
2876 /* Set packet length. */
2877 op->length = length;
2878
2879 if (oi->type == OSPF_IFTYPE_NBMA)
2880 {
2881 struct ospf_neighbor *nbr;
2882 struct route_node *rn;
2883
2884 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2885 if ((nbr = rn->info))
2886 if (nbr != oi->nbr_self)
2887 if (nbr->state != NSM_Down)
2888 {
2889 /* RFC 2328 Section 9.5.1
2890 If the router is not eligible to become Designated Router,
2891 it must periodically send Hello Packets to both the
2892 Designated Router and the Backup Designated Router (if they
2893 exist). */
2894 if (PRIORITY(oi) == 0 &&
2895 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
2896 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
2897 continue;
2898
2899 /* If the router is eligible to become Designated Router, it
2900 must periodically send Hello Packets to all neighbors that
2901 are also eligible. In addition, if the router is itself the
2902 Designated Router or Backup Designated Router, it must also
2903 send periodic Hello Packets to all other neighbors. */
2904
2905 if (nbr->priority == 0 && oi->state == ISM_DROther)
2906 continue;
2907 /* if oi->state == Waiting, send hello to all neighbors */
2908 {
2909 struct ospf_packet *op_dup;
2910
2911 op_dup = ospf_packet_dup(op);
2912 op_dup->dst = nbr->address.u.prefix4;
2913
2914 /* Add packet to the interface output queue. */
2915 ospf_packet_add (oi, op_dup);
2916
paul020709f2003-04-04 02:44:16 +00002917 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002918 }
2919
2920 }
2921 ospf_packet_free (op);
2922 }
2923 else
2924 {
2925 /* Decide destination address. */
2926 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2927 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
2928 else
2929 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
2930
2931 /* Add packet to the interface output queue. */
2932 ospf_packet_add (oi, op);
2933
2934 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002935 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002936 }
2937}
2938
2939/* Send OSPF Database Description. */
2940void
2941ospf_db_desc_send (struct ospf_neighbor *nbr)
2942{
2943 struct ospf_interface *oi;
2944 struct ospf_packet *op;
2945 u_int16_t length = OSPF_HEADER_SIZE;
2946
2947 oi = nbr->oi;
2948 op = ospf_packet_new (oi->ifp->mtu);
2949
2950 /* Prepare OSPF common header. */
2951 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
2952
2953 /* Prepare OSPF Database Description body. */
2954 length += ospf_make_db_desc (oi, nbr, op->s);
2955
2956 /* Fill OSPF header. */
2957 ospf_fill_header (oi, op->s, length);
2958
2959 /* Set packet length. */
2960 op->length = length;
2961
2962 /* Decide destination address. */
2963 op->dst = nbr->address.u.prefix4;
2964
2965 /* Add packet to the interface output queue. */
2966 ospf_packet_add (oi, op);
2967
2968 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002969 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002970
2971 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
2972 if (nbr->last_send)
2973 ospf_packet_free (nbr->last_send);
2974 nbr->last_send = ospf_packet_dup (op);
2975 gettimeofday (&nbr->last_send_ts, NULL);
2976}
2977
2978/* Re-send Database Description. */
2979void
2980ospf_db_desc_resend (struct ospf_neighbor *nbr)
2981{
2982 struct ospf_interface *oi;
2983
2984 oi = nbr->oi;
2985
2986 /* Add packet to the interface output queue. */
2987 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
2988
2989 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002990 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002991}
2992
2993/* Send Link State Request. */
2994void
2995ospf_ls_req_send (struct ospf_neighbor *nbr)
2996{
2997 struct ospf_interface *oi;
2998 struct ospf_packet *op;
2999 u_int16_t length = OSPF_HEADER_SIZE;
3000
3001 oi = nbr->oi;
3002 op = ospf_packet_new (oi->ifp->mtu);
3003
3004 /* Prepare OSPF common header. */
3005 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3006
3007 /* Prepare OSPF Link State Request body. */
3008 length += ospf_make_ls_req (nbr, op->s);
3009 if (length == OSPF_HEADER_SIZE)
3010 {
3011 ospf_packet_free (op);
3012 return;
3013 }
3014
3015 /* Fill OSPF header. */
3016 ospf_fill_header (oi, op->s, length);
3017
3018 /* Set packet length. */
3019 op->length = length;
3020
3021 /* Decide destination address. */
3022 op->dst = nbr->address.u.prefix4;
3023
3024 /* Add packet to the interface output queue. */
3025 ospf_packet_add (oi, op);
3026
3027 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003028 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003029
3030 /* Add Link State Request Retransmission Timer. */
3031 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3032}
3033
3034/* Send Link State Update with an LSA. */
3035void
3036ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3037 int flag)
3038{
3039 list update;
3040
3041 update = list_new ();
3042
3043 listnode_add (update, lsa);
3044 ospf_ls_upd_send (nbr, update, flag);
3045
3046 list_delete (update);
3047}
3048
3049static void
3050ospf_ls_upd_queue_send (struct ospf_interface *oi, list update,
3051 struct in_addr addr)
3052{
3053 struct ospf_packet *op;
3054 u_int16_t length = OSPF_HEADER_SIZE;
3055
3056 if (IS_DEBUG_OSPF_EVENT)
3057 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
3058
3059 op = ospf_packet_new (oi->ifp->mtu);
3060
3061 /* Prepare OSPF common header. */
3062 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3063
3064 /* Prepare OSPF Link State Update body. */
3065 /* Includes Type-7 translation. */
3066 length += ospf_make_ls_upd (oi, update, op->s);
3067
3068 /* Fill OSPF header. */
3069 ospf_fill_header (oi, op->s, length);
3070
3071 /* Set packet length. */
3072 op->length = length;
3073
3074 /* Decide destination address. */
3075 op->dst.s_addr = addr.s_addr;
3076
3077 /* Add packet to the interface output queue. */
3078 ospf_packet_add (oi, op);
3079
3080 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003081 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003082}
3083
3084static int
3085ospf_ls_upd_send_queue_event (struct thread *thread)
3086{
3087 struct ospf_interface *oi = THREAD_ARG(thread);
3088 struct route_node *rn;
3089
3090 oi->t_ls_upd_event = NULL;
3091
3092 if (IS_DEBUG_OSPF_EVENT)
3093 zlog_info ("ospf_ls_upd_send_queue start");
3094
3095 for (rn = route_top (oi->ls_upd_queue); rn; rn = route_next (rn))
3096 {
3097 if (rn->info == NULL)
3098 continue;
3099
3100 while (!list_isempty ((list)rn->info))
3101 ospf_ls_upd_queue_send (oi, rn->info, rn->p.u.prefix4);
3102
3103 list_delete (rn->info);
3104 rn->info = NULL;
3105
3106 route_unlock_node (rn);
3107 }
3108
3109 if (IS_DEBUG_OSPF_EVENT)
3110 zlog_info ("ospf_ls_upd_send_queue stop");
3111 return 0;
3112}
3113
3114void
3115ospf_ls_upd_send (struct ospf_neighbor *nbr, list update, int flag)
3116{
3117 struct ospf_interface *oi;
3118 struct prefix_ipv4 p;
3119 struct route_node *rn;
3120 listnode n;
3121
3122 oi = nbr->oi;
3123
3124 p.family = AF_INET;
3125 p.prefixlen = IPV4_MAX_BITLEN;
3126
3127 /* Decide destination address. */
3128 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3129 p.prefix = oi->vl_data->peer_addr;
3130 else if (flag == OSPF_SEND_PACKET_DIRECT)
3131 p.prefix = nbr->address.u.prefix4;
3132 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3133 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3134 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3135 && (flag == OSPF_SEND_PACKET_INDIRECT))
3136 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003137 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3138 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003139 else
3140 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3141
3142 if (oi->type == OSPF_IFTYPE_NBMA)
3143 {
3144 if (flag == OSPF_SEND_PACKET_INDIRECT)
3145 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3146 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3147 zlog_warn ("* LS-Update is sent to myself.");
3148 }
3149
3150 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3151
3152 if (rn->info == NULL)
3153 rn->info = list_new ();
3154
3155 for (n = listhead (update); n; nextnode (n))
3156 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3157
3158 if (oi->t_ls_upd_event == NULL)
3159 oi->t_ls_upd_event =
3160 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3161}
3162
3163static void
3164ospf_ls_ack_send_list (struct ospf_interface *oi, list ack, struct in_addr dst)
3165{
3166 struct ospf_packet *op;
3167 u_int16_t length = OSPF_HEADER_SIZE;
3168
3169 op = ospf_packet_new (oi->ifp->mtu);
3170
3171 /* Prepare OSPF common header. */
3172 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3173
3174 /* Prepare OSPF Link State Acknowledgment body. */
3175 length += ospf_make_ls_ack (oi, ack, op->s);
3176
3177 /* Fill OSPF header. */
3178 ospf_fill_header (oi, op->s, length);
3179
3180 /* Set packet length. */
3181 op->length = length;
3182
3183 /* Set destination IP address. */
3184 op->dst = dst;
3185
3186 /* Add packet to the interface output queue. */
3187 ospf_packet_add (oi, op);
3188
3189 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003190 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003191}
3192
3193static int
3194ospf_ls_ack_send_event (struct thread *thread)
3195{
3196 struct ospf_interface *oi = THREAD_ARG (thread);
3197
3198 oi->t_ls_ack_direct = NULL;
3199
3200 while (listcount (oi->ls_ack_direct.ls_ack))
3201 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3202 oi->ls_ack_direct.dst);
3203
3204 return 0;
3205}
3206
3207void
3208ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3209{
3210 struct ospf_interface *oi = nbr->oi;
3211
3212 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3213 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3214
3215 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3216
3217 if (oi->t_ls_ack_direct == NULL)
3218 oi->t_ls_ack_direct =
3219 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3220}
3221
3222/* Send Link State Acknowledgment delayed. */
3223void
3224ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3225{
3226 struct in_addr dst;
3227
3228 /* Decide destination address. */
3229 /* RFC2328 Section 13.5 On non-broadcast
3230 networks, delayed Link State Acknowledgment packets must be
3231 unicast separately over each adjacency (i.e., neighbor whose
3232 state is >= Exchange). */
3233 if (oi->type == OSPF_IFTYPE_NBMA)
3234 {
3235 struct ospf_neighbor *nbr;
3236 struct route_node *rn;
3237
3238 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3239 if ((nbr = rn->info) != NULL)
3240 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3241 while (listcount (oi->ls_ack))
3242 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3243 return;
3244 }
3245 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3246 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3247 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3248 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3249 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3250 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3251 else
3252 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3253
3254 while (listcount (oi->ls_ack))
3255 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3256}