blob: 1906cc1cc94585cc88e1c1a6e9141699a437f89f [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
paul718e3742002-12-13 20:15:29 +000051/* Packet Type String. */
hassoeb1ce602004-10-08 08:17:22 +000052const char *ospf_packet_type_str[] =
paul718e3742002-12-13 20:15:29 +000053{
54 "unknown",
55 "Hello",
56 "Database Description",
57 "Link State Request",
58 "Link State Update",
59 "Link State Acknowledgment",
60};
61
62extern int in_cksum (void *ptr, int nbytes);
63
64/* OSPF authentication checking function */
paul4dadc292005-05-06 21:37:42 +000065static int
paul718e3742002-12-13 20:15:29 +000066ospf_auth_type (struct ospf_interface *oi)
67{
68 int auth_type;
69
70 if (OSPF_IF_PARAM (oi, auth_type) == OSPF_AUTH_NOTSET)
71 auth_type = oi->area->auth_type;
72 else
73 auth_type = OSPF_IF_PARAM (oi, auth_type);
74
75 /* Handle case where MD5 key list is not configured aka Cisco */
76 if (auth_type == OSPF_AUTH_CRYPTOGRAPHIC &&
77 list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
78 return OSPF_AUTH_NULL;
79
80 return auth_type;
81
82}
83
paul718e3742002-12-13 20:15:29 +000084struct ospf_packet *
85ospf_packet_new (size_t size)
86{
87 struct ospf_packet *new;
88
89 new = XCALLOC (MTYPE_OSPF_PACKET, sizeof (struct ospf_packet));
90 new->s = stream_new (size);
91
92 return new;
93}
94
95void
96ospf_packet_free (struct ospf_packet *op)
97{
98 if (op->s)
99 stream_free (op->s);
100
101 XFREE (MTYPE_OSPF_PACKET, op);
102
103 op = NULL;
104}
105
106struct ospf_fifo *
107ospf_fifo_new ()
108{
109 struct ospf_fifo *new;
110
111 new = XCALLOC (MTYPE_OSPF_FIFO, sizeof (struct ospf_fifo));
112 return new;
113}
114
115/* Add new packet to fifo. */
116void
117ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)
118{
119 if (fifo->tail)
120 fifo->tail->next = op;
121 else
122 fifo->head = op;
123
124 fifo->tail = op;
125
126 fifo->count++;
127}
128
129/* Delete first packet from fifo. */
130struct ospf_packet *
131ospf_fifo_pop (struct ospf_fifo *fifo)
132{
133 struct ospf_packet *op;
134
135 op = fifo->head;
136
137 if (op)
138 {
139 fifo->head = op->next;
140
141 if (fifo->head == NULL)
142 fifo->tail = NULL;
143
144 fifo->count--;
145 }
146
147 return op;
148}
149
150/* Return first fifo entry. */
151struct ospf_packet *
152ospf_fifo_head (struct ospf_fifo *fifo)
153{
154 return fifo->head;
155}
156
157/* Flush ospf packet fifo. */
158void
159ospf_fifo_flush (struct ospf_fifo *fifo)
160{
161 struct ospf_packet *op;
162 struct ospf_packet *next;
163
164 for (op = fifo->head; op; op = next)
165 {
166 next = op->next;
167 ospf_packet_free (op);
168 }
169 fifo->head = fifo->tail = NULL;
170 fifo->count = 0;
171}
172
173/* Free ospf packet fifo. */
174void
175ospf_fifo_free (struct ospf_fifo *fifo)
176{
177 ospf_fifo_flush (fifo);
178
179 XFREE (MTYPE_OSPF_FIFO, fifo);
180}
181
182void
183ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)
184{
ajsc3eab872005-01-29 15:52:07 +0000185 if (!oi->obuf)
186 {
187 zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, "
188 "destination %s) called with NULL obuf, ignoring "
189 "(please report this bug)!\n",
190 IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state),
191 ospf_packet_type_str[stream_getc_from(op->s, 1)],
192 inet_ntoa (op->dst));
193 return;
194 }
195
paul718e3742002-12-13 20:15:29 +0000196 /* Add packet to end of queue. */
197 ospf_fifo_push (oi->obuf, op);
198
199 /* Debug of packet fifo*/
200 /* ospf_fifo_debug (oi->obuf); */
201}
202
203void
204ospf_packet_delete (struct ospf_interface *oi)
205{
206 struct ospf_packet *op;
207
208 op = ospf_fifo_pop (oi->obuf);
209
210 if (op)
211 ospf_packet_free (op);
212}
213
paul718e3742002-12-13 20:15:29 +0000214struct ospf_packet *
215ospf_packet_dup (struct ospf_packet *op)
216{
217 struct ospf_packet *new;
218
paul37163d62003-02-03 18:40:56 +0000219 if (stream_get_endp(op->s) != op->length)
220 zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch",
paul30961a12002-12-13 20:56:48 +0000221 STREAM_SIZE(op->s), op->length);
paul30961a12002-12-13 20:56:48 +0000222
223 /* Reserve space for MD5 authentication that may be added later. */
224 new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE);
paulfa81b712005-02-19 01:19:20 +0000225 stream_copy (new->s, op->s);
paul718e3742002-12-13 20:15:29 +0000226
227 new->dst = op->dst;
228 new->length = op->length;
229
230 return new;
231}
232
gdt86f1fd92005-01-10 14:20:43 +0000233/* XXX inline */
paul4dadc292005-05-06 21:37:42 +0000234static inline unsigned int
gdt86f1fd92005-01-10 14:20:43 +0000235ospf_packet_authspace (struct ospf_interface *oi)
236{
237 int auth = 0;
238
239 if ( ospf_auth_type (oi) == OSPF_AUTH_CRYPTOGRAPHIC)
240 auth = OSPF_AUTH_MD5_SIZE;
241
242 return auth;
243}
244
paul4dadc292005-05-06 21:37:42 +0000245static unsigned int
paul718e3742002-12-13 20:15:29 +0000246ospf_packet_max (struct ospf_interface *oi)
247{
248 int max;
249
gdt86f1fd92005-01-10 14:20:43 +0000250 max = oi->ifp->mtu - ospf_packet_authspace(oi);
251
paul68b73392004-09-12 14:21:37 +0000252 max -= (OSPF_HEADER_SIZE + sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000253
254 return max;
255}
256
257
paul4dadc292005-05-06 21:37:42 +0000258static int
paul718e3742002-12-13 20:15:29 +0000259ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s,
260 u_int16_t length)
261{
paul6c835672004-10-11 11:00:30 +0000262 unsigned char *ibuf;
paul718e3742002-12-13 20:15:29 +0000263 struct md5_ctx ctx;
264 unsigned char digest[OSPF_AUTH_MD5_SIZE];
265 unsigned char *pdigest;
266 struct crypt_key *ck;
267 struct ospf_header *ospfh;
268 struct ospf_neighbor *nbr;
269
270
271 ibuf = STREAM_PNT (s);
272 ospfh = (struct ospf_header *) ibuf;
273
274 /* Get pointer to the end of the packet. */
275 pdigest = ibuf + length;
276
277 /* Get secret key. */
278 ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt),
279 ospfh->u.crypt.key_id);
280 if (ck == NULL)
281 {
282 zlog_warn ("interface %s: ospf_check_md5 no key %d",
283 IF_NAME (oi), ospfh->u.crypt.key_id);
284 return 0;
285 }
286
287 /* check crypto seqnum. */
288 nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &ospfh->router_id);
289
290 if (nbr && ntohl(nbr->crypt_seqnum) > ntohl(ospfh->u.crypt.crypt_seqnum))
291 {
292 zlog_warn ("interface %s: ospf_check_md5 bad sequence %d (expect %d)",
293 IF_NAME (oi),
294 ntohl(ospfh->u.crypt.crypt_seqnum),
295 ntohl(nbr->crypt_seqnum));
296 return 0;
297 }
298
299 /* Generate a digest for the ospf packet - their digest + our digest. */
300 md5_init_ctx (&ctx);
301 md5_process_bytes (ibuf, length, &ctx);
302 md5_process_bytes (ck->auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
303 md5_finish_ctx (&ctx, digest);
304
305 /* compare the two */
306 if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE))
307 {
308 zlog_warn ("interface %s: ospf_check_md5 checksum mismatch",
309 IF_NAME (oi));
310 return 0;
311 }
312
313 /* save neighbor's crypt_seqnum */
314 if (nbr)
315 nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
316 return 1;
317}
318
319/* This function is called from ospf_write(), it will detect the
320 authentication scheme and if it is MD5, it will change the sequence
321 and update the MD5 digest. */
paul4dadc292005-05-06 21:37:42 +0000322static int
paul718e3742002-12-13 20:15:29 +0000323ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op)
324{
325 struct ospf_header *ospfh;
326 unsigned char digest[OSPF_AUTH_MD5_SIZE];
327 struct md5_ctx ctx;
328 void *ibuf;
paul9483e152002-12-13 20:55:25 +0000329 u_int32_t t;
paul718e3742002-12-13 20:15:29 +0000330 struct crypt_key *ck;
paul4dadc292005-05-06 21:37:42 +0000331 const char *auth_key;
paul718e3742002-12-13 20:15:29 +0000332
333 ibuf = STREAM_DATA (op->s);
334 ospfh = (struct ospf_header *) ibuf;
335
336 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
337 return 0;
338
339 /* We do this here so when we dup a packet, we don't have to
340 waste CPU rewriting other headers. */
paul9483e152002-12-13 20:55:25 +0000341 t = (time(NULL) & 0xFFFFFFFF);
342 oi->crypt_seqnum = ( t > oi->crypt_seqnum ? t : oi->crypt_seqnum++);
343 ospfh->u.crypt.crypt_seqnum = htonl (oi->crypt_seqnum);
paul718e3742002-12-13 20:15:29 +0000344
345 /* Get MD5 Authentication key from auth_key list. */
346 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
paul4dadc292005-05-06 21:37:42 +0000347 auth_key = "";
paul718e3742002-12-13 20:15:29 +0000348 else
349 {
paul1eb8ef22005-04-07 07:30:20 +0000350 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul4dadc292005-05-06 21:37:42 +0000351 auth_key = ck->auth_key;
paul718e3742002-12-13 20:15:29 +0000352 }
353
354 /* Generate a digest for the entire packet + our secret key. */
355 md5_init_ctx (&ctx);
356 md5_process_bytes (ibuf, ntohs (ospfh->length), &ctx);
357 md5_process_bytes (auth_key, OSPF_AUTH_MD5_SIZE, &ctx);
358 md5_finish_ctx (&ctx, digest);
359
360 /* Append md5 digest to the end of the stream. */
paul718e3742002-12-13 20:15:29 +0000361 stream_put (op->s, digest, OSPF_AUTH_MD5_SIZE);
paul718e3742002-12-13 20:15:29 +0000362
363 /* We do *NOT* increment the OSPF header length. */
paul30961a12002-12-13 20:56:48 +0000364 op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE;
365
paul37163d62003-02-03 18:40:56 +0000366 if (stream_get_endp(op->s) != op->length)
367 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 +0000368
369 return OSPF_AUTH_MD5_SIZE;
370}
371
372
paul4dadc292005-05-06 21:37:42 +0000373static int
paul718e3742002-12-13 20:15:29 +0000374ospf_ls_req_timer (struct thread *thread)
375{
376 struct ospf_neighbor *nbr;
377
378 nbr = THREAD_ARG (thread);
379 nbr->t_ls_req = NULL;
380
381 /* Send Link State Request. */
382 if (ospf_ls_request_count (nbr))
383 ospf_ls_req_send (nbr);
384
385 /* Set Link State Request retransmission timer. */
386 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
387
388 return 0;
389}
390
391void
392ospf_ls_req_event (struct ospf_neighbor *nbr)
393{
394 if (nbr->t_ls_req)
395 {
396 thread_cancel (nbr->t_ls_req);
397 nbr->t_ls_req = NULL;
398 }
399 nbr->t_ls_req = thread_add_event (master, ospf_ls_req_timer, nbr, 0);
400}
401
402/* Cyclic timer function. Fist registered in ospf_nbr_new () in
403 ospf_neighbor.c */
404int
405ospf_ls_upd_timer (struct thread *thread)
406{
407 struct ospf_neighbor *nbr;
408
409 nbr = THREAD_ARG (thread);
410 nbr->t_ls_upd = NULL;
411
412 /* Send Link State Update. */
413 if (ospf_ls_retransmit_count (nbr) > 0)
414 {
hasso52dc7ee2004-09-23 19:18:23 +0000415 struct list *update;
paul718e3742002-12-13 20:15:29 +0000416 struct ospf_lsdb *lsdb;
417 int i;
418 struct timeval now;
419 int retransmit_interval;
420
421 gettimeofday (&now, NULL);
422 retransmit_interval = OSPF_IF_PARAM (nbr->oi, retransmit_interval);
423
424 lsdb = &nbr->ls_rxmt;
425 update = list_new ();
426
427 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
428 {
429 struct route_table *table = lsdb->type[i].db;
430 struct route_node *rn;
431
432 for (rn = route_top (table); rn; rn = route_next (rn))
433 {
434 struct ospf_lsa *lsa;
435
436 if ((lsa = rn->info) != NULL)
437 /* Don't retransmit an LSA if we received it within
438 the last RxmtInterval seconds - this is to allow the
439 neighbour a chance to acknowledge the LSA as it may
440 have ben just received before the retransmit timer
441 fired. This is a small tweak to what is in the RFC,
442 but it will cut out out a lot of retransmit traffic
443 - MAG */
444 if (tv_cmp (tv_sub (now, lsa->tv_recv),
445 int2tv (retransmit_interval)) >= 0)
446 listnode_add (update, rn->info);
447 }
448 }
449
450 if (listcount (update) > 0)
451 ospf_ls_upd_send (nbr, update, OSPF_SEND_PACKET_DIRECT);
452 list_delete (update);
453 }
454
455 /* Set LS Update retransmission timer. */
456 OSPF_NSM_TIMER_ON (nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd);
457
458 return 0;
459}
460
461int
462ospf_ls_ack_timer (struct thread *thread)
463{
464 struct ospf_interface *oi;
465
466 oi = THREAD_ARG (thread);
467 oi->t_ls_ack = NULL;
468
469 /* Send Link State Acknowledgment. */
470 if (listcount (oi->ls_ack) > 0)
471 ospf_ls_ack_send_delayed (oi);
472
473 /* Set LS Ack timer. */
474 OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
475
476 return 0;
477}
478
paul0bfeca32004-09-24 08:07:54 +0000479#ifdef WANT_OSPF_WRITE_FRAGMENT
ajs5dcbdf82005-03-29 16:13:49 +0000480static void
paul6a99f832004-09-27 12:56:30 +0000481ospf_write_frags (int fd, struct ospf_packet *op, struct ip *iph,
paul62d8e962004-11-02 20:26:45 +0000482 struct msghdr *msg, unsigned int maxdatasize,
paul37ccfa32004-10-31 11:24:51 +0000483 unsigned int mtu, int flags, u_char type)
paul0bfeca32004-09-24 08:07:54 +0000484{
485#define OSPF_WRITE_FRAG_SHIFT 3
paul6a99f832004-09-27 12:56:30 +0000486 u_int16_t offset;
paul62d8e962004-11-02 20:26:45 +0000487 struct iovec *iovp;
paul6a99f832004-09-27 12:56:30 +0000488 int ret;
paul0bfeca32004-09-24 08:07:54 +0000489
490 assert ( op->length == stream_get_endp(op->s) );
paul62d8e962004-11-02 20:26:45 +0000491 assert (msg->msg_iovlen == 2);
paul0bfeca32004-09-24 08:07:54 +0000492
493 /* we can but try.
494 *
495 * SunOS, BSD and BSD derived kernels likely will clear ip_id, as
496 * well as the IP_MF flag, making this all quite pointless.
497 *
498 * However, for a system on which IP_MF is left alone, and ip_id left
499 * alone or else which sets same ip_id for each fragment this might
500 * work, eg linux.
501 *
502 * XXX-TODO: It would be much nicer to have the kernel's use their
503 * existing fragmentation support to do this for us. Bugs/RFEs need to
504 * be raised against the various kernels.
505 */
506
507 /* set More Frag */
508 iph->ip_off |= IP_MF;
509
510 /* ip frag offset is expressed in units of 8byte words */
511 offset = maxdatasize >> OSPF_WRITE_FRAG_SHIFT;
512
paul62d8e962004-11-02 20:26:45 +0000513 iovp = &msg->msg_iov[1];
514
paul0bfeca32004-09-24 08:07:54 +0000515 while ( (stream_get_endp(op->s) - stream_get_getp (op->s))
516 > maxdatasize )
517 {
518 /* data length of this frag is to next offset value */
paul62d8e962004-11-02 20:26:45 +0000519 iovp->iov_len = offset << OSPF_WRITE_FRAG_SHIFT;
520 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul6a99f832004-09-27 12:56:30 +0000521 assert (iph->ip_len <= mtu);
paul0bfeca32004-09-24 08:07:54 +0000522
paul18b12c32004-10-05 14:38:29 +0000523 sockopt_iphdrincl_swab_htosys (iph);
paul0bfeca32004-09-24 08:07:54 +0000524
paul6a99f832004-09-27 12:56:30 +0000525 ret = sendmsg (fd, msg, flags);
paul0bfeca32004-09-24 08:07:54 +0000526
paul18b12c32004-10-05 14:38:29 +0000527 sockopt_iphdrincl_swab_systoh (iph);
paul0bfeca32004-09-24 08:07:54 +0000528
529 if (ret < 0)
paul37ccfa32004-10-31 11:24:51 +0000530 zlog_warn ("*** ospf_write_frags: sendmsg failed to %s,"
ajs5dcbdf82005-03-29 16:13:49 +0000531 " id %d, off %d, len %d, mtu %u failed with %s",
532 inet_ntoa (iph->ip_dst),
533 iph->ip_id,
534 iph->ip_off,
535 iph->ip_len,
536 mtu,
537 safe_strerror (errno));
paul0bfeca32004-09-24 08:07:54 +0000538
paul37ccfa32004-10-31 11:24:51 +0000539 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
540 {
ajs2a42e282004-12-08 18:43:03 +0000541 zlog_debug ("ospf_write_frags: sent id %d, off %d, len %d to %s\n",
paul37ccfa32004-10-31 11:24:51 +0000542 iph->ip_id, iph->ip_off, iph->ip_len,
543 inet_ntoa (iph->ip_dst));
544 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
545 {
ajs2a42e282004-12-08 18:43:03 +0000546 zlog_debug ("-----------------IP Header Dump----------------------");
paul37ccfa32004-10-31 11:24:51 +0000547 ospf_ip_header_dump (iph);
ajs2a42e282004-12-08 18:43:03 +0000548 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000549 }
550 }
551
paul0bfeca32004-09-24 08:07:54 +0000552 iph->ip_off += offset;
paul9985f832005-02-09 15:51:56 +0000553 stream_forward_getp (op->s, iovp->iov_len);
paul62d8e962004-11-02 20:26:45 +0000554 iovp->iov_base = STREAM_PNT (op->s);
paul0bfeca32004-09-24 08:07:54 +0000555 }
556
557 /* setup for final fragment */
paul62d8e962004-11-02 20:26:45 +0000558 iovp->iov_len = stream_get_endp(op->s) - stream_get_getp (op->s);
559 iph->ip_len = iovp->iov_len + sizeof (struct ip);
paul0bfeca32004-09-24 08:07:54 +0000560 iph->ip_off &= (~IP_MF);
561}
562#endif /* WANT_OSPF_WRITE_FRAGMENT */
563
ajs5dcbdf82005-03-29 16:13:49 +0000564static int
paul718e3742002-12-13 20:15:29 +0000565ospf_write (struct thread *thread)
566{
paul68980082003-03-25 05:07:42 +0000567 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000568 struct ospf_interface *oi;
569 struct ospf_packet *op;
570 struct sockaddr_in sa_dst;
paul718e3742002-12-13 20:15:29 +0000571 struct ip iph;
572 struct msghdr msg;
paul62d8e962004-11-02 20:26:45 +0000573 struct iovec iov[2];
paul68980082003-03-25 05:07:42 +0000574 u_char type;
575 int ret;
576 int flags = 0;
hasso52dc7ee2004-09-23 19:18:23 +0000577 struct listnode *node;
paul0bfeca32004-09-24 08:07:54 +0000578#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000579 static u_int16_t ipid = 0;
paul0bfeca32004-09-24 08:07:54 +0000580#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul6a99f832004-09-27 12:56:30 +0000581 u_int16_t maxdatasize;
paul68b73392004-09-12 14:21:37 +0000582#define OSPF_WRITE_IPHL_SHIFT 2
paul718e3742002-12-13 20:15:29 +0000583
paul68980082003-03-25 05:07:42 +0000584 ospf->t_write = NULL;
paul718e3742002-12-13 20:15:29 +0000585
paul68980082003-03-25 05:07:42 +0000586 node = listhead (ospf->oi_write_q);
paul718e3742002-12-13 20:15:29 +0000587 assert (node);
paul1eb8ef22005-04-07 07:30:20 +0000588 oi = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000589 assert (oi);
paul0bfeca32004-09-24 08:07:54 +0000590
591#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000592 /* seed ipid static with low order bits of time */
593 if (ipid == 0)
594 ipid = (time(NULL) & 0xffff);
paul0bfeca32004-09-24 08:07:54 +0000595#endif /* WANT_OSPF_WRITE_FRAGMENT */
596
paul68b73392004-09-12 14:21:37 +0000597 /* convenience - max OSPF data per packet */
598 maxdatasize = oi->ifp->mtu - sizeof (struct ip);
599
paul718e3742002-12-13 20:15:29 +0000600 /* Get one packet from queue. */
601 op = ospf_fifo_head (oi->obuf);
602 assert (op);
603 assert (op->length >= OSPF_HEADER_SIZE);
604
paul68980082003-03-25 05:07:42 +0000605 if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS)
606 || op->dst.s_addr == htonl (OSPF_ALLDROUTERS))
paul68b73392004-09-12 14:21:37 +0000607 ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex);
608
paul718e3742002-12-13 20:15:29 +0000609 /* Rewrite the md5 signature & update the seq */
610 ospf_make_md5_digest (oi, op);
611
paul37ccfa32004-10-31 11:24:51 +0000612 /* Retrieve OSPF packet type. */
613 stream_set_getp (op->s, 1);
614 type = stream_getc (op->s);
615
paul68b73392004-09-12 14:21:37 +0000616 /* reset get pointer */
617 stream_set_getp (op->s, 0);
618
619 memset (&iph, 0, sizeof (struct ip));
paul718e3742002-12-13 20:15:29 +0000620 memset (&sa_dst, 0, sizeof (sa_dst));
paul68b73392004-09-12 14:21:37 +0000621
paul718e3742002-12-13 20:15:29 +0000622 sa_dst.sin_family = AF_INET;
623#ifdef HAVE_SIN_LEN
624 sa_dst.sin_len = sizeof(sa_dst);
625#endif /* HAVE_SIN_LEN */
626 sa_dst.sin_addr = op->dst;
627 sa_dst.sin_port = htons (0);
628
629 /* Set DONTROUTE flag if dst is unicast. */
630 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
631 if (!IN_MULTICAST (htonl (op->dst.s_addr)))
632 flags = MSG_DONTROUTE;
633
paul68b73392004-09-12 14:21:37 +0000634 iph.ip_hl = sizeof (struct ip) >> OSPF_WRITE_IPHL_SHIFT;
635 /* it'd be very strange for header to not be 4byte-word aligned but.. */
paul6c835672004-10-11 11:00:30 +0000636 if ( sizeof (struct ip)
637 > (unsigned int)(iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) )
paul68b73392004-09-12 14:21:37 +0000638 iph.ip_hl++; /* we presume sizeof struct ip cant overflow ip_hl.. */
639
paul718e3742002-12-13 20:15:29 +0000640 iph.ip_v = IPVERSION;
paul68980082003-03-25 05:07:42 +0000641 iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;
paul68b73392004-09-12 14:21:37 +0000642 iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length;
paul68b73392004-09-12 14:21:37 +0000643
paul0bfeca32004-09-24 08:07:54 +0000644#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000645 /* XXX-MT: not thread-safe at all..
646 * XXX: this presumes this is only programme sending OSPF packets
647 * otherwise, no guarantee ipid will be unique
648 */
649 iph.ip_id = ++ipid;
paul0bfeca32004-09-24 08:07:54 +0000650#endif /* WANT_OSPF_WRITE_FRAGMENT */
651
paul718e3742002-12-13 20:15:29 +0000652 iph.ip_off = 0;
653 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
654 iph.ip_ttl = OSPF_VL_IP_TTL;
655 else
656 iph.ip_ttl = OSPF_IP_TTL;
657 iph.ip_p = IPPROTO_OSPFIGP;
658 iph.ip_sum = 0;
659 iph.ip_src.s_addr = oi->address->u.prefix4.s_addr;
660 iph.ip_dst.s_addr = op->dst.s_addr;
661
662 memset (&msg, 0, sizeof (msg));
paul68defd62004-09-27 07:27:13 +0000663 msg.msg_name = (caddr_t) &sa_dst;
paul718e3742002-12-13 20:15:29 +0000664 msg.msg_namelen = sizeof (sa_dst);
665 msg.msg_iov = iov;
666 msg.msg_iovlen = 2;
667 iov[0].iov_base = (char*)&iph;
paul68b73392004-09-12 14:21:37 +0000668 iov[0].iov_len = iph.ip_hl << OSPF_WRITE_IPHL_SHIFT;
669 iov[1].iov_base = STREAM_PNT (op->s);
paul718e3742002-12-13 20:15:29 +0000670 iov[1].iov_len = op->length;
paul68b73392004-09-12 14:21:37 +0000671
672 /* Sadly we can not rely on kernels to fragment packets because of either
673 * IP_HDRINCL and/or multicast destination being set.
674 */
paul0bfeca32004-09-24 08:07:54 +0000675#ifdef WANT_OSPF_WRITE_FRAGMENT
paul68b73392004-09-12 14:21:37 +0000676 if ( op->length > maxdatasize )
paul62d8e962004-11-02 20:26:45 +0000677 ospf_write_frags (ospf->fd, op, &iph, &msg, maxdatasize,
678 oi->ifp->mtu, flags, type);
paul0bfeca32004-09-24 08:07:54 +0000679#endif /* WANT_OSPF_WRITE_FRAGMENT */
paul68b73392004-09-12 14:21:37 +0000680
681 /* send final fragment (could be first) */
paul18b12c32004-10-05 14:38:29 +0000682 sockopt_iphdrincl_swab_htosys (&iph);
paul68980082003-03-25 05:07:42 +0000683 ret = sendmsg (ospf->fd, &msg, flags);
paul6b333612004-10-11 10:11:25 +0000684 sockopt_iphdrincl_swab_systoh (&iph);
paul718e3742002-12-13 20:15:29 +0000685
686 if (ret < 0)
ajs083ee9d2005-02-09 15:35:50 +0000687 zlog_warn ("*** sendmsg in ospf_write failed to %s, "
ajs5dcbdf82005-03-29 16:13:49 +0000688 "id %d, off %d, len %d, interface %s, mtu %u: %s",
ajs083ee9d2005-02-09 15:35:50 +0000689 inet_ntoa (iph.ip_dst), iph.ip_id, iph.ip_off, iph.ip_len,
ajs5dcbdf82005-03-29 16:13:49 +0000690 oi->ifp->name, oi->ifp->mtu, safe_strerror (errno));
paul718e3742002-12-13 20:15:29 +0000691
paul718e3742002-12-13 20:15:29 +0000692 /* Show debug sending packet. */
693 if (IS_DEBUG_OSPF_PACKET (type - 1, SEND))
694 {
695 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
696 {
ajs2a42e282004-12-08 18:43:03 +0000697 zlog_debug ("-----------------------------------------------------");
paul37ccfa32004-10-31 11:24:51 +0000698 ospf_ip_header_dump (&iph);
paul718e3742002-12-13 20:15:29 +0000699 stream_set_getp (op->s, 0);
700 ospf_packet_dump (op->s);
701 }
702
ajs2a42e282004-12-08 18:43:03 +0000703 zlog_debug ("%s sent to [%s] via [%s].",
paul718e3742002-12-13 20:15:29 +0000704 ospf_packet_type_str[type], inet_ntoa (op->dst),
705 IF_NAME (oi));
706
707 if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +0000708 zlog_debug ("-----------------------------------------------------");
paul718e3742002-12-13 20:15:29 +0000709 }
710
711 /* Now delete packet from queue. */
712 ospf_packet_delete (oi);
713
714 if (ospf_fifo_head (oi->obuf) == NULL)
715 {
716 oi->on_write_q = 0;
paul68980082003-03-25 05:07:42 +0000717 list_delete_node (ospf->oi_write_q, node);
paul718e3742002-12-13 20:15:29 +0000718 }
719
720 /* If packets still remain in queue, call write thread. */
paul68980082003-03-25 05:07:42 +0000721 if (!list_isempty (ospf->oi_write_q))
722 ospf->t_write =
723 thread_add_write (master, ospf_write, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +0000724
725 return 0;
726}
727
728/* OSPF Hello message read -- RFC2328 Section 10.5. */
paul4dadc292005-05-06 21:37:42 +0000729static void
paul718e3742002-12-13 20:15:29 +0000730ospf_hello (struct ip *iph, struct ospf_header *ospfh,
731 struct stream * s, struct ospf_interface *oi, int size)
732{
733 struct ospf_hello *hello;
734 struct ospf_neighbor *nbr;
paul718e3742002-12-13 20:15:29 +0000735 int old_state;
pauld3f0d622004-05-05 15:27:15 +0000736 struct prefix p;
paul718e3742002-12-13 20:15:29 +0000737
738 /* increment statistics. */
739 oi->hello_in++;
740
741 hello = (struct ospf_hello *) STREAM_PNT (s);
742
743 /* If Hello is myself, silently discard. */
paul68980082003-03-25 05:07:42 +0000744 if (IPV4_ADDR_SAME (&ospfh->router_id, &oi->ospf->router_id))
pauld3241812003-09-29 12:42:39 +0000745 {
746 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
747 {
ajs2a42e282004-12-08 18:43:03 +0000748 zlog_debug ("ospf_header[%s/%s]: selforiginated, "
pauld3241812003-09-29 12:42:39 +0000749 "dropping.",
750 ospf_packet_type_str[ospfh->type],
751 inet_ntoa (iph->ip_src));
752 }
753 return;
754 }
paul718e3742002-12-13 20:15:29 +0000755
756 /* If incoming interface is passive one, ignore Hello. */
paulf2c80652002-12-13 21:44:27 +0000757 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
ajsba6454e2005-02-08 15:37:30 +0000758 char buf[3][INET_ADDRSTRLEN];
759 zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
760 "should not receive hellos on passive interface %s!",
761 inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
762 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
763 inet_ntop(AF_INET, &oi->address->u.prefix4,
764 buf[2], sizeof(buf[2])));
765 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
766 {
767 /* Try to fix multicast membership. */
768 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
769 ospf_if_set_multicast(oi);
770 }
paul718e3742002-12-13 20:15:29 +0000771 return;
paulf2c80652002-12-13 21:44:27 +0000772 }
paul718e3742002-12-13 20:15:29 +0000773
774 /* get neighbor prefix. */
775 p.family = AF_INET;
776 p.prefixlen = ip_masklen (hello->network_mask);
777 p.u.prefix4 = iph->ip_src;
778
779 /* Compare network mask. */
780 /* Checking is ignored for Point-to-Point and Virtual link. */
781 if (oi->type != OSPF_IFTYPE_POINTOPOINT
782 && oi->type != OSPF_IFTYPE_VIRTUALLINK)
783 if (oi->address->prefixlen != p.prefixlen)
784 {
785 zlog_warn ("Packet %s [Hello:RECV]: NetworkMask mismatch.",
786 inet_ntoa (ospfh->router_id));
787 return;
788 }
789
790 /* Compare Hello Interval. */
791 if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval))
792 {
793 zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.",
794 inet_ntoa (ospfh->router_id));
795 return;
796 }
797
798 /* Compare Router Dead Interval. */
799 if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval))
800 {
801 zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.",
802 inet_ntoa (ospfh->router_id));
803 return;
804 }
805
806 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +0000807 zlog_debug ("Packet %s [Hello:RECV]: Options %s",
paul718e3742002-12-13 20:15:29 +0000808 inet_ntoa (ospfh->router_id),
809 ospf_options_dump (hello->options));
810
811 /* Compare options. */
812#define REJECT_IF_TBIT_ON 1 /* XXX */
813#ifdef REJECT_IF_TBIT_ON
814 if (CHECK_FLAG (hello->options, OSPF_OPTION_T))
815 {
816 /*
817 * This router does not support non-zero TOS.
818 * Drop this Hello packet not to establish neighbor relationship.
819 */
820 zlog_warn ("Packet %s [Hello:RECV]: T-bit on, drop it.",
821 inet_ntoa (ospfh->router_id));
822 return;
823 }
824#endif /* REJECT_IF_TBIT_ON */
825
826#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +0000827 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE)
paul718e3742002-12-13 20:15:29 +0000828 && CHECK_FLAG (hello->options, OSPF_OPTION_O))
829 {
830 /*
831 * This router does know the correct usage of O-bit
832 * the bit should be set in DD packet only.
833 */
834 zlog_warn ("Packet %s [Hello:RECV]: O-bit abuse?",
835 inet_ntoa (ospfh->router_id));
836#ifdef STRICT_OBIT_USAGE_CHECK
837 return; /* Reject this packet. */
838#else /* STRICT_OBIT_USAGE_CHECK */
839 UNSET_FLAG (hello->options, OSPF_OPTION_O); /* Ignore O-bit. */
840#endif /* STRICT_OBIT_USAGE_CHECK */
841 }
842#endif /* HAVE_OPAQUE_LSA */
843
844 /* new for NSSA is to ensure that NP is on and E is off */
845
paul718e3742002-12-13 20:15:29 +0000846 if (oi->area->external_routing == OSPF_AREA_NSSA)
847 {
848 if (! (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_NP)
849 && CHECK_FLAG (hello->options, OSPF_OPTION_NP)
850 && ! CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E)
851 && ! CHECK_FLAG (hello->options, OSPF_OPTION_E)))
852 {
853 zlog_warn ("NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x", inet_ntoa (ospfh->router_id), OPTIONS (oi), hello->options);
854 return;
855 }
856 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +0000857 zlog_debug ("NSSA-Hello:RECV:Packet from %s:", inet_ntoa(ospfh->router_id));
paul718e3742002-12-13 20:15:29 +0000858 }
859 else
paul718e3742002-12-13 20:15:29 +0000860 /* The setting of the E-bit found in the Hello Packet's Options
861 field must match this area's ExternalRoutingCapability A
862 mismatch causes processing to stop and the packet to be
863 dropped. The setting of the rest of the bits in the Hello
864 Packet's Options field should be ignored. */
865 if (CHECK_FLAG (OPTIONS (oi), OSPF_OPTION_E) !=
866 CHECK_FLAG (hello->options, OSPF_OPTION_E))
867 {
ajs3aa8d5f2004-12-11 18:00:06 +0000868 zlog_warn ("Packet %s [Hello:RECV]: my options: %x, his options %x",
869 inet_ntoa(ospfh->router_id), OPTIONS (oi), hello->options);
paul718e3742002-12-13 20:15:29 +0000870 return;
871 }
paul718e3742002-12-13 20:15:29 +0000872
pauld3f0d622004-05-05 15:27:15 +0000873 /* get neighbour struct */
874 nbr = ospf_nbr_get (oi, ospfh, iph, &p);
875
876 /* neighbour must be valid, ospf_nbr_get creates if none existed */
877 assert (nbr);
paul718e3742002-12-13 20:15:29 +0000878
879 old_state = nbr->state;
880
881 /* Add event to thread. */
882 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived);
883
884 /* RFC2328 Section 9.5.1
885 If the router is not eligible to become Designated Router,
886 (snip) It must also send an Hello Packet in reply to an
887 Hello Packet received from any eligible neighbor (other than
888 the current Designated Router and Backup Designated Router). */
889 if (oi->type == OSPF_IFTYPE_NBMA)
890 if (PRIORITY(oi) == 0 && hello->priority > 0
891 && IPV4_ADDR_CMP(&DR(oi), &iph->ip_src)
892 && IPV4_ADDR_CMP(&BDR(oi), &iph->ip_src))
893 OSPF_NSM_TIMER_ON (nbr->t_hello_reply, ospf_hello_reply_timer,
894 OSPF_HELLO_REPLY_DELAY);
895
896 /* on NBMA network type, it happens to receive bidirectional Hello packet
897 without advance 1-Way Received event.
898 To avoid incorrect DR-seletion, raise 1-Way Received event.*/
899 if (oi->type == OSPF_IFTYPE_NBMA &&
900 (old_state == NSM_Down || old_state == NSM_Attempt))
901 {
902 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
903 nbr->priority = hello->priority;
904 nbr->d_router = hello->d_router;
905 nbr->bd_router = hello->bd_router;
906 return;
907 }
908
paul68980082003-03-25 05:07:42 +0000909 if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,
paul718e3742002-12-13 20:15:29 +0000910 size - OSPF_HELLO_MIN_SIZE))
911 {
912 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
913 nbr->options |= hello->options;
914 }
915 else
916 {
917 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived);
918 /* Set neighbor information. */
919 nbr->priority = hello->priority;
920 nbr->d_router = hello->d_router;
921 nbr->bd_router = hello->bd_router;
922 return;
923 }
924
925 /* If neighbor itself declares DR and no BDR exists,
926 cause event BackupSeen */
927 if (IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router))
928 if (hello->bd_router.s_addr == 0 && oi->state == ISM_Waiting)
929 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
930
931 /* neighbor itself declares BDR. */
932 if (oi->state == ISM_Waiting &&
933 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router))
934 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_BackupSeen);
935
936 /* had not previously. */
937 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->d_router) &&
938 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->d_router)) ||
939 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->d_router) &&
940 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->d_router)))
941 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
942
943 /* had not previously. */
944 if ((IPV4_ADDR_SAME (&nbr->address.u.prefix4, &hello->bd_router) &&
945 IPV4_ADDR_CMP (&nbr->address.u.prefix4, &nbr->bd_router)) ||
946 (IPV4_ADDR_CMP (&nbr->address.u.prefix4, &hello->bd_router) &&
947 IPV4_ADDR_SAME (&nbr->address.u.prefix4, &nbr->bd_router)))
948 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
949
950 /* Neighbor priority check. */
951 if (nbr->priority >= 0 && nbr->priority != hello->priority)
952 OSPF_ISM_EVENT_SCHEDULE (oi, ISM_NeighborChange);
953
954 /* Set neighbor information. */
955 nbr->priority = hello->priority;
956 nbr->d_router = hello->d_router;
957 nbr->bd_router = hello->bd_router;
958}
959
960/* Save DD flags/options/Seqnum received. */
paul4dadc292005-05-06 21:37:42 +0000961static void
paul718e3742002-12-13 20:15:29 +0000962ospf_db_desc_save_current (struct ospf_neighbor *nbr,
963 struct ospf_db_desc *dd)
964{
965 nbr->last_recv.flags = dd->flags;
966 nbr->last_recv.options = dd->options;
967 nbr->last_recv.dd_seqnum = ntohl (dd->dd_seqnum);
968}
969
970/* Process rest of DD packet. */
971static void
972ospf_db_desc_proc (struct stream *s, struct ospf_interface *oi,
973 struct ospf_neighbor *nbr, struct ospf_db_desc *dd,
974 u_int16_t size)
975{
976 struct ospf_lsa *new, *find;
977 struct lsa_header *lsah;
978
paul9985f832005-02-09 15:51:56 +0000979 stream_forward_getp (s, OSPF_DB_DESC_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +0000980 for (size -= OSPF_DB_DESC_MIN_SIZE;
981 size >= OSPF_LSA_HEADER_SIZE; size -= OSPF_LSA_HEADER_SIZE)
982 {
983 lsah = (struct lsa_header *) STREAM_PNT (s);
paul9985f832005-02-09 15:51:56 +0000984 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000985
986 /* Unknown LS type. */
987 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
988 {
ajsbec595a2004-11-30 22:38:43 +0000989 zlog_warn ("Packet [DD:RECV]: Unknown LS type %d.", lsah->type);
paul718e3742002-12-13 20:15:29 +0000990 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
991 return;
992 }
993
994#ifdef HAVE_OPAQUE_LSA
995 if (IS_OPAQUE_LSA (lsah->type)
996 && ! CHECK_FLAG (nbr->options, OSPF_OPTION_O))
997 {
998 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
999 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1000 return;
1001 }
1002#endif /* HAVE_OPAQUE_LSA */
1003
1004 switch (lsah->type)
1005 {
1006 case OSPF_AS_EXTERNAL_LSA:
1007#ifdef HAVE_OPAQUE_LSA
1008 case OSPF_OPAQUE_AS_LSA:
1009#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00001010 /* Check for stub area. Reject if AS-External from stub but
1011 allow if from NSSA. */
1012 if (oi->area->external_routing == OSPF_AREA_STUB)
paul718e3742002-12-13 20:15:29 +00001013 {
1014 zlog_warn ("Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
1015 lsah->type, inet_ntoa (lsah->id),
1016 (oi->area->external_routing == OSPF_AREA_STUB) ?\
1017 "STUB" : "NSSA");
1018 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1019 return;
1020 }
1021 break;
1022 default:
1023 break;
1024 }
1025
1026 /* Create LS-request object. */
1027 new = ospf_ls_request_new (lsah);
1028
1029 /* Lookup received LSA, then add LS request list. */
1030 find = ospf_lsa_lookup_by_header (oi->area, lsah);
1031 if (!find || ospf_lsa_more_recent (find, new) < 0)
1032 {
1033 ospf_ls_request_add (nbr, new);
1034 ospf_lsa_discard (new);
1035 }
1036 else
1037 {
1038 /* Received LSA is not recent. */
1039 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001040 zlog_debug ("Packet [DD:RECV]: LSA received Type %d, "
paul718e3742002-12-13 20:15:29 +00001041 "ID %s is not recent.", lsah->type, inet_ntoa (lsah->id));
1042 ospf_lsa_discard (new);
1043 continue;
1044 }
1045 }
1046
1047 /* Master */
1048 if (IS_SET_DD_MS (nbr->dd_flags))
1049 {
1050 nbr->dd_seqnum++;
1051 /* Entire DD packet sent. */
1052 if (!IS_SET_DD_M (dd->flags) && !IS_SET_DD_M (nbr->dd_flags))
1053 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1054 else
1055 /* Send new DD packet. */
1056 ospf_db_desc_send (nbr);
1057 }
1058 /* Slave */
1059 else
1060 {
1061 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1062
1063 /* When master's more flags is not set. */
1064 if (!IS_SET_DD_M (dd->flags) && ospf_db_summary_isempty (nbr))
1065 {
1066 nbr->dd_flags &= ~(OSPF_DD_FLAG_M);
1067 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_ExchangeDone);
1068 }
1069
ajsbec595a2004-11-30 22:38:43 +00001070 /* Send DD packet in reply. */
paul718e3742002-12-13 20:15:29 +00001071 ospf_db_desc_send (nbr);
1072 }
1073
1074 /* Save received neighbor values from DD. */
1075 ospf_db_desc_save_current (nbr, dd);
1076}
1077
paul4dadc292005-05-06 21:37:42 +00001078static int
paul718e3742002-12-13 20:15:29 +00001079ospf_db_desc_is_dup (struct ospf_db_desc *dd, struct ospf_neighbor *nbr)
1080{
1081 /* Is DD duplicated? */
1082 if (dd->options == nbr->last_recv.options &&
1083 dd->flags == nbr->last_recv.flags &&
1084 dd->dd_seqnum == htonl (nbr->last_recv.dd_seqnum))
1085 return 1;
1086
1087 return 0;
1088}
1089
1090/* OSPF Database Description message read -- RFC2328 Section 10.6. */
ajs3aa8d5f2004-12-11 18:00:06 +00001091static void
paul718e3742002-12-13 20:15:29 +00001092ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,
1093 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1094{
1095 struct ospf_db_desc *dd;
1096 struct ospf_neighbor *nbr;
1097
1098 /* Increment statistics. */
1099 oi->db_desc_in++;
1100
1101 dd = (struct ospf_db_desc *) STREAM_PNT (s);
pauld363df22003-06-19 00:26:34 +00001102
pauld3f0d622004-05-05 15:27:15 +00001103 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001104 if (nbr == NULL)
1105 {
1106 zlog_warn ("Packet[DD]: Unknown Neighbor %s",
1107 inet_ntoa (ospfh->router_id));
1108 return;
1109 }
1110
1111 /* Check MTU. */
1112 if (ntohs (dd->mtu) > oi->ifp->mtu)
1113 {
ajs3aa8d5f2004-12-11 18:00:06 +00001114 zlog_warn ("Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
1115 inet_ntoa (nbr->router_id), ntohs (dd->mtu),
1116 IF_NAME (oi), oi->ifp->mtu);
paul718e3742002-12-13 20:15:29 +00001117 return;
1118 }
1119
pauld363df22003-06-19 00:26:34 +00001120 /*
1121 * XXX HACK by Hasso Tepper. Setting N/P bit in NSSA area DD packets is not
1122 * required. In fact at least JunOS sends DD packets with P bit clear.
1123 * Until proper solution is developped, this hack should help.
1124 *
1125 * Update: According to the RFCs, N bit is specified /only/ for Hello
1126 * options, unfortunately its use in DD options is not specified. Hence some
1127 * implementations follow E-bit semantics and set it in DD options, and some
1128 * treat it as unspecified and hence follow the directive "default for
1129 * options is clear", ie unset.
1130 *
1131 * Reset the flag, as ospfd follows E-bit semantics.
1132 */
1133 if ( (oi->area->external_routing == OSPF_AREA_NSSA)
1134 && (CHECK_FLAG (nbr->options, OSPF_OPTION_NP))
1135 && (!CHECK_FLAG (dd->options, OSPF_OPTION_NP)) )
1136 {
1137 if (IS_DEBUG_OSPF_EVENT)
ajs1210fa62004-12-03 16:43:24 +00001138 zlog_debug ("Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
pauld363df22003-06-19 00:26:34 +00001139 inet_ntoa (nbr->router_id) );
1140 SET_FLAG (dd->options, OSPF_OPTION_NP);
1141 }
pauld363df22003-06-19 00:26:34 +00001142
paul718e3742002-12-13 20:15:29 +00001143#ifdef REJECT_IF_TBIT_ON
1144 if (CHECK_FLAG (dd->options, OSPF_OPTION_T))
1145 {
1146 /*
1147 * In Hello protocol, optional capability must have checked
1148 * to prevent this T-bit enabled router be my neighbor.
1149 */
1150 zlog_warn ("Packet[DD]: Neighbor %s: T-bit on?", inet_ntoa (nbr->router_id));
1151 return;
1152 }
1153#endif /* REJECT_IF_TBIT_ON */
1154
1155#ifdef HAVE_OPAQUE_LSA
1156 if (CHECK_FLAG (dd->options, OSPF_OPTION_O)
paul68980082003-03-25 05:07:42 +00001157 && !CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001158 {
1159 /*
1160 * This node is not configured to handle O-bit, for now.
1161 * Clear it to ignore unsupported capability proposed by neighbor.
1162 */
1163 UNSET_FLAG (dd->options, OSPF_OPTION_O);
1164 }
1165#endif /* HAVE_OPAQUE_LSA */
1166
1167 /* Process DD packet by neighbor status. */
1168 switch (nbr->state)
1169 {
1170 case NSM_Down:
1171 case NSM_Attempt:
1172 case NSM_TwoWay:
ajsbec595a2004-11-30 22:38:43 +00001173 zlog_warn ("Packet[DD]: Neighbor %s state is %s, packet discarded.",
ajs3aa8d5f2004-12-11 18:00:06 +00001174 inet_ntoa(nbr->router_id),
paul718e3742002-12-13 20:15:29 +00001175 LOOKUP (ospf_nsm_state_msg, nbr->state));
1176 break;
1177 case NSM_Init:
1178 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived);
1179 /* If the new state is ExStart, the processing of the current
1180 packet should then continue in this new state by falling
1181 through to case ExStart below. */
1182 if (nbr->state != NSM_ExStart)
1183 break;
1184 case NSM_ExStart:
1185 /* Initial DBD */
1186 if ((IS_SET_DD_ALL (dd->flags) == OSPF_DD_FLAG_ALL) &&
1187 (size == OSPF_DB_DESC_MIN_SIZE))
1188 {
paul68980082003-03-25 05:07:42 +00001189 if (IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) > 0)
paul718e3742002-12-13 20:15:29 +00001190 {
1191 /* We're Slave---obey */
ajs17eaa722004-12-29 21:04:48 +00001192 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Slave).",
ajs3aa8d5f2004-12-11 18:00:06 +00001193 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001194 nbr->dd_seqnum = ntohl (dd->dd_seqnum);
1195 nbr->dd_flags &= ~(OSPF_DD_FLAG_MS|OSPF_DD_FLAG_I); /* Reset I/MS */
1196 }
1197 else
1198 {
1199 /* We're Master, ignore the initial DBD from Slave */
ajs3aa8d5f2004-12-11 18:00:06 +00001200 zlog_warn ("Packet[DD]: Neighbor %s: Initial DBD from Slave, "
1201 "ignoring.", inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001202 break;
1203 }
1204 }
1205 /* Ack from the Slave */
1206 else if (!IS_SET_DD_MS (dd->flags) && !IS_SET_DD_I (dd->flags) &&
1207 ntohl (dd->dd_seqnum) == nbr->dd_seqnum &&
paul68980082003-03-25 05:07:42 +00001208 IPV4_ADDR_CMP (&nbr->router_id, &oi->ospf->router_id) < 0)
paul718e3742002-12-13 20:15:29 +00001209 {
ajs17eaa722004-12-29 21:04:48 +00001210 zlog_info ("Packet[DD]: Neighbor %s Negotiation done (Master).",
ajs3aa8d5f2004-12-11 18:00:06 +00001211 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001212 nbr->dd_flags &= ~OSPF_DD_FLAG_I;
1213 }
1214 else
1215 {
ajs3aa8d5f2004-12-11 18:00:06 +00001216 zlog_warn ("Packet[DD]: Neighbor %s Negotiation fails.",
1217 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001218 break;
1219 }
1220
1221 /* This is where the real Options are saved */
1222 nbr->options = dd->options;
1223
1224#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00001225 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00001226 {
1227 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001228 zlog_debug ("Neighbor[%s] is %sOpaque-capable.",
paul718e3742002-12-13 20:15:29 +00001229 inet_ntoa (nbr->router_id),
1230 CHECK_FLAG (nbr->options, OSPF_OPTION_O) ? "" : "NOT ");
1231
1232 if (! CHECK_FLAG (nbr->options, OSPF_OPTION_O)
1233 && IPV4_ADDR_SAME (&DR (oi), &nbr->address.u.prefix4))
1234 {
1235 zlog_warn ("DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.", inet_ntoa (nbr->router_id));
1236 /* This situation is undesirable, but not a real error. */
1237 }
1238 }
1239#endif /* HAVE_OPAQUE_LSA */
1240
1241 OSPF_NSM_EVENT_EXECUTE (nbr, NSM_NegotiationDone);
1242
1243 /* continue processing rest of packet. */
1244 ospf_db_desc_proc (s, oi, nbr, dd, size);
1245 break;
1246 case NSM_Exchange:
1247 if (ospf_db_desc_is_dup (dd, nbr))
1248 {
1249 if (IS_SET_DD_MS (nbr->dd_flags))
1250 /* Master: discard duplicated DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001251 zlog_warn ("Packet[DD] (Master): Neighbor %s packet duplicated.",
1252 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001253 else
1254 /* Slave: cause to retransmit the last Database Description. */
1255 {
ajs3aa8d5f2004-12-11 18:00:06 +00001256 zlog_warn ("Packet[DD] [Slave]: Neighbor %s packet duplicated.",
1257 inet_ntoa (nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001258 ospf_db_desc_resend (nbr);
1259 }
1260 break;
1261 }
1262
1263 /* Otherwise DD packet should be checked. */
1264 /* Check Master/Slave bit mismatch */
1265 if (IS_SET_DD_MS (dd->flags) != IS_SET_DD_MS (nbr->last_recv.flags))
1266 {
ajs3aa8d5f2004-12-11 18:00:06 +00001267 zlog_warn ("Packet[DD]: Neighbor %s MS-bit mismatch.",
1268 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001269 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1270 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001271 zlog_debug ("Packet[DD]: dd->flags=%d, nbr->dd_flags=%d",
ajs3aa8d5f2004-12-11 18:00:06 +00001272 dd->flags, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00001273 break;
1274 }
1275
1276 /* Check initialize bit is set. */
1277 if (IS_SET_DD_I (dd->flags))
1278 {
ajs3aa8d5f2004-12-11 18:00:06 +00001279 zlog_warn ("Packet[DD]: Neighbor %s I-bit set.",
1280 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001281 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1282 break;
1283 }
1284
1285 /* Check DD Options. */
1286 if (dd->options != nbr->options)
1287 {
1288#ifdef ORIGINAL_CODING
1289 /* Save the new options for debugging */
1290 nbr->options = dd->options;
1291#endif /* ORIGINAL_CODING */
ajs3aa8d5f2004-12-11 18:00:06 +00001292 zlog_warn ("Packet[DD]: Neighbor %s options mismatch.",
1293 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001294 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1295 break;
1296 }
1297
1298 /* Check DD sequence number. */
1299 if ((IS_SET_DD_MS (nbr->dd_flags) &&
1300 ntohl (dd->dd_seqnum) != nbr->dd_seqnum) ||
1301 (!IS_SET_DD_MS (nbr->dd_flags) &&
1302 ntohl (dd->dd_seqnum) != nbr->dd_seqnum + 1))
1303 {
ajs3aa8d5f2004-12-11 18:00:06 +00001304 zlog_warn ("Packet[DD]: Neighbor %s sequence number mismatch.",
1305 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001306 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1307 break;
1308 }
1309
1310 /* Continue processing rest of packet. */
1311 ospf_db_desc_proc (s, oi, nbr, dd, size);
1312 break;
1313 case NSM_Loading:
1314 case NSM_Full:
1315 if (ospf_db_desc_is_dup (dd, nbr))
1316 {
1317 if (IS_SET_DD_MS (nbr->dd_flags))
1318 {
1319 /* Master should discard duplicate DD packet. */
ajs3aa8d5f2004-12-11 18:00:06 +00001320 zlog_warn("Packet[DD]: Neighbor %s duplicated, packet discarded.",
1321 inet_ntoa(nbr->router_id));
paul718e3742002-12-13 20:15:29 +00001322 break;
1323 }
1324 else
1325 {
1326 struct timeval t, now;
1327 gettimeofday (&now, NULL);
1328 t = tv_sub (now, nbr->last_send_ts);
1329 if (tv_cmp (t, int2tv (nbr->v_inactivity)) < 0)
1330 {
1331 /* In states Loading and Full the slave must resend
1332 its last Database Description packet in response to
1333 duplicate Database Description packets received
1334 from the master. For this reason the slave must
1335 wait RouterDeadInterval seconds before freeing the
1336 last Database Description packet. Reception of a
1337 Database Description packet from the master after
1338 this interval will generate a SeqNumberMismatch
1339 neighbor event. RFC2328 Section 10.8 */
1340 ospf_db_desc_resend (nbr);
1341 break;
1342 }
1343 }
1344 }
1345
1346 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_SeqNumberMismatch);
1347 break;
1348 default:
ajs3aa8d5f2004-12-11 18:00:06 +00001349 zlog_warn ("Packet[DD]: Neighbor %s NSM illegal status %u.",
1350 inet_ntoa(nbr->router_id), nbr->state);
paul718e3742002-12-13 20:15:29 +00001351 break;
1352 }
1353}
1354
1355#define OSPF_LSA_KEY_SIZE 12 /* type(4) + id(4) + ar(4) */
1356
1357/* OSPF Link State Request Read -- RFC2328 Section 10.7. */
paul4dadc292005-05-06 21:37:42 +00001358static void
paul718e3742002-12-13 20:15:29 +00001359ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,
1360 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1361{
1362 struct ospf_neighbor *nbr;
1363 u_int32_t ls_type;
1364 struct in_addr ls_id;
1365 struct in_addr adv_router;
1366 struct ospf_lsa *find;
hasso52dc7ee2004-09-23 19:18:23 +00001367 struct list *ls_upd;
paul6c835672004-10-11 11:00:30 +00001368 unsigned int length;
paul718e3742002-12-13 20:15:29 +00001369
1370 /* Increment statistics. */
1371 oi->ls_req_in++;
1372
pauld3f0d622004-05-05 15:27:15 +00001373 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001374 if (nbr == NULL)
1375 {
1376 zlog_warn ("Link State Request: Unknown Neighbor %s.",
1377 inet_ntoa (ospfh->router_id));
1378 return;
1379 }
1380
1381 /* Neighbor State should be Exchange or later. */
1382 if (nbr->state != NSM_Exchange &&
1383 nbr->state != NSM_Loading &&
1384 nbr->state != NSM_Full)
1385 {
ajsbec595a2004-11-30 22:38:43 +00001386 zlog_warn ("Link State Request received from %s: "
1387 "Neighbor state is %s, packet discarded.",
1388 inet_ntoa (ospfh->router_id),
paul718e3742002-12-13 20:15:29 +00001389 LOOKUP (ospf_nsm_state_msg, nbr->state));
1390 return;
1391 }
1392
1393 /* Send Link State Update for ALL requested LSAs. */
1394 ls_upd = list_new ();
1395 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1396
1397 while (size >= OSPF_LSA_KEY_SIZE)
1398 {
1399 /* Get one slice of Link State Request. */
1400 ls_type = stream_getl (s);
1401 ls_id.s_addr = stream_get_ipv4 (s);
1402 adv_router.s_addr = stream_get_ipv4 (s);
1403
1404 /* Verify LSA type. */
1405 if (ls_type < OSPF_MIN_LSA || ls_type >= OSPF_MAX_LSA)
1406 {
1407 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1408 list_delete (ls_upd);
1409 return;
1410 }
1411
1412 /* Search proper LSA in LSDB. */
1413 find = ospf_lsa_lookup (oi->area, ls_type, ls_id, adv_router);
1414 if (find == NULL)
1415 {
1416 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
1417 list_delete (ls_upd);
1418 return;
1419 }
1420
gdt86f1fd92005-01-10 14:20:43 +00001421 /* Packet overflows MTU size, send immediately. */
1422 if (length + ntohs (find->data->length) > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00001423 {
1424 if (oi->type == OSPF_IFTYPE_NBMA)
1425 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1426 else
1427 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1428
1429 /* Only remove list contents. Keep ls_upd. */
1430 list_delete_all_node (ls_upd);
1431
1432 length = OSPF_HEADER_SIZE + OSPF_LS_UPD_MIN_SIZE;
1433 }
1434
1435 /* Append LSA to update list. */
1436 listnode_add (ls_upd, find);
1437 length += ntohs (find->data->length);
1438
1439 size -= OSPF_LSA_KEY_SIZE;
1440 }
1441
1442 /* Send rest of Link State Update. */
1443 if (listcount (ls_upd) > 0)
1444 {
1445 if (oi->type == OSPF_IFTYPE_NBMA)
1446 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_DIRECT);
1447 else
1448 ospf_ls_upd_send (nbr, ls_upd, OSPF_SEND_PACKET_INDIRECT);
1449
1450 list_delete (ls_upd);
1451 }
1452 else
1453 list_free (ls_upd);
1454}
1455
1456/* Get the list of LSAs from Link State Update packet.
1457 And process some validation -- RFC2328 Section 13. (1)-(2). */
hasso52dc7ee2004-09-23 19:18:23 +00001458static struct list *
paul718e3742002-12-13 20:15:29 +00001459ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s,
1460 struct ospf_interface *oi, size_t size)
1461{
1462 u_int16_t count, sum;
1463 u_int32_t length;
1464 struct lsa_header *lsah;
1465 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00001466 struct list *lsas;
paul718e3742002-12-13 20:15:29 +00001467
1468 lsas = list_new ();
1469
1470 count = stream_getl (s);
1471 size -= OSPF_LS_UPD_MIN_SIZE; /* # LSAs */
1472
1473 for (; size >= OSPF_LSA_HEADER_SIZE && count > 0;
paul9985f832005-02-09 15:51:56 +00001474 size -= length, stream_forward_getp (s, length), count--)
paul718e3742002-12-13 20:15:29 +00001475 {
1476 lsah = (struct lsa_header *) STREAM_PNT (s);
1477 length = ntohs (lsah->length);
1478
1479 if (length > size)
1480 {
1481 zlog_warn ("Link State Update: LSA length exceeds packet size.");
1482 break;
1483 }
1484
1485 /* Validate the LSA's LS checksum. */
1486 sum = lsah->checksum;
1487 if (sum != ospf_lsa_checksum (lsah))
1488 {
1489 zlog_warn ("Link State Update: LSA checksum error %x, %x.",
1490 sum, lsah->checksum);
1491 continue;
1492 }
1493
1494 /* Examine the LSA's LS type. */
1495 if (lsah->type < OSPF_MIN_LSA || lsah->type >= OSPF_MAX_LSA)
1496 {
1497 zlog_warn ("Link State Update: Unknown LS type %d", lsah->type);
1498 continue;
1499 }
1500
1501 /*
1502 * What if the received LSA's age is greater than MaxAge?
1503 * Treat it as a MaxAge case -- endo.
1504 */
1505 if (ntohs (lsah->ls_age) > OSPF_LSA_MAXAGE)
1506 lsah->ls_age = htons (OSPF_LSA_MAXAGE);
1507
1508#ifdef HAVE_OPAQUE_LSA
1509 if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
1510 {
1511#ifdef STRICT_OBIT_USAGE_CHECK
1512 if ((IS_OPAQUE_LSA(lsah->type) &&
1513 ! CHECK_FLAG (lsah->options, OSPF_OPTION_O))
1514 || (! IS_OPAQUE_LSA(lsah->type) &&
1515 CHECK_FLAG (lsah->options, OSPF_OPTION_O)))
1516 {
1517 /*
1518 * This neighbor must know the exact usage of O-bit;
1519 * the bit will be set in Type-9,10,11 LSAs only.
1520 */
1521 zlog_warn ("LSA[Type%d:%s]: O-bit abuse?", lsah->type, inet_ntoa (lsah->id));
1522 continue;
1523 }
1524#endif /* STRICT_OBIT_USAGE_CHECK */
1525
1526 /* Do not take in AS External Opaque-LSAs if we are a stub. */
1527 if (lsah->type == OSPF_OPAQUE_AS_LSA
1528 && nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1529 {
1530 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001531 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 +00001532 continue;
1533 }
1534 }
1535 else if (IS_OPAQUE_LSA(lsah->type))
1536 {
1537 zlog_warn ("LSA[Type%d:%s]: Opaque capability mismatch?", lsah->type, inet_ntoa (lsah->id));
1538 continue;
1539 }
1540#endif /* HAVE_OPAQUE_LSA */
1541
1542 /* Create OSPF LSA instance. */
1543 lsa = ospf_lsa_new ();
1544
1545 /* We may wish to put some error checking if type NSSA comes in
1546 and area not in NSSA mode */
1547 switch (lsah->type)
1548 {
1549 case OSPF_AS_EXTERNAL_LSA:
1550#ifdef HAVE_OPAQUE_LSA
1551 case OSPF_OPAQUE_AS_LSA:
1552 lsa->area = NULL;
1553 break;
1554 case OSPF_OPAQUE_LINK_LSA:
1555 lsa->oi = oi; /* Remember incoming interface for flooding control. */
1556 /* Fallthrough */
1557#endif /* HAVE_OPAQUE_LSA */
1558 default:
1559 lsa->area = oi->area;
1560 break;
1561 }
1562
1563 lsa->data = ospf_lsa_data_new (length);
1564 memcpy (lsa->data, lsah, length);
1565
1566 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001567 zlog_debug("LSA[Type%d:%s]: %p new LSA created with Link State Update",
paul718e3742002-12-13 20:15:29 +00001568 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
1569 listnode_add (lsas, lsa);
1570 }
1571
1572 return lsas;
1573}
1574
1575/* Cleanup Update list. */
paul4dadc292005-05-06 21:37:42 +00001576static void
hasso52dc7ee2004-09-23 19:18:23 +00001577ospf_upd_list_clean (struct list *lsas)
paul718e3742002-12-13 20:15:29 +00001578{
paul1eb8ef22005-04-07 07:30:20 +00001579 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001580 struct ospf_lsa *lsa;
1581
paul1eb8ef22005-04-07 07:30:20 +00001582 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
1583 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001584
1585 list_delete (lsas);
1586}
1587
1588/* OSPF Link State Update message read -- RFC2328 Section 13. */
paul4dadc292005-05-06 21:37:42 +00001589static void
paul718e3742002-12-13 20:15:29 +00001590ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,
1591 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1592{
1593 struct ospf_neighbor *nbr;
hasso52dc7ee2004-09-23 19:18:23 +00001594 struct list *lsas;
paul1eb8ef22005-04-07 07:30:20 +00001595 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001596 struct ospf_lsa *lsa = NULL;
1597 /* unsigned long ls_req_found = 0; */
1598
1599 /* Dis-assemble the stream, update each entry, re-encapsulate for flooding */
1600
1601 /* Increment statistics. */
1602 oi->ls_upd_in++;
1603
1604 /* Check neighbor. */
pauld3f0d622004-05-05 15:27:15 +00001605 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001606 if (nbr == NULL)
1607 {
1608 zlog_warn ("Link State Update: Unknown Neighbor %s on int: %s",
1609 inet_ntoa (ospfh->router_id), IF_NAME (oi));
1610 return;
1611 }
1612
1613 /* Check neighbor state. */
1614 if (nbr->state < NSM_Exchange)
1615 {
ajs3aa8d5f2004-12-11 18:00:06 +00001616 zlog_warn ("Link State Update: "
1617 "Neighbor[%s] state %s is less than Exchange",
1618 inet_ntoa (ospfh->router_id),
1619 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001620 return;
1621 }
1622
1623 /* Get list of LSAs from Link State Update packet. - Also perorms Stages
1624 * 1 (validate LSA checksum) and 2 (check for LSA consistent type)
1625 * of section 13.
1626 */
1627 lsas = ospf_ls_upd_list_lsa (nbr, s, oi, size);
1628
1629#ifdef HAVE_OPAQUE_LSA
1630 /*
paul718e3742002-12-13 20:15:29 +00001631 * If self-originated Opaque-LSAs that have flooded before restart
1632 * are contained in the received LSUpd message, corresponding LSReq
1633 * messages to be sent may have to be modified.
1634 * To eliminate possible race conditions such that flushing and normal
1635 * updating for the same LSA would take place alternately, this trick
1636 * must be done before entering to the loop below.
1637 */
paul69310a62005-05-11 18:09:59 +00001638 /* XXX: Why is this Opaque specific? Either our core code is deficient
1639 * and this should be fixed generally, or Opaque is inventing strawman
1640 * problems */
paul718e3742002-12-13 20:15:29 +00001641 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. */
paul1eb8ef22005-04-07 07:30:20 +00001651 for (ALL_LIST_ELEMENTS (lsas, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00001652 {
1653 struct ospf_lsa *ls_ret, *current;
1654 int ret = 1;
1655
paul718e3742002-12-13 20:15:29 +00001656 if (IS_DEBUG_OSPF_NSSA)
1657 {
1658 char buf1[INET_ADDRSTRLEN];
1659 char buf2[INET_ADDRSTRLEN];
1660 char buf3[INET_ADDRSTRLEN];
1661
ajs2a42e282004-12-08 18:43:03 +00001662 zlog_debug("LSA Type-%d from %s, ID: %s, ADV: %s",
paul718e3742002-12-13 20:15:29 +00001663 lsa->data->type,
1664 inet_ntop (AF_INET, &ospfh->router_id,
1665 buf1, INET_ADDRSTRLEN),
1666 inet_ntop (AF_INET, &lsa->data->id,
1667 buf2, INET_ADDRSTRLEN),
1668 inet_ntop (AF_INET, &lsa->data->adv_router,
1669 buf3, INET_ADDRSTRLEN));
1670 }
paul718e3742002-12-13 20:15:29 +00001671
1672 listnode_delete (lsas, lsa); /* We don't need it in list anymore */
1673
1674 /* Validate Checksum - Done above by ospf_ls_upd_list_lsa() */
1675
1676 /* LSA Type - Done above by ospf_ls_upd_list_lsa() */
1677
1678 /* Do not take in AS External LSAs if we are a stub or NSSA. */
1679
1680 /* Do not take in AS NSSA if this neighbor and we are not NSSA */
1681
1682 /* Do take in Type-7's if we are an NSSA */
1683
1684 /* If we are also an ABR, later translate them to a Type-5 packet */
1685
1686 /* Later, an NSSA Re-fresh can Re-fresh Type-7's and an ABR will
1687 translate them to a separate Type-5 packet. */
1688
1689 if (lsa->data->type == OSPF_AS_EXTERNAL_LSA)
1690 /* Reject from STUB or NSSA */
1691 if (nbr->oi->area->external_routing != OSPF_AREA_DEFAULT)
1692 {
1693 DISCARD_LSA (lsa, 1);
paul718e3742002-12-13 20:15:29 +00001694 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001695 zlog_debug("Incoming External LSA Discarded: We are NSSA/STUB Area");
paul718e3742002-12-13 20:15:29 +00001696 }
1697
paul718e3742002-12-13 20:15:29 +00001698 if (lsa->data->type == OSPF_AS_NSSA_LSA)
1699 if (nbr->oi->area->external_routing != OSPF_AREA_NSSA)
1700 {
1701 DISCARD_LSA (lsa,2);
1702 if (IS_DEBUG_OSPF_NSSA)
ajs2a42e282004-12-08 18:43:03 +00001703 zlog_debug("Incoming NSSA LSA Discarded: Not NSSA Area");
paul718e3742002-12-13 20:15:29 +00001704 }
paul718e3742002-12-13 20:15:29 +00001705
1706 /* Find the LSA in the current database. */
1707
1708 current = ospf_lsa_lookup_by_header (oi->area, lsa->data);
1709
1710 /* If the LSA's LS age is equal to MaxAge, and there is currently
1711 no instance of the LSA in the router's link state database,
1712 and none of router's neighbors are in states Exchange or Loading,
1713 then take the following actions. */
1714
1715 if (IS_LSA_MAXAGE (lsa) && !current &&
paul68980082003-03-25 05:07:42 +00001716 (ospf_nbr_count (oi, NSM_Exchange) +
1717 ospf_nbr_count (oi, NSM_Loading)) == 0)
paul718e3742002-12-13 20:15:29 +00001718 {
1719 /* Response Link State Acknowledgment. */
1720 ospf_ls_ack_send (nbr, lsa);
1721
1722 /* Discard LSA. */
ajs3aa8d5f2004-12-11 18:00:06 +00001723 zlog_warn("Link State Update[%s]: LS age is equal to MaxAge.",
1724 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001725 DISCARD_LSA (lsa, 3);
1726 }
1727
1728#ifdef HAVE_OPAQUE_LSA
1729 if (IS_OPAQUE_LSA (lsa->data->type)
paul68980082003-03-25 05:07:42 +00001730 && IPV4_ADDR_SAME (&lsa->data->adv_router, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001731 {
1732 /*
1733 * Even if initial flushing seems to be completed, there might
1734 * be a case that self-originated LSA with MaxAge still remain
1735 * in the routing domain.
1736 * Just send an LSAck message to cease retransmission.
1737 */
1738 if (IS_LSA_MAXAGE (lsa))
1739 {
1740 zlog_warn ("LSA[%s]: Boomerang effect?", dump_lsa_key (lsa));
1741 ospf_ls_ack_send (nbr, lsa);
1742 ospf_lsa_discard (lsa);
1743
1744 if (current != NULL && ! IS_LSA_MAXAGE (current))
1745 ospf_opaque_lsa_refresh_schedule (current);
1746 continue;
1747 }
1748
1749 /*
1750 * If an instance of self-originated Opaque-LSA is not found
1751 * in the LSDB, there are some possible cases here.
1752 *
1753 * 1) This node lost opaque-capability after restart.
1754 * 2) Else, a part of opaque-type is no more supported.
1755 * 3) Else, a part of opaque-id is no more supported.
1756 *
1757 * Anyway, it is still this node's responsibility to flush it.
1758 * Otherwise, the LSA instance remains in the routing domain
1759 * until its age reaches to MaxAge.
1760 */
paul69310a62005-05-11 18:09:59 +00001761 /* XXX: We should deal with this for *ALL* LSAs, not just opaque */
paul718e3742002-12-13 20:15:29 +00001762 if (current == NULL)
1763 {
1764 if (IS_DEBUG_OSPF_EVENT)
paul69310a62005-05-11 18:09:59 +00001765 zlog_debug ("LSA[%s]: Previously originated Opaque-LSA,"
1766 "not found in the LSDB.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00001767
1768 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
paul69310a62005-05-11 18:09:59 +00001769
1770 ospf_opaque_self_originated_lsa_received (nbr, lsa);
1771 ospf_ls_ack_send (nbr, lsa);
1772
paul718e3742002-12-13 20:15:29 +00001773 continue;
1774 }
1775 }
1776#endif /* HAVE_OPAQUE_LSA */
paul69310a62005-05-11 18:09:59 +00001777
hassocb05eb22004-02-11 21:10:19 +00001778 /* It might be happen that received LSA is self-originated network LSA, but
1779 * router ID is cahnged. So, we should check if LSA is a network-LSA whose
1780 * Link State ID is one of the router's own IP interface addresses but whose
1781 * Advertising Router is not equal to the router's own Router ID
1782 * According to RFC 2328 12.4.2 and 13.4 this LSA should be flushed.
1783 */
1784
1785 if(lsa->data->type == OSPF_NETWORK_LSA)
1786 {
paul1eb8ef22005-04-07 07:30:20 +00001787 struct listnode *oinode, *oinnode;
1788 struct ospf_interface *out_if;
hassocb05eb22004-02-11 21:10:19 +00001789 int Flag = 0;
1790
paul1eb8ef22005-04-07 07:30:20 +00001791 for (ALL_LIST_ELEMENTS (oi->ospf->oiflist, oinode, oinnode, out_if))
hassocb05eb22004-02-11 21:10:19 +00001792 {
hassocb05eb22004-02-11 21:10:19 +00001793 if(out_if == NULL)
1794 break;
1795
1796 if((IPV4_ADDR_SAME(&out_if->address->u.prefix4, &lsa->data->id)) &&
1797 (!(IPV4_ADDR_SAME(&oi->ospf->router_id, &lsa->data->adv_router))))
1798 {
1799 if(out_if->network_lsa_self)
1800 {
1801 ospf_lsa_flush_area(lsa,out_if->area);
1802 if(IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00001803 zlog_debug ("ospf_lsa_discard() in ospf_ls_upd() point 9: lsa %p Type-%d",
hassocb05eb22004-02-11 21:10:19 +00001804 lsa, (int) lsa->data->type);
1805 ospf_lsa_discard (lsa);
1806 Flag = 1;
1807 }
1808 break;
1809 }
1810 }
1811 if(Flag)
1812 continue;
1813 }
paul718e3742002-12-13 20:15:29 +00001814
1815 /* (5) Find the instance of this LSA that is currently contained
1816 in the router's link state database. If there is no
1817 database copy, or the received LSA is more recent than
1818 the database copy the following steps must be performed. */
1819
1820 if (current == NULL ||
1821 (ret = ospf_lsa_more_recent (current, lsa)) < 0)
1822 {
1823 /* Actual flooding procedure. */
paul68980082003-03-25 05:07:42 +00001824 if (ospf_flood (oi->ospf, nbr, current, lsa) < 0) /* Trap NSSA later. */
paul718e3742002-12-13 20:15:29 +00001825 DISCARD_LSA (lsa, 4);
1826 continue;
1827 }
1828
1829 /* (6) Else, If there is an instance of the LSA on the sending
1830 neighbor's Link state request list, an error has occurred in
1831 the Database Exchange process. In this case, restart the
1832 Database Exchange process by generating the neighbor event
1833 BadLSReq for the sending neighbor and stop processing the
1834 Link State Update packet. */
1835
1836 if (ospf_ls_request_lookup (nbr, lsa))
1837 {
1838 OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_BadLSReq);
ajs3aa8d5f2004-12-11 18:00:06 +00001839 zlog_warn("LSA[%s] instance exists on Link state request list",
1840 dump_lsa_key(lsa));
paul718e3742002-12-13 20:15:29 +00001841
1842 /* Clean list of LSAs. */
1843 ospf_upd_list_clean (lsas);
1844 /* this lsa is not on lsas list already. */
1845 ospf_lsa_discard (lsa);
paul718e3742002-12-13 20:15:29 +00001846 return;
1847 }
1848
1849 /* If the received LSA is the same instance as the database copy
1850 (i.e., neither one is more recent) the following two steps
1851 should be performed: */
1852
1853 if (ret == 0)
1854 {
1855 /* If the LSA is listed in the Link state retransmission list
1856 for the receiving adjacency, the router itself is expecting
1857 an acknowledgment for this LSA. The router should treat the
1858 received LSA as an acknowledgment by removing the LSA from
1859 the Link state retransmission list. This is termed an
1860 "implied acknowledgment". */
1861
1862 ls_ret = ospf_ls_retransmit_lookup (nbr, lsa);
1863
1864 if (ls_ret != NULL)
1865 {
1866 ospf_ls_retransmit_delete (nbr, ls_ret);
1867
1868 /* Delayed acknowledgment sent if advertisement received
1869 from Designated Router, otherwise do nothing. */
1870 if (oi->state == ISM_Backup)
1871 if (NBR_IS_DR (nbr))
1872 listnode_add (oi->ls_ack, ospf_lsa_lock (lsa));
1873
1874 DISCARD_LSA (lsa, 5);
1875 }
1876 else
1877 /* Acknowledge the receipt of the LSA by sending a
1878 Link State Acknowledgment packet back out the receiving
1879 interface. */
1880 {
1881 ospf_ls_ack_send (nbr, lsa);
1882 DISCARD_LSA (lsa, 6);
1883 }
1884 }
1885
1886 /* The database copy is more recent. If the database copy
1887 has LS age equal to MaxAge and LS sequence number equal to
1888 MaxSequenceNumber, simply discard the received LSA without
1889 acknowledging it. (In this case, the LSA's LS sequence number is
1890 wrapping, and the MaxSequenceNumber LSA must be completely
1891 flushed before any new LSA instance can be introduced). */
1892
1893 else if (ret > 0) /* Database copy is more recent */
1894 {
1895 if (IS_LSA_MAXAGE (current) &&
1896 current->data->ls_seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
1897 {
1898 DISCARD_LSA (lsa, 7);
1899 }
1900 /* Otherwise, as long as the database copy has not been sent in a
1901 Link State Update within the last MinLSArrival seconds, send the
1902 database copy back to the sending neighbor, encapsulated within
1903 a Link State Update Packet. The Link State Update Packet should
1904 be sent directly to the neighbor. In so doing, do not put the
1905 database copy of the LSA on the neighbor's link state
1906 retransmission list, and do not acknowledge the received (less
1907 recent) LSA instance. */
1908 else
1909 {
1910 struct timeval now;
1911
1912 gettimeofday (&now, NULL);
1913
1914 if (tv_cmp (tv_sub (now, current->tv_orig),
1915 int2tv (OSPF_MIN_LS_ARRIVAL)) > 0)
1916 /* Trap NSSA type later.*/
1917 ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);
1918 DISCARD_LSA (lsa, 8);
1919 }
1920 }
1921 }
1922
paul718e3742002-12-13 20:15:29 +00001923 assert (listcount (lsas) == 0);
1924 list_delete (lsas);
1925}
1926
1927/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
paul4dadc292005-05-06 21:37:42 +00001928static void
paul718e3742002-12-13 20:15:29 +00001929ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,
1930 struct stream *s, struct ospf_interface *oi, u_int16_t size)
1931{
1932 struct ospf_neighbor *nbr;
paul69310a62005-05-11 18:09:59 +00001933
paul718e3742002-12-13 20:15:29 +00001934 /* increment statistics. */
1935 oi->ls_ack_in++;
1936
pauld3f0d622004-05-05 15:27:15 +00001937 nbr = ospf_nbr_lookup (oi, iph, ospfh);
paul718e3742002-12-13 20:15:29 +00001938 if (nbr == NULL)
1939 {
1940 zlog_warn ("Link State Acknowledgment: Unknown Neighbor %s.",
1941 inet_ntoa (ospfh->router_id));
1942 return;
1943 }
1944
1945 if (nbr->state < NSM_Exchange)
1946 {
ajs3aa8d5f2004-12-11 18:00:06 +00001947 zlog_warn ("Link State Acknowledgment: "
1948 "Neighbor[%s] state %s is less than Exchange",
1949 inet_ntoa (ospfh->router_id),
1950 LOOKUP(ospf_nsm_state_msg, nbr->state));
paul718e3742002-12-13 20:15:29 +00001951 return;
1952 }
paul69310a62005-05-11 18:09:59 +00001953
paul718e3742002-12-13 20:15:29 +00001954 while (size >= OSPF_LSA_HEADER_SIZE)
1955 {
1956 struct ospf_lsa *lsa, *lsr;
1957
1958 lsa = ospf_lsa_new ();
1959 lsa->data = (struct lsa_header *) STREAM_PNT (s);
1960
1961 /* lsah = (struct lsa_header *) STREAM_PNT (s); */
1962 size -= OSPF_LSA_HEADER_SIZE;
paul9985f832005-02-09 15:51:56 +00001963 stream_forward_getp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00001964
1965 if (lsa->data->type < OSPF_MIN_LSA || lsa->data->type >= OSPF_MAX_LSA)
1966 {
1967 lsa->data = NULL;
1968 ospf_lsa_discard (lsa);
1969 continue;
1970 }
1971
1972 lsr = ospf_ls_retransmit_lookup (nbr, lsa);
1973
1974 if (lsr != NULL && lsr->data->ls_seqnum == lsa->data->ls_seqnum)
1975 {
1976#ifdef HAVE_OPAQUE_LSA
paul718e3742002-12-13 20:15:29 +00001977 if (IS_OPAQUE_LSA (lsr->data->type))
paul69310a62005-05-11 18:09:59 +00001978 ospf_opaque_ls_ack_received (nbr, lsr);
paul718e3742002-12-13 20:15:29 +00001979#endif /* HAVE_OPAQUE_LSA */
1980
1981 ospf_ls_retransmit_delete (nbr, lsr);
1982 }
1983
1984 lsa->data = NULL;
1985 ospf_lsa_discard (lsa);
1986 }
1987
paul718e3742002-12-13 20:15:29 +00001988 return;
paul718e3742002-12-13 20:15:29 +00001989}
1990
ajs038163f2005-02-17 19:55:59 +00001991static struct stream *
ajs5c333492005-02-23 15:43:01 +00001992ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)
paul718e3742002-12-13 20:15:29 +00001993{
1994 int ret;
ajs5c333492005-02-23 15:43:01 +00001995 struct ip *iph;
paul718e3742002-12-13 20:15:29 +00001996 u_int16_t ip_len;
paul718e3742002-12-13 20:15:29 +00001997 unsigned int ifindex = 0;
1998 struct iovec iov;
gdtd0deca62004-08-26 13:14:07 +00001999 /* Header and data both require alignment. */
gdte3049822004-08-26 13:19:40 +00002000 char buff [CMSG_SPACE(SOPT_SIZE_CMSG_IFINDEX_IPV4())];
paul2dd8bb42004-07-23 15:13:48 +00002001 struct msghdr msgh;
2002
paul68defd62004-09-27 07:27:13 +00002003 memset (&msgh, 0, sizeof (struct msghdr));
paul2dd8bb42004-07-23 15:13:48 +00002004 msgh.msg_iov = &iov;
2005 msgh.msg_iovlen = 1;
2006 msgh.msg_control = (caddr_t) buff;
2007 msgh.msg_controllen = sizeof (buff);
paul2dd8bb42004-07-23 15:13:48 +00002008
ajs5c333492005-02-23 15:43:01 +00002009 ret = stream_recvmsg (ibuf, fd, &msgh, 0, OSPF_MAX_PACKET_SIZE+1);
2010 if (ret < 0)
paul718e3742002-12-13 20:15:29 +00002011 {
ajs5c333492005-02-23 15:43:01 +00002012 zlog_warn("stream_recvmsg failed: %s", safe_strerror(errno));
2013 return NULL;
2014 }
paul69310a62005-05-11 18:09:59 +00002015 if ((unsigned int)ret < sizeof(iph)) /* ret must be > 0 now */
ajs5c333492005-02-23 15:43:01 +00002016 {
2017 zlog_warn("ospf_recv_packet: discarding runt packet of length %d "
2018 "(ip header size is %u)",
2019 ret, (u_int)sizeof(iph));
paul718e3742002-12-13 20:15:29 +00002020 return NULL;
2021 }
paul18b12c32004-10-05 14:38:29 +00002022
ajs5c333492005-02-23 15:43:01 +00002023 /* Note that there should not be alignment problems with this assignment
2024 because this is at the beginning of the stream data buffer. */
2025 iph = (struct ip *) STREAM_DATA(ibuf);
2026 sockopt_iphdrincl_swab_systoh (iph);
paul18b12c32004-10-05 14:38:29 +00002027
ajs5c333492005-02-23 15:43:01 +00002028 ip_len = iph->ip_len;
paul6b333612004-10-11 10:11:25 +00002029
paul239aecc2003-12-08 10:34:54 +00002030#if !defined(GNU_LINUX) && (OpenBSD < 200311)
paul718e3742002-12-13 20:15:29 +00002031 /*
2032 * Kernel network code touches incoming IP header parameters,
2033 * before protocol specific processing.
2034 *
2035 * 1) Convert byteorder to host representation.
2036 * --> ip_len, ip_id, ip_off
2037 *
2038 * 2) Adjust ip_len to strip IP header size!
2039 * --> If user process receives entire IP packet via RAW
2040 * socket, it must consider adding IP header size to
2041 * the "ip_len" field of "ip" structure.
2042 *
2043 * For more details, see <netinet/ip_input.c>.
2044 */
ajs5c333492005-02-23 15:43:01 +00002045 ip_len = ip_len + (iph->ip_hl << 2);
paul718e3742002-12-13 20:15:29 +00002046#endif
2047
paul863082d2004-08-19 04:43:43 +00002048 ifindex = getsockopt_ifindex (AF_INET, &msgh);
paul718e3742002-12-13 20:15:29 +00002049
2050 *ifp = if_lookup_by_index (ifindex);
2051
2052 if (ret != ip_len)
2053 {
ajs5c333492005-02-23 15:43:01 +00002054 zlog_warn ("ospf_recv_packet read length mismatch: ip_len is %d, "
2055 "but recvmsg returned %d", ip_len, ret);
paul718e3742002-12-13 20:15:29 +00002056 return NULL;
2057 }
2058
2059 return ibuf;
2060}
2061
paul4dadc292005-05-06 21:37:42 +00002062static struct ospf_interface *
pauld3f0d622004-05-05 15:27:15 +00002063ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,
paul718e3742002-12-13 20:15:29 +00002064 struct ip *iph, struct ospf_header *ospfh)
2065{
2066 struct ospf_interface *rcv_oi;
paul718e3742002-12-13 20:15:29 +00002067 struct ospf_vl_data *vl_data;
2068 struct ospf_area *vl_area;
hasso52dc7ee2004-09-23 19:18:23 +00002069 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002070
2071 if (IN_MULTICAST (ntohl (iph->ip_dst.s_addr)) ||
2072 !OSPF_IS_AREA_BACKBONE (ospfh))
pauld3f0d622004-05-05 15:27:15 +00002073 return NULL;
paul718e3742002-12-13 20:15:29 +00002074
pauld3f0d622004-05-05 15:27:15 +00002075 /* look for local OSPF interface matching the destination
2076 * to determine Area ID. We presume therefore the destination address
2077 * is unique, or at least (for "unnumbered" links), not used in other
2078 * areas
2079 */
2080 if ((rcv_oi = ospf_if_lookup_by_local_addr (ospf, NULL,
2081 iph->ip_dst)) == NULL)
2082 return NULL;
paul718e3742002-12-13 20:15:29 +00002083
paul1eb8ef22005-04-07 07:30:20 +00002084 for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
paul718e3742002-12-13 20:15:29 +00002085 {
paul020709f2003-04-04 02:44:16 +00002086 vl_area = ospf_area_lookup_by_area_id (ospf, vl_data->vl_area_id);
paul718e3742002-12-13 20:15:29 +00002087 if (!vl_area)
2088 continue;
2089
2090 if (OSPF_AREA_SAME (&vl_area, &rcv_oi->area) &&
2091 IPV4_ADDR_SAME (&vl_data->vl_peer, &ospfh->router_id))
2092 {
2093 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002094 zlog_debug ("associating packet with %s",
paul718e3742002-12-13 20:15:29 +00002095 IF_NAME (vl_data->vl_oi));
2096 if (! CHECK_FLAG (vl_data->vl_oi->ifp->flags, IFF_UP))
2097 {
2098 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002099 zlog_debug ("This VL is not up yet, sorry");
paul718e3742002-12-13 20:15:29 +00002100 return NULL;
2101 }
2102
2103 return vl_data->vl_oi;
2104 }
2105 }
2106
2107 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002108 zlog_debug ("couldn't find any VL to associate the packet with");
paul718e3742002-12-13 20:15:29 +00002109
pauld3f0d622004-05-05 15:27:15 +00002110 return NULL;
paul718e3742002-12-13 20:15:29 +00002111}
2112
paul4dadc292005-05-06 21:37:42 +00002113static inline int
paul718e3742002-12-13 20:15:29 +00002114ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)
2115{
2116 /* Check match the Area ID of the receiving interface. */
2117 if (OSPF_AREA_SAME (&oi->area, &ospfh))
2118 return 1;
2119
2120 return 0;
2121}
2122
2123/* Unbound socket will accept any Raw IP packets if proto is matched.
2124 To prevent it, compare src IP address and i/f address with masking
2125 i/f network mask. */
paul4dadc292005-05-06 21:37:42 +00002126static int
paul718e3742002-12-13 20:15:29 +00002127ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src)
2128{
2129 struct in_addr mask, me, him;
2130
2131 if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
2132 oi->type == OSPF_IFTYPE_VIRTUALLINK)
2133 return 1;
2134
2135 masklen2ip (oi->address->prefixlen, &mask);
2136
2137 me.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
2138 him.s_addr = ip_src.s_addr & mask.s_addr;
2139
2140 if (IPV4_ADDR_SAME (&me, &him))
2141 return 1;
2142
2143 return 0;
2144}
2145
paul4dadc292005-05-06 21:37:42 +00002146static int
paul718e3742002-12-13 20:15:29 +00002147ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf,
2148 struct ospf_header *ospfh)
2149{
2150 int ret = 0;
2151 struct crypt_key *ck;
2152
2153 switch (ntohs (ospfh->auth_type))
2154 {
2155 case OSPF_AUTH_NULL:
2156 ret = 1;
2157 break;
2158 case OSPF_AUTH_SIMPLE:
2159 if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE))
2160 ret = 1;
2161 else
2162 ret = 0;
2163 break;
2164 case OSPF_AUTH_CRYPTOGRAPHIC:
paul1eb8ef22005-04-07 07:30:20 +00002165 if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL)
paul718e3742002-12-13 20:15:29 +00002166 {
2167 ret = 0;
2168 break;
2169 }
2170
2171 /* This is very basic, the digest processing is elsewhere */
2172 if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE &&
2173 ospfh->u.crypt.key_id == ck->key_id &&
2174 ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf))
2175 ret = 1;
2176 else
2177 ret = 0;
2178 break;
2179 default:
2180 ret = 0;
2181 break;
2182 }
2183
2184 return ret;
2185}
2186
paul4dadc292005-05-06 21:37:42 +00002187static int
paul718e3742002-12-13 20:15:29 +00002188ospf_check_sum (struct ospf_header *ospfh)
2189{
2190 u_int32_t ret;
2191 u_int16_t sum;
2192 int in_cksum (void *ptr, int nbytes);
2193
2194 /* clear auth_data for checksum. */
2195 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2196
2197 /* keep checksum and clear. */
2198 sum = ospfh->checksum;
2199 memset (&ospfh->checksum, 0, sizeof (u_int16_t));
2200
2201 /* calculate checksum. */
2202 ret = in_cksum (ospfh, ntohs (ospfh->length));
2203
2204 if (ret != sum)
2205 {
2206 zlog_info ("ospf_check_sum(): checksum mismatch, my %X, his %X",
2207 ret, sum);
2208 return 0;
2209 }
2210
2211 return 1;
2212}
2213
2214/* OSPF Header verification. */
paul4dadc292005-05-06 21:37:42 +00002215static int
paul718e3742002-12-13 20:15:29 +00002216ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi,
2217 struct ip *iph, struct ospf_header *ospfh)
2218{
2219 /* check version. */
2220 if (ospfh->version != OSPF_VERSION)
2221 {
2222 zlog_warn ("interface %s: ospf_read version number mismatch.",
2223 IF_NAME (oi));
2224 return -1;
2225 }
2226
2227 /* Check Area ID. */
2228 if (!ospf_check_area_id (oi, ospfh))
2229 {
2230 zlog_warn ("interface %s: ospf_read invalid Area ID %s.",
2231 IF_NAME (oi), inet_ntoa (ospfh->area_id));
2232 return -1;
2233 }
2234
2235 /* Check network mask, Silently discarded. */
2236 if (! ospf_check_network_mask (oi, iph->ip_src))
2237 {
2238 zlog_warn ("interface %s: ospf_read network address is not same [%s]",
2239 IF_NAME (oi), inet_ntoa (iph->ip_src));
2240 return -1;
2241 }
2242
2243 /* Check authentication. */
2244 if (ospf_auth_type (oi) != ntohs (ospfh->auth_type))
2245 {
2246 zlog_warn ("interface %s: ospf_read authentication type mismatch.",
2247 IF_NAME (oi));
2248 return -1;
2249 }
2250
2251 if (! ospf_check_auth (oi, ibuf, ospfh))
2252 {
2253 zlog_warn ("interface %s: ospf_read authentication failed.",
2254 IF_NAME (oi));
2255 return -1;
2256 }
2257
2258 /* if check sum is invalid, packet is discarded. */
2259 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2260 {
2261 if (! ospf_check_sum (ospfh))
2262 {
2263 zlog_warn ("interface %s: ospf_read packet checksum error %s",
2264 IF_NAME (oi), inet_ntoa (ospfh->router_id));
2265 return -1;
2266 }
2267 }
2268 else
2269 {
2270 if (ospfh->checksum != 0)
2271 return -1;
2272 if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0)
2273 {
2274 zlog_warn ("interface %s: ospf_read md5 authentication failed.",
2275 IF_NAME (oi));
2276 return -1;
2277 }
2278 }
2279
2280 return 0;
2281}
2282
2283/* Starting point of packet process function. */
2284int
2285ospf_read (struct thread *thread)
2286{
2287 int ret;
2288 struct stream *ibuf;
paul68980082003-03-25 05:07:42 +00002289 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002290 struct ospf_interface *oi;
2291 struct ip *iph;
2292 struct ospf_header *ospfh;
2293 u_int16_t length;
2294 struct interface *ifp;
2295
2296 /* first of all get interface pointer. */
paul68980082003-03-25 05:07:42 +00002297 ospf = THREAD_ARG (thread);
ajs038163f2005-02-17 19:55:59 +00002298
2299 /* prepare for next packet. */
2300 ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd);
paul718e3742002-12-13 20:15:29 +00002301
2302 /* read OSPF packet. */
ajs5c333492005-02-23 15:43:01 +00002303 stream_reset(ospf->ibuf);
2304 if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf)))
paul718e3742002-12-13 20:15:29 +00002305 return -1;
2306
ajs5c333492005-02-23 15:43:01 +00002307 /* Note that there should not be alignment problems with this assignment
2308 because this is at the beginning of the stream data buffer. */
paul06f953f2004-10-22 17:00:38 +00002309 iph = (struct ip *) STREAM_DATA (ibuf);
ajs5c333492005-02-23 15:43:01 +00002310 /* Note that sockopt_iphdrincl_swab_systoh was called in ospf_recv_packet. */
paul06f953f2004-10-22 17:00:38 +00002311
paulac191232004-10-22 12:05:17 +00002312 if (ifp == NULL)
ajsb87f7722004-12-29 20:41:26 +00002313 /* Handle cases where the platform does not support retrieving the ifindex,
2314 and also platforms (such as Solaris 8) that claim to support ifindex
2315 retrieval but do not. */
paulac191232004-10-22 12:05:17 +00002316 ifp = if_lookup_address (iph->ip_src);
paulac191232004-10-22 12:05:17 +00002317
pauld3f0d622004-05-05 15:27:15 +00002318 if (ifp == NULL)
ajs5c333492005-02-23 15:43:01 +00002319 return 0;
paul718e3742002-12-13 20:15:29 +00002320
2321 /* IP Header dump. */
paul17b78d32003-02-13 22:04:01 +00002322 if (IS_DEBUG_OSPF_PACKET(0, RECV))
paul6b333612004-10-11 10:11:25 +00002323 ospf_ip_header_dump (iph);
paul7d95c612003-01-27 12:00:55 +00002324
paul718e3742002-12-13 20:15:29 +00002325 /* Self-originated packet should be discarded silently. */
paul68980082003-03-25 05:07:42 +00002326 if (ospf_if_lookup_by_local_addr (ospf, NULL, iph->ip_src))
paul718e3742002-12-13 20:15:29 +00002327 {
pauld3241812003-09-29 12:42:39 +00002328 if (IS_DEBUG_OSPF_PACKET (0, RECV))
2329 {
ajs2a42e282004-12-08 18:43:03 +00002330 zlog_debug ("ospf_read[%s]: Dropping self-originated packet",
pauld3241812003-09-29 12:42:39 +00002331 inet_ntoa (iph->ip_src));
2332 }
paul718e3742002-12-13 20:15:29 +00002333 return 0;
2334 }
2335
2336 /* Adjust size to message length. */
paul9985f832005-02-09 15:51:56 +00002337 stream_forward_getp (ibuf, iph->ip_hl * 4);
paul718e3742002-12-13 20:15:29 +00002338
2339 /* Get ospf packet header. */
2340 ospfh = (struct ospf_header *) STREAM_PNT (ibuf);
2341
2342 /* associate packet with ospf interface */
paul68980082003-03-25 05:07:42 +00002343 oi = ospf_if_lookup_recv_if (ospf, iph->ip_src);
pauld3f0d622004-05-05 15:27:15 +00002344
2345 /* if no local ospf_interface,
2346 * or header area is backbone but ospf_interface is not
2347 * check for VLINK interface
2348 */
2349 if ( (oi == NULL) ||
2350 (OSPF_IS_AREA_ID_BACKBONE(ospfh->area_id)
2351 && !OSPF_IS_AREA_ID_BACKBONE(oi->area->area_id))
2352 )
2353 {
2354 if ((oi = ospf_associate_packet_vl (ospf, ifp, iph, ospfh)) == NULL)
2355 {
2356 zlog_warn ("Packet from [%s] received on link %s"
2357 " but no ospf_interface",
2358 inet_ntoa (iph->ip_src), ifp->name);
pauld3f0d622004-05-05 15:27:15 +00002359 return 0;
2360 }
2361 }
2362
2363 /* else it must be a local ospf interface, check it was received on
2364 * correct link
2365 */
2366 else if (oi->ifp != ifp)
paul718e3742002-12-13 20:15:29 +00002367 {
2368 zlog_warn ("Packet from [%s] received on wrong link %s",
pauld3241812003-09-29 12:42:39 +00002369 inet_ntoa (iph->ip_src), ifp->name);
paul718e3742002-12-13 20:15:29 +00002370 return 0;
2371 }
ajs847947f2005-02-02 18:38:48 +00002372 else if (oi->state == ISM_Down)
ajsc3eab872005-01-29 15:52:07 +00002373 {
ajsba6454e2005-02-08 15:37:30 +00002374 char buf[2][INET_ADDRSTRLEN];
2375 zlog_warn ("Ignoring packet from %s to %s received on interface that is "
ajs847947f2005-02-02 18:38:48 +00002376 "down [%s]; interface flags are %s",
ajsba6454e2005-02-08 15:37:30 +00002377 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
2378 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
2379 ifp->name, if_flag_dump(ifp->flags));
ajsba6454e2005-02-08 15:37:30 +00002380 /* Fix multicast memberships? */
2381 if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
2382 SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
2383 else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
2384 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2385 if (oi->multicast_memberships)
2386 ospf_if_set_multicast(oi);
ajsc3eab872005-01-29 15:52:07 +00002387 return 0;
2388 }
paul718e3742002-12-13 20:15:29 +00002389
2390 /*
2391 * If the received packet is destined for AllDRouters, the packet
2392 * should be accepted only if the received ospf interface state is
2393 * either DR or Backup -- endo.
2394 */
2395 if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
2396 && (oi->state != ISM_DR && oi->state != ISM_Backup))
2397 {
ajsba6454e2005-02-08 15:37:30 +00002398 zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
paul718e3742002-12-13 20:15:29 +00002399 inet_ntoa (iph->ip_src), IF_NAME (oi),
2400 LOOKUP (ospf_ism_state_msg, oi->state));
ajsba6454e2005-02-08 15:37:30 +00002401 /* Try to fix multicast membership. */
2402 SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
2403 ospf_if_set_multicast(oi);
paul718e3742002-12-13 20:15:29 +00002404 return 0;
2405 }
2406
2407 /* Show debug receiving packet. */
paul1aa7b392003-04-08 08:51:58 +00002408 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2409 {
paul718e3742002-12-13 20:15:29 +00002410 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
paul1aa7b392003-04-08 08:51:58 +00002411 {
ajs2a42e282004-12-08 18:43:03 +00002412 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002413 ospf_packet_dump (ibuf);
2414 }
paul718e3742002-12-13 20:15:29 +00002415
ajs2a42e282004-12-08 18:43:03 +00002416 zlog_debug ("%s received from [%s] via [%s]",
paul1aa7b392003-04-08 08:51:58 +00002417 ospf_packet_type_str[ospfh->type],
2418 inet_ntoa (ospfh->router_id), IF_NAME (oi));
ajs2a42e282004-12-08 18:43:03 +00002419 zlog_debug (" src [%s],", inet_ntoa (iph->ip_src));
2420 zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst));
paul718e3742002-12-13 20:15:29 +00002421
2422 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL))
ajs2a42e282004-12-08 18:43:03 +00002423 zlog_debug ("-----------------------------------------------------");
paul1aa7b392003-04-08 08:51:58 +00002424 }
paul718e3742002-12-13 20:15:29 +00002425
2426 /* Some header verification. */
2427 ret = ospf_verify_header (ibuf, oi, iph, ospfh);
2428 if (ret < 0)
2429 {
pauld3241812003-09-29 12:42:39 +00002430 if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV))
2431 {
ajs2a42e282004-12-08 18:43:03 +00002432 zlog_debug ("ospf_read[%s/%s]: Header check failed, "
pauld3241812003-09-29 12:42:39 +00002433 "dropping.",
2434 ospf_packet_type_str[ospfh->type],
2435 inet_ntoa (iph->ip_src));
2436 }
paul718e3742002-12-13 20:15:29 +00002437 return ret;
2438 }
2439
paul9985f832005-02-09 15:51:56 +00002440 stream_forward_getp (ibuf, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002441
2442 /* Adjust size to message length. */
2443 length = ntohs (ospfh->length) - OSPF_HEADER_SIZE;
2444
2445 /* Read rest of the packet and call each sort of packet routine. */
2446 switch (ospfh->type)
2447 {
2448 case OSPF_MSG_HELLO:
2449 ospf_hello (iph, ospfh, ibuf, oi, length);
2450 break;
2451 case OSPF_MSG_DB_DESC:
2452 ospf_db_desc (iph, ospfh, ibuf, oi, length);
2453 break;
2454 case OSPF_MSG_LS_REQ:
2455 ospf_ls_req (iph, ospfh, ibuf, oi, length);
2456 break;
2457 case OSPF_MSG_LS_UPD:
2458 ospf_ls_upd (iph, ospfh, ibuf, oi, length);
2459 break;
2460 case OSPF_MSG_LS_ACK:
2461 ospf_ls_ack (iph, ospfh, ibuf, oi, length);
2462 break;
2463 default:
2464 zlog (NULL, LOG_WARNING,
2465 "interface %s: OSPF packet header type %d is illegal",
2466 IF_NAME (oi), ospfh->type);
2467 break;
2468 }
2469
paul718e3742002-12-13 20:15:29 +00002470 return 0;
2471}
2472
2473/* Make OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002474static void
paul718e3742002-12-13 20:15:29 +00002475ospf_make_header (int type, struct ospf_interface *oi, struct stream *s)
2476{
2477 struct ospf_header *ospfh;
2478
2479 ospfh = (struct ospf_header *) STREAM_DATA (s);
2480
2481 ospfh->version = (u_char) OSPF_VERSION;
2482 ospfh->type = (u_char) type;
2483
paul68980082003-03-25 05:07:42 +00002484 ospfh->router_id = oi->ospf->router_id;
paul718e3742002-12-13 20:15:29 +00002485
2486 ospfh->checksum = 0;
2487 ospfh->area_id = oi->area->area_id;
2488 ospfh->auth_type = htons (ospf_auth_type (oi));
2489
2490 memset (ospfh->u.auth_data, 0, OSPF_AUTH_SIMPLE_SIZE);
2491
paul9985f832005-02-09 15:51:56 +00002492 stream_forward_endp (s, OSPF_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002493}
2494
2495/* Make Authentication Data. */
paul4dadc292005-05-06 21:37:42 +00002496static int
paul718e3742002-12-13 20:15:29 +00002497ospf_make_auth (struct ospf_interface *oi, struct ospf_header *ospfh)
2498{
2499 struct crypt_key *ck;
2500
2501 switch (ospf_auth_type (oi))
2502 {
2503 case OSPF_AUTH_NULL:
2504 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2505 break;
2506 case OSPF_AUTH_SIMPLE:
2507 memcpy (ospfh->u.auth_data, OSPF_IF_PARAM (oi, auth_simple),
2508 OSPF_AUTH_SIMPLE_SIZE);
2509 break;
2510 case OSPF_AUTH_CRYPTOGRAPHIC:
2511 /* If key is not set, then set 0. */
2512 if (list_isempty (OSPF_IF_PARAM (oi, auth_crypt)))
2513 {
2514 ospfh->u.crypt.zero = 0;
2515 ospfh->u.crypt.key_id = 0;
2516 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2517 }
2518 else
2519 {
paul1eb8ef22005-04-07 07:30:20 +00002520 ck = listgetdata (listtail(OSPF_IF_PARAM (oi, auth_crypt)));
paul718e3742002-12-13 20:15:29 +00002521 ospfh->u.crypt.zero = 0;
2522 ospfh->u.crypt.key_id = ck->key_id;
2523 ospfh->u.crypt.auth_data_len = OSPF_AUTH_MD5_SIZE;
2524 }
2525 /* note: the seq is done in ospf_make_md5_digest() */
2526 break;
2527 default:
2528 /* memset (ospfh->u.auth_data, 0, sizeof (ospfh->u.auth_data)); */
2529 break;
2530 }
2531
2532 return 0;
2533}
2534
2535/* Fill rest of OSPF header. */
paul4dadc292005-05-06 21:37:42 +00002536static void
paul718e3742002-12-13 20:15:29 +00002537ospf_fill_header (struct ospf_interface *oi,
2538 struct stream *s, u_int16_t length)
2539{
2540 struct ospf_header *ospfh;
2541
2542 ospfh = (struct ospf_header *) STREAM_DATA (s);
2543
2544 /* Fill length. */
2545 ospfh->length = htons (length);
2546
2547 /* Calculate checksum. */
2548 if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC)
2549 ospfh->checksum = in_cksum (ospfh, length);
2550 else
2551 ospfh->checksum = 0;
2552
2553 /* Add Authentication Data. */
2554 ospf_make_auth (oi, ospfh);
2555}
2556
paul4dadc292005-05-06 21:37:42 +00002557static int
paul718e3742002-12-13 20:15:29 +00002558ospf_make_hello (struct ospf_interface *oi, struct stream *s)
2559{
2560 struct ospf_neighbor *nbr;
2561 struct route_node *rn;
2562 u_int16_t length = OSPF_HELLO_MIN_SIZE;
2563 struct in_addr mask;
2564 unsigned long p;
2565 int flag = 0;
2566
2567 /* Set netmask of interface. */
2568 if (oi->type != OSPF_IFTYPE_POINTOPOINT &&
2569 oi->type != OSPF_IFTYPE_VIRTUALLINK)
2570 masklen2ip (oi->address->prefixlen, &mask);
2571 else
2572 memset ((char *) &mask, 0, sizeof (struct in_addr));
2573 stream_put_ipv4 (s, mask.s_addr);
2574
2575 /* Set Hello Interval. */
2576 stream_putw (s, OSPF_IF_PARAM (oi, v_hello));
2577
2578 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002579 zlog_debug ("make_hello: options: %x, int: %s",
paul718e3742002-12-13 20:15:29 +00002580 OPTIONS(oi), IF_NAME (oi));
2581
2582 /* Set Options. */
2583 stream_putc (s, OPTIONS (oi));
2584
2585 /* Set Router Priority. */
2586 stream_putc (s, PRIORITY (oi));
2587
2588 /* Set Router Dead Interval. */
2589 stream_putl (s, OSPF_IF_PARAM (oi, v_wait));
2590
2591 /* Set Designated Router. */
2592 stream_put_ipv4 (s, DR (oi).s_addr);
2593
paul9985f832005-02-09 15:51:56 +00002594 p = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002595
2596 /* Set Backup Designated Router. */
2597 stream_put_ipv4 (s, BDR (oi).s_addr);
2598
2599 /* Add neighbor seen. */
2600 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
paul68980082003-03-25 05:07:42 +00002601 if ((nbr = rn->info))
2602 if (nbr->router_id.s_addr != 0) /* Ignore 0.0.0.0 node. */
2603 if (nbr->state != NSM_Attempt) /* Ignore Down neighbor. */
2604 if (nbr->state != NSM_Down) /* This is myself for DR election. */
2605 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +00002606 {
2607 /* Check neighbor is sane? */
paul68980082003-03-25 05:07:42 +00002608 if (nbr->d_router.s_addr != 0
2609 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4)
2610 && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4))
2611 flag = 1;
paul718e3742002-12-13 20:15:29 +00002612
2613 stream_put_ipv4 (s, nbr->router_id.s_addr);
2614 length += 4;
2615 }
2616
2617 /* Let neighbor generate BackupSeen. */
2618 if (flag == 1)
paul3a9eb092005-02-08 11:29:41 +00002619 stream_putl_at (s, p, 0); /* ipv4 address, normally */
paul718e3742002-12-13 20:15:29 +00002620
2621 return length;
2622}
2623
paul4dadc292005-05-06 21:37:42 +00002624static int
paul718e3742002-12-13 20:15:29 +00002625ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr,
2626 struct stream *s)
2627{
2628 struct ospf_lsa *lsa;
2629 u_int16_t length = OSPF_DB_DESC_MIN_SIZE;
2630 u_char options;
2631 unsigned long pp;
2632 int i;
2633 struct ospf_lsdb *lsdb;
2634
2635 /* Set Interface MTU. */
2636 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2637 stream_putw (s, 0);
2638 else
2639 stream_putw (s, oi->ifp->mtu);
2640
2641 /* Set Options. */
2642 options = OPTIONS (oi);
2643#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002644 if (CHECK_FLAG (oi->ospf->config, OSPF_OPAQUE_CAPABLE))
paul718e3742002-12-13 20:15:29 +00002645 {
2646 if (IS_SET_DD_I (nbr->dd_flags)
2647 || CHECK_FLAG (nbr->options, OSPF_OPTION_O))
2648 /*
2649 * Set O-bit in the outgoing DD packet for capablity negotiation,
2650 * if one of following case is applicable.
2651 *
2652 * 1) WaitTimer expiration event triggered the neighbor state to
2653 * change to Exstart, but no (valid) DD packet has received
2654 * from the neighbor yet.
2655 *
2656 * 2) At least one DD packet with O-bit on has received from the
2657 * neighbor.
2658 */
2659 SET_FLAG (options, OSPF_OPTION_O);
2660 }
2661#endif /* HAVE_OPAQUE_LSA */
2662 stream_putc (s, options);
2663
2664 /* Keep pointer to flags. */
paul9985f832005-02-09 15:51:56 +00002665 pp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002666 stream_putc (s, nbr->dd_flags);
2667
2668 /* Set DD Sequence Number. */
2669 stream_putl (s, nbr->dd_seqnum);
2670
2671 if (ospf_db_summary_isempty (nbr))
2672 {
2673 if (nbr->state >= NSM_Exchange)
2674 {
2675 nbr->dd_flags &= ~OSPF_DD_FLAG_M;
2676 /* Set DD flags again */
paul3a9eb092005-02-08 11:29:41 +00002677 stream_putc_at (s, pp, nbr->dd_flags);
paul718e3742002-12-13 20:15:29 +00002678 }
2679 return length;
2680 }
2681
2682 /* Describe LSA Header from Database Summary List. */
2683 lsdb = &nbr->db_sum;
2684
2685 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2686 {
2687 struct route_table *table = lsdb->type[i].db;
2688 struct route_node *rn;
2689
2690 for (rn = route_top (table); rn; rn = route_next (rn))
2691 if ((lsa = rn->info) != NULL)
2692 {
2693#ifdef HAVE_OPAQUE_LSA
2694 if (IS_OPAQUE_LSA (lsa->data->type)
2695 && (! CHECK_FLAG (options, OSPF_OPTION_O)))
2696 {
2697 /* Suppress advertising opaque-informations. */
2698 /* Remove LSA from DB summary list. */
2699 ospf_lsdb_delete (lsdb, lsa);
2700 continue;
2701 }
2702#endif /* HAVE_OPAQUE_LSA */
2703
2704 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
2705 {
2706 struct lsa_header *lsah;
2707 u_int16_t ls_age;
2708
2709 /* DD packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002710 if (length + OSPF_LSA_HEADER_SIZE > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002711 break;
2712
2713 /* Keep pointer to LS age. */
2714 lsah = (struct lsa_header *) (STREAM_DATA (s) +
paul9985f832005-02-09 15:51:56 +00002715 stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002716
2717 /* Proceed stream pointer. */
2718 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2719 length += OSPF_LSA_HEADER_SIZE;
2720
2721 /* Set LS age. */
2722 ls_age = LS_AGE (lsa);
2723 lsah->ls_age = htons (ls_age);
2724
2725 }
2726
2727 /* Remove LSA from DB summary list. */
2728 ospf_lsdb_delete (lsdb, lsa);
2729 }
2730 }
2731
2732 return length;
2733}
2734
paul4dadc292005-05-06 21:37:42 +00002735static int
paul718e3742002-12-13 20:15:29 +00002736ospf_make_ls_req_func (struct stream *s, u_int16_t *length,
2737 unsigned long delta, struct ospf_neighbor *nbr,
2738 struct ospf_lsa *lsa)
2739{
2740 struct ospf_interface *oi;
2741
2742 oi = nbr->oi;
2743
2744 /* LS Request packet overflows interface MTU. */
gdt86f1fd92005-01-10 14:20:43 +00002745 if (*length + delta > ospf_packet_max(oi))
paul718e3742002-12-13 20:15:29 +00002746 return 0;
2747
2748 stream_putl (s, lsa->data->type);
2749 stream_put_ipv4 (s, lsa->data->id.s_addr);
2750 stream_put_ipv4 (s, lsa->data->adv_router.s_addr);
2751
2752 ospf_lsa_unlock (nbr->ls_req_last);
2753 nbr->ls_req_last = ospf_lsa_lock (lsa);
2754
2755 *length += 12;
2756 return 1;
2757}
2758
paul4dadc292005-05-06 21:37:42 +00002759static int
paul718e3742002-12-13 20:15:29 +00002760ospf_make_ls_req (struct ospf_neighbor *nbr, struct stream *s)
2761{
2762 struct ospf_lsa *lsa;
2763 u_int16_t length = OSPF_LS_REQ_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002764 unsigned long delta = stream_get_endp(s)+12;
paul718e3742002-12-13 20:15:29 +00002765 struct route_table *table;
2766 struct route_node *rn;
2767 int i;
2768 struct ospf_lsdb *lsdb;
2769
2770 lsdb = &nbr->ls_req;
2771
2772 for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++)
2773 {
2774 table = lsdb->type[i].db;
2775 for (rn = route_top (table); rn; rn = route_next (rn))
2776 if ((lsa = (rn->info)) != NULL)
2777 if (ospf_make_ls_req_func (s, &length, delta, nbr, lsa) == 0)
2778 {
2779 route_unlock_node (rn);
2780 break;
2781 }
2782 }
2783 return length;
2784}
2785
paul4dadc292005-05-06 21:37:42 +00002786static int
paul718e3742002-12-13 20:15:29 +00002787ls_age_increment (struct ospf_lsa *lsa, int delay)
2788{
2789 int age;
2790
2791 age = IS_LSA_MAXAGE (lsa) ? OSPF_LSA_MAXAGE : LS_AGE (lsa) + delay;
2792
2793 return (age > OSPF_LSA_MAXAGE ? OSPF_LSA_MAXAGE : age);
2794}
2795
paul4dadc292005-05-06 21:37:42 +00002796static int
hasso52dc7ee2004-09-23 19:18:23 +00002797ospf_make_ls_upd (struct ospf_interface *oi, struct list *update, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002798{
2799 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002800 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002801 u_int16_t length = OSPF_LS_UPD_MIN_SIZE;
gdt86f1fd92005-01-10 14:20:43 +00002802 unsigned int size_noauth;
paul9985f832005-02-09 15:51:56 +00002803 unsigned long delta = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +00002804 unsigned long pp;
2805 int count = 0;
2806
2807 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002808 zlog_debug ("ospf_make_ls_upd: Start");
paul59ea14c2004-07-14 20:50:36 +00002809
paul9985f832005-02-09 15:51:56 +00002810 pp = stream_get_endp (s);
2811 stream_forward_endp (s, OSPF_LS_UPD_MIN_SIZE);
paul718e3742002-12-13 20:15:29 +00002812
gdt86f1fd92005-01-10 14:20:43 +00002813 /* Calculate amount of packet usable for data. */
2814 size_noauth = stream_get_size(s) - ospf_packet_authspace(oi);
2815
paul718e3742002-12-13 20:15:29 +00002816 while ((node = listhead (update)) != NULL)
2817 {
2818 struct lsa_header *lsah;
2819 u_int16_t ls_age;
2820
2821 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002822 zlog_debug ("ospf_make_ls_upd: List Iteration");
paul718e3742002-12-13 20:15:29 +00002823
paul1eb8ef22005-04-07 07:30:20 +00002824 lsa = listgetdata (node);
2825
paul718e3742002-12-13 20:15:29 +00002826 assert (lsa->data);
2827
paul68b73392004-09-12 14:21:37 +00002828 /* Will it fit? */
gdt86f1fd92005-01-10 14:20:43 +00002829 if (length + delta + ntohs (lsa->data->length) > size_noauth)
paul59ea14c2004-07-14 20:50:36 +00002830 break;
2831
paul718e3742002-12-13 20:15:29 +00002832 /* Keep pointer to LS age. */
paul9985f832005-02-09 15:51:56 +00002833 lsah = (struct lsa_header *) (STREAM_DATA (s) + stream_get_endp (s));
paul718e3742002-12-13 20:15:29 +00002834
2835 /* Put LSA to Link State Request. */
2836 stream_put (s, lsa->data, ntohs (lsa->data->length));
2837
2838 /* Set LS age. */
2839 /* each hop must increment an lsa_age by transmit_delay
2840 of OSPF interface */
2841 ls_age = ls_age_increment (lsa, OSPF_IF_PARAM (oi, transmit_delay));
2842 lsah->ls_age = htons (ls_age);
2843
2844 length += ntohs (lsa->data->length);
2845 count++;
2846
2847 list_delete_node (update, node);
2848 ospf_lsa_unlock (lsa);
2849 }
2850
2851 /* Now set #LSAs. */
paul3a9eb092005-02-08 11:29:41 +00002852 stream_putl_at (s, pp, count);
paul718e3742002-12-13 20:15:29 +00002853
2854 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00002855 zlog_debug ("ospf_make_ls_upd: Stop");
paul718e3742002-12-13 20:15:29 +00002856 return length;
2857}
2858
paul4dadc292005-05-06 21:37:42 +00002859static int
hasso52dc7ee2004-09-23 19:18:23 +00002860ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)
paul718e3742002-12-13 20:15:29 +00002861{
hasso52dc7ee2004-09-23 19:18:23 +00002862 struct list *rm_list;
2863 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002864 u_int16_t length = OSPF_LS_ACK_MIN_SIZE;
paul9985f832005-02-09 15:51:56 +00002865 unsigned long delta = stream_get_endp(s) + 24;
paul718e3742002-12-13 20:15:29 +00002866 struct ospf_lsa *lsa;
2867
2868 rm_list = list_new ();
2869
paul1eb8ef22005-04-07 07:30:20 +00002870 for (ALL_LIST_ELEMENTS_RO (ack, node, lsa))
paul718e3742002-12-13 20:15:29 +00002871 {
paul1eb8ef22005-04-07 07:30:20 +00002872 lsa = listgetdata (node);
paul718e3742002-12-13 20:15:29 +00002873 assert (lsa);
2874
gdt86f1fd92005-01-10 14:20:43 +00002875 if (length + delta > ospf_packet_max (oi))
paul718e3742002-12-13 20:15:29 +00002876 break;
2877
2878 stream_put (s, lsa->data, OSPF_LSA_HEADER_SIZE);
2879 length += OSPF_LSA_HEADER_SIZE;
2880
2881 listnode_add (rm_list, lsa);
2882 }
2883
2884 /* Remove LSA from LS-Ack list. */
paul1eb8ef22005-04-07 07:30:20 +00002885 /* XXX: this loop should be removed and the list move done in previous
2886 * loop
2887 */
2888 for (ALL_LIST_ELEMENTS_RO (rm_list, node, lsa))
paul718e3742002-12-13 20:15:29 +00002889 {
paul718e3742002-12-13 20:15:29 +00002890 listnode_delete (ack, lsa);
2891 ospf_lsa_unlock (lsa);
2892 }
2893
2894 list_delete (rm_list);
2895
2896 return length;
2897}
2898
2899void
2900ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)
2901{
2902 struct ospf_packet *op;
2903 u_int16_t length = OSPF_HEADER_SIZE;
2904
2905 op = ospf_packet_new (oi->ifp->mtu);
2906
2907 /* Prepare OSPF common header. */
2908 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
2909
2910 /* Prepare OSPF Hello body. */
2911 length += ospf_make_hello (oi, op->s);
2912
2913 /* Fill OSPF header. */
2914 ospf_fill_header (oi, op->s, length);
2915
2916 /* Set packet length. */
2917 op->length = length;
2918
2919 op->dst.s_addr = addr->s_addr;
2920
2921 /* Add packet to the interface output queue. */
2922 ospf_packet_add (oi, op);
2923
2924 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00002925 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00002926}
2927
paul4dadc292005-05-06 21:37:42 +00002928static void
paul718e3742002-12-13 20:15:29 +00002929ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)
2930{
2931 struct ospf_interface *oi;
2932
2933 oi = nbr_nbma->oi;
2934 assert(oi);
2935
2936 /* If this is passive interface, do not send OSPF Hello. */
2937 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
2938 return;
2939
2940 if (oi->type != OSPF_IFTYPE_NBMA)
2941 return;
2942
2943 if (nbr_nbma->nbr != NULL && nbr_nbma->nbr->state != NSM_Down)
2944 return;
2945
2946 if (PRIORITY(oi) == 0)
2947 return;
2948
2949 if (nbr_nbma->priority == 0
2950 && oi->state != ISM_DR && oi->state != ISM_Backup)
2951 return;
2952
2953 ospf_hello_send_sub (oi, &nbr_nbma->addr);
2954}
2955
2956int
2957ospf_poll_timer (struct thread *thread)
2958{
2959 struct ospf_nbr_nbma *nbr_nbma;
2960
2961 nbr_nbma = THREAD_ARG (thread);
2962 nbr_nbma->t_poll = NULL;
2963
2964 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002965 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Poll timer expire)",
paul718e3742002-12-13 20:15:29 +00002966 IF_NAME (nbr_nbma->oi), inet_ntoa (nbr_nbma->addr));
2967
2968 ospf_poll_send (nbr_nbma);
2969
2970 if (nbr_nbma->v_poll > 0)
2971 OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
2972 nbr_nbma->v_poll);
2973
2974 return 0;
2975}
2976
2977
2978int
2979ospf_hello_reply_timer (struct thread *thread)
2980{
2981 struct ospf_neighbor *nbr;
2982
2983 nbr = THREAD_ARG (thread);
2984 nbr->t_hello_reply = NULL;
2985
2986 assert (nbr->oi);
2987
2988 if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
ajs2a42e282004-12-08 18:43:03 +00002989 zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",
paul718e3742002-12-13 20:15:29 +00002990 IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));
2991
2992 ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4);
2993
2994 return 0;
2995}
2996
2997/* Send OSPF Hello. */
2998void
2999ospf_hello_send (struct ospf_interface *oi)
3000{
3001 struct ospf_packet *op;
3002 u_int16_t length = OSPF_HEADER_SIZE;
3003
3004 /* If this is passive interface, do not send OSPF Hello. */
3005 if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE)
3006 return;
3007
3008 op = ospf_packet_new (oi->ifp->mtu);
3009
3010 /* Prepare OSPF common header. */
3011 ospf_make_header (OSPF_MSG_HELLO, oi, op->s);
3012
3013 /* Prepare OSPF Hello body. */
3014 length += ospf_make_hello (oi, op->s);
3015
3016 /* Fill OSPF header. */
3017 ospf_fill_header (oi, op->s, length);
3018
3019 /* Set packet length. */
3020 op->length = length;
3021
3022 if (oi->type == OSPF_IFTYPE_NBMA)
3023 {
3024 struct ospf_neighbor *nbr;
3025 struct route_node *rn;
3026
3027 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3028 if ((nbr = rn->info))
3029 if (nbr != oi->nbr_self)
3030 if (nbr->state != NSM_Down)
3031 {
3032 /* RFC 2328 Section 9.5.1
3033 If the router is not eligible to become Designated Router,
3034 it must periodically send Hello Packets to both the
3035 Designated Router and the Backup Designated Router (if they
3036 exist). */
3037 if (PRIORITY(oi) == 0 &&
3038 IPV4_ADDR_CMP(&DR(oi), &nbr->address.u.prefix4) &&
3039 IPV4_ADDR_CMP(&BDR(oi), &nbr->address.u.prefix4))
3040 continue;
3041
3042 /* If the router is eligible to become Designated Router, it
3043 must periodically send Hello Packets to all neighbors that
3044 are also eligible. In addition, if the router is itself the
3045 Designated Router or Backup Designated Router, it must also
3046 send periodic Hello Packets to all other neighbors. */
3047
3048 if (nbr->priority == 0 && oi->state == ISM_DROther)
3049 continue;
3050 /* if oi->state == Waiting, send hello to all neighbors */
3051 {
3052 struct ospf_packet *op_dup;
3053
3054 op_dup = ospf_packet_dup(op);
3055 op_dup->dst = nbr->address.u.prefix4;
3056
3057 /* Add packet to the interface output queue. */
3058 ospf_packet_add (oi, op_dup);
3059
paul020709f2003-04-04 02:44:16 +00003060 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003061 }
3062
3063 }
3064 ospf_packet_free (op);
3065 }
3066 else
3067 {
3068 /* Decide destination address. */
3069 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3070 op->dst.s_addr = oi->vl_data->peer_addr.s_addr;
3071 else
3072 op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3073
3074 /* Add packet to the interface output queue. */
3075 ospf_packet_add (oi, op);
3076
3077 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003078 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003079 }
3080}
3081
3082/* Send OSPF Database Description. */
3083void
3084ospf_db_desc_send (struct ospf_neighbor *nbr)
3085{
3086 struct ospf_interface *oi;
3087 struct ospf_packet *op;
3088 u_int16_t length = OSPF_HEADER_SIZE;
3089
3090 oi = nbr->oi;
3091 op = ospf_packet_new (oi->ifp->mtu);
3092
3093 /* Prepare OSPF common header. */
3094 ospf_make_header (OSPF_MSG_DB_DESC, oi, op->s);
3095
3096 /* Prepare OSPF Database Description body. */
3097 length += ospf_make_db_desc (oi, nbr, op->s);
3098
3099 /* Fill OSPF header. */
3100 ospf_fill_header (oi, op->s, length);
3101
3102 /* Set packet length. */
3103 op->length = length;
3104
3105 /* Decide destination address. */
3106 op->dst = nbr->address.u.prefix4;
3107
3108 /* Add packet to the interface output queue. */
3109 ospf_packet_add (oi, op);
3110
3111 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003112 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003113
3114 /* Remove old DD packet, then copy new one and keep in neighbor structure. */
3115 if (nbr->last_send)
3116 ospf_packet_free (nbr->last_send);
3117 nbr->last_send = ospf_packet_dup (op);
3118 gettimeofday (&nbr->last_send_ts, NULL);
3119}
3120
3121/* Re-send Database Description. */
3122void
3123ospf_db_desc_resend (struct ospf_neighbor *nbr)
3124{
3125 struct ospf_interface *oi;
3126
3127 oi = nbr->oi;
3128
3129 /* Add packet to the interface output queue. */
3130 ospf_packet_add (oi, ospf_packet_dup (nbr->last_send));
3131
3132 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003133 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003134}
3135
3136/* Send Link State Request. */
3137void
3138ospf_ls_req_send (struct ospf_neighbor *nbr)
3139{
3140 struct ospf_interface *oi;
3141 struct ospf_packet *op;
3142 u_int16_t length = OSPF_HEADER_SIZE;
3143
3144 oi = nbr->oi;
3145 op = ospf_packet_new (oi->ifp->mtu);
3146
3147 /* Prepare OSPF common header. */
3148 ospf_make_header (OSPF_MSG_LS_REQ, oi, op->s);
3149
3150 /* Prepare OSPF Link State Request body. */
3151 length += ospf_make_ls_req (nbr, op->s);
3152 if (length == OSPF_HEADER_SIZE)
3153 {
3154 ospf_packet_free (op);
3155 return;
3156 }
3157
3158 /* Fill OSPF header. */
3159 ospf_fill_header (oi, op->s, length);
3160
3161 /* Set packet length. */
3162 op->length = length;
3163
3164 /* Decide destination address. */
3165 op->dst = nbr->address.u.prefix4;
3166
3167 /* Add packet to the interface output queue. */
3168 ospf_packet_add (oi, op);
3169
3170 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003171 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003172
3173 /* Add Link State Request Retransmission Timer. */
3174 OSPF_NSM_TIMER_ON (nbr->t_ls_req, ospf_ls_req_timer, nbr->v_ls_req);
3175}
3176
3177/* Send Link State Update with an LSA. */
3178void
3179ospf_ls_upd_send_lsa (struct ospf_neighbor *nbr, struct ospf_lsa *lsa,
3180 int flag)
3181{
hasso52dc7ee2004-09-23 19:18:23 +00003182 struct list *update;
paul718e3742002-12-13 20:15:29 +00003183
3184 update = list_new ();
3185
3186 listnode_add (update, lsa);
3187 ospf_ls_upd_send (nbr, update, flag);
3188
3189 list_delete (update);
3190}
3191
paul68b73392004-09-12 14:21:37 +00003192/* Determine size for packet. Must be at least big enough to accomodate next
3193 * LSA on list, which may be bigger than MTU size.
3194 *
3195 * Return pointer to new ospf_packet
3196 * NULL if we can not allocate, eg because LSA is bigger than imposed limit
3197 * on packet sizes (in which case offending LSA is deleted from update list)
3198 */
3199static struct ospf_packet *
3200ospf_ls_upd_packet_new (struct list *update, struct ospf_interface *oi)
3201{
3202 struct ospf_lsa *lsa;
3203 struct listnode *ln;
3204 size_t size;
3205 static char warned = 0;
3206
paul1eb8ef22005-04-07 07:30:20 +00003207 lsa = listgetdata((ln = listhead (update)));
paul68b73392004-09-12 14:21:37 +00003208 assert (lsa->data);
3209
3210 if ((OSPF_LS_UPD_MIN_SIZE + ntohs (lsa->data->length))
3211 > ospf_packet_max (oi))
3212 {
3213 if (!warned)
3214 {
3215 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA encountered!"
3216 "will need to fragment. Not optimal. Try divide up"
3217 " your network with areas. Use 'debug ospf packet send'"
3218 " to see details, or look at 'show ip ospf database ..'");
3219 warned = 1;
3220 }
3221
3222 if (IS_DEBUG_OSPF_PACKET (0, SEND))
ajs2a42e282004-12-08 18:43:03 +00003223 zlog_debug ("ospf_ls_upd_packet_new: oversized LSA id:%s,"
paul68b73392004-09-12 14:21:37 +00003224 " %d bytes originated by %s, will be fragmented!",
3225 inet_ntoa (lsa->data->id),
3226 ntohs (lsa->data->length),
3227 inet_ntoa (lsa->data->adv_router));
3228
3229 /*
3230 * Allocate just enough to fit this LSA only, to avoid including other
3231 * LSAs in fragmented LSA Updates.
3232 */
3233 size = ntohs (lsa->data->length) + (oi->ifp->mtu - ospf_packet_max (oi))
3234 + OSPF_LS_UPD_MIN_SIZE;
3235 }
3236 else
3237 size = oi->ifp->mtu;
3238
gdt86f1fd92005-01-10 14:20:43 +00003239 /* XXX Should this be - sizeof(struct ip)?? -gdt */
paul68b73392004-09-12 14:21:37 +00003240 if (size > OSPF_MAX_PACKET_SIZE)
3241 {
3242 zlog_warn ("ospf_ls_upd_packet_new: oversized LSA id:%s too big,"
paul64511f32004-10-31 18:01:13 +00003243 " %d bytes, packet size %ld, dropping it completely."
paul68b73392004-09-12 14:21:37 +00003244 " OSPF routing is broken!",
paul37ccfa32004-10-31 11:24:51 +00003245 inet_ntoa (lsa->data->id), ntohs (lsa->data->length),
paul62d8e962004-11-02 20:26:45 +00003246 (long int) size);
paul68b73392004-09-12 14:21:37 +00003247 list_delete_node (update, ln);
3248 return NULL;
3249 }
3250
3251 return ospf_packet_new (size);
3252}
3253
paul718e3742002-12-13 20:15:29 +00003254static void
hasso52dc7ee2004-09-23 19:18:23 +00003255ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,
paul718e3742002-12-13 20:15:29 +00003256 struct in_addr addr)
3257{
3258 struct ospf_packet *op;
3259 u_int16_t length = OSPF_HEADER_SIZE;
3260
3261 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003262 zlog_debug ("listcount = %d, dst %s", listcount (update), inet_ntoa(addr));
paul68b73392004-09-12 14:21:37 +00003263
3264 op = ospf_ls_upd_packet_new (update, oi);
paul718e3742002-12-13 20:15:29 +00003265
3266 /* Prepare OSPF common header. */
3267 ospf_make_header (OSPF_MSG_LS_UPD, oi, op->s);
3268
paul59ea14c2004-07-14 20:50:36 +00003269 /* Prepare OSPF Link State Update body.
3270 * Includes Type-7 translation.
3271 */
paul718e3742002-12-13 20:15:29 +00003272 length += ospf_make_ls_upd (oi, update, op->s);
3273
3274 /* Fill OSPF header. */
3275 ospf_fill_header (oi, op->s, length);
3276
3277 /* Set packet length. */
3278 op->length = length;
3279
3280 /* Decide destination address. */
3281 op->dst.s_addr = addr.s_addr;
3282
3283 /* Add packet to the interface output queue. */
3284 ospf_packet_add (oi, op);
3285
3286 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003287 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003288}
3289
3290static int
3291ospf_ls_upd_send_queue_event (struct thread *thread)
3292{
3293 struct ospf_interface *oi = THREAD_ARG(thread);
3294 struct route_node *rn;
paul736d3442003-07-24 23:22:57 +00003295 struct route_node *rnext;
paul59ea14c2004-07-14 20:50:36 +00003296 struct list *update;
paul68b73392004-09-12 14:21:37 +00003297 char again = 0;
paul718e3742002-12-13 20:15:29 +00003298
3299 oi->t_ls_upd_event = NULL;
3300
3301 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003302 zlog_debug ("ospf_ls_upd_send_queue start");
paul718e3742002-12-13 20:15:29 +00003303
paul736d3442003-07-24 23:22:57 +00003304 for (rn = route_top (oi->ls_upd_queue); rn; rn = rnext)
paul718e3742002-12-13 20:15:29 +00003305 {
paul736d3442003-07-24 23:22:57 +00003306 rnext = route_next (rn);
3307
paul718e3742002-12-13 20:15:29 +00003308 if (rn->info == NULL)
paul736d3442003-07-24 23:22:57 +00003309 continue;
paul68b73392004-09-12 14:21:37 +00003310
3311 update = (struct list *)rn->info;
paul718e3742002-12-13 20:15:29 +00003312
paul48fe13b2004-07-27 17:40:44 +00003313 ospf_ls_upd_queue_send (oi, update, rn->p.u.prefix4);
paul718e3742002-12-13 20:15:29 +00003314
paul68b73392004-09-12 14:21:37 +00003315 /* list might not be empty. */
paul59ea14c2004-07-14 20:50:36 +00003316 if (listcount(update) == 0)
3317 {
3318 list_delete (rn->info);
3319 rn->info = NULL;
3320 route_unlock_node (rn);
3321 }
3322 else
paul68b73392004-09-12 14:21:37 +00003323 again = 1;
paul59ea14c2004-07-14 20:50:36 +00003324 }
3325
3326 if (again != 0)
3327 {
3328 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003329 zlog_debug ("ospf_ls_upd_send_queue: update lists not cleared,"
paul59ea14c2004-07-14 20:50:36 +00003330 " %d nodes to try again, raising new event", again);
3331 oi->t_ls_upd_event =
3332 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
paul718e3742002-12-13 20:15:29 +00003333 }
3334
3335 if (IS_DEBUG_OSPF_EVENT)
ajs2a42e282004-12-08 18:43:03 +00003336 zlog_debug ("ospf_ls_upd_send_queue stop");
paul59ea14c2004-07-14 20:50:36 +00003337
paul718e3742002-12-13 20:15:29 +00003338 return 0;
3339}
3340
3341void
hasso52dc7ee2004-09-23 19:18:23 +00003342ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)
paul718e3742002-12-13 20:15:29 +00003343{
3344 struct ospf_interface *oi;
paul1eb8ef22005-04-07 07:30:20 +00003345 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003346 struct prefix_ipv4 p;
3347 struct route_node *rn;
paul1eb8ef22005-04-07 07:30:20 +00003348 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003349
3350 oi = nbr->oi;
3351
3352 p.family = AF_INET;
3353 p.prefixlen = IPV4_MAX_BITLEN;
3354
3355 /* Decide destination address. */
3356 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3357 p.prefix = oi->vl_data->peer_addr;
3358 else if (flag == OSPF_SEND_PACKET_DIRECT)
3359 p.prefix = nbr->address.u.prefix4;
3360 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3361 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
3362 else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)
3363 && (flag == OSPF_SEND_PACKET_INDIRECT))
3364 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul7afa08d2002-12-13 20:59:45 +00003365 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3366 p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003367 else
3368 p.prefix.s_addr = htonl (OSPF_ALLDROUTERS);
3369
3370 if (oi->type == OSPF_IFTYPE_NBMA)
3371 {
3372 if (flag == OSPF_SEND_PACKET_INDIRECT)
3373 zlog_warn ("* LS-Update is directly sent on NBMA network.");
3374 if (IPV4_ADDR_SAME(&oi->address->u.prefix4, &p.prefix.s_addr))
3375 zlog_warn ("* LS-Update is sent to myself.");
3376 }
3377
3378 rn = route_node_get (oi->ls_upd_queue, (struct prefix *) &p);
3379
3380 if (rn->info == NULL)
3381 rn->info = list_new ();
3382
paul1eb8ef22005-04-07 07:30:20 +00003383 for (ALL_LIST_ELEMENTS_RO (update, node, lsa))
3384 {
3385 ospf_lsa_lock (lsa);
3386 listnode_add (rn->info, lsa);
3387 }
paul718e3742002-12-13 20:15:29 +00003388
3389 if (oi->t_ls_upd_event == NULL)
3390 oi->t_ls_upd_event =
3391 thread_add_event (master, ospf_ls_upd_send_queue_event, oi, 0);
3392}
3393
3394static void
hasso52dc7ee2004-09-23 19:18:23 +00003395ospf_ls_ack_send_list (struct ospf_interface *oi, struct list *ack,
3396 struct in_addr dst)
paul718e3742002-12-13 20:15:29 +00003397{
3398 struct ospf_packet *op;
3399 u_int16_t length = OSPF_HEADER_SIZE;
3400
3401 op = ospf_packet_new (oi->ifp->mtu);
3402
3403 /* Prepare OSPF common header. */
3404 ospf_make_header (OSPF_MSG_LS_ACK, oi, op->s);
3405
3406 /* Prepare OSPF Link State Acknowledgment body. */
3407 length += ospf_make_ls_ack (oi, ack, op->s);
3408
3409 /* Fill OSPF header. */
3410 ospf_fill_header (oi, op->s, length);
3411
3412 /* Set packet length. */
3413 op->length = length;
3414
3415 /* Set destination IP address. */
3416 op->dst = dst;
3417
3418 /* Add packet to the interface output queue. */
3419 ospf_packet_add (oi, op);
3420
3421 /* Hook thread to write packet. */
paul020709f2003-04-04 02:44:16 +00003422 OSPF_ISM_WRITE_ON (oi->ospf);
paul718e3742002-12-13 20:15:29 +00003423}
3424
3425static int
3426ospf_ls_ack_send_event (struct thread *thread)
3427{
3428 struct ospf_interface *oi = THREAD_ARG (thread);
3429
3430 oi->t_ls_ack_direct = NULL;
3431
3432 while (listcount (oi->ls_ack_direct.ls_ack))
3433 ospf_ls_ack_send_list (oi, oi->ls_ack_direct.ls_ack,
3434 oi->ls_ack_direct.dst);
3435
3436 return 0;
3437}
3438
3439void
3440ospf_ls_ack_send (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
3441{
3442 struct ospf_interface *oi = nbr->oi;
3443
3444 if (listcount (oi->ls_ack_direct.ls_ack) == 0)
3445 oi->ls_ack_direct.dst = nbr->address.u.prefix4;
3446
3447 listnode_add (oi->ls_ack_direct.ls_ack, ospf_lsa_lock (lsa));
3448
3449 if (oi->t_ls_ack_direct == NULL)
3450 oi->t_ls_ack_direct =
3451 thread_add_event (master, ospf_ls_ack_send_event, oi, 0);
3452}
3453
3454/* Send Link State Acknowledgment delayed. */
3455void
3456ospf_ls_ack_send_delayed (struct ospf_interface *oi)
3457{
3458 struct in_addr dst;
3459
3460 /* Decide destination address. */
3461 /* RFC2328 Section 13.5 On non-broadcast
3462 networks, delayed Link State Acknowledgment packets must be
3463 unicast separately over each adjacency (i.e., neighbor whose
3464 state is >= Exchange). */
3465 if (oi->type == OSPF_IFTYPE_NBMA)
3466 {
3467 struct ospf_neighbor *nbr;
3468 struct route_node *rn;
3469
3470 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
3471 if ((nbr = rn->info) != NULL)
3472 if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange)
3473 while (listcount (oi->ls_ack))
3474 ospf_ls_ack_send_list (oi, oi->ls_ack, nbr->address.u.prefix4);
3475 return;
3476 }
3477 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
3478 dst.s_addr = oi->vl_data->peer_addr.s_addr;
3479 else if (oi->state == ISM_DR || oi->state == ISM_Backup)
3480 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
3481 else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
3482 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
gdt630e4802004-08-31 17:28:41 +00003483 else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
3484 dst.s_addr = htonl (OSPF_ALLSPFROUTERS);
paul718e3742002-12-13 20:15:29 +00003485 else
3486 dst.s_addr = htonl (OSPF_ALLDROUTERS);
3487
3488 while (listcount (oi->ls_ack))
3489 ospf_ls_ack_send_list (oi, oi->ls_ack, dst);
3490}