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