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