blob: 5a1c0916eeb5de04d7dd4fe139345320ee8351e4 [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
hasso52dc7ee2004-09-23 19:18:23 +000051static void ospf_ls_ack_send_list (struct ospf_interface *, struct list *,
paul718e3742002-12-13 20:15:29 +000052 struct in_addr);
53
54/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000055const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000056{
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
paul6c835672004-10-11 11:00:30 +0000244unsigned int
paul718e3742002-12-13 20:15:29 +0000245ospf_packet_max (struct ospf_interface *oi)
246{
247 int max;
248
249 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
paul68b73392004-09-12 14:21:37 +0000250 max = oi->ifp->mtu - OSPF_AUTH_MD5_SIZE;
paul718e3742002-12-13 20:15:29 +0000251 else
paul68b73392004-09-12 14:21:37 +0000252 max = oi->ifp->mtu;
253
254 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000255
256 return max;
257}
258
259
260int
261ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
262 u_int16_t length)
263{
paul6c835672004-10-11 11:00:30 +0000264 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000265 struct md5_ctx ctx;
266 unsigned char digest[OSPF_AUTH_MD5_SIZE];
267 unsigned char *pdigest;
268 struct crypt_key *ck;
269 struct ospf_header *ospfh;
270 struct ospf_neighbor *nbr;
271
272
273 ibuf = STREAM_PNT (s);
274 ospfh = (struct ospf_header *) ibuf;
275
276 /* Get pointer to the end of the packet. */
277 pdigest = ibuf + length;
278
279 /* Get secret key. */
280 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
281 ospfh->u.crypt.key_id);
282 if (ck == NULL)
283 {
284 zlog_warn ("interface %s: ospf_check_md5 no key %d",
285 IF_NAME (oi), ospfh->u.crypt.key_id);
286 return 0;
287 }
288
289 /* check crypto seqnum. */
290 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
291
292 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
293 {
294 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
295 IF_NAME (oi),
296 ntohl(ospfh->u.crypt.crypt_seqnum),
297 ntohl(nbr->crypt_seqnum));
298 return 0;
299 }
300
301 /* Generate a digest for the ospf packet - their digest + our digest. */
302 md5_init_ctx (&ctx);
303 md5_process_bytes (ibuf, length, &ctx);
304 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
305 md5_finish_ctx (&ctx, digest);
306
307 /* compare the two */
308 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
309 {
310 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
311 IF_NAME (oi));
312 return 0;
313 }
314
315 /* save neighbor's crypt_seqnum */
316 if (nbr)
317 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
318 return 1;
319}
320
321/* This function is called from ospf_write(), it will detect the
322 authentication scheme and if it is MD5, it will change the sequence
323 and update the MD5 digest. */
324int
325ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
326{
327 struct ospf_header *ospfh;
328 unsigned char digest[OSPF_AUTH_MD5_SIZE];
329 struct md5_ctx ctx;
330 void *ibuf;
331 unsigned long oldputp;
paul9483e152002-12-13 20:55:25 +0000332 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000333 struct crypt_key *ck;
334 char *auth_key;
335
336 ibuf = STREAM_DATA (op->s);
337 ospfh = (struct ospf_header *) ibuf;
338
339 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
340 return 0;
341
342 /* We do this here so when we dup a packet, we don't have to
343 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000344 t = (time(NULL) & 0xFFFFFFFF);
345 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
346 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000347
348 /* Get MD5 Authentication key from auth_key list. */
349 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000350 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000351 else
352 {
353 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000354 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000355 }
356
357 /* Generate a digest for the entire packet + our secret key. */
358 md5_init_ctx (&ctx);
359 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
360 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
361 md5_finish_ctx (&ctx, digest);
362
363 /* Append md5 digest to the end of the stream. */
364 oldputp = stream_get_putp (op->s);
365 stream_set_putp (op->s, ntohs (ospfh->length));
366 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
367 stream_set_putp (op->s, oldputp);
368
369 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000370 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
371
paul37163d62003-02-03 18:40:56 +0000372 if (stream_get_endp(op->s) != op->length)
373 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 +0000374
375 return OSPF_AUTH_MD5_SIZE;
376}
377
378
379int
380ospf_ls_req_timer (struct thread *thread)
381{
382 struct ospf_neighbor *nbr;
383
384 nbr = THREAD_ARG (thread);
385 nbr->t_ls_req = NULL;
386
387 /* Send Link State Request. */
388 if (ospf_ls_request_count (nbr))
389 ospf_ls_req_send (nbr);
390
391 /* Set Link State Request retransmission timer. */
392 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
393
394 return 0;
395}
396
397void
398ospf_ls_req_event (struct ospf_neighbor *nbr)
399{
400 if (nbr->t_ls_req)
401 {
402 thread_cancel (nbr->t_ls_req);
403 nbr->t_ls_req = NULL;
404 }
405 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
406}
407
408/* Cyclic timer function. Fist registered in ospf_nbr_new () in
409 ospf_neighbor.c */
410int
411ospf_ls_upd_timer (struct thread *thread)
412{
413 struct ospf_neighbor *nbr;
414
415 nbr = THREAD_ARG (thread);
416 nbr->t_ls_upd = NULL;
417
418 /* Send Link State Update. */
419 if (ospf_ls_retransmit_count (nbr) > 0)
420 {
hasso52dc7ee2004-09-23 19:18:23 +0000421 struct list *update;
paul718e3742002-12-13 20:15:29 +0000422 struct ospf_lsdb *lsdb;
423 int i;
424 struct timeval now;
425 int retransmit_interval;
426
427 gettimeofday (&now, NULL);
428 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
429
430 lsdb = &nbr->ls_rxmt;
431 update = list_new ();
432
433 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
434 {
435 struct route_table *table = lsdb->type[i].db;
436 struct route_node *rn;
437
438 for (rn = route_top (table); rn; rn = route_next (rn))
439 {
440 struct ospf_lsa *lsa;
441
442 if ((lsa = rn->info) != NULL)
443 /* Don't retransmit an LSA if we received it within
444 the last RxmtInterval seconds - this is to allow the
445 neighbour a chance to acknowledge the LSA as it may
446 have ben just received before the retransmit timer
447 fired. This is a small tweak to what is in the RFC,
448 but it will cut out out a lot of retransmit traffic
449 - MAG */
450 if (tv_cmp (tv_sub (now, lsa->tv_recv),
451 int2tv (retransmit_interval)) >= 0)
452 listnode_add (update, rn->info);
453 }
454 }
455
456 if (listcount (update) > 0)
457 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
458 list_delete (update);
459 }
460
461 /* Set LS Update retransmission timer. */
462 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
463
464 return 0;
465}
466
467int
468ospf_ls_ack_timer (struct thread *thread)
469{
470 struct ospf_interface *oi;
471
472 oi = THREAD_ARG (thread);
473 oi->t_ls_ack = NULL;
474
475 /* Send Link State Acknowledgment. */
476 if (listcount (oi->ls_ack) > 0)
477 ospf_ls_ack_send_delayed (oi);
478
479 /* Set LS Ack timer. */
480 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
481
482 return 0;
483}
484
paul0bfeca32004-09-24 08:07:54 +0000485#ifdef WANT_OSPF_WRITE_FRAGMENT
486void
paul6a99f832004-09-27 12:56:30 +0000487ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000488 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000489 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000490{
491#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000492 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000493 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000494 int ret;
paul0bfeca32004-09-24 08:07:54 +0000495
496 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000497 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000498
499 /* we can but try.
500 *
501 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
502 * well as the IP_MF flag, making this all quite pointless.
503 *
504 * However, for a system on which IP_MF is left alone, and ip_id left
505 * alone or else which sets same ip_id for each fragment this might
506 * work, eg linux.
507 *
508 * XXX-TODO: It would be much nicer to have the kernel's use their
509 * existing fragmentation support to do this for us. Bugs/RFEs need to
510 * be raised against the various kernels.
511 */
512
513 /* set More Frag */
514 iph->ip_off |= IP_MF;
515
516 /* ip frag offset is expressed in units of 8byte words */
517 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
518
paul62d8e962004-11-02 20:26:45 +0000519 iovp = &msg->msg_iov[1];
520
paul0bfeca32004-09-24 08:07:54 +0000521 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
522 > maxdatasize )
523 {
524 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000525 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
526 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000527 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000528
paul18b12c32004-10-05 14:38:29 +0000529 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000530
paul6a99f832004-09-27 12:56:30 +0000531 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000532
paul18b12c32004-10-05 14:38:29 +0000533 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000534
535 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000536 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000537 " id %d, off %d, len %d failed with %s",
538 inet_ntoa (iph->ip_dst),
539 iph->ip_id,
540 iph->ip_off,
541 iph->ip_len,
542 strerror (errno));
543
paul37ccfa32004-10-31 11:24:51 +0000544 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
545 {
546 zlog_info ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
547 iph->ip_id, iph->ip_off, iph->ip_len,
548 inet_ntoa (iph->ip_dst));
549 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
550 {
551 zlog_info ("-----------------IP Header Dump----------------------");
552 ospf_ip_header_dump (iph);
553 zlog_info ("-----------------------------------------------------");
554 }
555 }
556
paul0bfeca32004-09-24 08:07:54 +0000557 iph->ip_off += offset;
paul62d8e962004-11-02 20:26:45 +0000558 stream_forward (op->s, iovp->iov_len);
559 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000560 }
561
562 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000563 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
564 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000565 iph->ip_off &= (~IP_MF);
566}
567#endif /* WANT_OSPF_WRITE_FRAGMENT */
568
paul718e3742002-12-13 20:15:29 +0000569int
570ospf_write (struct thread *thread)
571{
paul68980082003-03-25 05:07:42 +0000572 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000573 struct ospf_interface *oi;
574 struct ospf_packet *op;
575 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000576 struct ip iph;
577 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000578 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000579 u_char type;
580 int ret;
581 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000582 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000583#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000584 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000585#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000586 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000587#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000588
paul68980082003-03-25 05:07:42 +0000589 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000590
paul68980082003-03-25 05:07:42 +0000591 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000592 assert (node);
593 oi = getdata (node);
594 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000595
596#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000597 /* seed ipid static with low order bits of time */
598 if (ipid == 0)
599 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000600#endif /* WANT_OSPF_WRITE_FRAGMENT */
601
paul68b73392004-09-12 14:21:37 +0000602 /* convenience - max OSPF data per packet */
603 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
604
paul718e3742002-12-13 20:15:29 +0000605 /* Get one packet from queue. */
606 op = ospf_fifo_head (oi->obuf);
607 assert (op);
608 assert (op->length >= OSPF_HEADER_SIZE);
609
paul68980082003-03-25 05:07:42 +0000610 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
611 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000612 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
613
paul718e3742002-12-13 20:15:29 +0000614 /* Rewrite the md5 signature & update the seq */
615 ospf_make_md5_digest (oi, op);
616
paul37ccfa32004-10-31 11:24:51 +0000617 /* Retrieve OSPF packet type. */
618 stream_set_getp (op->s, 1);
619 type = stream_getc (op->s);
620
paul68b73392004-09-12 14:21:37 +0000621 /* reset get pointer */
622 stream_set_getp (op->s, 0);
623
624 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000625 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000626
paul718e3742002-12-13 20:15:29 +0000627 sa_dst.sin_family = AF_INET;
628#ifdef HAVE_SIN_LEN
629 sa_dst.sin_len = sizeof(sa_dst);
630#endif /* HAVE_SIN_LEN */
631 sa_dst.sin_addr = op->dst;
632 sa_dst.sin_port = htons (0);
633
634 /* Set DONTROUTE flag if dst is unicast. */
635 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
636 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
637 flags = MSG_DONTROUTE;
638
paul68b73392004-09-12 14:21:37 +0000639 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
640 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000641 if ( sizeof (struct ip)
642 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000643 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
644
paul718e3742002-12-13 20:15:29 +0000645 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000646 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000647 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000648
paul0bfeca32004-09-24 08:07:54 +0000649#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000650 /* XXX-MT: not thread-safe at all..
651 * XXX: this presumes this is only programme sending OSPF packets
652 * otherwise, no guarantee ipid will be unique
653 */
654 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000655#endif /* WANT_OSPF_WRITE_FRAGMENT */
656
paul718e3742002-12-13 20:15:29 +0000657 iph.ip_off = 0;
658 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
659 iph.ip_ttl = OSPF_VL_IP_TTL;
660 else
661 iph.ip_ttl = OSPF_IP_TTL;
662 iph.ip_p = IPPROTO_OSPFIGP;
663 iph.ip_sum = 0;
664 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
665 iph.ip_dst.s_addr = op->dst.s_addr;
666
667 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000668 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000669 msg.msg_namelen = sizeof (sa_dst);
670 msg.msg_iov = iov;
671 msg.msg_iovlen = 2;
672 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000673 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
674 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000675 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000676
677 /* Sadly we can not rely on kernels to fragment packets because of either
678 * IP_HDRINCL and/or multicast destination being set.
679 */
paul0bfeca32004-09-24 08:07:54 +0000680#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000681 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000682 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
683 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000684#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000685
686 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000687 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000688 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000689 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000690
691 if (ret < 0)
paul68b73392004-09-12 14:21:37 +0000692 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
693 inet_ntoa (iph.ip_dst), strerror (errno));
paul718e3742002-12-13 20:15:29 +0000694
paul718e3742002-12-13 20:15:29 +0000695 /* Show debug sending packet. */
696 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
697 {
698 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
699 {
700 zlog_info ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000701 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000702 stream_set_getp (op->s, 0);
703 ospf_packet_dump (op->s);
704 }
705
706 zlog_info ("%s sent to [%s] via [%s].",
707 ospf_packet_type_str[type], inet_ntoa (op->dst),
708 IF_NAME (oi));
709
710 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
711 zlog_info ("-----------------------------------------------------");
712 }
713
714 /* Now delete packet from queue. */
715 ospf_packet_delete (oi);
716
717 if (ospf_fifo_head (oi->obuf) == NULL)
718 {
719 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000720 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000724 if (!list_isempty (ospf->oi_write_q))
725 ospf->t_write =
726 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000727
728 return 0;
729}
730
731/* OSPF Hello message read -- RFC2328 Section 10.5. */
732void
733ospf_hello (struct ip *iph, struct ospf_header *ospfh,
734 struct stream * s, struct ospf_interface *oi, int size)
735{
736 struct ospf_hello *hello;
737 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000738 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000739 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000740
741 /* increment statistics. */
742 oi->hello_in++;
743
744 hello = (struct ospf_hello *) STREAM_PNT (s);
745
746 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000747 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000748 {
749 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
750 {
751 zlog_info ("ospf_header[%s/%s]: selforiginated, "
752 "dropping.",
753 ospf_packet_type_str[ospfh->type],
754 inet_ntoa (iph->ip_src));
755 }
756 return;
757 }
paul718e3742002-12-13 20:15:29 +0000758
759 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000760 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
paulc2191ea2003-04-18 23:59:35 +0000761 zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
762 inet_ntoa (ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000763 return;
paulf2c80652002-12-13 21:44:27 +0000764 }
paul718e3742002-12-13 20:15:29 +0000765
766 /* get neighbor prefix. */
767 p.family = AF_INET;
768 p.prefixlen = ip_masklen (hello->network_mask);
769 p.u.prefix4 = iph->ip_src;
770
771 /* Compare network mask. */
772 /* Checking is ignored for Point-to-Point and Virtual link. */
773 if (oi->type != OSPF_IFTYPE_POINTOPOINT
774 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
775 if (oi->address->prefixlen != p.prefixlen)
776 {
777 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
778 inet_ntoa (ospfh->router_id));
779 return;
780 }
781
782 /* Compare Hello Interval. */
783 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
784 {
785 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
786 inet_ntoa (ospfh->router_id));
787 return;
788 }
789
790 /* Compare Router Dead Interval. */
791 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
792 {
793 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
794 inet_ntoa (ospfh->router_id));
795 return;
796 }
797
798 if (IS_DEBUG_OSPF_EVENT)
799 zlog_info ("Packet %s [Hello:RECV]: Options %s",
800 inet_ntoa (ospfh->router_id),
801 ospf_options_dump (hello->options));
802
803 /* Compare options. */
804#define REJECT_IF_TBIT_ON 1 /* XXX */
805#ifdef REJECT_IF_TBIT_ON
806 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
807 {
808 /*
809 * This router does not support non-zero TOS.
810 * Drop this Hello packet not to establish neighbor relationship.
811 */
812 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
813 inet_ntoa (ospfh->router_id));
814 return;
815 }
816#endif /* REJECT_IF_TBIT_ON */
817
818#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000819 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000820 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
821 {
822 /*
823 * This router does know the correct usage of O-bit
824 * the bit should be set in DD packet only.
825 */
826 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
827 inet_ntoa (ospfh->router_id));
828#ifdef STRICT_OBIT_USAGE_CHECK
829 return; /* Reject this packet. */
830#else /* STRICT_OBIT_USAGE_CHECK */
831 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
832#endif /* STRICT_OBIT_USAGE_CHECK */
833 }
834#endif /* HAVE_OPAQUE_LSA */
835
836 /* new for NSSA is to ensure that NP is on and E is off */
837
paul718e3742002-12-13 20:15:29 +0000838 if (oi->area->external_routing == OSPF_AREA_NSSA)
839 {
840 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
841 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
842 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
843 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
844 {
845 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
846 return;
847 }
848 if (IS_DEBUG_OSPF_NSSA)
849 zlog_info ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
850 }
851 else
paul718e3742002-12-13 20:15:29 +0000852 /* The setting of the E-bit found in the Hello Packet's Options
853 field must match this area's ExternalRoutingCapability A
854 mismatch causes processing to stop and the packet to be
855 dropped. The setting of the rest of the bits in the Hello
856 Packet's Options field should be ignored. */
857 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
858 CHECK_FLAG (hello->options, OSPF_OPTION_E))
859 {
860 zlog_warn ("Packet[Hello:RECV]: my options: %x, his options %x",
861 OPTIONS (oi), hello->options);
862 return;
863 }
paul718e3742002-12-13 20:15:29 +0000864
pauld3f0d622004-05-05 15:27:15 +0000865 /* get neighbour struct */
866 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
867
868 /* neighbour must be valid, ospf_nbr_get creates if none existed */
869 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000870
871 old_state = nbr->state;
872
873 /* Add event to thread. */
874 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
875
876 /* RFC2328 Section 9.5.1
877 If the router is not eligible to become Designated Router,
878 (snip) It must also send an Hello Packet in reply to an
879 Hello Packet received from any eligible neighbor (other than
880 the current Designated Router and Backup Designated Router). */
881 if (oi->type == OSPF_IFTYPE_NBMA)
882 if (PRIORITY(oi) == 0 && hello->priority > 0
883 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
884 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
885 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
886 OSPF_HELLO_REPLY_DELAY);
887
888 /* on NBMA network type, it happens to receive bidirectional Hello packet
889 without advance 1-Way Received event.
890 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
891 if (oi->type == OSPF_IFTYPE_NBMA &&
892 (old_state == NSM_Down || old_state == NSM_Attempt))
893 {
894 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
895 nbr->priority = hello->priority;
896 nbr->d_router = hello->d_router;
897 nbr->bd_router = hello->bd_router;
898 return;
899 }
900
paul68980082003-03-25 05:07:42 +0000901 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000902 size - OSPF_HELLO_MIN_SIZE))
903 {
904 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
905 nbr->options |= hello->options;
906 }
907 else
908 {
909 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
910 /* Set neighbor information. */
911 nbr->priority = hello->priority;
912 nbr->d_router = hello->d_router;
913 nbr->bd_router = hello->bd_router;
914 return;
915 }
916
917 /* If neighbor itself declares DR and no BDR exists,
918 cause event BackupSeen */
919 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
920 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
921 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
922
923 /* neighbor itself declares BDR. */
924 if (oi->state == ISM_Waiting &&
925 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
926 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
927
928 /* had not previously. */
929 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
930 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
931 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
932 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
933 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
934
935 /* had not previously. */
936 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
937 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
938 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
939 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
940 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
941
942 /* Neighbor priority check. */
943 if (nbr->priority >= 0 && nbr->priority != hello->priority)
944 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
945
946 /* Set neighbor information. */
947 nbr->priority = hello->priority;
948 nbr->d_router = hello->d_router;
949 nbr->bd_router = hello->bd_router;
950}
951
952/* Save DD flags/options/Seqnum received. */
953void
954ospf_db_desc_save_current (struct ospf_neighbor *nbr,
955 struct ospf_db_desc *dd)
956{
957 nbr->last_recv.flags = dd->flags;
958 nbr->last_recv.options = dd->options;
959 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
960}
961
962/* Process rest of DD packet. */
963static void
964ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
965 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
966 u_int16_t size)
967{
968 struct ospf_lsa *new, *find;
969 struct lsa_header *lsah;
970
971 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
972 for (size -= OSPF_DB_DESC_MIN_SIZE;
973 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
974 {
975 lsah = (struct lsa_header *) STREAM_PNT (s);
976 stream_forward (s, OSPF_LSA_HEADER_SIZE);
977
978 /* Unknown LS type. */
979 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
980 {
981 zlog_warn ("Pakcet [DD:RECV]: Unknown LS type %d.", lsah->type);
982 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
983 return;
984 }
985
986#ifdef HAVE_OPAQUE_LSA
987 if (IS_OPAQUE_LSA (lsah->type)
988 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
989 {
990 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
991 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
992 return;
993 }
994#endif /* HAVE_OPAQUE_LSA */
995
996 switch (lsah->type)
997 {
998 case OSPF_AS_EXTERNAL_LSA:
999#ifdef HAVE_OPAQUE_LSA
1000 case OSPF_OPAQUE_AS_LSA:
1001#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001002 /* Check for stub area. Reject if AS-External from stub but
1003 allow if from NSSA. */
1004 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001005 {
1006 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1007 lsah->type, inet_ntoa (lsah->id),
1008 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1009 "STUB" : "NSSA");
1010 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1011 return;
1012 }
1013 break;
1014 default:
1015 break;
1016 }
1017
1018 /* Create LS-request object. */
1019 new = ospf_ls_request_new (lsah);
1020
1021 /* Lookup received LSA, then add LS request list. */
1022 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1023 if (!find || ospf_lsa_more_recent (find, new) < 0)
1024 {
1025 ospf_ls_request_add (nbr, new);
1026 ospf_lsa_discard (new);
1027 }
1028 else
1029 {
1030 /* Received LSA is not recent. */
1031 if (IS_DEBUG_OSPF_EVENT)
1032 zlog_info ("Packet [DD:RECV]: LSA received Type %d, "
1033 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1034 ospf_lsa_discard (new);
1035 continue;
1036 }
1037 }
1038
1039 /* Master */
1040 if (IS_SET_DD_MS (nbr->dd_flags))
1041 {
1042 nbr->dd_seqnum++;
1043 /* Entire DD packet sent. */
1044 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1045 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1046 else
1047 /* Send new DD packet. */
1048 ospf_db_desc_send (nbr);
1049 }
1050 /* Slave */
1051 else
1052 {
1053 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1054
1055 /* When master's more flags is not set. */
1056 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1057 {
1058 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1059 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1060 }
1061
1062 /* Send DD pakcet in reply. */
1063 ospf_db_desc_send (nbr);
1064 }
1065
1066 /* Save received neighbor values from DD. */
1067 ospf_db_desc_save_current (nbr, dd);
1068}
1069
1070int
1071ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1072{
1073 /* Is DD duplicated? */
1074 if (dd->options == nbr->last_recv.options &&
1075 dd->flags == nbr->last_recv.flags &&
1076 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1077 return 1;
1078
1079 return 0;
1080}
1081
1082/* OSPF Database Description message read -- RFC2328 Section 10.6. */
1083void
1084ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1085 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1086{
1087 struct ospf_db_desc *dd;
1088 struct ospf_neighbor *nbr;
1089
1090 /* Increment statistics. */
1091 oi->db_desc_in++;
1092
1093 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001094
pauld3f0d622004-05-05 15:27:15 +00001095 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001096 if (nbr == NULL)
1097 {
1098 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1099 inet_ntoa (ospfh->router_id));
1100 return;
1101 }
1102
1103 /* Check MTU. */
1104 if (ntohs (dd->mtu) > oi->ifp->mtu)
1105 {
1106 zlog_warn ("Packet[DD]: MTU is larger than [%s]'s MTU", IF_NAME (oi));
1107 return;
1108 }
1109
pauld363df22003-06-19 00:26:34 +00001110 /*
1111 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1112 * required. In fact at least JunOS sends DD packets with P bit clear.
1113 * Until proper solution is developped, this hack should help.
1114 *
1115 * Update: According to the RFCs, N bit is specified /only/ for Hello
1116 * options, unfortunately its use in DD options is not specified. Hence some
1117 * implementations follow E-bit semantics and set it in DD options, and some
1118 * treat it as unspecified and hence follow the directive "default for
1119 * options is clear", ie unset.
1120 *
1121 * Reset the flag, as ospfd follows E-bit semantics.
1122 */
1123 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1124 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1125 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1126 {
1127 if (IS_DEBUG_OSPF_EVENT)
paul3db0a772003-06-19 01:07:40 +00001128 zlog_notice ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001129 inet_ntoa (nbr->router_id) );
1130 SET_FLAG (dd->options, OSPF_OPTION_NP);
1131 }
pauld363df22003-06-19 00:26:34 +00001132
paul718e3742002-12-13 20:15:29 +00001133#ifdef REJECT_IF_TBIT_ON
1134 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1135 {
1136 /*
1137 * In Hello protocol, optional capability must have checked
1138 * to prevent this T-bit enabled router be my neighbor.
1139 */
1140 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1141 return;
1142 }
1143#endif /* REJECT_IF_TBIT_ON */
1144
1145#ifdef HAVE_OPAQUE_LSA
1146 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001147 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001148 {
1149 /*
1150 * This node is not configured to handle O-bit, for now.
1151 * Clear it to ignore unsupported capability proposed by neighbor.
1152 */
1153 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1154 }
1155#endif /* HAVE_OPAQUE_LSA */
1156
1157 /* Process DD packet by neighbor status. */
1158 switch (nbr->state)
1159 {
1160 case NSM_Down:
1161 case NSM_Attempt:
1162 case NSM_TwoWay:
1163 zlog_warn ("Packet[DD]: Neighbor state is %s, packet discarded.",
1164 LOOKUP (ospf_nsm_state_msg, nbr->state));
1165 break;
1166 case NSM_Init:
1167 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1168 /* If the new state is ExStart, the processing of the current
1169 packet should then continue in this new state by falling
1170 through to case ExStart below. */
1171 if (nbr->state != NSM_ExStart)
1172 break;
1173 case NSM_ExStart:
1174 /* Initial DBD */
1175 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1176 (size == OSPF_DB_DESC_MIN_SIZE))
1177 {
paul68980082003-03-25 05:07:42 +00001178 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001179 {
1180 /* We're Slave---obey */
1181 zlog_warn ("Packet[DD]: Negotiation done (Slave).");
1182 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1183 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1184 }
1185 else
1186 {
1187 /* We're Master, ignore the initial DBD from Slave */
1188 zlog_warn ("Packet[DD]: Initial DBD from Slave, ignoring.");
1189 break;
1190 }
1191 }
1192 /* Ack from the Slave */
1193 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1194 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001195 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001196 {
1197 zlog_warn ("Packet[DD]: Negotiation done (Master).");
1198 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1199 }
1200 else
1201 {
1202 zlog_warn ("Packet[DD]: Negotiation fails.");
1203 break;
1204 }
1205
1206 /* This is where the real Options are saved */
1207 nbr->options = dd->options;
1208
1209#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001210 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001211 {
1212 if (IS_DEBUG_OSPF_EVENT)
1213 zlog_info ("Neighbor[%s] is %sOpaque-capable.",
1214 inet_ntoa (nbr->router_id),
1215 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1216
1217 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1218 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1219 {
1220 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1221 /* This situation is undesirable, but not a real error. */
1222 }
1223 }
1224#endif /* HAVE_OPAQUE_LSA */
1225
1226 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1227
1228 /* continue processing rest of packet. */
1229 ospf_db_desc_proc (s, oi, nbr, dd, size);
1230 break;
1231 case NSM_Exchange:
1232 if (ospf_db_desc_is_dup (dd, nbr))
1233 {
1234 if (IS_SET_DD_MS (nbr->dd_flags))
1235 /* Master: discard duplicated DD packet. */
1236 zlog_warn ("Packet[DD] (Master): packet duplicated.");
1237 else
1238 /* Slave: cause to retransmit the last Database Description. */
1239 {
1240 zlog_warn ("Packet[DD] [Slave]: packet duplicated.");
1241 ospf_db_desc_resend (nbr);
1242 }
1243 break;
1244 }
1245
1246 /* Otherwise DD packet should be checked. */
1247 /* Check Master/Slave bit mismatch */
1248 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1249 {
1250 zlog_warn ("Packet[DD]: MS-bit mismatch.");
1251 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1252 if (IS_DEBUG_OSPF_EVENT)
1253 zlog_info ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
1254 dd->flags, nbr->dd_flags);
1255 break;
1256 }
1257
1258 /* Check initialize bit is set. */
1259 if (IS_SET_DD_I (dd->flags))
1260 {
1261 zlog_warn ("Packet[DD]: I-bit set.");
1262 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1263 break;
1264 }
1265
1266 /* Check DD Options. */
1267 if (dd->options != nbr->options)
1268 {
1269#ifdef ORIGINAL_CODING
1270 /* Save the new options for debugging */
1271 nbr->options = dd->options;
1272#endif /* ORIGINAL_CODING */
1273 zlog_warn ("Packet[DD]: options mismatch.");
1274 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1275 break;
1276 }
1277
1278 /* Check DD sequence number. */
1279 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1280 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1281 (!IS_SET_DD_MS (nbr->dd_flags) &&
1282 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1283 {
1284 zlog_warn ("Pakcet[DD]: sequence number mismatch.");
1285 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1286 break;
1287 }
1288
1289 /* Continue processing rest of packet. */
1290 ospf_db_desc_proc (s, oi, nbr, dd, size);
1291 break;
1292 case NSM_Loading:
1293 case NSM_Full:
1294 if (ospf_db_desc_is_dup (dd, nbr))
1295 {
1296 if (IS_SET_DD_MS (nbr->dd_flags))
1297 {
1298 /* Master should discard duplicate DD packet. */
1299 zlog_warn ("Pakcet[DD]: duplicated, packet discarded.");
1300 break;
1301 }
1302 else
1303 {
1304 struct timeval t, now;
1305 gettimeofday (&now, NULL);
1306 t = tv_sub (now, nbr->last_send_ts);
1307 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1308 {
1309 /* In states Loading and Full the slave must resend
1310 its last Database Description packet in response to
1311 duplicate Database Description packets received
1312 from the master. For this reason the slave must
1313 wait RouterDeadInterval seconds before freeing the
1314 last Database Description packet. Reception of a
1315 Database Description packet from the master after
1316 this interval will generate a SeqNumberMismatch
1317 neighbor event. RFC2328 Section 10.8 */
1318 ospf_db_desc_resend (nbr);
1319 break;
1320 }
1321 }
1322 }
1323
1324 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1325 break;
1326 default:
1327 zlog_warn ("Packet[DD]: NSM illegal status.");
1328 break;
1329 }
1330}
1331
1332#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1333
1334/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1335void
1336ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1337 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1338{
1339 struct ospf_neighbor *nbr;
1340 u_int32_t ls_type;
1341 struct in_addr ls_id;
1342 struct in_addr adv_router;
1343 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001344 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001345 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001346
1347 /* Increment statistics. */
1348 oi->ls_req_in++;
1349
pauld3f0d622004-05-05 15:27:15 +00001350 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001351 if (nbr == NULL)
1352 {
1353 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1354 inet_ntoa (ospfh->router_id));
1355 return;
1356 }
1357
1358 /* Neighbor State should be Exchange or later. */
1359 if (nbr->state != NSM_Exchange &&
1360 nbr->state != NSM_Loading &&
1361 nbr->state != NSM_Full)
1362 {
1363 zlog_warn ("Link State Request: Neighbor state is %s, packet discarded.",
1364 LOOKUP (ospf_nsm_state_msg, nbr->state));
1365 return;
1366 }
1367
1368 /* Send Link State Update for ALL requested LSAs. */
1369 ls_upd = list_new ();
1370 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1371
1372 while (size >= OSPF_LSA_KEY_SIZE)
1373 {
1374 /* Get one slice of Link State Request. */
1375 ls_type = stream_getl (s);
1376 ls_id.s_addr = stream_get_ipv4 (s);
1377 adv_router.s_addr = stream_get_ipv4 (s);
1378
1379 /* Verify LSA type. */
1380 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1381 {
1382 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1383 list_delete (ls_upd);
1384 return;
1385 }
1386
1387 /* Search proper LSA in LSDB. */
1388 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1389 if (find == NULL)
1390 {
1391 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1392 list_delete (ls_upd);
1393 return;
1394 }
1395
1396 /* Packet overflows MTU size, send immediatly. */
1397 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1398 {
1399 if (oi->type == OSPF_IFTYPE_NBMA)
1400 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1401 else
1402 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1403
1404 /* Only remove list contents. Keep ls_upd. */
1405 list_delete_all_node (ls_upd);
1406
1407 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1408 }
1409
1410 /* Append LSA to update list. */
1411 listnode_add (ls_upd, find);
1412 length += ntohs (find->data->length);
1413
1414 size -= OSPF_LSA_KEY_SIZE;
1415 }
1416
1417 /* Send rest of Link State Update. */
1418 if (listcount (ls_upd) > 0)
1419 {
1420 if (oi->type == OSPF_IFTYPE_NBMA)
1421 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1422 else
1423 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1424
1425 list_delete (ls_upd);
1426 }
1427 else
1428 list_free (ls_upd);
1429}
1430
1431/* Get the list of LSAs from Link State Update packet.
1432 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001433static struct list *
paul718e3742002-12-13 20:15:29 +00001434ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1435 struct ospf_interface *oi, size_t size)
1436{
1437 u_int16_t count, sum;
1438 u_int32_t length;
1439 struct lsa_header *lsah;
1440 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001441 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001442
1443 lsas = list_new ();
1444
1445 count = stream_getl (s);
1446 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1447
1448 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1449 size -= length, stream_forward (s, length), count--)
1450 {
1451 lsah = (struct lsa_header *) STREAM_PNT (s);
1452 length = ntohs (lsah->length);
1453
1454 if (length > size)
1455 {
1456 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1457 break;
1458 }
1459
1460 /* Validate the LSA's LS checksum. */
1461 sum = lsah->checksum;
1462 if (sum != ospf_lsa_checksum (lsah))
1463 {
1464 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1465 sum, lsah->checksum);
1466 continue;
1467 }
1468
1469 /* Examine the LSA's LS type. */
1470 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1471 {
1472 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1473 continue;
1474 }
1475
1476 /*
1477 * What if the received LSA's age is greater than MaxAge?
1478 * Treat it as a MaxAge case -- endo.
1479 */
1480 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1481 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1482
1483#ifdef HAVE_OPAQUE_LSA
1484 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1485 {
1486#ifdef STRICT_OBIT_USAGE_CHECK
1487 if ((IS_OPAQUE_LSA(lsah->type) &&
1488 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1489 || (! IS_OPAQUE_LSA(lsah->type) &&
1490 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1491 {
1492 /*
1493 * This neighbor must know the exact usage of O-bit;
1494 * the bit will be set in Type-9,10,11 LSAs only.
1495 */
1496 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1497 continue;
1498 }
1499#endif /* STRICT_OBIT_USAGE_CHECK */
1500
1501 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1502 if (lsah->type == OSPF_OPAQUE_AS_LSA
1503 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1504 {
1505 if (IS_DEBUG_OSPF_EVENT)
1506 zlog_info ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
1507 continue;
1508 }
1509 }
1510 else if (IS_OPAQUE_LSA(lsah->type))
1511 {
1512 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1513 continue;
1514 }
1515#endif /* HAVE_OPAQUE_LSA */
1516
1517 /* Create OSPF LSA instance. */
1518 lsa = ospf_lsa_new ();
1519
1520 /* We may wish to put some error checking if type NSSA comes in
1521 and area not in NSSA mode */
1522 switch (lsah->type)
1523 {
1524 case OSPF_AS_EXTERNAL_LSA:
1525#ifdef HAVE_OPAQUE_LSA
1526 case OSPF_OPAQUE_AS_LSA:
1527 lsa->area = NULL;
1528 break;
1529 case OSPF_OPAQUE_LINK_LSA:
1530 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1531 /* Fallthrough */
1532#endif /* HAVE_OPAQUE_LSA */
1533 default:
1534 lsa->area = oi->area;
1535 break;
1536 }
1537
1538 lsa->data = ospf_lsa_data_new (length);
1539 memcpy (lsa->data, lsah, length);
1540
1541 if (IS_DEBUG_OSPF_EVENT)
1542 zlog_info("LSA[Type%d:%s]: %p new LSA created with Link State Update",
1543 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1544 listnode_add (lsas, lsa);
1545 }
1546
1547 return lsas;
1548}
1549
1550/* Cleanup Update list. */
1551void
hasso52dc7ee2004-09-23 19:18:23 +00001552ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001553{
hasso52dc7ee2004-09-23 19:18:23 +00001554 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001555 struct ospf_lsa *lsa;
1556
1557 for (node = listhead (lsas); node; nextnode (node))
1558 if ((lsa = getdata (node)) != NULL)
1559 ospf_lsa_discard (lsa);
1560
1561 list_delete (lsas);
1562}
1563
1564/* OSPF Link State Update message read -- RFC2328 Section 13. */
1565void
1566ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1567 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1568{
1569 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001570 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001571#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001572 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001573#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001574 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001575 struct ospf_lsa *lsa = NULL;
1576 /* unsigned long ls_req_found = 0; */
1577
1578 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1579
1580 /* Increment statistics. */
1581 oi->ls_upd_in++;
1582
1583 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001584 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001585 if (nbr == NULL)
1586 {
1587 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1588 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1589 return;
1590 }
1591
1592 /* Check neighbor state. */
1593 if (nbr->state < NSM_Exchange)
1594 {
1595 zlog_warn ("Link State Update: Neighbor[%s] state is less than Exchange",
1596 inet_ntoa (ospfh->router_id));
1597 return;
1598 }
1599
1600 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1601 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1602 * of section 13.
1603 */
1604 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1605
1606#ifdef HAVE_OPAQUE_LSA
1607 /*
1608 * Prepare two kinds of lists to clean up unwanted self-originated
1609 * Opaque-LSAs from the routing domain as soon as possible.
1610 */
1611 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1612 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1613
1614 /*
1615 * If self-originated Opaque-LSAs that have flooded before restart
1616 * are contained in the received LSUpd message, corresponding LSReq
1617 * messages to be sent may have to be modified.
1618 * To eliminate possible race conditions such that flushing and normal
1619 * updating for the same LSA would take place alternately, this trick
1620 * must be done before entering to the loop below.
1621 */
1622 ospf_opaque_adjust_lsreq (nbr, lsas);
1623#endif /* HAVE_OPAQUE_LSA */
1624
1625#define DISCARD_LSA(L,N) {\
1626 if (IS_DEBUG_OSPF_EVENT) \
1627 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
1628 ospf_lsa_discard (L); \
1629 continue; }
1630
1631 /* Process each LSA received in the one packet. */
1632 for (node = listhead (lsas); node; node = next)
1633 {
1634 struct ospf_lsa *ls_ret, *current;
1635 int ret = 1;
1636
1637 next = node->next;
1638
1639 lsa = getdata (node);
1640
paul718e3742002-12-13 20:15:29 +00001641 if (IS_DEBUG_OSPF_NSSA)
1642 {
1643 char buf1[INET_ADDRSTRLEN];
1644 char buf2[INET_ADDRSTRLEN];
1645 char buf3[INET_ADDRSTRLEN];
1646
1647 zlog_info("LSA Type-%d from %s, ID: %s, ADV: %s",
1648 lsa->data->type,
1649 inet_ntop (AF_INET, &ospfh->router_id,
1650 buf1, INET_ADDRSTRLEN),
1651 inet_ntop (AF_INET, &lsa->data->id,
1652 buf2, INET_ADDRSTRLEN),
1653 inet_ntop (AF_INET, &lsa->data->adv_router,
1654 buf3, INET_ADDRSTRLEN));
1655 }
paul718e3742002-12-13 20:15:29 +00001656
1657 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1658
1659 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1660
1661 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1662
1663 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1664
1665 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1666
1667 /* Do take in Type-7's if we are an NSSA */
1668
1669 /* If we are also an ABR, later translate them to a Type-5 packet */
1670
1671 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1672 translate them to a separate Type-5 packet. */
1673
1674 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1675 /* Reject from STUB or NSSA */
1676 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1677 {
1678 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001679 if (IS_DEBUG_OSPF_NSSA)
1680 zlog_info("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001681 }
1682
paul718e3742002-12-13 20:15:29 +00001683 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1684 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1685 {
1686 DISCARD_LSA (lsa,2);
1687 if (IS_DEBUG_OSPF_NSSA)
1688 zlog_info("Incoming NSSA LSA Discarded: Not NSSA Area");
1689 }
paul718e3742002-12-13 20:15:29 +00001690
1691 /* Find the LSA in the current database. */
1692
1693 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1694
1695 /* If the LSA's LS age is equal to MaxAge, and there is currently
1696 no instance of the LSA in the router's link state database,
1697 and none of router's neighbors are in states Exchange or Loading,
1698 then take the following actions. */
1699
1700 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001701 (ospf_nbr_count (oi, NSM_Exchange) +
1702 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001703 {
1704 /* Response Link State Acknowledgment. */
1705 ospf_ls_ack_send (nbr, lsa);
1706
1707 /* Discard LSA. */
1708 zlog_warn ("Link State Update: LS age is equal to MaxAge.");
1709 DISCARD_LSA (lsa, 3);
1710 }
1711
1712#ifdef HAVE_OPAQUE_LSA
1713 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001714 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001715 {
1716 /*
1717 * Even if initial flushing seems to be completed, there might
1718 * be a case that self-originated LSA with MaxAge still remain
1719 * in the routing domain.
1720 * Just send an LSAck message to cease retransmission.
1721 */
1722 if (IS_LSA_MAXAGE (lsa))
1723 {
1724 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1725 ospf_ls_ack_send (nbr, lsa);
1726 ospf_lsa_discard (lsa);
1727
1728 if (current != NULL && ! IS_LSA_MAXAGE (current))
1729 ospf_opaque_lsa_refresh_schedule (current);
1730 continue;
1731 }
1732
1733 /*
1734 * If an instance of self-originated Opaque-LSA is not found
1735 * in the LSDB, there are some possible cases here.
1736 *
1737 * 1) This node lost opaque-capability after restart.
1738 * 2) Else, a part of opaque-type is no more supported.
1739 * 3) Else, a part of opaque-id is no more supported.
1740 *
1741 * Anyway, it is still this node's responsibility to flush it.
1742 * Otherwise, the LSA instance remains in the routing domain
1743 * until its age reaches to MaxAge.
1744 */
1745 if (current == NULL)
1746 {
1747 if (IS_DEBUG_OSPF_EVENT)
1748 zlog_info ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
1749
1750 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1751 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1752 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1753 continue;
1754 }
1755 }
1756#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001757 /* It might be happen that received LSA is self-originated network LSA, but
1758 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1759 * Link State ID is one of the router's own IP interface addresses but whose
1760 * Advertising Router is not equal to the router's own Router ID
1761 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1762 */
1763
1764 if(lsa->data->type == OSPF_NETWORK_LSA)
1765 {
hasso52dc7ee2004-09-23 19:18:23 +00001766 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001767 int Flag = 0;
1768
1769 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1770 {
1771 struct ospf_interface *out_if = getdata(oi_node);
1772 if(out_if == NULL)
1773 break;
1774
1775 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1776 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1777 {
1778 if(out_if->network_lsa_self)
1779 {
1780 ospf_lsa_flush_area(lsa,out_if->area);
1781 if(IS_DEBUG_OSPF_EVENT)
1782 zlog_info ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
1783 lsa, (int) lsa->data->type);
1784 ospf_lsa_discard (lsa);
1785 Flag = 1;
1786 }
1787 break;
1788 }
1789 }
1790 if(Flag)
1791 continue;
1792 }
paul718e3742002-12-13 20:15:29 +00001793
1794 /* (5) Find the instance of this LSA that is currently contained
1795 in the router's link state database. If there is no
1796 database copy, or the received LSA is more recent than
1797 the database copy the following steps must be performed. */
1798
1799 if (current == NULL ||
1800 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1801 {
1802 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001803 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001804 DISCARD_LSA (lsa, 4);
1805 continue;
1806 }
1807
1808 /* (6) Else, If there is an instance of the LSA on the sending
1809 neighbor's Link state request list, an error has occurred in
1810 the Database Exchange process. In this case, restart the
1811 Database Exchange process by generating the neighbor event
1812 BadLSReq for the sending neighbor and stop processing the
1813 Link State Update packet. */
1814
1815 if (ospf_ls_request_lookup (nbr, lsa))
1816 {
1817 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1818 zlog_warn ("LSA instance exists on Link state request list");
1819
1820 /* Clean list of LSAs. */
1821 ospf_upd_list_clean (lsas);
1822 /* this lsa is not on lsas list already. */
1823 ospf_lsa_discard (lsa);
1824#ifdef HAVE_OPAQUE_LSA
1825 list_delete (mylsa_acks);
1826 list_delete (mylsa_upds);
1827#endif /* HAVE_OPAQUE_LSA */
1828 return;
1829 }
1830
1831 /* If the received LSA is the same instance as the database copy
1832 (i.e., neither one is more recent) the following two steps
1833 should be performed: */
1834
1835 if (ret == 0)
1836 {
1837 /* If the LSA is listed in the Link state retransmission list
1838 for the receiving adjacency, the router itself is expecting
1839 an acknowledgment for this LSA. The router should treat the
1840 received LSA as an acknowledgment by removing the LSA from
1841 the Link state retransmission list. This is termed an
1842 "implied acknowledgment". */
1843
1844 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1845
1846 if (ls_ret != NULL)
1847 {
1848 ospf_ls_retransmit_delete (nbr, ls_ret);
1849
1850 /* Delayed acknowledgment sent if advertisement received
1851 from Designated Router, otherwise do nothing. */
1852 if (oi->state == ISM_Backup)
1853 if (NBR_IS_DR (nbr))
1854 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1855
1856 DISCARD_LSA (lsa, 5);
1857 }
1858 else
1859 /* Acknowledge the receipt of the LSA by sending a
1860 Link State Acknowledgment packet back out the receiving
1861 interface. */
1862 {
1863 ospf_ls_ack_send (nbr, lsa);
1864 DISCARD_LSA (lsa, 6);
1865 }
1866 }
1867
1868 /* The database copy is more recent. If the database copy
1869 has LS age equal to MaxAge and LS sequence number equal to
1870 MaxSequenceNumber, simply discard the received LSA without
1871 acknowledging it. (In this case, the LSA's LS sequence number is
1872 wrapping, and the MaxSequenceNumber LSA must be completely
1873 flushed before any new LSA instance can be introduced). */
1874
1875 else if (ret > 0) /* Database copy is more recent */
1876 {
1877 if (IS_LSA_MAXAGE (current) &&
1878 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1879 {
1880 DISCARD_LSA (lsa, 7);
1881 }
1882 /* Otherwise, as long as the database copy has not been sent in a
1883 Link State Update within the last MinLSArrival seconds, send the
1884 database copy back to the sending neighbor, encapsulated within
1885 a Link State Update Packet. The Link State Update Packet should
1886 be sent directly to the neighbor. In so doing, do not put the
1887 database copy of the LSA on the neighbor's link state
1888 retransmission list, and do not acknowledge the received (less
1889 recent) LSA instance. */
1890 else
1891 {
1892 struct timeval now;
1893
1894 gettimeofday (&now, NULL);
1895
1896 if (tv_cmp (tv_sub (now, current->tv_orig),
1897 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1898 /* Trap NSSA type later.*/
1899 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1900 DISCARD_LSA (lsa, 8);
1901 }
1902 }
1903 }
1904
1905#ifdef HAVE_OPAQUE_LSA
1906 /*
1907 * Now that previously originated Opaque-LSAs those which not yet
1908 * installed into LSDB are captured, take several steps to clear
1909 * them completely from the routing domain, before proceeding to
1910 * origination for the current target Opaque-LSAs.
1911 */
1912 while (listcount (mylsa_acks) > 0)
1913 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1914
1915 if (listcount (mylsa_upds) > 0)
1916 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1917
1918 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001919 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001920#endif /* HAVE_OPAQUE_LSA */
1921
1922 assert (listcount (lsas) == 0);
1923 list_delete (lsas);
1924}
1925
1926/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1927void
1928ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1929 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1930{
1931 struct ospf_neighbor *nbr;
1932#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001933 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001934#endif /* HAVE_OPAQUE_LSA */
1935
1936 /* increment statistics. */
1937 oi->ls_ack_in++;
1938
pauld3f0d622004-05-05 15:27:15 +00001939 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001940 if (nbr == NULL)
1941 {
1942 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1943 inet_ntoa (ospfh->router_id));
1944 return;
1945 }
1946
1947 if (nbr->state < NSM_Exchange)
1948 {
1949 zlog_warn ("Link State Acknowledgment: State is less than Exchange.");
1950 return;
1951 }
1952
1953#ifdef HAVE_OPAQUE_LSA
1954 opaque_acks = list_new ();
1955#endif /* HAVE_OPAQUE_LSA */
1956
1957 while (size >= OSPF_LSA_HEADER_SIZE)
1958 {
1959 struct ospf_lsa *lsa, *lsr;
1960
1961 lsa = ospf_lsa_new ();
1962 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1963
1964 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1965 size -= OSPF_LSA_HEADER_SIZE;
1966 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1967
1968 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1969 {
1970 lsa->data = NULL;
1971 ospf_lsa_discard (lsa);
1972 continue;
1973 }
1974
1975 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1976
1977 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1978 {
1979#ifdef HAVE_OPAQUE_LSA
1980 /* Keep this LSA entry for later reference. */
1981 if (IS_OPAQUE_LSA (lsr->data->type))
1982 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
1983#endif /* HAVE_OPAQUE_LSA */
1984
1985 ospf_ls_retransmit_delete (nbr, lsr);
1986 }
1987
1988 lsa->data = NULL;
1989 ospf_lsa_discard (lsa);
1990 }
1991
1992#ifdef HAVE_OPAQUE_LSA
1993 if (listcount (opaque_acks) > 0)
1994 ospf_opaque_ls_ack_received (nbr, opaque_acks);
1995
1996 list_delete (opaque_acks);
1997 return;
1998#endif /* HAVE_OPAQUE_LSA */
1999}
2000
2001struct stream *
2002ospf_recv_packet (int fd, struct interface **ifp)
2003{
2004 int ret;
2005 struct ip iph;
2006 u_int16_t ip_len;
2007 struct stream *ibuf;
2008 unsigned int ifindex = 0;
2009 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002010#if defined(CMSG_SPACE)
2011 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002012 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
gdtd0deca62004-08-26 13:14:07 +00002013#else
hassoeb1ce602004-10-08 08:17:22 +00002014 char buff [sizeof (struct cmsghdr) + SOPT_SIZE_CMSG_IFINDEX_IPV4()];
gdtd0deca62004-08-26 13:14:07 +00002015#endif
paul2dd8bb42004-07-23 15:13:48 +00002016 struct msghdr msgh;
2017
paul68defd62004-09-27 07:27:13 +00002018 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002019 msgh.msg_iov = &iov;
2020 msgh.msg_iovlen = 1;
2021 msgh.msg_control = (caddr_t) buff;
2022 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002023
paul718e3742002-12-13 20:15:29 +00002024 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2025
2026 if (ret != sizeof (iph))
2027 {
2028 zlog_warn ("ospf_recv_packet packet smaller than ip header");
2029 return NULL;
2030 }
paul18b12c32004-10-05 14:38:29 +00002031
2032 sockopt_iphdrincl_swab_systoh (&iph);
2033
paul6b333612004-10-11 10:11:25 +00002034 ip_len = iph.ip_len;
2035
paul239aecc2003-12-08 10:34:54 +00002036#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002037 /*
2038 * Kernel network code touches incoming IP header parameters,
2039 * before protocol specific processing.
2040 *
2041 * 1) Convert byteorder to host representation.
2042 * --> ip_len, ip_id, ip_off
2043 *
2044 * 2) Adjust ip_len to strip IP header size!
2045 * --> If user process receives entire IP packet via RAW
2046 * socket, it must consider adding IP header size to
2047 * the "ip_len" field of "ip" structure.
2048 *
2049 * For more details, see <netinet/ip_input.c>.
2050 */
2051 ip_len = ip_len + (iph.ip_hl << 2);
2052#endif
2053
2054 ibuf = stream_new (ip_len);
2055 iov.iov_base = STREAM_DATA (ibuf);
2056 iov.iov_len = ip_len;
2057 ret = recvmsg (fd, &msgh, 0);
2058
paul863082d2004-08-19 04:43:43 +00002059 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002060
2061 *ifp = if_lookup_by_index (ifindex);
2062
2063 if (ret != ip_len)
2064 {
2065 zlog_warn ("ospf_recv_packet short read. "
2066 "ip_len %d bytes read %d", ip_len, ret);
2067 stream_free (ibuf);
2068 return NULL;
2069 }
2070
2071 return ibuf;
2072}
2073
2074struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002075ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002076 struct ip *iph, struct ospf_header *ospfh)
2077{
2078 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002079 struct ospf_vl_data *vl_data;
2080 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002081 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002082
2083 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2084 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002085 return NULL;
paul718e3742002-12-13 20:15:29 +00002086
pauld3f0d622004-05-05 15:27:15 +00002087 /* look for local OSPF interface matching the destination
2088 * to determine Area ID. We presume therefore the destination address
2089 * is unique, or at least (for "unnumbered" links), not used in other
2090 * areas
2091 */
2092 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2093 iph->ip_dst)) == NULL)
2094 return NULL;
paul718e3742002-12-13 20:15:29 +00002095
paul020709f2003-04-04 02:44:16 +00002096 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002097 {
2098 if ((vl_data = getdata (node)) == NULL)
2099 continue;
2100
paul020709f2003-04-04 02:44:16 +00002101 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002102 if (!vl_area)
2103 continue;
2104
2105 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2106 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2107 {
2108 if (IS_DEBUG_OSPF_EVENT)
2109 zlog_info ("associating packet with %s",
2110 IF_NAME (vl_data->vl_oi));
2111 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2112 {
2113 if (IS_DEBUG_OSPF_EVENT)
2114 zlog_info ("This VL is not up yet, sorry");
2115 return NULL;
2116 }
2117
2118 return vl_data->vl_oi;
2119 }
2120 }
2121
2122 if (IS_DEBUG_OSPF_EVENT)
2123 zlog_info ("couldn't find any VL to associate the packet with");
2124
pauld3f0d622004-05-05 15:27:15 +00002125 return NULL;
paul718e3742002-12-13 20:15:29 +00002126}
2127
2128int
2129ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2130{
2131 /* Check match the Area ID of the receiving interface. */
2132 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2133 return 1;
2134
2135 return 0;
2136}
2137
2138/* Unbound socket will accept any Raw IP packets if proto is matched.
2139 To prevent it, compare src IP address and i/f address with masking
2140 i/f network mask. */
2141int
2142ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2143{
2144 struct in_addr mask, me, him;
2145
2146 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2147 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2148 return 1;
2149
2150 masklen2ip (oi->address->prefixlen, &mask);
2151
2152 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2153 him.s_addr = ip_src.s_addr & mask.s_addr;
2154
2155 if (IPV4_ADDR_SAME (&me, &him))
2156 return 1;
2157
2158 return 0;
2159}
2160
2161int
2162ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2163 struct ospf_header *ospfh)
2164{
2165 int ret = 0;
2166 struct crypt_key *ck;
2167
2168 switch (ntohs (ospfh->auth_type))
2169 {
2170 case OSPF_AUTH_NULL:
2171 ret = 1;
2172 break;
2173 case OSPF_AUTH_SIMPLE:
2174 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2175 ret = 1;
2176 else
2177 ret = 0;
2178 break;
2179 case OSPF_AUTH_CRYPTOGRAPHIC:
2180 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2181 {
2182 ret = 0;
2183 break;
2184 }
2185
2186 /* This is very basic, the digest processing is elsewhere */
2187 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2188 ospfh->u.crypt.key_id == ck->key_id &&
2189 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2190 ret = 1;
2191 else
2192 ret = 0;
2193 break;
2194 default:
2195 ret = 0;
2196 break;
2197 }
2198
2199 return ret;
2200}
2201
2202int
2203ospf_check_sum (struct ospf_header *ospfh)
2204{
2205 u_int32_t ret;
2206 u_int16_t sum;
2207 int in_cksum (void *ptr, int nbytes);
2208
2209 /* clear auth_data for checksum. */
2210 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2211
2212 /* keep checksum and clear. */
2213 sum = ospfh->checksum;
2214 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2215
2216 /* calculate checksum. */
2217 ret = in_cksum (ospfh, ntohs (ospfh->length));
2218
2219 if (ret != sum)
2220 {
2221 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2222 ret, sum);
2223 return 0;
2224 }
2225
2226 return 1;
2227}
2228
2229/* OSPF Header verification. */
2230int
2231ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2232 struct ip *iph, struct ospf_header *ospfh)
2233{
2234 /* check version. */
2235 if (ospfh->version != OSPF_VERSION)
2236 {
2237 zlog_warn ("interface %s: ospf_read version number mismatch.",
2238 IF_NAME (oi));
2239 return -1;
2240 }
2241
2242 /* Check Area ID. */
2243 if (!ospf_check_area_id (oi, ospfh))
2244 {
2245 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2246 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2247 return -1;
2248 }
2249
2250 /* Check network mask, Silently discarded. */
2251 if (! ospf_check_network_mask (oi, iph->ip_src))
2252 {
2253 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2254 IF_NAME (oi), inet_ntoa (iph->ip_src));
2255 return -1;
2256 }
2257
2258 /* Check authentication. */
2259 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2260 {
2261 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2262 IF_NAME (oi));
2263 return -1;
2264 }
2265
2266 if (! ospf_check_auth (oi, ibuf, ospfh))
2267 {
2268 zlog_warn ("interface %s: ospf_read authentication failed.",
2269 IF_NAME (oi));
2270 return -1;
2271 }
2272
2273 /* if check sum is invalid, packet is discarded. */
2274 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2275 {
2276 if (! ospf_check_sum (ospfh))
2277 {
2278 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2279 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2280 return -1;
2281 }
2282 }
2283 else
2284 {
2285 if (ospfh->checksum != 0)
2286 return -1;
2287 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2288 {
2289 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2290 IF_NAME (oi));
2291 return -1;
2292 }
2293 }
2294
2295 return 0;
2296}
2297
2298/* Starting point of packet process function. */
2299int
2300ospf_read (struct thread *thread)
2301{
2302 int ret;
2303 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002304 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002305 struct ospf_interface *oi;
2306 struct ip *iph;
2307 struct ospf_header *ospfh;
2308 u_int16_t length;
2309 struct interface *ifp;
2310
2311 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002312 ospf = THREAD_ARG (thread);
2313 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002314
2315 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002316 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002317 if (ibuf == NULL)
2318 return -1;
2319
paul06f953f2004-10-22 17:00:38 +00002320 iph = (struct ip *) STREAM_DATA (ibuf);
2321 sockopt_iphdrincl_swab_systoh (iph);
2322
paulac191232004-10-22 12:05:17 +00002323 /* openbsd lacks IP_RECVIF */
2324#if !(defined(IP_PKTINFO) || defined(IP_RECVIF))
2325 if (ifp == NULL)
2326 ifp = if_lookup_address (iph->ip_src);
2327#endif /* !((defined(IP_PKTINFO) || defined(IP_RECVIF)) */
2328
pauld3f0d622004-05-05 15:27:15 +00002329 if (ifp == NULL)
2330 {
2331 stream_free (ibuf);
2332 return 0;
2333 }
paul6b333612004-10-11 10:11:25 +00002334
paul718e3742002-12-13 20:15:29 +00002335 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002336 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002337
2338 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002339 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002340 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002341
paul718e3742002-12-13 20:15:29 +00002342 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002343 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002344 {
pauld3241812003-09-29 12:42:39 +00002345 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2346 {
2347 zlog_info ("ospf_read[%s]: Dropping self-originated packet",
2348 inet_ntoa (iph->ip_src));
2349 }
paul718e3742002-12-13 20:15:29 +00002350 stream_free (ibuf);
2351 return 0;
2352 }
2353
2354 /* Adjust size to message length. */
2355 stream_forward (ibuf, iph->ip_hl * 4);
2356
2357 /* Get ospf packet header. */
2358 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2359
2360 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002361 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002362
2363 /* if no local ospf_interface,
2364 * or header area is backbone but ospf_interface is not
2365 * check for VLINK interface
2366 */
2367 if ( (oi == NULL) ||
2368 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2369 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2370 )
2371 {
2372 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2373 {
2374 zlog_warn ("Packet from [%s] received on link %s"
2375 " but no ospf_interface",
2376 inet_ntoa (iph->ip_src), ifp->name);
2377 stream_free (ibuf);
2378 return 0;
2379 }
2380 }
2381
2382 /* else it must be a local ospf interface, check it was received on
2383 * correct link
2384 */
2385 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002386 {
2387 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002388 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002389 stream_free (ibuf);
2390 return 0;
2391 }
paul718e3742002-12-13 20:15:29 +00002392
2393 /*
2394 * If the received packet is destined for AllDRouters, the packet
2395 * should be accepted only if the received ospf interface state is
2396 * either DR or Backup -- endo.
2397 */
2398 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2399 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2400 {
2401 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2402 inet_ntoa (iph->ip_src), IF_NAME (oi),
2403 LOOKUP (ospf_ism_state_msg, oi->state));
2404 stream_free (ibuf);
2405 return 0;
2406 }
2407
2408 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002409 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2410 {
paul718e3742002-12-13 20:15:29 +00002411 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002412 {
2413 zlog_info ("-----------------------------------------------------");
2414 ospf_packet_dump (ibuf);
2415 }
paul718e3742002-12-13 20:15:29 +00002416
2417 zlog_info ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002418 ospf_packet_type_str[ospfh->type],
2419 inet_ntoa (ospfh->router_id), IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +00002420 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2421 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2422
2423 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2424 zlog_info ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002425 }
paul718e3742002-12-13 20:15:29 +00002426
2427 /* Some header verification. */
2428 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2429 if (ret < 0)
2430 {
pauld3241812003-09-29 12:42:39 +00002431 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2432 {
2433 zlog_info ("ospf_read[%s/%s]: Header check failed, "
2434 "dropping.",
2435 ospf_packet_type_str[ospfh->type],
2436 inet_ntoa (iph->ip_src));
2437 }
paul718e3742002-12-13 20:15:29 +00002438 stream_free (ibuf);
2439 return ret;
2440 }
2441
2442 stream_forward (ibuf, OSPF_HEADER_SIZE);
2443
2444 /* Adjust size to message length. */
2445 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2446
2447 /* Read rest of the packet and call each sort of packet routine. */
2448 switch (ospfh->type)
2449 {
2450 case OSPF_MSG_HELLO:
2451 ospf_hello (iph, ospfh, ibuf, oi, length);
2452 break;
2453 case OSPF_MSG_DB_DESC:
2454 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2455 break;
2456 case OSPF_MSG_LS_REQ:
2457 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2458 break;
2459 case OSPF_MSG_LS_UPD:
2460 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2461 break;
2462 case OSPF_MSG_LS_ACK:
2463 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2464 break;
2465 default:
2466 zlog (NULL, LOG_WARNING,
2467 "interface %s: OSPF packet header type %d is illegal",
2468 IF_NAME (oi), ospfh->type);
2469 break;
2470 }
2471
2472 stream_free (ibuf);
2473 return 0;
2474}
2475
2476/* Make OSPF header. */
2477void
2478ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2479{
2480 struct ospf_header *ospfh;
2481
2482 ospfh = (struct ospf_header *) STREAM_DATA (s);
2483
2484 ospfh->version = (u_char) OSPF_VERSION;
2485 ospfh->type = (u_char) type;
2486
paul68980082003-03-25 05:07:42 +00002487 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002488
2489 ospfh->checksum = 0;
2490 ospfh->area_id = oi->area->area_id;
2491 ospfh->auth_type = htons (ospf_auth_type (oi));
2492
2493 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2494
2495 ospf_output_forward (s, OSPF_HEADER_SIZE);
2496}
2497
2498/* Make Authentication Data. */
2499int
2500ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2501{
2502 struct crypt_key *ck;
2503
2504 switch (ospf_auth_type (oi))
2505 {
2506 case OSPF_AUTH_NULL:
2507 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2508 break;
2509 case OSPF_AUTH_SIMPLE:
2510 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2511 OSPF_AUTH_SIMPLE_SIZE);
2512 break;
2513 case OSPF_AUTH_CRYPTOGRAPHIC:
2514 /* If key is not set, then set 0. */
2515 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2516 {
2517 ospfh->u.crypt.zero = 0;
2518 ospfh->u.crypt.key_id = 0;
2519 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2520 }
2521 else
2522 {
2523 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2524 ospfh->u.crypt.zero = 0;
2525 ospfh->u.crypt.key_id = ck->key_id;
2526 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2527 }
2528 /* note: the seq is done in ospf_make_md5_digest() */
2529 break;
2530 default:
2531 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2532 break;
2533 }
2534
2535 return 0;
2536}
2537
2538/* Fill rest of OSPF header. */
2539void
2540ospf_fill_header (struct ospf_interface *oi,
2541 struct stream *s, u_int16_t length)
2542{
2543 struct ospf_header *ospfh;
2544
2545 ospfh = (struct ospf_header *) STREAM_DATA (s);
2546
2547 /* Fill length. */
2548 ospfh->length = htons (length);
2549
2550 /* Calculate checksum. */
2551 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2552 ospfh->checksum = in_cksum (ospfh, length);
2553 else
2554 ospfh->checksum = 0;
2555
2556 /* Add Authentication Data. */
2557 ospf_make_auth (oi, ospfh);
2558}
2559
2560int
2561ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2562{
2563 struct ospf_neighbor *nbr;
2564 struct route_node *rn;
2565 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2566 struct in_addr mask;
2567 unsigned long p;
2568 int flag = 0;
2569
2570 /* Set netmask of interface. */
2571 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2572 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2573 masklen2ip (oi->address->prefixlen, &mask);
2574 else
2575 memset ((char *) &mask, 0, sizeof (struct in_addr));
2576 stream_put_ipv4 (s, mask.s_addr);
2577
2578 /* Set Hello Interval. */
2579 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2580
2581 if (IS_DEBUG_OSPF_EVENT)
2582 zlog_info ("make_hello: options: %x, int: %s",
2583 OPTIONS(oi), IF_NAME (oi));
2584
2585 /* Set Options. */
2586 stream_putc (s, OPTIONS (oi));
2587
2588 /* Set Router Priority. */
2589 stream_putc (s, PRIORITY (oi));
2590
2591 /* Set Router Dead Interval. */
2592 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2593
2594 /* Set Designated Router. */
2595 stream_put_ipv4 (s, DR (oi).s_addr);
2596
2597 p = s->putp;
2598
2599 /* Set Backup Designated Router. */
2600 stream_put_ipv4 (s, BDR (oi).s_addr);
2601
2602 /* Add neighbor seen. */
2603 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002604 if ((nbr = rn->info))
2605 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2606 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2607 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2608 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002609 {
2610 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002611 if (nbr->d_router.s_addr != 0
2612 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2613 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2614 flag = 1;
paul718e3742002-12-13 20:15:29 +00002615
2616 stream_put_ipv4 (s, nbr->router_id.s_addr);
2617 length += 4;
2618 }
2619
2620 /* Let neighbor generate BackupSeen. */
2621 if (flag == 1)
2622 {
2623 stream_set_putp (s, p);
2624 stream_put_ipv4 (s, 0);
2625 }
2626
2627 return length;
2628}
2629
2630int
2631ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2632 struct stream *s)
2633{
2634 struct ospf_lsa *lsa;
2635 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2636 u_char options;
2637 unsigned long pp;
2638 int i;
2639 struct ospf_lsdb *lsdb;
2640
2641 /* Set Interface MTU. */
2642 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2643 stream_putw (s, 0);
2644 else
2645 stream_putw (s, oi->ifp->mtu);
2646
2647 /* Set Options. */
2648 options = OPTIONS (oi);
2649#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002650 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002651 {
2652 if (IS_SET_DD_I (nbr->dd_flags)
2653 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2654 /*
2655 * Set O-bit in the outgoing DD packet for capablity negotiation,
2656 * if one of following case is applicable.
2657 *
2658 * 1) WaitTimer expiration event triggered the neighbor state to
2659 * change to Exstart, but no (valid) DD packet has received
2660 * from the neighbor yet.
2661 *
2662 * 2) At least one DD packet with O-bit on has received from the
2663 * neighbor.
2664 */
2665 SET_FLAG (options, OSPF_OPTION_O);
2666 }
2667#endif /* HAVE_OPAQUE_LSA */
2668 stream_putc (s, options);
2669
2670 /* Keep pointer to flags. */
2671 pp = stream_get_putp (s);
2672 stream_putc (s, nbr->dd_flags);
2673
2674 /* Set DD Sequence Number. */
2675 stream_putl (s, nbr->dd_seqnum);
2676
2677 if (ospf_db_summary_isempty (nbr))
2678 {
2679 if (nbr->state >= NSM_Exchange)
2680 {
2681 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2682 /* Set DD flags again */
2683 stream_set_putp (s, pp);
2684 stream_putc (s, nbr->dd_flags);
2685 }
2686 return length;
2687 }
2688
2689 /* Describe LSA Header from Database Summary List. */
2690 lsdb = &nbr->db_sum;
2691
2692 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2693 {
2694 struct route_table *table = lsdb->type[i].db;
2695 struct route_node *rn;
2696
2697 for (rn = route_top (table); rn; rn = route_next (rn))
2698 if ((lsa = rn->info) != NULL)
2699 {
2700#ifdef HAVE_OPAQUE_LSA
2701 if (IS_OPAQUE_LSA (lsa->data->type)
2702 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2703 {
2704 /* Suppress advertising opaque-informations. */
2705 /* Remove LSA from DB summary list. */
2706 ospf_lsdb_delete (lsdb, lsa);
2707 continue;
2708 }
2709#endif /* HAVE_OPAQUE_LSA */
2710
2711 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2712 {
2713 struct lsa_header *lsah;
2714 u_int16_t ls_age;
2715
2716 /* DD packet overflows interface MTU. */
2717 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2718 break;
2719
2720 /* Keep pointer to LS age. */
2721 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2722 stream_get_putp (s));
2723
2724 /* Proceed stream pointer. */
2725 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2726 length += OSPF_LSA_HEADER_SIZE;
2727
2728 /* Set LS age. */
2729 ls_age = LS_AGE (lsa);
2730 lsah->ls_age = htons (ls_age);
2731
2732 }
2733
2734 /* Remove LSA from DB summary list. */
2735 ospf_lsdb_delete (lsdb, lsa);
2736 }
2737 }
2738
2739 return length;
2740}
2741
2742int
2743ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2744 unsigned long delta, struct ospf_neighbor *nbr,
2745 struct ospf_lsa *lsa)
2746{
2747 struct ospf_interface *oi;
2748
2749 oi = nbr->oi;
2750
2751 /* LS Request packet overflows interface MTU. */
2752 if (*length + delta > OSPF_PACKET_MAX(oi))
2753 return 0;
2754
2755 stream_putl (s, lsa->data->type);
2756 stream_put_ipv4 (s, lsa->data->id.s_addr);
2757 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2758
2759 ospf_lsa_unlock (nbr->ls_req_last);
2760 nbr->ls_req_last = ospf_lsa_lock (lsa);
2761
2762 *length += 12;
2763 return 1;
2764}
2765
2766int
2767ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2768{
2769 struct ospf_lsa *lsa;
2770 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2771 unsigned long delta = stream_get_putp(s)+12;
2772 struct route_table *table;
2773 struct route_node *rn;
2774 int i;
2775 struct ospf_lsdb *lsdb;
2776
2777 lsdb = &nbr->ls_req;
2778
2779 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2780 {
2781 table = lsdb->type[i].db;
2782 for (rn = route_top (table); rn; rn = route_next (rn))
2783 if ((lsa = (rn->info)) != NULL)
2784 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2785 {
2786 route_unlock_node (rn);
2787 break;
2788 }
2789 }
2790 return length;
2791}
2792
2793int
2794ls_age_increment (struct ospf_lsa *lsa, int delay)
2795{
2796 int age;
2797
2798 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2799
2800 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2801}
2802
2803int
hasso52dc7ee2004-09-23 19:18:23 +00002804ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002805{
2806 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002807 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002808 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2809 unsigned long delta = stream_get_putp (s);
2810 unsigned long pp;
2811 int count = 0;
2812
2813 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002814 zlog_info ("ospf_make_ls_upd: Start");
2815
paul718e3742002-12-13 20:15:29 +00002816 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002817 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002818
2819 while ((node = listhead (update)) != NULL)
2820 {
2821 struct lsa_header *lsah;
2822 u_int16_t ls_age;
2823
2824 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002825 zlog_info ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002826
2827 lsa = getdata (node);
2828 assert (lsa);
2829 assert (lsa->data);
2830
paul68b73392004-09-12 14:21:37 +00002831 /* Will it fit? */
2832 if (length + delta + ntohs (lsa->data->length) > stream_get_size (s))
paul59ea14c2004-07-14 20:50:36 +00002833 break;
2834
paul718e3742002-12-13 20:15:29 +00002835 /* Keep pointer to LS age. */
2836 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2837
2838 /* Put LSA to Link State Request. */
2839 stream_put (s, lsa->data, ntohs (lsa->data->length));
2840
2841 /* Set LS age. */
2842 /* each hop must increment an lsa_age by transmit_delay
2843 of OSPF interface */
2844 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2845 lsah->ls_age = htons (ls_age);
2846
2847 length += ntohs (lsa->data->length);
2848 count++;
2849
2850 list_delete_node (update, node);
2851 ospf_lsa_unlock (lsa);
2852 }
2853
2854 /* Now set #LSAs. */
2855 stream_set_putp (s, pp);
2856 stream_putl (s, count);
2857
2858 stream_set_putp (s, s->endp);
2859
2860 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002861 zlog_info ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002862 return length;
2863}
2864
2865int
hasso52dc7ee2004-09-23 19:18:23 +00002866ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002867{
hasso52dc7ee2004-09-23 19:18:23 +00002868 struct list *rm_list;
2869 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002870 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2871 unsigned long delta = stream_get_putp(s) + 24;
2872 struct ospf_lsa *lsa;
2873
2874 rm_list = list_new ();
2875
2876 for (node = listhead (ack); node; nextnode (node))
2877 {
2878 lsa = getdata (node);
2879 assert (lsa);
2880
2881 if (length + delta > OSPF_PACKET_MAX (oi))
2882 break;
2883
2884 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2885 length += OSPF_LSA_HEADER_SIZE;
2886
2887 listnode_add (rm_list, lsa);
2888 }
2889
2890 /* Remove LSA from LS-Ack list. */
2891 for (node = listhead (rm_list); node; nextnode (node))
2892 {
2893 lsa = (struct ospf_lsa *) getdata (node);
2894
2895 listnode_delete (ack, lsa);
2896 ospf_lsa_unlock (lsa);
2897 }
2898
2899 list_delete (rm_list);
2900
2901 return length;
2902}
2903
2904void
2905ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2906{
2907 struct ospf_packet *op;
2908 u_int16_t length = OSPF_HEADER_SIZE;
2909
2910 op = ospf_packet_new (oi->ifp->mtu);
2911
2912 /* Prepare OSPF common header. */
2913 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2914
2915 /* Prepare OSPF Hello body. */
2916 length += ospf_make_hello (oi, op->s);
2917
2918 /* Fill OSPF header. */
2919 ospf_fill_header (oi, op->s, length);
2920
2921 /* Set packet length. */
2922 op->length = length;
2923
2924 op->dst.s_addr = addr->s_addr;
2925
2926 /* Add packet to the interface output queue. */
2927 ospf_packet_add (oi, op);
2928
2929 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002930 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002931}
2932
2933void
2934ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2935{
2936 struct ospf_interface *oi;
2937
2938 oi = nbr_nbma->oi;
2939 assert(oi);
2940
2941 /* If this is passive interface, do not send OSPF Hello. */
2942 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2943 return;
2944
2945 if (oi->type != OSPF_IFTYPE_NBMA)
2946 return;
2947
2948 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2949 return;
2950
2951 if (PRIORITY(oi) == 0)
2952 return;
2953
2954 if (nbr_nbma->priority == 0
2955 && oi->state != ISM_DR && oi->state != ISM_Backup)
2956 return;
2957
2958 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2959}
2960
2961int
2962ospf_poll_timer (struct thread *thread)
2963{
2964 struct ospf_nbr_nbma *nbr_nbma;
2965
2966 nbr_nbma = THREAD_ARG (thread);
2967 nbr_nbma->t_poll = NULL;
2968
2969 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2970 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2971 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2972
2973 ospf_poll_send (nbr_nbma);
2974
2975 if (nbr_nbma->v_poll > 0)
2976 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2977 nbr_nbma->v_poll);
2978
2979 return 0;
2980}
2981
2982
2983int
2984ospf_hello_reply_timer (struct thread *thread)
2985{
2986 struct ospf_neighbor *nbr;
2987
2988 nbr = THREAD_ARG (thread);
2989 nbr->t_hello_reply = NULL;
2990
2991 assert (nbr->oi);
2992
2993 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2994 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2995 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2996
2997 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2998
2999 return 0;
3000}
3001
3002/* Send OSPF Hello. */
3003void
3004ospf_hello_send (struct ospf_interface *oi)
3005{
3006 struct ospf_packet *op;
3007 u_int16_t length = OSPF_HEADER_SIZE;
3008
3009 /* If this is passive interface, do not send OSPF Hello. */
3010 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3011 return;
3012
3013 op = ospf_packet_new (oi->ifp->mtu);
3014
3015 /* Prepare OSPF common header. */
3016 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3017
3018 /* Prepare OSPF Hello body. */
3019 length += ospf_make_hello (oi, op->s);
3020
3021 /* Fill OSPF header. */
3022 ospf_fill_header (oi, op->s, length);
3023
3024 /* Set packet length. */
3025 op->length = length;
3026
3027 if (oi->type == OSPF_IFTYPE_NBMA)
3028 {
3029 struct ospf_neighbor *nbr;
3030 struct route_node *rn;
3031
3032 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3033 if ((nbr = rn->info))
3034 if (nbr != oi->nbr_self)
3035 if (nbr->state != NSM_Down)
3036 {
3037 /* RFC 2328 Section 9.5.1
3038 If the router is not eligible to become Designated Router,
3039 it must periodically send Hello Packets to both the
3040 Designated Router and the Backup Designated Router (if they
3041 exist). */
3042 if (PRIORITY(oi) == 0 &&
3043 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3044 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3045 continue;
3046
3047 /* If the router is eligible to become Designated Router, it
3048 must periodically send Hello Packets to all neighbors that
3049 are also eligible. In addition, if the router is itself the
3050 Designated Router or Backup Designated Router, it must also
3051 send periodic Hello Packets to all other neighbors. */
3052
3053 if (nbr->priority == 0 && oi->state == ISM_DROther)
3054 continue;
3055 /* if oi->state == Waiting, send hello to all neighbors */
3056 {
3057 struct ospf_packet *op_dup;
3058
3059 op_dup = ospf_packet_dup(op);
3060 op_dup->dst = nbr->address.u.prefix4;
3061
3062 /* Add packet to the interface output queue. */
3063 ospf_packet_add (oi, op_dup);
3064
paul020709f2003-04-04 02:44:16 +00003065 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003066 }
3067
3068 }
3069 ospf_packet_free (op);
3070 }
3071 else
3072 {
3073 /* Decide destination address. */
3074 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3075 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3076 else
3077 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3078
3079 /* Add packet to the interface output queue. */
3080 ospf_packet_add (oi, op);
3081
3082 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003083 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003084 }
3085}
3086
3087/* Send OSPF Database Description. */
3088void
3089ospf_db_desc_send (struct ospf_neighbor *nbr)
3090{
3091 struct ospf_interface *oi;
3092 struct ospf_packet *op;
3093 u_int16_t length = OSPF_HEADER_SIZE;
3094
3095 oi = nbr->oi;
3096 op = ospf_packet_new (oi->ifp->mtu);
3097
3098 /* Prepare OSPF common header. */
3099 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3100
3101 /* Prepare OSPF Database Description body. */
3102 length += ospf_make_db_desc (oi, nbr, op->s);
3103
3104 /* Fill OSPF header. */
3105 ospf_fill_header (oi, op->s, length);
3106
3107 /* Set packet length. */
3108 op->length = length;
3109
3110 /* Decide destination address. */
3111 op->dst = nbr->address.u.prefix4;
3112
3113 /* Add packet to the interface output queue. */
3114 ospf_packet_add (oi, op);
3115
3116 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003117 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003118
3119 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3120 if (nbr->last_send)
3121 ospf_packet_free (nbr->last_send);
3122 nbr->last_send = ospf_packet_dup (op);
3123 gettimeofday (&nbr->last_send_ts, NULL);
3124}
3125
3126/* Re-send Database Description. */
3127void
3128ospf_db_desc_resend (struct ospf_neighbor *nbr)
3129{
3130 struct ospf_interface *oi;
3131
3132 oi = nbr->oi;
3133
3134 /* Add packet to the interface output queue. */
3135 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3136
3137 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003138 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003139}
3140
3141/* Send Link State Request. */
3142void
3143ospf_ls_req_send (struct ospf_neighbor *nbr)
3144{
3145 struct ospf_interface *oi;
3146 struct ospf_packet *op;
3147 u_int16_t length = OSPF_HEADER_SIZE;
3148
3149 oi = nbr->oi;
3150 op = ospf_packet_new (oi->ifp->mtu);
3151
3152 /* Prepare OSPF common header. */
3153 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3154
3155 /* Prepare OSPF Link State Request body. */
3156 length += ospf_make_ls_req (nbr, op->s);
3157 if (length == OSPF_HEADER_SIZE)
3158 {
3159 ospf_packet_free (op);
3160 return;
3161 }
3162
3163 /* Fill OSPF header. */
3164 ospf_fill_header (oi, op->s, length);
3165
3166 /* Set packet length. */
3167 op->length = length;
3168
3169 /* Decide destination address. */
3170 op->dst = nbr->address.u.prefix4;
3171
3172 /* Add packet to the interface output queue. */
3173 ospf_packet_add (oi, op);
3174
3175 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003176 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003177
3178 /* Add Link State Request Retransmission Timer. */
3179 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3180}
3181
3182/* Send Link State Update with an LSA. */
3183void
3184ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3185 int flag)
3186{
hasso52dc7ee2004-09-23 19:18:23 +00003187 struct list *update;
paul718e3742002-12-13 20:15:29 +00003188
3189 update = list_new ();
3190
3191 listnode_add (update, lsa);
3192 ospf_ls_upd_send (nbr, update, flag);
3193
3194 list_delete (update);
3195}
3196
paul68b73392004-09-12 14:21:37 +00003197/* Determine size for packet. Must be at least big enough to accomodate next
3198 * LSA on list, which may be bigger than MTU size.
3199 *
3200 * Return pointer to new ospf_packet
3201 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3202 * on packet sizes (in which case offending LSA is deleted from update list)
3203 */
3204static struct ospf_packet *
3205ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3206{
3207 struct ospf_lsa *lsa;
3208 struct listnode *ln;
3209 size_t size;
3210 static char warned = 0;
3211
3212 ln = listhead (update);
3213 lsa = getdata (ln);
3214 assert (lsa);
3215 assert (lsa->data);
3216
3217 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3218 > ospf_packet_max (oi))
3219 {
3220 if (!warned)
3221 {
3222 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3223 "will need to fragment. Not optimal. Try divide up"
3224 " your network with areas. Use 'debug ospf packet send'"
3225 " to see details, or look at 'show ip ospf database ..'");
3226 warned = 1;
3227 }
3228
3229 if (IS_DEBUG_OSPF_PACKET (0, SEND))
3230 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3231 " %d bytes originated by %s, will be fragmented!",
3232 inet_ntoa (lsa->data->id),
3233 ntohs (lsa->data->length),
3234 inet_ntoa (lsa->data->adv_router));
3235
3236 /*
3237 * Allocate just enough to fit this LSA only, to avoid including other
3238 * LSAs in fragmented LSA Updates.
3239 */
3240 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3241 + OSPF_LS_UPD_MIN_SIZE;
3242 }
3243 else
3244 size = oi->ifp->mtu;
3245
3246 if (size > OSPF_MAX_PACKET_SIZE)
3247 {
3248 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003249 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003250 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003251 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003252 (long int) size);
paul68b73392004-09-12 14:21:37 +00003253 list_delete_node (update, ln);
3254 return NULL;
3255 }
3256
3257 return ospf_packet_new (size);
3258}
3259
paul718e3742002-12-13 20:15:29 +00003260static void
hasso52dc7ee2004-09-23 19:18:23 +00003261ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003262 struct in_addr addr)
3263{
3264 struct ospf_packet *op;
3265 u_int16_t length = OSPF_HEADER_SIZE;
3266
3267 if (IS_DEBUG_OSPF_EVENT)
3268 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003269
3270 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003271
3272 /* Prepare OSPF common header. */
3273 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3274
paul59ea14c2004-07-14 20:50:36 +00003275 /* Prepare OSPF Link State Update body.
3276 * Includes Type-7 translation.
3277 */
paul718e3742002-12-13 20:15:29 +00003278 length += ospf_make_ls_upd (oi, update, op->s);
3279
3280 /* Fill OSPF header. */
3281 ospf_fill_header (oi, op->s, length);
3282
3283 /* Set packet length. */
3284 op->length = length;
3285
3286 /* Decide destination address. */
3287 op->dst.s_addr = addr.s_addr;
3288
3289 /* Add packet to the interface output queue. */
3290 ospf_packet_add (oi, op);
3291
3292 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003293 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003294}
3295
3296static int
3297ospf_ls_upd_send_queue_event (struct thread *thread)
3298{
3299 struct ospf_interface *oi = THREAD_ARG(thread);
3300 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003301 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003302 struct list *update;
paul68b73392004-09-12 14:21:37 +00003303 char again = 0;
paul718e3742002-12-13 20:15:29 +00003304
3305 oi->t_ls_upd_event = NULL;
3306
3307 if (IS_DEBUG_OSPF_EVENT)
3308 zlog_info ("ospf_ls_upd_send_queue start");
3309
paul736d3442003-07-24 23:22:57 +00003310 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003311 {
paul736d3442003-07-24 23:22:57 +00003312 rnext = route_next (rn);
3313
paul718e3742002-12-13 20:15:29 +00003314 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003315 continue;
paul68b73392004-09-12 14:21:37 +00003316
3317 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003318
paul48fe13b2004-07-27 17:40:44 +00003319 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003320
paul68b73392004-09-12 14:21:37 +00003321 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003322 if (listcount(update) == 0)
3323 {
3324 list_delete (rn->info);
3325 rn->info = NULL;
3326 route_unlock_node (rn);
3327 }
3328 else
paul68b73392004-09-12 14:21:37 +00003329 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003330 }
3331
3332 if (again != 0)
3333 {
3334 if (IS_DEBUG_OSPF_EVENT)
3335 zlog_info ("ospf_ls_upd_send_queue: update lists not cleared,"
3336 " %d nodes to try again, raising new event", again);
3337 oi->t_ls_upd_event =
3338 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003339 }
3340
3341 if (IS_DEBUG_OSPF_EVENT)
3342 zlog_info ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003343
paul718e3742002-12-13 20:15:29 +00003344 return 0;
3345}
3346
3347void
hasso52dc7ee2004-09-23 19:18:23 +00003348ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003349{
3350 struct ospf_interface *oi;
3351 struct prefix_ipv4 p;
3352 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003353 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003354
3355 oi = nbr->oi;
3356
3357 p.family = AF_INET;
3358 p.prefixlen = IPV4_MAX_BITLEN;
3359
3360 /* Decide destination address. */
3361 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3362 p.prefix = oi->vl_data->peer_addr;
3363 else if (flag == OSPF_SEND_PACKET_DIRECT)
3364 p.prefix = nbr->address.u.prefix4;
3365 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3366 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3367 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3368 && (flag == OSPF_SEND_PACKET_INDIRECT))
3369 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003370 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3371 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003372 else
3373 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3374
3375 if (oi->type == OSPF_IFTYPE_NBMA)
3376 {
3377 if (flag == OSPF_SEND_PACKET_INDIRECT)
3378 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3379 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3380 zlog_warn ("* LS-Update is sent to myself.");
3381 }
3382
3383 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3384
3385 if (rn->info == NULL)
3386 rn->info = list_new ();
3387
3388 for (n = listhead (update); n; nextnode (n))
3389 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3390
3391 if (oi->t_ls_upd_event == NULL)
3392 oi->t_ls_upd_event =
3393 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3394}
3395
3396static void
hasso52dc7ee2004-09-23 19:18:23 +00003397ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3398 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003399{
3400 struct ospf_packet *op;
3401 u_int16_t length = OSPF_HEADER_SIZE;
3402
3403 op = ospf_packet_new (oi->ifp->mtu);
3404
3405 /* Prepare OSPF common header. */
3406 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3407
3408 /* Prepare OSPF Link State Acknowledgment body. */
3409 length += ospf_make_ls_ack (oi, ack, op->s);
3410
3411 /* Fill OSPF header. */
3412 ospf_fill_header (oi, op->s, length);
3413
3414 /* Set packet length. */
3415 op->length = length;
3416
3417 /* Set destination IP address. */
3418 op->dst = dst;
3419
3420 /* Add packet to the interface output queue. */
3421 ospf_packet_add (oi, op);
3422
3423 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003424 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003425}
3426
3427static int
3428ospf_ls_ack_send_event (struct thread *thread)
3429{
3430 struct ospf_interface *oi = THREAD_ARG (thread);
3431
3432 oi->t_ls_ack_direct = NULL;
3433
3434 while (listcount (oi->ls_ack_direct.ls_ack))
3435 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3436 oi->ls_ack_direct.dst);
3437
3438 return 0;
3439}
3440
3441void
3442ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3443{
3444 struct ospf_interface *oi = nbr->oi;
3445
3446 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3447 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3448
3449 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3450
3451 if (oi->t_ls_ack_direct == NULL)
3452 oi->t_ls_ack_direct =
3453 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3454}
3455
3456/* Send Link State Acknowledgment delayed. */
3457void
3458ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3459{
3460 struct in_addr dst;
3461
3462 /* Decide destination address. */
3463 /* RFC2328 Section 13.5 On non-broadcast
3464 networks, delayed Link State Acknowledgment packets must be
3465 unicast separately over each adjacency (i.e., neighbor whose
3466 state is >= Exchange). */
3467 if (oi->type == OSPF_IFTYPE_NBMA)
3468 {
3469 struct ospf_neighbor *nbr;
3470 struct route_node *rn;
3471
3472 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3473 if ((nbr = rn->info) != NULL)
3474 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3475 while (listcount (oi->ls_ack))
3476 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3477 return;
3478 }
3479 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3480 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3481 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3482 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3483 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3484 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003485 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3486 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003487 else
3488 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3489
3490 while (listcount (oi->ls_ack))
3491 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3492}