blob: 729c8f7ea88dd09777e022ffa1fca02563abc526 [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,
ajs6099b3b2004-11-20 02:06:59 +0000542 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000543
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",
ajs6099b3b2004-11-20 02:06:59 +0000693 inet_ntoa (iph.ip_dst), safe_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 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002011 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002012 struct msghdr msgh;
2013
paul68defd62004-09-27 07:27:13 +00002014 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002015 msgh.msg_iov = &iov;
2016 msgh.msg_iovlen = 1;
2017 msgh.msg_control = (caddr_t) buff;
2018 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002019
paul718e3742002-12-13 20:15:29 +00002020 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2021
2022 if (ret != sizeof (iph))
2023 {
2024 zlog_warn ("ospf_recv_packet packet smaller than ip header");
2025 return NULL;
2026 }
paul18b12c32004-10-05 14:38:29 +00002027
2028 sockopt_iphdrincl_swab_systoh (&iph);
2029
paul6b333612004-10-11 10:11:25 +00002030 ip_len = iph.ip_len;
2031
paul239aecc2003-12-08 10:34:54 +00002032#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002033 /*
2034 * Kernel network code touches incoming IP header parameters,
2035 * before protocol specific processing.
2036 *
2037 * 1) Convert byteorder to host representation.
2038 * --> ip_len, ip_id, ip_off
2039 *
2040 * 2) Adjust ip_len to strip IP header size!
2041 * --> If user process receives entire IP packet via RAW
2042 * socket, it must consider adding IP header size to
2043 * the "ip_len" field of "ip" structure.
2044 *
2045 * For more details, see <netinet/ip_input.c>.
2046 */
2047 ip_len = ip_len + (iph.ip_hl << 2);
2048#endif
2049
2050 ibuf = stream_new (ip_len);
2051 iov.iov_base = STREAM_DATA (ibuf);
2052 iov.iov_len = ip_len;
2053 ret = recvmsg (fd, &msgh, 0);
2054
paul863082d2004-08-19 04:43:43 +00002055 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002056
2057 *ifp = if_lookup_by_index (ifindex);
2058
2059 if (ret != ip_len)
2060 {
2061 zlog_warn ("ospf_recv_packet short read. "
2062 "ip_len %d bytes read %d", ip_len, ret);
2063 stream_free (ibuf);
2064 return NULL;
2065 }
2066
2067 return ibuf;
2068}
2069
2070struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002071ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002072 struct ip *iph, struct ospf_header *ospfh)
2073{
2074 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002075 struct ospf_vl_data *vl_data;
2076 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002077 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002078
2079 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2080 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002081 return NULL;
paul718e3742002-12-13 20:15:29 +00002082
pauld3f0d622004-05-05 15:27:15 +00002083 /* look for local OSPF interface matching the destination
2084 * to determine Area ID. We presume therefore the destination address
2085 * is unique, or at least (for "unnumbered" links), not used in other
2086 * areas
2087 */
2088 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2089 iph->ip_dst)) == NULL)
2090 return NULL;
paul718e3742002-12-13 20:15:29 +00002091
paul020709f2003-04-04 02:44:16 +00002092 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002093 {
2094 if ((vl_data = getdata (node)) == NULL)
2095 continue;
2096
paul020709f2003-04-04 02:44:16 +00002097 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002098 if (!vl_area)
2099 continue;
2100
2101 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2102 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2103 {
2104 if (IS_DEBUG_OSPF_EVENT)
2105 zlog_info ("associating packet with %s",
2106 IF_NAME (vl_data->vl_oi));
2107 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2108 {
2109 if (IS_DEBUG_OSPF_EVENT)
2110 zlog_info ("This VL is not up yet, sorry");
2111 return NULL;
2112 }
2113
2114 return vl_data->vl_oi;
2115 }
2116 }
2117
2118 if (IS_DEBUG_OSPF_EVENT)
2119 zlog_info ("couldn't find any VL to associate the packet with");
2120
pauld3f0d622004-05-05 15:27:15 +00002121 return NULL;
paul718e3742002-12-13 20:15:29 +00002122}
2123
2124int
2125ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2126{
2127 /* Check match the Area ID of the receiving interface. */
2128 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2129 return 1;
2130
2131 return 0;
2132}
2133
2134/* Unbound socket will accept any Raw IP packets if proto is matched.
2135 To prevent it, compare src IP address and i/f address with masking
2136 i/f network mask. */
2137int
2138ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2139{
2140 struct in_addr mask, me, him;
2141
2142 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2143 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2144 return 1;
2145
2146 masklen2ip (oi->address->prefixlen, &mask);
2147
2148 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2149 him.s_addr = ip_src.s_addr & mask.s_addr;
2150
2151 if (IPV4_ADDR_SAME (&me, &him))
2152 return 1;
2153
2154 return 0;
2155}
2156
2157int
2158ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2159 struct ospf_header *ospfh)
2160{
2161 int ret = 0;
2162 struct crypt_key *ck;
2163
2164 switch (ntohs (ospfh->auth_type))
2165 {
2166 case OSPF_AUTH_NULL:
2167 ret = 1;
2168 break;
2169 case OSPF_AUTH_SIMPLE:
2170 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2171 ret = 1;
2172 else
2173 ret = 0;
2174 break;
2175 case OSPF_AUTH_CRYPTOGRAPHIC:
2176 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2177 {
2178 ret = 0;
2179 break;
2180 }
2181
2182 /* This is very basic, the digest processing is elsewhere */
2183 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2184 ospfh->u.crypt.key_id == ck->key_id &&
2185 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2186 ret = 1;
2187 else
2188 ret = 0;
2189 break;
2190 default:
2191 ret = 0;
2192 break;
2193 }
2194
2195 return ret;
2196}
2197
2198int
2199ospf_check_sum (struct ospf_header *ospfh)
2200{
2201 u_int32_t ret;
2202 u_int16_t sum;
2203 int in_cksum (void *ptr, int nbytes);
2204
2205 /* clear auth_data for checksum. */
2206 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2207
2208 /* keep checksum and clear. */
2209 sum = ospfh->checksum;
2210 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2211
2212 /* calculate checksum. */
2213 ret = in_cksum (ospfh, ntohs (ospfh->length));
2214
2215 if (ret != sum)
2216 {
2217 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2218 ret, sum);
2219 return 0;
2220 }
2221
2222 return 1;
2223}
2224
2225/* OSPF Header verification. */
2226int
2227ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2228 struct ip *iph, struct ospf_header *ospfh)
2229{
2230 /* check version. */
2231 if (ospfh->version != OSPF_VERSION)
2232 {
2233 zlog_warn ("interface %s: ospf_read version number mismatch.",
2234 IF_NAME (oi));
2235 return -1;
2236 }
2237
2238 /* Check Area ID. */
2239 if (!ospf_check_area_id (oi, ospfh))
2240 {
2241 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2242 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2243 return -1;
2244 }
2245
2246 /* Check network mask, Silently discarded. */
2247 if (! ospf_check_network_mask (oi, iph->ip_src))
2248 {
2249 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2250 IF_NAME (oi), inet_ntoa (iph->ip_src));
2251 return -1;
2252 }
2253
2254 /* Check authentication. */
2255 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2256 {
2257 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2258 IF_NAME (oi));
2259 return -1;
2260 }
2261
2262 if (! ospf_check_auth (oi, ibuf, ospfh))
2263 {
2264 zlog_warn ("interface %s: ospf_read authentication failed.",
2265 IF_NAME (oi));
2266 return -1;
2267 }
2268
2269 /* if check sum is invalid, packet is discarded. */
2270 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2271 {
2272 if (! ospf_check_sum (ospfh))
2273 {
2274 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2275 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2276 return -1;
2277 }
2278 }
2279 else
2280 {
2281 if (ospfh->checksum != 0)
2282 return -1;
2283 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2284 {
2285 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2286 IF_NAME (oi));
2287 return -1;
2288 }
2289 }
2290
2291 return 0;
2292}
2293
2294/* Starting point of packet process function. */
2295int
2296ospf_read (struct thread *thread)
2297{
2298 int ret;
2299 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002300 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002301 struct ospf_interface *oi;
2302 struct ip *iph;
2303 struct ospf_header *ospfh;
2304 u_int16_t length;
2305 struct interface *ifp;
2306
2307 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002308 ospf = THREAD_ARG (thread);
2309 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002310
2311 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002312 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002313 if (ibuf == NULL)
2314 return -1;
2315
paul06f953f2004-10-22 17:00:38 +00002316 iph = (struct ip *) STREAM_DATA (ibuf);
2317 sockopt_iphdrincl_swab_systoh (iph);
2318
paulac191232004-10-22 12:05:17 +00002319 /* openbsd lacks IP_RECVIF */
2320#if !(defined(IP_PKTINFO) || defined(IP_RECVIF))
2321 if (ifp == NULL)
2322 ifp = if_lookup_address (iph->ip_src);
2323#endif /* !((defined(IP_PKTINFO) || defined(IP_RECVIF)) */
2324
pauld3f0d622004-05-05 15:27:15 +00002325 if (ifp == NULL)
2326 {
2327 stream_free (ibuf);
2328 return 0;
2329 }
paul6b333612004-10-11 10:11:25 +00002330
paul718e3742002-12-13 20:15:29 +00002331 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002332 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002333
2334 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002335 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002336 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002337
paul718e3742002-12-13 20:15:29 +00002338 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002339 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002340 {
pauld3241812003-09-29 12:42:39 +00002341 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2342 {
2343 zlog_info ("ospf_read[%s]: Dropping self-originated packet",
2344 inet_ntoa (iph->ip_src));
2345 }
paul718e3742002-12-13 20:15:29 +00002346 stream_free (ibuf);
2347 return 0;
2348 }
2349
2350 /* Adjust size to message length. */
2351 stream_forward (ibuf, iph->ip_hl * 4);
2352
2353 /* Get ospf packet header. */
2354 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2355
2356 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002357 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002358
2359 /* if no local ospf_interface,
2360 * or header area is backbone but ospf_interface is not
2361 * check for VLINK interface
2362 */
2363 if ( (oi == NULL) ||
2364 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2365 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2366 )
2367 {
2368 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2369 {
2370 zlog_warn ("Packet from [%s] received on link %s"
2371 " but no ospf_interface",
2372 inet_ntoa (iph->ip_src), ifp->name);
2373 stream_free (ibuf);
2374 return 0;
2375 }
2376 }
2377
2378 /* else it must be a local ospf interface, check it was received on
2379 * correct link
2380 */
2381 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002382 {
2383 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002384 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002385 stream_free (ibuf);
2386 return 0;
2387 }
paul718e3742002-12-13 20:15:29 +00002388
2389 /*
2390 * If the received packet is destined for AllDRouters, the packet
2391 * should be accepted only if the received ospf interface state is
2392 * either DR or Backup -- endo.
2393 */
2394 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2395 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2396 {
2397 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2398 inet_ntoa (iph->ip_src), IF_NAME (oi),
2399 LOOKUP (ospf_ism_state_msg, oi->state));
2400 stream_free (ibuf);
2401 return 0;
2402 }
2403
2404 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002405 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2406 {
paul718e3742002-12-13 20:15:29 +00002407 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002408 {
2409 zlog_info ("-----------------------------------------------------");
2410 ospf_packet_dump (ibuf);
2411 }
paul718e3742002-12-13 20:15:29 +00002412
2413 zlog_info ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002414 ospf_packet_type_str[ospfh->type],
2415 inet_ntoa (ospfh->router_id), IF_NAME (oi));
paul718e3742002-12-13 20:15:29 +00002416 zlog_info (" src [%s],", inet_ntoa (iph->ip_src));
2417 zlog_info (" dst [%s]", inet_ntoa (iph->ip_dst));
2418
2419 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
2420 zlog_info ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002421 }
paul718e3742002-12-13 20:15:29 +00002422
2423 /* Some header verification. */
2424 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2425 if (ret < 0)
2426 {
pauld3241812003-09-29 12:42:39 +00002427 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2428 {
2429 zlog_info ("ospf_read[%s/%s]: Header check failed, "
2430 "dropping.",
2431 ospf_packet_type_str[ospfh->type],
2432 inet_ntoa (iph->ip_src));
2433 }
paul718e3742002-12-13 20:15:29 +00002434 stream_free (ibuf);
2435 return ret;
2436 }
2437
2438 stream_forward (ibuf, OSPF_HEADER_SIZE);
2439
2440 /* Adjust size to message length. */
2441 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2442
2443 /* Read rest of the packet and call each sort of packet routine. */
2444 switch (ospfh->type)
2445 {
2446 case OSPF_MSG_HELLO:
2447 ospf_hello (iph, ospfh, ibuf, oi, length);
2448 break;
2449 case OSPF_MSG_DB_DESC:
2450 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2451 break;
2452 case OSPF_MSG_LS_REQ:
2453 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2454 break;
2455 case OSPF_MSG_LS_UPD:
2456 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2457 break;
2458 case OSPF_MSG_LS_ACK:
2459 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2460 break;
2461 default:
2462 zlog (NULL, LOG_WARNING,
2463 "interface %s: OSPF packet header type %d is illegal",
2464 IF_NAME (oi), ospfh->type);
2465 break;
2466 }
2467
2468 stream_free (ibuf);
2469 return 0;
2470}
2471
2472/* Make OSPF header. */
2473void
2474ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2475{
2476 struct ospf_header *ospfh;
2477
2478 ospfh = (struct ospf_header *) STREAM_DATA (s);
2479
2480 ospfh->version = (u_char) OSPF_VERSION;
2481 ospfh->type = (u_char) type;
2482
paul68980082003-03-25 05:07:42 +00002483 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002484
2485 ospfh->checksum = 0;
2486 ospfh->area_id = oi->area->area_id;
2487 ospfh->auth_type = htons (ospf_auth_type (oi));
2488
2489 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2490
2491 ospf_output_forward (s, OSPF_HEADER_SIZE);
2492}
2493
2494/* Make Authentication Data. */
2495int
2496ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2497{
2498 struct crypt_key *ck;
2499
2500 switch (ospf_auth_type (oi))
2501 {
2502 case OSPF_AUTH_NULL:
2503 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2504 break;
2505 case OSPF_AUTH_SIMPLE:
2506 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2507 OSPF_AUTH_SIMPLE_SIZE);
2508 break;
2509 case OSPF_AUTH_CRYPTOGRAPHIC:
2510 /* If key is not set, then set 0. */
2511 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2512 {
2513 ospfh->u.crypt.zero = 0;
2514 ospfh->u.crypt.key_id = 0;
2515 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2516 }
2517 else
2518 {
2519 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2520 ospfh->u.crypt.zero = 0;
2521 ospfh->u.crypt.key_id = ck->key_id;
2522 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2523 }
2524 /* note: the seq is done in ospf_make_md5_digest() */
2525 break;
2526 default:
2527 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2528 break;
2529 }
2530
2531 return 0;
2532}
2533
2534/* Fill rest of OSPF header. */
2535void
2536ospf_fill_header (struct ospf_interface *oi,
2537 struct stream *s, u_int16_t length)
2538{
2539 struct ospf_header *ospfh;
2540
2541 ospfh = (struct ospf_header *) STREAM_DATA (s);
2542
2543 /* Fill length. */
2544 ospfh->length = htons (length);
2545
2546 /* Calculate checksum. */
2547 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2548 ospfh->checksum = in_cksum (ospfh, length);
2549 else
2550 ospfh->checksum = 0;
2551
2552 /* Add Authentication Data. */
2553 ospf_make_auth (oi, ospfh);
2554}
2555
2556int
2557ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2558{
2559 struct ospf_neighbor *nbr;
2560 struct route_node *rn;
2561 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2562 struct in_addr mask;
2563 unsigned long p;
2564 int flag = 0;
2565
2566 /* Set netmask of interface. */
2567 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2568 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2569 masklen2ip (oi->address->prefixlen, &mask);
2570 else
2571 memset ((char *) &mask, 0, sizeof (struct in_addr));
2572 stream_put_ipv4 (s, mask.s_addr);
2573
2574 /* Set Hello Interval. */
2575 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2576
2577 if (IS_DEBUG_OSPF_EVENT)
2578 zlog_info ("make_hello: options: %x, int: %s",
2579 OPTIONS(oi), IF_NAME (oi));
2580
2581 /* Set Options. */
2582 stream_putc (s, OPTIONS (oi));
2583
2584 /* Set Router Priority. */
2585 stream_putc (s, PRIORITY (oi));
2586
2587 /* Set Router Dead Interval. */
2588 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2589
2590 /* Set Designated Router. */
2591 stream_put_ipv4 (s, DR (oi).s_addr);
2592
2593 p = s->putp;
2594
2595 /* Set Backup Designated Router. */
2596 stream_put_ipv4 (s, BDR (oi).s_addr);
2597
2598 /* Add neighbor seen. */
2599 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002600 if ((nbr = rn->info))
2601 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2602 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2603 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2604 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002605 {
2606 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002607 if (nbr->d_router.s_addr != 0
2608 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2609 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2610 flag = 1;
paul718e3742002-12-13 20:15:29 +00002611
2612 stream_put_ipv4 (s, nbr->router_id.s_addr);
2613 length += 4;
2614 }
2615
2616 /* Let neighbor generate BackupSeen. */
2617 if (flag == 1)
2618 {
2619 stream_set_putp (s, p);
2620 stream_put_ipv4 (s, 0);
2621 }
2622
2623 return length;
2624}
2625
2626int
2627ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2628 struct stream *s)
2629{
2630 struct ospf_lsa *lsa;
2631 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2632 u_char options;
2633 unsigned long pp;
2634 int i;
2635 struct ospf_lsdb *lsdb;
2636
2637 /* Set Interface MTU. */
2638 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2639 stream_putw (s, 0);
2640 else
2641 stream_putw (s, oi->ifp->mtu);
2642
2643 /* Set Options. */
2644 options = OPTIONS (oi);
2645#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002646 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002647 {
2648 if (IS_SET_DD_I (nbr->dd_flags)
2649 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2650 /*
2651 * Set O-bit in the outgoing DD packet for capablity negotiation,
2652 * if one of following case is applicable.
2653 *
2654 * 1) WaitTimer expiration event triggered the neighbor state to
2655 * change to Exstart, but no (valid) DD packet has received
2656 * from the neighbor yet.
2657 *
2658 * 2) At least one DD packet with O-bit on has received from the
2659 * neighbor.
2660 */
2661 SET_FLAG (options, OSPF_OPTION_O);
2662 }
2663#endif /* HAVE_OPAQUE_LSA */
2664 stream_putc (s, options);
2665
2666 /* Keep pointer to flags. */
2667 pp = stream_get_putp (s);
2668 stream_putc (s, nbr->dd_flags);
2669
2670 /* Set DD Sequence Number. */
2671 stream_putl (s, nbr->dd_seqnum);
2672
2673 if (ospf_db_summary_isempty (nbr))
2674 {
2675 if (nbr->state >= NSM_Exchange)
2676 {
2677 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2678 /* Set DD flags again */
2679 stream_set_putp (s, pp);
2680 stream_putc (s, nbr->dd_flags);
2681 }
2682 return length;
2683 }
2684
2685 /* Describe LSA Header from Database Summary List. */
2686 lsdb = &nbr->db_sum;
2687
2688 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2689 {
2690 struct route_table *table = lsdb->type[i].db;
2691 struct route_node *rn;
2692
2693 for (rn = route_top (table); rn; rn = route_next (rn))
2694 if ((lsa = rn->info) != NULL)
2695 {
2696#ifdef HAVE_OPAQUE_LSA
2697 if (IS_OPAQUE_LSA (lsa->data->type)
2698 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2699 {
2700 /* Suppress advertising opaque-informations. */
2701 /* Remove LSA from DB summary list. */
2702 ospf_lsdb_delete (lsdb, lsa);
2703 continue;
2704 }
2705#endif /* HAVE_OPAQUE_LSA */
2706
2707 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2708 {
2709 struct lsa_header *lsah;
2710 u_int16_t ls_age;
2711
2712 /* DD packet overflows interface MTU. */
2713 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2714 break;
2715
2716 /* Keep pointer to LS age. */
2717 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2718 stream_get_putp (s));
2719
2720 /* Proceed stream pointer. */
2721 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2722 length += OSPF_LSA_HEADER_SIZE;
2723
2724 /* Set LS age. */
2725 ls_age = LS_AGE (lsa);
2726 lsah->ls_age = htons (ls_age);
2727
2728 }
2729
2730 /* Remove LSA from DB summary list. */
2731 ospf_lsdb_delete (lsdb, lsa);
2732 }
2733 }
2734
2735 return length;
2736}
2737
2738int
2739ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2740 unsigned long delta, struct ospf_neighbor *nbr,
2741 struct ospf_lsa *lsa)
2742{
2743 struct ospf_interface *oi;
2744
2745 oi = nbr->oi;
2746
2747 /* LS Request packet overflows interface MTU. */
2748 if (*length + delta > OSPF_PACKET_MAX(oi))
2749 return 0;
2750
2751 stream_putl (s, lsa->data->type);
2752 stream_put_ipv4 (s, lsa->data->id.s_addr);
2753 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2754
2755 ospf_lsa_unlock (nbr->ls_req_last);
2756 nbr->ls_req_last = ospf_lsa_lock (lsa);
2757
2758 *length += 12;
2759 return 1;
2760}
2761
2762int
2763ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2764{
2765 struct ospf_lsa *lsa;
2766 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2767 unsigned long delta = stream_get_putp(s)+12;
2768 struct route_table *table;
2769 struct route_node *rn;
2770 int i;
2771 struct ospf_lsdb *lsdb;
2772
2773 lsdb = &nbr->ls_req;
2774
2775 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2776 {
2777 table = lsdb->type[i].db;
2778 for (rn = route_top (table); rn; rn = route_next (rn))
2779 if ((lsa = (rn->info)) != NULL)
2780 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2781 {
2782 route_unlock_node (rn);
2783 break;
2784 }
2785 }
2786 return length;
2787}
2788
2789int
2790ls_age_increment (struct ospf_lsa *lsa, int delay)
2791{
2792 int age;
2793
2794 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2795
2796 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2797}
2798
2799int
hasso52dc7ee2004-09-23 19:18:23 +00002800ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002801{
2802 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002803 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002804 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2805 unsigned long delta = stream_get_putp (s);
2806 unsigned long pp;
2807 int count = 0;
2808
2809 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002810 zlog_info ("ospf_make_ls_upd: Start");
2811
paul718e3742002-12-13 20:15:29 +00002812 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002813 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002814
2815 while ((node = listhead (update)) != NULL)
2816 {
2817 struct lsa_header *lsah;
2818 u_int16_t ls_age;
2819
2820 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002821 zlog_info ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002822
2823 lsa = getdata (node);
2824 assert (lsa);
2825 assert (lsa->data);
2826
paul68b73392004-09-12 14:21:37 +00002827 /* Will it fit? */
2828 if (length + delta + ntohs (lsa->data->length) > stream_get_size (s))
paul59ea14c2004-07-14 20:50:36 +00002829 break;
2830
paul718e3742002-12-13 20:15:29 +00002831 /* Keep pointer to LS age. */
2832 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2833
2834 /* Put LSA to Link State Request. */
2835 stream_put (s, lsa->data, ntohs (lsa->data->length));
2836
2837 /* Set LS age. */
2838 /* each hop must increment an lsa_age by transmit_delay
2839 of OSPF interface */
2840 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2841 lsah->ls_age = htons (ls_age);
2842
2843 length += ntohs (lsa->data->length);
2844 count++;
2845
2846 list_delete_node (update, node);
2847 ospf_lsa_unlock (lsa);
2848 }
2849
2850 /* Now set #LSAs. */
2851 stream_set_putp (s, pp);
2852 stream_putl (s, count);
2853
2854 stream_set_putp (s, s->endp);
2855
2856 if (IS_DEBUG_OSPF_EVENT)
paul59ea14c2004-07-14 20:50:36 +00002857 zlog_info ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002858 return length;
2859}
2860
2861int
hasso52dc7ee2004-09-23 19:18:23 +00002862ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002863{
hasso52dc7ee2004-09-23 19:18:23 +00002864 struct list *rm_list;
2865 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002866 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2867 unsigned long delta = stream_get_putp(s) + 24;
2868 struct ospf_lsa *lsa;
2869
2870 rm_list = list_new ();
2871
2872 for (node = listhead (ack); node; nextnode (node))
2873 {
2874 lsa = getdata (node);
2875 assert (lsa);
2876
2877 if (length + delta > OSPF_PACKET_MAX (oi))
2878 break;
2879
2880 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2881 length += OSPF_LSA_HEADER_SIZE;
2882
2883 listnode_add (rm_list, lsa);
2884 }
2885
2886 /* Remove LSA from LS-Ack list. */
2887 for (node = listhead (rm_list); node; nextnode (node))
2888 {
2889 lsa = (struct ospf_lsa *) getdata (node);
2890
2891 listnode_delete (ack, lsa);
2892 ospf_lsa_unlock (lsa);
2893 }
2894
2895 list_delete (rm_list);
2896
2897 return length;
2898}
2899
2900void
2901ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2902{
2903 struct ospf_packet *op;
2904 u_int16_t length = OSPF_HEADER_SIZE;
2905
2906 op = ospf_packet_new (oi->ifp->mtu);
2907
2908 /* Prepare OSPF common header. */
2909 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2910
2911 /* Prepare OSPF Hello body. */
2912 length += ospf_make_hello (oi, op->s);
2913
2914 /* Fill OSPF header. */
2915 ospf_fill_header (oi, op->s, length);
2916
2917 /* Set packet length. */
2918 op->length = length;
2919
2920 op->dst.s_addr = addr->s_addr;
2921
2922 /* Add packet to the interface output queue. */
2923 ospf_packet_add (oi, op);
2924
2925 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002926 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002927}
2928
2929void
2930ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2931{
2932 struct ospf_interface *oi;
2933
2934 oi = nbr_nbma->oi;
2935 assert(oi);
2936
2937 /* If this is passive interface, do not send OSPF Hello. */
2938 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2939 return;
2940
2941 if (oi->type != OSPF_IFTYPE_NBMA)
2942 return;
2943
2944 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2945 return;
2946
2947 if (PRIORITY(oi) == 0)
2948 return;
2949
2950 if (nbr_nbma->priority == 0
2951 && oi->state != ISM_DR && oi->state != ISM_Backup)
2952 return;
2953
2954 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2955}
2956
2957int
2958ospf_poll_timer (struct thread *thread)
2959{
2960 struct ospf_nbr_nbma *nbr_nbma;
2961
2962 nbr_nbma = THREAD_ARG (thread);
2963 nbr_nbma->t_poll = NULL;
2964
2965 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2966 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (Poll timer expire)",
2967 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2968
2969 ospf_poll_send (nbr_nbma);
2970
2971 if (nbr_nbma->v_poll > 0)
2972 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2973 nbr_nbma->v_poll);
2974
2975 return 0;
2976}
2977
2978
2979int
2980ospf_hello_reply_timer (struct thread *thread)
2981{
2982 struct ospf_neighbor *nbr;
2983
2984 nbr = THREAD_ARG (thread);
2985 nbr->t_hello_reply = NULL;
2986
2987 assert (nbr->oi);
2988
2989 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
2990 zlog (NULL, LOG_INFO, "NSM[%s:%s]: Timer (hello-reply timer expire)",
2991 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2992
2993 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2994
2995 return 0;
2996}
2997
2998/* Send OSPF Hello. */
2999void
3000ospf_hello_send (struct ospf_interface *oi)
3001{
3002 struct ospf_packet *op;
3003 u_int16_t length = OSPF_HEADER_SIZE;
3004
3005 /* If this is passive interface, do not send OSPF Hello. */
3006 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3007 return;
3008
3009 op = ospf_packet_new (oi->ifp->mtu);
3010
3011 /* Prepare OSPF common header. */
3012 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3013
3014 /* Prepare OSPF Hello body. */
3015 length += ospf_make_hello (oi, op->s);
3016
3017 /* Fill OSPF header. */
3018 ospf_fill_header (oi, op->s, length);
3019
3020 /* Set packet length. */
3021 op->length = length;
3022
3023 if (oi->type == OSPF_IFTYPE_NBMA)
3024 {
3025 struct ospf_neighbor *nbr;
3026 struct route_node *rn;
3027
3028 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3029 if ((nbr = rn->info))
3030 if (nbr != oi->nbr_self)
3031 if (nbr->state != NSM_Down)
3032 {
3033 /* RFC 2328 Section 9.5.1
3034 If the router is not eligible to become Designated Router,
3035 it must periodically send Hello Packets to both the
3036 Designated Router and the Backup Designated Router (if they
3037 exist). */
3038 if (PRIORITY(oi) == 0 &&
3039 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3040 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3041 continue;
3042
3043 /* If the router is eligible to become Designated Router, it
3044 must periodically send Hello Packets to all neighbors that
3045 are also eligible. In addition, if the router is itself the
3046 Designated Router or Backup Designated Router, it must also
3047 send periodic Hello Packets to all other neighbors. */
3048
3049 if (nbr->priority == 0 && oi->state == ISM_DROther)
3050 continue;
3051 /* if oi->state == Waiting, send hello to all neighbors */
3052 {
3053 struct ospf_packet *op_dup;
3054
3055 op_dup = ospf_packet_dup(op);
3056 op_dup->dst = nbr->address.u.prefix4;
3057
3058 /* Add packet to the interface output queue. */
3059 ospf_packet_add (oi, op_dup);
3060
paul020709f2003-04-04 02:44:16 +00003061 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003062 }
3063
3064 }
3065 ospf_packet_free (op);
3066 }
3067 else
3068 {
3069 /* Decide destination address. */
3070 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3071 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3072 else
3073 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3074
3075 /* Add packet to the interface output queue. */
3076 ospf_packet_add (oi, op);
3077
3078 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003079 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003080 }
3081}
3082
3083/* Send OSPF Database Description. */
3084void
3085ospf_db_desc_send (struct ospf_neighbor *nbr)
3086{
3087 struct ospf_interface *oi;
3088 struct ospf_packet *op;
3089 u_int16_t length = OSPF_HEADER_SIZE;
3090
3091 oi = nbr->oi;
3092 op = ospf_packet_new (oi->ifp->mtu);
3093
3094 /* Prepare OSPF common header. */
3095 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3096
3097 /* Prepare OSPF Database Description body. */
3098 length += ospf_make_db_desc (oi, nbr, op->s);
3099
3100 /* Fill OSPF header. */
3101 ospf_fill_header (oi, op->s, length);
3102
3103 /* Set packet length. */
3104 op->length = length;
3105
3106 /* Decide destination address. */
3107 op->dst = nbr->address.u.prefix4;
3108
3109 /* Add packet to the interface output queue. */
3110 ospf_packet_add (oi, op);
3111
3112 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003113 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003114
3115 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3116 if (nbr->last_send)
3117 ospf_packet_free (nbr->last_send);
3118 nbr->last_send = ospf_packet_dup (op);
3119 gettimeofday (&nbr->last_send_ts, NULL);
3120}
3121
3122/* Re-send Database Description. */
3123void
3124ospf_db_desc_resend (struct ospf_neighbor *nbr)
3125{
3126 struct ospf_interface *oi;
3127
3128 oi = nbr->oi;
3129
3130 /* Add packet to the interface output queue. */
3131 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3132
3133 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003134 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003135}
3136
3137/* Send Link State Request. */
3138void
3139ospf_ls_req_send (struct ospf_neighbor *nbr)
3140{
3141 struct ospf_interface *oi;
3142 struct ospf_packet *op;
3143 u_int16_t length = OSPF_HEADER_SIZE;
3144
3145 oi = nbr->oi;
3146 op = ospf_packet_new (oi->ifp->mtu);
3147
3148 /* Prepare OSPF common header. */
3149 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3150
3151 /* Prepare OSPF Link State Request body. */
3152 length += ospf_make_ls_req (nbr, op->s);
3153 if (length == OSPF_HEADER_SIZE)
3154 {
3155 ospf_packet_free (op);
3156 return;
3157 }
3158
3159 /* Fill OSPF header. */
3160 ospf_fill_header (oi, op->s, length);
3161
3162 /* Set packet length. */
3163 op->length = length;
3164
3165 /* Decide destination address. */
3166 op->dst = nbr->address.u.prefix4;
3167
3168 /* Add packet to the interface output queue. */
3169 ospf_packet_add (oi, op);
3170
3171 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003172 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003173
3174 /* Add Link State Request Retransmission Timer. */
3175 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3176}
3177
3178/* Send Link State Update with an LSA. */
3179void
3180ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3181 int flag)
3182{
hasso52dc7ee2004-09-23 19:18:23 +00003183 struct list *update;
paul718e3742002-12-13 20:15:29 +00003184
3185 update = list_new ();
3186
3187 listnode_add (update, lsa);
3188 ospf_ls_upd_send (nbr, update, flag);
3189
3190 list_delete (update);
3191}
3192
paul68b73392004-09-12 14:21:37 +00003193/* Determine size for packet. Must be at least big enough to accomodate next
3194 * LSA on list, which may be bigger than MTU size.
3195 *
3196 * Return pointer to new ospf_packet
3197 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3198 * on packet sizes (in which case offending LSA is deleted from update list)
3199 */
3200static struct ospf_packet *
3201ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3202{
3203 struct ospf_lsa *lsa;
3204 struct listnode *ln;
3205 size_t size;
3206 static char warned = 0;
3207
3208 ln = listhead (update);
3209 lsa = getdata (ln);
3210 assert (lsa);
3211 assert (lsa->data);
3212
3213 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3214 > ospf_packet_max (oi))
3215 {
3216 if (!warned)
3217 {
3218 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3219 "will need to fragment. Not optimal. Try divide up"
3220 " your network with areas. Use 'debug ospf packet send'"
3221 " to see details, or look at 'show ip ospf database ..'");
3222 warned = 1;
3223 }
3224
3225 if (IS_DEBUG_OSPF_PACKET (0, SEND))
3226 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
3227 " %d bytes originated by %s, will be fragmented!",
3228 inet_ntoa (lsa->data->id),
3229 ntohs (lsa->data->length),
3230 inet_ntoa (lsa->data->adv_router));
3231
3232 /*
3233 * Allocate just enough to fit this LSA only, to avoid including other
3234 * LSAs in fragmented LSA Updates.
3235 */
3236 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3237 + OSPF_LS_UPD_MIN_SIZE;
3238 }
3239 else
3240 size = oi->ifp->mtu;
3241
3242 if (size > OSPF_MAX_PACKET_SIZE)
3243 {
3244 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003245 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003246 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003247 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003248 (long int) size);
paul68b73392004-09-12 14:21:37 +00003249 list_delete_node (update, ln);
3250 return NULL;
3251 }
3252
3253 return ospf_packet_new (size);
3254}
3255
paul718e3742002-12-13 20:15:29 +00003256static void
hasso52dc7ee2004-09-23 19:18:23 +00003257ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003258 struct in_addr addr)
3259{
3260 struct ospf_packet *op;
3261 u_int16_t length = OSPF_HEADER_SIZE;
3262
3263 if (IS_DEBUG_OSPF_EVENT)
3264 zlog_info ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003265
3266 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003267
3268 /* Prepare OSPF common header. */
3269 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3270
paul59ea14c2004-07-14 20:50:36 +00003271 /* Prepare OSPF Link State Update body.
3272 * Includes Type-7 translation.
3273 */
paul718e3742002-12-13 20:15:29 +00003274 length += ospf_make_ls_upd (oi, update, op->s);
3275
3276 /* Fill OSPF header. */
3277 ospf_fill_header (oi, op->s, length);
3278
3279 /* Set packet length. */
3280 op->length = length;
3281
3282 /* Decide destination address. */
3283 op->dst.s_addr = addr.s_addr;
3284
3285 /* Add packet to the interface output queue. */
3286 ospf_packet_add (oi, op);
3287
3288 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003289 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003290}
3291
3292static int
3293ospf_ls_upd_send_queue_event (struct thread *thread)
3294{
3295 struct ospf_interface *oi = THREAD_ARG(thread);
3296 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003297 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003298 struct list *update;
paul68b73392004-09-12 14:21:37 +00003299 char again = 0;
paul718e3742002-12-13 20:15:29 +00003300
3301 oi->t_ls_upd_event = NULL;
3302
3303 if (IS_DEBUG_OSPF_EVENT)
3304 zlog_info ("ospf_ls_upd_send_queue start");
3305
paul736d3442003-07-24 23:22:57 +00003306 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003307 {
paul736d3442003-07-24 23:22:57 +00003308 rnext = route_next (rn);
3309
paul718e3742002-12-13 20:15:29 +00003310 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003311 continue;
paul68b73392004-09-12 14:21:37 +00003312
3313 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003314
paul48fe13b2004-07-27 17:40:44 +00003315 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003316
paul68b73392004-09-12 14:21:37 +00003317 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003318 if (listcount(update) == 0)
3319 {
3320 list_delete (rn->info);
3321 rn->info = NULL;
3322 route_unlock_node (rn);
3323 }
3324 else
paul68b73392004-09-12 14:21:37 +00003325 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003326 }
3327
3328 if (again != 0)
3329 {
3330 if (IS_DEBUG_OSPF_EVENT)
3331 zlog_info ("ospf_ls_upd_send_queue: update lists not cleared,"
3332 " %d nodes to try again, raising new event", again);
3333 oi->t_ls_upd_event =
3334 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003335 }
3336
3337 if (IS_DEBUG_OSPF_EVENT)
3338 zlog_info ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003339
paul718e3742002-12-13 20:15:29 +00003340 return 0;
3341}
3342
3343void
hasso52dc7ee2004-09-23 19:18:23 +00003344ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003345{
3346 struct ospf_interface *oi;
3347 struct prefix_ipv4 p;
3348 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003349 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003350
3351 oi = nbr->oi;
3352
3353 p.family = AF_INET;
3354 p.prefixlen = IPV4_MAX_BITLEN;
3355
3356 /* Decide destination address. */
3357 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3358 p.prefix = oi->vl_data->peer_addr;
3359 else if (flag == OSPF_SEND_PACKET_DIRECT)
3360 p.prefix = nbr->address.u.prefix4;
3361 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3362 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3363 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3364 && (flag == OSPF_SEND_PACKET_INDIRECT))
3365 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003366 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3367 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003368 else
3369 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3370
3371 if (oi->type == OSPF_IFTYPE_NBMA)
3372 {
3373 if (flag == OSPF_SEND_PACKET_INDIRECT)
3374 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3375 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3376 zlog_warn ("* LS-Update is sent to myself.");
3377 }
3378
3379 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3380
3381 if (rn->info == NULL)
3382 rn->info = list_new ();
3383
3384 for (n = listhead (update); n; nextnode (n))
3385 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3386
3387 if (oi->t_ls_upd_event == NULL)
3388 oi->t_ls_upd_event =
3389 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3390}
3391
3392static void
hasso52dc7ee2004-09-23 19:18:23 +00003393ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3394 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003395{
3396 struct ospf_packet *op;
3397 u_int16_t length = OSPF_HEADER_SIZE;
3398
3399 op = ospf_packet_new (oi->ifp->mtu);
3400
3401 /* Prepare OSPF common header. */
3402 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3403
3404 /* Prepare OSPF Link State Acknowledgment body. */
3405 length += ospf_make_ls_ack (oi, ack, op->s);
3406
3407 /* Fill OSPF header. */
3408 ospf_fill_header (oi, op->s, length);
3409
3410 /* Set packet length. */
3411 op->length = length;
3412
3413 /* Set destination IP address. */
3414 op->dst = dst;
3415
3416 /* Add packet to the interface output queue. */
3417 ospf_packet_add (oi, op);
3418
3419 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003420 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003421}
3422
3423static int
3424ospf_ls_ack_send_event (struct thread *thread)
3425{
3426 struct ospf_interface *oi = THREAD_ARG (thread);
3427
3428 oi->t_ls_ack_direct = NULL;
3429
3430 while (listcount (oi->ls_ack_direct.ls_ack))
3431 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3432 oi->ls_ack_direct.dst);
3433
3434 return 0;
3435}
3436
3437void
3438ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3439{
3440 struct ospf_interface *oi = nbr->oi;
3441
3442 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3443 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3444
3445 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3446
3447 if (oi->t_ls_ack_direct == NULL)
3448 oi->t_ls_ack_direct =
3449 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3450}
3451
3452/* Send Link State Acknowledgment delayed. */
3453void
3454ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3455{
3456 struct in_addr dst;
3457
3458 /* Decide destination address. */
3459 /* RFC2328 Section 13.5 On non-broadcast
3460 networks, delayed Link State Acknowledgment packets must be
3461 unicast separately over each adjacency (i.e., neighbor whose
3462 state is >= Exchange). */
3463 if (oi->type == OSPF_IFTYPE_NBMA)
3464 {
3465 struct ospf_neighbor *nbr;
3466 struct route_node *rn;
3467
3468 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3469 if ((nbr = rn->info) != NULL)
3470 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3471 while (listcount (oi->ls_ack))
3472 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3473 return;
3474 }
3475 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3476 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3477 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3478 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3479 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3480 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003481 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3482 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003483 else
3484 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3485
3486 while (listcount (oi->ls_ack))
3487 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3488}