blob: 915273954aa6cb9818d6ca5da9a49650fe009f9b [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
Paul Jakma2518efd2006-08-27 06:49:29 +0000340 waste CPU rewriting other headers.
341
342 Note that quagga_time /deliberately/ is not used here */
paul9483e152002-12-13 20:55:25 +0000343 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000344 if (t > oi->crypt_seqnum)
345 oi->crypt_seqnum = t;
346 else
347 oi->crypt_seqnum++;
348
paul9483e152002-12-13 20:55:25 +0000349 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000350
351 /* Get MD5 Authentication key from auth_key list. */
352 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000353 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000354 else
355 {
paul1eb8ef22005-04-07 07:30:20 +0000356 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000357 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000358 }
359
360 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000361 memset(&ctx, 0, sizeof(ctx));
362 MD5Init(&ctx);
363 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
364 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
365 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000366
367 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000368 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000369
370 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000371 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
372
paul37163d62003-02-03 18:40:56 +0000373 if (stream_get_endp(op->s) != op->length)
374 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 +0000375
376 return OSPF_AUTH_MD5_SIZE;
377}
378
379
paul4dadc292005-05-06 21:37:42 +0000380static int
paul718e3742002-12-13 20:15:29 +0000381ospf_ls_req_timer (struct thread *thread)
382{
383 struct ospf_neighbor *nbr;
384
385 nbr = THREAD_ARG (thread);
386 nbr->t_ls_req = NULL;
387
388 /* Send Link State Request. */
389 if (ospf_ls_request_count (nbr))
390 ospf_ls_req_send (nbr);
391
392 /* Set Link State Request retransmission timer. */
393 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
394
395 return 0;
396}
397
398void
399ospf_ls_req_event (struct ospf_neighbor *nbr)
400{
401 if (nbr->t_ls_req)
402 {
403 thread_cancel (nbr->t_ls_req);
404 nbr->t_ls_req = NULL;
405 }
406 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
407}
408
409/* Cyclic timer function. Fist registered in ospf_nbr_new () in
410 ospf_neighbor.c */
411int
412ospf_ls_upd_timer (struct thread *thread)
413{
414 struct ospf_neighbor *nbr;
415
416 nbr = THREAD_ARG (thread);
417 nbr->t_ls_upd = NULL;
418
419 /* Send Link State Update. */
420 if (ospf_ls_retransmit_count (nbr) > 0)
421 {
hasso52dc7ee2004-09-23 19:18:23 +0000422 struct list *update;
paul718e3742002-12-13 20:15:29 +0000423 struct ospf_lsdb *lsdb;
424 int i;
paul718e3742002-12-13 20:15:29 +0000425 int retransmit_interval;
426
paul718e3742002-12-13 20:15:29 +0000427 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
428
429 lsdb = &nbr->ls_rxmt;
430 update = list_new ();
431
432 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
433 {
434 struct route_table *table = lsdb->type[i].db;
435 struct route_node *rn;
436
437 for (rn = route_top (table); rn; rn = route_next (rn))
438 {
439 struct ospf_lsa *lsa;
440
441 if ((lsa = rn->info) != NULL)
442 /* Don't retransmit an LSA if we received it within
443 the last RxmtInterval seconds - this is to allow the
444 neighbour a chance to acknowledge the LSA as it may
445 have ben just received before the retransmit timer
446 fired. This is a small tweak to what is in the RFC,
447 but it will cut out out a lot of retransmit traffic
448 - MAG */
Paul Jakma2518efd2006-08-27 06:49:29 +0000449 if (tv_cmp (tv_sub (recent_relative_time (), lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000450 int2tv (retransmit_interval)) >= 0)
451 listnode_add (update, rn->info);
452 }
453 }
454
455 if (listcount (update) > 0)
456 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
457 list_delete (update);
458 }
459
460 /* Set LS Update retransmission timer. */
461 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
462
463 return 0;
464}
465
466int
467ospf_ls_ack_timer (struct thread *thread)
468{
469 struct ospf_interface *oi;
470
471 oi = THREAD_ARG (thread);
472 oi->t_ls_ack = NULL;
473
474 /* Send Link State Acknowledgment. */
475 if (listcount (oi->ls_ack) > 0)
476 ospf_ls_ack_send_delayed (oi);
477
478 /* Set LS Ack timer. */
479 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
480
481 return 0;
482}
483
paul0bfeca32004-09-24 08:07:54 +0000484#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000485static void
paul6a99f832004-09-27 12:56:30 +0000486ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000487 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000488 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000489{
490#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000491 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000492 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000493 int ret;
paul0bfeca32004-09-24 08:07:54 +0000494
495 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000496 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000497
498 /* we can but try.
499 *
500 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
501 * well as the IP_MF flag, making this all quite pointless.
502 *
503 * However, for a system on which IP_MF is left alone, and ip_id left
504 * alone or else which sets same ip_id for each fragment this might
505 * work, eg linux.
506 *
507 * XXX-TODO: It would be much nicer to have the kernel's use their
508 * existing fragmentation support to do this for us. Bugs/RFEs need to
509 * be raised against the various kernels.
510 */
511
512 /* set More Frag */
513 iph->ip_off |= IP_MF;
514
515 /* ip frag offset is expressed in units of 8byte words */
516 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
517
paul62d8e962004-11-02 20:26:45 +0000518 iovp = &msg->msg_iov[1];
519
paul0bfeca32004-09-24 08:07:54 +0000520 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
521 > maxdatasize )
522 {
523 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000524 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
525 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000526 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000527
paul18b12c32004-10-05 14:38:29 +0000528 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000529
paul6a99f832004-09-27 12:56:30 +0000530 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000531
paul18b12c32004-10-05 14:38:29 +0000532 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000533
534 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000535 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000536 " id %d, off %d, len %d, mtu %u failed with %s",
537 inet_ntoa (iph->ip_dst),
538 iph->ip_id,
539 iph->ip_off,
540 iph->ip_len,
541 mtu,
542 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000543
paul37ccfa32004-10-31 11:24:51 +0000544 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
545 {
ajs2a42e282004-12-08 18:43:03 +0000546 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000547 iph->ip_id, iph->ip_off, iph->ip_len,
548 inet_ntoa (iph->ip_dst));
549 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
550 {
ajs2a42e282004-12-08 18:43:03 +0000551 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000552 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000553 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000554 }
555 }
556
paul0bfeca32004-09-24 08:07:54 +0000557 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000558 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000559 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000560 }
561
562 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000563 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
564 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000565 iph->ip_off &= (~IP_MF);
566}
567#endif /* WANT_OSPF_WRITE_FRAGMENT */
568
ajs5dcbdf82005-03-29 16:13:49 +0000569static int
paul718e3742002-12-13 20:15:29 +0000570ospf_write (struct thread *thread)
571{
paul68980082003-03-25 05:07:42 +0000572 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000573 struct ospf_interface *oi;
574 struct ospf_packet *op;
575 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000576 struct ip iph;
577 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000578 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000579 u_char type;
580 int ret;
581 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000582 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000583#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000584 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000585#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000586 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000587#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000588
paul68980082003-03-25 05:07:42 +0000589 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000590
paul68980082003-03-25 05:07:42 +0000591 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000592 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000593 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000594 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000595
596#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000597 /* seed ipid static with low order bits of time */
598 if (ipid == 0)
599 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000600#endif /* WANT_OSPF_WRITE_FRAGMENT */
601
paul68b73392004-09-12 14:21:37 +0000602 /* convenience - max OSPF data per packet */
603 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
604
paul718e3742002-12-13 20:15:29 +0000605 /* Get one packet from queue. */
606 op = ospf_fifo_head (oi->obuf);
607 assert (op);
608 assert (op->length >= OSPF_HEADER_SIZE);
609
paul68980082003-03-25 05:07:42 +0000610 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
611 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000612 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
613
paul718e3742002-12-13 20:15:29 +0000614 /* Rewrite the md5 signature & update the seq */
615 ospf_make_md5_digest (oi, op);
616
paul37ccfa32004-10-31 11:24:51 +0000617 /* Retrieve OSPF packet type. */
618 stream_set_getp (op->s, 1);
619 type = stream_getc (op->s);
620
paul68b73392004-09-12 14:21:37 +0000621 /* reset get pointer */
622 stream_set_getp (op->s, 0);
623
624 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000625 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000626
paul718e3742002-12-13 20:15:29 +0000627 sa_dst.sin_family = AF_INET;
628#ifdef HAVE_SIN_LEN
629 sa_dst.sin_len = sizeof(sa_dst);
630#endif /* HAVE_SIN_LEN */
631 sa_dst.sin_addr = op->dst;
632 sa_dst.sin_port = htons (0);
633
634 /* Set DONTROUTE flag if dst is unicast. */
635 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
636 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
637 flags = MSG_DONTROUTE;
638
paul68b73392004-09-12 14:21:37 +0000639 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
640 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000641 if ( sizeof (struct ip)
642 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000643 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
644
paul718e3742002-12-13 20:15:29 +0000645 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000646 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000647 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000648
paul0bfeca32004-09-24 08:07:54 +0000649#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000650 /* XXX-MT: not thread-safe at all..
651 * XXX: this presumes this is only programme sending OSPF packets
652 * otherwise, no guarantee ipid will be unique
653 */
654 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000655#endif /* WANT_OSPF_WRITE_FRAGMENT */
656
paul718e3742002-12-13 20:15:29 +0000657 iph.ip_off = 0;
658 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
659 iph.ip_ttl = OSPF_VL_IP_TTL;
660 else
661 iph.ip_ttl = OSPF_IP_TTL;
662 iph.ip_p = IPPROTO_OSPFIGP;
663 iph.ip_sum = 0;
664 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
665 iph.ip_dst.s_addr = op->dst.s_addr;
666
667 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000668 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000669 msg.msg_namelen = sizeof (sa_dst);
670 msg.msg_iov = iov;
671 msg.msg_iovlen = 2;
672 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000673 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
674 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000675 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000676
677 /* Sadly we can not rely on kernels to fragment packets because of either
678 * IP_HDRINCL and/or multicast destination being set.
679 */
paul0bfeca32004-09-24 08:07:54 +0000680#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000681 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000682 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
683 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000684#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000685
686 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000687 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000688 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000689 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000690
691 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000692 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000693 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000694 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000695 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000696
paul718e3742002-12-13 20:15:29 +0000697 /* Show debug sending packet. */
698 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
699 {
700 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
701 {
ajs2a42e282004-12-08 18:43:03 +0000702 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000703 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000704 stream_set_getp (op->s, 0);
705 ospf_packet_dump (op->s);
706 }
707
ajs2a42e282004-12-08 18:43:03 +0000708 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000709 ospf_packet_type_str[type], inet_ntoa (op->dst),
710 IF_NAME (oi));
711
712 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000713 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000714 }
715
716 /* Now delete packet from queue. */
717 ospf_packet_delete (oi);
718
719 if (ospf_fifo_head (oi->obuf) == NULL)
720 {
721 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000722 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000723 }
724
725 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000726 if (!list_isempty (ospf->oi_write_q))
727 ospf->t_write =
728 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000729
730 return 0;
731}
732
733/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000734static void
paul718e3742002-12-13 20:15:29 +0000735ospf_hello (struct ip *iph, struct ospf_header *ospfh,
736 struct stream * s, struct ospf_interface *oi, int size)
737{
738 struct ospf_hello *hello;
739 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000740 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000741 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000742
743 /* increment statistics. */
744 oi->hello_in++;
745
746 hello = (struct ospf_hello *) STREAM_PNT (s);
747
748 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000749 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000750 {
751 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
752 {
ajs2a42e282004-12-08 18:43:03 +0000753 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000754 "dropping.",
755 ospf_packet_type_str[ospfh->type],
756 inet_ntoa (iph->ip_src));
757 }
758 return;
759 }
paul718e3742002-12-13 20:15:29 +0000760
761 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000762 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000763 char buf[3][INET_ADDRSTRLEN];
paul6d452762005-11-03 11:15:44 +0000764 zlog_debug ("ignoring HELLO from router %s sent to %s, "
765 "received on a passive interface, %s",
766 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
767 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
768 inet_ntop(AF_INET, &oi->address->u.prefix4,
769 buf[2], sizeof(buf[2])));
ajsba6454e2005-02-08 15:37:30 +0000770 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
771 {
772 /* Try to fix multicast membership. */
Paul Jakma429ac782006-06-15 18:40:49 +0000773 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +0000774 ospf_if_set_multicast(oi);
775 }
paul718e3742002-12-13 20:15:29 +0000776 return;
paulf2c80652002-12-13 21:44:27 +0000777 }
paul718e3742002-12-13 20:15:29 +0000778
779 /* get neighbor prefix. */
780 p.family = AF_INET;
781 p.prefixlen = ip_masklen (hello->network_mask);
782 p.u.prefix4 = iph->ip_src;
783
784 /* Compare network mask. */
785 /* Checking is ignored for Point-to-Point and Virtual link. */
786 if (oi->type != OSPF_IFTYPE_POINTOPOINT
787 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
788 if (oi->address->prefixlen != p.prefixlen)
789 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000790 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
791 inet_ntoa(ospfh->router_id), IF_NAME(oi),
792 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000793 return;
794 }
795
paul718e3742002-12-13 20:15:29 +0000796 /* Compare Router Dead Interval. */
797 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
798 {
799 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
800 inet_ntoa (ospfh->router_id));
801 return;
802 }
803
paulf9ad9372005-10-21 00:45:17 +0000804 /* Compare Hello Interval - ignored if fast-hellos are set. */
805 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
806 {
807 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
808 {
809 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
810 inet_ntoa (ospfh->router_id));
811 return;
812 }
813 }
814
paul718e3742002-12-13 20:15:29 +0000815 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000816 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000817 inet_ntoa (ospfh->router_id),
818 ospf_options_dump (hello->options));
819
820 /* Compare options. */
821#define REJECT_IF_TBIT_ON 1 /* XXX */
822#ifdef REJECT_IF_TBIT_ON
823 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
824 {
825 /*
826 * This router does not support non-zero TOS.
827 * Drop this Hello packet not to establish neighbor relationship.
828 */
829 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
830 inet_ntoa (ospfh->router_id));
831 return;
832 }
833#endif /* REJECT_IF_TBIT_ON */
834
835#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000836 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000837 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
838 {
839 /*
840 * This router does know the correct usage of O-bit
841 * the bit should be set in DD packet only.
842 */
843 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
844 inet_ntoa (ospfh->router_id));
845#ifdef STRICT_OBIT_USAGE_CHECK
846 return; /* Reject this packet. */
847#else /* STRICT_OBIT_USAGE_CHECK */
848 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
849#endif /* STRICT_OBIT_USAGE_CHECK */
850 }
851#endif /* HAVE_OPAQUE_LSA */
852
853 /* new for NSSA is to ensure that NP is on and E is off */
854
paul718e3742002-12-13 20:15:29 +0000855 if (oi->area->external_routing == OSPF_AREA_NSSA)
856 {
857 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
858 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
859 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
860 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
861 {
862 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
863 return;
864 }
865 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000866 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000867 }
868 else
paul718e3742002-12-13 20:15:29 +0000869 /* The setting of the E-bit found in the Hello Packet's Options
870 field must match this area's ExternalRoutingCapability A
871 mismatch causes processing to stop and the packet to be
872 dropped. The setting of the rest of the bits in the Hello
873 Packet's Options field should be ignored. */
874 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
875 CHECK_FLAG (hello->options, OSPF_OPTION_E))
876 {
ajs3aa8d5f2004-12-11 18:00:06 +0000877 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
878 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000879 return;
880 }
paul718e3742002-12-13 20:15:29 +0000881
pauld3f0d622004-05-05 15:27:15 +0000882 /* get neighbour struct */
883 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
884
885 /* neighbour must be valid, ospf_nbr_get creates if none existed */
886 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000887
888 old_state = nbr->state;
889
890 /* Add event to thread. */
891 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
892
893 /* RFC2328 Section 9.5.1
894 If the router is not eligible to become Designated Router,
895 (snip) It must also send an Hello Packet in reply to an
896 Hello Packet received from any eligible neighbor (other than
897 the current Designated Router and Backup Designated Router). */
898 if (oi->type == OSPF_IFTYPE_NBMA)
899 if (PRIORITY(oi) == 0 && hello->priority > 0
900 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
901 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
902 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
903 OSPF_HELLO_REPLY_DELAY);
904
905 /* on NBMA network type, it happens to receive bidirectional Hello packet
906 without advance 1-Way Received event.
907 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
908 if (oi->type == OSPF_IFTYPE_NBMA &&
909 (old_state == NSM_Down || old_state == NSM_Attempt))
910 {
911 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
912 nbr->priority = hello->priority;
913 nbr->d_router = hello->d_router;
914 nbr->bd_router = hello->bd_router;
915 return;
916 }
917
paul68980082003-03-25 05:07:42 +0000918 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000919 size - OSPF_HELLO_MIN_SIZE))
920 {
921 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
922 nbr->options |= hello->options;
923 }
924 else
925 {
926 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
927 /* Set neighbor information. */
928 nbr->priority = hello->priority;
929 nbr->d_router = hello->d_router;
930 nbr->bd_router = hello->bd_router;
931 return;
932 }
933
934 /* If neighbor itself declares DR and no BDR exists,
935 cause event BackupSeen */
936 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
937 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
938 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
939
940 /* neighbor itself declares BDR. */
941 if (oi->state == ISM_Waiting &&
942 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
943 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
944
945 /* had not previously. */
946 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
947 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
948 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
949 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
950 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
951
952 /* had not previously. */
953 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
954 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
955 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
956 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
957 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
958
959 /* Neighbor priority check. */
960 if (nbr->priority >= 0 && nbr->priority != hello->priority)
961 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
962
963 /* Set neighbor information. */
964 nbr->priority = hello->priority;
965 nbr->d_router = hello->d_router;
966 nbr->bd_router = hello->bd_router;
967}
968
969/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000970static void
paul718e3742002-12-13 20:15:29 +0000971ospf_db_desc_save_current (struct ospf_neighbor *nbr,
972 struct ospf_db_desc *dd)
973{
974 nbr->last_recv.flags = dd->flags;
975 nbr->last_recv.options = dd->options;
976 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
977}
978
979/* Process rest of DD packet. */
980static void
981ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
982 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
983 u_int16_t size)
984{
985 struct ospf_lsa *new, *find;
986 struct lsa_header *lsah;
987
paul9985f832005-02-09 15:51:56 +0000988 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000989 for (size -= OSPF_DB_DESC_MIN_SIZE;
990 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
991 {
992 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000993 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000994
995 /* Unknown LS type. */
996 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
997 {
ajsbec595a2004-11-30 22:38:43 +0000998 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000999 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1000 return;
1001 }
1002
1003#ifdef HAVE_OPAQUE_LSA
1004 if (IS_OPAQUE_LSA (lsah->type)
1005 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1006 {
1007 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1008 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1009 return;
1010 }
1011#endif /* HAVE_OPAQUE_LSA */
1012
1013 switch (lsah->type)
1014 {
1015 case OSPF_AS_EXTERNAL_LSA:
1016#ifdef HAVE_OPAQUE_LSA
1017 case OSPF_OPAQUE_AS_LSA:
1018#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001019 /* Check for stub area. Reject if AS-External from stub but
1020 allow if from NSSA. */
1021 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001022 {
1023 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1024 lsah->type, inet_ntoa (lsah->id),
1025 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1026 "STUB" : "NSSA");
1027 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1028 return;
1029 }
1030 break;
1031 default:
1032 break;
1033 }
1034
1035 /* Create LS-request object. */
1036 new = ospf_ls_request_new (lsah);
1037
1038 /* Lookup received LSA, then add LS request list. */
1039 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001040
1041 /* ospf_lsa_more_recent is fine with NULL pointers */
1042 switch (ospf_lsa_more_recent (find, new))
1043 {
1044 case -1:
1045 /* Neighbour has a more recent LSA, we must request it */
1046 ospf_ls_request_add (nbr, new);
1047 case 0:
1048 /* If we have a copy of this LSA, it's either less recent
1049 * and we're requesting it from neighbour (the case above), or
1050 * it's as recent and we both have same copy (this case).
1051 *
1052 * In neither of these two cases is there any point in
1053 * describing our copy of the LSA to the neighbour in a
1054 * DB-Summary packet, if we're still intending to do so.
1055 *
1056 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1057 * backward compatible optimisation to OSPF DB Exchange /
1058 * DB Description process implemented here.
1059 */
1060 if (find)
1061 ospf_lsdb_delete (&nbr->db_sum, find);
1062 ospf_lsa_discard (new);
1063 break;
1064 default:
1065 /* We have the more recent copy, nothing specific to do:
1066 * - no need to request neighbours stale copy
1067 * - must leave DB summary list copy alone
1068 */
1069 if (IS_DEBUG_OSPF_EVENT)
1070 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1071 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1072 ospf_lsa_discard (new);
1073 }
paul718e3742002-12-13 20:15:29 +00001074 }
1075
1076 /* Master */
1077 if (IS_SET_DD_MS (nbr->dd_flags))
1078 {
1079 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001080
1081 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001082 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1083 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1084 else
paul718e3742002-12-13 20:15:29 +00001085 ospf_db_desc_send (nbr);
1086 }
1087 /* Slave */
1088 else
1089 {
1090 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1091
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001092 /* Send DD packet in reply.
1093 *
1094 * Must be done to acknowledge the Master's DD, regardless of
1095 * whether we have more LSAs ourselves to describe.
1096 *
1097 * This function will clear the 'More' bit, if after this DD
1098 * we have no more LSAs to describe to the master..
1099 */
paul718e3742002-12-13 20:15:29 +00001100 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001101
1102 /* Slave can raise ExchangeDone now, if master is also done */
1103 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1104 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001105 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001106
paul718e3742002-12-13 20:15:29 +00001107 /* Save received neighbor values from DD. */
1108 ospf_db_desc_save_current (nbr, dd);
1109}
1110
paul4dadc292005-05-06 21:37:42 +00001111static int
paul718e3742002-12-13 20:15:29 +00001112ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1113{
1114 /* Is DD duplicated? */
1115 if (dd->options == nbr->last_recv.options &&
1116 dd->flags == nbr->last_recv.flags &&
1117 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1118 return 1;
1119
1120 return 0;
1121}
1122
1123/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001124static void
paul718e3742002-12-13 20:15:29 +00001125ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1126 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1127{
1128 struct ospf_db_desc *dd;
1129 struct ospf_neighbor *nbr;
1130
1131 /* Increment statistics. */
1132 oi->db_desc_in++;
1133
1134 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001135
pauld3f0d622004-05-05 15:27:15 +00001136 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001137 if (nbr == NULL)
1138 {
1139 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1140 inet_ntoa (ospfh->router_id));
1141 return;
1142 }
1143
1144 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001145 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1146 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001147 {
ajs3aa8d5f2004-12-11 18:00:06 +00001148 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1149 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1150 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001151 return;
1152 }
1153
pauld363df22003-06-19 00:26:34 +00001154 /*
1155 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1156 * required. In fact at least JunOS sends DD packets with P bit clear.
1157 * Until proper solution is developped, this hack should help.
1158 *
1159 * Update: According to the RFCs, N bit is specified /only/ for Hello
1160 * options, unfortunately its use in DD options is not specified. Hence some
1161 * implementations follow E-bit semantics and set it in DD options, and some
1162 * treat it as unspecified and hence follow the directive "default for
1163 * options is clear", ie unset.
1164 *
1165 * Reset the flag, as ospfd follows E-bit semantics.
1166 */
1167 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1168 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1169 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1170 {
1171 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001172 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001173 inet_ntoa (nbr->router_id) );
1174 SET_FLAG (dd->options, OSPF_OPTION_NP);
1175 }
pauld363df22003-06-19 00:26:34 +00001176
paul718e3742002-12-13 20:15:29 +00001177#ifdef REJECT_IF_TBIT_ON
1178 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1179 {
1180 /*
1181 * In Hello protocol, optional capability must have checked
1182 * to prevent this T-bit enabled router be my neighbor.
1183 */
1184 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1185 return;
1186 }
1187#endif /* REJECT_IF_TBIT_ON */
1188
1189#ifdef HAVE_OPAQUE_LSA
1190 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001191 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001192 {
1193 /*
1194 * This node is not configured to handle O-bit, for now.
1195 * Clear it to ignore unsupported capability proposed by neighbor.
1196 */
1197 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1198 }
1199#endif /* HAVE_OPAQUE_LSA */
1200
1201 /* Process DD packet by neighbor status. */
1202 switch (nbr->state)
1203 {
1204 case NSM_Down:
1205 case NSM_Attempt:
1206 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001207 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001208 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001209 LOOKUP (ospf_nsm_state_msg, nbr->state));
1210 break;
1211 case NSM_Init:
1212 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1213 /* If the new state is ExStart, the processing of the current
1214 packet should then continue in this new state by falling
1215 through to case ExStart below. */
1216 if (nbr->state != NSM_ExStart)
1217 break;
1218 case NSM_ExStart:
1219 /* Initial DBD */
1220 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1221 (size == OSPF_DB_DESC_MIN_SIZE))
1222 {
paul68980082003-03-25 05:07:42 +00001223 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001224 {
1225 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001226 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001227 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001228 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001229
1230 /* Reset I/MS */
1231 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001232 }
1233 else
1234 {
1235 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001236 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001237 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001238 break;
1239 }
1240 }
1241 /* Ack from the Slave */
1242 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1243 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001244 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001245 {
ajs17eaa722004-12-29 21:04:48 +00001246 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001247 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001248 /* Reset I, leaving MS */
1249 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001250 }
1251 else
1252 {
ajs3aa8d5f2004-12-11 18:00:06 +00001253 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1254 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001255 break;
1256 }
1257
1258 /* This is where the real Options are saved */
1259 nbr->options = dd->options;
1260
1261#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001262 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001263 {
1264 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001265 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001266 inet_ntoa (nbr->router_id),
1267 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1268
1269 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1270 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1271 {
paul6d452762005-11-03 11:15:44 +00001272 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1273 "Opaque-LSAs cannot be reliably advertised "
1274 "in this network.",
1275 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001276 /* This situation is undesirable, but not a real error. */
1277 }
1278 }
1279#endif /* HAVE_OPAQUE_LSA */
1280
1281 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1282
1283 /* continue processing rest of packet. */
1284 ospf_db_desc_proc (s, oi, nbr, dd, size);
1285 break;
1286 case NSM_Exchange:
1287 if (ospf_db_desc_is_dup (dd, nbr))
1288 {
1289 if (IS_SET_DD_MS (nbr->dd_flags))
1290 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001291 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001292 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001293 else
1294 /* Slave: cause to retransmit the last Database Description. */
1295 {
paul6d452762005-11-03 11:15:44 +00001296 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001297 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001298 ospf_db_desc_resend (nbr);
1299 }
1300 break;
1301 }
1302
1303 /* Otherwise DD packet should be checked. */
1304 /* Check Master/Slave bit mismatch */
1305 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1306 {
ajs3aa8d5f2004-12-11 18:00:06 +00001307 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1308 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001309 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1310 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001311 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001312 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001313 break;
1314 }
1315
1316 /* Check initialize bit is set. */
1317 if (IS_SET_DD_I (dd->flags))
1318 {
paul6d452762005-11-03 11:15:44 +00001319 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001320 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001321 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1322 break;
1323 }
1324
1325 /* Check DD Options. */
1326 if (dd->options != nbr->options)
1327 {
1328#ifdef ORIGINAL_CODING
1329 /* Save the new options for debugging */
1330 nbr->options = dd->options;
1331#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001332 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1333 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001334 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1335 break;
1336 }
1337
1338 /* Check DD sequence number. */
1339 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1340 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1341 (!IS_SET_DD_MS (nbr->dd_flags) &&
1342 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1343 {
ajs3aa8d5f2004-12-11 18:00:06 +00001344 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1345 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001346 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1347 break;
1348 }
1349
1350 /* Continue processing rest of packet. */
1351 ospf_db_desc_proc (s, oi, nbr, dd, size);
1352 break;
1353 case NSM_Loading:
1354 case NSM_Full:
1355 if (ospf_db_desc_is_dup (dd, nbr))
1356 {
1357 if (IS_SET_DD_MS (nbr->dd_flags))
1358 {
1359 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001360 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1361 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001362 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001363 break;
1364 }
1365 else
1366 {
1367 struct timeval t, now;
Paul Jakma2518efd2006-08-27 06:49:29 +00001368 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001369 t = tv_sub (now, nbr->last_send_ts);
1370 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1371 {
1372 /* In states Loading and Full the slave must resend
1373 its last Database Description packet in response to
1374 duplicate Database Description packets received
1375 from the master. For this reason the slave must
1376 wait RouterDeadInterval seconds before freeing the
1377 last Database Description packet. Reception of a
1378 Database Description packet from the master after
1379 this interval will generate a SeqNumberMismatch
1380 neighbor event. RFC2328 Section 10.8 */
1381 ospf_db_desc_resend (nbr);
1382 break;
1383 }
1384 }
1385 }
1386
1387 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1388 break;
1389 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001390 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1391 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001392 break;
1393 }
1394}
1395
1396#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1397
1398/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001399static void
paul718e3742002-12-13 20:15:29 +00001400ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1401 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1402{
1403 struct ospf_neighbor *nbr;
1404 u_int32_t ls_type;
1405 struct in_addr ls_id;
1406 struct in_addr adv_router;
1407 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001408 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001409 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001410
1411 /* Increment statistics. */
1412 oi->ls_req_in++;
1413
pauld3f0d622004-05-05 15:27:15 +00001414 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001415 if (nbr == NULL)
1416 {
1417 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1418 inet_ntoa (ospfh->router_id));
1419 return;
1420 }
1421
1422 /* Neighbor State should be Exchange or later. */
1423 if (nbr->state != NSM_Exchange &&
1424 nbr->state != NSM_Loading &&
1425 nbr->state != NSM_Full)
1426 {
ajsbec595a2004-11-30 22:38:43 +00001427 zlog_warn ("Link State Request received from %s: "
1428 "Neighbor state is %s, packet discarded.",
1429 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001430 LOOKUP (ospf_nsm_state_msg, nbr->state));
1431 return;
1432 }
1433
1434 /* Send Link State Update for ALL requested LSAs. */
1435 ls_upd = list_new ();
1436 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1437
1438 while (size >= OSPF_LSA_KEY_SIZE)
1439 {
1440 /* Get one slice of Link State Request. */
1441 ls_type = stream_getl (s);
1442 ls_id.s_addr = stream_get_ipv4 (s);
1443 adv_router.s_addr = stream_get_ipv4 (s);
1444
1445 /* Verify LSA type. */
1446 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1447 {
1448 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1449 list_delete (ls_upd);
1450 return;
1451 }
1452
1453 /* Search proper LSA in LSDB. */
1454 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1455 if (find == NULL)
1456 {
1457 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1458 list_delete (ls_upd);
1459 return;
1460 }
1461
gdt86f1fd92005-01-10 14:20:43 +00001462 /* Packet overflows MTU size, send immediately. */
1463 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001464 {
1465 if (oi->type == OSPF_IFTYPE_NBMA)
1466 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1467 else
1468 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1469
1470 /* Only remove list contents. Keep ls_upd. */
1471 list_delete_all_node (ls_upd);
1472
1473 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1474 }
1475
1476 /* Append LSA to update list. */
1477 listnode_add (ls_upd, find);
1478 length += ntohs (find->data->length);
1479
1480 size -= OSPF_LSA_KEY_SIZE;
1481 }
1482
1483 /* Send rest of Link State Update. */
1484 if (listcount (ls_upd) > 0)
1485 {
1486 if (oi->type == OSPF_IFTYPE_NBMA)
1487 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1488 else
1489 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1490
1491 list_delete (ls_upd);
1492 }
1493 else
1494 list_free (ls_upd);
1495}
1496
1497/* Get the list of LSAs from Link State Update packet.
1498 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001499static struct list *
paul718e3742002-12-13 20:15:29 +00001500ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1501 struct ospf_interface *oi, size_t size)
1502{
1503 u_int16_t count, sum;
1504 u_int32_t length;
1505 struct lsa_header *lsah;
1506 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001507 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001508
1509 lsas = list_new ();
1510
1511 count = stream_getl (s);
1512 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1513
1514 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001515 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001516 {
1517 lsah = (struct lsa_header *) STREAM_PNT (s);
1518 length = ntohs (lsah->length);
1519
1520 if (length > size)
1521 {
1522 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1523 break;
1524 }
1525
1526 /* Validate the LSA's LS checksum. */
1527 sum = lsah->checksum;
1528 if (sum != ospf_lsa_checksum (lsah))
1529 {
1530 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1531 sum, lsah->checksum);
1532 continue;
1533 }
1534
1535 /* Examine the LSA's LS type. */
1536 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1537 {
1538 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1539 continue;
1540 }
1541
1542 /*
1543 * What if the received LSA's age is greater than MaxAge?
1544 * Treat it as a MaxAge case -- endo.
1545 */
1546 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1547 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1548
1549#ifdef HAVE_OPAQUE_LSA
1550 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1551 {
1552#ifdef STRICT_OBIT_USAGE_CHECK
1553 if ((IS_OPAQUE_LSA(lsah->type) &&
1554 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1555 || (! IS_OPAQUE_LSA(lsah->type) &&
1556 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1557 {
1558 /*
1559 * This neighbor must know the exact usage of O-bit;
1560 * the bit will be set in Type-9,10,11 LSAs only.
1561 */
1562 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1563 continue;
1564 }
1565#endif /* STRICT_OBIT_USAGE_CHECK */
1566
1567 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1568 if (lsah->type == OSPF_OPAQUE_AS_LSA
1569 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1570 {
1571 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001572 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 +00001573 continue;
1574 }
1575 }
1576 else if (IS_OPAQUE_LSA(lsah->type))
1577 {
1578 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1579 continue;
1580 }
1581#endif /* HAVE_OPAQUE_LSA */
1582
1583 /* Create OSPF LSA instance. */
1584 lsa = ospf_lsa_new ();
1585
1586 /* We may wish to put some error checking if type NSSA comes in
1587 and area not in NSSA mode */
1588 switch (lsah->type)
1589 {
1590 case OSPF_AS_EXTERNAL_LSA:
1591#ifdef HAVE_OPAQUE_LSA
1592 case OSPF_OPAQUE_AS_LSA:
1593 lsa->area = NULL;
1594 break;
1595 case OSPF_OPAQUE_LINK_LSA:
1596 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1597 /* Fallthrough */
1598#endif /* HAVE_OPAQUE_LSA */
1599 default:
1600 lsa->area = oi->area;
1601 break;
1602 }
1603
1604 lsa->data = ospf_lsa_data_new (length);
1605 memcpy (lsa->data, lsah, length);
1606
1607 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001608 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001609 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1610 listnode_add (lsas, lsa);
1611 }
1612
1613 return lsas;
1614}
1615
1616/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001617static void
hasso52dc7ee2004-09-23 19:18:23 +00001618ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001619{
paul1eb8ef22005-04-07 07:30:20 +00001620 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001621 struct ospf_lsa *lsa;
1622
paul1eb8ef22005-04-07 07:30:20 +00001623 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1624 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001625
1626 list_delete (lsas);
1627}
1628
1629/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001630static void
paul718e3742002-12-13 20:15:29 +00001631ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1632 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1633{
1634 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001635 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001636 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001637 struct ospf_lsa *lsa = NULL;
1638 /* unsigned long ls_req_found = 0; */
1639
1640 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1641
1642 /* Increment statistics. */
1643 oi->ls_upd_in++;
1644
1645 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001646 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001647 if (nbr == NULL)
1648 {
1649 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1650 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1651 return;
1652 }
1653
1654 /* Check neighbor state. */
1655 if (nbr->state < NSM_Exchange)
1656 {
ajs3aa8d5f2004-12-11 18:00:06 +00001657 zlog_warn ("Link State Update: "
1658 "Neighbor[%s] state %s is less than Exchange",
1659 inet_ntoa (ospfh->router_id),
1660 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001661 return;
1662 }
1663
1664 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1665 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1666 * of section 13.
1667 */
1668 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1669
1670#ifdef HAVE_OPAQUE_LSA
1671 /*
paul718e3742002-12-13 20:15:29 +00001672 * If self-originated Opaque-LSAs that have flooded before restart
1673 * are contained in the received LSUpd message, corresponding LSReq
1674 * messages to be sent may have to be modified.
1675 * To eliminate possible race conditions such that flushing and normal
1676 * updating for the same LSA would take place alternately, this trick
1677 * must be done before entering to the loop below.
1678 */
paul69310a62005-05-11 18:09:59 +00001679 /* XXX: Why is this Opaque specific? Either our core code is deficient
1680 * and this should be fixed generally, or Opaque is inventing strawman
1681 * problems */
paul718e3742002-12-13 20:15:29 +00001682 ospf_opaque_adjust_lsreq (nbr, lsas);
1683#endif /* HAVE_OPAQUE_LSA */
1684
1685#define DISCARD_LSA(L,N) {\
1686 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001687 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 +00001688 ospf_lsa_discard (L); \
1689 continue; }
1690
1691 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001692 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001693 {
1694 struct ospf_lsa *ls_ret, *current;
1695 int ret = 1;
1696
paul718e3742002-12-13 20:15:29 +00001697 if (IS_DEBUG_OSPF_NSSA)
1698 {
1699 char buf1[INET_ADDRSTRLEN];
1700 char buf2[INET_ADDRSTRLEN];
1701 char buf3[INET_ADDRSTRLEN];
1702
ajs2a42e282004-12-08 18:43:03 +00001703 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001704 lsa->data->type,
1705 inet_ntop (AF_INET, &ospfh->router_id,
1706 buf1, INET_ADDRSTRLEN),
1707 inet_ntop (AF_INET, &lsa->data->id,
1708 buf2, INET_ADDRSTRLEN),
1709 inet_ntop (AF_INET, &lsa->data->adv_router,
1710 buf3, INET_ADDRSTRLEN));
1711 }
paul718e3742002-12-13 20:15:29 +00001712
1713 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1714
1715 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1716
1717 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1718
1719 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1720
1721 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1722
1723 /* Do take in Type-7's if we are an NSSA */
1724
1725 /* If we are also an ABR, later translate them to a Type-5 packet */
1726
1727 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1728 translate them to a separate Type-5 packet. */
1729
1730 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1731 /* Reject from STUB or NSSA */
1732 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1733 {
1734 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001735 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001736 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001737 }
1738
paul718e3742002-12-13 20:15:29 +00001739 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1740 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1741 {
1742 DISCARD_LSA (lsa,2);
1743 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001744 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001745 }
paul718e3742002-12-13 20:15:29 +00001746
1747 /* Find the LSA in the current database. */
1748
1749 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1750
1751 /* If the LSA's LS age is equal to MaxAge, and there is currently
1752 no instance of the LSA in the router's link state database,
1753 and none of router's neighbors are in states Exchange or Loading,
1754 then take the following actions. */
1755
1756 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001757 (ospf_nbr_count (oi, NSM_Exchange) +
1758 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001759 {
1760 /* Response Link State Acknowledgment. */
1761 ospf_ls_ack_send (nbr, lsa);
1762
1763 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001764 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1765 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001766 DISCARD_LSA (lsa, 3);
1767 }
1768
1769#ifdef HAVE_OPAQUE_LSA
1770 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001771 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001772 {
1773 /*
1774 * Even if initial flushing seems to be completed, there might
1775 * be a case that self-originated LSA with MaxAge still remain
1776 * in the routing domain.
1777 * Just send an LSAck message to cease retransmission.
1778 */
1779 if (IS_LSA_MAXAGE (lsa))
1780 {
1781 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1782 ospf_ls_ack_send (nbr, lsa);
1783 ospf_lsa_discard (lsa);
1784
1785 if (current != NULL && ! IS_LSA_MAXAGE (current))
1786 ospf_opaque_lsa_refresh_schedule (current);
1787 continue;
1788 }
1789
1790 /*
1791 * If an instance of self-originated Opaque-LSA is not found
1792 * in the LSDB, there are some possible cases here.
1793 *
1794 * 1) This node lost opaque-capability after restart.
1795 * 2) Else, a part of opaque-type is no more supported.
1796 * 3) Else, a part of opaque-id is no more supported.
1797 *
1798 * Anyway, it is still this node's responsibility to flush it.
1799 * Otherwise, the LSA instance remains in the routing domain
1800 * until its age reaches to MaxAge.
1801 */
paul69310a62005-05-11 18:09:59 +00001802 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001803 if (current == NULL)
1804 {
1805 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001806 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1807 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001808
1809 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001810
1811 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1812 ospf_ls_ack_send (nbr, lsa);
1813
paul718e3742002-12-13 20:15:29 +00001814 continue;
1815 }
1816 }
1817#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001818
hassocb05eb22004-02-11 21:10:19 +00001819 /* It might be happen that received LSA is self-originated network LSA, but
1820 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1821 * Link State ID is one of the router's own IP interface addresses but whose
1822 * Advertising Router is not equal to the router's own Router ID
1823 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1824 */
1825
1826 if(lsa->data->type == OSPF_NETWORK_LSA)
1827 {
paul1eb8ef22005-04-07 07:30:20 +00001828 struct listnode *oinode, *oinnode;
1829 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001830 int Flag = 0;
1831
paul1eb8ef22005-04-07 07:30:20 +00001832 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001833 {
hassocb05eb22004-02-11 21:10:19 +00001834 if(out_if == NULL)
1835 break;
1836
1837 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1838 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1839 {
1840 if(out_if->network_lsa_self)
1841 {
1842 ospf_lsa_flush_area(lsa,out_if->area);
1843 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001844 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001845 lsa, (int) lsa->data->type);
1846 ospf_lsa_discard (lsa);
1847 Flag = 1;
1848 }
1849 break;
1850 }
1851 }
1852 if(Flag)
1853 continue;
1854 }
paul718e3742002-12-13 20:15:29 +00001855
1856 /* (5) Find the instance of this LSA that is currently contained
1857 in the router's link state database. If there is no
1858 database copy, or the received LSA is more recent than
1859 the database copy the following steps must be performed. */
1860
1861 if (current == NULL ||
1862 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1863 {
1864 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001865 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001866 DISCARD_LSA (lsa, 4);
1867 continue;
1868 }
1869
1870 /* (6) Else, If there is an instance of the LSA on the sending
1871 neighbor's Link state request list, an error has occurred in
1872 the Database Exchange process. In this case, restart the
1873 Database Exchange process by generating the neighbor event
1874 BadLSReq for the sending neighbor and stop processing the
1875 Link State Update packet. */
1876
1877 if (ospf_ls_request_lookup (nbr, lsa))
1878 {
1879 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001880 zlog_warn("LSA[%s] instance exists on Link state request list",
1881 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001882
1883 /* Clean list of LSAs. */
1884 ospf_upd_list_clean (lsas);
1885 /* this lsa is not on lsas list already. */
1886 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001887 return;
1888 }
1889
1890 /* If the received LSA is the same instance as the database copy
1891 (i.e., neither one is more recent) the following two steps
1892 should be performed: */
1893
1894 if (ret == 0)
1895 {
1896 /* If the LSA is listed in the Link state retransmission list
1897 for the receiving adjacency, the router itself is expecting
1898 an acknowledgment for this LSA. The router should treat the
1899 received LSA as an acknowledgment by removing the LSA from
1900 the Link state retransmission list. This is termed an
1901 "implied acknowledgment". */
1902
1903 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1904
1905 if (ls_ret != NULL)
1906 {
1907 ospf_ls_retransmit_delete (nbr, ls_ret);
1908
1909 /* Delayed acknowledgment sent if advertisement received
1910 from Designated Router, otherwise do nothing. */
1911 if (oi->state == ISM_Backup)
1912 if (NBR_IS_DR (nbr))
1913 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1914
1915 DISCARD_LSA (lsa, 5);
1916 }
1917 else
1918 /* Acknowledge the receipt of the LSA by sending a
1919 Link State Acknowledgment packet back out the receiving
1920 interface. */
1921 {
1922 ospf_ls_ack_send (nbr, lsa);
1923 DISCARD_LSA (lsa, 6);
1924 }
1925 }
1926
1927 /* The database copy is more recent. If the database copy
1928 has LS age equal to MaxAge and LS sequence number equal to
1929 MaxSequenceNumber, simply discard the received LSA without
1930 acknowledging it. (In this case, the LSA's LS sequence number is
1931 wrapping, and the MaxSequenceNumber LSA must be completely
1932 flushed before any new LSA instance can be introduced). */
1933
1934 else if (ret > 0) /* Database copy is more recent */
1935 {
1936 if (IS_LSA_MAXAGE (current) &&
1937 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1938 {
1939 DISCARD_LSA (lsa, 7);
1940 }
1941 /* Otherwise, as long as the database copy has not been sent in a
1942 Link State Update within the last MinLSArrival seconds, send the
1943 database copy back to the sending neighbor, encapsulated within
1944 a Link State Update Packet. The Link State Update Packet should
1945 be sent directly to the neighbor. In so doing, do not put the
1946 database copy of the LSA on the neighbor's link state
1947 retransmission list, and do not acknowledge the received (less
1948 recent) LSA instance. */
1949 else
1950 {
1951 struct timeval now;
1952
Paul Jakma2518efd2006-08-27 06:49:29 +00001953 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +00001954
1955 if (tv_cmp (tv_sub (now, current->tv_orig),
1956 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1957 /* Trap NSSA type later.*/
1958 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1959 DISCARD_LSA (lsa, 8);
1960 }
1961 }
1962 }
1963
paul718e3742002-12-13 20:15:29 +00001964 assert (listcount (lsas) == 0);
1965 list_delete (lsas);
1966}
1967
1968/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001969static void
paul718e3742002-12-13 20:15:29 +00001970ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1971 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1972{
1973 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001974
paul718e3742002-12-13 20:15:29 +00001975 /* increment statistics. */
1976 oi->ls_ack_in++;
1977
pauld3f0d622004-05-05 15:27:15 +00001978 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001979 if (nbr == NULL)
1980 {
1981 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1982 inet_ntoa (ospfh->router_id));
1983 return;
1984 }
1985
1986 if (nbr->state < NSM_Exchange)
1987 {
ajs3aa8d5f2004-12-11 18:00:06 +00001988 zlog_warn ("Link State Acknowledgment: "
1989 "Neighbor[%s] state %s is less than Exchange",
1990 inet_ntoa (ospfh->router_id),
1991 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001992 return;
1993 }
paul69310a62005-05-11 18:09:59 +00001994
paul718e3742002-12-13 20:15:29 +00001995 while (size >= OSPF_LSA_HEADER_SIZE)
1996 {
1997 struct ospf_lsa *lsa, *lsr;
1998
1999 lsa = ospf_lsa_new ();
2000 lsa->data = (struct lsa_header *) STREAM_PNT (s);
2001
2002 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2003 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002004 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002005
2006 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2007 {
2008 lsa->data = NULL;
2009 ospf_lsa_discard (lsa);
2010 continue;
2011 }
2012
2013 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2014
2015 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2016 {
2017#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002018 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002019 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002020#endif /* HAVE_OPAQUE_LSA */
2021
2022 ospf_ls_retransmit_delete (nbr, lsr);
2023 }
2024
2025 lsa->data = NULL;
2026 ospf_lsa_discard (lsa);
2027 }
2028
paul718e3742002-12-13 20:15:29 +00002029 return;
paul718e3742002-12-13 20:15:29 +00002030}
2031
ajs038163f2005-02-17 19:55:59 +00002032static struct stream *
ajs5c333492005-02-23 15:43:01 +00002033ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002034{
2035 int ret;
ajs5c333492005-02-23 15:43:01 +00002036 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002037 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002038 unsigned int ifindex = 0;
2039 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002040 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002041 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002042 struct msghdr msgh;
2043
paul68defd62004-09-27 07:27:13 +00002044 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002045 msgh.msg_iov = &iov;
2046 msgh.msg_iovlen = 1;
2047 msgh.msg_control = (caddr_t) buff;
2048 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002049
ajs5c333492005-02-23 15:43:01 +00002050 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2051 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002052 {
ajs5c333492005-02-23 15:43:01 +00002053 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2054 return NULL;
2055 }
paul69310a62005-05-11 18:09:59 +00002056 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002057 {
2058 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2059 "(ip header size is %u)",
2060 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002061 return NULL;
2062 }
paul18b12c32004-10-05 14:38:29 +00002063
ajs5c333492005-02-23 15:43:01 +00002064 /* Note that there should not be alignment problems with this assignment
2065 because this is at the beginning of the stream data buffer. */
2066 iph = (struct ip *) STREAM_DATA(ibuf);
2067 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002068
ajs5c333492005-02-23 15:43:01 +00002069 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002070
paul239aecc2003-12-08 10:34:54 +00002071#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002072 /*
2073 * Kernel network code touches incoming IP header parameters,
2074 * before protocol specific processing.
2075 *
2076 * 1) Convert byteorder to host representation.
2077 * --> ip_len, ip_id, ip_off
2078 *
2079 * 2) Adjust ip_len to strip IP header size!
2080 * --> If user process receives entire IP packet via RAW
2081 * socket, it must consider adding IP header size to
2082 * the "ip_len" field of "ip" structure.
2083 *
2084 * For more details, see <netinet/ip_input.c>.
2085 */
ajs5c333492005-02-23 15:43:01 +00002086 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002087#endif
2088
paul863082d2004-08-19 04:43:43 +00002089 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002090
2091 *ifp = if_lookup_by_index (ifindex);
2092
2093 if (ret != ip_len)
2094 {
ajs5c333492005-02-23 15:43:01 +00002095 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2096 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002097 return NULL;
2098 }
2099
2100 return ibuf;
2101}
2102
paul4dadc292005-05-06 21:37:42 +00002103static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002104ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002105 struct ip *iph, struct ospf_header *ospfh)
2106{
2107 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002108 struct ospf_vl_data *vl_data;
2109 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002110 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002111
2112 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2113 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002114 return NULL;
paul718e3742002-12-13 20:15:29 +00002115
pauld3f0d622004-05-05 15:27:15 +00002116 /* look for local OSPF interface matching the destination
2117 * to determine Area ID. We presume therefore the destination address
2118 * is unique, or at least (for "unnumbered" links), not used in other
2119 * areas
2120 */
2121 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2122 iph->ip_dst)) == NULL)
2123 return NULL;
paul718e3742002-12-13 20:15:29 +00002124
paul1eb8ef22005-04-07 07:30:20 +00002125 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002126 {
paul020709f2003-04-04 02:44:16 +00002127 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002128 if (!vl_area)
2129 continue;
2130
2131 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2132 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2133 {
2134 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002135 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002136 IF_NAME (vl_data->vl_oi));
2137 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2138 {
2139 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002140 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002141 return NULL;
2142 }
2143
2144 return vl_data->vl_oi;
2145 }
2146 }
2147
2148 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002149 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002150
pauld3f0d622004-05-05 15:27:15 +00002151 return NULL;
paul718e3742002-12-13 20:15:29 +00002152}
2153
paul4dadc292005-05-06 21:37:42 +00002154static inline int
paul718e3742002-12-13 20:15:29 +00002155ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2156{
2157 /* Check match the Area ID of the receiving interface. */
2158 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2159 return 1;
2160
2161 return 0;
2162}
2163
2164/* Unbound socket will accept any Raw IP packets if proto is matched.
2165 To prevent it, compare src IP address and i/f address with masking
2166 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002167static int
paul718e3742002-12-13 20:15:29 +00002168ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2169{
2170 struct in_addr mask, me, him;
2171
2172 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2173 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2174 return 1;
2175
2176 masklen2ip (oi->address->prefixlen, &mask);
2177
2178 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2179 him.s_addr = ip_src.s_addr & mask.s_addr;
2180
2181 if (IPV4_ADDR_SAME (&me, &him))
2182 return 1;
2183
2184 return 0;
2185}
2186
paul4dadc292005-05-06 21:37:42 +00002187static int
paul718e3742002-12-13 20:15:29 +00002188ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2189 struct ospf_header *ospfh)
2190{
2191 int ret = 0;
2192 struct crypt_key *ck;
2193
2194 switch (ntohs (ospfh->auth_type))
2195 {
2196 case OSPF_AUTH_NULL:
2197 ret = 1;
2198 break;
2199 case OSPF_AUTH_SIMPLE:
2200 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2201 ret = 1;
2202 else
2203 ret = 0;
2204 break;
2205 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002206 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002207 {
2208 ret = 0;
2209 break;
2210 }
2211
2212 /* This is very basic, the digest processing is elsewhere */
2213 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2214 ospfh->u.crypt.key_id == ck->key_id &&
2215 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2216 ret = 1;
2217 else
2218 ret = 0;
2219 break;
2220 default:
2221 ret = 0;
2222 break;
2223 }
2224
2225 return ret;
2226}
2227
paul4dadc292005-05-06 21:37:42 +00002228static int
paul718e3742002-12-13 20:15:29 +00002229ospf_check_sum (struct ospf_header *ospfh)
2230{
2231 u_int32_t ret;
2232 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002233
2234 /* clear auth_data for checksum. */
2235 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2236
2237 /* keep checksum and clear. */
2238 sum = ospfh->checksum;
2239 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2240
2241 /* calculate checksum. */
2242 ret = in_cksum (ospfh, ntohs (ospfh->length));
2243
2244 if (ret != sum)
2245 {
2246 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2247 ret, sum);
2248 return 0;
2249 }
2250
2251 return 1;
2252}
2253
2254/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002255static int
paul718e3742002-12-13 20:15:29 +00002256ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2257 struct ip *iph, struct ospf_header *ospfh)
2258{
2259 /* check version. */
2260 if (ospfh->version != OSPF_VERSION)
2261 {
2262 zlog_warn ("interface %s: ospf_read version number mismatch.",
2263 IF_NAME (oi));
2264 return -1;
2265 }
2266
2267 /* Check Area ID. */
2268 if (!ospf_check_area_id (oi, ospfh))
2269 {
2270 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2271 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2272 return -1;
2273 }
2274
2275 /* Check network mask, Silently discarded. */
2276 if (! ospf_check_network_mask (oi, iph->ip_src))
2277 {
2278 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2279 IF_NAME (oi), inet_ntoa (iph->ip_src));
2280 return -1;
2281 }
2282
2283 /* Check authentication. */
2284 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2285 {
paulc6371712006-01-17 17:49:53 +00002286 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2287 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002288 return -1;
2289 }
2290
2291 if (! ospf_check_auth (oi, ibuf, ospfh))
2292 {
2293 zlog_warn ("interface %s: ospf_read authentication failed.",
2294 IF_NAME (oi));
2295 return -1;
2296 }
2297
2298 /* if check sum is invalid, packet is discarded. */
2299 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2300 {
2301 if (! ospf_check_sum (ospfh))
2302 {
2303 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2304 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2305 return -1;
2306 }
2307 }
2308 else
2309 {
2310 if (ospfh->checksum != 0)
2311 return -1;
2312 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2313 {
2314 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2315 IF_NAME (oi));
2316 return -1;
2317 }
2318 }
2319
2320 return 0;
2321}
2322
2323/* Starting point of packet process function. */
2324int
2325ospf_read (struct thread *thread)
2326{
2327 int ret;
2328 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002329 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002330 struct ospf_interface *oi;
2331 struct ip *iph;
2332 struct ospf_header *ospfh;
2333 u_int16_t length;
2334 struct interface *ifp;
2335
2336 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002337 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002338
2339 /* prepare for next packet. */
2340 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002341
2342 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002343 stream_reset(ospf->ibuf);
2344 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002345 return -1;
2346
ajs5c333492005-02-23 15:43:01 +00002347 /* Note that there should not be alignment problems with this assignment
2348 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002349 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002350 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002351
paulac191232004-10-22 12:05:17 +00002352 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002353 /* Handle cases where the platform does not support retrieving the ifindex,
2354 and also platforms (such as Solaris 8) that claim to support ifindex
2355 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002356 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002357
pauld3f0d622004-05-05 15:27:15 +00002358 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002359 return 0;
paul718e3742002-12-13 20:15:29 +00002360
2361 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002362 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002363 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002364
paul718e3742002-12-13 20:15:29 +00002365 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002366 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002367 {
pauld3241812003-09-29 12:42:39 +00002368 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2369 {
ajs2a42e282004-12-08 18:43:03 +00002370 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002371 inet_ntoa (iph->ip_src));
2372 }
paul718e3742002-12-13 20:15:29 +00002373 return 0;
2374 }
2375
2376 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002377 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002378
2379 /* Get ospf packet header. */
2380 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2381
2382 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002383 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002384
2385 /* if no local ospf_interface,
2386 * or header area is backbone but ospf_interface is not
2387 * check for VLINK interface
2388 */
2389 if ( (oi == NULL) ||
2390 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2391 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2392 )
2393 {
2394 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2395 {
Paul Jakma88871b12006-06-15 11:41:19 +00002396 if (IS_DEBUG_OSPF_EVENT)
2397 zlog_debug ("Packet from [%s] received on link %s"
2398 " but no ospf_interface",
2399 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002400 return 0;
2401 }
2402 }
2403
2404 /* else it must be a local ospf interface, check it was received on
2405 * correct link
2406 */
2407 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002408 {
2409 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002410 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002411 return 0;
2412 }
ajs847947f2005-02-02 18:38:48 +00002413 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002414 {
ajsba6454e2005-02-08 15:37:30 +00002415 char buf[2][INET_ADDRSTRLEN];
2416 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002417 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002418 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2419 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2420 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002421 /* Fix multicast memberships? */
2422 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002423 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002424 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002425 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002426 if (oi->multicast_memberships)
2427 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002428 return 0;
2429 }
paul718e3742002-12-13 20:15:29 +00002430
2431 /*
2432 * If the received packet is destined for AllDRouters, the packet
2433 * should be accepted only if the received ospf interface state is
2434 * either DR or Backup -- endo.
2435 */
2436 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2437 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2438 {
ajsba6454e2005-02-08 15:37:30 +00002439 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002440 inet_ntoa (iph->ip_src), IF_NAME (oi),
2441 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002442 /* Try to fix multicast membership. */
2443 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2444 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002445 return 0;
2446 }
2447
2448 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002449 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2450 {
paul718e3742002-12-13 20:15:29 +00002451 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002452 {
ajs2a42e282004-12-08 18:43:03 +00002453 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002454 ospf_packet_dump (ibuf);
2455 }
paul718e3742002-12-13 20:15:29 +00002456
ajs2a42e282004-12-08 18:43:03 +00002457 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002458 ospf_packet_type_str[ospfh->type],
2459 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002460 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2461 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002462
2463 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002464 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002465 }
paul718e3742002-12-13 20:15:29 +00002466
2467 /* Some header verification. */
2468 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2469 if (ret < 0)
2470 {
pauld3241812003-09-29 12:42:39 +00002471 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2472 {
ajs2a42e282004-12-08 18:43:03 +00002473 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002474 "dropping.",
2475 ospf_packet_type_str[ospfh->type],
2476 inet_ntoa (iph->ip_src));
2477 }
paul718e3742002-12-13 20:15:29 +00002478 return ret;
2479 }
2480
paul9985f832005-02-09 15:51:56 +00002481 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002482
2483 /* Adjust size to message length. */
2484 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2485
2486 /* Read rest of the packet and call each sort of packet routine. */
2487 switch (ospfh->type)
2488 {
2489 case OSPF_MSG_HELLO:
2490 ospf_hello (iph, ospfh, ibuf, oi, length);
2491 break;
2492 case OSPF_MSG_DB_DESC:
2493 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2494 break;
2495 case OSPF_MSG_LS_REQ:
2496 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2497 break;
2498 case OSPF_MSG_LS_UPD:
2499 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2500 break;
2501 case OSPF_MSG_LS_ACK:
2502 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2503 break;
2504 default:
2505 zlog (NULL, LOG_WARNING,
2506 "interface %s: OSPF packet header type %d is illegal",
2507 IF_NAME (oi), ospfh->type);
2508 break;
2509 }
2510
paul718e3742002-12-13 20:15:29 +00002511 return 0;
2512}
2513
2514/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002515static void
paul718e3742002-12-13 20:15:29 +00002516ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2517{
2518 struct ospf_header *ospfh;
2519
2520 ospfh = (struct ospf_header *) STREAM_DATA (s);
2521
2522 ospfh->version = (u_char) OSPF_VERSION;
2523 ospfh->type = (u_char) type;
2524
paul68980082003-03-25 05:07:42 +00002525 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002526
2527 ospfh->checksum = 0;
2528 ospfh->area_id = oi->area->area_id;
2529 ospfh->auth_type = htons (ospf_auth_type (oi));
2530
2531 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2532
paul9985f832005-02-09 15:51:56 +00002533 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002534}
2535
2536/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002537static int
paul718e3742002-12-13 20:15:29 +00002538ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2539{
2540 struct crypt_key *ck;
2541
2542 switch (ospf_auth_type (oi))
2543 {
2544 case OSPF_AUTH_NULL:
2545 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2546 break;
2547 case OSPF_AUTH_SIMPLE:
2548 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2549 OSPF_AUTH_SIMPLE_SIZE);
2550 break;
2551 case OSPF_AUTH_CRYPTOGRAPHIC:
2552 /* If key is not set, then set 0. */
2553 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2554 {
2555 ospfh->u.crypt.zero = 0;
2556 ospfh->u.crypt.key_id = 0;
2557 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2558 }
2559 else
2560 {
paul1eb8ef22005-04-07 07:30:20 +00002561 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002562 ospfh->u.crypt.zero = 0;
2563 ospfh->u.crypt.key_id = ck->key_id;
2564 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2565 }
2566 /* note: the seq is done in ospf_make_md5_digest() */
2567 break;
2568 default:
2569 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2570 break;
2571 }
2572
2573 return 0;
2574}
2575
2576/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002577static void
paul718e3742002-12-13 20:15:29 +00002578ospf_fill_header (struct ospf_interface *oi,
2579 struct stream *s, u_int16_t length)
2580{
2581 struct ospf_header *ospfh;
2582
2583 ospfh = (struct ospf_header *) STREAM_DATA (s);
2584
2585 /* Fill length. */
2586 ospfh->length = htons (length);
2587
2588 /* Calculate checksum. */
2589 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2590 ospfh->checksum = in_cksum (ospfh, length);
2591 else
2592 ospfh->checksum = 0;
2593
2594 /* Add Authentication Data. */
2595 ospf_make_auth (oi, ospfh);
2596}
2597
paul4dadc292005-05-06 21:37:42 +00002598static int
paul718e3742002-12-13 20:15:29 +00002599ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2600{
2601 struct ospf_neighbor *nbr;
2602 struct route_node *rn;
2603 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2604 struct in_addr mask;
2605 unsigned long p;
2606 int flag = 0;
2607
2608 /* Set netmask of interface. */
2609 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2610 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2611 masklen2ip (oi->address->prefixlen, &mask);
2612 else
2613 memset ((char *) &mask, 0, sizeof (struct in_addr));
2614 stream_put_ipv4 (s, mask.s_addr);
2615
2616 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002617 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2618 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2619 else
2620 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002621
2622 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002623 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002624 OPTIONS(oi), IF_NAME (oi));
2625
2626 /* Set Options. */
2627 stream_putc (s, OPTIONS (oi));
2628
2629 /* Set Router Priority. */
2630 stream_putc (s, PRIORITY (oi));
2631
2632 /* Set Router Dead Interval. */
2633 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2634
2635 /* Set Designated Router. */
2636 stream_put_ipv4 (s, DR (oi).s_addr);
2637
paul9985f832005-02-09 15:51:56 +00002638 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002639
2640 /* Set Backup Designated Router. */
2641 stream_put_ipv4 (s, BDR (oi).s_addr);
2642
2643 /* Add neighbor seen. */
2644 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002645 if ((nbr = rn->info))
2646 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2647 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2648 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2649 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002650 {
2651 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002652 if (nbr->d_router.s_addr != 0
2653 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2654 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2655 flag = 1;
paul718e3742002-12-13 20:15:29 +00002656
2657 stream_put_ipv4 (s, nbr->router_id.s_addr);
2658 length += 4;
2659 }
2660
2661 /* Let neighbor generate BackupSeen. */
2662 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002663 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002664
2665 return length;
2666}
2667
paul4dadc292005-05-06 21:37:42 +00002668static int
paul718e3742002-12-13 20:15:29 +00002669ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2670 struct stream *s)
2671{
2672 struct ospf_lsa *lsa;
2673 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2674 u_char options;
2675 unsigned long pp;
2676 int i;
2677 struct ospf_lsdb *lsdb;
2678
2679 /* Set Interface MTU. */
2680 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2681 stream_putw (s, 0);
2682 else
2683 stream_putw (s, oi->ifp->mtu);
2684
2685 /* Set Options. */
2686 options = OPTIONS (oi);
2687#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002688 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002689 {
2690 if (IS_SET_DD_I (nbr->dd_flags)
2691 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2692 /*
2693 * Set O-bit in the outgoing DD packet for capablity negotiation,
2694 * if one of following case is applicable.
2695 *
2696 * 1) WaitTimer expiration event triggered the neighbor state to
2697 * change to Exstart, but no (valid) DD packet has received
2698 * from the neighbor yet.
2699 *
2700 * 2) At least one DD packet with O-bit on has received from the
2701 * neighbor.
2702 */
2703 SET_FLAG (options, OSPF_OPTION_O);
2704 }
2705#endif /* HAVE_OPAQUE_LSA */
2706 stream_putc (s, options);
2707
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002708 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002709 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002710 stream_putc (s, nbr->dd_flags);
2711
2712 /* Set DD Sequence Number. */
2713 stream_putl (s, nbr->dd_seqnum);
2714
Paul Jakmab5aeb442006-08-30 18:47:37 +00002715 /* shortcut unneeded walk of (empty) summary LSDBs */
paul718e3742002-12-13 20:15:29 +00002716 if (ospf_db_summary_isempty (nbr))
Paul Jakmab5aeb442006-08-30 18:47:37 +00002717 goto empty;
paul718e3742002-12-13 20:15:29 +00002718
2719 /* Describe LSA Header from Database Summary List. */
2720 lsdb = &nbr->db_sum;
2721
2722 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2723 {
2724 struct route_table *table = lsdb->type[i].db;
2725 struct route_node *rn;
2726
2727 for (rn = route_top (table); rn; rn = route_next (rn))
2728 if ((lsa = rn->info) != NULL)
2729 {
2730#ifdef HAVE_OPAQUE_LSA
2731 if (IS_OPAQUE_LSA (lsa->data->type)
2732 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2733 {
2734 /* Suppress advertising opaque-informations. */
2735 /* Remove LSA from DB summary list. */
2736 ospf_lsdb_delete (lsdb, lsa);
2737 continue;
2738 }
2739#endif /* HAVE_OPAQUE_LSA */
2740
2741 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2742 {
2743 struct lsa_header *lsah;
2744 u_int16_t ls_age;
2745
2746 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002747 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002748 break;
2749
2750 /* Keep pointer to LS age. */
2751 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002752 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002753
2754 /* Proceed stream pointer. */
2755 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2756 length += OSPF_LSA_HEADER_SIZE;
2757
2758 /* Set LS age. */
2759 ls_age = LS_AGE (lsa);
2760 lsah->ls_age = htons (ls_age);
2761
2762 }
2763
2764 /* Remove LSA from DB summary list. */
2765 ospf_lsdb_delete (lsdb, lsa);
2766 }
2767 }
2768
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002769 /* Update 'More' bit */
2770 if (ospf_db_summary_isempty (nbr))
2771 {
Paul Jakmab5aeb442006-08-30 18:47:37 +00002772empty:
2773 if (nbr->state >= NSM_Exchange)
2774 {
2775 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2776 /* Rewrite DD flags */
2777 stream_putc_at (s, pp, nbr->dd_flags);
2778 }
2779 else
2780 {
2781 assert (IS_SET_DD_M(nbr->dd_flags));
2782 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002783 }
paul718e3742002-12-13 20:15:29 +00002784 return length;
2785}
2786
paul4dadc292005-05-06 21:37:42 +00002787static int
paul718e3742002-12-13 20:15:29 +00002788ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2789 unsigned long delta, struct ospf_neighbor *nbr,
2790 struct ospf_lsa *lsa)
2791{
2792 struct ospf_interface *oi;
2793
2794 oi = nbr->oi;
2795
2796 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002797 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002798 return 0;
2799
2800 stream_putl (s, lsa->data->type);
2801 stream_put_ipv4 (s, lsa->data->id.s_addr);
2802 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2803
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002804 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002805 nbr->ls_req_last = ospf_lsa_lock (lsa);
2806
2807 *length += 12;
2808 return 1;
2809}
2810
paul4dadc292005-05-06 21:37:42 +00002811static int
paul718e3742002-12-13 20:15:29 +00002812ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2813{
2814 struct ospf_lsa *lsa;
2815 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002816 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002817 struct route_table *table;
2818 struct route_node *rn;
2819 int i;
2820 struct ospf_lsdb *lsdb;
2821
2822 lsdb = &nbr->ls_req;
2823
2824 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2825 {
2826 table = lsdb->type[i].db;
2827 for (rn = route_top (table); rn; rn = route_next (rn))
2828 if ((lsa = (rn->info)) != NULL)
2829 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2830 {
2831 route_unlock_node (rn);
2832 break;
2833 }
2834 }
2835 return length;
2836}
2837
paul4dadc292005-05-06 21:37:42 +00002838static int
paul718e3742002-12-13 20:15:29 +00002839ls_age_increment (struct ospf_lsa *lsa, int delay)
2840{
2841 int age;
2842
2843 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2844
2845 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2846}
2847
paul4dadc292005-05-06 21:37:42 +00002848static int
hasso52dc7ee2004-09-23 19:18:23 +00002849ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002850{
2851 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002852 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002853 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002854 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002855 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002856 unsigned long pp;
2857 int count = 0;
2858
2859 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002860 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002861
paul9985f832005-02-09 15:51:56 +00002862 pp = stream_get_endp (s);
2863 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002864
gdt86f1fd92005-01-10 14:20:43 +00002865 /* Calculate amount of packet usable for data. */
2866 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2867
paul718e3742002-12-13 20:15:29 +00002868 while ((node = listhead (update)) != NULL)
2869 {
2870 struct lsa_header *lsah;
2871 u_int16_t ls_age;
2872
2873 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002874 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002875
paul1eb8ef22005-04-07 07:30:20 +00002876 lsa = listgetdata (node);
2877
paul718e3742002-12-13 20:15:29 +00002878 assert (lsa->data);
2879
paul68b73392004-09-12 14:21:37 +00002880 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002881 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002882 break;
2883
paul718e3742002-12-13 20:15:29 +00002884 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002885 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002886
2887 /* Put LSA to Link State Request. */
2888 stream_put (s, lsa->data, ntohs (lsa->data->length));
2889
2890 /* Set LS age. */
2891 /* each hop must increment an lsa_age by transmit_delay
2892 of OSPF interface */
2893 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2894 lsah->ls_age = htons (ls_age);
2895
2896 length += ntohs (lsa->data->length);
2897 count++;
2898
2899 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002900 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002901 }
2902
2903 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002904 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002905
2906 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002907 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002908 return length;
2909}
2910
paul4dadc292005-05-06 21:37:42 +00002911static int
hasso52dc7ee2004-09-23 19:18:23 +00002912ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002913{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002914 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002915 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002916 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002917 struct ospf_lsa *lsa;
2918
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002919 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002920 {
paul718e3742002-12-13 20:15:29 +00002921 assert (lsa);
2922
gdt86f1fd92005-01-10 14:20:43 +00002923 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002924 break;
2925
2926 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2927 length += OSPF_LSA_HEADER_SIZE;
2928
paul718e3742002-12-13 20:15:29 +00002929 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002930 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002931 }
2932
paul718e3742002-12-13 20:15:29 +00002933 return length;
2934}
2935
2936void
2937ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2938{
2939 struct ospf_packet *op;
2940 u_int16_t length = OSPF_HEADER_SIZE;
2941
2942 op = ospf_packet_new (oi->ifp->mtu);
2943
2944 /* Prepare OSPF common header. */
2945 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2946
2947 /* Prepare OSPF Hello body. */
2948 length += ospf_make_hello (oi, op->s);
2949
2950 /* Fill OSPF header. */
2951 ospf_fill_header (oi, op->s, length);
2952
2953 /* Set packet length. */
2954 op->length = length;
2955
2956 op->dst.s_addr = addr->s_addr;
2957
2958 /* Add packet to the interface output queue. */
2959 ospf_packet_add (oi, op);
2960
2961 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002962 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002963}
2964
paul4dadc292005-05-06 21:37:42 +00002965static void
paul718e3742002-12-13 20:15:29 +00002966ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2967{
2968 struct ospf_interface *oi;
2969
2970 oi = nbr_nbma->oi;
2971 assert(oi);
2972
2973 /* If this is passive interface, do not send OSPF Hello. */
2974 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2975 return;
2976
2977 if (oi->type != OSPF_IFTYPE_NBMA)
2978 return;
2979
2980 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2981 return;
2982
2983 if (PRIORITY(oi) == 0)
2984 return;
2985
2986 if (nbr_nbma->priority == 0
2987 && oi->state != ISM_DR && oi->state != ISM_Backup)
2988 return;
2989
2990 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2991}
2992
2993int
2994ospf_poll_timer (struct thread *thread)
2995{
2996 struct ospf_nbr_nbma *nbr_nbma;
2997
2998 nbr_nbma = THREAD_ARG (thread);
2999 nbr_nbma->t_poll = NULL;
3000
3001 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003002 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003003 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3004
3005 ospf_poll_send (nbr_nbma);
3006
3007 if (nbr_nbma->v_poll > 0)
3008 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3009 nbr_nbma->v_poll);
3010
3011 return 0;
3012}
3013
3014
3015int
3016ospf_hello_reply_timer (struct thread *thread)
3017{
3018 struct ospf_neighbor *nbr;
3019
3020 nbr = THREAD_ARG (thread);
3021 nbr->t_hello_reply = NULL;
3022
3023 assert (nbr->oi);
3024
3025 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003026 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003027 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3028
3029 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3030
3031 return 0;
3032}
3033
3034/* Send OSPF Hello. */
3035void
3036ospf_hello_send (struct ospf_interface *oi)
3037{
3038 struct ospf_packet *op;
3039 u_int16_t length = OSPF_HEADER_SIZE;
3040
3041 /* If this is passive interface, do not send OSPF Hello. */
3042 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3043 return;
3044
3045 op = ospf_packet_new (oi->ifp->mtu);
3046
3047 /* Prepare OSPF common header. */
3048 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3049
3050 /* Prepare OSPF Hello body. */
3051 length += ospf_make_hello (oi, op->s);
3052
3053 /* Fill OSPF header. */
3054 ospf_fill_header (oi, op->s, length);
3055
3056 /* Set packet length. */
3057 op->length = length;
3058
3059 if (oi->type == OSPF_IFTYPE_NBMA)
3060 {
3061 struct ospf_neighbor *nbr;
3062 struct route_node *rn;
3063
3064 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3065 if ((nbr = rn->info))
3066 if (nbr != oi->nbr_self)
3067 if (nbr->state != NSM_Down)
3068 {
3069 /* RFC 2328 Section 9.5.1
3070 If the router is not eligible to become Designated Router,
3071 it must periodically send Hello Packets to both the
3072 Designated Router and the Backup Designated Router (if they
3073 exist). */
3074 if (PRIORITY(oi) == 0 &&
3075 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3076 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3077 continue;
3078
3079 /* If the router is eligible to become Designated Router, it
3080 must periodically send Hello Packets to all neighbors that
3081 are also eligible. In addition, if the router is itself the
3082 Designated Router or Backup Designated Router, it must also
3083 send periodic Hello Packets to all other neighbors. */
3084
3085 if (nbr->priority == 0 && oi->state == ISM_DROther)
3086 continue;
3087 /* if oi->state == Waiting, send hello to all neighbors */
3088 {
3089 struct ospf_packet *op_dup;
3090
3091 op_dup = ospf_packet_dup(op);
3092 op_dup->dst = nbr->address.u.prefix4;
3093
3094 /* Add packet to the interface output queue. */
3095 ospf_packet_add (oi, op_dup);
3096
paul020709f2003-04-04 02:44:16 +00003097 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003098 }
3099
3100 }
3101 ospf_packet_free (op);
3102 }
3103 else
3104 {
3105 /* Decide destination address. */
3106 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3107 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3108 else
3109 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3110
3111 /* Add packet to the interface output queue. */
3112 ospf_packet_add (oi, op);
3113
3114 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003115 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003116 }
3117}
3118
3119/* Send OSPF Database Description. */
3120void
3121ospf_db_desc_send (struct ospf_neighbor *nbr)
3122{
3123 struct ospf_interface *oi;
3124 struct ospf_packet *op;
3125 u_int16_t length = OSPF_HEADER_SIZE;
3126
3127 oi = nbr->oi;
3128 op = ospf_packet_new (oi->ifp->mtu);
3129
3130 /* Prepare OSPF common header. */
3131 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3132
3133 /* Prepare OSPF Database Description body. */
3134 length += ospf_make_db_desc (oi, nbr, op->s);
3135
3136 /* Fill OSPF header. */
3137 ospf_fill_header (oi, op->s, length);
3138
3139 /* Set packet length. */
3140 op->length = length;
3141
3142 /* Decide destination address. */
3143 op->dst = nbr->address.u.prefix4;
3144
3145 /* Add packet to the interface output queue. */
3146 ospf_packet_add (oi, op);
3147
3148 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003149 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003150
3151 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3152 if (nbr->last_send)
3153 ospf_packet_free (nbr->last_send);
3154 nbr->last_send = ospf_packet_dup (op);
Paul Jakma2518efd2006-08-27 06:49:29 +00003155 quagga_gettime (QUAGGA_CLK_MONOTONIC, &nbr->last_send_ts);
paul718e3742002-12-13 20:15:29 +00003156}
3157
3158/* Re-send Database Description. */
3159void
3160ospf_db_desc_resend (struct ospf_neighbor *nbr)
3161{
3162 struct ospf_interface *oi;
3163
3164 oi = nbr->oi;
3165
3166 /* Add packet to the interface output queue. */
3167 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3168
3169 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003170 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003171}
3172
3173/* Send Link State Request. */
3174void
3175ospf_ls_req_send (struct ospf_neighbor *nbr)
3176{
3177 struct ospf_interface *oi;
3178 struct ospf_packet *op;
3179 u_int16_t length = OSPF_HEADER_SIZE;
3180
3181 oi = nbr->oi;
3182 op = ospf_packet_new (oi->ifp->mtu);
3183
3184 /* Prepare OSPF common header. */
3185 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3186
3187 /* Prepare OSPF Link State Request body. */
3188 length += ospf_make_ls_req (nbr, op->s);
3189 if (length == OSPF_HEADER_SIZE)
3190 {
3191 ospf_packet_free (op);
3192 return;
3193 }
3194
3195 /* Fill OSPF header. */
3196 ospf_fill_header (oi, op->s, length);
3197
3198 /* Set packet length. */
3199 op->length = length;
3200
3201 /* Decide destination address. */
3202 op->dst = nbr->address.u.prefix4;
3203
3204 /* Add packet to the interface output queue. */
3205 ospf_packet_add (oi, op);
3206
3207 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003208 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003209
3210 /* Add Link State Request Retransmission Timer. */
3211 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3212}
3213
3214/* Send Link State Update with an LSA. */
3215void
3216ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3217 int flag)
3218{
hasso52dc7ee2004-09-23 19:18:23 +00003219 struct list *update;
paul718e3742002-12-13 20:15:29 +00003220
3221 update = list_new ();
3222
3223 listnode_add (update, lsa);
3224 ospf_ls_upd_send (nbr, update, flag);
3225
3226 list_delete (update);
3227}
3228
paul68b73392004-09-12 14:21:37 +00003229/* Determine size for packet. Must be at least big enough to accomodate next
3230 * LSA on list, which may be bigger than MTU size.
3231 *
3232 * Return pointer to new ospf_packet
3233 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3234 * on packet sizes (in which case offending LSA is deleted from update list)
3235 */
3236static struct ospf_packet *
3237ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3238{
3239 struct ospf_lsa *lsa;
3240 struct listnode *ln;
3241 size_t size;
3242 static char warned = 0;
3243
paul1eb8ef22005-04-07 07:30:20 +00003244 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003245 assert (lsa->data);
3246
3247 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3248 > ospf_packet_max (oi))
3249 {
3250 if (!warned)
3251 {
3252 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3253 "will need to fragment. Not optimal. Try divide up"
3254 " your network with areas. Use 'debug ospf packet send'"
3255 " to see details, or look at 'show ip ospf database ..'");
3256 warned = 1;
3257 }
3258
3259 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003260 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003261 " %d bytes originated by %s, will be fragmented!",
3262 inet_ntoa (lsa->data->id),
3263 ntohs (lsa->data->length),
3264 inet_ntoa (lsa->data->adv_router));
3265
3266 /*
3267 * Allocate just enough to fit this LSA only, to avoid including other
3268 * LSAs in fragmented LSA Updates.
3269 */
3270 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3271 + OSPF_LS_UPD_MIN_SIZE;
3272 }
3273 else
3274 size = oi->ifp->mtu;
3275
gdt86f1fd92005-01-10 14:20:43 +00003276 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003277 if (size > OSPF_MAX_PACKET_SIZE)
3278 {
3279 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003280 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003281 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003282 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003283 (long int) size);
paul68b73392004-09-12 14:21:37 +00003284 list_delete_node (update, ln);
3285 return NULL;
3286 }
3287
3288 return ospf_packet_new (size);
3289}
3290
paul718e3742002-12-13 20:15:29 +00003291static void
hasso52dc7ee2004-09-23 19:18:23 +00003292ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003293 struct in_addr addr)
3294{
3295 struct ospf_packet *op;
3296 u_int16_t length = OSPF_HEADER_SIZE;
3297
3298 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003299 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003300
3301 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003302
3303 /* Prepare OSPF common header. */
3304 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3305
paul59ea14c2004-07-14 20:50:36 +00003306 /* Prepare OSPF Link State Update body.
3307 * Includes Type-7 translation.
3308 */
paul718e3742002-12-13 20:15:29 +00003309 length += ospf_make_ls_upd (oi, update, op->s);
3310
3311 /* Fill OSPF header. */
3312 ospf_fill_header (oi, op->s, length);
3313
3314 /* Set packet length. */
3315 op->length = length;
3316
3317 /* Decide destination address. */
3318 op->dst.s_addr = addr.s_addr;
3319
3320 /* Add packet to the interface output queue. */
3321 ospf_packet_add (oi, op);
3322
3323 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003324 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003325}
3326
3327static int
3328ospf_ls_upd_send_queue_event (struct thread *thread)
3329{
3330 struct ospf_interface *oi = THREAD_ARG(thread);
3331 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003332 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003333 struct list *update;
paul68b73392004-09-12 14:21:37 +00003334 char again = 0;
paul718e3742002-12-13 20:15:29 +00003335
3336 oi->t_ls_upd_event = NULL;
3337
3338 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003339 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003340
paul736d3442003-07-24 23:22:57 +00003341 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003342 {
paul736d3442003-07-24 23:22:57 +00003343 rnext = route_next (rn);
3344
paul718e3742002-12-13 20:15:29 +00003345 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003346 continue;
paul68b73392004-09-12 14:21:37 +00003347
3348 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003349
paul48fe13b2004-07-27 17:40:44 +00003350 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003351
paul68b73392004-09-12 14:21:37 +00003352 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003353 if (listcount(update) == 0)
3354 {
3355 list_delete (rn->info);
3356 rn->info = NULL;
3357 route_unlock_node (rn);
3358 }
3359 else
paul68b73392004-09-12 14:21:37 +00003360 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003361 }
3362
3363 if (again != 0)
3364 {
3365 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003366 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003367 " %d nodes to try again, raising new event", again);
3368 oi->t_ls_upd_event =
3369 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003370 }
3371
3372 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003373 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003374
paul718e3742002-12-13 20:15:29 +00003375 return 0;
3376}
3377
3378void
hasso52dc7ee2004-09-23 19:18:23 +00003379ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003380{
3381 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003382 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003383 struct prefix_ipv4 p;
3384 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003385 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003386
3387 oi = nbr->oi;
3388
3389 p.family = AF_INET;
3390 p.prefixlen = IPV4_MAX_BITLEN;
3391
3392 /* Decide destination address. */
3393 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3394 p.prefix = oi->vl_data->peer_addr;
3395 else if (flag == OSPF_SEND_PACKET_DIRECT)
3396 p.prefix = nbr->address.u.prefix4;
3397 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3398 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3399 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3400 && (flag == OSPF_SEND_PACKET_INDIRECT))
3401 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003402 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3403 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003404 else
3405 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3406
3407 if (oi->type == OSPF_IFTYPE_NBMA)
3408 {
3409 if (flag == OSPF_SEND_PACKET_INDIRECT)
3410 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3411 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3412 zlog_warn ("* LS-Update is sent to myself.");
3413 }
3414
3415 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3416
3417 if (rn->info == NULL)
3418 rn->info = list_new ();
3419
paul1eb8ef22005-04-07 07:30:20 +00003420 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003421 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003422
3423 if (oi->t_ls_upd_event == NULL)
3424 oi->t_ls_upd_event =
3425 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3426}
3427
3428static void
hasso52dc7ee2004-09-23 19:18:23 +00003429ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3430 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003431{
3432 struct ospf_packet *op;
3433 u_int16_t length = OSPF_HEADER_SIZE;
3434
3435 op = ospf_packet_new (oi->ifp->mtu);
3436
3437 /* Prepare OSPF common header. */
3438 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3439
3440 /* Prepare OSPF Link State Acknowledgment body. */
3441 length += ospf_make_ls_ack (oi, ack, op->s);
3442
3443 /* Fill OSPF header. */
3444 ospf_fill_header (oi, op->s, length);
3445
3446 /* Set packet length. */
3447 op->length = length;
3448
3449 /* Set destination IP address. */
3450 op->dst = dst;
3451
3452 /* Add packet to the interface output queue. */
3453 ospf_packet_add (oi, op);
3454
3455 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003456 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003457}
3458
3459static int
3460ospf_ls_ack_send_event (struct thread *thread)
3461{
3462 struct ospf_interface *oi = THREAD_ARG (thread);
3463
3464 oi->t_ls_ack_direct = NULL;
3465
3466 while (listcount (oi->ls_ack_direct.ls_ack))
3467 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3468 oi->ls_ack_direct.dst);
3469
3470 return 0;
3471}
3472
3473void
3474ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3475{
3476 struct ospf_interface *oi = nbr->oi;
3477
3478 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3479 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3480
3481 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3482
3483 if (oi->t_ls_ack_direct == NULL)
3484 oi->t_ls_ack_direct =
3485 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3486}
3487
3488/* Send Link State Acknowledgment delayed. */
3489void
3490ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3491{
3492 struct in_addr dst;
3493
3494 /* Decide destination address. */
3495 /* RFC2328 Section 13.5 On non-broadcast
3496 networks, delayed Link State Acknowledgment packets must be
3497 unicast separately over each adjacency (i.e., neighbor whose
3498 state is >= Exchange). */
3499 if (oi->type == OSPF_IFTYPE_NBMA)
3500 {
3501 struct ospf_neighbor *nbr;
3502 struct route_node *rn;
3503
3504 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3505 if ((nbr = rn->info) != NULL)
3506 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3507 while (listcount (oi->ls_ack))
3508 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3509 return;
3510 }
3511 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3512 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3513 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3514 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3515 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3516 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003517 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3518 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003519 else
3520 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3521
3522 while (listcount (oi->ls_ack))
3523 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3524}