blob: 569f2513a71f1cad5f184c22550dc71dd7886645 [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 {
788 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
789 inet_ntoa (ospfh->router_id));
790 return;
791 }
792
paul718e3742002-12-13 20:15:29 +0000793 /* Compare Router Dead Interval. */
794 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
795 {
796 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
797 inet_ntoa (ospfh->router_id));
798 return;
799 }
800
paulf9ad9372005-10-21 00:45:17 +0000801 /* Compare Hello Interval - ignored if fast-hellos are set. */
802 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
803 {
804 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
805 {
806 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
807 inet_ntoa (ospfh->router_id));
808 return;
809 }
810 }
811
paul718e3742002-12-13 20:15:29 +0000812 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000813 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000814 inet_ntoa (ospfh->router_id),
815 ospf_options_dump (hello->options));
816
817 /* Compare options. */
818#define REJECT_IF_TBIT_ON 1 /* XXX */
819#ifdef REJECT_IF_TBIT_ON
820 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
821 {
822 /*
823 * This router does not support non-zero TOS.
824 * Drop this Hello packet not to establish neighbor relationship.
825 */
826 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
827 inet_ntoa (ospfh->router_id));
828 return;
829 }
830#endif /* REJECT_IF_TBIT_ON */
831
832#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000833 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000834 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
835 {
836 /*
837 * This router does know the correct usage of O-bit
838 * the bit should be set in DD packet only.
839 */
840 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
841 inet_ntoa (ospfh->router_id));
842#ifdef STRICT_OBIT_USAGE_CHECK
843 return; /* Reject this packet. */
844#else /* STRICT_OBIT_USAGE_CHECK */
845 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
846#endif /* STRICT_OBIT_USAGE_CHECK */
847 }
848#endif /* HAVE_OPAQUE_LSA */
849
850 /* new for NSSA is to ensure that NP is on and E is off */
851
paul718e3742002-12-13 20:15:29 +0000852 if (oi->area->external_routing == OSPF_AREA_NSSA)
853 {
854 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
855 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
856 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
857 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
858 {
859 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
860 return;
861 }
862 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000863 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000864 }
865 else
paul718e3742002-12-13 20:15:29 +0000866 /* The setting of the E-bit found in the Hello Packet's Options
867 field must match this area's ExternalRoutingCapability A
868 mismatch causes processing to stop and the packet to be
869 dropped. The setting of the rest of the bits in the Hello
870 Packet's Options field should be ignored. */
871 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
872 CHECK_FLAG (hello->options, OSPF_OPTION_E))
873 {
ajs3aa8d5f2004-12-11 18:00:06 +0000874 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
875 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000876 return;
877 }
paul718e3742002-12-13 20:15:29 +0000878
pauld3f0d622004-05-05 15:27:15 +0000879 /* get neighbour struct */
880 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
881
882 /* neighbour must be valid, ospf_nbr_get creates if none existed */
883 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000884
885 old_state = nbr->state;
886
887 /* Add event to thread. */
888 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
889
890 /* RFC2328 Section 9.5.1
891 If the router is not eligible to become Designated Router,
892 (snip) It must also send an Hello Packet in reply to an
893 Hello Packet received from any eligible neighbor (other than
894 the current Designated Router and Backup Designated Router). */
895 if (oi->type == OSPF_IFTYPE_NBMA)
896 if (PRIORITY(oi) == 0 && hello->priority > 0
897 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
898 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
899 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
900 OSPF_HELLO_REPLY_DELAY);
901
902 /* on NBMA network type, it happens to receive bidirectional Hello packet
903 without advance 1-Way Received event.
904 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
905 if (oi->type == OSPF_IFTYPE_NBMA &&
906 (old_state == NSM_Down || old_state == NSM_Attempt))
907 {
908 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
909 nbr->priority = hello->priority;
910 nbr->d_router = hello->d_router;
911 nbr->bd_router = hello->bd_router;
912 return;
913 }
914
paul68980082003-03-25 05:07:42 +0000915 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000916 size - OSPF_HELLO_MIN_SIZE))
917 {
918 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
919 nbr->options |= hello->options;
920 }
921 else
922 {
923 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
924 /* Set neighbor information. */
925 nbr->priority = hello->priority;
926 nbr->d_router = hello->d_router;
927 nbr->bd_router = hello->bd_router;
928 return;
929 }
930
931 /* If neighbor itself declares DR and no BDR exists,
932 cause event BackupSeen */
933 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
934 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
935 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
936
937 /* neighbor itself declares BDR. */
938 if (oi->state == ISM_Waiting &&
939 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
940 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
941
942 /* had not previously. */
943 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
944 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
945 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
946 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
947 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
948
949 /* had not previously. */
950 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
951 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
952 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
953 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
955
956 /* Neighbor priority check. */
957 if (nbr->priority >= 0 && nbr->priority != hello->priority)
958 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
959
960 /* Set neighbor information. */
961 nbr->priority = hello->priority;
962 nbr->d_router = hello->d_router;
963 nbr->bd_router = hello->bd_router;
964}
965
966/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000967static void
paul718e3742002-12-13 20:15:29 +0000968ospf_db_desc_save_current (struct ospf_neighbor *nbr,
969 struct ospf_db_desc *dd)
970{
971 nbr->last_recv.flags = dd->flags;
972 nbr->last_recv.options = dd->options;
973 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
974}
975
976/* Process rest of DD packet. */
977static void
978ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
979 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
980 u_int16_t size)
981{
982 struct ospf_lsa *new, *find;
983 struct lsa_header *lsah;
984
paul9985f832005-02-09 15:51:56 +0000985 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000986 for (size -= OSPF_DB_DESC_MIN_SIZE;
987 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
988 {
989 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000990 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000991
992 /* Unknown LS type. */
993 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
994 {
ajsbec595a2004-11-30 22:38:43 +0000995 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000996 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
997 return;
998 }
999
1000#ifdef HAVE_OPAQUE_LSA
1001 if (IS_OPAQUE_LSA (lsah->type)
1002 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1003 {
1004 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1005 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1006 return;
1007 }
1008#endif /* HAVE_OPAQUE_LSA */
1009
1010 switch (lsah->type)
1011 {
1012 case OSPF_AS_EXTERNAL_LSA:
1013#ifdef HAVE_OPAQUE_LSA
1014 case OSPF_OPAQUE_AS_LSA:
1015#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001016 /* Check for stub area. Reject if AS-External from stub but
1017 allow if from NSSA. */
1018 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001019 {
1020 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1021 lsah->type, inet_ntoa (lsah->id),
1022 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1023 "STUB" : "NSSA");
1024 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1025 return;
1026 }
1027 break;
1028 default:
1029 break;
1030 }
1031
1032 /* Create LS-request object. */
1033 new = ospf_ls_request_new (lsah);
1034
1035 /* Lookup received LSA, then add LS request list. */
1036 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1037 if (!find || ospf_lsa_more_recent (find, new) < 0)
1038 {
1039 ospf_ls_request_add (nbr, new);
1040 ospf_lsa_discard (new);
1041 }
1042 else
1043 {
1044 /* Received LSA is not recent. */
1045 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001046 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001047 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1048 ospf_lsa_discard (new);
1049 continue;
1050 }
1051 }
1052
1053 /* Master */
1054 if (IS_SET_DD_MS (nbr->dd_flags))
1055 {
1056 nbr->dd_seqnum++;
1057 /* Entire DD packet sent. */
1058 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1059 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1060 else
1061 /* Send new DD packet. */
1062 ospf_db_desc_send (nbr);
1063 }
1064 /* Slave */
1065 else
1066 {
1067 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1068
1069 /* When master's more flags is not set. */
1070 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1071 {
1072 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1073 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1074 }
1075
ajsbec595a2004-11-30 22:38:43 +00001076 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001077 ospf_db_desc_send (nbr);
1078 }
1079
1080 /* Save received neighbor values from DD. */
1081 ospf_db_desc_save_current (nbr, dd);
1082}
1083
paul4dadc292005-05-06 21:37:42 +00001084static int
paul718e3742002-12-13 20:15:29 +00001085ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1086{
1087 /* Is DD duplicated? */
1088 if (dd->options == nbr->last_recv.options &&
1089 dd->flags == nbr->last_recv.flags &&
1090 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1091 return 1;
1092
1093 return 0;
1094}
1095
1096/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001097static void
paul718e3742002-12-13 20:15:29 +00001098ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1099 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1100{
1101 struct ospf_db_desc *dd;
1102 struct ospf_neighbor *nbr;
1103
1104 /* Increment statistics. */
1105 oi->db_desc_in++;
1106
1107 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001108
pauld3f0d622004-05-05 15:27:15 +00001109 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001110 if (nbr == NULL)
1111 {
1112 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1113 inet_ntoa (ospfh->router_id));
1114 return;
1115 }
1116
1117 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001118 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1119 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001120 {
ajs3aa8d5f2004-12-11 18:00:06 +00001121 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1122 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1123 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001124 return;
1125 }
1126
pauld363df22003-06-19 00:26:34 +00001127 /*
1128 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1129 * required. In fact at least JunOS sends DD packets with P bit clear.
1130 * Until proper solution is developped, this hack should help.
1131 *
1132 * Update: According to the RFCs, N bit is specified /only/ for Hello
1133 * options, unfortunately its use in DD options is not specified. Hence some
1134 * implementations follow E-bit semantics and set it in DD options, and some
1135 * treat it as unspecified and hence follow the directive "default for
1136 * options is clear", ie unset.
1137 *
1138 * Reset the flag, as ospfd follows E-bit semantics.
1139 */
1140 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1141 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1142 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1143 {
1144 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001145 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001146 inet_ntoa (nbr->router_id) );
1147 SET_FLAG (dd->options, OSPF_OPTION_NP);
1148 }
pauld363df22003-06-19 00:26:34 +00001149
paul718e3742002-12-13 20:15:29 +00001150#ifdef REJECT_IF_TBIT_ON
1151 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1152 {
1153 /*
1154 * In Hello protocol, optional capability must have checked
1155 * to prevent this T-bit enabled router be my neighbor.
1156 */
1157 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1158 return;
1159 }
1160#endif /* REJECT_IF_TBIT_ON */
1161
1162#ifdef HAVE_OPAQUE_LSA
1163 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001164 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001165 {
1166 /*
1167 * This node is not configured to handle O-bit, for now.
1168 * Clear it to ignore unsupported capability proposed by neighbor.
1169 */
1170 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1171 }
1172#endif /* HAVE_OPAQUE_LSA */
1173
1174 /* Process DD packet by neighbor status. */
1175 switch (nbr->state)
1176 {
1177 case NSM_Down:
1178 case NSM_Attempt:
1179 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001180 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001181 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001182 LOOKUP (ospf_nsm_state_msg, nbr->state));
1183 break;
1184 case NSM_Init:
1185 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1186 /* If the new state is ExStart, the processing of the current
1187 packet should then continue in this new state by falling
1188 through to case ExStart below. */
1189 if (nbr->state != NSM_ExStart)
1190 break;
1191 case NSM_ExStart:
1192 /* Initial DBD */
1193 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1194 (size == OSPF_DB_DESC_MIN_SIZE))
1195 {
paul68980082003-03-25 05:07:42 +00001196 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001197 {
1198 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001199 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001200 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001201 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1202 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1203 }
1204 else
1205 {
1206 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001207 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001208 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001209 break;
1210 }
1211 }
1212 /* Ack from the Slave */
1213 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1214 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001215 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001216 {
ajs17eaa722004-12-29 21:04:48 +00001217 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001218 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001219 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1220 }
1221 else
1222 {
ajs3aa8d5f2004-12-11 18:00:06 +00001223 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1224 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001225 break;
1226 }
1227
1228 /* This is where the real Options are saved */
1229 nbr->options = dd->options;
1230
1231#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001232 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001233 {
1234 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001235 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001236 inet_ntoa (nbr->router_id),
1237 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1238
1239 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1240 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1241 {
paul6d452762005-11-03 11:15:44 +00001242 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1243 "Opaque-LSAs cannot be reliably advertised "
1244 "in this network.",
1245 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001246 /* This situation is undesirable, but not a real error. */
1247 }
1248 }
1249#endif /* HAVE_OPAQUE_LSA */
1250
1251 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1252
1253 /* continue processing rest of packet. */
1254 ospf_db_desc_proc (s, oi, nbr, dd, size);
1255 break;
1256 case NSM_Exchange:
1257 if (ospf_db_desc_is_dup (dd, nbr))
1258 {
1259 if (IS_SET_DD_MS (nbr->dd_flags))
1260 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001261 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001262 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001263 else
1264 /* Slave: cause to retransmit the last Database Description. */
1265 {
paul6d452762005-11-03 11:15:44 +00001266 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001267 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001268 ospf_db_desc_resend (nbr);
1269 }
1270 break;
1271 }
1272
1273 /* Otherwise DD packet should be checked. */
1274 /* Check Master/Slave bit mismatch */
1275 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1276 {
ajs3aa8d5f2004-12-11 18:00:06 +00001277 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1278 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001279 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1280 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001281 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001282 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001283 break;
1284 }
1285
1286 /* Check initialize bit is set. */
1287 if (IS_SET_DD_I (dd->flags))
1288 {
paul6d452762005-11-03 11:15:44 +00001289 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001290 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001291 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1292 break;
1293 }
1294
1295 /* Check DD Options. */
1296 if (dd->options != nbr->options)
1297 {
1298#ifdef ORIGINAL_CODING
1299 /* Save the new options for debugging */
1300 nbr->options = dd->options;
1301#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001302 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1303 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001304 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1305 break;
1306 }
1307
1308 /* Check DD sequence number. */
1309 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1310 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1311 (!IS_SET_DD_MS (nbr->dd_flags) &&
1312 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1313 {
ajs3aa8d5f2004-12-11 18:00:06 +00001314 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1315 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001316 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1317 break;
1318 }
1319
1320 /* Continue processing rest of packet. */
1321 ospf_db_desc_proc (s, oi, nbr, dd, size);
1322 break;
1323 case NSM_Loading:
1324 case NSM_Full:
1325 if (ospf_db_desc_is_dup (dd, nbr))
1326 {
1327 if (IS_SET_DD_MS (nbr->dd_flags))
1328 {
1329 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001330 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1331 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001332 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001333 break;
1334 }
1335 else
1336 {
1337 struct timeval t, now;
1338 gettimeofday (&now, NULL);
1339 t = tv_sub (now, nbr->last_send_ts);
1340 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1341 {
1342 /* In states Loading and Full the slave must resend
1343 its last Database Description packet in response to
1344 duplicate Database Description packets received
1345 from the master. For this reason the slave must
1346 wait RouterDeadInterval seconds before freeing the
1347 last Database Description packet. Reception of a
1348 Database Description packet from the master after
1349 this interval will generate a SeqNumberMismatch
1350 neighbor event. RFC2328 Section 10.8 */
1351 ospf_db_desc_resend (nbr);
1352 break;
1353 }
1354 }
1355 }
1356
1357 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1358 break;
1359 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001360 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1361 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001362 break;
1363 }
1364}
1365
1366#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1367
1368/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001369static void
paul718e3742002-12-13 20:15:29 +00001370ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1371 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1372{
1373 struct ospf_neighbor *nbr;
1374 u_int32_t ls_type;
1375 struct in_addr ls_id;
1376 struct in_addr adv_router;
1377 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001378 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001379 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001380
1381 /* Increment statistics. */
1382 oi->ls_req_in++;
1383
pauld3f0d622004-05-05 15:27:15 +00001384 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001385 if (nbr == NULL)
1386 {
1387 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1388 inet_ntoa (ospfh->router_id));
1389 return;
1390 }
1391
1392 /* Neighbor State should be Exchange or later. */
1393 if (nbr->state != NSM_Exchange &&
1394 nbr->state != NSM_Loading &&
1395 nbr->state != NSM_Full)
1396 {
ajsbec595a2004-11-30 22:38:43 +00001397 zlog_warn ("Link State Request received from %s: "
1398 "Neighbor state is %s, packet discarded.",
1399 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001400 LOOKUP (ospf_nsm_state_msg, nbr->state));
1401 return;
1402 }
1403
1404 /* Send Link State Update for ALL requested LSAs. */
1405 ls_upd = list_new ();
1406 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1407
1408 while (size >= OSPF_LSA_KEY_SIZE)
1409 {
1410 /* Get one slice of Link State Request. */
1411 ls_type = stream_getl (s);
1412 ls_id.s_addr = stream_get_ipv4 (s);
1413 adv_router.s_addr = stream_get_ipv4 (s);
1414
1415 /* Verify LSA type. */
1416 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1417 {
1418 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1419 list_delete (ls_upd);
1420 return;
1421 }
1422
1423 /* Search proper LSA in LSDB. */
1424 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1425 if (find == NULL)
1426 {
1427 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1428 list_delete (ls_upd);
1429 return;
1430 }
1431
gdt86f1fd92005-01-10 14:20:43 +00001432 /* Packet overflows MTU size, send immediately. */
1433 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001434 {
1435 if (oi->type == OSPF_IFTYPE_NBMA)
1436 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1437 else
1438 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1439
1440 /* Only remove list contents. Keep ls_upd. */
1441 list_delete_all_node (ls_upd);
1442
1443 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1444 }
1445
1446 /* Append LSA to update list. */
1447 listnode_add (ls_upd, find);
1448 length += ntohs (find->data->length);
1449
1450 size -= OSPF_LSA_KEY_SIZE;
1451 }
1452
1453 /* Send rest of Link State Update. */
1454 if (listcount (ls_upd) > 0)
1455 {
1456 if (oi->type == OSPF_IFTYPE_NBMA)
1457 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1458 else
1459 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1460
1461 list_delete (ls_upd);
1462 }
1463 else
1464 list_free (ls_upd);
1465}
1466
1467/* Get the list of LSAs from Link State Update packet.
1468 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001469static struct list *
paul718e3742002-12-13 20:15:29 +00001470ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1471 struct ospf_interface *oi, size_t size)
1472{
1473 u_int16_t count, sum;
1474 u_int32_t length;
1475 struct lsa_header *lsah;
1476 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001477 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001478
1479 lsas = list_new ();
1480
1481 count = stream_getl (s);
1482 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1483
1484 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001485 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001486 {
1487 lsah = (struct lsa_header *) STREAM_PNT (s);
1488 length = ntohs (lsah->length);
1489
1490 if (length > size)
1491 {
1492 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1493 break;
1494 }
1495
1496 /* Validate the LSA's LS checksum. */
1497 sum = lsah->checksum;
1498 if (sum != ospf_lsa_checksum (lsah))
1499 {
1500 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1501 sum, lsah->checksum);
1502 continue;
1503 }
1504
1505 /* Examine the LSA's LS type. */
1506 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1507 {
1508 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1509 continue;
1510 }
1511
1512 /*
1513 * What if the received LSA's age is greater than MaxAge?
1514 * Treat it as a MaxAge case -- endo.
1515 */
1516 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1517 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1518
1519#ifdef HAVE_OPAQUE_LSA
1520 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1521 {
1522#ifdef STRICT_OBIT_USAGE_CHECK
1523 if ((IS_OPAQUE_LSA(lsah->type) &&
1524 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1525 || (! IS_OPAQUE_LSA(lsah->type) &&
1526 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1527 {
1528 /*
1529 * This neighbor must know the exact usage of O-bit;
1530 * the bit will be set in Type-9,10,11 LSAs only.
1531 */
1532 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1533 continue;
1534 }
1535#endif /* STRICT_OBIT_USAGE_CHECK */
1536
1537 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1538 if (lsah->type == OSPF_OPAQUE_AS_LSA
1539 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1540 {
1541 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001542 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 +00001543 continue;
1544 }
1545 }
1546 else if (IS_OPAQUE_LSA(lsah->type))
1547 {
1548 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1549 continue;
1550 }
1551#endif /* HAVE_OPAQUE_LSA */
1552
1553 /* Create OSPF LSA instance. */
1554 lsa = ospf_lsa_new ();
1555
1556 /* We may wish to put some error checking if type NSSA comes in
1557 and area not in NSSA mode */
1558 switch (lsah->type)
1559 {
1560 case OSPF_AS_EXTERNAL_LSA:
1561#ifdef HAVE_OPAQUE_LSA
1562 case OSPF_OPAQUE_AS_LSA:
1563 lsa->area = NULL;
1564 break;
1565 case OSPF_OPAQUE_LINK_LSA:
1566 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1567 /* Fallthrough */
1568#endif /* HAVE_OPAQUE_LSA */
1569 default:
1570 lsa->area = oi->area;
1571 break;
1572 }
1573
1574 lsa->data = ospf_lsa_data_new (length);
1575 memcpy (lsa->data, lsah, length);
1576
1577 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001578 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001579 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1580 listnode_add (lsas, lsa);
1581 }
1582
1583 return lsas;
1584}
1585
1586/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001587static void
hasso52dc7ee2004-09-23 19:18:23 +00001588ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001589{
paul1eb8ef22005-04-07 07:30:20 +00001590 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001591 struct ospf_lsa *lsa;
1592
paul1eb8ef22005-04-07 07:30:20 +00001593 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1594 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001595
1596 list_delete (lsas);
1597}
1598
1599/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001600static void
paul718e3742002-12-13 20:15:29 +00001601ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1602 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1603{
1604 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001605 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001606 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001607 struct ospf_lsa *lsa = NULL;
1608 /* unsigned long ls_req_found = 0; */
1609
1610 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1611
1612 /* Increment statistics. */
1613 oi->ls_upd_in++;
1614
1615 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001616 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001617 if (nbr == NULL)
1618 {
1619 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1620 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1621 return;
1622 }
1623
1624 /* Check neighbor state. */
1625 if (nbr->state < NSM_Exchange)
1626 {
ajs3aa8d5f2004-12-11 18:00:06 +00001627 zlog_warn ("Link State Update: "
1628 "Neighbor[%s] state %s is less than Exchange",
1629 inet_ntoa (ospfh->router_id),
1630 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001631 return;
1632 }
1633
1634 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1635 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1636 * of section 13.
1637 */
1638 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1639
1640#ifdef HAVE_OPAQUE_LSA
1641 /*
paul718e3742002-12-13 20:15:29 +00001642 * If self-originated Opaque-LSAs that have flooded before restart
1643 * are contained in the received LSUpd message, corresponding LSReq
1644 * messages to be sent may have to be modified.
1645 * To eliminate possible race conditions such that flushing and normal
1646 * updating for the same LSA would take place alternately, this trick
1647 * must be done before entering to the loop below.
1648 */
paul69310a62005-05-11 18:09:59 +00001649 /* XXX: Why is this Opaque specific? Either our core code is deficient
1650 * and this should be fixed generally, or Opaque is inventing strawman
1651 * problems */
paul718e3742002-12-13 20:15:29 +00001652 ospf_opaque_adjust_lsreq (nbr, lsas);
1653#endif /* HAVE_OPAQUE_LSA */
1654
1655#define DISCARD_LSA(L,N) {\
1656 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001657 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 +00001658 ospf_lsa_discard (L); \
1659 continue; }
1660
1661 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001662 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001663 {
1664 struct ospf_lsa *ls_ret, *current;
1665 int ret = 1;
1666
paul718e3742002-12-13 20:15:29 +00001667 if (IS_DEBUG_OSPF_NSSA)
1668 {
1669 char buf1[INET_ADDRSTRLEN];
1670 char buf2[INET_ADDRSTRLEN];
1671 char buf3[INET_ADDRSTRLEN];
1672
ajs2a42e282004-12-08 18:43:03 +00001673 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001674 lsa->data->type,
1675 inet_ntop (AF_INET, &ospfh->router_id,
1676 buf1, INET_ADDRSTRLEN),
1677 inet_ntop (AF_INET, &lsa->data->id,
1678 buf2, INET_ADDRSTRLEN),
1679 inet_ntop (AF_INET, &lsa->data->adv_router,
1680 buf3, INET_ADDRSTRLEN));
1681 }
paul718e3742002-12-13 20:15:29 +00001682
1683 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1684
1685 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1686
1687 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1688
1689 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1690
1691 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1692
1693 /* Do take in Type-7's if we are an NSSA */
1694
1695 /* If we are also an ABR, later translate them to a Type-5 packet */
1696
1697 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1698 translate them to a separate Type-5 packet. */
1699
1700 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1701 /* Reject from STUB or NSSA */
1702 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1703 {
1704 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001705 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001706 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001707 }
1708
paul718e3742002-12-13 20:15:29 +00001709 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1710 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1711 {
1712 DISCARD_LSA (lsa,2);
1713 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001714 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001715 }
paul718e3742002-12-13 20:15:29 +00001716
1717 /* Find the LSA in the current database. */
1718
1719 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1720
1721 /* If the LSA's LS age is equal to MaxAge, and there is currently
1722 no instance of the LSA in the router's link state database,
1723 and none of router's neighbors are in states Exchange or Loading,
1724 then take the following actions. */
1725
1726 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001727 (ospf_nbr_count (oi, NSM_Exchange) +
1728 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001729 {
1730 /* Response Link State Acknowledgment. */
1731 ospf_ls_ack_send (nbr, lsa);
1732
1733 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001734 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1735 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001736 DISCARD_LSA (lsa, 3);
1737 }
1738
1739#ifdef HAVE_OPAQUE_LSA
1740 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001741 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001742 {
1743 /*
1744 * Even if initial flushing seems to be completed, there might
1745 * be a case that self-originated LSA with MaxAge still remain
1746 * in the routing domain.
1747 * Just send an LSAck message to cease retransmission.
1748 */
1749 if (IS_LSA_MAXAGE (lsa))
1750 {
1751 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1752 ospf_ls_ack_send (nbr, lsa);
1753 ospf_lsa_discard (lsa);
1754
1755 if (current != NULL && ! IS_LSA_MAXAGE (current))
1756 ospf_opaque_lsa_refresh_schedule (current);
1757 continue;
1758 }
1759
1760 /*
1761 * If an instance of self-originated Opaque-LSA is not found
1762 * in the LSDB, there are some possible cases here.
1763 *
1764 * 1) This node lost opaque-capability after restart.
1765 * 2) Else, a part of opaque-type is no more supported.
1766 * 3) Else, a part of opaque-id is no more supported.
1767 *
1768 * Anyway, it is still this node's responsibility to flush it.
1769 * Otherwise, the LSA instance remains in the routing domain
1770 * until its age reaches to MaxAge.
1771 */
paul69310a62005-05-11 18:09:59 +00001772 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001773 if (current == NULL)
1774 {
1775 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001776 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1777 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001778
1779 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001780
1781 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1782 ospf_ls_ack_send (nbr, lsa);
1783
paul718e3742002-12-13 20:15:29 +00001784 continue;
1785 }
1786 }
1787#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001788
hassocb05eb22004-02-11 21:10:19 +00001789 /* It might be happen that received LSA is self-originated network LSA, but
1790 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1791 * Link State ID is one of the router's own IP interface addresses but whose
1792 * Advertising Router is not equal to the router's own Router ID
1793 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1794 */
1795
1796 if(lsa->data->type == OSPF_NETWORK_LSA)
1797 {
paul1eb8ef22005-04-07 07:30:20 +00001798 struct listnode *oinode, *oinnode;
1799 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001800 int Flag = 0;
1801
paul1eb8ef22005-04-07 07:30:20 +00001802 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001803 {
hassocb05eb22004-02-11 21:10:19 +00001804 if(out_if == NULL)
1805 break;
1806
1807 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1808 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1809 {
1810 if(out_if->network_lsa_self)
1811 {
1812 ospf_lsa_flush_area(lsa,out_if->area);
1813 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001814 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001815 lsa, (int) lsa->data->type);
1816 ospf_lsa_discard (lsa);
1817 Flag = 1;
1818 }
1819 break;
1820 }
1821 }
1822 if(Flag)
1823 continue;
1824 }
paul718e3742002-12-13 20:15:29 +00001825
1826 /* (5) Find the instance of this LSA that is currently contained
1827 in the router's link state database. If there is no
1828 database copy, or the received LSA is more recent than
1829 the database copy the following steps must be performed. */
1830
1831 if (current == NULL ||
1832 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1833 {
1834 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001835 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001836 DISCARD_LSA (lsa, 4);
1837 continue;
1838 }
1839
1840 /* (6) Else, If there is an instance of the LSA on the sending
1841 neighbor's Link state request list, an error has occurred in
1842 the Database Exchange process. In this case, restart the
1843 Database Exchange process by generating the neighbor event
1844 BadLSReq for the sending neighbor and stop processing the
1845 Link State Update packet. */
1846
1847 if (ospf_ls_request_lookup (nbr, lsa))
1848 {
1849 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001850 zlog_warn("LSA[%s] instance exists on Link state request list",
1851 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001852
1853 /* Clean list of LSAs. */
1854 ospf_upd_list_clean (lsas);
1855 /* this lsa is not on lsas list already. */
1856 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001857 return;
1858 }
1859
1860 /* If the received LSA is the same instance as the database copy
1861 (i.e., neither one is more recent) the following two steps
1862 should be performed: */
1863
1864 if (ret == 0)
1865 {
1866 /* If the LSA is listed in the Link state retransmission list
1867 for the receiving adjacency, the router itself is expecting
1868 an acknowledgment for this LSA. The router should treat the
1869 received LSA as an acknowledgment by removing the LSA from
1870 the Link state retransmission list. This is termed an
1871 "implied acknowledgment". */
1872
1873 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1874
1875 if (ls_ret != NULL)
1876 {
1877 ospf_ls_retransmit_delete (nbr, ls_ret);
1878
1879 /* Delayed acknowledgment sent if advertisement received
1880 from Designated Router, otherwise do nothing. */
1881 if (oi->state == ISM_Backup)
1882 if (NBR_IS_DR (nbr))
1883 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1884
1885 DISCARD_LSA (lsa, 5);
1886 }
1887 else
1888 /* Acknowledge the receipt of the LSA by sending a
1889 Link State Acknowledgment packet back out the receiving
1890 interface. */
1891 {
1892 ospf_ls_ack_send (nbr, lsa);
1893 DISCARD_LSA (lsa, 6);
1894 }
1895 }
1896
1897 /* The database copy is more recent. If the database copy
1898 has LS age equal to MaxAge and LS sequence number equal to
1899 MaxSequenceNumber, simply discard the received LSA without
1900 acknowledging it. (In this case, the LSA's LS sequence number is
1901 wrapping, and the MaxSequenceNumber LSA must be completely
1902 flushed before any new LSA instance can be introduced). */
1903
1904 else if (ret > 0) /* Database copy is more recent */
1905 {
1906 if (IS_LSA_MAXAGE (current) &&
1907 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1908 {
1909 DISCARD_LSA (lsa, 7);
1910 }
1911 /* Otherwise, as long as the database copy has not been sent in a
1912 Link State Update within the last MinLSArrival seconds, send the
1913 database copy back to the sending neighbor, encapsulated within
1914 a Link State Update Packet. The Link State Update Packet should
1915 be sent directly to the neighbor. In so doing, do not put the
1916 database copy of the LSA on the neighbor's link state
1917 retransmission list, and do not acknowledge the received (less
1918 recent) LSA instance. */
1919 else
1920 {
1921 struct timeval now;
1922
1923 gettimeofday (&now, NULL);
1924
1925 if (tv_cmp (tv_sub (now, current->tv_orig),
1926 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1927 /* Trap NSSA type later.*/
1928 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1929 DISCARD_LSA (lsa, 8);
1930 }
1931 }
1932 }
1933
paul718e3742002-12-13 20:15:29 +00001934 assert (listcount (lsas) == 0);
1935 list_delete (lsas);
1936}
1937
1938/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001939static void
paul718e3742002-12-13 20:15:29 +00001940ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1941 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1942{
1943 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001944
paul718e3742002-12-13 20:15:29 +00001945 /* increment statistics. */
1946 oi->ls_ack_in++;
1947
pauld3f0d622004-05-05 15:27:15 +00001948 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001949 if (nbr == NULL)
1950 {
1951 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1952 inet_ntoa (ospfh->router_id));
1953 return;
1954 }
1955
1956 if (nbr->state < NSM_Exchange)
1957 {
ajs3aa8d5f2004-12-11 18:00:06 +00001958 zlog_warn ("Link State Acknowledgment: "
1959 "Neighbor[%s] state %s is less than Exchange",
1960 inet_ntoa (ospfh->router_id),
1961 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001962 return;
1963 }
paul69310a62005-05-11 18:09:59 +00001964
paul718e3742002-12-13 20:15:29 +00001965 while (size >= OSPF_LSA_HEADER_SIZE)
1966 {
1967 struct ospf_lsa *lsa, *lsr;
1968
1969 lsa = ospf_lsa_new ();
1970 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1971
1972 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1973 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001974 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001975
1976 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1977 {
1978 lsa->data = NULL;
1979 ospf_lsa_discard (lsa);
1980 continue;
1981 }
1982
1983 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1984
1985 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1986 {
1987#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001988 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001989 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001990#endif /* HAVE_OPAQUE_LSA */
1991
1992 ospf_ls_retransmit_delete (nbr, lsr);
1993 }
1994
1995 lsa->data = NULL;
1996 ospf_lsa_discard (lsa);
1997 }
1998
paul718e3742002-12-13 20:15:29 +00001999 return;
paul718e3742002-12-13 20:15:29 +00002000}
2001
ajs038163f2005-02-17 19:55:59 +00002002static struct stream *
ajs5c333492005-02-23 15:43:01 +00002003ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002004{
2005 int ret;
ajs5c333492005-02-23 15:43:01 +00002006 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002007 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002008 unsigned int ifindex = 0;
2009 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002010 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002011 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002012 struct msghdr msgh;
2013
paul68defd62004-09-27 07:27:13 +00002014 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002015 msgh.msg_iov = &iov;
2016 msgh.msg_iovlen = 1;
2017 msgh.msg_control = (caddr_t) buff;
2018 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002019
ajs5c333492005-02-23 15:43:01 +00002020 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2021 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002022 {
ajs5c333492005-02-23 15:43:01 +00002023 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2024 return NULL;
2025 }
paul69310a62005-05-11 18:09:59 +00002026 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002027 {
2028 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2029 "(ip header size is %u)",
2030 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002031 return NULL;
2032 }
paul18b12c32004-10-05 14:38:29 +00002033
ajs5c333492005-02-23 15:43:01 +00002034 /* Note that there should not be alignment problems with this assignment
2035 because this is at the beginning of the stream data buffer. */
2036 iph = (struct ip *) STREAM_DATA(ibuf);
2037 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002038
ajs5c333492005-02-23 15:43:01 +00002039 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002040
paul239aecc2003-12-08 10:34:54 +00002041#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002042 /*
2043 * Kernel network code touches incoming IP header parameters,
2044 * before protocol specific processing.
2045 *
2046 * 1) Convert byteorder to host representation.
2047 * --> ip_len, ip_id, ip_off
2048 *
2049 * 2) Adjust ip_len to strip IP header size!
2050 * --> If user process receives entire IP packet via RAW
2051 * socket, it must consider adding IP header size to
2052 * the "ip_len" field of "ip" structure.
2053 *
2054 * For more details, see <netinet/ip_input.c>.
2055 */
ajs5c333492005-02-23 15:43:01 +00002056 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002057#endif
2058
paul863082d2004-08-19 04:43:43 +00002059 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002060
2061 *ifp = if_lookup_by_index (ifindex);
2062
2063 if (ret != ip_len)
2064 {
ajs5c333492005-02-23 15:43:01 +00002065 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2066 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002067 return NULL;
2068 }
2069
2070 return ibuf;
2071}
2072
paul4dadc292005-05-06 21:37:42 +00002073static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002074ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002075 struct ip *iph, struct ospf_header *ospfh)
2076{
2077 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002078 struct ospf_vl_data *vl_data;
2079 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002080 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002081
2082 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2083 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002084 return NULL;
paul718e3742002-12-13 20:15:29 +00002085
pauld3f0d622004-05-05 15:27:15 +00002086 /* look for local OSPF interface matching the destination
2087 * to determine Area ID. We presume therefore the destination address
2088 * is unique, or at least (for "unnumbered" links), not used in other
2089 * areas
2090 */
2091 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2092 iph->ip_dst)) == NULL)
2093 return NULL;
paul718e3742002-12-13 20:15:29 +00002094
paul1eb8ef22005-04-07 07:30:20 +00002095 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002096 {
paul020709f2003-04-04 02:44:16 +00002097 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002098 if (!vl_area)
2099 continue;
2100
2101 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2102 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2103 {
2104 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002105 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002106 IF_NAME (vl_data->vl_oi));
2107 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2108 {
2109 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002110 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002111 return NULL;
2112 }
2113
2114 return vl_data->vl_oi;
2115 }
2116 }
2117
2118 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002119 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002120
pauld3f0d622004-05-05 15:27:15 +00002121 return NULL;
paul718e3742002-12-13 20:15:29 +00002122}
2123
paul4dadc292005-05-06 21:37:42 +00002124static inline int
paul718e3742002-12-13 20:15:29 +00002125ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2126{
2127 /* Check match the Area ID of the receiving interface. */
2128 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2129 return 1;
2130
2131 return 0;
2132}
2133
2134/* Unbound socket will accept any Raw IP packets if proto is matched.
2135 To prevent it, compare src IP address and i/f address with masking
2136 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002137static int
paul718e3742002-12-13 20:15:29 +00002138ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2139{
2140 struct in_addr mask, me, him;
2141
2142 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2143 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2144 return 1;
2145
2146 masklen2ip (oi->address->prefixlen, &mask);
2147
2148 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2149 him.s_addr = ip_src.s_addr & mask.s_addr;
2150
2151 if (IPV4_ADDR_SAME (&me, &him))
2152 return 1;
2153
2154 return 0;
2155}
2156
paul4dadc292005-05-06 21:37:42 +00002157static int
paul718e3742002-12-13 20:15:29 +00002158ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2159 struct ospf_header *ospfh)
2160{
2161 int ret = 0;
2162 struct crypt_key *ck;
2163
2164 switch (ntohs (ospfh->auth_type))
2165 {
2166 case OSPF_AUTH_NULL:
2167 ret = 1;
2168 break;
2169 case OSPF_AUTH_SIMPLE:
2170 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2171 ret = 1;
2172 else
2173 ret = 0;
2174 break;
2175 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002176 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002177 {
2178 ret = 0;
2179 break;
2180 }
2181
2182 /* This is very basic, the digest processing is elsewhere */
2183 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2184 ospfh->u.crypt.key_id == ck->key_id &&
2185 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2186 ret = 1;
2187 else
2188 ret = 0;
2189 break;
2190 default:
2191 ret = 0;
2192 break;
2193 }
2194
2195 return ret;
2196}
2197
paul4dadc292005-05-06 21:37:42 +00002198static int
paul718e3742002-12-13 20:15:29 +00002199ospf_check_sum (struct ospf_header *ospfh)
2200{
2201 u_int32_t ret;
2202 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002203
2204 /* clear auth_data for checksum. */
2205 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2206
2207 /* keep checksum and clear. */
2208 sum = ospfh->checksum;
2209 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2210
2211 /* calculate checksum. */
2212 ret = in_cksum (ospfh, ntohs (ospfh->length));
2213
2214 if (ret != sum)
2215 {
2216 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2217 ret, sum);
2218 return 0;
2219 }
2220
2221 return 1;
2222}
2223
2224/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002225static int
paul718e3742002-12-13 20:15:29 +00002226ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2227 struct ip *iph, struct ospf_header *ospfh)
2228{
2229 /* check version. */
2230 if (ospfh->version != OSPF_VERSION)
2231 {
2232 zlog_warn ("interface %s: ospf_read version number mismatch.",
2233 IF_NAME (oi));
2234 return -1;
2235 }
2236
2237 /* Check Area ID. */
2238 if (!ospf_check_area_id (oi, ospfh))
2239 {
2240 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2241 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2242 return -1;
2243 }
2244
2245 /* Check network mask, Silently discarded. */
2246 if (! ospf_check_network_mask (oi, iph->ip_src))
2247 {
2248 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2249 IF_NAME (oi), inet_ntoa (iph->ip_src));
2250 return -1;
2251 }
2252
2253 /* Check authentication. */
2254 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2255 {
paulc6371712006-01-17 17:49:53 +00002256 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2257 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002258 return -1;
2259 }
2260
2261 if (! ospf_check_auth (oi, ibuf, ospfh))
2262 {
2263 zlog_warn ("interface %s: ospf_read authentication failed.",
2264 IF_NAME (oi));
2265 return -1;
2266 }
2267
2268 /* if check sum is invalid, packet is discarded. */
2269 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2270 {
2271 if (! ospf_check_sum (ospfh))
2272 {
2273 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2274 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2275 return -1;
2276 }
2277 }
2278 else
2279 {
2280 if (ospfh->checksum != 0)
2281 return -1;
2282 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2283 {
2284 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2285 IF_NAME (oi));
2286 return -1;
2287 }
2288 }
2289
2290 return 0;
2291}
2292
2293/* Starting point of packet process function. */
2294int
2295ospf_read (struct thread *thread)
2296{
2297 int ret;
2298 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002299 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002300 struct ospf_interface *oi;
2301 struct ip *iph;
2302 struct ospf_header *ospfh;
2303 u_int16_t length;
2304 struct interface *ifp;
2305
2306 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002307 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002308
2309 /* prepare for next packet. */
2310 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002311
2312 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002313 stream_reset(ospf->ibuf);
2314 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002315 return -1;
2316
ajs5c333492005-02-23 15:43:01 +00002317 /* Note that there should not be alignment problems with this assignment
2318 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002319 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002320 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002321
paulac191232004-10-22 12:05:17 +00002322 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002323 /* Handle cases where the platform does not support retrieving the ifindex,
2324 and also platforms (such as Solaris 8) that claim to support ifindex
2325 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002326 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002327
pauld3f0d622004-05-05 15:27:15 +00002328 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002329 return 0;
paul718e3742002-12-13 20:15:29 +00002330
2331 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002332 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002333 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002334
paul718e3742002-12-13 20:15:29 +00002335 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002336 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002337 {
pauld3241812003-09-29 12:42:39 +00002338 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2339 {
ajs2a42e282004-12-08 18:43:03 +00002340 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002341 inet_ntoa (iph->ip_src));
2342 }
paul718e3742002-12-13 20:15:29 +00002343 return 0;
2344 }
2345
2346 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002347 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002348
2349 /* Get ospf packet header. */
2350 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2351
2352 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002353 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002354
2355 /* if no local ospf_interface,
2356 * or header area is backbone but ospf_interface is not
2357 * check for VLINK interface
2358 */
2359 if ( (oi == NULL) ||
2360 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2361 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2362 )
2363 {
2364 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2365 {
Paul Jakma88871b12006-06-15 11:41:19 +00002366 if (IS_DEBUG_OSPF_EVENT)
2367 zlog_debug ("Packet from [%s] received on link %s"
2368 " but no ospf_interface",
2369 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002370 return 0;
2371 }
2372 }
2373
2374 /* else it must be a local ospf interface, check it was received on
2375 * correct link
2376 */
2377 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002378 {
2379 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002380 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002381 return 0;
2382 }
ajs847947f2005-02-02 18:38:48 +00002383 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002384 {
ajsba6454e2005-02-08 15:37:30 +00002385 char buf[2][INET_ADDRSTRLEN];
2386 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002387 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002388 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2389 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2390 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002391 /* Fix multicast memberships? */
2392 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002393 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002394 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002395 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002396 if (oi->multicast_memberships)
2397 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002398 return 0;
2399 }
paul718e3742002-12-13 20:15:29 +00002400
2401 /*
2402 * If the received packet is destined for AllDRouters, the packet
2403 * should be accepted only if the received ospf interface state is
2404 * either DR or Backup -- endo.
2405 */
2406 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2407 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2408 {
ajsba6454e2005-02-08 15:37:30 +00002409 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002410 inet_ntoa (iph->ip_src), IF_NAME (oi),
2411 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002412 /* Try to fix multicast membership. */
2413 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2414 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002415 return 0;
2416 }
2417
2418 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002419 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2420 {
paul718e3742002-12-13 20:15:29 +00002421 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002422 {
ajs2a42e282004-12-08 18:43:03 +00002423 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002424 ospf_packet_dump (ibuf);
2425 }
paul718e3742002-12-13 20:15:29 +00002426
ajs2a42e282004-12-08 18:43:03 +00002427 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002428 ospf_packet_type_str[ospfh->type],
2429 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002430 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2431 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002432
2433 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002434 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002435 }
paul718e3742002-12-13 20:15:29 +00002436
2437 /* Some header verification. */
2438 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2439 if (ret < 0)
2440 {
pauld3241812003-09-29 12:42:39 +00002441 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2442 {
ajs2a42e282004-12-08 18:43:03 +00002443 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002444 "dropping.",
2445 ospf_packet_type_str[ospfh->type],
2446 inet_ntoa (iph->ip_src));
2447 }
paul718e3742002-12-13 20:15:29 +00002448 return ret;
2449 }
2450
paul9985f832005-02-09 15:51:56 +00002451 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002452
2453 /* Adjust size to message length. */
2454 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2455
2456 /* Read rest of the packet and call each sort of packet routine. */
2457 switch (ospfh->type)
2458 {
2459 case OSPF_MSG_HELLO:
2460 ospf_hello (iph, ospfh, ibuf, oi, length);
2461 break;
2462 case OSPF_MSG_DB_DESC:
2463 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2464 break;
2465 case OSPF_MSG_LS_REQ:
2466 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2467 break;
2468 case OSPF_MSG_LS_UPD:
2469 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2470 break;
2471 case OSPF_MSG_LS_ACK:
2472 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2473 break;
2474 default:
2475 zlog (NULL, LOG_WARNING,
2476 "interface %s: OSPF packet header type %d is illegal",
2477 IF_NAME (oi), ospfh->type);
2478 break;
2479 }
2480
paul718e3742002-12-13 20:15:29 +00002481 return 0;
2482}
2483
2484/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002485static void
paul718e3742002-12-13 20:15:29 +00002486ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2487{
2488 struct ospf_header *ospfh;
2489
2490 ospfh = (struct ospf_header *) STREAM_DATA (s);
2491
2492 ospfh->version = (u_char) OSPF_VERSION;
2493 ospfh->type = (u_char) type;
2494
paul68980082003-03-25 05:07:42 +00002495 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002496
2497 ospfh->checksum = 0;
2498 ospfh->area_id = oi->area->area_id;
2499 ospfh->auth_type = htons (ospf_auth_type (oi));
2500
2501 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2502
paul9985f832005-02-09 15:51:56 +00002503 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002504}
2505
2506/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002507static int
paul718e3742002-12-13 20:15:29 +00002508ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2509{
2510 struct crypt_key *ck;
2511
2512 switch (ospf_auth_type (oi))
2513 {
2514 case OSPF_AUTH_NULL:
2515 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2516 break;
2517 case OSPF_AUTH_SIMPLE:
2518 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2519 OSPF_AUTH_SIMPLE_SIZE);
2520 break;
2521 case OSPF_AUTH_CRYPTOGRAPHIC:
2522 /* If key is not set, then set 0. */
2523 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2524 {
2525 ospfh->u.crypt.zero = 0;
2526 ospfh->u.crypt.key_id = 0;
2527 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2528 }
2529 else
2530 {
paul1eb8ef22005-04-07 07:30:20 +00002531 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002532 ospfh->u.crypt.zero = 0;
2533 ospfh->u.crypt.key_id = ck->key_id;
2534 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2535 }
2536 /* note: the seq is done in ospf_make_md5_digest() */
2537 break;
2538 default:
2539 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2540 break;
2541 }
2542
2543 return 0;
2544}
2545
2546/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002547static void
paul718e3742002-12-13 20:15:29 +00002548ospf_fill_header (struct ospf_interface *oi,
2549 struct stream *s, u_int16_t length)
2550{
2551 struct ospf_header *ospfh;
2552
2553 ospfh = (struct ospf_header *) STREAM_DATA (s);
2554
2555 /* Fill length. */
2556 ospfh->length = htons (length);
2557
2558 /* Calculate checksum. */
2559 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2560 ospfh->checksum = in_cksum (ospfh, length);
2561 else
2562 ospfh->checksum = 0;
2563
2564 /* Add Authentication Data. */
2565 ospf_make_auth (oi, ospfh);
2566}
2567
paul4dadc292005-05-06 21:37:42 +00002568static int
paul718e3742002-12-13 20:15:29 +00002569ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2570{
2571 struct ospf_neighbor *nbr;
2572 struct route_node *rn;
2573 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2574 struct in_addr mask;
2575 unsigned long p;
2576 int flag = 0;
2577
2578 /* Set netmask of interface. */
2579 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2580 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2581 masklen2ip (oi->address->prefixlen, &mask);
2582 else
2583 memset ((char *) &mask, 0, sizeof (struct in_addr));
2584 stream_put_ipv4 (s, mask.s_addr);
2585
2586 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002587 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2588 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2589 else
2590 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002591
2592 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002593 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002594 OPTIONS(oi), IF_NAME (oi));
2595
2596 /* Set Options. */
2597 stream_putc (s, OPTIONS (oi));
2598
2599 /* Set Router Priority. */
2600 stream_putc (s, PRIORITY (oi));
2601
2602 /* Set Router Dead Interval. */
2603 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2604
2605 /* Set Designated Router. */
2606 stream_put_ipv4 (s, DR (oi).s_addr);
2607
paul9985f832005-02-09 15:51:56 +00002608 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002609
2610 /* Set Backup Designated Router. */
2611 stream_put_ipv4 (s, BDR (oi).s_addr);
2612
2613 /* Add neighbor seen. */
2614 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002615 if ((nbr = rn->info))
2616 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2617 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2618 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2619 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002620 {
2621 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002622 if (nbr->d_router.s_addr != 0
2623 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2624 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2625 flag = 1;
paul718e3742002-12-13 20:15:29 +00002626
2627 stream_put_ipv4 (s, nbr->router_id.s_addr);
2628 length += 4;
2629 }
2630
2631 /* Let neighbor generate BackupSeen. */
2632 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002633 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002634
2635 return length;
2636}
2637
paul4dadc292005-05-06 21:37:42 +00002638static int
paul718e3742002-12-13 20:15:29 +00002639ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2640 struct stream *s)
2641{
2642 struct ospf_lsa *lsa;
2643 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2644 u_char options;
2645 unsigned long pp;
2646 int i;
2647 struct ospf_lsdb *lsdb;
2648
2649 /* Set Interface MTU. */
2650 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2651 stream_putw (s, 0);
2652 else
2653 stream_putw (s, oi->ifp->mtu);
2654
2655 /* Set Options. */
2656 options = OPTIONS (oi);
2657#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002658 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002659 {
2660 if (IS_SET_DD_I (nbr->dd_flags)
2661 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2662 /*
2663 * Set O-bit in the outgoing DD packet for capablity negotiation,
2664 * if one of following case is applicable.
2665 *
2666 * 1) WaitTimer expiration event triggered the neighbor state to
2667 * change to Exstart, but no (valid) DD packet has received
2668 * from the neighbor yet.
2669 *
2670 * 2) At least one DD packet with O-bit on has received from the
2671 * neighbor.
2672 */
2673 SET_FLAG (options, OSPF_OPTION_O);
2674 }
2675#endif /* HAVE_OPAQUE_LSA */
2676 stream_putc (s, options);
2677
2678 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002679 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002680 stream_putc (s, nbr->dd_flags);
2681
2682 /* Set DD Sequence Number. */
2683 stream_putl (s, nbr->dd_seqnum);
2684
2685 if (ospf_db_summary_isempty (nbr))
2686 {
2687 if (nbr->state >= NSM_Exchange)
2688 {
2689 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2690 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002691 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002692 }
2693 return length;
2694 }
2695
2696 /* Describe LSA Header from Database Summary List. */
2697 lsdb = &nbr->db_sum;
2698
2699 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2700 {
2701 struct route_table *table = lsdb->type[i].db;
2702 struct route_node *rn;
2703
2704 for (rn = route_top (table); rn; rn = route_next (rn))
2705 if ((lsa = rn->info) != NULL)
2706 {
2707#ifdef HAVE_OPAQUE_LSA
2708 if (IS_OPAQUE_LSA (lsa->data->type)
2709 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2710 {
2711 /* Suppress advertising opaque-informations. */
2712 /* Remove LSA from DB summary list. */
2713 ospf_lsdb_delete (lsdb, lsa);
2714 continue;
2715 }
2716#endif /* HAVE_OPAQUE_LSA */
2717
2718 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2719 {
2720 struct lsa_header *lsah;
2721 u_int16_t ls_age;
2722
2723 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002724 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002725 break;
2726
2727 /* Keep pointer to LS age. */
2728 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002729 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002730
2731 /* Proceed stream pointer. */
2732 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2733 length += OSPF_LSA_HEADER_SIZE;
2734
2735 /* Set LS age. */
2736 ls_age = LS_AGE (lsa);
2737 lsah->ls_age = htons (ls_age);
2738
2739 }
2740
2741 /* Remove LSA from DB summary list. */
2742 ospf_lsdb_delete (lsdb, lsa);
2743 }
2744 }
2745
2746 return length;
2747}
2748
paul4dadc292005-05-06 21:37:42 +00002749static int
paul718e3742002-12-13 20:15:29 +00002750ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2751 unsigned long delta, struct ospf_neighbor *nbr,
2752 struct ospf_lsa *lsa)
2753{
2754 struct ospf_interface *oi;
2755
2756 oi = nbr->oi;
2757
2758 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002759 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002760 return 0;
2761
2762 stream_putl (s, lsa->data->type);
2763 stream_put_ipv4 (s, lsa->data->id.s_addr);
2764 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2765
2766 ospf_lsa_unlock (nbr->ls_req_last);
2767 nbr->ls_req_last = ospf_lsa_lock (lsa);
2768
2769 *length += 12;
2770 return 1;
2771}
2772
paul4dadc292005-05-06 21:37:42 +00002773static int
paul718e3742002-12-13 20:15:29 +00002774ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2775{
2776 struct ospf_lsa *lsa;
2777 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002778 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002779 struct route_table *table;
2780 struct route_node *rn;
2781 int i;
2782 struct ospf_lsdb *lsdb;
2783
2784 lsdb = &nbr->ls_req;
2785
2786 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2787 {
2788 table = lsdb->type[i].db;
2789 for (rn = route_top (table); rn; rn = route_next (rn))
2790 if ((lsa = (rn->info)) != NULL)
2791 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2792 {
2793 route_unlock_node (rn);
2794 break;
2795 }
2796 }
2797 return length;
2798}
2799
paul4dadc292005-05-06 21:37:42 +00002800static int
paul718e3742002-12-13 20:15:29 +00002801ls_age_increment (struct ospf_lsa *lsa, int delay)
2802{
2803 int age;
2804
2805 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2806
2807 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2808}
2809
paul4dadc292005-05-06 21:37:42 +00002810static int
hasso52dc7ee2004-09-23 19:18:23 +00002811ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002812{
2813 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002814 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002815 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002816 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002817 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002818 unsigned long pp;
2819 int count = 0;
2820
2821 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002822 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002823
paul9985f832005-02-09 15:51:56 +00002824 pp = stream_get_endp (s);
2825 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002826
gdt86f1fd92005-01-10 14:20:43 +00002827 /* Calculate amount of packet usable for data. */
2828 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2829
paul718e3742002-12-13 20:15:29 +00002830 while ((node = listhead (update)) != NULL)
2831 {
2832 struct lsa_header *lsah;
2833 u_int16_t ls_age;
2834
2835 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002836 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002837
paul1eb8ef22005-04-07 07:30:20 +00002838 lsa = listgetdata (node);
2839
paul718e3742002-12-13 20:15:29 +00002840 assert (lsa->data);
2841
paul68b73392004-09-12 14:21:37 +00002842 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002843 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002844 break;
2845
paul718e3742002-12-13 20:15:29 +00002846 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002847 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002848
2849 /* Put LSA to Link State Request. */
2850 stream_put (s, lsa->data, ntohs (lsa->data->length));
2851
2852 /* Set LS age. */
2853 /* each hop must increment an lsa_age by transmit_delay
2854 of OSPF interface */
2855 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2856 lsah->ls_age = htons (ls_age);
2857
2858 length += ntohs (lsa->data->length);
2859 count++;
2860
2861 list_delete_node (update, node);
2862 ospf_lsa_unlock (lsa);
2863 }
2864
2865 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002866 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002867
2868 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002869 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002870 return length;
2871}
2872
paul4dadc292005-05-06 21:37:42 +00002873static int
hasso52dc7ee2004-09-23 19:18:23 +00002874ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002875{
hasso52dc7ee2004-09-23 19:18:23 +00002876 struct list *rm_list;
2877 struct listnode *node;
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
2882 rm_list = list_new ();
2883
paul1eb8ef22005-04-07 07:30:20 +00002884 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002885 {
paul1eb8ef22005-04-07 07:30:20 +00002886 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002887 assert (lsa);
2888
gdt86f1fd92005-01-10 14:20:43 +00002889 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002890 break;
2891
2892 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2893 length += OSPF_LSA_HEADER_SIZE;
2894
2895 listnode_add (rm_list, lsa);
2896 }
2897
2898 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002899 /* XXX: this loop should be removed and the list move done in previous
2900 * loop
2901 */
2902 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002903 {
paul718e3742002-12-13 20:15:29 +00002904 listnode_delete (ack, lsa);
2905 ospf_lsa_unlock (lsa);
2906 }
2907
2908 list_delete (rm_list);
2909
2910 return length;
2911}
2912
2913void
2914ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2915{
2916 struct ospf_packet *op;
2917 u_int16_t length = OSPF_HEADER_SIZE;
2918
2919 op = ospf_packet_new (oi->ifp->mtu);
2920
2921 /* Prepare OSPF common header. */
2922 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2923
2924 /* Prepare OSPF Hello body. */
2925 length += ospf_make_hello (oi, op->s);
2926
2927 /* Fill OSPF header. */
2928 ospf_fill_header (oi, op->s, length);
2929
2930 /* Set packet length. */
2931 op->length = length;
2932
2933 op->dst.s_addr = addr->s_addr;
2934
2935 /* Add packet to the interface output queue. */
2936 ospf_packet_add (oi, op);
2937
2938 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002939 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002940}
2941
paul4dadc292005-05-06 21:37:42 +00002942static void
paul718e3742002-12-13 20:15:29 +00002943ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2944{
2945 struct ospf_interface *oi;
2946
2947 oi = nbr_nbma->oi;
2948 assert(oi);
2949
2950 /* If this is passive interface, do not send OSPF Hello. */
2951 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2952 return;
2953
2954 if (oi->type != OSPF_IFTYPE_NBMA)
2955 return;
2956
2957 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2958 return;
2959
2960 if (PRIORITY(oi) == 0)
2961 return;
2962
2963 if (nbr_nbma->priority == 0
2964 && oi->state != ISM_DR && oi->state != ISM_Backup)
2965 return;
2966
2967 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2968}
2969
2970int
2971ospf_poll_timer (struct thread *thread)
2972{
2973 struct ospf_nbr_nbma *nbr_nbma;
2974
2975 nbr_nbma = THREAD_ARG (thread);
2976 nbr_nbma->t_poll = NULL;
2977
2978 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002979 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002980 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2981
2982 ospf_poll_send (nbr_nbma);
2983
2984 if (nbr_nbma->v_poll > 0)
2985 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2986 nbr_nbma->v_poll);
2987
2988 return 0;
2989}
2990
2991
2992int
2993ospf_hello_reply_timer (struct thread *thread)
2994{
2995 struct ospf_neighbor *nbr;
2996
2997 nbr = THREAD_ARG (thread);
2998 nbr->t_hello_reply = NULL;
2999
3000 assert (nbr->oi);
3001
3002 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003003 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003004 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3005
3006 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3007
3008 return 0;
3009}
3010
3011/* Send OSPF Hello. */
3012void
3013ospf_hello_send (struct ospf_interface *oi)
3014{
3015 struct ospf_packet *op;
3016 u_int16_t length = OSPF_HEADER_SIZE;
3017
3018 /* If this is passive interface, do not send OSPF Hello. */
3019 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3020 return;
3021
3022 op = ospf_packet_new (oi->ifp->mtu);
3023
3024 /* Prepare OSPF common header. */
3025 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3026
3027 /* Prepare OSPF Hello body. */
3028 length += ospf_make_hello (oi, op->s);
3029
3030 /* Fill OSPF header. */
3031 ospf_fill_header (oi, op->s, length);
3032
3033 /* Set packet length. */
3034 op->length = length;
3035
3036 if (oi->type == OSPF_IFTYPE_NBMA)
3037 {
3038 struct ospf_neighbor *nbr;
3039 struct route_node *rn;
3040
3041 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3042 if ((nbr = rn->info))
3043 if (nbr != oi->nbr_self)
3044 if (nbr->state != NSM_Down)
3045 {
3046 /* RFC 2328 Section 9.5.1
3047 If the router is not eligible to become Designated Router,
3048 it must periodically send Hello Packets to both the
3049 Designated Router and the Backup Designated Router (if they
3050 exist). */
3051 if (PRIORITY(oi) == 0 &&
3052 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3053 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3054 continue;
3055
3056 /* If the router is eligible to become Designated Router, it
3057 must periodically send Hello Packets to all neighbors that
3058 are also eligible. In addition, if the router is itself the
3059 Designated Router or Backup Designated Router, it must also
3060 send periodic Hello Packets to all other neighbors. */
3061
3062 if (nbr->priority == 0 && oi->state == ISM_DROther)
3063 continue;
3064 /* if oi->state == Waiting, send hello to all neighbors */
3065 {
3066 struct ospf_packet *op_dup;
3067
3068 op_dup = ospf_packet_dup(op);
3069 op_dup->dst = nbr->address.u.prefix4;
3070
3071 /* Add packet to the interface output queue. */
3072 ospf_packet_add (oi, op_dup);
3073
paul020709f2003-04-04 02:44:16 +00003074 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003075 }
3076
3077 }
3078 ospf_packet_free (op);
3079 }
3080 else
3081 {
3082 /* Decide destination address. */
3083 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3084 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3085 else
3086 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3087
3088 /* Add packet to the interface output queue. */
3089 ospf_packet_add (oi, op);
3090
3091 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003092 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003093 }
3094}
3095
3096/* Send OSPF Database Description. */
3097void
3098ospf_db_desc_send (struct ospf_neighbor *nbr)
3099{
3100 struct ospf_interface *oi;
3101 struct ospf_packet *op;
3102 u_int16_t length = OSPF_HEADER_SIZE;
3103
3104 oi = nbr->oi;
3105 op = ospf_packet_new (oi->ifp->mtu);
3106
3107 /* Prepare OSPF common header. */
3108 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3109
3110 /* Prepare OSPF Database Description body. */
3111 length += ospf_make_db_desc (oi, nbr, op->s);
3112
3113 /* Fill OSPF header. */
3114 ospf_fill_header (oi, op->s, length);
3115
3116 /* Set packet length. */
3117 op->length = length;
3118
3119 /* Decide destination address. */
3120 op->dst = nbr->address.u.prefix4;
3121
3122 /* Add packet to the interface output queue. */
3123 ospf_packet_add (oi, op);
3124
3125 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003126 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003127
3128 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3129 if (nbr->last_send)
3130 ospf_packet_free (nbr->last_send);
3131 nbr->last_send = ospf_packet_dup (op);
3132 gettimeofday (&nbr->last_send_ts, NULL);
3133}
3134
3135/* Re-send Database Description. */
3136void
3137ospf_db_desc_resend (struct ospf_neighbor *nbr)
3138{
3139 struct ospf_interface *oi;
3140
3141 oi = nbr->oi;
3142
3143 /* Add packet to the interface output queue. */
3144 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3145
3146 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003147 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003148}
3149
3150/* Send Link State Request. */
3151void
3152ospf_ls_req_send (struct ospf_neighbor *nbr)
3153{
3154 struct ospf_interface *oi;
3155 struct ospf_packet *op;
3156 u_int16_t length = OSPF_HEADER_SIZE;
3157
3158 oi = nbr->oi;
3159 op = ospf_packet_new (oi->ifp->mtu);
3160
3161 /* Prepare OSPF common header. */
3162 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3163
3164 /* Prepare OSPF Link State Request body. */
3165 length += ospf_make_ls_req (nbr, op->s);
3166 if (length == OSPF_HEADER_SIZE)
3167 {
3168 ospf_packet_free (op);
3169 return;
3170 }
3171
3172 /* Fill OSPF header. */
3173 ospf_fill_header (oi, op->s, length);
3174
3175 /* Set packet length. */
3176 op->length = length;
3177
3178 /* Decide destination address. */
3179 op->dst = nbr->address.u.prefix4;
3180
3181 /* Add packet to the interface output queue. */
3182 ospf_packet_add (oi, op);
3183
3184 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003185 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003186
3187 /* Add Link State Request Retransmission Timer. */
3188 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3189}
3190
3191/* Send Link State Update with an LSA. */
3192void
3193ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3194 int flag)
3195{
hasso52dc7ee2004-09-23 19:18:23 +00003196 struct list *update;
paul718e3742002-12-13 20:15:29 +00003197
3198 update = list_new ();
3199
3200 listnode_add (update, lsa);
3201 ospf_ls_upd_send (nbr, update, flag);
3202
3203 list_delete (update);
3204}
3205
paul68b73392004-09-12 14:21:37 +00003206/* Determine size for packet. Must be at least big enough to accomodate next
3207 * LSA on list, which may be bigger than MTU size.
3208 *
3209 * Return pointer to new ospf_packet
3210 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3211 * on packet sizes (in which case offending LSA is deleted from update list)
3212 */
3213static struct ospf_packet *
3214ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3215{
3216 struct ospf_lsa *lsa;
3217 struct listnode *ln;
3218 size_t size;
3219 static char warned = 0;
3220
paul1eb8ef22005-04-07 07:30:20 +00003221 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003222 assert (lsa->data);
3223
3224 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3225 > ospf_packet_max (oi))
3226 {
3227 if (!warned)
3228 {
3229 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3230 "will need to fragment. Not optimal. Try divide up"
3231 " your network with areas. Use 'debug ospf packet send'"
3232 " to see details, or look at 'show ip ospf database ..'");
3233 warned = 1;
3234 }
3235
3236 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003237 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003238 " %d bytes originated by %s, will be fragmented!",
3239 inet_ntoa (lsa->data->id),
3240 ntohs (lsa->data->length),
3241 inet_ntoa (lsa->data->adv_router));
3242
3243 /*
3244 * Allocate just enough to fit this LSA only, to avoid including other
3245 * LSAs in fragmented LSA Updates.
3246 */
3247 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3248 + OSPF_LS_UPD_MIN_SIZE;
3249 }
3250 else
3251 size = oi->ifp->mtu;
3252
gdt86f1fd92005-01-10 14:20:43 +00003253 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003254 if (size > OSPF_MAX_PACKET_SIZE)
3255 {
3256 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003257 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003258 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003259 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003260 (long int) size);
paul68b73392004-09-12 14:21:37 +00003261 list_delete_node (update, ln);
3262 return NULL;
3263 }
3264
3265 return ospf_packet_new (size);
3266}
3267
paul718e3742002-12-13 20:15:29 +00003268static void
hasso52dc7ee2004-09-23 19:18:23 +00003269ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003270 struct in_addr addr)
3271{
3272 struct ospf_packet *op;
3273 u_int16_t length = OSPF_HEADER_SIZE;
3274
3275 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003276 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003277
3278 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003279
3280 /* Prepare OSPF common header. */
3281 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3282
paul59ea14c2004-07-14 20:50:36 +00003283 /* Prepare OSPF Link State Update body.
3284 * Includes Type-7 translation.
3285 */
paul718e3742002-12-13 20:15:29 +00003286 length += ospf_make_ls_upd (oi, update, op->s);
3287
3288 /* Fill OSPF header. */
3289 ospf_fill_header (oi, op->s, length);
3290
3291 /* Set packet length. */
3292 op->length = length;
3293
3294 /* Decide destination address. */
3295 op->dst.s_addr = addr.s_addr;
3296
3297 /* Add packet to the interface output queue. */
3298 ospf_packet_add (oi, op);
3299
3300 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003301 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003302}
3303
3304static int
3305ospf_ls_upd_send_queue_event (struct thread *thread)
3306{
3307 struct ospf_interface *oi = THREAD_ARG(thread);
3308 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003309 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003310 struct list *update;
paul68b73392004-09-12 14:21:37 +00003311 char again = 0;
paul718e3742002-12-13 20:15:29 +00003312
3313 oi->t_ls_upd_event = NULL;
3314
3315 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003316 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003317
paul736d3442003-07-24 23:22:57 +00003318 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003319 {
paul736d3442003-07-24 23:22:57 +00003320 rnext = route_next (rn);
3321
paul718e3742002-12-13 20:15:29 +00003322 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003323 continue;
paul68b73392004-09-12 14:21:37 +00003324
3325 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003326
paul48fe13b2004-07-27 17:40:44 +00003327 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003328
paul68b73392004-09-12 14:21:37 +00003329 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003330 if (listcount(update) == 0)
3331 {
3332 list_delete (rn->info);
3333 rn->info = NULL;
3334 route_unlock_node (rn);
3335 }
3336 else
paul68b73392004-09-12 14:21:37 +00003337 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003338 }
3339
3340 if (again != 0)
3341 {
3342 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003343 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003344 " %d nodes to try again, raising new event", again);
3345 oi->t_ls_upd_event =
3346 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003347 }
3348
3349 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003350 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003351
paul718e3742002-12-13 20:15:29 +00003352 return 0;
3353}
3354
3355void
hasso52dc7ee2004-09-23 19:18:23 +00003356ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003357{
3358 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003359 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003360 struct prefix_ipv4 p;
3361 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003362 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003363
3364 oi = nbr->oi;
3365
3366 p.family = AF_INET;
3367 p.prefixlen = IPV4_MAX_BITLEN;
3368
3369 /* Decide destination address. */
3370 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3371 p.prefix = oi->vl_data->peer_addr;
3372 else if (flag == OSPF_SEND_PACKET_DIRECT)
3373 p.prefix = nbr->address.u.prefix4;
3374 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3375 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3376 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3377 && (flag == OSPF_SEND_PACKET_INDIRECT))
3378 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003379 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3380 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003381 else
3382 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3383
3384 if (oi->type == OSPF_IFTYPE_NBMA)
3385 {
3386 if (flag == OSPF_SEND_PACKET_INDIRECT)
3387 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3388 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3389 zlog_warn ("* LS-Update is sent to myself.");
3390 }
3391
3392 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3393
3394 if (rn->info == NULL)
3395 rn->info = list_new ();
3396
paul1eb8ef22005-04-07 07:30:20 +00003397 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3398 {
3399 ospf_lsa_lock (lsa);
3400 listnode_add (rn->info, lsa);
3401 }
paul718e3742002-12-13 20:15:29 +00003402
3403 if (oi->t_ls_upd_event == NULL)
3404 oi->t_ls_upd_event =
3405 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3406}
3407
3408static void
hasso52dc7ee2004-09-23 19:18:23 +00003409ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3410 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003411{
3412 struct ospf_packet *op;
3413 u_int16_t length = OSPF_HEADER_SIZE;
3414
3415 op = ospf_packet_new (oi->ifp->mtu);
3416
3417 /* Prepare OSPF common header. */
3418 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3419
3420 /* Prepare OSPF Link State Acknowledgment body. */
3421 length += ospf_make_ls_ack (oi, ack, op->s);
3422
3423 /* Fill OSPF header. */
3424 ospf_fill_header (oi, op->s, length);
3425
3426 /* Set packet length. */
3427 op->length = length;
3428
3429 /* Set destination IP address. */
3430 op->dst = dst;
3431
3432 /* Add packet to the interface output queue. */
3433 ospf_packet_add (oi, op);
3434
3435 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003436 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003437}
3438
3439static int
3440ospf_ls_ack_send_event (struct thread *thread)
3441{
3442 struct ospf_interface *oi = THREAD_ARG (thread);
3443
3444 oi->t_ls_ack_direct = NULL;
3445
3446 while (listcount (oi->ls_ack_direct.ls_ack))
3447 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3448 oi->ls_ack_direct.dst);
3449
3450 return 0;
3451}
3452
3453void
3454ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3455{
3456 struct ospf_interface *oi = nbr->oi;
3457
3458 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3459 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3460
3461 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3462
3463 if (oi->t_ls_ack_direct == NULL)
3464 oi->t_ls_ack_direct =
3465 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3466}
3467
3468/* Send Link State Acknowledgment delayed. */
3469void
3470ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3471{
3472 struct in_addr dst;
3473
3474 /* Decide destination address. */
3475 /* RFC2328 Section 13.5 On non-broadcast
3476 networks, delayed Link State Acknowledgment packets must be
3477 unicast separately over each adjacency (i.e., neighbor whose
3478 state is >= Exchange). */
3479 if (oi->type == OSPF_IFTYPE_NBMA)
3480 {
3481 struct ospf_neighbor *nbr;
3482 struct route_node *rn;
3483
3484 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3485 if ((nbr = rn->info) != NULL)
3486 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3487 while (listcount (oi->ls_ack))
3488 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3489 return;
3490 }
3491 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3492 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3493 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3494 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3495 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3496 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003497 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3498 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003499 else
3500 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3501
3502 while (listcount (oi->ls_ack))
3503 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3504}