blob: b4695f43d0e04c644984b3c33b8c21cf7e142465 [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
paul6c835672004-10-11 11:00:30 +0000244unsigned int
paul718e3742002-12-13 20:15:29 +0000245ospf_packet_max (struct ospf_interface *oi)
246{
247 int max;
248
249 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
paul68b73392004-09-12 14:21:37 +0000250 max = oi->ifp->mtu - OSPF_AUTH_MD5_SIZE;
paul718e3742002-12-13 20:15:29 +0000251 else
paul68b73392004-09-12 14:21:37 +0000252 max = oi->ifp->mtu;
253
254 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000255
256 return max;
257}
258
259
260int
261ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
262 u_int16_t length)
263{
paul6c835672004-10-11 11:00:30 +0000264 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000265 struct md5_ctx ctx;
266 unsigned char digest[OSPF_AUTH_MD5_SIZE];
267 unsigned char *pdigest;
268 struct crypt_key *ck;
269 struct ospf_header *ospfh;
270 struct ospf_neighbor *nbr;
271
272
273 ibuf = STREAM_PNT (s);
274 ospfh = (struct ospf_header *) ibuf;
275
276 /* Get pointer to the end of the packet. */
277 pdigest = ibuf + length;
278
279 /* Get secret key. */
280 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
281 ospfh->u.crypt.key_id);
282 if (ck == NULL)
283 {
284 zlog_warn ("interface %s: ospf_check_md5 no key %d",
285 IF_NAME (oi), ospfh->u.crypt.key_id);
286 return 0;
287 }
288
289 /* check crypto seqnum. */
290 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
291
292 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
293 {
294 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
295 IF_NAME (oi),
296 ntohl(ospfh->u.crypt.crypt_seqnum),
297 ntohl(nbr->crypt_seqnum));
298 return 0;
299 }
300
301 /* Generate a digest for the ospf packet - their digest + our digest. */
302 md5_init_ctx (&ctx);
303 md5_process_bytes (ibuf, length, &ctx);
304 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
305 md5_finish_ctx (&ctx, digest);
306
307 /* compare the two */
308 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
309 {
310 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
311 IF_NAME (oi));
312 return 0;
313 }
314
315 /* save neighbor's crypt_seqnum */
316 if (nbr)
317 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
318 return 1;
319}
320
321/* This function is called from ospf_write(), it will detect the
322 authentication scheme and if it is MD5, it will change the sequence
323 and update the MD5 digest. */
324int
325ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
326{
327 struct ospf_header *ospfh;
328 unsigned char digest[OSPF_AUTH_MD5_SIZE];
329 struct md5_ctx ctx;
330 void *ibuf;
331 unsigned long oldputp;
paul9483e152002-12-13 20:55:25 +0000332 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000333 struct crypt_key *ck;
334 char *auth_key;
335
336 ibuf = STREAM_DATA (op->s);
337 ospfh = (struct ospf_header *) ibuf;
338
339 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
340 return 0;
341
342 /* We do this here so when we dup a packet, we don't have to
343 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000344 t = (time(NULL) & 0xFFFFFFFF);
345 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
346 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000347
348 /* Get MD5 Authentication key from auth_key list. */
349 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
hassoeb1ce602004-10-08 08:17:22 +0000350 auth_key = (char *) "";
paul718e3742002-12-13 20:15:29 +0000351 else
352 {
353 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
hassoc9e52be2004-09-26 16:09:34 +0000354 auth_key = (char *) ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000355 }
356
357 /* Generate a digest for the entire packet + our secret key. */
358 md5_init_ctx (&ctx);
359 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
360 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
361 md5_finish_ctx (&ctx, digest);
362
363 /* Append md5 digest to the end of the stream. */
364 oldputp = stream_get_putp (op->s);
365 stream_set_putp (op->s, ntohs (ospfh->length));
366 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
367 stream_set_putp (op->s, oldputp);
368
369 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000370 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
371
paul37163d62003-02-03 18:40:56 +0000372 if (stream_get_endp(op->s) != op->length)
373 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 +0000374
375 return OSPF_AUTH_MD5_SIZE;
376}
377
378
379int
380ospf_ls_req_timer (struct thread *thread)
381{
382 struct ospf_neighbor *nbr;
383
384 nbr = THREAD_ARG (thread);
385 nbr->t_ls_req = NULL;
386
387 /* Send Link State Request. */
388 if (ospf_ls_request_count (nbr))
389 ospf_ls_req_send (nbr);
390
391 /* Set Link State Request retransmission timer. */
392 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
393
394 return 0;
395}
396
397void
398ospf_ls_req_event (struct ospf_neighbor *nbr)
399{
400 if (nbr->t_ls_req)
401 {
402 thread_cancel (nbr->t_ls_req);
403 nbr->t_ls_req = NULL;
404 }
405 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
406}
407
408/* Cyclic timer function. Fist registered in ospf_nbr_new () in
409 ospf_neighbor.c */
410int
411ospf_ls_upd_timer (struct thread *thread)
412{
413 struct ospf_neighbor *nbr;
414
415 nbr = THREAD_ARG (thread);
416 nbr->t_ls_upd = NULL;
417
418 /* Send Link State Update. */
419 if (ospf_ls_retransmit_count (nbr) > 0)
420 {
hasso52dc7ee2004-09-23 19:18:23 +0000421 struct list *update;
paul718e3742002-12-13 20:15:29 +0000422 struct ospf_lsdb *lsdb;
423 int i;
424 struct timeval now;
425 int retransmit_interval;
426
427 gettimeofday (&now, NULL);
428 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
429
430 lsdb = &nbr->ls_rxmt;
431 update = list_new ();
432
433 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
434 {
435 struct route_table *table = lsdb->type[i].db;
436 struct route_node *rn;
437
438 for (rn = route_top (table); rn; rn = route_next (rn))
439 {
440 struct ospf_lsa *lsa;
441
442 if ((lsa = rn->info) != NULL)
443 /* Don't retransmit an LSA if we received it within
444 the last RxmtInterval seconds - this is to allow the
445 neighbour a chance to acknowledge the LSA as it may
446 have ben just received before the retransmit timer
447 fired. This is a small tweak to what is in the RFC,
448 but it will cut out out a lot of retransmit traffic
449 - MAG */
450 if (tv_cmp (tv_sub (now, lsa->tv_recv),
451 int2tv (retransmit_interval)) >= 0)
452 listnode_add (update, rn->info);
453 }
454 }
455
456 if (listcount (update) > 0)
457 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
458 list_delete (update);
459 }
460
461 /* Set LS Update retransmission timer. */
462 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
463
464 return 0;
465}
466
467int
468ospf_ls_ack_timer (struct thread *thread)
469{
470 struct ospf_interface *oi;
471
472 oi = THREAD_ARG (thread);
473 oi->t_ls_ack = NULL;
474
475 /* Send Link State Acknowledgment. */
476 if (listcount (oi->ls_ack) > 0)
477 ospf_ls_ack_send_delayed (oi);
478
479 /* Set LS Ack timer. */
480 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
481
482 return 0;
483}
484
paul0bfeca32004-09-24 08:07:54 +0000485#ifdef WANT_OSPF_WRITE_FRAGMENT
486void
paul6a99f832004-09-27 12:56:30 +0000487ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000488 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000489 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000490{
491#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000492 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000493 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000494 int ret;
paul0bfeca32004-09-24 08:07:54 +0000495
496 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000497 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000498
499 /* we can but try.
500 *
501 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
502 * well as the IP_MF flag, making this all quite pointless.
503 *
504 * However, for a system on which IP_MF is left alone, and ip_id left
505 * alone or else which sets same ip_id for each fragment this might
506 * work, eg linux.
507 *
508 * XXX-TODO: It would be much nicer to have the kernel's use their
509 * existing fragmentation support to do this for us. Bugs/RFEs need to
510 * be raised against the various kernels.
511 */
512
513 /* set More Frag */
514 iph->ip_off |= IP_MF;
515
516 /* ip frag offset is expressed in units of 8byte words */
517 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
518
paul62d8e962004-11-02 20:26:45 +0000519 iovp = &msg->msg_iov[1];
520
paul0bfeca32004-09-24 08:07:54 +0000521 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
522 > maxdatasize )
523 {
524 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000525 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
526 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000527 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000528
paul18b12c32004-10-05 14:38:29 +0000529 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000530
paul6a99f832004-09-27 12:56:30 +0000531 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000532
paul18b12c32004-10-05 14:38:29 +0000533 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000534
535 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000536 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
paul0bfeca32004-09-24 08:07:54 +0000537 " id %d, off %d, len %d failed with %s",
538 inet_ntoa (iph->ip_dst),
539 iph->ip_id,
540 iph->ip_off,
541 iph->ip_len,
ajs6099b3b2004-11-20 02:06:59 +0000542 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000543
paul37ccfa32004-10-31 11:24:51 +0000544 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
545 {
ajs2a42e282004-12-08 18:43:03 +0000546 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000547 iph->ip_id, iph->ip_off, iph->ip_len,
548 inet_ntoa (iph->ip_dst));
549 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
550 {
ajs2a42e282004-12-08 18:43:03 +0000551 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000552 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000553 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000554 }
555 }
556
paul0bfeca32004-09-24 08:07:54 +0000557 iph->ip_off += offset;
paul62d8e962004-11-02 20:26:45 +0000558 stream_forward (op->s, iovp->iov_len);
559 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000560 }
561
562 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000563 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
564 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000565 iph->ip_off &= (~IP_MF);
566}
567#endif /* WANT_OSPF_WRITE_FRAGMENT */
568
paul718e3742002-12-13 20:15:29 +0000569int
570ospf_write (struct thread *thread)
571{
paul68980082003-03-25 05:07:42 +0000572 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000573 struct ospf_interface *oi;
574 struct ospf_packet *op;
575 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000576 struct ip iph;
577 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000578 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000579 u_char type;
580 int ret;
581 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000582 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000583#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000584 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000585#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000586 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000587#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000588
paul68980082003-03-25 05:07:42 +0000589 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000590
paul68980082003-03-25 05:07:42 +0000591 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000592 assert (node);
593 oi = getdata (node);
594 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000595
596#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000597 /* seed ipid static with low order bits of time */
598 if (ipid == 0)
599 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000600#endif /* WANT_OSPF_WRITE_FRAGMENT */
601
paul68b73392004-09-12 14:21:37 +0000602 /* convenience - max OSPF data per packet */
603 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
604
paul718e3742002-12-13 20:15:29 +0000605 /* Get one packet from queue. */
606 op = ospf_fifo_head (oi->obuf);
607 assert (op);
608 assert (op->length >= OSPF_HEADER_SIZE);
609
paul68980082003-03-25 05:07:42 +0000610 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
611 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000612 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
613
paul718e3742002-12-13 20:15:29 +0000614 /* Rewrite the md5 signature & update the seq */
615 ospf_make_md5_digest (oi, op);
616
paul37ccfa32004-10-31 11:24:51 +0000617 /* Retrieve OSPF packet type. */
618 stream_set_getp (op->s, 1);
619 type = stream_getc (op->s);
620
paul68b73392004-09-12 14:21:37 +0000621 /* reset get pointer */
622 stream_set_getp (op->s, 0);
623
624 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000625 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000626
paul718e3742002-12-13 20:15:29 +0000627 sa_dst.sin_family = AF_INET;
628#ifdef HAVE_SIN_LEN
629 sa_dst.sin_len = sizeof(sa_dst);
630#endif /* HAVE_SIN_LEN */
631 sa_dst.sin_addr = op->dst;
632 sa_dst.sin_port = htons (0);
633
634 /* Set DONTROUTE flag if dst is unicast. */
635 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
636 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
637 flags = MSG_DONTROUTE;
638
paul68b73392004-09-12 14:21:37 +0000639 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
640 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000641 if ( sizeof (struct ip)
642 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000643 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
644
paul718e3742002-12-13 20:15:29 +0000645 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000646 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000647 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000648
paul0bfeca32004-09-24 08:07:54 +0000649#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000650 /* XXX-MT: not thread-safe at all..
651 * XXX: this presumes this is only programme sending OSPF packets
652 * otherwise, no guarantee ipid will be unique
653 */
654 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000655#endif /* WANT_OSPF_WRITE_FRAGMENT */
656
paul718e3742002-12-13 20:15:29 +0000657 iph.ip_off = 0;
658 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
659 iph.ip_ttl = OSPF_VL_IP_TTL;
660 else
661 iph.ip_ttl = OSPF_IP_TTL;
662 iph.ip_p = IPPROTO_OSPFIGP;
663 iph.ip_sum = 0;
664 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
665 iph.ip_dst.s_addr = op->dst.s_addr;
666
667 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000668 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000669 msg.msg_namelen = sizeof (sa_dst);
670 msg.msg_iov = iov;
671 msg.msg_iovlen = 2;
672 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000673 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
674 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000675 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000676
677 /* Sadly we can not rely on kernels to fragment packets because of either
678 * IP_HDRINCL and/or multicast destination being set.
679 */
paul0bfeca32004-09-24 08:07:54 +0000680#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000681 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000682 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
683 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000684#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000685
686 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000687 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000688 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000689 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000690
691 if (ret < 0)
paul68b73392004-09-12 14:21:37 +0000692 zlog_warn ("*** sendmsg in ospf_write to %s failed with %s",
ajs6099b3b2004-11-20 02:06:59 +0000693 inet_ntoa (iph.ip_dst), safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000694
paul718e3742002-12-13 20:15:29 +0000695 /* Show debug sending packet. */
696 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
697 {
698 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
699 {
ajs2a42e282004-12-08 18:43:03 +0000700 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000701 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000702 stream_set_getp (op->s, 0);
703 ospf_packet_dump (op->s);
704 }
705
ajs2a42e282004-12-08 18:43:03 +0000706 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000707 ospf_packet_type_str[type], inet_ntoa (op->dst),
708 IF_NAME (oi));
709
710 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000711 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000712 }
713
714 /* Now delete packet from queue. */
715 ospf_packet_delete (oi);
716
717 if (ospf_fifo_head (oi->obuf) == NULL)
718 {
719 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000720 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000721 }
722
723 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000724 if (!list_isempty (ospf->oi_write_q))
725 ospf->t_write =
726 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000727
728 return 0;
729}
730
731/* OSPF Hello message read -- RFC2328 Section 10.5. */
732void
733ospf_hello (struct ip *iph, struct ospf_header *ospfh,
734 struct stream * s, struct ospf_interface *oi, int size)
735{
736 struct ospf_hello *hello;
737 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000738 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000739 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000740
741 /* increment statistics. */
742 oi->hello_in++;
743
744 hello = (struct ospf_hello *) STREAM_PNT (s);
745
746 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000747 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000748 {
749 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
750 {
ajs2a42e282004-12-08 18:43:03 +0000751 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000752 "dropping.",
753 ospf_packet_type_str[ospfh->type],
754 inet_ntoa (iph->ip_src));
755 }
756 return;
757 }
paul718e3742002-12-13 20:15:29 +0000758
759 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000760 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
paulc2191ea2003-04-18 23:59:35 +0000761 zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
762 inet_ntoa (ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000763 return;
paulf2c80652002-12-13 21:44:27 +0000764 }
paul718e3742002-12-13 20:15:29 +0000765
766 /* get neighbor prefix. */
767 p.family = AF_INET;
768 p.prefixlen = ip_masklen (hello->network_mask);
769 p.u.prefix4 = iph->ip_src;
770
771 /* Compare network mask. */
772 /* Checking is ignored for Point-to-Point and Virtual link. */
773 if (oi->type != OSPF_IFTYPE_POINTOPOINT
774 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
775 if (oi->address->prefixlen != p.prefixlen)
776 {
777 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
778 inet_ntoa (ospfh->router_id));
779 return;
780 }
781
782 /* Compare Hello Interval. */
783 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
784 {
785 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
786 inet_ntoa (ospfh->router_id));
787 return;
788 }
789
790 /* Compare Router Dead Interval. */
791 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
792 {
793 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
794 inet_ntoa (ospfh->router_id));
795 return;
796 }
797
798 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000799 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000800 inet_ntoa (ospfh->router_id),
801 ospf_options_dump (hello->options));
802
803 /* Compare options. */
804#define REJECT_IF_TBIT_ON 1 /* XXX */
805#ifdef REJECT_IF_TBIT_ON
806 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
807 {
808 /*
809 * This router does not support non-zero TOS.
810 * Drop this Hello packet not to establish neighbor relationship.
811 */
812 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
813 inet_ntoa (ospfh->router_id));
814 return;
815 }
816#endif /* REJECT_IF_TBIT_ON */
817
818#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000819 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000820 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
821 {
822 /*
823 * This router does know the correct usage of O-bit
824 * the bit should be set in DD packet only.
825 */
826 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
827 inet_ntoa (ospfh->router_id));
828#ifdef STRICT_OBIT_USAGE_CHECK
829 return; /* Reject this packet. */
830#else /* STRICT_OBIT_USAGE_CHECK */
831 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
832#endif /* STRICT_OBIT_USAGE_CHECK */
833 }
834#endif /* HAVE_OPAQUE_LSA */
835
836 /* new for NSSA is to ensure that NP is on and E is off */
837
paul718e3742002-12-13 20:15:29 +0000838 if (oi->area->external_routing == OSPF_AREA_NSSA)
839 {
840 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
841 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
842 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
843 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
844 {
845 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
846 return;
847 }
848 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000849 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000850 }
851 else
paul718e3742002-12-13 20:15:29 +0000852 /* The setting of the E-bit found in the Hello Packet's Options
853 field must match this area's ExternalRoutingCapability A
854 mismatch causes processing to stop and the packet to be
855 dropped. The setting of the rest of the bits in the Hello
856 Packet's Options field should be ignored. */
857 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
858 CHECK_FLAG (hello->options, OSPF_OPTION_E))
859 {
ajs3aa8d5f2004-12-11 18:00:06 +0000860 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
861 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000862 return;
863 }
paul718e3742002-12-13 20:15:29 +0000864
pauld3f0d622004-05-05 15:27:15 +0000865 /* get neighbour struct */
866 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
867
868 /* neighbour must be valid, ospf_nbr_get creates if none existed */
869 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000870
871 old_state = nbr->state;
872
873 /* Add event to thread. */
874 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
875
876 /* RFC2328 Section 9.5.1
877 If the router is not eligible to become Designated Router,
878 (snip) It must also send an Hello Packet in reply to an
879 Hello Packet received from any eligible neighbor (other than
880 the current Designated Router and Backup Designated Router). */
881 if (oi->type == OSPF_IFTYPE_NBMA)
882 if (PRIORITY(oi) == 0 && hello->priority > 0
883 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
884 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
885 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
886 OSPF_HELLO_REPLY_DELAY);
887
888 /* on NBMA network type, it happens to receive bidirectional Hello packet
889 without advance 1-Way Received event.
890 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
891 if (oi->type == OSPF_IFTYPE_NBMA &&
892 (old_state == NSM_Down || old_state == NSM_Attempt))
893 {
894 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
895 nbr->priority = hello->priority;
896 nbr->d_router = hello->d_router;
897 nbr->bd_router = hello->bd_router;
898 return;
899 }
900
paul68980082003-03-25 05:07:42 +0000901 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000902 size - OSPF_HELLO_MIN_SIZE))
903 {
904 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
905 nbr->options |= hello->options;
906 }
907 else
908 {
909 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
910 /* Set neighbor information. */
911 nbr->priority = hello->priority;
912 nbr->d_router = hello->d_router;
913 nbr->bd_router = hello->bd_router;
914 return;
915 }
916
917 /* If neighbor itself declares DR and no BDR exists,
918 cause event BackupSeen */
919 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
920 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
921 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
922
923 /* neighbor itself declares BDR. */
924 if (oi->state == ISM_Waiting &&
925 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
926 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
927
928 /* had not previously. */
929 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
930 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
931 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
932 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
933 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
934
935 /* had not previously. */
936 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
937 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
938 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
939 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
940 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
941
942 /* Neighbor priority check. */
943 if (nbr->priority >= 0 && nbr->priority != hello->priority)
944 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
945
946 /* Set neighbor information. */
947 nbr->priority = hello->priority;
948 nbr->d_router = hello->d_router;
949 nbr->bd_router = hello->bd_router;
950}
951
952/* Save DD flags/options/Seqnum received. */
953void
954ospf_db_desc_save_current (struct ospf_neighbor *nbr,
955 struct ospf_db_desc *dd)
956{
957 nbr->last_recv.flags = dd->flags;
958 nbr->last_recv.options = dd->options;
959 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
960}
961
962/* Process rest of DD packet. */
963static void
964ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
965 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
966 u_int16_t size)
967{
968 struct ospf_lsa *new, *find;
969 struct lsa_header *lsah;
970
971 stream_forward (s, OSPF_DB_DESC_MIN_SIZE);
972 for (size -= OSPF_DB_DESC_MIN_SIZE;
973 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
974 {
975 lsah = (struct lsa_header *) STREAM_PNT (s);
976 stream_forward (s, OSPF_LSA_HEADER_SIZE);
977
978 /* Unknown LS type. */
979 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
980 {
ajsbec595a2004-11-30 22:38:43 +0000981 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000982 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
983 return;
984 }
985
986#ifdef HAVE_OPAQUE_LSA
987 if (IS_OPAQUE_LSA (lsah->type)
988 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
989 {
990 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
991 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
992 return;
993 }
994#endif /* HAVE_OPAQUE_LSA */
995
996 switch (lsah->type)
997 {
998 case OSPF_AS_EXTERNAL_LSA:
999#ifdef HAVE_OPAQUE_LSA
1000 case OSPF_OPAQUE_AS_LSA:
1001#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001002 /* Check for stub area. Reject if AS-External from stub but
1003 allow if from NSSA. */
1004 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001005 {
1006 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1007 lsah->type, inet_ntoa (lsah->id),
1008 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1009 "STUB" : "NSSA");
1010 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1011 return;
1012 }
1013 break;
1014 default:
1015 break;
1016 }
1017
1018 /* Create LS-request object. */
1019 new = ospf_ls_request_new (lsah);
1020
1021 /* Lookup received LSA, then add LS request list. */
1022 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1023 if (!find || ospf_lsa_more_recent (find, new) < 0)
1024 {
1025 ospf_ls_request_add (nbr, new);
1026 ospf_lsa_discard (new);
1027 }
1028 else
1029 {
1030 /* Received LSA is not recent. */
1031 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001032 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001033 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1034 ospf_lsa_discard (new);
1035 continue;
1036 }
1037 }
1038
1039 /* Master */
1040 if (IS_SET_DD_MS (nbr->dd_flags))
1041 {
1042 nbr->dd_seqnum++;
1043 /* Entire DD packet sent. */
1044 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1045 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1046 else
1047 /* Send new DD packet. */
1048 ospf_db_desc_send (nbr);
1049 }
1050 /* Slave */
1051 else
1052 {
1053 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1054
1055 /* When master's more flags is not set. */
1056 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1057 {
1058 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1059 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1060 }
1061
ajsbec595a2004-11-30 22:38:43 +00001062 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001063 ospf_db_desc_send (nbr);
1064 }
1065
1066 /* Save received neighbor values from DD. */
1067 ospf_db_desc_save_current (nbr, dd);
1068}
1069
1070int
1071ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1072{
1073 /* Is DD duplicated? */
1074 if (dd->options == nbr->last_recv.options &&
1075 dd->flags == nbr->last_recv.flags &&
1076 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1077 return 1;
1078
1079 return 0;
1080}
1081
1082/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001083static void
paul718e3742002-12-13 20:15:29 +00001084ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1085 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1086{
1087 struct ospf_db_desc *dd;
1088 struct ospf_neighbor *nbr;
1089
1090 /* Increment statistics. */
1091 oi->db_desc_in++;
1092
1093 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001094
pauld3f0d622004-05-05 15:27:15 +00001095 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001096 if (nbr == NULL)
1097 {
1098 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1099 inet_ntoa (ospfh->router_id));
1100 return;
1101 }
1102
1103 /* Check MTU. */
1104 if (ntohs (dd->mtu) > oi->ifp->mtu)
1105 {
ajs3aa8d5f2004-12-11 18:00:06 +00001106 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1107 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1108 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001109 return;
1110 }
1111
pauld363df22003-06-19 00:26:34 +00001112 /*
1113 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1114 * required. In fact at least JunOS sends DD packets with P bit clear.
1115 * Until proper solution is developped, this hack should help.
1116 *
1117 * Update: According to the RFCs, N bit is specified /only/ for Hello
1118 * options, unfortunately its use in DD options is not specified. Hence some
1119 * implementations follow E-bit semantics and set it in DD options, and some
1120 * treat it as unspecified and hence follow the directive "default for
1121 * options is clear", ie unset.
1122 *
1123 * Reset the flag, as ospfd follows E-bit semantics.
1124 */
1125 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1126 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1127 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1128 {
1129 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001130 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001131 inet_ntoa (nbr->router_id) );
1132 SET_FLAG (dd->options, OSPF_OPTION_NP);
1133 }
pauld363df22003-06-19 00:26:34 +00001134
paul718e3742002-12-13 20:15:29 +00001135#ifdef REJECT_IF_TBIT_ON
1136 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1137 {
1138 /*
1139 * In Hello protocol, optional capability must have checked
1140 * to prevent this T-bit enabled router be my neighbor.
1141 */
1142 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1143 return;
1144 }
1145#endif /* REJECT_IF_TBIT_ON */
1146
1147#ifdef HAVE_OPAQUE_LSA
1148 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001149 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001150 {
1151 /*
1152 * This node is not configured to handle O-bit, for now.
1153 * Clear it to ignore unsupported capability proposed by neighbor.
1154 */
1155 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1156 }
1157#endif /* HAVE_OPAQUE_LSA */
1158
1159 /* Process DD packet by neighbor status. */
1160 switch (nbr->state)
1161 {
1162 case NSM_Down:
1163 case NSM_Attempt:
1164 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001165 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001166 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001167 LOOKUP (ospf_nsm_state_msg, nbr->state));
1168 break;
1169 case NSM_Init:
1170 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1171 /* If the new state is ExStart, the processing of the current
1172 packet should then continue in this new state by falling
1173 through to case ExStart below. */
1174 if (nbr->state != NSM_ExStart)
1175 break;
1176 case NSM_ExStart:
1177 /* Initial DBD */
1178 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1179 (size == OSPF_DB_DESC_MIN_SIZE))
1180 {
paul68980082003-03-25 05:07:42 +00001181 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001182 {
1183 /* We're Slave---obey */
ajs3aa8d5f2004-12-11 18:00:06 +00001184 zlog_warn ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
1185 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001186 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1187 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1188 }
1189 else
1190 {
1191 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001192 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1193 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001194 break;
1195 }
1196 }
1197 /* Ack from the Slave */
1198 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1199 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001200 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001201 {
ajs3aa8d5f2004-12-11 18:00:06 +00001202 zlog_warn ("Packet[DD]: Neighbor %s Negotiation done (Master).",
1203 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001204 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1205 }
1206 else
1207 {
ajs3aa8d5f2004-12-11 18:00:06 +00001208 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1209 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001210 break;
1211 }
1212
1213 /* This is where the real Options are saved */
1214 nbr->options = dd->options;
1215
1216#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001217 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001218 {
1219 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001220 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001221 inet_ntoa (nbr->router_id),
1222 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1223
1224 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1225 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1226 {
1227 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1228 /* This situation is undesirable, but not a real error. */
1229 }
1230 }
1231#endif /* HAVE_OPAQUE_LSA */
1232
1233 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1234
1235 /* continue processing rest of packet. */
1236 ospf_db_desc_proc (s, oi, nbr, dd, size);
1237 break;
1238 case NSM_Exchange:
1239 if (ospf_db_desc_is_dup (dd, nbr))
1240 {
1241 if (IS_SET_DD_MS (nbr->dd_flags))
1242 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001243 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1244 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001245 else
1246 /* Slave: cause to retransmit the last Database Description. */
1247 {
ajs3aa8d5f2004-12-11 18:00:06 +00001248 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1249 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001250 ospf_db_desc_resend (nbr);
1251 }
1252 break;
1253 }
1254
1255 /* Otherwise DD packet should be checked. */
1256 /* Check Master/Slave bit mismatch */
1257 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1258 {
ajs3aa8d5f2004-12-11 18:00:06 +00001259 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1260 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001261 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1262 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001263 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001264 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001265 break;
1266 }
1267
1268 /* Check initialize bit is set. */
1269 if (IS_SET_DD_I (dd->flags))
1270 {
ajs3aa8d5f2004-12-11 18:00:06 +00001271 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1272 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001273 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1274 break;
1275 }
1276
1277 /* Check DD Options. */
1278 if (dd->options != nbr->options)
1279 {
1280#ifdef ORIGINAL_CODING
1281 /* Save the new options for debugging */
1282 nbr->options = dd->options;
1283#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001284 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1285 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001286 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1287 break;
1288 }
1289
1290 /* Check DD sequence number. */
1291 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1292 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1293 (!IS_SET_DD_MS (nbr->dd_flags) &&
1294 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1295 {
ajs3aa8d5f2004-12-11 18:00:06 +00001296 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1297 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001298 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1299 break;
1300 }
1301
1302 /* Continue processing rest of packet. */
1303 ospf_db_desc_proc (s, oi, nbr, dd, size);
1304 break;
1305 case NSM_Loading:
1306 case NSM_Full:
1307 if (ospf_db_desc_is_dup (dd, nbr))
1308 {
1309 if (IS_SET_DD_MS (nbr->dd_flags))
1310 {
1311 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001312 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1313 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001314 break;
1315 }
1316 else
1317 {
1318 struct timeval t, now;
1319 gettimeofday (&now, NULL);
1320 t = tv_sub (now, nbr->last_send_ts);
1321 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1322 {
1323 /* In states Loading and Full the slave must resend
1324 its last Database Description packet in response to
1325 duplicate Database Description packets received
1326 from the master. For this reason the slave must
1327 wait RouterDeadInterval seconds before freeing the
1328 last Database Description packet. Reception of a
1329 Database Description packet from the master after
1330 this interval will generate a SeqNumberMismatch
1331 neighbor event. RFC2328 Section 10.8 */
1332 ospf_db_desc_resend (nbr);
1333 break;
1334 }
1335 }
1336 }
1337
1338 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1339 break;
1340 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001341 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1342 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001343 break;
1344 }
1345}
1346
1347#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1348
1349/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
1350void
1351ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1352 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1353{
1354 struct ospf_neighbor *nbr;
1355 u_int32_t ls_type;
1356 struct in_addr ls_id;
1357 struct in_addr adv_router;
1358 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001359 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001360 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001361
1362 /* Increment statistics. */
1363 oi->ls_req_in++;
1364
pauld3f0d622004-05-05 15:27:15 +00001365 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001366 if (nbr == NULL)
1367 {
1368 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1369 inet_ntoa (ospfh->router_id));
1370 return;
1371 }
1372
1373 /* Neighbor State should be Exchange or later. */
1374 if (nbr->state != NSM_Exchange &&
1375 nbr->state != NSM_Loading &&
1376 nbr->state != NSM_Full)
1377 {
ajsbec595a2004-11-30 22:38:43 +00001378 zlog_warn ("Link State Request received from %s: "
1379 "Neighbor state is %s, packet discarded.",
1380 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001381 LOOKUP (ospf_nsm_state_msg, nbr->state));
1382 return;
1383 }
1384
1385 /* Send Link State Update for ALL requested LSAs. */
1386 ls_upd = list_new ();
1387 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1388
1389 while (size >= OSPF_LSA_KEY_SIZE)
1390 {
1391 /* Get one slice of Link State Request. */
1392 ls_type = stream_getl (s);
1393 ls_id.s_addr = stream_get_ipv4 (s);
1394 adv_router.s_addr = stream_get_ipv4 (s);
1395
1396 /* Verify LSA type. */
1397 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1398 {
1399 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1400 list_delete (ls_upd);
1401 return;
1402 }
1403
1404 /* Search proper LSA in LSDB. */
1405 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1406 if (find == NULL)
1407 {
1408 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1409 list_delete (ls_upd);
1410 return;
1411 }
1412
1413 /* Packet overflows MTU size, send immediatly. */
1414 if (length + ntohs (find->data->length) > OSPF_PACKET_MAX (oi))
1415 {
1416 if (oi->type == OSPF_IFTYPE_NBMA)
1417 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1418 else
1419 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1420
1421 /* Only remove list contents. Keep ls_upd. */
1422 list_delete_all_node (ls_upd);
1423
1424 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1425 }
1426
1427 /* Append LSA to update list. */
1428 listnode_add (ls_upd, find);
1429 length += ntohs (find->data->length);
1430
1431 size -= OSPF_LSA_KEY_SIZE;
1432 }
1433
1434 /* Send rest of Link State Update. */
1435 if (listcount (ls_upd) > 0)
1436 {
1437 if (oi->type == OSPF_IFTYPE_NBMA)
1438 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1439 else
1440 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1441
1442 list_delete (ls_upd);
1443 }
1444 else
1445 list_free (ls_upd);
1446}
1447
1448/* Get the list of LSAs from Link State Update packet.
1449 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001450static struct list *
paul718e3742002-12-13 20:15:29 +00001451ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1452 struct ospf_interface *oi, size_t size)
1453{
1454 u_int16_t count, sum;
1455 u_int32_t length;
1456 struct lsa_header *lsah;
1457 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001458 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001459
1460 lsas = list_new ();
1461
1462 count = stream_getl (s);
1463 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1464
1465 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
1466 size -= length, stream_forward (s, length), count--)
1467 {
1468 lsah = (struct lsa_header *) STREAM_PNT (s);
1469 length = ntohs (lsah->length);
1470
1471 if (length > size)
1472 {
1473 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1474 break;
1475 }
1476
1477 /* Validate the LSA's LS checksum. */
1478 sum = lsah->checksum;
1479 if (sum != ospf_lsa_checksum (lsah))
1480 {
1481 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1482 sum, lsah->checksum);
1483 continue;
1484 }
1485
1486 /* Examine the LSA's LS type. */
1487 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1488 {
1489 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1490 continue;
1491 }
1492
1493 /*
1494 * What if the received LSA's age is greater than MaxAge?
1495 * Treat it as a MaxAge case -- endo.
1496 */
1497 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1498 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1499
1500#ifdef HAVE_OPAQUE_LSA
1501 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1502 {
1503#ifdef STRICT_OBIT_USAGE_CHECK
1504 if ((IS_OPAQUE_LSA(lsah->type) &&
1505 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1506 || (! IS_OPAQUE_LSA(lsah->type) &&
1507 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1508 {
1509 /*
1510 * This neighbor must know the exact usage of O-bit;
1511 * the bit will be set in Type-9,10,11 LSAs only.
1512 */
1513 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1514 continue;
1515 }
1516#endif /* STRICT_OBIT_USAGE_CHECK */
1517
1518 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1519 if (lsah->type == OSPF_OPAQUE_AS_LSA
1520 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1521 {
1522 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001523 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 +00001524 continue;
1525 }
1526 }
1527 else if (IS_OPAQUE_LSA(lsah->type))
1528 {
1529 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1530 continue;
1531 }
1532#endif /* HAVE_OPAQUE_LSA */
1533
1534 /* Create OSPF LSA instance. */
1535 lsa = ospf_lsa_new ();
1536
1537 /* We may wish to put some error checking if type NSSA comes in
1538 and area not in NSSA mode */
1539 switch (lsah->type)
1540 {
1541 case OSPF_AS_EXTERNAL_LSA:
1542#ifdef HAVE_OPAQUE_LSA
1543 case OSPF_OPAQUE_AS_LSA:
1544 lsa->area = NULL;
1545 break;
1546 case OSPF_OPAQUE_LINK_LSA:
1547 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1548 /* Fallthrough */
1549#endif /* HAVE_OPAQUE_LSA */
1550 default:
1551 lsa->area = oi->area;
1552 break;
1553 }
1554
1555 lsa->data = ospf_lsa_data_new (length);
1556 memcpy (lsa->data, lsah, length);
1557
1558 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001559 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001560 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1561 listnode_add (lsas, lsa);
1562 }
1563
1564 return lsas;
1565}
1566
1567/* Cleanup Update list. */
1568void
hasso52dc7ee2004-09-23 19:18:23 +00001569ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001570{
hasso52dc7ee2004-09-23 19:18:23 +00001571 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001572 struct ospf_lsa *lsa;
1573
1574 for (node = listhead (lsas); node; nextnode (node))
1575 if ((lsa = getdata (node)) != NULL)
1576 ospf_lsa_discard (lsa);
1577
1578 list_delete (lsas);
1579}
1580
1581/* OSPF Link State Update message read -- RFC2328 Section 13. */
1582void
1583ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1584 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1585{
1586 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001587 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001588#ifdef HAVE_OPAQUE_LSA
hasso52dc7ee2004-09-23 19:18:23 +00001589 struct list *mylsa_acks, *mylsa_upds;
paul718e3742002-12-13 20:15:29 +00001590#endif /* HAVE_OPAQUE_LSA */
hasso52dc7ee2004-09-23 19:18:23 +00001591 struct listnode *node, *next;
paul718e3742002-12-13 20:15:29 +00001592 struct ospf_lsa *lsa = NULL;
1593 /* unsigned long ls_req_found = 0; */
1594
1595 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1596
1597 /* Increment statistics. */
1598 oi->ls_upd_in++;
1599
1600 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001601 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001602 if (nbr == NULL)
1603 {
1604 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1605 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1606 return;
1607 }
1608
1609 /* Check neighbor state. */
1610 if (nbr->state < NSM_Exchange)
1611 {
ajs3aa8d5f2004-12-11 18:00:06 +00001612 zlog_warn ("Link State Update: "
1613 "Neighbor[%s] state %s is less than Exchange",
1614 inet_ntoa (ospfh->router_id),
1615 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001616 return;
1617 }
1618
1619 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1620 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1621 * of section 13.
1622 */
1623 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1624
1625#ifdef HAVE_OPAQUE_LSA
1626 /*
1627 * Prepare two kinds of lists to clean up unwanted self-originated
1628 * Opaque-LSAs from the routing domain as soon as possible.
1629 */
1630 mylsa_acks = list_new (); /* Let the sender cease retransmission. */
1631 mylsa_upds = list_new (); /* Flush target LSAs if necessary. */
1632
1633 /*
1634 * If self-originated Opaque-LSAs that have flooded before restart
1635 * are contained in the received LSUpd message, corresponding LSReq
1636 * messages to be sent may have to be modified.
1637 * To eliminate possible race conditions such that flushing and normal
1638 * updating for the same LSA would take place alternately, this trick
1639 * must be done before entering to the loop below.
1640 */
1641 ospf_opaque_adjust_lsreq (nbr, lsas);
1642#endif /* HAVE_OPAQUE_LSA */
1643
1644#define DISCARD_LSA(L,N) {\
1645 if (IS_DEBUG_OSPF_EVENT) \
ajs2a42e282004-12-08 18:43:03 +00001646 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 +00001647 ospf_lsa_discard (L); \
1648 continue; }
1649
1650 /* Process each LSA received in the one packet. */
1651 for (node = listhead (lsas); node; node = next)
1652 {
1653 struct ospf_lsa *ls_ret, *current;
1654 int ret = 1;
1655
1656 next = node->next;
1657
1658 lsa = getdata (node);
1659
paul718e3742002-12-13 20:15:29 +00001660 if (IS_DEBUG_OSPF_NSSA)
1661 {
1662 char buf1[INET_ADDRSTRLEN];
1663 char buf2[INET_ADDRSTRLEN];
1664 char buf3[INET_ADDRSTRLEN];
1665
ajs2a42e282004-12-08 18:43:03 +00001666 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001667 lsa->data->type,
1668 inet_ntop (AF_INET, &ospfh->router_id,
1669 buf1, INET_ADDRSTRLEN),
1670 inet_ntop (AF_INET, &lsa->data->id,
1671 buf2, INET_ADDRSTRLEN),
1672 inet_ntop (AF_INET, &lsa->data->adv_router,
1673 buf3, INET_ADDRSTRLEN));
1674 }
paul718e3742002-12-13 20:15:29 +00001675
1676 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1677
1678 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1679
1680 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1681
1682 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1683
1684 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1685
1686 /* Do take in Type-7's if we are an NSSA */
1687
1688 /* If we are also an ABR, later translate them to a Type-5 packet */
1689
1690 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1691 translate them to a separate Type-5 packet. */
1692
1693 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1694 /* Reject from STUB or NSSA */
1695 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1696 {
1697 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001698 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001699 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001700 }
1701
paul718e3742002-12-13 20:15:29 +00001702 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1703 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1704 {
1705 DISCARD_LSA (lsa,2);
1706 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001707 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001708 }
paul718e3742002-12-13 20:15:29 +00001709
1710 /* Find the LSA in the current database. */
1711
1712 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1713
1714 /* If the LSA's LS age is equal to MaxAge, and there is currently
1715 no instance of the LSA in the router's link state database,
1716 and none of router's neighbors are in states Exchange or Loading,
1717 then take the following actions. */
1718
1719 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001720 (ospf_nbr_count (oi, NSM_Exchange) +
1721 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001722 {
1723 /* Response Link State Acknowledgment. */
1724 ospf_ls_ack_send (nbr, lsa);
1725
1726 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001727 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1728 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001729 DISCARD_LSA (lsa, 3);
1730 }
1731
1732#ifdef HAVE_OPAQUE_LSA
1733 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001734 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001735 {
1736 /*
1737 * Even if initial flushing seems to be completed, there might
1738 * be a case that self-originated LSA with MaxAge still remain
1739 * in the routing domain.
1740 * Just send an LSAck message to cease retransmission.
1741 */
1742 if (IS_LSA_MAXAGE (lsa))
1743 {
1744 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1745 ospf_ls_ack_send (nbr, lsa);
1746 ospf_lsa_discard (lsa);
1747
1748 if (current != NULL && ! IS_LSA_MAXAGE (current))
1749 ospf_opaque_lsa_refresh_schedule (current);
1750 continue;
1751 }
1752
1753 /*
1754 * If an instance of self-originated Opaque-LSA is not found
1755 * in the LSDB, there are some possible cases here.
1756 *
1757 * 1) This node lost opaque-capability after restart.
1758 * 2) Else, a part of opaque-type is no more supported.
1759 * 3) Else, a part of opaque-id is no more supported.
1760 *
1761 * Anyway, it is still this node's responsibility to flush it.
1762 * Otherwise, the LSA instance remains in the routing domain
1763 * until its age reaches to MaxAge.
1764 */
1765 if (current == NULL)
1766 {
1767 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001768 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA, not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001769
1770 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
1771 listnode_add (mylsa_upds, ospf_lsa_dup (lsa));
1772 listnode_add (mylsa_acks, ospf_lsa_lock (lsa));
1773 continue;
1774 }
1775 }
1776#endif /* HAVE_OPAQUE_LSA */
hassocb05eb22004-02-11 21:10:19 +00001777 /* It might be happen that received LSA is self-originated network LSA, but
1778 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1779 * Link State ID is one of the router's own IP interface addresses but whose
1780 * Advertising Router is not equal to the router's own Router ID
1781 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1782 */
1783
1784 if(lsa->data->type == OSPF_NETWORK_LSA)
1785 {
hasso52dc7ee2004-09-23 19:18:23 +00001786 struct listnode *oi_node;
hassocb05eb22004-02-11 21:10:19 +00001787 int Flag = 0;
1788
1789 for(oi_node = listhead(oi->ospf->oiflist); oi_node; oi_node = nextnode(oi_node))
1790 {
1791 struct ospf_interface *out_if = getdata(oi_node);
1792 if(out_if == NULL)
1793 break;
1794
1795 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1796 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1797 {
1798 if(out_if->network_lsa_self)
1799 {
1800 ospf_lsa_flush_area(lsa,out_if->area);
1801 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001802 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001803 lsa, (int) lsa->data->type);
1804 ospf_lsa_discard (lsa);
1805 Flag = 1;
1806 }
1807 break;
1808 }
1809 }
1810 if(Flag)
1811 continue;
1812 }
paul718e3742002-12-13 20:15:29 +00001813
1814 /* (5) Find the instance of this LSA that is currently contained
1815 in the router's link state database. If there is no
1816 database copy, or the received LSA is more recent than
1817 the database copy the following steps must be performed. */
1818
1819 if (current == NULL ||
1820 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1821 {
1822 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001823 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001824 DISCARD_LSA (lsa, 4);
1825 continue;
1826 }
1827
1828 /* (6) Else, If there is an instance of the LSA on the sending
1829 neighbor's Link state request list, an error has occurred in
1830 the Database Exchange process. In this case, restart the
1831 Database Exchange process by generating the neighbor event
1832 BadLSReq for the sending neighbor and stop processing the
1833 Link State Update packet. */
1834
1835 if (ospf_ls_request_lookup (nbr, lsa))
1836 {
1837 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001838 zlog_warn("LSA[%s] instance exists on Link state request list",
1839 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001840
1841 /* Clean list of LSAs. */
1842 ospf_upd_list_clean (lsas);
1843 /* this lsa is not on lsas list already. */
1844 ospf_lsa_discard (lsa);
1845#ifdef HAVE_OPAQUE_LSA
1846 list_delete (mylsa_acks);
1847 list_delete (mylsa_upds);
1848#endif /* HAVE_OPAQUE_LSA */
1849 return;
1850 }
1851
1852 /* If the received LSA is the same instance as the database copy
1853 (i.e., neither one is more recent) the following two steps
1854 should be performed: */
1855
1856 if (ret == 0)
1857 {
1858 /* If the LSA is listed in the Link state retransmission list
1859 for the receiving adjacency, the router itself is expecting
1860 an acknowledgment for this LSA. The router should treat the
1861 received LSA as an acknowledgment by removing the LSA from
1862 the Link state retransmission list. This is termed an
1863 "implied acknowledgment". */
1864
1865 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1866
1867 if (ls_ret != NULL)
1868 {
1869 ospf_ls_retransmit_delete (nbr, ls_ret);
1870
1871 /* Delayed acknowledgment sent if advertisement received
1872 from Designated Router, otherwise do nothing. */
1873 if (oi->state == ISM_Backup)
1874 if (NBR_IS_DR (nbr))
1875 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1876
1877 DISCARD_LSA (lsa, 5);
1878 }
1879 else
1880 /* Acknowledge the receipt of the LSA by sending a
1881 Link State Acknowledgment packet back out the receiving
1882 interface. */
1883 {
1884 ospf_ls_ack_send (nbr, lsa);
1885 DISCARD_LSA (lsa, 6);
1886 }
1887 }
1888
1889 /* The database copy is more recent. If the database copy
1890 has LS age equal to MaxAge and LS sequence number equal to
1891 MaxSequenceNumber, simply discard the received LSA without
1892 acknowledging it. (In this case, the LSA's LS sequence number is
1893 wrapping, and the MaxSequenceNumber LSA must be completely
1894 flushed before any new LSA instance can be introduced). */
1895
1896 else if (ret > 0) /* Database copy is more recent */
1897 {
1898 if (IS_LSA_MAXAGE (current) &&
1899 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1900 {
1901 DISCARD_LSA (lsa, 7);
1902 }
1903 /* Otherwise, as long as the database copy has not been sent in a
1904 Link State Update within the last MinLSArrival seconds, send the
1905 database copy back to the sending neighbor, encapsulated within
1906 a Link State Update Packet. The Link State Update Packet should
1907 be sent directly to the neighbor. In so doing, do not put the
1908 database copy of the LSA on the neighbor's link state
1909 retransmission list, and do not acknowledge the received (less
1910 recent) LSA instance. */
1911 else
1912 {
1913 struct timeval now;
1914
1915 gettimeofday (&now, NULL);
1916
1917 if (tv_cmp (tv_sub (now, current->tv_orig),
1918 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1919 /* Trap NSSA type later.*/
1920 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1921 DISCARD_LSA (lsa, 8);
1922 }
1923 }
1924 }
1925
1926#ifdef HAVE_OPAQUE_LSA
1927 /*
1928 * Now that previously originated Opaque-LSAs those which not yet
1929 * installed into LSDB are captured, take several steps to clear
1930 * them completely from the routing domain, before proceeding to
1931 * origination for the current target Opaque-LSAs.
1932 */
1933 while (listcount (mylsa_acks) > 0)
1934 ospf_ls_ack_send_list (oi, mylsa_acks, nbr->address.u.prefix4);
1935
1936 if (listcount (mylsa_upds) > 0)
1937 ospf_opaque_self_originated_lsa_received (nbr, mylsa_upds);
1938
1939 list_delete (mylsa_upds);
paul683b2262003-03-28 00:43:48 +00001940 list_delete (mylsa_acks);
paul718e3742002-12-13 20:15:29 +00001941#endif /* HAVE_OPAQUE_LSA */
1942
1943 assert (listcount (lsas) == 0);
1944 list_delete (lsas);
1945}
1946
1947/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
1948void
1949ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1950 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1951{
1952 struct ospf_neighbor *nbr;
1953#ifdef HAVE_OPAQUE_LSA
paul87d6f872004-09-24 08:01:38 +00001954 struct list *opaque_acks;
paul718e3742002-12-13 20:15:29 +00001955#endif /* HAVE_OPAQUE_LSA */
1956
1957 /* increment statistics. */
1958 oi->ls_ack_in++;
1959
pauld3f0d622004-05-05 15:27:15 +00001960 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001961 if (nbr == NULL)
1962 {
1963 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1964 inet_ntoa (ospfh->router_id));
1965 return;
1966 }
1967
1968 if (nbr->state < NSM_Exchange)
1969 {
ajs3aa8d5f2004-12-11 18:00:06 +00001970 zlog_warn ("Link State Acknowledgment: "
1971 "Neighbor[%s] state %s is less than Exchange",
1972 inet_ntoa (ospfh->router_id),
1973 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001974 return;
1975 }
1976
1977#ifdef HAVE_OPAQUE_LSA
1978 opaque_acks = list_new ();
1979#endif /* HAVE_OPAQUE_LSA */
1980
1981 while (size >= OSPF_LSA_HEADER_SIZE)
1982 {
1983 struct ospf_lsa *lsa, *lsr;
1984
1985 lsa = ospf_lsa_new ();
1986 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1987
1988 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1989 size -= OSPF_LSA_HEADER_SIZE;
1990 stream_forward (s, OSPF_LSA_HEADER_SIZE);
1991
1992 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1993 {
1994 lsa->data = NULL;
1995 ospf_lsa_discard (lsa);
1996 continue;
1997 }
1998
1999 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
2000
2001 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
2002 {
2003#ifdef HAVE_OPAQUE_LSA
2004 /* Keep this LSA entry for later reference. */
2005 if (IS_OPAQUE_LSA (lsr->data->type))
2006 listnode_add (opaque_acks, ospf_lsa_dup (lsr));
2007#endif /* HAVE_OPAQUE_LSA */
2008
2009 ospf_ls_retransmit_delete (nbr, lsr);
2010 }
2011
2012 lsa->data = NULL;
2013 ospf_lsa_discard (lsa);
2014 }
2015
2016#ifdef HAVE_OPAQUE_LSA
2017 if (listcount (opaque_acks) > 0)
2018 ospf_opaque_ls_ack_received (nbr, opaque_acks);
2019
2020 list_delete (opaque_acks);
2021 return;
2022#endif /* HAVE_OPAQUE_LSA */
2023}
2024
2025struct stream *
2026ospf_recv_packet (int fd, struct interface **ifp)
2027{
2028 int ret;
2029 struct ip iph;
2030 u_int16_t ip_len;
2031 struct stream *ibuf;
2032 unsigned int ifindex = 0;
2033 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00002034 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002035 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002036 struct msghdr msgh;
2037
paul68defd62004-09-27 07:27:13 +00002038 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002039 msgh.msg_iov = &iov;
2040 msgh.msg_iovlen = 1;
2041 msgh.msg_control = (caddr_t) buff;
2042 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002043
paul718e3742002-12-13 20:15:29 +00002044 ret = recvfrom (fd, (void *)&iph, sizeof (iph), MSG_PEEK, NULL, 0);
2045
2046 if (ret != sizeof (iph))
2047 {
2048 zlog_warn ("ospf_recv_packet packet smaller than ip header");
2049 return NULL;
2050 }
paul18b12c32004-10-05 14:38:29 +00002051
2052 sockopt_iphdrincl_swab_systoh (&iph);
2053
paul6b333612004-10-11 10:11:25 +00002054 ip_len = iph.ip_len;
2055
paul239aecc2003-12-08 10:34:54 +00002056#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002057 /*
2058 * Kernel network code touches incoming IP header parameters,
2059 * before protocol specific processing.
2060 *
2061 * 1) Convert byteorder to host representation.
2062 * --> ip_len, ip_id, ip_off
2063 *
2064 * 2) Adjust ip_len to strip IP header size!
2065 * --> If user process receives entire IP packet via RAW
2066 * socket, it must consider adding IP header size to
2067 * the "ip_len" field of "ip" structure.
2068 *
2069 * For more details, see <netinet/ip_input.c>.
2070 */
2071 ip_len = ip_len + (iph.ip_hl << 2);
2072#endif
2073
2074 ibuf = stream_new (ip_len);
2075 iov.iov_base = STREAM_DATA (ibuf);
2076 iov.iov_len = ip_len;
2077 ret = recvmsg (fd, &msgh, 0);
2078
paul863082d2004-08-19 04:43:43 +00002079 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002080
2081 *ifp = if_lookup_by_index (ifindex);
2082
2083 if (ret != ip_len)
2084 {
2085 zlog_warn ("ospf_recv_packet short read. "
2086 "ip_len %d bytes read %d", ip_len, ret);
2087 stream_free (ibuf);
2088 return NULL;
2089 }
2090
2091 return ibuf;
2092}
2093
2094struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002095ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002096 struct ip *iph, struct ospf_header *ospfh)
2097{
2098 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002099 struct ospf_vl_data *vl_data;
2100 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002101 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002102
2103 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2104 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002105 return NULL;
paul718e3742002-12-13 20:15:29 +00002106
pauld3f0d622004-05-05 15:27:15 +00002107 /* look for local OSPF interface matching the destination
2108 * to determine Area ID. We presume therefore the destination address
2109 * is unique, or at least (for "unnumbered" links), not used in other
2110 * areas
2111 */
2112 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2113 iph->ip_dst)) == NULL)
2114 return NULL;
paul718e3742002-12-13 20:15:29 +00002115
paul020709f2003-04-04 02:44:16 +00002116 for (node = listhead (ospf->vlinks); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002117 {
2118 if ((vl_data = getdata (node)) == NULL)
2119 continue;
2120
paul020709f2003-04-04 02:44:16 +00002121 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002122 if (!vl_area)
2123 continue;
2124
2125 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2126 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2127 {
2128 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002129 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002130 IF_NAME (vl_data->vl_oi));
2131 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2132 {
2133 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002134 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002135 return NULL;
2136 }
2137
2138 return vl_data->vl_oi;
2139 }
2140 }
2141
2142 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002143 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002144
pauld3f0d622004-05-05 15:27:15 +00002145 return NULL;
paul718e3742002-12-13 20:15:29 +00002146}
2147
2148int
2149ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2150{
2151 /* Check match the Area ID of the receiving interface. */
2152 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2153 return 1;
2154
2155 return 0;
2156}
2157
2158/* Unbound socket will accept any Raw IP packets if proto is matched.
2159 To prevent it, compare src IP address and i/f address with masking
2160 i/f network mask. */
2161int
2162ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2163{
2164 struct in_addr mask, me, him;
2165
2166 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2167 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2168 return 1;
2169
2170 masklen2ip (oi->address->prefixlen, &mask);
2171
2172 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2173 him.s_addr = ip_src.s_addr & mask.s_addr;
2174
2175 if (IPV4_ADDR_SAME (&me, &him))
2176 return 1;
2177
2178 return 0;
2179}
2180
2181int
2182ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2183 struct ospf_header *ospfh)
2184{
2185 int ret = 0;
2186 struct crypt_key *ck;
2187
2188 switch (ntohs (ospfh->auth_type))
2189 {
2190 case OSPF_AUTH_NULL:
2191 ret = 1;
2192 break;
2193 case OSPF_AUTH_SIMPLE:
2194 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2195 ret = 1;
2196 else
2197 ret = 0;
2198 break;
2199 case OSPF_AUTH_CRYPTOGRAPHIC:
2200 if ((ck = getdata (OSPF_IF_PARAM (oi,auth_crypt)->tail)) == NULL)
2201 {
2202 ret = 0;
2203 break;
2204 }
2205
2206 /* This is very basic, the digest processing is elsewhere */
2207 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2208 ospfh->u.crypt.key_id == ck->key_id &&
2209 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2210 ret = 1;
2211 else
2212 ret = 0;
2213 break;
2214 default:
2215 ret = 0;
2216 break;
2217 }
2218
2219 return ret;
2220}
2221
2222int
2223ospf_check_sum (struct ospf_header *ospfh)
2224{
2225 u_int32_t ret;
2226 u_int16_t sum;
2227 int in_cksum (void *ptr, int nbytes);
2228
2229 /* clear auth_data for checksum. */
2230 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2231
2232 /* keep checksum and clear. */
2233 sum = ospfh->checksum;
2234 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2235
2236 /* calculate checksum. */
2237 ret = in_cksum (ospfh, ntohs (ospfh->length));
2238
2239 if (ret != sum)
2240 {
2241 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2242 ret, sum);
2243 return 0;
2244 }
2245
2246 return 1;
2247}
2248
2249/* OSPF Header verification. */
2250int
2251ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2252 struct ip *iph, struct ospf_header *ospfh)
2253{
2254 /* check version. */
2255 if (ospfh->version != OSPF_VERSION)
2256 {
2257 zlog_warn ("interface %s: ospf_read version number mismatch.",
2258 IF_NAME (oi));
2259 return -1;
2260 }
2261
2262 /* Check Area ID. */
2263 if (!ospf_check_area_id (oi, ospfh))
2264 {
2265 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2266 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2267 return -1;
2268 }
2269
2270 /* Check network mask, Silently discarded. */
2271 if (! ospf_check_network_mask (oi, iph->ip_src))
2272 {
2273 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2274 IF_NAME (oi), inet_ntoa (iph->ip_src));
2275 return -1;
2276 }
2277
2278 /* Check authentication. */
2279 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2280 {
2281 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2282 IF_NAME (oi));
2283 return -1;
2284 }
2285
2286 if (! ospf_check_auth (oi, ibuf, ospfh))
2287 {
2288 zlog_warn ("interface %s: ospf_read authentication failed.",
2289 IF_NAME (oi));
2290 return -1;
2291 }
2292
2293 /* if check sum is invalid, packet is discarded. */
2294 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2295 {
2296 if (! ospf_check_sum (ospfh))
2297 {
2298 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2299 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2300 return -1;
2301 }
2302 }
2303 else
2304 {
2305 if (ospfh->checksum != 0)
2306 return -1;
2307 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2308 {
2309 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2310 IF_NAME (oi));
2311 return -1;
2312 }
2313 }
2314
2315 return 0;
2316}
2317
2318/* Starting point of packet process function. */
2319int
2320ospf_read (struct thread *thread)
2321{
2322 int ret;
2323 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002324 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002325 struct ospf_interface *oi;
2326 struct ip *iph;
2327 struct ospf_header *ospfh;
2328 u_int16_t length;
2329 struct interface *ifp;
2330
2331 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002332 ospf = THREAD_ARG (thread);
2333 ospf->t_read = NULL;
paul718e3742002-12-13 20:15:29 +00002334
2335 /* read OSPF packet. */
paul68980082003-03-25 05:07:42 +00002336 ibuf = ospf_recv_packet (ospf->fd, &ifp);
paul718e3742002-12-13 20:15:29 +00002337 if (ibuf == NULL)
2338 return -1;
2339
paul06f953f2004-10-22 17:00:38 +00002340 iph = (struct ip *) STREAM_DATA (ibuf);
2341 sockopt_iphdrincl_swab_systoh (iph);
2342
paulac191232004-10-22 12:05:17 +00002343 /* openbsd lacks IP_RECVIF */
2344#if !(defined(IP_PKTINFO) || defined(IP_RECVIF))
2345 if (ifp == NULL)
2346 ifp = if_lookup_address (iph->ip_src);
2347#endif /* !((defined(IP_PKTINFO) || defined(IP_RECVIF)) */
2348
pauld3f0d622004-05-05 15:27:15 +00002349 if (ifp == NULL)
2350 {
2351 stream_free (ibuf);
2352 return 0;
2353 }
paul6b333612004-10-11 10:11:25 +00002354
paul718e3742002-12-13 20:15:29 +00002355 /* prepare for next packet. */
paul68980082003-03-25 05:07:42 +00002356 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002357
2358 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002359 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002360 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002361
paul718e3742002-12-13 20:15:29 +00002362 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002363 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002364 {
pauld3241812003-09-29 12:42:39 +00002365 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2366 {
ajs2a42e282004-12-08 18:43:03 +00002367 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002368 inet_ntoa (iph->ip_src));
2369 }
paul718e3742002-12-13 20:15:29 +00002370 stream_free (ibuf);
2371 return 0;
2372 }
2373
2374 /* Adjust size to message length. */
2375 stream_forward (ibuf, iph->ip_hl * 4);
2376
2377 /* Get ospf packet header. */
2378 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2379
2380 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002381 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002382
2383 /* if no local ospf_interface,
2384 * or header area is backbone but ospf_interface is not
2385 * check for VLINK interface
2386 */
2387 if ( (oi == NULL) ||
2388 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2389 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2390 )
2391 {
2392 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2393 {
2394 zlog_warn ("Packet from [%s] received on link %s"
2395 " but no ospf_interface",
2396 inet_ntoa (iph->ip_src), ifp->name);
2397 stream_free (ibuf);
2398 return 0;
2399 }
2400 }
2401
2402 /* else it must be a local ospf interface, check it was received on
2403 * correct link
2404 */
2405 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002406 {
2407 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002408 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002409 stream_free (ibuf);
2410 return 0;
2411 }
paul718e3742002-12-13 20:15:29 +00002412
2413 /*
2414 * If the received packet is destined for AllDRouters, the packet
2415 * should be accepted only if the received ospf interface state is
2416 * either DR or Backup -- endo.
2417 */
2418 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2419 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2420 {
2421 zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
2422 inet_ntoa (iph->ip_src), IF_NAME (oi),
2423 LOOKUP (ospf_ism_state_msg, oi->state));
2424 stream_free (ibuf);
2425 return 0;
2426 }
2427
2428 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002429 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2430 {
paul718e3742002-12-13 20:15:29 +00002431 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002432 {
ajs2a42e282004-12-08 18:43:03 +00002433 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002434 ospf_packet_dump (ibuf);
2435 }
paul718e3742002-12-13 20:15:29 +00002436
ajs2a42e282004-12-08 18:43:03 +00002437 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002438 ospf_packet_type_str[ospfh->type],
2439 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002440 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2441 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002442
2443 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002444 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002445 }
paul718e3742002-12-13 20:15:29 +00002446
2447 /* Some header verification. */
2448 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2449 if (ret < 0)
2450 {
pauld3241812003-09-29 12:42:39 +00002451 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2452 {
ajs2a42e282004-12-08 18:43:03 +00002453 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002454 "dropping.",
2455 ospf_packet_type_str[ospfh->type],
2456 inet_ntoa (iph->ip_src));
2457 }
paul718e3742002-12-13 20:15:29 +00002458 stream_free (ibuf);
2459 return ret;
2460 }
2461
2462 stream_forward (ibuf, OSPF_HEADER_SIZE);
2463
2464 /* Adjust size to message length. */
2465 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2466
2467 /* Read rest of the packet and call each sort of packet routine. */
2468 switch (ospfh->type)
2469 {
2470 case OSPF_MSG_HELLO:
2471 ospf_hello (iph, ospfh, ibuf, oi, length);
2472 break;
2473 case OSPF_MSG_DB_DESC:
2474 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2475 break;
2476 case OSPF_MSG_LS_REQ:
2477 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2478 break;
2479 case OSPF_MSG_LS_UPD:
2480 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2481 break;
2482 case OSPF_MSG_LS_ACK:
2483 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2484 break;
2485 default:
2486 zlog (NULL, LOG_WARNING,
2487 "interface %s: OSPF packet header type %d is illegal",
2488 IF_NAME (oi), ospfh->type);
2489 break;
2490 }
2491
2492 stream_free (ibuf);
2493 return 0;
2494}
2495
2496/* Make OSPF header. */
2497void
2498ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2499{
2500 struct ospf_header *ospfh;
2501
2502 ospfh = (struct ospf_header *) STREAM_DATA (s);
2503
2504 ospfh->version = (u_char) OSPF_VERSION;
2505 ospfh->type = (u_char) type;
2506
paul68980082003-03-25 05:07:42 +00002507 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002508
2509 ospfh->checksum = 0;
2510 ospfh->area_id = oi->area->area_id;
2511 ospfh->auth_type = htons (ospf_auth_type (oi));
2512
2513 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2514
2515 ospf_output_forward (s, OSPF_HEADER_SIZE);
2516}
2517
2518/* Make Authentication Data. */
2519int
2520ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2521{
2522 struct crypt_key *ck;
2523
2524 switch (ospf_auth_type (oi))
2525 {
2526 case OSPF_AUTH_NULL:
2527 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2528 break;
2529 case OSPF_AUTH_SIMPLE:
2530 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2531 OSPF_AUTH_SIMPLE_SIZE);
2532 break;
2533 case OSPF_AUTH_CRYPTOGRAPHIC:
2534 /* If key is not set, then set 0. */
2535 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2536 {
2537 ospfh->u.crypt.zero = 0;
2538 ospfh->u.crypt.key_id = 0;
2539 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2540 }
2541 else
2542 {
2543 ck = getdata (OSPF_IF_PARAM (oi, auth_crypt)->tail);
2544 ospfh->u.crypt.zero = 0;
2545 ospfh->u.crypt.key_id = ck->key_id;
2546 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2547 }
2548 /* note: the seq is done in ospf_make_md5_digest() */
2549 break;
2550 default:
2551 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2552 break;
2553 }
2554
2555 return 0;
2556}
2557
2558/* Fill rest of OSPF header. */
2559void
2560ospf_fill_header (struct ospf_interface *oi,
2561 struct stream *s, u_int16_t length)
2562{
2563 struct ospf_header *ospfh;
2564
2565 ospfh = (struct ospf_header *) STREAM_DATA (s);
2566
2567 /* Fill length. */
2568 ospfh->length = htons (length);
2569
2570 /* Calculate checksum. */
2571 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2572 ospfh->checksum = in_cksum (ospfh, length);
2573 else
2574 ospfh->checksum = 0;
2575
2576 /* Add Authentication Data. */
2577 ospf_make_auth (oi, ospfh);
2578}
2579
2580int
2581ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2582{
2583 struct ospf_neighbor *nbr;
2584 struct route_node *rn;
2585 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2586 struct in_addr mask;
2587 unsigned long p;
2588 int flag = 0;
2589
2590 /* Set netmask of interface. */
2591 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2592 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2593 masklen2ip (oi->address->prefixlen, &mask);
2594 else
2595 memset ((char *) &mask, 0, sizeof (struct in_addr));
2596 stream_put_ipv4 (s, mask.s_addr);
2597
2598 /* Set Hello Interval. */
2599 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2600
2601 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002602 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002603 OPTIONS(oi), IF_NAME (oi));
2604
2605 /* Set Options. */
2606 stream_putc (s, OPTIONS (oi));
2607
2608 /* Set Router Priority. */
2609 stream_putc (s, PRIORITY (oi));
2610
2611 /* Set Router Dead Interval. */
2612 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2613
2614 /* Set Designated Router. */
2615 stream_put_ipv4 (s, DR (oi).s_addr);
2616
2617 p = s->putp;
2618
2619 /* Set Backup Designated Router. */
2620 stream_put_ipv4 (s, BDR (oi).s_addr);
2621
2622 /* Add neighbor seen. */
2623 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002624 if ((nbr = rn->info))
2625 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2626 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2627 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2628 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002629 {
2630 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002631 if (nbr->d_router.s_addr != 0
2632 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2633 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2634 flag = 1;
paul718e3742002-12-13 20:15:29 +00002635
2636 stream_put_ipv4 (s, nbr->router_id.s_addr);
2637 length += 4;
2638 }
2639
2640 /* Let neighbor generate BackupSeen. */
2641 if (flag == 1)
2642 {
2643 stream_set_putp (s, p);
2644 stream_put_ipv4 (s, 0);
2645 }
2646
2647 return length;
2648}
2649
2650int
2651ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2652 struct stream *s)
2653{
2654 struct ospf_lsa *lsa;
2655 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2656 u_char options;
2657 unsigned long pp;
2658 int i;
2659 struct ospf_lsdb *lsdb;
2660
2661 /* Set Interface MTU. */
2662 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2663 stream_putw (s, 0);
2664 else
2665 stream_putw (s, oi->ifp->mtu);
2666
2667 /* Set Options. */
2668 options = OPTIONS (oi);
2669#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002670 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002671 {
2672 if (IS_SET_DD_I (nbr->dd_flags)
2673 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2674 /*
2675 * Set O-bit in the outgoing DD packet for capablity negotiation,
2676 * if one of following case is applicable.
2677 *
2678 * 1) WaitTimer expiration event triggered the neighbor state to
2679 * change to Exstart, but no (valid) DD packet has received
2680 * from the neighbor yet.
2681 *
2682 * 2) At least one DD packet with O-bit on has received from the
2683 * neighbor.
2684 */
2685 SET_FLAG (options, OSPF_OPTION_O);
2686 }
2687#endif /* HAVE_OPAQUE_LSA */
2688 stream_putc (s, options);
2689
2690 /* Keep pointer to flags. */
2691 pp = stream_get_putp (s);
2692 stream_putc (s, nbr->dd_flags);
2693
2694 /* Set DD Sequence Number. */
2695 stream_putl (s, nbr->dd_seqnum);
2696
2697 if (ospf_db_summary_isempty (nbr))
2698 {
2699 if (nbr->state >= NSM_Exchange)
2700 {
2701 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2702 /* Set DD flags again */
2703 stream_set_putp (s, pp);
2704 stream_putc (s, nbr->dd_flags);
2705 }
2706 return length;
2707 }
2708
2709 /* Describe LSA Header from Database Summary List. */
2710 lsdb = &nbr->db_sum;
2711
2712 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2713 {
2714 struct route_table *table = lsdb->type[i].db;
2715 struct route_node *rn;
2716
2717 for (rn = route_top (table); rn; rn = route_next (rn))
2718 if ((lsa = rn->info) != NULL)
2719 {
2720#ifdef HAVE_OPAQUE_LSA
2721 if (IS_OPAQUE_LSA (lsa->data->type)
2722 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2723 {
2724 /* Suppress advertising opaque-informations. */
2725 /* Remove LSA from DB summary list. */
2726 ospf_lsdb_delete (lsdb, lsa);
2727 continue;
2728 }
2729#endif /* HAVE_OPAQUE_LSA */
2730
2731 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2732 {
2733 struct lsa_header *lsah;
2734 u_int16_t ls_age;
2735
2736 /* DD packet overflows interface MTU. */
2737 if (length + OSPF_LSA_HEADER_SIZE > OSPF_PACKET_MAX (oi))
2738 break;
2739
2740 /* Keep pointer to LS age. */
2741 lsah = (struct lsa_header *) (STREAM_DATA (s) +
2742 stream_get_putp (s));
2743
2744 /* Proceed stream pointer. */
2745 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2746 length += OSPF_LSA_HEADER_SIZE;
2747
2748 /* Set LS age. */
2749 ls_age = LS_AGE (lsa);
2750 lsah->ls_age = htons (ls_age);
2751
2752 }
2753
2754 /* Remove LSA from DB summary list. */
2755 ospf_lsdb_delete (lsdb, lsa);
2756 }
2757 }
2758
2759 return length;
2760}
2761
2762int
2763ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2764 unsigned long delta, struct ospf_neighbor *nbr,
2765 struct ospf_lsa *lsa)
2766{
2767 struct ospf_interface *oi;
2768
2769 oi = nbr->oi;
2770
2771 /* LS Request packet overflows interface MTU. */
2772 if (*length + delta > OSPF_PACKET_MAX(oi))
2773 return 0;
2774
2775 stream_putl (s, lsa->data->type);
2776 stream_put_ipv4 (s, lsa->data->id.s_addr);
2777 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2778
2779 ospf_lsa_unlock (nbr->ls_req_last);
2780 nbr->ls_req_last = ospf_lsa_lock (lsa);
2781
2782 *length += 12;
2783 return 1;
2784}
2785
2786int
2787ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2788{
2789 struct ospf_lsa *lsa;
2790 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
2791 unsigned long delta = stream_get_putp(s)+12;
2792 struct route_table *table;
2793 struct route_node *rn;
2794 int i;
2795 struct ospf_lsdb *lsdb;
2796
2797 lsdb = &nbr->ls_req;
2798
2799 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2800 {
2801 table = lsdb->type[i].db;
2802 for (rn = route_top (table); rn; rn = route_next (rn))
2803 if ((lsa = (rn->info)) != NULL)
2804 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2805 {
2806 route_unlock_node (rn);
2807 break;
2808 }
2809 }
2810 return length;
2811}
2812
2813int
2814ls_age_increment (struct ospf_lsa *lsa, int delay)
2815{
2816 int age;
2817
2818 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2819
2820 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2821}
2822
2823int
hasso52dc7ee2004-09-23 19:18:23 +00002824ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002825{
2826 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002827 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002828 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
2829 unsigned long delta = stream_get_putp (s);
2830 unsigned long pp;
2831 int count = 0;
2832
2833 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002834 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002835
paul718e3742002-12-13 20:15:29 +00002836 pp = stream_get_putp (s);
paul68b73392004-09-12 14:21:37 +00002837 ospf_output_forward (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002838
2839 while ((node = listhead (update)) != NULL)
2840 {
2841 struct lsa_header *lsah;
2842 u_int16_t ls_age;
2843
2844 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002845 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002846
2847 lsa = getdata (node);
2848 assert (lsa);
2849 assert (lsa->data);
2850
paul68b73392004-09-12 14:21:37 +00002851 /* Will it fit? */
2852 if (length + delta + ntohs (lsa->data->length) > stream_get_size (s))
paul59ea14c2004-07-14 20:50:36 +00002853 break;
2854
paul718e3742002-12-13 20:15:29 +00002855 /* Keep pointer to LS age. */
2856 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_putp (s));
2857
2858 /* Put LSA to Link State Request. */
2859 stream_put (s, lsa->data, ntohs (lsa->data->length));
2860
2861 /* Set LS age. */
2862 /* each hop must increment an lsa_age by transmit_delay
2863 of OSPF interface */
2864 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2865 lsah->ls_age = htons (ls_age);
2866
2867 length += ntohs (lsa->data->length);
2868 count++;
2869
2870 list_delete_node (update, node);
2871 ospf_lsa_unlock (lsa);
2872 }
2873
2874 /* Now set #LSAs. */
2875 stream_set_putp (s, pp);
2876 stream_putl (s, count);
2877
2878 stream_set_putp (s, s->endp);
2879
2880 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002881 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002882 return length;
2883}
2884
2885int
hasso52dc7ee2004-09-23 19:18:23 +00002886ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002887{
hasso52dc7ee2004-09-23 19:18:23 +00002888 struct list *rm_list;
2889 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002890 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
2891 unsigned long delta = stream_get_putp(s) + 24;
2892 struct ospf_lsa *lsa;
2893
2894 rm_list = list_new ();
2895
2896 for (node = listhead (ack); node; nextnode (node))
2897 {
2898 lsa = getdata (node);
2899 assert (lsa);
2900
2901 if (length + delta > OSPF_PACKET_MAX (oi))
2902 break;
2903
2904 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2905 length += OSPF_LSA_HEADER_SIZE;
2906
2907 listnode_add (rm_list, lsa);
2908 }
2909
2910 /* Remove LSA from LS-Ack list. */
2911 for (node = listhead (rm_list); node; nextnode (node))
2912 {
2913 lsa = (struct ospf_lsa *) getdata (node);
2914
2915 listnode_delete (ack, lsa);
2916 ospf_lsa_unlock (lsa);
2917 }
2918
2919 list_delete (rm_list);
2920
2921 return length;
2922}
2923
2924void
2925ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2926{
2927 struct ospf_packet *op;
2928 u_int16_t length = OSPF_HEADER_SIZE;
2929
2930 op = ospf_packet_new (oi->ifp->mtu);
2931
2932 /* Prepare OSPF common header. */
2933 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2934
2935 /* Prepare OSPF Hello body. */
2936 length += ospf_make_hello (oi, op->s);
2937
2938 /* Fill OSPF header. */
2939 ospf_fill_header (oi, op->s, length);
2940
2941 /* Set packet length. */
2942 op->length = length;
2943
2944 op->dst.s_addr = addr->s_addr;
2945
2946 /* Add packet to the interface output queue. */
2947 ospf_packet_add (oi, op);
2948
2949 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002950 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002951}
2952
2953void
2954ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2955{
2956 struct ospf_interface *oi;
2957
2958 oi = nbr_nbma->oi;
2959 assert(oi);
2960
2961 /* If this is passive interface, do not send OSPF Hello. */
2962 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2963 return;
2964
2965 if (oi->type != OSPF_IFTYPE_NBMA)
2966 return;
2967
2968 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2969 return;
2970
2971 if (PRIORITY(oi) == 0)
2972 return;
2973
2974 if (nbr_nbma->priority == 0
2975 && oi->state != ISM_DR && oi->state != ISM_Backup)
2976 return;
2977
2978 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2979}
2980
2981int
2982ospf_poll_timer (struct thread *thread)
2983{
2984 struct ospf_nbr_nbma *nbr_nbma;
2985
2986 nbr_nbma = THREAD_ARG (thread);
2987 nbr_nbma->t_poll = NULL;
2988
2989 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002990 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002991 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2992
2993 ospf_poll_send (nbr_nbma);
2994
2995 if (nbr_nbma->v_poll > 0)
2996 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2997 nbr_nbma->v_poll);
2998
2999 return 0;
3000}
3001
3002
3003int
3004ospf_hello_reply_timer (struct thread *thread)
3005{
3006 struct ospf_neighbor *nbr;
3007
3008 nbr = THREAD_ARG (thread);
3009 nbr->t_hello_reply = NULL;
3010
3011 assert (nbr->oi);
3012
3013 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00003014 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00003015 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
3016
3017 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
3018
3019 return 0;
3020}
3021
3022/* Send OSPF Hello. */
3023void
3024ospf_hello_send (struct ospf_interface *oi)
3025{
3026 struct ospf_packet *op;
3027 u_int16_t length = OSPF_HEADER_SIZE;
3028
3029 /* If this is passive interface, do not send OSPF Hello. */
3030 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3031 return;
3032
3033 op = ospf_packet_new (oi->ifp->mtu);
3034
3035 /* Prepare OSPF common header. */
3036 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3037
3038 /* Prepare OSPF Hello body. */
3039 length += ospf_make_hello (oi, op->s);
3040
3041 /* Fill OSPF header. */
3042 ospf_fill_header (oi, op->s, length);
3043
3044 /* Set packet length. */
3045 op->length = length;
3046
3047 if (oi->type == OSPF_IFTYPE_NBMA)
3048 {
3049 struct ospf_neighbor *nbr;
3050 struct route_node *rn;
3051
3052 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3053 if ((nbr = rn->info))
3054 if (nbr != oi->nbr_self)
3055 if (nbr->state != NSM_Down)
3056 {
3057 /* RFC 2328 Section 9.5.1
3058 If the router is not eligible to become Designated Router,
3059 it must periodically send Hello Packets to both the
3060 Designated Router and the Backup Designated Router (if they
3061 exist). */
3062 if (PRIORITY(oi) == 0 &&
3063 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3064 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3065 continue;
3066
3067 /* If the router is eligible to become Designated Router, it
3068 must periodically send Hello Packets to all neighbors that
3069 are also eligible. In addition, if the router is itself the
3070 Designated Router or Backup Designated Router, it must also
3071 send periodic Hello Packets to all other neighbors. */
3072
3073 if (nbr->priority == 0 && oi->state == ISM_DROther)
3074 continue;
3075 /* if oi->state == Waiting, send hello to all neighbors */
3076 {
3077 struct ospf_packet *op_dup;
3078
3079 op_dup = ospf_packet_dup(op);
3080 op_dup->dst = nbr->address.u.prefix4;
3081
3082 /* Add packet to the interface output queue. */
3083 ospf_packet_add (oi, op_dup);
3084
paul020709f2003-04-04 02:44:16 +00003085 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003086 }
3087
3088 }
3089 ospf_packet_free (op);
3090 }
3091 else
3092 {
3093 /* Decide destination address. */
3094 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3095 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3096 else
3097 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3098
3099 /* Add packet to the interface output queue. */
3100 ospf_packet_add (oi, op);
3101
3102 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003103 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003104 }
3105}
3106
3107/* Send OSPF Database Description. */
3108void
3109ospf_db_desc_send (struct ospf_neighbor *nbr)
3110{
3111 struct ospf_interface *oi;
3112 struct ospf_packet *op;
3113 u_int16_t length = OSPF_HEADER_SIZE;
3114
3115 oi = nbr->oi;
3116 op = ospf_packet_new (oi->ifp->mtu);
3117
3118 /* Prepare OSPF common header. */
3119 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3120
3121 /* Prepare OSPF Database Description body. */
3122 length += ospf_make_db_desc (oi, nbr, op->s);
3123
3124 /* Fill OSPF header. */
3125 ospf_fill_header (oi, op->s, length);
3126
3127 /* Set packet length. */
3128 op->length = length;
3129
3130 /* Decide destination address. */
3131 op->dst = nbr->address.u.prefix4;
3132
3133 /* Add packet to the interface output queue. */
3134 ospf_packet_add (oi, op);
3135
3136 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003137 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003138
3139 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3140 if (nbr->last_send)
3141 ospf_packet_free (nbr->last_send);
3142 nbr->last_send = ospf_packet_dup (op);
3143 gettimeofday (&nbr->last_send_ts, NULL);
3144}
3145
3146/* Re-send Database Description. */
3147void
3148ospf_db_desc_resend (struct ospf_neighbor *nbr)
3149{
3150 struct ospf_interface *oi;
3151
3152 oi = nbr->oi;
3153
3154 /* Add packet to the interface output queue. */
3155 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3156
3157 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003158 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003159}
3160
3161/* Send Link State Request. */
3162void
3163ospf_ls_req_send (struct ospf_neighbor *nbr)
3164{
3165 struct ospf_interface *oi;
3166 struct ospf_packet *op;
3167 u_int16_t length = OSPF_HEADER_SIZE;
3168
3169 oi = nbr->oi;
3170 op = ospf_packet_new (oi->ifp->mtu);
3171
3172 /* Prepare OSPF common header. */
3173 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3174
3175 /* Prepare OSPF Link State Request body. */
3176 length += ospf_make_ls_req (nbr, op->s);
3177 if (length == OSPF_HEADER_SIZE)
3178 {
3179 ospf_packet_free (op);
3180 return;
3181 }
3182
3183 /* Fill OSPF header. */
3184 ospf_fill_header (oi, op->s, length);
3185
3186 /* Set packet length. */
3187 op->length = length;
3188
3189 /* Decide destination address. */
3190 op->dst = nbr->address.u.prefix4;
3191
3192 /* Add packet to the interface output queue. */
3193 ospf_packet_add (oi, op);
3194
3195 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003196 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003197
3198 /* Add Link State Request Retransmission Timer. */
3199 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3200}
3201
3202/* Send Link State Update with an LSA. */
3203void
3204ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3205 int flag)
3206{
hasso52dc7ee2004-09-23 19:18:23 +00003207 struct list *update;
paul718e3742002-12-13 20:15:29 +00003208
3209 update = list_new ();
3210
3211 listnode_add (update, lsa);
3212 ospf_ls_upd_send (nbr, update, flag);
3213
3214 list_delete (update);
3215}
3216
paul68b73392004-09-12 14:21:37 +00003217/* Determine size for packet. Must be at least big enough to accomodate next
3218 * LSA on list, which may be bigger than MTU size.
3219 *
3220 * Return pointer to new ospf_packet
3221 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3222 * on packet sizes (in which case offending LSA is deleted from update list)
3223 */
3224static struct ospf_packet *
3225ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3226{
3227 struct ospf_lsa *lsa;
3228 struct listnode *ln;
3229 size_t size;
3230 static char warned = 0;
3231
3232 ln = listhead (update);
3233 lsa = getdata (ln);
3234 assert (lsa);
3235 assert (lsa->data);
3236
3237 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3238 > ospf_packet_max (oi))
3239 {
3240 if (!warned)
3241 {
3242 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3243 "will need to fragment. Not optimal. Try divide up"
3244 " your network with areas. Use 'debug ospf packet send'"
3245 " to see details, or look at 'show ip ospf database ..'");
3246 warned = 1;
3247 }
3248
3249 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003250 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003251 " %d bytes originated by %s, will be fragmented!",
3252 inet_ntoa (lsa->data->id),
3253 ntohs (lsa->data->length),
3254 inet_ntoa (lsa->data->adv_router));
3255
3256 /*
3257 * Allocate just enough to fit this LSA only, to avoid including other
3258 * LSAs in fragmented LSA Updates.
3259 */
3260 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3261 + OSPF_LS_UPD_MIN_SIZE;
3262 }
3263 else
3264 size = oi->ifp->mtu;
3265
3266 if (size > OSPF_MAX_PACKET_SIZE)
3267 {
3268 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003269 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003270 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003271 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003272 (long int) size);
paul68b73392004-09-12 14:21:37 +00003273 list_delete_node (update, ln);
3274 return NULL;
3275 }
3276
3277 return ospf_packet_new (size);
3278}
3279
paul718e3742002-12-13 20:15:29 +00003280static void
hasso52dc7ee2004-09-23 19:18:23 +00003281ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003282 struct in_addr addr)
3283{
3284 struct ospf_packet *op;
3285 u_int16_t length = OSPF_HEADER_SIZE;
3286
3287 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003288 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003289
3290 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003291
3292 /* Prepare OSPF common header. */
3293 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3294
paul59ea14c2004-07-14 20:50:36 +00003295 /* Prepare OSPF Link State Update body.
3296 * Includes Type-7 translation.
3297 */
paul718e3742002-12-13 20:15:29 +00003298 length += ospf_make_ls_upd (oi, update, op->s);
3299
3300 /* Fill OSPF header. */
3301 ospf_fill_header (oi, op->s, length);
3302
3303 /* Set packet length. */
3304 op->length = length;
3305
3306 /* Decide destination address. */
3307 op->dst.s_addr = addr.s_addr;
3308
3309 /* Add packet to the interface output queue. */
3310 ospf_packet_add (oi, op);
3311
3312 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003313 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003314}
3315
3316static int
3317ospf_ls_upd_send_queue_event (struct thread *thread)
3318{
3319 struct ospf_interface *oi = THREAD_ARG(thread);
3320 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003321 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003322 struct list *update;
paul68b73392004-09-12 14:21:37 +00003323 char again = 0;
paul718e3742002-12-13 20:15:29 +00003324
3325 oi->t_ls_upd_event = NULL;
3326
3327 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003328 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003329
paul736d3442003-07-24 23:22:57 +00003330 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003331 {
paul736d3442003-07-24 23:22:57 +00003332 rnext = route_next (rn);
3333
paul718e3742002-12-13 20:15:29 +00003334 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003335 continue;
paul68b73392004-09-12 14:21:37 +00003336
3337 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003338
paul48fe13b2004-07-27 17:40:44 +00003339 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003340
paul68b73392004-09-12 14:21:37 +00003341 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003342 if (listcount(update) == 0)
3343 {
3344 list_delete (rn->info);
3345 rn->info = NULL;
3346 route_unlock_node (rn);
3347 }
3348 else
paul68b73392004-09-12 14:21:37 +00003349 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003350 }
3351
3352 if (again != 0)
3353 {
3354 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003355 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003356 " %d nodes to try again, raising new event", again);
3357 oi->t_ls_upd_event =
3358 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003359 }
3360
3361 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003362 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003363
paul718e3742002-12-13 20:15:29 +00003364 return 0;
3365}
3366
3367void
hasso52dc7ee2004-09-23 19:18:23 +00003368ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003369{
3370 struct ospf_interface *oi;
3371 struct prefix_ipv4 p;
3372 struct route_node *rn;
hasso52dc7ee2004-09-23 19:18:23 +00003373 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003374
3375 oi = nbr->oi;
3376
3377 p.family = AF_INET;
3378 p.prefixlen = IPV4_MAX_BITLEN;
3379
3380 /* Decide destination address. */
3381 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3382 p.prefix = oi->vl_data->peer_addr;
3383 else if (flag == OSPF_SEND_PACKET_DIRECT)
3384 p.prefix = nbr->address.u.prefix4;
3385 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3386 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3387 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3388 && (flag == OSPF_SEND_PACKET_INDIRECT))
3389 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003390 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3391 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003392 else
3393 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3394
3395 if (oi->type == OSPF_IFTYPE_NBMA)
3396 {
3397 if (flag == OSPF_SEND_PACKET_INDIRECT)
3398 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3399 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3400 zlog_warn ("* LS-Update is sent to myself.");
3401 }
3402
3403 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3404
3405 if (rn->info == NULL)
3406 rn->info = list_new ();
3407
3408 for (n = listhead (update); n; nextnode (n))
3409 listnode_add (rn->info, ospf_lsa_lock (getdata (n)));
3410
3411 if (oi->t_ls_upd_event == NULL)
3412 oi->t_ls_upd_event =
3413 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3414}
3415
3416static void
hasso52dc7ee2004-09-23 19:18:23 +00003417ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3418 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003419{
3420 struct ospf_packet *op;
3421 u_int16_t length = OSPF_HEADER_SIZE;
3422
3423 op = ospf_packet_new (oi->ifp->mtu);
3424
3425 /* Prepare OSPF common header. */
3426 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3427
3428 /* Prepare OSPF Link State Acknowledgment body. */
3429 length += ospf_make_ls_ack (oi, ack, op->s);
3430
3431 /* Fill OSPF header. */
3432 ospf_fill_header (oi, op->s, length);
3433
3434 /* Set packet length. */
3435 op->length = length;
3436
3437 /* Set destination IP address. */
3438 op->dst = dst;
3439
3440 /* Add packet to the interface output queue. */
3441 ospf_packet_add (oi, op);
3442
3443 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003444 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003445}
3446
3447static int
3448ospf_ls_ack_send_event (struct thread *thread)
3449{
3450 struct ospf_interface *oi = THREAD_ARG (thread);
3451
3452 oi->t_ls_ack_direct = NULL;
3453
3454 while (listcount (oi->ls_ack_direct.ls_ack))
3455 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3456 oi->ls_ack_direct.dst);
3457
3458 return 0;
3459}
3460
3461void
3462ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3463{
3464 struct ospf_interface *oi = nbr->oi;
3465
3466 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3467 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3468
3469 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3470
3471 if (oi->t_ls_ack_direct == NULL)
3472 oi->t_ls_ack_direct =
3473 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3474}
3475
3476/* Send Link State Acknowledgment delayed. */
3477void
3478ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3479{
3480 struct in_addr dst;
3481
3482 /* Decide destination address. */
3483 /* RFC2328 Section 13.5 On non-broadcast
3484 networks, delayed Link State Acknowledgment packets must be
3485 unicast separately over each adjacency (i.e., neighbor whose
3486 state is >= Exchange). */
3487 if (oi->type == OSPF_IFTYPE_NBMA)
3488 {
3489 struct ospf_neighbor *nbr;
3490 struct route_node *rn;
3491
3492 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3493 if ((nbr = rn->info) != NULL)
3494 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3495 while (listcount (oi->ls_ack))
3496 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3497 return;
3498 }
3499 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3500 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3501 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3502 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3503 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3504 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003505 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3506 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003507 else
3508 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3509
3510 while (listcount (oi->ls_ack))
3511 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3512}