blob: eb97ddbf00f6273f39708bc440220e0c3b9c3449 [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);
342 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
343 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000344
345 /* Get MD5 Authentication key from auth_key list. */
346 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000347 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000348 else
349 {
paul1eb8ef22005-04-07 07:30:20 +0000350 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000351 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000352 }
353
354 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000355 memset(&ctx, 0, sizeof(ctx));
356 MD5Init(&ctx);
357 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
358 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
359 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000360
361 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000362 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000363
364 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000365 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
366
paul37163d62003-02-03 18:40:56 +0000367 if (stream_get_endp(op->s) != op->length)
368 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 +0000369
370 return OSPF_AUTH_MD5_SIZE;
371}
372
373
paul4dadc292005-05-06 21:37:42 +0000374static int
paul718e3742002-12-13 20:15:29 +0000375ospf_ls_req_timer (struct thread *thread)
376{
377 struct ospf_neighbor *nbr;
378
379 nbr = THREAD_ARG (thread);
380 nbr->t_ls_req = NULL;
381
382 /* Send Link State Request. */
383 if (ospf_ls_request_count (nbr))
384 ospf_ls_req_send (nbr);
385
386 /* Set Link State Request retransmission timer. */
387 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
388
389 return 0;
390}
391
392void
393ospf_ls_req_event (struct ospf_neighbor *nbr)
394{
395 if (nbr->t_ls_req)
396 {
397 thread_cancel (nbr->t_ls_req);
398 nbr->t_ls_req = NULL;
399 }
400 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
401}
402
403/* Cyclic timer function. Fist registered in ospf_nbr_new () in
404 ospf_neighbor.c */
405int
406ospf_ls_upd_timer (struct thread *thread)
407{
408 struct ospf_neighbor *nbr;
409
410 nbr = THREAD_ARG (thread);
411 nbr->t_ls_upd = NULL;
412
413 /* Send Link State Update. */
414 if (ospf_ls_retransmit_count (nbr) > 0)
415 {
hasso52dc7ee2004-09-23 19:18:23 +0000416 struct list *update;
paul718e3742002-12-13 20:15:29 +0000417 struct ospf_lsdb *lsdb;
418 int i;
paul718e3742002-12-13 20:15:29 +0000419 int retransmit_interval;
420
paul718e3742002-12-13 20:15:29 +0000421 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
422
423 lsdb = &nbr->ls_rxmt;
424 update = list_new ();
425
426 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
427 {
428 struct route_table *table = lsdb->type[i].db;
429 struct route_node *rn;
430
431 for (rn = route_top (table); rn; rn = route_next (rn))
432 {
433 struct ospf_lsa *lsa;
434
435 if ((lsa = rn->info) != NULL)
436 /* Don't retransmit an LSA if we received it within
437 the last RxmtInterval seconds - this is to allow the
438 neighbour a chance to acknowledge the LSA as it may
439 have ben just received before the retransmit timer
440 fired. This is a small tweak to what is in the RFC,
441 but it will cut out out a lot of retransmit traffic
442 - MAG */
pauld24f6e22005-10-21 09:23:12 +0000443 if (tv_cmp (tv_sub (recent_time, lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000444 int2tv (retransmit_interval)) >= 0)
445 listnode_add (update, rn->info);
446 }
447 }
448
449 if (listcount (update) > 0)
450 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
451 list_delete (update);
452 }
453
454 /* Set LS Update retransmission timer. */
455 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
456
457 return 0;
458}
459
460int
461ospf_ls_ack_timer (struct thread *thread)
462{
463 struct ospf_interface *oi;
464
465 oi = THREAD_ARG (thread);
466 oi->t_ls_ack = NULL;
467
468 /* Send Link State Acknowledgment. */
469 if (listcount (oi->ls_ack) > 0)
470 ospf_ls_ack_send_delayed (oi);
471
472 /* Set LS Ack timer. */
473 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
474
475 return 0;
476}
477
paul0bfeca32004-09-24 08:07:54 +0000478#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000479static void
paul6a99f832004-09-27 12:56:30 +0000480ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000481 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000482 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000483{
484#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000485 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000486 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000487 int ret;
paul0bfeca32004-09-24 08:07:54 +0000488
489 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000490 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000491
492 /* we can but try.
493 *
494 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
495 * well as the IP_MF flag, making this all quite pointless.
496 *
497 * However, for a system on which IP_MF is left alone, and ip_id left
498 * alone or else which sets same ip_id for each fragment this might
499 * work, eg linux.
500 *
501 * XXX-TODO: It would be much nicer to have the kernel's use their
502 * existing fragmentation support to do this for us. Bugs/RFEs need to
503 * be raised against the various kernels.
504 */
505
506 /* set More Frag */
507 iph->ip_off |= IP_MF;
508
509 /* ip frag offset is expressed in units of 8byte words */
510 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
511
paul62d8e962004-11-02 20:26:45 +0000512 iovp = &msg->msg_iov[1];
513
paul0bfeca32004-09-24 08:07:54 +0000514 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
515 > maxdatasize )
516 {
517 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000518 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
519 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000520 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000521
paul18b12c32004-10-05 14:38:29 +0000522 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000523
paul6a99f832004-09-27 12:56:30 +0000524 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000525
paul18b12c32004-10-05 14:38:29 +0000526 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000527
528 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000529 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000530 " id %d, off %d, len %d, mtu %u failed with %s",
531 inet_ntoa (iph->ip_dst),
532 iph->ip_id,
533 iph->ip_off,
534 iph->ip_len,
535 mtu,
536 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000537
paul37ccfa32004-10-31 11:24:51 +0000538 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
539 {
ajs2a42e282004-12-08 18:43:03 +0000540 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000541 iph->ip_id, iph->ip_off, iph->ip_len,
542 inet_ntoa (iph->ip_dst));
543 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
544 {
ajs2a42e282004-12-08 18:43:03 +0000545 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000546 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000547 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000548 }
549 }
550
paul0bfeca32004-09-24 08:07:54 +0000551 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000552 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000553 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000554 }
555
556 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000557 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
558 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000559 iph->ip_off &= (~IP_MF);
560}
561#endif /* WANT_OSPF_WRITE_FRAGMENT */
562
ajs5dcbdf82005-03-29 16:13:49 +0000563static int
paul718e3742002-12-13 20:15:29 +0000564ospf_write (struct thread *thread)
565{
paul68980082003-03-25 05:07:42 +0000566 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000567 struct ospf_interface *oi;
568 struct ospf_packet *op;
569 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000570 struct ip iph;
571 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000572 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000573 u_char type;
574 int ret;
575 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000576 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000577#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000578 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000579#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000580 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000581#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000582
paul68980082003-03-25 05:07:42 +0000583 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000584
paul68980082003-03-25 05:07:42 +0000585 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000586 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000587 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000588 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000589
590#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000591 /* seed ipid static with low order bits of time */
592 if (ipid == 0)
593 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000594#endif /* WANT_OSPF_WRITE_FRAGMENT */
595
paul68b73392004-09-12 14:21:37 +0000596 /* convenience - max OSPF data per packet */
597 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
598
paul718e3742002-12-13 20:15:29 +0000599 /* Get one packet from queue. */
600 op = ospf_fifo_head (oi->obuf);
601 assert (op);
602 assert (op->length >= OSPF_HEADER_SIZE);
603
paul68980082003-03-25 05:07:42 +0000604 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
605 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000606 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
607
paul718e3742002-12-13 20:15:29 +0000608 /* Rewrite the md5 signature & update the seq */
609 ospf_make_md5_digest (oi, op);
610
paul37ccfa32004-10-31 11:24:51 +0000611 /* Retrieve OSPF packet type. */
612 stream_set_getp (op->s, 1);
613 type = stream_getc (op->s);
614
paul68b73392004-09-12 14:21:37 +0000615 /* reset get pointer */
616 stream_set_getp (op->s, 0);
617
618 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000619 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000620
paul718e3742002-12-13 20:15:29 +0000621 sa_dst.sin_family = AF_INET;
622#ifdef HAVE_SIN_LEN
623 sa_dst.sin_len = sizeof(sa_dst);
624#endif /* HAVE_SIN_LEN */
625 sa_dst.sin_addr = op->dst;
626 sa_dst.sin_port = htons (0);
627
628 /* Set DONTROUTE flag if dst is unicast. */
629 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
630 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
631 flags = MSG_DONTROUTE;
632
paul68b73392004-09-12 14:21:37 +0000633 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
634 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000635 if ( sizeof (struct ip)
636 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000637 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
638
paul718e3742002-12-13 20:15:29 +0000639 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000640 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000641 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000642
paul0bfeca32004-09-24 08:07:54 +0000643#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000644 /* XXX-MT: not thread-safe at all..
645 * XXX: this presumes this is only programme sending OSPF packets
646 * otherwise, no guarantee ipid will be unique
647 */
648 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000649#endif /* WANT_OSPF_WRITE_FRAGMENT */
650
paul718e3742002-12-13 20:15:29 +0000651 iph.ip_off = 0;
652 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
653 iph.ip_ttl = OSPF_VL_IP_TTL;
654 else
655 iph.ip_ttl = OSPF_IP_TTL;
656 iph.ip_p = IPPROTO_OSPFIGP;
657 iph.ip_sum = 0;
658 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
659 iph.ip_dst.s_addr = op->dst.s_addr;
660
661 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000662 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000663 msg.msg_namelen = sizeof (sa_dst);
664 msg.msg_iov = iov;
665 msg.msg_iovlen = 2;
666 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000667 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
668 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000669 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000670
671 /* Sadly we can not rely on kernels to fragment packets because of either
672 * IP_HDRINCL and/or multicast destination being set.
673 */
paul0bfeca32004-09-24 08:07:54 +0000674#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000675 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000676 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
677 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000678#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000679
680 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000681 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000682 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000683 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000684
685 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000686 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000687 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000688 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000689 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000690
paul718e3742002-12-13 20:15:29 +0000691 /* Show debug sending packet. */
692 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
693 {
694 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
695 {
ajs2a42e282004-12-08 18:43:03 +0000696 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000697 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000698 stream_set_getp (op->s, 0);
699 ospf_packet_dump (op->s);
700 }
701
ajs2a42e282004-12-08 18:43:03 +0000702 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000703 ospf_packet_type_str[type], inet_ntoa (op->dst),
704 IF_NAME (oi));
705
706 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000707 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000708 }
709
710 /* Now delete packet from queue. */
711 ospf_packet_delete (oi);
712
713 if (ospf_fifo_head (oi->obuf) == NULL)
714 {
715 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000716 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000717 }
718
719 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000720 if (!list_isempty (ospf->oi_write_q))
721 ospf->t_write =
722 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000723
724 return 0;
725}
726
727/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000728static void
paul718e3742002-12-13 20:15:29 +0000729ospf_hello (struct ip *iph, struct ospf_header *ospfh,
730 struct stream * s, struct ospf_interface *oi, int size)
731{
732 struct ospf_hello *hello;
733 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000734 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000735 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000736
737 /* increment statistics. */
738 oi->hello_in++;
739
740 hello = (struct ospf_hello *) STREAM_PNT (s);
741
742 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000743 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000744 {
745 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
746 {
ajs2a42e282004-12-08 18:43:03 +0000747 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000748 "dropping.",
749 ospf_packet_type_str[ospfh->type],
750 inet_ntoa (iph->ip_src));
751 }
752 return;
753 }
paul718e3742002-12-13 20:15:29 +0000754
755 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000756 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000757 char buf[3][INET_ADDRSTRLEN];
paul6d452762005-11-03 11:15:44 +0000758 zlog_debug ("ignoring HELLO from router %s sent to %s, "
759 "received on a passive interface, %s",
760 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
761 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
762 inet_ntop(AF_INET, &oi->address->u.prefix4,
763 buf[2], sizeof(buf[2])));
ajsba6454e2005-02-08 15:37:30 +0000764 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
765 {
766 /* Try to fix multicast membership. */
767 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
768 ospf_if_set_multicast(oi);
769 }
paul718e3742002-12-13 20:15:29 +0000770 return;
paulf2c80652002-12-13 21:44:27 +0000771 }
paul718e3742002-12-13 20:15:29 +0000772
773 /* get neighbor prefix. */
774 p.family = AF_INET;
775 p.prefixlen = ip_masklen (hello->network_mask);
776 p.u.prefix4 = iph->ip_src;
777
778 /* Compare network mask. */
779 /* Checking is ignored for Point-to-Point and Virtual link. */
780 if (oi->type != OSPF_IFTYPE_POINTOPOINT
781 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
782 if (oi->address->prefixlen != p.prefixlen)
783 {
784 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
785 inet_ntoa (ospfh->router_id));
786 return;
787 }
788
paul718e3742002-12-13 20:15:29 +0000789 /* Compare Router Dead Interval. */
790 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
791 {
792 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
793 inet_ntoa (ospfh->router_id));
794 return;
795 }
796
paulf9ad9372005-10-21 00:45:17 +0000797 /* Compare Hello Interval - ignored if fast-hellos are set. */
798 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
799 {
800 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
801 {
802 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
803 inet_ntoa (ospfh->router_id));
804 return;
805 }
806 }
807
paul718e3742002-12-13 20:15:29 +0000808 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000809 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000810 inet_ntoa (ospfh->router_id),
811 ospf_options_dump (hello->options));
812
813 /* Compare options. */
814#define REJECT_IF_TBIT_ON 1 /* XXX */
815#ifdef REJECT_IF_TBIT_ON
816 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
817 {
818 /*
819 * This router does not support non-zero TOS.
820 * Drop this Hello packet not to establish neighbor relationship.
821 */
822 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
823 inet_ntoa (ospfh->router_id));
824 return;
825 }
826#endif /* REJECT_IF_TBIT_ON */
827
828#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000829 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000830 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
831 {
832 /*
833 * This router does know the correct usage of O-bit
834 * the bit should be set in DD packet only.
835 */
836 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
837 inet_ntoa (ospfh->router_id));
838#ifdef STRICT_OBIT_USAGE_CHECK
839 return; /* Reject this packet. */
840#else /* STRICT_OBIT_USAGE_CHECK */
841 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
842#endif /* STRICT_OBIT_USAGE_CHECK */
843 }
844#endif /* HAVE_OPAQUE_LSA */
845
846 /* new for NSSA is to ensure that NP is on and E is off */
847
paul718e3742002-12-13 20:15:29 +0000848 if (oi->area->external_routing == OSPF_AREA_NSSA)
849 {
850 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
851 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
852 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
853 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
854 {
855 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
856 return;
857 }
858 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000859 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000860 }
861 else
paul718e3742002-12-13 20:15:29 +0000862 /* The setting of the E-bit found in the Hello Packet's Options
863 field must match this area's ExternalRoutingCapability A
864 mismatch causes processing to stop and the packet to be
865 dropped. The setting of the rest of the bits in the Hello
866 Packet's Options field should be ignored. */
867 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
868 CHECK_FLAG (hello->options, OSPF_OPTION_E))
869 {
ajs3aa8d5f2004-12-11 18:00:06 +0000870 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
871 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000872 return;
873 }
paul718e3742002-12-13 20:15:29 +0000874
pauld3f0d622004-05-05 15:27:15 +0000875 /* get neighbour struct */
876 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
877
878 /* neighbour must be valid, ospf_nbr_get creates if none existed */
879 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000880
881 old_state = nbr->state;
882
883 /* Add event to thread. */
884 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
885
886 /* RFC2328 Section 9.5.1
887 If the router is not eligible to become Designated Router,
888 (snip) It must also send an Hello Packet in reply to an
889 Hello Packet received from any eligible neighbor (other than
890 the current Designated Router and Backup Designated Router). */
891 if (oi->type == OSPF_IFTYPE_NBMA)
892 if (PRIORITY(oi) == 0 && hello->priority > 0
893 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
894 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
895 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
896 OSPF_HELLO_REPLY_DELAY);
897
898 /* on NBMA network type, it happens to receive bidirectional Hello packet
899 without advance 1-Way Received event.
900 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
901 if (oi->type == OSPF_IFTYPE_NBMA &&
902 (old_state == NSM_Down || old_state == NSM_Attempt))
903 {
904 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
905 nbr->priority = hello->priority;
906 nbr->d_router = hello->d_router;
907 nbr->bd_router = hello->bd_router;
908 return;
909 }
910
paul68980082003-03-25 05:07:42 +0000911 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000912 size - OSPF_HELLO_MIN_SIZE))
913 {
914 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
915 nbr->options |= hello->options;
916 }
917 else
918 {
919 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
920 /* Set neighbor information. */
921 nbr->priority = hello->priority;
922 nbr->d_router = hello->d_router;
923 nbr->bd_router = hello->bd_router;
924 return;
925 }
926
927 /* If neighbor itself declares DR and no BDR exists,
928 cause event BackupSeen */
929 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
930 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
931 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
932
933 /* neighbor itself declares BDR. */
934 if (oi->state == ISM_Waiting &&
935 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
936 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
937
938 /* had not previously. */
939 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
940 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
941 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
942 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
943 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
944
945 /* had not previously. */
946 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
947 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
948 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
951
952 /* Neighbor priority check. */
953 if (nbr->priority >= 0 && nbr->priority != hello->priority)
954 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
955
956 /* Set neighbor information. */
957 nbr->priority = hello->priority;
958 nbr->d_router = hello->d_router;
959 nbr->bd_router = hello->bd_router;
960}
961
962/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000963static void
paul718e3742002-12-13 20:15:29 +0000964ospf_db_desc_save_current (struct ospf_neighbor *nbr,
965 struct ospf_db_desc *dd)
966{
967 nbr->last_recv.flags = dd->flags;
968 nbr->last_recv.options = dd->options;
969 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
970}
971
972/* Process rest of DD packet. */
973static void
974ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
975 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
976 u_int16_t size)
977{
978 struct ospf_lsa *new, *find;
979 struct lsa_header *lsah;
980
paul9985f832005-02-09 15:51:56 +0000981 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000982 for (size -= OSPF_DB_DESC_MIN_SIZE;
983 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
984 {
985 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000986 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000987
988 /* Unknown LS type. */
989 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
990 {
ajsbec595a2004-11-30 22:38:43 +0000991 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000992 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
993 return;
994 }
995
996#ifdef HAVE_OPAQUE_LSA
997 if (IS_OPAQUE_LSA (lsah->type)
998 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
999 {
1000 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1001 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1002 return;
1003 }
1004#endif /* HAVE_OPAQUE_LSA */
1005
1006 switch (lsah->type)
1007 {
1008 case OSPF_AS_EXTERNAL_LSA:
1009#ifdef HAVE_OPAQUE_LSA
1010 case OSPF_OPAQUE_AS_LSA:
1011#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001012 /* Check for stub area. Reject if AS-External from stub but
1013 allow if from NSSA. */
1014 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001015 {
1016 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1017 lsah->type, inet_ntoa (lsah->id),
1018 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1019 "STUB" : "NSSA");
1020 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1021 return;
1022 }
1023 break;
1024 default:
1025 break;
1026 }
1027
1028 /* Create LS-request object. */
1029 new = ospf_ls_request_new (lsah);
1030
1031 /* Lookup received LSA, then add LS request list. */
1032 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1033 if (!find || ospf_lsa_more_recent (find, new) < 0)
1034 {
1035 ospf_ls_request_add (nbr, new);
1036 ospf_lsa_discard (new);
1037 }
1038 else
1039 {
1040 /* Received LSA is not recent. */
1041 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001042 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001043 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1044 ospf_lsa_discard (new);
1045 continue;
1046 }
1047 }
1048
1049 /* Master */
1050 if (IS_SET_DD_MS (nbr->dd_flags))
1051 {
1052 nbr->dd_seqnum++;
1053 /* Entire DD packet sent. */
1054 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1055 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1056 else
1057 /* Send new DD packet. */
1058 ospf_db_desc_send (nbr);
1059 }
1060 /* Slave */
1061 else
1062 {
1063 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1064
1065 /* When master's more flags is not set. */
1066 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1067 {
1068 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1069 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1070 }
1071
ajsbec595a2004-11-30 22:38:43 +00001072 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001073 ospf_db_desc_send (nbr);
1074 }
1075
1076 /* Save received neighbor values from DD. */
1077 ospf_db_desc_save_current (nbr, dd);
1078}
1079
paul4dadc292005-05-06 21:37:42 +00001080static int
paul718e3742002-12-13 20:15:29 +00001081ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1082{
1083 /* Is DD duplicated? */
1084 if (dd->options == nbr->last_recv.options &&
1085 dd->flags == nbr->last_recv.flags &&
1086 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1087 return 1;
1088
1089 return 0;
1090}
1091
1092/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001093static void
paul718e3742002-12-13 20:15:29 +00001094ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1095 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1096{
1097 struct ospf_db_desc *dd;
1098 struct ospf_neighbor *nbr;
1099
1100 /* Increment statistics. */
1101 oi->db_desc_in++;
1102
1103 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001104
pauld3f0d622004-05-05 15:27:15 +00001105 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001106 if (nbr == NULL)
1107 {
1108 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1109 inet_ntoa (ospfh->router_id));
1110 return;
1111 }
1112
1113 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001114 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1115 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001116 {
ajs3aa8d5f2004-12-11 18:00:06 +00001117 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1118 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1119 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001120 return;
1121 }
1122
pauld363df22003-06-19 00:26:34 +00001123 /*
1124 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1125 * required. In fact at least JunOS sends DD packets with P bit clear.
1126 * Until proper solution is developped, this hack should help.
1127 *
1128 * Update: According to the RFCs, N bit is specified /only/ for Hello
1129 * options, unfortunately its use in DD options is not specified. Hence some
1130 * implementations follow E-bit semantics and set it in DD options, and some
1131 * treat it as unspecified and hence follow the directive "default for
1132 * options is clear", ie unset.
1133 *
1134 * Reset the flag, as ospfd follows E-bit semantics.
1135 */
1136 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1137 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1138 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1139 {
1140 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001141 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001142 inet_ntoa (nbr->router_id) );
1143 SET_FLAG (dd->options, OSPF_OPTION_NP);
1144 }
pauld363df22003-06-19 00:26:34 +00001145
paul718e3742002-12-13 20:15:29 +00001146#ifdef REJECT_IF_TBIT_ON
1147 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1148 {
1149 /*
1150 * In Hello protocol, optional capability must have checked
1151 * to prevent this T-bit enabled router be my neighbor.
1152 */
1153 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1154 return;
1155 }
1156#endif /* REJECT_IF_TBIT_ON */
1157
1158#ifdef HAVE_OPAQUE_LSA
1159 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001160 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001161 {
1162 /*
1163 * This node is not configured to handle O-bit, for now.
1164 * Clear it to ignore unsupported capability proposed by neighbor.
1165 */
1166 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1167 }
1168#endif /* HAVE_OPAQUE_LSA */
1169
1170 /* Process DD packet by neighbor status. */
1171 switch (nbr->state)
1172 {
1173 case NSM_Down:
1174 case NSM_Attempt:
1175 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001176 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001177 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001178 LOOKUP (ospf_nsm_state_msg, nbr->state));
1179 break;
1180 case NSM_Init:
1181 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1182 /* If the new state is ExStart, the processing of the current
1183 packet should then continue in this new state by falling
1184 through to case ExStart below. */
1185 if (nbr->state != NSM_ExStart)
1186 break;
1187 case NSM_ExStart:
1188 /* Initial DBD */
1189 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1190 (size == OSPF_DB_DESC_MIN_SIZE))
1191 {
paul68980082003-03-25 05:07:42 +00001192 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001193 {
1194 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001195 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001196 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001197 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1198 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1199 }
1200 else
1201 {
1202 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001203 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001204 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001205 break;
1206 }
1207 }
1208 /* Ack from the Slave */
1209 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1210 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001211 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001212 {
ajs17eaa722004-12-29 21:04:48 +00001213 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001214 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001215 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1216 }
1217 else
1218 {
ajs3aa8d5f2004-12-11 18:00:06 +00001219 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1220 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001221 break;
1222 }
1223
1224 /* This is where the real Options are saved */
1225 nbr->options = dd->options;
1226
1227#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001228 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001229 {
1230 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001231 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001232 inet_ntoa (nbr->router_id),
1233 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1234
1235 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1236 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1237 {
paul6d452762005-11-03 11:15:44 +00001238 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1239 "Opaque-LSAs cannot be reliably advertised "
1240 "in this network.",
1241 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001242 /* This situation is undesirable, but not a real error. */
1243 }
1244 }
1245#endif /* HAVE_OPAQUE_LSA */
1246
1247 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1248
1249 /* continue processing rest of packet. */
1250 ospf_db_desc_proc (s, oi, nbr, dd, size);
1251 break;
1252 case NSM_Exchange:
1253 if (ospf_db_desc_is_dup (dd, nbr))
1254 {
1255 if (IS_SET_DD_MS (nbr->dd_flags))
1256 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001257 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001258 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001259 else
1260 /* Slave: cause to retransmit the last Database Description. */
1261 {
paul6d452762005-11-03 11:15:44 +00001262 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001263 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001264 ospf_db_desc_resend (nbr);
1265 }
1266 break;
1267 }
1268
1269 /* Otherwise DD packet should be checked. */
1270 /* Check Master/Slave bit mismatch */
1271 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1272 {
ajs3aa8d5f2004-12-11 18:00:06 +00001273 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1274 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001275 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1276 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001277 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001278 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001279 break;
1280 }
1281
1282 /* Check initialize bit is set. */
1283 if (IS_SET_DD_I (dd->flags))
1284 {
paul6d452762005-11-03 11:15:44 +00001285 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001286 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001287 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1288 break;
1289 }
1290
1291 /* Check DD Options. */
1292 if (dd->options != nbr->options)
1293 {
1294#ifdef ORIGINAL_CODING
1295 /* Save the new options for debugging */
1296 nbr->options = dd->options;
1297#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001298 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1299 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001300 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1301 break;
1302 }
1303
1304 /* Check DD sequence number. */
1305 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1306 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1307 (!IS_SET_DD_MS (nbr->dd_flags) &&
1308 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1309 {
ajs3aa8d5f2004-12-11 18:00:06 +00001310 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1311 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001312 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1313 break;
1314 }
1315
1316 /* Continue processing rest of packet. */
1317 ospf_db_desc_proc (s, oi, nbr, dd, size);
1318 break;
1319 case NSM_Loading:
1320 case NSM_Full:
1321 if (ospf_db_desc_is_dup (dd, nbr))
1322 {
1323 if (IS_SET_DD_MS (nbr->dd_flags))
1324 {
1325 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001326 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1327 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001328 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001329 break;
1330 }
1331 else
1332 {
1333 struct timeval t, now;
1334 gettimeofday (&now, NULL);
1335 t = tv_sub (now, nbr->last_send_ts);
1336 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1337 {
1338 /* In states Loading and Full the slave must resend
1339 its last Database Description packet in response to
1340 duplicate Database Description packets received
1341 from the master. For this reason the slave must
1342 wait RouterDeadInterval seconds before freeing the
1343 last Database Description packet. Reception of a
1344 Database Description packet from the master after
1345 this interval will generate a SeqNumberMismatch
1346 neighbor event. RFC2328 Section 10.8 */
1347 ospf_db_desc_resend (nbr);
1348 break;
1349 }
1350 }
1351 }
1352
1353 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1354 break;
1355 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001356 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1357 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001358 break;
1359 }
1360}
1361
1362#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1363
1364/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001365static void
paul718e3742002-12-13 20:15:29 +00001366ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1367 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1368{
1369 struct ospf_neighbor *nbr;
1370 u_int32_t ls_type;
1371 struct in_addr ls_id;
1372 struct in_addr adv_router;
1373 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001374 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001375 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001376
1377 /* Increment statistics. */
1378 oi->ls_req_in++;
1379
pauld3f0d622004-05-05 15:27:15 +00001380 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001381 if (nbr == NULL)
1382 {
1383 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1384 inet_ntoa (ospfh->router_id));
1385 return;
1386 }
1387
1388 /* Neighbor State should be Exchange or later. */
1389 if (nbr->state != NSM_Exchange &&
1390 nbr->state != NSM_Loading &&
1391 nbr->state != NSM_Full)
1392 {
ajsbec595a2004-11-30 22:38:43 +00001393 zlog_warn ("Link State Request received from %s: "
1394 "Neighbor state is %s, packet discarded.",
1395 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001396 LOOKUP (ospf_nsm_state_msg, nbr->state));
1397 return;
1398 }
1399
1400 /* Send Link State Update for ALL requested LSAs. */
1401 ls_upd = list_new ();
1402 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1403
1404 while (size >= OSPF_LSA_KEY_SIZE)
1405 {
1406 /* Get one slice of Link State Request. */
1407 ls_type = stream_getl (s);
1408 ls_id.s_addr = stream_get_ipv4 (s);
1409 adv_router.s_addr = stream_get_ipv4 (s);
1410
1411 /* Verify LSA type. */
1412 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1413 {
1414 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1415 list_delete (ls_upd);
1416 return;
1417 }
1418
1419 /* Search proper LSA in LSDB. */
1420 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1421 if (find == NULL)
1422 {
1423 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1424 list_delete (ls_upd);
1425 return;
1426 }
1427
gdt86f1fd92005-01-10 14:20:43 +00001428 /* Packet overflows MTU size, send immediately. */
1429 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001430 {
1431 if (oi->type == OSPF_IFTYPE_NBMA)
1432 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1433 else
1434 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1435
1436 /* Only remove list contents. Keep ls_upd. */
1437 list_delete_all_node (ls_upd);
1438
1439 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1440 }
1441
1442 /* Append LSA to update list. */
1443 listnode_add (ls_upd, find);
1444 length += ntohs (find->data->length);
1445
1446 size -= OSPF_LSA_KEY_SIZE;
1447 }
1448
1449 /* Send rest of Link State Update. */
1450 if (listcount (ls_upd) > 0)
1451 {
1452 if (oi->type == OSPF_IFTYPE_NBMA)
1453 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1454 else
1455 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1456
1457 list_delete (ls_upd);
1458 }
1459 else
1460 list_free (ls_upd);
1461}
1462
1463/* Get the list of LSAs from Link State Update packet.
1464 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001465static struct list *
paul718e3742002-12-13 20:15:29 +00001466ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1467 struct ospf_interface *oi, size_t size)
1468{
1469 u_int16_t count, sum;
1470 u_int32_t length;
1471 struct lsa_header *lsah;
1472 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001473 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001474
1475 lsas = list_new ();
1476
1477 count = stream_getl (s);
1478 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1479
1480 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001481 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001482 {
1483 lsah = (struct lsa_header *) STREAM_PNT (s);
1484 length = ntohs (lsah->length);
1485
1486 if (length > size)
1487 {
1488 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1489 break;
1490 }
1491
1492 /* Validate the LSA's LS checksum. */
1493 sum = lsah->checksum;
1494 if (sum != ospf_lsa_checksum (lsah))
1495 {
1496 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1497 sum, lsah->checksum);
1498 continue;
1499 }
1500
1501 /* Examine the LSA's LS type. */
1502 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1503 {
1504 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1505 continue;
1506 }
1507
1508 /*
1509 * What if the received LSA's age is greater than MaxAge?
1510 * Treat it as a MaxAge case -- endo.
1511 */
1512 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1513 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1514
1515#ifdef HAVE_OPAQUE_LSA
1516 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1517 {
1518#ifdef STRICT_OBIT_USAGE_CHECK
1519 if ((IS_OPAQUE_LSA(lsah->type) &&
1520 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1521 || (! IS_OPAQUE_LSA(lsah->type) &&
1522 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1523 {
1524 /*
1525 * This neighbor must know the exact usage of O-bit;
1526 * the bit will be set in Type-9,10,11 LSAs only.
1527 */
1528 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1529 continue;
1530 }
1531#endif /* STRICT_OBIT_USAGE_CHECK */
1532
1533 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1534 if (lsah->type == OSPF_OPAQUE_AS_LSA
1535 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1536 {
1537 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001538 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 +00001539 continue;
1540 }
1541 }
1542 else if (IS_OPAQUE_LSA(lsah->type))
1543 {
1544 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1545 continue;
1546 }
1547#endif /* HAVE_OPAQUE_LSA */
1548
1549 /* Create OSPF LSA instance. */
1550 lsa = ospf_lsa_new ();
1551
1552 /* We may wish to put some error checking if type NSSA comes in
1553 and area not in NSSA mode */
1554 switch (lsah->type)
1555 {
1556 case OSPF_AS_EXTERNAL_LSA:
1557#ifdef HAVE_OPAQUE_LSA
1558 case OSPF_OPAQUE_AS_LSA:
1559 lsa->area = NULL;
1560 break;
1561 case OSPF_OPAQUE_LINK_LSA:
1562 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1563 /* Fallthrough */
1564#endif /* HAVE_OPAQUE_LSA */
1565 default:
1566 lsa->area = oi->area;
1567 break;
1568 }
1569
1570 lsa->data = ospf_lsa_data_new (length);
1571 memcpy (lsa->data, lsah, length);
1572
1573 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001574 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001575 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1576 listnode_add (lsas, lsa);
1577 }
1578
1579 return lsas;
1580}
1581
1582/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001583static void
hasso52dc7ee2004-09-23 19:18:23 +00001584ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001585{
paul1eb8ef22005-04-07 07:30:20 +00001586 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001587 struct ospf_lsa *lsa;
1588
paul1eb8ef22005-04-07 07:30:20 +00001589 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1590 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001591
1592 list_delete (lsas);
1593}
1594
1595/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001596static void
paul718e3742002-12-13 20:15:29 +00001597ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1598 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1599{
1600 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001601 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001602 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001603 struct ospf_lsa *lsa = NULL;
1604 /* unsigned long ls_req_found = 0; */
1605
1606 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1607
1608 /* Increment statistics. */
1609 oi->ls_upd_in++;
1610
1611 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001612 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001613 if (nbr == NULL)
1614 {
1615 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1616 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1617 return;
1618 }
1619
1620 /* Check neighbor state. */
1621 if (nbr->state < NSM_Exchange)
1622 {
ajs3aa8d5f2004-12-11 18:00:06 +00001623 zlog_warn ("Link State Update: "
1624 "Neighbor[%s] state %s is less than Exchange",
1625 inet_ntoa (ospfh->router_id),
1626 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001627 return;
1628 }
1629
1630 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1631 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1632 * of section 13.
1633 */
1634 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1635
1636#ifdef HAVE_OPAQUE_LSA
1637 /*
paul718e3742002-12-13 20:15:29 +00001638 * If self-originated Opaque-LSAs that have flooded before restart
1639 * are contained in the received LSUpd message, corresponding LSReq
1640 * messages to be sent may have to be modified.
1641 * To eliminate possible race conditions such that flushing and normal
1642 * updating for the same LSA would take place alternately, this trick
1643 * must be done before entering to the loop below.
1644 */
paul69310a62005-05-11 18:09:59 +00001645 /* XXX: Why is this Opaque specific? Either our core code is deficient
1646 * and this should be fixed generally, or Opaque is inventing strawman
1647 * problems */
paul718e3742002-12-13 20:15:29 +00001648 ospf_opaque_adjust_lsreq (nbr, lsas);
1649#endif /* HAVE_OPAQUE_LSA */
1650
1651#define DISCARD_LSA(L,N) {\
1652 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001653 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 +00001654 ospf_lsa_discard (L); \
1655 continue; }
1656
1657 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001658 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001659 {
1660 struct ospf_lsa *ls_ret, *current;
1661 int ret = 1;
1662
paul718e3742002-12-13 20:15:29 +00001663 if (IS_DEBUG_OSPF_NSSA)
1664 {
1665 char buf1[INET_ADDRSTRLEN];
1666 char buf2[INET_ADDRSTRLEN];
1667 char buf3[INET_ADDRSTRLEN];
1668
ajs2a42e282004-12-08 18:43:03 +00001669 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001670 lsa->data->type,
1671 inet_ntop (AF_INET, &ospfh->router_id,
1672 buf1, INET_ADDRSTRLEN),
1673 inet_ntop (AF_INET, &lsa->data->id,
1674 buf2, INET_ADDRSTRLEN),
1675 inet_ntop (AF_INET, &lsa->data->adv_router,
1676 buf3, INET_ADDRSTRLEN));
1677 }
paul718e3742002-12-13 20:15:29 +00001678
1679 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1680
1681 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1682
1683 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1684
1685 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1686
1687 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1688
1689 /* Do take in Type-7's if we are an NSSA */
1690
1691 /* If we are also an ABR, later translate them to a Type-5 packet */
1692
1693 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1694 translate them to a separate Type-5 packet. */
1695
1696 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1697 /* Reject from STUB or NSSA */
1698 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1699 {
1700 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001701 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001702 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001703 }
1704
paul718e3742002-12-13 20:15:29 +00001705 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1706 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1707 {
1708 DISCARD_LSA (lsa,2);
1709 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001710 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001711 }
paul718e3742002-12-13 20:15:29 +00001712
1713 /* Find the LSA in the current database. */
1714
1715 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1716
1717 /* If the LSA's LS age is equal to MaxAge, and there is currently
1718 no instance of the LSA in the router's link state database,
1719 and none of router's neighbors are in states Exchange or Loading,
1720 then take the following actions. */
1721
1722 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001723 (ospf_nbr_count (oi, NSM_Exchange) +
1724 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001725 {
1726 /* Response Link State Acknowledgment. */
1727 ospf_ls_ack_send (nbr, lsa);
1728
1729 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001730 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1731 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001732 DISCARD_LSA (lsa, 3);
1733 }
1734
1735#ifdef HAVE_OPAQUE_LSA
1736 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001737 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001738 {
1739 /*
1740 * Even if initial flushing seems to be completed, there might
1741 * be a case that self-originated LSA with MaxAge still remain
1742 * in the routing domain.
1743 * Just send an LSAck message to cease retransmission.
1744 */
1745 if (IS_LSA_MAXAGE (lsa))
1746 {
1747 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1748 ospf_ls_ack_send (nbr, lsa);
1749 ospf_lsa_discard (lsa);
1750
1751 if (current != NULL && ! IS_LSA_MAXAGE (current))
1752 ospf_opaque_lsa_refresh_schedule (current);
1753 continue;
1754 }
1755
1756 /*
1757 * If an instance of self-originated Opaque-LSA is not found
1758 * in the LSDB, there are some possible cases here.
1759 *
1760 * 1) This node lost opaque-capability after restart.
1761 * 2) Else, a part of opaque-type is no more supported.
1762 * 3) Else, a part of opaque-id is no more supported.
1763 *
1764 * Anyway, it is still this node's responsibility to flush it.
1765 * Otherwise, the LSA instance remains in the routing domain
1766 * until its age reaches to MaxAge.
1767 */
paul69310a62005-05-11 18:09:59 +00001768 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001769 if (current == NULL)
1770 {
1771 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001772 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1773 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001774
1775 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001776
1777 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1778 ospf_ls_ack_send (nbr, lsa);
1779
paul718e3742002-12-13 20:15:29 +00001780 continue;
1781 }
1782 }
1783#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001784
hassocb05eb22004-02-11 21:10:19 +00001785 /* It might be happen that received LSA is self-originated network LSA, but
1786 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1787 * Link State ID is one of the router's own IP interface addresses but whose
1788 * Advertising Router is not equal to the router's own Router ID
1789 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1790 */
1791
1792 if(lsa->data->type == OSPF_NETWORK_LSA)
1793 {
paul1eb8ef22005-04-07 07:30:20 +00001794 struct listnode *oinode, *oinnode;
1795 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001796 int Flag = 0;
1797
paul1eb8ef22005-04-07 07:30:20 +00001798 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001799 {
hassocb05eb22004-02-11 21:10:19 +00001800 if(out_if == NULL)
1801 break;
1802
1803 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1804 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1805 {
1806 if(out_if->network_lsa_self)
1807 {
1808 ospf_lsa_flush_area(lsa,out_if->area);
1809 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001810 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001811 lsa, (int) lsa->data->type);
1812 ospf_lsa_discard (lsa);
1813 Flag = 1;
1814 }
1815 break;
1816 }
1817 }
1818 if(Flag)
1819 continue;
1820 }
paul718e3742002-12-13 20:15:29 +00001821
1822 /* (5) Find the instance of this LSA that is currently contained
1823 in the router's link state database. If there is no
1824 database copy, or the received LSA is more recent than
1825 the database copy the following steps must be performed. */
1826
1827 if (current == NULL ||
1828 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1829 {
1830 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001831 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001832 DISCARD_LSA (lsa, 4);
1833 continue;
1834 }
1835
1836 /* (6) Else, If there is an instance of the LSA on the sending
1837 neighbor's Link state request list, an error has occurred in
1838 the Database Exchange process. In this case, restart the
1839 Database Exchange process by generating the neighbor event
1840 BadLSReq for the sending neighbor and stop processing the
1841 Link State Update packet. */
1842
1843 if (ospf_ls_request_lookup (nbr, lsa))
1844 {
1845 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001846 zlog_warn("LSA[%s] instance exists on Link state request list",
1847 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001848
1849 /* Clean list of LSAs. */
1850 ospf_upd_list_clean (lsas);
1851 /* this lsa is not on lsas list already. */
1852 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001853 return;
1854 }
1855
1856 /* If the received LSA is the same instance as the database copy
1857 (i.e., neither one is more recent) the following two steps
1858 should be performed: */
1859
1860 if (ret == 0)
1861 {
1862 /* If the LSA is listed in the Link state retransmission list
1863 for the receiving adjacency, the router itself is expecting
1864 an acknowledgment for this LSA. The router should treat the
1865 received LSA as an acknowledgment by removing the LSA from
1866 the Link state retransmission list. This is termed an
1867 "implied acknowledgment". */
1868
1869 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1870
1871 if (ls_ret != NULL)
1872 {
1873 ospf_ls_retransmit_delete (nbr, ls_ret);
1874
1875 /* Delayed acknowledgment sent if advertisement received
1876 from Designated Router, otherwise do nothing. */
1877 if (oi->state == ISM_Backup)
1878 if (NBR_IS_DR (nbr))
1879 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1880
1881 DISCARD_LSA (lsa, 5);
1882 }
1883 else
1884 /* Acknowledge the receipt of the LSA by sending a
1885 Link State Acknowledgment packet back out the receiving
1886 interface. */
1887 {
1888 ospf_ls_ack_send (nbr, lsa);
1889 DISCARD_LSA (lsa, 6);
1890 }
1891 }
1892
1893 /* The database copy is more recent. If the database copy
1894 has LS age equal to MaxAge and LS sequence number equal to
1895 MaxSequenceNumber, simply discard the received LSA without
1896 acknowledging it. (In this case, the LSA's LS sequence number is
1897 wrapping, and the MaxSequenceNumber LSA must be completely
1898 flushed before any new LSA instance can be introduced). */
1899
1900 else if (ret > 0) /* Database copy is more recent */
1901 {
1902 if (IS_LSA_MAXAGE (current) &&
1903 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1904 {
1905 DISCARD_LSA (lsa, 7);
1906 }
1907 /* Otherwise, as long as the database copy has not been sent in a
1908 Link State Update within the last MinLSArrival seconds, send the
1909 database copy back to the sending neighbor, encapsulated within
1910 a Link State Update Packet. The Link State Update Packet should
1911 be sent directly to the neighbor. In so doing, do not put the
1912 database copy of the LSA on the neighbor's link state
1913 retransmission list, and do not acknowledge the received (less
1914 recent) LSA instance. */
1915 else
1916 {
1917 struct timeval now;
1918
1919 gettimeofday (&now, NULL);
1920
1921 if (tv_cmp (tv_sub (now, current->tv_orig),
1922 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1923 /* Trap NSSA type later.*/
1924 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1925 DISCARD_LSA (lsa, 8);
1926 }
1927 }
1928 }
1929
paul718e3742002-12-13 20:15:29 +00001930 assert (listcount (lsas) == 0);
1931 list_delete (lsas);
1932}
1933
1934/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001935static void
paul718e3742002-12-13 20:15:29 +00001936ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1937 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1938{
1939 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001940
paul718e3742002-12-13 20:15:29 +00001941 /* increment statistics. */
1942 oi->ls_ack_in++;
1943
pauld3f0d622004-05-05 15:27:15 +00001944 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001945 if (nbr == NULL)
1946 {
1947 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1948 inet_ntoa (ospfh->router_id));
1949 return;
1950 }
1951
1952 if (nbr->state < NSM_Exchange)
1953 {
ajs3aa8d5f2004-12-11 18:00:06 +00001954 zlog_warn ("Link State Acknowledgment: "
1955 "Neighbor[%s] state %s is less than Exchange",
1956 inet_ntoa (ospfh->router_id),
1957 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001958 return;
1959 }
paul69310a62005-05-11 18:09:59 +00001960
paul718e3742002-12-13 20:15:29 +00001961 while (size >= OSPF_LSA_HEADER_SIZE)
1962 {
1963 struct ospf_lsa *lsa, *lsr;
1964
1965 lsa = ospf_lsa_new ();
1966 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1967
1968 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1969 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001970 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001971
1972 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1973 {
1974 lsa->data = NULL;
1975 ospf_lsa_discard (lsa);
1976 continue;
1977 }
1978
1979 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1980
1981 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1982 {
1983#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001984 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001985 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001986#endif /* HAVE_OPAQUE_LSA */
1987
1988 ospf_ls_retransmit_delete (nbr, lsr);
1989 }
1990
1991 lsa->data = NULL;
1992 ospf_lsa_discard (lsa);
1993 }
1994
paul718e3742002-12-13 20:15:29 +00001995 return;
paul718e3742002-12-13 20:15:29 +00001996}
1997
ajs038163f2005-02-17 19:55:59 +00001998static struct stream *
ajs5c333492005-02-23 15:43:01 +00001999ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002000{
2001 int ret;
ajs5c333492005-02-23 15:43:01 +00002002 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002003 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002004 unsigned int ifindex = 0;
2005 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002006 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002007 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002008 struct msghdr msgh;
2009
paul68defd62004-09-27 07:27:13 +00002010 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002011 msgh.msg_iov = &iov;
2012 msgh.msg_iovlen = 1;
2013 msgh.msg_control = (caddr_t) buff;
2014 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002015
ajs5c333492005-02-23 15:43:01 +00002016 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2017 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002018 {
ajs5c333492005-02-23 15:43:01 +00002019 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2020 return NULL;
2021 }
paul69310a62005-05-11 18:09:59 +00002022 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002023 {
2024 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2025 "(ip header size is %u)",
2026 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002027 return NULL;
2028 }
paul18b12c32004-10-05 14:38:29 +00002029
ajs5c333492005-02-23 15:43:01 +00002030 /* Note that there should not be alignment problems with this assignment
2031 because this is at the beginning of the stream data buffer. */
2032 iph = (struct ip *) STREAM_DATA(ibuf);
2033 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002034
ajs5c333492005-02-23 15:43:01 +00002035 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002036
paul239aecc2003-12-08 10:34:54 +00002037#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002038 /*
2039 * Kernel network code touches incoming IP header parameters,
2040 * before protocol specific processing.
2041 *
2042 * 1) Convert byteorder to host representation.
2043 * --> ip_len, ip_id, ip_off
2044 *
2045 * 2) Adjust ip_len to strip IP header size!
2046 * --> If user process receives entire IP packet via RAW
2047 * socket, it must consider adding IP header size to
2048 * the "ip_len" field of "ip" structure.
2049 *
2050 * For more details, see <netinet/ip_input.c>.
2051 */
ajs5c333492005-02-23 15:43:01 +00002052 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002053#endif
2054
paul863082d2004-08-19 04:43:43 +00002055 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002056
2057 *ifp = if_lookup_by_index (ifindex);
2058
2059 if (ret != ip_len)
2060 {
ajs5c333492005-02-23 15:43:01 +00002061 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2062 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002063 return NULL;
2064 }
2065
2066 return ibuf;
2067}
2068
paul4dadc292005-05-06 21:37:42 +00002069static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002070ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002071 struct ip *iph, struct ospf_header *ospfh)
2072{
2073 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002074 struct ospf_vl_data *vl_data;
2075 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002076 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002077
2078 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2079 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002080 return NULL;
paul718e3742002-12-13 20:15:29 +00002081
pauld3f0d622004-05-05 15:27:15 +00002082 /* look for local OSPF interface matching the destination
2083 * to determine Area ID. We presume therefore the destination address
2084 * is unique, or at least (for "unnumbered" links), not used in other
2085 * areas
2086 */
2087 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2088 iph->ip_dst)) == NULL)
2089 return NULL;
paul718e3742002-12-13 20:15:29 +00002090
paul1eb8ef22005-04-07 07:30:20 +00002091 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002092 {
paul020709f2003-04-04 02:44:16 +00002093 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002094 if (!vl_area)
2095 continue;
2096
2097 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2098 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2099 {
2100 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002101 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002102 IF_NAME (vl_data->vl_oi));
2103 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2104 {
2105 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002106 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002107 return NULL;
2108 }
2109
2110 return vl_data->vl_oi;
2111 }
2112 }
2113
2114 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002115 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002116
pauld3f0d622004-05-05 15:27:15 +00002117 return NULL;
paul718e3742002-12-13 20:15:29 +00002118}
2119
paul4dadc292005-05-06 21:37:42 +00002120static inline int
paul718e3742002-12-13 20:15:29 +00002121ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2122{
2123 /* Check match the Area ID of the receiving interface. */
2124 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2125 return 1;
2126
2127 return 0;
2128}
2129
2130/* Unbound socket will accept any Raw IP packets if proto is matched.
2131 To prevent it, compare src IP address and i/f address with masking
2132 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002133static int
paul718e3742002-12-13 20:15:29 +00002134ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2135{
2136 struct in_addr mask, me, him;
2137
2138 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2139 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2140 return 1;
2141
2142 masklen2ip (oi->address->prefixlen, &mask);
2143
2144 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2145 him.s_addr = ip_src.s_addr & mask.s_addr;
2146
2147 if (IPV4_ADDR_SAME (&me, &him))
2148 return 1;
2149
2150 return 0;
2151}
2152
paul4dadc292005-05-06 21:37:42 +00002153static int
paul718e3742002-12-13 20:15:29 +00002154ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2155 struct ospf_header *ospfh)
2156{
2157 int ret = 0;
2158 struct crypt_key *ck;
2159
2160 switch (ntohs (ospfh->auth_type))
2161 {
2162 case OSPF_AUTH_NULL:
2163 ret = 1;
2164 break;
2165 case OSPF_AUTH_SIMPLE:
2166 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2167 ret = 1;
2168 else
2169 ret = 0;
2170 break;
2171 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002172 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002173 {
2174 ret = 0;
2175 break;
2176 }
2177
2178 /* This is very basic, the digest processing is elsewhere */
2179 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2180 ospfh->u.crypt.key_id == ck->key_id &&
2181 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2182 ret = 1;
2183 else
2184 ret = 0;
2185 break;
2186 default:
2187 ret = 0;
2188 break;
2189 }
2190
2191 return ret;
2192}
2193
paul4dadc292005-05-06 21:37:42 +00002194static int
paul718e3742002-12-13 20:15:29 +00002195ospf_check_sum (struct ospf_header *ospfh)
2196{
2197 u_int32_t ret;
2198 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002199
2200 /* clear auth_data for checksum. */
2201 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2202
2203 /* keep checksum and clear. */
2204 sum = ospfh->checksum;
2205 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2206
2207 /* calculate checksum. */
2208 ret = in_cksum (ospfh, ntohs (ospfh->length));
2209
2210 if (ret != sum)
2211 {
2212 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2213 ret, sum);
2214 return 0;
2215 }
2216
2217 return 1;
2218}
2219
2220/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002221static int
paul718e3742002-12-13 20:15:29 +00002222ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2223 struct ip *iph, struct ospf_header *ospfh)
2224{
2225 /* check version. */
2226 if (ospfh->version != OSPF_VERSION)
2227 {
2228 zlog_warn ("interface %s: ospf_read version number mismatch.",
2229 IF_NAME (oi));
2230 return -1;
2231 }
2232
2233 /* Check Area ID. */
2234 if (!ospf_check_area_id (oi, ospfh))
2235 {
2236 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2237 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2238 return -1;
2239 }
2240
2241 /* Check network mask, Silently discarded. */
2242 if (! ospf_check_network_mask (oi, iph->ip_src))
2243 {
2244 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2245 IF_NAME (oi), inet_ntoa (iph->ip_src));
2246 return -1;
2247 }
2248
2249 /* Check authentication. */
2250 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2251 {
2252 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2253 IF_NAME (oi));
2254 return -1;
2255 }
2256
2257 if (! ospf_check_auth (oi, ibuf, ospfh))
2258 {
2259 zlog_warn ("interface %s: ospf_read authentication failed.",
2260 IF_NAME (oi));
2261 return -1;
2262 }
2263
2264 /* if check sum is invalid, packet is discarded. */
2265 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2266 {
2267 if (! ospf_check_sum (ospfh))
2268 {
2269 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2270 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2271 return -1;
2272 }
2273 }
2274 else
2275 {
2276 if (ospfh->checksum != 0)
2277 return -1;
2278 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2279 {
2280 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2281 IF_NAME (oi));
2282 return -1;
2283 }
2284 }
2285
2286 return 0;
2287}
2288
2289/* Starting point of packet process function. */
2290int
2291ospf_read (struct thread *thread)
2292{
2293 int ret;
2294 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002295 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002296 struct ospf_interface *oi;
2297 struct ip *iph;
2298 struct ospf_header *ospfh;
2299 u_int16_t length;
2300 struct interface *ifp;
2301
2302 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002303 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002304
2305 /* prepare for next packet. */
2306 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002307
2308 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002309 stream_reset(ospf->ibuf);
2310 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002311 return -1;
2312
ajs5c333492005-02-23 15:43:01 +00002313 /* Note that there should not be alignment problems with this assignment
2314 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002315 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002316 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002317
paulac191232004-10-22 12:05:17 +00002318 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002319 /* Handle cases where the platform does not support retrieving the ifindex,
2320 and also platforms (such as Solaris 8) that claim to support ifindex
2321 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002322 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002323
pauld3f0d622004-05-05 15:27:15 +00002324 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002325 return 0;
paul718e3742002-12-13 20:15:29 +00002326
2327 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002328 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002329 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002330
paul718e3742002-12-13 20:15:29 +00002331 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002332 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002333 {
pauld3241812003-09-29 12:42:39 +00002334 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2335 {
ajs2a42e282004-12-08 18:43:03 +00002336 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002337 inet_ntoa (iph->ip_src));
2338 }
paul718e3742002-12-13 20:15:29 +00002339 return 0;
2340 }
2341
2342 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002343 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002344
2345 /* Get ospf packet header. */
2346 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2347
2348 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002349 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002350
2351 /* if no local ospf_interface,
2352 * or header area is backbone but ospf_interface is not
2353 * check for VLINK interface
2354 */
2355 if ( (oi == NULL) ||
2356 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2357 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2358 )
2359 {
2360 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2361 {
paulf9ad9372005-10-21 00:45:17 +00002362 zlog_debug ("Packet from [%s] received on link %s"
pauld3f0d622004-05-05 15:27:15 +00002363 " but no ospf_interface",
2364 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002365 return 0;
2366 }
2367 }
2368
2369 /* else it must be a local ospf interface, check it was received on
2370 * correct link
2371 */
2372 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002373 {
2374 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002375 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002376 return 0;
2377 }
ajs847947f2005-02-02 18:38:48 +00002378 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002379 {
ajsba6454e2005-02-08 15:37:30 +00002380 char buf[2][INET_ADDRSTRLEN];
2381 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002382 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002383 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2384 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2385 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002386 /* Fix multicast memberships? */
2387 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2388 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2389 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2390 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2391 if (oi->multicast_memberships)
2392 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002393 return 0;
2394 }
paul718e3742002-12-13 20:15:29 +00002395
2396 /*
2397 * If the received packet is destined for AllDRouters, the packet
2398 * should be accepted only if the received ospf interface state is
2399 * either DR or Backup -- endo.
2400 */
2401 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2402 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2403 {
ajsba6454e2005-02-08 15:37:30 +00002404 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002405 inet_ntoa (iph->ip_src), IF_NAME (oi),
2406 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002407 /* Try to fix multicast membership. */
2408 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2409 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002410 return 0;
2411 }
2412
2413 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002414 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2415 {
paul718e3742002-12-13 20:15:29 +00002416 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002417 {
ajs2a42e282004-12-08 18:43:03 +00002418 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002419 ospf_packet_dump (ibuf);
2420 }
paul718e3742002-12-13 20:15:29 +00002421
ajs2a42e282004-12-08 18:43:03 +00002422 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002423 ospf_packet_type_str[ospfh->type],
2424 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002425 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2426 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002427
2428 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002429 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002430 }
paul718e3742002-12-13 20:15:29 +00002431
2432 /* Some header verification. */
2433 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2434 if (ret < 0)
2435 {
pauld3241812003-09-29 12:42:39 +00002436 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2437 {
ajs2a42e282004-12-08 18:43:03 +00002438 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002439 "dropping.",
2440 ospf_packet_type_str[ospfh->type],
2441 inet_ntoa (iph->ip_src));
2442 }
paul718e3742002-12-13 20:15:29 +00002443 return ret;
2444 }
2445
paul9985f832005-02-09 15:51:56 +00002446 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002447
2448 /* Adjust size to message length. */
2449 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2450
2451 /* Read rest of the packet and call each sort of packet routine. */
2452 switch (ospfh->type)
2453 {
2454 case OSPF_MSG_HELLO:
2455 ospf_hello (iph, ospfh, ibuf, oi, length);
2456 break;
2457 case OSPF_MSG_DB_DESC:
2458 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2459 break;
2460 case OSPF_MSG_LS_REQ:
2461 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2462 break;
2463 case OSPF_MSG_LS_UPD:
2464 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2465 break;
2466 case OSPF_MSG_LS_ACK:
2467 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2468 break;
2469 default:
2470 zlog (NULL, LOG_WARNING,
2471 "interface %s: OSPF packet header type %d is illegal",
2472 IF_NAME (oi), ospfh->type);
2473 break;
2474 }
2475
paul718e3742002-12-13 20:15:29 +00002476 return 0;
2477}
2478
2479/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002480static void
paul718e3742002-12-13 20:15:29 +00002481ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2482{
2483 struct ospf_header *ospfh;
2484
2485 ospfh = (struct ospf_header *) STREAM_DATA (s);
2486
2487 ospfh->version = (u_char) OSPF_VERSION;
2488 ospfh->type = (u_char) type;
2489
paul68980082003-03-25 05:07:42 +00002490 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002491
2492 ospfh->checksum = 0;
2493 ospfh->area_id = oi->area->area_id;
2494 ospfh->auth_type = htons (ospf_auth_type (oi));
2495
2496 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2497
paul9985f832005-02-09 15:51:56 +00002498 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002499}
2500
2501/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002502static int
paul718e3742002-12-13 20:15:29 +00002503ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2504{
2505 struct crypt_key *ck;
2506
2507 switch (ospf_auth_type (oi))
2508 {
2509 case OSPF_AUTH_NULL:
2510 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2511 break;
2512 case OSPF_AUTH_SIMPLE:
2513 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2514 OSPF_AUTH_SIMPLE_SIZE);
2515 break;
2516 case OSPF_AUTH_CRYPTOGRAPHIC:
2517 /* If key is not set, then set 0. */
2518 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2519 {
2520 ospfh->u.crypt.zero = 0;
2521 ospfh->u.crypt.key_id = 0;
2522 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2523 }
2524 else
2525 {
paul1eb8ef22005-04-07 07:30:20 +00002526 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002527 ospfh->u.crypt.zero = 0;
2528 ospfh->u.crypt.key_id = ck->key_id;
2529 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2530 }
2531 /* note: the seq is done in ospf_make_md5_digest() */
2532 break;
2533 default:
2534 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2535 break;
2536 }
2537
2538 return 0;
2539}
2540
2541/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002542static void
paul718e3742002-12-13 20:15:29 +00002543ospf_fill_header (struct ospf_interface *oi,
2544 struct stream *s, u_int16_t length)
2545{
2546 struct ospf_header *ospfh;
2547
2548 ospfh = (struct ospf_header *) STREAM_DATA (s);
2549
2550 /* Fill length. */
2551 ospfh->length = htons (length);
2552
2553 /* Calculate checksum. */
2554 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2555 ospfh->checksum = in_cksum (ospfh, length);
2556 else
2557 ospfh->checksum = 0;
2558
2559 /* Add Authentication Data. */
2560 ospf_make_auth (oi, ospfh);
2561}
2562
paul4dadc292005-05-06 21:37:42 +00002563static int
paul718e3742002-12-13 20:15:29 +00002564ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2565{
2566 struct ospf_neighbor *nbr;
2567 struct route_node *rn;
2568 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2569 struct in_addr mask;
2570 unsigned long p;
2571 int flag = 0;
2572
2573 /* Set netmask of interface. */
2574 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2575 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2576 masklen2ip (oi->address->prefixlen, &mask);
2577 else
2578 memset ((char *) &mask, 0, sizeof (struct in_addr));
2579 stream_put_ipv4 (s, mask.s_addr);
2580
2581 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002582 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2583 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2584 else
2585 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002586
2587 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002588 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002589 OPTIONS(oi), IF_NAME (oi));
2590
2591 /* Set Options. */
2592 stream_putc (s, OPTIONS (oi));
2593
2594 /* Set Router Priority. */
2595 stream_putc (s, PRIORITY (oi));
2596
2597 /* Set Router Dead Interval. */
2598 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2599
2600 /* Set Designated Router. */
2601 stream_put_ipv4 (s, DR (oi).s_addr);
2602
paul9985f832005-02-09 15:51:56 +00002603 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002604
2605 /* Set Backup Designated Router. */
2606 stream_put_ipv4 (s, BDR (oi).s_addr);
2607
2608 /* Add neighbor seen. */
2609 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002610 if ((nbr = rn->info))
2611 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2612 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2613 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2614 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002615 {
2616 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002617 if (nbr->d_router.s_addr != 0
2618 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2619 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2620 flag = 1;
paul718e3742002-12-13 20:15:29 +00002621
2622 stream_put_ipv4 (s, nbr->router_id.s_addr);
2623 length += 4;
2624 }
2625
2626 /* Let neighbor generate BackupSeen. */
2627 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002628 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002629
2630 return length;
2631}
2632
paul4dadc292005-05-06 21:37:42 +00002633static int
paul718e3742002-12-13 20:15:29 +00002634ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2635 struct stream *s)
2636{
2637 struct ospf_lsa *lsa;
2638 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2639 u_char options;
2640 unsigned long pp;
2641 int i;
2642 struct ospf_lsdb *lsdb;
2643
2644 /* Set Interface MTU. */
2645 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2646 stream_putw (s, 0);
2647 else
2648 stream_putw (s, oi->ifp->mtu);
2649
2650 /* Set Options. */
2651 options = OPTIONS (oi);
2652#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002653 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002654 {
2655 if (IS_SET_DD_I (nbr->dd_flags)
2656 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2657 /*
2658 * Set O-bit in the outgoing DD packet for capablity negotiation,
2659 * if one of following case is applicable.
2660 *
2661 * 1) WaitTimer expiration event triggered the neighbor state to
2662 * change to Exstart, but no (valid) DD packet has received
2663 * from the neighbor yet.
2664 *
2665 * 2) At least one DD packet with O-bit on has received from the
2666 * neighbor.
2667 */
2668 SET_FLAG (options, OSPF_OPTION_O);
2669 }
2670#endif /* HAVE_OPAQUE_LSA */
2671 stream_putc (s, options);
2672
2673 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002674 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002675 stream_putc (s, nbr->dd_flags);
2676
2677 /* Set DD Sequence Number. */
2678 stream_putl (s, nbr->dd_seqnum);
2679
2680 if (ospf_db_summary_isempty (nbr))
2681 {
2682 if (nbr->state >= NSM_Exchange)
2683 {
2684 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2685 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002686 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002687 }
2688 return length;
2689 }
2690
2691 /* Describe LSA Header from Database Summary List. */
2692 lsdb = &nbr->db_sum;
2693
2694 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2695 {
2696 struct route_table *table = lsdb->type[i].db;
2697 struct route_node *rn;
2698
2699 for (rn = route_top (table); rn; rn = route_next (rn))
2700 if ((lsa = rn->info) != NULL)
2701 {
2702#ifdef HAVE_OPAQUE_LSA
2703 if (IS_OPAQUE_LSA (lsa->data->type)
2704 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2705 {
2706 /* Suppress advertising opaque-informations. */
2707 /* Remove LSA from DB summary list. */
2708 ospf_lsdb_delete (lsdb, lsa);
2709 continue;
2710 }
2711#endif /* HAVE_OPAQUE_LSA */
2712
2713 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2714 {
2715 struct lsa_header *lsah;
2716 u_int16_t ls_age;
2717
2718 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002719 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002720 break;
2721
2722 /* Keep pointer to LS age. */
2723 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002724 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002725
2726 /* Proceed stream pointer. */
2727 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2728 length += OSPF_LSA_HEADER_SIZE;
2729
2730 /* Set LS age. */
2731 ls_age = LS_AGE (lsa);
2732 lsah->ls_age = htons (ls_age);
2733
2734 }
2735
2736 /* Remove LSA from DB summary list. */
2737 ospf_lsdb_delete (lsdb, lsa);
2738 }
2739 }
2740
2741 return length;
2742}
2743
paul4dadc292005-05-06 21:37:42 +00002744static int
paul718e3742002-12-13 20:15:29 +00002745ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2746 unsigned long delta, struct ospf_neighbor *nbr,
2747 struct ospf_lsa *lsa)
2748{
2749 struct ospf_interface *oi;
2750
2751 oi = nbr->oi;
2752
2753 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002754 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002755 return 0;
2756
2757 stream_putl (s, lsa->data->type);
2758 stream_put_ipv4 (s, lsa->data->id.s_addr);
2759 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2760
2761 ospf_lsa_unlock (nbr->ls_req_last);
2762 nbr->ls_req_last = ospf_lsa_lock (lsa);
2763
2764 *length += 12;
2765 return 1;
2766}
2767
paul4dadc292005-05-06 21:37:42 +00002768static int
paul718e3742002-12-13 20:15:29 +00002769ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2770{
2771 struct ospf_lsa *lsa;
2772 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002773 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002774 struct route_table *table;
2775 struct route_node *rn;
2776 int i;
2777 struct ospf_lsdb *lsdb;
2778
2779 lsdb = &nbr->ls_req;
2780
2781 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2782 {
2783 table = lsdb->type[i].db;
2784 for (rn = route_top (table); rn; rn = route_next (rn))
2785 if ((lsa = (rn->info)) != NULL)
2786 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2787 {
2788 route_unlock_node (rn);
2789 break;
2790 }
2791 }
2792 return length;
2793}
2794
paul4dadc292005-05-06 21:37:42 +00002795static int
paul718e3742002-12-13 20:15:29 +00002796ls_age_increment (struct ospf_lsa *lsa, int delay)
2797{
2798 int age;
2799
2800 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2801
2802 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2803}
2804
paul4dadc292005-05-06 21:37:42 +00002805static int
hasso52dc7ee2004-09-23 19:18:23 +00002806ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002807{
2808 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002809 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002810 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002811 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002812 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002813 unsigned long pp;
2814 int count = 0;
2815
2816 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002817 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002818
paul9985f832005-02-09 15:51:56 +00002819 pp = stream_get_endp (s);
2820 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002821
gdt86f1fd92005-01-10 14:20:43 +00002822 /* Calculate amount of packet usable for data. */
2823 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2824
paul718e3742002-12-13 20:15:29 +00002825 while ((node = listhead (update)) != NULL)
2826 {
2827 struct lsa_header *lsah;
2828 u_int16_t ls_age;
2829
2830 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002831 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002832
paul1eb8ef22005-04-07 07:30:20 +00002833 lsa = listgetdata (node);
2834
paul718e3742002-12-13 20:15:29 +00002835 assert (lsa->data);
2836
paul68b73392004-09-12 14:21:37 +00002837 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002838 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002839 break;
2840
paul718e3742002-12-13 20:15:29 +00002841 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002842 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002843
2844 /* Put LSA to Link State Request. */
2845 stream_put (s, lsa->data, ntohs (lsa->data->length));
2846
2847 /* Set LS age. */
2848 /* each hop must increment an lsa_age by transmit_delay
2849 of OSPF interface */
2850 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2851 lsah->ls_age = htons (ls_age);
2852
2853 length += ntohs (lsa->data->length);
2854 count++;
2855
2856 list_delete_node (update, node);
2857 ospf_lsa_unlock (lsa);
2858 }
2859
2860 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002861 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002862
2863 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002864 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002865 return length;
2866}
2867
paul4dadc292005-05-06 21:37:42 +00002868static int
hasso52dc7ee2004-09-23 19:18:23 +00002869ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002870{
hasso52dc7ee2004-09-23 19:18:23 +00002871 struct list *rm_list;
2872 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002873 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002874 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002875 struct ospf_lsa *lsa;
2876
2877 rm_list = list_new ();
2878
paul1eb8ef22005-04-07 07:30:20 +00002879 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002880 {
paul1eb8ef22005-04-07 07:30:20 +00002881 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002882 assert (lsa);
2883
gdt86f1fd92005-01-10 14:20:43 +00002884 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002885 break;
2886
2887 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2888 length += OSPF_LSA_HEADER_SIZE;
2889
2890 listnode_add (rm_list, lsa);
2891 }
2892
2893 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002894 /* XXX: this loop should be removed and the list move done in previous
2895 * loop
2896 */
2897 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002898 {
paul718e3742002-12-13 20:15:29 +00002899 listnode_delete (ack, lsa);
2900 ospf_lsa_unlock (lsa);
2901 }
2902
2903 list_delete (rm_list);
2904
2905 return length;
2906}
2907
2908void
2909ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2910{
2911 struct ospf_packet *op;
2912 u_int16_t length = OSPF_HEADER_SIZE;
2913
2914 op = ospf_packet_new (oi->ifp->mtu);
2915
2916 /* Prepare OSPF common header. */
2917 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2918
2919 /* Prepare OSPF Hello body. */
2920 length += ospf_make_hello (oi, op->s);
2921
2922 /* Fill OSPF header. */
2923 ospf_fill_header (oi, op->s, length);
2924
2925 /* Set packet length. */
2926 op->length = length;
2927
2928 op->dst.s_addr = addr->s_addr;
2929
2930 /* Add packet to the interface output queue. */
2931 ospf_packet_add (oi, op);
2932
2933 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002934 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002935}
2936
paul4dadc292005-05-06 21:37:42 +00002937static void
paul718e3742002-12-13 20:15:29 +00002938ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2939{
2940 struct ospf_interface *oi;
2941
2942 oi = nbr_nbma->oi;
2943 assert(oi);
2944
2945 /* If this is passive interface, do not send OSPF Hello. */
2946 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2947 return;
2948
2949 if (oi->type != OSPF_IFTYPE_NBMA)
2950 return;
2951
2952 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2953 return;
2954
2955 if (PRIORITY(oi) == 0)
2956 return;
2957
2958 if (nbr_nbma->priority == 0
2959 && oi->state != ISM_DR && oi->state != ISM_Backup)
2960 return;
2961
2962 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2963}
2964
2965int
2966ospf_poll_timer (struct thread *thread)
2967{
2968 struct ospf_nbr_nbma *nbr_nbma;
2969
2970 nbr_nbma = THREAD_ARG (thread);
2971 nbr_nbma->t_poll = NULL;
2972
2973 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002974 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002975 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2976
2977 ospf_poll_send (nbr_nbma);
2978
2979 if (nbr_nbma->v_poll > 0)
2980 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2981 nbr_nbma->v_poll);
2982
2983 return 0;
2984}
2985
2986
2987int
2988ospf_hello_reply_timer (struct thread *thread)
2989{
2990 struct ospf_neighbor *nbr;
2991
2992 nbr = THREAD_ARG (thread);
2993 nbr->t_hello_reply = NULL;
2994
2995 assert (nbr->oi);
2996
2997 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002998 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00002999 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3000
3001 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3002
3003 return 0;
3004}
3005
3006/* Send OSPF Hello. */
3007void
3008ospf_hello_send (struct ospf_interface *oi)
3009{
3010 struct ospf_packet *op;
3011 u_int16_t length = OSPF_HEADER_SIZE;
3012
3013 /* If this is passive interface, do not send OSPF Hello. */
3014 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3015 return;
3016
3017 op = ospf_packet_new (oi->ifp->mtu);
3018
3019 /* Prepare OSPF common header. */
3020 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3021
3022 /* Prepare OSPF Hello body. */
3023 length += ospf_make_hello (oi, op->s);
3024
3025 /* Fill OSPF header. */
3026 ospf_fill_header (oi, op->s, length);
3027
3028 /* Set packet length. */
3029 op->length = length;
3030
3031 if (oi->type == OSPF_IFTYPE_NBMA)
3032 {
3033 struct ospf_neighbor *nbr;
3034 struct route_node *rn;
3035
3036 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3037 if ((nbr = rn->info))
3038 if (nbr != oi->nbr_self)
3039 if (nbr->state != NSM_Down)
3040 {
3041 /* RFC 2328 Section 9.5.1
3042 If the router is not eligible to become Designated Router,
3043 it must periodically send Hello Packets to both the
3044 Designated Router and the Backup Designated Router (if they
3045 exist). */
3046 if (PRIORITY(oi) == 0 &&
3047 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3048 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3049 continue;
3050
3051 /* If the router is eligible to become Designated Router, it
3052 must periodically send Hello Packets to all neighbors that
3053 are also eligible. In addition, if the router is itself the
3054 Designated Router or Backup Designated Router, it must also
3055 send periodic Hello Packets to all other neighbors. */
3056
3057 if (nbr->priority == 0 && oi->state == ISM_DROther)
3058 continue;
3059 /* if oi->state == Waiting, send hello to all neighbors */
3060 {
3061 struct ospf_packet *op_dup;
3062
3063 op_dup = ospf_packet_dup(op);
3064 op_dup->dst = nbr->address.u.prefix4;
3065
3066 /* Add packet to the interface output queue. */
3067 ospf_packet_add (oi, op_dup);
3068
paul020709f2003-04-04 02:44:16 +00003069 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003070 }
3071
3072 }
3073 ospf_packet_free (op);
3074 }
3075 else
3076 {
3077 /* Decide destination address. */
3078 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3079 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3080 else
3081 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3082
3083 /* Add packet to the interface output queue. */
3084 ospf_packet_add (oi, op);
3085
3086 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003087 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003088 }
3089}
3090
3091/* Send OSPF Database Description. */
3092void
3093ospf_db_desc_send (struct ospf_neighbor *nbr)
3094{
3095 struct ospf_interface *oi;
3096 struct ospf_packet *op;
3097 u_int16_t length = OSPF_HEADER_SIZE;
3098
3099 oi = nbr->oi;
3100 op = ospf_packet_new (oi->ifp->mtu);
3101
3102 /* Prepare OSPF common header. */
3103 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3104
3105 /* Prepare OSPF Database Description body. */
3106 length += ospf_make_db_desc (oi, nbr, op->s);
3107
3108 /* Fill OSPF header. */
3109 ospf_fill_header (oi, op->s, length);
3110
3111 /* Set packet length. */
3112 op->length = length;
3113
3114 /* Decide destination address. */
3115 op->dst = nbr->address.u.prefix4;
3116
3117 /* Add packet to the interface output queue. */
3118 ospf_packet_add (oi, op);
3119
3120 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003121 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003122
3123 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3124 if (nbr->last_send)
3125 ospf_packet_free (nbr->last_send);
3126 nbr->last_send = ospf_packet_dup (op);
3127 gettimeofday (&nbr->last_send_ts, NULL);
3128}
3129
3130/* Re-send Database Description. */
3131void
3132ospf_db_desc_resend (struct ospf_neighbor *nbr)
3133{
3134 struct ospf_interface *oi;
3135
3136 oi = nbr->oi;
3137
3138 /* Add packet to the interface output queue. */
3139 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3140
3141 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003142 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003143}
3144
3145/* Send Link State Request. */
3146void
3147ospf_ls_req_send (struct ospf_neighbor *nbr)
3148{
3149 struct ospf_interface *oi;
3150 struct ospf_packet *op;
3151 u_int16_t length = OSPF_HEADER_SIZE;
3152
3153 oi = nbr->oi;
3154 op = ospf_packet_new (oi->ifp->mtu);
3155
3156 /* Prepare OSPF common header. */
3157 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3158
3159 /* Prepare OSPF Link State Request body. */
3160 length += ospf_make_ls_req (nbr, op->s);
3161 if (length == OSPF_HEADER_SIZE)
3162 {
3163 ospf_packet_free (op);
3164 return;
3165 }
3166
3167 /* Fill OSPF header. */
3168 ospf_fill_header (oi, op->s, length);
3169
3170 /* Set packet length. */
3171 op->length = length;
3172
3173 /* Decide destination address. */
3174 op->dst = nbr->address.u.prefix4;
3175
3176 /* Add packet to the interface output queue. */
3177 ospf_packet_add (oi, op);
3178
3179 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003180 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003181
3182 /* Add Link State Request Retransmission Timer. */
3183 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3184}
3185
3186/* Send Link State Update with an LSA. */
3187void
3188ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3189 int flag)
3190{
hasso52dc7ee2004-09-23 19:18:23 +00003191 struct list *update;
paul718e3742002-12-13 20:15:29 +00003192
3193 update = list_new ();
3194
3195 listnode_add (update, lsa);
3196 ospf_ls_upd_send (nbr, update, flag);
3197
3198 list_delete (update);
3199}
3200
paul68b73392004-09-12 14:21:37 +00003201/* Determine size for packet. Must be at least big enough to accomodate next
3202 * LSA on list, which may be bigger than MTU size.
3203 *
3204 * Return pointer to new ospf_packet
3205 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3206 * on packet sizes (in which case offending LSA is deleted from update list)
3207 */
3208static struct ospf_packet *
3209ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3210{
3211 struct ospf_lsa *lsa;
3212 struct listnode *ln;
3213 size_t size;
3214 static char warned = 0;
3215
paul1eb8ef22005-04-07 07:30:20 +00003216 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003217 assert (lsa->data);
3218
3219 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3220 > ospf_packet_max (oi))
3221 {
3222 if (!warned)
3223 {
3224 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3225 "will need to fragment. Not optimal. Try divide up"
3226 " your network with areas. Use 'debug ospf packet send'"
3227 " to see details, or look at 'show ip ospf database ..'");
3228 warned = 1;
3229 }
3230
3231 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003232 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003233 " %d bytes originated by %s, will be fragmented!",
3234 inet_ntoa (lsa->data->id),
3235 ntohs (lsa->data->length),
3236 inet_ntoa (lsa->data->adv_router));
3237
3238 /*
3239 * Allocate just enough to fit this LSA only, to avoid including other
3240 * LSAs in fragmented LSA Updates.
3241 */
3242 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3243 + OSPF_LS_UPD_MIN_SIZE;
3244 }
3245 else
3246 size = oi->ifp->mtu;
3247
gdt86f1fd92005-01-10 14:20:43 +00003248 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003249 if (size > OSPF_MAX_PACKET_SIZE)
3250 {
3251 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003252 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003253 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003254 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003255 (long int) size);
paul68b73392004-09-12 14:21:37 +00003256 list_delete_node (update, ln);
3257 return NULL;
3258 }
3259
3260 return ospf_packet_new (size);
3261}
3262
paul718e3742002-12-13 20:15:29 +00003263static void
hasso52dc7ee2004-09-23 19:18:23 +00003264ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003265 struct in_addr addr)
3266{
3267 struct ospf_packet *op;
3268 u_int16_t length = OSPF_HEADER_SIZE;
3269
3270 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003271 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003272
3273 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003274
3275 /* Prepare OSPF common header. */
3276 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3277
paul59ea14c2004-07-14 20:50:36 +00003278 /* Prepare OSPF Link State Update body.
3279 * Includes Type-7 translation.
3280 */
paul718e3742002-12-13 20:15:29 +00003281 length += ospf_make_ls_upd (oi, update, op->s);
3282
3283 /* Fill OSPF header. */
3284 ospf_fill_header (oi, op->s, length);
3285
3286 /* Set packet length. */
3287 op->length = length;
3288
3289 /* Decide destination address. */
3290 op->dst.s_addr = addr.s_addr;
3291
3292 /* Add packet to the interface output queue. */
3293 ospf_packet_add (oi, op);
3294
3295 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003296 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003297}
3298
3299static int
3300ospf_ls_upd_send_queue_event (struct thread *thread)
3301{
3302 struct ospf_interface *oi = THREAD_ARG(thread);
3303 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003304 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003305 struct list *update;
paul68b73392004-09-12 14:21:37 +00003306 char again = 0;
paul718e3742002-12-13 20:15:29 +00003307
3308 oi->t_ls_upd_event = NULL;
3309
3310 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003311 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003312
paul736d3442003-07-24 23:22:57 +00003313 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003314 {
paul736d3442003-07-24 23:22:57 +00003315 rnext = route_next (rn);
3316
paul718e3742002-12-13 20:15:29 +00003317 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003318 continue;
paul68b73392004-09-12 14:21:37 +00003319
3320 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003321
paul48fe13b2004-07-27 17:40:44 +00003322 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003323
paul68b73392004-09-12 14:21:37 +00003324 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003325 if (listcount(update) == 0)
3326 {
3327 list_delete (rn->info);
3328 rn->info = NULL;
3329 route_unlock_node (rn);
3330 }
3331 else
paul68b73392004-09-12 14:21:37 +00003332 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003333 }
3334
3335 if (again != 0)
3336 {
3337 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003338 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003339 " %d nodes to try again, raising new event", again);
3340 oi->t_ls_upd_event =
3341 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003342 }
3343
3344 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003345 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003346
paul718e3742002-12-13 20:15:29 +00003347 return 0;
3348}
3349
3350void
hasso52dc7ee2004-09-23 19:18:23 +00003351ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003352{
3353 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003354 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003355 struct prefix_ipv4 p;
3356 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003357 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003358
3359 oi = nbr->oi;
3360
3361 p.family = AF_INET;
3362 p.prefixlen = IPV4_MAX_BITLEN;
3363
3364 /* Decide destination address. */
3365 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3366 p.prefix = oi->vl_data->peer_addr;
3367 else if (flag == OSPF_SEND_PACKET_DIRECT)
3368 p.prefix = nbr->address.u.prefix4;
3369 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3370 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3371 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3372 && (flag == OSPF_SEND_PACKET_INDIRECT))
3373 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003374 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3375 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003376 else
3377 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3378
3379 if (oi->type == OSPF_IFTYPE_NBMA)
3380 {
3381 if (flag == OSPF_SEND_PACKET_INDIRECT)
3382 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3383 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3384 zlog_warn ("* LS-Update is sent to myself.");
3385 }
3386
3387 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3388
3389 if (rn->info == NULL)
3390 rn->info = list_new ();
3391
paul1eb8ef22005-04-07 07:30:20 +00003392 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3393 {
3394 ospf_lsa_lock (lsa);
3395 listnode_add (rn->info, lsa);
3396 }
paul718e3742002-12-13 20:15:29 +00003397
3398 if (oi->t_ls_upd_event == NULL)
3399 oi->t_ls_upd_event =
3400 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3401}
3402
3403static void
hasso52dc7ee2004-09-23 19:18:23 +00003404ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3405 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003406{
3407 struct ospf_packet *op;
3408 u_int16_t length = OSPF_HEADER_SIZE;
3409
3410 op = ospf_packet_new (oi->ifp->mtu);
3411
3412 /* Prepare OSPF common header. */
3413 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3414
3415 /* Prepare OSPF Link State Acknowledgment body. */
3416 length += ospf_make_ls_ack (oi, ack, op->s);
3417
3418 /* Fill OSPF header. */
3419 ospf_fill_header (oi, op->s, length);
3420
3421 /* Set packet length. */
3422 op->length = length;
3423
3424 /* Set destination IP address. */
3425 op->dst = dst;
3426
3427 /* Add packet to the interface output queue. */
3428 ospf_packet_add (oi, op);
3429
3430 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003431 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003432}
3433
3434static int
3435ospf_ls_ack_send_event (struct thread *thread)
3436{
3437 struct ospf_interface *oi = THREAD_ARG (thread);
3438
3439 oi->t_ls_ack_direct = NULL;
3440
3441 while (listcount (oi->ls_ack_direct.ls_ack))
3442 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3443 oi->ls_ack_direct.dst);
3444
3445 return 0;
3446}
3447
3448void
3449ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3450{
3451 struct ospf_interface *oi = nbr->oi;
3452
3453 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3454 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3455
3456 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3457
3458 if (oi->t_ls_ack_direct == NULL)
3459 oi->t_ls_ack_direct =
3460 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3461}
3462
3463/* Send Link State Acknowledgment delayed. */
3464void
3465ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3466{
3467 struct in_addr dst;
3468
3469 /* Decide destination address. */
3470 /* RFC2328 Section 13.5 On non-broadcast
3471 networks, delayed Link State Acknowledgment packets must be
3472 unicast separately over each adjacency (i.e., neighbor whose
3473 state is >= Exchange). */
3474 if (oi->type == OSPF_IFTYPE_NBMA)
3475 {
3476 struct ospf_neighbor *nbr;
3477 struct route_node *rn;
3478
3479 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3480 if ((nbr = rn->info) != NULL)
3481 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3482 while (listcount (oi->ls_ack))
3483 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3484 return;
3485 }
3486 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3487 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3488 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3489 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3490 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3491 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003492 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3493 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003494 else
3495 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3496
3497 while (listcount (oi->ls_ack))
3498 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3499}