blob: 1c1a1e69521c2847b9e26aa73766a448f2712d0f [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
paul0bfeca32004-09-24 08:07:54 +0000656#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000657 /* XXX-MT: not thread-safe at all..
658 * XXX: this presumes this is only programme sending OSPF packets
659 * otherwise, no guarantee ipid will be unique
660 */
661 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000662#endif /* WANT_OSPF_WRITE_FRAGMENT */
663
paul718e3742002-12-13 20:15:29 +0000664 iph.ip_off = 0;
665 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
666 iph.ip_ttl = OSPF_VL_IP_TTL;
667 else
668 iph.ip_ttl = OSPF_IP_TTL;
669 iph.ip_p = IPPROTO_OSPFIGP;
670 iph.ip_sum = 0;
671 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
672 iph.ip_dst.s_addr = op->dst.s_addr;
673
674 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000675 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000676 msg.msg_namelen = sizeof (sa_dst);
677 msg.msg_iov = iov;
678 msg.msg_iovlen = 2;
679 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000680 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
681 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000682 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000683
684 /* Sadly we can not rely on kernels to fragment packets because of either
685 * IP_HDRINCL and/or multicast destination being set.
686 */
paul0bfeca32004-09-24 08:07:54 +0000687#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000688 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000689 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
690 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000691#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000692
693 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000694 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000695 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000696 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000697
698 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000699 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000700 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000701 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000702 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000703
paul718e3742002-12-13 20:15:29 +0000704 /* Show debug sending packet. */
705 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
706 {
707 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
708 {
ajs2a42e282004-12-08 18:43:03 +0000709 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000710 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000711 stream_set_getp (op->s, 0);
712 ospf_packet_dump (op->s);
713 }
714
ajs2a42e282004-12-08 18:43:03 +0000715 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000716 ospf_packet_type_str[type], inet_ntoa (op->dst),
717 IF_NAME (oi));
718
719 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000720 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* Now delete packet from queue. */
724 ospf_packet_delete (oi);
725
726 if (ospf_fifo_head (oi->obuf) == NULL)
727 {
728 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000729 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000730 }
731
732 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000733 if (!list_isempty (ospf->oi_write_q))
734 ospf->t_write =
735 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000736
737 return 0;
738}
739
740/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000741static void
paul718e3742002-12-13 20:15:29 +0000742ospf_hello (struct ip *iph, struct ospf_header *ospfh,
743 struct stream * s, struct ospf_interface *oi, int size)
744{
745 struct ospf_hello *hello;
746 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000747 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000748 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000749
750 /* increment statistics. */
751 oi->hello_in++;
752
753 hello = (struct ospf_hello *) STREAM_PNT (s);
754
755 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000756 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000757 {
758 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
759 {
ajs2a42e282004-12-08 18:43:03 +0000760 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000761 "dropping.",
762 ospf_packet_type_str[ospfh->type],
763 inet_ntoa (iph->ip_src));
764 }
765 return;
766 }
paul718e3742002-12-13 20:15:29 +0000767
paul718e3742002-12-13 20:15:29 +0000768 /* get neighbor prefix. */
769 p.family = AF_INET;
770 p.prefixlen = ip_masklen (hello->network_mask);
771 p.u.prefix4 = iph->ip_src;
772
773 /* Compare network mask. */
774 /* Checking is ignored for Point-to-Point and Virtual link. */
775 if (oi->type != OSPF_IFTYPE_POINTOPOINT
776 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
777 if (oi->address->prefixlen != p.prefixlen)
778 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000779 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
780 inet_ntoa(ospfh->router_id), IF_NAME(oi),
781 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000782 return;
783 }
784
paul718e3742002-12-13 20:15:29 +0000785 /* Compare Router Dead Interval. */
786 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
787 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000788 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
789 "(expected %u, but received %u).",
790 inet_ntoa(ospfh->router_id),
791 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000792 return;
793 }
794
paulf9ad9372005-10-21 00:45:17 +0000795 /* Compare Hello Interval - ignored if fast-hellos are set. */
796 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
797 {
798 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
799 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000800 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
801 "(expected %u, but received %u).",
802 inet_ntoa(ospfh->router_id),
803 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000804 return;
805 }
806 }
807
paul718e3742002-12-13 20:15:29 +0000808 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000809 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000810 inet_ntoa (ospfh->router_id),
811 ospf_options_dump (hello->options));
812
813 /* Compare options. */
814#define REJECT_IF_TBIT_ON 1 /* XXX */
815#ifdef REJECT_IF_TBIT_ON
816 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
817 {
818 /*
819 * This router does not support non-zero TOS.
820 * Drop this Hello packet not to establish neighbor relationship.
821 */
822 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
823 inet_ntoa (ospfh->router_id));
824 return;
825 }
826#endif /* REJECT_IF_TBIT_ON */
827
828#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000829 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000830 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
831 {
832 /*
833 * This router does know the correct usage of O-bit
834 * the bit should be set in DD packet only.
835 */
836 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
837 inet_ntoa (ospfh->router_id));
838#ifdef STRICT_OBIT_USAGE_CHECK
839 return; /* Reject this packet. */
840#else /* STRICT_OBIT_USAGE_CHECK */
841 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
842#endif /* STRICT_OBIT_USAGE_CHECK */
843 }
844#endif /* HAVE_OPAQUE_LSA */
845
846 /* new for NSSA is to ensure that NP is on and E is off */
847
paul718e3742002-12-13 20:15:29 +0000848 if (oi->area->external_routing == OSPF_AREA_NSSA)
849 {
850 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
851 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
852 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
853 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
854 {
855 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
856 return;
857 }
858 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000859 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000860 }
861 else
paul718e3742002-12-13 20:15:29 +0000862 /* The setting of the E-bit found in the Hello Packet's Options
863 field must match this area's ExternalRoutingCapability A
864 mismatch causes processing to stop and the packet to be
865 dropped. The setting of the rest of the bits in the Hello
866 Packet's Options field should be ignored. */
867 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
868 CHECK_FLAG (hello->options, OSPF_OPTION_E))
869 {
ajs3aa8d5f2004-12-11 18:00:06 +0000870 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
871 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000872 return;
873 }
paul718e3742002-12-13 20:15:29 +0000874
pauld3f0d622004-05-05 15:27:15 +0000875 /* get neighbour struct */
876 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
877
878 /* neighbour must be valid, ospf_nbr_get creates if none existed */
879 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000880
881 old_state = nbr->state;
882
883 /* Add event to thread. */
884 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
885
886 /* RFC2328 Section 9.5.1
887 If the router is not eligible to become Designated Router,
888 (snip) It must also send an Hello Packet in reply to an
889 Hello Packet received from any eligible neighbor (other than
890 the current Designated Router and Backup Designated Router). */
891 if (oi->type == OSPF_IFTYPE_NBMA)
892 if (PRIORITY(oi) == 0 && hello->priority > 0
893 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
894 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
895 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
896 OSPF_HELLO_REPLY_DELAY);
897
898 /* on NBMA network type, it happens to receive bidirectional Hello packet
899 without advance 1-Way Received event.
900 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
901 if (oi->type == OSPF_IFTYPE_NBMA &&
902 (old_state == NSM_Down || old_state == NSM_Attempt))
903 {
904 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
905 nbr->priority = hello->priority;
906 nbr->d_router = hello->d_router;
907 nbr->bd_router = hello->bd_router;
908 return;
909 }
910
paul68980082003-03-25 05:07:42 +0000911 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000912 size - OSPF_HELLO_MIN_SIZE))
913 {
914 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
915 nbr->options |= hello->options;
916 }
917 else
918 {
919 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
920 /* Set neighbor information. */
921 nbr->priority = hello->priority;
922 nbr->d_router = hello->d_router;
923 nbr->bd_router = hello->bd_router;
924 return;
925 }
926
927 /* If neighbor itself declares DR and no BDR exists,
928 cause event BackupSeen */
929 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
930 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
931 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
932
933 /* neighbor itself declares BDR. */
934 if (oi->state == ISM_Waiting &&
935 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
936 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
937
938 /* had not previously. */
939 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
940 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
941 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
942 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
943 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
944
945 /* had not previously. */
946 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
947 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
948 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
951
952 /* Neighbor priority check. */
953 if (nbr->priority >= 0 && nbr->priority != hello->priority)
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
955
956 /* Set neighbor information. */
957 nbr->priority = hello->priority;
958 nbr->d_router = hello->d_router;
959 nbr->bd_router = hello->bd_router;
960}
961
962/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000963static void
paul718e3742002-12-13 20:15:29 +0000964ospf_db_desc_save_current (struct ospf_neighbor *nbr,
965 struct ospf_db_desc *dd)
966{
967 nbr->last_recv.flags = dd->flags;
968 nbr->last_recv.options = dd->options;
969 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
970}
971
972/* Process rest of DD packet. */
973static void
974ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
975 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
976 u_int16_t size)
977{
978 struct ospf_lsa *new, *find;
979 struct lsa_header *lsah;
980
paul9985f832005-02-09 15:51:56 +0000981 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000982 for (size -= OSPF_DB_DESC_MIN_SIZE;
983 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
984 {
985 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000986 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000987
988 /* Unknown LS type. */
989 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
990 {
ajsbec595a2004-11-30 22:38:43 +0000991 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000992 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
993 return;
994 }
995
996#ifdef HAVE_OPAQUE_LSA
997 if (IS_OPAQUE_LSA (lsah->type)
998 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
999 {
1000 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1001 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1002 return;
1003 }
1004#endif /* HAVE_OPAQUE_LSA */
1005
1006 switch (lsah->type)
1007 {
1008 case OSPF_AS_EXTERNAL_LSA:
1009#ifdef HAVE_OPAQUE_LSA
1010 case OSPF_OPAQUE_AS_LSA:
1011#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001012 /* Check for stub area. Reject if AS-External from stub but
1013 allow if from NSSA. */
1014 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001015 {
1016 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1017 lsah->type, inet_ntoa (lsah->id),
1018 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1019 "STUB" : "NSSA");
1020 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1021 return;
1022 }
1023 break;
1024 default:
1025 break;
1026 }
1027
1028 /* Create LS-request object. */
1029 new = ospf_ls_request_new (lsah);
1030
1031 /* Lookup received LSA, then add LS request list. */
1032 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001033
1034 /* ospf_lsa_more_recent is fine with NULL pointers */
1035 switch (ospf_lsa_more_recent (find, new))
1036 {
1037 case -1:
1038 /* Neighbour has a more recent LSA, we must request it */
1039 ospf_ls_request_add (nbr, new);
1040 case 0:
1041 /* If we have a copy of this LSA, it's either less recent
1042 * and we're requesting it from neighbour (the case above), or
1043 * it's as recent and we both have same copy (this case).
1044 *
1045 * In neither of these two cases is there any point in
1046 * describing our copy of the LSA to the neighbour in a
1047 * DB-Summary packet, if we're still intending to do so.
1048 *
1049 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1050 * backward compatible optimisation to OSPF DB Exchange /
1051 * DB Description process implemented here.
1052 */
1053 if (find)
1054 ospf_lsdb_delete (&nbr->db_sum, find);
1055 ospf_lsa_discard (new);
1056 break;
1057 default:
1058 /* We have the more recent copy, nothing specific to do:
1059 * - no need to request neighbours stale copy
1060 * - must leave DB summary list copy alone
1061 */
1062 if (IS_DEBUG_OSPF_EVENT)
1063 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1064 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1065 ospf_lsa_discard (new);
1066 }
paul718e3742002-12-13 20:15:29 +00001067 }
1068
1069 /* Master */
1070 if (IS_SET_DD_MS (nbr->dd_flags))
1071 {
1072 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001073
1074 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001075 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1076 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1077 else
paul718e3742002-12-13 20:15:29 +00001078 ospf_db_desc_send (nbr);
1079 }
1080 /* Slave */
1081 else
1082 {
1083 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1084
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001085 /* Send DD packet in reply.
1086 *
1087 * Must be done to acknowledge the Master's DD, regardless of
1088 * whether we have more LSAs ourselves to describe.
1089 *
1090 * This function will clear the 'More' bit, if after this DD
1091 * we have no more LSAs to describe to the master..
1092 */
paul718e3742002-12-13 20:15:29 +00001093 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001094
1095 /* Slave can raise ExchangeDone now, if master is also done */
1096 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1097 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001098 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001099
paul718e3742002-12-13 20:15:29 +00001100 /* Save received neighbor values from DD. */
1101 ospf_db_desc_save_current (nbr, dd);
1102}
1103
paul4dadc292005-05-06 21:37:42 +00001104static int
paul718e3742002-12-13 20:15:29 +00001105ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1106{
1107 /* Is DD duplicated? */
1108 if (dd->options == nbr->last_recv.options &&
1109 dd->flags == nbr->last_recv.flags &&
1110 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1111 return 1;
1112
1113 return 0;
1114}
1115
1116/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001117static void
paul718e3742002-12-13 20:15:29 +00001118ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1119 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1120{
1121 struct ospf_db_desc *dd;
1122 struct ospf_neighbor *nbr;
1123
1124 /* Increment statistics. */
1125 oi->db_desc_in++;
1126
1127 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001128
pauld3f0d622004-05-05 15:27:15 +00001129 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001130 if (nbr == NULL)
1131 {
1132 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1133 inet_ntoa (ospfh->router_id));
1134 return;
1135 }
1136
1137 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001138 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1139 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001140 {
ajs3aa8d5f2004-12-11 18:00:06 +00001141 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1142 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1143 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001144 return;
1145 }
1146
pauld363df22003-06-19 00:26:34 +00001147 /*
1148 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1149 * required. In fact at least JunOS sends DD packets with P bit clear.
1150 * Until proper solution is developped, this hack should help.
1151 *
1152 * Update: According to the RFCs, N bit is specified /only/ for Hello
1153 * options, unfortunately its use in DD options is not specified. Hence some
1154 * implementations follow E-bit semantics and set it in DD options, and some
1155 * treat it as unspecified and hence follow the directive "default for
1156 * options is clear", ie unset.
1157 *
1158 * Reset the flag, as ospfd follows E-bit semantics.
1159 */
1160 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1161 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1162 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1163 {
1164 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001165 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001166 inet_ntoa (nbr->router_id) );
1167 SET_FLAG (dd->options, OSPF_OPTION_NP);
1168 }
pauld363df22003-06-19 00:26:34 +00001169
paul718e3742002-12-13 20:15:29 +00001170#ifdef REJECT_IF_TBIT_ON
1171 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1172 {
1173 /*
1174 * In Hello protocol, optional capability must have checked
1175 * to prevent this T-bit enabled router be my neighbor.
1176 */
1177 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1178 return;
1179 }
1180#endif /* REJECT_IF_TBIT_ON */
1181
1182#ifdef HAVE_OPAQUE_LSA
1183 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001184 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001185 {
1186 /*
1187 * This node is not configured to handle O-bit, for now.
1188 * Clear it to ignore unsupported capability proposed by neighbor.
1189 */
1190 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1191 }
1192#endif /* HAVE_OPAQUE_LSA */
1193
1194 /* Process DD packet by neighbor status. */
1195 switch (nbr->state)
1196 {
1197 case NSM_Down:
1198 case NSM_Attempt:
1199 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001200 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001201 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001202 LOOKUP (ospf_nsm_state_msg, nbr->state));
1203 break;
1204 case NSM_Init:
1205 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1206 /* If the new state is ExStart, the processing of the current
1207 packet should then continue in this new state by falling
1208 through to case ExStart below. */
1209 if (nbr->state != NSM_ExStart)
1210 break;
1211 case NSM_ExStart:
1212 /* Initial DBD */
1213 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1214 (size == OSPF_DB_DESC_MIN_SIZE))
1215 {
paul68980082003-03-25 05:07:42 +00001216 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001217 {
1218 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001219 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001220 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001221 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001222
1223 /* Reset I/MS */
1224 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001225 }
1226 else
1227 {
1228 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001229 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001230 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001231 break;
1232 }
1233 }
1234 /* Ack from the Slave */
1235 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1236 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001237 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001238 {
ajs17eaa722004-12-29 21:04:48 +00001239 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001240 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001241 /* Reset I, leaving MS */
1242 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001243 }
1244 else
1245 {
ajs3aa8d5f2004-12-11 18:00:06 +00001246 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1247 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001248 break;
1249 }
1250
1251 /* This is where the real Options are saved */
1252 nbr->options = dd->options;
1253
1254#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001255 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001256 {
1257 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001258 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001259 inet_ntoa (nbr->router_id),
1260 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1261
1262 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1263 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1264 {
paul6d452762005-11-03 11:15:44 +00001265 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1266 "Opaque-LSAs cannot be reliably advertised "
1267 "in this network.",
1268 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001269 /* This situation is undesirable, but not a real error. */
1270 }
1271 }
1272#endif /* HAVE_OPAQUE_LSA */
1273
1274 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1275
1276 /* continue processing rest of packet. */
1277 ospf_db_desc_proc (s, oi, nbr, dd, size);
1278 break;
1279 case NSM_Exchange:
1280 if (ospf_db_desc_is_dup (dd, nbr))
1281 {
1282 if (IS_SET_DD_MS (nbr->dd_flags))
1283 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001284 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001285 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001286 else
1287 /* Slave: cause to retransmit the last Database Description. */
1288 {
paul6d452762005-11-03 11:15:44 +00001289 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001290 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001291 ospf_db_desc_resend (nbr);
1292 }
1293 break;
1294 }
1295
1296 /* Otherwise DD packet should be checked. */
1297 /* Check Master/Slave bit mismatch */
1298 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1299 {
ajs3aa8d5f2004-12-11 18:00:06 +00001300 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1301 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001302 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1303 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001304 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001305 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001306 break;
1307 }
1308
1309 /* Check initialize bit is set. */
1310 if (IS_SET_DD_I (dd->flags))
1311 {
paul6d452762005-11-03 11:15:44 +00001312 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001313 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001314 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1315 break;
1316 }
1317
1318 /* Check DD Options. */
1319 if (dd->options != nbr->options)
1320 {
1321#ifdef ORIGINAL_CODING
1322 /* Save the new options for debugging */
1323 nbr->options = dd->options;
1324#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001325 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1326 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001327 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1328 break;
1329 }
1330
1331 /* Check DD sequence number. */
1332 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1333 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1334 (!IS_SET_DD_MS (nbr->dd_flags) &&
1335 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1336 {
ajs3aa8d5f2004-12-11 18:00:06 +00001337 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1338 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001339 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1340 break;
1341 }
1342
1343 /* Continue processing rest of packet. */
1344 ospf_db_desc_proc (s, oi, nbr, dd, size);
1345 break;
1346 case NSM_Loading:
1347 case NSM_Full:
1348 if (ospf_db_desc_is_dup (dd, nbr))
1349 {
1350 if (IS_SET_DD_MS (nbr->dd_flags))
1351 {
1352 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001353 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1354 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001355 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001356 break;
1357 }
1358 else
1359 {
1360 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001361 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001362 t = tv_sub (now, nbr->last_send_ts);
1363 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1364 {
1365 /* In states Loading and Full the slave must resend
1366 its last Database Description packet in response to
1367 duplicate Database Description packets received
1368 from the master. For this reason the slave must
1369 wait RouterDeadInterval seconds before freeing the
1370 last Database Description packet. Reception of a
1371 Database Description packet from the master after
1372 this interval will generate a SeqNumberMismatch
1373 neighbor event. RFC2328 Section 10.8 */
1374 ospf_db_desc_resend (nbr);
1375 break;
1376 }
1377 }
1378 }
1379
1380 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1381 break;
1382 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001383 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1384 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001385 break;
1386 }
1387}
1388
1389#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1390
1391/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001392static void
paul718e3742002-12-13 20:15:29 +00001393ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1394 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1395{
1396 struct ospf_neighbor *nbr;
1397 u_int32_t ls_type;
1398 struct in_addr ls_id;
1399 struct in_addr adv_router;
1400 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001401 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001402 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001403
1404 /* Increment statistics. */
1405 oi->ls_req_in++;
1406
pauld3f0d622004-05-05 15:27:15 +00001407 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001408 if (nbr == NULL)
1409 {
1410 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1411 inet_ntoa (ospfh->router_id));
1412 return;
1413 }
1414
1415 /* Neighbor State should be Exchange or later. */
1416 if (nbr->state != NSM_Exchange &&
1417 nbr->state != NSM_Loading &&
1418 nbr->state != NSM_Full)
1419 {
ajsbec595a2004-11-30 22:38:43 +00001420 zlog_warn ("Link State Request received from %s: "
1421 "Neighbor state is %s, packet discarded.",
1422 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001423 LOOKUP (ospf_nsm_state_msg, nbr->state));
1424 return;
1425 }
1426
1427 /* Send Link State Update for ALL requested LSAs. */
1428 ls_upd = list_new ();
1429 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1430
1431 while (size >= OSPF_LSA_KEY_SIZE)
1432 {
1433 /* Get one slice of Link State Request. */
1434 ls_type = stream_getl (s);
1435 ls_id.s_addr = stream_get_ipv4 (s);
1436 adv_router.s_addr = stream_get_ipv4 (s);
1437
1438 /* Verify LSA type. */
1439 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1440 {
1441 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1442 list_delete (ls_upd);
1443 return;
1444 }
1445
1446 /* Search proper LSA in LSDB. */
1447 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1448 if (find == NULL)
1449 {
1450 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1451 list_delete (ls_upd);
1452 return;
1453 }
1454
gdt86f1fd92005-01-10 14:20:43 +00001455 /* Packet overflows MTU size, send immediately. */
1456 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001457 {
1458 if (oi->type == OSPF_IFTYPE_NBMA)
1459 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1460 else
1461 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1462
1463 /* Only remove list contents. Keep ls_upd. */
1464 list_delete_all_node (ls_upd);
1465
1466 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1467 }
1468
1469 /* Append LSA to update list. */
1470 listnode_add (ls_upd, find);
1471 length += ntohs (find->data->length);
1472
1473 size -= OSPF_LSA_KEY_SIZE;
1474 }
1475
1476 /* Send rest of Link State Update. */
1477 if (listcount (ls_upd) > 0)
1478 {
1479 if (oi->type == OSPF_IFTYPE_NBMA)
1480 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1481 else
1482 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1483
1484 list_delete (ls_upd);
1485 }
1486 else
1487 list_free (ls_upd);
1488}
1489
1490/* Get the list of LSAs from Link State Update packet.
1491 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001492static struct list *
paul718e3742002-12-13 20:15:29 +00001493ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1494 struct ospf_interface *oi, size_t size)
1495{
1496 u_int16_t count, sum;
1497 u_int32_t length;
1498 struct lsa_header *lsah;
1499 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001500 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001501
1502 lsas = list_new ();
1503
1504 count = stream_getl (s);
1505 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1506
1507 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001508 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001509 {
1510 lsah = (struct lsa_header *) STREAM_PNT (s);
1511 length = ntohs (lsah->length);
1512
1513 if (length > size)
1514 {
1515 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1516 break;
1517 }
1518
1519 /* Validate the LSA's LS checksum. */
1520 sum = lsah->checksum;
1521 if (sum != ospf_lsa_checksum (lsah))
1522 {
Jaroslav Fojtik7b0d1c62011-12-11 18:22:16 +04001523 /* (bug #685) more details in a one-line message make it possible
1524 * to identify problem source on the one hand and to have a better
1525 * chance to compress repeated messages in syslog on the other */
1526 zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
1527 sum, lsah->checksum, inet_ntoa (lsah->id),
1528 inet_ntoa (nbr->src), inet_ntoa (nbr->router_id),
1529 inet_ntoa (lsah->adv_router));
paul718e3742002-12-13 20:15:29 +00001530 continue;
1531 }
1532
1533 /* Examine the LSA's LS type. */
1534 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1535 {
1536 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1537 continue;
1538 }
1539
1540 /*
1541 * What if the received LSA's age is greater than MaxAge?
1542 * Treat it as a MaxAge case -- endo.
1543 */
1544 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1545 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1546
1547#ifdef HAVE_OPAQUE_LSA
1548 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1549 {
1550#ifdef STRICT_OBIT_USAGE_CHECK
1551 if ((IS_OPAQUE_LSA(lsah->type) &&
1552 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1553 || (! IS_OPAQUE_LSA(lsah->type) &&
1554 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1555 {
1556 /*
1557 * This neighbor must know the exact usage of O-bit;
1558 * the bit will be set in Type-9,10,11 LSAs only.
1559 */
1560 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1561 continue;
1562 }
1563#endif /* STRICT_OBIT_USAGE_CHECK */
1564
1565 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1566 if (lsah->type == OSPF_OPAQUE_AS_LSA
1567 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1568 {
1569 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001570 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 +00001571 continue;
1572 }
1573 }
1574 else if (IS_OPAQUE_LSA(lsah->type))
1575 {
1576 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1577 continue;
1578 }
1579#endif /* HAVE_OPAQUE_LSA */
1580
1581 /* Create OSPF LSA instance. */
1582 lsa = ospf_lsa_new ();
1583
1584 /* We may wish to put some error checking if type NSSA comes in
1585 and area not in NSSA mode */
1586 switch (lsah->type)
1587 {
1588 case OSPF_AS_EXTERNAL_LSA:
1589#ifdef HAVE_OPAQUE_LSA
1590 case OSPF_OPAQUE_AS_LSA:
1591 lsa->area = NULL;
1592 break;
1593 case OSPF_OPAQUE_LINK_LSA:
1594 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1595 /* Fallthrough */
1596#endif /* HAVE_OPAQUE_LSA */
1597 default:
1598 lsa->area = oi->area;
1599 break;
1600 }
1601
1602 lsa->data = ospf_lsa_data_new (length);
1603 memcpy (lsa->data, lsah, length);
1604
1605 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001606 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001607 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1608 listnode_add (lsas, lsa);
1609 }
1610
1611 return lsas;
1612}
1613
1614/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001615static void
hasso52dc7ee2004-09-23 19:18:23 +00001616ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001617{
paul1eb8ef22005-04-07 07:30:20 +00001618 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001619 struct ospf_lsa *lsa;
1620
paul1eb8ef22005-04-07 07:30:20 +00001621 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1622 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001623
1624 list_delete (lsas);
1625}
1626
1627/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001628static void
paul718e3742002-12-13 20:15:29 +00001629ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1630 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1631{
1632 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001633 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001634 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001635 struct ospf_lsa *lsa = NULL;
1636 /* unsigned long ls_req_found = 0; */
1637
1638 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1639
1640 /* Increment statistics. */
1641 oi->ls_upd_in++;
1642
1643 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001644 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001645 if (nbr == NULL)
1646 {
1647 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1648 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1649 return;
1650 }
1651
1652 /* Check neighbor state. */
1653 if (nbr->state < NSM_Exchange)
1654 {
ajs3aa8d5f2004-12-11 18:00:06 +00001655 zlog_warn ("Link State Update: "
1656 "Neighbor[%s] state %s is less than Exchange",
1657 inet_ntoa (ospfh->router_id),
1658 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001659 return;
1660 }
1661
1662 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1663 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1664 * of section 13.
1665 */
1666 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1667
1668#ifdef HAVE_OPAQUE_LSA
1669 /*
paul718e3742002-12-13 20:15:29 +00001670 * If self-originated Opaque-LSAs that have flooded before restart
1671 * are contained in the received LSUpd message, corresponding LSReq
1672 * messages to be sent may have to be modified.
1673 * To eliminate possible race conditions such that flushing and normal
1674 * updating for the same LSA would take place alternately, this trick
1675 * must be done before entering to the loop below.
1676 */
paul69310a62005-05-11 18:09:59 +00001677 /* XXX: Why is this Opaque specific? Either our core code is deficient
1678 * and this should be fixed generally, or Opaque is inventing strawman
1679 * problems */
paul718e3742002-12-13 20:15:29 +00001680 ospf_opaque_adjust_lsreq (nbr, lsas);
1681#endif /* HAVE_OPAQUE_LSA */
1682
1683#define DISCARD_LSA(L,N) {\
1684 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001685 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 +00001686 ospf_lsa_discard (L); \
1687 continue; }
1688
1689 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001690 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001691 {
1692 struct ospf_lsa *ls_ret, *current;
1693 int ret = 1;
1694
paul718e3742002-12-13 20:15:29 +00001695 if (IS_DEBUG_OSPF_NSSA)
1696 {
1697 char buf1[INET_ADDRSTRLEN];
1698 char buf2[INET_ADDRSTRLEN];
1699 char buf3[INET_ADDRSTRLEN];
1700
ajs2a42e282004-12-08 18:43:03 +00001701 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001702 lsa->data->type,
1703 inet_ntop (AF_INET, &ospfh->router_id,
1704 buf1, INET_ADDRSTRLEN),
1705 inet_ntop (AF_INET, &lsa->data->id,
1706 buf2, INET_ADDRSTRLEN),
1707 inet_ntop (AF_INET, &lsa->data->adv_router,
1708 buf3, INET_ADDRSTRLEN));
1709 }
paul718e3742002-12-13 20:15:29 +00001710
1711 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1712
1713 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1714
1715 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1716
1717 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1718
1719 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1720
1721 /* Do take in Type-7's if we are an NSSA */
1722
1723 /* If we are also an ABR, later translate them to a Type-5 packet */
1724
1725 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1726 translate them to a separate Type-5 packet. */
1727
1728 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1729 /* Reject from STUB or NSSA */
1730 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1731 {
paul718e3742002-12-13 20:15:29 +00001732 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001733 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001734 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001735 }
1736
paul718e3742002-12-13 20:15:29 +00001737 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1738 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1739 {
paul718e3742002-12-13 20:15:29 +00001740 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001741 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
Paul Jakma2cd754d2010-01-14 16:26:12 +03001742 DISCARD_LSA (lsa,2);
paul718e3742002-12-13 20:15:29 +00001743 }
paul718e3742002-12-13 20:15:29 +00001744
1745 /* Find the LSA in the current database. */
1746
1747 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1748
1749 /* If the LSA's LS age is equal to MaxAge, and there is currently
1750 no instance of the LSA in the router's link state database,
1751 and none of router's neighbors are in states Exchange or Loading,
1752 then take the following actions. */
1753
1754 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001755 (ospf_nbr_count (oi, NSM_Exchange) +
1756 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001757 {
1758 /* Response Link State Acknowledgment. */
1759 ospf_ls_ack_send (nbr, lsa);
1760
1761 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001762 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1763 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001764 DISCARD_LSA (lsa, 3);
1765 }
1766
1767#ifdef HAVE_OPAQUE_LSA
1768 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001769 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001770 {
1771 /*
1772 * Even if initial flushing seems to be completed, there might
1773 * be a case that self-originated LSA with MaxAge still remain
1774 * in the routing domain.
1775 * Just send an LSAck message to cease retransmission.
1776 */
1777 if (IS_LSA_MAXAGE (lsa))
1778 {
1779 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1780 ospf_ls_ack_send (nbr, lsa);
1781 ospf_lsa_discard (lsa);
1782
1783 if (current != NULL && ! IS_LSA_MAXAGE (current))
1784 ospf_opaque_lsa_refresh_schedule (current);
1785 continue;
1786 }
1787
1788 /*
1789 * If an instance of self-originated Opaque-LSA is not found
1790 * in the LSDB, there are some possible cases here.
1791 *
1792 * 1) This node lost opaque-capability after restart.
1793 * 2) Else, a part of opaque-type is no more supported.
1794 * 3) Else, a part of opaque-id is no more supported.
1795 *
1796 * Anyway, it is still this node's responsibility to flush it.
1797 * Otherwise, the LSA instance remains in the routing domain
1798 * until its age reaches to MaxAge.
1799 */
paul69310a62005-05-11 18:09:59 +00001800 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001801 if (current == NULL)
1802 {
1803 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001804 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1805 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001806
1807 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001808
1809 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1810 ospf_ls_ack_send (nbr, lsa);
1811
paul718e3742002-12-13 20:15:29 +00001812 continue;
1813 }
1814 }
1815#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001816
hassocb05eb22004-02-11 21:10:19 +00001817 /* It might be happen that received LSA is self-originated network LSA, but
1818 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1819 * Link State ID is one of the router's own IP interface addresses but whose
1820 * Advertising Router is not equal to the router's own Router ID
1821 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1822 */
1823
1824 if(lsa->data->type == OSPF_NETWORK_LSA)
1825 {
paul1eb8ef22005-04-07 07:30:20 +00001826 struct listnode *oinode, *oinnode;
1827 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001828 int Flag = 0;
1829
paul1eb8ef22005-04-07 07:30:20 +00001830 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001831 {
hassocb05eb22004-02-11 21:10:19 +00001832 if(out_if == NULL)
1833 break;
1834
1835 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1836 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1837 {
1838 if(out_if->network_lsa_self)
1839 {
1840 ospf_lsa_flush_area(lsa,out_if->area);
1841 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001842 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001843 lsa, (int) lsa->data->type);
1844 ospf_lsa_discard (lsa);
1845 Flag = 1;
1846 }
1847 break;
1848 }
1849 }
1850 if(Flag)
1851 continue;
1852 }
paul718e3742002-12-13 20:15:29 +00001853
1854 /* (5) Find the instance of this LSA that is currently contained
1855 in the router's link state database. If there is no
1856 database copy, or the received LSA is more recent than
1857 the database copy the following steps must be performed. */
1858
1859 if (current == NULL ||
1860 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1861 {
1862 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001863 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001864 DISCARD_LSA (lsa, 4);
1865 continue;
1866 }
1867
1868 /* (6) Else, If there is an instance of the LSA on the sending
1869 neighbor's Link state request list, an error has occurred in
1870 the Database Exchange process. In this case, restart the
1871 Database Exchange process by generating the neighbor event
1872 BadLSReq for the sending neighbor and stop processing the
1873 Link State Update packet. */
1874
1875 if (ospf_ls_request_lookup (nbr, lsa))
1876 {
1877 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001878 zlog_warn("LSA[%s] instance exists on Link state request list",
1879 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001880
1881 /* Clean list of LSAs. */
1882 ospf_upd_list_clean (lsas);
1883 /* this lsa is not on lsas list already. */
1884 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001885 return;
1886 }
1887
1888 /* If the received LSA is the same instance as the database copy
1889 (i.e., neither one is more recent) the following two steps
1890 should be performed: */
1891
1892 if (ret == 0)
1893 {
1894 /* If the LSA is listed in the Link state retransmission list
1895 for the receiving adjacency, the router itself is expecting
1896 an acknowledgment for this LSA. The router should treat the
1897 received LSA as an acknowledgment by removing the LSA from
1898 the Link state retransmission list. This is termed an
1899 "implied acknowledgment". */
1900
1901 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1902
1903 if (ls_ret != NULL)
1904 {
1905 ospf_ls_retransmit_delete (nbr, ls_ret);
1906
1907 /* Delayed acknowledgment sent if advertisement received
1908 from Designated Router, otherwise do nothing. */
1909 if (oi->state == ISM_Backup)
1910 if (NBR_IS_DR (nbr))
1911 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1912
1913 DISCARD_LSA (lsa, 5);
1914 }
1915 else
1916 /* Acknowledge the receipt of the LSA by sending a
1917 Link State Acknowledgment packet back out the receiving
1918 interface. */
1919 {
1920 ospf_ls_ack_send (nbr, lsa);
1921 DISCARD_LSA (lsa, 6);
1922 }
1923 }
1924
1925 /* The database copy is more recent. If the database copy
1926 has LS age equal to MaxAge and LS sequence number equal to
1927 MaxSequenceNumber, simply discard the received LSA without
1928 acknowledging it. (In this case, the LSA's LS sequence number is
1929 wrapping, and the MaxSequenceNumber LSA must be completely
1930 flushed before any new LSA instance can be introduced). */
1931
1932 else if (ret > 0) /* Database copy is more recent */
1933 {
1934 if (IS_LSA_MAXAGE (current) &&
1935 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1936 {
1937 DISCARD_LSA (lsa, 7);
1938 }
1939 /* Otherwise, as long as the database copy has not been sent in a
1940 Link State Update within the last MinLSArrival seconds, send the
1941 database copy back to the sending neighbor, encapsulated within
1942 a Link State Update Packet. The Link State Update Packet should
1943 be sent directly to the neighbor. In so doing, do not put the
1944 database copy of the LSA on the neighbor's link state
1945 retransmission list, and do not acknowledge the received (less
1946 recent) LSA instance. */
1947 else
1948 {
1949 struct timeval now;
1950
Paul Jakma2518efd2006-08-27 06:49:29 +00001951 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001952
1953 if (tv_cmp (tv_sub (now, current->tv_orig),
1954 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1955 /* Trap NSSA type later.*/
1956 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1957 DISCARD_LSA (lsa, 8);
1958 }
1959 }
1960 }
Paul Jakma2cd754d2010-01-14 16:26:12 +03001961#undef DISCARD_LSA
1962
paul718e3742002-12-13 20:15:29 +00001963 assert (listcount (lsas) == 0);
1964 list_delete (lsas);
1965}
1966
1967/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001968static void
paul718e3742002-12-13 20:15:29 +00001969ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1970 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1971{
1972 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001973
paul718e3742002-12-13 20:15:29 +00001974 /* increment statistics. */
1975 oi->ls_ack_in++;
1976
pauld3f0d622004-05-05 15:27:15 +00001977 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001978 if (nbr == NULL)
1979 {
1980 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1981 inet_ntoa (ospfh->router_id));
1982 return;
1983 }
1984
1985 if (nbr->state < NSM_Exchange)
1986 {
ajs3aa8d5f2004-12-11 18:00:06 +00001987 zlog_warn ("Link State Acknowledgment: "
1988 "Neighbor[%s] state %s is less than Exchange",
1989 inet_ntoa (ospfh->router_id),
1990 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001991 return;
1992 }
paul69310a62005-05-11 18:09:59 +00001993
paul718e3742002-12-13 20:15:29 +00001994 while (size >= OSPF_LSA_HEADER_SIZE)
1995 {
1996 struct ospf_lsa *lsa, *lsr;
1997
1998 lsa = ospf_lsa_new ();
1999 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2000
2001 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2002 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002003 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002004
2005 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2006 {
2007 lsa->data = NULL;
2008 ospf_lsa_discard (lsa);
2009 continue;
2010 }
2011
2012 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2013
2014 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2015 {
2016#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002017 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002018 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002019#endif /* HAVE_OPAQUE_LSA */
2020
2021 ospf_ls_retransmit_delete (nbr, lsr);
2022 }
2023
2024 lsa->data = NULL;
2025 ospf_lsa_discard (lsa);
2026 }
2027
paul718e3742002-12-13 20:15:29 +00002028 return;
paul718e3742002-12-13 20:15:29 +00002029}
2030
ajs038163f2005-02-17 19:55:59 +00002031static struct stream *
ajs5c333492005-02-23 15:43:01 +00002032ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002033{
2034 int ret;
ajs5c333492005-02-23 15:43:01 +00002035 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002036 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002037 unsigned int ifindex = 0;
2038 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002039 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002040 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002041 struct msghdr msgh;
2042
paul68defd62004-09-27 07:27:13 +00002043 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002044 msgh.msg_iov = &iov;
2045 msgh.msg_iovlen = 1;
2046 msgh.msg_control = (caddr_t) buff;
2047 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002048
ajs5c333492005-02-23 15:43:01 +00002049 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2050 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002051 {
ajs5c333492005-02-23 15:43:01 +00002052 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2053 return NULL;
2054 }
paul69310a62005-05-11 18:09:59 +00002055 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002056 {
2057 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2058 "(ip header size is %u)",
2059 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002060 return NULL;
2061 }
paul18b12c32004-10-05 14:38:29 +00002062
ajs5c333492005-02-23 15:43:01 +00002063 /* Note that there should not be alignment problems with this assignment
2064 because this is at the beginning of the stream data buffer. */
2065 iph = (struct ip *) STREAM_DATA(ibuf);
2066 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002067
ajs5c333492005-02-23 15:43:01 +00002068 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002069
paul239aecc2003-12-08 10:34:54 +00002070#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002071 /*
2072 * Kernel network code touches incoming IP header parameters,
2073 * before protocol specific processing.
2074 *
2075 * 1) Convert byteorder to host representation.
2076 * --> ip_len, ip_id, ip_off
2077 *
2078 * 2) Adjust ip_len to strip IP header size!
2079 * --> If user process receives entire IP packet via RAW
2080 * socket, it must consider adding IP header size to
2081 * the "ip_len" field of "ip" structure.
2082 *
2083 * For more details, see <netinet/ip_input.c>.
2084 */
ajs5c333492005-02-23 15:43:01 +00002085 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002086#endif
2087
paul863082d2004-08-19 04:43:43 +00002088 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002089
2090 *ifp = if_lookup_by_index (ifindex);
2091
2092 if (ret != ip_len)
2093 {
ajs5c333492005-02-23 15:43:01 +00002094 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2095 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002096 return NULL;
2097 }
2098
2099 return ibuf;
2100}
2101
paul4dadc292005-05-06 21:37:42 +00002102static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002103ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002104 struct ip *iph, struct ospf_header *ospfh)
2105{
2106 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002107 struct ospf_vl_data *vl_data;
2108 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002109 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002110
2111 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2112 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002113 return NULL;
paul718e3742002-12-13 20:15:29 +00002114
pauld3f0d622004-05-05 15:27:15 +00002115 /* look for local OSPF interface matching the destination
2116 * to determine Area ID. We presume therefore the destination address
2117 * is unique, or at least (for "unnumbered" links), not used in other
2118 * areas
2119 */
2120 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2121 iph->ip_dst)) == NULL)
2122 return NULL;
paul718e3742002-12-13 20:15:29 +00002123
paul1eb8ef22005-04-07 07:30:20 +00002124 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002125 {
paul020709f2003-04-04 02:44:16 +00002126 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002127 if (!vl_area)
2128 continue;
2129
2130 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2131 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2132 {
2133 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002134 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002135 IF_NAME (vl_data->vl_oi));
2136 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2137 {
2138 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002139 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002140 return NULL;
2141 }
2142
2143 return vl_data->vl_oi;
2144 }
2145 }
2146
2147 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002148 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002149
pauld3f0d622004-05-05 15:27:15 +00002150 return NULL;
paul718e3742002-12-13 20:15:29 +00002151}
2152
paul4dadc292005-05-06 21:37:42 +00002153static inline int
paul718e3742002-12-13 20:15:29 +00002154ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2155{
2156 /* Check match the Area ID of the receiving interface. */
2157 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2158 return 1;
2159
2160 return 0;
2161}
2162
2163/* Unbound socket will accept any Raw IP packets if proto is matched.
2164 To prevent it, compare src IP address and i/f address with masking
2165 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002166static int
paul718e3742002-12-13 20:15:29 +00002167ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2168{
2169 struct in_addr mask, me, him;
2170
2171 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2172 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2173 return 1;
2174
2175 masklen2ip (oi->address->prefixlen, &mask);
2176
2177 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2178 him.s_addr = ip_src.s_addr & mask.s_addr;
2179
2180 if (IPV4_ADDR_SAME (&me, &him))
2181 return 1;
2182
2183 return 0;
2184}
2185
paul4dadc292005-05-06 21:37:42 +00002186static int
paul718e3742002-12-13 20:15:29 +00002187ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2188 struct ospf_header *ospfh)
2189{
2190 int ret = 0;
2191 struct crypt_key *ck;
2192
2193 switch (ntohs (ospfh->auth_type))
2194 {
2195 case OSPF_AUTH_NULL:
2196 ret = 1;
2197 break;
2198 case OSPF_AUTH_SIMPLE:
2199 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2200 ret = 1;
2201 else
2202 ret = 0;
2203 break;
2204 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002205 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002206 {
2207 ret = 0;
2208 break;
2209 }
2210
2211 /* This is very basic, the digest processing is elsewhere */
2212 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2213 ospfh->u.crypt.key_id == ck->key_id &&
2214 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2215 ret = 1;
2216 else
2217 ret = 0;
2218 break;
2219 default:
2220 ret = 0;
2221 break;
2222 }
2223
2224 return ret;
2225}
2226
paul4dadc292005-05-06 21:37:42 +00002227static int
paul718e3742002-12-13 20:15:29 +00002228ospf_check_sum (struct ospf_header *ospfh)
2229{
2230 u_int32_t ret;
2231 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002232
2233 /* clear auth_data for checksum. */
2234 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2235
2236 /* keep checksum and clear. */
2237 sum = ospfh->checksum;
2238 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2239
2240 /* calculate checksum. */
2241 ret = in_cksum (ospfh, ntohs (ospfh->length));
2242
2243 if (ret != sum)
2244 {
2245 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2246 ret, sum);
2247 return 0;
2248 }
2249
2250 return 1;
2251}
2252
2253/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002254static int
paul718e3742002-12-13 20:15:29 +00002255ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2256 struct ip *iph, struct ospf_header *ospfh)
2257{
2258 /* check version. */
2259 if (ospfh->version != OSPF_VERSION)
2260 {
2261 zlog_warn ("interface %s: ospf_read version number mismatch.",
2262 IF_NAME (oi));
2263 return -1;
2264 }
2265
Denis Ovsienko1f54cef2011-09-26 13:18:02 +04002266 /* Valid OSPFv2 packet types are 1 through 5 inclusive. */
2267 if (ospfh->type < 1 || ospfh->type > 5)
2268 {
2269 zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type);
2270 return -1;
2271 }
2272
paul718e3742002-12-13 20:15:29 +00002273 /* Check Area ID. */
2274 if (!ospf_check_area_id (oi, ospfh))
2275 {
2276 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2277 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2278 return -1;
2279 }
2280
2281 /* Check network mask, Silently discarded. */
2282 if (! ospf_check_network_mask (oi, iph->ip_src))
2283 {
2284 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2285 IF_NAME (oi), inet_ntoa (iph->ip_src));
2286 return -1;
2287 }
2288
2289 /* Check authentication. */
2290 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2291 {
paulc6371712006-01-17 17:49:53 +00002292 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2293 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002294 return -1;
2295 }
2296
2297 if (! ospf_check_auth (oi, ibuf, ospfh))
2298 {
2299 zlog_warn ("interface %s: ospf_read authentication failed.",
2300 IF_NAME (oi));
2301 return -1;
2302 }
2303
2304 /* if check sum is invalid, packet is discarded. */
2305 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2306 {
2307 if (! ospf_check_sum (ospfh))
2308 {
2309 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2310 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2311 return -1;
2312 }
2313 }
2314 else
2315 {
2316 if (ospfh->checksum != 0)
2317 return -1;
2318 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2319 {
2320 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2321 IF_NAME (oi));
2322 return -1;
2323 }
2324 }
2325
2326 return 0;
2327}
2328
2329/* Starting point of packet process function. */
2330int
2331ospf_read (struct thread *thread)
2332{
2333 int ret;
2334 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002335 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002336 struct ospf_interface *oi;
2337 struct ip *iph;
2338 struct ospf_header *ospfh;
2339 u_int16_t length;
2340 struct interface *ifp;
2341
2342 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002343 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002344
2345 /* prepare for next packet. */
2346 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002347
2348 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002349 stream_reset(ospf->ibuf);
2350 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002351 return -1;
2352
ajs5c333492005-02-23 15:43:01 +00002353 /* Note that there should not be alignment problems with this assignment
2354 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002355 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002356 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002357
paulac191232004-10-22 12:05:17 +00002358 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002359 /* Handle cases where the platform does not support retrieving the ifindex,
2360 and also platforms (such as Solaris 8) that claim to support ifindex
2361 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002362 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002363
pauld3f0d622004-05-05 15:27:15 +00002364 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002365 return 0;
paul718e3742002-12-13 20:15:29 +00002366
2367 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002368 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002369 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002370
paul718e3742002-12-13 20:15:29 +00002371 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002372 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002373 {
pauld3241812003-09-29 12:42:39 +00002374 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2375 {
ajs2a42e282004-12-08 18:43:03 +00002376 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002377 inet_ntoa (iph->ip_src));
2378 }
paul718e3742002-12-13 20:15:29 +00002379 return 0;
2380 }
2381
Denis Ovsienko3d3380d2011-09-26 13:17:52 +04002382 /* Advance from IP header to OSPF header (iph->ip_hl has been verified
2383 by ospf_recv_packet() to be correct). */
paul9985f832005-02-09 15:51:56 +00002384 stream_forward_getp (ibuf, iph->ip_hl * 4);
Denis Ovsienko3d3380d2011-09-26 13:17:52 +04002385
2386 /* Make sure the OSPF header is really there. */
2387 if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE)
2388 {
2389 zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header",
2390 stream_get_endp (ibuf) - stream_get_getp (ibuf));
2391 return -1;
2392 }
2393
2394 /* Now it is safe to access all fields of OSPF packet header. */
paul718e3742002-12-13 20:15:29 +00002395 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2396
2397 /* associate packet with ospf interface */
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002398 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);
pauld3f0d622004-05-05 15:27:15 +00002399
YAMAMOTO Shigeru992d4d12011-09-28 21:00:14 +04002400 /* ospf_verify_header() relies on a valid "oi" and thus can be called only
2401 after the passive/backbone/other checks below are passed. These checks
2402 in turn access the fields of unverified "ospfh" structure for their own
2403 purposes and must remain very accurate in doing this. */
Denis Ovsienko1f54cef2011-09-26 13:18:02 +04002404
Joakim Tjernlund491eddc2008-09-24 17:03:59 +01002405 /* If incoming interface is passive one, ignore it. */
2406 if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
2407 {
2408 char buf[3][INET_ADDRSTRLEN];
2409
2410 if (IS_DEBUG_OSPF_EVENT)
2411 zlog_debug ("ignoring packet from router %s sent to %s, "
2412 "received on a passive interface, %s",
2413 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
2414 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2415 inet_ntop(AF_INET, &oi->address->u.prefix4,
2416 buf[2], sizeof(buf[2])));
2417
2418 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2419 {
2420 /* Try to fix multicast membership.
2421 * Some OS:es may have problems in this area,
2422 * make sure it is removed.
2423 */
2424 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
2425 ospf_if_set_multicast(oi);
2426 }
2427 return 0;
2428 }
2429
2430
pauld3f0d622004-05-05 15:27:15 +00002431 /* if no local ospf_interface,
2432 * or header area is backbone but ospf_interface is not
2433 * check for VLINK interface
2434 */
2435 if ( (oi == NULL) ||
2436 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2437 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2438 )
2439 {
2440 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2441 {
Paul Jakma88871b12006-06-15 11:41:19 +00002442 if (IS_DEBUG_OSPF_EVENT)
2443 zlog_debug ("Packet from [%s] received on link %s"
2444 " but no ospf_interface",
2445 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002446 return 0;
2447 }
2448 }
Joakim Tjernlund05cf46b2009-07-27 12:42:30 +02002449
pauld3f0d622004-05-05 15:27:15 +00002450 /* else it must be a local ospf interface, check it was received on
2451 * correct link
2452 */
2453 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002454 {
Paul Jakma11637432009-08-11 12:25:42 +01002455 if (IS_DEBUG_OSPF_EVENT)
2456 zlog_warn ("Packet from [%s] received on wrong link %s",
2457 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002458 return 0;
2459 }
ajs847947f2005-02-02 18:38:48 +00002460 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002461 {
ajsba6454e2005-02-08 15:37:30 +00002462 char buf[2][INET_ADDRSTRLEN];
2463 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002464 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002465 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2466 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2467 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002468 /* Fix multicast memberships? */
2469 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002470 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002471 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002472 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002473 if (oi->multicast_memberships)
2474 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002475 return 0;
2476 }
paul718e3742002-12-13 20:15:29 +00002477
2478 /*
2479 * If the received packet is destined for AllDRouters, the packet
2480 * should be accepted only if the received ospf interface state is
2481 * either DR or Backup -- endo.
2482 */
2483 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2484 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2485 {
ajsba6454e2005-02-08 15:37:30 +00002486 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002487 inet_ntoa (iph->ip_src), IF_NAME (oi),
2488 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002489 /* Try to fix multicast membership. */
2490 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2491 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002492 return 0;
2493 }
2494
YAMAMOTO Shigeru992d4d12011-09-28 21:00:14 +04002495 /* Verify more OSPF header fields. */
2496 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2497 if (ret < 0)
2498 {
2499 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2500 zlog_debug ("ospf_read[%s]: Header check failed, "
2501 "dropping.",
2502 inet_ntoa (iph->ip_src));
2503 return ret;
2504 }
2505
paul718e3742002-12-13 20:15:29 +00002506 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002507 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2508 {
paul718e3742002-12-13 20:15:29 +00002509 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002510 {
ajs2a42e282004-12-08 18:43:03 +00002511 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002512 ospf_packet_dump (ibuf);
2513 }
paul718e3742002-12-13 20:15:29 +00002514
ajs2a42e282004-12-08 18:43:03 +00002515 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002516 ospf_packet_type_str[ospfh->type],
2517 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002518 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2519 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002520
2521 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002522 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002523 }
paul718e3742002-12-13 20:15:29 +00002524
paul9985f832005-02-09 15:51:56 +00002525 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002526
2527 /* Adjust size to message length. */
2528 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2529
2530 /* Read rest of the packet and call each sort of packet routine. */
2531 switch (ospfh->type)
2532 {
2533 case OSPF_MSG_HELLO:
2534 ospf_hello (iph, ospfh, ibuf, oi, length);
2535 break;
2536 case OSPF_MSG_DB_DESC:
2537 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2538 break;
2539 case OSPF_MSG_LS_REQ:
2540 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2541 break;
2542 case OSPF_MSG_LS_UPD:
2543 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2544 break;
2545 case OSPF_MSG_LS_ACK:
2546 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2547 break;
2548 default:
2549 zlog (NULL, LOG_WARNING,
2550 "interface %s: OSPF packet header type %d is illegal",
2551 IF_NAME (oi), ospfh->type);
2552 break;
2553 }
2554
paul718e3742002-12-13 20:15:29 +00002555 return 0;
2556}
2557
2558/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002559static void
paul718e3742002-12-13 20:15:29 +00002560ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2561{
2562 struct ospf_header *ospfh;
2563
2564 ospfh = (struct ospf_header *) STREAM_DATA (s);
2565
2566 ospfh->version = (u_char) OSPF_VERSION;
2567 ospfh->type = (u_char) type;
2568
paul68980082003-03-25 05:07:42 +00002569 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002570
2571 ospfh->checksum = 0;
2572 ospfh->area_id = oi->area->area_id;
2573 ospfh->auth_type = htons (ospf_auth_type (oi));
2574
2575 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2576
paul9985f832005-02-09 15:51:56 +00002577 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002578}
2579
2580/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002581static int
paul718e3742002-12-13 20:15:29 +00002582ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2583{
2584 struct crypt_key *ck;
2585
2586 switch (ospf_auth_type (oi))
2587 {
2588 case OSPF_AUTH_NULL:
2589 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2590 break;
2591 case OSPF_AUTH_SIMPLE:
2592 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2593 OSPF_AUTH_SIMPLE_SIZE);
2594 break;
2595 case OSPF_AUTH_CRYPTOGRAPHIC:
2596 /* If key is not set, then set 0. */
2597 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2598 {
2599 ospfh->u.crypt.zero = 0;
2600 ospfh->u.crypt.key_id = 0;
2601 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2602 }
2603 else
2604 {
paul1eb8ef22005-04-07 07:30:20 +00002605 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002606 ospfh->u.crypt.zero = 0;
2607 ospfh->u.crypt.key_id = ck->key_id;
2608 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2609 }
2610 /* note: the seq is done in ospf_make_md5_digest() */
2611 break;
2612 default:
2613 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2614 break;
2615 }
2616
2617 return 0;
2618}
2619
2620/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002621static void
paul718e3742002-12-13 20:15:29 +00002622ospf_fill_header (struct ospf_interface *oi,
2623 struct stream *s, u_int16_t length)
2624{
2625 struct ospf_header *ospfh;
2626
2627 ospfh = (struct ospf_header *) STREAM_DATA (s);
2628
2629 /* Fill length. */
2630 ospfh->length = htons (length);
2631
2632 /* Calculate checksum. */
2633 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2634 ospfh->checksum = in_cksum (ospfh, length);
2635 else
2636 ospfh->checksum = 0;
2637
2638 /* Add Authentication Data. */
2639 ospf_make_auth (oi, ospfh);
2640}
2641
paul4dadc292005-05-06 21:37:42 +00002642static int
paul718e3742002-12-13 20:15:29 +00002643ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2644{
2645 struct ospf_neighbor *nbr;
2646 struct route_node *rn;
2647 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2648 struct in_addr mask;
2649 unsigned long p;
2650 int flag = 0;
2651
2652 /* Set netmask of interface. */
2653 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2654 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2655 masklen2ip (oi->address->prefixlen, &mask);
2656 else
2657 memset ((char *) &mask, 0, sizeof (struct in_addr));
2658 stream_put_ipv4 (s, mask.s_addr);
2659
2660 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002661 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2662 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2663 else
2664 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002665
2666 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002667 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002668 OPTIONS(oi), IF_NAME (oi));
2669
2670 /* Set Options. */
2671 stream_putc (s, OPTIONS (oi));
2672
2673 /* Set Router Priority. */
2674 stream_putc (s, PRIORITY (oi));
2675
2676 /* Set Router Dead Interval. */
2677 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2678
2679 /* Set Designated Router. */
2680 stream_put_ipv4 (s, DR (oi).s_addr);
2681
paul9985f832005-02-09 15:51:56 +00002682 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002683
2684 /* Set Backup Designated Router. */
2685 stream_put_ipv4 (s, BDR (oi).s_addr);
2686
2687 /* Add neighbor seen. */
2688 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002689 if ((nbr = rn->info))
2690 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2691 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2692 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2693 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002694 {
2695 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002696 if (nbr->d_router.s_addr != 0
2697 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2698 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2699 flag = 1;
paul718e3742002-12-13 20:15:29 +00002700
2701 stream_put_ipv4 (s, nbr->router_id.s_addr);
2702 length += 4;
2703 }
2704
2705 /* Let neighbor generate BackupSeen. */
2706 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002707 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002708
2709 return length;
2710}
2711
paul4dadc292005-05-06 21:37:42 +00002712static int
paul718e3742002-12-13 20:15:29 +00002713ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2714 struct stream *s)
2715{
2716 struct ospf_lsa *lsa;
2717 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2718 u_char options;
2719 unsigned long pp;
2720 int i;
2721 struct ospf_lsdb *lsdb;
2722
2723 /* Set Interface MTU. */
2724 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2725 stream_putw (s, 0);
2726 else
2727 stream_putw (s, oi->ifp->mtu);
2728
2729 /* Set Options. */
2730 options = OPTIONS (oi);
2731#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002732 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002733 {
2734 if (IS_SET_DD_I (nbr->dd_flags)
2735 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2736 /*
2737 * Set O-bit in the outgoing DD packet for capablity negotiation,
2738 * if one of following case is applicable.
2739 *
2740 * 1) WaitTimer expiration event triggered the neighbor state to
2741 * change to Exstart, but no (valid) DD packet has received
2742 * from the neighbor yet.
2743 *
2744 * 2) At least one DD packet with O-bit on has received from the
2745 * neighbor.
2746 */
2747 SET_FLAG (options, OSPF_OPTION_O);
2748 }
2749#endif /* HAVE_OPAQUE_LSA */
2750 stream_putc (s, options);
2751
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002752 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002753 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002754 stream_putc (s, nbr->dd_flags);
2755
2756 /* Set DD Sequence Number. */
2757 stream_putl (s, nbr->dd_seqnum);
2758
Paul Jakmab5aeb442006-08-30 18:47:37 +00002759 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002760 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002761 goto empty;
paul718e3742002-12-13 20:15:29 +00002762
2763 /* Describe LSA Header from Database Summary List. */
2764 lsdb = &nbr->db_sum;
2765
2766 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2767 {
2768 struct route_table *table = lsdb->type[i].db;
2769 struct route_node *rn;
2770
2771 for (rn = route_top (table); rn; rn = route_next (rn))
2772 if ((lsa = rn->info) != NULL)
2773 {
2774#ifdef HAVE_OPAQUE_LSA
2775 if (IS_OPAQUE_LSA (lsa->data->type)
2776 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2777 {
2778 /* Suppress advertising opaque-informations. */
2779 /* Remove LSA from DB summary list. */
2780 ospf_lsdb_delete (lsdb, lsa);
2781 continue;
2782 }
2783#endif /* HAVE_OPAQUE_LSA */
2784
2785 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2786 {
2787 struct lsa_header *lsah;
2788 u_int16_t ls_age;
2789
2790 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002791 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002792 break;
2793
2794 /* Keep pointer to LS age. */
2795 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002796 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002797
2798 /* Proceed stream pointer. */
2799 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2800 length += OSPF_LSA_HEADER_SIZE;
2801
2802 /* Set LS age. */
2803 ls_age = LS_AGE (lsa);
2804 lsah->ls_age = htons (ls_age);
2805
2806 }
2807
2808 /* Remove LSA from DB summary list. */
2809 ospf_lsdb_delete (lsdb, lsa);
2810 }
2811 }
2812
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002813 /* Update 'More' bit */
2814 if (ospf_db_summary_isempty (nbr))
2815 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002816empty:
2817 if (nbr->state >= NSM_Exchange)
2818 {
2819 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2820 /* Rewrite DD flags */
2821 stream_putc_at (s, pp, nbr->dd_flags);
2822 }
2823 else
2824 {
2825 assert (IS_SET_DD_M(nbr->dd_flags));
2826 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002827 }
paul718e3742002-12-13 20:15:29 +00002828 return length;
2829}
2830
paul4dadc292005-05-06 21:37:42 +00002831static int
paul718e3742002-12-13 20:15:29 +00002832ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2833 unsigned long delta, struct ospf_neighbor *nbr,
2834 struct ospf_lsa *lsa)
2835{
2836 struct ospf_interface *oi;
2837
2838 oi = nbr->oi;
2839
2840 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002841 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002842 return 0;
2843
2844 stream_putl (s, lsa->data->type);
2845 stream_put_ipv4 (s, lsa->data->id.s_addr);
2846 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2847
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002848 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002849 nbr->ls_req_last = ospf_lsa_lock (lsa);
2850
2851 *length += 12;
2852 return 1;
2853}
2854
paul4dadc292005-05-06 21:37:42 +00002855static int
paul718e3742002-12-13 20:15:29 +00002856ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2857{
2858 struct ospf_lsa *lsa;
2859 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002860 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002861 struct route_table *table;
2862 struct route_node *rn;
2863 int i;
2864 struct ospf_lsdb *lsdb;
2865
2866 lsdb = &nbr->ls_req;
2867
2868 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2869 {
2870 table = lsdb->type[i].db;
2871 for (rn = route_top (table); rn; rn = route_next (rn))
2872 if ((lsa = (rn->info)) != NULL)
2873 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2874 {
2875 route_unlock_node (rn);
2876 break;
2877 }
2878 }
2879 return length;
2880}
2881
paul4dadc292005-05-06 21:37:42 +00002882static int
paul718e3742002-12-13 20:15:29 +00002883ls_age_increment (struct ospf_lsa *lsa, int delay)
2884{
2885 int age;
2886
2887 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2888
2889 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2890}
2891
paul4dadc292005-05-06 21:37:42 +00002892static int
hasso52dc7ee2004-09-23 19:18:23 +00002893ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002894{
2895 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002896 struct listnode *node;
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002897 u_int16_t length = 0;
gdt86f1fd92005-01-10 14:20:43 +00002898 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002899 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002900 unsigned long pp;
2901 int count = 0;
2902
2903 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002904 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002905
paul9985f832005-02-09 15:51:56 +00002906 pp = stream_get_endp (s);
2907 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04002908 length += OSPF_LS_UPD_MIN_SIZE;
paul718e3742002-12-13 20:15:29 +00002909
gdt86f1fd92005-01-10 14:20:43 +00002910 /* Calculate amount of packet usable for data. */
2911 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2912
paul718e3742002-12-13 20:15:29 +00002913 while ((node = listhead (update)) != NULL)
2914 {
2915 struct lsa_header *lsah;
2916 u_int16_t ls_age;
2917
2918 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002919 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002920
paul1eb8ef22005-04-07 07:30:20 +00002921 lsa = listgetdata (node);
2922
paul718e3742002-12-13 20:15:29 +00002923 assert (lsa->data);
2924
paul68b73392004-09-12 14:21:37 +00002925 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002926 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002927 break;
2928
paul718e3742002-12-13 20:15:29 +00002929 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002930 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002931
2932 /* Put LSA to Link State Request. */
2933 stream_put (s, lsa->data, ntohs (lsa->data->length));
2934
2935 /* Set LS age. */
2936 /* each hop must increment an lsa_age by transmit_delay
2937 of OSPF interface */
2938 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2939 lsah->ls_age = htons (ls_age);
2940
2941 length += ntohs (lsa->data->length);
2942 count++;
2943
2944 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002945 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002946 }
2947
2948 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002949 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002950
2951 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002952 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002953 return length;
2954}
2955
paul4dadc292005-05-06 21:37:42 +00002956static int
hasso52dc7ee2004-09-23 19:18:23 +00002957ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002958{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002959 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002960 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002961 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002962 struct ospf_lsa *lsa;
2963
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002964 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002965 {
paul718e3742002-12-13 20:15:29 +00002966 assert (lsa);
2967
gdt86f1fd92005-01-10 14:20:43 +00002968 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002969 break;
2970
2971 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2972 length += OSPF_LSA_HEADER_SIZE;
2973
paul718e3742002-12-13 20:15:29 +00002974 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002975 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002976 }
2977
paul718e3742002-12-13 20:15:29 +00002978 return length;
2979}
2980
2981void
2982ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2983{
2984 struct ospf_packet *op;
2985 u_int16_t length = OSPF_HEADER_SIZE;
2986
2987 op = ospf_packet_new (oi->ifp->mtu);
2988
2989 /* Prepare OSPF common header. */
2990 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2991
2992 /* Prepare OSPF Hello body. */
2993 length += ospf_make_hello (oi, op->s);
2994
2995 /* Fill OSPF header. */
2996 ospf_fill_header (oi, op->s, length);
2997
2998 /* Set packet length. */
2999 op->length = length;
3000
3001 op->dst.s_addr = addr->s_addr;
3002
3003 /* Add packet to the interface output queue. */
3004 ospf_packet_add (oi, op);
3005
3006 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003007 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003008}
3009
paul4dadc292005-05-06 21:37:42 +00003010static void
paul718e3742002-12-13 20:15:29 +00003011ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
3012{
3013 struct ospf_interface *oi;
3014
3015 oi = nbr_nbma->oi;
3016 assert(oi);
3017
3018 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003019 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003020 return;
3021
3022 if (oi->type != OSPF_IFTYPE_NBMA)
3023 return;
3024
3025 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
3026 return;
3027
3028 if (PRIORITY(oi) == 0)
3029 return;
3030
3031 if (nbr_nbma->priority == 0
3032 && oi->state != ISM_DR && oi->state != ISM_Backup)
3033 return;
3034
3035 ospf_hello_send_sub (oi, &nbr_nbma->addr);
3036}
3037
3038int
3039ospf_poll_timer (struct thread *thread)
3040{
3041 struct ospf_nbr_nbma *nbr_nbma;
3042
3043 nbr_nbma = THREAD_ARG (thread);
3044 nbr_nbma->t_poll = NULL;
3045
3046 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003047 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003048 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3049
3050 ospf_poll_send (nbr_nbma);
3051
3052 if (nbr_nbma->v_poll > 0)
3053 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3054 nbr_nbma->v_poll);
3055
3056 return 0;
3057}
3058
3059
3060int
3061ospf_hello_reply_timer (struct thread *thread)
3062{
3063 struct ospf_neighbor *nbr;
3064
3065 nbr = THREAD_ARG (thread);
3066 nbr->t_hello_reply = NULL;
3067
3068 assert (nbr->oi);
3069
3070 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003071 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003072 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3073
3074 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3075
3076 return 0;
3077}
3078
3079/* Send OSPF Hello. */
3080void
3081ospf_hello_send (struct ospf_interface *oi)
3082{
3083 struct ospf_packet *op;
3084 u_int16_t length = OSPF_HEADER_SIZE;
3085
3086 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003087 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003088 return;
3089
3090 op = ospf_packet_new (oi->ifp->mtu);
3091
3092 /* Prepare OSPF common header. */
3093 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3094
3095 /* Prepare OSPF Hello body. */
3096 length += ospf_make_hello (oi, op->s);
3097
3098 /* Fill OSPF header. */
3099 ospf_fill_header (oi, op->s, length);
3100
3101 /* Set packet length. */
3102 op->length = length;
3103
3104 if (oi->type == OSPF_IFTYPE_NBMA)
3105 {
3106 struct ospf_neighbor *nbr;
3107 struct route_node *rn;
3108
3109 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3110 if ((nbr = rn->info))
3111 if (nbr != oi->nbr_self)
3112 if (nbr->state != NSM_Down)
3113 {
3114 /* RFC 2328 Section 9.5.1
3115 If the router is not eligible to become Designated Router,
3116 it must periodically send Hello Packets to both the
3117 Designated Router and the Backup Designated Router (if they
3118 exist). */
3119 if (PRIORITY(oi) == 0 &&
3120 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3121 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3122 continue;
3123
3124 /* If the router is eligible to become Designated Router, it
3125 must periodically send Hello Packets to all neighbors that
3126 are also eligible. In addition, if the router is itself the
3127 Designated Router or Backup Designated Router, it must also
3128 send periodic Hello Packets to all other neighbors. */
3129
3130 if (nbr->priority == 0 && oi->state == ISM_DROther)
3131 continue;
3132 /* if oi->state == Waiting, send hello to all neighbors */
3133 {
3134 struct ospf_packet *op_dup;
3135
3136 op_dup = ospf_packet_dup(op);
3137 op_dup->dst = nbr->address.u.prefix4;
3138
3139 /* Add packet to the interface output queue. */
3140 ospf_packet_add (oi, op_dup);
3141
paul020709f2003-04-04 02:44:16 +00003142 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003143 }
3144
3145 }
3146 ospf_packet_free (op);
3147 }
3148 else
3149 {
3150 /* Decide destination address. */
3151 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3152 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3153 else
3154 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3155
3156 /* Add packet to the interface output queue. */
3157 ospf_packet_add (oi, op);
3158
3159 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003160 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003161 }
3162}
3163
3164/* Send OSPF Database Description. */
3165void
3166ospf_db_desc_send (struct ospf_neighbor *nbr)
3167{
3168 struct ospf_interface *oi;
3169 struct ospf_packet *op;
3170 u_int16_t length = OSPF_HEADER_SIZE;
3171
3172 oi = nbr->oi;
3173 op = ospf_packet_new (oi->ifp->mtu);
3174
3175 /* Prepare OSPF common header. */
3176 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3177
3178 /* Prepare OSPF Database Description body. */
3179 length += ospf_make_db_desc (oi, nbr, op->s);
3180
3181 /* Fill OSPF header. */
3182 ospf_fill_header (oi, op->s, length);
3183
3184 /* Set packet length. */
3185 op->length = length;
3186
3187 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003188 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3189 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3190 else
3191 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003192
3193 /* Add packet to the interface output queue. */
3194 ospf_packet_add (oi, op);
3195
3196 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003197 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003198
3199 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3200 if (nbr->last_send)
3201 ospf_packet_free (nbr->last_send);
3202 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003203 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003204}
3205
3206/* Re-send Database Description. */
3207void
3208ospf_db_desc_resend (struct ospf_neighbor *nbr)
3209{
3210 struct ospf_interface *oi;
3211
3212 oi = nbr->oi;
3213
3214 /* Add packet to the interface output queue. */
3215 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3216
3217 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003218 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003219}
3220
3221/* Send Link State Request. */
3222void
3223ospf_ls_req_send (struct ospf_neighbor *nbr)
3224{
3225 struct ospf_interface *oi;
3226 struct ospf_packet *op;
3227 u_int16_t length = OSPF_HEADER_SIZE;
3228
3229 oi = nbr->oi;
3230 op = ospf_packet_new (oi->ifp->mtu);
3231
3232 /* Prepare OSPF common header. */
3233 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3234
3235 /* Prepare OSPF Link State Request body. */
3236 length += ospf_make_ls_req (nbr, op->s);
3237 if (length == OSPF_HEADER_SIZE)
3238 {
3239 ospf_packet_free (op);
3240 return;
3241 }
3242
3243 /* Fill OSPF header. */
3244 ospf_fill_header (oi, op->s, length);
3245
3246 /* Set packet length. */
3247 op->length = length;
3248
3249 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003250 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3251 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3252 else
3253 op->dst = nbr->address.u.prefix4;
paul718e3742002-12-13 20:15:29 +00003254
3255 /* Add packet to the interface output queue. */
3256 ospf_packet_add (oi, op);
3257
3258 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003259 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003260
3261 /* Add Link State Request Retransmission Timer. */
3262 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3263}
3264
3265/* Send Link State Update with an LSA. */
3266void
3267ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3268 int flag)
3269{
hasso52dc7ee2004-09-23 19:18:23 +00003270 struct list *update;
paul718e3742002-12-13 20:15:29 +00003271
3272 update = list_new ();
3273
3274 listnode_add (update, lsa);
3275 ospf_ls_upd_send (nbr, update, flag);
3276
3277 list_delete (update);
3278}
3279
paul68b73392004-09-12 14:21:37 +00003280/* Determine size for packet. Must be at least big enough to accomodate next
3281 * LSA on list, which may be bigger than MTU size.
3282 *
3283 * Return pointer to new ospf_packet
3284 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3285 * on packet sizes (in which case offending LSA is deleted from update list)
3286 */
3287static struct ospf_packet *
3288ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3289{
3290 struct ospf_lsa *lsa;
3291 struct listnode *ln;
3292 size_t size;
3293 static char warned = 0;
3294
paul1eb8ef22005-04-07 07:30:20 +00003295 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003296 assert (lsa->data);
3297
3298 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3299 > ospf_packet_max (oi))
3300 {
3301 if (!warned)
3302 {
3303 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3304 "will need to fragment. Not optimal. Try divide up"
3305 " your network with areas. Use 'debug ospf packet send'"
3306 " to see details, or look at 'show ip ospf database ..'");
3307 warned = 1;
3308 }
3309
3310 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003311 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003312 " %d bytes originated by %s, will be fragmented!",
3313 inet_ntoa (lsa->data->id),
3314 ntohs (lsa->data->length),
3315 inet_ntoa (lsa->data->adv_router));
3316
3317 /*
3318 * Allocate just enough to fit this LSA only, to avoid including other
3319 * LSAs in fragmented LSA Updates.
3320 */
3321 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3322 + OSPF_LS_UPD_MIN_SIZE;
3323 }
3324 else
3325 size = oi->ifp->mtu;
3326
3327 if (size > OSPF_MAX_PACKET_SIZE)
3328 {
3329 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003330 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003331 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003332 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003333 (long int) size);
paul68b73392004-09-12 14:21:37 +00003334 list_delete_node (update, ln);
3335 return NULL;
3336 }
3337
Dmitry Tejblumc9035cc2009-06-24 20:14:30 +04003338 /* IP header is built up separately by ospf_write(). This means, that we must
3339 * reduce the "affordable" size just calculated by length of an IP header.
3340 * This makes sure, that even if we manage to fill the payload with LSA data
3341 * completely, the final packet (our data plus IP header) still fits into
3342 * outgoing interface MTU. This correction isn't really meaningful for an
3343 * oversized LSA, but for consistency the correction is done for both cases.
3344 *
3345 * P.S. OSPF_MAX_PACKET_SIZE above already includes IP header size
3346 */
3347 return ospf_packet_new (size - sizeof (struct ip));
paul68b73392004-09-12 14:21:37 +00003348}
3349
paul718e3742002-12-13 20:15:29 +00003350static void
hasso52dc7ee2004-09-23 19:18:23 +00003351ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003352 struct in_addr addr)
3353{
3354 struct ospf_packet *op;
3355 u_int16_t length = OSPF_HEADER_SIZE;
3356
3357 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003358 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003359
3360 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003361
3362 /* Prepare OSPF common header. */
3363 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3364
paul59ea14c2004-07-14 20:50:36 +00003365 /* Prepare OSPF Link State Update body.
3366 * Includes Type-7 translation.
3367 */
paul718e3742002-12-13 20:15:29 +00003368 length += ospf_make_ls_upd (oi, update, op->s);
3369
3370 /* Fill OSPF header. */
3371 ospf_fill_header (oi, op->s, length);
3372
3373 /* Set packet length. */
3374 op->length = length;
3375
3376 /* Decide destination address. */
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003377 if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3378 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3379 else
3380 op->dst.s_addr = addr.s_addr;
paul718e3742002-12-13 20:15:29 +00003381
3382 /* Add packet to the interface output queue. */
3383 ospf_packet_add (oi, op);
3384
3385 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003386 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003387}
3388
3389static int
3390ospf_ls_upd_send_queue_event (struct thread *thread)
3391{
3392 struct ospf_interface *oi = THREAD_ARG(thread);
3393 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003394 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003395 struct list *update;
paul68b73392004-09-12 14:21:37 +00003396 char again = 0;
paul718e3742002-12-13 20:15:29 +00003397
3398 oi->t_ls_upd_event = NULL;
3399
3400 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003401 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003402
paul736d3442003-07-24 23:22:57 +00003403 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003404 {
paul736d3442003-07-24 23:22:57 +00003405 rnext = route_next (rn);
3406
paul718e3742002-12-13 20:15:29 +00003407 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003408 continue;
paul68b73392004-09-12 14:21:37 +00003409
3410 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003411
paul48fe13b2004-07-27 17:40:44 +00003412 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003413
paul68b73392004-09-12 14:21:37 +00003414 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003415 if (listcount(update) == 0)
3416 {
3417 list_delete (rn->info);
3418 rn->info = NULL;
3419 route_unlock_node (rn);
3420 }
3421 else
paul68b73392004-09-12 14:21:37 +00003422 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003423 }
3424
3425 if (again != 0)
3426 {
3427 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003428 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003429 " %d nodes to try again, raising new event", again);
3430 oi->t_ls_upd_event =
3431 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003432 }
3433
3434 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003435 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003436
paul718e3742002-12-13 20:15:29 +00003437 return 0;
3438}
3439
3440void
hasso52dc7ee2004-09-23 19:18:23 +00003441ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003442{
3443 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003444 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003445 struct prefix_ipv4 p;
3446 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003447 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003448
3449 oi = nbr->oi;
3450
3451 p.family = AF_INET;
3452 p.prefixlen = IPV4_MAX_BITLEN;
3453
3454 /* Decide destination address. */
3455 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3456 p.prefix = oi->vl_data->peer_addr;
Joakim Tjernlund53d0dec2008-05-30 16:04:39 +02003457 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3458 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003459 else if (flag == OSPF_SEND_PACKET_DIRECT)
3460 p.prefix = nbr->address.u.prefix4;
3461 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3462 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003463 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3464 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003465 else
3466 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3467
3468 if (oi->type == OSPF_IFTYPE_NBMA)
3469 {
3470 if (flag == OSPF_SEND_PACKET_INDIRECT)
3471 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3472 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3473 zlog_warn ("* LS-Update is sent to myself.");
3474 }
3475
3476 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3477
3478 if (rn->info == NULL)
3479 rn->info = list_new ();
3480
paul1eb8ef22005-04-07 07:30:20 +00003481 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003482 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003483
3484 if (oi->t_ls_upd_event == NULL)
3485 oi->t_ls_upd_event =
3486 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3487}
3488
3489static void
hasso52dc7ee2004-09-23 19:18:23 +00003490ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3491 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003492{
3493 struct ospf_packet *op;
3494 u_int16_t length = OSPF_HEADER_SIZE;
3495
3496 op = ospf_packet_new (oi->ifp->mtu);
3497
3498 /* Prepare OSPF common header. */
3499 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3500
3501 /* Prepare OSPF Link State Acknowledgment body. */
3502 length += ospf_make_ls_ack (oi, ack, op->s);
3503
3504 /* Fill OSPF header. */
3505 ospf_fill_header (oi, op->s, length);
3506
3507 /* Set packet length. */
3508 op->length = length;
3509
3510 /* Set destination IP address. */
3511 op->dst = dst;
3512
3513 /* Add packet to the interface output queue. */
3514 ospf_packet_add (oi, op);
3515
3516 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003517 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003518}
3519
3520static int
3521ospf_ls_ack_send_event (struct thread *thread)
3522{
3523 struct ospf_interface *oi = THREAD_ARG (thread);
3524
3525 oi->t_ls_ack_direct = NULL;
3526
3527 while (listcount (oi->ls_ack_direct.ls_ack))
3528 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3529 oi->ls_ack_direct.dst);
3530
3531 return 0;
3532}
3533
3534void
3535ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3536{
3537 struct ospf_interface *oi = nbr->oi;
3538
3539 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3540 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3541
3542 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3543
3544 if (oi->t_ls_ack_direct == NULL)
3545 oi->t_ls_ack_direct =
3546 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3547}
3548
3549/* Send Link State Acknowledgment delayed. */
3550void
3551ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3552{
3553 struct in_addr dst;
3554
3555 /* Decide destination address. */
3556 /* RFC2328 Section 13.5 On non-broadcast
3557 networks, delayed Link State Acknowledgment packets must be
3558 unicast separately over each adjacency (i.e., neighbor whose
3559 state is >= Exchange). */
3560 if (oi->type == OSPF_IFTYPE_NBMA)
3561 {
3562 struct ospf_neighbor *nbr;
3563 struct route_node *rn;
3564
3565 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3566 if ((nbr = rn->info) != NULL)
3567 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3568 while (listcount (oi->ls_ack))
3569 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3570 return;
3571 }
3572 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3573 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3574 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3575 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3576 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3577 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003578 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3579 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003580 else
3581 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3582
3583 while (listcount (oi->ls_ack))
3584 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3585}