blob: d6aca719862452271b25eabdcb1d1974f7874cc3 [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. */
771 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
772 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 {
paulf9ad9372005-10-21 00:45:17 +00002366 zlog_debug ("Packet from [%s] received on link %s"
pauld3f0d622004-05-05 15:27:15 +00002367 " but no ospf_interface",
2368 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002369 return 0;
2370 }
2371 }
2372
2373 /* else it must be a local ospf interface, check it was received on
2374 * correct link
2375 */
2376 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002377 {
2378 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002379 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002380 return 0;
2381 }
ajs847947f2005-02-02 18:38:48 +00002382 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002383 {
ajsba6454e2005-02-08 15:37:30 +00002384 char buf[2][INET_ADDRSTRLEN];
2385 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002386 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002387 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2388 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2389 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002390 /* Fix multicast memberships? */
2391 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2392 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2393 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2394 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2395 if (oi->multicast_memberships)
2396 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002397 return 0;
2398 }
paul718e3742002-12-13 20:15:29 +00002399
2400 /*
2401 * If the received packet is destined for AllDRouters, the packet
2402 * should be accepted only if the received ospf interface state is
2403 * either DR or Backup -- endo.
2404 */
2405 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2406 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2407 {
ajsba6454e2005-02-08 15:37:30 +00002408 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002409 inet_ntoa (iph->ip_src), IF_NAME (oi),
2410 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002411 /* Try to fix multicast membership. */
2412 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2413 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002414 return 0;
2415 }
2416
2417 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002418 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2419 {
paul718e3742002-12-13 20:15:29 +00002420 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002421 {
ajs2a42e282004-12-08 18:43:03 +00002422 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002423 ospf_packet_dump (ibuf);
2424 }
paul718e3742002-12-13 20:15:29 +00002425
ajs2a42e282004-12-08 18:43:03 +00002426 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002427 ospf_packet_type_str[ospfh->type],
2428 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002429 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2430 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002431
2432 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002433 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002434 }
paul718e3742002-12-13 20:15:29 +00002435
2436 /* Some header verification. */
2437 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2438 if (ret < 0)
2439 {
pauld3241812003-09-29 12:42:39 +00002440 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2441 {
ajs2a42e282004-12-08 18:43:03 +00002442 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002443 "dropping.",
2444 ospf_packet_type_str[ospfh->type],
2445 inet_ntoa (iph->ip_src));
2446 }
paul718e3742002-12-13 20:15:29 +00002447 return ret;
2448 }
2449
paul9985f832005-02-09 15:51:56 +00002450 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002451
2452 /* Adjust size to message length. */
2453 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2454
2455 /* Read rest of the packet and call each sort of packet routine. */
2456 switch (ospfh->type)
2457 {
2458 case OSPF_MSG_HELLO:
2459 ospf_hello (iph, ospfh, ibuf, oi, length);
2460 break;
2461 case OSPF_MSG_DB_DESC:
2462 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2463 break;
2464 case OSPF_MSG_LS_REQ:
2465 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2466 break;
2467 case OSPF_MSG_LS_UPD:
2468 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2469 break;
2470 case OSPF_MSG_LS_ACK:
2471 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2472 break;
2473 default:
2474 zlog (NULL, LOG_WARNING,
2475 "interface %s: OSPF packet header type %d is illegal",
2476 IF_NAME (oi), ospfh->type);
2477 break;
2478 }
2479
paul718e3742002-12-13 20:15:29 +00002480 return 0;
2481}
2482
2483/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002484static void
paul718e3742002-12-13 20:15:29 +00002485ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2486{
2487 struct ospf_header *ospfh;
2488
2489 ospfh = (struct ospf_header *) STREAM_DATA (s);
2490
2491 ospfh->version = (u_char) OSPF_VERSION;
2492 ospfh->type = (u_char) type;
2493
paul68980082003-03-25 05:07:42 +00002494 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002495
2496 ospfh->checksum = 0;
2497 ospfh->area_id = oi->area->area_id;
2498 ospfh->auth_type = htons (ospf_auth_type (oi));
2499
2500 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2501
paul9985f832005-02-09 15:51:56 +00002502 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002503}
2504
2505/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002506static int
paul718e3742002-12-13 20:15:29 +00002507ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2508{
2509 struct crypt_key *ck;
2510
2511 switch (ospf_auth_type (oi))
2512 {
2513 case OSPF_AUTH_NULL:
2514 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2515 break;
2516 case OSPF_AUTH_SIMPLE:
2517 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2518 OSPF_AUTH_SIMPLE_SIZE);
2519 break;
2520 case OSPF_AUTH_CRYPTOGRAPHIC:
2521 /* If key is not set, then set 0. */
2522 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2523 {
2524 ospfh->u.crypt.zero = 0;
2525 ospfh->u.crypt.key_id = 0;
2526 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2527 }
2528 else
2529 {
paul1eb8ef22005-04-07 07:30:20 +00002530 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002531 ospfh->u.crypt.zero = 0;
2532 ospfh->u.crypt.key_id = ck->key_id;
2533 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2534 }
2535 /* note: the seq is done in ospf_make_md5_digest() */
2536 break;
2537 default:
2538 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2539 break;
2540 }
2541
2542 return 0;
2543}
2544
2545/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002546static void
paul718e3742002-12-13 20:15:29 +00002547ospf_fill_header (struct ospf_interface *oi,
2548 struct stream *s, u_int16_t length)
2549{
2550 struct ospf_header *ospfh;
2551
2552 ospfh = (struct ospf_header *) STREAM_DATA (s);
2553
2554 /* Fill length. */
2555 ospfh->length = htons (length);
2556
2557 /* Calculate checksum. */
2558 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2559 ospfh->checksum = in_cksum (ospfh, length);
2560 else
2561 ospfh->checksum = 0;
2562
2563 /* Add Authentication Data. */
2564 ospf_make_auth (oi, ospfh);
2565}
2566
paul4dadc292005-05-06 21:37:42 +00002567static int
paul718e3742002-12-13 20:15:29 +00002568ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2569{
2570 struct ospf_neighbor *nbr;
2571 struct route_node *rn;
2572 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2573 struct in_addr mask;
2574 unsigned long p;
2575 int flag = 0;
2576
2577 /* Set netmask of interface. */
2578 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2579 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2580 masklen2ip (oi->address->prefixlen, &mask);
2581 else
2582 memset ((char *) &mask, 0, sizeof (struct in_addr));
2583 stream_put_ipv4 (s, mask.s_addr);
2584
2585 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002586 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2587 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2588 else
2589 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002590
2591 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002592 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002593 OPTIONS(oi), IF_NAME (oi));
2594
2595 /* Set Options. */
2596 stream_putc (s, OPTIONS (oi));
2597
2598 /* Set Router Priority. */
2599 stream_putc (s, PRIORITY (oi));
2600
2601 /* Set Router Dead Interval. */
2602 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2603
2604 /* Set Designated Router. */
2605 stream_put_ipv4 (s, DR (oi).s_addr);
2606
paul9985f832005-02-09 15:51:56 +00002607 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002608
2609 /* Set Backup Designated Router. */
2610 stream_put_ipv4 (s, BDR (oi).s_addr);
2611
2612 /* Add neighbor seen. */
2613 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002614 if ((nbr = rn->info))
2615 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2616 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2617 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2618 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002619 {
2620 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002621 if (nbr->d_router.s_addr != 0
2622 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2623 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2624 flag = 1;
paul718e3742002-12-13 20:15:29 +00002625
2626 stream_put_ipv4 (s, nbr->router_id.s_addr);
2627 length += 4;
2628 }
2629
2630 /* Let neighbor generate BackupSeen. */
2631 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002632 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002633
2634 return length;
2635}
2636
paul4dadc292005-05-06 21:37:42 +00002637static int
paul718e3742002-12-13 20:15:29 +00002638ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2639 struct stream *s)
2640{
2641 struct ospf_lsa *lsa;
2642 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2643 u_char options;
2644 unsigned long pp;
2645 int i;
2646 struct ospf_lsdb *lsdb;
2647
2648 /* Set Interface MTU. */
2649 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2650 stream_putw (s, 0);
2651 else
2652 stream_putw (s, oi->ifp->mtu);
2653
2654 /* Set Options. */
2655 options = OPTIONS (oi);
2656#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002657 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002658 {
2659 if (IS_SET_DD_I (nbr->dd_flags)
2660 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2661 /*
2662 * Set O-bit in the outgoing DD packet for capablity negotiation,
2663 * if one of following case is applicable.
2664 *
2665 * 1) WaitTimer expiration event triggered the neighbor state to
2666 * change to Exstart, but no (valid) DD packet has received
2667 * from the neighbor yet.
2668 *
2669 * 2) At least one DD packet with O-bit on has received from the
2670 * neighbor.
2671 */
2672 SET_FLAG (options, OSPF_OPTION_O);
2673 }
2674#endif /* HAVE_OPAQUE_LSA */
2675 stream_putc (s, options);
2676
2677 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002678 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002679 stream_putc (s, nbr->dd_flags);
2680
2681 /* Set DD Sequence Number. */
2682 stream_putl (s, nbr->dd_seqnum);
2683
2684 if (ospf_db_summary_isempty (nbr))
2685 {
2686 if (nbr->state >= NSM_Exchange)
2687 {
2688 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2689 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002690 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002691 }
2692 return length;
2693 }
2694
2695 /* Describe LSA Header from Database Summary List. */
2696 lsdb = &nbr->db_sum;
2697
2698 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2699 {
2700 struct route_table *table = lsdb->type[i].db;
2701 struct route_node *rn;
2702
2703 for (rn = route_top (table); rn; rn = route_next (rn))
2704 if ((lsa = rn->info) != NULL)
2705 {
2706#ifdef HAVE_OPAQUE_LSA
2707 if (IS_OPAQUE_LSA (lsa->data->type)
2708 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2709 {
2710 /* Suppress advertising opaque-informations. */
2711 /* Remove LSA from DB summary list. */
2712 ospf_lsdb_delete (lsdb, lsa);
2713 continue;
2714 }
2715#endif /* HAVE_OPAQUE_LSA */
2716
2717 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2718 {
2719 struct lsa_header *lsah;
2720 u_int16_t ls_age;
2721
2722 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002723 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002724 break;
2725
2726 /* Keep pointer to LS age. */
2727 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002728 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002729
2730 /* Proceed stream pointer. */
2731 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2732 length += OSPF_LSA_HEADER_SIZE;
2733
2734 /* Set LS age. */
2735 ls_age = LS_AGE (lsa);
2736 lsah->ls_age = htons (ls_age);
2737
2738 }
2739
2740 /* Remove LSA from DB summary list. */
2741 ospf_lsdb_delete (lsdb, lsa);
2742 }
2743 }
2744
2745 return length;
2746}
2747
paul4dadc292005-05-06 21:37:42 +00002748static int
paul718e3742002-12-13 20:15:29 +00002749ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2750 unsigned long delta, struct ospf_neighbor *nbr,
2751 struct ospf_lsa *lsa)
2752{
2753 struct ospf_interface *oi;
2754
2755 oi = nbr->oi;
2756
2757 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002758 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002759 return 0;
2760
2761 stream_putl (s, lsa->data->type);
2762 stream_put_ipv4 (s, lsa->data->id.s_addr);
2763 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2764
2765 ospf_lsa_unlock (nbr->ls_req_last);
2766 nbr->ls_req_last = ospf_lsa_lock (lsa);
2767
2768 *length += 12;
2769 return 1;
2770}
2771
paul4dadc292005-05-06 21:37:42 +00002772static int
paul718e3742002-12-13 20:15:29 +00002773ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2774{
2775 struct ospf_lsa *lsa;
2776 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002777 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002778 struct route_table *table;
2779 struct route_node *rn;
2780 int i;
2781 struct ospf_lsdb *lsdb;
2782
2783 lsdb = &nbr->ls_req;
2784
2785 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2786 {
2787 table = lsdb->type[i].db;
2788 for (rn = route_top (table); rn; rn = route_next (rn))
2789 if ((lsa = (rn->info)) != NULL)
2790 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2791 {
2792 route_unlock_node (rn);
2793 break;
2794 }
2795 }
2796 return length;
2797}
2798
paul4dadc292005-05-06 21:37:42 +00002799static int
paul718e3742002-12-13 20:15:29 +00002800ls_age_increment (struct ospf_lsa *lsa, int delay)
2801{
2802 int age;
2803
2804 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2805
2806 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2807}
2808
paul4dadc292005-05-06 21:37:42 +00002809static int
hasso52dc7ee2004-09-23 19:18:23 +00002810ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002811{
2812 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002813 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002814 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002815 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002816 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002817 unsigned long pp;
2818 int count = 0;
2819
2820 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002821 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002822
paul9985f832005-02-09 15:51:56 +00002823 pp = stream_get_endp (s);
2824 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002825
gdt86f1fd92005-01-10 14:20:43 +00002826 /* Calculate amount of packet usable for data. */
2827 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2828
paul718e3742002-12-13 20:15:29 +00002829 while ((node = listhead (update)) != NULL)
2830 {
2831 struct lsa_header *lsah;
2832 u_int16_t ls_age;
2833
2834 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002835 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002836
paul1eb8ef22005-04-07 07:30:20 +00002837 lsa = listgetdata (node);
2838
paul718e3742002-12-13 20:15:29 +00002839 assert (lsa->data);
2840
paul68b73392004-09-12 14:21:37 +00002841 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002842 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002843 break;
2844
paul718e3742002-12-13 20:15:29 +00002845 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002846 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002847
2848 /* Put LSA to Link State Request. */
2849 stream_put (s, lsa->data, ntohs (lsa->data->length));
2850
2851 /* Set LS age. */
2852 /* each hop must increment an lsa_age by transmit_delay
2853 of OSPF interface */
2854 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2855 lsah->ls_age = htons (ls_age);
2856
2857 length += ntohs (lsa->data->length);
2858 count++;
2859
2860 list_delete_node (update, node);
2861 ospf_lsa_unlock (lsa);
2862 }
2863
2864 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002865 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002866
2867 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002868 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002869 return length;
2870}
2871
paul4dadc292005-05-06 21:37:42 +00002872static int
hasso52dc7ee2004-09-23 19:18:23 +00002873ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002874{
hasso52dc7ee2004-09-23 19:18:23 +00002875 struct list *rm_list;
2876 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002877 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002878 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002879 struct ospf_lsa *lsa;
2880
2881 rm_list = list_new ();
2882
paul1eb8ef22005-04-07 07:30:20 +00002883 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002884 {
paul1eb8ef22005-04-07 07:30:20 +00002885 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002886 assert (lsa);
2887
gdt86f1fd92005-01-10 14:20:43 +00002888 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002889 break;
2890
2891 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2892 length += OSPF_LSA_HEADER_SIZE;
2893
2894 listnode_add (rm_list, lsa);
2895 }
2896
2897 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002898 /* XXX: this loop should be removed and the list move done in previous
2899 * loop
2900 */
2901 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002902 {
paul718e3742002-12-13 20:15:29 +00002903 listnode_delete (ack, lsa);
2904 ospf_lsa_unlock (lsa);
2905 }
2906
2907 list_delete (rm_list);
2908
2909 return length;
2910}
2911
2912void
2913ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2914{
2915 struct ospf_packet *op;
2916 u_int16_t length = OSPF_HEADER_SIZE;
2917
2918 op = ospf_packet_new (oi->ifp->mtu);
2919
2920 /* Prepare OSPF common header. */
2921 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2922
2923 /* Prepare OSPF Hello body. */
2924 length += ospf_make_hello (oi, op->s);
2925
2926 /* Fill OSPF header. */
2927 ospf_fill_header (oi, op->s, length);
2928
2929 /* Set packet length. */
2930 op->length = length;
2931
2932 op->dst.s_addr = addr->s_addr;
2933
2934 /* Add packet to the interface output queue. */
2935 ospf_packet_add (oi, op);
2936
2937 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002938 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002939}
2940
paul4dadc292005-05-06 21:37:42 +00002941static void
paul718e3742002-12-13 20:15:29 +00002942ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2943{
2944 struct ospf_interface *oi;
2945
2946 oi = nbr_nbma->oi;
2947 assert(oi);
2948
2949 /* If this is passive interface, do not send OSPF Hello. */
2950 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2951 return;
2952
2953 if (oi->type != OSPF_IFTYPE_NBMA)
2954 return;
2955
2956 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2957 return;
2958
2959 if (PRIORITY(oi) == 0)
2960 return;
2961
2962 if (nbr_nbma->priority == 0
2963 && oi->state != ISM_DR && oi->state != ISM_Backup)
2964 return;
2965
2966 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2967}
2968
2969int
2970ospf_poll_timer (struct thread *thread)
2971{
2972 struct ospf_nbr_nbma *nbr_nbma;
2973
2974 nbr_nbma = THREAD_ARG (thread);
2975 nbr_nbma->t_poll = NULL;
2976
2977 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002978 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002979 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2980
2981 ospf_poll_send (nbr_nbma);
2982
2983 if (nbr_nbma->v_poll > 0)
2984 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2985 nbr_nbma->v_poll);
2986
2987 return 0;
2988}
2989
2990
2991int
2992ospf_hello_reply_timer (struct thread *thread)
2993{
2994 struct ospf_neighbor *nbr;
2995
2996 nbr = THREAD_ARG (thread);
2997 nbr->t_hello_reply = NULL;
2998
2999 assert (nbr->oi);
3000
3001 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003002 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003003 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3004
3005 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3006
3007 return 0;
3008}
3009
3010/* Send OSPF Hello. */
3011void
3012ospf_hello_send (struct ospf_interface *oi)
3013{
3014 struct ospf_packet *op;
3015 u_int16_t length = OSPF_HEADER_SIZE;
3016
3017 /* If this is passive interface, do not send OSPF Hello. */
3018 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3019 return;
3020
3021 op = ospf_packet_new (oi->ifp->mtu);
3022
3023 /* Prepare OSPF common header. */
3024 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3025
3026 /* Prepare OSPF Hello body. */
3027 length += ospf_make_hello (oi, op->s);
3028
3029 /* Fill OSPF header. */
3030 ospf_fill_header (oi, op->s, length);
3031
3032 /* Set packet length. */
3033 op->length = length;
3034
3035 if (oi->type == OSPF_IFTYPE_NBMA)
3036 {
3037 struct ospf_neighbor *nbr;
3038 struct route_node *rn;
3039
3040 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3041 if ((nbr = rn->info))
3042 if (nbr != oi->nbr_self)
3043 if (nbr->state != NSM_Down)
3044 {
3045 /* RFC 2328 Section 9.5.1
3046 If the router is not eligible to become Designated Router,
3047 it must periodically send Hello Packets to both the
3048 Designated Router and the Backup Designated Router (if they
3049 exist). */
3050 if (PRIORITY(oi) == 0 &&
3051 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3052 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3053 continue;
3054
3055 /* If the router is eligible to become Designated Router, it
3056 must periodically send Hello Packets to all neighbors that
3057 are also eligible. In addition, if the router is itself the
3058 Designated Router or Backup Designated Router, it must also
3059 send periodic Hello Packets to all other neighbors. */
3060
3061 if (nbr->priority == 0 && oi->state == ISM_DROther)
3062 continue;
3063 /* if oi->state == Waiting, send hello to all neighbors */
3064 {
3065 struct ospf_packet *op_dup;
3066
3067 op_dup = ospf_packet_dup(op);
3068 op_dup->dst = nbr->address.u.prefix4;
3069
3070 /* Add packet to the interface output queue. */
3071 ospf_packet_add (oi, op_dup);
3072
paul020709f2003-04-04 02:44:16 +00003073 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003074 }
3075
3076 }
3077 ospf_packet_free (op);
3078 }
3079 else
3080 {
3081 /* Decide destination address. */
3082 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3083 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3084 else
3085 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3086
3087 /* Add packet to the interface output queue. */
3088 ospf_packet_add (oi, op);
3089
3090 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003091 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003092 }
3093}
3094
3095/* Send OSPF Database Description. */
3096void
3097ospf_db_desc_send (struct ospf_neighbor *nbr)
3098{
3099 struct ospf_interface *oi;
3100 struct ospf_packet *op;
3101 u_int16_t length = OSPF_HEADER_SIZE;
3102
3103 oi = nbr->oi;
3104 op = ospf_packet_new (oi->ifp->mtu);
3105
3106 /* Prepare OSPF common header. */
3107 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3108
3109 /* Prepare OSPF Database Description body. */
3110 length += ospf_make_db_desc (oi, nbr, op->s);
3111
3112 /* Fill OSPF header. */
3113 ospf_fill_header (oi, op->s, length);
3114
3115 /* Set packet length. */
3116 op->length = length;
3117
3118 /* Decide destination address. */
3119 op->dst = nbr->address.u.prefix4;
3120
3121 /* Add packet to the interface output queue. */
3122 ospf_packet_add (oi, op);
3123
3124 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003125 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003126
3127 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3128 if (nbr->last_send)
3129 ospf_packet_free (nbr->last_send);
3130 nbr->last_send = ospf_packet_dup (op);
3131 gettimeofday (&nbr->last_send_ts, NULL);
3132}
3133
3134/* Re-send Database Description. */
3135void
3136ospf_db_desc_resend (struct ospf_neighbor *nbr)
3137{
3138 struct ospf_interface *oi;
3139
3140 oi = nbr->oi;
3141
3142 /* Add packet to the interface output queue. */
3143 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3144
3145 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003146 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003147}
3148
3149/* Send Link State Request. */
3150void
3151ospf_ls_req_send (struct ospf_neighbor *nbr)
3152{
3153 struct ospf_interface *oi;
3154 struct ospf_packet *op;
3155 u_int16_t length = OSPF_HEADER_SIZE;
3156
3157 oi = nbr->oi;
3158 op = ospf_packet_new (oi->ifp->mtu);
3159
3160 /* Prepare OSPF common header. */
3161 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3162
3163 /* Prepare OSPF Link State Request body. */
3164 length += ospf_make_ls_req (nbr, op->s);
3165 if (length == OSPF_HEADER_SIZE)
3166 {
3167 ospf_packet_free (op);
3168 return;
3169 }
3170
3171 /* Fill OSPF header. */
3172 ospf_fill_header (oi, op->s, length);
3173
3174 /* Set packet length. */
3175 op->length = length;
3176
3177 /* Decide destination address. */
3178 op->dst = nbr->address.u.prefix4;
3179
3180 /* Add packet to the interface output queue. */
3181 ospf_packet_add (oi, op);
3182
3183 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003184 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003185
3186 /* Add Link State Request Retransmission Timer. */
3187 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3188}
3189
3190/* Send Link State Update with an LSA. */
3191void
3192ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3193 int flag)
3194{
hasso52dc7ee2004-09-23 19:18:23 +00003195 struct list *update;
paul718e3742002-12-13 20:15:29 +00003196
3197 update = list_new ();
3198
3199 listnode_add (update, lsa);
3200 ospf_ls_upd_send (nbr, update, flag);
3201
3202 list_delete (update);
3203}
3204
paul68b73392004-09-12 14:21:37 +00003205/* Determine size for packet. Must be at least big enough to accomodate next
3206 * LSA on list, which may be bigger than MTU size.
3207 *
3208 * Return pointer to new ospf_packet
3209 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3210 * on packet sizes (in which case offending LSA is deleted from update list)
3211 */
3212static struct ospf_packet *
3213ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3214{
3215 struct ospf_lsa *lsa;
3216 struct listnode *ln;
3217 size_t size;
3218 static char warned = 0;
3219
paul1eb8ef22005-04-07 07:30:20 +00003220 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003221 assert (lsa->data);
3222
3223 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3224 > ospf_packet_max (oi))
3225 {
3226 if (!warned)
3227 {
3228 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3229 "will need to fragment. Not optimal. Try divide up"
3230 " your network with areas. Use 'debug ospf packet send'"
3231 " to see details, or look at 'show ip ospf database ..'");
3232 warned = 1;
3233 }
3234
3235 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003236 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003237 " %d bytes originated by %s, will be fragmented!",
3238 inet_ntoa (lsa->data->id),
3239 ntohs (lsa->data->length),
3240 inet_ntoa (lsa->data->adv_router));
3241
3242 /*
3243 * Allocate just enough to fit this LSA only, to avoid including other
3244 * LSAs in fragmented LSA Updates.
3245 */
3246 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3247 + OSPF_LS_UPD_MIN_SIZE;
3248 }
3249 else
3250 size = oi->ifp->mtu;
3251
gdt86f1fd92005-01-10 14:20:43 +00003252 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003253 if (size > OSPF_MAX_PACKET_SIZE)
3254 {
3255 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003256 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003257 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003258 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003259 (long int) size);
paul68b73392004-09-12 14:21:37 +00003260 list_delete_node (update, ln);
3261 return NULL;
3262 }
3263
3264 return ospf_packet_new (size);
3265}
3266
paul718e3742002-12-13 20:15:29 +00003267static void
hasso52dc7ee2004-09-23 19:18:23 +00003268ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003269 struct in_addr addr)
3270{
3271 struct ospf_packet *op;
3272 u_int16_t length = OSPF_HEADER_SIZE;
3273
3274 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003275 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003276
3277 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003278
3279 /* Prepare OSPF common header. */
3280 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3281
paul59ea14c2004-07-14 20:50:36 +00003282 /* Prepare OSPF Link State Update body.
3283 * Includes Type-7 translation.
3284 */
paul718e3742002-12-13 20:15:29 +00003285 length += ospf_make_ls_upd (oi, update, op->s);
3286
3287 /* Fill OSPF header. */
3288 ospf_fill_header (oi, op->s, length);
3289
3290 /* Set packet length. */
3291 op->length = length;
3292
3293 /* Decide destination address. */
3294 op->dst.s_addr = addr.s_addr;
3295
3296 /* Add packet to the interface output queue. */
3297 ospf_packet_add (oi, op);
3298
3299 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003300 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003301}
3302
3303static int
3304ospf_ls_upd_send_queue_event (struct thread *thread)
3305{
3306 struct ospf_interface *oi = THREAD_ARG(thread);
3307 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003308 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003309 struct list *update;
paul68b73392004-09-12 14:21:37 +00003310 char again = 0;
paul718e3742002-12-13 20:15:29 +00003311
3312 oi->t_ls_upd_event = NULL;
3313
3314 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003315 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003316
paul736d3442003-07-24 23:22:57 +00003317 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003318 {
paul736d3442003-07-24 23:22:57 +00003319 rnext = route_next (rn);
3320
paul718e3742002-12-13 20:15:29 +00003321 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003322 continue;
paul68b73392004-09-12 14:21:37 +00003323
3324 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003325
paul48fe13b2004-07-27 17:40:44 +00003326 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003327
paul68b73392004-09-12 14:21:37 +00003328 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003329 if (listcount(update) == 0)
3330 {
3331 list_delete (rn->info);
3332 rn->info = NULL;
3333 route_unlock_node (rn);
3334 }
3335 else
paul68b73392004-09-12 14:21:37 +00003336 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003337 }
3338
3339 if (again != 0)
3340 {
3341 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003342 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003343 " %d nodes to try again, raising new event", again);
3344 oi->t_ls_upd_event =
3345 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003346 }
3347
3348 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003349 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003350
paul718e3742002-12-13 20:15:29 +00003351 return 0;
3352}
3353
3354void
hasso52dc7ee2004-09-23 19:18:23 +00003355ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003356{
3357 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003358 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003359 struct prefix_ipv4 p;
3360 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003361 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003362
3363 oi = nbr->oi;
3364
3365 p.family = AF_INET;
3366 p.prefixlen = IPV4_MAX_BITLEN;
3367
3368 /* Decide destination address. */
3369 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3370 p.prefix = oi->vl_data->peer_addr;
3371 else if (flag == OSPF_SEND_PACKET_DIRECT)
3372 p.prefix = nbr->address.u.prefix4;
3373 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3374 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3375 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3376 && (flag == OSPF_SEND_PACKET_INDIRECT))
3377 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003378 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3379 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003380 else
3381 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3382
3383 if (oi->type == OSPF_IFTYPE_NBMA)
3384 {
3385 if (flag == OSPF_SEND_PACKET_INDIRECT)
3386 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3387 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3388 zlog_warn ("* LS-Update is sent to myself.");
3389 }
3390
3391 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3392
3393 if (rn->info == NULL)
3394 rn->info = list_new ();
3395
paul1eb8ef22005-04-07 07:30:20 +00003396 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3397 {
3398 ospf_lsa_lock (lsa);
3399 listnode_add (rn->info, lsa);
3400 }
paul718e3742002-12-13 20:15:29 +00003401
3402 if (oi->t_ls_upd_event == NULL)
3403 oi->t_ls_upd_event =
3404 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3405}
3406
3407static void
hasso52dc7ee2004-09-23 19:18:23 +00003408ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3409 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003410{
3411 struct ospf_packet *op;
3412 u_int16_t length = OSPF_HEADER_SIZE;
3413
3414 op = ospf_packet_new (oi->ifp->mtu);
3415
3416 /* Prepare OSPF common header. */
3417 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3418
3419 /* Prepare OSPF Link State Acknowledgment body. */
3420 length += ospf_make_ls_ack (oi, ack, op->s);
3421
3422 /* Fill OSPF header. */
3423 ospf_fill_header (oi, op->s, length);
3424
3425 /* Set packet length. */
3426 op->length = length;
3427
3428 /* Set destination IP address. */
3429 op->dst = dst;
3430
3431 /* Add packet to the interface output queue. */
3432 ospf_packet_add (oi, op);
3433
3434 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003435 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003436}
3437
3438static int
3439ospf_ls_ack_send_event (struct thread *thread)
3440{
3441 struct ospf_interface *oi = THREAD_ARG (thread);
3442
3443 oi->t_ls_ack_direct = NULL;
3444
3445 while (listcount (oi->ls_ack_direct.ls_ack))
3446 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3447 oi->ls_ack_direct.dst);
3448
3449 return 0;
3450}
3451
3452void
3453ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3454{
3455 struct ospf_interface *oi = nbr->oi;
3456
3457 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3458 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3459
3460 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3461
3462 if (oi->t_ls_ack_direct == NULL)
3463 oi->t_ls_ack_direct =
3464 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3465}
3466
3467/* Send Link State Acknowledgment delayed. */
3468void
3469ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3470{
3471 struct in_addr dst;
3472
3473 /* Decide destination address. */
3474 /* RFC2328 Section 13.5 On non-broadcast
3475 networks, delayed Link State Acknowledgment packets must be
3476 unicast separately over each adjacency (i.e., neighbor whose
3477 state is >= Exchange). */
3478 if (oi->type == OSPF_IFTYPE_NBMA)
3479 {
3480 struct ospf_neighbor *nbr;
3481 struct route_node *rn;
3482
3483 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3484 if ((nbr = rn->info) != NULL)
3485 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3486 while (listcount (oi->ls_ack))
3487 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3488 return;
3489 }
3490 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3491 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3492 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3493 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3494 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3495 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003496 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3497 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003498 else
3499 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3500
3501 while (listcount (oi->ls_ack))
3502 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3503}