blob: f636e2be6d4e52b06471cded183b3c5069efba1e [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"
paul718e3742002-12-13 20:15:29 +000035#include "md5-gnu.h"
36
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_network.h"
39#include "ospfd/ospf_interface.h"
40#include "ospfd/ospf_ism.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_neighbor.h"
45#include "ospfd/ospf_nsm.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_flood.h"
49#include "ospfd/ospf_dump.h"
50
hasso52dc7ee2004-09-23 19:18:23 +000051static void ospf_ls_ack_send_list (struct ospf_interface *, struct list *,
paul718e3742002-12-13 20:15:29 +000052 struct in_addr);
53
54/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000055const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000056{
57 "unknown",
58 "Hello",
59 "Database Description",
60 "Link State Request",
61 "Link State Update",
62 "Link State Acknowledgment",
63};
64
65extern int in_cksum (void *ptr, int nbytes);
66
67/* OSPF authentication checking function */
68int
69ospf_auth_type (struct ospf_interface *oi)
70{
71 int auth_type;
72
73 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
74 auth_type = oi->area->auth_type;
75 else
76 auth_type = OSPF_IF_PARAM (oi, auth_type);
77
78 /* Handle case where MD5 key list is not configured aka Cisco */
79 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
80 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
81 return OSPF_AUTH_NULL;
82
83 return auth_type;
84
85}
86
87/* forward output pointer. */
88void
89ospf_output_forward (struct stream *s, int size)
90{
91 s->putp += size;
92}
93
94struct ospf_packet *
95ospf_packet_new (size_t size)
96{
97 struct ospf_packet *new;
98
99 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
100 new->s = stream_new (size);
101
102 return new;
103}
104
105void
106ospf_packet_free (struct ospf_packet *op)
107{
108 if (op->s)
109 stream_free (op->s);
110
111 XFREE (MTYPE_OSPF_PACKET, op);
112
113 op = NULL;
114}
115
116struct ospf_fifo *
117ospf_fifo_new ()
118{
119 struct ospf_fifo *new;
120
121 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
122 return new;
123}
124
125/* Add new packet to fifo. */
126void
127ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
128{
129 if (fifo->tail)
130 fifo->tail->next = op;
131 else
132 fifo->head = op;
133
134 fifo->tail = op;
135
136 fifo->count++;
137}
138
139/* Delete first packet from fifo. */
140struct ospf_packet *
141ospf_fifo_pop (struct ospf_fifo *fifo)
142{
143 struct ospf_packet *op;
144
145 op = fifo->head;
146
147 if (op)
148 {
149 fifo->head = op->next;
150
151 if (fifo->head == NULL)
152 fifo->tail = NULL;
153
154 fifo->count--;
155 }
156
157 return op;
158}
159
160/* Return first fifo entry. */
161struct ospf_packet *
162ospf_fifo_head (struct ospf_fifo *fifo)
163{
164 return fifo->head;
165}
166
167/* Flush ospf packet fifo. */
168void
169ospf_fifo_flush (struct ospf_fifo *fifo)
170{
171 struct ospf_packet *op;
172 struct ospf_packet *next;
173
174 for (op = fifo->head; op; op = next)
175 {
176 next = op->next;
177 ospf_packet_free (op);
178 }
179 fifo->head = fifo->tail = NULL;
180 fifo->count = 0;
181}
182
183/* Free ospf packet fifo. */
184void
185ospf_fifo_free (struct ospf_fifo *fifo)
186{
187 ospf_fifo_flush (fifo);
188
189 XFREE (MTYPE_OSPF_FIFO, fifo);
190}
191
192void
193ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
194{
195 /* 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
213struct stream *
214ospf_stream_copy (struct stream *new, struct stream *s)
215{
216 new->endp = s->endp;
217 new->putp = s->putp;
218 new->getp = s->getp;
219
220 memcpy (new->data, s->data, stream_get_endp (s));
221
222 return new;
223}
224
225struct ospf_packet *
226ospf_packet_dup (struct ospf_packet *op)
227{
228 struct ospf_packet *new;
229
paul37163d62003-02-03 18:40:56 +0000230 if (stream_get_endp(op->s) != op->length)
231 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000232 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000233
234 /* Reserve space for MD5 authentication that may be added later. */
235 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000236 ospf_stream_copy (new->s, op->s);
237
238 new->dst = op->dst;
239 new->length = op->length;
240
241 return new;
242}
243
gdt86f1fd92005-01-10 14:20:43 +0000244/* XXX inline */
245unsigned int
246ospf_packet_authspace (struct ospf_interface *oi)
247{
248 int auth = 0;
249
250 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
251 auth = OSPF_AUTH_MD5_SIZE;
252
253 return auth;
254}
255
paul6c835672004-10-11 11:00:30 +0000256unsigned int
paul718e3742002-12-13 20:15:29 +0000257ospf_packet_max (struct ospf_interface *oi)
258{
259 int max;
260
gdt86f1fd92005-01-10 14:20:43 +0000261 max = oi->ifp->mtu - ospf_packet_authspace(oi);
262
paul68b73392004-09-12 14:21:37 +0000263 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000264
265 return max;
266}
267
268
269int
270ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
271 u_int16_t length)
272{
paul6c835672004-10-11 11:00:30 +0000273 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000274 struct md5_ctx ctx;
275 unsigned char digest[OSPF_AUTH_MD5_SIZE];
276 unsigned char *pdigest;
277 struct crypt_key *ck;
278 struct ospf_header *ospfh;
279 struct ospf_neighbor *nbr;
280
281
282 ibuf = STREAM_PNT (s);
283 ospfh = (struct ospf_header *) ibuf;
284
285 /* Get pointer to the end of the packet. */
286 pdigest = ibuf + length;
287
288 /* Get secret key. */
289 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
290 ospfh->u.crypt.key_id);
291 if (ck == NULL)
292 {
293 zlog_warn ("interface %s: ospf_check_md5 no key %d",
294 IF_NAME (oi), ospfh->u.crypt.key_id);
295 return 0;
296 }
297
298 /* check crypto seqnum. */
299 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
300
301 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
302 {
303 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
304 IF_NAME (oi),
305 ntohl(ospfh->u.crypt.crypt_seqnum),
306 ntohl(nbr->crypt_seqnum));
307 return 0;
308 }
309
310 /* Generate a digest for the ospf packet - their digest + our digest. */
311 md5_init_ctx (&ctx);
312 md5_process_bytes (ibuf, length, &ctx);
313 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
314 md5_finish_ctx (&ctx, digest);
315
316 /* compare the two */
317 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
318 {
319 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
320 IF_NAME (oi));
321 return 0;
322 }
323
324 /* save neighbor's crypt_seqnum */
325 if (nbr)
326 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
327 return 1;
328}
329
330/* This function is called from ospf_write(), it will detect the
331 authentication scheme and if it is MD5, it will change the sequence
332 and update the MD5 digest. */
333int
334ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
335{
336 struct ospf_header *ospfh;
337 unsigned char digest[OSPF_AUTH_MD5_SIZE];
338 struct md5_ctx ctx;
339 void *ibuf;
340 unsigned long oldputp;
paul9483e152002-12-13 20:55:25 +0000341 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000342 struct crypt_key *ck;
343 char *auth_key;
344
345 ibuf = STREAM_DATA (op->s);
346 ospfh = (struct ospf_header *) ibuf;
347
348 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
349 return 0;
350
351 /* We do this here so when we dup a packet, we don't have to
352 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000353 t = (time(NULL) & 0xFFFFFFFF);
354 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
355 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000356
357 /* Get MD5 Authentication key from auth_key list. */
358 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000359 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000360 else
361 {
362 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000363 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000364 }
365
366 /* Generate a digest for the entire packet + our secret key. */
367 md5_init_ctx (&ctx);
368 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
369 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
370 md5_finish_ctx (&ctx, digest);
371
372 /* Append md5 digest to the end of the stream. */
373 oldputp = stream_get_putp (op->s);
374 stream_set_putp (op->s, ntohs (ospfh->length));
375 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
376 stream_set_putp (op->s, oldputp);
377
378 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000379 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
380
paul37163d62003-02-03 18:40:56 +0000381 if (stream_get_endp(op->s) != op->length)
382 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 +0000383
384 return OSPF_AUTH_MD5_SIZE;
385}
386
387
388int
389ospf_ls_req_timer (struct thread *thread)
390{
391 struct ospf_neighbor *nbr;
392
393 nbr = THREAD_ARG (thread);
394 nbr->t_ls_req = NULL;
395
396 /* Send Link State Request. */
397 if (ospf_ls_request_count (nbr))
398 ospf_ls_req_send (nbr);
399
400 /* Set Link State Request retransmission timer. */
401 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
402
403 return 0;
404}
405
406void
407ospf_ls_req_event (struct ospf_neighbor *nbr)
408{
409 if (nbr->t_ls_req)
410 {
411 thread_cancel (nbr->t_ls_req);
412 nbr->t_ls_req = NULL;
413 }
414 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
415}
416
417/* Cyclic timer function. Fist registered in ospf_nbr_new () in
418 ospf_neighbor.c */
419int
420ospf_ls_upd_timer (struct thread *thread)
421{
422 struct ospf_neighbor *nbr;
423
424 nbr = THREAD_ARG (thread);
425 nbr->t_ls_upd = NULL;
426
427 /* Send Link State Update. */
428 if (ospf_ls_retransmit_count (nbr) > 0)
429 {
hasso52dc7ee2004-09-23 19:18:23 +0000430 struct list *update;
paul718e3742002-12-13 20:15:29 +0000431 struct ospf_lsdb *lsdb;
432 int i;
433 struct timeval now;
434 int retransmit_interval;
435
436 gettimeofday (&now, NULL);
437 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
438
439 lsdb = &nbr->ls_rxmt;
440 update = list_new ();
441
442 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
443 {
444 struct route_table *table = lsdb->type[i].db;
445 struct route_node *rn;
446
447 for (rn = route_top (table); rn; rn = route_next (rn))
448 {
449 struct ospf_lsa *lsa;
450
451 if ((lsa = rn->info) != NULL)
452 /* Don't retransmit an LSA if we received it within
453 the last RxmtInterval seconds - this is to allow the
454 neighbour a chance to acknowledge the LSA as it may
455 have ben just received before the retransmit timer
456 fired. This is a small tweak to what is in the RFC,
457 but it will cut out out a lot of retransmit traffic
458 - MAG */
459 if (tv_cmp (tv_sub (now, lsa->tv_recv),
460 int2tv (retransmit_interval)) >= 0)
461 listnode_add (update, rn->info);
462 }
463 }
464
465 if (listcount (update) > 0)
466 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
467 list_delete (update);
468 }
469
470 /* Set LS Update retransmission timer. */
471 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
472
473 return 0;
474}
475
476int
477ospf_ls_ack_timer (struct thread *thread)
478{
479 struct ospf_interface *oi;
480
481 oi = THREAD_ARG (thread);
482 oi->t_ls_ack = NULL;
483
484 /* Send Link State Acknowledgment. */
485 if (listcount (oi->ls_ack) > 0)
486 ospf_ls_ack_send_delayed (oi);
487
488 /* Set LS Ack timer. */
489 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
490
491 return 0;
492}
493
paul0bfeca32004-09-24 08:07:54 +0000494#ifdef WANT_OSPF_WRITE_FRAGMENT
495void
paul6a99f832004-09-27 12:56:30 +0000496ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000497 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000498 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000499{
500#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000501 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000502 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000503 int ret;
paul0bfeca32004-09-24 08:07:54 +0000504
505 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000506 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000507
508 /* we can but try.
509 *
510 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
511 * well as the IP_MF flag, making this all quite pointless.
512 *
513 * However, for a system on which IP_MF is left alone, and ip_id left
514 * alone or else which sets same ip_id for each fragment this might
515 * work, eg linux.
516 *
517 * XXX-TODO: It would be much nicer to have the kernel's use their
518 * existing fragmentation support to do this for us. Bugs/RFEs need to
519 * be raised against the various kernels.
520 */
521
522 /* set More Frag */
523 iph->ip_off |= IP_MF;
524
525 /* ip frag offset is expressed in units of 8byte words */
526 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
527
paul62d8e962004-11-02 20:26:45 +0000528 iovp = &msg->msg_iov[1];
529
paul0bfeca32004-09-24 08:07:54 +0000530 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
531 > maxdatasize )
532 {
533 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000534 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
535 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000536 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000537
paul18b12c32004-10-05 14:38:29 +0000538 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000539
paul6a99f832004-09-27 12:56:30 +0000540 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000541
paul18b12c32004-10-05 14:38:29 +0000542 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000543
544 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000545 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000546 " id %d, off %d, len %d failed with %s",
547 inet_ntoa (iph->ip_dst),
548 iph->ip_id,
549 iph->ip_off,
550 iph->ip_len,
ajs6099b3b2004-11-20 02:06:59 +0000551 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000552
paul37ccfa32004-10-31 11:24:51 +0000553 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
554 {
ajs2a42e282004-12-08 18:43:03 +0000555 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000556 iph->ip_id, iph->ip_off, iph->ip_len,
557 inet_ntoa (iph->ip_dst));
558 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
559 {
ajs2a42e282004-12-08 18:43:03 +0000560 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000561 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000562 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000563 }
564 }
565
paul0bfeca32004-09-24 08:07:54 +0000566 iph->ip_off += offset;
paul62d8e962004-11-02 20:26:45 +0000567 stream_forward (op->s, iovp->iov_len);
568 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000569 }
570
571 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000572 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
573 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000574 iph->ip_off &= (~IP_MF);
575}
576#endif /* WANT_OSPF_WRITE_FRAGMENT */
577
paul718e3742002-12-13 20:15:29 +0000578int
579ospf_write (struct thread *thread)
580{
paul68980082003-03-25 05:07:42 +0000581 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000582 struct ospf_interface *oi;
583 struct ospf_packet *op;
584 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000585 struct ip iph;
586 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000587 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000588 u_char type;
589 int ret;
590 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000591 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000592#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000593 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000594#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000595 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000596#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000597
paul68980082003-03-25 05:07:42 +0000598 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000599
paul68980082003-03-25 05:07:42 +0000600 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000601 assert (node);
602 oi = getdata (node);
603 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000604
605#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000606 /* seed ipid static with low order bits of time */
607 if (ipid == 0)
608 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000609#endif /* WANT_OSPF_WRITE_FRAGMENT */
610
paul68b73392004-09-12 14:21:37 +0000611 /* convenience - max OSPF data per packet */
612 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
613
paul718e3742002-12-13 20:15:29 +0000614 /* Get one packet from queue. */
615 op = ospf_fifo_head (oi->obuf);
616 assert (op);
617 assert (op->length >= OSPF_HEADER_SIZE);
618
paul68980082003-03-25 05:07:42 +0000619 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
620 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000621 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
622
paul718e3742002-12-13 20:15:29 +0000623 /* Rewrite the md5 signature & update the seq */
624 ospf_make_md5_digest (oi, op);
625
paul37ccfa32004-10-31 11:24:51 +0000626 /* Retrieve OSPF packet type. */
627 stream_set_getp (op->s, 1);
628 type = stream_getc (op->s);
629
paul68b73392004-09-12 14:21:37 +0000630 /* reset get pointer */
631 stream_set_getp (op->s, 0);
632
633 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000634 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000635
paul718e3742002-12-13 20:15:29 +0000636 sa_dst.sin_family = AF_INET;
637#ifdef HAVE_SIN_LEN
638 sa_dst.sin_len = sizeof(sa_dst);
639#endif /* HAVE_SIN_LEN */
640 sa_dst.sin_addr = op->dst;
641 sa_dst.sin_port = htons (0);
642
643 /* Set DONTROUTE flag if dst is unicast. */
644 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
645 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
646 flags = MSG_DONTROUTE;
647
paul68b73392004-09-12 14:21:37 +0000648 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
649 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000650 if ( sizeof (struct ip)
651 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000652 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
653
paul718e3742002-12-13 20:15:29 +0000654 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000655 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000656 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000657
paul0bfeca32004-09-24 08:07:54 +0000658#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000659 /* XXX-MT: not thread-safe at all..
660 * XXX: this presumes this is only programme sending OSPF packets
661 * otherwise, no guarantee ipid will be unique
662 */
663 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000664#endif /* WANT_OSPF_WRITE_FRAGMENT */
665
paul718e3742002-12-13 20:15:29 +0000666 iph.ip_off = 0;
667 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
668 iph.ip_ttl = OSPF_VL_IP_TTL;
669 else
670 iph.ip_ttl = OSPF_IP_TTL;
671 iph.ip_p = IPPROTO_OSPFIGP;
672 iph.ip_sum = 0;
673 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
674 iph.ip_dst.s_addr = op->dst.s_addr;
675
676 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000677 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000678 msg.msg_namelen = sizeof (sa_dst);
679 msg.msg_iov = iov;
680 msg.msg_iovlen = 2;
681 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000682 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
683 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000684 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000685
686 /* Sadly we can not rely on kernels to fragment packets because of either
687 * IP_HDRINCL and/or multicast destination being set.
688 */
paul0bfeca32004-09-24 08:07:54 +0000689#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000690 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000691 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
692 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000693#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000694
695 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000696 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000697 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000698 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000699
700 if (ret < 0)
paul68b73392004-09-12 14:21:37 +0000701 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
ajs6099b3b2004-11-20 02:06:59 +0000702 inet_ntoa (iph.ip_dst), safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000703
paul718e3742002-12-13 20:15:29 +0000704 /* Show debug sending packet. */
705 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
706 {
707 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
708 {
ajs2a42e282004-12-08 18:43:03 +0000709 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000710 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000711 stream_set_getp (op->s, 0);
712 ospf_packet_dump (op->s);
713 }
714
ajs2a42e282004-12-08 18:43:03 +0000715 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000716 ospf_packet_type_str[type], inet_ntoa (op->dst),
717 IF_NAME (oi));
718
719 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000720 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* Now delete packet from queue. */
724 ospf_packet_delete (oi);
725
726 if (ospf_fifo_head (oi->obuf) == NULL)
727 {
728 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000729 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000730 }
731
732 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000733 if (!list_isempty (ospf->oi_write_q))
734 ospf->t_write =
735 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000736
737 return 0;
738}
739
740/* OSPF Hello message read -- RFC2328 Section 10.5. */
741void
742ospf_hello (struct ip *iph, struct ospf_header *ospfh,
743 struct stream * s, struct ospf_interface *oi, int size)
744{
745 struct ospf_hello *hello;
746 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000747 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000748 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000749
750 /* increment statistics. */
751 oi->hello_in++;
752
753 hello = (struct ospf_hello *) STREAM_PNT (s);
754
755 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000756 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000757 {
758 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
759 {
ajs2a42e282004-12-08 18:43:03 +0000760 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000761 "dropping.",
762 ospf_packet_type_str[ospfh->type],
763 inet_ntoa (iph->ip_src));
764 }
765 return;
766 }
paul718e3742002-12-13 20:15:29 +0000767
768 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000769 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
paulc2191ea2003-04-18 23:59:35 +0000770 zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
771 inet_ntoa (ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000772 return;
paulf2c80652002-12-13 21:44:27 +0000773 }
paul718e3742002-12-13 20:15:29 +0000774
775 /* get neighbor prefix. */
776 p.family = AF_INET;
777 p.prefixlen = ip_masklen (hello->network_mask);
778 p.u.prefix4 = iph->ip_src;
779
780 /* Compare network mask. */
781 /* Checking is ignored for Point-to-Point and Virtual link. */
782 if (oi->type != OSPF_IFTYPE_POINTOPOINT
783 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
784 if (oi->address->prefixlen != p.prefixlen)
785 {
786 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
787 inet_ntoa (ospfh->router_id));
788 return;
789 }
790
791 /* Compare Hello Interval. */
792 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
793 {
794 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
795 inet_ntoa (ospfh->router_id));
796 return;
797 }
798
799 /* Compare Router Dead Interval. */
800 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
801 {
802 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
803 inet_ntoa (ospfh->router_id));
804 return;
805 }
806
807 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000808 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000809 inet_ntoa (ospfh->router_id),
810 ospf_options_dump (hello->options));
811
812 /* Compare options. */
813#define REJECT_IF_TBIT_ON 1 /* XXX */
814#ifdef REJECT_IF_TBIT_ON
815 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
816 {
817 /*
818 * This router does not support non-zero TOS.
819 * Drop this Hello packet not to establish neighbor relationship.
820 */
821 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
822 inet_ntoa (ospfh->router_id));
823 return;
824 }
825#endif /* REJECT_IF_TBIT_ON */
826
827#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000828 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000829 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
830 {
831 /*
832 * This router does know the correct usage of O-bit
833 * the bit should be set in DD packet only.
834 */
835 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
836 inet_ntoa (ospfh->router_id));
837#ifdef STRICT_OBIT_USAGE_CHECK
838 return; /* Reject this packet. */
839#else /* STRICT_OBIT_USAGE_CHECK */
840 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
841#endif /* STRICT_OBIT_USAGE_CHECK */
842 }
843#endif /* HAVE_OPAQUE_LSA */
844
845 /* new for NSSA is to ensure that NP is on and E is off */
846
paul718e3742002-12-13 20:15:29 +0000847 if (oi->area->external_routing == OSPF_AREA_NSSA)
848 {
849 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
850 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
851 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
852 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
853 {
854 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
855 return;
856 }
857 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000858 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000859 }
860 else
paul718e3742002-12-13 20:15:29 +0000861 /* The setting of the E-bit found in the Hello Packet's Options
862 field must match this area's ExternalRoutingCapability A
863 mismatch causes processing to stop and the packet to be
864 dropped. The setting of the rest of the bits in the Hello
865 Packet's Options field should be ignored. */
866 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
867 CHECK_FLAG (hello->options, OSPF_OPTION_E))
868 {
ajs3aa8d5f2004-12-11 18:00:06 +0000869 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
870 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000871 return;
872 }
paul718e3742002-12-13 20:15:29 +0000873
pauld3f0d622004-05-05 15:27:15 +0000874 /* get neighbour struct */
875 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
876
877 /* neighbour must be valid, ospf_nbr_get creates if none existed */
878 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000879
880 old_state = nbr->state;
881
882 /* Add event to thread. */
883 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
884
885 /* RFC2328 Section 9.5.1
886 If the router is not eligible to become Designated Router,
887 (snip) It must also send an Hello Packet in reply to an
888 Hello Packet received from any eligible neighbor (other than
889 the current Designated Router and Backup Designated Router). */
890 if (oi->type == OSPF_IFTYPE_NBMA)
891 if (PRIORITY(oi) == 0 && hello->priority > 0
892 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
893 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
894 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
895 OSPF_HELLO_REPLY_DELAY);
896
897 /* on NBMA network type, it happens to receive bidirectional Hello packet
898 without advance 1-Way Received event.
899 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
900 if (oi->type == OSPF_IFTYPE_NBMA &&
901 (old_state == NSM_Down || old_state == NSM_Attempt))
902 {
903 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
904 nbr->priority = hello->priority;
905 nbr->d_router = hello->d_router;
906 nbr->bd_router = hello->bd_router;
907 return;
908 }
909
paul68980082003-03-25 05:07:42 +0000910 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000911 size - OSPF_HELLO_MIN_SIZE))
912 {
913 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
914 nbr->options |= hello->options;
915 }
916 else
917 {
918 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
919 /* Set neighbor information. */
920 nbr->priority = hello->priority;
921 nbr->d_router = hello->d_router;
922 nbr->bd_router = hello->bd_router;
923 return;
924 }
925
926 /* If neighbor itself declares DR and no BDR exists,
927 cause event BackupSeen */
928 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
929 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
930 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
931
932 /* neighbor itself declares BDR. */
933 if (oi->state == ISM_Waiting &&
934 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
935 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
936
937 /* had not previously. */
938 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
939 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
940 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
941 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
942 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
943
944 /* had not previously. */
945 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
946 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
947 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
948 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
949 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
950
951 /* Neighbor priority check. */
952 if (nbr->priority >= 0 && nbr->priority != hello->priority)
953 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
954
955 /* Set neighbor information. */
956 nbr->priority = hello->priority;
957 nbr->d_router = hello->d_router;
958 nbr->bd_router = hello->bd_router;
959}
960
961/* Save DD flags/options/Seqnum received. */
962void
963ospf_db_desc_save_current (struct ospf_neighbor *nbr,
964 struct ospf_db_desc *dd)
965{
966 nbr->last_recv.flags = dd->flags;
967 nbr->last_recv.options = dd->options;
968 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
969}
970
971/* Process rest of DD packet. */
972static void
973ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
974 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
975 u_int16_t size)
976{
977 struct ospf_lsa *new, *find;
978 struct lsa_header *lsah;
979
980 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
981 for (size -= OSPF_DB_DESC_MIN_SIZE;
982 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
983 {
984 lsah = (struct lsa_header *) STREAM_PNT (s);
985 stream_forward (s, OSPF_LSA_HEADER_SIZE);
986
987 /* Unknown LS type. */
988 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
989 {
ajsbec595a2004-11-30 22:38:43 +0000990 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000991 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
992 return;
993 }
994
995#ifdef HAVE_OPAQUE_LSA
996 if (IS_OPAQUE_LSA (lsah->type)
997 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
998 {
999 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1000 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1001 return;
1002 }
1003#endif /* HAVE_OPAQUE_LSA */
1004
1005 switch (lsah->type)
1006 {
1007 case OSPF_AS_EXTERNAL_LSA:
1008#ifdef HAVE_OPAQUE_LSA
1009 case OSPF_OPAQUE_AS_LSA:
1010#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001011 /* Check for stub area. Reject if AS-External from stub but
1012 allow if from NSSA. */
1013 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001014 {
1015 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1016 lsah->type, inet_ntoa (lsah->id),
1017 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1018 "STUB" : "NSSA");
1019 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1020 return;
1021 }
1022 break;
1023 default:
1024 break;
1025 }
1026
1027 /* Create LS-request object. */
1028 new = ospf_ls_request_new (lsah);
1029
1030 /* Lookup received LSA, then add LS request list. */
1031 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1032 if (!find || ospf_lsa_more_recent (find, new) < 0)
1033 {
1034 ospf_ls_request_add (nbr, new);
1035 ospf_lsa_discard (new);
1036 }
1037 else
1038 {
1039 /* Received LSA is not recent. */
1040 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001041 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001042 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1043 ospf_lsa_discard (new);
1044 continue;
1045 }
1046 }
1047
1048 /* Master */
1049 if (IS_SET_DD_MS (nbr->dd_flags))
1050 {
1051 nbr->dd_seqnum++;
1052 /* Entire DD packet sent. */
1053 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1054 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1055 else
1056 /* Send new DD packet. */
1057 ospf_db_desc_send (nbr);
1058 }
1059 /* Slave */
1060 else
1061 {
1062 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1063
1064 /* When master's more flags is not set. */
1065 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1066 {
1067 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1068 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1069 }
1070
ajsbec595a2004-11-30 22:38:43 +00001071 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001072 ospf_db_desc_send (nbr);
1073 }
1074
1075 /* Save received neighbor values from DD. */
1076 ospf_db_desc_save_current (nbr, dd);
1077}
1078
1079int
1080ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1081{
1082 /* Is DD duplicated? */
1083 if (dd->options == nbr->last_recv.options &&
1084 dd->flags == nbr->last_recv.flags &&
1085 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1086 return 1;
1087
1088 return 0;
1089}
1090
1091/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001092static void
paul718e3742002-12-13 20:15:29 +00001093ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1094 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1095{
1096 struct ospf_db_desc *dd;
1097 struct ospf_neighbor *nbr;
1098
1099 /* Increment statistics. */
1100 oi->db_desc_in++;
1101
1102 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001103
pauld3f0d622004-05-05 15:27:15 +00001104 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001105 if (nbr == NULL)
1106 {
1107 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1108 inet_ntoa (ospfh->router_id));
1109 return;
1110 }
1111
1112 /* Check MTU. */
1113 if (ntohs (dd->mtu) > oi->ifp->mtu)
1114 {
ajs3aa8d5f2004-12-11 18:00:06 +00001115 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1116 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1117 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001118 return;
1119 }
1120
pauld363df22003-06-19 00:26:34 +00001121 /*
1122 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1123 * required. In fact at least JunOS sends DD packets with P bit clear.
1124 * Until proper solution is developped, this hack should help.
1125 *
1126 * Update: According to the RFCs, N bit is specified /only/ for Hello
1127 * options, unfortunately its use in DD options is not specified. Hence some
1128 * implementations follow E-bit semantics and set it in DD options, and some
1129 * treat it as unspecified and hence follow the directive "default for
1130 * options is clear", ie unset.
1131 *
1132 * Reset the flag, as ospfd follows E-bit semantics.
1133 */
1134 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1135 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1136 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1137 {
1138 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001139 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001140 inet_ntoa (nbr->router_id) );
1141 SET_FLAG (dd->options, OSPF_OPTION_NP);
1142 }
pauld363df22003-06-19 00:26:34 +00001143
paul718e3742002-12-13 20:15:29 +00001144#ifdef REJECT_IF_TBIT_ON
1145 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1146 {
1147 /*
1148 * In Hello protocol, optional capability must have checked
1149 * to prevent this T-bit enabled router be my neighbor.
1150 */
1151 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1152 return;
1153 }
1154#endif /* REJECT_IF_TBIT_ON */
1155
1156#ifdef HAVE_OPAQUE_LSA
1157 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001158 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001159 {
1160 /*
1161 * This node is not configured to handle O-bit, for now.
1162 * Clear it to ignore unsupported capability proposed by neighbor.
1163 */
1164 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1165 }
1166#endif /* HAVE_OPAQUE_LSA */
1167
1168 /* Process DD packet by neighbor status. */
1169 switch (nbr->state)
1170 {
1171 case NSM_Down:
1172 case NSM_Attempt:
1173 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001174 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001175 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001176 LOOKUP (ospf_nsm_state_msg, nbr->state));
1177 break;
1178 case NSM_Init:
1179 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1180 /* If the new state is ExStart, the processing of the current
1181 packet should then continue in this new state by falling
1182 through to case ExStart below. */
1183 if (nbr->state != NSM_ExStart)
1184 break;
1185 case NSM_ExStart:
1186 /* Initial DBD */
1187 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1188 (size == OSPF_DB_DESC_MIN_SIZE))
1189 {
paul68980082003-03-25 05:07:42 +00001190 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001191 {
1192 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001193 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001194 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001195 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1196 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1197 }
1198 else
1199 {
1200 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001201 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1202 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001203 break;
1204 }
1205 }
1206 /* Ack from the Slave */
1207 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1208 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001209 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001210 {
ajs17eaa722004-12-29 21:04:48 +00001211 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001212 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001213 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1214 }
1215 else
1216 {
ajs3aa8d5f2004-12-11 18:00:06 +00001217 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1218 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001219 break;
1220 }
1221
1222 /* This is where the real Options are saved */
1223 nbr->options = dd->options;
1224
1225#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001226 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001227 {
1228 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001229 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001230 inet_ntoa (nbr->router_id),
1231 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1232
1233 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1234 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1235 {
1236 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1237 /* This situation is undesirable, but not a real error. */
1238 }
1239 }
1240#endif /* HAVE_OPAQUE_LSA */
1241
1242 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1243
1244 /* continue processing rest of packet. */
1245 ospf_db_desc_proc (s, oi, nbr, dd, size);
1246 break;
1247 case NSM_Exchange:
1248 if (ospf_db_desc_is_dup (dd, nbr))
1249 {
1250 if (IS_SET_DD_MS (nbr->dd_flags))
1251 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001252 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1253 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001254 else
1255 /* Slave: cause to retransmit the last Database Description. */
1256 {
ajs3aa8d5f2004-12-11 18:00:06 +00001257 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1258 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001259 ospf_db_desc_resend (nbr);
1260 }
1261 break;
1262 }
1263
1264 /* Otherwise DD packet should be checked. */
1265 /* Check Master/Slave bit mismatch */
1266 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1267 {
ajs3aa8d5f2004-12-11 18:00:06 +00001268 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1269 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001270 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1271 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001272 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001273 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001274 break;
1275 }
1276
1277 /* Check initialize bit is set. */
1278 if (IS_SET_DD_I (dd->flags))
1279 {
ajs3aa8d5f2004-12-11 18:00:06 +00001280 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1281 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001282 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1283 break;
1284 }
1285
1286 /* Check DD Options. */
1287 if (dd->options != nbr->options)
1288 {
1289#ifdef ORIGINAL_CODING
1290 /* Save the new options for debugging */
1291 nbr->options = dd->options;
1292#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001293 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1294 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001295 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1296 break;
1297 }
1298
1299 /* Check DD sequence number. */
1300 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1301 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1302 (!IS_SET_DD_MS (nbr->dd_flags) &&
1303 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1304 {
ajs3aa8d5f2004-12-11 18:00:06 +00001305 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1306 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001307 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1308 break;
1309 }
1310
1311 /* Continue processing rest of packet. */
1312 ospf_db_desc_proc (s, oi, nbr, dd, size);
1313 break;
1314 case NSM_Loading:
1315 case NSM_Full:
1316 if (ospf_db_desc_is_dup (dd, nbr))
1317 {
1318 if (IS_SET_DD_MS (nbr->dd_flags))
1319 {
1320 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001321 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1322 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001323 break;
1324 }
1325 else
1326 {
1327 struct timeval t, now;
1328 gettimeofday (&now, NULL);
1329 t = tv_sub (now, nbr->last_send_ts);
1330 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1331 {
1332 /* In states Loading and Full the slave must resend
1333 its last Database Description packet in response to
1334 duplicate Database Description packets received
1335 from the master. For this reason the slave must
1336 wait RouterDeadInterval seconds before freeing the
1337 last Database Description packet. Reception of a
1338 Database Description packet from the master after
1339 this interval will generate a SeqNumberMismatch
1340 neighbor event. RFC2328 Section 10.8 */
1341 ospf_db_desc_resend (nbr);
1342 break;
1343 }
1344 }
1345 }
1346
1347 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1348 break;
1349 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001350 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1351 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001352 break;
1353 }
1354}
1355
1356#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1357
1358/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1359void
1360ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1361 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1362{
1363 struct ospf_neighbor *nbr;
1364 u_int32_t ls_type;
1365 struct in_addr ls_id;
1366 struct in_addr adv_router;
1367 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001368 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001369 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001370
1371 /* Increment statistics. */
1372 oi->ls_req_in++;
1373
pauld3f0d622004-05-05 15:27:15 +00001374 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001375 if (nbr == NULL)
1376 {
1377 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1378 inet_ntoa (ospfh->router_id));
1379 return;
1380 }
1381
1382 /* Neighbor State should be Exchange or later. */
1383 if (nbr->state != NSM_Exchange &&
1384 nbr->state != NSM_Loading &&
1385 nbr->state != NSM_Full)
1386 {
ajsbec595a2004-11-30 22:38:43 +00001387 zlog_warn ("Link State Request received from %s: "
1388 "Neighbor state is %s, packet discarded.",
1389 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001390 LOOKUP (ospf_nsm_state_msg, nbr->state));
1391 return;
1392 }
1393
1394 /* Send Link State Update for ALL requested LSAs. */
1395 ls_upd = list_new ();
1396 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1397
1398 while (size >= OSPF_LSA_KEY_SIZE)
1399 {
1400 /* Get one slice of Link State Request. */
1401 ls_type = stream_getl (s);
1402 ls_id.s_addr = stream_get_ipv4 (s);
1403 adv_router.s_addr = stream_get_ipv4 (s);
1404
1405 /* Verify LSA type. */
1406 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1407 {
1408 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1409 list_delete (ls_upd);
1410 return;
1411 }
1412
1413 /* Search proper LSA in LSDB. */
1414 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1415 if (find == NULL)
1416 {
1417 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1418 list_delete (ls_upd);
1419 return;
1420 }
1421
gdt86f1fd92005-01-10 14:20:43 +00001422 /* Packet overflows MTU size, send immediately. */
1423 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001424 {
1425 if (oi->type == OSPF_IFTYPE_NBMA)
1426 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1427 else
1428 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1429
1430 /* Only remove list contents. Keep ls_upd. */
1431 list_delete_all_node (ls_upd);
1432
1433 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1434 }
1435
1436 /* Append LSA to update list. */
1437 listnode_add (ls_upd, find);
1438 length += ntohs (find->data->length);
1439
1440 size -= OSPF_LSA_KEY_SIZE;
1441 }
1442
1443 /* Send rest of Link State Update. */
1444 if (listcount (ls_upd) > 0)
1445 {
1446 if (oi->type == OSPF_IFTYPE_NBMA)
1447 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1448 else
1449 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1450
1451 list_delete (ls_upd);
1452 }
1453 else
1454 list_free (ls_upd);
1455}
1456
1457/* Get the list of LSAs from Link State Update packet.
1458 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001459static struct list *
paul718e3742002-12-13 20:15:29 +00001460ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1461 struct ospf_interface *oi, size_t size)
1462{
1463 u_int16_t count, sum;
1464 u_int32_t length;
1465 struct lsa_header *lsah;
1466 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001467 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001468
1469 lsas = list_new ();
1470
1471 count = stream_getl (s);
1472 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1473
1474 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1475 size -= length, stream_forward (s, length), count--)
1476 {
1477 lsah = (struct lsa_header *) STREAM_PNT (s);
1478 length = ntohs (lsah->length);
1479
1480 if (length > size)
1481 {
1482 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1483 break;
1484 }
1485
1486 /* Validate the LSA's LS checksum. */
1487 sum = lsah->checksum;
1488 if (sum != ospf_lsa_checksum (lsah))
1489 {
1490 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1491 sum, lsah->checksum);
1492 continue;
1493 }
1494
1495 /* Examine the LSA's LS type. */
1496 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1497 {
1498 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1499 continue;
1500 }
1501
1502 /*
1503 * What if the received LSA's age is greater than MaxAge?
1504 * Treat it as a MaxAge case -- endo.
1505 */
1506 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1507 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1508
1509#ifdef HAVE_OPAQUE_LSA
1510 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1511 {
1512#ifdef STRICT_OBIT_USAGE_CHECK
1513 if ((IS_OPAQUE_LSA(lsah->type) &&
1514 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1515 || (! IS_OPAQUE_LSA(lsah->type) &&
1516 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1517 {
1518 /*
1519 * This neighbor must know the exact usage of O-bit;
1520 * the bit will be set in Type-9,10,11 LSAs only.
1521 */
1522 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1523 continue;
1524 }
1525#endif /* STRICT_OBIT_USAGE_CHECK */
1526
1527 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1528 if (lsah->type == OSPF_OPAQUE_AS_LSA
1529 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1530 {
1531 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001532 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 +00001533 continue;
1534 }
1535 }
1536 else if (IS_OPAQUE_LSA(lsah->type))
1537 {
1538 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1539 continue;
1540 }
1541#endif /* HAVE_OPAQUE_LSA */
1542
1543 /* Create OSPF LSA instance. */
1544 lsa = ospf_lsa_new ();
1545
1546 /* We may wish to put some error checking if type NSSA comes in
1547 and area not in NSSA mode */
1548 switch (lsah->type)
1549 {
1550 case OSPF_AS_EXTERNAL_LSA:
1551#ifdef HAVE_OPAQUE_LSA
1552 case OSPF_OPAQUE_AS_LSA:
1553 lsa->area = NULL;
1554 break;
1555 case OSPF_OPAQUE_LINK_LSA:
1556 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1557 /* Fallthrough */
1558#endif /* HAVE_OPAQUE_LSA */
1559 default:
1560 lsa->area = oi->area;
1561 break;
1562 }
1563
1564 lsa->data = ospf_lsa_data_new (length);
1565 memcpy (lsa->data, lsah, length);
1566
1567 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001568 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001569 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1570 listnode_add (lsas, lsa);
1571 }
1572
1573 return lsas;
1574}
1575
1576/* Cleanup Update list. */
1577void
hasso52dc7ee2004-09-23 19:18:23 +00001578ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001579{
hasso52dc7ee2004-09-23 19:18:23 +00001580 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001581 struct ospf_lsa *lsa;
1582
1583 for (node = listhead (lsas); node; nextnode (node))
1584 if ((lsa = getdata (node)) != NULL)
1585 ospf_lsa_discard (lsa);
1586
1587 list_delete (lsas);
1588}
1589
1590/* OSPF Link State Update message read -- RFC2328 Section 13. */
1591void
1592ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1593 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1594{
1595 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001596 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001597#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001598 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001599#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001600 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001601 struct ospf_lsa *lsa = NULL;
1602 /* unsigned long ls_req_found = 0; */
1603
1604 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1605
1606 /* Increment statistics. */
1607 oi->ls_upd_in++;
1608
1609 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001610 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001611 if (nbr == NULL)
1612 {
1613 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1614 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1615 return;
1616 }
1617
1618 /* Check neighbor state. */
1619 if (nbr->state < NSM_Exchange)
1620 {
ajs3aa8d5f2004-12-11 18:00:06 +00001621 zlog_warn ("Link State Update: "
1622 "Neighbor[%s] state %s is less than Exchange",
1623 inet_ntoa (ospfh->router_id),
1624 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001625 return;
1626 }
1627
1628 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1629 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1630 * of section 13.
1631 */
1632 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1633
1634#ifdef HAVE_OPAQUE_LSA
1635 /*
1636 * Prepare two kinds of lists to clean up unwanted self-originated
1637 * Opaque-LSAs from the routing domain as soon as possible.
1638 */
1639 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1640 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1641
1642 /*
1643 * If self-originated Opaque-LSAs that have flooded before restart
1644 * are contained in the received LSUpd message, corresponding LSReq
1645 * messages to be sent may have to be modified.
1646 * To eliminate possible race conditions such that flushing and normal
1647 * updating for the same LSA would take place alternately, this trick
1648 * must be done before entering to the loop below.
1649 */
1650 ospf_opaque_adjust_lsreq (nbr, lsas);
1651#endif /* HAVE_OPAQUE_LSA */
1652
1653#define DISCARD_LSA(L,N) {\
1654 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001655 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 +00001656 ospf_lsa_discard (L); \
1657 continue; }
1658
1659 /* Process each LSA received in the one packet. */
1660 for (node = listhead (lsas); node; node = next)
1661 {
1662 struct ospf_lsa *ls_ret, *current;
1663 int ret = 1;
1664
1665 next = node->next;
1666
1667 lsa = getdata (node);
1668
paul718e3742002-12-13 20:15:29 +00001669 if (IS_DEBUG_OSPF_NSSA)
1670 {
1671 char buf1[INET_ADDRSTRLEN];
1672 char buf2[INET_ADDRSTRLEN];
1673 char buf3[INET_ADDRSTRLEN];
1674
ajs2a42e282004-12-08 18:43:03 +00001675 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001676 lsa->data->type,
1677 inet_ntop (AF_INET, &ospfh->router_id,
1678 buf1, INET_ADDRSTRLEN),
1679 inet_ntop (AF_INET, &lsa->data->id,
1680 buf2, INET_ADDRSTRLEN),
1681 inet_ntop (AF_INET, &lsa->data->adv_router,
1682 buf3, INET_ADDRSTRLEN));
1683 }
paul718e3742002-12-13 20:15:29 +00001684
1685 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1686
1687 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1688
1689 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1690
1691 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1692
1693 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1694
1695 /* Do take in Type-7's if we are an NSSA */
1696
1697 /* If we are also an ABR, later translate them to a Type-5 packet */
1698
1699 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1700 translate them to a separate Type-5 packet. */
1701
1702 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1703 /* Reject from STUB or NSSA */
1704 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1705 {
1706 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001707 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001708 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001709 }
1710
paul718e3742002-12-13 20:15:29 +00001711 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1712 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1713 {
1714 DISCARD_LSA (lsa,2);
1715 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001716 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001717 }
paul718e3742002-12-13 20:15:29 +00001718
1719 /* Find the LSA in the current database. */
1720
1721 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1722
1723 /* If the LSA's LS age is equal to MaxAge, and there is currently
1724 no instance of the LSA in the router's link state database,
1725 and none of router's neighbors are in states Exchange or Loading,
1726 then take the following actions. */
1727
1728 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001729 (ospf_nbr_count (oi, NSM_Exchange) +
1730 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001731 {
1732 /* Response Link State Acknowledgment. */
1733 ospf_ls_ack_send (nbr, lsa);
1734
1735 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001736 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1737 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001738 DISCARD_LSA (lsa, 3);
1739 }
1740
1741#ifdef HAVE_OPAQUE_LSA
1742 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001743 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001744 {
1745 /*
1746 * Even if initial flushing seems to be completed, there might
1747 * be a case that self-originated LSA with MaxAge still remain
1748 * in the routing domain.
1749 * Just send an LSAck message to cease retransmission.
1750 */
1751 if (IS_LSA_MAXAGE (lsa))
1752 {
1753 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1754 ospf_ls_ack_send (nbr, lsa);
1755 ospf_lsa_discard (lsa);
1756
1757 if (current != NULL && ! IS_LSA_MAXAGE (current))
1758 ospf_opaque_lsa_refresh_schedule (current);
1759 continue;
1760 }
1761
1762 /*
1763 * If an instance of self-originated Opaque-LSA is not found
1764 * in the LSDB, there are some possible cases here.
1765 *
1766 * 1) This node lost opaque-capability after restart.
1767 * 2) Else, a part of opaque-type is no more supported.
1768 * 3) Else, a part of opaque-id is no more supported.
1769 *
1770 * Anyway, it is still this node's responsibility to flush it.
1771 * Otherwise, the LSA instance remains in the routing domain
1772 * until its age reaches to MaxAge.
1773 */
1774 if (current == NULL)
1775 {
1776 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001777 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001778
1779 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1780 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1781 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1782 continue;
1783 }
1784 }
1785#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001786 /* It might be happen that received LSA is self-originated network LSA, but
1787 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1788 * Link State ID is one of the router's own IP interface addresses but whose
1789 * Advertising Router is not equal to the router's own Router ID
1790 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1791 */
1792
1793 if(lsa->data->type == OSPF_NETWORK_LSA)
1794 {
hasso52dc7ee2004-09-23 19:18:23 +00001795 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001796 int Flag = 0;
1797
1798 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1799 {
1800 struct ospf_interface *out_if = getdata(oi_node);
1801 if(out_if == NULL)
1802 break;
1803
1804 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1805 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1806 {
1807 if(out_if->network_lsa_self)
1808 {
1809 ospf_lsa_flush_area(lsa,out_if->area);
1810 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001811 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001812 lsa, (int) lsa->data->type);
1813 ospf_lsa_discard (lsa);
1814 Flag = 1;
1815 }
1816 break;
1817 }
1818 }
1819 if(Flag)
1820 continue;
1821 }
paul718e3742002-12-13 20:15:29 +00001822
1823 /* (5) Find the instance of this LSA that is currently contained
1824 in the router's link state database. If there is no
1825 database copy, or the received LSA is more recent than
1826 the database copy the following steps must be performed. */
1827
1828 if (current == NULL ||
1829 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1830 {
1831 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001832 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001833 DISCARD_LSA (lsa, 4);
1834 continue;
1835 }
1836
1837 /* (6) Else, If there is an instance of the LSA on the sending
1838 neighbor's Link state request list, an error has occurred in
1839 the Database Exchange process. In this case, restart the
1840 Database Exchange process by generating the neighbor event
1841 BadLSReq for the sending neighbor and stop processing the
1842 Link State Update packet. */
1843
1844 if (ospf_ls_request_lookup (nbr, lsa))
1845 {
1846 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001847 zlog_warn("LSA[%s] instance exists on Link state request list",
1848 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001849
1850 /* Clean list of LSAs. */
1851 ospf_upd_list_clean (lsas);
1852 /* this lsa is not on lsas list already. */
1853 ospf_lsa_discard (lsa);
1854#ifdef HAVE_OPAQUE_LSA
1855 list_delete (mylsa_acks);
1856 list_delete (mylsa_upds);
1857#endif /* HAVE_OPAQUE_LSA */
1858 return;
1859 }
1860
1861 /* If the received LSA is the same instance as the database copy
1862 (i.e., neither one is more recent) the following two steps
1863 should be performed: */
1864
1865 if (ret == 0)
1866 {
1867 /* If the LSA is listed in the Link state retransmission list
1868 for the receiving adjacency, the router itself is expecting
1869 an acknowledgment for this LSA. The router should treat the
1870 received LSA as an acknowledgment by removing the LSA from
1871 the Link state retransmission list. This is termed an
1872 "implied acknowledgment". */
1873
1874 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1875
1876 if (ls_ret != NULL)
1877 {
1878 ospf_ls_retransmit_delete (nbr, ls_ret);
1879
1880 /* Delayed acknowledgment sent if advertisement received
1881 from Designated Router, otherwise do nothing. */
1882 if (oi->state == ISM_Backup)
1883 if (NBR_IS_DR (nbr))
1884 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1885
1886 DISCARD_LSA (lsa, 5);
1887 }
1888 else
1889 /* Acknowledge the receipt of the LSA by sending a
1890 Link State Acknowledgment packet back out the receiving
1891 interface. */
1892 {
1893 ospf_ls_ack_send (nbr, lsa);
1894 DISCARD_LSA (lsa, 6);
1895 }
1896 }
1897
1898 /* The database copy is more recent. If the database copy
1899 has LS age equal to MaxAge and LS sequence number equal to
1900 MaxSequenceNumber, simply discard the received LSA without
1901 acknowledging it. (In this case, the LSA's LS sequence number is
1902 wrapping, and the MaxSequenceNumber LSA must be completely
1903 flushed before any new LSA instance can be introduced). */
1904
1905 else if (ret > 0) /* Database copy is more recent */
1906 {
1907 if (IS_LSA_MAXAGE (current) &&
1908 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1909 {
1910 DISCARD_LSA (lsa, 7);
1911 }
1912 /* Otherwise, as long as the database copy has not been sent in a
1913 Link State Update within the last MinLSArrival seconds, send the
1914 database copy back to the sending neighbor, encapsulated within
1915 a Link State Update Packet. The Link State Update Packet should
1916 be sent directly to the neighbor. In so doing, do not put the
1917 database copy of the LSA on the neighbor's link state
1918 retransmission list, and do not acknowledge the received (less
1919 recent) LSA instance. */
1920 else
1921 {
1922 struct timeval now;
1923
1924 gettimeofday (&now, NULL);
1925
1926 if (tv_cmp (tv_sub (now, current->tv_orig),
1927 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1928 /* Trap NSSA type later.*/
1929 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1930 DISCARD_LSA (lsa, 8);
1931 }
1932 }
1933 }
1934
1935#ifdef HAVE_OPAQUE_LSA
1936 /*
1937 * Now that previously originated Opaque-LSAs those which not yet
1938 * installed into LSDB are captured, take several steps to clear
1939 * them completely from the routing domain, before proceeding to
1940 * origination for the current target Opaque-LSAs.
1941 */
1942 while (listcount (mylsa_acks) > 0)
1943 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1944
1945 if (listcount (mylsa_upds) > 0)
1946 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1947
1948 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001949 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001950#endif /* HAVE_OPAQUE_LSA */
1951
1952 assert (listcount (lsas) == 0);
1953 list_delete (lsas);
1954}
1955
1956/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1957void
1958ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1959 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1960{
1961 struct ospf_neighbor *nbr;
1962#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001963 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001964#endif /* HAVE_OPAQUE_LSA */
1965
1966 /* increment statistics. */
1967 oi->ls_ack_in++;
1968
pauld3f0d622004-05-05 15:27:15 +00001969 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001970 if (nbr == NULL)
1971 {
1972 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1973 inet_ntoa (ospfh->router_id));
1974 return;
1975 }
1976
1977 if (nbr->state < NSM_Exchange)
1978 {
ajs3aa8d5f2004-12-11 18:00:06 +00001979 zlog_warn ("Link State Acknowledgment: "
1980 "Neighbor[%s] state %s is less than Exchange",
1981 inet_ntoa (ospfh->router_id),
1982 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001983 return;
1984 }
1985
1986#ifdef HAVE_OPAQUE_LSA
1987 opaque_acks = list_new ();
1988#endif /* HAVE_OPAQUE_LSA */
1989
1990 while (size >= OSPF_LSA_HEADER_SIZE)
1991 {
1992 struct ospf_lsa *lsa, *lsr;
1993
1994 lsa = ospf_lsa_new ();
1995 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1996
1997 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1998 size -= OSPF_LSA_HEADER_SIZE;
1999 stream_forward (s, OSPF_LSA_HEADER_SIZE);
2000
2001 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
2002 {
2003 lsa->data = NULL;
2004 ospf_lsa_discard (lsa);
2005 continue;
2006 }
2007
2008 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2009
2010 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2011 {
2012#ifdef HAVE_OPAQUE_LSA
2013 /* Keep this LSA entry for later reference. */
2014 if (IS_OPAQUE_LSA (lsr->data->type))
2015 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2016#endif /* HAVE_OPAQUE_LSA */
2017
2018 ospf_ls_retransmit_delete (nbr, lsr);
2019 }
2020
2021 lsa->data = NULL;
2022 ospf_lsa_discard (lsa);
2023 }
2024
2025#ifdef HAVE_OPAQUE_LSA
2026 if (listcount (opaque_acks) > 0)
2027 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2028
2029 list_delete (opaque_acks);
2030 return;
2031#endif /* HAVE_OPAQUE_LSA */
2032}
2033
2034struct stream *
2035ospf_recv_packet (int fd, struct interface **ifp)
2036{
2037 int ret;
2038 struct ip iph;
2039 u_int16_t ip_len;
2040 struct stream *ibuf;
2041 unsigned int ifindex = 0;
2042 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002043 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002044 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002045 struct msghdr msgh;
2046
paul68defd62004-09-27 07:27:13 +00002047 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002048 msgh.msg_iov = &iov;
2049 msgh.msg_iovlen = 1;
2050 msgh.msg_control = (caddr_t) buff;
2051 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002052
paul718e3742002-12-13 20:15:29 +00002053 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2054
2055 if (ret != sizeof (iph))
2056 {
2057 zlog_warn ("ospf_recv_packet packet smaller than ip header");
gdtbe210242004-12-29 20:12:59 +00002058 /* XXX: We peeked, and thus perhaps should discard this packet. */
paul718e3742002-12-13 20:15:29 +00002059 return NULL;
2060 }
paul18b12c32004-10-05 14:38:29 +00002061
2062 sockopt_iphdrincl_swab_systoh (&iph);
2063
paul6b333612004-10-11 10:11:25 +00002064 ip_len = iph.ip_len;
2065
paul239aecc2003-12-08 10:34:54 +00002066#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002067 /*
2068 * Kernel network code touches incoming IP header parameters,
2069 * before protocol specific processing.
2070 *
2071 * 1) Convert byteorder to host representation.
2072 * --> ip_len, ip_id, ip_off
2073 *
2074 * 2) Adjust ip_len to strip IP header size!
2075 * --> If user process receives entire IP packet via RAW
2076 * socket, it must consider adding IP header size to
2077 * the "ip_len" field of "ip" structure.
2078 *
2079 * For more details, see <netinet/ip_input.c>.
2080 */
2081 ip_len = ip_len + (iph.ip_hl << 2);
2082#endif
2083
2084 ibuf = stream_new (ip_len);
2085 iov.iov_base = STREAM_DATA (ibuf);
2086 iov.iov_len = ip_len;
2087 ret = recvmsg (fd, &msgh, 0);
2088
paul863082d2004-08-19 04:43:43 +00002089 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002090
2091 *ifp = if_lookup_by_index (ifindex);
2092
2093 if (ret != ip_len)
2094 {
2095 zlog_warn ("ospf_recv_packet short read. "
2096 "ip_len %d bytes read %d", ip_len, ret);
2097 stream_free (ibuf);
2098 return NULL;
2099 }
2100
2101 return ibuf;
2102}
2103
2104struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002105ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002106 struct ip *iph, struct ospf_header *ospfh)
2107{
2108 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002109 struct ospf_vl_data *vl_data;
2110 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002111 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002112
2113 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2114 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002115 return NULL;
paul718e3742002-12-13 20:15:29 +00002116
pauld3f0d622004-05-05 15:27:15 +00002117 /* look for local OSPF interface matching the destination
2118 * to determine Area ID. We presume therefore the destination address
2119 * is unique, or at least (for "unnumbered" links), not used in other
2120 * areas
2121 */
2122 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2123 iph->ip_dst)) == NULL)
2124 return NULL;
paul718e3742002-12-13 20:15:29 +00002125
paul020709f2003-04-04 02:44:16 +00002126 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002127 {
2128 if ((vl_data = getdata (node)) == NULL)
2129 continue;
2130
paul020709f2003-04-04 02:44:16 +00002131 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002132 if (!vl_area)
2133 continue;
2134
2135 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2136 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2137 {
2138 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002139 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002140 IF_NAME (vl_data->vl_oi));
2141 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2142 {
2143 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002144 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002145 return NULL;
2146 }
2147
2148 return vl_data->vl_oi;
2149 }
2150 }
2151
2152 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002153 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002154
pauld3f0d622004-05-05 15:27:15 +00002155 return NULL;
paul718e3742002-12-13 20:15:29 +00002156}
2157
2158int
2159ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2160{
2161 /* Check match the Area ID of the receiving interface. */
2162 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2163 return 1;
2164
2165 return 0;
2166}
2167
2168/* Unbound socket will accept any Raw IP packets if proto is matched.
2169 To prevent it, compare src IP address and i/f address with masking
2170 i/f network mask. */
2171int
2172ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2173{
2174 struct in_addr mask, me, him;
2175
2176 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2177 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2178 return 1;
2179
2180 masklen2ip (oi->address->prefixlen, &mask);
2181
2182 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2183 him.s_addr = ip_src.s_addr & mask.s_addr;
2184
2185 if (IPV4_ADDR_SAME (&me, &him))
2186 return 1;
2187
2188 return 0;
2189}
2190
2191int
2192ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2193 struct ospf_header *ospfh)
2194{
2195 int ret = 0;
2196 struct crypt_key *ck;
2197
2198 switch (ntohs (ospfh->auth_type))
2199 {
2200 case OSPF_AUTH_NULL:
2201 ret = 1;
2202 break;
2203 case OSPF_AUTH_SIMPLE:
2204 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2205 ret = 1;
2206 else
2207 ret = 0;
2208 break;
2209 case OSPF_AUTH_CRYPTOGRAPHIC:
2210 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2211 {
2212 ret = 0;
2213 break;
2214 }
2215
2216 /* This is very basic, the digest processing is elsewhere */
2217 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2218 ospfh->u.crypt.key_id == ck->key_id &&
2219 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2220 ret = 1;
2221 else
2222 ret = 0;
2223 break;
2224 default:
2225 ret = 0;
2226 break;
2227 }
2228
2229 return ret;
2230}
2231
2232int
2233ospf_check_sum (struct ospf_header *ospfh)
2234{
2235 u_int32_t ret;
2236 u_int16_t sum;
2237 int in_cksum (void *ptr, int nbytes);
2238
2239 /* clear auth_data for checksum. */
2240 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2241
2242 /* keep checksum and clear. */
2243 sum = ospfh->checksum;
2244 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2245
2246 /* calculate checksum. */
2247 ret = in_cksum (ospfh, ntohs (ospfh->length));
2248
2249 if (ret != sum)
2250 {
2251 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2252 ret, sum);
2253 return 0;
2254 }
2255
2256 return 1;
2257}
2258
2259/* OSPF Header verification. */
2260int
2261ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2262 struct ip *iph, struct ospf_header *ospfh)
2263{
2264 /* check version. */
2265 if (ospfh->version != OSPF_VERSION)
2266 {
2267 zlog_warn ("interface %s: ospf_read version number mismatch.",
2268 IF_NAME (oi));
2269 return -1;
2270 }
2271
2272 /* Check Area ID. */
2273 if (!ospf_check_area_id (oi, ospfh))
2274 {
2275 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2276 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2277 return -1;
2278 }
2279
2280 /* Check network mask, Silently discarded. */
2281 if (! ospf_check_network_mask (oi, iph->ip_src))
2282 {
2283 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2284 IF_NAME (oi), inet_ntoa (iph->ip_src));
2285 return -1;
2286 }
2287
2288 /* Check authentication. */
2289 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2290 {
2291 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2292 IF_NAME (oi));
2293 return -1;
2294 }
2295
2296 if (! ospf_check_auth (oi, ibuf, ospfh))
2297 {
2298 zlog_warn ("interface %s: ospf_read authentication failed.",
2299 IF_NAME (oi));
2300 return -1;
2301 }
2302
2303 /* if check sum is invalid, packet is discarded. */
2304 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2305 {
2306 if (! ospf_check_sum (ospfh))
2307 {
2308 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2309 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2310 return -1;
2311 }
2312 }
2313 else
2314 {
2315 if (ospfh->checksum != 0)
2316 return -1;
2317 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2318 {
2319 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2320 IF_NAME (oi));
2321 return -1;
2322 }
2323 }
2324
2325 return 0;
2326}
2327
2328/* Starting point of packet process function. */
2329int
2330ospf_read (struct thread *thread)
2331{
2332 int ret;
2333 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002334 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002335 struct ospf_interface *oi;
2336 struct ip *iph;
2337 struct ospf_header *ospfh;
2338 u_int16_t length;
2339 struct interface *ifp;
2340
2341 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002342 ospf = THREAD_ARG (thread);
2343 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002344
2345 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002346 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002347 if (ibuf == NULL)
2348 return -1;
2349
paul06f953f2004-10-22 17:00:38 +00002350 iph = (struct ip *) STREAM_DATA (ibuf);
2351 sockopt_iphdrincl_swab_systoh (iph);
2352
paulac191232004-10-22 12:05:17 +00002353 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002354 /* Handle cases where the platform does not support retrieving the ifindex,
2355 and also platforms (such as Solaris 8) that claim to support ifindex
2356 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002357 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002358
pauld3f0d622004-05-05 15:27:15 +00002359 if (ifp == NULL)
2360 {
2361 stream_free (ibuf);
2362 return 0;
2363 }
paul6b333612004-10-11 10:11:25 +00002364
paul718e3742002-12-13 20:15:29 +00002365 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002366 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002367
2368 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002369 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002370 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002371
paul718e3742002-12-13 20:15:29 +00002372 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002373 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002374 {
pauld3241812003-09-29 12:42:39 +00002375 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2376 {
ajs2a42e282004-12-08 18:43:03 +00002377 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002378 inet_ntoa (iph->ip_src));
2379 }
paul718e3742002-12-13 20:15:29 +00002380 stream_free (ibuf);
2381 return 0;
2382 }
2383
2384 /* Adjust size to message length. */
2385 stream_forward (ibuf, iph->ip_hl * 4);
2386
2387 /* Get ospf packet header. */
2388 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2389
2390 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002391 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002392
2393 /* if no local ospf_interface,
2394 * or header area is backbone but ospf_interface is not
2395 * check for VLINK interface
2396 */
2397 if ( (oi == NULL) ||
2398 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2399 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2400 )
2401 {
2402 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2403 {
2404 zlog_warn ("Packet from [%s] received on link %s"
2405 " but no ospf_interface",
2406 inet_ntoa (iph->ip_src), ifp->name);
2407 stream_free (ibuf);
2408 return 0;
2409 }
2410 }
2411
2412 /* else it must be a local ospf interface, check it was received on
2413 * correct link
2414 */
2415 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002416 {
2417 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002418 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002419 stream_free (ibuf);
2420 return 0;
2421 }
paul718e3742002-12-13 20:15:29 +00002422
2423 /*
2424 * If the received packet is destined for AllDRouters, the packet
2425 * should be accepted only if the received ospf interface state is
2426 * either DR or Backup -- endo.
2427 */
2428 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2429 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2430 {
2431 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2432 inet_ntoa (iph->ip_src), IF_NAME (oi),
2433 LOOKUP (ospf_ism_state_msg, oi->state));
2434 stream_free (ibuf);
2435 return 0;
2436 }
2437
2438 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002439 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2440 {
paul718e3742002-12-13 20:15:29 +00002441 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002442 {
ajs2a42e282004-12-08 18:43:03 +00002443 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002444 ospf_packet_dump (ibuf);
2445 }
paul718e3742002-12-13 20:15:29 +00002446
ajs2a42e282004-12-08 18:43:03 +00002447 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002448 ospf_packet_type_str[ospfh->type],
2449 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002450 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2451 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002452
2453 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002454 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002455 }
paul718e3742002-12-13 20:15:29 +00002456
2457 /* Some header verification. */
2458 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2459 if (ret < 0)
2460 {
pauld3241812003-09-29 12:42:39 +00002461 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2462 {
ajs2a42e282004-12-08 18:43:03 +00002463 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002464 "dropping.",
2465 ospf_packet_type_str[ospfh->type],
2466 inet_ntoa (iph->ip_src));
2467 }
paul718e3742002-12-13 20:15:29 +00002468 stream_free (ibuf);
2469 return ret;
2470 }
2471
2472 stream_forward (ibuf, OSPF_HEADER_SIZE);
2473
2474 /* Adjust size to message length. */
2475 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2476
2477 /* Read rest of the packet and call each sort of packet routine. */
2478 switch (ospfh->type)
2479 {
2480 case OSPF_MSG_HELLO:
2481 ospf_hello (iph, ospfh, ibuf, oi, length);
2482 break;
2483 case OSPF_MSG_DB_DESC:
2484 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2485 break;
2486 case OSPF_MSG_LS_REQ:
2487 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2488 break;
2489 case OSPF_MSG_LS_UPD:
2490 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2491 break;
2492 case OSPF_MSG_LS_ACK:
2493 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2494 break;
2495 default:
2496 zlog (NULL, LOG_WARNING,
2497 "interface %s: OSPF packet header type %d is illegal",
2498 IF_NAME (oi), ospfh->type);
2499 break;
2500 }
2501
2502 stream_free (ibuf);
2503 return 0;
2504}
2505
2506/* Make OSPF header. */
2507void
2508ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2509{
2510 struct ospf_header *ospfh;
2511
2512 ospfh = (struct ospf_header *) STREAM_DATA (s);
2513
2514 ospfh->version = (u_char) OSPF_VERSION;
2515 ospfh->type = (u_char) type;
2516
paul68980082003-03-25 05:07:42 +00002517 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002518
2519 ospfh->checksum = 0;
2520 ospfh->area_id = oi->area->area_id;
2521 ospfh->auth_type = htons (ospf_auth_type (oi));
2522
2523 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2524
2525 ospf_output_forward (s, OSPF_HEADER_SIZE);
2526}
2527
2528/* Make Authentication Data. */
2529int
2530ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2531{
2532 struct crypt_key *ck;
2533
2534 switch (ospf_auth_type (oi))
2535 {
2536 case OSPF_AUTH_NULL:
2537 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2538 break;
2539 case OSPF_AUTH_SIMPLE:
2540 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2541 OSPF_AUTH_SIMPLE_SIZE);
2542 break;
2543 case OSPF_AUTH_CRYPTOGRAPHIC:
2544 /* If key is not set, then set 0. */
2545 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2546 {
2547 ospfh->u.crypt.zero = 0;
2548 ospfh->u.crypt.key_id = 0;
2549 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2550 }
2551 else
2552 {
2553 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2554 ospfh->u.crypt.zero = 0;
2555 ospfh->u.crypt.key_id = ck->key_id;
2556 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2557 }
2558 /* note: the seq is done in ospf_make_md5_digest() */
2559 break;
2560 default:
2561 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2562 break;
2563 }
2564
2565 return 0;
2566}
2567
2568/* Fill rest of OSPF header. */
2569void
2570ospf_fill_header (struct ospf_interface *oi,
2571 struct stream *s, u_int16_t length)
2572{
2573 struct ospf_header *ospfh;
2574
2575 ospfh = (struct ospf_header *) STREAM_DATA (s);
2576
2577 /* Fill length. */
2578 ospfh->length = htons (length);
2579
2580 /* Calculate checksum. */
2581 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2582 ospfh->checksum = in_cksum (ospfh, length);
2583 else
2584 ospfh->checksum = 0;
2585
2586 /* Add Authentication Data. */
2587 ospf_make_auth (oi, ospfh);
2588}
2589
2590int
2591ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2592{
2593 struct ospf_neighbor *nbr;
2594 struct route_node *rn;
2595 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2596 struct in_addr mask;
2597 unsigned long p;
2598 int flag = 0;
2599
2600 /* Set netmask of interface. */
2601 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2602 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2603 masklen2ip (oi->address->prefixlen, &mask);
2604 else
2605 memset ((char *) &mask, 0, sizeof (struct in_addr));
2606 stream_put_ipv4 (s, mask.s_addr);
2607
2608 /* Set Hello Interval. */
2609 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2610
2611 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002612 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002613 OPTIONS(oi), IF_NAME (oi));
2614
2615 /* Set Options. */
2616 stream_putc (s, OPTIONS (oi));
2617
2618 /* Set Router Priority. */
2619 stream_putc (s, PRIORITY (oi));
2620
2621 /* Set Router Dead Interval. */
2622 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2623
2624 /* Set Designated Router. */
2625 stream_put_ipv4 (s, DR (oi).s_addr);
2626
2627 p = s->putp;
2628
2629 /* Set Backup Designated Router. */
2630 stream_put_ipv4 (s, BDR (oi).s_addr);
2631
2632 /* Add neighbor seen. */
2633 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002634 if ((nbr = rn->info))
2635 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2636 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2637 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2638 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002639 {
2640 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002641 if (nbr->d_router.s_addr != 0
2642 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2643 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2644 flag = 1;
paul718e3742002-12-13 20:15:29 +00002645
2646 stream_put_ipv4 (s, nbr->router_id.s_addr);
2647 length += 4;
2648 }
2649
2650 /* Let neighbor generate BackupSeen. */
2651 if (flag == 1)
2652 {
2653 stream_set_putp (s, p);
2654 stream_put_ipv4 (s, 0);
2655 }
2656
2657 return length;
2658}
2659
2660int
2661ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2662 struct stream *s)
2663{
2664 struct ospf_lsa *lsa;
2665 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2666 u_char options;
2667 unsigned long pp;
2668 int i;
2669 struct ospf_lsdb *lsdb;
2670
2671 /* Set Interface MTU. */
2672 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2673 stream_putw (s, 0);
2674 else
2675 stream_putw (s, oi->ifp->mtu);
2676
2677 /* Set Options. */
2678 options = OPTIONS (oi);
2679#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002680 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002681 {
2682 if (IS_SET_DD_I (nbr->dd_flags)
2683 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2684 /*
2685 * Set O-bit in the outgoing DD packet for capablity negotiation,
2686 * if one of following case is applicable.
2687 *
2688 * 1) WaitTimer expiration event triggered the neighbor state to
2689 * change to Exstart, but no (valid) DD packet has received
2690 * from the neighbor yet.
2691 *
2692 * 2) At least one DD packet with O-bit on has received from the
2693 * neighbor.
2694 */
2695 SET_FLAG (options, OSPF_OPTION_O);
2696 }
2697#endif /* HAVE_OPAQUE_LSA */
2698 stream_putc (s, options);
2699
2700 /* Keep pointer to flags. */
2701 pp = stream_get_putp (s);
2702 stream_putc (s, nbr->dd_flags);
2703
2704 /* Set DD Sequence Number. */
2705 stream_putl (s, nbr->dd_seqnum);
2706
2707 if (ospf_db_summary_isempty (nbr))
2708 {
2709 if (nbr->state >= NSM_Exchange)
2710 {
2711 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2712 /* Set DD flags again */
2713 stream_set_putp (s, pp);
2714 stream_putc (s, nbr->dd_flags);
2715 }
2716 return length;
2717 }
2718
2719 /* Describe LSA Header from Database Summary List. */
2720 lsdb = &nbr->db_sum;
2721
2722 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2723 {
2724 struct route_table *table = lsdb->type[i].db;
2725 struct route_node *rn;
2726
2727 for (rn = route_top (table); rn; rn = route_next (rn))
2728 if ((lsa = rn->info) != NULL)
2729 {
2730#ifdef HAVE_OPAQUE_LSA
2731 if (IS_OPAQUE_LSA (lsa->data->type)
2732 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2733 {
2734 /* Suppress advertising opaque-informations. */
2735 /* Remove LSA from DB summary list. */
2736 ospf_lsdb_delete (lsdb, lsa);
2737 continue;
2738 }
2739#endif /* HAVE_OPAQUE_LSA */
2740
2741 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2742 {
2743 struct lsa_header *lsah;
2744 u_int16_t ls_age;
2745
2746 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002747 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002748 break;
2749
2750 /* Keep pointer to LS age. */
2751 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2752 stream_get_putp (s));
2753
2754 /* Proceed stream pointer. */
2755 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2756 length += OSPF_LSA_HEADER_SIZE;
2757
2758 /* Set LS age. */
2759 ls_age = LS_AGE (lsa);
2760 lsah->ls_age = htons (ls_age);
2761
2762 }
2763
2764 /* Remove LSA from DB summary list. */
2765 ospf_lsdb_delete (lsdb, lsa);
2766 }
2767 }
2768
2769 return length;
2770}
2771
2772int
2773ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2774 unsigned long delta, struct ospf_neighbor *nbr,
2775 struct ospf_lsa *lsa)
2776{
2777 struct ospf_interface *oi;
2778
2779 oi = nbr->oi;
2780
2781 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002782 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002783 return 0;
2784
2785 stream_putl (s, lsa->data->type);
2786 stream_put_ipv4 (s, lsa->data->id.s_addr);
2787 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2788
2789 ospf_lsa_unlock (nbr->ls_req_last);
2790 nbr->ls_req_last = ospf_lsa_lock (lsa);
2791
2792 *length += 12;
2793 return 1;
2794}
2795
2796int
2797ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2798{
2799 struct ospf_lsa *lsa;
2800 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2801 unsigned long delta = stream_get_putp(s)+12;
2802 struct route_table *table;
2803 struct route_node *rn;
2804 int i;
2805 struct ospf_lsdb *lsdb;
2806
2807 lsdb = &nbr->ls_req;
2808
2809 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2810 {
2811 table = lsdb->type[i].db;
2812 for (rn = route_top (table); rn; rn = route_next (rn))
2813 if ((lsa = (rn->info)) != NULL)
2814 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2815 {
2816 route_unlock_node (rn);
2817 break;
2818 }
2819 }
2820 return length;
2821}
2822
2823int
2824ls_age_increment (struct ospf_lsa *lsa, int delay)
2825{
2826 int age;
2827
2828 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2829
2830 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2831}
2832
2833int
hasso52dc7ee2004-09-23 19:18:23 +00002834ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002835{
2836 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002837 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002838 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002839 unsigned int size_noauth;
paul718e3742002-12-13 20:15:29 +00002840 unsigned long delta = stream_get_putp (s);
2841 unsigned long pp;
2842 int count = 0;
2843
2844 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002845 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002846
paul718e3742002-12-13 20:15:29 +00002847 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002848 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002849
gdt86f1fd92005-01-10 14:20:43 +00002850 /* Calculate amount of packet usable for data. */
2851 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2852
paul718e3742002-12-13 20:15:29 +00002853 while ((node = listhead (update)) != NULL)
2854 {
2855 struct lsa_header *lsah;
2856 u_int16_t ls_age;
2857
2858 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002859 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002860
2861 lsa = getdata (node);
2862 assert (lsa);
2863 assert (lsa->data);
2864
paul68b73392004-09-12 14:21:37 +00002865 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002866 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002867 break;
2868
paul718e3742002-12-13 20:15:29 +00002869 /* Keep pointer to LS age. */
2870 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2871
2872 /* Put LSA to Link State Request. */
2873 stream_put (s, lsa->data, ntohs (lsa->data->length));
2874
2875 /* Set LS age. */
2876 /* each hop must increment an lsa_age by transmit_delay
2877 of OSPF interface */
2878 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2879 lsah->ls_age = htons (ls_age);
2880
2881 length += ntohs (lsa->data->length);
2882 count++;
2883
2884 list_delete_node (update, node);
2885 ospf_lsa_unlock (lsa);
2886 }
2887
2888 /* Now set #LSAs. */
2889 stream_set_putp (s, pp);
2890 stream_putl (s, count);
2891
2892 stream_set_putp (s, s->endp);
2893
2894 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002895 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002896 return length;
2897}
2898
2899int
hasso52dc7ee2004-09-23 19:18:23 +00002900ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002901{
hasso52dc7ee2004-09-23 19:18:23 +00002902 struct list *rm_list;
2903 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002904 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2905 unsigned long delta = stream_get_putp(s) + 24;
2906 struct ospf_lsa *lsa;
2907
2908 rm_list = list_new ();
2909
2910 for (node = listhead (ack); node; nextnode (node))
2911 {
2912 lsa = getdata (node);
2913 assert (lsa);
2914
gdt86f1fd92005-01-10 14:20:43 +00002915 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002916 break;
2917
2918 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2919 length += OSPF_LSA_HEADER_SIZE;
2920
2921 listnode_add (rm_list, lsa);
2922 }
2923
2924 /* Remove LSA from LS-Ack list. */
2925 for (node = listhead (rm_list); node; nextnode (node))
2926 {
2927 lsa = (struct ospf_lsa *) getdata (node);
2928
2929 listnode_delete (ack, lsa);
2930 ospf_lsa_unlock (lsa);
2931 }
2932
2933 list_delete (rm_list);
2934
2935 return length;
2936}
2937
2938void
2939ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2940{
2941 struct ospf_packet *op;
2942 u_int16_t length = OSPF_HEADER_SIZE;
2943
2944 op = ospf_packet_new (oi->ifp->mtu);
2945
2946 /* Prepare OSPF common header. */
2947 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2948
2949 /* Prepare OSPF Hello body. */
2950 length += ospf_make_hello (oi, op->s);
2951
2952 /* Fill OSPF header. */
2953 ospf_fill_header (oi, op->s, length);
2954
2955 /* Set packet length. */
2956 op->length = length;
2957
2958 op->dst.s_addr = addr->s_addr;
2959
2960 /* Add packet to the interface output queue. */
2961 ospf_packet_add (oi, op);
2962
2963 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002964 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002965}
2966
2967void
2968ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2969{
2970 struct ospf_interface *oi;
2971
2972 oi = nbr_nbma->oi;
2973 assert(oi);
2974
2975 /* If this is passive interface, do not send OSPF Hello. */
2976 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2977 return;
2978
2979 if (oi->type != OSPF_IFTYPE_NBMA)
2980 return;
2981
2982 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2983 return;
2984
2985 if (PRIORITY(oi) == 0)
2986 return;
2987
2988 if (nbr_nbma->priority == 0
2989 && oi->state != ISM_DR && oi->state != ISM_Backup)
2990 return;
2991
2992 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2993}
2994
2995int
2996ospf_poll_timer (struct thread *thread)
2997{
2998 struct ospf_nbr_nbma *nbr_nbma;
2999
3000 nbr_nbma = THREAD_ARG (thread);
3001 nbr_nbma->t_poll = NULL;
3002
3003 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003004 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00003005 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
3006
3007 ospf_poll_send (nbr_nbma);
3008
3009 if (nbr_nbma->v_poll > 0)
3010 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
3011 nbr_nbma->v_poll);
3012
3013 return 0;
3014}
3015
3016
3017int
3018ospf_hello_reply_timer (struct thread *thread)
3019{
3020 struct ospf_neighbor *nbr;
3021
3022 nbr = THREAD_ARG (thread);
3023 nbr->t_hello_reply = NULL;
3024
3025 assert (nbr->oi);
3026
3027 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003028 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003029 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3030
3031 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3032
3033 return 0;
3034}
3035
3036/* Send OSPF Hello. */
3037void
3038ospf_hello_send (struct ospf_interface *oi)
3039{
3040 struct ospf_packet *op;
3041 u_int16_t length = OSPF_HEADER_SIZE;
3042
3043 /* If this is passive interface, do not send OSPF Hello. */
3044 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3045 return;
3046
3047 op = ospf_packet_new (oi->ifp->mtu);
3048
3049 /* Prepare OSPF common header. */
3050 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3051
3052 /* Prepare OSPF Hello body. */
3053 length += ospf_make_hello (oi, op->s);
3054
3055 /* Fill OSPF header. */
3056 ospf_fill_header (oi, op->s, length);
3057
3058 /* Set packet length. */
3059 op->length = length;
3060
3061 if (oi->type == OSPF_IFTYPE_NBMA)
3062 {
3063 struct ospf_neighbor *nbr;
3064 struct route_node *rn;
3065
3066 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3067 if ((nbr = rn->info))
3068 if (nbr != oi->nbr_self)
3069 if (nbr->state != NSM_Down)
3070 {
3071 /* RFC 2328 Section 9.5.1
3072 If the router is not eligible to become Designated Router,
3073 it must periodically send Hello Packets to both the
3074 Designated Router and the Backup Designated Router (if they
3075 exist). */
3076 if (PRIORITY(oi) == 0 &&
3077 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3078 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3079 continue;
3080
3081 /* If the router is eligible to become Designated Router, it
3082 must periodically send Hello Packets to all neighbors that
3083 are also eligible. In addition, if the router is itself the
3084 Designated Router or Backup Designated Router, it must also
3085 send periodic Hello Packets to all other neighbors. */
3086
3087 if (nbr->priority == 0 && oi->state == ISM_DROther)
3088 continue;
3089 /* if oi->state == Waiting, send hello to all neighbors */
3090 {
3091 struct ospf_packet *op_dup;
3092
3093 op_dup = ospf_packet_dup(op);
3094 op_dup->dst = nbr->address.u.prefix4;
3095
3096 /* Add packet to the interface output queue. */
3097 ospf_packet_add (oi, op_dup);
3098
paul020709f2003-04-04 02:44:16 +00003099 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003100 }
3101
3102 }
3103 ospf_packet_free (op);
3104 }
3105 else
3106 {
3107 /* Decide destination address. */
3108 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3109 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3110 else
3111 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3112
3113 /* Add packet to the interface output queue. */
3114 ospf_packet_add (oi, op);
3115
3116 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003117 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003118 }
3119}
3120
3121/* Send OSPF Database Description. */
3122void
3123ospf_db_desc_send (struct ospf_neighbor *nbr)
3124{
3125 struct ospf_interface *oi;
3126 struct ospf_packet *op;
3127 u_int16_t length = OSPF_HEADER_SIZE;
3128
3129 oi = nbr->oi;
3130 op = ospf_packet_new (oi->ifp->mtu);
3131
3132 /* Prepare OSPF common header. */
3133 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3134
3135 /* Prepare OSPF Database Description body. */
3136 length += ospf_make_db_desc (oi, nbr, op->s);
3137
3138 /* Fill OSPF header. */
3139 ospf_fill_header (oi, op->s, length);
3140
3141 /* Set packet length. */
3142 op->length = length;
3143
3144 /* Decide destination address. */
3145 op->dst = nbr->address.u.prefix4;
3146
3147 /* Add packet to the interface output queue. */
3148 ospf_packet_add (oi, op);
3149
3150 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003151 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003152
3153 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3154 if (nbr->last_send)
3155 ospf_packet_free (nbr->last_send);
3156 nbr->last_send = ospf_packet_dup (op);
3157 gettimeofday (&nbr->last_send_ts, NULL);
3158}
3159
3160/* Re-send Database Description. */
3161void
3162ospf_db_desc_resend (struct ospf_neighbor *nbr)
3163{
3164 struct ospf_interface *oi;
3165
3166 oi = nbr->oi;
3167
3168 /* Add packet to the interface output queue. */
3169 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3170
3171 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003172 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003173}
3174
3175/* Send Link State Request. */
3176void
3177ospf_ls_req_send (struct ospf_neighbor *nbr)
3178{
3179 struct ospf_interface *oi;
3180 struct ospf_packet *op;
3181 u_int16_t length = OSPF_HEADER_SIZE;
3182
3183 oi = nbr->oi;
3184 op = ospf_packet_new (oi->ifp->mtu);
3185
3186 /* Prepare OSPF common header. */
3187 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3188
3189 /* Prepare OSPF Link State Request body. */
3190 length += ospf_make_ls_req (nbr, op->s);
3191 if (length == OSPF_HEADER_SIZE)
3192 {
3193 ospf_packet_free (op);
3194 return;
3195 }
3196
3197 /* Fill OSPF header. */
3198 ospf_fill_header (oi, op->s, length);
3199
3200 /* Set packet length. */
3201 op->length = length;
3202
3203 /* Decide destination address. */
3204 op->dst = nbr->address.u.prefix4;
3205
3206 /* Add packet to the interface output queue. */
3207 ospf_packet_add (oi, op);
3208
3209 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003210 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003211
3212 /* Add Link State Request Retransmission Timer. */
3213 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3214}
3215
3216/* Send Link State Update with an LSA. */
3217void
3218ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3219 int flag)
3220{
hasso52dc7ee2004-09-23 19:18:23 +00003221 struct list *update;
paul718e3742002-12-13 20:15:29 +00003222
3223 update = list_new ();
3224
3225 listnode_add (update, lsa);
3226 ospf_ls_upd_send (nbr, update, flag);
3227
3228 list_delete (update);
3229}
3230
paul68b73392004-09-12 14:21:37 +00003231/* Determine size for packet. Must be at least big enough to accomodate next
3232 * LSA on list, which may be bigger than MTU size.
3233 *
3234 * Return pointer to new ospf_packet
3235 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3236 * on packet sizes (in which case offending LSA is deleted from update list)
3237 */
3238static struct ospf_packet *
3239ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3240{
3241 struct ospf_lsa *lsa;
3242 struct listnode *ln;
3243 size_t size;
3244 static char warned = 0;
3245
3246 ln = listhead (update);
3247 lsa = getdata (ln);
3248 assert (lsa);
3249 assert (lsa->data);
3250
3251 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3252 > ospf_packet_max (oi))
3253 {
3254 if (!warned)
3255 {
3256 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3257 "will need to fragment. Not optimal. Try divide up"
3258 " your network with areas. Use 'debug ospf packet send'"
3259 " to see details, or look at 'show ip ospf database ..'");
3260 warned = 1;
3261 }
3262
3263 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003264 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003265 " %d bytes originated by %s, will be fragmented!",
3266 inet_ntoa (lsa->data->id),
3267 ntohs (lsa->data->length),
3268 inet_ntoa (lsa->data->adv_router));
3269
3270 /*
3271 * Allocate just enough to fit this LSA only, to avoid including other
3272 * LSAs in fragmented LSA Updates.
3273 */
3274 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3275 + OSPF_LS_UPD_MIN_SIZE;
3276 }
3277 else
3278 size = oi->ifp->mtu;
3279
gdt86f1fd92005-01-10 14:20:43 +00003280 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003281 if (size > OSPF_MAX_PACKET_SIZE)
3282 {
3283 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003284 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003285 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003286 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003287 (long int) size);
paul68b73392004-09-12 14:21:37 +00003288 list_delete_node (update, ln);
3289 return NULL;
3290 }
3291
3292 return ospf_packet_new (size);
3293}
3294
paul718e3742002-12-13 20:15:29 +00003295static void
hasso52dc7ee2004-09-23 19:18:23 +00003296ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003297 struct in_addr addr)
3298{
3299 struct ospf_packet *op;
3300 u_int16_t length = OSPF_HEADER_SIZE;
3301
3302 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003303 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003304
3305 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003306
3307 /* Prepare OSPF common header. */
3308 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3309
paul59ea14c2004-07-14 20:50:36 +00003310 /* Prepare OSPF Link State Update body.
3311 * Includes Type-7 translation.
3312 */
paul718e3742002-12-13 20:15:29 +00003313 length += ospf_make_ls_upd (oi, update, op->s);
3314
3315 /* Fill OSPF header. */
3316 ospf_fill_header (oi, op->s, length);
3317
3318 /* Set packet length. */
3319 op->length = length;
3320
3321 /* Decide destination address. */
3322 op->dst.s_addr = addr.s_addr;
3323
3324 /* Add packet to the interface output queue. */
3325 ospf_packet_add (oi, op);
3326
3327 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003328 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003329}
3330
3331static int
3332ospf_ls_upd_send_queue_event (struct thread *thread)
3333{
3334 struct ospf_interface *oi = THREAD_ARG(thread);
3335 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003336 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003337 struct list *update;
paul68b73392004-09-12 14:21:37 +00003338 char again = 0;
paul718e3742002-12-13 20:15:29 +00003339
3340 oi->t_ls_upd_event = NULL;
3341
3342 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003343 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003344
paul736d3442003-07-24 23:22:57 +00003345 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003346 {
paul736d3442003-07-24 23:22:57 +00003347 rnext = route_next (rn);
3348
paul718e3742002-12-13 20:15:29 +00003349 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003350 continue;
paul68b73392004-09-12 14:21:37 +00003351
3352 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003353
paul48fe13b2004-07-27 17:40:44 +00003354 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003355
paul68b73392004-09-12 14:21:37 +00003356 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003357 if (listcount(update) == 0)
3358 {
3359 list_delete (rn->info);
3360 rn->info = NULL;
3361 route_unlock_node (rn);
3362 }
3363 else
paul68b73392004-09-12 14:21:37 +00003364 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003365 }
3366
3367 if (again != 0)
3368 {
3369 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003370 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003371 " %d nodes to try again, raising new event", again);
3372 oi->t_ls_upd_event =
3373 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003374 }
3375
3376 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003377 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003378
paul718e3742002-12-13 20:15:29 +00003379 return 0;
3380}
3381
3382void
hasso52dc7ee2004-09-23 19:18:23 +00003383ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003384{
3385 struct ospf_interface *oi;
3386 struct prefix_ipv4 p;
3387 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003388 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003389
3390 oi = nbr->oi;
3391
3392 p.family = AF_INET;
3393 p.prefixlen = IPV4_MAX_BITLEN;
3394
3395 /* Decide destination address. */
3396 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3397 p.prefix = oi->vl_data->peer_addr;
3398 else if (flag == OSPF_SEND_PACKET_DIRECT)
3399 p.prefix = nbr->address.u.prefix4;
3400 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3401 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3402 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3403 && (flag == OSPF_SEND_PACKET_INDIRECT))
3404 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003405 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3406 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003407 else
3408 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3409
3410 if (oi->type == OSPF_IFTYPE_NBMA)
3411 {
3412 if (flag == OSPF_SEND_PACKET_INDIRECT)
3413 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3414 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3415 zlog_warn ("* LS-Update is sent to myself.");
3416 }
3417
3418 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3419
3420 if (rn->info == NULL)
3421 rn->info = list_new ();
3422
3423 for (n = listhead (update); n; nextnode (n))
3424 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3425
3426 if (oi->t_ls_upd_event == NULL)
3427 oi->t_ls_upd_event =
3428 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3429}
3430
3431static void
hasso52dc7ee2004-09-23 19:18:23 +00003432ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3433 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003434{
3435 struct ospf_packet *op;
3436 u_int16_t length = OSPF_HEADER_SIZE;
3437
3438 op = ospf_packet_new (oi->ifp->mtu);
3439
3440 /* Prepare OSPF common header. */
3441 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3442
3443 /* Prepare OSPF Link State Acknowledgment body. */
3444 length += ospf_make_ls_ack (oi, ack, op->s);
3445
3446 /* Fill OSPF header. */
3447 ospf_fill_header (oi, op->s, length);
3448
3449 /* Set packet length. */
3450 op->length = length;
3451
3452 /* Set destination IP address. */
3453 op->dst = dst;
3454
3455 /* Add packet to the interface output queue. */
3456 ospf_packet_add (oi, op);
3457
3458 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003459 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003460}
3461
3462static int
3463ospf_ls_ack_send_event (struct thread *thread)
3464{
3465 struct ospf_interface *oi = THREAD_ARG (thread);
3466
3467 oi->t_ls_ack_direct = NULL;
3468
3469 while (listcount (oi->ls_ack_direct.ls_ack))
3470 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3471 oi->ls_ack_direct.dst);
3472
3473 return 0;
3474}
3475
3476void
3477ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3478{
3479 struct ospf_interface *oi = nbr->oi;
3480
3481 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3482 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3483
3484 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3485
3486 if (oi->t_ls_ack_direct == NULL)
3487 oi->t_ls_ack_direct =
3488 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3489}
3490
3491/* Send Link State Acknowledgment delayed. */
3492void
3493ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3494{
3495 struct in_addr dst;
3496
3497 /* Decide destination address. */
3498 /* RFC2328 Section 13.5 On non-broadcast
3499 networks, delayed Link State Acknowledgment packets must be
3500 unicast separately over each adjacency (i.e., neighbor whose
3501 state is >= Exchange). */
3502 if (oi->type == OSPF_IFTYPE_NBMA)
3503 {
3504 struct ospf_neighbor *nbr;
3505 struct route_node *rn;
3506
3507 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3508 if ((nbr = rn->info) != NULL)
3509 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3510 while (listcount (oi->ls_ack))
3511 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3512 return;
3513 }
3514 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3515 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3516 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3517 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3518 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3519 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003520 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3521 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003522 else
3523 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3524
3525 while (listcount (oi->ls_ack))
3526 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3527}