blob: 6449e63a79c473316d14b060803e04d91093809e [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Sending and Receiving OSPF Packets.
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "thread.h"
26#include "memory.h"
27#include "linklist.h"
28#include "prefix.h"
29#include "if.h"
30#include "table.h"
31#include "sockunion.h"
32#include "stream.h"
33#include "log.h"
paul2dd8bb42004-07-23 15:13:48 +000034#include "sockopt.h"
paul484315f2005-11-03 09:08:29 +000035#include "checksum.h"
vincentc1a03d42005-09-28 15:47:44 +000036#include "md5.h"
paul718e3742002-12-13 20:15:29 +000037
38#include "ospfd/ospfd.h"
39#include "ospfd/ospf_network.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_ism.h"
42#include "ospfd/ospf_asbr.h"
43#include "ospfd/ospf_lsa.h"
44#include "ospfd/ospf_lsdb.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_packet.h"
48#include "ospfd/ospf_spf.h"
49#include "ospfd/ospf_flood.h"
50#include "ospfd/ospf_dump.h"
51
paul718e3742002-12-13 20:15:29 +000052/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000053const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000054{
55 "unknown",
56 "Hello",
57 "Database Description",
58 "Link State Request",
59 "Link State Update",
60 "Link State Acknowledgment",
61};
62
paul718e3742002-12-13 20:15:29 +000063/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000064static int
paul718e3742002-12-13 20:15:29 +000065ospf_auth_type (struct ospf_interface *oi)
66{
67 int auth_type;
68
69 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
70 auth_type = oi->area->auth_type;
71 else
72 auth_type = OSPF_IF_PARAM (oi, auth_type);
73
74 /* Handle case where MD5 key list is not configured aka Cisco */
75 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
76 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
77 return OSPF_AUTH_NULL;
78
79 return auth_type;
80
81}
82
paul718e3742002-12-13 20:15:29 +000083struct ospf_packet *
84ospf_packet_new (size_t size)
85{
86 struct ospf_packet *new;
87
88 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
89 new->s = stream_new (size);
90
91 return new;
92}
93
94void
95ospf_packet_free (struct ospf_packet *op)
96{
97 if (op->s)
98 stream_free (op->s);
99
100 XFREE (MTYPE_OSPF_PACKET, op);
101
102 op = NULL;
103}
104
105struct ospf_fifo *
106ospf_fifo_new ()
107{
108 struct ospf_fifo *new;
109
110 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
111 return new;
112}
113
114/* Add new packet to fifo. */
115void
116ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
117{
118 if (fifo->tail)
119 fifo->tail->next = op;
120 else
121 fifo->head = op;
122
123 fifo->tail = op;
124
125 fifo->count++;
126}
127
128/* Delete first packet from fifo. */
129struct ospf_packet *
130ospf_fifo_pop (struct ospf_fifo *fifo)
131{
132 struct ospf_packet *op;
133
134 op = fifo->head;
135
136 if (op)
137 {
138 fifo->head = op->next;
139
140 if (fifo->head == NULL)
141 fifo->tail = NULL;
142
143 fifo->count--;
144 }
145
146 return op;
147}
148
149/* Return first fifo entry. */
150struct ospf_packet *
151ospf_fifo_head (struct ospf_fifo *fifo)
152{
153 return fifo->head;
154}
155
156/* Flush ospf packet fifo. */
157void
158ospf_fifo_flush (struct ospf_fifo *fifo)
159{
160 struct ospf_packet *op;
161 struct ospf_packet *next;
162
163 for (op = fifo->head; op; op = next)
164 {
165 next = op->next;
166 ospf_packet_free (op);
167 }
168 fifo->head = fifo->tail = NULL;
169 fifo->count = 0;
170}
171
172/* Free ospf packet fifo. */
173void
174ospf_fifo_free (struct ospf_fifo *fifo)
175{
176 ospf_fifo_flush (fifo);
177
178 XFREE (MTYPE_OSPF_FIFO, fifo);
179}
180
181void
182ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
183{
ajsc3eab872005-01-29 15:52:07 +0000184 if (!oi->obuf)
185 {
186 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
187 "destination %s) called with NULL obuf, ignoring "
188 "(please report this bug)!\n",
189 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
190 ospf_packet_type_str[stream_getc_from(op->s, 1)],
191 inet_ntoa (op->dst));
192 return;
193 }
194
paul718e3742002-12-13 20:15:29 +0000195 /* Add packet to end of queue. */
196 ospf_fifo_push (oi->obuf, op);
197
198 /* Debug of packet fifo*/
199 /* ospf_fifo_debug (oi->obuf); */
200}
201
202void
203ospf_packet_delete (struct ospf_interface *oi)
204{
205 struct ospf_packet *op;
206
207 op = ospf_fifo_pop (oi->obuf);
208
209 if (op)
210 ospf_packet_free (op);
211}
212
paul718e3742002-12-13 20:15:29 +0000213struct ospf_packet *
214ospf_packet_dup (struct ospf_packet *op)
215{
216 struct ospf_packet *new;
217
paul37163d62003-02-03 18:40:56 +0000218 if (stream_get_endp(op->s) != op->length)
219 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000220 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000221
222 /* Reserve space for MD5 authentication that may be added later. */
223 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000224 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000225
226 new->dst = op->dst;
227 new->length = op->length;
228
229 return new;
230}
231
gdt86f1fd92005-01-10 14:20:43 +0000232/* XXX inline */
paul4dadc292005-05-06 21:37:42 +0000233static inline unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000234ospf_packet_authspace (struct ospf_interface *oi)
235{
236 int auth = 0;
237
238 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
239 auth = OSPF_AUTH_MD5_SIZE;
240
241 return auth;
242}
243
paul4dadc292005-05-06 21:37:42 +0000244static unsigned int
paul718e3742002-12-13 20:15:29 +0000245ospf_packet_max (struct ospf_interface *oi)
246{
247 int max;
248
gdt86f1fd92005-01-10 14:20:43 +0000249 max = oi->ifp->mtu - ospf_packet_authspace(oi);
250
paul68b73392004-09-12 14:21:37 +0000251 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000252
253 return max;
254}
255
256
paul4dadc292005-05-06 21:37:42 +0000257static int
paul718e3742002-12-13 20:15:29 +0000258ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
259 u_int16_t length)
260{
paul6c835672004-10-11 11:00:30 +0000261 unsigned char *ibuf;
vincentc1a03d42005-09-28 15:47:44 +0000262 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000263 unsigned char digest[OSPF_AUTH_MD5_SIZE];
264 unsigned char *pdigest;
265 struct crypt_key *ck;
266 struct ospf_header *ospfh;
267 struct ospf_neighbor *nbr;
268
269
270 ibuf = STREAM_PNT (s);
271 ospfh = (struct ospf_header *) ibuf;
272
273 /* Get pointer to the end of the packet. */
274 pdigest = ibuf + length;
275
276 /* Get secret key. */
277 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
278 ospfh->u.crypt.key_id);
279 if (ck == NULL)
280 {
281 zlog_warn ("interface %s: ospf_check_md5 no key %d",
282 IF_NAME (oi), ospfh->u.crypt.key_id);
283 return 0;
284 }
285
286 /* check crypto seqnum. */
287 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
288
289 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
290 {
291 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
292 IF_NAME (oi),
293 ntohl(ospfh->u.crypt.crypt_seqnum),
294 ntohl(nbr->crypt_seqnum));
295 return 0;
296 }
297
298 /* Generate a digest for the ospf packet - their digest + our digest. */
vincentc1a03d42005-09-28 15:47:44 +0000299 memset(&ctx, 0, sizeof(ctx));
300 MD5Init(&ctx);
301 MD5Update(&ctx, ibuf, length);
302 MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE);
303 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000304
305 /* compare the two */
306 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
307 {
308 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
309 IF_NAME (oi));
310 return 0;
311 }
312
313 /* save neighbor's crypt_seqnum */
314 if (nbr)
315 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
316 return 1;
317}
318
319/* This function is called from ospf_write(), it will detect the
320 authentication scheme and if it is MD5, it will change the sequence
321 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000322static int
paul718e3742002-12-13 20:15:29 +0000323ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
324{
325 struct ospf_header *ospfh;
326 unsigned char digest[OSPF_AUTH_MD5_SIZE];
vincentc1a03d42005-09-28 15:47:44 +0000327 MD5_CTX ctx;
paul718e3742002-12-13 20:15:29 +0000328 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000329 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000330 struct crypt_key *ck;
paul36238142005-10-11 04:12:54 +0000331 const u_int8_t *auth_key;
paul718e3742002-12-13 20:15:29 +0000332
333 ibuf = STREAM_DATA (op->s);
334 ospfh = (struct ospf_header *) ibuf;
335
336 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
337 return 0;
338
339 /* We do this here so when we dup a packet, we don't have to
340 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000341 t = (time(NULL) & 0xFFFFFFFF);
paul818e56c2006-01-10 23:27:05 +0000342 if (t > oi->crypt_seqnum)
343 oi->crypt_seqnum = t;
344 else
345 oi->crypt_seqnum++;
346
paul9483e152002-12-13 20:55:25 +0000347 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000348
349 /* Get MD5 Authentication key from auth_key list. */
350 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul36238142005-10-11 04:12:54 +0000351 auth_key = (const u_int8_t *) "";
paul718e3742002-12-13 20:15:29 +0000352 else
353 {
paul1eb8ef22005-04-07 07:30:20 +0000354 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000355 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000356 }
357
358 /* Generate a digest for the entire packet + our secret key. */
vincentc1a03d42005-09-28 15:47:44 +0000359 memset(&ctx, 0, sizeof(ctx));
360 MD5Init(&ctx);
361 MD5Update(&ctx, ibuf, ntohs (ospfh->length));
362 MD5Update(&ctx, auth_key, OSPF_AUTH_MD5_SIZE);
363 MD5Final(digest, &ctx);
paul718e3742002-12-13 20:15:29 +0000364
365 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000366 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000367
368 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000369 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
370
paul37163d62003-02-03 18:40:56 +0000371 if (stream_get_endp(op->s) != op->length)
372 zlog_warn("ospf_make_md5_digest: length mismatch stream %ld ospf_packet %d", stream_get_endp(op->s), op->length);
paul718e3742002-12-13 20:15:29 +0000373
374 return OSPF_AUTH_MD5_SIZE;
375}
376
377
paul4dadc292005-05-06 21:37:42 +0000378static int
paul718e3742002-12-13 20:15:29 +0000379ospf_ls_req_timer (struct thread *thread)
380{
381 struct ospf_neighbor *nbr;
382
383 nbr = THREAD_ARG (thread);
384 nbr->t_ls_req = NULL;
385
386 /* Send Link State Request. */
387 if (ospf_ls_request_count (nbr))
388 ospf_ls_req_send (nbr);
389
390 /* Set Link State Request retransmission timer. */
391 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
392
393 return 0;
394}
395
396void
397ospf_ls_req_event (struct ospf_neighbor *nbr)
398{
399 if (nbr->t_ls_req)
400 {
401 thread_cancel (nbr->t_ls_req);
402 nbr->t_ls_req = NULL;
403 }
404 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
405}
406
407/* Cyclic timer function. Fist registered in ospf_nbr_new () in
408 ospf_neighbor.c */
409int
410ospf_ls_upd_timer (struct thread *thread)
411{
412 struct ospf_neighbor *nbr;
413
414 nbr = THREAD_ARG (thread);
415 nbr->t_ls_upd = NULL;
416
417 /* Send Link State Update. */
418 if (ospf_ls_retransmit_count (nbr) > 0)
419 {
hasso52dc7ee2004-09-23 19:18:23 +0000420 struct list *update;
paul718e3742002-12-13 20:15:29 +0000421 struct ospf_lsdb *lsdb;
422 int i;
paul718e3742002-12-13 20:15:29 +0000423 int retransmit_interval;
424
paul718e3742002-12-13 20:15:29 +0000425 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
426
427 lsdb = &nbr->ls_rxmt;
428 update = list_new ();
429
430 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
431 {
432 struct route_table *table = lsdb->type[i].db;
433 struct route_node *rn;
434
435 for (rn = route_top (table); rn; rn = route_next (rn))
436 {
437 struct ospf_lsa *lsa;
438
439 if ((lsa = rn->info) != NULL)
440 /* Don't retransmit an LSA if we received it within
441 the last RxmtInterval seconds - this is to allow the
442 neighbour a chance to acknowledge the LSA as it may
443 have ben just received before the retransmit timer
444 fired. This is a small tweak to what is in the RFC,
445 but it will cut out out a lot of retransmit traffic
446 - MAG */
pauld24f6e22005-10-21 09:23:12 +0000447 if (tv_cmp (tv_sub (recent_time, lsa->tv_recv),
paul718e3742002-12-13 20:15:29 +0000448 int2tv (retransmit_interval)) >= 0)
449 listnode_add (update, rn->info);
450 }
451 }
452
453 if (listcount (update) > 0)
454 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
455 list_delete (update);
456 }
457
458 /* Set LS Update retransmission timer. */
459 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
460
461 return 0;
462}
463
464int
465ospf_ls_ack_timer (struct thread *thread)
466{
467 struct ospf_interface *oi;
468
469 oi = THREAD_ARG (thread);
470 oi->t_ls_ack = NULL;
471
472 /* Send Link State Acknowledgment. */
473 if (listcount (oi->ls_ack) > 0)
474 ospf_ls_ack_send_delayed (oi);
475
476 /* Set LS Ack timer. */
477 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
478
479 return 0;
480}
481
paul0bfeca32004-09-24 08:07:54 +0000482#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000483static void
paul6a99f832004-09-27 12:56:30 +0000484ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000485 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000486 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000487{
488#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000489 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000490 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000491 int ret;
paul0bfeca32004-09-24 08:07:54 +0000492
493 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000494 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000495
496 /* we can but try.
497 *
498 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
499 * well as the IP_MF flag, making this all quite pointless.
500 *
501 * However, for a system on which IP_MF is left alone, and ip_id left
502 * alone or else which sets same ip_id for each fragment this might
503 * work, eg linux.
504 *
505 * XXX-TODO: It would be much nicer to have the kernel's use their
506 * existing fragmentation support to do this for us. Bugs/RFEs need to
507 * be raised against the various kernels.
508 */
509
510 /* set More Frag */
511 iph->ip_off |= IP_MF;
512
513 /* ip frag offset is expressed in units of 8byte words */
514 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
515
paul62d8e962004-11-02 20:26:45 +0000516 iovp = &msg->msg_iov[1];
517
paul0bfeca32004-09-24 08:07:54 +0000518 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
519 > maxdatasize )
520 {
521 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000522 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
523 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000524 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000525
paul18b12c32004-10-05 14:38:29 +0000526 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000527
paul6a99f832004-09-27 12:56:30 +0000528 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000529
paul18b12c32004-10-05 14:38:29 +0000530 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000531
532 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000533 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000534 " id %d, off %d, len %d, mtu %u failed with %s",
535 inet_ntoa (iph->ip_dst),
536 iph->ip_id,
537 iph->ip_off,
538 iph->ip_len,
539 mtu,
540 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000541
paul37ccfa32004-10-31 11:24:51 +0000542 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
543 {
ajs2a42e282004-12-08 18:43:03 +0000544 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000545 iph->ip_id, iph->ip_off, iph->ip_len,
546 inet_ntoa (iph->ip_dst));
547 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
548 {
ajs2a42e282004-12-08 18:43:03 +0000549 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000550 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000551 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000552 }
553 }
554
paul0bfeca32004-09-24 08:07:54 +0000555 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000556 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000557 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000558 }
559
560 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000561 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
562 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000563 iph->ip_off &= (~IP_MF);
564}
565#endif /* WANT_OSPF_WRITE_FRAGMENT */
566
ajs5dcbdf82005-03-29 16:13:49 +0000567static int
paul718e3742002-12-13 20:15:29 +0000568ospf_write (struct thread *thread)
569{
paul68980082003-03-25 05:07:42 +0000570 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000571 struct ospf_interface *oi;
572 struct ospf_packet *op;
573 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000574 struct ip iph;
575 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000576 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000577 u_char type;
578 int ret;
579 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000580 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000581#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000582 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000583#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000584 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000585#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000586
paul68980082003-03-25 05:07:42 +0000587 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000588
paul68980082003-03-25 05:07:42 +0000589 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000590 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000591 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000592 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000593
594#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000595 /* seed ipid static with low order bits of time */
596 if (ipid == 0)
597 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000598#endif /* WANT_OSPF_WRITE_FRAGMENT */
599
paul68b73392004-09-12 14:21:37 +0000600 /* convenience - max OSPF data per packet */
601 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
602
paul718e3742002-12-13 20:15:29 +0000603 /* Get one packet from queue. */
604 op = ospf_fifo_head (oi->obuf);
605 assert (op);
606 assert (op->length >= OSPF_HEADER_SIZE);
607
paul68980082003-03-25 05:07:42 +0000608 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
609 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000610 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
611
paul718e3742002-12-13 20:15:29 +0000612 /* Rewrite the md5 signature & update the seq */
613 ospf_make_md5_digest (oi, op);
614
paul37ccfa32004-10-31 11:24:51 +0000615 /* Retrieve OSPF packet type. */
616 stream_set_getp (op->s, 1);
617 type = stream_getc (op->s);
618
paul68b73392004-09-12 14:21:37 +0000619 /* reset get pointer */
620 stream_set_getp (op->s, 0);
621
622 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000623 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000624
paul718e3742002-12-13 20:15:29 +0000625 sa_dst.sin_family = AF_INET;
626#ifdef HAVE_SIN_LEN
627 sa_dst.sin_len = sizeof(sa_dst);
628#endif /* HAVE_SIN_LEN */
629 sa_dst.sin_addr = op->dst;
630 sa_dst.sin_port = htons (0);
631
632 /* Set DONTROUTE flag if dst is unicast. */
633 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
634 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
635 flags = MSG_DONTROUTE;
636
paul68b73392004-09-12 14:21:37 +0000637 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
638 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000639 if ( sizeof (struct ip)
640 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000641 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
642
paul718e3742002-12-13 20:15:29 +0000643 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000644 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000645 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000646
paul0bfeca32004-09-24 08:07:54 +0000647#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000648 /* XXX-MT: not thread-safe at all..
649 * XXX: this presumes this is only programme sending OSPF packets
650 * otherwise, no guarantee ipid will be unique
651 */
652 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000653#endif /* WANT_OSPF_WRITE_FRAGMENT */
654
paul718e3742002-12-13 20:15:29 +0000655 iph.ip_off = 0;
656 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
657 iph.ip_ttl = OSPF_VL_IP_TTL;
658 else
659 iph.ip_ttl = OSPF_IP_TTL;
660 iph.ip_p = IPPROTO_OSPFIGP;
661 iph.ip_sum = 0;
662 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
663 iph.ip_dst.s_addr = op->dst.s_addr;
664
665 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000666 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000667 msg.msg_namelen = sizeof (sa_dst);
668 msg.msg_iov = iov;
669 msg.msg_iovlen = 2;
670 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000671 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
672 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000673 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000674
675 /* Sadly we can not rely on kernels to fragment packets because of either
676 * IP_HDRINCL and/or multicast destination being set.
677 */
paul0bfeca32004-09-24 08:07:54 +0000678#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000679 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000680 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
681 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000682#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000683
684 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000685 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000686 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000687 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000688
689 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000690 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000691 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000692 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000693 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000694
paul718e3742002-12-13 20:15:29 +0000695 /* Show debug sending packet. */
696 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
697 {
698 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
699 {
ajs2a42e282004-12-08 18:43:03 +0000700 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000701 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000702 stream_set_getp (op->s, 0);
703 ospf_packet_dump (op->s);
704 }
705
ajs2a42e282004-12-08 18:43:03 +0000706 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000707 ospf_packet_type_str[type], inet_ntoa (op->dst),
708 IF_NAME (oi));
709
710 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000711 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000712 }
713
714 /* Now delete packet from queue. */
715 ospf_packet_delete (oi);
716
717 if (ospf_fifo_head (oi->obuf) == NULL)
718 {
719 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000720 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000724 if (!list_isempty (ospf->oi_write_q))
725 ospf->t_write =
726 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000727
728 return 0;
729}
730
731/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000732static void
paul718e3742002-12-13 20:15:29 +0000733ospf_hello (struct ip *iph, struct ospf_header *ospfh,
734 struct stream * s, struct ospf_interface *oi, int size)
735{
736 struct ospf_hello *hello;
737 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000738 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000739 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000740
741 /* increment statistics. */
742 oi->hello_in++;
743
744 hello = (struct ospf_hello *) STREAM_PNT (s);
745
746 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000747 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000748 {
749 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
750 {
ajs2a42e282004-12-08 18:43:03 +0000751 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000752 "dropping.",
753 ospf_packet_type_str[ospfh->type],
754 inet_ntoa (iph->ip_src));
755 }
756 return;
757 }
paul718e3742002-12-13 20:15:29 +0000758
759 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000760 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000761 char buf[3][INET_ADDRSTRLEN];
paul6d452762005-11-03 11:15:44 +0000762 zlog_debug ("ignoring HELLO from router %s sent to %s, "
763 "received on a passive interface, %s",
764 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
765 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
766 inet_ntop(AF_INET, &oi->address->u.prefix4,
767 buf[2], sizeof(buf[2])));
ajsba6454e2005-02-08 15:37:30 +0000768 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
769 {
770 /* Try to fix multicast membership. */
Paul Jakma429ac782006-06-15 18:40:49 +0000771 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +0000772 ospf_if_set_multicast(oi);
773 }
paul718e3742002-12-13 20:15:29 +0000774 return;
paulf2c80652002-12-13 21:44:27 +0000775 }
paul718e3742002-12-13 20:15:29 +0000776
777 /* get neighbor prefix. */
778 p.family = AF_INET;
779 p.prefixlen = ip_masklen (hello->network_mask);
780 p.u.prefix4 = iph->ip_src;
781
782 /* Compare network mask. */
783 /* Checking is ignored for Point-to-Point and Virtual link. */
784 if (oi->type != OSPF_IFTYPE_POINTOPOINT
785 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
786 if (oi->address->prefixlen != p.prefixlen)
787 {
Andrew J. Schorr13cd3dc2006-07-11 01:50:30 +0000788 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
789 inet_ntoa(ospfh->router_id), IF_NAME(oi),
790 (int)oi->address->prefixlen, (int)p.prefixlen);
paul718e3742002-12-13 20:15:29 +0000791 return;
792 }
793
paul718e3742002-12-13 20:15:29 +0000794 /* Compare Router Dead Interval. */
795 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
796 {
797 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
798 inet_ntoa (ospfh->router_id));
799 return;
800 }
801
paulf9ad9372005-10-21 00:45:17 +0000802 /* Compare Hello Interval - ignored if fast-hellos are set. */
803 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
804 {
805 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
806 {
807 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
808 inet_ntoa (ospfh->router_id));
809 return;
810 }
811 }
812
paul718e3742002-12-13 20:15:29 +0000813 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000814 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000815 inet_ntoa (ospfh->router_id),
816 ospf_options_dump (hello->options));
817
818 /* Compare options. */
819#define REJECT_IF_TBIT_ON 1 /* XXX */
820#ifdef REJECT_IF_TBIT_ON
821 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
822 {
823 /*
824 * This router does not support non-zero TOS.
825 * Drop this Hello packet not to establish neighbor relationship.
826 */
827 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
828 inet_ntoa (ospfh->router_id));
829 return;
830 }
831#endif /* REJECT_IF_TBIT_ON */
832
833#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000834 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000835 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
836 {
837 /*
838 * This router does know the correct usage of O-bit
839 * the bit should be set in DD packet only.
840 */
841 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
842 inet_ntoa (ospfh->router_id));
843#ifdef STRICT_OBIT_USAGE_CHECK
844 return; /* Reject this packet. */
845#else /* STRICT_OBIT_USAGE_CHECK */
846 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
847#endif /* STRICT_OBIT_USAGE_CHECK */
848 }
849#endif /* HAVE_OPAQUE_LSA */
850
851 /* new for NSSA is to ensure that NP is on and E is off */
852
paul718e3742002-12-13 20:15:29 +0000853 if (oi->area->external_routing == OSPF_AREA_NSSA)
854 {
855 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
856 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
857 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
858 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
859 {
860 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
861 return;
862 }
863 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000864 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000865 }
866 else
paul718e3742002-12-13 20:15:29 +0000867 /* The setting of the E-bit found in the Hello Packet's Options
868 field must match this area's ExternalRoutingCapability A
869 mismatch causes processing to stop and the packet to be
870 dropped. The setting of the rest of the bits in the Hello
871 Packet's Options field should be ignored. */
872 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
873 CHECK_FLAG (hello->options, OSPF_OPTION_E))
874 {
ajs3aa8d5f2004-12-11 18:00:06 +0000875 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
876 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000877 return;
878 }
paul718e3742002-12-13 20:15:29 +0000879
pauld3f0d622004-05-05 15:27:15 +0000880 /* get neighbour struct */
881 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
882
883 /* neighbour must be valid, ospf_nbr_get creates if none existed */
884 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000885
886 old_state = nbr->state;
887
888 /* Add event to thread. */
889 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
890
891 /* RFC2328 Section 9.5.1
892 If the router is not eligible to become Designated Router,
893 (snip) It must also send an Hello Packet in reply to an
894 Hello Packet received from any eligible neighbor (other than
895 the current Designated Router and Backup Designated Router). */
896 if (oi->type == OSPF_IFTYPE_NBMA)
897 if (PRIORITY(oi) == 0 && hello->priority > 0
898 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
899 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
900 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
901 OSPF_HELLO_REPLY_DELAY);
902
903 /* on NBMA network type, it happens to receive bidirectional Hello packet
904 without advance 1-Way Received event.
905 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
906 if (oi->type == OSPF_IFTYPE_NBMA &&
907 (old_state == NSM_Down || old_state == NSM_Attempt))
908 {
909 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
910 nbr->priority = hello->priority;
911 nbr->d_router = hello->d_router;
912 nbr->bd_router = hello->bd_router;
913 return;
914 }
915
paul68980082003-03-25 05:07:42 +0000916 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000917 size - OSPF_HELLO_MIN_SIZE))
918 {
919 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
920 nbr->options |= hello->options;
921 }
922 else
923 {
924 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
925 /* Set neighbor information. */
926 nbr->priority = hello->priority;
927 nbr->d_router = hello->d_router;
928 nbr->bd_router = hello->bd_router;
929 return;
930 }
931
932 /* If neighbor itself declares DR and no BDR exists,
933 cause event BackupSeen */
934 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
935 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
936 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
937
938 /* neighbor itself declares BDR. */
939 if (oi->state == ISM_Waiting &&
940 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
941 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
942
943 /* had not previously. */
944 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
945 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
946 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
947 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
948 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
949
950 /* had not previously. */
951 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
952 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
953 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
954 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
955 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
956
957 /* Neighbor priority check. */
958 if (nbr->priority >= 0 && nbr->priority != hello->priority)
959 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
960
961 /* Set neighbor information. */
962 nbr->priority = hello->priority;
963 nbr->d_router = hello->d_router;
964 nbr->bd_router = hello->bd_router;
965}
966
967/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000968static void
paul718e3742002-12-13 20:15:29 +0000969ospf_db_desc_save_current (struct ospf_neighbor *nbr,
970 struct ospf_db_desc *dd)
971{
972 nbr->last_recv.flags = dd->flags;
973 nbr->last_recv.options = dd->options;
974 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
975}
976
977/* Process rest of DD packet. */
978static void
979ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
980 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
981 u_int16_t size)
982{
983 struct ospf_lsa *new, *find;
984 struct lsa_header *lsah;
985
paul9985f832005-02-09 15:51:56 +0000986 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000987 for (size -= OSPF_DB_DESC_MIN_SIZE;
988 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
989 {
990 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000991 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000992
993 /* Unknown LS type. */
994 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
995 {
ajsbec595a2004-11-30 22:38:43 +0000996 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000997 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
998 return;
999 }
1000
1001#ifdef HAVE_OPAQUE_LSA
1002 if (IS_OPAQUE_LSA (lsah->type)
1003 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1004 {
1005 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1006 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1007 return;
1008 }
1009#endif /* HAVE_OPAQUE_LSA */
1010
1011 switch (lsah->type)
1012 {
1013 case OSPF_AS_EXTERNAL_LSA:
1014#ifdef HAVE_OPAQUE_LSA
1015 case OSPF_OPAQUE_AS_LSA:
1016#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001017 /* Check for stub area. Reject if AS-External from stub but
1018 allow if from NSSA. */
1019 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001020 {
1021 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1022 lsah->type, inet_ntoa (lsah->id),
1023 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1024 "STUB" : "NSSA");
1025 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1026 return;
1027 }
1028 break;
1029 default:
1030 break;
1031 }
1032
1033 /* Create LS-request object. */
1034 new = ospf_ls_request_new (lsah);
1035
1036 /* Lookup received LSA, then add LS request list. */
1037 find = ospf_lsa_lookup_by_header (oi->area, lsah);
Paul Jakmaf0894cf2006-08-27 06:40:04 +00001038
1039 /* ospf_lsa_more_recent is fine with NULL pointers */
1040 switch (ospf_lsa_more_recent (find, new))
1041 {
1042 case -1:
1043 /* Neighbour has a more recent LSA, we must request it */
1044 ospf_ls_request_add (nbr, new);
1045 case 0:
1046 /* If we have a copy of this LSA, it's either less recent
1047 * and we're requesting it from neighbour (the case above), or
1048 * it's as recent and we both have same copy (this case).
1049 *
1050 * In neither of these two cases is there any point in
1051 * describing our copy of the LSA to the neighbour in a
1052 * DB-Summary packet, if we're still intending to do so.
1053 *
1054 * See: draft-ogier-ospf-dbex-opt-00.txt, describing the
1055 * backward compatible optimisation to OSPF DB Exchange /
1056 * DB Description process implemented here.
1057 */
1058 if (find)
1059 ospf_lsdb_delete (&nbr->db_sum, find);
1060 ospf_lsa_discard (new);
1061 break;
1062 default:
1063 /* We have the more recent copy, nothing specific to do:
1064 * - no need to request neighbours stale copy
1065 * - must leave DB summary list copy alone
1066 */
1067 if (IS_DEBUG_OSPF_EVENT)
1068 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
1069 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1070 ospf_lsa_discard (new);
1071 }
paul718e3742002-12-13 20:15:29 +00001072 }
1073
1074 /* Master */
1075 if (IS_SET_DD_MS (nbr->dd_flags))
1076 {
1077 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001078
1079 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001080 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1081 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1082 else
paul718e3742002-12-13 20:15:29 +00001083 ospf_db_desc_send (nbr);
1084 }
1085 /* Slave */
1086 else
1087 {
1088 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1089
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001090 /* Send DD packet in reply.
1091 *
1092 * Must be done to acknowledge the Master's DD, regardless of
1093 * whether we have more LSAs ourselves to describe.
1094 *
1095 * This function will clear the 'More' bit, if after this DD
1096 * we have no more LSAs to describe to the master..
1097 */
paul718e3742002-12-13 20:15:29 +00001098 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001099
1100 /* Slave can raise ExchangeDone now, if master is also done */
1101 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1102 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001103 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001104
paul718e3742002-12-13 20:15:29 +00001105 /* Save received neighbor values from DD. */
1106 ospf_db_desc_save_current (nbr, dd);
1107}
1108
paul4dadc292005-05-06 21:37:42 +00001109static int
paul718e3742002-12-13 20:15:29 +00001110ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1111{
1112 /* Is DD duplicated? */
1113 if (dd->options == nbr->last_recv.options &&
1114 dd->flags == nbr->last_recv.flags &&
1115 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1116 return 1;
1117
1118 return 0;
1119}
1120
1121/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001122static void
paul718e3742002-12-13 20:15:29 +00001123ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1124 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1125{
1126 struct ospf_db_desc *dd;
1127 struct ospf_neighbor *nbr;
1128
1129 /* Increment statistics. */
1130 oi->db_desc_in++;
1131
1132 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001133
pauld3f0d622004-05-05 15:27:15 +00001134 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001135 if (nbr == NULL)
1136 {
1137 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1138 inet_ntoa (ospfh->router_id));
1139 return;
1140 }
1141
1142 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001143 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1144 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001145 {
ajs3aa8d5f2004-12-11 18:00:06 +00001146 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1147 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1148 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001149 return;
1150 }
1151
pauld363df22003-06-19 00:26:34 +00001152 /*
1153 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1154 * required. In fact at least JunOS sends DD packets with P bit clear.
1155 * Until proper solution is developped, this hack should help.
1156 *
1157 * Update: According to the RFCs, N bit is specified /only/ for Hello
1158 * options, unfortunately its use in DD options is not specified. Hence some
1159 * implementations follow E-bit semantics and set it in DD options, and some
1160 * treat it as unspecified and hence follow the directive "default for
1161 * options is clear", ie unset.
1162 *
1163 * Reset the flag, as ospfd follows E-bit semantics.
1164 */
1165 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1166 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1167 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1168 {
1169 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001170 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001171 inet_ntoa (nbr->router_id) );
1172 SET_FLAG (dd->options, OSPF_OPTION_NP);
1173 }
pauld363df22003-06-19 00:26:34 +00001174
paul718e3742002-12-13 20:15:29 +00001175#ifdef REJECT_IF_TBIT_ON
1176 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1177 {
1178 /*
1179 * In Hello protocol, optional capability must have checked
1180 * to prevent this T-bit enabled router be my neighbor.
1181 */
1182 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1183 return;
1184 }
1185#endif /* REJECT_IF_TBIT_ON */
1186
1187#ifdef HAVE_OPAQUE_LSA
1188 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001189 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001190 {
1191 /*
1192 * This node is not configured to handle O-bit, for now.
1193 * Clear it to ignore unsupported capability proposed by neighbor.
1194 */
1195 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1196 }
1197#endif /* HAVE_OPAQUE_LSA */
1198
1199 /* Process DD packet by neighbor status. */
1200 switch (nbr->state)
1201 {
1202 case NSM_Down:
1203 case NSM_Attempt:
1204 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001205 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001206 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001207 LOOKUP (ospf_nsm_state_msg, nbr->state));
1208 break;
1209 case NSM_Init:
1210 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1211 /* If the new state is ExStart, the processing of the current
1212 packet should then continue in this new state by falling
1213 through to case ExStart below. */
1214 if (nbr->state != NSM_ExStart)
1215 break;
1216 case NSM_ExStart:
1217 /* Initial DBD */
1218 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1219 (size == OSPF_DB_DESC_MIN_SIZE))
1220 {
paul68980082003-03-25 05:07:42 +00001221 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001222 {
1223 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001224 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001225 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001226 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001227
1228 /* Reset I/MS */
1229 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001230 }
1231 else
1232 {
1233 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001234 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001235 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001236 break;
1237 }
1238 }
1239 /* Ack from the Slave */
1240 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1241 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001242 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001243 {
ajs17eaa722004-12-29 21:04:48 +00001244 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001245 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001246 /* Reset I, leaving MS */
1247 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001248 }
1249 else
1250 {
ajs3aa8d5f2004-12-11 18:00:06 +00001251 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1252 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001253 break;
1254 }
1255
1256 /* This is where the real Options are saved */
1257 nbr->options = dd->options;
1258
1259#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001260 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001261 {
1262 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001263 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001264 inet_ntoa (nbr->router_id),
1265 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1266
1267 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1268 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1269 {
paul6d452762005-11-03 11:15:44 +00001270 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1271 "Opaque-LSAs cannot be reliably advertised "
1272 "in this network.",
1273 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001274 /* This situation is undesirable, but not a real error. */
1275 }
1276 }
1277#endif /* HAVE_OPAQUE_LSA */
1278
1279 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1280
1281 /* continue processing rest of packet. */
1282 ospf_db_desc_proc (s, oi, nbr, dd, size);
1283 break;
1284 case NSM_Exchange:
1285 if (ospf_db_desc_is_dup (dd, nbr))
1286 {
1287 if (IS_SET_DD_MS (nbr->dd_flags))
1288 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001289 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001290 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001291 else
1292 /* Slave: cause to retransmit the last Database Description. */
1293 {
paul6d452762005-11-03 11:15:44 +00001294 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001295 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001296 ospf_db_desc_resend (nbr);
1297 }
1298 break;
1299 }
1300
1301 /* Otherwise DD packet should be checked. */
1302 /* Check Master/Slave bit mismatch */
1303 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1304 {
ajs3aa8d5f2004-12-11 18:00:06 +00001305 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1306 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001307 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1308 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001309 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001310 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001311 break;
1312 }
1313
1314 /* Check initialize bit is set. */
1315 if (IS_SET_DD_I (dd->flags))
1316 {
paul6d452762005-11-03 11:15:44 +00001317 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001318 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001319 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1320 break;
1321 }
1322
1323 /* Check DD Options. */
1324 if (dd->options != nbr->options)
1325 {
1326#ifdef ORIGINAL_CODING
1327 /* Save the new options for debugging */
1328 nbr->options = dd->options;
1329#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001330 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1331 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001332 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1333 break;
1334 }
1335
1336 /* Check DD sequence number. */
1337 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1338 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1339 (!IS_SET_DD_MS (nbr->dd_flags) &&
1340 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1341 {
ajs3aa8d5f2004-12-11 18:00:06 +00001342 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1343 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001344 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1345 break;
1346 }
1347
1348 /* Continue processing rest of packet. */
1349 ospf_db_desc_proc (s, oi, nbr, dd, size);
1350 break;
1351 case NSM_Loading:
1352 case NSM_Full:
1353 if (ospf_db_desc_is_dup (dd, nbr))
1354 {
1355 if (IS_SET_DD_MS (nbr->dd_flags))
1356 {
1357 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001358 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1359 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001360 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001361 break;
1362 }
1363 else
1364 {
1365 struct timeval t, now;
1366 gettimeofday (&now, NULL);
1367 t = tv_sub (now, nbr->last_send_ts);
1368 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1369 {
1370 /* In states Loading and Full the slave must resend
1371 its last Database Description packet in response to
1372 duplicate Database Description packets received
1373 from the master. For this reason the slave must
1374 wait RouterDeadInterval seconds before freeing the
1375 last Database Description packet. Reception of a
1376 Database Description packet from the master after
1377 this interval will generate a SeqNumberMismatch
1378 neighbor event. RFC2328 Section 10.8 */
1379 ospf_db_desc_resend (nbr);
1380 break;
1381 }
1382 }
1383 }
1384
1385 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1386 break;
1387 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001388 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1389 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001390 break;
1391 }
1392}
1393
1394#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1395
1396/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001397static void
paul718e3742002-12-13 20:15:29 +00001398ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1399 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1400{
1401 struct ospf_neighbor *nbr;
1402 u_int32_t ls_type;
1403 struct in_addr ls_id;
1404 struct in_addr adv_router;
1405 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001406 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001407 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001408
1409 /* Increment statistics. */
1410 oi->ls_req_in++;
1411
pauld3f0d622004-05-05 15:27:15 +00001412 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001413 if (nbr == NULL)
1414 {
1415 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1416 inet_ntoa (ospfh->router_id));
1417 return;
1418 }
1419
1420 /* Neighbor State should be Exchange or later. */
1421 if (nbr->state != NSM_Exchange &&
1422 nbr->state != NSM_Loading &&
1423 nbr->state != NSM_Full)
1424 {
ajsbec595a2004-11-30 22:38:43 +00001425 zlog_warn ("Link State Request received from %s: "
1426 "Neighbor state is %s, packet discarded.",
1427 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001428 LOOKUP (ospf_nsm_state_msg, nbr->state));
1429 return;
1430 }
1431
1432 /* Send Link State Update for ALL requested LSAs. */
1433 ls_upd = list_new ();
1434 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1435
1436 while (size >= OSPF_LSA_KEY_SIZE)
1437 {
1438 /* Get one slice of Link State Request. */
1439 ls_type = stream_getl (s);
1440 ls_id.s_addr = stream_get_ipv4 (s);
1441 adv_router.s_addr = stream_get_ipv4 (s);
1442
1443 /* Verify LSA type. */
1444 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1445 {
1446 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1447 list_delete (ls_upd);
1448 return;
1449 }
1450
1451 /* Search proper LSA in LSDB. */
1452 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1453 if (find == NULL)
1454 {
1455 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1456 list_delete (ls_upd);
1457 return;
1458 }
1459
gdt86f1fd92005-01-10 14:20:43 +00001460 /* Packet overflows MTU size, send immediately. */
1461 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001462 {
1463 if (oi->type == OSPF_IFTYPE_NBMA)
1464 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1465 else
1466 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1467
1468 /* Only remove list contents. Keep ls_upd. */
1469 list_delete_all_node (ls_upd);
1470
1471 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1472 }
1473
1474 /* Append LSA to update list. */
1475 listnode_add (ls_upd, find);
1476 length += ntohs (find->data->length);
1477
1478 size -= OSPF_LSA_KEY_SIZE;
1479 }
1480
1481 /* Send rest of Link State Update. */
1482 if (listcount (ls_upd) > 0)
1483 {
1484 if (oi->type == OSPF_IFTYPE_NBMA)
1485 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1486 else
1487 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1488
1489 list_delete (ls_upd);
1490 }
1491 else
1492 list_free (ls_upd);
1493}
1494
1495/* Get the list of LSAs from Link State Update packet.
1496 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001497static struct list *
paul718e3742002-12-13 20:15:29 +00001498ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1499 struct ospf_interface *oi, size_t size)
1500{
1501 u_int16_t count, sum;
1502 u_int32_t length;
1503 struct lsa_header *lsah;
1504 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001505 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001506
1507 lsas = list_new ();
1508
1509 count = stream_getl (s);
1510 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1511
1512 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001513 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001514 {
1515 lsah = (struct lsa_header *) STREAM_PNT (s);
1516 length = ntohs (lsah->length);
1517
1518 if (length > size)
1519 {
1520 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1521 break;
1522 }
1523
1524 /* Validate the LSA's LS checksum. */
1525 sum = lsah->checksum;
1526 if (sum != ospf_lsa_checksum (lsah))
1527 {
1528 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1529 sum, lsah->checksum);
1530 continue;
1531 }
1532
1533 /* Examine the LSA's LS type. */
1534 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1535 {
1536 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1537 continue;
1538 }
1539
1540 /*
1541 * What if the received LSA's age is greater than MaxAge?
1542 * Treat it as a MaxAge case -- endo.
1543 */
1544 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1545 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1546
1547#ifdef HAVE_OPAQUE_LSA
1548 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1549 {
1550#ifdef STRICT_OBIT_USAGE_CHECK
1551 if ((IS_OPAQUE_LSA(lsah->type) &&
1552 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1553 || (! IS_OPAQUE_LSA(lsah->type) &&
1554 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1555 {
1556 /*
1557 * This neighbor must know the exact usage of O-bit;
1558 * the bit will be set in Type-9,10,11 LSAs only.
1559 */
1560 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1561 continue;
1562 }
1563#endif /* STRICT_OBIT_USAGE_CHECK */
1564
1565 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1566 if (lsah->type == OSPF_OPAQUE_AS_LSA
1567 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1568 {
1569 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001570 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 +00001571 continue;
1572 }
1573 }
1574 else if (IS_OPAQUE_LSA(lsah->type))
1575 {
1576 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1577 continue;
1578 }
1579#endif /* HAVE_OPAQUE_LSA */
1580
1581 /* Create OSPF LSA instance. */
1582 lsa = ospf_lsa_new ();
1583
1584 /* We may wish to put some error checking if type NSSA comes in
1585 and area not in NSSA mode */
1586 switch (lsah->type)
1587 {
1588 case OSPF_AS_EXTERNAL_LSA:
1589#ifdef HAVE_OPAQUE_LSA
1590 case OSPF_OPAQUE_AS_LSA:
1591 lsa->area = NULL;
1592 break;
1593 case OSPF_OPAQUE_LINK_LSA:
1594 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1595 /* Fallthrough */
1596#endif /* HAVE_OPAQUE_LSA */
1597 default:
1598 lsa->area = oi->area;
1599 break;
1600 }
1601
1602 lsa->data = ospf_lsa_data_new (length);
1603 memcpy (lsa->data, lsah, length);
1604
1605 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001606 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001607 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1608 listnode_add (lsas, lsa);
1609 }
1610
1611 return lsas;
1612}
1613
1614/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001615static void
hasso52dc7ee2004-09-23 19:18:23 +00001616ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001617{
paul1eb8ef22005-04-07 07:30:20 +00001618 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001619 struct ospf_lsa *lsa;
1620
paul1eb8ef22005-04-07 07:30:20 +00001621 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1622 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001623
1624 list_delete (lsas);
1625}
1626
1627/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001628static void
paul718e3742002-12-13 20:15:29 +00001629ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1630 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1631{
1632 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001633 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001634 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001635 struct ospf_lsa *lsa = NULL;
1636 /* unsigned long ls_req_found = 0; */
1637
1638 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1639
1640 /* Increment statistics. */
1641 oi->ls_upd_in++;
1642
1643 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001644 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001645 if (nbr == NULL)
1646 {
1647 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1648 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1649 return;
1650 }
1651
1652 /* Check neighbor state. */
1653 if (nbr->state < NSM_Exchange)
1654 {
ajs3aa8d5f2004-12-11 18:00:06 +00001655 zlog_warn ("Link State Update: "
1656 "Neighbor[%s] state %s is less than Exchange",
1657 inet_ntoa (ospfh->router_id),
1658 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001659 return;
1660 }
1661
1662 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1663 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1664 * of section 13.
1665 */
1666 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1667
1668#ifdef HAVE_OPAQUE_LSA
1669 /*
paul718e3742002-12-13 20:15:29 +00001670 * If self-originated Opaque-LSAs that have flooded before restart
1671 * are contained in the received LSUpd message, corresponding LSReq
1672 * messages to be sent may have to be modified.
1673 * To eliminate possible race conditions such that flushing and normal
1674 * updating for the same LSA would take place alternately, this trick
1675 * must be done before entering to the loop below.
1676 */
paul69310a62005-05-11 18:09:59 +00001677 /* XXX: Why is this Opaque specific? Either our core code is deficient
1678 * and this should be fixed generally, or Opaque is inventing strawman
1679 * problems */
paul718e3742002-12-13 20:15:29 +00001680 ospf_opaque_adjust_lsreq (nbr, lsas);
1681#endif /* HAVE_OPAQUE_LSA */
1682
1683#define DISCARD_LSA(L,N) {\
1684 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001685 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 +00001686 ospf_lsa_discard (L); \
1687 continue; }
1688
1689 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001690 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001691 {
1692 struct ospf_lsa *ls_ret, *current;
1693 int ret = 1;
1694
paul718e3742002-12-13 20:15:29 +00001695 if (IS_DEBUG_OSPF_NSSA)
1696 {
1697 char buf1[INET_ADDRSTRLEN];
1698 char buf2[INET_ADDRSTRLEN];
1699 char buf3[INET_ADDRSTRLEN];
1700
ajs2a42e282004-12-08 18:43:03 +00001701 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001702 lsa->data->type,
1703 inet_ntop (AF_INET, &ospfh->router_id,
1704 buf1, INET_ADDRSTRLEN),
1705 inet_ntop (AF_INET, &lsa->data->id,
1706 buf2, INET_ADDRSTRLEN),
1707 inet_ntop (AF_INET, &lsa->data->adv_router,
1708 buf3, INET_ADDRSTRLEN));
1709 }
paul718e3742002-12-13 20:15:29 +00001710
1711 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1712
1713 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1714
1715 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1716
1717 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1718
1719 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1720
1721 /* Do take in Type-7's if we are an NSSA */
1722
1723 /* If we are also an ABR, later translate them to a Type-5 packet */
1724
1725 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1726 translate them to a separate Type-5 packet. */
1727
1728 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1729 /* Reject from STUB or NSSA */
1730 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1731 {
1732 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001733 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001734 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001735 }
1736
paul718e3742002-12-13 20:15:29 +00001737 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1738 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1739 {
1740 DISCARD_LSA (lsa,2);
1741 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001742 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001743 }
paul718e3742002-12-13 20:15:29 +00001744
1745 /* Find the LSA in the current database. */
1746
1747 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1748
1749 /* If the LSA's LS age is equal to MaxAge, and there is currently
1750 no instance of the LSA in the router's link state database,
1751 and none of router's neighbors are in states Exchange or Loading,
1752 then take the following actions. */
1753
1754 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001755 (ospf_nbr_count (oi, NSM_Exchange) +
1756 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001757 {
1758 /* Response Link State Acknowledgment. */
1759 ospf_ls_ack_send (nbr, lsa);
1760
1761 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001762 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1763 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001764 DISCARD_LSA (lsa, 3);
1765 }
1766
1767#ifdef HAVE_OPAQUE_LSA
1768 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001769 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001770 {
1771 /*
1772 * Even if initial flushing seems to be completed, there might
1773 * be a case that self-originated LSA with MaxAge still remain
1774 * in the routing domain.
1775 * Just send an LSAck message to cease retransmission.
1776 */
1777 if (IS_LSA_MAXAGE (lsa))
1778 {
1779 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1780 ospf_ls_ack_send (nbr, lsa);
1781 ospf_lsa_discard (lsa);
1782
1783 if (current != NULL && ! IS_LSA_MAXAGE (current))
1784 ospf_opaque_lsa_refresh_schedule (current);
1785 continue;
1786 }
1787
1788 /*
1789 * If an instance of self-originated Opaque-LSA is not found
1790 * in the LSDB, there are some possible cases here.
1791 *
1792 * 1) This node lost opaque-capability after restart.
1793 * 2) Else, a part of opaque-type is no more supported.
1794 * 3) Else, a part of opaque-id is no more supported.
1795 *
1796 * Anyway, it is still this node's responsibility to flush it.
1797 * Otherwise, the LSA instance remains in the routing domain
1798 * until its age reaches to MaxAge.
1799 */
paul69310a62005-05-11 18:09:59 +00001800 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001801 if (current == NULL)
1802 {
1803 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001804 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1805 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001806
1807 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001808
1809 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1810 ospf_ls_ack_send (nbr, lsa);
1811
paul718e3742002-12-13 20:15:29 +00001812 continue;
1813 }
1814 }
1815#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001816
hassocb05eb22004-02-11 21:10:19 +00001817 /* It might be happen that received LSA is self-originated network LSA, but
1818 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1819 * Link State ID is one of the router's own IP interface addresses but whose
1820 * Advertising Router is not equal to the router's own Router ID
1821 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1822 */
1823
1824 if(lsa->data->type == OSPF_NETWORK_LSA)
1825 {
paul1eb8ef22005-04-07 07:30:20 +00001826 struct listnode *oinode, *oinnode;
1827 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001828 int Flag = 0;
1829
paul1eb8ef22005-04-07 07:30:20 +00001830 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001831 {
hassocb05eb22004-02-11 21:10:19 +00001832 if(out_if == NULL)
1833 break;
1834
1835 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1836 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1837 {
1838 if(out_if->network_lsa_self)
1839 {
1840 ospf_lsa_flush_area(lsa,out_if->area);
1841 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001842 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001843 lsa, (int) lsa->data->type);
1844 ospf_lsa_discard (lsa);
1845 Flag = 1;
1846 }
1847 break;
1848 }
1849 }
1850 if(Flag)
1851 continue;
1852 }
paul718e3742002-12-13 20:15:29 +00001853
1854 /* (5) Find the instance of this LSA that is currently contained
1855 in the router's link state database. If there is no
1856 database copy, or the received LSA is more recent than
1857 the database copy the following steps must be performed. */
1858
1859 if (current == NULL ||
1860 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1861 {
1862 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001863 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001864 DISCARD_LSA (lsa, 4);
1865 continue;
1866 }
1867
1868 /* (6) Else, If there is an instance of the LSA on the sending
1869 neighbor's Link state request list, an error has occurred in
1870 the Database Exchange process. In this case, restart the
1871 Database Exchange process by generating the neighbor event
1872 BadLSReq for the sending neighbor and stop processing the
1873 Link State Update packet. */
1874
1875 if (ospf_ls_request_lookup (nbr, lsa))
1876 {
1877 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001878 zlog_warn("LSA[%s] instance exists on Link state request list",
1879 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001880
1881 /* Clean list of LSAs. */
1882 ospf_upd_list_clean (lsas);
1883 /* this lsa is not on lsas list already. */
1884 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001885 return;
1886 }
1887
1888 /* If the received LSA is the same instance as the database copy
1889 (i.e., neither one is more recent) the following two steps
1890 should be performed: */
1891
1892 if (ret == 0)
1893 {
1894 /* If the LSA is listed in the Link state retransmission list
1895 for the receiving adjacency, the router itself is expecting
1896 an acknowledgment for this LSA. The router should treat the
1897 received LSA as an acknowledgment by removing the LSA from
1898 the Link state retransmission list. This is termed an
1899 "implied acknowledgment". */
1900
1901 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1902
1903 if (ls_ret != NULL)
1904 {
1905 ospf_ls_retransmit_delete (nbr, ls_ret);
1906
1907 /* Delayed acknowledgment sent if advertisement received
1908 from Designated Router, otherwise do nothing. */
1909 if (oi->state == ISM_Backup)
1910 if (NBR_IS_DR (nbr))
1911 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1912
1913 DISCARD_LSA (lsa, 5);
1914 }
1915 else
1916 /* Acknowledge the receipt of the LSA by sending a
1917 Link State Acknowledgment packet back out the receiving
1918 interface. */
1919 {
1920 ospf_ls_ack_send (nbr, lsa);
1921 DISCARD_LSA (lsa, 6);
1922 }
1923 }
1924
1925 /* The database copy is more recent. If the database copy
1926 has LS age equal to MaxAge and LS sequence number equal to
1927 MaxSequenceNumber, simply discard the received LSA without
1928 acknowledging it. (In this case, the LSA's LS sequence number is
1929 wrapping, and the MaxSequenceNumber LSA must be completely
1930 flushed before any new LSA instance can be introduced). */
1931
1932 else if (ret > 0) /* Database copy is more recent */
1933 {
1934 if (IS_LSA_MAXAGE (current) &&
1935 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1936 {
1937 DISCARD_LSA (lsa, 7);
1938 }
1939 /* Otherwise, as long as the database copy has not been sent in a
1940 Link State Update within the last MinLSArrival seconds, send the
1941 database copy back to the sending neighbor, encapsulated within
1942 a Link State Update Packet. The Link State Update Packet should
1943 be sent directly to the neighbor. In so doing, do not put the
1944 database copy of the LSA on the neighbor's link state
1945 retransmission list, and do not acknowledge the received (less
1946 recent) LSA instance. */
1947 else
1948 {
1949 struct timeval now;
1950
1951 gettimeofday (&now, NULL);
1952
1953 if (tv_cmp (tv_sub (now, current->tv_orig),
1954 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1955 /* Trap NSSA type later.*/
1956 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1957 DISCARD_LSA (lsa, 8);
1958 }
1959 }
1960 }
1961
paul718e3742002-12-13 20:15:29 +00001962 assert (listcount (lsas) == 0);
1963 list_delete (lsas);
1964}
1965
1966/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001967static void
paul718e3742002-12-13 20:15:29 +00001968ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1969 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1970{
1971 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001972
paul718e3742002-12-13 20:15:29 +00001973 /* increment statistics. */
1974 oi->ls_ack_in++;
1975
pauld3f0d622004-05-05 15:27:15 +00001976 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001977 if (nbr == NULL)
1978 {
1979 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1980 inet_ntoa (ospfh->router_id));
1981 return;
1982 }
1983
1984 if (nbr->state < NSM_Exchange)
1985 {
ajs3aa8d5f2004-12-11 18:00:06 +00001986 zlog_warn ("Link State Acknowledgment: "
1987 "Neighbor[%s] state %s is less than Exchange",
1988 inet_ntoa (ospfh->router_id),
1989 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001990 return;
1991 }
paul69310a62005-05-11 18:09:59 +00001992
paul718e3742002-12-13 20:15:29 +00001993 while (size >= OSPF_LSA_HEADER_SIZE)
1994 {
1995 struct ospf_lsa *lsa, *lsr;
1996
1997 lsa = ospf_lsa_new ();
1998 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1999
2000 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
2001 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00002002 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002003
2004 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2005 {
2006 lsa->data = NULL;
2007 ospf_lsa_discard (lsa);
2008 continue;
2009 }
2010
2011 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2012
2013 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2014 {
2015#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00002016 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00002017 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00002018#endif /* HAVE_OPAQUE_LSA */
2019
2020 ospf_ls_retransmit_delete (nbr, lsr);
2021 }
2022
2023 lsa->data = NULL;
2024 ospf_lsa_discard (lsa);
2025 }
2026
paul718e3742002-12-13 20:15:29 +00002027 return;
paul718e3742002-12-13 20:15:29 +00002028}
2029
ajs038163f2005-02-17 19:55:59 +00002030static struct stream *
ajs5c333492005-02-23 15:43:01 +00002031ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002032{
2033 int ret;
ajs5c333492005-02-23 15:43:01 +00002034 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002035 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002036 unsigned int ifindex = 0;
2037 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002038 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002039 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002040 struct msghdr msgh;
2041
paul68defd62004-09-27 07:27:13 +00002042 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002043 msgh.msg_iov = &iov;
2044 msgh.msg_iovlen = 1;
2045 msgh.msg_control = (caddr_t) buff;
2046 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002047
ajs5c333492005-02-23 15:43:01 +00002048 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2049 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002050 {
ajs5c333492005-02-23 15:43:01 +00002051 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2052 return NULL;
2053 }
paul69310a62005-05-11 18:09:59 +00002054 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002055 {
2056 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2057 "(ip header size is %u)",
2058 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002059 return NULL;
2060 }
paul18b12c32004-10-05 14:38:29 +00002061
ajs5c333492005-02-23 15:43:01 +00002062 /* Note that there should not be alignment problems with this assignment
2063 because this is at the beginning of the stream data buffer. */
2064 iph = (struct ip *) STREAM_DATA(ibuf);
2065 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002066
ajs5c333492005-02-23 15:43:01 +00002067 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002068
paul239aecc2003-12-08 10:34:54 +00002069#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002070 /*
2071 * Kernel network code touches incoming IP header parameters,
2072 * before protocol specific processing.
2073 *
2074 * 1) Convert byteorder to host representation.
2075 * --> ip_len, ip_id, ip_off
2076 *
2077 * 2) Adjust ip_len to strip IP header size!
2078 * --> If user process receives entire IP packet via RAW
2079 * socket, it must consider adding IP header size to
2080 * the "ip_len" field of "ip" structure.
2081 *
2082 * For more details, see <netinet/ip_input.c>.
2083 */
ajs5c333492005-02-23 15:43:01 +00002084 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002085#endif
2086
paul863082d2004-08-19 04:43:43 +00002087 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002088
2089 *ifp = if_lookup_by_index (ifindex);
2090
2091 if (ret != ip_len)
2092 {
ajs5c333492005-02-23 15:43:01 +00002093 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2094 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002095 return NULL;
2096 }
2097
2098 return ibuf;
2099}
2100
paul4dadc292005-05-06 21:37:42 +00002101static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002102ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002103 struct ip *iph, struct ospf_header *ospfh)
2104{
2105 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002106 struct ospf_vl_data *vl_data;
2107 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002108 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002109
2110 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2111 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002112 return NULL;
paul718e3742002-12-13 20:15:29 +00002113
pauld3f0d622004-05-05 15:27:15 +00002114 /* look for local OSPF interface matching the destination
2115 * to determine Area ID. We presume therefore the destination address
2116 * is unique, or at least (for "unnumbered" links), not used in other
2117 * areas
2118 */
2119 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2120 iph->ip_dst)) == NULL)
2121 return NULL;
paul718e3742002-12-13 20:15:29 +00002122
paul1eb8ef22005-04-07 07:30:20 +00002123 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002124 {
paul020709f2003-04-04 02:44:16 +00002125 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002126 if (!vl_area)
2127 continue;
2128
2129 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2130 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2131 {
2132 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002133 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002134 IF_NAME (vl_data->vl_oi));
2135 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2136 {
2137 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002138 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002139 return NULL;
2140 }
2141
2142 return vl_data->vl_oi;
2143 }
2144 }
2145
2146 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002147 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002148
pauld3f0d622004-05-05 15:27:15 +00002149 return NULL;
paul718e3742002-12-13 20:15:29 +00002150}
2151
paul4dadc292005-05-06 21:37:42 +00002152static inline int
paul718e3742002-12-13 20:15:29 +00002153ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2154{
2155 /* Check match the Area ID of the receiving interface. */
2156 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2157 return 1;
2158
2159 return 0;
2160}
2161
2162/* Unbound socket will accept any Raw IP packets if proto is matched.
2163 To prevent it, compare src IP address and i/f address with masking
2164 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002165static int
paul718e3742002-12-13 20:15:29 +00002166ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2167{
2168 struct in_addr mask, me, him;
2169
2170 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2171 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2172 return 1;
2173
2174 masklen2ip (oi->address->prefixlen, &mask);
2175
2176 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2177 him.s_addr = ip_src.s_addr & mask.s_addr;
2178
2179 if (IPV4_ADDR_SAME (&me, &him))
2180 return 1;
2181
2182 return 0;
2183}
2184
paul4dadc292005-05-06 21:37:42 +00002185static int
paul718e3742002-12-13 20:15:29 +00002186ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2187 struct ospf_header *ospfh)
2188{
2189 int ret = 0;
2190 struct crypt_key *ck;
2191
2192 switch (ntohs (ospfh->auth_type))
2193 {
2194 case OSPF_AUTH_NULL:
2195 ret = 1;
2196 break;
2197 case OSPF_AUTH_SIMPLE:
2198 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2199 ret = 1;
2200 else
2201 ret = 0;
2202 break;
2203 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002204 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002205 {
2206 ret = 0;
2207 break;
2208 }
2209
2210 /* This is very basic, the digest processing is elsewhere */
2211 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2212 ospfh->u.crypt.key_id == ck->key_id &&
2213 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2214 ret = 1;
2215 else
2216 ret = 0;
2217 break;
2218 default:
2219 ret = 0;
2220 break;
2221 }
2222
2223 return ret;
2224}
2225
paul4dadc292005-05-06 21:37:42 +00002226static int
paul718e3742002-12-13 20:15:29 +00002227ospf_check_sum (struct ospf_header *ospfh)
2228{
2229 u_int32_t ret;
2230 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002231
2232 /* clear auth_data for checksum. */
2233 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2234
2235 /* keep checksum and clear. */
2236 sum = ospfh->checksum;
2237 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2238
2239 /* calculate checksum. */
2240 ret = in_cksum (ospfh, ntohs (ospfh->length));
2241
2242 if (ret != sum)
2243 {
2244 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2245 ret, sum);
2246 return 0;
2247 }
2248
2249 return 1;
2250}
2251
2252/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002253static int
paul718e3742002-12-13 20:15:29 +00002254ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2255 struct ip *iph, struct ospf_header *ospfh)
2256{
2257 /* check version. */
2258 if (ospfh->version != OSPF_VERSION)
2259 {
2260 zlog_warn ("interface %s: ospf_read version number mismatch.",
2261 IF_NAME (oi));
2262 return -1;
2263 }
2264
2265 /* Check Area ID. */
2266 if (!ospf_check_area_id (oi, ospfh))
2267 {
2268 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2269 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2270 return -1;
2271 }
2272
2273 /* Check network mask, Silently discarded. */
2274 if (! ospf_check_network_mask (oi, iph->ip_src))
2275 {
2276 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2277 IF_NAME (oi), inet_ntoa (iph->ip_src));
2278 return -1;
2279 }
2280
2281 /* Check authentication. */
2282 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2283 {
paulc6371712006-01-17 17:49:53 +00002284 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2285 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002286 return -1;
2287 }
2288
2289 if (! ospf_check_auth (oi, ibuf, ospfh))
2290 {
2291 zlog_warn ("interface %s: ospf_read authentication failed.",
2292 IF_NAME (oi));
2293 return -1;
2294 }
2295
2296 /* if check sum is invalid, packet is discarded. */
2297 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2298 {
2299 if (! ospf_check_sum (ospfh))
2300 {
2301 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2302 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2303 return -1;
2304 }
2305 }
2306 else
2307 {
2308 if (ospfh->checksum != 0)
2309 return -1;
2310 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2311 {
2312 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2313 IF_NAME (oi));
2314 return -1;
2315 }
2316 }
2317
2318 return 0;
2319}
2320
2321/* Starting point of packet process function. */
2322int
2323ospf_read (struct thread *thread)
2324{
2325 int ret;
2326 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002327 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002328 struct ospf_interface *oi;
2329 struct ip *iph;
2330 struct ospf_header *ospfh;
2331 u_int16_t length;
2332 struct interface *ifp;
2333
2334 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002335 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002336
2337 /* prepare for next packet. */
2338 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002339
2340 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002341 stream_reset(ospf->ibuf);
2342 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002343 return -1;
2344
ajs5c333492005-02-23 15:43:01 +00002345 /* Note that there should not be alignment problems with this assignment
2346 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002347 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002348 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002349
paulac191232004-10-22 12:05:17 +00002350 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002351 /* Handle cases where the platform does not support retrieving the ifindex,
2352 and also platforms (such as Solaris 8) that claim to support ifindex
2353 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002354 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002355
pauld3f0d622004-05-05 15:27:15 +00002356 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002357 return 0;
paul718e3742002-12-13 20:15:29 +00002358
2359 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002360 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002361 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002362
paul718e3742002-12-13 20:15:29 +00002363 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002364 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002365 {
pauld3241812003-09-29 12:42:39 +00002366 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2367 {
ajs2a42e282004-12-08 18:43:03 +00002368 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002369 inet_ntoa (iph->ip_src));
2370 }
paul718e3742002-12-13 20:15:29 +00002371 return 0;
2372 }
2373
2374 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002375 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002376
2377 /* Get ospf packet header. */
2378 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2379
2380 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002381 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002382
2383 /* if no local ospf_interface,
2384 * or header area is backbone but ospf_interface is not
2385 * check for VLINK interface
2386 */
2387 if ( (oi == NULL) ||
2388 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2389 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2390 )
2391 {
2392 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2393 {
Paul Jakma88871b12006-06-15 11:41:19 +00002394 if (IS_DEBUG_OSPF_EVENT)
2395 zlog_debug ("Packet from [%s] received on link %s"
2396 " but no ospf_interface",
2397 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002398 return 0;
2399 }
2400 }
2401
2402 /* else it must be a local ospf interface, check it was received on
2403 * correct link
2404 */
2405 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002406 {
2407 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002408 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002409 return 0;
2410 }
ajs847947f2005-02-02 18:38:48 +00002411 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002412 {
ajsba6454e2005-02-08 15:37:30 +00002413 char buf[2][INET_ADDRSTRLEN];
2414 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002415 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002416 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2417 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2418 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002419 /* Fix multicast memberships? */
2420 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002421 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002422 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002423 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002424 if (oi->multicast_memberships)
2425 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002426 return 0;
2427 }
paul718e3742002-12-13 20:15:29 +00002428
2429 /*
2430 * If the received packet is destined for AllDRouters, the packet
2431 * should be accepted only if the received ospf interface state is
2432 * either DR or Backup -- endo.
2433 */
2434 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2435 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2436 {
ajsba6454e2005-02-08 15:37:30 +00002437 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002438 inet_ntoa (iph->ip_src), IF_NAME (oi),
2439 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002440 /* Try to fix multicast membership. */
2441 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2442 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002443 return 0;
2444 }
2445
2446 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002447 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2448 {
paul718e3742002-12-13 20:15:29 +00002449 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002450 {
ajs2a42e282004-12-08 18:43:03 +00002451 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002452 ospf_packet_dump (ibuf);
2453 }
paul718e3742002-12-13 20:15:29 +00002454
ajs2a42e282004-12-08 18:43:03 +00002455 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002456 ospf_packet_type_str[ospfh->type],
2457 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002458 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2459 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002460
2461 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002462 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002463 }
paul718e3742002-12-13 20:15:29 +00002464
2465 /* Some header verification. */
2466 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2467 if (ret < 0)
2468 {
pauld3241812003-09-29 12:42:39 +00002469 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2470 {
ajs2a42e282004-12-08 18:43:03 +00002471 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002472 "dropping.",
2473 ospf_packet_type_str[ospfh->type],
2474 inet_ntoa (iph->ip_src));
2475 }
paul718e3742002-12-13 20:15:29 +00002476 return ret;
2477 }
2478
paul9985f832005-02-09 15:51:56 +00002479 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002480
2481 /* Adjust size to message length. */
2482 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2483
2484 /* Read rest of the packet and call each sort of packet routine. */
2485 switch (ospfh->type)
2486 {
2487 case OSPF_MSG_HELLO:
2488 ospf_hello (iph, ospfh, ibuf, oi, length);
2489 break;
2490 case OSPF_MSG_DB_DESC:
2491 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2492 break;
2493 case OSPF_MSG_LS_REQ:
2494 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2495 break;
2496 case OSPF_MSG_LS_UPD:
2497 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2498 break;
2499 case OSPF_MSG_LS_ACK:
2500 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2501 break;
2502 default:
2503 zlog (NULL, LOG_WARNING,
2504 "interface %s: OSPF packet header type %d is illegal",
2505 IF_NAME (oi), ospfh->type);
2506 break;
2507 }
2508
paul718e3742002-12-13 20:15:29 +00002509 return 0;
2510}
2511
2512/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002513static void
paul718e3742002-12-13 20:15:29 +00002514ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2515{
2516 struct ospf_header *ospfh;
2517
2518 ospfh = (struct ospf_header *) STREAM_DATA (s);
2519
2520 ospfh->version = (u_char) OSPF_VERSION;
2521 ospfh->type = (u_char) type;
2522
paul68980082003-03-25 05:07:42 +00002523 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002524
2525 ospfh->checksum = 0;
2526 ospfh->area_id = oi->area->area_id;
2527 ospfh->auth_type = htons (ospf_auth_type (oi));
2528
2529 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2530
paul9985f832005-02-09 15:51:56 +00002531 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002532}
2533
2534/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002535static int
paul718e3742002-12-13 20:15:29 +00002536ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2537{
2538 struct crypt_key *ck;
2539
2540 switch (ospf_auth_type (oi))
2541 {
2542 case OSPF_AUTH_NULL:
2543 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2544 break;
2545 case OSPF_AUTH_SIMPLE:
2546 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2547 OSPF_AUTH_SIMPLE_SIZE);
2548 break;
2549 case OSPF_AUTH_CRYPTOGRAPHIC:
2550 /* If key is not set, then set 0. */
2551 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2552 {
2553 ospfh->u.crypt.zero = 0;
2554 ospfh->u.crypt.key_id = 0;
2555 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2556 }
2557 else
2558 {
paul1eb8ef22005-04-07 07:30:20 +00002559 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002560 ospfh->u.crypt.zero = 0;
2561 ospfh->u.crypt.key_id = ck->key_id;
2562 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2563 }
2564 /* note: the seq is done in ospf_make_md5_digest() */
2565 break;
2566 default:
2567 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2568 break;
2569 }
2570
2571 return 0;
2572}
2573
2574/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002575static void
paul718e3742002-12-13 20:15:29 +00002576ospf_fill_header (struct ospf_interface *oi,
2577 struct stream *s, u_int16_t length)
2578{
2579 struct ospf_header *ospfh;
2580
2581 ospfh = (struct ospf_header *) STREAM_DATA (s);
2582
2583 /* Fill length. */
2584 ospfh->length = htons (length);
2585
2586 /* Calculate checksum. */
2587 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2588 ospfh->checksum = in_cksum (ospfh, length);
2589 else
2590 ospfh->checksum = 0;
2591
2592 /* Add Authentication Data. */
2593 ospf_make_auth (oi, ospfh);
2594}
2595
paul4dadc292005-05-06 21:37:42 +00002596static int
paul718e3742002-12-13 20:15:29 +00002597ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2598{
2599 struct ospf_neighbor *nbr;
2600 struct route_node *rn;
2601 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2602 struct in_addr mask;
2603 unsigned long p;
2604 int flag = 0;
2605
2606 /* Set netmask of interface. */
2607 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2608 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2609 masklen2ip (oi->address->prefixlen, &mask);
2610 else
2611 memset ((char *) &mask, 0, sizeof (struct in_addr));
2612 stream_put_ipv4 (s, mask.s_addr);
2613
2614 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002615 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2616 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2617 else
2618 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002619
2620 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002621 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002622 OPTIONS(oi), IF_NAME (oi));
2623
2624 /* Set Options. */
2625 stream_putc (s, OPTIONS (oi));
2626
2627 /* Set Router Priority. */
2628 stream_putc (s, PRIORITY (oi));
2629
2630 /* Set Router Dead Interval. */
2631 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2632
2633 /* Set Designated Router. */
2634 stream_put_ipv4 (s, DR (oi).s_addr);
2635
paul9985f832005-02-09 15:51:56 +00002636 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002637
2638 /* Set Backup Designated Router. */
2639 stream_put_ipv4 (s, BDR (oi).s_addr);
2640
2641 /* Add neighbor seen. */
2642 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002643 if ((nbr = rn->info))
2644 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2645 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2646 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2647 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002648 {
2649 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002650 if (nbr->d_router.s_addr != 0
2651 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2652 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2653 flag = 1;
paul718e3742002-12-13 20:15:29 +00002654
2655 stream_put_ipv4 (s, nbr->router_id.s_addr);
2656 length += 4;
2657 }
2658
2659 /* Let neighbor generate BackupSeen. */
2660 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002661 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002662
2663 return length;
2664}
2665
paul4dadc292005-05-06 21:37:42 +00002666static int
paul718e3742002-12-13 20:15:29 +00002667ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2668 struct stream *s)
2669{
2670 struct ospf_lsa *lsa;
2671 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2672 u_char options;
2673 unsigned long pp;
2674 int i;
2675 struct ospf_lsdb *lsdb;
2676
2677 /* Set Interface MTU. */
2678 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2679 stream_putw (s, 0);
2680 else
2681 stream_putw (s, oi->ifp->mtu);
2682
2683 /* Set Options. */
2684 options = OPTIONS (oi);
2685#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002686 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002687 {
2688 if (IS_SET_DD_I (nbr->dd_flags)
2689 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2690 /*
2691 * Set O-bit in the outgoing DD packet for capablity negotiation,
2692 * if one of following case is applicable.
2693 *
2694 * 1) WaitTimer expiration event triggered the neighbor state to
2695 * change to Exstart, but no (valid) DD packet has received
2696 * from the neighbor yet.
2697 *
2698 * 2) At least one DD packet with O-bit on has received from the
2699 * neighbor.
2700 */
2701 SET_FLAG (options, OSPF_OPTION_O);
2702 }
2703#endif /* HAVE_OPAQUE_LSA */
2704 stream_putc (s, options);
2705
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002706 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002707 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002708 stream_putc (s, nbr->dd_flags);
2709
2710 /* Set DD Sequence Number. */
2711 stream_putl (s, nbr->dd_seqnum);
2712
2713 if (ospf_db_summary_isempty (nbr))
2714 {
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002715 /* Sanity check:
2716 *
2717 * Must be here either:
2718 * - Initial DBD (ospf_nsm.c)
2719 * - M must be set
2720 * or
2721 * - finishing Exchange, and DB-Summary list empty
2722 * - from ospf_db_desc_proc()
2723 * - M must not be set
2724 */
paul718e3742002-12-13 20:15:29 +00002725 if (nbr->state >= NSM_Exchange)
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002726 assert (!IS_SET_DD_M(nbr->dd_flags));
2727 else
2728 assert (IS_SET_DD_M(nbr->dd_flags));
2729
paul718e3742002-12-13 20:15:29 +00002730 return length;
2731 }
2732
2733 /* Describe LSA Header from Database Summary List. */
2734 lsdb = &nbr->db_sum;
2735
2736 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2737 {
2738 struct route_table *table = lsdb->type[i].db;
2739 struct route_node *rn;
2740
2741 for (rn = route_top (table); rn; rn = route_next (rn))
2742 if ((lsa = rn->info) != NULL)
2743 {
2744#ifdef HAVE_OPAQUE_LSA
2745 if (IS_OPAQUE_LSA (lsa->data->type)
2746 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2747 {
2748 /* Suppress advertising opaque-informations. */
2749 /* Remove LSA from DB summary list. */
2750 ospf_lsdb_delete (lsdb, lsa);
2751 continue;
2752 }
2753#endif /* HAVE_OPAQUE_LSA */
2754
2755 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2756 {
2757 struct lsa_header *lsah;
2758 u_int16_t ls_age;
2759
2760 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002761 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002762 break;
2763
2764 /* Keep pointer to LS age. */
2765 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002766 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002767
2768 /* Proceed stream pointer. */
2769 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2770 length += OSPF_LSA_HEADER_SIZE;
2771
2772 /* Set LS age. */
2773 ls_age = LS_AGE (lsa);
2774 lsah->ls_age = htons (ls_age);
2775
2776 }
2777
2778 /* Remove LSA from DB summary list. */
2779 ospf_lsdb_delete (lsdb, lsa);
2780 }
2781 }
2782
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002783 /* Update 'More' bit */
2784 if (ospf_db_summary_isempty (nbr))
2785 {
2786 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2787 /* Rewrite DD flags */
2788 stream_putc_at (s, pp, nbr->dd_flags);
2789 }
paul718e3742002-12-13 20:15:29 +00002790 return length;
2791}
2792
paul4dadc292005-05-06 21:37:42 +00002793static int
paul718e3742002-12-13 20:15:29 +00002794ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2795 unsigned long delta, struct ospf_neighbor *nbr,
2796 struct ospf_lsa *lsa)
2797{
2798 struct ospf_interface *oi;
2799
2800 oi = nbr->oi;
2801
2802 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002803 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002804 return 0;
2805
2806 stream_putl (s, lsa->data->type);
2807 stream_put_ipv4 (s, lsa->data->id.s_addr);
2808 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2809
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002810 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002811 nbr->ls_req_last = ospf_lsa_lock (lsa);
2812
2813 *length += 12;
2814 return 1;
2815}
2816
paul4dadc292005-05-06 21:37:42 +00002817static int
paul718e3742002-12-13 20:15:29 +00002818ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2819{
2820 struct ospf_lsa *lsa;
2821 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002822 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002823 struct route_table *table;
2824 struct route_node *rn;
2825 int i;
2826 struct ospf_lsdb *lsdb;
2827
2828 lsdb = &nbr->ls_req;
2829
2830 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2831 {
2832 table = lsdb->type[i].db;
2833 for (rn = route_top (table); rn; rn = route_next (rn))
2834 if ((lsa = (rn->info)) != NULL)
2835 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2836 {
2837 route_unlock_node (rn);
2838 break;
2839 }
2840 }
2841 return length;
2842}
2843
paul4dadc292005-05-06 21:37:42 +00002844static int
paul718e3742002-12-13 20:15:29 +00002845ls_age_increment (struct ospf_lsa *lsa, int delay)
2846{
2847 int age;
2848
2849 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2850
2851 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2852}
2853
paul4dadc292005-05-06 21:37:42 +00002854static int
hasso52dc7ee2004-09-23 19:18:23 +00002855ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002856{
2857 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002858 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002859 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002860 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002861 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002862 unsigned long pp;
2863 int count = 0;
2864
2865 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002866 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002867
paul9985f832005-02-09 15:51:56 +00002868 pp = stream_get_endp (s);
2869 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002870
gdt86f1fd92005-01-10 14:20:43 +00002871 /* Calculate amount of packet usable for data. */
2872 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2873
paul718e3742002-12-13 20:15:29 +00002874 while ((node = listhead (update)) != NULL)
2875 {
2876 struct lsa_header *lsah;
2877 u_int16_t ls_age;
2878
2879 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002880 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002881
paul1eb8ef22005-04-07 07:30:20 +00002882 lsa = listgetdata (node);
2883
paul718e3742002-12-13 20:15:29 +00002884 assert (lsa->data);
2885
paul68b73392004-09-12 14:21:37 +00002886 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002887 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002888 break;
2889
paul718e3742002-12-13 20:15:29 +00002890 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002891 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002892
2893 /* Put LSA to Link State Request. */
2894 stream_put (s, lsa->data, ntohs (lsa->data->length));
2895
2896 /* Set LS age. */
2897 /* each hop must increment an lsa_age by transmit_delay
2898 of OSPF interface */
2899 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2900 lsah->ls_age = htons (ls_age);
2901
2902 length += ntohs (lsa->data->length);
2903 count++;
2904
2905 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002906 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002907 }
2908
2909 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002910 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002911
2912 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002913 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002914 return length;
2915}
2916
paul4dadc292005-05-06 21:37:42 +00002917static int
hasso52dc7ee2004-09-23 19:18:23 +00002918ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002919{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002920 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002921 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002922 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002923 struct ospf_lsa *lsa;
2924
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002925 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002926 {
paul718e3742002-12-13 20:15:29 +00002927 assert (lsa);
2928
gdt86f1fd92005-01-10 14:20:43 +00002929 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002930 break;
2931
2932 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2933 length += OSPF_LSA_HEADER_SIZE;
2934
paul718e3742002-12-13 20:15:29 +00002935 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002936 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002937 }
2938
paul718e3742002-12-13 20:15:29 +00002939 return length;
2940}
2941
2942void
2943ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2944{
2945 struct ospf_packet *op;
2946 u_int16_t length = OSPF_HEADER_SIZE;
2947
2948 op = ospf_packet_new (oi->ifp->mtu);
2949
2950 /* Prepare OSPF common header. */
2951 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2952
2953 /* Prepare OSPF Hello body. */
2954 length += ospf_make_hello (oi, op->s);
2955
2956 /* Fill OSPF header. */
2957 ospf_fill_header (oi, op->s, length);
2958
2959 /* Set packet length. */
2960 op->length = length;
2961
2962 op->dst.s_addr = addr->s_addr;
2963
2964 /* Add packet to the interface output queue. */
2965 ospf_packet_add (oi, op);
2966
2967 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002968 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002969}
2970
paul4dadc292005-05-06 21:37:42 +00002971static void
paul718e3742002-12-13 20:15:29 +00002972ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2973{
2974 struct ospf_interface *oi;
2975
2976 oi = nbr_nbma->oi;
2977 assert(oi);
2978
2979 /* If this is passive interface, do not send OSPF Hello. */
2980 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2981 return;
2982
2983 if (oi->type != OSPF_IFTYPE_NBMA)
2984 return;
2985
2986 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2987 return;
2988
2989 if (PRIORITY(oi) == 0)
2990 return;
2991
2992 if (nbr_nbma->priority == 0
2993 && oi->state != ISM_DR && oi->state != ISM_Backup)
2994 return;
2995
2996 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2997}
2998
2999int
3000ospf_poll_timer (struct thread *thread)
3001{
3002 struct ospf_nbr_nbma *nbr_nbma;
3003
3004 nbr_nbma = THREAD_ARG (thread);
3005 nbr_nbma->t_poll = NULL;
3006
3007 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003008 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003009 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3010
3011 ospf_poll_send (nbr_nbma);
3012
3013 if (nbr_nbma->v_poll > 0)
3014 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3015 nbr_nbma->v_poll);
3016
3017 return 0;
3018}
3019
3020
3021int
3022ospf_hello_reply_timer (struct thread *thread)
3023{
3024 struct ospf_neighbor *nbr;
3025
3026 nbr = THREAD_ARG (thread);
3027 nbr->t_hello_reply = NULL;
3028
3029 assert (nbr->oi);
3030
3031 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003032 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003033 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3034
3035 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3036
3037 return 0;
3038}
3039
3040/* Send OSPF Hello. */
3041void
3042ospf_hello_send (struct ospf_interface *oi)
3043{
3044 struct ospf_packet *op;
3045 u_int16_t length = OSPF_HEADER_SIZE;
3046
3047 /* If this is passive interface, do not send OSPF Hello. */
3048 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3049 return;
3050
3051 op = ospf_packet_new (oi->ifp->mtu);
3052
3053 /* Prepare OSPF common header. */
3054 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3055
3056 /* Prepare OSPF Hello body. */
3057 length += ospf_make_hello (oi, op->s);
3058
3059 /* Fill OSPF header. */
3060 ospf_fill_header (oi, op->s, length);
3061
3062 /* Set packet length. */
3063 op->length = length;
3064
3065 if (oi->type == OSPF_IFTYPE_NBMA)
3066 {
3067 struct ospf_neighbor *nbr;
3068 struct route_node *rn;
3069
3070 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3071 if ((nbr = rn->info))
3072 if (nbr != oi->nbr_self)
3073 if (nbr->state != NSM_Down)
3074 {
3075 /* RFC 2328 Section 9.5.1
3076 If the router is not eligible to become Designated Router,
3077 it must periodically send Hello Packets to both the
3078 Designated Router and the Backup Designated Router (if they
3079 exist). */
3080 if (PRIORITY(oi) == 0 &&
3081 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3082 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3083 continue;
3084
3085 /* If the router is eligible to become Designated Router, it
3086 must periodically send Hello Packets to all neighbors that
3087 are also eligible. In addition, if the router is itself the
3088 Designated Router or Backup Designated Router, it must also
3089 send periodic Hello Packets to all other neighbors. */
3090
3091 if (nbr->priority == 0 && oi->state == ISM_DROther)
3092 continue;
3093 /* if oi->state == Waiting, send hello to all neighbors */
3094 {
3095 struct ospf_packet *op_dup;
3096
3097 op_dup = ospf_packet_dup(op);
3098 op_dup->dst = nbr->address.u.prefix4;
3099
3100 /* Add packet to the interface output queue. */
3101 ospf_packet_add (oi, op_dup);
3102
paul020709f2003-04-04 02:44:16 +00003103 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003104 }
3105
3106 }
3107 ospf_packet_free (op);
3108 }
3109 else
3110 {
3111 /* Decide destination address. */
3112 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3113 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3114 else
3115 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3116
3117 /* Add packet to the interface output queue. */
3118 ospf_packet_add (oi, op);
3119
3120 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003121 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003122 }
3123}
3124
3125/* Send OSPF Database Description. */
3126void
3127ospf_db_desc_send (struct ospf_neighbor *nbr)
3128{
3129 struct ospf_interface *oi;
3130 struct ospf_packet *op;
3131 u_int16_t length = OSPF_HEADER_SIZE;
3132
3133 oi = nbr->oi;
3134 op = ospf_packet_new (oi->ifp->mtu);
3135
3136 /* Prepare OSPF common header. */
3137 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3138
3139 /* Prepare OSPF Database Description body. */
3140 length += ospf_make_db_desc (oi, nbr, op->s);
3141
3142 /* Fill OSPF header. */
3143 ospf_fill_header (oi, op->s, length);
3144
3145 /* Set packet length. */
3146 op->length = length;
3147
3148 /* Decide destination address. */
3149 op->dst = nbr->address.u.prefix4;
3150
3151 /* Add packet to the interface output queue. */
3152 ospf_packet_add (oi, op);
3153
3154 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003155 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003156
3157 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3158 if (nbr->last_send)
3159 ospf_packet_free (nbr->last_send);
3160 nbr->last_send = ospf_packet_dup (op);
3161 gettimeofday (&nbr->last_send_ts, NULL);
3162}
3163
3164/* Re-send Database Description. */
3165void
3166ospf_db_desc_resend (struct ospf_neighbor *nbr)
3167{
3168 struct ospf_interface *oi;
3169
3170 oi = nbr->oi;
3171
3172 /* Add packet to the interface output queue. */
3173 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3174
3175 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003176 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003177}
3178
3179/* Send Link State Request. */
3180void
3181ospf_ls_req_send (struct ospf_neighbor *nbr)
3182{
3183 struct ospf_interface *oi;
3184 struct ospf_packet *op;
3185 u_int16_t length = OSPF_HEADER_SIZE;
3186
3187 oi = nbr->oi;
3188 op = ospf_packet_new (oi->ifp->mtu);
3189
3190 /* Prepare OSPF common header. */
3191 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3192
3193 /* Prepare OSPF Link State Request body. */
3194 length += ospf_make_ls_req (nbr, op->s);
3195 if (length == OSPF_HEADER_SIZE)
3196 {
3197 ospf_packet_free (op);
3198 return;
3199 }
3200
3201 /* Fill OSPF header. */
3202 ospf_fill_header (oi, op->s, length);
3203
3204 /* Set packet length. */
3205 op->length = length;
3206
3207 /* Decide destination address. */
3208 op->dst = nbr->address.u.prefix4;
3209
3210 /* Add packet to the interface output queue. */
3211 ospf_packet_add (oi, op);
3212
3213 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003214 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003215
3216 /* Add Link State Request Retransmission Timer. */
3217 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3218}
3219
3220/* Send Link State Update with an LSA. */
3221void
3222ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3223 int flag)
3224{
hasso52dc7ee2004-09-23 19:18:23 +00003225 struct list *update;
paul718e3742002-12-13 20:15:29 +00003226
3227 update = list_new ();
3228
3229 listnode_add (update, lsa);
3230 ospf_ls_upd_send (nbr, update, flag);
3231
3232 list_delete (update);
3233}
3234
paul68b73392004-09-12 14:21:37 +00003235/* Determine size for packet. Must be at least big enough to accomodate next
3236 * LSA on list, which may be bigger than MTU size.
3237 *
3238 * Return pointer to new ospf_packet
3239 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3240 * on packet sizes (in which case offending LSA is deleted from update list)
3241 */
3242static struct ospf_packet *
3243ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3244{
3245 struct ospf_lsa *lsa;
3246 struct listnode *ln;
3247 size_t size;
3248 static char warned = 0;
3249
paul1eb8ef22005-04-07 07:30:20 +00003250 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003251 assert (lsa->data);
3252
3253 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3254 > ospf_packet_max (oi))
3255 {
3256 if (!warned)
3257 {
3258 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3259 "will need to fragment. Not optimal. Try divide up"
3260 " your network with areas. Use 'debug ospf packet send'"
3261 " to see details, or look at 'show ip ospf database ..'");
3262 warned = 1;
3263 }
3264
3265 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003266 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003267 " %d bytes originated by %s, will be fragmented!",
3268 inet_ntoa (lsa->data->id),
3269 ntohs (lsa->data->length),
3270 inet_ntoa (lsa->data->adv_router));
3271
3272 /*
3273 * Allocate just enough to fit this LSA only, to avoid including other
3274 * LSAs in fragmented LSA Updates.
3275 */
3276 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3277 + OSPF_LS_UPD_MIN_SIZE;
3278 }
3279 else
3280 size = oi->ifp->mtu;
3281
gdt86f1fd92005-01-10 14:20:43 +00003282 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003283 if (size > OSPF_MAX_PACKET_SIZE)
3284 {
3285 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003286 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003287 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003288 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003289 (long int) size);
paul68b73392004-09-12 14:21:37 +00003290 list_delete_node (update, ln);
3291 return NULL;
3292 }
3293
3294 return ospf_packet_new (size);
3295}
3296
paul718e3742002-12-13 20:15:29 +00003297static void
hasso52dc7ee2004-09-23 19:18:23 +00003298ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003299 struct in_addr addr)
3300{
3301 struct ospf_packet *op;
3302 u_int16_t length = OSPF_HEADER_SIZE;
3303
3304 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003305 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003306
3307 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003308
3309 /* Prepare OSPF common header. */
3310 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3311
paul59ea14c2004-07-14 20:50:36 +00003312 /* Prepare OSPF Link State Update body.
3313 * Includes Type-7 translation.
3314 */
paul718e3742002-12-13 20:15:29 +00003315 length += ospf_make_ls_upd (oi, update, op->s);
3316
3317 /* Fill OSPF header. */
3318 ospf_fill_header (oi, op->s, length);
3319
3320 /* Set packet length. */
3321 op->length = length;
3322
3323 /* Decide destination address. */
3324 op->dst.s_addr = addr.s_addr;
3325
3326 /* Add packet to the interface output queue. */
3327 ospf_packet_add (oi, op);
3328
3329 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003330 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003331}
3332
3333static int
3334ospf_ls_upd_send_queue_event (struct thread *thread)
3335{
3336 struct ospf_interface *oi = THREAD_ARG(thread);
3337 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003338 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003339 struct list *update;
paul68b73392004-09-12 14:21:37 +00003340 char again = 0;
paul718e3742002-12-13 20:15:29 +00003341
3342 oi->t_ls_upd_event = NULL;
3343
3344 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003345 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003346
paul736d3442003-07-24 23:22:57 +00003347 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003348 {
paul736d3442003-07-24 23:22:57 +00003349 rnext = route_next (rn);
3350
paul718e3742002-12-13 20:15:29 +00003351 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003352 continue;
paul68b73392004-09-12 14:21:37 +00003353
3354 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003355
paul48fe13b2004-07-27 17:40:44 +00003356 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003357
paul68b73392004-09-12 14:21:37 +00003358 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003359 if (listcount(update) == 0)
3360 {
3361 list_delete (rn->info);
3362 rn->info = NULL;
3363 route_unlock_node (rn);
3364 }
3365 else
paul68b73392004-09-12 14:21:37 +00003366 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003367 }
3368
3369 if (again != 0)
3370 {
3371 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003372 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003373 " %d nodes to try again, raising new event", again);
3374 oi->t_ls_upd_event =
3375 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003376 }
3377
3378 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003379 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003380
paul718e3742002-12-13 20:15:29 +00003381 return 0;
3382}
3383
3384void
hasso52dc7ee2004-09-23 19:18:23 +00003385ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003386{
3387 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003388 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003389 struct prefix_ipv4 p;
3390 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003391 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003392
3393 oi = nbr->oi;
3394
3395 p.family = AF_INET;
3396 p.prefixlen = IPV4_MAX_BITLEN;
3397
3398 /* Decide destination address. */
3399 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3400 p.prefix = oi->vl_data->peer_addr;
3401 else if (flag == OSPF_SEND_PACKET_DIRECT)
3402 p.prefix = nbr->address.u.prefix4;
3403 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3404 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3405 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3406 && (flag == OSPF_SEND_PACKET_INDIRECT))
3407 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003408 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3409 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003410 else
3411 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3412
3413 if (oi->type == OSPF_IFTYPE_NBMA)
3414 {
3415 if (flag == OSPF_SEND_PACKET_INDIRECT)
3416 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3417 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3418 zlog_warn ("* LS-Update is sent to myself.");
3419 }
3420
3421 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3422
3423 if (rn->info == NULL)
3424 rn->info = list_new ();
3425
paul1eb8ef22005-04-07 07:30:20 +00003426 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003427 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003428
3429 if (oi->t_ls_upd_event == NULL)
3430 oi->t_ls_upd_event =
3431 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3432}
3433
3434static void
hasso52dc7ee2004-09-23 19:18:23 +00003435ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3436 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003437{
3438 struct ospf_packet *op;
3439 u_int16_t length = OSPF_HEADER_SIZE;
3440
3441 op = ospf_packet_new (oi->ifp->mtu);
3442
3443 /* Prepare OSPF common header. */
3444 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3445
3446 /* Prepare OSPF Link State Acknowledgment body. */
3447 length += ospf_make_ls_ack (oi, ack, op->s);
3448
3449 /* Fill OSPF header. */
3450 ospf_fill_header (oi, op->s, length);
3451
3452 /* Set packet length. */
3453 op->length = length;
3454
3455 /* Set destination IP address. */
3456 op->dst = dst;
3457
3458 /* Add packet to the interface output queue. */
3459 ospf_packet_add (oi, op);
3460
3461 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003462 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003463}
3464
3465static int
3466ospf_ls_ack_send_event (struct thread *thread)
3467{
3468 struct ospf_interface *oi = THREAD_ARG (thread);
3469
3470 oi->t_ls_ack_direct = NULL;
3471
3472 while (listcount (oi->ls_ack_direct.ls_ack))
3473 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3474 oi->ls_ack_direct.dst);
3475
3476 return 0;
3477}
3478
3479void
3480ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3481{
3482 struct ospf_interface *oi = nbr->oi;
3483
3484 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3485 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3486
3487 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3488
3489 if (oi->t_ls_ack_direct == NULL)
3490 oi->t_ls_ack_direct =
3491 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3492}
3493
3494/* Send Link State Acknowledgment delayed. */
3495void
3496ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3497{
3498 struct in_addr dst;
3499
3500 /* Decide destination address. */
3501 /* RFC2328 Section 13.5 On non-broadcast
3502 networks, delayed Link State Acknowledgment packets must be
3503 unicast separately over each adjacency (i.e., neighbor whose
3504 state is >= Exchange). */
3505 if (oi->type == OSPF_IFTYPE_NBMA)
3506 {
3507 struct ospf_neighbor *nbr;
3508 struct route_node *rn;
3509
3510 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3511 if ((nbr = rn->info) != NULL)
3512 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3513 while (listcount (oi->ls_ack))
3514 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3515 return;
3516 }
3517 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3518 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3519 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3520 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3521 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3522 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003523 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3524 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003525 else
3526 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3527
3528 while (listcount (oi->ls_ack))
3529 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3530}