blob: 74caaa77c167c8b556851fed934f4e372fb23583 [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);
1038 if (!find || ospf_lsa_more_recent (find, new) < 0)
1039 {
1040 ospf_ls_request_add (nbr, new);
1041 ospf_lsa_discard (new);
1042 }
1043 else
1044 {
1045 /* Received LSA is not recent. */
1046 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001047 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001048 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1049 ospf_lsa_discard (new);
1050 continue;
1051 }
1052 }
1053
1054 /* Master */
1055 if (IS_SET_DD_MS (nbr->dd_flags))
1056 {
1057 nbr->dd_seqnum++;
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001058
1059 /* Both sides have no More, then we're done with Exchange */
paul718e3742002-12-13 20:15:29 +00001060 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1061 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1062 else
paul718e3742002-12-13 20:15:29 +00001063 ospf_db_desc_send (nbr);
1064 }
1065 /* Slave */
1066 else
1067 {
1068 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1069
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001070 /* Send DD packet in reply.
1071 *
1072 * Must be done to acknowledge the Master's DD, regardless of
1073 * whether we have more LSAs ourselves to describe.
1074 *
1075 * This function will clear the 'More' bit, if after this DD
1076 * we have no more LSAs to describe to the master..
1077 */
paul718e3742002-12-13 20:15:29 +00001078 ospf_db_desc_send (nbr);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001079
1080 /* Slave can raise ExchangeDone now, if master is also done */
1081 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1082 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
paul718e3742002-12-13 20:15:29 +00001083 }
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001084
paul718e3742002-12-13 20:15:29 +00001085 /* Save received neighbor values from DD. */
1086 ospf_db_desc_save_current (nbr, dd);
1087}
1088
paul4dadc292005-05-06 21:37:42 +00001089static int
paul718e3742002-12-13 20:15:29 +00001090ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1091{
1092 /* Is DD duplicated? */
1093 if (dd->options == nbr->last_recv.options &&
1094 dd->flags == nbr->last_recv.flags &&
1095 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1096 return 1;
1097
1098 return 0;
1099}
1100
1101/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001102static void
paul718e3742002-12-13 20:15:29 +00001103ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1104 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1105{
1106 struct ospf_db_desc *dd;
1107 struct ospf_neighbor *nbr;
1108
1109 /* Increment statistics. */
1110 oi->db_desc_in++;
1111
1112 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001113
pauld3f0d622004-05-05 15:27:15 +00001114 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001115 if (nbr == NULL)
1116 {
1117 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1118 inet_ntoa (ospfh->router_id));
1119 return;
1120 }
1121
1122 /* Check MTU. */
vincentba682532005-09-29 13:52:57 +00001123 if ((OSPF_IF_PARAM (oi, mtu_ignore) == 0) &&
1124 (ntohs (dd->mtu) > oi->ifp->mtu))
paul718e3742002-12-13 20:15:29 +00001125 {
ajs3aa8d5f2004-12-11 18:00:06 +00001126 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1127 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1128 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001129 return;
1130 }
1131
pauld363df22003-06-19 00:26:34 +00001132 /*
1133 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1134 * required. In fact at least JunOS sends DD packets with P bit clear.
1135 * Until proper solution is developped, this hack should help.
1136 *
1137 * Update: According to the RFCs, N bit is specified /only/ for Hello
1138 * options, unfortunately its use in DD options is not specified. Hence some
1139 * implementations follow E-bit semantics and set it in DD options, and some
1140 * treat it as unspecified and hence follow the directive "default for
1141 * options is clear", ie unset.
1142 *
1143 * Reset the flag, as ospfd follows E-bit semantics.
1144 */
1145 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1146 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1147 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1148 {
1149 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001150 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001151 inet_ntoa (nbr->router_id) );
1152 SET_FLAG (dd->options, OSPF_OPTION_NP);
1153 }
pauld363df22003-06-19 00:26:34 +00001154
paul718e3742002-12-13 20:15:29 +00001155#ifdef REJECT_IF_TBIT_ON
1156 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1157 {
1158 /*
1159 * In Hello protocol, optional capability must have checked
1160 * to prevent this T-bit enabled router be my neighbor.
1161 */
1162 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1163 return;
1164 }
1165#endif /* REJECT_IF_TBIT_ON */
1166
1167#ifdef HAVE_OPAQUE_LSA
1168 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001169 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001170 {
1171 /*
1172 * This node is not configured to handle O-bit, for now.
1173 * Clear it to ignore unsupported capability proposed by neighbor.
1174 */
1175 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1176 }
1177#endif /* HAVE_OPAQUE_LSA */
1178
1179 /* Process DD packet by neighbor status. */
1180 switch (nbr->state)
1181 {
1182 case NSM_Down:
1183 case NSM_Attempt:
1184 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001185 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001186 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001187 LOOKUP (ospf_nsm_state_msg, nbr->state));
1188 break;
1189 case NSM_Init:
1190 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1191 /* If the new state is ExStart, the processing of the current
1192 packet should then continue in this new state by falling
1193 through to case ExStart below. */
1194 if (nbr->state != NSM_ExStart)
1195 break;
1196 case NSM_ExStart:
1197 /* Initial DBD */
1198 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1199 (size == OSPF_DB_DESC_MIN_SIZE))
1200 {
paul68980082003-03-25 05:07:42 +00001201 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001202 {
1203 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001204 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001205 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001206 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001207
1208 /* Reset I/MS */
1209 UNSET_FLAG (nbr->dd_flags, (OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I));
paul718e3742002-12-13 20:15:29 +00001210 }
1211 else
1212 {
1213 /* We're Master, ignore the initial DBD from Slave */
paul6d452762005-11-03 11:15:44 +00001214 zlog_info ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
ajs3aa8d5f2004-12-11 18:00:06 +00001215 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001216 break;
1217 }
1218 }
1219 /* Ack from the Slave */
1220 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1221 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001222 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001223 {
ajs17eaa722004-12-29 21:04:48 +00001224 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001225 inet_ntoa(nbr->router_id));
Paul Jakma8dd24ee2006-08-27 06:29:30 +00001226 /* Reset I, leaving MS */
1227 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_I);
paul718e3742002-12-13 20:15:29 +00001228 }
1229 else
1230 {
ajs3aa8d5f2004-12-11 18:00:06 +00001231 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1232 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001233 break;
1234 }
1235
1236 /* This is where the real Options are saved */
1237 nbr->options = dd->options;
1238
1239#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001240 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001241 {
1242 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001243 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001244 inet_ntoa (nbr->router_id),
1245 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1246
1247 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1248 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1249 {
paul6d452762005-11-03 11:15:44 +00001250 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; "
1251 "Opaque-LSAs cannot be reliably advertised "
1252 "in this network.",
1253 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001254 /* This situation is undesirable, but not a real error. */
1255 }
1256 }
1257#endif /* HAVE_OPAQUE_LSA */
1258
1259 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1260
1261 /* continue processing rest of packet. */
1262 ospf_db_desc_proc (s, oi, nbr, dd, size);
1263 break;
1264 case NSM_Exchange:
1265 if (ospf_db_desc_is_dup (dd, nbr))
1266 {
1267 if (IS_SET_DD_MS (nbr->dd_flags))
1268 /* Master: discard duplicated DD packet. */
paul6d452762005-11-03 11:15:44 +00001269 zlog_info ("Packet[DD] (Master): Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001270 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001271 else
1272 /* Slave: cause to retransmit the last Database Description. */
1273 {
paul6d452762005-11-03 11:15:44 +00001274 zlog_info ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
ajs3aa8d5f2004-12-11 18:00:06 +00001275 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001276 ospf_db_desc_resend (nbr);
1277 }
1278 break;
1279 }
1280
1281 /* Otherwise DD packet should be checked. */
1282 /* Check Master/Slave bit mismatch */
1283 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1284 {
ajs3aa8d5f2004-12-11 18:00:06 +00001285 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1286 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001287 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1288 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001289 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001290 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001291 break;
1292 }
1293
1294 /* Check initialize bit is set. */
1295 if (IS_SET_DD_I (dd->flags))
1296 {
paul6d452762005-11-03 11:15:44 +00001297 zlog_info ("Packet[DD]: Neighbor %s I-bit set.",
ajs3aa8d5f2004-12-11 18:00:06 +00001298 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001299 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1300 break;
1301 }
1302
1303 /* Check DD Options. */
1304 if (dd->options != nbr->options)
1305 {
1306#ifdef ORIGINAL_CODING
1307 /* Save the new options for debugging */
1308 nbr->options = dd->options;
1309#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001310 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1311 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001312 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1313 break;
1314 }
1315
1316 /* Check DD sequence number. */
1317 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1318 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1319 (!IS_SET_DD_MS (nbr->dd_flags) &&
1320 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1321 {
ajs3aa8d5f2004-12-11 18:00:06 +00001322 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1323 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001324 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1325 break;
1326 }
1327
1328 /* Continue processing rest of packet. */
1329 ospf_db_desc_proc (s, oi, nbr, dd, size);
1330 break;
1331 case NSM_Loading:
1332 case NSM_Full:
1333 if (ospf_db_desc_is_dup (dd, nbr))
1334 {
1335 if (IS_SET_DD_MS (nbr->dd_flags))
1336 {
1337 /* Master should discard duplicate DD packet. */
paul6d452762005-11-03 11:15:44 +00001338 zlog_info ("Packet[DD]: Neighbor %s duplicated, "
1339 "packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001340 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001341 break;
1342 }
1343 else
1344 {
1345 struct timeval t, now;
1346 gettimeofday (&now, NULL);
1347 t = tv_sub (now, nbr->last_send_ts);
1348 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1349 {
1350 /* In states Loading and Full the slave must resend
1351 its last Database Description packet in response to
1352 duplicate Database Description packets received
1353 from the master. For this reason the slave must
1354 wait RouterDeadInterval seconds before freeing the
1355 last Database Description packet. Reception of a
1356 Database Description packet from the master after
1357 this interval will generate a SeqNumberMismatch
1358 neighbor event. RFC2328 Section 10.8 */
1359 ospf_db_desc_resend (nbr);
1360 break;
1361 }
1362 }
1363 }
1364
1365 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1366 break;
1367 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001368 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1369 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001370 break;
1371 }
1372}
1373
1374#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1375
1376/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001377static void
paul718e3742002-12-13 20:15:29 +00001378ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1379 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1380{
1381 struct ospf_neighbor *nbr;
1382 u_int32_t ls_type;
1383 struct in_addr ls_id;
1384 struct in_addr adv_router;
1385 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001386 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001387 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001388
1389 /* Increment statistics. */
1390 oi->ls_req_in++;
1391
pauld3f0d622004-05-05 15:27:15 +00001392 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001393 if (nbr == NULL)
1394 {
1395 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1396 inet_ntoa (ospfh->router_id));
1397 return;
1398 }
1399
1400 /* Neighbor State should be Exchange or later. */
1401 if (nbr->state != NSM_Exchange &&
1402 nbr->state != NSM_Loading &&
1403 nbr->state != NSM_Full)
1404 {
ajsbec595a2004-11-30 22:38:43 +00001405 zlog_warn ("Link State Request received from %s: "
1406 "Neighbor state is %s, packet discarded.",
1407 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001408 LOOKUP (ospf_nsm_state_msg, nbr->state));
1409 return;
1410 }
1411
1412 /* Send Link State Update for ALL requested LSAs. */
1413 ls_upd = list_new ();
1414 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1415
1416 while (size >= OSPF_LSA_KEY_SIZE)
1417 {
1418 /* Get one slice of Link State Request. */
1419 ls_type = stream_getl (s);
1420 ls_id.s_addr = stream_get_ipv4 (s);
1421 adv_router.s_addr = stream_get_ipv4 (s);
1422
1423 /* Verify LSA type. */
1424 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1425 {
1426 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1427 list_delete (ls_upd);
1428 return;
1429 }
1430
1431 /* Search proper LSA in LSDB. */
1432 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1433 if (find == NULL)
1434 {
1435 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1436 list_delete (ls_upd);
1437 return;
1438 }
1439
gdt86f1fd92005-01-10 14:20:43 +00001440 /* Packet overflows MTU size, send immediately. */
1441 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001442 {
1443 if (oi->type == OSPF_IFTYPE_NBMA)
1444 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1445 else
1446 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1447
1448 /* Only remove list contents. Keep ls_upd. */
1449 list_delete_all_node (ls_upd);
1450
1451 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1452 }
1453
1454 /* Append LSA to update list. */
1455 listnode_add (ls_upd, find);
1456 length += ntohs (find->data->length);
1457
1458 size -= OSPF_LSA_KEY_SIZE;
1459 }
1460
1461 /* Send rest of Link State Update. */
1462 if (listcount (ls_upd) > 0)
1463 {
1464 if (oi->type == OSPF_IFTYPE_NBMA)
1465 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1466 else
1467 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1468
1469 list_delete (ls_upd);
1470 }
1471 else
1472 list_free (ls_upd);
1473}
1474
1475/* Get the list of LSAs from Link State Update packet.
1476 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001477static struct list *
paul718e3742002-12-13 20:15:29 +00001478ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1479 struct ospf_interface *oi, size_t size)
1480{
1481 u_int16_t count, sum;
1482 u_int32_t length;
1483 struct lsa_header *lsah;
1484 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001485 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001486
1487 lsas = list_new ();
1488
1489 count = stream_getl (s);
1490 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1491
1492 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001493 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001494 {
1495 lsah = (struct lsa_header *) STREAM_PNT (s);
1496 length = ntohs (lsah->length);
1497
1498 if (length > size)
1499 {
1500 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1501 break;
1502 }
1503
1504 /* Validate the LSA's LS checksum. */
1505 sum = lsah->checksum;
1506 if (sum != ospf_lsa_checksum (lsah))
1507 {
1508 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1509 sum, lsah->checksum);
1510 continue;
1511 }
1512
1513 /* Examine the LSA's LS type. */
1514 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1515 {
1516 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1517 continue;
1518 }
1519
1520 /*
1521 * What if the received LSA's age is greater than MaxAge?
1522 * Treat it as a MaxAge case -- endo.
1523 */
1524 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1525 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1526
1527#ifdef HAVE_OPAQUE_LSA
1528 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1529 {
1530#ifdef STRICT_OBIT_USAGE_CHECK
1531 if ((IS_OPAQUE_LSA(lsah->type) &&
1532 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1533 || (! IS_OPAQUE_LSA(lsah->type) &&
1534 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1535 {
1536 /*
1537 * This neighbor must know the exact usage of O-bit;
1538 * the bit will be set in Type-9,10,11 LSAs only.
1539 */
1540 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1541 continue;
1542 }
1543#endif /* STRICT_OBIT_USAGE_CHECK */
1544
1545 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1546 if (lsah->type == OSPF_OPAQUE_AS_LSA
1547 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1548 {
1549 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001550 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 +00001551 continue;
1552 }
1553 }
1554 else if (IS_OPAQUE_LSA(lsah->type))
1555 {
1556 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1557 continue;
1558 }
1559#endif /* HAVE_OPAQUE_LSA */
1560
1561 /* Create OSPF LSA instance. */
1562 lsa = ospf_lsa_new ();
1563
1564 /* We may wish to put some error checking if type NSSA comes in
1565 and area not in NSSA mode */
1566 switch (lsah->type)
1567 {
1568 case OSPF_AS_EXTERNAL_LSA:
1569#ifdef HAVE_OPAQUE_LSA
1570 case OSPF_OPAQUE_AS_LSA:
1571 lsa->area = NULL;
1572 break;
1573 case OSPF_OPAQUE_LINK_LSA:
1574 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1575 /* Fallthrough */
1576#endif /* HAVE_OPAQUE_LSA */
1577 default:
1578 lsa->area = oi->area;
1579 break;
1580 }
1581
1582 lsa->data = ospf_lsa_data_new (length);
1583 memcpy (lsa->data, lsah, length);
1584
1585 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001586 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001587 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1588 listnode_add (lsas, lsa);
1589 }
1590
1591 return lsas;
1592}
1593
1594/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001595static void
hasso52dc7ee2004-09-23 19:18:23 +00001596ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001597{
paul1eb8ef22005-04-07 07:30:20 +00001598 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001599 struct ospf_lsa *lsa;
1600
paul1eb8ef22005-04-07 07:30:20 +00001601 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1602 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001603
1604 list_delete (lsas);
1605}
1606
1607/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001608static void
paul718e3742002-12-13 20:15:29 +00001609ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1610 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1611{
1612 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001613 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001614 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001615 struct ospf_lsa *lsa = NULL;
1616 /* unsigned long ls_req_found = 0; */
1617
1618 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1619
1620 /* Increment statistics. */
1621 oi->ls_upd_in++;
1622
1623 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001624 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001625 if (nbr == NULL)
1626 {
1627 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1628 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1629 return;
1630 }
1631
1632 /* Check neighbor state. */
1633 if (nbr->state < NSM_Exchange)
1634 {
ajs3aa8d5f2004-12-11 18:00:06 +00001635 zlog_warn ("Link State Update: "
1636 "Neighbor[%s] state %s is less than Exchange",
1637 inet_ntoa (ospfh->router_id),
1638 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001639 return;
1640 }
1641
1642 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1643 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1644 * of section 13.
1645 */
1646 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1647
1648#ifdef HAVE_OPAQUE_LSA
1649 /*
paul718e3742002-12-13 20:15:29 +00001650 * If self-originated Opaque-LSAs that have flooded before restart
1651 * are contained in the received LSUpd message, corresponding LSReq
1652 * messages to be sent may have to be modified.
1653 * To eliminate possible race conditions such that flushing and normal
1654 * updating for the same LSA would take place alternately, this trick
1655 * must be done before entering to the loop below.
1656 */
paul69310a62005-05-11 18:09:59 +00001657 /* XXX: Why is this Opaque specific? Either our core code is deficient
1658 * and this should be fixed generally, or Opaque is inventing strawman
1659 * problems */
paul718e3742002-12-13 20:15:29 +00001660 ospf_opaque_adjust_lsreq (nbr, lsas);
1661#endif /* HAVE_OPAQUE_LSA */
1662
1663#define DISCARD_LSA(L,N) {\
1664 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001665 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 +00001666 ospf_lsa_discard (L); \
1667 continue; }
1668
1669 /* Process each LSA received in the one packet. */
paul1eb8ef22005-04-07 07:30:20 +00001670 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001671 {
1672 struct ospf_lsa *ls_ret, *current;
1673 int ret = 1;
1674
paul718e3742002-12-13 20:15:29 +00001675 if (IS_DEBUG_OSPF_NSSA)
1676 {
1677 char buf1[INET_ADDRSTRLEN];
1678 char buf2[INET_ADDRSTRLEN];
1679 char buf3[INET_ADDRSTRLEN];
1680
ajs2a42e282004-12-08 18:43:03 +00001681 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001682 lsa->data->type,
1683 inet_ntop (AF_INET, &ospfh->router_id,
1684 buf1, INET_ADDRSTRLEN),
1685 inet_ntop (AF_INET, &lsa->data->id,
1686 buf2, INET_ADDRSTRLEN),
1687 inet_ntop (AF_INET, &lsa->data->adv_router,
1688 buf3, INET_ADDRSTRLEN));
1689 }
paul718e3742002-12-13 20:15:29 +00001690
1691 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1692
1693 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1694
1695 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1696
1697 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1698
1699 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1700
1701 /* Do take in Type-7's if we are an NSSA */
1702
1703 /* If we are also an ABR, later translate them to a Type-5 packet */
1704
1705 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1706 translate them to a separate Type-5 packet. */
1707
1708 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1709 /* Reject from STUB or NSSA */
1710 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1711 {
1712 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001713 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001714 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001715 }
1716
paul718e3742002-12-13 20:15:29 +00001717 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1718 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1719 {
1720 DISCARD_LSA (lsa,2);
1721 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001722 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001723 }
paul718e3742002-12-13 20:15:29 +00001724
1725 /* Find the LSA in the current database. */
1726
1727 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1728
1729 /* If the LSA's LS age is equal to MaxAge, and there is currently
1730 no instance of the LSA in the router's link state database,
1731 and none of router's neighbors are in states Exchange or Loading,
1732 then take the following actions. */
1733
1734 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001735 (ospf_nbr_count (oi, NSM_Exchange) +
1736 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001737 {
1738 /* Response Link State Acknowledgment. */
1739 ospf_ls_ack_send (nbr, lsa);
1740
1741 /* Discard LSA. */
paul6d452762005-11-03 11:15:44 +00001742 zlog_info ("Link State Update[%s]: LS age is equal to MaxAge.",
1743 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001744 DISCARD_LSA (lsa, 3);
1745 }
1746
1747#ifdef HAVE_OPAQUE_LSA
1748 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001749 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001750 {
1751 /*
1752 * Even if initial flushing seems to be completed, there might
1753 * be a case that self-originated LSA with MaxAge still remain
1754 * in the routing domain.
1755 * Just send an LSAck message to cease retransmission.
1756 */
1757 if (IS_LSA_MAXAGE (lsa))
1758 {
1759 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1760 ospf_ls_ack_send (nbr, lsa);
1761 ospf_lsa_discard (lsa);
1762
1763 if (current != NULL && ! IS_LSA_MAXAGE (current))
1764 ospf_opaque_lsa_refresh_schedule (current);
1765 continue;
1766 }
1767
1768 /*
1769 * If an instance of self-originated Opaque-LSA is not found
1770 * in the LSDB, there are some possible cases here.
1771 *
1772 * 1) This node lost opaque-capability after restart.
1773 * 2) Else, a part of opaque-type is no more supported.
1774 * 3) Else, a part of opaque-id is no more supported.
1775 *
1776 * Anyway, it is still this node's responsibility to flush it.
1777 * Otherwise, the LSA instance remains in the routing domain
1778 * until its age reaches to MaxAge.
1779 */
paul69310a62005-05-11 18:09:59 +00001780 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001781 if (current == NULL)
1782 {
1783 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001784 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1785 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001786
1787 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001788
1789 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1790 ospf_ls_ack_send (nbr, lsa);
1791
paul718e3742002-12-13 20:15:29 +00001792 continue;
1793 }
1794 }
1795#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001796
hassocb05eb22004-02-11 21:10:19 +00001797 /* It might be happen that received LSA is self-originated network LSA, but
1798 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1799 * Link State ID is one of the router's own IP interface addresses but whose
1800 * Advertising Router is not equal to the router's own Router ID
1801 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1802 */
1803
1804 if(lsa->data->type == OSPF_NETWORK_LSA)
1805 {
paul1eb8ef22005-04-07 07:30:20 +00001806 struct listnode *oinode, *oinnode;
1807 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001808 int Flag = 0;
1809
paul1eb8ef22005-04-07 07:30:20 +00001810 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001811 {
hassocb05eb22004-02-11 21:10:19 +00001812 if(out_if == NULL)
1813 break;
1814
1815 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1816 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1817 {
1818 if(out_if->network_lsa_self)
1819 {
1820 ospf_lsa_flush_area(lsa,out_if->area);
1821 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001822 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001823 lsa, (int) lsa->data->type);
1824 ospf_lsa_discard (lsa);
1825 Flag = 1;
1826 }
1827 break;
1828 }
1829 }
1830 if(Flag)
1831 continue;
1832 }
paul718e3742002-12-13 20:15:29 +00001833
1834 /* (5) Find the instance of this LSA that is currently contained
1835 in the router's link state database. If there is no
1836 database copy, or the received LSA is more recent than
1837 the database copy the following steps must be performed. */
1838
1839 if (current == NULL ||
1840 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1841 {
1842 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001843 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001844 DISCARD_LSA (lsa, 4);
1845 continue;
1846 }
1847
1848 /* (6) Else, If there is an instance of the LSA on the sending
1849 neighbor's Link state request list, an error has occurred in
1850 the Database Exchange process. In this case, restart the
1851 Database Exchange process by generating the neighbor event
1852 BadLSReq for the sending neighbor and stop processing the
1853 Link State Update packet. */
1854
1855 if (ospf_ls_request_lookup (nbr, lsa))
1856 {
1857 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001858 zlog_warn("LSA[%s] instance exists on Link state request list",
1859 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001860
1861 /* Clean list of LSAs. */
1862 ospf_upd_list_clean (lsas);
1863 /* this lsa is not on lsas list already. */
1864 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001865 return;
1866 }
1867
1868 /* If the received LSA is the same instance as the database copy
1869 (i.e., neither one is more recent) the following two steps
1870 should be performed: */
1871
1872 if (ret == 0)
1873 {
1874 /* If the LSA is listed in the Link state retransmission list
1875 for the receiving adjacency, the router itself is expecting
1876 an acknowledgment for this LSA. The router should treat the
1877 received LSA as an acknowledgment by removing the LSA from
1878 the Link state retransmission list. This is termed an
1879 "implied acknowledgment". */
1880
1881 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1882
1883 if (ls_ret != NULL)
1884 {
1885 ospf_ls_retransmit_delete (nbr, ls_ret);
1886
1887 /* Delayed acknowledgment sent if advertisement received
1888 from Designated Router, otherwise do nothing. */
1889 if (oi->state == ISM_Backup)
1890 if (NBR_IS_DR (nbr))
1891 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1892
1893 DISCARD_LSA (lsa, 5);
1894 }
1895 else
1896 /* Acknowledge the receipt of the LSA by sending a
1897 Link State Acknowledgment packet back out the receiving
1898 interface. */
1899 {
1900 ospf_ls_ack_send (nbr, lsa);
1901 DISCARD_LSA (lsa, 6);
1902 }
1903 }
1904
1905 /* The database copy is more recent. If the database copy
1906 has LS age equal to MaxAge and LS sequence number equal to
1907 MaxSequenceNumber, simply discard the received LSA without
1908 acknowledging it. (In this case, the LSA's LS sequence number is
1909 wrapping, and the MaxSequenceNumber LSA must be completely
1910 flushed before any new LSA instance can be introduced). */
1911
1912 else if (ret > 0) /* Database copy is more recent */
1913 {
1914 if (IS_LSA_MAXAGE (current) &&
1915 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1916 {
1917 DISCARD_LSA (lsa, 7);
1918 }
1919 /* Otherwise, as long as the database copy has not been sent in a
1920 Link State Update within the last MinLSArrival seconds, send the
1921 database copy back to the sending neighbor, encapsulated within
1922 a Link State Update Packet. The Link State Update Packet should
1923 be sent directly to the neighbor. In so doing, do not put the
1924 database copy of the LSA on the neighbor's link state
1925 retransmission list, and do not acknowledge the received (less
1926 recent) LSA instance. */
1927 else
1928 {
1929 struct timeval now;
1930
1931 gettimeofday (&now, NULL);
1932
1933 if (tv_cmp (tv_sub (now, current->tv_orig),
1934 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1935 /* Trap NSSA type later.*/
1936 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1937 DISCARD_LSA (lsa, 8);
1938 }
1939 }
1940 }
1941
paul718e3742002-12-13 20:15:29 +00001942 assert (listcount (lsas) == 0);
1943 list_delete (lsas);
1944}
1945
1946/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001947static void
paul718e3742002-12-13 20:15:29 +00001948ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1949 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1950{
1951 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001952
paul718e3742002-12-13 20:15:29 +00001953 /* increment statistics. */
1954 oi->ls_ack_in++;
1955
pauld3f0d622004-05-05 15:27:15 +00001956 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001957 if (nbr == NULL)
1958 {
1959 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1960 inet_ntoa (ospfh->router_id));
1961 return;
1962 }
1963
1964 if (nbr->state < NSM_Exchange)
1965 {
ajs3aa8d5f2004-12-11 18:00:06 +00001966 zlog_warn ("Link State Acknowledgment: "
1967 "Neighbor[%s] state %s is less than Exchange",
1968 inet_ntoa (ospfh->router_id),
1969 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001970 return;
1971 }
paul69310a62005-05-11 18:09:59 +00001972
paul718e3742002-12-13 20:15:29 +00001973 while (size >= OSPF_LSA_HEADER_SIZE)
1974 {
1975 struct ospf_lsa *lsa, *lsr;
1976
1977 lsa = ospf_lsa_new ();
1978 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1979
1980 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1981 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001982 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001983
1984 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1985 {
1986 lsa->data = NULL;
1987 ospf_lsa_discard (lsa);
1988 continue;
1989 }
1990
1991 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1992
1993 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1994 {
1995#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001996 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001997 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001998#endif /* HAVE_OPAQUE_LSA */
1999
2000 ospf_ls_retransmit_delete (nbr, lsr);
2001 }
2002
2003 lsa->data = NULL;
2004 ospf_lsa_discard (lsa);
2005 }
2006
paul718e3742002-12-13 20:15:29 +00002007 return;
paul718e3742002-12-13 20:15:29 +00002008}
2009
ajs038163f2005-02-17 19:55:59 +00002010static struct stream *
ajs5c333492005-02-23 15:43:01 +00002011ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00002012{
2013 int ret;
ajs5c333492005-02-23 15:43:01 +00002014 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00002015 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00002016 unsigned int ifindex = 0;
2017 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002018 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002019 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002020 struct msghdr msgh;
2021
paul68defd62004-09-27 07:27:13 +00002022 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002023 msgh.msg_iov = &iov;
2024 msgh.msg_iovlen = 1;
2025 msgh.msg_control = (caddr_t) buff;
2026 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002027
ajs5c333492005-02-23 15:43:01 +00002028 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2029 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002030 {
ajs5c333492005-02-23 15:43:01 +00002031 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2032 return NULL;
2033 }
paul69310a62005-05-11 18:09:59 +00002034 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002035 {
2036 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2037 "(ip header size is %u)",
2038 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002039 return NULL;
2040 }
paul18b12c32004-10-05 14:38:29 +00002041
ajs5c333492005-02-23 15:43:01 +00002042 /* Note that there should not be alignment problems with this assignment
2043 because this is at the beginning of the stream data buffer. */
2044 iph = (struct ip *) STREAM_DATA(ibuf);
2045 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002046
ajs5c333492005-02-23 15:43:01 +00002047 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002048
paul239aecc2003-12-08 10:34:54 +00002049#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002050 /*
2051 * Kernel network code touches incoming IP header parameters,
2052 * before protocol specific processing.
2053 *
2054 * 1) Convert byteorder to host representation.
2055 * --> ip_len, ip_id, ip_off
2056 *
2057 * 2) Adjust ip_len to strip IP header size!
2058 * --> If user process receives entire IP packet via RAW
2059 * socket, it must consider adding IP header size to
2060 * the "ip_len" field of "ip" structure.
2061 *
2062 * For more details, see <netinet/ip_input.c>.
2063 */
ajs5c333492005-02-23 15:43:01 +00002064 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002065#endif
2066
paul863082d2004-08-19 04:43:43 +00002067 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002068
2069 *ifp = if_lookup_by_index (ifindex);
2070
2071 if (ret != ip_len)
2072 {
ajs5c333492005-02-23 15:43:01 +00002073 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2074 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002075 return NULL;
2076 }
2077
2078 return ibuf;
2079}
2080
paul4dadc292005-05-06 21:37:42 +00002081static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002082ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002083 struct ip *iph, struct ospf_header *ospfh)
2084{
2085 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002086 struct ospf_vl_data *vl_data;
2087 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002088 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002089
2090 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2091 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002092 return NULL;
paul718e3742002-12-13 20:15:29 +00002093
pauld3f0d622004-05-05 15:27:15 +00002094 /* look for local OSPF interface matching the destination
2095 * to determine Area ID. We presume therefore the destination address
2096 * is unique, or at least (for "unnumbered" links), not used in other
2097 * areas
2098 */
2099 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2100 iph->ip_dst)) == NULL)
2101 return NULL;
paul718e3742002-12-13 20:15:29 +00002102
paul1eb8ef22005-04-07 07:30:20 +00002103 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002104 {
paul020709f2003-04-04 02:44:16 +00002105 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002106 if (!vl_area)
2107 continue;
2108
2109 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2110 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2111 {
2112 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002113 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002114 IF_NAME (vl_data->vl_oi));
2115 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2116 {
2117 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002118 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002119 return NULL;
2120 }
2121
2122 return vl_data->vl_oi;
2123 }
2124 }
2125
2126 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002127 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002128
pauld3f0d622004-05-05 15:27:15 +00002129 return NULL;
paul718e3742002-12-13 20:15:29 +00002130}
2131
paul4dadc292005-05-06 21:37:42 +00002132static inline int
paul718e3742002-12-13 20:15:29 +00002133ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2134{
2135 /* Check match the Area ID of the receiving interface. */
2136 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2137 return 1;
2138
2139 return 0;
2140}
2141
2142/* Unbound socket will accept any Raw IP packets if proto is matched.
2143 To prevent it, compare src IP address and i/f address with masking
2144 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002145static int
paul718e3742002-12-13 20:15:29 +00002146ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2147{
2148 struct in_addr mask, me, him;
2149
2150 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2151 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2152 return 1;
2153
2154 masklen2ip (oi->address->prefixlen, &mask);
2155
2156 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2157 him.s_addr = ip_src.s_addr & mask.s_addr;
2158
2159 if (IPV4_ADDR_SAME (&me, &him))
2160 return 1;
2161
2162 return 0;
2163}
2164
paul4dadc292005-05-06 21:37:42 +00002165static int
paul718e3742002-12-13 20:15:29 +00002166ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2167 struct ospf_header *ospfh)
2168{
2169 int ret = 0;
2170 struct crypt_key *ck;
2171
2172 switch (ntohs (ospfh->auth_type))
2173 {
2174 case OSPF_AUTH_NULL:
2175 ret = 1;
2176 break;
2177 case OSPF_AUTH_SIMPLE:
2178 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2179 ret = 1;
2180 else
2181 ret = 0;
2182 break;
2183 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002184 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002185 {
2186 ret = 0;
2187 break;
2188 }
2189
2190 /* This is very basic, the digest processing is elsewhere */
2191 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2192 ospfh->u.crypt.key_id == ck->key_id &&
2193 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2194 ret = 1;
2195 else
2196 ret = 0;
2197 break;
2198 default:
2199 ret = 0;
2200 break;
2201 }
2202
2203 return ret;
2204}
2205
paul4dadc292005-05-06 21:37:42 +00002206static int
paul718e3742002-12-13 20:15:29 +00002207ospf_check_sum (struct ospf_header *ospfh)
2208{
2209 u_int32_t ret;
2210 u_int16_t sum;
paul718e3742002-12-13 20:15:29 +00002211
2212 /* clear auth_data for checksum. */
2213 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2214
2215 /* keep checksum and clear. */
2216 sum = ospfh->checksum;
2217 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2218
2219 /* calculate checksum. */
2220 ret = in_cksum (ospfh, ntohs (ospfh->length));
2221
2222 if (ret != sum)
2223 {
2224 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2225 ret, sum);
2226 return 0;
2227 }
2228
2229 return 1;
2230}
2231
2232/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002233static int
paul718e3742002-12-13 20:15:29 +00002234ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2235 struct ip *iph, struct ospf_header *ospfh)
2236{
2237 /* check version. */
2238 if (ospfh->version != OSPF_VERSION)
2239 {
2240 zlog_warn ("interface %s: ospf_read version number mismatch.",
2241 IF_NAME (oi));
2242 return -1;
2243 }
2244
2245 /* Check Area ID. */
2246 if (!ospf_check_area_id (oi, ospfh))
2247 {
2248 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2249 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2250 return -1;
2251 }
2252
2253 /* Check network mask, Silently discarded. */
2254 if (! ospf_check_network_mask (oi, iph->ip_src))
2255 {
2256 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2257 IF_NAME (oi), inet_ntoa (iph->ip_src));
2258 return -1;
2259 }
2260
2261 /* Check authentication. */
2262 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2263 {
paulc6371712006-01-17 17:49:53 +00002264 zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d",
2265 IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type));
paul718e3742002-12-13 20:15:29 +00002266 return -1;
2267 }
2268
2269 if (! ospf_check_auth (oi, ibuf, ospfh))
2270 {
2271 zlog_warn ("interface %s: ospf_read authentication failed.",
2272 IF_NAME (oi));
2273 return -1;
2274 }
2275
2276 /* if check sum is invalid, packet is discarded. */
2277 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2278 {
2279 if (! ospf_check_sum (ospfh))
2280 {
2281 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2282 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2283 return -1;
2284 }
2285 }
2286 else
2287 {
2288 if (ospfh->checksum != 0)
2289 return -1;
2290 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2291 {
2292 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2293 IF_NAME (oi));
2294 return -1;
2295 }
2296 }
2297
2298 return 0;
2299}
2300
2301/* Starting point of packet process function. */
2302int
2303ospf_read (struct thread *thread)
2304{
2305 int ret;
2306 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002307 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002308 struct ospf_interface *oi;
2309 struct ip *iph;
2310 struct ospf_header *ospfh;
2311 u_int16_t length;
2312 struct interface *ifp;
2313
2314 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002315 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002316
2317 /* prepare for next packet. */
2318 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002319
2320 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002321 stream_reset(ospf->ibuf);
2322 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002323 return -1;
2324
ajs5c333492005-02-23 15:43:01 +00002325 /* Note that there should not be alignment problems with this assignment
2326 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002327 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002328 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002329
paulac191232004-10-22 12:05:17 +00002330 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002331 /* Handle cases where the platform does not support retrieving the ifindex,
2332 and also platforms (such as Solaris 8) that claim to support ifindex
2333 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002334 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002335
pauld3f0d622004-05-05 15:27:15 +00002336 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002337 return 0;
paul718e3742002-12-13 20:15:29 +00002338
2339 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002340 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002341 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002342
paul718e3742002-12-13 20:15:29 +00002343 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002344 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002345 {
pauld3241812003-09-29 12:42:39 +00002346 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2347 {
ajs2a42e282004-12-08 18:43:03 +00002348 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002349 inet_ntoa (iph->ip_src));
2350 }
paul718e3742002-12-13 20:15:29 +00002351 return 0;
2352 }
2353
2354 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002355 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002356
2357 /* Get ospf packet header. */
2358 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2359
2360 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002361 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002362
2363 /* if no local ospf_interface,
2364 * or header area is backbone but ospf_interface is not
2365 * check for VLINK interface
2366 */
2367 if ( (oi == NULL) ||
2368 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2369 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2370 )
2371 {
2372 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2373 {
Paul Jakma88871b12006-06-15 11:41:19 +00002374 if (IS_DEBUG_OSPF_EVENT)
2375 zlog_debug ("Packet from [%s] received on link %s"
2376 " but no ospf_interface",
2377 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002378 return 0;
2379 }
2380 }
2381
2382 /* else it must be a local ospf interface, check it was received on
2383 * correct link
2384 */
2385 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002386 {
2387 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002388 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002389 return 0;
2390 }
ajs847947f2005-02-02 18:38:48 +00002391 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002392 {
ajsba6454e2005-02-08 15:37:30 +00002393 char buf[2][INET_ADDRSTRLEN];
2394 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002395 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002396 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2397 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2398 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002399 /* Fix multicast memberships? */
2400 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002401 OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002402 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
Paul Jakma429ac782006-06-15 18:40:49 +00002403 OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
ajsba6454e2005-02-08 15:37:30 +00002404 if (oi->multicast_memberships)
2405 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002406 return 0;
2407 }
paul718e3742002-12-13 20:15:29 +00002408
2409 /*
2410 * If the received packet is destined for AllDRouters, the packet
2411 * should be accepted only if the received ospf interface state is
2412 * either DR or Backup -- endo.
2413 */
2414 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2415 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2416 {
ajsba6454e2005-02-08 15:37:30 +00002417 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002418 inet_ntoa (iph->ip_src), IF_NAME (oi),
2419 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002420 /* Try to fix multicast membership. */
2421 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2422 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002423 return 0;
2424 }
2425
2426 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002427 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2428 {
paul718e3742002-12-13 20:15:29 +00002429 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002430 {
ajs2a42e282004-12-08 18:43:03 +00002431 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002432 ospf_packet_dump (ibuf);
2433 }
paul718e3742002-12-13 20:15:29 +00002434
ajs2a42e282004-12-08 18:43:03 +00002435 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002436 ospf_packet_type_str[ospfh->type],
2437 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002438 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2439 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002440
2441 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002442 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002443 }
paul718e3742002-12-13 20:15:29 +00002444
2445 /* Some header verification. */
2446 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2447 if (ret < 0)
2448 {
pauld3241812003-09-29 12:42:39 +00002449 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2450 {
ajs2a42e282004-12-08 18:43:03 +00002451 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002452 "dropping.",
2453 ospf_packet_type_str[ospfh->type],
2454 inet_ntoa (iph->ip_src));
2455 }
paul718e3742002-12-13 20:15:29 +00002456 return ret;
2457 }
2458
paul9985f832005-02-09 15:51:56 +00002459 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002460
2461 /* Adjust size to message length. */
2462 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2463
2464 /* Read rest of the packet and call each sort of packet routine. */
2465 switch (ospfh->type)
2466 {
2467 case OSPF_MSG_HELLO:
2468 ospf_hello (iph, ospfh, ibuf, oi, length);
2469 break;
2470 case OSPF_MSG_DB_DESC:
2471 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2472 break;
2473 case OSPF_MSG_LS_REQ:
2474 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2475 break;
2476 case OSPF_MSG_LS_UPD:
2477 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2478 break;
2479 case OSPF_MSG_LS_ACK:
2480 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2481 break;
2482 default:
2483 zlog (NULL, LOG_WARNING,
2484 "interface %s: OSPF packet header type %d is illegal",
2485 IF_NAME (oi), ospfh->type);
2486 break;
2487 }
2488
paul718e3742002-12-13 20:15:29 +00002489 return 0;
2490}
2491
2492/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002493static void
paul718e3742002-12-13 20:15:29 +00002494ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2495{
2496 struct ospf_header *ospfh;
2497
2498 ospfh = (struct ospf_header *) STREAM_DATA (s);
2499
2500 ospfh->version = (u_char) OSPF_VERSION;
2501 ospfh->type = (u_char) type;
2502
paul68980082003-03-25 05:07:42 +00002503 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002504
2505 ospfh->checksum = 0;
2506 ospfh->area_id = oi->area->area_id;
2507 ospfh->auth_type = htons (ospf_auth_type (oi));
2508
2509 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2510
paul9985f832005-02-09 15:51:56 +00002511 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002512}
2513
2514/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002515static int
paul718e3742002-12-13 20:15:29 +00002516ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2517{
2518 struct crypt_key *ck;
2519
2520 switch (ospf_auth_type (oi))
2521 {
2522 case OSPF_AUTH_NULL:
2523 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2524 break;
2525 case OSPF_AUTH_SIMPLE:
2526 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2527 OSPF_AUTH_SIMPLE_SIZE);
2528 break;
2529 case OSPF_AUTH_CRYPTOGRAPHIC:
2530 /* If key is not set, then set 0. */
2531 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2532 {
2533 ospfh->u.crypt.zero = 0;
2534 ospfh->u.crypt.key_id = 0;
2535 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2536 }
2537 else
2538 {
paul1eb8ef22005-04-07 07:30:20 +00002539 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002540 ospfh->u.crypt.zero = 0;
2541 ospfh->u.crypt.key_id = ck->key_id;
2542 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2543 }
2544 /* note: the seq is done in ospf_make_md5_digest() */
2545 break;
2546 default:
2547 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2548 break;
2549 }
2550
2551 return 0;
2552}
2553
2554/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002555static void
paul718e3742002-12-13 20:15:29 +00002556ospf_fill_header (struct ospf_interface *oi,
2557 struct stream *s, u_int16_t length)
2558{
2559 struct ospf_header *ospfh;
2560
2561 ospfh = (struct ospf_header *) STREAM_DATA (s);
2562
2563 /* Fill length. */
2564 ospfh->length = htons (length);
2565
2566 /* Calculate checksum. */
2567 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2568 ospfh->checksum = in_cksum (ospfh, length);
2569 else
2570 ospfh->checksum = 0;
2571
2572 /* Add Authentication Data. */
2573 ospf_make_auth (oi, ospfh);
2574}
2575
paul4dadc292005-05-06 21:37:42 +00002576static int
paul718e3742002-12-13 20:15:29 +00002577ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2578{
2579 struct ospf_neighbor *nbr;
2580 struct route_node *rn;
2581 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2582 struct in_addr mask;
2583 unsigned long p;
2584 int flag = 0;
2585
2586 /* Set netmask of interface. */
2587 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2588 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2589 masklen2ip (oi->address->prefixlen, &mask);
2590 else
2591 memset ((char *) &mask, 0, sizeof (struct in_addr));
2592 stream_put_ipv4 (s, mask.s_addr);
2593
2594 /* Set Hello Interval. */
paulf9ad9372005-10-21 00:45:17 +00002595 if (OSPF_IF_PARAM (oi, fast_hello) == 0)
2596 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2597 else
2598 stream_putw (s, 0); /* hello-interval of 0 for fast-hellos */
paul718e3742002-12-13 20:15:29 +00002599
2600 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002601 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002602 OPTIONS(oi), IF_NAME (oi));
2603
2604 /* Set Options. */
2605 stream_putc (s, OPTIONS (oi));
2606
2607 /* Set Router Priority. */
2608 stream_putc (s, PRIORITY (oi));
2609
2610 /* Set Router Dead Interval. */
2611 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2612
2613 /* Set Designated Router. */
2614 stream_put_ipv4 (s, DR (oi).s_addr);
2615
paul9985f832005-02-09 15:51:56 +00002616 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002617
2618 /* Set Backup Designated Router. */
2619 stream_put_ipv4 (s, BDR (oi).s_addr);
2620
2621 /* Add neighbor seen. */
2622 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002623 if ((nbr = rn->info))
2624 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2625 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2626 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2627 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002628 {
2629 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002630 if (nbr->d_router.s_addr != 0
2631 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2632 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2633 flag = 1;
paul718e3742002-12-13 20:15:29 +00002634
2635 stream_put_ipv4 (s, nbr->router_id.s_addr);
2636 length += 4;
2637 }
2638
2639 /* Let neighbor generate BackupSeen. */
2640 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002641 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002642
2643 return length;
2644}
2645
paul4dadc292005-05-06 21:37:42 +00002646static int
paul718e3742002-12-13 20:15:29 +00002647ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2648 struct stream *s)
2649{
2650 struct ospf_lsa *lsa;
2651 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2652 u_char options;
2653 unsigned long pp;
2654 int i;
2655 struct ospf_lsdb *lsdb;
2656
2657 /* Set Interface MTU. */
2658 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2659 stream_putw (s, 0);
2660 else
2661 stream_putw (s, oi->ifp->mtu);
2662
2663 /* Set Options. */
2664 options = OPTIONS (oi);
2665#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002666 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002667 {
2668 if (IS_SET_DD_I (nbr->dd_flags)
2669 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2670 /*
2671 * Set O-bit in the outgoing DD packet for capablity negotiation,
2672 * if one of following case is applicable.
2673 *
2674 * 1) WaitTimer expiration event triggered the neighbor state to
2675 * change to Exstart, but no (valid) DD packet has received
2676 * from the neighbor yet.
2677 *
2678 * 2) At least one DD packet with O-bit on has received from the
2679 * neighbor.
2680 */
2681 SET_FLAG (options, OSPF_OPTION_O);
2682 }
2683#endif /* HAVE_OPAQUE_LSA */
2684 stream_putc (s, options);
2685
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002686 /* DD flags */
paul9985f832005-02-09 15:51:56 +00002687 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002688 stream_putc (s, nbr->dd_flags);
2689
2690 /* Set DD Sequence Number. */
2691 stream_putl (s, nbr->dd_seqnum);
2692
2693 if (ospf_db_summary_isempty (nbr))
2694 {
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002695 /* Sanity check:
2696 *
2697 * Must be here either:
2698 * - Initial DBD (ospf_nsm.c)
2699 * - M must be set
2700 * or
2701 * - finishing Exchange, and DB-Summary list empty
2702 * - from ospf_db_desc_proc()
2703 * - M must not be set
2704 */
paul718e3742002-12-13 20:15:29 +00002705 if (nbr->state >= NSM_Exchange)
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002706 assert (!IS_SET_DD_M(nbr->dd_flags));
2707 else
2708 assert (IS_SET_DD_M(nbr->dd_flags));
2709
paul718e3742002-12-13 20:15:29 +00002710 return length;
2711 }
2712
2713 /* Describe LSA Header from Database Summary List. */
2714 lsdb = &nbr->db_sum;
2715
2716 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2717 {
2718 struct route_table *table = lsdb->type[i].db;
2719 struct route_node *rn;
2720
2721 for (rn = route_top (table); rn; rn = route_next (rn))
2722 if ((lsa = rn->info) != NULL)
2723 {
2724#ifdef HAVE_OPAQUE_LSA
2725 if (IS_OPAQUE_LSA (lsa->data->type)
2726 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2727 {
2728 /* Suppress advertising opaque-informations. */
2729 /* Remove LSA from DB summary list. */
2730 ospf_lsdb_delete (lsdb, lsa);
2731 continue;
2732 }
2733#endif /* HAVE_OPAQUE_LSA */
2734
2735 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2736 {
2737 struct lsa_header *lsah;
2738 u_int16_t ls_age;
2739
2740 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002741 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002742 break;
2743
2744 /* Keep pointer to LS age. */
2745 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002746 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002747
2748 /* Proceed stream pointer. */
2749 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2750 length += OSPF_LSA_HEADER_SIZE;
2751
2752 /* Set LS age. */
2753 ls_age = LS_AGE (lsa);
2754 lsah->ls_age = htons (ls_age);
2755
2756 }
2757
2758 /* Remove LSA from DB summary list. */
2759 ospf_lsdb_delete (lsdb, lsa);
2760 }
2761 }
2762
Paul Jakma8dd24ee2006-08-27 06:29:30 +00002763 /* Update 'More' bit */
2764 if (ospf_db_summary_isempty (nbr))
2765 {
2766 UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M);
2767 /* Rewrite DD flags */
2768 stream_putc_at (s, pp, nbr->dd_flags);
2769 }
paul718e3742002-12-13 20:15:29 +00002770 return length;
2771}
2772
paul4dadc292005-05-06 21:37:42 +00002773static int
paul718e3742002-12-13 20:15:29 +00002774ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2775 unsigned long delta, struct ospf_neighbor *nbr,
2776 struct ospf_lsa *lsa)
2777{
2778 struct ospf_interface *oi;
2779
2780 oi = nbr->oi;
2781
2782 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002783 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002784 return 0;
2785
2786 stream_putl (s, lsa->data->type);
2787 stream_put_ipv4 (s, lsa->data->id.s_addr);
2788 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2789
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002790 ospf_lsa_unlock (&nbr->ls_req_last);
paul718e3742002-12-13 20:15:29 +00002791 nbr->ls_req_last = ospf_lsa_lock (lsa);
2792
2793 *length += 12;
2794 return 1;
2795}
2796
paul4dadc292005-05-06 21:37:42 +00002797static int
paul718e3742002-12-13 20:15:29 +00002798ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2799{
2800 struct ospf_lsa *lsa;
2801 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002802 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002803 struct route_table *table;
2804 struct route_node *rn;
2805 int i;
2806 struct ospf_lsdb *lsdb;
2807
2808 lsdb = &nbr->ls_req;
2809
2810 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2811 {
2812 table = lsdb->type[i].db;
2813 for (rn = route_top (table); rn; rn = route_next (rn))
2814 if ((lsa = (rn->info)) != NULL)
2815 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2816 {
2817 route_unlock_node (rn);
2818 break;
2819 }
2820 }
2821 return length;
2822}
2823
paul4dadc292005-05-06 21:37:42 +00002824static int
paul718e3742002-12-13 20:15:29 +00002825ls_age_increment (struct ospf_lsa *lsa, int delay)
2826{
2827 int age;
2828
2829 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2830
2831 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2832}
2833
paul4dadc292005-05-06 21:37:42 +00002834static int
hasso52dc7ee2004-09-23 19:18:23 +00002835ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002836{
2837 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002838 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002839 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002840 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002841 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002842 unsigned long pp;
2843 int count = 0;
2844
2845 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002846 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002847
paul9985f832005-02-09 15:51:56 +00002848 pp = stream_get_endp (s);
2849 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002850
gdt86f1fd92005-01-10 14:20:43 +00002851 /* Calculate amount of packet usable for data. */
2852 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2853
paul718e3742002-12-13 20:15:29 +00002854 while ((node = listhead (update)) != NULL)
2855 {
2856 struct lsa_header *lsah;
2857 u_int16_t ls_age;
2858
2859 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002860 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002861
paul1eb8ef22005-04-07 07:30:20 +00002862 lsa = listgetdata (node);
2863
paul718e3742002-12-13 20:15:29 +00002864 assert (lsa->data);
2865
paul68b73392004-09-12 14:21:37 +00002866 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002867 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002868 break;
2869
paul718e3742002-12-13 20:15:29 +00002870 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002871 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002872
2873 /* Put LSA to Link State Request. */
2874 stream_put (s, lsa->data, ntohs (lsa->data->length));
2875
2876 /* Set LS age. */
2877 /* each hop must increment an lsa_age by transmit_delay
2878 of OSPF interface */
2879 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2880 lsah->ls_age = htons (ls_age);
2881
2882 length += ntohs (lsa->data->length);
2883 count++;
2884
2885 list_delete_node (update, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002886 ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00002887 }
2888
2889 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002890 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002891
2892 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002893 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002894 return length;
2895}
2896
paul4dadc292005-05-06 21:37:42 +00002897static int
hasso52dc7ee2004-09-23 19:18:23 +00002898ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002899{
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002900 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002901 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002902 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002903 struct ospf_lsa *lsa;
2904
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002905 for (ALL_LIST_ELEMENTS (ack, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002906 {
paul718e3742002-12-13 20:15:29 +00002907 assert (lsa);
2908
gdt86f1fd92005-01-10 14:20:43 +00002909 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002910 break;
2911
2912 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2913 length += OSPF_LSA_HEADER_SIZE;
2914
paul718e3742002-12-13 20:15:29 +00002915 listnode_delete (ack, lsa);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002916 ospf_lsa_unlock (&lsa); /* oi->ls_ack_direct.ls_ack */
paul718e3742002-12-13 20:15:29 +00002917 }
2918
paul718e3742002-12-13 20:15:29 +00002919 return length;
2920}
2921
2922void
2923ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2924{
2925 struct ospf_packet *op;
2926 u_int16_t length = OSPF_HEADER_SIZE;
2927
2928 op = ospf_packet_new (oi->ifp->mtu);
2929
2930 /* Prepare OSPF common header. */
2931 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2932
2933 /* Prepare OSPF Hello body. */
2934 length += ospf_make_hello (oi, op->s);
2935
2936 /* Fill OSPF header. */
2937 ospf_fill_header (oi, op->s, length);
2938
2939 /* Set packet length. */
2940 op->length = length;
2941
2942 op->dst.s_addr = addr->s_addr;
2943
2944 /* Add packet to the interface output queue. */
2945 ospf_packet_add (oi, op);
2946
2947 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002948 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002949}
2950
paul4dadc292005-05-06 21:37:42 +00002951static void
paul718e3742002-12-13 20:15:29 +00002952ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2953{
2954 struct ospf_interface *oi;
2955
2956 oi = nbr_nbma->oi;
2957 assert(oi);
2958
2959 /* If this is passive interface, do not send OSPF Hello. */
2960 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2961 return;
2962
2963 if (oi->type != OSPF_IFTYPE_NBMA)
2964 return;
2965
2966 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2967 return;
2968
2969 if (PRIORITY(oi) == 0)
2970 return;
2971
2972 if (nbr_nbma->priority == 0
2973 && oi->state != ISM_DR && oi->state != ISM_Backup)
2974 return;
2975
2976 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2977}
2978
2979int
2980ospf_poll_timer (struct thread *thread)
2981{
2982 struct ospf_nbr_nbma *nbr_nbma;
2983
2984 nbr_nbma = THREAD_ARG (thread);
2985 nbr_nbma->t_poll = NULL;
2986
2987 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002988 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002989 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2990
2991 ospf_poll_send (nbr_nbma);
2992
2993 if (nbr_nbma->v_poll > 0)
2994 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2995 nbr_nbma->v_poll);
2996
2997 return 0;
2998}
2999
3000
3001int
3002ospf_hello_reply_timer (struct thread *thread)
3003{
3004 struct ospf_neighbor *nbr;
3005
3006 nbr = THREAD_ARG (thread);
3007 nbr->t_hello_reply = NULL;
3008
3009 assert (nbr->oi);
3010
3011 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003012 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003013 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3014
3015 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3016
3017 return 0;
3018}
3019
3020/* Send OSPF Hello. */
3021void
3022ospf_hello_send (struct ospf_interface *oi)
3023{
3024 struct ospf_packet *op;
3025 u_int16_t length = OSPF_HEADER_SIZE;
3026
3027 /* If this is passive interface, do not send OSPF Hello. */
3028 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3029 return;
3030
3031 op = ospf_packet_new (oi->ifp->mtu);
3032
3033 /* Prepare OSPF common header. */
3034 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3035
3036 /* Prepare OSPF Hello body. */
3037 length += ospf_make_hello (oi, op->s);
3038
3039 /* Fill OSPF header. */
3040 ospf_fill_header (oi, op->s, length);
3041
3042 /* Set packet length. */
3043 op->length = length;
3044
3045 if (oi->type == OSPF_IFTYPE_NBMA)
3046 {
3047 struct ospf_neighbor *nbr;
3048 struct route_node *rn;
3049
3050 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3051 if ((nbr = rn->info))
3052 if (nbr != oi->nbr_self)
3053 if (nbr->state != NSM_Down)
3054 {
3055 /* RFC 2328 Section 9.5.1
3056 If the router is not eligible to become Designated Router,
3057 it must periodically send Hello Packets to both the
3058 Designated Router and the Backup Designated Router (if they
3059 exist). */
3060 if (PRIORITY(oi) == 0 &&
3061 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3062 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3063 continue;
3064
3065 /* If the router is eligible to become Designated Router, it
3066 must periodically send Hello Packets to all neighbors that
3067 are also eligible. In addition, if the router is itself the
3068 Designated Router or Backup Designated Router, it must also
3069 send periodic Hello Packets to all other neighbors. */
3070
3071 if (nbr->priority == 0 && oi->state == ISM_DROther)
3072 continue;
3073 /* if oi->state == Waiting, send hello to all neighbors */
3074 {
3075 struct ospf_packet *op_dup;
3076
3077 op_dup = ospf_packet_dup(op);
3078 op_dup->dst = nbr->address.u.prefix4;
3079
3080 /* Add packet to the interface output queue. */
3081 ospf_packet_add (oi, op_dup);
3082
paul020709f2003-04-04 02:44:16 +00003083 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003084 }
3085
3086 }
3087 ospf_packet_free (op);
3088 }
3089 else
3090 {
3091 /* Decide destination address. */
3092 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3093 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3094 else
3095 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3096
3097 /* Add packet to the interface output queue. */
3098 ospf_packet_add (oi, op);
3099
3100 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003101 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003102 }
3103}
3104
3105/* Send OSPF Database Description. */
3106void
3107ospf_db_desc_send (struct ospf_neighbor *nbr)
3108{
3109 struct ospf_interface *oi;
3110 struct ospf_packet *op;
3111 u_int16_t length = OSPF_HEADER_SIZE;
3112
3113 oi = nbr->oi;
3114 op = ospf_packet_new (oi->ifp->mtu);
3115
3116 /* Prepare OSPF common header. */
3117 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3118
3119 /* Prepare OSPF Database Description body. */
3120 length += ospf_make_db_desc (oi, nbr, op->s);
3121
3122 /* Fill OSPF header. */
3123 ospf_fill_header (oi, op->s, length);
3124
3125 /* Set packet length. */
3126 op->length = length;
3127
3128 /* Decide destination address. */
3129 op->dst = nbr->address.u.prefix4;
3130
3131 /* Add packet to the interface output queue. */
3132 ospf_packet_add (oi, op);
3133
3134 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003135 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003136
3137 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3138 if (nbr->last_send)
3139 ospf_packet_free (nbr->last_send);
3140 nbr->last_send = ospf_packet_dup (op);
3141 gettimeofday (&nbr->last_send_ts, NULL);
3142}
3143
3144/* Re-send Database Description. */
3145void
3146ospf_db_desc_resend (struct ospf_neighbor *nbr)
3147{
3148 struct ospf_interface *oi;
3149
3150 oi = nbr->oi;
3151
3152 /* Add packet to the interface output queue. */
3153 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3154
3155 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003156 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003157}
3158
3159/* Send Link State Request. */
3160void
3161ospf_ls_req_send (struct ospf_neighbor *nbr)
3162{
3163 struct ospf_interface *oi;
3164 struct ospf_packet *op;
3165 u_int16_t length = OSPF_HEADER_SIZE;
3166
3167 oi = nbr->oi;
3168 op = ospf_packet_new (oi->ifp->mtu);
3169
3170 /* Prepare OSPF common header. */
3171 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3172
3173 /* Prepare OSPF Link State Request body. */
3174 length += ospf_make_ls_req (nbr, op->s);
3175 if (length == OSPF_HEADER_SIZE)
3176 {
3177 ospf_packet_free (op);
3178 return;
3179 }
3180
3181 /* Fill OSPF header. */
3182 ospf_fill_header (oi, op->s, length);
3183
3184 /* Set packet length. */
3185 op->length = length;
3186
3187 /* Decide destination address. */
3188 op->dst = nbr->address.u.prefix4;
3189
3190 /* Add packet to the interface output queue. */
3191 ospf_packet_add (oi, op);
3192
3193 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003194 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003195
3196 /* Add Link State Request Retransmission Timer. */
3197 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3198}
3199
3200/* Send Link State Update with an LSA. */
3201void
3202ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3203 int flag)
3204{
hasso52dc7ee2004-09-23 19:18:23 +00003205 struct list *update;
paul718e3742002-12-13 20:15:29 +00003206
3207 update = list_new ();
3208
3209 listnode_add (update, lsa);
3210 ospf_ls_upd_send (nbr, update, flag);
3211
3212 list_delete (update);
3213}
3214
paul68b73392004-09-12 14:21:37 +00003215/* Determine size for packet. Must be at least big enough to accomodate next
3216 * LSA on list, which may be bigger than MTU size.
3217 *
3218 * Return pointer to new ospf_packet
3219 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3220 * on packet sizes (in which case offending LSA is deleted from update list)
3221 */
3222static struct ospf_packet *
3223ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3224{
3225 struct ospf_lsa *lsa;
3226 struct listnode *ln;
3227 size_t size;
3228 static char warned = 0;
3229
paul1eb8ef22005-04-07 07:30:20 +00003230 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003231 assert (lsa->data);
3232
3233 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3234 > ospf_packet_max (oi))
3235 {
3236 if (!warned)
3237 {
3238 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3239 "will need to fragment. Not optimal. Try divide up"
3240 " your network with areas. Use 'debug ospf packet send'"
3241 " to see details, or look at 'show ip ospf database ..'");
3242 warned = 1;
3243 }
3244
3245 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003246 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003247 " %d bytes originated by %s, will be fragmented!",
3248 inet_ntoa (lsa->data->id),
3249 ntohs (lsa->data->length),
3250 inet_ntoa (lsa->data->adv_router));
3251
3252 /*
3253 * Allocate just enough to fit this LSA only, to avoid including other
3254 * LSAs in fragmented LSA Updates.
3255 */
3256 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3257 + OSPF_LS_UPD_MIN_SIZE;
3258 }
3259 else
3260 size = oi->ifp->mtu;
3261
gdt86f1fd92005-01-10 14:20:43 +00003262 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003263 if (size > OSPF_MAX_PACKET_SIZE)
3264 {
3265 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003266 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003267 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003268 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003269 (long int) size);
paul68b73392004-09-12 14:21:37 +00003270 list_delete_node (update, ln);
3271 return NULL;
3272 }
3273
3274 return ospf_packet_new (size);
3275}
3276
paul718e3742002-12-13 20:15:29 +00003277static void
hasso52dc7ee2004-09-23 19:18:23 +00003278ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003279 struct in_addr addr)
3280{
3281 struct ospf_packet *op;
3282 u_int16_t length = OSPF_HEADER_SIZE;
3283
3284 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003285 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003286
3287 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003288
3289 /* Prepare OSPF common header. */
3290 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3291
paul59ea14c2004-07-14 20:50:36 +00003292 /* Prepare OSPF Link State Update body.
3293 * Includes Type-7 translation.
3294 */
paul718e3742002-12-13 20:15:29 +00003295 length += ospf_make_ls_upd (oi, update, op->s);
3296
3297 /* Fill OSPF header. */
3298 ospf_fill_header (oi, op->s, length);
3299
3300 /* Set packet length. */
3301 op->length = length;
3302
3303 /* Decide destination address. */
3304 op->dst.s_addr = addr.s_addr;
3305
3306 /* Add packet to the interface output queue. */
3307 ospf_packet_add (oi, op);
3308
3309 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003310 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003311}
3312
3313static int
3314ospf_ls_upd_send_queue_event (struct thread *thread)
3315{
3316 struct ospf_interface *oi = THREAD_ARG(thread);
3317 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003318 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003319 struct list *update;
paul68b73392004-09-12 14:21:37 +00003320 char again = 0;
paul718e3742002-12-13 20:15:29 +00003321
3322 oi->t_ls_upd_event = NULL;
3323
3324 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003325 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003326
paul736d3442003-07-24 23:22:57 +00003327 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003328 {
paul736d3442003-07-24 23:22:57 +00003329 rnext = route_next (rn);
3330
paul718e3742002-12-13 20:15:29 +00003331 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003332 continue;
paul68b73392004-09-12 14:21:37 +00003333
3334 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003335
paul48fe13b2004-07-27 17:40:44 +00003336 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003337
paul68b73392004-09-12 14:21:37 +00003338 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003339 if (listcount(update) == 0)
3340 {
3341 list_delete (rn->info);
3342 rn->info = NULL;
3343 route_unlock_node (rn);
3344 }
3345 else
paul68b73392004-09-12 14:21:37 +00003346 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003347 }
3348
3349 if (again != 0)
3350 {
3351 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003352 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003353 " %d nodes to try again, raising new event", again);
3354 oi->t_ls_upd_event =
3355 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003356 }
3357
3358 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003359 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003360
paul718e3742002-12-13 20:15:29 +00003361 return 0;
3362}
3363
3364void
hasso52dc7ee2004-09-23 19:18:23 +00003365ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003366{
3367 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003368 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003369 struct prefix_ipv4 p;
3370 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003371 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003372
3373 oi = nbr->oi;
3374
3375 p.family = AF_INET;
3376 p.prefixlen = IPV4_MAX_BITLEN;
3377
3378 /* Decide destination address. */
3379 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3380 p.prefix = oi->vl_data->peer_addr;
3381 else if (flag == OSPF_SEND_PACKET_DIRECT)
3382 p.prefix = nbr->address.u.prefix4;
3383 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3384 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3385 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3386 && (flag == OSPF_SEND_PACKET_INDIRECT))
3387 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003388 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3389 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003390 else
3391 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3392
3393 if (oi->type == OSPF_IFTYPE_NBMA)
3394 {
3395 if (flag == OSPF_SEND_PACKET_INDIRECT)
3396 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3397 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3398 zlog_warn ("* LS-Update is sent to myself.");
3399 }
3400
3401 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3402
3403 if (rn->info == NULL)
3404 rn->info = list_new ();
3405
paul1eb8ef22005-04-07 07:30:20 +00003406 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003407 listnode_add (rn->info, ospf_lsa_lock (lsa)); /* oi->ls_upd_queue */
paul718e3742002-12-13 20:15:29 +00003408
3409 if (oi->t_ls_upd_event == NULL)
3410 oi->t_ls_upd_event =
3411 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3412}
3413
3414static void
hasso52dc7ee2004-09-23 19:18:23 +00003415ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3416 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003417{
3418 struct ospf_packet *op;
3419 u_int16_t length = OSPF_HEADER_SIZE;
3420
3421 op = ospf_packet_new (oi->ifp->mtu);
3422
3423 /* Prepare OSPF common header. */
3424 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3425
3426 /* Prepare OSPF Link State Acknowledgment body. */
3427 length += ospf_make_ls_ack (oi, ack, op->s);
3428
3429 /* Fill OSPF header. */
3430 ospf_fill_header (oi, op->s, length);
3431
3432 /* Set packet length. */
3433 op->length = length;
3434
3435 /* Set destination IP address. */
3436 op->dst = dst;
3437
3438 /* Add packet to the interface output queue. */
3439 ospf_packet_add (oi, op);
3440
3441 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003442 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003443}
3444
3445static int
3446ospf_ls_ack_send_event (struct thread *thread)
3447{
3448 struct ospf_interface *oi = THREAD_ARG (thread);
3449
3450 oi->t_ls_ack_direct = NULL;
3451
3452 while (listcount (oi->ls_ack_direct.ls_ack))
3453 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3454 oi->ls_ack_direct.dst);
3455
3456 return 0;
3457}
3458
3459void
3460ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3461{
3462 struct ospf_interface *oi = nbr->oi;
3463
3464 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3465 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3466
3467 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3468
3469 if (oi->t_ls_ack_direct == NULL)
3470 oi->t_ls_ack_direct =
3471 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3472}
3473
3474/* Send Link State Acknowledgment delayed. */
3475void
3476ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3477{
3478 struct in_addr dst;
3479
3480 /* Decide destination address. */
3481 /* RFC2328 Section 13.5 On non-broadcast
3482 networks, delayed Link State Acknowledgment packets must be
3483 unicast separately over each adjacency (i.e., neighbor whose
3484 state is >= Exchange). */
3485 if (oi->type == OSPF_IFTYPE_NBMA)
3486 {
3487 struct ospf_neighbor *nbr;
3488 struct route_node *rn;
3489
3490 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3491 if ((nbr = rn->info) != NULL)
3492 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3493 while (listcount (oi->ls_ack))
3494 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3495 return;
3496 }
3497 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3498 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3499 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3500 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3501 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3502 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003503 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3504 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003505 else
3506 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3507
3508 while (listcount (oi->ls_ack))
3509 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3510}