blob: 1b68fd5a5dfe49b8e28573bdf068620cdd7eb6cd [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"
paul484315f2005-11-03 09:08:29 +000035#include "checksum.h"
vincentc1a03d42005-09-28 15:47:44 +000036#include "md5.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_network.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_lsdb.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_spf.h"
49#include "ospfd/ospf_flood.h"
50#include "ospfd/ospf_dump.h"
51
paul718e3742002-12-13 20:15:29 +000052/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000053const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000054{
55 "unknown",
56 "Hello",
57 "Database Description",
58 "Link State Request",
59 "Link State Update",
60 "Link State Acknowledgment",
61};
62
paul718e3742002-12-13 20:15:29 +000063/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000064static int
paul718e3742002-12-13 20:15:29 +000065ospf_auth_type (struct ospf_interface *oi)
66{
67 int auth_type;
68
69 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
70 auth_type = oi->area->auth_type;
71 else
72 auth_type = OSPF_IF_PARAM (oi, auth_type);
73
74 /* Handle case where MD5 key list is not configured aka Cisco */
75 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
76 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
77 return OSPF_AUTH_NULL;
78
79 return auth_type;
80
81}
82
paul718e3742002-12-13 20:15:29 +000083struct ospf_packet *
84ospf_packet_new (size_t size)
85{
86 struct ospf_packet *new;
87
88 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
89 new->s = stream_new (size);
90
91 return new;
92}
93
94void
95ospf_packet_free (struct ospf_packet *op)
96{
97 if (op->s)
98 stream_free (op->s);
99
100 XFREE (MTYPE_OSPF_PACKET, op);
101
102 op = NULL;
103}
104
105struct ospf_fifo *
106ospf_fifo_new ()
107{
108 struct ospf_fifo *new;
109
110 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
111 return new;
112}
113
114/* Add new packet to fifo. */
115void
116ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
117{
118 if (fifo->tail)
119 fifo->tail->next = op;
120 else
121 fifo->head = op;
122
123 fifo->tail = op;
124
125 fifo->count++;
126}
127
128/* Delete first packet from fifo. */
129struct ospf_packet *
130ospf_fifo_pop (struct ospf_fifo *fifo)
131{
132 struct ospf_packet *op;
133
134 op = fifo->head;
135
136 if (op)
137 {
138 fifo->head = op->next;
139
140 if (fifo->head == NULL)
141 fifo->tail = NULL;
142
143 fifo->count--;
144 }
145
146 return op;
147}
148
149/* Return first fifo entry. */
150struct ospf_packet *
151ospf_fifo_head (struct ospf_fifo *fifo)
152{
153 return fifo->head;
154}
155
156/* Flush ospf packet fifo. */
157void
158ospf_fifo_flush (struct ospf_fifo *fifo)
159{
160 struct ospf_packet *op;
161 struct ospf_packet *next;
162
163 for (op = fifo->head; op; op = next)
164 {
165 next = op->next;
166 ospf_packet_free (op);
167 }
168 fifo->head = fifo->tail = NULL;
169 fifo->count = 0;
170}
171
172/* Free ospf packet fifo. */
173void
174ospf_fifo_free (struct ospf_fifo *fifo)
175{
176 ospf_fifo_flush (fifo);
177
178 XFREE (MTYPE_OSPF_FIFO, fifo);
179}
180
181void
182ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
183{
ajsc3eab872005-01-29 15:52:07 +0000184 if (!oi->obuf)
185 {
186 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
187 "destination %s) called with NULL obuf, ignoring "
188 "(please report this bug)!\n",
189 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
190 ospf_packet_type_str[stream_getc_from(op->s, 1)],
191 inet_ntoa (op->dst));
192 return;
193 }
194
paul718e3742002-12-13 20:15:29 +0000195 /* 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
paul718e3742002-12-13 20:15:29 +0000213struct ospf_packet *
214ospf_packet_dup (struct ospf_packet *op)
215{
216 struct ospf_packet *new;
217
paul37163d62003-02-03 18:40:56 +0000218 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000219 /* XXX size_t */
220 zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch",
221 (u_long)STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000222
223 /* Reserve space for MD5 authentication that may be added later. */
224 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000225 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000226
227 new->dst = op->dst;
228 new->length = op->length;
229
230 return new;
231}
232
gdt86f1fd92005-01-10 14:20:43 +0000233/* XXX inline */
paul4dadc292005-05-06 21:37:42 +0000234static inline unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000235ospf_packet_authspace (struct ospf_interface *oi)
236{
237 int auth = 0;
238
239 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
240 auth = OSPF_AUTH_MD5_SIZE;
241
242 return auth;
243}
244
paul4dadc292005-05-06 21:37:42 +0000245static unsigned int
paul718e3742002-12-13 20:15:29 +0000246ospf_packet_max (struct ospf_interface *oi)
247{
248 int max;
249
gdt86f1fd92005-01-10 14:20:43 +0000250 max = oi->ifp->mtu - ospf_packet_authspace(oi);
251
paul68b73392004-09-12 14:21:37 +0000252 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000253
254 return max;
255}
256
257
paul4dadc292005-05-06 21:37:42 +0000258static int
paul718e3742002-12-13 20:15:29 +0000259ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
260 u_int16_t length)
261{
paul6c835672004-10-11 11:00:30 +0000262 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000263 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000264 unsigned char digest[OSPF_AUTH_MD5_SIZE];
265 unsigned char *pdigest;
266 struct crypt_key *ck;
267 struct ospf_header *ospfh;
268 struct ospf_neighbor *nbr;
269
270
271 ibuf = STREAM_PNT (s);
272 ospfh = (struct ospf_header *) ibuf;
273
274 /* Get pointer to the end of the packet. */
275 pdigest = ibuf + length;
276
277 /* Get secret key. */
278 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
279 ospfh->u.crypt.key_id);
280 if (ck == NULL)
281 {
282 zlog_warn ("interface %s: ospf_check_md5 no key %d",
283 IF_NAME (oi), ospfh->u.crypt.key_id);
284 return 0;
285 }
286
287 /* check crypto seqnum. */
288 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
289
290 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
291 {
292 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
293 IF_NAME (oi),
294 ntohl(ospfh->u.crypt.crypt_seqnum),
295 ntohl(nbr->crypt_seqnum));
296 return 0;
297 }
298
299 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000300 memset(&ctx, 0, sizeof(ctx));
301 MD5Init(&ctx);
302 MD5Update(&ctx, ibuf, length);
303 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
304 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000305
306 /* compare the two */
307 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
308 {
309 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
310 IF_NAME (oi));
311 return 0;
312 }
313
314 /* save neighbor's crypt_seqnum */
315 if (nbr)
316 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
317 return 1;
318}
319
320/* This function is called from ospf_write(), it will detect the
321 authentication scheme and if it is MD5, it will change the sequence
322 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000323static int
paul718e3742002-12-13 20:15:29 +0000324ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
325{
326 struct ospf_header *ospfh;
327 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000328 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000329 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000330 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000331 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000332 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000333
334 ibuf = STREAM_DATA (op->s);
335 ospfh = (struct ospf_header *) ibuf;
336
337 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
338 return 0;
339
340 /* We do this here so when we dup a packet, we don't have to
Paul Jakma2518efd2006-08-27 06:49:29 +0000341 waste CPU rewriting other headers.
342
343 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000344 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000345 if (t > oi->crypt_seqnum)
346 oi->crypt_seqnum = t;
347 else
348 oi->crypt_seqnum++;
349
paul9483e152002-12-13 20:55:25 +0000350 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000351
352 /* Get MD5 Authentication key from auth_key list. */
353 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000354 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000355 else
356 {
paul1eb8ef22005-04-07 07:30:20 +0000357 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000358 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000359 }
360
361 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000362 memset(&ctx, 0, sizeof(ctx));
363 MD5Init(&ctx);
364 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
365 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
366 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000367
368 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000369 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000370
371 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000372 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
373
paul37163d62003-02-03 18:40:56 +0000374 if (stream_get_endp(op->s) != op->length)
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000375 /* XXX size_t */
376 zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u",
377 (u_long)stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000378
379 return OSPF_AUTH_MD5_SIZE;
380}
381
382
paul4dadc292005-05-06 21:37:42 +0000383static int
paul718e3742002-12-13 20:15:29 +0000384ospf_ls_req_timer (struct thread *thread)
385{
386 struct ospf_neighbor *nbr;
387
388 nbr = THREAD_ARG (thread);
389 nbr->t_ls_req = NULL;
390
391 /* Send Link State Request. */
392 if (ospf_ls_request_count (nbr))
393 ospf_ls_req_send (nbr);
394
395 /* Set Link State Request retransmission timer. */
396 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
397
398 return 0;
399}
400
401void
402ospf_ls_req_event (struct ospf_neighbor *nbr)
403{
404 if (nbr->t_ls_req)
405 {
406 thread_cancel (nbr->t_ls_req);
407 nbr->t_ls_req = NULL;
408 }
409 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
410}
411
412/* Cyclic timer function. Fist registered in ospf_nbr_new () in
413 ospf_neighbor.c */
414int
415ospf_ls_upd_timer (struct thread *thread)
416{
417 struct ospf_neighbor *nbr;
418
419 nbr = THREAD_ARG (thread);
420 nbr->t_ls_upd = NULL;
421
422 /* Send Link State Update. */
423 if (ospf_ls_retransmit_count (nbr) > 0)
424 {
hasso52dc7ee2004-09-23 19:18:23 +0000425 struct list *update;
paul718e3742002-12-13 20:15:29 +0000426 struct ospf_lsdb *lsdb;
427 int i;
paul718e3742002-12-13 20:15:29 +0000428 int retransmit_interval;
429
paul718e3742002-12-13 20:15:29 +0000430 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
431
432 lsdb = &nbr->ls_rxmt;
433 update = list_new ();
434
435 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
436 {
437 struct route_table *table = lsdb->type[i].db;
438 struct route_node *rn;
439
440 for (rn = route_top (table); rn; rn = route_next (rn))
441 {
442 struct ospf_lsa *lsa;
443
444 if ((lsa = rn->info) != NULL)
445 /* Don't retransmit an LSA if we received it within
446 the last RxmtInterval seconds - this is to allow the
447 neighbour a chance to acknowledge the LSA as it may
448 have ben just received before the retransmit timer
449 fired. This is a small tweak to what is in the RFC,
450 but it will cut out out a lot of retransmit traffic
451 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000452 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000453 int2tv (retransmit_interval)) >= 0)
454 listnode_add (update, rn->info);
455 }
456 }
457
458 if (listcount (update) > 0)
459 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
460 list_delete (update);
461 }
462
463 /* Set LS Update retransmission timer. */
464 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
465
466 return 0;
467}
468
469int
470ospf_ls_ack_timer (struct thread *thread)
471{
472 struct ospf_interface *oi;
473
474 oi = THREAD_ARG (thread);
475 oi->t_ls_ack = NULL;
476
477 /* Send Link State Acknowledgment. */
478 if (listcount (oi->ls_ack) > 0)
479 ospf_ls_ack_send_delayed (oi);
480
481 /* Set LS Ack timer. */
482 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
483
484 return 0;
485}
486
paul0bfeca32004-09-24 08:07:54 +0000487#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000488static void
paul6a99f832004-09-27 12:56:30 +0000489ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000490 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000491 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000492{
493#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000494 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000495 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000496 int ret;
paul0bfeca32004-09-24 08:07:54 +0000497
498 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000499 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000500
501 /* we can but try.
502 *
503 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
504 * well as the IP_MF flag, making this all quite pointless.
505 *
506 * However, for a system on which IP_MF is left alone, and ip_id left
507 * alone or else which sets same ip_id for each fragment this might
508 * work, eg linux.
509 *
510 * XXX-TODO: It would be much nicer to have the kernel's use their
511 * existing fragmentation support to do this for us. Bugs/RFEs need to
512 * be raised against the various kernels.
513 */
514
515 /* set More Frag */
516 iph->ip_off |= IP_MF;
517
518 /* ip frag offset is expressed in units of 8byte words */
519 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
520
paul62d8e962004-11-02 20:26:45 +0000521 iovp = &msg->msg_iov[1];
522
paul0bfeca32004-09-24 08:07:54 +0000523 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
524 > maxdatasize )
525 {
526 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000527 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
528 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000529 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000530
paul18b12c32004-10-05 14:38:29 +0000531 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000532
paul6a99f832004-09-27 12:56:30 +0000533 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000534
paul18b12c32004-10-05 14:38:29 +0000535 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000536
537 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000538 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000539 " id %d, off %d, len %d, mtu %u failed with %s",
540 inet_ntoa (iph->ip_dst),
541 iph->ip_id,
542 iph->ip_off,
543 iph->ip_len,
544 mtu,
545 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000546
paul37ccfa32004-10-31 11:24:51 +0000547 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
548 {
ajs2a42e282004-12-08 18:43:03 +0000549 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000550 iph->ip_id, iph->ip_off, iph->ip_len,
551 inet_ntoa (iph->ip_dst));
552 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
553 {
ajs2a42e282004-12-08 18:43:03 +0000554 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000555 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000556 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000557 }
558 }
559
paul0bfeca32004-09-24 08:07:54 +0000560 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000561 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000562 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000563 }
564
565 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000566 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
567 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000568 iph->ip_off &= (~IP_MF);
569}
570#endif /* WANT_OSPF_WRITE_FRAGMENT */
571
ajs5dcbdf82005-03-29 16:13:49 +0000572static int
paul718e3742002-12-13 20:15:29 +0000573ospf_write (struct thread *thread)
574{
paul68980082003-03-25 05:07:42 +0000575 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000576 struct ospf_interface *oi;
577 struct ospf_packet *op;
578 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000579 struct ip iph;
580 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000581 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000582 u_char type;
583 int ret;
584 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000585 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000586#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000587 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000588#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000589 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000590#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000591
paul68980082003-03-25 05:07:42 +0000592 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000593
paul68980082003-03-25 05:07:42 +0000594 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000595 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000596 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000597 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000598
599#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000600 /* seed ipid static with low order bits of time */
601 if (ipid == 0)
602 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000603#endif /* WANT_OSPF_WRITE_FRAGMENT */
604
Denis Ovsienkob7fe4142007-08-21 16:32:56 +0000605 /* convenience - max OSPF data per packet,
606 * and reliability - not more data, than our
607 * socket can accept
608 */
609 maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) -
610 sizeof (struct ip);
paul68b73392004-09-12 14:21:37 +0000611
paul718e3742002-12-13 20:15:29 +0000612 /* Get one packet from queue. */
613 op = ospf_fifo_head (oi->obuf);
614 assert (op);
615 assert (op->length >= OSPF_HEADER_SIZE);
616
paul68980082003-03-25 05:07:42 +0000617 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
618 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000619 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
620
paul718e3742002-12-13 20:15:29 +0000621 /* Rewrite the md5 signature & update the seq */
622 ospf_make_md5_digest (oi, op);
623
paul37ccfa32004-10-31 11:24:51 +0000624 /* Retrieve OSPF packet type. */
625 stream_set_getp (op->s, 1);
626 type = stream_getc (op->s);
627
paul68b73392004-09-12 14:21:37 +0000628 /* reset get pointer */
629 stream_set_getp (op->s, 0);
630
631 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000632 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000633
paul718e3742002-12-13 20:15:29 +0000634 sa_dst.sin_family = AF_INET;
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000635#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
paul718e3742002-12-13 20:15:29 +0000636 sa_dst.sin_len = sizeof(sa_dst);
Paul Jakma6f0e3f62007-05-10 02:38:51 +0000637#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
paul718e3742002-12-13 20:15:29 +0000638 sa_dst.sin_addr = op->dst;
639 sa_dst.sin_port = htons (0);
640
641 /* Set DONTROUTE flag if dst is unicast. */
642 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
643 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
644 flags = MSG_DONTROUTE;
645
paul68b73392004-09-12 14:21:37 +0000646 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
647 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000648 if ( sizeof (struct ip)
649 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000650 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
651
paul718e3742002-12-13 20:15:29 +0000652 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000653 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000654 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000655
David BÉRARD0150c9c2010-05-11 10:17:53 +0200656#if defined(__DragonFly__)
657 /*
658 * DragonFly's raw socket expects ip_len/ip_off in network byte order.
659 */
660 iph.ip_len = htons(iph.ip_len);
661#endif
662
paul0bfeca32004-09-24 08:07:54 +0000663#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000664 /* XXX-MT: not thread-safe at all..
665 * XXX: this presumes this is only programme sending OSPF packets
666 * otherwise, no guarantee ipid will be unique
667 */
668 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000669#endif /* WANT_OSPF_WRITE_FRAGMENT */
670
paul718e3742002-12-13 20:15:29 +0000671 iph.ip_off = 0;
672 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
673 iph.ip_ttl = OSPF_VL_IP_TTL;
674 else
675 iph.ip_ttl = OSPF_IP_TTL;
676 iph.ip_p = IPPROTO_OSPFIGP;
677 iph.ip_sum = 0;
678 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
679 iph.ip_dst.s_addr = op->dst.s_addr;
680
681 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000682 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000683 msg.msg_namelen = sizeof (sa_dst);
684 msg.msg_iov = iov;
685 msg.msg_iovlen = 2;
686 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000687 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
688 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000689 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000690
691 /* Sadly we can not rely on kernels to fragment packets because of either
692 * IP_HDRINCL and/or multicast destination being set.
693 */
paul0bfeca32004-09-24 08:07:54 +0000694#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000695 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000696 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
697 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000698#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000699
700 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000701 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000702 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000703 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000704
705 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000706 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000707 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000708 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000709 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000710
paul718e3742002-12-13 20:15:29 +0000711 /* Show debug sending packet. */
712 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
713 {
714 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
715 {
ajs2a42e282004-12-08 18:43:03 +0000716 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000717 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000718 stream_set_getp (op->s, 0);
719 ospf_packet_dump (op->s);
720 }
721
ajs2a42e282004-12-08 18:43:03 +0000722 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000723 ospf_packet_type_str[type], inet_ntoa (op->dst),
724 IF_NAME (oi));
725
726 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000727 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000728 }
729
730 /* Now delete packet from queue. */
731 ospf_packet_delete (oi);
732
733 if (ospf_fifo_head (oi->obuf) == NULL)
734 {
735 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000736 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000737 }
738
739 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000740 if (!list_isempty (ospf->oi_write_q))
741 ospf->t_write =
742 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000743
744 return 0;
745}
746
747/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000748static void
paul718e3742002-12-13 20:15:29 +0000749ospf_hello (struct ip *iph, struct ospf_header *ospfh,
750 struct stream * s, struct ospf_interface *oi, int size)
751{
752 struct ospf_hello *hello;
753 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000754 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000755 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000756
757 /* increment statistics. */
758 oi->hello_in++;
759
760 hello = (struct ospf_hello *) STREAM_PNT (s);
761
762 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000763 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000764 {
765 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
766 {
ajs2a42e282004-12-08 18:43:03 +0000767 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000768 "dropping.",
769 ospf_packet_type_str[ospfh->type],
770 inet_ntoa (iph->ip_src));
771 }
772 return;
773 }
paul718e3742002-12-13 20:15:29 +0000774
paul718e3742002-12-13 20:15:29 +0000775 /* get neighbor prefix. */
776 p.family = AF_INET;
777 p.prefixlen = ip_masklen (hello->network_mask);
778 p.u.prefix4 = iph->ip_src;
779
780 /* Compare network mask. */
781 /* Checking is ignored for Point-to-Point and Virtual link. */
782 if (oi->type != OSPF_IFTYPE_POINTOPOINT
783 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
784 if (oi->address->prefixlen != p.prefixlen)
785 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000786 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
787 inet_ntoa(ospfh->router_id), IF_NAME(oi),
788 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000789 return;
790 }
791
paul718e3742002-12-13 20:15:29 +0000792 /* Compare Router Dead Interval. */
793 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
794 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000795 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
796 "(expected %u, but received %u).",
797 inet_ntoa(ospfh->router_id),
798 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000799 return;
800 }
801
paulf9ad9372005-10-21 00:45:17 +0000802 /* Compare Hello Interval - ignored if fast-hellos are set. */
803 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
804 {
805 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
806 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000807 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
808 "(expected %u, but received %u).",
809 inet_ntoa(ospfh->router_id),
810 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000811 return;
812 }
813 }
814
paul718e3742002-12-13 20:15:29 +0000815 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000816 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000817 inet_ntoa (ospfh->router_id),
818 ospf_options_dump (hello->options));
819
820 /* Compare options. */
821#define REJECT_IF_TBIT_ON 1 /* XXX */
822#ifdef REJECT_IF_TBIT_ON
823 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
824 {
825 /*
826 * This router does not support non-zero TOS.
827 * Drop this Hello packet not to establish neighbor relationship.
828 */
829 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
830 inet_ntoa (ospfh->router_id));
831 return;
832 }
833#endif /* REJECT_IF_TBIT_ON */
834
835#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000836 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000837 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
838 {
839 /*
840 * This router does know the correct usage of O-bit
841 * the bit should be set in DD packet only.
842 */
843 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
844 inet_ntoa (ospfh->router_id));
845#ifdef STRICT_OBIT_USAGE_CHECK
846 return; /* Reject this packet. */
847#else /* STRICT_OBIT_USAGE_CHECK */
848 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
849#endif /* STRICT_OBIT_USAGE_CHECK */
850 }
851#endif /* HAVE_OPAQUE_LSA */
852
853 /* new for NSSA is to ensure that NP is on and E is off */
854
paul718e3742002-12-13 20:15:29 +0000855 if (oi->area->external_routing == OSPF_AREA_NSSA)
856 {
857 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
858 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
859 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
860 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
861 {
862 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
863 return;
864 }
865 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000866 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000867 }
868 else
paul718e3742002-12-13 20:15:29 +0000869 /* The setting of the E-bit found in the Hello Packet's Options
870 field must match this area's ExternalRoutingCapability A
871 mismatch causes processing to stop and the packet to be
872 dropped. The setting of the rest of the bits in the Hello
873 Packet's Options field should be ignored. */
874 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
875 CHECK_FLAG (hello->options, OSPF_OPTION_E))
876 {
ajs3aa8d5f2004-12-11 18:00:06 +0000877 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
878 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000879 return;
880 }
paul718e3742002-12-13 20:15:29 +0000881
pauld3f0d622004-05-05 15:27:15 +0000882 /* get neighbour struct */
883 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
884
885 /* neighbour must be valid, ospf_nbr_get creates if none existed */
886 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000887
888 old_state = nbr->state;
889
890 /* Add event to thread. */
891 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
892
893 /* RFC2328 Section 9.5.1
894 If the router is not eligible to become Designated Router,
895 (snip) It must also send an Hello Packet in reply to an
896 Hello Packet received from any eligible neighbor (other than
897 the current Designated Router and Backup Designated Router). */
898 if (oi->type == OSPF_IFTYPE_NBMA)
899 if (PRIORITY(oi) == 0 && hello->priority > 0
900 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
901 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
902 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
903 OSPF_HELLO_REPLY_DELAY);
904
905 /* on NBMA network type, it happens to receive bidirectional Hello packet
906 without advance 1-Way Received event.
907 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
908 if (oi->type == OSPF_IFTYPE_NBMA &&
909 (old_state == NSM_Down || old_state == NSM_Attempt))
910 {
911 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
912 nbr->priority = hello->priority;
913 nbr->d_router = hello->d_router;
914 nbr->bd_router = hello->bd_router;
915 return;
916 }
917
paul68980082003-03-25 05:07:42 +0000918 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000919 size - OSPF_HELLO_MIN_SIZE))
920 {
921 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
922 nbr->options |= hello->options;
923 }
924 else
925 {
926 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
927 /* Set neighbor information. */
928 nbr->priority = hello->priority;
929 nbr->d_router = hello->d_router;
930 nbr->bd_router = hello->bd_router;
931 return;
932 }
933
934 /* If neighbor itself declares DR and no BDR exists,
935 cause event BackupSeen */
936 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
937 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
938 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
939
940 /* neighbor itself declares BDR. */
941 if (oi->state == ISM_Waiting &&
942 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
943 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
944
945 /* had not previously. */
946 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
947 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
948 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
951
952 /* had not previously. */
953 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
954 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
955 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
956 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
957 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
958
959 /* Neighbor priority check. */
960 if (nbr->priority >= 0 && nbr->priority != hello->priority)
961 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
962
963 /* Set neighbor information. */
964 nbr->priority = hello->priority;
965 nbr->d_router = hello->d_router;
966 nbr->bd_router = hello->bd_router;
967}
968
969/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000970static void
paul718e3742002-12-13 20:15:29 +0000971ospf_db_desc_save_current (struct ospf_neighbor *nbr,
972 struct ospf_db_desc *dd)
973{
974 nbr->last_recv.flags = dd->flags;
975 nbr->last_recv.options = dd->options;
976 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
977}
978
979/* Process rest of DD packet. */
980static void
981ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
982 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
983 u_int16_t size)
984{
985 struct ospf_lsa *new, *find;
986 struct lsa_header *lsah;
987
paul9985f832005-02-09 15:51:56 +0000988 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000989 for (size -= OSPF_DB_DESC_MIN_SIZE;
990 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
991 {
992 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000993 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000994
995 /* Unknown LS type. */
996 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
997 {
ajsbec595a2004-11-30 22:38:43 +0000998 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000999 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1000 return;
1001 }
1002
1003#ifdef HAVE_OPAQUE_LSA
1004 if (IS_OPAQUE_LSA (lsah->type)
1005 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1006 {
1007 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1008 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1009 return;
1010 }
1011#endif /* HAVE_OPAQUE_LSA */
1012
1013 switch (lsah->type)
1014 {
1015 case OSPF_AS_EXTERNAL_LSA:
1016#ifdef HAVE_OPAQUE_LSA
1017 case OSPF_OPAQUE_AS_LSA:
1018#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001019 /* Check for stub area. Reject if AS-External from stub but
1020 allow if from NSSA. */
1021 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001022 {
1023 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1024 lsah->type, inet_ntoa (lsah->id),
1025 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1026 "STUB" : "NSSA");
1027 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1028 return;
1029 }
1030 break;
1031 default:
1032 break;
1033 }
1034
1035 /* Create LS-request object. */
1036 new = ospf_ls_request_new (lsah);
1037
1038 /* Lookup received LSA, then add LS request list. */
1039 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001040
1041 /* ospf_lsa_more_recent is fine with NULL pointers */
1042 switch (ospf_lsa_more_recent (find, new))
1043 {
1044 case -1:
1045 /* Neighbour has a more recent LSA, we must request it */
1046 ospf_ls_request_add (nbr, new);
1047 case 0:
1048 /* If we have a copy of this LSA, it's either less recent
1049 * and we're requesting it from neighbour (the case above), or
1050 * it's as recent and we both have same copy (this case).
1051 *
1052 * In neither of these two cases is there any point in
1053 * describing our copy of the LSA to the neighbour in a
1054 * DB-Summary packet, if we're still intending to do so.
1055 *
1056 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1057 * backward compatible optimisation to OSPF DB Exchange /
1058 * DB Description process implemented here.
1059 */
1060 if (find)
1061 ospf_lsdb_delete (&nbr->db_sum, find);
1062 ospf_lsa_discard (new);
1063 break;
1064 default:
1065 /* We have the more recent copy, nothing specific to do:
1066 * - no need to request neighbours stale copy
1067 * - must leave DB summary list copy alone
1068 */
1069 if (IS_DEBUG_OSPF_EVENT)
1070 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1071 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1072 ospf_lsa_discard (new);
1073 }
paul718e3742002-12-13 20:15:29 +00001074 }
1075
1076 /* Master */
1077 if (IS_SET_DD_MS (nbr->dd_flags))
1078 {
1079 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001080
1081 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001082 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1083 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1084 else
paul718e3742002-12-13 20:15:29 +00001085 ospf_db_desc_send (nbr);
1086 }
1087 /* Slave */
1088 else
1089 {
1090 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1091
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001092 /* Send DD packet in reply.
1093 *
1094 * Must be done to acknowledge the Master's DD, regardless of
1095 * whether we have more LSAs ourselves to describe.
1096 *
1097 * This function will clear the 'More' bit, if after this DD
1098 * we have no more LSAs to describe to the master..
1099 */
paul718e3742002-12-13 20:15:29 +00001100 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001101
1102 /* Slave can raise ExchangeDone now, if master is also done */
1103 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1104 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001105 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001106
paul718e3742002-12-13 20:15:29 +00001107 /* Save received neighbor values from DD. */
1108 ospf_db_desc_save_current (nbr, dd);
1109}
1110
paul4dadc292005-05-06 21:37:42 +00001111static int
paul718e3742002-12-13 20:15:29 +00001112ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1113{
1114 /* Is DD duplicated? */
1115 if (dd->options == nbr->last_recv.options &&
1116 dd->flags == nbr->last_recv.flags &&
1117 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1118 return 1;
1119
1120 return 0;
1121}
1122
1123/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001124static void
paul718e3742002-12-13 20:15:29 +00001125ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1126 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1127{
1128 struct ospf_db_desc *dd;
1129 struct ospf_neighbor *nbr;
1130
1131 /* Increment statistics. */
1132 oi->db_desc_in++;
1133
1134 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001135
pauld3f0d622004-05-05 15:27:15 +00001136 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001137 if (nbr == NULL)
1138 {
1139 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1140 inet_ntoa (ospfh->router_id));
1141 return;
1142 }
1143
1144 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001145 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1146 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001147 {
ajs3aa8d5f2004-12-11 18:00:06 +00001148 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1149 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1150 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001151 return;
1152 }
1153
pauld363df22003-06-19 00:26:34 +00001154 /*
1155 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1156 * required. In fact at least JunOS sends DD packets with P bit clear.
1157 * Until proper solution is developped, this hack should help.
1158 *
1159 * Update: According to the RFCs, N bit is specified /only/ for Hello
1160 * options, unfortunately its use in DD options is not specified. Hence some
1161 * implementations follow E-bit semantics and set it in DD options, and some
1162 * treat it as unspecified and hence follow the directive "default for
1163 * options is clear", ie unset.
1164 *
1165 * Reset the flag, as ospfd follows E-bit semantics.
1166 */
1167 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1168 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1169 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1170 {
1171 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001172 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001173 inet_ntoa (nbr->router_id) );
1174 SET_FLAG (dd->options, OSPF_OPTION_NP);
1175 }
pauld363df22003-06-19 00:26:34 +00001176
paul718e3742002-12-13 20:15:29 +00001177#ifdef REJECT_IF_TBIT_ON
1178 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1179 {
1180 /*
1181 * In Hello protocol, optional capability must have checked
1182 * to prevent this T-bit enabled router be my neighbor.
1183 */
1184 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1185 return;
1186 }
1187#endif /* REJECT_IF_TBIT_ON */
1188
1189#ifdef HAVE_OPAQUE_LSA
1190 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001191 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001192 {
1193 /*
1194 * This node is not configured to handle O-bit, for now.
1195 * Clear it to ignore unsupported capability proposed by neighbor.
1196 */
1197 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1198 }
1199#endif /* HAVE_OPAQUE_LSA */
1200
1201 /* Process DD packet by neighbor status. */
1202 switch (nbr->state)
1203 {
1204 case NSM_Down:
1205 case NSM_Attempt:
1206 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001207 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001208 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001209 LOOKUP (ospf_nsm_state_msg, nbr->state));
1210 break;
1211 case NSM_Init:
1212 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1213 /* If the new state is ExStart, the processing of the current
1214 packet should then continue in this new state by falling
1215 through to case ExStart below. */
1216 if (nbr->state != NSM_ExStart)
1217 break;
1218 case NSM_ExStart:
1219 /* Initial DBD */
1220 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1221 (size == OSPF_DB_DESC_MIN_SIZE))
1222 {
paul68980082003-03-25 05:07:42 +00001223 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001224 {
1225 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001226 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001227 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001228 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001229
1230 /* Reset I/MS */
1231 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001232 }
1233 else
1234 {
1235 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001236 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001237 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001238 break;
1239 }
1240 }
1241 /* Ack from the Slave */
1242 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1243 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001244 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001245 {
ajs17eaa722004-12-29 21:04:48 +00001246 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001247 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001248 /* Reset I, leaving MS */
1249 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001250 }
1251 else
1252 {
ajs3aa8d5f2004-12-11 18:00:06 +00001253 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1254 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001255 break;
1256 }
1257
1258 /* This is where the real Options are saved */
1259 nbr->options = dd->options;
1260
1261#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001262 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001263 {
1264 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001265 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001266 inet_ntoa (nbr->router_id),
1267 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1268
1269 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1270 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1271 {
paul6d452762005-11-03 11:15:44 +00001272 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1273 "Opaque-LSAs cannot be reliably advertised "
1274 "in this network.",
1275 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001276 /* This situation is undesirable, but not a real error. */
1277 }
1278 }
1279#endif /* HAVE_OPAQUE_LSA */
1280
1281 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1282
1283 /* continue processing rest of packet. */
1284 ospf_db_desc_proc (s, oi, nbr, dd, size);
1285 break;
1286 case NSM_Exchange:
1287 if (ospf_db_desc_is_dup (dd, nbr))
1288 {
1289 if (IS_SET_DD_MS (nbr->dd_flags))
1290 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001291 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001292 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001293 else
1294 /* Slave: cause to retransmit the last Database Description. */
1295 {
paul6d452762005-11-03 11:15:44 +00001296 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001297 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001298 ospf_db_desc_resend (nbr);
1299 }
1300 break;
1301 }
1302
1303 /* Otherwise DD packet should be checked. */
1304 /* Check Master/Slave bit mismatch */
1305 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1306 {
ajs3aa8d5f2004-12-11 18:00:06 +00001307 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1308 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001309 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1310 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001311 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001312 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001313 break;
1314 }
1315
1316 /* Check initialize bit is set. */
1317 if (IS_SET_DD_I (dd->flags))
1318 {
paul6d452762005-11-03 11:15:44 +00001319 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001320 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001321 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1322 break;
1323 }
1324
1325 /* Check DD Options. */
1326 if (dd->options != nbr->options)
1327 {
1328#ifdef ORIGINAL_CODING
1329 /* Save the new options for debugging */
1330 nbr->options = dd->options;
1331#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001332 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1333 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001334 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1335 break;
1336 }
1337
1338 /* Check DD sequence number. */
1339 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1340 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1341 (!IS_SET_DD_MS (nbr->dd_flags) &&
1342 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1343 {
ajs3aa8d5f2004-12-11 18:00:06 +00001344 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1345 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001346 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1347 break;
1348 }
1349
1350 /* Continue processing rest of packet. */
1351 ospf_db_desc_proc (s, oi, nbr, dd, size);
1352 break;
1353 case NSM_Loading:
1354 case NSM_Full:
1355 if (ospf_db_desc_is_dup (dd, nbr))
1356 {
1357 if (IS_SET_DD_MS (nbr->dd_flags))
1358 {
1359 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001360 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1361 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001362 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001363 break;
1364 }
1365 else
1366 {
1367 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001368 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001369 t = tv_sub (now, nbr->last_send_ts);
1370 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1371 {
1372 /* In states Loading and Full the slave must resend
1373 its last Database Description packet in response to
1374 duplicate Database Description packets received
1375 from the master. For this reason the slave must
1376 wait RouterDeadInterval seconds before freeing the
1377 last Database Description packet. Reception of a
1378 Database Description packet from the master after
1379 this interval will generate a SeqNumberMismatch
1380 neighbor event. RFC2328 Section 10.8 */
1381 ospf_db_desc_resend (nbr);
1382 break;
1383 }
1384 }
1385 }
1386
1387 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1388 break;
1389 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001390 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1391 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001392 break;
1393 }
1394}
1395
1396#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1397
1398/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001399static void
paul718e3742002-12-13 20:15:29 +00001400ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1401 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1402{
1403 struct ospf_neighbor *nbr;
1404 u_int32_t ls_type;
1405 struct in_addr ls_id;
1406 struct in_addr adv_router;
1407 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001408 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001409 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001410
1411 /* Increment statistics. */
1412 oi->ls_req_in++;
1413
pauld3f0d622004-05-05 15:27:15 +00001414 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001415 if (nbr == NULL)
1416 {
1417 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1418 inet_ntoa (ospfh->router_id));
1419 return;
1420 }
1421
1422 /* Neighbor State should be Exchange or later. */
1423 if (nbr->state != NSM_Exchange &&
1424 nbr->state != NSM_Loading &&
1425 nbr->state != NSM_Full)
1426 {
ajsbec595a2004-11-30 22:38:43 +00001427 zlog_warn ("Link State Request received from %s: "
1428 "Neighbor state is %s, packet discarded.",
1429 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001430 LOOKUP (ospf_nsm_state_msg, nbr->state));
1431 return;
1432 }
1433
1434 /* Send Link State Update for ALL requested LSAs. */
1435 ls_upd = list_new ();
1436 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1437
1438 while (size >= OSPF_LSA_KEY_SIZE)
1439 {
1440 /* Get one slice of Link State Request. */
1441 ls_type = stream_getl (s);
1442 ls_id.s_addr = stream_get_ipv4 (s);
1443 adv_router.s_addr = stream_get_ipv4 (s);
1444
1445 /* Verify LSA type. */
1446 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1447 {
1448 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1449 list_delete (ls_upd);
1450 return;
1451 }
1452
1453 /* Search proper LSA in LSDB. */
1454 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1455 if (find == NULL)
1456 {
1457 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1458 list_delete (ls_upd);
1459 return;
1460 }
1461
gdt86f1fd92005-01-10 14:20:43 +00001462 /* Packet overflows MTU size, send immediately. */
1463 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001464 {
1465 if (oi->type == OSPF_IFTYPE_NBMA)
1466 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1467 else
1468 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1469
1470 /* Only remove list contents. Keep ls_upd. */
1471 list_delete_all_node (ls_upd);
1472
1473 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1474 }
1475
1476 /* Append LSA to update list. */
1477 listnode_add (ls_upd, find);
1478 length += ntohs (find->data->length);
1479
1480 size -= OSPF_LSA_KEY_SIZE;
1481 }
1482
1483 /* Send rest of Link State Update. */
1484 if (listcount (ls_upd) > 0)
1485 {
1486 if (oi->type == OSPF_IFTYPE_NBMA)
1487 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1488 else
1489 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1490
1491 list_delete (ls_upd);
1492 }
1493 else
1494 list_free (ls_upd);
1495}
1496
1497/* Get the list of LSAs from Link State Update packet.
1498 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001499static struct list *
paul718e3742002-12-13 20:15:29 +00001500ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1501 struct ospf_interface *oi, size_t size)
1502{
1503 u_int16_t count, sum;
1504 u_int32_t length;
1505 struct lsa_header *lsah;
1506 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001507 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001508
1509 lsas = list_new ();
1510
1511 count = stream_getl (s);
1512 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1513
1514 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001515 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001516 {
1517 lsah = (struct lsa_header *) STREAM_PNT (s);
1518 length = ntohs (lsah->length);
1519
1520 if (length > size)
1521 {
1522 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1523 break;
1524 }
1525
1526 /* Validate the LSA's LS checksum. */
1527 sum = lsah->checksum;
1528 if (sum != ospf_lsa_checksum (lsah))
1529 {
1530 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1531 sum, lsah->checksum);
1532 continue;
1533 }
1534
1535 /* Examine the LSA's LS type. */
1536 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1537 {
1538 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1539 continue;
1540 }
1541
1542 /*
1543 * What if the received LSA's age is greater than MaxAge?
1544 * Treat it as a MaxAge case -- endo.
1545 */
1546 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1547 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1548
1549#ifdef HAVE_OPAQUE_LSA
1550 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1551 {
1552#ifdef STRICT_OBIT_USAGE_CHECK
1553 if ((IS_OPAQUE_LSA(lsah->type) &&
1554 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1555 || (! IS_OPAQUE_LSA(lsah->type) &&
1556 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1557 {
1558 /*
1559 * This neighbor must know the exact usage of O-bit;
1560 * the bit will be set in Type-9,10,11 LSAs only.
1561 */
1562 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1563 continue;
1564 }
1565#endif /* STRICT_OBIT_USAGE_CHECK */
1566
1567 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1568 if (lsah->type == OSPF_OPAQUE_AS_LSA
1569 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1570 {
1571 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001572 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 +00001573 continue;
1574 }
1575 }
1576 else if (IS_OPAQUE_LSA(lsah->type))
1577 {
1578 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1579 continue;
1580 }
1581#endif /* HAVE_OPAQUE_LSA */
1582
1583 /* Create OSPF LSA instance. */
1584 lsa = ospf_lsa_new ();
1585
1586 /* We may wish to put some error checking if type NSSA comes in
1587 and area not in NSSA mode */
1588 switch (lsah->type)
1589 {
1590 case OSPF_AS_EXTERNAL_LSA:
1591#ifdef HAVE_OPAQUE_LSA
1592 case OSPF_OPAQUE_AS_LSA:
1593 lsa->area = NULL;
1594 break;
1595 case OSPF_OPAQUE_LINK_LSA:
1596 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1597 /* Fallthrough */
1598#endif /* HAVE_OPAQUE_LSA */
1599 default:
1600 lsa->area = oi->area;
1601 break;
1602 }
1603
1604 lsa->data = ospf_lsa_data_new (length);
1605 memcpy (lsa->data, lsah, length);
1606
1607 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001608 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001609 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1610 listnode_add (lsas, lsa);
1611 }
1612
1613 return lsas;
1614}
1615
1616/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001617static void
hasso52dc7ee2004-09-23 19:18:23 +00001618ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001619{
paul1eb8ef22005-04-07 07:30:20 +00001620 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001621 struct ospf_lsa *lsa;
1622
paul1eb8ef22005-04-07 07:30:20 +00001623 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1624 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001625
1626 list_delete (lsas);
1627}
1628
1629/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001630static void
paul718e3742002-12-13 20:15:29 +00001631ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1632 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1633{
1634 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001635 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001636 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001637 struct ospf_lsa *lsa = NULL;
1638 /* unsigned long ls_req_found = 0; */
1639
1640 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1641
1642 /* Increment statistics. */
1643 oi->ls_upd_in++;
1644
1645 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001646 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001647 if (nbr == NULL)
1648 {
1649 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1650 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1651 return;
1652 }
1653
1654 /* Check neighbor state. */
1655 if (nbr->state < NSM_Exchange)
1656 {
ajs3aa8d5f2004-12-11 18:00:06 +00001657 zlog_warn ("Link State Update: "
1658 "Neighbor[%s] state %s is less than Exchange",
1659 inet_ntoa (ospfh->router_id),
1660 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001661 return;
1662 }
1663
1664 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1665 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1666 * of section 13.
1667 */
1668 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1669
1670#ifdef HAVE_OPAQUE_LSA
1671 /*
paul718e3742002-12-13 20:15:29 +00001672 * If self-originated Opaque-LSAs that have flooded before restart
1673 * are contained in the received LSUpd message, corresponding LSReq
1674 * messages to be sent may have to be modified.
1675 * To eliminate possible race conditions such that flushing and normal
1676 * updating for the same LSA would take place alternately, this trick
1677 * must be done before entering to the loop below.
1678 */
paul69310a62005-05-11 18:09:59 +00001679 /* XXX: Why is this Opaque specific? Either our core code is deficient
1680 * and this should be fixed generally, or Opaque is inventing strawman
1681 * problems */
paul718e3742002-12-13 20:15:29 +00001682 ospf_opaque_adjust_lsreq (nbr, lsas);
1683#endif /* HAVE_OPAQUE_LSA */
1684
1685#define DISCARD_LSA(L,N) {\
1686 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001687 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 +00001688 ospf_lsa_discard (L); \
1689 continue; }
1690
1691 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001692 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001693 {
1694 struct ospf_lsa *ls_ret, *current;
1695 int ret = 1;
1696
paul718e3742002-12-13 20:15:29 +00001697 if (IS_DEBUG_OSPF_NSSA)
1698 {
1699 char buf1[INET_ADDRSTRLEN];
1700 char buf2[INET_ADDRSTRLEN];
1701 char buf3[INET_ADDRSTRLEN];
1702
ajs2a42e282004-12-08 18:43:03 +00001703 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001704 lsa->data->type,
1705 inet_ntop (AF_INET, &ospfh->router_id,
1706 buf1, INET_ADDRSTRLEN),
1707 inet_ntop (AF_INET, &lsa->data->id,
1708 buf2, INET_ADDRSTRLEN),
1709 inet_ntop (AF_INET, &lsa->data->adv_router,
1710 buf3, INET_ADDRSTRLEN));
1711 }
paul718e3742002-12-13 20:15:29 +00001712
1713 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1714
1715 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1716
1717 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1718
1719 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1720
1721 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1722
1723 /* Do take in Type-7's if we are an NSSA */
1724
1725 /* If we are also an ABR, later translate them to a Type-5 packet */
1726
1727 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1728 translate them to a separate Type-5 packet. */
1729
1730 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1731 /* Reject from STUB or NSSA */
1732 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1733 {
paul718e3742002-12-13 20:15:29 +00001734 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001735 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001736 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001737 }
1738
paul718e3742002-12-13 20:15:29 +00001739 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1740 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1741 {
paul718e3742002-12-13 20:15:29 +00001742 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001743 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001744 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001745 }
paul718e3742002-12-13 20:15:29 +00001746
1747 /* Find the LSA in the current database. */
1748
1749 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1750
1751 /* If the LSA's LS age is equal to MaxAge, and there is currently
1752 no instance of the LSA in the router's link state database,
1753 and none of router's neighbors are in states Exchange or Loading,
1754 then take the following actions. */
1755
1756 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001757 (ospf_nbr_count (oi, NSM_Exchange) +
1758 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001759 {
1760 /* Response Link State Acknowledgment. */
1761 ospf_ls_ack_send (nbr, lsa);
1762
1763 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001764 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1765 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001766 DISCARD_LSA (lsa, 3);
1767 }
1768
1769#ifdef HAVE_OPAQUE_LSA
1770 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001771 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001772 {
1773 /*
1774 * Even if initial flushing seems to be completed, there might
1775 * be a case that self-originated LSA with MaxAge still remain
1776 * in the routing domain.
1777 * Just send an LSAck message to cease retransmission.
1778 */
1779 if (IS_LSA_MAXAGE (lsa))
1780 {
1781 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1782 ospf_ls_ack_send (nbr, lsa);
1783 ospf_lsa_discard (lsa);
1784
1785 if (current != NULL && ! IS_LSA_MAXAGE (current))
1786 ospf_opaque_lsa_refresh_schedule (current);
1787 continue;
1788 }
1789
1790 /*
1791 * If an instance of self-originated Opaque-LSA is not found
1792 * in the LSDB, there are some possible cases here.
1793 *
1794 * 1) This node lost opaque-capability after restart.
1795 * 2) Else, a part of opaque-type is no more supported.
1796 * 3) Else, a part of opaque-id is no more supported.
1797 *
1798 * Anyway, it is still this node's responsibility to flush it.
1799 * Otherwise, the LSA instance remains in the routing domain
1800 * until its age reaches to MaxAge.
1801 */
paul69310a62005-05-11 18:09:59 +00001802 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001803 if (current == NULL)
1804 {
1805 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001806 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1807 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001808
1809 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001810
1811 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1812 ospf_ls_ack_send (nbr, lsa);
1813
paul718e3742002-12-13 20:15:29 +00001814 continue;
1815 }
1816 }
1817#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001818
hassocb05eb22004-02-11 21:10:19 +00001819 /* It might be happen that received LSA is self-originated network LSA, but
1820 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1821 * Link State ID is one of the router's own IP interface addresses but whose
1822 * Advertising Router is not equal to the router's own Router ID
1823 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1824 */
1825
1826 if(lsa->data->type == OSPF_NETWORK_LSA)
1827 {
paul1eb8ef22005-04-07 07:30:20 +00001828 struct listnode *oinode, *oinnode;
1829 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001830 int Flag = 0;
1831
paul1eb8ef22005-04-07 07:30:20 +00001832 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001833 {
hassocb05eb22004-02-11 21:10:19 +00001834 if(out_if == NULL)
1835 break;
1836
1837 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1838 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1839 {
1840 if(out_if->network_lsa_self)
1841 {
1842 ospf_lsa_flush_area(lsa,out_if->area);
1843 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001844 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001845 lsa, (int) lsa->data->type);
1846 ospf_lsa_discard (lsa);
1847 Flag = 1;
1848 }
1849 break;
1850 }
1851 }
1852 if(Flag)
1853 continue;
1854 }
paul718e3742002-12-13 20:15:29 +00001855
1856 /* (5) Find the instance of this LSA that is currently contained
1857 in the router's link state database. If there is no
1858 database copy, or the received LSA is more recent than
1859 the database copy the following steps must be performed. */
1860
1861 if (current == NULL ||
1862 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1863 {
1864 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001865 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001866 DISCARD_LSA (lsa, 4);
1867 continue;
1868 }
1869
1870 /* (6) Else, If there is an instance of the LSA on the sending
1871 neighbor's Link state request list, an error has occurred in
1872 the Database Exchange process. In this case, restart the
1873 Database Exchange process by generating the neighbor event
1874 BadLSReq for the sending neighbor and stop processing the
1875 Link State Update packet. */
1876
1877 if (ospf_ls_request_lookup (nbr, lsa))
1878 {
1879 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001880 zlog_warn("LSA[%s] instance exists on Link state request list",
1881 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001882
1883 /* Clean list of LSAs. */
1884 ospf_upd_list_clean (lsas);
1885 /* this lsa is not on lsas list already. */
1886 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001887 return;
1888 }
1889
1890 /* If the received LSA is the same instance as the database copy
1891 (i.e., neither one is more recent) the following two steps
1892 should be performed: */
1893
1894 if (ret == 0)
1895 {
1896 /* If the LSA is listed in the Link state retransmission list
1897 for the receiving adjacency, the router itself is expecting
1898 an acknowledgment for this LSA. The router should treat the
1899 received LSA as an acknowledgment by removing the LSA from
1900 the Link state retransmission list. This is termed an
1901 "implied acknowledgment". */
1902
1903 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1904
1905 if (ls_ret != NULL)
1906 {
1907 ospf_ls_retransmit_delete (nbr, ls_ret);
1908
1909 /* Delayed acknowledgment sent if advertisement received
1910 from Designated Router, otherwise do nothing. */
1911 if (oi->state == ISM_Backup)
1912 if (NBR_IS_DR (nbr))
1913 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1914
1915 DISCARD_LSA (lsa, 5);
1916 }
1917 else
1918 /* Acknowledge the receipt of the LSA by sending a
1919 Link State Acknowledgment packet back out the receiving
1920 interface. */
1921 {
1922 ospf_ls_ack_send (nbr, lsa);
1923 DISCARD_LSA (lsa, 6);
1924 }
1925 }
1926
1927 /* The database copy is more recent. If the database copy
1928 has LS age equal to MaxAge and LS sequence number equal to
1929 MaxSequenceNumber, simply discard the received LSA without
1930 acknowledging it. (In this case, the LSA's LS sequence number is
1931 wrapping, and the MaxSequenceNumber LSA must be completely
1932 flushed before any new LSA instance can be introduced). */
1933
1934 else if (ret > 0) /* Database copy is more recent */
1935 {
1936 if (IS_LSA_MAXAGE (current) &&
1937 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1938 {
1939 DISCARD_LSA (lsa, 7);
1940 }
1941 /* Otherwise, as long as the database copy has not been sent in a
1942 Link State Update within the last MinLSArrival seconds, send the
1943 database copy back to the sending neighbor, encapsulated within
1944 a Link State Update Packet. The Link State Update Packet should
1945 be sent directly to the neighbor. In so doing, do not put the
1946 database copy of the LSA on the neighbor's link state
1947 retransmission list, and do not acknowledge the received (less
1948 recent) LSA instance. */
1949 else
1950 {
1951 struct timeval now;
1952
Paul Jakma2518efd2006-08-27 06:49:29 +00001953 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001954
1955 if (tv_cmp (tv_sub (now, current->tv_orig),
1956 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1957 /* Trap NSSA type later.*/
1958 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1959 DISCARD_LSA (lsa, 8);
1960 }
1961 }
1962 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03001963#undef DISCARD_LSA
1964
paul718e3742002-12-13 20:15:29 +00001965 assert (listcount (lsas) == 0);
1966 list_delete (lsas);
1967}
1968
1969/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001970static void
paul718e3742002-12-13 20:15:29 +00001971ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1972 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1973{
1974 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001975
paul718e3742002-12-13 20:15:29 +00001976 /* increment statistics. */
1977 oi->ls_ack_in++;
1978
pauld3f0d622004-05-05 15:27:15 +00001979 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001980 if (nbr == NULL)
1981 {
1982 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1983 inet_ntoa (ospfh->router_id));
1984 return;
1985 }
1986
1987 if (nbr->state < NSM_Exchange)
1988 {
ajs3aa8d5f2004-12-11 18:00:06 +00001989 zlog_warn ("Link State Acknowledgment: "
1990 "Neighbor[%s] state %s is less than Exchange",
1991 inet_ntoa (ospfh->router_id),
1992 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001993 return;
1994 }
paul69310a62005-05-11 18:09:59 +00001995
paul718e3742002-12-13 20:15:29 +00001996 while (size >= OSPF_LSA_HEADER_SIZE)
1997 {
1998 struct ospf_lsa *lsa, *lsr;
1999
2000 lsa = ospf_lsa_new ();
2001 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2002
2003 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2004 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002005 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002006
2007 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2008 {
2009 lsa->data = NULL;
2010 ospf_lsa_discard (lsa);
2011 continue;
2012 }
2013
2014 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2015
2016 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2017 {
2018#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002019 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002020 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002021#endif /* HAVE_OPAQUE_LSA */
2022
2023 ospf_ls_retransmit_delete (nbr, lsr);
2024 }
2025
2026 lsa->data = NULL;
2027 ospf_lsa_discard (lsa);
2028 }
2029
paul718e3742002-12-13 20:15:29 +00002030 return;
paul718e3742002-12-13 20:15:29 +00002031}
2032
ajs038163f2005-02-17 19:55:59 +00002033static struct stream *
ajs5c333492005-02-23 15:43:01 +00002034ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002035{
2036 int ret;
ajs5c333492005-02-23 15:43:01 +00002037 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002038 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002039 unsigned int ifindex = 0;
2040 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002041 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002042 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002043 struct msghdr msgh;
2044
paul68defd62004-09-27 07:27:13 +00002045 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002046 msgh.msg_iov = &iov;
2047 msgh.msg_iovlen = 1;
2048 msgh.msg_control = (caddr_t) buff;
2049 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002050
ajs5c333492005-02-23 15:43:01 +00002051 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2052 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002053 {
ajs5c333492005-02-23 15:43:01 +00002054 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2055 return NULL;
2056 }
paul69310a62005-05-11 18:09:59 +00002057 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002058 {
2059 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2060 "(ip header size is %u)",
2061 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002062 return NULL;
2063 }
paul18b12c32004-10-05 14:38:29 +00002064
ajs5c333492005-02-23 15:43:01 +00002065 /* Note that there should not be alignment problems with this assignment
2066 because this is at the beginning of the stream data buffer. */
2067 iph = (struct ip *) STREAM_DATA(ibuf);
2068 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002069
ajs5c333492005-02-23 15:43:01 +00002070 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002071
paul239aecc2003-12-08 10:34:54 +00002072#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002073 /*
2074 * Kernel network code touches incoming IP header parameters,
2075 * before protocol specific processing.
2076 *
2077 * 1) Convert byteorder to host representation.
2078 * --> ip_len, ip_id, ip_off
2079 *
2080 * 2) Adjust ip_len to strip IP header size!
2081 * --> If user process receives entire IP packet via RAW
2082 * socket, it must consider adding IP header size to
2083 * the "ip_len" field of "ip" structure.
2084 *
2085 * For more details, see <netinet/ip_input.c>.
2086 */
ajs5c333492005-02-23 15:43:01 +00002087 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002088#endif
2089
David BÉRARD0150c9c2010-05-11 10:17:53 +02002090#if defined(__DragonFly__)
2091 /*
2092 * in DragonFly's raw socket, ip_len/ip_off are read
2093 * in network byte order.
2094 * As OpenBSD < 200311 adjust ip_len to strip IP header size!
2095 */
2096 ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2);
2097#endif
2098
paul863082d2004-08-19 04:43:43 +00002099 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002100
2101 *ifp = if_lookup_by_index (ifindex);
2102
2103 if (ret != ip_len)
2104 {
ajs5c333492005-02-23 15:43:01 +00002105 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2106 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002107 return NULL;
2108 }
2109
2110 return ibuf;
2111}
2112
paul4dadc292005-05-06 21:37:42 +00002113static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002114ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002115 struct ip *iph, struct ospf_header *ospfh)
2116{
2117 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002118 struct ospf_vl_data *vl_data;
2119 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002120 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002121
2122 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2123 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002124 return NULL;
paul718e3742002-12-13 20:15:29 +00002125
pauld3f0d622004-05-05 15:27:15 +00002126 /* look for local OSPF interface matching the destination
2127 * to determine Area ID. We presume therefore the destination address
2128 * is unique, or at least (for "unnumbered" links), not used in other
2129 * areas
2130 */
2131 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2132 iph->ip_dst)) == NULL)
2133 return NULL;
paul718e3742002-12-13 20:15:29 +00002134
paul1eb8ef22005-04-07 07:30:20 +00002135 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002136 {
paul020709f2003-04-04 02:44:16 +00002137 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002138 if (!vl_area)
2139 continue;
2140
2141 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2142 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2143 {
2144 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002145 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002146 IF_NAME (vl_data->vl_oi));
2147 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2148 {
2149 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002150 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002151 return NULL;
2152 }
2153
2154 return vl_data->vl_oi;
2155 }
2156 }
2157
2158 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002159 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002160
pauld3f0d622004-05-05 15:27:15 +00002161 return NULL;
paul718e3742002-12-13 20:15:29 +00002162}
2163
paul4dadc292005-05-06 21:37:42 +00002164static inline int
paul718e3742002-12-13 20:15:29 +00002165ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2166{
2167 /* Check match the Area ID of the receiving interface. */
2168 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2169 return 1;
2170
2171 return 0;
2172}
2173
2174/* Unbound socket will accept any Raw IP packets if proto is matched.
2175 To prevent it, compare src IP address and i/f address with masking
2176 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002177static int
paul718e3742002-12-13 20:15:29 +00002178ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2179{
2180 struct in_addr mask, me, him;
2181
2182 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2183 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2184 return 1;
2185
2186 masklen2ip (oi->address->prefixlen, &mask);
2187
2188 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2189 him.s_addr = ip_src.s_addr & mask.s_addr;
2190
2191 if (IPV4_ADDR_SAME (&me, &him))
2192 return 1;
2193
2194 return 0;
2195}
2196
paul4dadc292005-05-06 21:37:42 +00002197static int
paul718e3742002-12-13 20:15:29 +00002198ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2199 struct ospf_header *ospfh)
2200{
2201 int ret = 0;
2202 struct crypt_key *ck;
2203
2204 switch (ntohs (ospfh->auth_type))
2205 {
2206 case OSPF_AUTH_NULL:
2207 ret = 1;
2208 break;
2209 case OSPF_AUTH_SIMPLE:
2210 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2211 ret = 1;
2212 else
2213 ret = 0;
2214 break;
2215 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002216 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002217 {
2218 ret = 0;
2219 break;
2220 }
2221
2222 /* This is very basic, the digest processing is elsewhere */
2223 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2224 ospfh->u.crypt.key_id == ck->key_id &&
2225 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2226 ret = 1;
2227 else
2228 ret = 0;
2229 break;
2230 default:
2231 ret = 0;
2232 break;
2233 }
2234
2235 return ret;
2236}
2237
paul4dadc292005-05-06 21:37:42 +00002238static int
paul718e3742002-12-13 20:15:29 +00002239ospf_check_sum (struct ospf_header *ospfh)
2240{
2241 u_int32_t ret;
2242 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002243
2244 /* clear auth_data for checksum. */
2245 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2246
2247 /* keep checksum and clear. */
2248 sum = ospfh->checksum;
2249 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2250
2251 /* calculate checksum. */
2252 ret = in_cksum (ospfh, ntohs (ospfh->length));
2253
2254 if (ret != sum)
2255 {
2256 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2257 ret, sum);
2258 return 0;
2259 }
2260
2261 return 1;
2262}
2263
2264/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002265static int
paul718e3742002-12-13 20:15:29 +00002266ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2267 struct ip *iph, struct ospf_header *ospfh)
2268{
2269 /* check version. */
2270 if (ospfh->version != OSPF_VERSION)
2271 {
2272 zlog_warn ("interface %s: ospf_read version number mismatch.",
2273 IF_NAME (oi));
2274 return -1;
2275 }
2276
2277 /* Check Area ID. */
2278 if (!ospf_check_area_id (oi, ospfh))
2279 {
2280 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2281 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2282 return -1;
2283 }
2284
2285 /* Check network mask, Silently discarded. */
2286 if (! ospf_check_network_mask (oi, iph->ip_src))
2287 {
2288 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2289 IF_NAME (oi), inet_ntoa (iph->ip_src));
2290 return -1;
2291 }
2292
2293 /* Check authentication. */
2294 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2295 {
paulc6371712006-01-17 17:49:53 +00002296 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2297 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002298 return -1;
2299 }
2300
2301 if (! ospf_check_auth (oi, ibuf, ospfh))
2302 {
2303 zlog_warn ("interface %s: ospf_read authentication failed.",
2304 IF_NAME (oi));
2305 return -1;
2306 }
2307
2308 /* if check sum is invalid, packet is discarded. */
2309 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2310 {
2311 if (! ospf_check_sum (ospfh))
2312 {
2313 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2314 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2315 return -1;
2316 }
2317 }
2318 else
2319 {
2320 if (ospfh->checksum != 0)
2321 return -1;
2322 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2323 {
2324 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2325 IF_NAME (oi));
2326 return -1;
2327 }
2328 }
2329
2330 return 0;
2331}
2332
2333/* Starting point of packet process function. */
2334int
2335ospf_read (struct thread *thread)
2336{
2337 int ret;
2338 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002339 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002340 struct ospf_interface *oi;
2341 struct ip *iph;
2342 struct ospf_header *ospfh;
2343 u_int16_t length;
2344 struct interface *ifp;
2345
2346 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002347 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002348
2349 /* prepare for next packet. */
2350 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002351
2352 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002353 stream_reset(ospf->ibuf);
2354 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002355 return -1;
2356
ajs5c333492005-02-23 15:43:01 +00002357 /* Note that there should not be alignment problems with this assignment
2358 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002359 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002360 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002361
paulac191232004-10-22 12:05:17 +00002362 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002363 /* Handle cases where the platform does not support retrieving the ifindex,
2364 and also platforms (such as Solaris 8) that claim to support ifindex
2365 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002366 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002367
pauld3f0d622004-05-05 15:27:15 +00002368 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002369 return 0;
paul718e3742002-12-13 20:15:29 +00002370
2371 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002372 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002373 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002374
paul718e3742002-12-13 20:15:29 +00002375 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002376 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002377 {
pauld3241812003-09-29 12:42:39 +00002378 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2379 {
ajs2a42e282004-12-08 18:43:03 +00002380 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002381 inet_ntoa (iph->ip_src));
2382 }
paul718e3742002-12-13 20:15:29 +00002383 return 0;
2384 }
2385
2386 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002387 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002388
2389 /* Get ospf packet header. */
2390 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2391
2392 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002393 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002394
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002395 /* If incoming interface is passive one, ignore it. */
2396 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2397 {
2398 char buf[3][INET_ADDRSTRLEN];
2399
2400 if (IS_DEBUG_OSPF_EVENT)
2401 zlog_debug ("ignoring packet from router %s sent to %s, "
2402 "received on a passive interface, %s",
2403 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2404 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2405 inet_ntop(AF_INET, &oi->address->u.prefix4,
2406 buf[2], sizeof(buf[2])));
2407
2408 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2409 {
2410 /* Try to fix multicast membership.
2411 * Some OS:es may have problems in this area,
2412 * make sure it is removed.
2413 */
2414 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2415 ospf_if_set_multicast(oi);
2416 }
2417 return 0;
2418 }
2419
2420
pauld3f0d622004-05-05 15:27:15 +00002421 /* if no local ospf_interface,
2422 * or header area is backbone but ospf_interface is not
2423 * check for VLINK interface
2424 */
2425 if ( (oi == NULL) ||
2426 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2427 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2428 )
2429 {
2430 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2431 {
Paul Jakma88871b12006-06-15 11:41:19 +00002432 if (IS_DEBUG_OSPF_EVENT)
2433 zlog_debug ("Packet from [%s] received on link %s"
2434 " but no ospf_interface",
2435 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002436 return 0;
2437 }
2438 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002439
pauld3f0d622004-05-05 15:27:15 +00002440 /* else it must be a local ospf interface, check it was received on
2441 * correct link
2442 */
2443 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002444 {
Paul Jakma11637432009-08-11 12:25:42 +01002445 if (IS_DEBUG_OSPF_EVENT)
2446 zlog_warn ("Packet from [%s] received on wrong link %s",
2447 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002448 return 0;
2449 }
ajs847947f2005-02-02 18:38:48 +00002450 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002451 {
ajsba6454e2005-02-08 15:37:30 +00002452 char buf[2][INET_ADDRSTRLEN];
2453 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002454 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002455 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2456 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2457 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002458 /* Fix multicast memberships? */
2459 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002460 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002461 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002462 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002463 if (oi->multicast_memberships)
2464 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002465 return 0;
2466 }
paul718e3742002-12-13 20:15:29 +00002467
2468 /*
2469 * If the received packet is destined for AllDRouters, the packet
2470 * should be accepted only if the received ospf interface state is
2471 * either DR or Backup -- endo.
2472 */
2473 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2474 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2475 {
ajsba6454e2005-02-08 15:37:30 +00002476 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002477 inet_ntoa (iph->ip_src), IF_NAME (oi),
2478 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002479 /* Try to fix multicast membership. */
2480 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2481 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002482 return 0;
2483 }
2484
2485 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002486 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2487 {
paul718e3742002-12-13 20:15:29 +00002488 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002489 {
ajs2a42e282004-12-08 18:43:03 +00002490 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002491 ospf_packet_dump (ibuf);
2492 }
paul718e3742002-12-13 20:15:29 +00002493
ajs2a42e282004-12-08 18:43:03 +00002494 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002495 ospf_packet_type_str[ospfh->type],
2496 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002497 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2498 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002499
2500 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002501 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002502 }
paul718e3742002-12-13 20:15:29 +00002503
2504 /* Some header verification. */
2505 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2506 if (ret < 0)
2507 {
pauld3241812003-09-29 12:42:39 +00002508 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2509 {
ajs2a42e282004-12-08 18:43:03 +00002510 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002511 "dropping.",
2512 ospf_packet_type_str[ospfh->type],
2513 inet_ntoa (iph->ip_src));
2514 }
paul718e3742002-12-13 20:15:29 +00002515 return ret;
2516 }
2517
paul9985f832005-02-09 15:51:56 +00002518 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002519
2520 /* Adjust size to message length. */
2521 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2522
2523 /* Read rest of the packet and call each sort of packet routine. */
2524 switch (ospfh->type)
2525 {
2526 case OSPF_MSG_HELLO:
2527 ospf_hello (iph, ospfh, ibuf, oi, length);
2528 break;
2529 case OSPF_MSG_DB_DESC:
2530 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2531 break;
2532 case OSPF_MSG_LS_REQ:
2533 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2534 break;
2535 case OSPF_MSG_LS_UPD:
2536 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2537 break;
2538 case OSPF_MSG_LS_ACK:
2539 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2540 break;
2541 default:
2542 zlog (NULL, LOG_WARNING,
2543 "interface %s: OSPF packet header type %d is illegal",
2544 IF_NAME (oi), ospfh->type);
2545 break;
2546 }
2547
paul718e3742002-12-13 20:15:29 +00002548 return 0;
2549}
2550
2551/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002552static void
paul718e3742002-12-13 20:15:29 +00002553ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2554{
2555 struct ospf_header *ospfh;
2556
2557 ospfh = (struct ospf_header *) STREAM_DATA (s);
2558
2559 ospfh->version = (u_char) OSPF_VERSION;
2560 ospfh->type = (u_char) type;
2561
paul68980082003-03-25 05:07:42 +00002562 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002563
2564 ospfh->checksum = 0;
2565 ospfh->area_id = oi->area->area_id;
2566 ospfh->auth_type = htons (ospf_auth_type (oi));
2567
2568 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2569
paul9985f832005-02-09 15:51:56 +00002570 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002571}
2572
2573/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002574static int
paul718e3742002-12-13 20:15:29 +00002575ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2576{
2577 struct crypt_key *ck;
2578
2579 switch (ospf_auth_type (oi))
2580 {
2581 case OSPF_AUTH_NULL:
2582 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2583 break;
2584 case OSPF_AUTH_SIMPLE:
2585 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2586 OSPF_AUTH_SIMPLE_SIZE);
2587 break;
2588 case OSPF_AUTH_CRYPTOGRAPHIC:
2589 /* If key is not set, then set 0. */
2590 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2591 {
2592 ospfh->u.crypt.zero = 0;
2593 ospfh->u.crypt.key_id = 0;
2594 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2595 }
2596 else
2597 {
paul1eb8ef22005-04-07 07:30:20 +00002598 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002599 ospfh->u.crypt.zero = 0;
2600 ospfh->u.crypt.key_id = ck->key_id;
2601 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2602 }
2603 /* note: the seq is done in ospf_make_md5_digest() */
2604 break;
2605 default:
2606 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2607 break;
2608 }
2609
2610 return 0;
2611}
2612
2613/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002614static void
paul718e3742002-12-13 20:15:29 +00002615ospf_fill_header (struct ospf_interface *oi,
2616 struct stream *s, u_int16_t length)
2617{
2618 struct ospf_header *ospfh;
2619
2620 ospfh = (struct ospf_header *) STREAM_DATA (s);
2621
2622 /* Fill length. */
2623 ospfh->length = htons (length);
2624
2625 /* Calculate checksum. */
2626 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2627 ospfh->checksum = in_cksum (ospfh, length);
2628 else
2629 ospfh->checksum = 0;
2630
2631 /* Add Authentication Data. */
2632 ospf_make_auth (oi, ospfh);
2633}
2634
paul4dadc292005-05-06 21:37:42 +00002635static int
paul718e3742002-12-13 20:15:29 +00002636ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2637{
2638 struct ospf_neighbor *nbr;
2639 struct route_node *rn;
2640 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2641 struct in_addr mask;
2642 unsigned long p;
2643 int flag = 0;
2644
2645 /* Set netmask of interface. */
2646 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2647 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2648 masklen2ip (oi->address->prefixlen, &mask);
2649 else
2650 memset ((char *) &mask, 0, sizeof (struct in_addr));
2651 stream_put_ipv4 (s, mask.s_addr);
2652
2653 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002654 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2655 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2656 else
2657 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002658
2659 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002660 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002661 OPTIONS(oi), IF_NAME (oi));
2662
2663 /* Set Options. */
2664 stream_putc (s, OPTIONS (oi));
2665
2666 /* Set Router Priority. */
2667 stream_putc (s, PRIORITY (oi));
2668
2669 /* Set Router Dead Interval. */
2670 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2671
2672 /* Set Designated Router. */
2673 stream_put_ipv4 (s, DR (oi).s_addr);
2674
paul9985f832005-02-09 15:51:56 +00002675 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002676
2677 /* Set Backup Designated Router. */
2678 stream_put_ipv4 (s, BDR (oi).s_addr);
2679
2680 /* Add neighbor seen. */
2681 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002682 if ((nbr = rn->info))
2683 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2684 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2685 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2686 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002687 {
2688 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002689 if (nbr->d_router.s_addr != 0
2690 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2691 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2692 flag = 1;
paul718e3742002-12-13 20:15:29 +00002693
2694 stream_put_ipv4 (s, nbr->router_id.s_addr);
2695 length += 4;
2696 }
2697
2698 /* Let neighbor generate BackupSeen. */
2699 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002700 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002701
2702 return length;
2703}
2704
paul4dadc292005-05-06 21:37:42 +00002705static int
paul718e3742002-12-13 20:15:29 +00002706ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2707 struct stream *s)
2708{
2709 struct ospf_lsa *lsa;
2710 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2711 u_char options;
2712 unsigned long pp;
2713 int i;
2714 struct ospf_lsdb *lsdb;
2715
2716 /* Set Interface MTU. */
2717 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2718 stream_putw (s, 0);
2719 else
2720 stream_putw (s, oi->ifp->mtu);
2721
2722 /* Set Options. */
2723 options = OPTIONS (oi);
2724#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002725 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002726 {
2727 if (IS_SET_DD_I (nbr->dd_flags)
2728 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2729 /*
2730 * Set O-bit in the outgoing DD packet for capablity negotiation,
2731 * if one of following case is applicable.
2732 *
2733 * 1) WaitTimer expiration event triggered the neighbor state to
2734 * change to Exstart, but no (valid) DD packet has received
2735 * from the neighbor yet.
2736 *
2737 * 2) At least one DD packet with O-bit on has received from the
2738 * neighbor.
2739 */
2740 SET_FLAG (options, OSPF_OPTION_O);
2741 }
2742#endif /* HAVE_OPAQUE_LSA */
2743 stream_putc (s, options);
2744
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002745 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002746 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002747 stream_putc (s, nbr->dd_flags);
2748
2749 /* Set DD Sequence Number. */
2750 stream_putl (s, nbr->dd_seqnum);
2751
Paul Jakmab5aeb442006-08-30 18:47:37 +00002752 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002753 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002754 goto empty;
paul718e3742002-12-13 20:15:29 +00002755
2756 /* Describe LSA Header from Database Summary List. */
2757 lsdb = &nbr->db_sum;
2758
2759 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2760 {
2761 struct route_table *table = lsdb->type[i].db;
2762 struct route_node *rn;
2763
2764 for (rn = route_top (table); rn; rn = route_next (rn))
2765 if ((lsa = rn->info) != NULL)
2766 {
2767#ifdef HAVE_OPAQUE_LSA
2768 if (IS_OPAQUE_LSA (lsa->data->type)
2769 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2770 {
2771 /* Suppress advertising opaque-informations. */
2772 /* Remove LSA from DB summary list. */
2773 ospf_lsdb_delete (lsdb, lsa);
2774 continue;
2775 }
2776#endif /* HAVE_OPAQUE_LSA */
2777
2778 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2779 {
2780 struct lsa_header *lsah;
2781 u_int16_t ls_age;
2782
2783 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002784 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002785 break;
2786
2787 /* Keep pointer to LS age. */
2788 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002789 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002790
2791 /* Proceed stream pointer. */
2792 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2793 length += OSPF_LSA_HEADER_SIZE;
2794
2795 /* Set LS age. */
2796 ls_age = LS_AGE (lsa);
2797 lsah->ls_age = htons (ls_age);
2798
2799 }
2800
2801 /* Remove LSA from DB summary list. */
2802 ospf_lsdb_delete (lsdb, lsa);
2803 }
2804 }
2805
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002806 /* Update 'More' bit */
2807 if (ospf_db_summary_isempty (nbr))
2808 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002809empty:
2810 if (nbr->state >= NSM_Exchange)
2811 {
2812 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2813 /* Rewrite DD flags */
2814 stream_putc_at (s, pp, nbr->dd_flags);
2815 }
2816 else
2817 {
2818 assert (IS_SET_DD_M(nbr->dd_flags));
2819 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002820 }
paul718e3742002-12-13 20:15:29 +00002821 return length;
2822}
2823
paul4dadc292005-05-06 21:37:42 +00002824static int
paul718e3742002-12-13 20:15:29 +00002825ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2826 unsigned long delta, struct ospf_neighbor *nbr,
2827 struct ospf_lsa *lsa)
2828{
2829 struct ospf_interface *oi;
2830
2831 oi = nbr->oi;
2832
2833 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002834 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002835 return 0;
2836
2837 stream_putl (s, lsa->data->type);
2838 stream_put_ipv4 (s, lsa->data->id.s_addr);
2839 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2840
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002841 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002842 nbr->ls_req_last = ospf_lsa_lock (lsa);
2843
2844 *length += 12;
2845 return 1;
2846}
2847
paul4dadc292005-05-06 21:37:42 +00002848static int
paul718e3742002-12-13 20:15:29 +00002849ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2850{
2851 struct ospf_lsa *lsa;
2852 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002853 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002854 struct route_table *table;
2855 struct route_node *rn;
2856 int i;
2857 struct ospf_lsdb *lsdb;
2858
2859 lsdb = &nbr->ls_req;
2860
2861 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2862 {
2863 table = lsdb->type[i].db;
2864 for (rn = route_top (table); rn; rn = route_next (rn))
2865 if ((lsa = (rn->info)) != NULL)
2866 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2867 {
2868 route_unlock_node (rn);
2869 break;
2870 }
2871 }
2872 return length;
2873}
2874
paul4dadc292005-05-06 21:37:42 +00002875static int
paul718e3742002-12-13 20:15:29 +00002876ls_age_increment (struct ospf_lsa *lsa, int delay)
2877{
2878 int age;
2879
2880 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2881
2882 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2883}
2884
paul4dadc292005-05-06 21:37:42 +00002885static int
hasso52dc7ee2004-09-23 19:18:23 +00002886ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002887{
2888 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002889 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002890 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00002891 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002892 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002893 unsigned long pp;
2894 int count = 0;
2895
2896 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002897 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002898
paul9985f832005-02-09 15:51:56 +00002899 pp = stream_get_endp (s);
2900 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002901 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00002902
gdt86f1fd92005-01-10 14:20:43 +00002903 /* Calculate amount of packet usable for data. */
2904 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2905
paul718e3742002-12-13 20:15:29 +00002906 while ((node = listhead (update)) != NULL)
2907 {
2908 struct lsa_header *lsah;
2909 u_int16_t ls_age;
2910
2911 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002912 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002913
paul1eb8ef22005-04-07 07:30:20 +00002914 lsa = listgetdata (node);
2915
paul718e3742002-12-13 20:15:29 +00002916 assert (lsa->data);
2917
paul68b73392004-09-12 14:21:37 +00002918 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002919 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002920 break;
2921
paul718e3742002-12-13 20:15:29 +00002922 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002923 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002924
2925 /* Put LSA to Link State Request. */
2926 stream_put (s, lsa->data, ntohs (lsa->data->length));
2927
2928 /* Set LS age. */
2929 /* each hop must increment an lsa_age by transmit_delay
2930 of OSPF interface */
2931 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2932 lsah->ls_age = htons (ls_age);
2933
2934 length += ntohs (lsa->data->length);
2935 count++;
2936
2937 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002938 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002939 }
2940
2941 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002942 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002943
2944 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002945 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002946 return length;
2947}
2948
paul4dadc292005-05-06 21:37:42 +00002949static int
hasso52dc7ee2004-09-23 19:18:23 +00002950ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002951{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002952 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002953 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002954 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002955 struct ospf_lsa *lsa;
2956
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002957 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002958 {
paul718e3742002-12-13 20:15:29 +00002959 assert (lsa);
2960
gdt86f1fd92005-01-10 14:20:43 +00002961 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002962 break;
2963
2964 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2965 length += OSPF_LSA_HEADER_SIZE;
2966
paul718e3742002-12-13 20:15:29 +00002967 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002968 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002969 }
2970
paul718e3742002-12-13 20:15:29 +00002971 return length;
2972}
2973
2974void
2975ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2976{
2977 struct ospf_packet *op;
2978 u_int16_t length = OSPF_HEADER_SIZE;
2979
2980 op = ospf_packet_new (oi->ifp->mtu);
2981
2982 /* Prepare OSPF common header. */
2983 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2984
2985 /* Prepare OSPF Hello body. */
2986 length += ospf_make_hello (oi, op->s);
2987
2988 /* Fill OSPF header. */
2989 ospf_fill_header (oi, op->s, length);
2990
2991 /* Set packet length. */
2992 op->length = length;
2993
2994 op->dst.s_addr = addr->s_addr;
2995
2996 /* Add packet to the interface output queue. */
2997 ospf_packet_add (oi, op);
2998
2999 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003000 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003001}
3002
paul4dadc292005-05-06 21:37:42 +00003003static void
paul718e3742002-12-13 20:15:29 +00003004ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3005{
3006 struct ospf_interface *oi;
3007
3008 oi = nbr_nbma->oi;
3009 assert(oi);
3010
3011 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003012 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003013 return;
3014
3015 if (oi->type != OSPF_IFTYPE_NBMA)
3016 return;
3017
3018 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3019 return;
3020
3021 if (PRIORITY(oi) == 0)
3022 return;
3023
3024 if (nbr_nbma->priority == 0
3025 && oi->state != ISM_DR && oi->state != ISM_Backup)
3026 return;
3027
3028 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3029}
3030
3031int
3032ospf_poll_timer (struct thread *thread)
3033{
3034 struct ospf_nbr_nbma *nbr_nbma;
3035
3036 nbr_nbma = THREAD_ARG (thread);
3037 nbr_nbma->t_poll = NULL;
3038
3039 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003040 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003041 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3042
3043 ospf_poll_send (nbr_nbma);
3044
3045 if (nbr_nbma->v_poll > 0)
3046 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3047 nbr_nbma->v_poll);
3048
3049 return 0;
3050}
3051
3052
3053int
3054ospf_hello_reply_timer (struct thread *thread)
3055{
3056 struct ospf_neighbor *nbr;
3057
3058 nbr = THREAD_ARG (thread);
3059 nbr->t_hello_reply = NULL;
3060
3061 assert (nbr->oi);
3062
3063 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003064 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003065 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3066
3067 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3068
3069 return 0;
3070}
3071
3072/* Send OSPF Hello. */
3073void
3074ospf_hello_send (struct ospf_interface *oi)
3075{
3076 struct ospf_packet *op;
3077 u_int16_t length = OSPF_HEADER_SIZE;
3078
3079 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003080 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003081 return;
3082
3083 op = ospf_packet_new (oi->ifp->mtu);
3084
3085 /* Prepare OSPF common header. */
3086 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3087
3088 /* Prepare OSPF Hello body. */
3089 length += ospf_make_hello (oi, op->s);
3090
3091 /* Fill OSPF header. */
3092 ospf_fill_header (oi, op->s, length);
3093
3094 /* Set packet length. */
3095 op->length = length;
3096
3097 if (oi->type == OSPF_IFTYPE_NBMA)
3098 {
3099 struct ospf_neighbor *nbr;
3100 struct route_node *rn;
3101
3102 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3103 if ((nbr = rn->info))
3104 if (nbr != oi->nbr_self)
3105 if (nbr->state != NSM_Down)
3106 {
3107 /* RFC 2328 Section 9.5.1
3108 If the router is not eligible to become Designated Router,
3109 it must periodically send Hello Packets to both the
3110 Designated Router and the Backup Designated Router (if they
3111 exist). */
3112 if (PRIORITY(oi) == 0 &&
3113 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3114 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3115 continue;
3116
3117 /* If the router is eligible to become Designated Router, it
3118 must periodically send Hello Packets to all neighbors that
3119 are also eligible. In addition, if the router is itself the
3120 Designated Router or Backup Designated Router, it must also
3121 send periodic Hello Packets to all other neighbors. */
3122
3123 if (nbr->priority == 0 && oi->state == ISM_DROther)
3124 continue;
3125 /* if oi->state == Waiting, send hello to all neighbors */
3126 {
3127 struct ospf_packet *op_dup;
3128
3129 op_dup = ospf_packet_dup(op);
3130 op_dup->dst = nbr->address.u.prefix4;
3131
3132 /* Add packet to the interface output queue. */
3133 ospf_packet_add (oi, op_dup);
3134
paul020709f2003-04-04 02:44:16 +00003135 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003136 }
3137
3138 }
3139 ospf_packet_free (op);
3140 }
3141 else
3142 {
3143 /* Decide destination address. */
3144 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3145 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3146 else
3147 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3148
3149 /* Add packet to the interface output queue. */
3150 ospf_packet_add (oi, op);
3151
3152 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003153 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003154 }
3155}
3156
3157/* Send OSPF Database Description. */
3158void
3159ospf_db_desc_send (struct ospf_neighbor *nbr)
3160{
3161 struct ospf_interface *oi;
3162 struct ospf_packet *op;
3163 u_int16_t length = OSPF_HEADER_SIZE;
3164
3165 oi = nbr->oi;
3166 op = ospf_packet_new (oi->ifp->mtu);
3167
3168 /* Prepare OSPF common header. */
3169 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3170
3171 /* Prepare OSPF Database Description body. */
3172 length += ospf_make_db_desc (oi, nbr, op->s);
3173
3174 /* Fill OSPF header. */
3175 ospf_fill_header (oi, op->s, length);
3176
3177 /* Set packet length. */
3178 op->length = length;
3179
3180 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003181 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3182 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3183 else
3184 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003185
3186 /* Add packet to the interface output queue. */
3187 ospf_packet_add (oi, op);
3188
3189 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003190 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003191
3192 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3193 if (nbr->last_send)
3194 ospf_packet_free (nbr->last_send);
3195 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003196 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003197}
3198
3199/* Re-send Database Description. */
3200void
3201ospf_db_desc_resend (struct ospf_neighbor *nbr)
3202{
3203 struct ospf_interface *oi;
3204
3205 oi = nbr->oi;
3206
3207 /* Add packet to the interface output queue. */
3208 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3209
3210 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003211 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003212}
3213
3214/* Send Link State Request. */
3215void
3216ospf_ls_req_send (struct ospf_neighbor *nbr)
3217{
3218 struct ospf_interface *oi;
3219 struct ospf_packet *op;
3220 u_int16_t length = OSPF_HEADER_SIZE;
3221
3222 oi = nbr->oi;
3223 op = ospf_packet_new (oi->ifp->mtu);
3224
3225 /* Prepare OSPF common header. */
3226 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3227
3228 /* Prepare OSPF Link State Request body. */
3229 length += ospf_make_ls_req (nbr, op->s);
3230 if (length == OSPF_HEADER_SIZE)
3231 {
3232 ospf_packet_free (op);
3233 return;
3234 }
3235
3236 /* Fill OSPF header. */
3237 ospf_fill_header (oi, op->s, length);
3238
3239 /* Set packet length. */
3240 op->length = length;
3241
3242 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003243 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3244 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3245 else
3246 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003247
3248 /* Add packet to the interface output queue. */
3249 ospf_packet_add (oi, op);
3250
3251 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003252 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003253
3254 /* Add Link State Request Retransmission Timer. */
3255 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3256}
3257
3258/* Send Link State Update with an LSA. */
3259void
3260ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3261 int flag)
3262{
hasso52dc7ee2004-09-23 19:18:23 +00003263 struct list *update;
paul718e3742002-12-13 20:15:29 +00003264
3265 update = list_new ();
3266
3267 listnode_add (update, lsa);
3268 ospf_ls_upd_send (nbr, update, flag);
3269
3270 list_delete (update);
3271}
3272
paul68b73392004-09-12 14:21:37 +00003273/* Determine size for packet. Must be at least big enough to accomodate next
3274 * LSA on list, which may be bigger than MTU size.
3275 *
3276 * Return pointer to new ospf_packet
3277 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3278 * on packet sizes (in which case offending LSA is deleted from update list)
3279 */
3280static struct ospf_packet *
3281ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3282{
3283 struct ospf_lsa *lsa;
3284 struct listnode *ln;
3285 size_t size;
3286 static char warned = 0;
3287
paul1eb8ef22005-04-07 07:30:20 +00003288 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003289 assert (lsa->data);
3290
3291 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3292 > ospf_packet_max (oi))
3293 {
3294 if (!warned)
3295 {
3296 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3297 "will need to fragment. Not optimal. Try divide up"
3298 " your network with areas. Use 'debug ospf packet send'"
3299 " to see details, or look at 'show ip ospf database ..'");
3300 warned = 1;
3301 }
3302
3303 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003304 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003305 " %d bytes originated by %s, will be fragmented!",
3306 inet_ntoa (lsa->data->id),
3307 ntohs (lsa->data->length),
3308 inet_ntoa (lsa->data->adv_router));
3309
3310 /*
3311 * Allocate just enough to fit this LSA only, to avoid including other
3312 * LSAs in fragmented LSA Updates.
3313 */
3314 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3315 + OSPF_LS_UPD_MIN_SIZE;
3316 }
3317 else
3318 size = oi->ifp->mtu;
3319
3320 if (size > OSPF_MAX_PACKET_SIZE)
3321 {
3322 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003323 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003324 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003325 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003326 (long int) size);
paul68b73392004-09-12 14:21:37 +00003327 list_delete_node (update, ln);
3328 return NULL;
3329 }
3330
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003331 /* IP header is built up separately by ospf_write(). This means, that we must
3332 * reduce the "affordable" size just calculated by length of an IP header.
3333 * This makes sure, that even if we manage to fill the payload with LSA data
3334 * completely, the final packet (our data plus IP header) still fits into
3335 * outgoing interface MTU. This correction isn't really meaningful for an
3336 * oversized LSA, but for consistency the correction is done for both cases.
3337 *
3338 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3339 */
3340 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003341}
3342
paul718e3742002-12-13 20:15:29 +00003343static void
hasso52dc7ee2004-09-23 19:18:23 +00003344ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003345 struct in_addr addr)
3346{
3347 struct ospf_packet *op;
3348 u_int16_t length = OSPF_HEADER_SIZE;
3349
3350 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003351 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003352
3353 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003354
3355 /* Prepare OSPF common header. */
3356 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3357
paul59ea14c2004-07-14 20:50:36 +00003358 /* Prepare OSPF Link State Update body.
3359 * Includes Type-7 translation.
3360 */
paul718e3742002-12-13 20:15:29 +00003361 length += ospf_make_ls_upd (oi, update, op->s);
3362
3363 /* Fill OSPF header. */
3364 ospf_fill_header (oi, op->s, length);
3365
3366 /* Set packet length. */
3367 op->length = length;
3368
3369 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003370 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3371 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3372 else
3373 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003374
3375 /* Add packet to the interface output queue. */
3376 ospf_packet_add (oi, op);
3377
3378 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003379 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003380}
3381
3382static int
3383ospf_ls_upd_send_queue_event (struct thread *thread)
3384{
3385 struct ospf_interface *oi = THREAD_ARG(thread);
3386 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003387 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003388 struct list *update;
paul68b73392004-09-12 14:21:37 +00003389 char again = 0;
paul718e3742002-12-13 20:15:29 +00003390
3391 oi->t_ls_upd_event = NULL;
3392
3393 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003394 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003395
paul736d3442003-07-24 23:22:57 +00003396 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003397 {
paul736d3442003-07-24 23:22:57 +00003398 rnext = route_next (rn);
3399
paul718e3742002-12-13 20:15:29 +00003400 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003401 continue;
paul68b73392004-09-12 14:21:37 +00003402
3403 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003404
paul48fe13b2004-07-27 17:40:44 +00003405 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003406
paul68b73392004-09-12 14:21:37 +00003407 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003408 if (listcount(update) == 0)
3409 {
3410 list_delete (rn->info);
3411 rn->info = NULL;
3412 route_unlock_node (rn);
3413 }
3414 else
paul68b73392004-09-12 14:21:37 +00003415 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003416 }
3417
3418 if (again != 0)
3419 {
3420 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003421 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003422 " %d nodes to try again, raising new event", again);
3423 oi->t_ls_upd_event =
3424 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003425 }
3426
3427 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003428 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003429
paul718e3742002-12-13 20:15:29 +00003430 return 0;
3431}
3432
3433void
hasso52dc7ee2004-09-23 19:18:23 +00003434ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003435{
3436 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003437 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003438 struct prefix_ipv4 p;
3439 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003440 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003441
3442 oi = nbr->oi;
3443
3444 p.family = AF_INET;
3445 p.prefixlen = IPV4_MAX_BITLEN;
3446
3447 /* Decide destination address. */
3448 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3449 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003450 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3451 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003452 else if (flag == OSPF_SEND_PACKET_DIRECT)
3453 p.prefix = nbr->address.u.prefix4;
3454 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3455 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003456 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3457 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003458 else
3459 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3460
3461 if (oi->type == OSPF_IFTYPE_NBMA)
3462 {
3463 if (flag == OSPF_SEND_PACKET_INDIRECT)
3464 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3465 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3466 zlog_warn ("* LS-Update is sent to myself.");
3467 }
3468
3469 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3470
3471 if (rn->info == NULL)
3472 rn->info = list_new ();
3473
paul1eb8ef22005-04-07 07:30:20 +00003474 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003475 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003476
3477 if (oi->t_ls_upd_event == NULL)
3478 oi->t_ls_upd_event =
3479 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3480}
3481
3482static void
hasso52dc7ee2004-09-23 19:18:23 +00003483ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3484 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003485{
3486 struct ospf_packet *op;
3487 u_int16_t length = OSPF_HEADER_SIZE;
3488
3489 op = ospf_packet_new (oi->ifp->mtu);
3490
3491 /* Prepare OSPF common header. */
3492 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3493
3494 /* Prepare OSPF Link State Acknowledgment body. */
3495 length += ospf_make_ls_ack (oi, ack, op->s);
3496
3497 /* Fill OSPF header. */
3498 ospf_fill_header (oi, op->s, length);
3499
3500 /* Set packet length. */
3501 op->length = length;
3502
3503 /* Set destination IP address. */
3504 op->dst = dst;
3505
3506 /* Add packet to the interface output queue. */
3507 ospf_packet_add (oi, op);
3508
3509 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003510 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003511}
3512
3513static int
3514ospf_ls_ack_send_event (struct thread *thread)
3515{
3516 struct ospf_interface *oi = THREAD_ARG (thread);
3517
3518 oi->t_ls_ack_direct = NULL;
3519
3520 while (listcount (oi->ls_ack_direct.ls_ack))
3521 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3522 oi->ls_ack_direct.dst);
3523
3524 return 0;
3525}
3526
3527void
3528ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3529{
3530 struct ospf_interface *oi = nbr->oi;
3531
3532 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3533 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3534
3535 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3536
3537 if (oi->t_ls_ack_direct == NULL)
3538 oi->t_ls_ack_direct =
3539 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3540}
3541
3542/* Send Link State Acknowledgment delayed. */
3543void
3544ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3545{
3546 struct in_addr dst;
3547
3548 /* Decide destination address. */
3549 /* RFC2328 Section 13.5 On non-broadcast
3550 networks, delayed Link State Acknowledgment packets must be
3551 unicast separately over each adjacency (i.e., neighbor whose
3552 state is >= Exchange). */
3553 if (oi->type == OSPF_IFTYPE_NBMA)
3554 {
3555 struct ospf_neighbor *nbr;
3556 struct route_node *rn;
3557
3558 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3559 if ((nbr = rn->info) != NULL)
3560 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3561 while (listcount (oi->ls_ack))
3562 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3563 return;
3564 }
3565 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3566 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3567 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3568 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3569 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3570 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003571 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3572 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003573 else
3574 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3575
3576 while (listcount (oi->ls_ack))
3577 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3578}