blob: 6eb6651f2a31b840264e9032685f3929a4b6d376 [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 {
ajs2a42e282004-12-08 18:43:03 +0000546 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000547 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 {
ajs2a42e282004-12-08 18:43:03 +0000551 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000552 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000553 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000554 }
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 {
ajs2a42e282004-12-08 18:43:03 +0000700 zlog_debug ("-----------------------------------------------------");
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
ajs2a42e282004-12-08 18:43:03 +0000706 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000707 ospf_packet_type_str[type], inet_ntoa (op->dst),
708 IF_NAME (oi));
709
710 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000711 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000712 }
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 {
ajs2a42e282004-12-08 18:43:03 +0000751 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000752 "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)
ajs2a42e282004-12-08 18:43:03 +0000799 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000800 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)
ajs2a42e282004-12-08 18:43:03 +0000849 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000850 }
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 {
ajs3aa8d5f2004-12-11 18:00:06 +0000860 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
861 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000862 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 {
ajsbec595a2004-11-30 22:38:43 +0000981 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000982 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)
ajs2a42e282004-12-08 18:43:03 +00001032 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001033 "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
ajsbec595a2004-11-30 22:38:43 +00001062 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001063 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. */
ajs3aa8d5f2004-12-11 18:00:06 +00001083static void
paul718e3742002-12-13 20:15:29 +00001084ospf_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 {
ajs3aa8d5f2004-12-11 18:00:06 +00001106 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1107 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1108 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001109 return;
1110 }
1111
pauld363df22003-06-19 00:26:34 +00001112 /*
1113 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1114 * required. In fact at least JunOS sends DD packets with P bit clear.
1115 * Until proper solution is developped, this hack should help.
1116 *
1117 * Update: According to the RFCs, N bit is specified /only/ for Hello
1118 * options, unfortunately its use in DD options is not specified. Hence some
1119 * implementations follow E-bit semantics and set it in DD options, and some
1120 * treat it as unspecified and hence follow the directive "default for
1121 * options is clear", ie unset.
1122 *
1123 * Reset the flag, as ospfd follows E-bit semantics.
1124 */
1125 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1126 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1127 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1128 {
1129 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001130 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001131 inet_ntoa (nbr->router_id) );
1132 SET_FLAG (dd->options, OSPF_OPTION_NP);
1133 }
pauld363df22003-06-19 00:26:34 +00001134
paul718e3742002-12-13 20:15:29 +00001135#ifdef REJECT_IF_TBIT_ON
1136 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1137 {
1138 /*
1139 * In Hello protocol, optional capability must have checked
1140 * to prevent this T-bit enabled router be my neighbor.
1141 */
1142 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1143 return;
1144 }
1145#endif /* REJECT_IF_TBIT_ON */
1146
1147#ifdef HAVE_OPAQUE_LSA
1148 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001149 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001150 {
1151 /*
1152 * This node is not configured to handle O-bit, for now.
1153 * Clear it to ignore unsupported capability proposed by neighbor.
1154 */
1155 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1156 }
1157#endif /* HAVE_OPAQUE_LSA */
1158
1159 /* Process DD packet by neighbor status. */
1160 switch (nbr->state)
1161 {
1162 case NSM_Down:
1163 case NSM_Attempt:
1164 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001165 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001166 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001167 LOOKUP (ospf_nsm_state_msg, nbr->state));
1168 break;
1169 case NSM_Init:
1170 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1171 /* If the new state is ExStart, the processing of the current
1172 packet should then continue in this new state by falling
1173 through to case ExStart below. */
1174 if (nbr->state != NSM_ExStart)
1175 break;
1176 case NSM_ExStart:
1177 /* Initial DBD */
1178 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1179 (size == OSPF_DB_DESC_MIN_SIZE))
1180 {
paul68980082003-03-25 05:07:42 +00001181 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001182 {
1183 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001184 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001185 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001186 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1187 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1188 }
1189 else
1190 {
1191 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001192 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1193 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001194 break;
1195 }
1196 }
1197 /* Ack from the Slave */
1198 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1199 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001200 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001201 {
ajs17eaa722004-12-29 21:04:48 +00001202 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001203 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001204 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1205 }
1206 else
1207 {
ajs3aa8d5f2004-12-11 18:00:06 +00001208 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1209 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001210 break;
1211 }
1212
1213 /* This is where the real Options are saved */
1214 nbr->options = dd->options;
1215
1216#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001217 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001218 {
1219 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001220 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001221 inet_ntoa (nbr->router_id),
1222 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1223
1224 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1225 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1226 {
1227 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1228 /* This situation is undesirable, but not a real error. */
1229 }
1230 }
1231#endif /* HAVE_OPAQUE_LSA */
1232
1233 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1234
1235 /* continue processing rest of packet. */
1236 ospf_db_desc_proc (s, oi, nbr, dd, size);
1237 break;
1238 case NSM_Exchange:
1239 if (ospf_db_desc_is_dup (dd, nbr))
1240 {
1241 if (IS_SET_DD_MS (nbr->dd_flags))
1242 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001243 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1244 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001245 else
1246 /* Slave: cause to retransmit the last Database Description. */
1247 {
ajs3aa8d5f2004-12-11 18:00:06 +00001248 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1249 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001250 ospf_db_desc_resend (nbr);
1251 }
1252 break;
1253 }
1254
1255 /* Otherwise DD packet should be checked. */
1256 /* Check Master/Slave bit mismatch */
1257 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1258 {
ajs3aa8d5f2004-12-11 18:00:06 +00001259 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1260 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001261 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1262 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001263 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001264 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001265 break;
1266 }
1267
1268 /* Check initialize bit is set. */
1269 if (IS_SET_DD_I (dd->flags))
1270 {
ajs3aa8d5f2004-12-11 18:00:06 +00001271 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1272 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001273 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1274 break;
1275 }
1276
1277 /* Check DD Options. */
1278 if (dd->options != nbr->options)
1279 {
1280#ifdef ORIGINAL_CODING
1281 /* Save the new options for debugging */
1282 nbr->options = dd->options;
1283#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001284 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1285 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001286 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1287 break;
1288 }
1289
1290 /* Check DD sequence number. */
1291 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1292 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1293 (!IS_SET_DD_MS (nbr->dd_flags) &&
1294 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1295 {
ajs3aa8d5f2004-12-11 18:00:06 +00001296 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1297 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001298 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1299 break;
1300 }
1301
1302 /* Continue processing rest of packet. */
1303 ospf_db_desc_proc (s, oi, nbr, dd, size);
1304 break;
1305 case NSM_Loading:
1306 case NSM_Full:
1307 if (ospf_db_desc_is_dup (dd, nbr))
1308 {
1309 if (IS_SET_DD_MS (nbr->dd_flags))
1310 {
1311 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001312 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1313 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001314 break;
1315 }
1316 else
1317 {
1318 struct timeval t, now;
1319 gettimeofday (&now, NULL);
1320 t = tv_sub (now, nbr->last_send_ts);
1321 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1322 {
1323 /* In states Loading and Full the slave must resend
1324 its last Database Description packet in response to
1325 duplicate Database Description packets received
1326 from the master. For this reason the slave must
1327 wait RouterDeadInterval seconds before freeing the
1328 last Database Description packet. Reception of a
1329 Database Description packet from the master after
1330 this interval will generate a SeqNumberMismatch
1331 neighbor event. RFC2328 Section 10.8 */
1332 ospf_db_desc_resend (nbr);
1333 break;
1334 }
1335 }
1336 }
1337
1338 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1339 break;
1340 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001341 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1342 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001343 break;
1344 }
1345}
1346
1347#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1348
1349/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1350void
1351ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1352 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1353{
1354 struct ospf_neighbor *nbr;
1355 u_int32_t ls_type;
1356 struct in_addr ls_id;
1357 struct in_addr adv_router;
1358 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001359 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001360 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001361
1362 /* Increment statistics. */
1363 oi->ls_req_in++;
1364
pauld3f0d622004-05-05 15:27:15 +00001365 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001366 if (nbr == NULL)
1367 {
1368 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1369 inet_ntoa (ospfh->router_id));
1370 return;
1371 }
1372
1373 /* Neighbor State should be Exchange or later. */
1374 if (nbr->state != NSM_Exchange &&
1375 nbr->state != NSM_Loading &&
1376 nbr->state != NSM_Full)
1377 {
ajsbec595a2004-11-30 22:38:43 +00001378 zlog_warn ("Link State Request received from %s: "
1379 "Neighbor state is %s, packet discarded.",
1380 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001381 LOOKUP (ospf_nsm_state_msg, nbr->state));
1382 return;
1383 }
1384
1385 /* Send Link State Update for ALL requested LSAs. */
1386 ls_upd = list_new ();
1387 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1388
1389 while (size >= OSPF_LSA_KEY_SIZE)
1390 {
1391 /* Get one slice of Link State Request. */
1392 ls_type = stream_getl (s);
1393 ls_id.s_addr = stream_get_ipv4 (s);
1394 adv_router.s_addr = stream_get_ipv4 (s);
1395
1396 /* Verify LSA type. */
1397 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1398 {
1399 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1400 list_delete (ls_upd);
1401 return;
1402 }
1403
1404 /* Search proper LSA in LSDB. */
1405 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1406 if (find == NULL)
1407 {
1408 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1409 list_delete (ls_upd);
1410 return;
1411 }
1412
1413 /* Packet overflows MTU size, send immediatly. */
1414 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1415 {
1416 if (oi->type == OSPF_IFTYPE_NBMA)
1417 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1418 else
1419 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1420
1421 /* Only remove list contents. Keep ls_upd. */
1422 list_delete_all_node (ls_upd);
1423
1424 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1425 }
1426
1427 /* Append LSA to update list. */
1428 listnode_add (ls_upd, find);
1429 length += ntohs (find->data->length);
1430
1431 size -= OSPF_LSA_KEY_SIZE;
1432 }
1433
1434 /* Send rest of Link State Update. */
1435 if (listcount (ls_upd) > 0)
1436 {
1437 if (oi->type == OSPF_IFTYPE_NBMA)
1438 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1439 else
1440 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1441
1442 list_delete (ls_upd);
1443 }
1444 else
1445 list_free (ls_upd);
1446}
1447
1448/* Get the list of LSAs from Link State Update packet.
1449 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001450static struct list *
paul718e3742002-12-13 20:15:29 +00001451ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1452 struct ospf_interface *oi, size_t size)
1453{
1454 u_int16_t count, sum;
1455 u_int32_t length;
1456 struct lsa_header *lsah;
1457 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001458 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001459
1460 lsas = list_new ();
1461
1462 count = stream_getl (s);
1463 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1464
1465 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1466 size -= length, stream_forward (s, length), count--)
1467 {
1468 lsah = (struct lsa_header *) STREAM_PNT (s);
1469 length = ntohs (lsah->length);
1470
1471 if (length > size)
1472 {
1473 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1474 break;
1475 }
1476
1477 /* Validate the LSA's LS checksum. */
1478 sum = lsah->checksum;
1479 if (sum != ospf_lsa_checksum (lsah))
1480 {
1481 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1482 sum, lsah->checksum);
1483 continue;
1484 }
1485
1486 /* Examine the LSA's LS type. */
1487 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1488 {
1489 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1490 continue;
1491 }
1492
1493 /*
1494 * What if the received LSA's age is greater than MaxAge?
1495 * Treat it as a MaxAge case -- endo.
1496 */
1497 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1498 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1499
1500#ifdef HAVE_OPAQUE_LSA
1501 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1502 {
1503#ifdef STRICT_OBIT_USAGE_CHECK
1504 if ((IS_OPAQUE_LSA(lsah->type) &&
1505 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1506 || (! IS_OPAQUE_LSA(lsah->type) &&
1507 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1508 {
1509 /*
1510 * This neighbor must know the exact usage of O-bit;
1511 * the bit will be set in Type-9,10,11 LSAs only.
1512 */
1513 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1514 continue;
1515 }
1516#endif /* STRICT_OBIT_USAGE_CHECK */
1517
1518 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1519 if (lsah->type == OSPF_OPAQUE_AS_LSA
1520 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1521 {
1522 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001523 zlog_debug ("LSA[Type%d:%s]: We are a stub, don't take this LSA.", lsah->type, inet_ntoa (lsah->id));
paul718e3742002-12-13 20:15:29 +00001524 continue;
1525 }
1526 }
1527 else if (IS_OPAQUE_LSA(lsah->type))
1528 {
1529 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1530 continue;
1531 }
1532#endif /* HAVE_OPAQUE_LSA */
1533
1534 /* Create OSPF LSA instance. */
1535 lsa = ospf_lsa_new ();
1536
1537 /* We may wish to put some error checking if type NSSA comes in
1538 and area not in NSSA mode */
1539 switch (lsah->type)
1540 {
1541 case OSPF_AS_EXTERNAL_LSA:
1542#ifdef HAVE_OPAQUE_LSA
1543 case OSPF_OPAQUE_AS_LSA:
1544 lsa->area = NULL;
1545 break;
1546 case OSPF_OPAQUE_LINK_LSA:
1547 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1548 /* Fallthrough */
1549#endif /* HAVE_OPAQUE_LSA */
1550 default:
1551 lsa->area = oi->area;
1552 break;
1553 }
1554
1555 lsa->data = ospf_lsa_data_new (length);
1556 memcpy (lsa->data, lsah, length);
1557
1558 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001559 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001560 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1561 listnode_add (lsas, lsa);
1562 }
1563
1564 return lsas;
1565}
1566
1567/* Cleanup Update list. */
1568void
hasso52dc7ee2004-09-23 19:18:23 +00001569ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001570{
hasso52dc7ee2004-09-23 19:18:23 +00001571 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001572 struct ospf_lsa *lsa;
1573
1574 for (node = listhead (lsas); node; nextnode (node))
1575 if ((lsa = getdata (node)) != NULL)
1576 ospf_lsa_discard (lsa);
1577
1578 list_delete (lsas);
1579}
1580
1581/* OSPF Link State Update message read -- RFC2328 Section 13. */
1582void
1583ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1584 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1585{
1586 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001587 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001588#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001589 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001590#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001591 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001592 struct ospf_lsa *lsa = NULL;
1593 /* unsigned long ls_req_found = 0; */
1594
1595 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1596
1597 /* Increment statistics. */
1598 oi->ls_upd_in++;
1599
1600 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001601 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001602 if (nbr == NULL)
1603 {
1604 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1605 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1606 return;
1607 }
1608
1609 /* Check neighbor state. */
1610 if (nbr->state < NSM_Exchange)
1611 {
ajs3aa8d5f2004-12-11 18:00:06 +00001612 zlog_warn ("Link State Update: "
1613 "Neighbor[%s] state %s is less than Exchange",
1614 inet_ntoa (ospfh->router_id),
1615 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001616 return;
1617 }
1618
1619 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1620 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1621 * of section 13.
1622 */
1623 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1624
1625#ifdef HAVE_OPAQUE_LSA
1626 /*
1627 * Prepare two kinds of lists to clean up unwanted self-originated
1628 * Opaque-LSAs from the routing domain as soon as possible.
1629 */
1630 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1631 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1632
1633 /*
1634 * If self-originated Opaque-LSAs that have flooded before restart
1635 * are contained in the received LSUpd message, corresponding LSReq
1636 * messages to be sent may have to be modified.
1637 * To eliminate possible race conditions such that flushing and normal
1638 * updating for the same LSA would take place alternately, this trick
1639 * must be done before entering to the loop below.
1640 */
1641 ospf_opaque_adjust_lsreq (nbr, lsas);
1642#endif /* HAVE_OPAQUE_LSA */
1643
1644#define DISCARD_LSA(L,N) {\
1645 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001646 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point %d: lsa %p Type-%d", N, lsa, (int) lsa->data->type); \
paul718e3742002-12-13 20:15:29 +00001647 ospf_lsa_discard (L); \
1648 continue; }
1649
1650 /* Process each LSA received in the one packet. */
1651 for (node = listhead (lsas); node; node = next)
1652 {
1653 struct ospf_lsa *ls_ret, *current;
1654 int ret = 1;
1655
1656 next = node->next;
1657
1658 lsa = getdata (node);
1659
paul718e3742002-12-13 20:15:29 +00001660 if (IS_DEBUG_OSPF_NSSA)
1661 {
1662 char buf1[INET_ADDRSTRLEN];
1663 char buf2[INET_ADDRSTRLEN];
1664 char buf3[INET_ADDRSTRLEN];
1665
ajs2a42e282004-12-08 18:43:03 +00001666 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001667 lsa->data->type,
1668 inet_ntop (AF_INET, &ospfh->router_id,
1669 buf1, INET_ADDRSTRLEN),
1670 inet_ntop (AF_INET, &lsa->data->id,
1671 buf2, INET_ADDRSTRLEN),
1672 inet_ntop (AF_INET, &lsa->data->adv_router,
1673 buf3, INET_ADDRSTRLEN));
1674 }
paul718e3742002-12-13 20:15:29 +00001675
1676 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1677
1678 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1679
1680 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1681
1682 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1683
1684 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1685
1686 /* Do take in Type-7's if we are an NSSA */
1687
1688 /* If we are also an ABR, later translate them to a Type-5 packet */
1689
1690 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1691 translate them to a separate Type-5 packet. */
1692
1693 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1694 /* Reject from STUB or NSSA */
1695 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1696 {
1697 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001698 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001699 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001700 }
1701
paul718e3742002-12-13 20:15:29 +00001702 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1703 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1704 {
1705 DISCARD_LSA (lsa,2);
1706 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001707 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001708 }
paul718e3742002-12-13 20:15:29 +00001709
1710 /* Find the LSA in the current database. */
1711
1712 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1713
1714 /* If the LSA's LS age is equal to MaxAge, and there is currently
1715 no instance of the LSA in the router's link state database,
1716 and none of router's neighbors are in states Exchange or Loading,
1717 then take the following actions. */
1718
1719 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001720 (ospf_nbr_count (oi, NSM_Exchange) +
1721 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001722 {
1723 /* Response Link State Acknowledgment. */
1724 ospf_ls_ack_send (nbr, lsa);
1725
1726 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001727 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1728 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001729 DISCARD_LSA (lsa, 3);
1730 }
1731
1732#ifdef HAVE_OPAQUE_LSA
1733 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001734 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001735 {
1736 /*
1737 * Even if initial flushing seems to be completed, there might
1738 * be a case that self-originated LSA with MaxAge still remain
1739 * in the routing domain.
1740 * Just send an LSAck message to cease retransmission.
1741 */
1742 if (IS_LSA_MAXAGE (lsa))
1743 {
1744 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1745 ospf_ls_ack_send (nbr, lsa);
1746 ospf_lsa_discard (lsa);
1747
1748 if (current != NULL && ! IS_LSA_MAXAGE (current))
1749 ospf_opaque_lsa_refresh_schedule (current);
1750 continue;
1751 }
1752
1753 /*
1754 * If an instance of self-originated Opaque-LSA is not found
1755 * in the LSDB, there are some possible cases here.
1756 *
1757 * 1) This node lost opaque-capability after restart.
1758 * 2) Else, a part of opaque-type is no more supported.
1759 * 3) Else, a part of opaque-id is no more supported.
1760 *
1761 * Anyway, it is still this node's responsibility to flush it.
1762 * Otherwise, the LSA instance remains in the routing domain
1763 * until its age reaches to MaxAge.
1764 */
1765 if (current == NULL)
1766 {
1767 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001768 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001769
1770 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1771 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1772 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1773 continue;
1774 }
1775 }
1776#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001777 /* It might be happen that received LSA is self-originated network LSA, but
1778 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1779 * Link State ID is one of the router's own IP interface addresses but whose
1780 * Advertising Router is not equal to the router's own Router ID
1781 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1782 */
1783
1784 if(lsa->data->type == OSPF_NETWORK_LSA)
1785 {
hasso52dc7ee2004-09-23 19:18:23 +00001786 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001787 int Flag = 0;
1788
1789 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1790 {
1791 struct ospf_interface *out_if = getdata(oi_node);
1792 if(out_if == NULL)
1793 break;
1794
1795 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1796 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1797 {
1798 if(out_if->network_lsa_self)
1799 {
1800 ospf_lsa_flush_area(lsa,out_if->area);
1801 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001802 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001803 lsa, (int) lsa->data->type);
1804 ospf_lsa_discard (lsa);
1805 Flag = 1;
1806 }
1807 break;
1808 }
1809 }
1810 if(Flag)
1811 continue;
1812 }
paul718e3742002-12-13 20:15:29 +00001813
1814 /* (5) Find the instance of this LSA that is currently contained
1815 in the router's link state database. If there is no
1816 database copy, or the received LSA is more recent than
1817 the database copy the following steps must be performed. */
1818
1819 if (current == NULL ||
1820 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1821 {
1822 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001823 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001824 DISCARD_LSA (lsa, 4);
1825 continue;
1826 }
1827
1828 /* (6) Else, If there is an instance of the LSA on the sending
1829 neighbor's Link state request list, an error has occurred in
1830 the Database Exchange process. In this case, restart the
1831 Database Exchange process by generating the neighbor event
1832 BadLSReq for the sending neighbor and stop processing the
1833 Link State Update packet. */
1834
1835 if (ospf_ls_request_lookup (nbr, lsa))
1836 {
1837 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001838 zlog_warn("LSA[%s] instance exists on Link state request list",
1839 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001840
1841 /* Clean list of LSAs. */
1842 ospf_upd_list_clean (lsas);
1843 /* this lsa is not on lsas list already. */
1844 ospf_lsa_discard (lsa);
1845#ifdef HAVE_OPAQUE_LSA
1846 list_delete (mylsa_acks);
1847 list_delete (mylsa_upds);
1848#endif /* HAVE_OPAQUE_LSA */
1849 return;
1850 }
1851
1852 /* If the received LSA is the same instance as the database copy
1853 (i.e., neither one is more recent) the following two steps
1854 should be performed: */
1855
1856 if (ret == 0)
1857 {
1858 /* If the LSA is listed in the Link state retransmission list
1859 for the receiving adjacency, the router itself is expecting
1860 an acknowledgment for this LSA. The router should treat the
1861 received LSA as an acknowledgment by removing the LSA from
1862 the Link state retransmission list. This is termed an
1863 "implied acknowledgment". */
1864
1865 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1866
1867 if (ls_ret != NULL)
1868 {
1869 ospf_ls_retransmit_delete (nbr, ls_ret);
1870
1871 /* Delayed acknowledgment sent if advertisement received
1872 from Designated Router, otherwise do nothing. */
1873 if (oi->state == ISM_Backup)
1874 if (NBR_IS_DR (nbr))
1875 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1876
1877 DISCARD_LSA (lsa, 5);
1878 }
1879 else
1880 /* Acknowledge the receipt of the LSA by sending a
1881 Link State Acknowledgment packet back out the receiving
1882 interface. */
1883 {
1884 ospf_ls_ack_send (nbr, lsa);
1885 DISCARD_LSA (lsa, 6);
1886 }
1887 }
1888
1889 /* The database copy is more recent. If the database copy
1890 has LS age equal to MaxAge and LS sequence number equal to
1891 MaxSequenceNumber, simply discard the received LSA without
1892 acknowledging it. (In this case, the LSA's LS sequence number is
1893 wrapping, and the MaxSequenceNumber LSA must be completely
1894 flushed before any new LSA instance can be introduced). */
1895
1896 else if (ret > 0) /* Database copy is more recent */
1897 {
1898 if (IS_LSA_MAXAGE (current) &&
1899 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1900 {
1901 DISCARD_LSA (lsa, 7);
1902 }
1903 /* Otherwise, as long as the database copy has not been sent in a
1904 Link State Update within the last MinLSArrival seconds, send the
1905 database copy back to the sending neighbor, encapsulated within
1906 a Link State Update Packet. The Link State Update Packet should
1907 be sent directly to the neighbor. In so doing, do not put the
1908 database copy of the LSA on the neighbor's link state
1909 retransmission list, and do not acknowledge the received (less
1910 recent) LSA instance. */
1911 else
1912 {
1913 struct timeval now;
1914
1915 gettimeofday (&now, NULL);
1916
1917 if (tv_cmp (tv_sub (now, current->tv_orig),
1918 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1919 /* Trap NSSA type later.*/
1920 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1921 DISCARD_LSA (lsa, 8);
1922 }
1923 }
1924 }
1925
1926#ifdef HAVE_OPAQUE_LSA
1927 /*
1928 * Now that previously originated Opaque-LSAs those which not yet
1929 * installed into LSDB are captured, take several steps to clear
1930 * them completely from the routing domain, before proceeding to
1931 * origination for the current target Opaque-LSAs.
1932 */
1933 while (listcount (mylsa_acks) > 0)
1934 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1935
1936 if (listcount (mylsa_upds) > 0)
1937 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1938
1939 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001940 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001941#endif /* HAVE_OPAQUE_LSA */
1942
1943 assert (listcount (lsas) == 0);
1944 list_delete (lsas);
1945}
1946
1947/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1948void
1949ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1950 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1951{
1952 struct ospf_neighbor *nbr;
1953#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001954 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001955#endif /* HAVE_OPAQUE_LSA */
1956
1957 /* increment statistics. */
1958 oi->ls_ack_in++;
1959
pauld3f0d622004-05-05 15:27:15 +00001960 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001961 if (nbr == NULL)
1962 {
1963 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1964 inet_ntoa (ospfh->router_id));
1965 return;
1966 }
1967
1968 if (nbr->state < NSM_Exchange)
1969 {
ajs3aa8d5f2004-12-11 18:00:06 +00001970 zlog_warn ("Link State Acknowledgment: "
1971 "Neighbor[%s] state %s is less than Exchange",
1972 inet_ntoa (ospfh->router_id),
1973 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001974 return;
1975 }
1976
1977#ifdef HAVE_OPAQUE_LSA
1978 opaque_acks = list_new ();
1979#endif /* HAVE_OPAQUE_LSA */
1980
1981 while (size >= OSPF_LSA_HEADER_SIZE)
1982 {
1983 struct ospf_lsa *lsa, *lsr;
1984
1985 lsa = ospf_lsa_new ();
1986 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1987
1988 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1989 size -= OSPF_LSA_HEADER_SIZE;
1990 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1991
1992 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1993 {
1994 lsa->data = NULL;
1995 ospf_lsa_discard (lsa);
1996 continue;
1997 }
1998
1999 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2000
2001 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2002 {
2003#ifdef HAVE_OPAQUE_LSA
2004 /* Keep this LSA entry for later reference. */
2005 if (IS_OPAQUE_LSA (lsr->data->type))
2006 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2007#endif /* HAVE_OPAQUE_LSA */
2008
2009 ospf_ls_retransmit_delete (nbr, lsr);
2010 }
2011
2012 lsa->data = NULL;
2013 ospf_lsa_discard (lsa);
2014 }
2015
2016#ifdef HAVE_OPAQUE_LSA
2017 if (listcount (opaque_acks) > 0)
2018 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2019
2020 list_delete (opaque_acks);
2021 return;
2022#endif /* HAVE_OPAQUE_LSA */
2023}
2024
2025struct stream *
2026ospf_recv_packet (int fd, struct interface **ifp)
2027{
2028 int ret;
2029 struct ip iph;
2030 u_int16_t ip_len;
2031 struct stream *ibuf;
2032 unsigned int ifindex = 0;
2033 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002034 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002035 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002036 struct msghdr msgh;
2037
paul68defd62004-09-27 07:27:13 +00002038 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002039 msgh.msg_iov = &iov;
2040 msgh.msg_iovlen = 1;
2041 msgh.msg_control = (caddr_t) buff;
2042 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002043
paul718e3742002-12-13 20:15:29 +00002044 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2045
2046 if (ret != sizeof (iph))
2047 {
2048 zlog_warn ("ospf_recv_packet packet smaller than ip header");
gdtbe210242004-12-29 20:12:59 +00002049 /* XXX: We peeked, and thus perhaps should discard this packet. */
paul718e3742002-12-13 20:15:29 +00002050 return NULL;
2051 }
paul18b12c32004-10-05 14:38:29 +00002052
2053 sockopt_iphdrincl_swab_systoh (&iph);
2054
paul6b333612004-10-11 10:11:25 +00002055 ip_len = iph.ip_len;
2056
paul239aecc2003-12-08 10:34:54 +00002057#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002058 /*
2059 * Kernel network code touches incoming IP header parameters,
2060 * before protocol specific processing.
2061 *
2062 * 1) Convert byteorder to host representation.
2063 * --> ip_len, ip_id, ip_off
2064 *
2065 * 2) Adjust ip_len to strip IP header size!
2066 * --> If user process receives entire IP packet via RAW
2067 * socket, it must consider adding IP header size to
2068 * the "ip_len" field of "ip" structure.
2069 *
2070 * For more details, see <netinet/ip_input.c>.
2071 */
2072 ip_len = ip_len + (iph.ip_hl << 2);
2073#endif
2074
2075 ibuf = stream_new (ip_len);
2076 iov.iov_base = STREAM_DATA (ibuf);
2077 iov.iov_len = ip_len;
2078 ret = recvmsg (fd, &msgh, 0);
2079
paul863082d2004-08-19 04:43:43 +00002080 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002081
2082 *ifp = if_lookup_by_index (ifindex);
2083
2084 if (ret != ip_len)
2085 {
2086 zlog_warn ("ospf_recv_packet short read. "
2087 "ip_len %d bytes read %d", ip_len, ret);
2088 stream_free (ibuf);
2089 return NULL;
2090 }
2091
2092 return ibuf;
2093}
2094
2095struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002096ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002097 struct ip *iph, struct ospf_header *ospfh)
2098{
2099 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002100 struct ospf_vl_data *vl_data;
2101 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002102 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002103
2104 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2105 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002106 return NULL;
paul718e3742002-12-13 20:15:29 +00002107
pauld3f0d622004-05-05 15:27:15 +00002108 /* look for local OSPF interface matching the destination
2109 * to determine Area ID. We presume therefore the destination address
2110 * is unique, or at least (for "unnumbered" links), not used in other
2111 * areas
2112 */
2113 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2114 iph->ip_dst)) == NULL)
2115 return NULL;
paul718e3742002-12-13 20:15:29 +00002116
paul020709f2003-04-04 02:44:16 +00002117 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002118 {
2119 if ((vl_data = getdata (node)) == NULL)
2120 continue;
2121
paul020709f2003-04-04 02:44:16 +00002122 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002123 if (!vl_area)
2124 continue;
2125
2126 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2127 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2128 {
2129 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002130 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002131 IF_NAME (vl_data->vl_oi));
2132 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2133 {
2134 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002135 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002136 return NULL;
2137 }
2138
2139 return vl_data->vl_oi;
2140 }
2141 }
2142
2143 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002144 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002145
pauld3f0d622004-05-05 15:27:15 +00002146 return NULL;
paul718e3742002-12-13 20:15:29 +00002147}
2148
2149int
2150ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2151{
2152 /* Check match the Area ID of the receiving interface. */
2153 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2154 return 1;
2155
2156 return 0;
2157}
2158
2159/* Unbound socket will accept any Raw IP packets if proto is matched.
2160 To prevent it, compare src IP address and i/f address with masking
2161 i/f network mask. */
2162int
2163ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2164{
2165 struct in_addr mask, me, him;
2166
2167 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2168 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2169 return 1;
2170
2171 masklen2ip (oi->address->prefixlen, &mask);
2172
2173 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2174 him.s_addr = ip_src.s_addr & mask.s_addr;
2175
2176 if (IPV4_ADDR_SAME (&me, &him))
2177 return 1;
2178
2179 return 0;
2180}
2181
2182int
2183ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2184 struct ospf_header *ospfh)
2185{
2186 int ret = 0;
2187 struct crypt_key *ck;
2188
2189 switch (ntohs (ospfh->auth_type))
2190 {
2191 case OSPF_AUTH_NULL:
2192 ret = 1;
2193 break;
2194 case OSPF_AUTH_SIMPLE:
2195 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2196 ret = 1;
2197 else
2198 ret = 0;
2199 break;
2200 case OSPF_AUTH_CRYPTOGRAPHIC:
2201 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2202 {
2203 ret = 0;
2204 break;
2205 }
2206
2207 /* This is very basic, the digest processing is elsewhere */
2208 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2209 ospfh->u.crypt.key_id == ck->key_id &&
2210 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2211 ret = 1;
2212 else
2213 ret = 0;
2214 break;
2215 default:
2216 ret = 0;
2217 break;
2218 }
2219
2220 return ret;
2221}
2222
2223int
2224ospf_check_sum (struct ospf_header *ospfh)
2225{
2226 u_int32_t ret;
2227 u_int16_t sum;
2228 int in_cksum (void *ptr, int nbytes);
2229
2230 /* clear auth_data for checksum. */
2231 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2232
2233 /* keep checksum and clear. */
2234 sum = ospfh->checksum;
2235 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2236
2237 /* calculate checksum. */
2238 ret = in_cksum (ospfh, ntohs (ospfh->length));
2239
2240 if (ret != sum)
2241 {
2242 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2243 ret, sum);
2244 return 0;
2245 }
2246
2247 return 1;
2248}
2249
2250/* OSPF Header verification. */
2251int
2252ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2253 struct ip *iph, struct ospf_header *ospfh)
2254{
2255 /* check version. */
2256 if (ospfh->version != OSPF_VERSION)
2257 {
2258 zlog_warn ("interface %s: ospf_read version number mismatch.",
2259 IF_NAME (oi));
2260 return -1;
2261 }
2262
2263 /* Check Area ID. */
2264 if (!ospf_check_area_id (oi, ospfh))
2265 {
2266 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2267 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2268 return -1;
2269 }
2270
2271 /* Check network mask, Silently discarded. */
2272 if (! ospf_check_network_mask (oi, iph->ip_src))
2273 {
2274 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2275 IF_NAME (oi), inet_ntoa (iph->ip_src));
2276 return -1;
2277 }
2278
2279 /* Check authentication. */
2280 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2281 {
2282 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2283 IF_NAME (oi));
2284 return -1;
2285 }
2286
2287 if (! ospf_check_auth (oi, ibuf, ospfh))
2288 {
2289 zlog_warn ("interface %s: ospf_read authentication failed.",
2290 IF_NAME (oi));
2291 return -1;
2292 }
2293
2294 /* if check sum is invalid, packet is discarded. */
2295 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2296 {
2297 if (! ospf_check_sum (ospfh))
2298 {
2299 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2300 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2301 return -1;
2302 }
2303 }
2304 else
2305 {
2306 if (ospfh->checksum != 0)
2307 return -1;
2308 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2309 {
2310 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2311 IF_NAME (oi));
2312 return -1;
2313 }
2314 }
2315
2316 return 0;
2317}
2318
2319/* Starting point of packet process function. */
2320int
2321ospf_read (struct thread *thread)
2322{
2323 int ret;
2324 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002325 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002326 struct ospf_interface *oi;
2327 struct ip *iph;
2328 struct ospf_header *ospfh;
2329 u_int16_t length;
2330 struct interface *ifp;
2331
2332 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002333 ospf = THREAD_ARG (thread);
2334 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002335
2336 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002337 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002338 if (ibuf == NULL)
2339 return -1;
2340
paul06f953f2004-10-22 17:00:38 +00002341 iph = (struct ip *) STREAM_DATA (ibuf);
2342 sockopt_iphdrincl_swab_systoh (iph);
2343
paulac191232004-10-22 12:05:17 +00002344 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002345 /* Handle cases where the platform does not support retrieving the ifindex,
2346 and also platforms (such as Solaris 8) that claim to support ifindex
2347 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002348 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002349
pauld3f0d622004-05-05 15:27:15 +00002350 if (ifp == NULL)
2351 {
2352 stream_free (ibuf);
2353 return 0;
2354 }
paul6b333612004-10-11 10:11:25 +00002355
paul718e3742002-12-13 20:15:29 +00002356 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002357 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002358
2359 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002360 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002361 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002362
paul718e3742002-12-13 20:15:29 +00002363 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002364 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002365 {
pauld3241812003-09-29 12:42:39 +00002366 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2367 {
ajs2a42e282004-12-08 18:43:03 +00002368 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002369 inet_ntoa (iph->ip_src));
2370 }
paul718e3742002-12-13 20:15:29 +00002371 stream_free (ibuf);
2372 return 0;
2373 }
2374
2375 /* Adjust size to message length. */
2376 stream_forward (ibuf, iph->ip_hl * 4);
2377
2378 /* Get ospf packet header. */
2379 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2380
2381 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002382 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002383
2384 /* if no local ospf_interface,
2385 * or header area is backbone but ospf_interface is not
2386 * check for VLINK interface
2387 */
2388 if ( (oi == NULL) ||
2389 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2390 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2391 )
2392 {
2393 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2394 {
2395 zlog_warn ("Packet from [%s] received on link %s"
2396 " but no ospf_interface",
2397 inet_ntoa (iph->ip_src), ifp->name);
2398 stream_free (ibuf);
2399 return 0;
2400 }
2401 }
2402
2403 /* else it must be a local ospf interface, check it was received on
2404 * correct link
2405 */
2406 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002407 {
2408 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002409 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002410 stream_free (ibuf);
2411 return 0;
2412 }
paul718e3742002-12-13 20:15:29 +00002413
2414 /*
2415 * If the received packet is destined for AllDRouters, the packet
2416 * should be accepted only if the received ospf interface state is
2417 * either DR or Backup -- endo.
2418 */
2419 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2420 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2421 {
2422 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2423 inet_ntoa (iph->ip_src), IF_NAME (oi),
2424 LOOKUP (ospf_ism_state_msg, oi->state));
2425 stream_free (ibuf);
2426 return 0;
2427 }
2428
2429 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002430 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2431 {
paul718e3742002-12-13 20:15:29 +00002432 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002433 {
ajs2a42e282004-12-08 18:43:03 +00002434 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002435 ospf_packet_dump (ibuf);
2436 }
paul718e3742002-12-13 20:15:29 +00002437
ajs2a42e282004-12-08 18:43:03 +00002438 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002439 ospf_packet_type_str[ospfh->type],
2440 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002441 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2442 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002443
2444 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002445 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002446 }
paul718e3742002-12-13 20:15:29 +00002447
2448 /* Some header verification. */
2449 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2450 if (ret < 0)
2451 {
pauld3241812003-09-29 12:42:39 +00002452 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2453 {
ajs2a42e282004-12-08 18:43:03 +00002454 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002455 "dropping.",
2456 ospf_packet_type_str[ospfh->type],
2457 inet_ntoa (iph->ip_src));
2458 }
paul718e3742002-12-13 20:15:29 +00002459 stream_free (ibuf);
2460 return ret;
2461 }
2462
2463 stream_forward (ibuf, OSPF_HEADER_SIZE);
2464
2465 /* Adjust size to message length. */
2466 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2467
2468 /* Read rest of the packet and call each sort of packet routine. */
2469 switch (ospfh->type)
2470 {
2471 case OSPF_MSG_HELLO:
2472 ospf_hello (iph, ospfh, ibuf, oi, length);
2473 break;
2474 case OSPF_MSG_DB_DESC:
2475 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2476 break;
2477 case OSPF_MSG_LS_REQ:
2478 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2479 break;
2480 case OSPF_MSG_LS_UPD:
2481 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2482 break;
2483 case OSPF_MSG_LS_ACK:
2484 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2485 break;
2486 default:
2487 zlog (NULL, LOG_WARNING,
2488 "interface %s: OSPF packet header type %d is illegal",
2489 IF_NAME (oi), ospfh->type);
2490 break;
2491 }
2492
2493 stream_free (ibuf);
2494 return 0;
2495}
2496
2497/* Make OSPF header. */
2498void
2499ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2500{
2501 struct ospf_header *ospfh;
2502
2503 ospfh = (struct ospf_header *) STREAM_DATA (s);
2504
2505 ospfh->version = (u_char) OSPF_VERSION;
2506 ospfh->type = (u_char) type;
2507
paul68980082003-03-25 05:07:42 +00002508 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002509
2510 ospfh->checksum = 0;
2511 ospfh->area_id = oi->area->area_id;
2512 ospfh->auth_type = htons (ospf_auth_type (oi));
2513
2514 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2515
2516 ospf_output_forward (s, OSPF_HEADER_SIZE);
2517}
2518
2519/* Make Authentication Data. */
2520int
2521ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2522{
2523 struct crypt_key *ck;
2524
2525 switch (ospf_auth_type (oi))
2526 {
2527 case OSPF_AUTH_NULL:
2528 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2529 break;
2530 case OSPF_AUTH_SIMPLE:
2531 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2532 OSPF_AUTH_SIMPLE_SIZE);
2533 break;
2534 case OSPF_AUTH_CRYPTOGRAPHIC:
2535 /* If key is not set, then set 0. */
2536 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2537 {
2538 ospfh->u.crypt.zero = 0;
2539 ospfh->u.crypt.key_id = 0;
2540 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2541 }
2542 else
2543 {
2544 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2545 ospfh->u.crypt.zero = 0;
2546 ospfh->u.crypt.key_id = ck->key_id;
2547 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2548 }
2549 /* note: the seq is done in ospf_make_md5_digest() */
2550 break;
2551 default:
2552 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2553 break;
2554 }
2555
2556 return 0;
2557}
2558
2559/* Fill rest of OSPF header. */
2560void
2561ospf_fill_header (struct ospf_interface *oi,
2562 struct stream *s, u_int16_t length)
2563{
2564 struct ospf_header *ospfh;
2565
2566 ospfh = (struct ospf_header *) STREAM_DATA (s);
2567
2568 /* Fill length. */
2569 ospfh->length = htons (length);
2570
2571 /* Calculate checksum. */
2572 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2573 ospfh->checksum = in_cksum (ospfh, length);
2574 else
2575 ospfh->checksum = 0;
2576
2577 /* Add Authentication Data. */
2578 ospf_make_auth (oi, ospfh);
2579}
2580
2581int
2582ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2583{
2584 struct ospf_neighbor *nbr;
2585 struct route_node *rn;
2586 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2587 struct in_addr mask;
2588 unsigned long p;
2589 int flag = 0;
2590
2591 /* Set netmask of interface. */
2592 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2593 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2594 masklen2ip (oi->address->prefixlen, &mask);
2595 else
2596 memset ((char *) &mask, 0, sizeof (struct in_addr));
2597 stream_put_ipv4 (s, mask.s_addr);
2598
2599 /* Set Hello Interval. */
2600 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2601
2602 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002603 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002604 OPTIONS(oi), IF_NAME (oi));
2605
2606 /* Set Options. */
2607 stream_putc (s, OPTIONS (oi));
2608
2609 /* Set Router Priority. */
2610 stream_putc (s, PRIORITY (oi));
2611
2612 /* Set Router Dead Interval. */
2613 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2614
2615 /* Set Designated Router. */
2616 stream_put_ipv4 (s, DR (oi).s_addr);
2617
2618 p = s->putp;
2619
2620 /* Set Backup Designated Router. */
2621 stream_put_ipv4 (s, BDR (oi).s_addr);
2622
2623 /* Add neighbor seen. */
2624 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002625 if ((nbr = rn->info))
2626 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2627 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2628 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2629 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002630 {
2631 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002632 if (nbr->d_router.s_addr != 0
2633 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2634 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2635 flag = 1;
paul718e3742002-12-13 20:15:29 +00002636
2637 stream_put_ipv4 (s, nbr->router_id.s_addr);
2638 length += 4;
2639 }
2640
2641 /* Let neighbor generate BackupSeen. */
2642 if (flag == 1)
2643 {
2644 stream_set_putp (s, p);
2645 stream_put_ipv4 (s, 0);
2646 }
2647
2648 return length;
2649}
2650
2651int
2652ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2653 struct stream *s)
2654{
2655 struct ospf_lsa *lsa;
2656 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2657 u_char options;
2658 unsigned long pp;
2659 int i;
2660 struct ospf_lsdb *lsdb;
2661
2662 /* Set Interface MTU. */
2663 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2664 stream_putw (s, 0);
2665 else
2666 stream_putw (s, oi->ifp->mtu);
2667
2668 /* Set Options. */
2669 options = OPTIONS (oi);
2670#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002671 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002672 {
2673 if (IS_SET_DD_I (nbr->dd_flags)
2674 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2675 /*
2676 * Set O-bit in the outgoing DD packet for capablity negotiation,
2677 * if one of following case is applicable.
2678 *
2679 * 1) WaitTimer expiration event triggered the neighbor state to
2680 * change to Exstart, but no (valid) DD packet has received
2681 * from the neighbor yet.
2682 *
2683 * 2) At least one DD packet with O-bit on has received from the
2684 * neighbor.
2685 */
2686 SET_FLAG (options, OSPF_OPTION_O);
2687 }
2688#endif /* HAVE_OPAQUE_LSA */
2689 stream_putc (s, options);
2690
2691 /* Keep pointer to flags. */
2692 pp = stream_get_putp (s);
2693 stream_putc (s, nbr->dd_flags);
2694
2695 /* Set DD Sequence Number. */
2696 stream_putl (s, nbr->dd_seqnum);
2697
2698 if (ospf_db_summary_isempty (nbr))
2699 {
2700 if (nbr->state >= NSM_Exchange)
2701 {
2702 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2703 /* Set DD flags again */
2704 stream_set_putp (s, pp);
2705 stream_putc (s, nbr->dd_flags);
2706 }
2707 return length;
2708 }
2709
2710 /* Describe LSA Header from Database Summary List. */
2711 lsdb = &nbr->db_sum;
2712
2713 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2714 {
2715 struct route_table *table = lsdb->type[i].db;
2716 struct route_node *rn;
2717
2718 for (rn = route_top (table); rn; rn = route_next (rn))
2719 if ((lsa = rn->info) != NULL)
2720 {
2721#ifdef HAVE_OPAQUE_LSA
2722 if (IS_OPAQUE_LSA (lsa->data->type)
2723 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2724 {
2725 /* Suppress advertising opaque-informations. */
2726 /* Remove LSA from DB summary list. */
2727 ospf_lsdb_delete (lsdb, lsa);
2728 continue;
2729 }
2730#endif /* HAVE_OPAQUE_LSA */
2731
2732 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2733 {
2734 struct lsa_header *lsah;
2735 u_int16_t ls_age;
2736
2737 /* DD packet overflows interface MTU. */
2738 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2739 break;
2740
2741 /* Keep pointer to LS age. */
2742 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2743 stream_get_putp (s));
2744
2745 /* Proceed stream pointer. */
2746 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2747 length += OSPF_LSA_HEADER_SIZE;
2748
2749 /* Set LS age. */
2750 ls_age = LS_AGE (lsa);
2751 lsah->ls_age = htons (ls_age);
2752
2753 }
2754
2755 /* Remove LSA from DB summary list. */
2756 ospf_lsdb_delete (lsdb, lsa);
2757 }
2758 }
2759
2760 return length;
2761}
2762
2763int
2764ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2765 unsigned long delta, struct ospf_neighbor *nbr,
2766 struct ospf_lsa *lsa)
2767{
2768 struct ospf_interface *oi;
2769
2770 oi = nbr->oi;
2771
2772 /* LS Request packet overflows interface MTU. */
2773 if (*length + delta > OSPF_PACKET_MAX(oi))
2774 return 0;
2775
2776 stream_putl (s, lsa->data->type);
2777 stream_put_ipv4 (s, lsa->data->id.s_addr);
2778 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2779
2780 ospf_lsa_unlock (nbr->ls_req_last);
2781 nbr->ls_req_last = ospf_lsa_lock (lsa);
2782
2783 *length += 12;
2784 return 1;
2785}
2786
2787int
2788ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2789{
2790 struct ospf_lsa *lsa;
2791 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2792 unsigned long delta = stream_get_putp(s)+12;
2793 struct route_table *table;
2794 struct route_node *rn;
2795 int i;
2796 struct ospf_lsdb *lsdb;
2797
2798 lsdb = &nbr->ls_req;
2799
2800 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2801 {
2802 table = lsdb->type[i].db;
2803 for (rn = route_top (table); rn; rn = route_next (rn))
2804 if ((lsa = (rn->info)) != NULL)
2805 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2806 {
2807 route_unlock_node (rn);
2808 break;
2809 }
2810 }
2811 return length;
2812}
2813
2814int
2815ls_age_increment (struct ospf_lsa *lsa, int delay)
2816{
2817 int age;
2818
2819 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2820
2821 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2822}
2823
2824int
hasso52dc7ee2004-09-23 19:18:23 +00002825ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002826{
2827 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002828 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002829 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2830 unsigned long delta = stream_get_putp (s);
2831 unsigned long pp;
2832 int count = 0;
2833
2834 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002835 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002836
paul718e3742002-12-13 20:15:29 +00002837 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002838 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002839
2840 while ((node = listhead (update)) != NULL)
2841 {
2842 struct lsa_header *lsah;
2843 u_int16_t ls_age;
2844
2845 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002846 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002847
2848 lsa = getdata (node);
2849 assert (lsa);
2850 assert (lsa->data);
2851
paul68b73392004-09-12 14:21:37 +00002852 /* Will it fit? */
2853 if (length + delta + ntohs (lsa->data->length) > stream_get_size (s))
paul59ea14c2004-07-14 20:50:36 +00002854 break;
2855
paul718e3742002-12-13 20:15:29 +00002856 /* Keep pointer to LS age. */
2857 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2858
2859 /* Put LSA to Link State Request. */
2860 stream_put (s, lsa->data, ntohs (lsa->data->length));
2861
2862 /* Set LS age. */
2863 /* each hop must increment an lsa_age by transmit_delay
2864 of OSPF interface */
2865 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2866 lsah->ls_age = htons (ls_age);
2867
2868 length += ntohs (lsa->data->length);
2869 count++;
2870
2871 list_delete_node (update, node);
2872 ospf_lsa_unlock (lsa);
2873 }
2874
2875 /* Now set #LSAs. */
2876 stream_set_putp (s, pp);
2877 stream_putl (s, count);
2878
2879 stream_set_putp (s, s->endp);
2880
2881 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002882 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002883 return length;
2884}
2885
2886int
hasso52dc7ee2004-09-23 19:18:23 +00002887ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002888{
hasso52dc7ee2004-09-23 19:18:23 +00002889 struct list *rm_list;
2890 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002891 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2892 unsigned long delta = stream_get_putp(s) + 24;
2893 struct ospf_lsa *lsa;
2894
2895 rm_list = list_new ();
2896
2897 for (node = listhead (ack); node; nextnode (node))
2898 {
2899 lsa = getdata (node);
2900 assert (lsa);
2901
2902 if (length + delta > OSPF_PACKET_MAX (oi))
2903 break;
2904
2905 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2906 length += OSPF_LSA_HEADER_SIZE;
2907
2908 listnode_add (rm_list, lsa);
2909 }
2910
2911 /* Remove LSA from LS-Ack list. */
2912 for (node = listhead (rm_list); node; nextnode (node))
2913 {
2914 lsa = (struct ospf_lsa *) getdata (node);
2915
2916 listnode_delete (ack, lsa);
2917 ospf_lsa_unlock (lsa);
2918 }
2919
2920 list_delete (rm_list);
2921
2922 return length;
2923}
2924
2925void
2926ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2927{
2928 struct ospf_packet *op;
2929 u_int16_t length = OSPF_HEADER_SIZE;
2930
2931 op = ospf_packet_new (oi->ifp->mtu);
2932
2933 /* Prepare OSPF common header. */
2934 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2935
2936 /* Prepare OSPF Hello body. */
2937 length += ospf_make_hello (oi, op->s);
2938
2939 /* Fill OSPF header. */
2940 ospf_fill_header (oi, op->s, length);
2941
2942 /* Set packet length. */
2943 op->length = length;
2944
2945 op->dst.s_addr = addr->s_addr;
2946
2947 /* Add packet to the interface output queue. */
2948 ospf_packet_add (oi, op);
2949
2950 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002951 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002952}
2953
2954void
2955ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2956{
2957 struct ospf_interface *oi;
2958
2959 oi = nbr_nbma->oi;
2960 assert(oi);
2961
2962 /* If this is passive interface, do not send OSPF Hello. */
2963 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2964 return;
2965
2966 if (oi->type != OSPF_IFTYPE_NBMA)
2967 return;
2968
2969 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2970 return;
2971
2972 if (PRIORITY(oi) == 0)
2973 return;
2974
2975 if (nbr_nbma->priority == 0
2976 && oi->state != ISM_DR && oi->state != ISM_Backup)
2977 return;
2978
2979 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2980}
2981
2982int
2983ospf_poll_timer (struct thread *thread)
2984{
2985 struct ospf_nbr_nbma *nbr_nbma;
2986
2987 nbr_nbma = THREAD_ARG (thread);
2988 nbr_nbma->t_poll = NULL;
2989
2990 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002991 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002992 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2993
2994 ospf_poll_send (nbr_nbma);
2995
2996 if (nbr_nbma->v_poll > 0)
2997 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2998 nbr_nbma->v_poll);
2999
3000 return 0;
3001}
3002
3003
3004int
3005ospf_hello_reply_timer (struct thread *thread)
3006{
3007 struct ospf_neighbor *nbr;
3008
3009 nbr = THREAD_ARG (thread);
3010 nbr->t_hello_reply = NULL;
3011
3012 assert (nbr->oi);
3013
3014 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003015 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003016 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3017
3018 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3019
3020 return 0;
3021}
3022
3023/* Send OSPF Hello. */
3024void
3025ospf_hello_send (struct ospf_interface *oi)
3026{
3027 struct ospf_packet *op;
3028 u_int16_t length = OSPF_HEADER_SIZE;
3029
3030 /* If this is passive interface, do not send OSPF Hello. */
3031 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3032 return;
3033
3034 op = ospf_packet_new (oi->ifp->mtu);
3035
3036 /* Prepare OSPF common header. */
3037 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3038
3039 /* Prepare OSPF Hello body. */
3040 length += ospf_make_hello (oi, op->s);
3041
3042 /* Fill OSPF header. */
3043 ospf_fill_header (oi, op->s, length);
3044
3045 /* Set packet length. */
3046 op->length = length;
3047
3048 if (oi->type == OSPF_IFTYPE_NBMA)
3049 {
3050 struct ospf_neighbor *nbr;
3051 struct route_node *rn;
3052
3053 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3054 if ((nbr = rn->info))
3055 if (nbr != oi->nbr_self)
3056 if (nbr->state != NSM_Down)
3057 {
3058 /* RFC 2328 Section 9.5.1
3059 If the router is not eligible to become Designated Router,
3060 it must periodically send Hello Packets to both the
3061 Designated Router and the Backup Designated Router (if they
3062 exist). */
3063 if (PRIORITY(oi) == 0 &&
3064 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3065 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3066 continue;
3067
3068 /* If the router is eligible to become Designated Router, it
3069 must periodically send Hello Packets to all neighbors that
3070 are also eligible. In addition, if the router is itself the
3071 Designated Router or Backup Designated Router, it must also
3072 send periodic Hello Packets to all other neighbors. */
3073
3074 if (nbr->priority == 0 && oi->state == ISM_DROther)
3075 continue;
3076 /* if oi->state == Waiting, send hello to all neighbors */
3077 {
3078 struct ospf_packet *op_dup;
3079
3080 op_dup = ospf_packet_dup(op);
3081 op_dup->dst = nbr->address.u.prefix4;
3082
3083 /* Add packet to the interface output queue. */
3084 ospf_packet_add (oi, op_dup);
3085
paul020709f2003-04-04 02:44:16 +00003086 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003087 }
3088
3089 }
3090 ospf_packet_free (op);
3091 }
3092 else
3093 {
3094 /* Decide destination address. */
3095 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3096 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3097 else
3098 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3099
3100 /* Add packet to the interface output queue. */
3101 ospf_packet_add (oi, op);
3102
3103 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003104 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003105 }
3106}
3107
3108/* Send OSPF Database Description. */
3109void
3110ospf_db_desc_send (struct ospf_neighbor *nbr)
3111{
3112 struct ospf_interface *oi;
3113 struct ospf_packet *op;
3114 u_int16_t length = OSPF_HEADER_SIZE;
3115
3116 oi = nbr->oi;
3117 op = ospf_packet_new (oi->ifp->mtu);
3118
3119 /* Prepare OSPF common header. */
3120 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3121
3122 /* Prepare OSPF Database Description body. */
3123 length += ospf_make_db_desc (oi, nbr, op->s);
3124
3125 /* Fill OSPF header. */
3126 ospf_fill_header (oi, op->s, length);
3127
3128 /* Set packet length. */
3129 op->length = length;
3130
3131 /* Decide destination address. */
3132 op->dst = nbr->address.u.prefix4;
3133
3134 /* Add packet to the interface output queue. */
3135 ospf_packet_add (oi, op);
3136
3137 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003138 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003139
3140 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3141 if (nbr->last_send)
3142 ospf_packet_free (nbr->last_send);
3143 nbr->last_send = ospf_packet_dup (op);
3144 gettimeofday (&nbr->last_send_ts, NULL);
3145}
3146
3147/* Re-send Database Description. */
3148void
3149ospf_db_desc_resend (struct ospf_neighbor *nbr)
3150{
3151 struct ospf_interface *oi;
3152
3153 oi = nbr->oi;
3154
3155 /* Add packet to the interface output queue. */
3156 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3157
3158 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003159 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003160}
3161
3162/* Send Link State Request. */
3163void
3164ospf_ls_req_send (struct ospf_neighbor *nbr)
3165{
3166 struct ospf_interface *oi;
3167 struct ospf_packet *op;
3168 u_int16_t length = OSPF_HEADER_SIZE;
3169
3170 oi = nbr->oi;
3171 op = ospf_packet_new (oi->ifp->mtu);
3172
3173 /* Prepare OSPF common header. */
3174 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3175
3176 /* Prepare OSPF Link State Request body. */
3177 length += ospf_make_ls_req (nbr, op->s);
3178 if (length == OSPF_HEADER_SIZE)
3179 {
3180 ospf_packet_free (op);
3181 return;
3182 }
3183
3184 /* Fill OSPF header. */
3185 ospf_fill_header (oi, op->s, length);
3186
3187 /* Set packet length. */
3188 op->length = length;
3189
3190 /* Decide destination address. */
3191 op->dst = nbr->address.u.prefix4;
3192
3193 /* Add packet to the interface output queue. */
3194 ospf_packet_add (oi, op);
3195
3196 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003197 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003198
3199 /* Add Link State Request Retransmission Timer. */
3200 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3201}
3202
3203/* Send Link State Update with an LSA. */
3204void
3205ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3206 int flag)
3207{
hasso52dc7ee2004-09-23 19:18:23 +00003208 struct list *update;
paul718e3742002-12-13 20:15:29 +00003209
3210 update = list_new ();
3211
3212 listnode_add (update, lsa);
3213 ospf_ls_upd_send (nbr, update, flag);
3214
3215 list_delete (update);
3216}
3217
paul68b73392004-09-12 14:21:37 +00003218/* Determine size for packet. Must be at least big enough to accomodate next
3219 * LSA on list, which may be bigger than MTU size.
3220 *
3221 * Return pointer to new ospf_packet
3222 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3223 * on packet sizes (in which case offending LSA is deleted from update list)
3224 */
3225static struct ospf_packet *
3226ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3227{
3228 struct ospf_lsa *lsa;
3229 struct listnode *ln;
3230 size_t size;
3231 static char warned = 0;
3232
3233 ln = listhead (update);
3234 lsa = getdata (ln);
3235 assert (lsa);
3236 assert (lsa->data);
3237
3238 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3239 > ospf_packet_max (oi))
3240 {
3241 if (!warned)
3242 {
3243 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3244 "will need to fragment. Not optimal. Try divide up"
3245 " your network with areas. Use 'debug ospf packet send'"
3246 " to see details, or look at 'show ip ospf database ..'");
3247 warned = 1;
3248 }
3249
3250 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003251 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003252 " %d bytes originated by %s, will be fragmented!",
3253 inet_ntoa (lsa->data->id),
3254 ntohs (lsa->data->length),
3255 inet_ntoa (lsa->data->adv_router));
3256
3257 /*
3258 * Allocate just enough to fit this LSA only, to avoid including other
3259 * LSAs in fragmented LSA Updates.
3260 */
3261 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3262 + OSPF_LS_UPD_MIN_SIZE;
3263 }
3264 else
3265 size = oi->ifp->mtu;
3266
3267 if (size > OSPF_MAX_PACKET_SIZE)
3268 {
3269 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003270 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003271 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003272 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003273 (long int) size);
paul68b73392004-09-12 14:21:37 +00003274 list_delete_node (update, ln);
3275 return NULL;
3276 }
3277
3278 return ospf_packet_new (size);
3279}
3280
paul718e3742002-12-13 20:15:29 +00003281static void
hasso52dc7ee2004-09-23 19:18:23 +00003282ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003283 struct in_addr addr)
3284{
3285 struct ospf_packet *op;
3286 u_int16_t length = OSPF_HEADER_SIZE;
3287
3288 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003289 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003290
3291 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003292
3293 /* Prepare OSPF common header. */
3294 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3295
paul59ea14c2004-07-14 20:50:36 +00003296 /* Prepare OSPF Link State Update body.
3297 * Includes Type-7 translation.
3298 */
paul718e3742002-12-13 20:15:29 +00003299 length += ospf_make_ls_upd (oi, update, op->s);
3300
3301 /* Fill OSPF header. */
3302 ospf_fill_header (oi, op->s, length);
3303
3304 /* Set packet length. */
3305 op->length = length;
3306
3307 /* Decide destination address. */
3308 op->dst.s_addr = addr.s_addr;
3309
3310 /* Add packet to the interface output queue. */
3311 ospf_packet_add (oi, op);
3312
3313 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003314 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003315}
3316
3317static int
3318ospf_ls_upd_send_queue_event (struct thread *thread)
3319{
3320 struct ospf_interface *oi = THREAD_ARG(thread);
3321 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003322 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003323 struct list *update;
paul68b73392004-09-12 14:21:37 +00003324 char again = 0;
paul718e3742002-12-13 20:15:29 +00003325
3326 oi->t_ls_upd_event = NULL;
3327
3328 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003329 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003330
paul736d3442003-07-24 23:22:57 +00003331 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003332 {
paul736d3442003-07-24 23:22:57 +00003333 rnext = route_next (rn);
3334
paul718e3742002-12-13 20:15:29 +00003335 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003336 continue;
paul68b73392004-09-12 14:21:37 +00003337
3338 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003339
paul48fe13b2004-07-27 17:40:44 +00003340 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003341
paul68b73392004-09-12 14:21:37 +00003342 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003343 if (listcount(update) == 0)
3344 {
3345 list_delete (rn->info);
3346 rn->info = NULL;
3347 route_unlock_node (rn);
3348 }
3349 else
paul68b73392004-09-12 14:21:37 +00003350 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003351 }
3352
3353 if (again != 0)
3354 {
3355 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003356 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003357 " %d nodes to try again, raising new event", again);
3358 oi->t_ls_upd_event =
3359 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003360 }
3361
3362 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003363 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003364
paul718e3742002-12-13 20:15:29 +00003365 return 0;
3366}
3367
3368void
hasso52dc7ee2004-09-23 19:18:23 +00003369ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003370{
3371 struct ospf_interface *oi;
3372 struct prefix_ipv4 p;
3373 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003374 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003375
3376 oi = nbr->oi;
3377
3378 p.family = AF_INET;
3379 p.prefixlen = IPV4_MAX_BITLEN;
3380
3381 /* Decide destination address. */
3382 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3383 p.prefix = oi->vl_data->peer_addr;
3384 else if (flag == OSPF_SEND_PACKET_DIRECT)
3385 p.prefix = nbr->address.u.prefix4;
3386 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3387 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3388 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3389 && (flag == OSPF_SEND_PACKET_INDIRECT))
3390 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003391 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3392 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003393 else
3394 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3395
3396 if (oi->type == OSPF_IFTYPE_NBMA)
3397 {
3398 if (flag == OSPF_SEND_PACKET_INDIRECT)
3399 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3400 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3401 zlog_warn ("* LS-Update is sent to myself.");
3402 }
3403
3404 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3405
3406 if (rn->info == NULL)
3407 rn->info = list_new ();
3408
3409 for (n = listhead (update); n; nextnode (n))
3410 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3411
3412 if (oi->t_ls_upd_event == NULL)
3413 oi->t_ls_upd_event =
3414 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3415}
3416
3417static void
hasso52dc7ee2004-09-23 19:18:23 +00003418ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3419 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003420{
3421 struct ospf_packet *op;
3422 u_int16_t length = OSPF_HEADER_SIZE;
3423
3424 op = ospf_packet_new (oi->ifp->mtu);
3425
3426 /* Prepare OSPF common header. */
3427 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3428
3429 /* Prepare OSPF Link State Acknowledgment body. */
3430 length += ospf_make_ls_ack (oi, ack, op->s);
3431
3432 /* Fill OSPF header. */
3433 ospf_fill_header (oi, op->s, length);
3434
3435 /* Set packet length. */
3436 op->length = length;
3437
3438 /* Set destination IP address. */
3439 op->dst = dst;
3440
3441 /* Add packet to the interface output queue. */
3442 ospf_packet_add (oi, op);
3443
3444 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003445 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003446}
3447
3448static int
3449ospf_ls_ack_send_event (struct thread *thread)
3450{
3451 struct ospf_interface *oi = THREAD_ARG (thread);
3452
3453 oi->t_ls_ack_direct = NULL;
3454
3455 while (listcount (oi->ls_ack_direct.ls_ack))
3456 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3457 oi->ls_ack_direct.dst);
3458
3459 return 0;
3460}
3461
3462void
3463ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3464{
3465 struct ospf_interface *oi = nbr->oi;
3466
3467 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3468 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3469
3470 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3471
3472 if (oi->t_ls_ack_direct == NULL)
3473 oi->t_ls_ack_direct =
3474 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3475}
3476
3477/* Send Link State Acknowledgment delayed. */
3478void
3479ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3480{
3481 struct in_addr dst;
3482
3483 /* Decide destination address. */
3484 /* RFC2328 Section 13.5 On non-broadcast
3485 networks, delayed Link State Acknowledgment packets must be
3486 unicast separately over each adjacency (i.e., neighbor whose
3487 state is >= Exchange). */
3488 if (oi->type == OSPF_IFTYPE_NBMA)
3489 {
3490 struct ospf_neighbor *nbr;
3491 struct route_node *rn;
3492
3493 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3494 if ((nbr = rn->info) != NULL)
3495 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3496 while (listcount (oi->ls_ack))
3497 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3498 return;
3499 }
3500 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3501 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3502 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3503 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3504 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3505 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003506 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3507 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003508 else
3509 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3510
3511 while (listcount (oi->ls_ack))
3512 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3513}