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