blob: 2addc4979829681286c1008f974408416690ccbc [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
paul68b73392004-09-12 14:21:37 +0000605 /* convenience - max OSPF data per packet */
606 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
607
paul718e3742002-12-13 20:15:29 +0000608 /* Get one packet from queue. */
609 op = ospf_fifo_head (oi->obuf);
610 assert (op);
611 assert (op->length >= OSPF_HEADER_SIZE);
612
paul68980082003-03-25 05:07:42 +0000613 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
614 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000615 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
616
paul718e3742002-12-13 20:15:29 +0000617 /* Rewrite the md5 signature & update the seq */
618 ospf_make_md5_digest (oi, op);
619
paul37ccfa32004-10-31 11:24:51 +0000620 /* Retrieve OSPF packet type. */
621 stream_set_getp (op->s, 1);
622 type = stream_getc (op->s);
623
paul68b73392004-09-12 14:21:37 +0000624 /* reset get pointer */
625 stream_set_getp (op->s, 0);
626
627 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000628 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000629
paul718e3742002-12-13 20:15:29 +0000630 sa_dst.sin_family = AF_INET;
631#ifdef HAVE_SIN_LEN
632 sa_dst.sin_len = sizeof(sa_dst);
633#endif /* HAVE_SIN_LEN */
634 sa_dst.sin_addr = op->dst;
635 sa_dst.sin_port = htons (0);
636
637 /* Set DONTROUTE flag if dst is unicast. */
638 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
639 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
640 flags = MSG_DONTROUTE;
641
paul68b73392004-09-12 14:21:37 +0000642 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
643 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000644 if ( sizeof (struct ip)
645 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000646 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
647
paul718e3742002-12-13 20:15:29 +0000648 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000649 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000650 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000651
paul0bfeca32004-09-24 08:07:54 +0000652#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000653 /* XXX-MT: not thread-safe at all..
654 * XXX: this presumes this is only programme sending OSPF packets
655 * otherwise, no guarantee ipid will be unique
656 */
657 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000658#endif /* WANT_OSPF_WRITE_FRAGMENT */
659
paul718e3742002-12-13 20:15:29 +0000660 iph.ip_off = 0;
661 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
662 iph.ip_ttl = OSPF_VL_IP_TTL;
663 else
664 iph.ip_ttl = OSPF_IP_TTL;
665 iph.ip_p = IPPROTO_OSPFIGP;
666 iph.ip_sum = 0;
667 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
668 iph.ip_dst.s_addr = op->dst.s_addr;
669
670 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000671 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000672 msg.msg_namelen = sizeof (sa_dst);
673 msg.msg_iov = iov;
674 msg.msg_iovlen = 2;
675 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000676 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
677 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000678 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000679
680 /* Sadly we can not rely on kernels to fragment packets because of either
681 * IP_HDRINCL and/or multicast destination being set.
682 */
paul0bfeca32004-09-24 08:07:54 +0000683#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000684 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000685 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
686 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000687#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000688
689 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000690 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000691 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000692 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000693
694 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000695 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000696 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000697 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000698 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000699
paul718e3742002-12-13 20:15:29 +0000700 /* Show debug sending packet. */
701 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
702 {
703 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
704 {
ajs2a42e282004-12-08 18:43:03 +0000705 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000706 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000707 stream_set_getp (op->s, 0);
708 ospf_packet_dump (op->s);
709 }
710
ajs2a42e282004-12-08 18:43:03 +0000711 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000712 ospf_packet_type_str[type], inet_ntoa (op->dst),
713 IF_NAME (oi));
714
715 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000716 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000717 }
718
719 /* Now delete packet from queue. */
720 ospf_packet_delete (oi);
721
722 if (ospf_fifo_head (oi->obuf) == NULL)
723 {
724 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000725 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000726 }
727
728 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000729 if (!list_isempty (ospf->oi_write_q))
730 ospf->t_write =
731 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000732
733 return 0;
734}
735
736/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000737static void
paul718e3742002-12-13 20:15:29 +0000738ospf_hello (struct ip *iph, struct ospf_header *ospfh,
739 struct stream * s, struct ospf_interface *oi, int size)
740{
741 struct ospf_hello *hello;
742 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000743 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000744 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000745
746 /* increment statistics. */
747 oi->hello_in++;
748
749 hello = (struct ospf_hello *) STREAM_PNT (s);
750
751 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000752 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000753 {
754 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
755 {
ajs2a42e282004-12-08 18:43:03 +0000756 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000757 "dropping.",
758 ospf_packet_type_str[ospfh->type],
759 inet_ntoa (iph->ip_src));
760 }
761 return;
762 }
paul718e3742002-12-13 20:15:29 +0000763
764 /* If incoming interface is passive one, ignore Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +0000765 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000766 char buf[3][INET_ADDRSTRLEN];
paul6d452762005-11-03 11:15:44 +0000767 zlog_debug ("ignoring HELLO from router %s sent to %s, "
768 "received on a passive interface, %s",
769 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
770 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
771 inet_ntop(AF_INET, &oi->address->u.prefix4,
772 buf[2], sizeof(buf[2])));
ajsba6454e2005-02-08 15:37:30 +0000773 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
774 {
775 /* Try to fix multicast membership. */
Paul Jakma429ac782006-06-15 18:40:49 +0000776 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +0000777 ospf_if_set_multicast(oi);
778 }
paul718e3742002-12-13 20:15:29 +0000779 return;
paulf2c80652002-12-13 21:44:27 +0000780 }
paul718e3742002-12-13 20:15:29 +0000781
782 /* get neighbor prefix. */
783 p.family = AF_INET;
784 p.prefixlen = ip_masklen (hello->network_mask);
785 p.u.prefix4 = iph->ip_src;
786
787 /* Compare network mask. */
788 /* Checking is ignored for Point-to-Point and Virtual link. */
789 if (oi->type != OSPF_IFTYPE_POINTOPOINT
790 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
791 if (oi->address->prefixlen != p.prefixlen)
792 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000793 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
794 inet_ntoa(ospfh->router_id), IF_NAME(oi),
795 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000796 return;
797 }
798
paul718e3742002-12-13 20:15:29 +0000799 /* Compare Router Dead Interval. */
800 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
801 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000802 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch "
803 "(expected %u, but received %u).",
804 inet_ntoa(ospfh->router_id),
805 OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval));
paul718e3742002-12-13 20:15:29 +0000806 return;
807 }
808
paulf9ad9372005-10-21 00:45:17 +0000809 /* Compare Hello Interval - ignored if fast-hellos are set. */
810 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
811 {
812 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
813 {
Andrew J. Schorr08c83672006-09-25 13:26:14 +0000814 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch "
815 "(expected %u, but received %u).",
816 inet_ntoa(ospfh->router_id),
817 OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval));
paulf9ad9372005-10-21 00:45:17 +0000818 return;
819 }
820 }
821
paul718e3742002-12-13 20:15:29 +0000822 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000823 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000824 inet_ntoa (ospfh->router_id),
825 ospf_options_dump (hello->options));
826
827 /* Compare options. */
828#define REJECT_IF_TBIT_ON 1 /* XXX */
829#ifdef REJECT_IF_TBIT_ON
830 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
831 {
832 /*
833 * This router does not support non-zero TOS.
834 * Drop this Hello packet not to establish neighbor relationship.
835 */
836 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
837 inet_ntoa (ospfh->router_id));
838 return;
839 }
840#endif /* REJECT_IF_TBIT_ON */
841
842#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000843 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000844 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
845 {
846 /*
847 * This router does know the correct usage of O-bit
848 * the bit should be set in DD packet only.
849 */
850 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
851 inet_ntoa (ospfh->router_id));
852#ifdef STRICT_OBIT_USAGE_CHECK
853 return; /* Reject this packet. */
854#else /* STRICT_OBIT_USAGE_CHECK */
855 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
856#endif /* STRICT_OBIT_USAGE_CHECK */
857 }
858#endif /* HAVE_OPAQUE_LSA */
859
860 /* new for NSSA is to ensure that NP is on and E is off */
861
paul718e3742002-12-13 20:15:29 +0000862 if (oi->area->external_routing == OSPF_AREA_NSSA)
863 {
864 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
865 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
866 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
867 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
868 {
869 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
870 return;
871 }
872 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000873 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000874 }
875 else
paul718e3742002-12-13 20:15:29 +0000876 /* The setting of the E-bit found in the Hello Packet's Options
877 field must match this area's ExternalRoutingCapability A
878 mismatch causes processing to stop and the packet to be
879 dropped. The setting of the rest of the bits in the Hello
880 Packet's Options field should be ignored. */
881 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
882 CHECK_FLAG (hello->options, OSPF_OPTION_E))
883 {
ajs3aa8d5f2004-12-11 18:00:06 +0000884 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
885 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000886 return;
887 }
paul718e3742002-12-13 20:15:29 +0000888
pauld3f0d622004-05-05 15:27:15 +0000889 /* get neighbour struct */
890 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
891
892 /* neighbour must be valid, ospf_nbr_get creates if none existed */
893 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000894
895 old_state = nbr->state;
896
897 /* Add event to thread. */
898 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
899
900 /* RFC2328 Section 9.5.1
901 If the router is not eligible to become Designated Router,
902 (snip) It must also send an Hello Packet in reply to an
903 Hello Packet received from any eligible neighbor (other than
904 the current Designated Router and Backup Designated Router). */
905 if (oi->type == OSPF_IFTYPE_NBMA)
906 if (PRIORITY(oi) == 0 && hello->priority > 0
907 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
908 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
909 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
910 OSPF_HELLO_REPLY_DELAY);
911
912 /* on NBMA network type, it happens to receive bidirectional Hello packet
913 without advance 1-Way Received event.
914 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
915 if (oi->type == OSPF_IFTYPE_NBMA &&
916 (old_state == NSM_Down || old_state == NSM_Attempt))
917 {
918 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
919 nbr->priority = hello->priority;
920 nbr->d_router = hello->d_router;
921 nbr->bd_router = hello->bd_router;
922 return;
923 }
924
paul68980082003-03-25 05:07:42 +0000925 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000926 size - OSPF_HELLO_MIN_SIZE))
927 {
928 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
929 nbr->options |= hello->options;
930 }
931 else
932 {
933 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
934 /* Set neighbor information. */
935 nbr->priority = hello->priority;
936 nbr->d_router = hello->d_router;
937 nbr->bd_router = hello->bd_router;
938 return;
939 }
940
941 /* If neighbor itself declares DR and no BDR exists,
942 cause event BackupSeen */
943 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
944 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
945 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
946
947 /* neighbor itself declares BDR. */
948 if (oi->state == ISM_Waiting &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
951
952 /* had not previously. */
953 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
954 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
955 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
956 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
957 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
958
959 /* had not previously. */
960 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
961 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
962 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
963 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
964 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
965
966 /* Neighbor priority check. */
967 if (nbr->priority >= 0 && nbr->priority != hello->priority)
968 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
969
970 /* Set neighbor information. */
971 nbr->priority = hello->priority;
972 nbr->d_router = hello->d_router;
973 nbr->bd_router = hello->bd_router;
974}
975
976/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000977static void
paul718e3742002-12-13 20:15:29 +0000978ospf_db_desc_save_current (struct ospf_neighbor *nbr,
979 struct ospf_db_desc *dd)
980{
981 nbr->last_recv.flags = dd->flags;
982 nbr->last_recv.options = dd->options;
983 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
984}
985
986/* Process rest of DD packet. */
987static void
988ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
989 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
990 u_int16_t size)
991{
992 struct ospf_lsa *new, *find;
993 struct lsa_header *lsah;
994
paul9985f832005-02-09 15:51:56 +0000995 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000996 for (size -= OSPF_DB_DESC_MIN_SIZE;
997 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
998 {
999 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +00001000 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001001
1002 /* Unknown LS type. */
1003 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1004 {
ajsbec595a2004-11-30 22:38:43 +00001005 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +00001006 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1007 return;
1008 }
1009
1010#ifdef HAVE_OPAQUE_LSA
1011 if (IS_OPAQUE_LSA (lsah->type)
1012 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1013 {
1014 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1015 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1016 return;
1017 }
1018#endif /* HAVE_OPAQUE_LSA */
1019
1020 switch (lsah->type)
1021 {
1022 case OSPF_AS_EXTERNAL_LSA:
1023#ifdef HAVE_OPAQUE_LSA
1024 case OSPF_OPAQUE_AS_LSA:
1025#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001026 /* Check for stub area. Reject if AS-External from stub but
1027 allow if from NSSA. */
1028 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001029 {
1030 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1031 lsah->type, inet_ntoa (lsah->id),
1032 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1033 "STUB" : "NSSA");
1034 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1035 return;
1036 }
1037 break;
1038 default:
1039 break;
1040 }
1041
1042 /* Create LS-request object. */
1043 new = ospf_ls_request_new (lsah);
1044
1045 /* Lookup received LSA, then add LS request list. */
1046 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001047
1048 /* ospf_lsa_more_recent is fine with NULL pointers */
1049 switch (ospf_lsa_more_recent (find, new))
1050 {
1051 case -1:
1052 /* Neighbour has a more recent LSA, we must request it */
1053 ospf_ls_request_add (nbr, new);
1054 case 0:
1055 /* If we have a copy of this LSA, it's either less recent
1056 * and we're requesting it from neighbour (the case above), or
1057 * it's as recent and we both have same copy (this case).
1058 *
1059 * In neither of these two cases is there any point in
1060 * describing our copy of the LSA to the neighbour in a
1061 * DB-Summary packet, if we're still intending to do so.
1062 *
1063 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1064 * backward compatible optimisation to OSPF DB Exchange /
1065 * DB Description process implemented here.
1066 */
1067 if (find)
1068 ospf_lsdb_delete (&nbr->db_sum, find);
1069 ospf_lsa_discard (new);
1070 break;
1071 default:
1072 /* We have the more recent copy, nothing specific to do:
1073 * - no need to request neighbours stale copy
1074 * - must leave DB summary list copy alone
1075 */
1076 if (IS_DEBUG_OSPF_EVENT)
1077 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1078 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1079 ospf_lsa_discard (new);
1080 }
paul718e3742002-12-13 20:15:29 +00001081 }
1082
1083 /* Master */
1084 if (IS_SET_DD_MS (nbr->dd_flags))
1085 {
1086 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001087
1088 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001089 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1090 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1091 else
paul718e3742002-12-13 20:15:29 +00001092 ospf_db_desc_send (nbr);
1093 }
1094 /* Slave */
1095 else
1096 {
1097 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1098
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001099 /* Send DD packet in reply.
1100 *
1101 * Must be done to acknowledge the Master's DD, regardless of
1102 * whether we have more LSAs ourselves to describe.
1103 *
1104 * This function will clear the 'More' bit, if after this DD
1105 * we have no more LSAs to describe to the master..
1106 */
paul718e3742002-12-13 20:15:29 +00001107 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001108
1109 /* Slave can raise ExchangeDone now, if master is also done */
1110 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1111 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001112 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001113
paul718e3742002-12-13 20:15:29 +00001114 /* Save received neighbor values from DD. */
1115 ospf_db_desc_save_current (nbr, dd);
1116}
1117
paul4dadc292005-05-06 21:37:42 +00001118static int
paul718e3742002-12-13 20:15:29 +00001119ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1120{
1121 /* Is DD duplicated? */
1122 if (dd->options == nbr->last_recv.options &&
1123 dd->flags == nbr->last_recv.flags &&
1124 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1125 return 1;
1126
1127 return 0;
1128}
1129
1130/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001131static void
paul718e3742002-12-13 20:15:29 +00001132ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1133 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1134{
1135 struct ospf_db_desc *dd;
1136 struct ospf_neighbor *nbr;
1137
1138 /* Increment statistics. */
1139 oi->db_desc_in++;
1140
1141 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001142
pauld3f0d622004-05-05 15:27:15 +00001143 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001144 if (nbr == NULL)
1145 {
1146 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1147 inet_ntoa (ospfh->router_id));
1148 return;
1149 }
1150
1151 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001152 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1153 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001154 {
ajs3aa8d5f2004-12-11 18:00:06 +00001155 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1156 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1157 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001158 return;
1159 }
1160
pauld363df22003-06-19 00:26:34 +00001161 /*
1162 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1163 * required. In fact at least JunOS sends DD packets with P bit clear.
1164 * Until proper solution is developped, this hack should help.
1165 *
1166 * Update: According to the RFCs, N bit is specified /only/ for Hello
1167 * options, unfortunately its use in DD options is not specified. Hence some
1168 * implementations follow E-bit semantics and set it in DD options, and some
1169 * treat it as unspecified and hence follow the directive "default for
1170 * options is clear", ie unset.
1171 *
1172 * Reset the flag, as ospfd follows E-bit semantics.
1173 */
1174 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1175 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1176 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1177 {
1178 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001179 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001180 inet_ntoa (nbr->router_id) );
1181 SET_FLAG (dd->options, OSPF_OPTION_NP);
1182 }
pauld363df22003-06-19 00:26:34 +00001183
paul718e3742002-12-13 20:15:29 +00001184#ifdef REJECT_IF_TBIT_ON
1185 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1186 {
1187 /*
1188 * In Hello protocol, optional capability must have checked
1189 * to prevent this T-bit enabled router be my neighbor.
1190 */
1191 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1192 return;
1193 }
1194#endif /* REJECT_IF_TBIT_ON */
1195
1196#ifdef HAVE_OPAQUE_LSA
1197 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001198 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001199 {
1200 /*
1201 * This node is not configured to handle O-bit, for now.
1202 * Clear it to ignore unsupported capability proposed by neighbor.
1203 */
1204 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1205 }
1206#endif /* HAVE_OPAQUE_LSA */
1207
1208 /* Process DD packet by neighbor status. */
1209 switch (nbr->state)
1210 {
1211 case NSM_Down:
1212 case NSM_Attempt:
1213 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001214 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001215 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001216 LOOKUP (ospf_nsm_state_msg, nbr->state));
1217 break;
1218 case NSM_Init:
1219 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1220 /* If the new state is ExStart, the processing of the current
1221 packet should then continue in this new state by falling
1222 through to case ExStart below. */
1223 if (nbr->state != NSM_ExStart)
1224 break;
1225 case NSM_ExStart:
1226 /* Initial DBD */
1227 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1228 (size == OSPF_DB_DESC_MIN_SIZE))
1229 {
paul68980082003-03-25 05:07:42 +00001230 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001231 {
1232 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001233 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001234 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001235 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001236
1237 /* Reset I/MS */
1238 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001239 }
1240 else
1241 {
1242 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001243 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001244 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001245 break;
1246 }
1247 }
1248 /* Ack from the Slave */
1249 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1250 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001251 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001252 {
ajs17eaa722004-12-29 21:04:48 +00001253 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001254 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001255 /* Reset I, leaving MS */
1256 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001257 }
1258 else
1259 {
ajs3aa8d5f2004-12-11 18:00:06 +00001260 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1261 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001262 break;
1263 }
1264
1265 /* This is where the real Options are saved */
1266 nbr->options = dd->options;
1267
1268#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001269 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001270 {
1271 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001272 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001273 inet_ntoa (nbr->router_id),
1274 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1275
1276 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1277 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1278 {
paul6d452762005-11-03 11:15:44 +00001279 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1280 "Opaque-LSAs cannot be reliably advertised "
1281 "in this network.",
1282 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001283 /* This situation is undesirable, but not a real error. */
1284 }
1285 }
1286#endif /* HAVE_OPAQUE_LSA */
1287
1288 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1289
1290 /* continue processing rest of packet. */
1291 ospf_db_desc_proc (s, oi, nbr, dd, size);
1292 break;
1293 case NSM_Exchange:
1294 if (ospf_db_desc_is_dup (dd, nbr))
1295 {
1296 if (IS_SET_DD_MS (nbr->dd_flags))
1297 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001298 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001299 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001300 else
1301 /* Slave: cause to retransmit the last Database Description. */
1302 {
paul6d452762005-11-03 11:15:44 +00001303 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001304 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001305 ospf_db_desc_resend (nbr);
1306 }
1307 break;
1308 }
1309
1310 /* Otherwise DD packet should be checked. */
1311 /* Check Master/Slave bit mismatch */
1312 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1313 {
ajs3aa8d5f2004-12-11 18:00:06 +00001314 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1315 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001316 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1317 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001318 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001319 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001320 break;
1321 }
1322
1323 /* Check initialize bit is set. */
1324 if (IS_SET_DD_I (dd->flags))
1325 {
paul6d452762005-11-03 11:15:44 +00001326 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001327 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001328 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1329 break;
1330 }
1331
1332 /* Check DD Options. */
1333 if (dd->options != nbr->options)
1334 {
1335#ifdef ORIGINAL_CODING
1336 /* Save the new options for debugging */
1337 nbr->options = dd->options;
1338#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001339 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1340 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001341 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1342 break;
1343 }
1344
1345 /* Check DD sequence number. */
1346 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1347 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1348 (!IS_SET_DD_MS (nbr->dd_flags) &&
1349 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1350 {
ajs3aa8d5f2004-12-11 18:00:06 +00001351 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1352 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001353 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1354 break;
1355 }
1356
1357 /* Continue processing rest of packet. */
1358 ospf_db_desc_proc (s, oi, nbr, dd, size);
1359 break;
1360 case NSM_Loading:
1361 case NSM_Full:
1362 if (ospf_db_desc_is_dup (dd, nbr))
1363 {
1364 if (IS_SET_DD_MS (nbr->dd_flags))
1365 {
1366 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001367 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1368 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001369 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001370 break;
1371 }
1372 else
1373 {
1374 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001375 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001376 t = tv_sub (now, nbr->last_send_ts);
1377 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1378 {
1379 /* In states Loading and Full the slave must resend
1380 its last Database Description packet in response to
1381 duplicate Database Description packets received
1382 from the master. For this reason the slave must
1383 wait RouterDeadInterval seconds before freeing the
1384 last Database Description packet. Reception of a
1385 Database Description packet from the master after
1386 this interval will generate a SeqNumberMismatch
1387 neighbor event. RFC2328 Section 10.8 */
1388 ospf_db_desc_resend (nbr);
1389 break;
1390 }
1391 }
1392 }
1393
1394 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1395 break;
1396 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001397 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1398 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001399 break;
1400 }
1401}
1402
1403#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1404
1405/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001406static void
paul718e3742002-12-13 20:15:29 +00001407ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1408 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1409{
1410 struct ospf_neighbor *nbr;
1411 u_int32_t ls_type;
1412 struct in_addr ls_id;
1413 struct in_addr adv_router;
1414 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001415 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001416 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001417
1418 /* Increment statistics. */
1419 oi->ls_req_in++;
1420
pauld3f0d622004-05-05 15:27:15 +00001421 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001422 if (nbr == NULL)
1423 {
1424 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1425 inet_ntoa (ospfh->router_id));
1426 return;
1427 }
1428
1429 /* Neighbor State should be Exchange or later. */
1430 if (nbr->state != NSM_Exchange &&
1431 nbr->state != NSM_Loading &&
1432 nbr->state != NSM_Full)
1433 {
ajsbec595a2004-11-30 22:38:43 +00001434 zlog_warn ("Link State Request received from %s: "
1435 "Neighbor state is %s, packet discarded.",
1436 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001437 LOOKUP (ospf_nsm_state_msg, nbr->state));
1438 return;
1439 }
1440
1441 /* Send Link State Update for ALL requested LSAs. */
1442 ls_upd = list_new ();
1443 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1444
1445 while (size >= OSPF_LSA_KEY_SIZE)
1446 {
1447 /* Get one slice of Link State Request. */
1448 ls_type = stream_getl (s);
1449 ls_id.s_addr = stream_get_ipv4 (s);
1450 adv_router.s_addr = stream_get_ipv4 (s);
1451
1452 /* Verify LSA type. */
1453 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1454 {
1455 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1456 list_delete (ls_upd);
1457 return;
1458 }
1459
1460 /* Search proper LSA in LSDB. */
1461 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1462 if (find == NULL)
1463 {
1464 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1465 list_delete (ls_upd);
1466 return;
1467 }
1468
gdt86f1fd92005-01-10 14:20:43 +00001469 /* Packet overflows MTU size, send immediately. */
1470 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001471 {
1472 if (oi->type == OSPF_IFTYPE_NBMA)
1473 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1474 else
1475 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1476
1477 /* Only remove list contents. Keep ls_upd. */
1478 list_delete_all_node (ls_upd);
1479
1480 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1481 }
1482
1483 /* Append LSA to update list. */
1484 listnode_add (ls_upd, find);
1485 length += ntohs (find->data->length);
1486
1487 size -= OSPF_LSA_KEY_SIZE;
1488 }
1489
1490 /* Send rest of Link State Update. */
1491 if (listcount (ls_upd) > 0)
1492 {
1493 if (oi->type == OSPF_IFTYPE_NBMA)
1494 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1495 else
1496 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1497
1498 list_delete (ls_upd);
1499 }
1500 else
1501 list_free (ls_upd);
1502}
1503
1504/* Get the list of LSAs from Link State Update packet.
1505 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001506static struct list *
paul718e3742002-12-13 20:15:29 +00001507ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1508 struct ospf_interface *oi, size_t size)
1509{
1510 u_int16_t count, sum;
1511 u_int32_t length;
1512 struct lsa_header *lsah;
1513 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001514 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001515
1516 lsas = list_new ();
1517
1518 count = stream_getl (s);
1519 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1520
1521 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001522 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001523 {
1524 lsah = (struct lsa_header *) STREAM_PNT (s);
1525 length = ntohs (lsah->length);
1526
1527 if (length > size)
1528 {
1529 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1530 break;
1531 }
1532
1533 /* Validate the LSA's LS checksum. */
1534 sum = lsah->checksum;
1535 if (sum != ospf_lsa_checksum (lsah))
1536 {
1537 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1538 sum, lsah->checksum);
1539 continue;
1540 }
1541
1542 /* Examine the LSA's LS type. */
1543 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1544 {
1545 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1546 continue;
1547 }
1548
1549 /*
1550 * What if the received LSA's age is greater than MaxAge?
1551 * Treat it as a MaxAge case -- endo.
1552 */
1553 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1554 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1555
1556#ifdef HAVE_OPAQUE_LSA
1557 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1558 {
1559#ifdef STRICT_OBIT_USAGE_CHECK
1560 if ((IS_OPAQUE_LSA(lsah->type) &&
1561 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1562 || (! IS_OPAQUE_LSA(lsah->type) &&
1563 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1564 {
1565 /*
1566 * This neighbor must know the exact usage of O-bit;
1567 * the bit will be set in Type-9,10,11 LSAs only.
1568 */
1569 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1570 continue;
1571 }
1572#endif /* STRICT_OBIT_USAGE_CHECK */
1573
1574 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1575 if (lsah->type == OSPF_OPAQUE_AS_LSA
1576 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1577 {
1578 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001579 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 +00001580 continue;
1581 }
1582 }
1583 else if (IS_OPAQUE_LSA(lsah->type))
1584 {
1585 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1586 continue;
1587 }
1588#endif /* HAVE_OPAQUE_LSA */
1589
1590 /* Create OSPF LSA instance. */
1591 lsa = ospf_lsa_new ();
1592
1593 /* We may wish to put some error checking if type NSSA comes in
1594 and area not in NSSA mode */
1595 switch (lsah->type)
1596 {
1597 case OSPF_AS_EXTERNAL_LSA:
1598#ifdef HAVE_OPAQUE_LSA
1599 case OSPF_OPAQUE_AS_LSA:
1600 lsa->area = NULL;
1601 break;
1602 case OSPF_OPAQUE_LINK_LSA:
1603 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1604 /* Fallthrough */
1605#endif /* HAVE_OPAQUE_LSA */
1606 default:
1607 lsa->area = oi->area;
1608 break;
1609 }
1610
1611 lsa->data = ospf_lsa_data_new (length);
1612 memcpy (lsa->data, lsah, length);
1613
1614 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001615 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001616 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1617 listnode_add (lsas, lsa);
1618 }
1619
1620 return lsas;
1621}
1622
1623/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001624static void
hasso52dc7ee2004-09-23 19:18:23 +00001625ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001626{
paul1eb8ef22005-04-07 07:30:20 +00001627 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001628 struct ospf_lsa *lsa;
1629
paul1eb8ef22005-04-07 07:30:20 +00001630 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1631 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001632
1633 list_delete (lsas);
1634}
1635
1636/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001637static void
paul718e3742002-12-13 20:15:29 +00001638ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1639 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1640{
1641 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001642 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001643 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001644 struct ospf_lsa *lsa = NULL;
1645 /* unsigned long ls_req_found = 0; */
1646
1647 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1648
1649 /* Increment statistics. */
1650 oi->ls_upd_in++;
1651
1652 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001653 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001654 if (nbr == NULL)
1655 {
1656 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1657 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1658 return;
1659 }
1660
1661 /* Check neighbor state. */
1662 if (nbr->state < NSM_Exchange)
1663 {
ajs3aa8d5f2004-12-11 18:00:06 +00001664 zlog_warn ("Link State Update: "
1665 "Neighbor[%s] state %s is less than Exchange",
1666 inet_ntoa (ospfh->router_id),
1667 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001668 return;
1669 }
1670
1671 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1672 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1673 * of section 13.
1674 */
1675 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1676
1677#ifdef HAVE_OPAQUE_LSA
1678 /*
paul718e3742002-12-13 20:15:29 +00001679 * If self-originated Opaque-LSAs that have flooded before restart
1680 * are contained in the received LSUpd message, corresponding LSReq
1681 * messages to be sent may have to be modified.
1682 * To eliminate possible race conditions such that flushing and normal
1683 * updating for the same LSA would take place alternately, this trick
1684 * must be done before entering to the loop below.
1685 */
paul69310a62005-05-11 18:09:59 +00001686 /* XXX: Why is this Opaque specific? Either our core code is deficient
1687 * and this should be fixed generally, or Opaque is inventing strawman
1688 * problems */
paul718e3742002-12-13 20:15:29 +00001689 ospf_opaque_adjust_lsreq (nbr, lsas);
1690#endif /* HAVE_OPAQUE_LSA */
1691
1692#define DISCARD_LSA(L,N) {\
1693 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001694 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 +00001695 ospf_lsa_discard (L); \
1696 continue; }
1697
1698 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001699 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001700 {
1701 struct ospf_lsa *ls_ret, *current;
1702 int ret = 1;
1703
paul718e3742002-12-13 20:15:29 +00001704 if (IS_DEBUG_OSPF_NSSA)
1705 {
1706 char buf1[INET_ADDRSTRLEN];
1707 char buf2[INET_ADDRSTRLEN];
1708 char buf3[INET_ADDRSTRLEN];
1709
ajs2a42e282004-12-08 18:43:03 +00001710 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001711 lsa->data->type,
1712 inet_ntop (AF_INET, &ospfh->router_id,
1713 buf1, INET_ADDRSTRLEN),
1714 inet_ntop (AF_INET, &lsa->data->id,
1715 buf2, INET_ADDRSTRLEN),
1716 inet_ntop (AF_INET, &lsa->data->adv_router,
1717 buf3, INET_ADDRSTRLEN));
1718 }
paul718e3742002-12-13 20:15:29 +00001719
1720 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1721
1722 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1723
1724 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1725
1726 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1727
1728 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1729
1730 /* Do take in Type-7's if we are an NSSA */
1731
1732 /* If we are also an ABR, later translate them to a Type-5 packet */
1733
1734 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1735 translate them to a separate Type-5 packet. */
1736
1737 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1738 /* Reject from STUB or NSSA */
1739 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1740 {
1741 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001742 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001743 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001744 }
1745
paul718e3742002-12-13 20:15:29 +00001746 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1747 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1748 {
1749 DISCARD_LSA (lsa,2);
1750 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001751 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001752 }
paul718e3742002-12-13 20:15:29 +00001753
1754 /* Find the LSA in the current database. */
1755
1756 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1757
1758 /* If the LSA's LS age is equal to MaxAge, and there is currently
1759 no instance of the LSA in the router's link state database,
1760 and none of router's neighbors are in states Exchange or Loading,
1761 then take the following actions. */
1762
1763 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001764 (ospf_nbr_count (oi, NSM_Exchange) +
1765 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001766 {
1767 /* Response Link State Acknowledgment. */
1768 ospf_ls_ack_send (nbr, lsa);
1769
1770 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001771 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1772 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001773 DISCARD_LSA (lsa, 3);
1774 }
1775
1776#ifdef HAVE_OPAQUE_LSA
1777 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001778 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001779 {
1780 /*
1781 * Even if initial flushing seems to be completed, there might
1782 * be a case that self-originated LSA with MaxAge still remain
1783 * in the routing domain.
1784 * Just send an LSAck message to cease retransmission.
1785 */
1786 if (IS_LSA_MAXAGE (lsa))
1787 {
1788 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1789 ospf_ls_ack_send (nbr, lsa);
1790 ospf_lsa_discard (lsa);
1791
1792 if (current != NULL && ! IS_LSA_MAXAGE (current))
1793 ospf_opaque_lsa_refresh_schedule (current);
1794 continue;
1795 }
1796
1797 /*
1798 * If an instance of self-originated Opaque-LSA is not found
1799 * in the LSDB, there are some possible cases here.
1800 *
1801 * 1) This node lost opaque-capability after restart.
1802 * 2) Else, a part of opaque-type is no more supported.
1803 * 3) Else, a part of opaque-id is no more supported.
1804 *
1805 * Anyway, it is still this node's responsibility to flush it.
1806 * Otherwise, the LSA instance remains in the routing domain
1807 * until its age reaches to MaxAge.
1808 */
paul69310a62005-05-11 18:09:59 +00001809 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001810 if (current == NULL)
1811 {
1812 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001813 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1814 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001815
1816 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001817
1818 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1819 ospf_ls_ack_send (nbr, lsa);
1820
paul718e3742002-12-13 20:15:29 +00001821 continue;
1822 }
1823 }
1824#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001825
hassocb05eb22004-02-11 21:10:19 +00001826 /* It might be happen that received LSA is self-originated network LSA, but
1827 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1828 * Link State ID is one of the router's own IP interface addresses but whose
1829 * Advertising Router is not equal to the router's own Router ID
1830 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1831 */
1832
1833 if(lsa->data->type == OSPF_NETWORK_LSA)
1834 {
paul1eb8ef22005-04-07 07:30:20 +00001835 struct listnode *oinode, *oinnode;
1836 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001837 int Flag = 0;
1838
paul1eb8ef22005-04-07 07:30:20 +00001839 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001840 {
hassocb05eb22004-02-11 21:10:19 +00001841 if(out_if == NULL)
1842 break;
1843
1844 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1845 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1846 {
1847 if(out_if->network_lsa_self)
1848 {
1849 ospf_lsa_flush_area(lsa,out_if->area);
1850 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001851 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001852 lsa, (int) lsa->data->type);
1853 ospf_lsa_discard (lsa);
1854 Flag = 1;
1855 }
1856 break;
1857 }
1858 }
1859 if(Flag)
1860 continue;
1861 }
paul718e3742002-12-13 20:15:29 +00001862
1863 /* (5) Find the instance of this LSA that is currently contained
1864 in the router's link state database. If there is no
1865 database copy, or the received LSA is more recent than
1866 the database copy the following steps must be performed. */
1867
1868 if (current == NULL ||
1869 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1870 {
1871 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001872 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001873 DISCARD_LSA (lsa, 4);
1874 continue;
1875 }
1876
1877 /* (6) Else, If there is an instance of the LSA on the sending
1878 neighbor's Link state request list, an error has occurred in
1879 the Database Exchange process. In this case, restart the
1880 Database Exchange process by generating the neighbor event
1881 BadLSReq for the sending neighbor and stop processing the
1882 Link State Update packet. */
1883
1884 if (ospf_ls_request_lookup (nbr, lsa))
1885 {
1886 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001887 zlog_warn("LSA[%s] instance exists on Link state request list",
1888 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001889
1890 /* Clean list of LSAs. */
1891 ospf_upd_list_clean (lsas);
1892 /* this lsa is not on lsas list already. */
1893 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001894 return;
1895 }
1896
1897 /* If the received LSA is the same instance as the database copy
1898 (i.e., neither one is more recent) the following two steps
1899 should be performed: */
1900
1901 if (ret == 0)
1902 {
1903 /* If the LSA is listed in the Link state retransmission list
1904 for the receiving adjacency, the router itself is expecting
1905 an acknowledgment for this LSA. The router should treat the
1906 received LSA as an acknowledgment by removing the LSA from
1907 the Link state retransmission list. This is termed an
1908 "implied acknowledgment". */
1909
1910 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1911
1912 if (ls_ret != NULL)
1913 {
1914 ospf_ls_retransmit_delete (nbr, ls_ret);
1915
1916 /* Delayed acknowledgment sent if advertisement received
1917 from Designated Router, otherwise do nothing. */
1918 if (oi->state == ISM_Backup)
1919 if (NBR_IS_DR (nbr))
1920 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1921
1922 DISCARD_LSA (lsa, 5);
1923 }
1924 else
1925 /* Acknowledge the receipt of the LSA by sending a
1926 Link State Acknowledgment packet back out the receiving
1927 interface. */
1928 {
1929 ospf_ls_ack_send (nbr, lsa);
1930 DISCARD_LSA (lsa, 6);
1931 }
1932 }
1933
1934 /* The database copy is more recent. If the database copy
1935 has LS age equal to MaxAge and LS sequence number equal to
1936 MaxSequenceNumber, simply discard the received LSA without
1937 acknowledging it. (In this case, the LSA's LS sequence number is
1938 wrapping, and the MaxSequenceNumber LSA must be completely
1939 flushed before any new LSA instance can be introduced). */
1940
1941 else if (ret > 0) /* Database copy is more recent */
1942 {
1943 if (IS_LSA_MAXAGE (current) &&
1944 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1945 {
1946 DISCARD_LSA (lsa, 7);
1947 }
1948 /* Otherwise, as long as the database copy has not been sent in a
1949 Link State Update within the last MinLSArrival seconds, send the
1950 database copy back to the sending neighbor, encapsulated within
1951 a Link State Update Packet. The Link State Update Packet should
1952 be sent directly to the neighbor. In so doing, do not put the
1953 database copy of the LSA on the neighbor's link state
1954 retransmission list, and do not acknowledge the received (less
1955 recent) LSA instance. */
1956 else
1957 {
1958 struct timeval now;
1959
Paul Jakma2518efd2006-08-27 06:49:29 +00001960 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001961
1962 if (tv_cmp (tv_sub (now, current->tv_orig),
1963 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1964 /* Trap NSSA type later.*/
1965 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1966 DISCARD_LSA (lsa, 8);
1967 }
1968 }
1969 }
1970
paul718e3742002-12-13 20:15:29 +00001971 assert (listcount (lsas) == 0);
1972 list_delete (lsas);
1973}
1974
1975/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001976static void
paul718e3742002-12-13 20:15:29 +00001977ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1978 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1979{
1980 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001981
paul718e3742002-12-13 20:15:29 +00001982 /* increment statistics. */
1983 oi->ls_ack_in++;
1984
pauld3f0d622004-05-05 15:27:15 +00001985 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001986 if (nbr == NULL)
1987 {
1988 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1989 inet_ntoa (ospfh->router_id));
1990 return;
1991 }
1992
1993 if (nbr->state < NSM_Exchange)
1994 {
ajs3aa8d5f2004-12-11 18:00:06 +00001995 zlog_warn ("Link State Acknowledgment: "
1996 "Neighbor[%s] state %s is less than Exchange",
1997 inet_ntoa (ospfh->router_id),
1998 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001999 return;
2000 }
paul69310a62005-05-11 18:09:59 +00002001
paul718e3742002-12-13 20:15:29 +00002002 while (size >= OSPF_LSA_HEADER_SIZE)
2003 {
2004 struct ospf_lsa *lsa, *lsr;
2005
2006 lsa = ospf_lsa_new ();
2007 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2008
2009 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2010 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002011 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002012
2013 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2014 {
2015 lsa->data = NULL;
2016 ospf_lsa_discard (lsa);
2017 continue;
2018 }
2019
2020 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2021
2022 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2023 {
2024#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002025 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002026 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002027#endif /* HAVE_OPAQUE_LSA */
2028
2029 ospf_ls_retransmit_delete (nbr, lsr);
2030 }
2031
2032 lsa->data = NULL;
2033 ospf_lsa_discard (lsa);
2034 }
2035
paul718e3742002-12-13 20:15:29 +00002036 return;
paul718e3742002-12-13 20:15:29 +00002037}
2038
ajs038163f2005-02-17 19:55:59 +00002039static struct stream *
ajs5c333492005-02-23 15:43:01 +00002040ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002041{
2042 int ret;
ajs5c333492005-02-23 15:43:01 +00002043 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002044 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002045 unsigned int ifindex = 0;
2046 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002047 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002048 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002049 struct msghdr msgh;
2050
paul68defd62004-09-27 07:27:13 +00002051 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002052 msgh.msg_iov = &iov;
2053 msgh.msg_iovlen = 1;
2054 msgh.msg_control = (caddr_t) buff;
2055 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002056
ajs5c333492005-02-23 15:43:01 +00002057 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2058 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002059 {
ajs5c333492005-02-23 15:43:01 +00002060 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2061 return NULL;
2062 }
paul69310a62005-05-11 18:09:59 +00002063 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002064 {
2065 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2066 "(ip header size is %u)",
2067 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002068 return NULL;
2069 }
paul18b12c32004-10-05 14:38:29 +00002070
ajs5c333492005-02-23 15:43:01 +00002071 /* Note that there should not be alignment problems with this assignment
2072 because this is at the beginning of the stream data buffer. */
2073 iph = (struct ip *) STREAM_DATA(ibuf);
2074 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002075
ajs5c333492005-02-23 15:43:01 +00002076 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002077
paul239aecc2003-12-08 10:34:54 +00002078#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002079 /*
2080 * Kernel network code touches incoming IP header parameters,
2081 * before protocol specific processing.
2082 *
2083 * 1) Convert byteorder to host representation.
2084 * --> ip_len, ip_id, ip_off
2085 *
2086 * 2) Adjust ip_len to strip IP header size!
2087 * --> If user process receives entire IP packet via RAW
2088 * socket, it must consider adding IP header size to
2089 * the "ip_len" field of "ip" structure.
2090 *
2091 * For more details, see <netinet/ip_input.c>.
2092 */
ajs5c333492005-02-23 15:43:01 +00002093 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002094#endif
2095
paul863082d2004-08-19 04:43:43 +00002096 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002097
2098 *ifp = if_lookup_by_index (ifindex);
2099
2100 if (ret != ip_len)
2101 {
ajs5c333492005-02-23 15:43:01 +00002102 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2103 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002104 return NULL;
2105 }
2106
2107 return ibuf;
2108}
2109
paul4dadc292005-05-06 21:37:42 +00002110static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002111ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002112 struct ip *iph, struct ospf_header *ospfh)
2113{
2114 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002115 struct ospf_vl_data *vl_data;
2116 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002117 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002118
2119 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2120 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002121 return NULL;
paul718e3742002-12-13 20:15:29 +00002122
pauld3f0d622004-05-05 15:27:15 +00002123 /* look for local OSPF interface matching the destination
2124 * to determine Area ID. We presume therefore the destination address
2125 * is unique, or at least (for "unnumbered" links), not used in other
2126 * areas
2127 */
2128 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2129 iph->ip_dst)) == NULL)
2130 return NULL;
paul718e3742002-12-13 20:15:29 +00002131
paul1eb8ef22005-04-07 07:30:20 +00002132 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002133 {
paul020709f2003-04-04 02:44:16 +00002134 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002135 if (!vl_area)
2136 continue;
2137
2138 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2139 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2140 {
2141 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002142 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002143 IF_NAME (vl_data->vl_oi));
2144 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2145 {
2146 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002147 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002148 return NULL;
2149 }
2150
2151 return vl_data->vl_oi;
2152 }
2153 }
2154
2155 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002156 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002157
pauld3f0d622004-05-05 15:27:15 +00002158 return NULL;
paul718e3742002-12-13 20:15:29 +00002159}
2160
paul4dadc292005-05-06 21:37:42 +00002161static inline int
paul718e3742002-12-13 20:15:29 +00002162ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2163{
2164 /* Check match the Area ID of the receiving interface. */
2165 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2166 return 1;
2167
2168 return 0;
2169}
2170
2171/* Unbound socket will accept any Raw IP packets if proto is matched.
2172 To prevent it, compare src IP address and i/f address with masking
2173 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002174static int
paul718e3742002-12-13 20:15:29 +00002175ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2176{
2177 struct in_addr mask, me, him;
2178
2179 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2180 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2181 return 1;
2182
2183 masklen2ip (oi->address->prefixlen, &mask);
2184
2185 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2186 him.s_addr = ip_src.s_addr & mask.s_addr;
2187
2188 if (IPV4_ADDR_SAME (&me, &him))
2189 return 1;
2190
2191 return 0;
2192}
2193
paul4dadc292005-05-06 21:37:42 +00002194static int
paul718e3742002-12-13 20:15:29 +00002195ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2196 struct ospf_header *ospfh)
2197{
2198 int ret = 0;
2199 struct crypt_key *ck;
2200
2201 switch (ntohs (ospfh->auth_type))
2202 {
2203 case OSPF_AUTH_NULL:
2204 ret = 1;
2205 break;
2206 case OSPF_AUTH_SIMPLE:
2207 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2208 ret = 1;
2209 else
2210 ret = 0;
2211 break;
2212 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002213 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002214 {
2215 ret = 0;
2216 break;
2217 }
2218
2219 /* This is very basic, the digest processing is elsewhere */
2220 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2221 ospfh->u.crypt.key_id == ck->key_id &&
2222 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2223 ret = 1;
2224 else
2225 ret = 0;
2226 break;
2227 default:
2228 ret = 0;
2229 break;
2230 }
2231
2232 return ret;
2233}
2234
paul4dadc292005-05-06 21:37:42 +00002235static int
paul718e3742002-12-13 20:15:29 +00002236ospf_check_sum (struct ospf_header *ospfh)
2237{
2238 u_int32_t ret;
2239 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002240
2241 /* clear auth_data for checksum. */
2242 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2243
2244 /* keep checksum and clear. */
2245 sum = ospfh->checksum;
2246 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2247
2248 /* calculate checksum. */
2249 ret = in_cksum (ospfh, ntohs (ospfh->length));
2250
2251 if (ret != sum)
2252 {
2253 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2254 ret, sum);
2255 return 0;
2256 }
2257
2258 return 1;
2259}
2260
2261/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002262static int
paul718e3742002-12-13 20:15:29 +00002263ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2264 struct ip *iph, struct ospf_header *ospfh)
2265{
2266 /* check version. */
2267 if (ospfh->version != OSPF_VERSION)
2268 {
2269 zlog_warn ("interface %s: ospf_read version number mismatch.",
2270 IF_NAME (oi));
2271 return -1;
2272 }
2273
2274 /* Check Area ID. */
2275 if (!ospf_check_area_id (oi, ospfh))
2276 {
2277 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2278 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2279 return -1;
2280 }
2281
2282 /* Check network mask, Silently discarded. */
2283 if (! ospf_check_network_mask (oi, iph->ip_src))
2284 {
2285 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2286 IF_NAME (oi), inet_ntoa (iph->ip_src));
2287 return -1;
2288 }
2289
2290 /* Check authentication. */
2291 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2292 {
paulc6371712006-01-17 17:49:53 +00002293 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2294 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002295 return -1;
2296 }
2297
2298 if (! ospf_check_auth (oi, ibuf, ospfh))
2299 {
2300 zlog_warn ("interface %s: ospf_read authentication failed.",
2301 IF_NAME (oi));
2302 return -1;
2303 }
2304
2305 /* if check sum is invalid, packet is discarded. */
2306 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2307 {
2308 if (! ospf_check_sum (ospfh))
2309 {
2310 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2311 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2312 return -1;
2313 }
2314 }
2315 else
2316 {
2317 if (ospfh->checksum != 0)
2318 return -1;
2319 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2320 {
2321 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2322 IF_NAME (oi));
2323 return -1;
2324 }
2325 }
2326
2327 return 0;
2328}
2329
2330/* Starting point of packet process function. */
2331int
2332ospf_read (struct thread *thread)
2333{
2334 int ret;
2335 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002336 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002337 struct ospf_interface *oi;
2338 struct ip *iph;
2339 struct ospf_header *ospfh;
2340 u_int16_t length;
2341 struct interface *ifp;
2342
2343 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002344 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002345
2346 /* prepare for next packet. */
2347 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002348
2349 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002350 stream_reset(ospf->ibuf);
2351 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002352 return -1;
2353
ajs5c333492005-02-23 15:43:01 +00002354 /* Note that there should not be alignment problems with this assignment
2355 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002356 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002357 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002358
paulac191232004-10-22 12:05:17 +00002359 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002360 /* Handle cases where the platform does not support retrieving the ifindex,
2361 and also platforms (such as Solaris 8) that claim to support ifindex
2362 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002363 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002364
pauld3f0d622004-05-05 15:27:15 +00002365 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002366 return 0;
paul718e3742002-12-13 20:15:29 +00002367
2368 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002369 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002370 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002371
paul718e3742002-12-13 20:15:29 +00002372 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002373 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002374 {
pauld3241812003-09-29 12:42:39 +00002375 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2376 {
ajs2a42e282004-12-08 18:43:03 +00002377 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002378 inet_ntoa (iph->ip_src));
2379 }
paul718e3742002-12-13 20:15:29 +00002380 return 0;
2381 }
2382
2383 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002384 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002385
2386 /* Get ospf packet header. */
2387 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2388
2389 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002390 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002391
2392 /* if no local ospf_interface,
2393 * or header area is backbone but ospf_interface is not
2394 * check for VLINK interface
2395 */
2396 if ( (oi == NULL) ||
2397 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2398 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2399 )
2400 {
2401 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2402 {
Paul Jakma88871b12006-06-15 11:41:19 +00002403 if (IS_DEBUG_OSPF_EVENT)
2404 zlog_debug ("Packet from [%s] received on link %s"
2405 " but no ospf_interface",
2406 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002407 return 0;
2408 }
2409 }
2410
2411 /* else it must be a local ospf interface, check it was received on
2412 * correct link
2413 */
2414 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002415 {
2416 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002417 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002418 return 0;
2419 }
ajs847947f2005-02-02 18:38:48 +00002420 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002421 {
ajsba6454e2005-02-08 15:37:30 +00002422 char buf[2][INET_ADDRSTRLEN];
2423 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002424 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002425 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2426 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2427 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002428 /* Fix multicast memberships? */
2429 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002430 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002431 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002432 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002433 if (oi->multicast_memberships)
2434 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002435 return 0;
2436 }
paul718e3742002-12-13 20:15:29 +00002437
2438 /*
2439 * If the received packet is destined for AllDRouters, the packet
2440 * should be accepted only if the received ospf interface state is
2441 * either DR or Backup -- endo.
2442 */
2443 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2444 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2445 {
ajsba6454e2005-02-08 15:37:30 +00002446 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002447 inet_ntoa (iph->ip_src), IF_NAME (oi),
2448 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002449 /* Try to fix multicast membership. */
2450 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2451 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002452 return 0;
2453 }
2454
2455 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002456 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2457 {
paul718e3742002-12-13 20:15:29 +00002458 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002459 {
ajs2a42e282004-12-08 18:43:03 +00002460 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002461 ospf_packet_dump (ibuf);
2462 }
paul718e3742002-12-13 20:15:29 +00002463
ajs2a42e282004-12-08 18:43:03 +00002464 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002465 ospf_packet_type_str[ospfh->type],
2466 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002467 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2468 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002469
2470 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002471 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002472 }
paul718e3742002-12-13 20:15:29 +00002473
2474 /* Some header verification. */
2475 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2476 if (ret < 0)
2477 {
pauld3241812003-09-29 12:42:39 +00002478 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2479 {
ajs2a42e282004-12-08 18:43:03 +00002480 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002481 "dropping.",
2482 ospf_packet_type_str[ospfh->type],
2483 inet_ntoa (iph->ip_src));
2484 }
paul718e3742002-12-13 20:15:29 +00002485 return ret;
2486 }
2487
paul9985f832005-02-09 15:51:56 +00002488 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002489
2490 /* Adjust size to message length. */
2491 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2492
2493 /* Read rest of the packet and call each sort of packet routine. */
2494 switch (ospfh->type)
2495 {
2496 case OSPF_MSG_HELLO:
2497 ospf_hello (iph, ospfh, ibuf, oi, length);
2498 break;
2499 case OSPF_MSG_DB_DESC:
2500 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2501 break;
2502 case OSPF_MSG_LS_REQ:
2503 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2504 break;
2505 case OSPF_MSG_LS_UPD:
2506 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2507 break;
2508 case OSPF_MSG_LS_ACK:
2509 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2510 break;
2511 default:
2512 zlog (NULL, LOG_WARNING,
2513 "interface %s: OSPF packet header type %d is illegal",
2514 IF_NAME (oi), ospfh->type);
2515 break;
2516 }
2517
paul718e3742002-12-13 20:15:29 +00002518 return 0;
2519}
2520
2521/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002522static void
paul718e3742002-12-13 20:15:29 +00002523ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2524{
2525 struct ospf_header *ospfh;
2526
2527 ospfh = (struct ospf_header *) STREAM_DATA (s);
2528
2529 ospfh->version = (u_char) OSPF_VERSION;
2530 ospfh->type = (u_char) type;
2531
paul68980082003-03-25 05:07:42 +00002532 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002533
2534 ospfh->checksum = 0;
2535 ospfh->area_id = oi->area->area_id;
2536 ospfh->auth_type = htons (ospf_auth_type (oi));
2537
2538 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2539
paul9985f832005-02-09 15:51:56 +00002540 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002541}
2542
2543/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002544static int
paul718e3742002-12-13 20:15:29 +00002545ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2546{
2547 struct crypt_key *ck;
2548
2549 switch (ospf_auth_type (oi))
2550 {
2551 case OSPF_AUTH_NULL:
2552 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2553 break;
2554 case OSPF_AUTH_SIMPLE:
2555 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2556 OSPF_AUTH_SIMPLE_SIZE);
2557 break;
2558 case OSPF_AUTH_CRYPTOGRAPHIC:
2559 /* If key is not set, then set 0. */
2560 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2561 {
2562 ospfh->u.crypt.zero = 0;
2563 ospfh->u.crypt.key_id = 0;
2564 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2565 }
2566 else
2567 {
paul1eb8ef22005-04-07 07:30:20 +00002568 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002569 ospfh->u.crypt.zero = 0;
2570 ospfh->u.crypt.key_id = ck->key_id;
2571 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2572 }
2573 /* note: the seq is done in ospf_make_md5_digest() */
2574 break;
2575 default:
2576 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2577 break;
2578 }
2579
2580 return 0;
2581}
2582
2583/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002584static void
paul718e3742002-12-13 20:15:29 +00002585ospf_fill_header (struct ospf_interface *oi,
2586 struct stream *s, u_int16_t length)
2587{
2588 struct ospf_header *ospfh;
2589
2590 ospfh = (struct ospf_header *) STREAM_DATA (s);
2591
2592 /* Fill length. */
2593 ospfh->length = htons (length);
2594
2595 /* Calculate checksum. */
2596 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2597 ospfh->checksum = in_cksum (ospfh, length);
2598 else
2599 ospfh->checksum = 0;
2600
2601 /* Add Authentication Data. */
2602 ospf_make_auth (oi, ospfh);
2603}
2604
paul4dadc292005-05-06 21:37:42 +00002605static int
paul718e3742002-12-13 20:15:29 +00002606ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2607{
2608 struct ospf_neighbor *nbr;
2609 struct route_node *rn;
2610 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2611 struct in_addr mask;
2612 unsigned long p;
2613 int flag = 0;
2614
2615 /* Set netmask of interface. */
2616 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2617 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2618 masklen2ip (oi->address->prefixlen, &mask);
2619 else
2620 memset ((char *) &mask, 0, sizeof (struct in_addr));
2621 stream_put_ipv4 (s, mask.s_addr);
2622
2623 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002624 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2625 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2626 else
2627 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002628
2629 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002630 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002631 OPTIONS(oi), IF_NAME (oi));
2632
2633 /* Set Options. */
2634 stream_putc (s, OPTIONS (oi));
2635
2636 /* Set Router Priority. */
2637 stream_putc (s, PRIORITY (oi));
2638
2639 /* Set Router Dead Interval. */
2640 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2641
2642 /* Set Designated Router. */
2643 stream_put_ipv4 (s, DR (oi).s_addr);
2644
paul9985f832005-02-09 15:51:56 +00002645 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002646
2647 /* Set Backup Designated Router. */
2648 stream_put_ipv4 (s, BDR (oi).s_addr);
2649
2650 /* Add neighbor seen. */
2651 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002652 if ((nbr = rn->info))
2653 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2654 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2655 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2656 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002657 {
2658 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002659 if (nbr->d_router.s_addr != 0
2660 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2661 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2662 flag = 1;
paul718e3742002-12-13 20:15:29 +00002663
2664 stream_put_ipv4 (s, nbr->router_id.s_addr);
2665 length += 4;
2666 }
2667
2668 /* Let neighbor generate BackupSeen. */
2669 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002670 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002671
2672 return length;
2673}
2674
paul4dadc292005-05-06 21:37:42 +00002675static int
paul718e3742002-12-13 20:15:29 +00002676ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2677 struct stream *s)
2678{
2679 struct ospf_lsa *lsa;
2680 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2681 u_char options;
2682 unsigned long pp;
2683 int i;
2684 struct ospf_lsdb *lsdb;
2685
2686 /* Set Interface MTU. */
2687 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2688 stream_putw (s, 0);
2689 else
2690 stream_putw (s, oi->ifp->mtu);
2691
2692 /* Set Options. */
2693 options = OPTIONS (oi);
2694#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002695 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002696 {
2697 if (IS_SET_DD_I (nbr->dd_flags)
2698 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2699 /*
2700 * Set O-bit in the outgoing DD packet for capablity negotiation,
2701 * if one of following case is applicable.
2702 *
2703 * 1) WaitTimer expiration event triggered the neighbor state to
2704 * change to Exstart, but no (valid) DD packet has received
2705 * from the neighbor yet.
2706 *
2707 * 2) At least one DD packet with O-bit on has received from the
2708 * neighbor.
2709 */
2710 SET_FLAG (options, OSPF_OPTION_O);
2711 }
2712#endif /* HAVE_OPAQUE_LSA */
2713 stream_putc (s, options);
2714
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002715 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002716 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002717 stream_putc (s, nbr->dd_flags);
2718
2719 /* Set DD Sequence Number. */
2720 stream_putl (s, nbr->dd_seqnum);
2721
Paul Jakmab5aeb442006-08-30 18:47:37 +00002722 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002723 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002724 goto empty;
paul718e3742002-12-13 20:15:29 +00002725
2726 /* Describe LSA Header from Database Summary List. */
2727 lsdb = &nbr->db_sum;
2728
2729 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2730 {
2731 struct route_table *table = lsdb->type[i].db;
2732 struct route_node *rn;
2733
2734 for (rn = route_top (table); rn; rn = route_next (rn))
2735 if ((lsa = rn->info) != NULL)
2736 {
2737#ifdef HAVE_OPAQUE_LSA
2738 if (IS_OPAQUE_LSA (lsa->data->type)
2739 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2740 {
2741 /* Suppress advertising opaque-informations. */
2742 /* Remove LSA from DB summary list. */
2743 ospf_lsdb_delete (lsdb, lsa);
2744 continue;
2745 }
2746#endif /* HAVE_OPAQUE_LSA */
2747
2748 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2749 {
2750 struct lsa_header *lsah;
2751 u_int16_t ls_age;
2752
2753 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002754 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002755 break;
2756
2757 /* Keep pointer to LS age. */
2758 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002759 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002760
2761 /* Proceed stream pointer. */
2762 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2763 length += OSPF_LSA_HEADER_SIZE;
2764
2765 /* Set LS age. */
2766 ls_age = LS_AGE (lsa);
2767 lsah->ls_age = htons (ls_age);
2768
2769 }
2770
2771 /* Remove LSA from DB summary list. */
2772 ospf_lsdb_delete (lsdb, lsa);
2773 }
2774 }
2775
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002776 /* Update 'More' bit */
2777 if (ospf_db_summary_isempty (nbr))
2778 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002779empty:
2780 if (nbr->state >= NSM_Exchange)
2781 {
2782 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2783 /* Rewrite DD flags */
2784 stream_putc_at (s, pp, nbr->dd_flags);
2785 }
2786 else
2787 {
2788 assert (IS_SET_DD_M(nbr->dd_flags));
2789 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002790 }
paul718e3742002-12-13 20:15:29 +00002791 return length;
2792}
2793
paul4dadc292005-05-06 21:37:42 +00002794static int
paul718e3742002-12-13 20:15:29 +00002795ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2796 unsigned long delta, struct ospf_neighbor *nbr,
2797 struct ospf_lsa *lsa)
2798{
2799 struct ospf_interface *oi;
2800
2801 oi = nbr->oi;
2802
2803 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002804 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002805 return 0;
2806
2807 stream_putl (s, lsa->data->type);
2808 stream_put_ipv4 (s, lsa->data->id.s_addr);
2809 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2810
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002811 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002812 nbr->ls_req_last = ospf_lsa_lock (lsa);
2813
2814 *length += 12;
2815 return 1;
2816}
2817
paul4dadc292005-05-06 21:37:42 +00002818static int
paul718e3742002-12-13 20:15:29 +00002819ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2820{
2821 struct ospf_lsa *lsa;
2822 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002823 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002824 struct route_table *table;
2825 struct route_node *rn;
2826 int i;
2827 struct ospf_lsdb *lsdb;
2828
2829 lsdb = &nbr->ls_req;
2830
2831 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2832 {
2833 table = lsdb->type[i].db;
2834 for (rn = route_top (table); rn; rn = route_next (rn))
2835 if ((lsa = (rn->info)) != NULL)
2836 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2837 {
2838 route_unlock_node (rn);
2839 break;
2840 }
2841 }
2842 return length;
2843}
2844
paul4dadc292005-05-06 21:37:42 +00002845static int
paul718e3742002-12-13 20:15:29 +00002846ls_age_increment (struct ospf_lsa *lsa, int delay)
2847{
2848 int age;
2849
2850 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2851
2852 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2853}
2854
paul4dadc292005-05-06 21:37:42 +00002855static int
hasso52dc7ee2004-09-23 19:18:23 +00002856ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002857{
2858 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002859 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002860 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002861 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002862 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002863 unsigned long pp;
2864 int count = 0;
2865
2866 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002867 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002868
paul9985f832005-02-09 15:51:56 +00002869 pp = stream_get_endp (s);
2870 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002871
gdt86f1fd92005-01-10 14:20:43 +00002872 /* Calculate amount of packet usable for data. */
2873 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2874
paul718e3742002-12-13 20:15:29 +00002875 while ((node = listhead (update)) != NULL)
2876 {
2877 struct lsa_header *lsah;
2878 u_int16_t ls_age;
2879
2880 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002881 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002882
paul1eb8ef22005-04-07 07:30:20 +00002883 lsa = listgetdata (node);
2884
paul718e3742002-12-13 20:15:29 +00002885 assert (lsa->data);
2886
paul68b73392004-09-12 14:21:37 +00002887 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002888 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002889 break;
2890
paul718e3742002-12-13 20:15:29 +00002891 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002892 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002893
2894 /* Put LSA to Link State Request. */
2895 stream_put (s, lsa->data, ntohs (lsa->data->length));
2896
2897 /* Set LS age. */
2898 /* each hop must increment an lsa_age by transmit_delay
2899 of OSPF interface */
2900 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2901 lsah->ls_age = htons (ls_age);
2902
2903 length += ntohs (lsa->data->length);
2904 count++;
2905
2906 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002907 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002908 }
2909
2910 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002911 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002912
2913 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002914 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002915 return length;
2916}
2917
paul4dadc292005-05-06 21:37:42 +00002918static int
hasso52dc7ee2004-09-23 19:18:23 +00002919ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002920{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002921 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002922 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002923 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002924 struct ospf_lsa *lsa;
2925
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002926 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002927 {
paul718e3742002-12-13 20:15:29 +00002928 assert (lsa);
2929
gdt86f1fd92005-01-10 14:20:43 +00002930 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002931 break;
2932
2933 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2934 length += OSPF_LSA_HEADER_SIZE;
2935
paul718e3742002-12-13 20:15:29 +00002936 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002937 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002938 }
2939
paul718e3742002-12-13 20:15:29 +00002940 return length;
2941}
2942
2943void
2944ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2945{
2946 struct ospf_packet *op;
2947 u_int16_t length = OSPF_HEADER_SIZE;
2948
2949 op = ospf_packet_new (oi->ifp->mtu);
2950
2951 /* Prepare OSPF common header. */
2952 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2953
2954 /* Prepare OSPF Hello body. */
2955 length += ospf_make_hello (oi, op->s);
2956
2957 /* Fill OSPF header. */
2958 ospf_fill_header (oi, op->s, length);
2959
2960 /* Set packet length. */
2961 op->length = length;
2962
2963 op->dst.s_addr = addr->s_addr;
2964
2965 /* Add packet to the interface output queue. */
2966 ospf_packet_add (oi, op);
2967
2968 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002969 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002970}
2971
paul4dadc292005-05-06 21:37:42 +00002972static void
paul718e3742002-12-13 20:15:29 +00002973ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2974{
2975 struct ospf_interface *oi;
2976
2977 oi = nbr_nbma->oi;
2978 assert(oi);
2979
2980 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00002981 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00002982 return;
2983
2984 if (oi->type != OSPF_IFTYPE_NBMA)
2985 return;
2986
2987 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2988 return;
2989
2990 if (PRIORITY(oi) == 0)
2991 return;
2992
2993 if (nbr_nbma->priority == 0
2994 && oi->state != ISM_DR && oi->state != ISM_Backup)
2995 return;
2996
2997 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2998}
2999
3000int
3001ospf_poll_timer (struct thread *thread)
3002{
3003 struct ospf_nbr_nbma *nbr_nbma;
3004
3005 nbr_nbma = THREAD_ARG (thread);
3006 nbr_nbma->t_poll = NULL;
3007
3008 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003009 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003010 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3011
3012 ospf_poll_send (nbr_nbma);
3013
3014 if (nbr_nbma->v_poll > 0)
3015 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3016 nbr_nbma->v_poll);
3017
3018 return 0;
3019}
3020
3021
3022int
3023ospf_hello_reply_timer (struct thread *thread)
3024{
3025 struct ospf_neighbor *nbr;
3026
3027 nbr = THREAD_ARG (thread);
3028 nbr->t_hello_reply = NULL;
3029
3030 assert (nbr->oi);
3031
3032 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003033 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003034 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3035
3036 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3037
3038 return 0;
3039}
3040
3041/* Send OSPF Hello. */
3042void
3043ospf_hello_send (struct ospf_interface *oi)
3044{
3045 struct ospf_packet *op;
3046 u_int16_t length = OSPF_HEADER_SIZE;
3047
3048 /* If this is passive interface, do not send OSPF Hello. */
Paul Jakma7ffa8fa2006-10-22 20:07:53 +00003049 if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)
paul718e3742002-12-13 20:15:29 +00003050 return;
3051
3052 op = ospf_packet_new (oi->ifp->mtu);
3053
3054 /* Prepare OSPF common header. */
3055 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3056
3057 /* Prepare OSPF Hello body. */
3058 length += ospf_make_hello (oi, op->s);
3059
3060 /* Fill OSPF header. */
3061 ospf_fill_header (oi, op->s, length);
3062
3063 /* Set packet length. */
3064 op->length = length;
3065
3066 if (oi->type == OSPF_IFTYPE_NBMA)
3067 {
3068 struct ospf_neighbor *nbr;
3069 struct route_node *rn;
3070
3071 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3072 if ((nbr = rn->info))
3073 if (nbr != oi->nbr_self)
3074 if (nbr->state != NSM_Down)
3075 {
3076 /* RFC 2328 Section 9.5.1
3077 If the router is not eligible to become Designated Router,
3078 it must periodically send Hello Packets to both the
3079 Designated Router and the Backup Designated Router (if they
3080 exist). */
3081 if (PRIORITY(oi) == 0 &&
3082 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3083 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3084 continue;
3085
3086 /* If the router is eligible to become Designated Router, it
3087 must periodically send Hello Packets to all neighbors that
3088 are also eligible. In addition, if the router is itself the
3089 Designated Router or Backup Designated Router, it must also
3090 send periodic Hello Packets to all other neighbors. */
3091
3092 if (nbr->priority == 0 && oi->state == ISM_DROther)
3093 continue;
3094 /* if oi->state == Waiting, send hello to all neighbors */
3095 {
3096 struct ospf_packet *op_dup;
3097
3098 op_dup = ospf_packet_dup(op);
3099 op_dup->dst = nbr->address.u.prefix4;
3100
3101 /* Add packet to the interface output queue. */
3102 ospf_packet_add (oi, op_dup);
3103
paul020709f2003-04-04 02:44:16 +00003104 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003105 }
3106
3107 }
3108 ospf_packet_free (op);
3109 }
3110 else
3111 {
3112 /* Decide destination address. */
3113 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3114 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3115 else
3116 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3117
3118 /* Add packet to the interface output queue. */
3119 ospf_packet_add (oi, op);
3120
3121 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003122 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003123 }
3124}
3125
3126/* Send OSPF Database Description. */
3127void
3128ospf_db_desc_send (struct ospf_neighbor *nbr)
3129{
3130 struct ospf_interface *oi;
3131 struct ospf_packet *op;
3132 u_int16_t length = OSPF_HEADER_SIZE;
3133
3134 oi = nbr->oi;
3135 op = ospf_packet_new (oi->ifp->mtu);
3136
3137 /* Prepare OSPF common header. */
3138 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3139
3140 /* Prepare OSPF Database Description body. */
3141 length += ospf_make_db_desc (oi, nbr, op->s);
3142
3143 /* Fill OSPF header. */
3144 ospf_fill_header (oi, op->s, length);
3145
3146 /* Set packet length. */
3147 op->length = length;
3148
3149 /* Decide destination address. */
3150 op->dst = nbr->address.u.prefix4;
3151
3152 /* Add packet to the interface output queue. */
3153 ospf_packet_add (oi, op);
3154
3155 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003156 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003157
3158 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3159 if (nbr->last_send)
3160 ospf_packet_free (nbr->last_send);
3161 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003162 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003163}
3164
3165/* Re-send Database Description. */
3166void
3167ospf_db_desc_resend (struct ospf_neighbor *nbr)
3168{
3169 struct ospf_interface *oi;
3170
3171 oi = nbr->oi;
3172
3173 /* Add packet to the interface output queue. */
3174 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3175
3176 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003177 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003178}
3179
3180/* Send Link State Request. */
3181void
3182ospf_ls_req_send (struct ospf_neighbor *nbr)
3183{
3184 struct ospf_interface *oi;
3185 struct ospf_packet *op;
3186 u_int16_t length = OSPF_HEADER_SIZE;
3187
3188 oi = nbr->oi;
3189 op = ospf_packet_new (oi->ifp->mtu);
3190
3191 /* Prepare OSPF common header. */
3192 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3193
3194 /* Prepare OSPF Link State Request body. */
3195 length += ospf_make_ls_req (nbr, op->s);
3196 if (length == OSPF_HEADER_SIZE)
3197 {
3198 ospf_packet_free (op);
3199 return;
3200 }
3201
3202 /* Fill OSPF header. */
3203 ospf_fill_header (oi, op->s, length);
3204
3205 /* Set packet length. */
3206 op->length = length;
3207
3208 /* Decide destination address. */
3209 op->dst = nbr->address.u.prefix4;
3210
3211 /* Add packet to the interface output queue. */
3212 ospf_packet_add (oi, op);
3213
3214 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003215 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003216
3217 /* Add Link State Request Retransmission Timer. */
3218 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3219}
3220
3221/* Send Link State Update with an LSA. */
3222void
3223ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3224 int flag)
3225{
hasso52dc7ee2004-09-23 19:18:23 +00003226 struct list *update;
paul718e3742002-12-13 20:15:29 +00003227
3228 update = list_new ();
3229
3230 listnode_add (update, lsa);
3231 ospf_ls_upd_send (nbr, update, flag);
3232
3233 list_delete (update);
3234}
3235
paul68b73392004-09-12 14:21:37 +00003236/* Determine size for packet. Must be at least big enough to accomodate next
3237 * LSA on list, which may be bigger than MTU size.
3238 *
3239 * Return pointer to new ospf_packet
3240 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3241 * on packet sizes (in which case offending LSA is deleted from update list)
3242 */
3243static struct ospf_packet *
3244ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3245{
3246 struct ospf_lsa *lsa;
3247 struct listnode *ln;
3248 size_t size;
3249 static char warned = 0;
3250
paul1eb8ef22005-04-07 07:30:20 +00003251 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003252 assert (lsa->data);
3253
3254 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3255 > ospf_packet_max (oi))
3256 {
3257 if (!warned)
3258 {
3259 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3260 "will need to fragment. Not optimal. Try divide up"
3261 " your network with areas. Use 'debug ospf packet send'"
3262 " to see details, or look at 'show ip ospf database ..'");
3263 warned = 1;
3264 }
3265
3266 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003267 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003268 " %d bytes originated by %s, will be fragmented!",
3269 inet_ntoa (lsa->data->id),
3270 ntohs (lsa->data->length),
3271 inet_ntoa (lsa->data->adv_router));
3272
3273 /*
3274 * Allocate just enough to fit this LSA only, to avoid including other
3275 * LSAs in fragmented LSA Updates.
3276 */
3277 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3278 + OSPF_LS_UPD_MIN_SIZE;
3279 }
3280 else
3281 size = oi->ifp->mtu;
3282
gdt86f1fd92005-01-10 14:20:43 +00003283 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003284 if (size > OSPF_MAX_PACKET_SIZE)
3285 {
3286 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003287 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003288 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003289 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003290 (long int) size);
paul68b73392004-09-12 14:21:37 +00003291 list_delete_node (update, ln);
3292 return NULL;
3293 }
3294
3295 return ospf_packet_new (size);
3296}
3297
paul718e3742002-12-13 20:15:29 +00003298static void
hasso52dc7ee2004-09-23 19:18:23 +00003299ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003300 struct in_addr addr)
3301{
3302 struct ospf_packet *op;
3303 u_int16_t length = OSPF_HEADER_SIZE;
3304
3305 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003306 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003307
3308 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003309
3310 /* Prepare OSPF common header. */
3311 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3312
paul59ea14c2004-07-14 20:50:36 +00003313 /* Prepare OSPF Link State Update body.
3314 * Includes Type-7 translation.
3315 */
paul718e3742002-12-13 20:15:29 +00003316 length += ospf_make_ls_upd (oi, update, op->s);
3317
3318 /* Fill OSPF header. */
3319 ospf_fill_header (oi, op->s, length);
3320
3321 /* Set packet length. */
3322 op->length = length;
3323
3324 /* Decide destination address. */
3325 op->dst.s_addr = addr.s_addr;
3326
3327 /* Add packet to the interface output queue. */
3328 ospf_packet_add (oi, op);
3329
3330 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003331 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003332}
3333
3334static int
3335ospf_ls_upd_send_queue_event (struct thread *thread)
3336{
3337 struct ospf_interface *oi = THREAD_ARG(thread);
3338 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003339 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003340 struct list *update;
paul68b73392004-09-12 14:21:37 +00003341 char again = 0;
paul718e3742002-12-13 20:15:29 +00003342
3343 oi->t_ls_upd_event = NULL;
3344
3345 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003346 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003347
paul736d3442003-07-24 23:22:57 +00003348 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003349 {
paul736d3442003-07-24 23:22:57 +00003350 rnext = route_next (rn);
3351
paul718e3742002-12-13 20:15:29 +00003352 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003353 continue;
paul68b73392004-09-12 14:21:37 +00003354
3355 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003356
paul48fe13b2004-07-27 17:40:44 +00003357 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003358
paul68b73392004-09-12 14:21:37 +00003359 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003360 if (listcount(update) == 0)
3361 {
3362 list_delete (rn->info);
3363 rn->info = NULL;
3364 route_unlock_node (rn);
3365 }
3366 else
paul68b73392004-09-12 14:21:37 +00003367 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003368 }
3369
3370 if (again != 0)
3371 {
3372 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003373 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003374 " %d nodes to try again, raising new event", again);
3375 oi->t_ls_upd_event =
3376 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003377 }
3378
3379 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003380 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003381
paul718e3742002-12-13 20:15:29 +00003382 return 0;
3383}
3384
3385void
hasso52dc7ee2004-09-23 19:18:23 +00003386ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003387{
3388 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003389 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003390 struct prefix_ipv4 p;
3391 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003392 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003393
3394 oi = nbr->oi;
3395
3396 p.family = AF_INET;
3397 p.prefixlen = IPV4_MAX_BITLEN;
3398
3399 /* Decide destination address. */
3400 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3401 p.prefix = oi->vl_data->peer_addr;
3402 else if (flag == OSPF_SEND_PACKET_DIRECT)
3403 p.prefix = nbr->address.u.prefix4;
3404 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3405 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3406 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3407 && (flag == OSPF_SEND_PACKET_INDIRECT))
3408 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003409 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3410 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003411 else
3412 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3413
3414 if (oi->type == OSPF_IFTYPE_NBMA)
3415 {
3416 if (flag == OSPF_SEND_PACKET_INDIRECT)
3417 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3418 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3419 zlog_warn ("* LS-Update is sent to myself.");
3420 }
3421
3422 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3423
3424 if (rn->info == NULL)
3425 rn->info = list_new ();
3426
paul1eb8ef22005-04-07 07:30:20 +00003427 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003428 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003429
3430 if (oi->t_ls_upd_event == NULL)
3431 oi->t_ls_upd_event =
3432 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3433}
3434
3435static void
hasso52dc7ee2004-09-23 19:18:23 +00003436ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3437 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003438{
3439 struct ospf_packet *op;
3440 u_int16_t length = OSPF_HEADER_SIZE;
3441
3442 op = ospf_packet_new (oi->ifp->mtu);
3443
3444 /* Prepare OSPF common header. */
3445 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3446
3447 /* Prepare OSPF Link State Acknowledgment body. */
3448 length += ospf_make_ls_ack (oi, ack, op->s);
3449
3450 /* Fill OSPF header. */
3451 ospf_fill_header (oi, op->s, length);
3452
3453 /* Set packet length. */
3454 op->length = length;
3455
3456 /* Set destination IP address. */
3457 op->dst = dst;
3458
3459 /* Add packet to the interface output queue. */
3460 ospf_packet_add (oi, op);
3461
3462 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003463 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003464}
3465
3466static int
3467ospf_ls_ack_send_event (struct thread *thread)
3468{
3469 struct ospf_interface *oi = THREAD_ARG (thread);
3470
3471 oi->t_ls_ack_direct = NULL;
3472
3473 while (listcount (oi->ls_ack_direct.ls_ack))
3474 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3475 oi->ls_ack_direct.dst);
3476
3477 return 0;
3478}
3479
3480void
3481ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3482{
3483 struct ospf_interface *oi = nbr->oi;
3484
3485 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3486 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3487
3488 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3489
3490 if (oi->t_ls_ack_direct == NULL)
3491 oi->t_ls_ack_direct =
3492 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3493}
3494
3495/* Send Link State Acknowledgment delayed. */
3496void
3497ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3498{
3499 struct in_addr dst;
3500
3501 /* Decide destination address. */
3502 /* RFC2328 Section 13.5 On non-broadcast
3503 networks, delayed Link State Acknowledgment packets must be
3504 unicast separately over each adjacency (i.e., neighbor whose
3505 state is >= Exchange). */
3506 if (oi->type == OSPF_IFTYPE_NBMA)
3507 {
3508 struct ospf_neighbor *nbr;
3509 struct route_node *rn;
3510
3511 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3512 if ((nbr = rn->info) != NULL)
3513 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3514 while (listcount (oi->ls_ack))
3515 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3516 return;
3517 }
3518 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3519 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3520 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3521 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3522 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3523 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003524 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3525 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003526 else
3527 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3528
3529 while (listcount (oi->ls_ack))
3530 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3531}