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