blob: 44dca1817848b1a5f24809296f1601233250dd4f [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)
219 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000220 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000221
222 /* Reserve space for MD5 authentication that may be added later. */
223 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000224 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000225
226 new->dst = op->dst;
227 new->length = op->length;
228
229 return new;
230}
231
gdt86f1fd92005-01-10 14:20:43 +0000232/* XXX inline */
paul4dadc292005-05-06 21:37:42 +0000233static inline unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000234ospf_packet_authspace (struct ospf_interface *oi)
235{
236 int auth = 0;
237
238 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
239 auth = OSPF_AUTH_MD5_SIZE;
240
241 return auth;
242}
243
paul4dadc292005-05-06 21:37:42 +0000244static unsigned int
paul718e3742002-12-13 20:15:29 +0000245ospf_packet_max (struct ospf_interface *oi)
246{
247 int max;
248
gdt86f1fd92005-01-10 14:20:43 +0000249 max = oi->ifp->mtu - ospf_packet_authspace(oi);
250
paul68b73392004-09-12 14:21:37 +0000251 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000252
253 return max;
254}
255
256
paul4dadc292005-05-06 21:37:42 +0000257static int
paul718e3742002-12-13 20:15:29 +0000258ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
259 u_int16_t length)
260{
paul6c835672004-10-11 11:00:30 +0000261 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000262 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000263 unsigned char digest[OSPF_AUTH_MD5_SIZE];
264 unsigned char *pdigest;
265 struct crypt_key *ck;
266 struct ospf_header *ospfh;
267 struct ospf_neighbor *nbr;
268
269
270 ibuf = STREAM_PNT (s);
271 ospfh = (struct ospf_header *) ibuf;
272
273 /* Get pointer to the end of the packet. */
274 pdigest = ibuf + length;
275
276 /* Get secret key. */
277 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
278 ospfh->u.crypt.key_id);
279 if (ck == NULL)
280 {
281 zlog_warn ("interface %s: ospf_check_md5 no key %d",
282 IF_NAME (oi), ospfh->u.crypt.key_id);
283 return 0;
284 }
285
286 /* check crypto seqnum. */
287 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
288
289 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
290 {
291 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
292 IF_NAME (oi),
293 ntohl(ospfh->u.crypt.crypt_seqnum),
294 ntohl(nbr->crypt_seqnum));
295 return 0;
296 }
297
298 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000299 memset(&ctx, 0, sizeof(ctx));
300 MD5Init(&ctx);
301 MD5Update(&ctx, ibuf, length);
302 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
303 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000304
305 /* compare the two */
306 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
307 {
308 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
309 IF_NAME (oi));
310 return 0;
311 }
312
313 /* save neighbor's crypt_seqnum */
314 if (nbr)
315 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
316 return 1;
317}
318
319/* This function is called from ospf_write(), it will detect the
320 authentication scheme and if it is MD5, it will change the sequence
321 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000322static int
paul718e3742002-12-13 20:15:29 +0000323ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
324{
325 struct ospf_header *ospfh;
326 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000327 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000328 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000329 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000330 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000331 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000332
333 ibuf = STREAM_DATA (op->s);
334 ospfh = (struct ospf_header *) ibuf;
335
336 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
337 return 0;
338
339 /* We do this here so when we dup a packet, we don't have to
340 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000341 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000342 if (t > oi->crypt_seqnum)
343 oi->crypt_seqnum = t;
344 else
345 oi->crypt_seqnum++;
346
paul9483e152002-12-13 20:55:25 +0000347 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000348
349 /* Get MD5 Authentication key from auth_key list. */
350 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000351 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000352 else
353 {
paul1eb8ef22005-04-07 07:30:20 +0000354 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000355 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000356 }
357
358 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000359 memset(&ctx, 0, sizeof(ctx));
360 MD5Init(&ctx);
361 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
362 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
363 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000364
365 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000366 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000367
368 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000369 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
370
paul37163d62003-02-03 18:40:56 +0000371 if (stream_get_endp(op->s) != op->length)
372 zlog_warn("ospf_make_md5_digest: length mismatch stream %ld ospf_packet %d", stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000373
374 return OSPF_AUTH_MD5_SIZE;
375}
376
377
paul4dadc292005-05-06 21:37:42 +0000378static int
paul718e3742002-12-13 20:15:29 +0000379ospf_ls_req_timer (struct thread *thread)
380{
381 struct ospf_neighbor *nbr;
382
383 nbr = THREAD_ARG (thread);
384 nbr->t_ls_req = NULL;
385
386 /* Send Link State Request. */
387 if (ospf_ls_request_count (nbr))
388 ospf_ls_req_send (nbr);
389
390 /* Set Link State Request retransmission timer. */
391 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
392
393 return 0;
394}
395
396void
397ospf_ls_req_event (struct ospf_neighbor *nbr)
398{
399 if (nbr->t_ls_req)
400 {
401 thread_cancel (nbr->t_ls_req);
402 nbr->t_ls_req = NULL;
403 }
404 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
405}
406
407/* Cyclic timer function. Fist registered in ospf_nbr_new () in
408 ospf_neighbor.c */
409int
410ospf_ls_upd_timer (struct thread *thread)
411{
412 struct ospf_neighbor *nbr;
413
414 nbr = THREAD_ARG (thread);
415 nbr->t_ls_upd = NULL;
416
417 /* Send Link State Update. */
418 if (ospf_ls_retransmit_count (nbr) > 0)
419 {
hasso52dc7ee2004-09-23 19:18:23 +0000420 struct list *update;
paul718e3742002-12-13 20:15:29 +0000421 struct ospf_lsdb *lsdb;
422 int i;
paul718e3742002-12-13 20:15:29 +0000423 int retransmit_interval;
424
paul718e3742002-12-13 20:15:29 +0000425 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
426
427 lsdb = &nbr->ls_rxmt;
428 update = list_new ();
429
430 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
431 {
432 struct route_table *table = lsdb->type[i].db;
433 struct route_node *rn;
434
435 for (rn = route_top (table); rn; rn = route_next (rn))
436 {
437 struct ospf_lsa *lsa;
438
439 if ((lsa = rn->info) != NULL)
440 /* Don't retransmit an LSA if we received it within
441 the last RxmtInterval seconds - this is to allow the
442 neighbour a chance to acknowledge the LSA as it may
443 have ben just received before the retransmit timer
444 fired. This is a small tweak to what is in the RFC,
445 but it will cut out out a lot of retransmit traffic
446 - MAG */
pauld24f6e22005-10-21 09:23:12 +0000447 if (tv_cmp (tv_sub (recent_time, lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000448 int2tv (retransmit_interval)) >= 0)
449 listnode_add (update, rn->info);
450 }
451 }
452
453 if (listcount (update) > 0)
454 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
455 list_delete (update);
456 }
457
458 /* Set LS Update retransmission timer. */
459 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
460
461 return 0;
462}
463
464int
465ospf_ls_ack_timer (struct thread *thread)
466{
467 struct ospf_interface *oi;
468
469 oi = THREAD_ARG (thread);
470 oi->t_ls_ack = NULL;
471
472 /* Send Link State Acknowledgment. */
473 if (listcount (oi->ls_ack) > 0)
474 ospf_ls_ack_send_delayed (oi);
475
476 /* Set LS Ack timer. */
477 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
478
479 return 0;
480}
481
paul0bfeca32004-09-24 08:07:54 +0000482#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000483static void
paul6a99f832004-09-27 12:56:30 +0000484ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000485 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000486 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000487{
488#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000489 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000490 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000491 int ret;
paul0bfeca32004-09-24 08:07:54 +0000492
493 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000494 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000495
496 /* we can but try.
497 *
498 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
499 * well as the IP_MF flag, making this all quite pointless.
500 *
501 * However, for a system on which IP_MF is left alone, and ip_id left
502 * alone or else which sets same ip_id for each fragment this might
503 * work, eg linux.
504 *
505 * XXX-TODO: It would be much nicer to have the kernel's use their
506 * existing fragmentation support to do this for us. Bugs/RFEs need to
507 * be raised against the various kernels.
508 */
509
510 /* set More Frag */
511 iph->ip_off |= IP_MF;
512
513 /* ip frag offset is expressed in units of 8byte words */
514 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
515
paul62d8e962004-11-02 20:26:45 +0000516 iovp = &msg->msg_iov[1];
517
paul0bfeca32004-09-24 08:07:54 +0000518 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
519 > maxdatasize )
520 {
521 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000522 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
523 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000524 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000525
paul18b12c32004-10-05 14:38:29 +0000526 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000527
paul6a99f832004-09-27 12:56:30 +0000528 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000529
paul18b12c32004-10-05 14:38:29 +0000530 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000531
532 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000533 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000534 " id %d, off %d, len %d, mtu %u failed with %s",
535 inet_ntoa (iph->ip_dst),
536 iph->ip_id,
537 iph->ip_off,
538 iph->ip_len,
539 mtu,
540 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000541
paul37ccfa32004-10-31 11:24:51 +0000542 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
543 {
ajs2a42e282004-12-08 18:43:03 +0000544 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000545 iph->ip_id, iph->ip_off, iph->ip_len,
546 inet_ntoa (iph->ip_dst));
547 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
548 {
ajs2a42e282004-12-08 18:43:03 +0000549 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000550 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000551 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000552 }
553 }
554
paul0bfeca32004-09-24 08:07:54 +0000555 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000556 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000557 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000558 }
559
560 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000561 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
562 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000563 iph->ip_off &= (~IP_MF);
564}
565#endif /* WANT_OSPF_WRITE_FRAGMENT */
566
ajs5dcbdf82005-03-29 16:13:49 +0000567static int
paul718e3742002-12-13 20:15:29 +0000568ospf_write (struct thread *thread)
569{
paul68980082003-03-25 05:07:42 +0000570 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000571 struct ospf_interface *oi;
572 struct ospf_packet *op;
573 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000574 struct ip iph;
575 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000576 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000577 u_char type;
578 int ret;
579 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000580 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000581#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000582 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000583#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000584 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000585#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000586
paul68980082003-03-25 05:07:42 +0000587 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000588
paul68980082003-03-25 05:07:42 +0000589 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000590 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000591 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000592 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000593
594#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000595 /* seed ipid static with low order bits of time */
596 if (ipid == 0)
597 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000598#endif /* WANT_OSPF_WRITE_FRAGMENT */
599
paul68b73392004-09-12 14:21:37 +0000600 /* convenience - max OSPF data per packet */
601 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
602
paul718e3742002-12-13 20:15:29 +0000603 /* Get one packet from queue. */
604 op = ospf_fifo_head (oi->obuf);
605 assert (op);
606 assert (op->length >= OSPF_HEADER_SIZE);
607
paul68980082003-03-25 05:07:42 +0000608 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
609 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000610 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
611
paul718e3742002-12-13 20:15:29 +0000612 /* Rewrite the md5 signature & update the seq */
613 ospf_make_md5_digest (oi, op);
614
paul37ccfa32004-10-31 11:24:51 +0000615 /* Retrieve OSPF packet type. */
616 stream_set_getp (op->s, 1);
617 type = stream_getc (op->s);
618
paul68b73392004-09-12 14:21:37 +0000619 /* reset get pointer */
620 stream_set_getp (op->s, 0);
621
622 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000623 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000624
paul718e3742002-12-13 20:15:29 +0000625 sa_dst.sin_family = AF_INET;
626#ifdef HAVE_SIN_LEN
627 sa_dst.sin_len = sizeof(sa_dst);
628#endif /* HAVE_SIN_LEN */
629 sa_dst.sin_addr = op->dst;
630 sa_dst.sin_port = htons (0);
631
632 /* Set DONTROUTE flag if dst is unicast. */
633 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
634 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
635 flags = MSG_DONTROUTE;
636
paul68b73392004-09-12 14:21:37 +0000637 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
638 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000639 if ( sizeof (struct ip)
640 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000641 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
642
paul718e3742002-12-13 20:15:29 +0000643 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000644 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000645 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000646
paul0bfeca32004-09-24 08:07:54 +0000647#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000648 /* XXX-MT: not thread-safe at all..
649 * XXX: this presumes this is only programme sending OSPF packets
650 * otherwise, no guarantee ipid will be unique
651 */
652 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000653#endif /* WANT_OSPF_WRITE_FRAGMENT */
654
paul718e3742002-12-13 20:15:29 +0000655 iph.ip_off = 0;
656 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
657 iph.ip_ttl = OSPF_VL_IP_TTL;
658 else
659 iph.ip_ttl = OSPF_IP_TTL;
660 iph.ip_p = IPPROTO_OSPFIGP;
661 iph.ip_sum = 0;
662 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
663 iph.ip_dst.s_addr = op->dst.s_addr;
664
665 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000666 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000667 msg.msg_namelen = sizeof (sa_dst);
668 msg.msg_iov = iov;
669 msg.msg_iovlen = 2;
670 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000671 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
672 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000673 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000674
675 /* Sadly we can not rely on kernels to fragment packets because of either
676 * IP_HDRINCL and/or multicast destination being set.
677 */
paul0bfeca32004-09-24 08:07:54 +0000678#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000679 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000680 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
681 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000682#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000683
684 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000685 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000686 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000687 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000688
689 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000690 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000691 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000692 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000693 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000694
paul718e3742002-12-13 20:15:29 +0000695 /* Show debug sending packet. */
696 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
697 {
698 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
699 {
ajs2a42e282004-12-08 18:43:03 +0000700 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000701 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000702 stream_set_getp (op->s, 0);
703 ospf_packet_dump (op->s);
704 }
705
ajs2a42e282004-12-08 18:43:03 +0000706 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000707 ospf_packet_type_str[type], inet_ntoa (op->dst),
708 IF_NAME (oi));
709
710 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000711 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000712 }
713
714 /* Now delete packet from queue. */
715 ospf_packet_delete (oi);
716
717 if (ospf_fifo_head (oi->obuf) == NULL)
718 {
719 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000720 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000724 if (!list_isempty (ospf->oi_write_q))
725 ospf->t_write =
726 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000727
728 return 0;
729}
730
731/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000732static void
paul718e3742002-12-13 20:15:29 +0000733ospf_hello (struct ip *iph, struct ospf_header *ospfh,
734 struct stream * s, struct ospf_interface *oi, int size)
735{
736 struct ospf_hello *hello;
737 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000738 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000739 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000740
741 /* increment statistics. */
742 oi->hello_in++;
743
744 hello = (struct ospf_hello *) STREAM_PNT (s);
745
746 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000747 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000748 {
749 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
750 {
ajs2a42e282004-12-08 18:43:03 +0000751 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000752 "dropping.",
753 ospf_packet_type_str[ospfh->type],
754 inet_ntoa (iph->ip_src));
755 }
756 return;
757 }
paul718e3742002-12-13 20:15:29 +0000758
759 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000760 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000761 char buf[3][INET_ADDRSTRLEN];
paul6d452762005-11-03 11:15:44 +0000762 zlog_debug ("ignoring HELLO from router %s sent to %s, "
763 "received on a passive interface, %s",
764 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
765 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
766 inet_ntop(AF_INET, &oi->address->u.prefix4,
767 buf[2], sizeof(buf[2])));
ajsba6454e2005-02-08 15:37:30 +0000768 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
769 {
770 /* Try to fix multicast membership. */
Paul Jakma429ac782006-06-15 18:40:49 +0000771 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +0000772 ospf_if_set_multicast(oi);
773 }
paul718e3742002-12-13 20:15:29 +0000774 return;
paulf2c80652002-12-13 21:44:27 +0000775 }
paul718e3742002-12-13 20:15:29 +0000776
777 /* get neighbor prefix. */
778 p.family = AF_INET;
779 p.prefixlen = ip_masklen (hello->network_mask);
780 p.u.prefix4 = iph->ip_src;
781
782 /* Compare network mask. */
783 /* Checking is ignored for Point-to-Point and Virtual link. */
784 if (oi->type != OSPF_IFTYPE_POINTOPOINT
785 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
786 if (oi->address->prefixlen != p.prefixlen)
787 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000788 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
789 inet_ntoa(ospfh->router_id), IF_NAME(oi),
790 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000791 return;
792 }
793
paul718e3742002-12-13 20:15:29 +0000794 /* Compare Router Dead Interval. */
795 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
796 {
797 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
798 inet_ntoa (ospfh->router_id));
799 return;
800 }
801
paulf9ad9372005-10-21 00:45:17 +0000802 /* Compare Hello Interval - ignored if fast-hellos are set. */
803 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
804 {
805 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
806 {
807 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
808 inet_ntoa (ospfh->router_id));
809 return;
810 }
811 }
812
paul718e3742002-12-13 20:15:29 +0000813 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000814 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000815 inet_ntoa (ospfh->router_id),
816 ospf_options_dump (hello->options));
817
818 /* Compare options. */
819#define REJECT_IF_TBIT_ON 1 /* XXX */
820#ifdef REJECT_IF_TBIT_ON
821 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
822 {
823 /*
824 * This router does not support non-zero TOS.
825 * Drop this Hello packet not to establish neighbor relationship.
826 */
827 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
828 inet_ntoa (ospfh->router_id));
829 return;
830 }
831#endif /* REJECT_IF_TBIT_ON */
832
833#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000834 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000835 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
836 {
837 /*
838 * This router does know the correct usage of O-bit
839 * the bit should be set in DD packet only.
840 */
841 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
842 inet_ntoa (ospfh->router_id));
843#ifdef STRICT_OBIT_USAGE_CHECK
844 return; /* Reject this packet. */
845#else /* STRICT_OBIT_USAGE_CHECK */
846 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
847#endif /* STRICT_OBIT_USAGE_CHECK */
848 }
849#endif /* HAVE_OPAQUE_LSA */
850
851 /* new for NSSA is to ensure that NP is on and E is off */
852
paul718e3742002-12-13 20:15:29 +0000853 if (oi->area->external_routing == OSPF_AREA_NSSA)
854 {
855 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
856 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
857 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
858 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
859 {
860 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
861 return;
862 }
863 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000864 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000865 }
866 else
paul718e3742002-12-13 20:15:29 +0000867 /* The setting of the E-bit found in the Hello Packet's Options
868 field must match this area's ExternalRoutingCapability A
869 mismatch causes processing to stop and the packet to be
870 dropped. The setting of the rest of the bits in the Hello
871 Packet's Options field should be ignored. */
872 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
873 CHECK_FLAG (hello->options, OSPF_OPTION_E))
874 {
ajs3aa8d5f2004-12-11 18:00:06 +0000875 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
876 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000877 return;
878 }
paul718e3742002-12-13 20:15:29 +0000879
pauld3f0d622004-05-05 15:27:15 +0000880 /* get neighbour struct */
881 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
882
883 /* neighbour must be valid, ospf_nbr_get creates if none existed */
884 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000885
886 old_state = nbr->state;
887
888 /* Add event to thread. */
889 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
890
891 /* RFC2328 Section 9.5.1
892 If the router is not eligible to become Designated Router,
893 (snip) It must also send an Hello Packet in reply to an
894 Hello Packet received from any eligible neighbor (other than
895 the current Designated Router and Backup Designated Router). */
896 if (oi->type == OSPF_IFTYPE_NBMA)
897 if (PRIORITY(oi) == 0 && hello->priority > 0
898 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
899 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
900 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
901 OSPF_HELLO_REPLY_DELAY);
902
903 /* on NBMA network type, it happens to receive bidirectional Hello packet
904 without advance 1-Way Received event.
905 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
906 if (oi->type == OSPF_IFTYPE_NBMA &&
907 (old_state == NSM_Down || old_state == NSM_Attempt))
908 {
909 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
910 nbr->priority = hello->priority;
911 nbr->d_router = hello->d_router;
912 nbr->bd_router = hello->bd_router;
913 return;
914 }
915
paul68980082003-03-25 05:07:42 +0000916 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000917 size - OSPF_HELLO_MIN_SIZE))
918 {
919 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
920 nbr->options |= hello->options;
921 }
922 else
923 {
924 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
925 /* Set neighbor information. */
926 nbr->priority = hello->priority;
927 nbr->d_router = hello->d_router;
928 nbr->bd_router = hello->bd_router;
929 return;
930 }
931
932 /* If neighbor itself declares DR and no BDR exists,
933 cause event BackupSeen */
934 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
935 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
936 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
937
938 /* neighbor itself declares BDR. */
939 if (oi->state == ISM_Waiting &&
940 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
941 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
942
943 /* had not previously. */
944 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
945 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
946 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
947 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
948 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
949
950 /* had not previously. */
951 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
952 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
953 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
954 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
955 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
956
957 /* Neighbor priority check. */
958 if (nbr->priority >= 0 && nbr->priority != hello->priority)
959 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
960
961 /* Set neighbor information. */
962 nbr->priority = hello->priority;
963 nbr->d_router = hello->d_router;
964 nbr->bd_router = hello->bd_router;
965}
966
967/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000968static void
paul718e3742002-12-13 20:15:29 +0000969ospf_db_desc_save_current (struct ospf_neighbor *nbr,
970 struct ospf_db_desc *dd)
971{
972 nbr->last_recv.flags = dd->flags;
973 nbr->last_recv.options = dd->options;
974 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
975}
976
977/* Process rest of DD packet. */
978static void
979ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
980 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
981 u_int16_t size)
982{
983 struct ospf_lsa *new, *find;
984 struct lsa_header *lsah;
985
paul9985f832005-02-09 15:51:56 +0000986 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000987 for (size -= OSPF_DB_DESC_MIN_SIZE;
988 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
989 {
990 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000991 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000992
993 /* Unknown LS type. */
994 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
995 {
ajsbec595a2004-11-30 22:38:43 +0000996 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000997 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
998 return;
999 }
1000
1001#ifdef HAVE_OPAQUE_LSA
1002 if (IS_OPAQUE_LSA (lsah->type)
1003 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1004 {
1005 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1006 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1007 return;
1008 }
1009#endif /* HAVE_OPAQUE_LSA */
1010
1011 switch (lsah->type)
1012 {
1013 case OSPF_AS_EXTERNAL_LSA:
1014#ifdef HAVE_OPAQUE_LSA
1015 case OSPF_OPAQUE_AS_LSA:
1016#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001017 /* Check for stub area. Reject if AS-External from stub but
1018 allow if from NSSA. */
1019 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001020 {
1021 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1022 lsah->type, inet_ntoa (lsah->id),
1023 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1024 "STUB" : "NSSA");
1025 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1026 return;
1027 }
1028 break;
1029 default:
1030 break;
1031 }
1032
1033 /* Create LS-request object. */
1034 new = ospf_ls_request_new (lsah);
1035
1036 /* Lookup received LSA, then add LS request list. */
1037 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1038 if (!find || ospf_lsa_more_recent (find, new) < 0)
1039 {
1040 ospf_ls_request_add (nbr, new);
1041 ospf_lsa_discard (new);
1042 }
1043 else
1044 {
1045 /* Received LSA is not recent. */
1046 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001047 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001048 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1049 ospf_lsa_discard (new);
1050 continue;
1051 }
1052 }
1053
1054 /* Master */
1055 if (IS_SET_DD_MS (nbr->dd_flags))
1056 {
1057 nbr->dd_seqnum++;
1058 /* Entire DD packet sent. */
1059 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1060 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1061 else
1062 /* Send new DD packet. */
1063 ospf_db_desc_send (nbr);
1064 }
1065 /* Slave */
1066 else
1067 {
1068 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1069
1070 /* When master's more flags is not set. */
1071 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1072 {
1073 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1074 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1075 }
1076
ajsbec595a2004-11-30 22:38:43 +00001077 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001078 ospf_db_desc_send (nbr);
1079 }
1080
1081 /* Save received neighbor values from DD. */
1082 ospf_db_desc_save_current (nbr, dd);
1083}
1084
paul4dadc292005-05-06 21:37:42 +00001085static int
paul718e3742002-12-13 20:15:29 +00001086ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1087{
1088 /* Is DD duplicated? */
1089 if (dd->options == nbr->last_recv.options &&
1090 dd->flags == nbr->last_recv.flags &&
1091 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1092 return 1;
1093
1094 return 0;
1095}
1096
1097/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001098static void
paul718e3742002-12-13 20:15:29 +00001099ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1100 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1101{
1102 struct ospf_db_desc *dd;
1103 struct ospf_neighbor *nbr;
1104
1105 /* Increment statistics. */
1106 oi->db_desc_in++;
1107
1108 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001109
pauld3f0d622004-05-05 15:27:15 +00001110 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001111 if (nbr == NULL)
1112 {
1113 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1114 inet_ntoa (ospfh->router_id));
1115 return;
1116 }
1117
1118 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001119 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1120 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001121 {
ajs3aa8d5f2004-12-11 18:00:06 +00001122 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1123 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1124 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001125 return;
1126 }
1127
pauld363df22003-06-19 00:26:34 +00001128 /*
1129 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1130 * required. In fact at least JunOS sends DD packets with P bit clear.
1131 * Until proper solution is developped, this hack should help.
1132 *
1133 * Update: According to the RFCs, N bit is specified /only/ for Hello
1134 * options, unfortunately its use in DD options is not specified. Hence some
1135 * implementations follow E-bit semantics and set it in DD options, and some
1136 * treat it as unspecified and hence follow the directive "default for
1137 * options is clear", ie unset.
1138 *
1139 * Reset the flag, as ospfd follows E-bit semantics.
1140 */
1141 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1142 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1143 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1144 {
1145 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001146 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001147 inet_ntoa (nbr->router_id) );
1148 SET_FLAG (dd->options, OSPF_OPTION_NP);
1149 }
pauld363df22003-06-19 00:26:34 +00001150
paul718e3742002-12-13 20:15:29 +00001151#ifdef REJECT_IF_TBIT_ON
1152 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1153 {
1154 /*
1155 * In Hello protocol, optional capability must have checked
1156 * to prevent this T-bit enabled router be my neighbor.
1157 */
1158 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1159 return;
1160 }
1161#endif /* REJECT_IF_TBIT_ON */
1162
1163#ifdef HAVE_OPAQUE_LSA
1164 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001165 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001166 {
1167 /*
1168 * This node is not configured to handle O-bit, for now.
1169 * Clear it to ignore unsupported capability proposed by neighbor.
1170 */
1171 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1172 }
1173#endif /* HAVE_OPAQUE_LSA */
1174
1175 /* Process DD packet by neighbor status. */
1176 switch (nbr->state)
1177 {
1178 case NSM_Down:
1179 case NSM_Attempt:
1180 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001181 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001182 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001183 LOOKUP (ospf_nsm_state_msg, nbr->state));
1184 break;
1185 case NSM_Init:
1186 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1187 /* If the new state is ExStart, the processing of the current
1188 packet should then continue in this new state by falling
1189 through to case ExStart below. */
1190 if (nbr->state != NSM_ExStart)
1191 break;
1192 case NSM_ExStart:
1193 /* Initial DBD */
1194 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1195 (size == OSPF_DB_DESC_MIN_SIZE))
1196 {
paul68980082003-03-25 05:07:42 +00001197 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001198 {
1199 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001200 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001201 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001202 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1203 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1204 }
1205 else
1206 {
1207 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001208 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001209 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001210 break;
1211 }
1212 }
1213 /* Ack from the Slave */
1214 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1215 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001216 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001217 {
ajs17eaa722004-12-29 21:04:48 +00001218 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001219 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001220 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1221 }
1222 else
1223 {
ajs3aa8d5f2004-12-11 18:00:06 +00001224 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1225 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001226 break;
1227 }
1228
1229 /* This is where the real Options are saved */
1230 nbr->options = dd->options;
1231
1232#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001233 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001234 {
1235 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001236 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001237 inet_ntoa (nbr->router_id),
1238 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1239
1240 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1241 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1242 {
paul6d452762005-11-03 11:15:44 +00001243 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1244 "Opaque-LSAs cannot be reliably advertised "
1245 "in this network.",
1246 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001247 /* This situation is undesirable, but not a real error. */
1248 }
1249 }
1250#endif /* HAVE_OPAQUE_LSA */
1251
1252 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1253
1254 /* continue processing rest of packet. */
1255 ospf_db_desc_proc (s, oi, nbr, dd, size);
1256 break;
1257 case NSM_Exchange:
1258 if (ospf_db_desc_is_dup (dd, nbr))
1259 {
1260 if (IS_SET_DD_MS (nbr->dd_flags))
1261 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001262 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001263 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001264 else
1265 /* Slave: cause to retransmit the last Database Description. */
1266 {
paul6d452762005-11-03 11:15:44 +00001267 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001268 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001269 ospf_db_desc_resend (nbr);
1270 }
1271 break;
1272 }
1273
1274 /* Otherwise DD packet should be checked. */
1275 /* Check Master/Slave bit mismatch */
1276 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1277 {
ajs3aa8d5f2004-12-11 18:00:06 +00001278 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1279 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001280 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1281 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001282 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001283 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001284 break;
1285 }
1286
1287 /* Check initialize bit is set. */
1288 if (IS_SET_DD_I (dd->flags))
1289 {
paul6d452762005-11-03 11:15:44 +00001290 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001291 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001292 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1293 break;
1294 }
1295
1296 /* Check DD Options. */
1297 if (dd->options != nbr->options)
1298 {
1299#ifdef ORIGINAL_CODING
1300 /* Save the new options for debugging */
1301 nbr->options = dd->options;
1302#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001303 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1304 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001305 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1306 break;
1307 }
1308
1309 /* Check DD sequence number. */
1310 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1311 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1312 (!IS_SET_DD_MS (nbr->dd_flags) &&
1313 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1314 {
ajs3aa8d5f2004-12-11 18:00:06 +00001315 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1316 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001317 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1318 break;
1319 }
1320
1321 /* Continue processing rest of packet. */
1322 ospf_db_desc_proc (s, oi, nbr, dd, size);
1323 break;
1324 case NSM_Loading:
1325 case NSM_Full:
1326 if (ospf_db_desc_is_dup (dd, nbr))
1327 {
1328 if (IS_SET_DD_MS (nbr->dd_flags))
1329 {
1330 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001331 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1332 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001333 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001334 break;
1335 }
1336 else
1337 {
1338 struct timeval t, now;
1339 gettimeofday (&now, NULL);
1340 t = tv_sub (now, nbr->last_send_ts);
1341 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1342 {
1343 /* In states Loading and Full the slave must resend
1344 its last Database Description packet in response to
1345 duplicate Database Description packets received
1346 from the master. For this reason the slave must
1347 wait RouterDeadInterval seconds before freeing the
1348 last Database Description packet. Reception of a
1349 Database Description packet from the master after
1350 this interval will generate a SeqNumberMismatch
1351 neighbor event. RFC2328 Section 10.8 */
1352 ospf_db_desc_resend (nbr);
1353 break;
1354 }
1355 }
1356 }
1357
1358 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1359 break;
1360 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001361 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1362 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001363 break;
1364 }
1365}
1366
1367#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1368
1369/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001370static void
paul718e3742002-12-13 20:15:29 +00001371ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1372 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1373{
1374 struct ospf_neighbor *nbr;
1375 u_int32_t ls_type;
1376 struct in_addr ls_id;
1377 struct in_addr adv_router;
1378 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001379 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001380 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001381
1382 /* Increment statistics. */
1383 oi->ls_req_in++;
1384
pauld3f0d622004-05-05 15:27:15 +00001385 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001386 if (nbr == NULL)
1387 {
1388 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1389 inet_ntoa (ospfh->router_id));
1390 return;
1391 }
1392
1393 /* Neighbor State should be Exchange or later. */
1394 if (nbr->state != NSM_Exchange &&
1395 nbr->state != NSM_Loading &&
1396 nbr->state != NSM_Full)
1397 {
ajsbec595a2004-11-30 22:38:43 +00001398 zlog_warn ("Link State Request received from %s: "
1399 "Neighbor state is %s, packet discarded.",
1400 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001401 LOOKUP (ospf_nsm_state_msg, nbr->state));
1402 return;
1403 }
1404
1405 /* Send Link State Update for ALL requested LSAs. */
1406 ls_upd = list_new ();
1407 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1408
1409 while (size >= OSPF_LSA_KEY_SIZE)
1410 {
1411 /* Get one slice of Link State Request. */
1412 ls_type = stream_getl (s);
1413 ls_id.s_addr = stream_get_ipv4 (s);
1414 adv_router.s_addr = stream_get_ipv4 (s);
1415
1416 /* Verify LSA type. */
1417 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1418 {
1419 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1420 list_delete (ls_upd);
1421 return;
1422 }
1423
1424 /* Search proper LSA in LSDB. */
1425 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1426 if (find == NULL)
1427 {
1428 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1429 list_delete (ls_upd);
1430 return;
1431 }
1432
gdt86f1fd92005-01-10 14:20:43 +00001433 /* Packet overflows MTU size, send immediately. */
1434 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001435 {
1436 if (oi->type == OSPF_IFTYPE_NBMA)
1437 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1438 else
1439 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1440
1441 /* Only remove list contents. Keep ls_upd. */
1442 list_delete_all_node (ls_upd);
1443
1444 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1445 }
1446
1447 /* Append LSA to update list. */
1448 listnode_add (ls_upd, find);
1449 length += ntohs (find->data->length);
1450
1451 size -= OSPF_LSA_KEY_SIZE;
1452 }
1453
1454 /* Send rest of Link State Update. */
1455 if (listcount (ls_upd) > 0)
1456 {
1457 if (oi->type == OSPF_IFTYPE_NBMA)
1458 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1459 else
1460 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1461
1462 list_delete (ls_upd);
1463 }
1464 else
1465 list_free (ls_upd);
1466}
1467
1468/* Get the list of LSAs from Link State Update packet.
1469 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001470static struct list *
paul718e3742002-12-13 20:15:29 +00001471ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1472 struct ospf_interface *oi, size_t size)
1473{
1474 u_int16_t count, sum;
1475 u_int32_t length;
1476 struct lsa_header *lsah;
1477 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001478 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001479
1480 lsas = list_new ();
1481
1482 count = stream_getl (s);
1483 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1484
1485 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001486 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001487 {
1488 lsah = (struct lsa_header *) STREAM_PNT (s);
1489 length = ntohs (lsah->length);
1490
1491 if (length > size)
1492 {
1493 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1494 break;
1495 }
1496
1497 /* Validate the LSA's LS checksum. */
1498 sum = lsah->checksum;
1499 if (sum != ospf_lsa_checksum (lsah))
1500 {
1501 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1502 sum, lsah->checksum);
1503 continue;
1504 }
1505
1506 /* Examine the LSA's LS type. */
1507 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1508 {
1509 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1510 continue;
1511 }
1512
1513 /*
1514 * What if the received LSA's age is greater than MaxAge?
1515 * Treat it as a MaxAge case -- endo.
1516 */
1517 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1518 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1519
1520#ifdef HAVE_OPAQUE_LSA
1521 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1522 {
1523#ifdef STRICT_OBIT_USAGE_CHECK
1524 if ((IS_OPAQUE_LSA(lsah->type) &&
1525 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1526 || (! IS_OPAQUE_LSA(lsah->type) &&
1527 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1528 {
1529 /*
1530 * This neighbor must know the exact usage of O-bit;
1531 * the bit will be set in Type-9,10,11 LSAs only.
1532 */
1533 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1534 continue;
1535 }
1536#endif /* STRICT_OBIT_USAGE_CHECK */
1537
1538 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1539 if (lsah->type == OSPF_OPAQUE_AS_LSA
1540 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1541 {
1542 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001543 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 +00001544 continue;
1545 }
1546 }
1547 else if (IS_OPAQUE_LSA(lsah->type))
1548 {
1549 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1550 continue;
1551 }
1552#endif /* HAVE_OPAQUE_LSA */
1553
1554 /* Create OSPF LSA instance. */
1555 lsa = ospf_lsa_new ();
1556
1557 /* We may wish to put some error checking if type NSSA comes in
1558 and area not in NSSA mode */
1559 switch (lsah->type)
1560 {
1561 case OSPF_AS_EXTERNAL_LSA:
1562#ifdef HAVE_OPAQUE_LSA
1563 case OSPF_OPAQUE_AS_LSA:
1564 lsa->area = NULL;
1565 break;
1566 case OSPF_OPAQUE_LINK_LSA:
1567 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1568 /* Fallthrough */
1569#endif /* HAVE_OPAQUE_LSA */
1570 default:
1571 lsa->area = oi->area;
1572 break;
1573 }
1574
1575 lsa->data = ospf_lsa_data_new (length);
1576 memcpy (lsa->data, lsah, length);
1577
1578 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001579 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001580 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1581 listnode_add (lsas, lsa);
1582 }
1583
1584 return lsas;
1585}
1586
1587/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001588static void
hasso52dc7ee2004-09-23 19:18:23 +00001589ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001590{
paul1eb8ef22005-04-07 07:30:20 +00001591 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001592 struct ospf_lsa *lsa;
1593
paul1eb8ef22005-04-07 07:30:20 +00001594 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1595 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001596
1597 list_delete (lsas);
1598}
1599
1600/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001601static void
paul718e3742002-12-13 20:15:29 +00001602ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1603 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1604{
1605 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001606 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001607 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001608 struct ospf_lsa *lsa = NULL;
1609 /* unsigned long ls_req_found = 0; */
1610
1611 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1612
1613 /* Increment statistics. */
1614 oi->ls_upd_in++;
1615
1616 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001617 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001618 if (nbr == NULL)
1619 {
1620 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1621 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1622 return;
1623 }
1624
1625 /* Check neighbor state. */
1626 if (nbr->state < NSM_Exchange)
1627 {
ajs3aa8d5f2004-12-11 18:00:06 +00001628 zlog_warn ("Link State Update: "
1629 "Neighbor[%s] state %s is less than Exchange",
1630 inet_ntoa (ospfh->router_id),
1631 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001632 return;
1633 }
1634
1635 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1636 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1637 * of section 13.
1638 */
1639 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1640
1641#ifdef HAVE_OPAQUE_LSA
1642 /*
paul718e3742002-12-13 20:15:29 +00001643 * If self-originated Opaque-LSAs that have flooded before restart
1644 * are contained in the received LSUpd message, corresponding LSReq
1645 * messages to be sent may have to be modified.
1646 * To eliminate possible race conditions such that flushing and normal
1647 * updating for the same LSA would take place alternately, this trick
1648 * must be done before entering to the loop below.
1649 */
paul69310a62005-05-11 18:09:59 +00001650 /* XXX: Why is this Opaque specific? Either our core code is deficient
1651 * and this should be fixed generally, or Opaque is inventing strawman
1652 * problems */
paul718e3742002-12-13 20:15:29 +00001653 ospf_opaque_adjust_lsreq (nbr, lsas);
1654#endif /* HAVE_OPAQUE_LSA */
1655
1656#define DISCARD_LSA(L,N) {\
1657 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001658 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 +00001659 ospf_lsa_discard (L); \
1660 continue; }
1661
1662 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001663 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001664 {
1665 struct ospf_lsa *ls_ret, *current;
1666 int ret = 1;
1667
paul718e3742002-12-13 20:15:29 +00001668 if (IS_DEBUG_OSPF_NSSA)
1669 {
1670 char buf1[INET_ADDRSTRLEN];
1671 char buf2[INET_ADDRSTRLEN];
1672 char buf3[INET_ADDRSTRLEN];
1673
ajs2a42e282004-12-08 18:43:03 +00001674 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001675 lsa->data->type,
1676 inet_ntop (AF_INET, &ospfh->router_id,
1677 buf1, INET_ADDRSTRLEN),
1678 inet_ntop (AF_INET, &lsa->data->id,
1679 buf2, INET_ADDRSTRLEN),
1680 inet_ntop (AF_INET, &lsa->data->adv_router,
1681 buf3, INET_ADDRSTRLEN));
1682 }
paul718e3742002-12-13 20:15:29 +00001683
1684 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1685
1686 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1687
1688 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1689
1690 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1691
1692 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1693
1694 /* Do take in Type-7's if we are an NSSA */
1695
1696 /* If we are also an ABR, later translate them to a Type-5 packet */
1697
1698 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1699 translate them to a separate Type-5 packet. */
1700
1701 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1702 /* Reject from STUB or NSSA */
1703 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1704 {
1705 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001706 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001707 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001708 }
1709
paul718e3742002-12-13 20:15:29 +00001710 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1711 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1712 {
1713 DISCARD_LSA (lsa,2);
1714 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001715 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001716 }
paul718e3742002-12-13 20:15:29 +00001717
1718 /* Find the LSA in the current database. */
1719
1720 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1721
1722 /* If the LSA's LS age is equal to MaxAge, and there is currently
1723 no instance of the LSA in the router's link state database,
1724 and none of router's neighbors are in states Exchange or Loading,
1725 then take the following actions. */
1726
1727 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001728 (ospf_nbr_count (oi, NSM_Exchange) +
1729 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001730 {
1731 /* Response Link State Acknowledgment. */
1732 ospf_ls_ack_send (nbr, lsa);
1733
1734 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001735 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1736 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001737 DISCARD_LSA (lsa, 3);
1738 }
1739
1740#ifdef HAVE_OPAQUE_LSA
1741 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001742 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001743 {
1744 /*
1745 * Even if initial flushing seems to be completed, there might
1746 * be a case that self-originated LSA with MaxAge still remain
1747 * in the routing domain.
1748 * Just send an LSAck message to cease retransmission.
1749 */
1750 if (IS_LSA_MAXAGE (lsa))
1751 {
1752 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1753 ospf_ls_ack_send (nbr, lsa);
1754 ospf_lsa_discard (lsa);
1755
1756 if (current != NULL && ! IS_LSA_MAXAGE (current))
1757 ospf_opaque_lsa_refresh_schedule (current);
1758 continue;
1759 }
1760
1761 /*
1762 * If an instance of self-originated Opaque-LSA is not found
1763 * in the LSDB, there are some possible cases here.
1764 *
1765 * 1) This node lost opaque-capability after restart.
1766 * 2) Else, a part of opaque-type is no more supported.
1767 * 3) Else, a part of opaque-id is no more supported.
1768 *
1769 * Anyway, it is still this node's responsibility to flush it.
1770 * Otherwise, the LSA instance remains in the routing domain
1771 * until its age reaches to MaxAge.
1772 */
paul69310a62005-05-11 18:09:59 +00001773 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001774 if (current == NULL)
1775 {
1776 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001777 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1778 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001779
1780 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001781
1782 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1783 ospf_ls_ack_send (nbr, lsa);
1784
paul718e3742002-12-13 20:15:29 +00001785 continue;
1786 }
1787 }
1788#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001789
hassocb05eb22004-02-11 21:10:19 +00001790 /* It might be happen that received LSA is self-originated network LSA, but
1791 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1792 * Link State ID is one of the router's own IP interface addresses but whose
1793 * Advertising Router is not equal to the router's own Router ID
1794 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1795 */
1796
1797 if(lsa->data->type == OSPF_NETWORK_LSA)
1798 {
paul1eb8ef22005-04-07 07:30:20 +00001799 struct listnode *oinode, *oinnode;
1800 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001801 int Flag = 0;
1802
paul1eb8ef22005-04-07 07:30:20 +00001803 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001804 {
hassocb05eb22004-02-11 21:10:19 +00001805 if(out_if == NULL)
1806 break;
1807
1808 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1809 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1810 {
1811 if(out_if->network_lsa_self)
1812 {
1813 ospf_lsa_flush_area(lsa,out_if->area);
1814 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001815 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001816 lsa, (int) lsa->data->type);
1817 ospf_lsa_discard (lsa);
1818 Flag = 1;
1819 }
1820 break;
1821 }
1822 }
1823 if(Flag)
1824 continue;
1825 }
paul718e3742002-12-13 20:15:29 +00001826
1827 /* (5) Find the instance of this LSA that is currently contained
1828 in the router's link state database. If there is no
1829 database copy, or the received LSA is more recent than
1830 the database copy the following steps must be performed. */
1831
1832 if (current == NULL ||
1833 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1834 {
1835 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001836 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001837 DISCARD_LSA (lsa, 4);
1838 continue;
1839 }
1840
1841 /* (6) Else, If there is an instance of the LSA on the sending
1842 neighbor's Link state request list, an error has occurred in
1843 the Database Exchange process. In this case, restart the
1844 Database Exchange process by generating the neighbor event
1845 BadLSReq for the sending neighbor and stop processing the
1846 Link State Update packet. */
1847
1848 if (ospf_ls_request_lookup (nbr, lsa))
1849 {
1850 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001851 zlog_warn("LSA[%s] instance exists on Link state request list",
1852 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001853
1854 /* Clean list of LSAs. */
1855 ospf_upd_list_clean (lsas);
1856 /* this lsa is not on lsas list already. */
1857 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001858 return;
1859 }
1860
1861 /* If the received LSA is the same instance as the database copy
1862 (i.e., neither one is more recent) the following two steps
1863 should be performed: */
1864
1865 if (ret == 0)
1866 {
1867 /* If the LSA is listed in the Link state retransmission list
1868 for the receiving adjacency, the router itself is expecting
1869 an acknowledgment for this LSA. The router should treat the
1870 received LSA as an acknowledgment by removing the LSA from
1871 the Link state retransmission list. This is termed an
1872 "implied acknowledgment". */
1873
1874 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1875
1876 if (ls_ret != NULL)
1877 {
1878 ospf_ls_retransmit_delete (nbr, ls_ret);
1879
1880 /* Delayed acknowledgment sent if advertisement received
1881 from Designated Router, otherwise do nothing. */
1882 if (oi->state == ISM_Backup)
1883 if (NBR_IS_DR (nbr))
1884 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1885
1886 DISCARD_LSA (lsa, 5);
1887 }
1888 else
1889 /* Acknowledge the receipt of the LSA by sending a
1890 Link State Acknowledgment packet back out the receiving
1891 interface. */
1892 {
1893 ospf_ls_ack_send (nbr, lsa);
1894 DISCARD_LSA (lsa, 6);
1895 }
1896 }
1897
1898 /* The database copy is more recent. If the database copy
1899 has LS age equal to MaxAge and LS sequence number equal to
1900 MaxSequenceNumber, simply discard the received LSA without
1901 acknowledging it. (In this case, the LSA's LS sequence number is
1902 wrapping, and the MaxSequenceNumber LSA must be completely
1903 flushed before any new LSA instance can be introduced). */
1904
1905 else if (ret > 0) /* Database copy is more recent */
1906 {
1907 if (IS_LSA_MAXAGE (current) &&
1908 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1909 {
1910 DISCARD_LSA (lsa, 7);
1911 }
1912 /* Otherwise, as long as the database copy has not been sent in a
1913 Link State Update within the last MinLSArrival seconds, send the
1914 database copy back to the sending neighbor, encapsulated within
1915 a Link State Update Packet. The Link State Update Packet should
1916 be sent directly to the neighbor. In so doing, do not put the
1917 database copy of the LSA on the neighbor's link state
1918 retransmission list, and do not acknowledge the received (less
1919 recent) LSA instance. */
1920 else
1921 {
1922 struct timeval now;
1923
1924 gettimeofday (&now, NULL);
1925
1926 if (tv_cmp (tv_sub (now, current->tv_orig),
1927 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1928 /* Trap NSSA type later.*/
1929 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1930 DISCARD_LSA (lsa, 8);
1931 }
1932 }
1933 }
1934
paul718e3742002-12-13 20:15:29 +00001935 assert (listcount (lsas) == 0);
1936 list_delete (lsas);
1937}
1938
1939/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001940static void
paul718e3742002-12-13 20:15:29 +00001941ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1942 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1943{
1944 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001945
paul718e3742002-12-13 20:15:29 +00001946 /* increment statistics. */
1947 oi->ls_ack_in++;
1948
pauld3f0d622004-05-05 15:27:15 +00001949 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001950 if (nbr == NULL)
1951 {
1952 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1953 inet_ntoa (ospfh->router_id));
1954 return;
1955 }
1956
1957 if (nbr->state < NSM_Exchange)
1958 {
ajs3aa8d5f2004-12-11 18:00:06 +00001959 zlog_warn ("Link State Acknowledgment: "
1960 "Neighbor[%s] state %s is less than Exchange",
1961 inet_ntoa (ospfh->router_id),
1962 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001963 return;
1964 }
paul69310a62005-05-11 18:09:59 +00001965
paul718e3742002-12-13 20:15:29 +00001966 while (size >= OSPF_LSA_HEADER_SIZE)
1967 {
1968 struct ospf_lsa *lsa, *lsr;
1969
1970 lsa = ospf_lsa_new ();
1971 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1972
1973 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1974 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001975 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001976
1977 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1978 {
1979 lsa->data = NULL;
1980 ospf_lsa_discard (lsa);
1981 continue;
1982 }
1983
1984 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1985
1986 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1987 {
1988#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001989 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001990 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001991#endif /* HAVE_OPAQUE_LSA */
1992
1993 ospf_ls_retransmit_delete (nbr, lsr);
1994 }
1995
1996 lsa->data = NULL;
1997 ospf_lsa_discard (lsa);
1998 }
1999
paul718e3742002-12-13 20:15:29 +00002000 return;
paul718e3742002-12-13 20:15:29 +00002001}
2002
ajs038163f2005-02-17 19:55:59 +00002003static struct stream *
ajs5c333492005-02-23 15:43:01 +00002004ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002005{
2006 int ret;
ajs5c333492005-02-23 15:43:01 +00002007 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002008 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002009 unsigned int ifindex = 0;
2010 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002011 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002012 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002013 struct msghdr msgh;
2014
paul68defd62004-09-27 07:27:13 +00002015 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002016 msgh.msg_iov = &iov;
2017 msgh.msg_iovlen = 1;
2018 msgh.msg_control = (caddr_t) buff;
2019 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002020
ajs5c333492005-02-23 15:43:01 +00002021 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2022 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002023 {
ajs5c333492005-02-23 15:43:01 +00002024 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2025 return NULL;
2026 }
paul69310a62005-05-11 18:09:59 +00002027 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002028 {
2029 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2030 "(ip header size is %u)",
2031 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002032 return NULL;
2033 }
paul18b12c32004-10-05 14:38:29 +00002034
ajs5c333492005-02-23 15:43:01 +00002035 /* Note that there should not be alignment problems with this assignment
2036 because this is at the beginning of the stream data buffer. */
2037 iph = (struct ip *) STREAM_DATA(ibuf);
2038 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002039
ajs5c333492005-02-23 15:43:01 +00002040 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002041
paul239aecc2003-12-08 10:34:54 +00002042#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002043 /*
2044 * Kernel network code touches incoming IP header parameters,
2045 * before protocol specific processing.
2046 *
2047 * 1) Convert byteorder to host representation.
2048 * --> ip_len, ip_id, ip_off
2049 *
2050 * 2) Adjust ip_len to strip IP header size!
2051 * --> If user process receives entire IP packet via RAW
2052 * socket, it must consider adding IP header size to
2053 * the "ip_len" field of "ip" structure.
2054 *
2055 * For more details, see <netinet/ip_input.c>.
2056 */
ajs5c333492005-02-23 15:43:01 +00002057 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002058#endif
2059
paul863082d2004-08-19 04:43:43 +00002060 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002061
2062 *ifp = if_lookup_by_index (ifindex);
2063
2064 if (ret != ip_len)
2065 {
ajs5c333492005-02-23 15:43:01 +00002066 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2067 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002068 return NULL;
2069 }
2070
2071 return ibuf;
2072}
2073
paul4dadc292005-05-06 21:37:42 +00002074static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002075ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002076 struct ip *iph, struct ospf_header *ospfh)
2077{
2078 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002079 struct ospf_vl_data *vl_data;
2080 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002081 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002082
2083 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2084 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002085 return NULL;
paul718e3742002-12-13 20:15:29 +00002086
pauld3f0d622004-05-05 15:27:15 +00002087 /* look for local OSPF interface matching the destination
2088 * to determine Area ID. We presume therefore the destination address
2089 * is unique, or at least (for "unnumbered" links), not used in other
2090 * areas
2091 */
2092 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2093 iph->ip_dst)) == NULL)
2094 return NULL;
paul718e3742002-12-13 20:15:29 +00002095
paul1eb8ef22005-04-07 07:30:20 +00002096 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002097 {
paul020709f2003-04-04 02:44:16 +00002098 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002099 if (!vl_area)
2100 continue;
2101
2102 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2103 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2104 {
2105 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002106 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002107 IF_NAME (vl_data->vl_oi));
2108 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2109 {
2110 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002111 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002112 return NULL;
2113 }
2114
2115 return vl_data->vl_oi;
2116 }
2117 }
2118
2119 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002120 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002121
pauld3f0d622004-05-05 15:27:15 +00002122 return NULL;
paul718e3742002-12-13 20:15:29 +00002123}
2124
paul4dadc292005-05-06 21:37:42 +00002125static inline int
paul718e3742002-12-13 20:15:29 +00002126ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2127{
2128 /* Check match the Area ID of the receiving interface. */
2129 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2130 return 1;
2131
2132 return 0;
2133}
2134
2135/* Unbound socket will accept any Raw IP packets if proto is matched.
2136 To prevent it, compare src IP address and i/f address with masking
2137 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002138static int
paul718e3742002-12-13 20:15:29 +00002139ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2140{
2141 struct in_addr mask, me, him;
2142
2143 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2144 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2145 return 1;
2146
2147 masklen2ip (oi->address->prefixlen, &mask);
2148
2149 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2150 him.s_addr = ip_src.s_addr & mask.s_addr;
2151
2152 if (IPV4_ADDR_SAME (&me, &him))
2153 return 1;
2154
2155 return 0;
2156}
2157
paul4dadc292005-05-06 21:37:42 +00002158static int
paul718e3742002-12-13 20:15:29 +00002159ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2160 struct ospf_header *ospfh)
2161{
2162 int ret = 0;
2163 struct crypt_key *ck;
2164
2165 switch (ntohs (ospfh->auth_type))
2166 {
2167 case OSPF_AUTH_NULL:
2168 ret = 1;
2169 break;
2170 case OSPF_AUTH_SIMPLE:
2171 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2172 ret = 1;
2173 else
2174 ret = 0;
2175 break;
2176 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002177 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002178 {
2179 ret = 0;
2180 break;
2181 }
2182
2183 /* This is very basic, the digest processing is elsewhere */
2184 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2185 ospfh->u.crypt.key_id == ck->key_id &&
2186 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2187 ret = 1;
2188 else
2189 ret = 0;
2190 break;
2191 default:
2192 ret = 0;
2193 break;
2194 }
2195
2196 return ret;
2197}
2198
paul4dadc292005-05-06 21:37:42 +00002199static int
paul718e3742002-12-13 20:15:29 +00002200ospf_check_sum (struct ospf_header *ospfh)
2201{
2202 u_int32_t ret;
2203 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002204
2205 /* clear auth_data for checksum. */
2206 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2207
2208 /* keep checksum and clear. */
2209 sum = ospfh->checksum;
2210 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2211
2212 /* calculate checksum. */
2213 ret = in_cksum (ospfh, ntohs (ospfh->length));
2214
2215 if (ret != sum)
2216 {
2217 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2218 ret, sum);
2219 return 0;
2220 }
2221
2222 return 1;
2223}
2224
2225/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002226static int
paul718e3742002-12-13 20:15:29 +00002227ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2228 struct ip *iph, struct ospf_header *ospfh)
2229{
2230 /* check version. */
2231 if (ospfh->version != OSPF_VERSION)
2232 {
2233 zlog_warn ("interface %s: ospf_read version number mismatch.",
2234 IF_NAME (oi));
2235 return -1;
2236 }
2237
2238 /* Check Area ID. */
2239 if (!ospf_check_area_id (oi, ospfh))
2240 {
2241 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2242 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2243 return -1;
2244 }
2245
2246 /* Check network mask, Silently discarded. */
2247 if (! ospf_check_network_mask (oi, iph->ip_src))
2248 {
2249 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2250 IF_NAME (oi), inet_ntoa (iph->ip_src));
2251 return -1;
2252 }
2253
2254 /* Check authentication. */
2255 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2256 {
paulc6371712006-01-17 17:49:53 +00002257 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2258 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002259 return -1;
2260 }
2261
2262 if (! ospf_check_auth (oi, ibuf, ospfh))
2263 {
2264 zlog_warn ("interface %s: ospf_read authentication failed.",
2265 IF_NAME (oi));
2266 return -1;
2267 }
2268
2269 /* if check sum is invalid, packet is discarded. */
2270 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2271 {
2272 if (! ospf_check_sum (ospfh))
2273 {
2274 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2275 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2276 return -1;
2277 }
2278 }
2279 else
2280 {
2281 if (ospfh->checksum != 0)
2282 return -1;
2283 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2284 {
2285 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2286 IF_NAME (oi));
2287 return -1;
2288 }
2289 }
2290
2291 return 0;
2292}
2293
2294/* Starting point of packet process function. */
2295int
2296ospf_read (struct thread *thread)
2297{
2298 int ret;
2299 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002300 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002301 struct ospf_interface *oi;
2302 struct ip *iph;
2303 struct ospf_header *ospfh;
2304 u_int16_t length;
2305 struct interface *ifp;
2306
2307 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002308 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002309
2310 /* prepare for next packet. */
2311 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002312
2313 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002314 stream_reset(ospf->ibuf);
2315 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002316 return -1;
2317
ajs5c333492005-02-23 15:43:01 +00002318 /* Note that there should not be alignment problems with this assignment
2319 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002320 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002321 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002322
paulac191232004-10-22 12:05:17 +00002323 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002324 /* Handle cases where the platform does not support retrieving the ifindex,
2325 and also platforms (such as Solaris 8) that claim to support ifindex
2326 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002327 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002328
pauld3f0d622004-05-05 15:27:15 +00002329 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002330 return 0;
paul718e3742002-12-13 20:15:29 +00002331
2332 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002333 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002334 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002335
paul718e3742002-12-13 20:15:29 +00002336 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002337 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002338 {
pauld3241812003-09-29 12:42:39 +00002339 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2340 {
ajs2a42e282004-12-08 18:43:03 +00002341 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002342 inet_ntoa (iph->ip_src));
2343 }
paul718e3742002-12-13 20:15:29 +00002344 return 0;
2345 }
2346
2347 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002348 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002349
2350 /* Get ospf packet header. */
2351 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2352
2353 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002354 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002355
2356 /* if no local ospf_interface,
2357 * or header area is backbone but ospf_interface is not
2358 * check for VLINK interface
2359 */
2360 if ( (oi == NULL) ||
2361 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2362 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2363 )
2364 {
2365 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2366 {
Paul Jakma88871b12006-06-15 11:41:19 +00002367 if (IS_DEBUG_OSPF_EVENT)
2368 zlog_debug ("Packet from [%s] received on link %s"
2369 " but no ospf_interface",
2370 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002371 return 0;
2372 }
2373 }
2374
2375 /* else it must be a local ospf interface, check it was received on
2376 * correct link
2377 */
2378 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002379 {
2380 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002381 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002382 return 0;
2383 }
ajs847947f2005-02-02 18:38:48 +00002384 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002385 {
ajsba6454e2005-02-08 15:37:30 +00002386 char buf[2][INET_ADDRSTRLEN];
2387 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002388 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002389 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2390 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2391 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002392 /* Fix multicast memberships? */
2393 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002394 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002395 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002396 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002397 if (oi->multicast_memberships)
2398 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002399 return 0;
2400 }
paul718e3742002-12-13 20:15:29 +00002401
2402 /*
2403 * If the received packet is destined for AllDRouters, the packet
2404 * should be accepted only if the received ospf interface state is
2405 * either DR or Backup -- endo.
2406 */
2407 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2408 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2409 {
ajsba6454e2005-02-08 15:37:30 +00002410 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002411 inet_ntoa (iph->ip_src), IF_NAME (oi),
2412 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002413 /* Try to fix multicast membership. */
2414 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2415 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002416 return 0;
2417 }
2418
2419 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002420 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2421 {
paul718e3742002-12-13 20:15:29 +00002422 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002423 {
ajs2a42e282004-12-08 18:43:03 +00002424 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002425 ospf_packet_dump (ibuf);
2426 }
paul718e3742002-12-13 20:15:29 +00002427
ajs2a42e282004-12-08 18:43:03 +00002428 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002429 ospf_packet_type_str[ospfh->type],
2430 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002431 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2432 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002433
2434 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002435 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002436 }
paul718e3742002-12-13 20:15:29 +00002437
2438 /* Some header verification. */
2439 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2440 if (ret < 0)
2441 {
pauld3241812003-09-29 12:42:39 +00002442 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2443 {
ajs2a42e282004-12-08 18:43:03 +00002444 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002445 "dropping.",
2446 ospf_packet_type_str[ospfh->type],
2447 inet_ntoa (iph->ip_src));
2448 }
paul718e3742002-12-13 20:15:29 +00002449 return ret;
2450 }
2451
paul9985f832005-02-09 15:51:56 +00002452 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002453
2454 /* Adjust size to message length. */
2455 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2456
2457 /* Read rest of the packet and call each sort of packet routine. */
2458 switch (ospfh->type)
2459 {
2460 case OSPF_MSG_HELLO:
2461 ospf_hello (iph, ospfh, ibuf, oi, length);
2462 break;
2463 case OSPF_MSG_DB_DESC:
2464 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2465 break;
2466 case OSPF_MSG_LS_REQ:
2467 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2468 break;
2469 case OSPF_MSG_LS_UPD:
2470 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2471 break;
2472 case OSPF_MSG_LS_ACK:
2473 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2474 break;
2475 default:
2476 zlog (NULL, LOG_WARNING,
2477 "interface %s: OSPF packet header type %d is illegal",
2478 IF_NAME (oi), ospfh->type);
2479 break;
2480 }
2481
paul718e3742002-12-13 20:15:29 +00002482 return 0;
2483}
2484
2485/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002486static void
paul718e3742002-12-13 20:15:29 +00002487ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2488{
2489 struct ospf_header *ospfh;
2490
2491 ospfh = (struct ospf_header *) STREAM_DATA (s);
2492
2493 ospfh->version = (u_char) OSPF_VERSION;
2494 ospfh->type = (u_char) type;
2495
paul68980082003-03-25 05:07:42 +00002496 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002497
2498 ospfh->checksum = 0;
2499 ospfh->area_id = oi->area->area_id;
2500 ospfh->auth_type = htons (ospf_auth_type (oi));
2501
2502 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2503
paul9985f832005-02-09 15:51:56 +00002504 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002505}
2506
2507/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002508static int
paul718e3742002-12-13 20:15:29 +00002509ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2510{
2511 struct crypt_key *ck;
2512
2513 switch (ospf_auth_type (oi))
2514 {
2515 case OSPF_AUTH_NULL:
2516 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2517 break;
2518 case OSPF_AUTH_SIMPLE:
2519 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2520 OSPF_AUTH_SIMPLE_SIZE);
2521 break;
2522 case OSPF_AUTH_CRYPTOGRAPHIC:
2523 /* If key is not set, then set 0. */
2524 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2525 {
2526 ospfh->u.crypt.zero = 0;
2527 ospfh->u.crypt.key_id = 0;
2528 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2529 }
2530 else
2531 {
paul1eb8ef22005-04-07 07:30:20 +00002532 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002533 ospfh->u.crypt.zero = 0;
2534 ospfh->u.crypt.key_id = ck->key_id;
2535 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2536 }
2537 /* note: the seq is done in ospf_make_md5_digest() */
2538 break;
2539 default:
2540 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2541 break;
2542 }
2543
2544 return 0;
2545}
2546
2547/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002548static void
paul718e3742002-12-13 20:15:29 +00002549ospf_fill_header (struct ospf_interface *oi,
2550 struct stream *s, u_int16_t length)
2551{
2552 struct ospf_header *ospfh;
2553
2554 ospfh = (struct ospf_header *) STREAM_DATA (s);
2555
2556 /* Fill length. */
2557 ospfh->length = htons (length);
2558
2559 /* Calculate checksum. */
2560 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2561 ospfh->checksum = in_cksum (ospfh, length);
2562 else
2563 ospfh->checksum = 0;
2564
2565 /* Add Authentication Data. */
2566 ospf_make_auth (oi, ospfh);
2567}
2568
paul4dadc292005-05-06 21:37:42 +00002569static int
paul718e3742002-12-13 20:15:29 +00002570ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2571{
2572 struct ospf_neighbor *nbr;
2573 struct route_node *rn;
2574 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2575 struct in_addr mask;
2576 unsigned long p;
2577 int flag = 0;
2578
2579 /* Set netmask of interface. */
2580 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2581 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2582 masklen2ip (oi->address->prefixlen, &mask);
2583 else
2584 memset ((char *) &mask, 0, sizeof (struct in_addr));
2585 stream_put_ipv4 (s, mask.s_addr);
2586
2587 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002588 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2589 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2590 else
2591 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002592
2593 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002594 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002595 OPTIONS(oi), IF_NAME (oi));
2596
2597 /* Set Options. */
2598 stream_putc (s, OPTIONS (oi));
2599
2600 /* Set Router Priority. */
2601 stream_putc (s, PRIORITY (oi));
2602
2603 /* Set Router Dead Interval. */
2604 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2605
2606 /* Set Designated Router. */
2607 stream_put_ipv4 (s, DR (oi).s_addr);
2608
paul9985f832005-02-09 15:51:56 +00002609 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002610
2611 /* Set Backup Designated Router. */
2612 stream_put_ipv4 (s, BDR (oi).s_addr);
2613
2614 /* Add neighbor seen. */
2615 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002616 if ((nbr = rn->info))
2617 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2618 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2619 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2620 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002621 {
2622 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002623 if (nbr->d_router.s_addr != 0
2624 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2625 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2626 flag = 1;
paul718e3742002-12-13 20:15:29 +00002627
2628 stream_put_ipv4 (s, nbr->router_id.s_addr);
2629 length += 4;
2630 }
2631
2632 /* Let neighbor generate BackupSeen. */
2633 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002634 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002635
2636 return length;
2637}
2638
paul4dadc292005-05-06 21:37:42 +00002639static int
paul718e3742002-12-13 20:15:29 +00002640ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2641 struct stream *s)
2642{
2643 struct ospf_lsa *lsa;
2644 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2645 u_char options;
2646 unsigned long pp;
2647 int i;
2648 struct ospf_lsdb *lsdb;
2649
2650 /* Set Interface MTU. */
2651 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2652 stream_putw (s, 0);
2653 else
2654 stream_putw (s, oi->ifp->mtu);
2655
2656 /* Set Options. */
2657 options = OPTIONS (oi);
2658#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002659 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002660 {
2661 if (IS_SET_DD_I (nbr->dd_flags)
2662 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2663 /*
2664 * Set O-bit in the outgoing DD packet for capablity negotiation,
2665 * if one of following case is applicable.
2666 *
2667 * 1) WaitTimer expiration event triggered the neighbor state to
2668 * change to Exstart, but no (valid) DD packet has received
2669 * from the neighbor yet.
2670 *
2671 * 2) At least one DD packet with O-bit on has received from the
2672 * neighbor.
2673 */
2674 SET_FLAG (options, OSPF_OPTION_O);
2675 }
2676#endif /* HAVE_OPAQUE_LSA */
2677 stream_putc (s, options);
2678
2679 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002680 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002681 stream_putc (s, nbr->dd_flags);
2682
2683 /* Set DD Sequence Number. */
2684 stream_putl (s, nbr->dd_seqnum);
2685
2686 if (ospf_db_summary_isempty (nbr))
2687 {
2688 if (nbr->state >= NSM_Exchange)
2689 {
2690 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2691 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002692 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002693 }
2694 return length;
2695 }
2696
2697 /* Describe LSA Header from Database Summary List. */
2698 lsdb = &nbr->db_sum;
2699
2700 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2701 {
2702 struct route_table *table = lsdb->type[i].db;
2703 struct route_node *rn;
2704
2705 for (rn = route_top (table); rn; rn = route_next (rn))
2706 if ((lsa = rn->info) != NULL)
2707 {
2708#ifdef HAVE_OPAQUE_LSA
2709 if (IS_OPAQUE_LSA (lsa->data->type)
2710 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2711 {
2712 /* Suppress advertising opaque-informations. */
2713 /* Remove LSA from DB summary list. */
2714 ospf_lsdb_delete (lsdb, lsa);
2715 continue;
2716 }
2717#endif /* HAVE_OPAQUE_LSA */
2718
2719 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2720 {
2721 struct lsa_header *lsah;
2722 u_int16_t ls_age;
2723
2724 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002725 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002726 break;
2727
2728 /* Keep pointer to LS age. */
2729 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002730 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002731
2732 /* Proceed stream pointer. */
2733 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2734 length += OSPF_LSA_HEADER_SIZE;
2735
2736 /* Set LS age. */
2737 ls_age = LS_AGE (lsa);
2738 lsah->ls_age = htons (ls_age);
2739
2740 }
2741
2742 /* Remove LSA from DB summary list. */
2743 ospf_lsdb_delete (lsdb, lsa);
2744 }
2745 }
2746
2747 return length;
2748}
2749
paul4dadc292005-05-06 21:37:42 +00002750static int
paul718e3742002-12-13 20:15:29 +00002751ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2752 unsigned long delta, struct ospf_neighbor *nbr,
2753 struct ospf_lsa *lsa)
2754{
2755 struct ospf_interface *oi;
2756
2757 oi = nbr->oi;
2758
2759 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002760 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002761 return 0;
2762
2763 stream_putl (s, lsa->data->type);
2764 stream_put_ipv4 (s, lsa->data->id.s_addr);
2765 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2766
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002767 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002768 nbr->ls_req_last = ospf_lsa_lock (lsa);
2769
2770 *length += 12;
2771 return 1;
2772}
2773
paul4dadc292005-05-06 21:37:42 +00002774static int
paul718e3742002-12-13 20:15:29 +00002775ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2776{
2777 struct ospf_lsa *lsa;
2778 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002779 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002780 struct route_table *table;
2781 struct route_node *rn;
2782 int i;
2783 struct ospf_lsdb *lsdb;
2784
2785 lsdb = &nbr->ls_req;
2786
2787 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2788 {
2789 table = lsdb->type[i].db;
2790 for (rn = route_top (table); rn; rn = route_next (rn))
2791 if ((lsa = (rn->info)) != NULL)
2792 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2793 {
2794 route_unlock_node (rn);
2795 break;
2796 }
2797 }
2798 return length;
2799}
2800
paul4dadc292005-05-06 21:37:42 +00002801static int
paul718e3742002-12-13 20:15:29 +00002802ls_age_increment (struct ospf_lsa *lsa, int delay)
2803{
2804 int age;
2805
2806 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2807
2808 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2809}
2810
paul4dadc292005-05-06 21:37:42 +00002811static int
hasso52dc7ee2004-09-23 19:18:23 +00002812ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002813{
2814 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002815 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002816 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002817 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002818 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002819 unsigned long pp;
2820 int count = 0;
2821
2822 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002823 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002824
paul9985f832005-02-09 15:51:56 +00002825 pp = stream_get_endp (s);
2826 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002827
gdt86f1fd92005-01-10 14:20:43 +00002828 /* Calculate amount of packet usable for data. */
2829 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2830
paul718e3742002-12-13 20:15:29 +00002831 while ((node = listhead (update)) != NULL)
2832 {
2833 struct lsa_header *lsah;
2834 u_int16_t ls_age;
2835
2836 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002837 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002838
paul1eb8ef22005-04-07 07:30:20 +00002839 lsa = listgetdata (node);
2840
paul718e3742002-12-13 20:15:29 +00002841 assert (lsa->data);
2842
paul68b73392004-09-12 14:21:37 +00002843 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002844 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002845 break;
2846
paul718e3742002-12-13 20:15:29 +00002847 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002848 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002849
2850 /* Put LSA to Link State Request. */
2851 stream_put (s, lsa->data, ntohs (lsa->data->length));
2852
2853 /* Set LS age. */
2854 /* each hop must increment an lsa_age by transmit_delay
2855 of OSPF interface */
2856 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2857 lsah->ls_age = htons (ls_age);
2858
2859 length += ntohs (lsa->data->length);
2860 count++;
2861
2862 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002863 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002864 }
2865
2866 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002867 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002868
2869 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002870 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002871 return length;
2872}
2873
paul4dadc292005-05-06 21:37:42 +00002874static int
hasso52dc7ee2004-09-23 19:18:23 +00002875ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002876{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002877 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002878 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002879 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002880 struct ospf_lsa *lsa;
2881
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002882 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002883 {
paul718e3742002-12-13 20:15:29 +00002884 assert (lsa);
2885
gdt86f1fd92005-01-10 14:20:43 +00002886 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002887 break;
2888
2889 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2890 length += OSPF_LSA_HEADER_SIZE;
2891
paul718e3742002-12-13 20:15:29 +00002892 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002893 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002894 }
2895
paul718e3742002-12-13 20:15:29 +00002896 return length;
2897}
2898
2899void
2900ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2901{
2902 struct ospf_packet *op;
2903 u_int16_t length = OSPF_HEADER_SIZE;
2904
2905 op = ospf_packet_new (oi->ifp->mtu);
2906
2907 /* Prepare OSPF common header. */
2908 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2909
2910 /* Prepare OSPF Hello body. */
2911 length += ospf_make_hello (oi, op->s);
2912
2913 /* Fill OSPF header. */
2914 ospf_fill_header (oi, op->s, length);
2915
2916 /* Set packet length. */
2917 op->length = length;
2918
2919 op->dst.s_addr = addr->s_addr;
2920
2921 /* Add packet to the interface output queue. */
2922 ospf_packet_add (oi, op);
2923
2924 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002925 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002926}
2927
paul4dadc292005-05-06 21:37:42 +00002928static void
paul718e3742002-12-13 20:15:29 +00002929ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2930{
2931 struct ospf_interface *oi;
2932
2933 oi = nbr_nbma->oi;
2934 assert(oi);
2935
2936 /* If this is passive interface, do not send OSPF Hello. */
2937 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2938 return;
2939
2940 if (oi->type != OSPF_IFTYPE_NBMA)
2941 return;
2942
2943 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2944 return;
2945
2946 if (PRIORITY(oi) == 0)
2947 return;
2948
2949 if (nbr_nbma->priority == 0
2950 && oi->state != ISM_DR && oi->state != ISM_Backup)
2951 return;
2952
2953 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2954}
2955
2956int
2957ospf_poll_timer (struct thread *thread)
2958{
2959 struct ospf_nbr_nbma *nbr_nbma;
2960
2961 nbr_nbma = THREAD_ARG (thread);
2962 nbr_nbma->t_poll = NULL;
2963
2964 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002965 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002966 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2967
2968 ospf_poll_send (nbr_nbma);
2969
2970 if (nbr_nbma->v_poll > 0)
2971 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2972 nbr_nbma->v_poll);
2973
2974 return 0;
2975}
2976
2977
2978int
2979ospf_hello_reply_timer (struct thread *thread)
2980{
2981 struct ospf_neighbor *nbr;
2982
2983 nbr = THREAD_ARG (thread);
2984 nbr->t_hello_reply = NULL;
2985
2986 assert (nbr->oi);
2987
2988 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002989 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00002990 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2991
2992 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2993
2994 return 0;
2995}
2996
2997/* Send OSPF Hello. */
2998void
2999ospf_hello_send (struct ospf_interface *oi)
3000{
3001 struct ospf_packet *op;
3002 u_int16_t length = OSPF_HEADER_SIZE;
3003
3004 /* If this is passive interface, do not send OSPF Hello. */
3005 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3006 return;
3007
3008 op = ospf_packet_new (oi->ifp->mtu);
3009
3010 /* Prepare OSPF common header. */
3011 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3012
3013 /* Prepare OSPF Hello body. */
3014 length += ospf_make_hello (oi, op->s);
3015
3016 /* Fill OSPF header. */
3017 ospf_fill_header (oi, op->s, length);
3018
3019 /* Set packet length. */
3020 op->length = length;
3021
3022 if (oi->type == OSPF_IFTYPE_NBMA)
3023 {
3024 struct ospf_neighbor *nbr;
3025 struct route_node *rn;
3026
3027 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3028 if ((nbr = rn->info))
3029 if (nbr != oi->nbr_self)
3030 if (nbr->state != NSM_Down)
3031 {
3032 /* RFC 2328 Section 9.5.1
3033 If the router is not eligible to become Designated Router,
3034 it must periodically send Hello Packets to both the
3035 Designated Router and the Backup Designated Router (if they
3036 exist). */
3037 if (PRIORITY(oi) == 0 &&
3038 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3039 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3040 continue;
3041
3042 /* If the router is eligible to become Designated Router, it
3043 must periodically send Hello Packets to all neighbors that
3044 are also eligible. In addition, if the router is itself the
3045 Designated Router or Backup Designated Router, it must also
3046 send periodic Hello Packets to all other neighbors. */
3047
3048 if (nbr->priority == 0 && oi->state == ISM_DROther)
3049 continue;
3050 /* if oi->state == Waiting, send hello to all neighbors */
3051 {
3052 struct ospf_packet *op_dup;
3053
3054 op_dup = ospf_packet_dup(op);
3055 op_dup->dst = nbr->address.u.prefix4;
3056
3057 /* Add packet to the interface output queue. */
3058 ospf_packet_add (oi, op_dup);
3059
paul020709f2003-04-04 02:44:16 +00003060 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003061 }
3062
3063 }
3064 ospf_packet_free (op);
3065 }
3066 else
3067 {
3068 /* Decide destination address. */
3069 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3070 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3071 else
3072 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3073
3074 /* Add packet to the interface output queue. */
3075 ospf_packet_add (oi, op);
3076
3077 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003078 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003079 }
3080}
3081
3082/* Send OSPF Database Description. */
3083void
3084ospf_db_desc_send (struct ospf_neighbor *nbr)
3085{
3086 struct ospf_interface *oi;
3087 struct ospf_packet *op;
3088 u_int16_t length = OSPF_HEADER_SIZE;
3089
3090 oi = nbr->oi;
3091 op = ospf_packet_new (oi->ifp->mtu);
3092
3093 /* Prepare OSPF common header. */
3094 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3095
3096 /* Prepare OSPF Database Description body. */
3097 length += ospf_make_db_desc (oi, nbr, op->s);
3098
3099 /* Fill OSPF header. */
3100 ospf_fill_header (oi, op->s, length);
3101
3102 /* Set packet length. */
3103 op->length = length;
3104
3105 /* Decide destination address. */
3106 op->dst = nbr->address.u.prefix4;
3107
3108 /* Add packet to the interface output queue. */
3109 ospf_packet_add (oi, op);
3110
3111 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003112 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003113
3114 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3115 if (nbr->last_send)
3116 ospf_packet_free (nbr->last_send);
3117 nbr->last_send = ospf_packet_dup (op);
3118 gettimeofday (&nbr->last_send_ts, NULL);
3119}
3120
3121/* Re-send Database Description. */
3122void
3123ospf_db_desc_resend (struct ospf_neighbor *nbr)
3124{
3125 struct ospf_interface *oi;
3126
3127 oi = nbr->oi;
3128
3129 /* Add packet to the interface output queue. */
3130 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3131
3132 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003133 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003134}
3135
3136/* Send Link State Request. */
3137void
3138ospf_ls_req_send (struct ospf_neighbor *nbr)
3139{
3140 struct ospf_interface *oi;
3141 struct ospf_packet *op;
3142 u_int16_t length = OSPF_HEADER_SIZE;
3143
3144 oi = nbr->oi;
3145 op = ospf_packet_new (oi->ifp->mtu);
3146
3147 /* Prepare OSPF common header. */
3148 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3149
3150 /* Prepare OSPF Link State Request body. */
3151 length += ospf_make_ls_req (nbr, op->s);
3152 if (length == OSPF_HEADER_SIZE)
3153 {
3154 ospf_packet_free (op);
3155 return;
3156 }
3157
3158 /* Fill OSPF header. */
3159 ospf_fill_header (oi, op->s, length);
3160
3161 /* Set packet length. */
3162 op->length = length;
3163
3164 /* Decide destination address. */
3165 op->dst = nbr->address.u.prefix4;
3166
3167 /* Add packet to the interface output queue. */
3168 ospf_packet_add (oi, op);
3169
3170 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003171 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003172
3173 /* Add Link State Request Retransmission Timer. */
3174 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3175}
3176
3177/* Send Link State Update with an LSA. */
3178void
3179ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3180 int flag)
3181{
hasso52dc7ee2004-09-23 19:18:23 +00003182 struct list *update;
paul718e3742002-12-13 20:15:29 +00003183
3184 update = list_new ();
3185
3186 listnode_add (update, lsa);
3187 ospf_ls_upd_send (nbr, update, flag);
3188
3189 list_delete (update);
3190}
3191
paul68b73392004-09-12 14:21:37 +00003192/* Determine size for packet. Must be at least big enough to accomodate next
3193 * LSA on list, which may be bigger than MTU size.
3194 *
3195 * Return pointer to new ospf_packet
3196 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3197 * on packet sizes (in which case offending LSA is deleted from update list)
3198 */
3199static struct ospf_packet *
3200ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3201{
3202 struct ospf_lsa *lsa;
3203 struct listnode *ln;
3204 size_t size;
3205 static char warned = 0;
3206
paul1eb8ef22005-04-07 07:30:20 +00003207 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003208 assert (lsa->data);
3209
3210 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3211 > ospf_packet_max (oi))
3212 {
3213 if (!warned)
3214 {
3215 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3216 "will need to fragment. Not optimal. Try divide up"
3217 " your network with areas. Use 'debug ospf packet send'"
3218 " to see details, or look at 'show ip ospf database ..'");
3219 warned = 1;
3220 }
3221
3222 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003223 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003224 " %d bytes originated by %s, will be fragmented!",
3225 inet_ntoa (lsa->data->id),
3226 ntohs (lsa->data->length),
3227 inet_ntoa (lsa->data->adv_router));
3228
3229 /*
3230 * Allocate just enough to fit this LSA only, to avoid including other
3231 * LSAs in fragmented LSA Updates.
3232 */
3233 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3234 + OSPF_LS_UPD_MIN_SIZE;
3235 }
3236 else
3237 size = oi->ifp->mtu;
3238
gdt86f1fd92005-01-10 14:20:43 +00003239 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003240 if (size > OSPF_MAX_PACKET_SIZE)
3241 {
3242 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003243 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003244 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003245 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003246 (long int) size);
paul68b73392004-09-12 14:21:37 +00003247 list_delete_node (update, ln);
3248 return NULL;
3249 }
3250
3251 return ospf_packet_new (size);
3252}
3253
paul718e3742002-12-13 20:15:29 +00003254static void
hasso52dc7ee2004-09-23 19:18:23 +00003255ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003256 struct in_addr addr)
3257{
3258 struct ospf_packet *op;
3259 u_int16_t length = OSPF_HEADER_SIZE;
3260
3261 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003262 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003263
3264 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003265
3266 /* Prepare OSPF common header. */
3267 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3268
paul59ea14c2004-07-14 20:50:36 +00003269 /* Prepare OSPF Link State Update body.
3270 * Includes Type-7 translation.
3271 */
paul718e3742002-12-13 20:15:29 +00003272 length += ospf_make_ls_upd (oi, update, op->s);
3273
3274 /* Fill OSPF header. */
3275 ospf_fill_header (oi, op->s, length);
3276
3277 /* Set packet length. */
3278 op->length = length;
3279
3280 /* Decide destination address. */
3281 op->dst.s_addr = addr.s_addr;
3282
3283 /* Add packet to the interface output queue. */
3284 ospf_packet_add (oi, op);
3285
3286 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003287 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003288}
3289
3290static int
3291ospf_ls_upd_send_queue_event (struct thread *thread)
3292{
3293 struct ospf_interface *oi = THREAD_ARG(thread);
3294 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003295 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003296 struct list *update;
paul68b73392004-09-12 14:21:37 +00003297 char again = 0;
paul718e3742002-12-13 20:15:29 +00003298
3299 oi->t_ls_upd_event = NULL;
3300
3301 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003302 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003303
paul736d3442003-07-24 23:22:57 +00003304 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003305 {
paul736d3442003-07-24 23:22:57 +00003306 rnext = route_next (rn);
3307
paul718e3742002-12-13 20:15:29 +00003308 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003309 continue;
paul68b73392004-09-12 14:21:37 +00003310
3311 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003312
paul48fe13b2004-07-27 17:40:44 +00003313 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003314
paul68b73392004-09-12 14:21:37 +00003315 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003316 if (listcount(update) == 0)
3317 {
3318 list_delete (rn->info);
3319 rn->info = NULL;
3320 route_unlock_node (rn);
3321 }
3322 else
paul68b73392004-09-12 14:21:37 +00003323 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003324 }
3325
3326 if (again != 0)
3327 {
3328 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003329 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003330 " %d nodes to try again, raising new event", again);
3331 oi->t_ls_upd_event =
3332 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003333 }
3334
3335 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003336 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003337
paul718e3742002-12-13 20:15:29 +00003338 return 0;
3339}
3340
3341void
hasso52dc7ee2004-09-23 19:18:23 +00003342ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003343{
3344 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003345 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003346 struct prefix_ipv4 p;
3347 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003348 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003349
3350 oi = nbr->oi;
3351
3352 p.family = AF_INET;
3353 p.prefixlen = IPV4_MAX_BITLEN;
3354
3355 /* Decide destination address. */
3356 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3357 p.prefix = oi->vl_data->peer_addr;
3358 else if (flag == OSPF_SEND_PACKET_DIRECT)
3359 p.prefix = nbr->address.u.prefix4;
3360 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3361 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3362 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3363 && (flag == OSPF_SEND_PACKET_INDIRECT))
3364 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003365 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3366 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003367 else
3368 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3369
3370 if (oi->type == OSPF_IFTYPE_NBMA)
3371 {
3372 if (flag == OSPF_SEND_PACKET_INDIRECT)
3373 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3374 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3375 zlog_warn ("* LS-Update is sent to myself.");
3376 }
3377
3378 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3379
3380 if (rn->info == NULL)
3381 rn->info = list_new ();
3382
paul1eb8ef22005-04-07 07:30:20 +00003383 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003384 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003385
3386 if (oi->t_ls_upd_event == NULL)
3387 oi->t_ls_upd_event =
3388 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3389}
3390
3391static void
hasso52dc7ee2004-09-23 19:18:23 +00003392ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3393 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003394{
3395 struct ospf_packet *op;
3396 u_int16_t length = OSPF_HEADER_SIZE;
3397
3398 op = ospf_packet_new (oi->ifp->mtu);
3399
3400 /* Prepare OSPF common header. */
3401 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3402
3403 /* Prepare OSPF Link State Acknowledgment body. */
3404 length += ospf_make_ls_ack (oi, ack, op->s);
3405
3406 /* Fill OSPF header. */
3407 ospf_fill_header (oi, op->s, length);
3408
3409 /* Set packet length. */
3410 op->length = length;
3411
3412 /* Set destination IP address. */
3413 op->dst = dst;
3414
3415 /* Add packet to the interface output queue. */
3416 ospf_packet_add (oi, op);
3417
3418 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003419 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003420}
3421
3422static int
3423ospf_ls_ack_send_event (struct thread *thread)
3424{
3425 struct ospf_interface *oi = THREAD_ARG (thread);
3426
3427 oi->t_ls_ack_direct = NULL;
3428
3429 while (listcount (oi->ls_ack_direct.ls_ack))
3430 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3431 oi->ls_ack_direct.dst);
3432
3433 return 0;
3434}
3435
3436void
3437ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3438{
3439 struct ospf_interface *oi = nbr->oi;
3440
3441 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3442 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3443
3444 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3445
3446 if (oi->t_ls_ack_direct == NULL)
3447 oi->t_ls_ack_direct =
3448 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3449}
3450
3451/* Send Link State Acknowledgment delayed. */
3452void
3453ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3454{
3455 struct in_addr dst;
3456
3457 /* Decide destination address. */
3458 /* RFC2328 Section 13.5 On non-broadcast
3459 networks, delayed Link State Acknowledgment packets must be
3460 unicast separately over each adjacency (i.e., neighbor whose
3461 state is >= Exchange). */
3462 if (oi->type == OSPF_IFTYPE_NBMA)
3463 {
3464 struct ospf_neighbor *nbr;
3465 struct route_node *rn;
3466
3467 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3468 if ((nbr = rn->info) != NULL)
3469 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3470 while (listcount (oi->ls_ack))
3471 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3472 return;
3473 }
3474 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3475 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3476 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3477 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3478 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3479 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003480 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3481 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003482 else
3483 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3484
3485 while (listcount (oi->ls_ack))
3486 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3487}