blob: 89d35c5847d282e199904941a6a4935cfc05f321 [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);
pauld363df22003-06-19 00:26:34 +00001021
paul718e3742002-12-13 20:15:29 +00001022 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
pauld363df22003-06-19 00:26:34 +00001037#ifdef HAVE_NSSA
1038 /*
1039 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1040 * required. In fact at least JunOS sends DD packets with P bit clear.
1041 * Until proper solution is developped, this hack should help.
1042 *
1043 * Update: According to the RFCs, N bit is specified /only/ for Hello
1044 * options, unfortunately its use in DD options is not specified. Hence some
1045 * implementations follow E-bit semantics and set it in DD options, and some
1046 * treat it as unspecified and hence follow the directive "default for
1047 * options is clear", ie unset.
1048 *
1049 * Reset the flag, as ospfd follows E-bit semantics.
1050 */
1051 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1052 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1053 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1054 {
1055 if (IS_DEBUG_OSPF_EVENT)
paul3db0a772003-06-19 01:07:40 +00001056 zlog_notice ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001057 inet_ntoa (nbr->router_id) );
1058 SET_FLAG (dd->options, OSPF_OPTION_NP);
1059 }
pauld363df22003-06-19 00:26:34 +00001060#endif /* HAVE_NSSA */
1061
paul718e3742002-12-13 20:15:29 +00001062#ifdef REJECT_IF_TBIT_ON
1063 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1064 {
1065 /*
1066 * In Hello protocol, optional capability must have checked
1067 * to prevent this T-bit enabled router be my neighbor.
1068 */
1069 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1070 return;
1071 }
1072#endif /* REJECT_IF_TBIT_ON */
1073
1074#ifdef HAVE_OPAQUE_LSA
1075 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001076 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001077 {
1078 /*
1079 * This node is not configured to handle O-bit, for now.
1080 * Clear it to ignore unsupported capability proposed by neighbor.
1081 */
1082 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1083 }
1084#endif /* HAVE_OPAQUE_LSA */
1085
1086 /* Process DD packet by neighbor status. */
1087 switch (nbr->state)
1088 {
1089 case NSM_Down:
1090 case NSM_Attempt:
1091 case NSM_TwoWay:
1092 zlog_warn ("Packet[DD]: Neighbor state is %s, packet discarded.",
1093 LOOKUP (ospf_nsm_state_msg, nbr->state));
1094 break;
1095 case NSM_Init:
1096 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1097 /* If the new state is ExStart, the processing of the current
1098 packet should then continue in this new state by falling
1099 through to case ExStart below. */
1100 if (nbr->state != NSM_ExStart)
1101 break;
1102 case NSM_ExStart:
1103 /* Initial DBD */
1104 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1105 (size == OSPF_DB_DESC_MIN_SIZE))
1106 {
paul68980082003-03-25 05:07:42 +00001107 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001108 {
1109 /* We're Slave---obey */
1110 zlog_warn ("Packet[DD]: Negotiation done (Slave).");
1111 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1112 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1113 }
1114 else
1115 {
1116 /* We're Master, ignore the initial DBD from Slave */
1117 zlog_warn ("Packet[DD]: Initial DBD from Slave, ignoring.");
1118 break;
1119 }
1120 }
1121 /* Ack from the Slave */
1122 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1123 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001124 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001125 {
1126 zlog_warn ("Packet[DD]: Negotiation done (Master).");
1127 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1128 }
1129 else
1130 {
1131 zlog_warn ("Packet[DD]: Negotiation fails.");
1132 break;
1133 }
1134
1135 /* This is where the real Options are saved */
1136 nbr->options = dd->options;
1137
1138#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001139 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001140 {
1141 if (IS_DEBUG_OSPF_EVENT)
1142 zlog_info ("Neighbor[%s] is %sOpaque-capable.",
1143 inet_ntoa (nbr->router_id),
1144 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1145
1146 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1147 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1148 {
1149 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1150 /* This situation is undesirable, but not a real error. */
1151 }
1152 }
1153#endif /* HAVE_OPAQUE_LSA */
1154
1155 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1156
1157 /* continue processing rest of packet. */
1158 ospf_db_desc_proc (s, oi, nbr, dd, size);
1159 break;
1160 case NSM_Exchange:
1161 if (ospf_db_desc_is_dup (dd, nbr))
1162 {
1163 if (IS_SET_DD_MS (nbr->dd_flags))
1164 /* Master: discard duplicated DD packet. */
1165 zlog_warn ("Packet[DD] (Master): packet duplicated.");
1166 else
1167 /* Slave: cause to retransmit the last Database Description. */
1168 {
1169 zlog_warn ("Packet[DD] [Slave]: packet duplicated.");
1170 ospf_db_desc_resend (nbr);
1171 }
1172 break;
1173 }
1174
1175 /* Otherwise DD packet should be checked. */
1176 /* Check Master/Slave bit mismatch */
1177 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1178 {
1179 zlog_warn ("Packet[DD]: MS-bit mismatch.");
1180 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1181 if (IS_DEBUG_OSPF_EVENT)
1182 zlog_info ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1183 dd->flags, nbr->dd_flags);
1184 break;
1185 }
1186
1187 /* Check initialize bit is set. */
1188 if (IS_SET_DD_I (dd->flags))
1189 {
1190 zlog_warn ("Packet[DD]: I-bit set.");
1191 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1192 break;
1193 }
1194
1195 /* Check DD Options. */
1196 if (dd->options != nbr->options)
1197 {
1198#ifdef ORIGINAL_CODING
1199 /* Save the new options for debugging */
1200 nbr->options = dd->options;
1201#endif /* ORIGINAL_CODING */
1202 zlog_warn ("Packet[DD]: options mismatch.");
1203 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1204 break;
1205 }
1206
1207 /* Check DD sequence number. */
1208 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1209 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1210 (!IS_SET_DD_MS (nbr->dd_flags) &&
1211 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1212 {
1213 zlog_warn ("Pakcet[DD]: sequence number mismatch.");
1214 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1215 break;
1216 }
1217
1218 /* Continue processing rest of packet. */
1219 ospf_db_desc_proc (s, oi, nbr, dd, size);
1220 break;
1221 case NSM_Loading:
1222 case NSM_Full:
1223 if (ospf_db_desc_is_dup (dd, nbr))
1224 {
1225 if (IS_SET_DD_MS (nbr->dd_flags))
1226 {
1227 /* Master should discard duplicate DD packet. */
1228 zlog_warn ("Pakcet[DD]: duplicated, packet discarded.");
1229 break;
1230 }
1231 else
1232 {
1233 struct timeval t, now;
1234 gettimeofday (&now, NULL);
1235 t = tv_sub (now, nbr->last_send_ts);
1236 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1237 {
1238 /* In states Loading and Full the slave must resend
1239 its last Database Description packet in response to
1240 duplicate Database Description packets received
1241 from the master. For this reason the slave must
1242 wait RouterDeadInterval seconds before freeing the
1243 last Database Description packet. Reception of a
1244 Database Description packet from the master after
1245 this interval will generate a SeqNumberMismatch
1246 neighbor event. RFC2328 Section 10.8 */
1247 ospf_db_desc_resend (nbr);
1248 break;
1249 }
1250 }
1251 }
1252
1253 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1254 break;
1255 default:
1256 zlog_warn ("Packet[DD]: NSM illegal status.");
1257 break;
1258 }
1259}
1260
1261#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1262
1263/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1264void
1265ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1266 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1267{
1268 struct ospf_neighbor *nbr;
1269 u_int32_t ls_type;
1270 struct in_addr ls_id;
1271 struct in_addr adv_router;
1272 struct ospf_lsa *find;
1273 list ls_upd;
1274 int length;
1275
1276 /* Increment statistics. */
1277 oi->ls_req_in++;
1278
1279 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1280 if (nbr == NULL)
1281 {
1282 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1283 inet_ntoa (ospfh->router_id));
1284 return;
1285 }
1286
1287 /* Neighbor State should be Exchange or later. */
1288 if (nbr->state != NSM_Exchange &&
1289 nbr->state != NSM_Loading &&
1290 nbr->state != NSM_Full)
1291 {
1292 zlog_warn ("Link State Request: Neighbor state is %s, packet discarded.",
1293 LOOKUP (ospf_nsm_state_msg, nbr->state));
1294 return;
1295 }
1296
1297 /* Send Link State Update for ALL requested LSAs. */
1298 ls_upd = list_new ();
1299 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1300
1301 while (size >= OSPF_LSA_KEY_SIZE)
1302 {
1303 /* Get one slice of Link State Request. */
1304 ls_type = stream_getl (s);
1305 ls_id.s_addr = stream_get_ipv4 (s);
1306 adv_router.s_addr = stream_get_ipv4 (s);
1307
1308 /* Verify LSA type. */
1309 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1310 {
1311 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1312 list_delete (ls_upd);
1313 return;
1314 }
1315
1316 /* Search proper LSA in LSDB. */
1317 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1318 if (find == NULL)
1319 {
1320 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1321 list_delete (ls_upd);
1322 return;
1323 }
1324
1325 /* Packet overflows MTU size, send immediatly. */
1326 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1327 {
1328 if (oi->type == OSPF_IFTYPE_NBMA)
1329 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1330 else
1331 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1332
1333 /* Only remove list contents. Keep ls_upd. */
1334 list_delete_all_node (ls_upd);
1335
1336 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1337 }
1338
1339 /* Append LSA to update list. */
1340 listnode_add (ls_upd, find);
1341 length += ntohs (find->data->length);
1342
1343 size -= OSPF_LSA_KEY_SIZE;
1344 }
1345
1346 /* Send rest of Link State Update. */
1347 if (listcount (ls_upd) > 0)
1348 {
1349 if (oi->type == OSPF_IFTYPE_NBMA)
1350 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1351 else
1352 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1353
1354 list_delete (ls_upd);
1355 }
1356 else
1357 list_free (ls_upd);
1358}
1359
1360/* Get the list of LSAs from Link State Update packet.
1361 And process some validation -- RFC2328 Section 13. (1)-(2). */
1362static list
1363ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1364 struct ospf_interface *oi, size_t size)
1365{
1366 u_int16_t count, sum;
1367 u_int32_t length;
1368 struct lsa_header *lsah;
1369 struct ospf_lsa *lsa;
1370 list lsas;
1371
1372 lsas = list_new ();
1373
1374 count = stream_getl (s);
1375 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1376
1377 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1378 size -= length, stream_forward (s, length), count--)
1379 {
1380 lsah = (struct lsa_header *) STREAM_PNT (s);
1381 length = ntohs (lsah->length);
1382
1383 if (length > size)
1384 {
1385 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1386 break;
1387 }
1388
1389 /* Validate the LSA's LS checksum. */
1390 sum = lsah->checksum;
1391 if (sum != ospf_lsa_checksum (lsah))
1392 {
1393 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1394 sum, lsah->checksum);
1395 continue;
1396 }
1397
1398 /* Examine the LSA's LS type. */
1399 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1400 {
1401 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1402 continue;
1403 }
1404
1405 /*
1406 * What if the received LSA's age is greater than MaxAge?
1407 * Treat it as a MaxAge case -- endo.
1408 */
1409 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1410 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1411
1412#ifdef HAVE_OPAQUE_LSA
1413 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1414 {
1415#ifdef STRICT_OBIT_USAGE_CHECK
1416 if ((IS_OPAQUE_LSA(lsah->type) &&
1417 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1418 || (! IS_OPAQUE_LSA(lsah->type) &&
1419 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1420 {
1421 /*
1422 * This neighbor must know the exact usage of O-bit;
1423 * the bit will be set in Type-9,10,11 LSAs only.
1424 */
1425 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1426 continue;
1427 }
1428#endif /* STRICT_OBIT_USAGE_CHECK */
1429
1430 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1431 if (lsah->type == OSPF_OPAQUE_AS_LSA
1432 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1433 {
1434 if (IS_DEBUG_OSPF_EVENT)
1435 zlog_info ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1436 continue;
1437 }
1438 }
1439 else if (IS_OPAQUE_LSA(lsah->type))
1440 {
1441 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1442 continue;
1443 }
1444#endif /* HAVE_OPAQUE_LSA */
1445
1446 /* Create OSPF LSA instance. */
1447 lsa = ospf_lsa_new ();
1448
1449 /* We may wish to put some error checking if type NSSA comes in
1450 and area not in NSSA mode */
1451 switch (lsah->type)
1452 {
1453 case OSPF_AS_EXTERNAL_LSA:
1454#ifdef HAVE_OPAQUE_LSA
1455 case OSPF_OPAQUE_AS_LSA:
1456 lsa->area = NULL;
1457 break;
1458 case OSPF_OPAQUE_LINK_LSA:
1459 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1460 /* Fallthrough */
1461#endif /* HAVE_OPAQUE_LSA */
1462 default:
1463 lsa->area = oi->area;
1464 break;
1465 }
1466
1467 lsa->data = ospf_lsa_data_new (length);
1468 memcpy (lsa->data, lsah, length);
1469
1470 if (IS_DEBUG_OSPF_EVENT)
1471 zlog_info("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1472 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1473 listnode_add (lsas, lsa);
1474 }
1475
1476 return lsas;
1477}
1478
1479/* Cleanup Update list. */
1480void
1481ospf_upd_list_clean (list lsas)
1482{
1483 listnode node;
1484 struct ospf_lsa *lsa;
1485
1486 for (node = listhead (lsas); node; nextnode (node))
1487 if ((lsa = getdata (node)) != NULL)
1488 ospf_lsa_discard (lsa);
1489
1490 list_delete (lsas);
1491}
1492
1493/* OSPF Link State Update message read -- RFC2328 Section 13. */
1494void
1495ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1496 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1497{
1498 struct ospf_neighbor *nbr;
1499 list lsas;
1500#ifdef HAVE_OPAQUE_LSA
1501 list mylsa_acks, mylsa_upds;
1502#endif /* HAVE_OPAQUE_LSA */
1503 listnode node, next;
1504 struct ospf_lsa *lsa = NULL;
1505 /* unsigned long ls_req_found = 0; */
1506
1507 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1508
1509 /* Increment statistics. */
1510 oi->ls_upd_in++;
1511
1512 /* Check neighbor. */
1513 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1514 if (nbr == NULL)
1515 {
1516 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1517 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1518 return;
1519 }
1520
1521 /* Check neighbor state. */
1522 if (nbr->state < NSM_Exchange)
1523 {
1524 zlog_warn ("Link State Update: Neighbor[%s] state is less than Exchange",
1525 inet_ntoa (ospfh->router_id));
1526 return;
1527 }
1528
1529 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1530 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1531 * of section 13.
1532 */
1533 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1534
1535#ifdef HAVE_OPAQUE_LSA
1536 /*
1537 * Prepare two kinds of lists to clean up unwanted self-originated
1538 * Opaque-LSAs from the routing domain as soon as possible.
1539 */
1540 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1541 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1542
1543 /*
1544 * If self-originated Opaque-LSAs that have flooded before restart
1545 * are contained in the received LSUpd message, corresponding LSReq
1546 * messages to be sent may have to be modified.
1547 * To eliminate possible race conditions such that flushing and normal
1548 * updating for the same LSA would take place alternately, this trick
1549 * must be done before entering to the loop below.
1550 */
1551 ospf_opaque_adjust_lsreq (nbr, lsas);
1552#endif /* HAVE_OPAQUE_LSA */
1553
1554#define DISCARD_LSA(L,N) {\
1555 if (IS_DEBUG_OSPF_EVENT) \
1556 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1557 ospf_lsa_discard (L); \
1558 continue; }
1559
1560 /* Process each LSA received in the one packet. */
1561 for (node = listhead (lsas); node; node = next)
1562 {
1563 struct ospf_lsa *ls_ret, *current;
1564 int ret = 1;
1565
1566 next = node->next;
1567
1568 lsa = getdata (node);
1569
1570#ifdef HAVE_NSSA
1571 if (IS_DEBUG_OSPF_NSSA)
1572 {
1573 char buf1[INET_ADDRSTRLEN];
1574 char buf2[INET_ADDRSTRLEN];
1575 char buf3[INET_ADDRSTRLEN];
1576
1577 zlog_info("LSA Type-%d from %s, ID: %s, ADV: %s",
1578 lsa->data->type,
1579 inet_ntop (AF_INET, &ospfh->router_id,
1580 buf1, INET_ADDRSTRLEN),
1581 inet_ntop (AF_INET, &lsa->data->id,
1582 buf2, INET_ADDRSTRLEN),
1583 inet_ntop (AF_INET, &lsa->data->adv_router,
1584 buf3, INET_ADDRSTRLEN));
1585 }
1586#endif /* HAVE_NSSA */
1587
1588 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1589
1590 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1591
1592 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1593
1594 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1595
1596 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1597
1598 /* Do take in Type-7's if we are an NSSA */
1599
1600 /* If we are also an ABR, later translate them to a Type-5 packet */
1601
1602 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1603 translate them to a separate Type-5 packet. */
1604
1605 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1606 /* Reject from STUB or NSSA */
1607 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1608 {
1609 DISCARD_LSA (lsa, 1);
1610#ifdef HAVE_NSSA
1611 if (IS_DEBUG_OSPF_NSSA)
1612 zlog_info("Incoming External LSA Discarded: We are NSSA/STUB Area");
1613#endif /* HAVE_NSSA */
1614 }
1615
1616#ifdef HAVE_NSSA
1617 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1618 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1619 {
1620 DISCARD_LSA (lsa,2);
1621 if (IS_DEBUG_OSPF_NSSA)
1622 zlog_info("Incoming NSSA LSA Discarded: Not NSSA Area");
1623 }
1624#endif /* HAVE_NSSA */
1625
1626 /* Find the LSA in the current database. */
1627
1628 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1629
1630 /* If the LSA's LS age is equal to MaxAge, and there is currently
1631 no instance of the LSA in the router's link state database,
1632 and none of router's neighbors are in states Exchange or Loading,
1633 then take the following actions. */
1634
1635 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001636 (ospf_nbr_count (oi, NSM_Exchange) +
1637 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001638 {
1639 /* Response Link State Acknowledgment. */
1640 ospf_ls_ack_send (nbr, lsa);
1641
1642 /* Discard LSA. */
1643 zlog_warn ("Link State Update: LS age is equal to MaxAge.");
1644 DISCARD_LSA (lsa, 3);
1645 }
1646
1647#ifdef HAVE_OPAQUE_LSA
1648 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001649 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001650 {
1651 /*
1652 * Even if initial flushing seems to be completed, there might
1653 * be a case that self-originated LSA with MaxAge still remain
1654 * in the routing domain.
1655 * Just send an LSAck message to cease retransmission.
1656 */
1657 if (IS_LSA_MAXAGE (lsa))
1658 {
1659 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1660 ospf_ls_ack_send (nbr, lsa);
1661 ospf_lsa_discard (lsa);
1662
1663 if (current != NULL && ! IS_LSA_MAXAGE (current))
1664 ospf_opaque_lsa_refresh_schedule (current);
1665 continue;
1666 }
1667
1668 /*
1669 * If an instance of self-originated Opaque-LSA is not found
1670 * in the LSDB, there are some possible cases here.
1671 *
1672 * 1) This node lost opaque-capability after restart.
1673 * 2) Else, a part of opaque-type is no more supported.
1674 * 3) Else, a part of opaque-id is no more supported.
1675 *
1676 * Anyway, it is still this node's responsibility to flush it.
1677 * Otherwise, the LSA instance remains in the routing domain
1678 * until its age reaches to MaxAge.
1679 */
1680 if (current == NULL)
1681 {
1682 if (IS_DEBUG_OSPF_EVENT)
1683 zlog_info ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
1684
1685 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1686 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1687 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1688 continue;
1689 }
1690 }
1691#endif /* HAVE_OPAQUE_LSA */
1692
1693 /* (5) Find the instance of this LSA that is currently contained
1694 in the router's link state database. If there is no
1695 database copy, or the received LSA is more recent than
1696 the database copy the following steps must be performed. */
1697
1698 if (current == NULL ||
1699 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1700 {
1701 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001702 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001703 DISCARD_LSA (lsa, 4);
1704 continue;
1705 }
1706
1707 /* (6) Else, If there is an instance of the LSA on the sending
1708 neighbor's Link state request list, an error has occurred in
1709 the Database Exchange process. In this case, restart the
1710 Database Exchange process by generating the neighbor event
1711 BadLSReq for the sending neighbor and stop processing the
1712 Link State Update packet. */
1713
1714 if (ospf_ls_request_lookup (nbr, lsa))
1715 {
1716 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1717 zlog_warn ("LSA instance exists on Link state request list");
1718
1719 /* Clean list of LSAs. */
1720 ospf_upd_list_clean (lsas);
1721 /* this lsa is not on lsas list already. */
1722 ospf_lsa_discard (lsa);
1723#ifdef HAVE_OPAQUE_LSA
1724 list_delete (mylsa_acks);
1725 list_delete (mylsa_upds);
1726#endif /* HAVE_OPAQUE_LSA */
1727 return;
1728 }
1729
1730 /* If the received LSA is the same instance as the database copy
1731 (i.e., neither one is more recent) the following two steps
1732 should be performed: */
1733
1734 if (ret == 0)
1735 {
1736 /* If the LSA is listed in the Link state retransmission list
1737 for the receiving adjacency, the router itself is expecting
1738 an acknowledgment for this LSA. The router should treat the
1739 received LSA as an acknowledgment by removing the LSA from
1740 the Link state retransmission list. This is termed an
1741 "implied acknowledgment". */
1742
1743 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1744
1745 if (ls_ret != NULL)
1746 {
1747 ospf_ls_retransmit_delete (nbr, ls_ret);
1748
1749 /* Delayed acknowledgment sent if advertisement received
1750 from Designated Router, otherwise do nothing. */
1751 if (oi->state == ISM_Backup)
1752 if (NBR_IS_DR (nbr))
1753 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1754
1755 DISCARD_LSA (lsa, 5);
1756 }
1757 else
1758 /* Acknowledge the receipt of the LSA by sending a
1759 Link State Acknowledgment packet back out the receiving
1760 interface. */
1761 {
1762 ospf_ls_ack_send (nbr, lsa);
1763 DISCARD_LSA (lsa, 6);
1764 }
1765 }
1766
1767 /* The database copy is more recent. If the database copy
1768 has LS age equal to MaxAge and LS sequence number equal to
1769 MaxSequenceNumber, simply discard the received LSA without
1770 acknowledging it. (In this case, the LSA's LS sequence number is
1771 wrapping, and the MaxSequenceNumber LSA must be completely
1772 flushed before any new LSA instance can be introduced). */
1773
1774 else if (ret > 0) /* Database copy is more recent */
1775 {
1776 if (IS_LSA_MAXAGE (current) &&
1777 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1778 {
1779 DISCARD_LSA (lsa, 7);
1780 }
1781 /* Otherwise, as long as the database copy has not been sent in a
1782 Link State Update within the last MinLSArrival seconds, send the
1783 database copy back to the sending neighbor, encapsulated within
1784 a Link State Update Packet. The Link State Update Packet should
1785 be sent directly to the neighbor. In so doing, do not put the
1786 database copy of the LSA on the neighbor's link state
1787 retransmission list, and do not acknowledge the received (less
1788 recent) LSA instance. */
1789 else
1790 {
1791 struct timeval now;
1792
1793 gettimeofday (&now, NULL);
1794
1795 if (tv_cmp (tv_sub (now, current->tv_orig),
1796 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1797 /* Trap NSSA type later.*/
1798 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1799 DISCARD_LSA (lsa, 8);
1800 }
1801 }
1802 }
1803
1804#ifdef HAVE_OPAQUE_LSA
1805 /*
1806 * Now that previously originated Opaque-LSAs those which not yet
1807 * installed into LSDB are captured, take several steps to clear
1808 * them completely from the routing domain, before proceeding to
1809 * origination for the current target Opaque-LSAs.
1810 */
1811 while (listcount (mylsa_acks) > 0)
1812 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1813
1814 if (listcount (mylsa_upds) > 0)
1815 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1816
1817 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001818 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001819#endif /* HAVE_OPAQUE_LSA */
1820
1821 assert (listcount (lsas) == 0);
1822 list_delete (lsas);
1823}
1824
1825/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1826void
1827ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1828 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1829{
1830 struct ospf_neighbor *nbr;
1831#ifdef HAVE_OPAQUE_LSA
1832 list opaque_acks;
1833#endif /* HAVE_OPAQUE_LSA */
1834
1835 /* increment statistics. */
1836 oi->ls_ack_in++;
1837
1838 nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &iph->ip_src);
1839 if (nbr == NULL)
1840 {
1841 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1842 inet_ntoa (ospfh->router_id));
1843 return;
1844 }
1845
1846 if (nbr->state < NSM_Exchange)
1847 {
1848 zlog_warn ("Link State Acknowledgment: State is less than Exchange.");
1849 return;
1850 }
1851
1852#ifdef HAVE_OPAQUE_LSA
1853 opaque_acks = list_new ();
1854#endif /* HAVE_OPAQUE_LSA */
1855
1856 while (size >= OSPF_LSA_HEADER_SIZE)
1857 {
1858 struct ospf_lsa *lsa, *lsr;
1859
1860 lsa = ospf_lsa_new ();
1861 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1862
1863 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1864 size -= OSPF_LSA_HEADER_SIZE;
1865 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1866
1867 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1868 {
1869 lsa->data = NULL;
1870 ospf_lsa_discard (lsa);
1871 continue;
1872 }
1873
1874 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1875
1876 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1877 {
1878#ifdef HAVE_OPAQUE_LSA
1879 /* Keep this LSA entry for later reference. */
1880 if (IS_OPAQUE_LSA (lsr->data->type))
1881 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
1882#endif /* HAVE_OPAQUE_LSA */
1883
1884 ospf_ls_retransmit_delete (nbr, lsr);
1885 }
1886
1887 lsa->data = NULL;
1888 ospf_lsa_discard (lsa);
1889 }
1890
1891#ifdef HAVE_OPAQUE_LSA
1892 if (listcount (opaque_acks) > 0)
1893 ospf_opaque_ls_ack_received (nbr, opaque_acks);
1894
1895 list_delete (opaque_acks);
1896 return;
1897#endif /* HAVE_OPAQUE_LSA */
1898}
1899
1900struct stream *
1901ospf_recv_packet (int fd, struct interface **ifp)
1902{
1903 int ret;
1904 struct ip iph;
1905 u_int16_t ip_len;
1906 struct stream *ibuf;
1907 unsigned int ifindex = 0;
1908 struct iovec iov;
1909 struct cmsghdr *cmsg;
1910#if defined (IP_PKTINFO)
1911 struct in_pktinfo *pktinfo;
1912#elif defined (IP_RECVIF)
1913 struct sockaddr_dl *pktinfo;
1914#else
1915 char *pktinfo; /* dummy */
1916#endif
1917 char buff [sizeof (*cmsg) + sizeof (*pktinfo)];
1918 struct msghdr msgh = {NULL, 0, &iov, 1, buff,
1919 sizeof (*cmsg) + sizeof (*pktinfo), 0};
1920
1921 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
1922
1923 if (ret != sizeof (iph))
1924 {
1925 zlog_warn ("ospf_recv_packet packet smaller than ip header");
1926 return NULL;
1927 }
1928
1929#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
1930 ip_len = iph.ip_len;
1931#else
1932 ip_len = ntohs (iph.ip_len);
1933#endif
1934
1935#if !defined(GNU_LINUX)
1936 /*
1937 * Kernel network code touches incoming IP header parameters,
1938 * before protocol specific processing.
1939 *
1940 * 1) Convert byteorder to host representation.
1941 * --> ip_len, ip_id, ip_off
1942 *
1943 * 2) Adjust ip_len to strip IP header size!
1944 * --> If user process receives entire IP packet via RAW
1945 * socket, it must consider adding IP header size to
1946 * the "ip_len" field of "ip" structure.
1947 *
1948 * For more details, see <netinet/ip_input.c>.
1949 */
1950 ip_len = ip_len + (iph.ip_hl << 2);
1951#endif
1952
1953 ibuf = stream_new (ip_len);
1954 iov.iov_base = STREAM_DATA (ibuf);
1955 iov.iov_len = ip_len;
1956 ret = recvmsg (fd, &msgh, 0);
1957
1958 cmsg = CMSG_FIRSTHDR (&msgh);
1959
1960 if (cmsg != NULL && //cmsg->cmsg_len == sizeof (*pktinfo) &&
1961 cmsg->cmsg_level == IPPROTO_IP &&
1962#if defined (IP_PKTINFO)
1963 cmsg->cmsg_type == IP_PKTINFO
1964#elif defined (IP_RECVIF)
1965 cmsg->cmsg_type == IP_RECVIF
1966#else
1967 0
1968#endif
1969 )
1970 {
1971#if defined (IP_PKTINFO)
1972 pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
1973 ifindex = pktinfo->ipi_ifindex;
1974#elif defined (IP_RECVIF)
1975 pktinfo = (struct sockaddr_dl *)CMSG_DATA(cmsg);
1976 ifindex = pktinfo->sdl_index;
1977#else
1978 ifindex = 0;
1979#endif
1980 }
1981
1982 *ifp = if_lookup_by_index (ifindex);
1983
1984 if (ret != ip_len)
1985 {
1986 zlog_warn ("ospf_recv_packet short read. "
1987 "ip_len %d bytes read %d", ip_len, ret);
1988 stream_free (ibuf);
1989 return NULL;
1990 }
1991
1992 return ibuf;
1993}
1994
1995struct ospf_interface *
paul020709f2003-04-04 02:44:16 +00001996ospf_associate_packet_vl (struct ospf *ospf,
1997 struct interface *ifp, struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00001998 struct ip *iph, struct ospf_header *ospfh)
1999{
2000 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002001 struct ospf_vl_data *vl_data;
2002 struct ospf_area *vl_area;
paul68980082003-03-25 05:07:42 +00002003 listnode node;
paul718e3742002-12-13 20:15:29 +00002004
2005 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2006 !OSPF_IS_AREA_BACKBONE (ospfh))
2007 return oi;
2008
2009 if ((rcv_oi = oi) == NULL)
2010 {
paul020709f2003-04-04 02:44:16 +00002011 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, ifp,
paul68980082003-03-25 05:07:42 +00002012 iph->ip_dst)) == NULL)
paul718e3742002-12-13 20:15:29 +00002013 return NULL;
2014 }
2015
paul020709f2003-04-04 02:44:16 +00002016 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002017 {
2018 if ((vl_data = getdata (node)) == NULL)
2019 continue;
2020
paul020709f2003-04-04 02:44:16 +00002021 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002022 if (!vl_area)
2023 continue;
2024
2025 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2026 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2027 {
2028 if (IS_DEBUG_OSPF_EVENT)
2029 zlog_info ("associating packet with %s",
2030 IF_NAME (vl_data->vl_oi));
2031 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2032 {
2033 if (IS_DEBUG_OSPF_EVENT)
2034 zlog_info ("This VL is not up yet, sorry");
2035 return NULL;
2036 }
2037
2038 return vl_data->vl_oi;
2039 }
2040 }
2041
2042 if (IS_DEBUG_OSPF_EVENT)
2043 zlog_info ("couldn't find any VL to associate the packet with");
2044
2045 return oi;
2046}
2047
2048int
2049ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2050{
2051 /* Check match the Area ID of the receiving interface. */
2052 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2053 return 1;
2054
2055 return 0;
2056}
2057
2058/* Unbound socket will accept any Raw IP packets if proto is matched.
2059 To prevent it, compare src IP address and i/f address with masking
2060 i/f network mask. */
2061int
2062ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2063{
2064 struct in_addr mask, me, him;
2065
2066 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2067 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2068 return 1;
2069
2070 masklen2ip (oi->address->prefixlen, &mask);
2071
2072 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2073 him.s_addr = ip_src.s_addr & mask.s_addr;
2074
2075 if (IPV4_ADDR_SAME (&me, &him))
2076 return 1;
2077
2078 return 0;
2079}
2080
2081int
2082ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2083 struct ospf_header *ospfh)
2084{
2085 int ret = 0;
2086 struct crypt_key *ck;
2087
2088 switch (ntohs (ospfh->auth_type))
2089 {
2090 case OSPF_AUTH_NULL:
2091 ret = 1;
2092 break;
2093 case OSPF_AUTH_SIMPLE:
2094 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2095 ret = 1;
2096 else
2097 ret = 0;
2098 break;
2099 case OSPF_AUTH_CRYPTOGRAPHIC:
2100 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2101 {
2102 ret = 0;
2103 break;
2104 }
2105
2106 /* This is very basic, the digest processing is elsewhere */
2107 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2108 ospfh->u.crypt.key_id == ck->key_id &&
2109 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2110 ret = 1;
2111 else
2112 ret = 0;
2113 break;
2114 default:
2115 ret = 0;
2116 break;
2117 }
2118
2119 return ret;
2120}
2121
2122int
2123ospf_check_sum (struct ospf_header *ospfh)
2124{
2125 u_int32_t ret;
2126 u_int16_t sum;
2127 int in_cksum (void *ptr, int nbytes);
2128
2129 /* clear auth_data for checksum. */
2130 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2131
2132 /* keep checksum and clear. */
2133 sum = ospfh->checksum;
2134 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2135
2136 /* calculate checksum. */
2137 ret = in_cksum (ospfh, ntohs (ospfh->length));
2138
2139 if (ret != sum)
2140 {
2141 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2142 ret, sum);
2143 return 0;
2144 }
2145
2146 return 1;
2147}
2148
2149/* OSPF Header verification. */
2150int
2151ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2152 struct ip *iph, struct ospf_header *ospfh)
2153{
2154 /* check version. */
2155 if (ospfh->version != OSPF_VERSION)
2156 {
2157 zlog_warn ("interface %s: ospf_read version number mismatch.",
2158 IF_NAME (oi));
2159 return -1;
2160 }
2161
2162 /* Check Area ID. */
2163 if (!ospf_check_area_id (oi, ospfh))
2164 {
2165 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2166 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2167 return -1;
2168 }
2169
2170 /* Check network mask, Silently discarded. */
2171 if (! ospf_check_network_mask (oi, iph->ip_src))
2172 {
2173 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2174 IF_NAME (oi), inet_ntoa (iph->ip_src));
2175 return -1;
2176 }
2177
2178 /* Check authentication. */
2179 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2180 {
2181 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2182 IF_NAME (oi));
2183 return -1;
2184 }
2185
2186 if (! ospf_check_auth (oi, ibuf, ospfh))
2187 {
2188 zlog_warn ("interface %s: ospf_read authentication failed.",
2189 IF_NAME (oi));
2190 return -1;
2191 }
2192
2193 /* if check sum is invalid, packet is discarded. */
2194 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2195 {
2196 if (! ospf_check_sum (ospfh))
2197 {
2198 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2199 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2200 return -1;
2201 }
2202 }
2203 else
2204 {
2205 if (ospfh->checksum != 0)
2206 return -1;
2207 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2208 {
2209 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2210 IF_NAME (oi));
2211 return -1;
2212 }
2213 }
2214
2215 return 0;
2216}
2217
2218/* Starting point of packet process function. */
2219int
2220ospf_read (struct thread *thread)
2221{
2222 int ret;
2223 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002224 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002225 struct ospf_interface *oi;
2226 struct ip *iph;
2227 struct ospf_header *ospfh;
2228 u_int16_t length;
2229 struct interface *ifp;
2230
2231 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002232 ospf = THREAD_ARG (thread);
2233 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002234
2235 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002236 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002237 if (ibuf == NULL)
2238 return -1;
2239
2240 iph = (struct ip *) STREAM_DATA (ibuf);
2241
2242 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002243 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002244
2245 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002246 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul7d95c612003-01-27 12:00:55 +00002247 ospf_ip_header_dump (ibuf);
2248
paul718e3742002-12-13 20:15:29 +00002249 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002250 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002251 {
2252 stream_free (ibuf);
2253 return 0;
2254 }
2255
2256 /* Adjust size to message length. */
2257 stream_forward (ibuf, iph->ip_hl * 4);
2258
2259 /* Get ospf packet header. */
2260 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2261
2262 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002263 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
paul718e3742002-12-13 20:15:29 +00002264 if (ifp && oi && oi->ifp != ifp)
2265 {
2266 zlog_warn ("Packet from [%s] received on wrong link %s",
2267 inet_ntoa (iph->ip_src), ifp->name);
2268 stream_free (ibuf);
2269 return 0;
2270 }
2271
paul020709f2003-04-04 02:44:16 +00002272 if ((oi = ospf_associate_packet_vl (ospf, ifp, oi, iph, ospfh)) == NULL)
paul718e3742002-12-13 20:15:29 +00002273 {
2274 stream_free (ibuf);
2275 return 0;
2276 }
2277
2278 /*
2279 * If the received packet is destined for AllDRouters, the packet
2280 * should be accepted only if the received ospf interface state is
2281 * either DR or Backup -- endo.
2282 */
2283 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2284 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2285 {
2286 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2287 inet_ntoa (iph->ip_src), IF_NAME (oi),
2288 LOOKUP (ospf_ism_state_msg, oi->state));
2289 stream_free (ibuf);
2290 return 0;
2291 }
2292
2293 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002294 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2295 {
paul718e3742002-12-13 20:15:29 +00002296 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002297 {
2298 zlog_info ("-----------------------------------------------------");
2299 ospf_packet_dump (ibuf);
2300 }
paul718e3742002-12-13 20:15:29 +00002301
2302 zlog_info ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002303 ospf_packet_type_str[ospfh->type],
2304 inet_ntoa (ospfh->router_id), IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +00002305 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2306 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2307
2308 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2309 zlog_info ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002310 }
paul718e3742002-12-13 20:15:29 +00002311
2312 /* Some header verification. */
2313 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2314 if (ret < 0)
2315 {
2316 stream_free (ibuf);
2317 return ret;
2318 }
2319
2320 stream_forward (ibuf, OSPF_HEADER_SIZE);
2321
2322 /* Adjust size to message length. */
2323 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2324
2325 /* Read rest of the packet and call each sort of packet routine. */
2326 switch (ospfh->type)
2327 {
2328 case OSPF_MSG_HELLO:
2329 ospf_hello (iph, ospfh, ibuf, oi, length);
2330 break;
2331 case OSPF_MSG_DB_DESC:
2332 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2333 break;
2334 case OSPF_MSG_LS_REQ:
2335 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2336 break;
2337 case OSPF_MSG_LS_UPD:
2338 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2339 break;
2340 case OSPF_MSG_LS_ACK:
2341 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2342 break;
2343 default:
2344 zlog (NULL, LOG_WARNING,
2345 "interface %s: OSPF packet header type %d is illegal",
2346 IF_NAME (oi), ospfh->type);
2347 break;
2348 }
2349
2350 stream_free (ibuf);
2351 return 0;
2352}
2353
2354/* Make OSPF header. */
2355void
2356ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2357{
2358 struct ospf_header *ospfh;
2359
2360 ospfh = (struct ospf_header *) STREAM_DATA (s);
2361
2362 ospfh->version = (u_char) OSPF_VERSION;
2363 ospfh->type = (u_char) type;
2364
paul68980082003-03-25 05:07:42 +00002365 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002366
2367 ospfh->checksum = 0;
2368 ospfh->area_id = oi->area->area_id;
2369 ospfh->auth_type = htons (ospf_auth_type (oi));
2370
2371 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2372
2373 ospf_output_forward (s, OSPF_HEADER_SIZE);
2374}
2375
2376/* Make Authentication Data. */
2377int
2378ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2379{
2380 struct crypt_key *ck;
2381
2382 switch (ospf_auth_type (oi))
2383 {
2384 case OSPF_AUTH_NULL:
2385 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2386 break;
2387 case OSPF_AUTH_SIMPLE:
2388 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2389 OSPF_AUTH_SIMPLE_SIZE);
2390 break;
2391 case OSPF_AUTH_CRYPTOGRAPHIC:
2392 /* If key is not set, then set 0. */
2393 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2394 {
2395 ospfh->u.crypt.zero = 0;
2396 ospfh->u.crypt.key_id = 0;
2397 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2398 }
2399 else
2400 {
2401 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2402 ospfh->u.crypt.zero = 0;
2403 ospfh->u.crypt.key_id = ck->key_id;
2404 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2405 }
2406 /* note: the seq is done in ospf_make_md5_digest() */
2407 break;
2408 default:
2409 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2410 break;
2411 }
2412
2413 return 0;
2414}
2415
2416/* Fill rest of OSPF header. */
2417void
2418ospf_fill_header (struct ospf_interface *oi,
2419 struct stream *s, u_int16_t length)
2420{
2421 struct ospf_header *ospfh;
2422
2423 ospfh = (struct ospf_header *) STREAM_DATA (s);
2424
2425 /* Fill length. */
2426 ospfh->length = htons (length);
2427
2428 /* Calculate checksum. */
2429 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2430 ospfh->checksum = in_cksum (ospfh, length);
2431 else
2432 ospfh->checksum = 0;
2433
2434 /* Add Authentication Data. */
2435 ospf_make_auth (oi, ospfh);
2436}
2437
2438int
2439ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2440{
2441 struct ospf_neighbor *nbr;
2442 struct route_node *rn;
2443 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2444 struct in_addr mask;
2445 unsigned long p;
2446 int flag = 0;
2447
2448 /* Set netmask of interface. */
2449 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2450 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2451 masklen2ip (oi->address->prefixlen, &mask);
2452 else
2453 memset ((char *) &mask, 0, sizeof (struct in_addr));
2454 stream_put_ipv4 (s, mask.s_addr);
2455
2456 /* Set Hello Interval. */
2457 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2458
2459 if (IS_DEBUG_OSPF_EVENT)
2460 zlog_info ("make_hello: options: %x, int: %s",
2461 OPTIONS(oi), IF_NAME (oi));
2462
2463 /* Set Options. */
2464 stream_putc (s, OPTIONS (oi));
2465
2466 /* Set Router Priority. */
2467 stream_putc (s, PRIORITY (oi));
2468
2469 /* Set Router Dead Interval. */
2470 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2471
2472 /* Set Designated Router. */
2473 stream_put_ipv4 (s, DR (oi).s_addr);
2474
2475 p = s->putp;
2476
2477 /* Set Backup Designated Router. */
2478 stream_put_ipv4 (s, BDR (oi).s_addr);
2479
2480 /* Add neighbor seen. */
2481 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002482 if ((nbr = rn->info))
2483 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2484 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2485 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2486 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002487 {
2488 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002489 if (nbr->d_router.s_addr != 0
2490 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2491 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2492 flag = 1;
paul718e3742002-12-13 20:15:29 +00002493
2494 stream_put_ipv4 (s, nbr->router_id.s_addr);
2495 length += 4;
2496 }
2497
2498 /* Let neighbor generate BackupSeen. */
2499 if (flag == 1)
2500 {
2501 stream_set_putp (s, p);
2502 stream_put_ipv4 (s, 0);
2503 }
2504
2505 return length;
2506}
2507
2508int
2509ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2510 struct stream *s)
2511{
2512 struct ospf_lsa *lsa;
2513 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2514 u_char options;
2515 unsigned long pp;
2516 int i;
2517 struct ospf_lsdb *lsdb;
2518
2519 /* Set Interface MTU. */
2520 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2521 stream_putw (s, 0);
2522 else
2523 stream_putw (s, oi->ifp->mtu);
2524
2525 /* Set Options. */
2526 options = OPTIONS (oi);
2527#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002528 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002529 {
2530 if (IS_SET_DD_I (nbr->dd_flags)
2531 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2532 /*
2533 * Set O-bit in the outgoing DD packet for capablity negotiation,
2534 * if one of following case is applicable.
2535 *
2536 * 1) WaitTimer expiration event triggered the neighbor state to
2537 * change to Exstart, but no (valid) DD packet has received
2538 * from the neighbor yet.
2539 *
2540 * 2) At least one DD packet with O-bit on has received from the
2541 * neighbor.
2542 */
2543 SET_FLAG (options, OSPF_OPTION_O);
2544 }
2545#endif /* HAVE_OPAQUE_LSA */
2546 stream_putc (s, options);
2547
2548 /* Keep pointer to flags. */
2549 pp = stream_get_putp (s);
2550 stream_putc (s, nbr->dd_flags);
2551
2552 /* Set DD Sequence Number. */
2553 stream_putl (s, nbr->dd_seqnum);
2554
2555 if (ospf_db_summary_isempty (nbr))
2556 {
2557 if (nbr->state >= NSM_Exchange)
2558 {
2559 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2560 /* Set DD flags again */
2561 stream_set_putp (s, pp);
2562 stream_putc (s, nbr->dd_flags);
2563 }
2564 return length;
2565 }
2566
2567 /* Describe LSA Header from Database Summary List. */
2568 lsdb = &nbr->db_sum;
2569
2570 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2571 {
2572 struct route_table *table = lsdb->type[i].db;
2573 struct route_node *rn;
2574
2575 for (rn = route_top (table); rn; rn = route_next (rn))
2576 if ((lsa = rn->info) != NULL)
2577 {
2578#ifdef HAVE_OPAQUE_LSA
2579 if (IS_OPAQUE_LSA (lsa->data->type)
2580 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2581 {
2582 /* Suppress advertising opaque-informations. */
2583 /* Remove LSA from DB summary list. */
2584 ospf_lsdb_delete (lsdb, lsa);
2585 continue;
2586 }
2587#endif /* HAVE_OPAQUE_LSA */
2588
2589 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2590 {
2591 struct lsa_header *lsah;
2592 u_int16_t ls_age;
2593
2594 /* DD packet overflows interface MTU. */
2595 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2596 break;
2597
2598 /* Keep pointer to LS age. */
2599 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2600 stream_get_putp (s));
2601
2602 /* Proceed stream pointer. */
2603 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2604 length += OSPF_LSA_HEADER_SIZE;
2605
2606 /* Set LS age. */
2607 ls_age = LS_AGE (lsa);
2608 lsah->ls_age = htons (ls_age);
2609
2610 }
2611
2612 /* Remove LSA from DB summary list. */
2613 ospf_lsdb_delete (lsdb, lsa);
2614 }
2615 }
2616
2617 return length;
2618}
2619
2620int
2621ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2622 unsigned long delta, struct ospf_neighbor *nbr,
2623 struct ospf_lsa *lsa)
2624{
2625 struct ospf_interface *oi;
2626
2627 oi = nbr->oi;
2628
2629 /* LS Request packet overflows interface MTU. */
2630 if (*length + delta > OSPF_PACKET_MAX(oi))
2631 return 0;
2632
2633 stream_putl (s, lsa->data->type);
2634 stream_put_ipv4 (s, lsa->data->id.s_addr);
2635 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2636
2637 ospf_lsa_unlock (nbr->ls_req_last);
2638 nbr->ls_req_last = ospf_lsa_lock (lsa);
2639
2640 *length += 12;
2641 return 1;
2642}
2643
2644int
2645ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2646{
2647 struct ospf_lsa *lsa;
2648 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2649 unsigned long delta = stream_get_putp(s)+12;
2650 struct route_table *table;
2651 struct route_node *rn;
2652 int i;
2653 struct ospf_lsdb *lsdb;
2654
2655 lsdb = &nbr->ls_req;
2656
2657 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2658 {
2659 table = lsdb->type[i].db;
2660 for (rn = route_top (table); rn; rn = route_next (rn))
2661 if ((lsa = (rn->info)) != NULL)
2662 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2663 {
2664 route_unlock_node (rn);
2665 break;
2666 }
2667 }
2668 return length;
2669}
2670
2671int
2672ls_age_increment (struct ospf_lsa *lsa, int delay)
2673{
2674 int age;
2675
2676 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2677
2678 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2679}
2680
2681int
2682ospf_make_ls_upd (struct ospf_interface *oi, list update, struct stream *s)
2683{
2684 struct ospf_lsa *lsa;
2685 listnode node;
2686 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2687 unsigned long delta = stream_get_putp (s);
2688 unsigned long pp;
2689 int count = 0;
2690
2691 if (IS_DEBUG_OSPF_EVENT)
2692 zlog_info("ospf_make_ls_upd: Start");
2693
2694 pp = stream_get_putp (s);
2695 ospf_output_forward (s, 4);
2696
2697 while ((node = listhead (update)) != NULL)
2698 {
2699 struct lsa_header *lsah;
2700 u_int16_t ls_age;
2701
2702 if (IS_DEBUG_OSPF_EVENT)
2703 zlog_info("ospf_make_ls_upd: List Iteration");
2704
2705 lsa = getdata (node);
2706 assert (lsa);
2707 assert (lsa->data);
2708
2709 /* Check packet size. */
2710 if (length + delta + ntohs (lsa->data->length) > OSPF_PACKET_MAX (oi))
paul8cb90ff2003-06-26 03:00:40 +00002711 {
2712 /* clean up */
2713 list_delete_node (update, node);
2714 ospf_lsa_unlock (lsa);
2715 break;
2716 }
paul718e3742002-12-13 20:15:29 +00002717
2718 /* Keep pointer to LS age. */
2719 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2720
2721 /* Put LSA to Link State Request. */
2722 stream_put (s, lsa->data, ntohs (lsa->data->length));
2723
2724 /* Set LS age. */
2725 /* each hop must increment an lsa_age by transmit_delay
2726 of OSPF interface */
2727 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2728 lsah->ls_age = htons (ls_age);
2729
2730 length += ntohs (lsa->data->length);
2731 count++;
2732
2733 list_delete_node (update, node);
2734 ospf_lsa_unlock (lsa);
2735 }
2736
2737 /* Now set #LSAs. */
2738 stream_set_putp (s, pp);
2739 stream_putl (s, count);
2740
2741 stream_set_putp (s, s->endp);
2742
2743 if (IS_DEBUG_OSPF_EVENT)
2744 zlog_info("ospf_make_ls_upd: Stop");
2745 return length;
2746}
2747
2748int
2749ospf_make_ls_ack (struct ospf_interface *oi, list ack, struct stream *s)
2750{
2751 list rm_list;
2752 listnode node;
2753 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2754 unsigned long delta = stream_get_putp(s) + 24;
2755 struct ospf_lsa *lsa;
2756
2757 rm_list = list_new ();
2758
2759 for (node = listhead (ack); node; nextnode (node))
2760 {
2761 lsa = getdata (node);
2762 assert (lsa);
2763
2764 if (length + delta > OSPF_PACKET_MAX (oi))
2765 break;
2766
2767 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2768 length += OSPF_LSA_HEADER_SIZE;
2769
2770 listnode_add (rm_list, lsa);
2771 }
2772
2773 /* Remove LSA from LS-Ack list. */
2774 for (node = listhead (rm_list); node; nextnode (node))
2775 {
2776 lsa = (struct ospf_lsa *) getdata (node);
2777
2778 listnode_delete (ack, lsa);
2779 ospf_lsa_unlock (lsa);
2780 }
2781
2782 list_delete (rm_list);
2783
2784 return length;
2785}
2786
2787void
2788ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2789{
2790 struct ospf_packet *op;
2791 u_int16_t length = OSPF_HEADER_SIZE;
2792
2793 op = ospf_packet_new (oi->ifp->mtu);
2794
2795 /* Prepare OSPF common header. */
2796 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2797
2798 /* Prepare OSPF Hello body. */
2799 length += ospf_make_hello (oi, op->s);
2800
2801 /* Fill OSPF header. */
2802 ospf_fill_header (oi, op->s, length);
2803
2804 /* Set packet length. */
2805 op->length = length;
2806
2807 op->dst.s_addr = addr->s_addr;
2808
2809 /* Add packet to the interface output queue. */
2810 ospf_packet_add (oi, op);
2811
2812 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002813 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002814}
2815
2816void
2817ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2818{
2819 struct ospf_interface *oi;
2820
2821 oi = nbr_nbma->oi;
2822 assert(oi);
2823
2824 /* If this is passive interface, do not send OSPF Hello. */
2825 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2826 return;
2827
2828 if (oi->type != OSPF_IFTYPE_NBMA)
2829 return;
2830
2831 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2832 return;
2833
2834 if (PRIORITY(oi) == 0)
2835 return;
2836
2837 if (nbr_nbma->priority == 0
2838 && oi->state != ISM_DR && oi->state != ISM_Backup)
2839 return;
2840
2841 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2842}
2843
2844int
2845ospf_poll_timer (struct thread *thread)
2846{
2847 struct ospf_nbr_nbma *nbr_nbma;
2848
2849 nbr_nbma = THREAD_ARG (thread);
2850 nbr_nbma->t_poll = NULL;
2851
2852 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2853 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2854 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2855
2856 ospf_poll_send (nbr_nbma);
2857
2858 if (nbr_nbma->v_poll > 0)
2859 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2860 nbr_nbma->v_poll);
2861
2862 return 0;
2863}
2864
2865
2866int
2867ospf_hello_reply_timer (struct thread *thread)
2868{
2869 struct ospf_neighbor *nbr;
2870
2871 nbr = THREAD_ARG (thread);
2872 nbr->t_hello_reply = NULL;
2873
2874 assert (nbr->oi);
2875
2876 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2877 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2878 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2879
2880 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2881
2882 return 0;
2883}
2884
2885/* Send OSPF Hello. */
2886void
2887ospf_hello_send (struct ospf_interface *oi)
2888{
2889 struct ospf_packet *op;
2890 u_int16_t length = OSPF_HEADER_SIZE;
2891
2892 /* If this is passive interface, do not send OSPF Hello. */
2893 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2894 return;
2895
2896 op = ospf_packet_new (oi->ifp->mtu);
2897
2898 /* Prepare OSPF common header. */
2899 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2900
2901 /* Prepare OSPF Hello body. */
2902 length += ospf_make_hello (oi, op->s);
2903
2904 /* Fill OSPF header. */
2905 ospf_fill_header (oi, op->s, length);
2906
2907 /* Set packet length. */
2908 op->length = length;
2909
2910 if (oi->type == OSPF_IFTYPE_NBMA)
2911 {
2912 struct ospf_neighbor *nbr;
2913 struct route_node *rn;
2914
2915 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2916 if ((nbr = rn->info))
2917 if (nbr != oi->nbr_self)
2918 if (nbr->state != NSM_Down)
2919 {
2920 /* RFC 2328 Section 9.5.1
2921 If the router is not eligible to become Designated Router,
2922 it must periodically send Hello Packets to both the
2923 Designated Router and the Backup Designated Router (if they
2924 exist). */
2925 if (PRIORITY(oi) == 0 &&
2926 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
2927 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
2928 continue;
2929
2930 /* If the router is eligible to become Designated Router, it
2931 must periodically send Hello Packets to all neighbors that
2932 are also eligible. In addition, if the router is itself the
2933 Designated Router or Backup Designated Router, it must also
2934 send periodic Hello Packets to all other neighbors. */
2935
2936 if (nbr->priority == 0 && oi->state == ISM_DROther)
2937 continue;
2938 /* if oi->state == Waiting, send hello to all neighbors */
2939 {
2940 struct ospf_packet *op_dup;
2941
2942 op_dup = ospf_packet_dup(op);
2943 op_dup->dst = nbr->address.u.prefix4;
2944
2945 /* Add packet to the interface output queue. */
2946 ospf_packet_add (oi, op_dup);
2947
paul020709f2003-04-04 02:44:16 +00002948 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002949 }
2950
2951 }
2952 ospf_packet_free (op);
2953 }
2954 else
2955 {
2956 /* Decide destination address. */
2957 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2958 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
2959 else
2960 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
2961
2962 /* Add packet to the interface output queue. */
2963 ospf_packet_add (oi, op);
2964
2965 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002966 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002967 }
2968}
2969
2970/* Send OSPF Database Description. */
2971void
2972ospf_db_desc_send (struct ospf_neighbor *nbr)
2973{
2974 struct ospf_interface *oi;
2975 struct ospf_packet *op;
2976 u_int16_t length = OSPF_HEADER_SIZE;
2977
2978 oi = nbr->oi;
2979 op = ospf_packet_new (oi->ifp->mtu);
2980
2981 /* Prepare OSPF common header. */
2982 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
2983
2984 /* Prepare OSPF Database Description body. */
2985 length += ospf_make_db_desc (oi, nbr, op->s);
2986
2987 /* Fill OSPF header. */
2988 ospf_fill_header (oi, op->s, length);
2989
2990 /* Set packet length. */
2991 op->length = length;
2992
2993 /* Decide destination address. */
2994 op->dst = nbr->address.u.prefix4;
2995
2996 /* Add packet to the interface output queue. */
2997 ospf_packet_add (oi, op);
2998
2999 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003000 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003001
3002 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3003 if (nbr->last_send)
3004 ospf_packet_free (nbr->last_send);
3005 nbr->last_send = ospf_packet_dup (op);
3006 gettimeofday (&nbr->last_send_ts, NULL);
3007}
3008
3009/* Re-send Database Description. */
3010void
3011ospf_db_desc_resend (struct ospf_neighbor *nbr)
3012{
3013 struct ospf_interface *oi;
3014
3015 oi = nbr->oi;
3016
3017 /* Add packet to the interface output queue. */
3018 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3019
3020 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003021 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003022}
3023
3024/* Send Link State Request. */
3025void
3026ospf_ls_req_send (struct ospf_neighbor *nbr)
3027{
3028 struct ospf_interface *oi;
3029 struct ospf_packet *op;
3030 u_int16_t length = OSPF_HEADER_SIZE;
3031
3032 oi = nbr->oi;
3033 op = ospf_packet_new (oi->ifp->mtu);
3034
3035 /* Prepare OSPF common header. */
3036 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3037
3038 /* Prepare OSPF Link State Request body. */
3039 length += ospf_make_ls_req (nbr, op->s);
3040 if (length == OSPF_HEADER_SIZE)
3041 {
3042 ospf_packet_free (op);
3043 return;
3044 }
3045
3046 /* Fill OSPF header. */
3047 ospf_fill_header (oi, op->s, length);
3048
3049 /* Set packet length. */
3050 op->length = length;
3051
3052 /* Decide destination address. */
3053 op->dst = nbr->address.u.prefix4;
3054
3055 /* Add packet to the interface output queue. */
3056 ospf_packet_add (oi, op);
3057
3058 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003059 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003060
3061 /* Add Link State Request Retransmission Timer. */
3062 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3063}
3064
3065/* Send Link State Update with an LSA. */
3066void
3067ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3068 int flag)
3069{
3070 list update;
3071
3072 update = list_new ();
3073
3074 listnode_add (update, lsa);
3075 ospf_ls_upd_send (nbr, update, flag);
3076
3077 list_delete (update);
3078}
3079
3080static void
3081ospf_ls_upd_queue_send (struct ospf_interface *oi, list update,
3082 struct in_addr addr)
3083{
3084 struct ospf_packet *op;
3085 u_int16_t length = OSPF_HEADER_SIZE;
3086
3087 if (IS_DEBUG_OSPF_EVENT)
3088 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
3089
3090 op = ospf_packet_new (oi->ifp->mtu);
3091
3092 /* Prepare OSPF common header. */
3093 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3094
3095 /* Prepare OSPF Link State Update body. */
3096 /* Includes Type-7 translation. */
3097 length += ospf_make_ls_upd (oi, update, op->s);
3098
3099 /* Fill OSPF header. */
3100 ospf_fill_header (oi, op->s, length);
3101
3102 /* Set packet length. */
3103 op->length = length;
3104
3105 /* Decide destination address. */
3106 op->dst.s_addr = addr.s_addr;
3107
3108 /* Add packet to the interface output queue. */
3109 ospf_packet_add (oi, op);
3110
3111 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003112 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003113}
3114
3115static int
3116ospf_ls_upd_send_queue_event (struct thread *thread)
3117{
3118 struct ospf_interface *oi = THREAD_ARG(thread);
3119 struct route_node *rn;
3120
3121 oi->t_ls_upd_event = NULL;
3122
3123 if (IS_DEBUG_OSPF_EVENT)
3124 zlog_info ("ospf_ls_upd_send_queue start");
3125
3126 for (rn = route_top (oi->ls_upd_queue); rn; rn = route_next (rn))
3127 {
3128 if (rn->info == NULL)
3129 continue;
3130
3131 while (!list_isempty ((list)rn->info))
3132 ospf_ls_upd_queue_send (oi, rn->info, rn->p.u.prefix4);
3133
3134 list_delete (rn->info);
3135 rn->info = NULL;
3136
3137 route_unlock_node (rn);
3138 }
3139
3140 if (IS_DEBUG_OSPF_EVENT)
3141 zlog_info ("ospf_ls_upd_send_queue stop");
3142 return 0;
3143}
3144
3145void
3146ospf_ls_upd_send (struct ospf_neighbor *nbr, list update, int flag)
3147{
3148 struct ospf_interface *oi;
3149 struct prefix_ipv4 p;
3150 struct route_node *rn;
3151 listnode n;
3152
3153 oi = nbr->oi;
3154
3155 p.family = AF_INET;
3156 p.prefixlen = IPV4_MAX_BITLEN;
3157
3158 /* Decide destination address. */
3159 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3160 p.prefix = oi->vl_data->peer_addr;
3161 else if (flag == OSPF_SEND_PACKET_DIRECT)
3162 p.prefix = nbr->address.u.prefix4;
3163 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3164 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3165 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3166 && (flag == OSPF_SEND_PACKET_INDIRECT))
3167 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003168 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3169 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003170 else
3171 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3172
3173 if (oi->type == OSPF_IFTYPE_NBMA)
3174 {
3175 if (flag == OSPF_SEND_PACKET_INDIRECT)
3176 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3177 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3178 zlog_warn ("* LS-Update is sent to myself.");
3179 }
3180
3181 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3182
3183 if (rn->info == NULL)
3184 rn->info = list_new ();
3185
3186 for (n = listhead (update); n; nextnode (n))
3187 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3188
3189 if (oi->t_ls_upd_event == NULL)
3190 oi->t_ls_upd_event =
3191 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3192}
3193
3194static void
3195ospf_ls_ack_send_list (struct ospf_interface *oi, list ack, struct in_addr dst)
3196{
3197 struct ospf_packet *op;
3198 u_int16_t length = OSPF_HEADER_SIZE;
3199
3200 op = ospf_packet_new (oi->ifp->mtu);
3201
3202 /* Prepare OSPF common header. */
3203 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3204
3205 /* Prepare OSPF Link State Acknowledgment body. */
3206 length += ospf_make_ls_ack (oi, ack, op->s);
3207
3208 /* Fill OSPF header. */
3209 ospf_fill_header (oi, op->s, length);
3210
3211 /* Set packet length. */
3212 op->length = length;
3213
3214 /* Set destination IP address. */
3215 op->dst = dst;
3216
3217 /* Add packet to the interface output queue. */
3218 ospf_packet_add (oi, op);
3219
3220 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003221 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003222}
3223
3224static int
3225ospf_ls_ack_send_event (struct thread *thread)
3226{
3227 struct ospf_interface *oi = THREAD_ARG (thread);
3228
3229 oi->t_ls_ack_direct = NULL;
3230
3231 while (listcount (oi->ls_ack_direct.ls_ack))
3232 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3233 oi->ls_ack_direct.dst);
3234
3235 return 0;
3236}
3237
3238void
3239ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3240{
3241 struct ospf_interface *oi = nbr->oi;
3242
3243 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3244 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3245
3246 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3247
3248 if (oi->t_ls_ack_direct == NULL)
3249 oi->t_ls_ack_direct =
3250 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3251}
3252
3253/* Send Link State Acknowledgment delayed. */
3254void
3255ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3256{
3257 struct in_addr dst;
3258
3259 /* Decide destination address. */
3260 /* RFC2328 Section 13.5 On non-broadcast
3261 networks, delayed Link State Acknowledgment packets must be
3262 unicast separately over each adjacency (i.e., neighbor whose
3263 state is >= Exchange). */
3264 if (oi->type == OSPF_IFTYPE_NBMA)
3265 {
3266 struct ospf_neighbor *nbr;
3267 struct route_node *rn;
3268
3269 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3270 if ((nbr = rn->info) != NULL)
3271 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3272 while (listcount (oi->ls_ack))
3273 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3274 return;
3275 }
3276 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3277 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3278 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3279 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3280 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3281 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3282 else
3283 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3284
3285 while (listcount (oi->ls_ack))
3286 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3287}